fixes for buggy GCC compilers
[tinycc.git] / tcc.c
blobbab22f73b2724c2b3c906001714151f871bcebfa
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 #define _GNU_SOURCE
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <math.h>
27 #include <unistd.h>
28 #include <signal.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <setjmp.h>
32 #ifdef WIN32
33 #include <sys/timeb.h>
34 #endif
35 #ifndef WIN32
36 #include <sys/time.h>
37 #include <sys/ucontext.h>
38 #endif
39 #include "elf.h"
40 #include "stab.h"
41 #ifndef CONFIG_TCC_STATIC
42 #include <dlfcn.h>
43 #endif
45 #include "libtcc.h"
47 /* parser debug */
48 //#define PARSE_DEBUG
49 /* preprocessor debug */
50 //#define PP_DEBUG
51 /* include file debug */
52 //#define INC_DEBUG
54 //#define MEM_DEBUG
56 /* target selection */
57 //#define TCC_TARGET_I386 /* i386 code generator */
58 //#define TCC_TARGET_IL /* .NET CLI generator */
60 /* default target is I386 */
61 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
62 #define TCC_TARGET_I386
63 #endif
65 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
66 #define CONFIG_TCC_BCHECK /* enable bound checking code */
67 #endif
69 #ifndef CONFIG_TCC_PREFIX
70 #define CONFIG_TCC_PREFIX "/usr/local"
71 #endif
73 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
74 executables or dlls */
75 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
77 #define INCLUDE_STACK_SIZE 32
78 #define IFDEF_STACK_SIZE 64
79 #define VSTACK_SIZE 64
80 #define STRING_MAX_SIZE 1024
82 #define TOK_HASH_SIZE 2048 /* must be a power of two */
83 #define TOK_ALLOC_INCR 512 /* must be a power of two */
84 #define TOK_STR_ALLOC_INCR_BITS 6
85 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
86 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
88 /* token symbol management */
89 typedef struct TokenSym {
90 struct TokenSym *hash_next;
91 struct Sym *sym_define; /* direct pointer to define */
92 struct Sym *sym_label; /* direct pointer to label */
93 struct Sym *sym_struct; /* direct pointer to structure */
94 struct Sym *sym_identifier; /* direct pointer to identifier */
95 int tok; /* token number */
96 int len;
97 char str[1];
98 } TokenSym;
100 typedef struct CString {
101 int size; /* size in bytes */
102 void *data; /* either 'char *' or 'int *' */
103 int size_allocated;
104 void *data_allocated; /* if non NULL, data has been malloced */
105 } CString;
107 /* type definition */
108 typedef struct CType {
109 int t;
110 struct Sym *ref;
111 } CType;
113 /* constant value */
114 typedef union CValue {
115 long double ld;
116 double d;
117 float f;
118 int i;
119 unsigned int ui;
120 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
121 long long ll;
122 unsigned long long ull;
123 struct CString *cstr;
124 void *ptr;
125 int tab[1];
126 } CValue;
128 /* value on stack */
129 typedef struct SValue {
130 CType type; /* type */
131 unsigned short r; /* register + flags */
132 unsigned short r2; /* second register, used for 'long long'
133 type. If not used, set to VT_CONST */
134 CValue c; /* constant, if VT_CONST */
135 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
136 } SValue;
138 /* symbol management */
139 typedef struct Sym {
140 int v; /* symbol token */
141 int r; /* associated register */
142 int c; /* associated number */
143 CType type; /* associated type */
144 struct Sym *next; /* next related symbol */
145 struct Sym *prev; /* prev symbol in stack */
146 struct Sym *prev_tok; /* previous symbol for this token */
147 } Sym;
149 /* section definition */
150 /* XXX: use directly ELF structure for parameters ? */
151 /* special flag to indicate that the section should not be linked to
152 the other ones */
153 #define SHF_PRIVATE 0x80000000
155 typedef struct Section {
156 unsigned long data_offset; /* current data offset */
157 unsigned char *data; /* section data */
158 unsigned long data_allocated; /* used for realloc() handling */
159 int sh_name; /* elf section name (only used during output) */
160 int sh_num; /* elf section number */
161 int sh_type; /* elf section type */
162 int sh_flags; /* elf section flags */
163 int sh_info; /* elf section info */
164 int sh_addralign; /* elf section alignment */
165 int sh_entsize; /* elf entry size */
166 unsigned long sh_size; /* section size (only used during output) */
167 unsigned long sh_addr; /* address at which the section is relocated */
168 unsigned long sh_offset; /* address at which the section is relocated */
169 int nb_hashed_syms; /* used to resize the hash table */
170 struct Section *link; /* link to another section */
171 struct Section *reloc; /* corresponding section for relocation, if any */
172 struct Section *hash; /* hash table for symbols */
173 struct Section *next;
174 char name[64]; /* section name */
175 } Section;
177 typedef struct DLLReference {
178 int level;
179 char name[1];
180 } DLLReference;
182 /* GNUC attribute definition */
183 typedef struct AttributeDef {
184 int aligned;
185 Section *section;
186 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
187 } AttributeDef;
189 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
190 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
191 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
193 /* stored in 'Sym.c' field */
194 #define FUNC_NEW 1 /* ansi function prototype */
195 #define FUNC_OLD 2 /* old function prototype */
196 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
198 /* stored in 'Sym.r' field */
199 #define FUNC_CDECL 0 /* standard c call */
200 #define FUNC_STDCALL 1 /* pascal c call */
202 /* field 'Sym.t' for macros */
203 #define MACRO_OBJ 0 /* object like macro */
204 #define MACRO_FUNC 1 /* function like macro */
206 /* field 'Sym.r' for labels */
207 #define LABEL_FORWARD 1 /* label is forward defined */
209 /* type_decl() types */
210 #define TYPE_ABSTRACT 1 /* type without variable */
211 #define TYPE_DIRECT 2 /* type with variable */
213 #define IO_BUF_SIZE 8192
215 typedef struct BufferedFile {
216 uint8_t *buf_ptr;
217 uint8_t *buf_end;
218 int fd;
219 int line_num; /* current line number - here to simply code */
220 int ifndef_macro; /* #ifndef macro / #endif search */
221 int ifndef_macro_saved; /* saved ifndef_macro */
222 int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
223 char inc_type; /* type of include */
224 char inc_filename[512]; /* filename specified by the user */
225 char filename[1024]; /* current filename - here to simplify code */
226 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
227 } BufferedFile;
229 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
230 #define CH_EOF (-1) /* end of file */
232 /* parsing state (used to save parser state to reparse part of the
233 source several times) */
234 typedef struct ParseState {
235 int *macro_ptr;
236 int line_num;
237 int tok;
238 CValue tokc;
239 } ParseState;
241 /* used to record tokens */
242 typedef struct TokenString {
243 int *str;
244 int len;
245 int allocated_len;
246 int last_line_num;
247 } TokenString;
249 /* include file cache, used to find files faster and also to eliminate
250 inclusion if the include file is protected by #ifndef ... #endif */
251 typedef struct CachedInclude {
252 int ifndef_macro;
253 char type; /* '"' or '>' to give include type */
254 char filename[1]; /* path specified in #include */
255 } CachedInclude;
257 /* parser */
258 static struct BufferedFile *file;
259 static int ch, tok, tok1;
260 static CValue tokc, tok1c;
261 static CString tokcstr; /* current parsed string, if any */
262 /* additionnal informations about token */
263 static int tok_flags;
264 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
265 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
266 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
268 /* if true, line feed is returned as a token. line feed is also
269 returned at eof */
270 static int return_linefeed;
271 static Section *text_section, *data_section, *bss_section; /* predefined sections */
272 static Section *cur_text_section; /* current section where function code is
273 generated */
274 /* bound check related sections */
275 static Section *bounds_section; /* contains global data bound description */
276 static Section *lbounds_section; /* contains local data bound description */
277 /* symbol sections */
278 static Section *symtab_section, *strtab_section;
280 /* debug sections */
281 static Section *stab_section, *stabstr_section;
283 /* loc : local variable index
284 ind : output code index
285 rsym: return symbol
286 anon_sym: anonymous symbol index
288 static int rsym, anon_sym, ind, loc;
289 /* expression generation modifiers */
290 static int const_wanted; /* true if constant wanted */
291 static int nocode_wanted; /* true if no code generation wanted for an expression */
292 static int global_expr; /* true if compound literals must be allocated
293 globally (used during initializers parsing */
294 static CType func_vt; /* current function return type (used by return
295 instruction) */
296 static int func_vc;
297 static int last_line_num, last_ind, func_ind; /* debug last line number and pc */
298 static int tok_ident;
299 static TokenSym **table_ident;
300 static TokenSym *hash_ident[TOK_HASH_SIZE];
301 static char token_buf[STRING_MAX_SIZE + 1];
302 static char *funcname;
303 static Sym *global_stack, *local_stack;
304 static Sym *define_stack;
305 static Sym *label_stack;
307 static SValue vstack[VSTACK_SIZE], *vtop;
308 static int *macro_ptr, *macro_ptr_allocated;
309 /* some predefined types */
310 static CType char_pointer_type, func_old_type, int_type;
312 /* compile with debug symbol (and use them if error during execution) */
313 static int do_debug = 0;
315 /* compile with built-in memory and bounds checker */
316 static int do_bounds_check = 0;
318 /* display benchmark infos */
319 static int do_bench = 0;
320 static int total_lines;
321 static int total_bytes;
323 /* use GNU C extensions */
324 static int gnu_ext = 1;
326 /* use Tiny C extensions */
327 static int tcc_ext = 1;
329 /* max number of callers shown if error */
330 static int num_callers = 6;
331 static const char **rt_bound_error_msg;
333 /* XXX: suppress that ASAP */
334 static struct TCCState *tcc_state;
336 /* give the path of the tcc libraries */
337 static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc";
339 struct TCCState {
340 int output_type;
342 BufferedFile **include_stack_ptr;
343 int *ifdef_stack_ptr;
345 /* include file handling */
346 char **include_paths;
347 int nb_include_paths;
348 char **sysinclude_paths;
349 int nb_sysinclude_paths;
350 CachedInclude **cached_includes;
351 int nb_cached_includes;
353 char **library_paths;
354 int nb_library_paths;
356 /* array of all loaded dlls (including those referenced by loaded
357 dlls) */
358 DLLReference **loaded_dlls;
359 int nb_loaded_dlls;
361 /* sections */
362 Section **sections;
363 int nb_sections; /* number of sections, including first dummy section */
365 /* got handling */
366 Section *got;
367 unsigned long *got_offsets;
368 int nb_got_offsets;
369 int nb_plt_entries;
370 /* give the correspondance from symtab indexes to dynsym indexes */
371 int *symtab_to_dynsym;
373 /* temporary dynamic symbol sections (for dll loading) */
374 Section *dynsymtab_section;
375 /* exported dynamic symbol section */
376 Section *dynsym;
378 /* if true, static linking is performed */
379 int static_link;
381 /* error handling */
382 void *error_opaque;
383 void (*error_func)(void *opaque, const char *msg);
384 int error_set_jmp_enabled;
385 jmp_buf error_jmp_buf;
386 int nb_errors;
388 /* see include_stack_ptr */
389 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
391 /* see ifdef_stack_ptr */
392 int ifdef_stack[IFDEF_STACK_SIZE];
395 /* The current value can be: */
396 #define VT_VALMASK 0x00ff
397 #define VT_CONST 0x00f0 /* constant in vc
398 (must be first non register value) */
399 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
400 #define VT_LOCAL 0x00f2 /* offset on stack */
401 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
402 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
403 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
404 #define VT_LVAL 0x0100 /* var is an lvalue */
405 #define VT_SYM 0x0200 /* a symbol value is added */
406 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
407 char/short stored in integer registers) */
408 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
409 dereferencing value */
410 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
411 bounding function call point is in vc */
412 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
413 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
414 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
415 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
417 /* types */
418 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
420 #define VT_INT 0 /* integer type */
421 #define VT_BYTE 1 /* signed byte type */
422 #define VT_SHORT 2 /* short type */
423 #define VT_VOID 3 /* void type */
424 #define VT_PTR 4 /* pointer */
425 #define VT_ENUM 5 /* enum definition */
426 #define VT_FUNC 6 /* function type */
427 #define VT_STRUCT 7 /* struct/union definition */
428 #define VT_FLOAT 8 /* IEEE float */
429 #define VT_DOUBLE 9 /* IEEE double */
430 #define VT_LDOUBLE 10 /* IEEE long double */
431 #define VT_BOOL 11 /* ISOC99 boolean type */
432 #define VT_LLONG 12 /* 64 bit integer */
433 #define VT_LONG 13 /* long integer (NEVER USED as type, only
434 during parsing) */
435 #define VT_BTYPE 0x000f /* mask for basic type */
436 #define VT_UNSIGNED 0x0010 /* unsigned type */
437 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
438 #define VT_BITFIELD 0x0040 /* bitfield modifier */
440 /* storage */
441 #define VT_EXTERN 0x00000080 /* extern definition */
442 #define VT_STATIC 0x00000100 /* static variable */
443 #define VT_TYPEDEF 0x00000200 /* typedef definition */
445 /* type mask (except storage) */
446 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
448 /* token values */
450 /* warning: the following compare tokens depend on i386 asm code */
451 #define TOK_ULT 0x92
452 #define TOK_UGE 0x93
453 #define TOK_EQ 0x94
454 #define TOK_NE 0x95
455 #define TOK_ULE 0x96
456 #define TOK_UGT 0x97
457 #define TOK_LT 0x9c
458 #define TOK_GE 0x9d
459 #define TOK_LE 0x9e
460 #define TOK_GT 0x9f
462 #define TOK_LAND 0xa0
463 #define TOK_LOR 0xa1
465 #define TOK_DEC 0xa2
466 #define TOK_MID 0xa3 /* inc/dec, to void constant */
467 #define TOK_INC 0xa4
468 #define TOK_UDIV 0xb0 /* unsigned division */
469 #define TOK_UMOD 0xb1 /* unsigned modulo */
470 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
471 #define TOK_CINT 0xb3 /* number in tokc */
472 #define TOK_CCHAR 0xb4 /* char constant in tokc */
473 #define TOK_STR 0xb5 /* pointer to string in tokc */
474 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
475 #define TOK_LCHAR 0xb7
476 #define TOK_LSTR 0xb8
477 #define TOK_CFLOAT 0xb9 /* float constant */
478 #define TOK_LINENUM 0xba /* line number info */
479 #define TOK_CDOUBLE 0xc0 /* double constant */
480 #define TOK_CLDOUBLE 0xc1 /* long double constant */
481 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
482 #define TOK_ADDC1 0xc3 /* add with carry generation */
483 #define TOK_ADDC2 0xc4 /* add with carry use */
484 #define TOK_SUBC1 0xc5 /* add with carry generation */
485 #define TOK_SUBC2 0xc6 /* add with carry use */
486 #define TOK_CUINT 0xc8 /* unsigned int constant */
487 #define TOK_CLLONG 0xc9 /* long long constant */
488 #define TOK_CULLONG 0xca /* unsigned long long constant */
489 #define TOK_ARROW 0xcb
490 #define TOK_DOTS 0xcc /* three dots */
491 #define TOK_SHR 0xcd /* unsigned shift right */
492 #define TOK_PPNUM 0xce /* preprocessor number */
494 #define TOK_SHL 0x01 /* shift left */
495 #define TOK_SAR 0x02 /* signed shift right */
497 /* assignement operators : normal operator or 0x80 */
498 #define TOK_A_MOD 0xa5
499 #define TOK_A_AND 0xa6
500 #define TOK_A_MUL 0xaa
501 #define TOK_A_ADD 0xab
502 #define TOK_A_SUB 0xad
503 #define TOK_A_DIV 0xaf
504 #define TOK_A_XOR 0xde
505 #define TOK_A_OR 0xfc
506 #define TOK_A_SHL 0x81
507 #define TOK_A_SAR 0x82
509 /* WARNING: the content of this string encodes token numbers */
510 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";
512 #define TOK_EOF (-1) /* end of file */
513 #define TOK_LINEFEED 10 /* line feed */
515 /* all identificators and strings have token above that */
516 #define TOK_IDENT 256
518 enum {
519 TOK_LAST = TOK_IDENT - 1,
520 #define DEF(id, str) id,
521 #include "tcctok.h"
522 #undef DEF
525 static const char *tcc_keywords =
526 #define DEF(id, str) str "\0"
527 #include "tcctok.h"
528 #undef DEF
531 #define TOK_UIDENT TOK_DEFINE
533 #ifdef WIN32
534 #define snprintf _snprintf
535 #define vsnprintf _vsnprintf
536 #endif
538 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
539 /* currently incorrect */
540 long double strtold(const char *nptr, char **endptr)
542 return (long double)strtod(nptr, endptr);
544 float strtof(const char *nptr, char **endptr)
546 return (float)strtod(nptr, endptr);
548 #else
549 /* XXX: need to define this to use them in non ISOC99 context */
550 extern float strtof (const char *__nptr, char **__endptr);
551 extern long double strtold (const char *__nptr, char **__endptr);
552 #endif
554 static char *pstrcpy(char *buf, int buf_size, const char *s);
555 static char *pstrcat(char *buf, int buf_size, const char *s);
557 static void next(void);
558 static void next_nomacro(void);
559 static void parse_expr_type(CType *type);
560 static void expr_type(CType *type);
561 static void unary_type(CType *type);
562 static int expr_const(void);
563 static void expr_eq(void);
564 static void gexpr(void);
565 static void decl(int l);
566 static void decl_initializer(CType *type, Section *sec, unsigned long c,
567 int first, int size_only);
568 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
569 int has_init, int v, int scope);
570 int gv(int rc);
571 void gv2(int rc1, int rc2);
572 void move_reg(int r, int s);
573 void save_regs(int n);
574 void save_reg(int r);
575 void vpop(void);
576 void vswap(void);
577 void vdup(void);
578 int get_reg(int rc);
580 static void macro_subst(TokenString *tok_str,
581 Sym **nested_list, int *macro_str);
582 int save_reg_forced(int r);
583 void gen_op(int op);
584 void force_charshort_cast(int t);
585 static void gen_cast(CType *type);
586 void vstore(void);
587 static Sym *sym_find(int v);
588 static Sym *sym_push(int v, CType *type, int r, int c);
590 /* type handling */
591 static int type_size(CType *type, int *a);
592 static inline CType *pointed_type(CType *type);
593 static int pointed_size(CType *type);
594 static int lvalue_type(int t);
595 static int is_compatible_types(CType *type1, CType *type2);
596 static int parse_btype(CType *type, AttributeDef *ad);
597 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
599 void error(const char *fmt, ...);
600 void vpushi(int v);
601 void vset(CType *type, int r, int v);
602 void type_to_str(char *buf, int buf_size,
603 CType *type, const char *varstr);
604 char *get_tok_str(int v, CValue *cv);
605 static Sym *get_sym_ref(CType *type, Section *sec,
606 unsigned long offset, unsigned long size);
607 static Sym *external_global_sym(int v, CType *type, int r);
609 /* section generation */
610 static void section_realloc(Section *sec, unsigned long new_size);
611 static void *section_ptr_add(Section *sec, unsigned long size);
612 static void put_extern_sym(Sym *sym, Section *section,
613 unsigned long value, unsigned long size);
614 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
615 static int put_elf_str(Section *s, const char *sym);
616 static int put_elf_sym(Section *s,
617 unsigned long value, unsigned long size,
618 int info, int other, int shndx, const char *name);
619 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
620 int info, int sh_num, const char *name);
621 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
622 int type, int symbol);
623 static void put_stabs(const char *str, int type, int other, int desc,
624 unsigned long value);
625 static void put_stabs_r(const char *str, int type, int other, int desc,
626 unsigned long value, Section *sec, int sym_index);
627 static void put_stabn(int type, int other, int desc, int value);
628 static void put_stabd(int type, int other, int desc);
629 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
631 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
632 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
633 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
635 /* true if float/double/long double type */
636 static inline int is_float(int t)
638 int bt;
639 bt = t & VT_BTYPE;
640 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
643 #ifdef TCC_TARGET_I386
644 #include "i386-gen.c"
645 #endif
646 #ifdef TCC_TARGET_IL
647 #include "il-gen.c"
648 #endif
650 #ifdef CONFIG_TCC_STATIC
652 #define RTLD_LAZY 0x001
653 #define RTLD_NOW 0x002
654 #define RTLD_GLOBAL 0x100
655 #define RTLD_DEFAULT NULL
657 /* dummy function for profiling */
658 void *dlopen(const char *filename, int flag)
660 return NULL;
663 const char *dlerror(void)
665 return "error";
668 typedef struct TCCSyms {
669 char *str;
670 void *ptr;
671 } TCCSyms;
673 #define TCCSYM(a) { #a, &a, },
675 /* add the symbol you want here if no dynamic linking is done */
676 static TCCSyms tcc_syms[] = {
677 TCCSYM(printf)
678 TCCSYM(fprintf)
679 TCCSYM(fopen)
680 TCCSYM(fclose)
681 { NULL, NULL },
684 void *dlsym(void *handle, const char *symbol)
686 TCCSyms *p;
687 p = tcc_syms;
688 while (p->str != NULL) {
689 if (!strcmp(p->str, symbol))
690 return p->ptr;
691 p++;
693 return NULL;
696 #endif
698 /********************************************************/
700 /* we use our own 'finite' function to avoid potential problems with
701 non standard math libs */
702 /* XXX: endianness dependant */
703 int ieee_finite(double d)
705 int *p = (int *)&d;
706 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
709 /* copy a string and truncate it. */
710 static char *pstrcpy(char *buf, int buf_size, const char *s)
712 char *q, *q_end;
713 int c;
715 if (buf_size > 0) {
716 q = buf;
717 q_end = buf + buf_size - 1;
718 while (q < q_end) {
719 c = *s++;
720 if (c == '\0')
721 break;
722 *q++ = c;
724 *q = '\0';
726 return buf;
729 /* strcat and truncate. */
730 static char *pstrcat(char *buf, int buf_size, const char *s)
732 int len;
733 len = strlen(buf);
734 if (len < buf_size)
735 pstrcpy(buf + len, buf_size - len, s);
736 return buf;
739 /* memory management */
740 #ifdef MEM_DEBUG
741 int mem_cur_size;
742 int mem_max_size;
743 #endif
745 static inline void tcc_free(void *ptr)
747 #ifdef MEM_DEBUG
748 mem_cur_size -= malloc_usable_size(ptr);
749 #endif
750 free(ptr);
753 static void *tcc_malloc(unsigned long size)
755 void *ptr;
756 ptr = malloc(size);
757 if (!ptr && size)
758 error("memory full");
759 #ifdef MEM_DEBUG
760 mem_cur_size += malloc_usable_size(ptr);
761 if (mem_cur_size > mem_max_size)
762 mem_max_size = mem_cur_size;
763 #endif
764 return ptr;
767 static void *tcc_mallocz(unsigned long size)
769 void *ptr;
770 ptr = tcc_malloc(size);
771 memset(ptr, 0, size);
772 return ptr;
775 static inline void *tcc_realloc(void *ptr, unsigned long size)
777 void *ptr1;
778 #ifdef MEM_DEBUG
779 mem_cur_size -= malloc_usable_size(ptr);
780 #endif
781 ptr1 = realloc(ptr, size);
782 #ifdef MEM_DEBUG
783 /* NOTE: count not correct if alloc error, but not critical */
784 mem_cur_size += malloc_usable_size(ptr1);
785 if (mem_cur_size > mem_max_size)
786 mem_max_size = mem_cur_size;
787 #endif
788 return ptr1;
791 static char *tcc_strdup(const char *str)
793 char *ptr;
794 ptr = tcc_malloc(strlen(str) + 1);
795 strcpy(ptr, str);
796 return ptr;
799 #define free(p) use_tcc_free(p)
800 #define malloc(s) use_tcc_malloc(s)
801 #define realloc(p, s) use_tcc_realloc(p, s)
803 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
805 int nb, nb_alloc;
806 void **pp;
808 nb = *nb_ptr;
809 pp = *ptab;
810 /* every power of two we double array size */
811 if ((nb & (nb - 1)) == 0) {
812 if (!nb)
813 nb_alloc = 1;
814 else
815 nb_alloc = nb * 2;
816 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
817 if (!pp)
818 error("memory full");
819 *ptab = pp;
821 pp[nb++] = data;
822 *nb_ptr = nb;
825 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
827 Section *sec;
829 sec = tcc_mallocz(sizeof(Section));
830 pstrcpy(sec->name, sizeof(sec->name), name);
831 sec->sh_type = sh_type;
832 sec->sh_flags = sh_flags;
833 switch(sh_type) {
834 case SHT_HASH:
835 case SHT_REL:
836 case SHT_DYNSYM:
837 case SHT_SYMTAB:
838 case SHT_DYNAMIC:
839 sec->sh_addralign = 4;
840 break;
841 case SHT_STRTAB:
842 sec->sh_addralign = 1;
843 break;
844 default:
845 sec->sh_addralign = 32; /* default conservative alignment */
846 break;
849 /* only add section if not private */
850 if (!(sh_flags & SHF_PRIVATE)) {
851 sec->sh_num = s1->nb_sections;
852 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
854 return sec;
857 static void free_section(Section *s)
859 tcc_free(s->data);
860 tcc_free(s);
863 /* realloc section and set its content to zero */
864 static void section_realloc(Section *sec, unsigned long new_size)
866 unsigned long size;
867 unsigned char *data;
869 size = sec->data_allocated;
870 if (size == 0)
871 size = 1;
872 while (size < new_size)
873 size = size * 2;
874 data = tcc_realloc(sec->data, size);
875 if (!data)
876 error("memory full");
877 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
878 sec->data = data;
879 sec->data_allocated = size;
882 /* reserve at least 'size' bytes in section 'sec' from
883 sec->data_offset. */
884 static void *section_ptr_add(Section *sec, unsigned long size)
886 unsigned long offset, offset1;
888 offset = sec->data_offset;
889 offset1 = offset + size;
890 if (offset1 > sec->data_allocated)
891 section_realloc(sec, offset1);
892 sec->data_offset = offset1;
893 return sec->data + offset;
896 /* return a reference to a section, and create it if it does not
897 exists */
898 Section *find_section(TCCState *s1, const char *name)
900 Section *sec;
901 int i;
902 for(i = 1; i < s1->nb_sections; i++) {
903 sec = s1->sections[i];
904 if (!strcmp(name, sec->name))
905 return sec;
907 /* sections are created as PROGBITS */
908 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
911 /* update sym->c so that it points to an external symbol in section
912 'section' with value 'value' */
913 static void put_extern_sym(Sym *sym, Section *section,
914 unsigned long value, unsigned long size)
916 int sym_type, sym_bind, sh_num, info;
917 Elf32_Sym *esym;
918 const char *name;
920 if (section)
921 sh_num = section->sh_num;
922 else
923 sh_num = SHN_UNDEF;
924 if (!sym->c) {
925 if ((sym->type.t & VT_BTYPE) == VT_FUNC)
926 sym_type = STT_FUNC;
927 else
928 sym_type = STT_OBJECT;
929 if (sym->type.t & VT_STATIC)
930 sym_bind = STB_LOCAL;
931 else
932 sym_bind = STB_GLOBAL;
934 name = get_tok_str(sym->v, NULL);
935 #ifdef CONFIG_TCC_BCHECK
936 if (do_bounds_check) {
937 char buf[32];
939 /* XXX: avoid doing that for statics ? */
940 /* if bound checking is activated, we change some function
941 names by adding the "__bound" prefix */
942 switch(sym->v) {
943 #if 0
944 /* XXX: we rely only on malloc hooks */
945 case TOK_malloc:
946 case TOK_free:
947 case TOK_realloc:
948 case TOK_memalign:
949 case TOK_calloc:
950 #endif
951 case TOK_memcpy:
952 case TOK_memmove:
953 case TOK_memset:
954 case TOK_strlen:
955 case TOK_strcpy:
956 strcpy(buf, "__bound_");
957 strcat(buf, name);
958 name = buf;
959 break;
962 #endif
963 info = ELF32_ST_INFO(sym_bind, sym_type);
964 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
965 } else {
966 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
967 esym->st_value = value;
968 esym->st_size = size;
969 esym->st_shndx = sh_num;
973 /* add a new relocation entry to symbol 'sym' in section 's' */
974 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
976 if (!sym->c)
977 put_extern_sym(sym, NULL, 0, 0);
978 /* now we can add ELF relocation info */
979 put_elf_reloc(symtab_section, s, offset, type, sym->c);
982 static inline int isid(int c)
984 return (c >= 'a' && c <= 'z') ||
985 (c >= 'A' && c <= 'Z') ||
986 c == '_';
989 static inline int isnum(int c)
991 return c >= '0' && c <= '9';
994 static inline int isoct(int c)
996 return c >= '0' && c <= '7';
999 static inline int toup(int c)
1001 if (c >= 'a' && c <= 'z')
1002 return c - 'a' + 'A';
1003 else
1004 return c;
1007 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
1009 int len;
1010 len = strlen(buf);
1011 vsnprintf(buf + len, buf_size - len, fmt, ap);
1014 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
1016 va_list ap;
1017 va_start(ap, fmt);
1018 strcat_vprintf(buf, buf_size, fmt, ap);
1019 va_end(ap);
1022 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
1024 char buf[2048];
1025 BufferedFile **f;
1027 buf[0] = '\0';
1028 if (file) {
1029 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1030 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1031 (*f)->filename, (*f)->line_num);
1032 if (file->line_num > 0) {
1033 strcat_printf(buf, sizeof(buf),
1034 "%s:%d: ", file->filename, file->line_num);
1035 } else {
1036 strcat_printf(buf, sizeof(buf),
1037 "%s: ", file->filename);
1039 } else {
1040 strcat_printf(buf, sizeof(buf),
1041 "tcc: ");
1043 if (is_warning)
1044 strcat_printf(buf, sizeof(buf), "warning: ");
1045 strcat_vprintf(buf, sizeof(buf), fmt, ap);
1047 if (!s1->error_func) {
1048 /* default case: stderr */
1049 fprintf(stderr, "%s\n", buf);
1050 } else {
1051 s1->error_func(s1->error_opaque, buf);
1053 if (!is_warning)
1054 s1->nb_errors++;
1057 #ifdef LIBTCC
1058 void tcc_set_error_func(TCCState *s, void *error_opaque,
1059 void (*error_func)(void *opaque, const char *msg))
1061 s->error_opaque = error_opaque;
1062 s->error_func = error_func;
1064 #endif
1066 /* error without aborting current compilation */
1067 void error_noabort(const char *fmt, ...)
1069 TCCState *s1 = tcc_state;
1070 va_list ap;
1072 va_start(ap, fmt);
1073 error1(s1, 0, fmt, ap);
1074 va_end(ap);
1077 void error(const char *fmt, ...)
1079 TCCState *s1 = tcc_state;
1080 va_list ap;
1082 va_start(ap, fmt);
1083 error1(s1, 0, fmt, ap);
1084 va_end(ap);
1085 /* better than nothing: in some cases, we accept to handle errors */
1086 if (s1->error_set_jmp_enabled) {
1087 longjmp(s1->error_jmp_buf, 1);
1088 } else {
1089 /* XXX: suppress it someday */
1090 exit(1);
1094 void expect(const char *msg)
1096 error("%s expected", msg);
1099 void warning(const char *fmt, ...)
1101 TCCState *s1 = tcc_state;
1102 va_list ap;
1104 va_start(ap, fmt);
1105 error1(s1, 1, fmt, ap);
1106 va_end(ap);
1109 void skip(int c)
1111 if (tok != c)
1112 error("'%c' expected", c);
1113 next();
1116 void test_lvalue(void)
1118 if (!(vtop->r & VT_LVAL))
1119 expect("lvalue");
1122 /* allocate a new token */
1123 static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
1125 TokenSym *ts, **ptable;
1126 int i;
1128 if (tok_ident >= SYM_FIRST_ANOM)
1129 error("memory full");
1131 /* expand token table if needed */
1132 i = tok_ident - TOK_IDENT;
1133 if ((i % TOK_ALLOC_INCR) == 0) {
1134 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1135 if (!ptable)
1136 error("memory full");
1137 table_ident = ptable;
1140 ts = tcc_malloc(sizeof(TokenSym) + len);
1141 table_ident[i] = ts;
1142 ts->tok = tok_ident++;
1143 ts->sym_define = NULL;
1144 ts->sym_label = NULL;
1145 ts->sym_struct = NULL;
1146 ts->sym_identifier = NULL;
1147 ts->len = len;
1148 ts->hash_next = NULL;
1149 memcpy(ts->str, str, len);
1150 ts->str[len] = '\0';
1151 *pts = ts;
1152 return ts;
1155 #define TOK_HASH_INIT 1
1156 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1158 /* find a token and add it if not found */
1159 static TokenSym *tok_alloc(const char *str, int len)
1161 TokenSym *ts, **pts;
1162 int i;
1163 unsigned int h;
1165 h = TOK_HASH_INIT;
1166 for(i=0;i<len;i++)
1167 h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
1168 h &= (TOK_HASH_SIZE - 1);
1170 pts = &hash_ident[h];
1171 for(;;) {
1172 ts = *pts;
1173 if (!ts)
1174 break;
1175 if (ts->len == len && !memcmp(ts->str, str, len))
1176 return ts;
1177 pts = &(ts->hash_next);
1179 return tok_alloc_new(pts, str, len);
1182 /* CString handling */
1184 static void cstr_realloc(CString *cstr, int new_size)
1186 int size;
1187 void *data;
1189 size = cstr->size_allocated;
1190 if (size == 0)
1191 size = 8; /* no need to allocate a too small first string */
1192 while (size < new_size)
1193 size = size * 2;
1194 data = tcc_realloc(cstr->data_allocated, size);
1195 if (!data)
1196 error("memory full");
1197 cstr->data_allocated = data;
1198 cstr->size_allocated = size;
1199 cstr->data = data;
1202 /* add a byte */
1203 static void cstr_ccat(CString *cstr, int ch)
1205 int size;
1206 size = cstr->size + 1;
1207 if (size > cstr->size_allocated)
1208 cstr_realloc(cstr, size);
1209 ((unsigned char *)cstr->data)[size - 1] = ch;
1210 cstr->size = size;
1213 static void cstr_cat(CString *cstr, const char *str)
1215 int c;
1216 for(;;) {
1217 c = *str;
1218 if (c == '\0')
1219 break;
1220 cstr_ccat(cstr, c);
1221 str++;
1225 /* add a wide char */
1226 static void cstr_wccat(CString *cstr, int ch)
1228 int size;
1229 size = cstr->size + sizeof(int);
1230 if (size > cstr->size_allocated)
1231 cstr_realloc(cstr, size);
1232 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1233 cstr->size = size;
1236 static void cstr_new(CString *cstr)
1238 memset(cstr, 0, sizeof(CString));
1241 /* free string and reset it to NULL */
1242 static void cstr_free(CString *cstr)
1244 tcc_free(cstr->data_allocated);
1245 cstr_new(cstr);
1248 #define cstr_reset(cstr) cstr_free(cstr)
1250 static CString *cstr_dup(CString *cstr1)
1252 CString *cstr;
1253 int size;
1255 cstr = tcc_malloc(sizeof(CString));
1256 size = cstr1->size;
1257 cstr->size = size;
1258 cstr->size_allocated = size;
1259 cstr->data_allocated = tcc_malloc(size);
1260 cstr->data = cstr->data_allocated;
1261 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1262 return cstr;
1265 /* XXX: unicode ? */
1266 static void add_char(CString *cstr, int c)
1268 if (c == '\'' || c == '\"' || c == '\\') {
1269 /* XXX: could be more precise if char or string */
1270 cstr_ccat(cstr, '\\');
1272 if (c >= 32 && c <= 126) {
1273 cstr_ccat(cstr, c);
1274 } else {
1275 cstr_ccat(cstr, '\\');
1276 if (c == '\n') {
1277 cstr_ccat(cstr, 'n');
1278 } else {
1279 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1280 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1281 cstr_ccat(cstr, '0' + (c & 7));
1286 /* XXX: buffer overflow */
1287 /* XXX: float tokens */
1288 char *get_tok_str(int v, CValue *cv)
1290 static char buf[STRING_MAX_SIZE + 1];
1291 static CString cstr_buf;
1292 CString *cstr;
1293 unsigned char *q;
1294 char *p;
1295 int i, len;
1297 /* NOTE: to go faster, we give a fixed buffer for small strings */
1298 cstr_reset(&cstr_buf);
1299 cstr_buf.data = buf;
1300 cstr_buf.size_allocated = sizeof(buf);
1301 p = buf;
1303 switch(v) {
1304 case TOK_CINT:
1305 case TOK_CUINT:
1306 /* XXX: not quite exact, but only useful for testing */
1307 sprintf(p, "%u", cv->ui);
1308 break;
1309 case TOK_CLLONG:
1310 case TOK_CULLONG:
1311 /* XXX: not quite exact, but only useful for testing */
1312 sprintf(p, "%Lu", cv->ull);
1313 break;
1314 case TOK_CCHAR:
1315 case TOK_LCHAR:
1316 cstr_ccat(&cstr_buf, '\'');
1317 add_char(&cstr_buf, cv->i);
1318 cstr_ccat(&cstr_buf, '\'');
1319 cstr_ccat(&cstr_buf, '\0');
1320 break;
1321 case TOK_PPNUM:
1322 cstr = cv->cstr;
1323 len = cstr->size - 1;
1324 for(i=0;i<len;i++)
1325 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1326 cstr_ccat(&cstr_buf, '\0');
1327 break;
1328 case TOK_STR:
1329 case TOK_LSTR:
1330 cstr = cv->cstr;
1331 cstr_ccat(&cstr_buf, '\"');
1332 if (v == TOK_STR) {
1333 len = cstr->size - 1;
1334 for(i=0;i<len;i++)
1335 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1336 } else {
1337 len = (cstr->size / sizeof(int)) - 1;
1338 for(i=0;i<len;i++)
1339 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1341 cstr_ccat(&cstr_buf, '\"');
1342 cstr_ccat(&cstr_buf, '\0');
1343 break;
1344 case TOK_LT:
1345 v = '<';
1346 goto addv;
1347 case TOK_GT:
1348 v = '>';
1349 goto addv;
1350 case TOK_A_SHL:
1351 return strcpy(p, "<<=");
1352 case TOK_A_SAR:
1353 return strcpy(p, ">>=");
1354 default:
1355 if (v < TOK_IDENT) {
1356 /* search in two bytes table */
1357 q = tok_two_chars;
1358 while (*q) {
1359 if (q[2] == v) {
1360 *p++ = q[0];
1361 *p++ = q[1];
1362 *p = '\0';
1363 return buf;
1365 q += 3;
1367 addv:
1368 *p++ = v;
1369 *p = '\0';
1370 } else if (v < tok_ident) {
1371 return table_ident[v - TOK_IDENT]->str;
1372 } else if (v >= SYM_FIRST_ANOM) {
1373 /* special name for anonymous symbol */
1374 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1375 } else {
1376 /* should never happen */
1377 return NULL;
1379 break;
1381 return cstr_buf.data;
1384 /* push, without hashing */
1385 static Sym *sym_push2(Sym **ps, int v, int t, int c)
1387 Sym *s;
1388 s = tcc_malloc(sizeof(Sym));
1389 s->v = v;
1390 s->type.t = t;
1391 s->c = c;
1392 s->next = NULL;
1393 /* add in stack */
1394 s->prev = *ps;
1395 *ps = s;
1396 return s;
1399 /* find a symbol and return its associated structure. 's' is the top
1400 of the symbol stack */
1401 static Sym *sym_find2(Sym *s, int v)
1403 while (s) {
1404 if (s->v == v)
1405 return s;
1406 s = s->prev;
1408 return NULL;
1411 /* structure lookup */
1412 static Sym *struct_find(int v)
1414 v -= TOK_IDENT;
1415 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1416 return NULL;
1417 return table_ident[v]->sym_struct;
1420 /* find an identifier */
1421 static inline Sym *sym_find(int v)
1423 v -= TOK_IDENT;
1424 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1425 return NULL;
1426 return table_ident[v]->sym_identifier;
1429 /* push a given symbol on the symbol stack */
1430 static Sym *sym_push(int v, CType *type, int r, int c)
1432 Sym *s, **ps;
1433 TokenSym *ts;
1435 if (local_stack)
1436 ps = &local_stack;
1437 else
1438 ps = &global_stack;
1439 s = sym_push2(ps, v, type->t, c);
1440 s->type.ref = type->ref;
1441 s->r = r;
1442 /* don't record fields or anonymous symbols */
1443 /* XXX: simplify */
1444 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1445 /* record symbol in token array */
1446 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1447 if (v & SYM_STRUCT)
1448 ps = &ts->sym_struct;
1449 else
1450 ps = &ts->sym_identifier;
1451 s->prev_tok = *ps;
1452 *ps = s;
1454 return s;
1457 /* push a global identifier */
1458 static Sym *global_identifier_push(int v, int t, int c)
1460 Sym *s, **ps;
1461 s = sym_push2(&global_stack, v, t, c);
1462 /* don't record anonymous symbol */
1463 if (v < SYM_FIRST_ANOM) {
1464 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1465 /* modify the top most local identifier, so that
1466 sym_identifier will point to 's' when popped */
1467 while (*ps != NULL)
1468 ps = &(*ps)->prev_tok;
1469 s->prev_tok = NULL;
1470 *ps = s;
1472 return s;
1475 /* pop symbols until top reaches 'b' */
1476 static void sym_pop(Sym **ptop, Sym *b)
1478 Sym *s, *ss, **ps;
1479 TokenSym *ts;
1480 int v;
1482 s = *ptop;
1483 while(s != b) {
1484 ss = s->prev;
1485 v = s->v;
1486 /* remove symbol in token array */
1487 /* XXX: simplify */
1488 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1489 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1490 if (v & SYM_STRUCT)
1491 ps = &ts->sym_struct;
1492 else
1493 ps = &ts->sym_identifier;
1494 *ps = s->prev_tok;
1496 tcc_free(s);
1497 s = ss;
1499 *ptop = b;
1502 /* I/O layer */
1504 BufferedFile *tcc_open(TCCState *s1, const char *filename)
1506 int fd;
1507 BufferedFile *bf;
1509 fd = open(filename, O_RDONLY);
1510 if (fd < 0)
1511 return NULL;
1512 bf = tcc_malloc(sizeof(BufferedFile));
1513 if (!bf) {
1514 close(fd);
1515 return NULL;
1517 bf->fd = fd;
1518 bf->buf_ptr = bf->buffer;
1519 bf->buf_end = bf->buffer;
1520 bf->buffer[0] = CH_EOB; /* put eob symbol */
1521 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1522 bf->line_num = 1;
1523 bf->ifndef_macro = 0;
1524 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1525 // printf("opening '%s'\n", filename);
1526 return bf;
1529 void tcc_close(BufferedFile *bf)
1531 total_lines += bf->line_num;
1532 close(bf->fd);
1533 tcc_free(bf);
1536 /* fill input buffer and peek next char */
1537 static int tcc_peekc_slow(BufferedFile *bf)
1539 int len;
1540 /* only tries to read if really end of buffer */
1541 if (bf->buf_ptr >= bf->buf_end) {
1542 if (bf->fd != -1) {
1543 #if defined(PARSE_DEBUG)
1544 len = 8;
1545 #else
1546 len = IO_BUF_SIZE;
1547 #endif
1548 len = read(bf->fd, bf->buffer, len);
1549 if (len < 0)
1550 len = 0;
1551 } else {
1552 len = 0;
1554 total_bytes += len;
1555 bf->buf_ptr = bf->buffer;
1556 bf->buf_end = bf->buffer + len;
1557 *bf->buf_end = CH_EOB;
1559 if (bf->buf_ptr < bf->buf_end) {
1560 return bf->buf_ptr[0];
1561 } else {
1562 bf->buf_ptr = bf->buf_end;
1563 return CH_EOF;
1567 /* return the current character, handling end of block if necessary
1568 (but not stray) */
1569 static int handle_eob(void)
1571 return tcc_peekc_slow(file);
1574 /* read next char from current input file and handle end of input buffer */
1575 static inline void inp(void)
1577 ch = *(++(file->buf_ptr));
1578 /* end of buffer/file handling */
1579 if (ch == CH_EOB)
1580 ch = handle_eob();
1583 /* handle '\[\r]\n' */
1584 static void handle_stray(void)
1586 while (ch == '\\') {
1587 inp();
1588 if (ch == '\n') {
1589 file->line_num++;
1590 inp();
1591 } else if (ch == '\r') {
1592 inp();
1593 if (ch != '\n')
1594 goto fail;
1595 file->line_num++;
1596 inp();
1597 } else {
1598 fail:
1599 error("stray '\\' in program");
1604 /* skip the stray and handle the \\n case. Output an error if
1605 incorrect char after the stray */
1606 static int handle_stray1(uint8_t *p)
1608 int c;
1610 if (p >= file->buf_end) {
1611 file->buf_ptr = p;
1612 c = handle_eob();
1613 p = file->buf_ptr;
1614 if (c == '\\')
1615 goto parse_stray;
1616 } else {
1617 parse_stray:
1618 file->buf_ptr = p;
1619 ch = *p;
1620 handle_stray();
1621 p = file->buf_ptr;
1622 c = *p;
1624 return c;
1627 /* handle the complicated stray case */
1628 #define PEEKC(c, p)\
1630 p++;\
1631 c = *p;\
1632 if (c == '\\') {\
1633 c = handle_stray1(p);\
1634 p = file->buf_ptr;\
1638 /* input with '\[\r]\n' handling. Note that this function cannot
1639 handle other characters after '\', so you cannot call it inside
1640 strings or comments */
1641 static void minp(void)
1643 inp();
1644 if (ch == '\\')
1645 handle_stray();
1649 static void parse_line_comment(void)
1651 /* single line C++ comments */
1652 /* XXX: accept '\\\n' ? */
1653 inp();
1654 while (ch != '\n' && ch != CH_EOF)
1655 inp();
1658 static void parse_comment(void)
1660 uint8_t *p;
1661 int c;
1663 /* C comments */
1664 p = file->buf_ptr;
1665 p++;
1666 for(;;) {
1667 /* fast skip loop */
1668 for(;;) {
1669 c = *p;
1670 if (c == '\n' || c == '*' || c == '\\')
1671 break;
1672 p++;
1673 c = *p;
1674 if (c == '\n' || c == '*' || c == '\\')
1675 break;
1676 p++;
1678 /* now we can handle all the cases */
1679 if (c == '\n') {
1680 file->line_num++;
1681 p++;
1682 } else if (c == '*') {
1683 p++;
1684 for(;;) {
1685 c = *p;
1686 if (c == '*') {
1687 p++;
1688 } else if (c == '/') {
1689 goto end_of_comment;
1690 } else if (c == '\\') {
1691 file->buf_ptr = p;
1692 c = handle_eob();
1693 if (c == '\\') {
1694 /* skip '\\n', but if '\' followed but another
1695 char, behave asif a stray was parsed */
1696 ch = file->buf_ptr[0];
1697 while (ch == '\\') {
1698 inp();
1699 if (ch == '\n') {
1700 file->line_num++;
1701 inp();
1702 } else if (ch == '\r') {
1703 inp();
1704 if (ch == '\n') {
1705 file->line_num++;
1706 inp();
1708 } else {
1709 p = file->buf_ptr;
1710 break;
1714 p = file->buf_ptr;
1715 } else {
1716 break;
1719 } else {
1720 /* stray, eob or eof */
1721 file->buf_ptr = p;
1722 c = handle_eob();
1723 p = file->buf_ptr;
1724 if (c == CH_EOF) {
1725 error("unexpected end of file in comment");
1726 } else if (c == '\\') {
1727 p++;
1731 end_of_comment:
1732 p++;
1733 file->buf_ptr = p;
1734 ch = *p;
1737 #define cinp minp
1739 /* space exlcuding newline */
1740 static inline int is_space(int ch)
1742 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1745 static inline void skip_spaces(void)
1747 while (is_space(ch))
1748 cinp();
1751 /* skip block of text until #else, #elif or #endif. skip also pairs of
1752 #if/#endif */
1753 void preprocess_skip(void)
1755 int a, start_of_line, sep, c;
1756 uint8_t *p;
1758 p = file->buf_ptr;
1759 start_of_line = 1;
1760 a = 0;
1761 for(;;) {
1762 redo_no_start:
1763 c = *p;
1764 switch(c) {
1765 case ' ':
1766 case '\t':
1767 case '\f':
1768 case '\v':
1769 case '\r':
1770 p++;
1771 goto redo_no_start;
1772 case '\n':
1773 start_of_line = 1;
1774 file->line_num++;
1775 p++;
1776 goto redo_no_start;
1777 case '\\':
1778 file->buf_ptr = p;
1779 c = handle_eob();
1780 if (c == CH_EOF) {
1781 expect("#endif");
1782 } else if (c == '\\') {
1783 /* XXX: incorrect: should not give an error */
1784 ch = file->buf_ptr[0];
1785 handle_stray();
1787 p = file->buf_ptr;
1788 goto redo_no_start;
1789 /* skip strings */
1790 case '\"':
1791 case '\'':
1792 sep = c;
1793 p++;
1794 for(;;) {
1795 c = *p;
1796 if (c == sep) {
1797 break;
1798 } else if (c == '\\') {
1799 file->buf_ptr = p;
1800 c = handle_eob();
1801 p = file->buf_ptr;
1802 if (c == CH_EOF) {
1803 /* XXX: better error message */
1804 error("unterminated string");
1805 } else if (c == '\\') {
1806 /* ignore next char */
1807 p++;
1808 c = *p;
1809 if (c == '\\') {
1810 file->buf_ptr = p;
1811 c = handle_eob();
1812 p = file->buf_ptr;
1814 if (c == '\n')
1815 file->line_num++;
1816 else if (c != CH_EOF)
1817 p++;
1819 } else if (c == '\n') {
1820 file->line_num++;
1821 p++;
1822 } else {
1823 p++;
1826 p++;
1827 break;
1828 /* skip comments */
1829 case '/':
1830 file->buf_ptr = p;
1831 ch = *p;
1832 minp();
1833 if (ch == '*') {
1834 parse_comment();
1835 } else if (ch == '/') {
1836 parse_line_comment();
1838 p = file->buf_ptr;
1839 break;
1841 case '#':
1842 p++;
1843 if (start_of_line) {
1844 file->buf_ptr = p;
1845 next_nomacro();
1846 p = file->buf_ptr;
1847 if (a == 0 &&
1848 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1849 goto the_end;
1850 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1851 a++;
1852 else if (tok == TOK_ENDIF)
1853 a--;
1855 break;
1856 default:
1857 p++;
1858 break;
1860 start_of_line = 0;
1862 the_end: ;
1863 file->buf_ptr = p;
1866 /* ParseState handling */
1868 /* XXX: currently, no include file info is stored. Thus, we cannot display
1869 accurate messages if the function or data definition spans multiple
1870 files */
1872 /* save current parse state in 's' */
1873 void save_parse_state(ParseState *s)
1875 s->line_num = file->line_num;
1876 s->macro_ptr = macro_ptr;
1877 s->tok = tok;
1878 s->tokc = tokc;
1881 /* restore parse state from 's' */
1882 void restore_parse_state(ParseState *s)
1884 file->line_num = s->line_num;
1885 macro_ptr = s->macro_ptr;
1886 tok = s->tok;
1887 tokc = s->tokc;
1890 /* return the number of additionnal 'ints' necessary to store the
1891 token */
1892 static inline int tok_ext_size(int t)
1894 switch(t) {
1895 /* 4 bytes */
1896 case TOK_CINT:
1897 case TOK_CUINT:
1898 case TOK_CCHAR:
1899 case TOK_LCHAR:
1900 case TOK_STR:
1901 case TOK_LSTR:
1902 case TOK_CFLOAT:
1903 case TOK_LINENUM:
1904 case TOK_PPNUM:
1905 return 1;
1906 case TOK_CDOUBLE:
1907 case TOK_CLLONG:
1908 case TOK_CULLONG:
1909 return 2;
1910 case TOK_CLDOUBLE:
1911 return LDOUBLE_SIZE / 4;
1912 default:
1913 return 0;
1917 /* token string handling */
1919 static inline void tok_str_new(TokenString *s)
1921 s->str = NULL;
1922 s->len = 0;
1923 s->allocated_len = 0;
1924 s->last_line_num = -1;
1927 static void tok_str_free(int *str)
1929 const int *p;
1930 CString *cstr;
1931 int t;
1933 p = str;
1934 for(;;) {
1935 t = *p;
1936 /* NOTE: we test zero separately so that GCC can generate a
1937 table for the following switch */
1938 if (t == 0)
1939 break;
1940 switch(t) {
1941 case TOK_CINT:
1942 case TOK_CUINT:
1943 case TOK_CCHAR:
1944 case TOK_LCHAR:
1945 case TOK_CFLOAT:
1946 case TOK_LINENUM:
1947 p += 2;
1948 break;
1949 case TOK_PPNUM:
1950 case TOK_STR:
1951 case TOK_LSTR:
1952 /* XXX: use a macro to be portable on 64 bit ? */
1953 cstr = (CString *)p[1];
1954 cstr_free(cstr);
1955 tcc_free(cstr);
1956 p += 2;
1957 break;
1958 case TOK_CDOUBLE:
1959 case TOK_CLLONG:
1960 case TOK_CULLONG:
1961 p += 3;
1962 break;
1963 case TOK_CLDOUBLE:
1964 p += 1 + (LDOUBLE_SIZE / 4);
1965 break;
1966 default:
1967 p++;
1968 break;
1971 tcc_free(str);
1974 static int *tok_str_realloc(TokenString *s)
1976 int *str, len;
1978 len = s->allocated_len + TOK_STR_ALLOC_INCR;
1979 str = tcc_realloc(s->str, len * sizeof(int));
1980 if (!str)
1981 error("memory full");
1982 s->allocated_len = len;
1983 s->str = str;
1984 return str;
1987 static void tok_str_add(TokenString *s, int t)
1989 int len, *str;
1991 len = s->len;
1992 str = s->str;
1993 if (len >= s->allocated_len)
1994 str = tok_str_realloc(s);
1995 str[len++] = t;
1996 s->len = len;
1999 static void tok_str_add2(TokenString *s, int t, CValue *cv)
2001 int len, *str;
2003 len = s->len;
2004 str = s->str;
2006 /* allocate space for worst case */
2007 if (len + TOK_MAX_SIZE > s->allocated_len)
2008 str = tok_str_realloc(s);
2009 str[len++] = t;
2010 switch(t) {
2011 case TOK_CINT:
2012 case TOK_CUINT:
2013 case TOK_CCHAR:
2014 case TOK_LCHAR:
2015 case TOK_CFLOAT:
2016 case TOK_LINENUM:
2017 str[len++] = cv->tab[0];
2018 break;
2019 case TOK_PPNUM:
2020 case TOK_STR:
2021 case TOK_LSTR:
2022 str[len++] = (int)cstr_dup(cv->cstr);
2023 break;
2024 case TOK_CDOUBLE:
2025 case TOK_CLLONG:
2026 case TOK_CULLONG:
2027 str[len++] = cv->tab[0];
2028 str[len++] = cv->tab[1];
2029 break;
2030 case TOK_CLDOUBLE:
2031 #if LDOUBLE_SIZE == 12
2032 str[len++] = cv->tab[0];
2033 str[len++] = cv->tab[1];
2034 str[len++] = cv->tab[2];
2035 #else
2036 #error add long double size support
2037 #endif
2038 break;
2039 default:
2040 break;
2042 s->len = len;
2045 /* add the current parse token in token string 's' */
2046 static void tok_str_add_tok(TokenString *s)
2048 CValue cval;
2050 /* save line number info */
2051 if (file->line_num != s->last_line_num) {
2052 s->last_line_num = file->line_num;
2053 cval.i = s->last_line_num;
2054 tok_str_add2(s, TOK_LINENUM, &cval);
2056 tok_str_add2(s, tok, &tokc);
2059 #if LDOUBLE_SIZE == 12
2060 #define LDOUBLE_GET(p, cv) \
2061 cv.tab[0] = p[0]; \
2062 cv.tab[1] = p[1]; \
2063 cv.tab[2] = p[2];
2064 #else
2065 #error add long double size support
2066 #endif
2069 /* get a token from an integer array and increment pointer
2070 accordingly. we code it as a macro to avoid pointer aliasing. */
2071 #define TOK_GET(t, p, cv) \
2073 t = *p++; \
2074 switch(t) { \
2075 case TOK_CINT: \
2076 case TOK_CUINT: \
2077 case TOK_CCHAR: \
2078 case TOK_LCHAR: \
2079 case TOK_CFLOAT: \
2080 case TOK_LINENUM: \
2081 case TOK_STR: \
2082 case TOK_LSTR: \
2083 case TOK_PPNUM: \
2084 cv.tab[0] = *p++; \
2085 break; \
2086 case TOK_CDOUBLE: \
2087 case TOK_CLLONG: \
2088 case TOK_CULLONG: \
2089 cv.tab[0] = p[0]; \
2090 cv.tab[1] = p[1]; \
2091 p += 2; \
2092 break; \
2093 case TOK_CLDOUBLE: \
2094 LDOUBLE_GET(p, cv); \
2095 p += LDOUBLE_SIZE / 4; \
2096 break; \
2097 default: \
2098 break; \
2102 /* defines handling */
2103 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
2105 Sym *s;
2107 s = sym_push2(&define_stack, v, macro_type, (int)str);
2108 s->next = first_arg;
2109 table_ident[v - TOK_IDENT]->sym_define = s;
2112 /* undefined a define symbol. Its name is just set to zero */
2113 static void define_undef(Sym *s)
2115 int v;
2116 v = s->v;
2117 if (v >= TOK_IDENT && v < tok_ident)
2118 table_ident[v - TOK_IDENT]->sym_define = NULL;
2119 s->v = 0;
2122 static inline Sym *define_find(int v)
2124 v -= TOK_IDENT;
2125 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2126 return NULL;
2127 return table_ident[v]->sym_define;
2130 /* free define stack until top reaches 'b' */
2131 static void free_defines(Sym *b)
2133 Sym *top, *top1;
2134 int v;
2136 top = define_stack;
2137 while (top != b) {
2138 top1 = top->prev;
2139 /* do not free args or predefined defines */
2140 if (top->c)
2141 tok_str_free((int *)top->c);
2142 v = top->v;
2143 if (v >= TOK_IDENT && v < tok_ident)
2144 table_ident[v - TOK_IDENT]->sym_define = NULL;
2145 tcc_free(top);
2146 top = top1;
2148 define_stack = b;
2151 /* label lookup */
2152 static Sym *label_find(int v)
2154 v -= TOK_IDENT;
2155 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2156 return NULL;
2157 return table_ident[v]->sym_label;
2160 static Sym *label_push(int v, int flags)
2162 Sym *s;
2163 s = sym_push2(&label_stack, v, 0, 0);
2164 s->r = flags;
2165 table_ident[v - TOK_IDENT]->sym_label = s;
2166 return s;
2169 /* eval an expression for #if/#elif */
2170 static int expr_preprocess(void)
2172 int c, t;
2173 TokenString str;
2175 tok_str_new(&str);
2176 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2177 next(); /* do macro subst */
2178 if (tok == TOK_DEFINED) {
2179 next_nomacro();
2180 t = tok;
2181 if (t == '(')
2182 next_nomacro();
2183 c = define_find(tok) != 0;
2184 if (t == '(')
2185 next_nomacro();
2186 tok = TOK_CINT;
2187 tokc.i = c;
2188 } else if (tok >= TOK_IDENT) {
2189 /* if undefined macro */
2190 tok = TOK_CINT;
2191 tokc.i = 0;
2193 tok_str_add_tok(&str);
2195 tok_str_add(&str, -1); /* simulate end of file */
2196 tok_str_add(&str, 0);
2197 /* now evaluate C constant expression */
2198 macro_ptr = str.str;
2199 next();
2200 c = expr_const();
2201 macro_ptr = NULL;
2202 tok_str_free(str.str);
2203 return c != 0;
2206 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2207 static void tok_print(int *str)
2209 int t;
2210 CValue cval;
2212 while (1) {
2213 TOK_GET(t, str, cval);
2214 if (!t)
2215 break;
2216 printf(" %s", get_tok_str(t, &cval));
2218 printf("\n");
2220 #endif
2222 /* parse after #define */
2223 static void parse_define(void)
2225 Sym *s, *first, **ps;
2226 int v, t, varg, is_vaargs, c;
2227 TokenString str;
2229 v = tok;
2230 if (v < TOK_IDENT)
2231 error("invalid macro name '%s'", get_tok_str(tok, &tokc));
2232 /* XXX: should check if same macro (ANSI) */
2233 first = NULL;
2234 t = MACRO_OBJ;
2235 /* '(' must be just after macro definition for MACRO_FUNC */
2236 c = file->buf_ptr[0];
2237 if (c == '\\')
2238 c = handle_stray1(file->buf_ptr);
2239 if (c == '(') {
2240 next_nomacro();
2241 next_nomacro();
2242 ps = &first;
2243 while (tok != ')') {
2244 varg = tok;
2245 next_nomacro();
2246 is_vaargs = 0;
2247 if (varg == TOK_DOTS) {
2248 varg = TOK___VA_ARGS__;
2249 is_vaargs = 1;
2250 } else if (tok == TOK_DOTS && gnu_ext) {
2251 is_vaargs = 1;
2252 next_nomacro();
2254 if (varg < TOK_IDENT)
2255 error("badly punctuated parameter list");
2256 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
2257 *ps = s;
2258 ps = &s->next;
2259 if (tok != ',')
2260 break;
2261 next_nomacro();
2263 t = MACRO_FUNC;
2265 tok_str_new(&str);
2266 next_nomacro();
2267 /* EOF testing necessary for '-D' handling */
2268 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2269 tok_str_add2(&str, tok, &tokc);
2270 next_nomacro();
2272 tok_str_add(&str, 0);
2273 #ifdef PP_DEBUG
2274 printf("define %s %d: ", get_tok_str(v, NULL), t);
2275 tok_print(str.str);
2276 #endif
2277 define_push(v, t, str.str, first);
2280 /* XXX: use a token or a hash table to accelerate matching ? */
2281 static CachedInclude *search_cached_include(TCCState *s1,
2282 int type, const char *filename)
2284 CachedInclude *e;
2285 int i;
2287 for(i = 0;i < s1->nb_cached_includes; i++) {
2288 e = s1->cached_includes[i];
2289 if (e->type == type && !strcmp(e->filename, filename))
2290 return e;
2292 return NULL;
2295 static inline void add_cached_include(TCCState *s1, int type,
2296 const char *filename, int ifndef_macro)
2298 CachedInclude *e;
2300 if (search_cached_include(s1, type, filename))
2301 return;
2302 #ifdef INC_DEBUG
2303 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
2304 #endif
2305 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
2306 if (!e)
2307 return;
2308 e->type = type;
2309 strcpy(e->filename, filename);
2310 e->ifndef_macro = ifndef_macro;
2311 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
2314 /* is_bof is true if first non space token at beginning of file */
2315 static void preprocess(int is_bof)
2317 TCCState *s1 = tcc_state;
2318 int size, i, c, n;
2319 char buf[1024], *q, *p;
2320 char buf1[1024];
2321 BufferedFile *f;
2322 Sym *s;
2323 CachedInclude *e;
2325 return_linefeed = 1; /* linefeed will be returned as a
2326 token. EOF is also returned as line feed */
2327 next_nomacro();
2328 redo:
2329 switch(tok) {
2330 case TOK_DEFINE:
2331 next_nomacro();
2332 parse_define();
2333 break;
2334 case TOK_UNDEF:
2335 next_nomacro();
2336 s = define_find(tok);
2337 /* undefine symbol by putting an invalid name */
2338 if (s)
2339 define_undef(s);
2340 break;
2341 case TOK_INCLUDE:
2342 ch = file->buf_ptr[0];
2343 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2344 skip_spaces();
2345 if (ch == '<') {
2346 c = '>';
2347 goto read_name;
2348 } else if (ch == '\"') {
2349 c = ch;
2350 read_name:
2351 /* XXX: better stray handling */
2352 minp();
2353 q = buf;
2354 while (ch != c && ch != '\n' && ch != CH_EOF) {
2355 if ((q - buf) < sizeof(buf) - 1)
2356 *q++ = ch;
2357 minp();
2359 *q = '\0';
2360 minp();
2361 #if 0
2362 /* eat all spaces and comments after include */
2363 /* XXX: slightly incorrect */
2364 while (ch1 != '\n' && ch1 != CH_EOF)
2365 inp();
2366 #endif
2367 } else {
2368 /* computed #include : either we have only strings or
2369 we have anything enclosed in '<>' */
2370 next();
2371 buf[0] = '\0';
2372 if (tok == TOK_STR) {
2373 while (tok != TOK_LINEFEED) {
2374 if (tok != TOK_STR) {
2375 include_syntax:
2376 error("'#include' expects \"FILENAME\" or <FILENAME>");
2378 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2379 next();
2381 c = '\"';
2382 } else {
2383 int len;
2384 while (tok != TOK_LINEFEED) {
2385 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2386 next();
2388 len = strlen(buf);
2389 /* check syntax and remove '<>' */
2390 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2391 goto include_syntax;
2392 memmove(buf, buf + 1, len - 2);
2393 buf[len - 2] = '\0';
2394 c = '>';
2398 e = search_cached_include(s1, c, buf);
2399 if (e && define_find(e->ifndef_macro)) {
2400 /* no need to parse the include because the 'ifndef macro'
2401 is defined */
2402 #ifdef INC_DEBUG
2403 printf("%s: skipping %s\n", file->filename, buf);
2404 #endif
2405 } else {
2406 if (c == '\"') {
2407 /* first search in current dir if "header.h" */
2408 size = 0;
2409 p = strrchr(file->filename, '/');
2410 if (p)
2411 size = p + 1 - file->filename;
2412 if (size > sizeof(buf1) - 1)
2413 size = sizeof(buf1) - 1;
2414 memcpy(buf1, file->filename, size);
2415 buf1[size] = '\0';
2416 pstrcat(buf1, sizeof(buf1), buf);
2417 f = tcc_open(s1, buf1);
2418 if (f)
2419 goto found;
2421 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2422 error("#include recursion too deep");
2423 /* now search in all the include paths */
2424 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2425 for(i = 0; i < n; i++) {
2426 const char *path;
2427 if (i < s1->nb_include_paths)
2428 path = s1->include_paths[i];
2429 else
2430 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2431 pstrcpy(buf1, sizeof(buf1), path);
2432 pstrcat(buf1, sizeof(buf1), "/");
2433 pstrcat(buf1, sizeof(buf1), buf);
2434 f = tcc_open(s1, buf1);
2435 if (f)
2436 goto found;
2438 error("include file '%s' not found", buf);
2439 f = NULL;
2440 found:
2441 #ifdef INC_DEBUG
2442 printf("%s: including %s\n", file->filename, buf1);
2443 #endif
2444 f->inc_type = c;
2445 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2446 /* push current file in stack */
2447 /* XXX: fix current line init */
2448 *s1->include_stack_ptr++ = file;
2449 file = f;
2450 /* add include file debug info */
2451 if (do_debug) {
2452 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2454 tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
2455 ch = file->buf_ptr[0];
2456 goto the_end;
2458 break;
2459 case TOK_IFNDEF:
2460 c = 1;
2461 goto do_ifdef;
2462 case TOK_IF:
2463 c = expr_preprocess();
2464 goto do_if;
2465 case TOK_IFDEF:
2466 c = 0;
2467 do_ifdef:
2468 next_nomacro();
2469 if (tok < TOK_IDENT)
2470 error("invalid argument for '#if%sdef'", c ? "n" : "");
2471 if (is_bof) {
2472 if (c) {
2473 #ifdef INC_DEBUG
2474 printf("#ifndef %s\n", get_tok_str(tok, NULL));
2475 #endif
2476 file->ifndef_macro = tok;
2479 c = (define_find(tok) != 0) ^ c;
2480 do_if:
2481 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2482 error("memory full");
2483 *s1->ifdef_stack_ptr++ = c;
2484 goto test_skip;
2485 case TOK_ELSE:
2486 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2487 error("#else without matching #if");
2488 if (s1->ifdef_stack_ptr[-1] & 2)
2489 error("#else after #else");
2490 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2491 goto test_skip;
2492 case TOK_ELIF:
2493 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2494 error("#elif without matching #if");
2495 c = s1->ifdef_stack_ptr[-1];
2496 if (c > 1)
2497 error("#elif after #else");
2498 /* last #if/#elif expression was true: we skip */
2499 if (c == 1)
2500 goto skip;
2501 c = expr_preprocess();
2502 s1->ifdef_stack_ptr[-1] = c;
2503 test_skip:
2504 if (!(c & 1)) {
2505 skip:
2506 preprocess_skip();
2507 is_bof = 0;
2508 goto redo;
2510 break;
2511 case TOK_ENDIF:
2512 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2513 error("#endif without matching #if");
2514 s1->ifdef_stack_ptr--;
2515 /* '#ifndef macro' was at the start of file. Now we check if
2516 an '#endif' is exactly at the end of file */
2517 if (file->ifndef_macro &&
2518 s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
2519 file->ifndef_macro_saved = file->ifndef_macro;
2520 /* need to set to zero to avoid false matches if another
2521 #ifndef at middle of file */
2522 file->ifndef_macro = 0;
2523 while (tok != TOK_LINEFEED)
2524 next_nomacro();
2525 tok_flags |= TOK_FLAG_ENDIF;
2526 goto the_end;
2528 break;
2529 case TOK_LINE:
2530 next();
2531 if (tok != TOK_CINT)
2532 error("#line");
2533 file->line_num = tokc.i - 1; /* the line number will be incremented after */
2534 next();
2535 if (tok != TOK_LINEFEED) {
2536 if (tok != TOK_STR)
2537 error("#line");
2538 pstrcpy(file->filename, sizeof(file->filename),
2539 (char *)tokc.cstr->data);
2541 break;
2542 case TOK_ERROR:
2543 case TOK_WARNING:
2544 c = tok;
2545 ch = file->buf_ptr[0];
2546 skip_spaces();
2547 q = buf;
2548 while (ch != '\n' && ch != CH_EOF) {
2549 if ((q - buf) < sizeof(buf) - 1)
2550 *q++ = ch;
2551 minp();
2553 *q = '\0';
2554 if (c == TOK_ERROR)
2555 error("#error %s", buf);
2556 else
2557 warning("#warning %s", buf);
2558 break;
2559 case TOK_PRAGMA:
2560 /* ignored */
2561 break;
2562 default:
2563 if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
2564 /* '!' is ignored to allow C scripts. numbers are ignored
2565 to emulate cpp behaviour */
2566 } else {
2567 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
2569 break;
2571 /* ignore other preprocess commands or #! for C scripts */
2572 while (tok != TOK_LINEFEED)
2573 next_nomacro();
2574 the_end:
2575 return_linefeed = 0;
2578 /* read a number in base b */
2579 static int getn(int b)
2581 int n, t;
2582 n = 0;
2583 while (1) {
2584 if (ch >= 'a' && ch <= 'f')
2585 t = ch - 'a' + 10;
2586 else if (ch >= 'A' && ch <= 'F')
2587 t = ch - 'A' + 10;
2588 else if (isnum(ch))
2589 t = ch - '0';
2590 else
2591 break;
2592 if (t < 0 || t >= b)
2593 break;
2594 n = n * b + t;
2595 inp();
2597 return n;
2600 /* read a character for string or char constant and eval escape codes */
2601 static int getq(void)
2603 int c;
2605 redo:
2606 c = ch;
2607 inp();
2608 if (c == '\\') {
2609 switch(ch) {
2610 case '0': case '1': case '2': case '3':
2611 case '4': case '5': case '6': case '7':
2612 /* at most three octal digits */
2613 c = ch - '0';
2614 inp();
2615 if (isoct(ch)) {
2616 c = c * 8 + ch - '0';
2617 inp();
2618 if (isoct(ch)) {
2619 c = c * 8 + ch - '0';
2620 inp();
2623 return c;
2624 case 'x':
2625 inp();
2626 return getn(16);
2627 case 'a':
2628 c = '\a';
2629 break;
2630 case 'b':
2631 c = '\b';
2632 break;
2633 case 'f':
2634 c = '\f';
2635 break;
2636 case 'n':
2637 c = '\n';
2638 break;
2639 case 'r':
2640 c = '\r';
2641 break;
2642 case 't':
2643 c = '\t';
2644 break;
2645 case 'v':
2646 c = '\v';
2647 break;
2648 case 'e':
2649 if (!gnu_ext)
2650 goto invalid_escape;
2651 c = 27;
2652 break;
2653 case '\'':
2654 case '\"':
2655 case '\\':
2656 case '?':
2657 c = ch;
2658 break;
2659 case '\n':
2660 inp();
2661 goto redo;
2662 case '\r':
2663 inp();
2664 if (ch != '\n')
2665 goto invalid_escape;
2666 inp();
2667 goto redo;
2668 default:
2669 invalid_escape:
2670 error("invalid escaped char");
2672 inp();
2673 } else if (c == '\r' && ch == '\n') {
2674 inp();
2675 c = '\n';
2677 return c;
2680 /* we use 64 bit numbers */
2681 #define BN_SIZE 2
2683 /* bn = (bn << shift) | or_val */
2684 void bn_lshift(unsigned int *bn, int shift, int or_val)
2686 int i;
2687 unsigned int v;
2688 for(i=0;i<BN_SIZE;i++) {
2689 v = bn[i];
2690 bn[i] = (v << shift) | or_val;
2691 or_val = v >> (32 - shift);
2695 void bn_zero(unsigned int *bn)
2697 int i;
2698 for(i=0;i<BN_SIZE;i++) {
2699 bn[i] = 0;
2703 /* parse number in null terminated string 'p' and return it in the
2704 current token */
2705 void parse_number(const char *p)
2707 int b, t, shift, frac_bits, s, exp_val, ch;
2708 char *q;
2709 unsigned int bn[BN_SIZE];
2710 double d;
2712 /* number */
2713 q = token_buf;
2714 ch = *p++;
2715 t = ch;
2716 ch = *p++;
2717 *q++ = t;
2718 b = 10;
2719 if (t == '.') {
2720 goto float_frac_parse;
2721 } else if (t == '0') {
2722 if (ch == 'x' || ch == 'X') {
2723 q--;
2724 ch = *p++;
2725 b = 16;
2726 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2727 q--;
2728 ch = *p++;
2729 b = 2;
2732 /* parse all digits. cannot check octal numbers at this stage
2733 because of floating point constants */
2734 while (1) {
2735 if (ch >= 'a' && ch <= 'f')
2736 t = ch - 'a' + 10;
2737 else if (ch >= 'A' && ch <= 'F')
2738 t = ch - 'A' + 10;
2739 else if (isnum(ch))
2740 t = ch - '0';
2741 else
2742 break;
2743 if (t >= b)
2744 break;
2745 if (q >= token_buf + STRING_MAX_SIZE) {
2746 num_too_long:
2747 error("number too long");
2749 *q++ = ch;
2750 ch = *p++;
2752 if (ch == '.' ||
2753 ((ch == 'e' || ch == 'E') && b == 10) ||
2754 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2755 if (b != 10) {
2756 /* NOTE: strtox should support that for hexa numbers, but
2757 non ISOC99 libcs do not support it, so we prefer to do
2758 it by hand */
2759 /* hexadecimal or binary floats */
2760 /* XXX: handle overflows */
2761 *q = '\0';
2762 if (b == 16)
2763 shift = 4;
2764 else
2765 shift = 2;
2766 bn_zero(bn);
2767 q = token_buf;
2768 while (1) {
2769 t = *q++;
2770 if (t == '\0') {
2771 break;
2772 } else if (t >= 'a') {
2773 t = t - 'a' + 10;
2774 } else if (t >= 'A') {
2775 t = t - 'A' + 10;
2776 } else {
2777 t = t - '0';
2779 bn_lshift(bn, shift, t);
2781 frac_bits = 0;
2782 if (ch == '.') {
2783 ch = *p++;
2784 while (1) {
2785 t = ch;
2786 if (t >= 'a' && t <= 'f') {
2787 t = t - 'a' + 10;
2788 } else if (t >= 'A' && t <= 'F') {
2789 t = t - 'A' + 10;
2790 } else if (t >= '0' && t <= '9') {
2791 t = t - '0';
2792 } else {
2793 break;
2795 if (t >= b)
2796 error("invalid digit");
2797 bn_lshift(bn, shift, t);
2798 frac_bits += shift;
2799 ch = *p++;
2802 if (ch != 'p' && ch != 'P')
2803 expect("exponent");
2804 ch = *p++;
2805 s = 1;
2806 exp_val = 0;
2807 if (ch == '+') {
2808 ch = *p++;
2809 } else if (ch == '-') {
2810 s = -1;
2811 ch = *p++;
2813 if (ch < '0' || ch > '9')
2814 expect("exponent digits");
2815 while (ch >= '0' && ch <= '9') {
2816 exp_val = exp_val * 10 + ch - '0';
2817 ch = *p++;
2819 exp_val = exp_val * s;
2821 /* now we can generate the number */
2822 /* XXX: should patch directly float number */
2823 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
2824 d = ldexp(d, exp_val - frac_bits);
2825 t = toup(ch);
2826 if (t == 'F') {
2827 ch = *p++;
2828 tok = TOK_CFLOAT;
2829 /* float : should handle overflow */
2830 tokc.f = (float)d;
2831 } else if (t == 'L') {
2832 ch = *p++;
2833 tok = TOK_CLDOUBLE;
2834 /* XXX: not large enough */
2835 tokc.ld = (long double)d;
2836 } else {
2837 tok = TOK_CDOUBLE;
2838 tokc.d = d;
2840 } else {
2841 /* decimal floats */
2842 if (ch == '.') {
2843 if (q >= token_buf + STRING_MAX_SIZE)
2844 goto num_too_long;
2845 *q++ = ch;
2846 ch = *p++;
2847 float_frac_parse:
2848 while (ch >= '0' && ch <= '9') {
2849 if (q >= token_buf + STRING_MAX_SIZE)
2850 goto num_too_long;
2851 *q++ = ch;
2852 ch = *p++;
2855 if (ch == 'e' || ch == 'E') {
2856 if (q >= token_buf + STRING_MAX_SIZE)
2857 goto num_too_long;
2858 *q++ = ch;
2859 ch = *p++;
2860 if (ch == '-' || ch == '+') {
2861 if (q >= token_buf + STRING_MAX_SIZE)
2862 goto num_too_long;
2863 *q++ = ch;
2864 ch = *p++;
2866 if (ch < '0' || ch > '9')
2867 expect("exponent digits");
2868 while (ch >= '0' && ch <= '9') {
2869 if (q >= token_buf + STRING_MAX_SIZE)
2870 goto num_too_long;
2871 *q++ = ch;
2872 ch = *p++;
2875 *q = '\0';
2876 t = toup(ch);
2877 errno = 0;
2878 if (t == 'F') {
2879 ch = *p++;
2880 tok = TOK_CFLOAT;
2881 tokc.f = strtof(token_buf, NULL);
2882 } else if (t == 'L') {
2883 ch = *p++;
2884 tok = TOK_CLDOUBLE;
2885 tokc.ld = strtold(token_buf, NULL);
2886 } else {
2887 tok = TOK_CDOUBLE;
2888 tokc.d = strtod(token_buf, NULL);
2891 } else {
2892 unsigned long long n, n1;
2893 int lcount, ucount;
2895 /* integer number */
2896 *q = '\0';
2897 q = token_buf;
2898 if (b == 10 && *q == '0') {
2899 b = 8;
2900 q++;
2902 n = 0;
2903 while(1) {
2904 t = *q++;
2905 /* no need for checks except for base 10 / 8 errors */
2906 if (t == '\0') {
2907 break;
2908 } else if (t >= 'a') {
2909 t = t - 'a' + 10;
2910 } else if (t >= 'A') {
2911 t = t - 'A' + 10;
2912 } else {
2913 t = t - '0';
2914 if (t >= b)
2915 error("invalid digit");
2917 n1 = n;
2918 n = n * b + t;
2919 /* detect overflow */
2920 /* XXX: this test is not reliable */
2921 if (n < n1)
2922 error("integer constant overflow");
2925 /* XXX: not exactly ANSI compliant */
2926 if ((n & 0xffffffff00000000LL) != 0) {
2927 if ((n >> 63) != 0)
2928 tok = TOK_CULLONG;
2929 else
2930 tok = TOK_CLLONG;
2931 } else if (n > 0x7fffffff) {
2932 tok = TOK_CUINT;
2933 } else {
2934 tok = TOK_CINT;
2936 lcount = 0;
2937 ucount = 0;
2938 for(;;) {
2939 t = toup(ch);
2940 if (t == 'L') {
2941 if (lcount >= 2)
2942 error("three 'l's in integer constant");
2943 lcount++;
2944 if (lcount == 2) {
2945 if (tok == TOK_CINT)
2946 tok = TOK_CLLONG;
2947 else if (tok == TOK_CUINT)
2948 tok = TOK_CULLONG;
2950 ch = *p++;
2951 } else if (t == 'U') {
2952 if (ucount >= 1)
2953 error("two 'u's in integer constant");
2954 ucount++;
2955 if (tok == TOK_CINT)
2956 tok = TOK_CUINT;
2957 else if (tok == TOK_CLLONG)
2958 tok = TOK_CULLONG;
2959 ch = *p++;
2960 } else {
2961 break;
2964 if (tok == TOK_CINT || tok == TOK_CUINT)
2965 tokc.ui = n;
2966 else
2967 tokc.ull = n;
2972 #define PARSE2(c1, tok1, c2, tok2) \
2973 case c1: \
2974 PEEKC(c, p); \
2975 if (c == c2) { \
2976 p++; \
2977 tok = tok2; \
2978 } else { \
2979 tok = tok1; \
2981 break;
2983 /* return next token without macro substitution */
2984 static inline void next_nomacro1(void)
2986 int b, t, c;
2987 TokenSym *ts;
2988 uint8_t *p, *p1;
2989 unsigned int h;
2991 p = file->buf_ptr;
2992 redo_no_start:
2993 c = *p;
2994 switch(c) {
2995 case ' ':
2996 case '\t':
2997 case '\f':
2998 case '\v':
2999 case '\r':
3000 p++;
3001 goto redo_no_start;
3003 case '\\':
3004 /* first look if it is in fact an end of buffer */
3005 if (p >= file->buf_end) {
3006 file->buf_ptr = p;
3007 handle_eob();
3008 p = file->buf_ptr;
3009 if (p >= file->buf_end)
3010 goto parse_eof;
3011 else
3012 goto redo_no_start;
3013 } else {
3014 file->buf_ptr = p;
3015 ch = *p;
3016 handle_stray();
3017 p = file->buf_ptr;
3018 goto redo_no_start;
3020 parse_eof:
3022 TCCState *s1 = tcc_state;
3024 if (return_linefeed) {
3025 tok = TOK_LINEFEED;
3026 } else if (s1->include_stack_ptr == s1->include_stack) {
3027 /* no include left : end of file */
3028 tok = TOK_EOF;
3029 } else {
3030 /* pop include file */
3032 /* test if previous '#endif' was after a #ifdef at
3033 start of file */
3034 if (tok_flags & TOK_FLAG_ENDIF) {
3035 #ifdef INC_DEBUG
3036 printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
3037 #endif
3038 add_cached_include(s1, file->inc_type, file->inc_filename,
3039 file->ifndef_macro_saved);
3042 /* add end of include file debug info */
3043 if (do_debug) {
3044 put_stabd(N_EINCL, 0, 0);
3046 /* pop include stack */
3047 tcc_close(file);
3048 s1->include_stack_ptr--;
3049 file = *s1->include_stack_ptr;
3050 p = file->buf_ptr;
3051 goto redo_no_start;
3054 break;
3056 case '\n':
3057 if (return_linefeed) {
3058 tok = TOK_LINEFEED;
3059 } else {
3060 file->line_num++;
3061 tok_flags |= TOK_FLAG_BOL;
3062 p++;
3063 goto redo_no_start;
3065 break;
3067 case '#':
3068 /* XXX: simplify */
3069 PEEKC(c, p);
3070 if (tok_flags & TOK_FLAG_BOL) {
3071 file->buf_ptr = p;
3072 preprocess(tok_flags & TOK_FLAG_BOF);
3073 p = file->buf_ptr;
3074 goto redo_no_start;
3075 } else {
3076 if (c == '#') {
3077 p++;
3078 tok = TOK_TWOSHARPS;
3079 } else {
3080 tok = '#';
3083 break;
3085 case 'a': case 'b': case 'c': case 'd':
3086 case 'e': case 'f': case 'g': case 'h':
3087 case 'i': case 'j': case 'k': case 'l':
3088 case 'm': case 'n': case 'o': case 'p':
3089 case 'q': case 'r': case 's': case 't':
3090 case 'u': case 'v': case 'w': case 'x':
3091 case 'y': case 'z':
3092 case 'A': case 'B': case 'C': case 'D':
3093 case 'E': case 'F': case 'G': case 'H':
3094 case 'I': case 'J': case 'K':
3095 case 'M': case 'N': case 'O': case 'P':
3096 case 'Q': case 'R': case 'S': case 'T':
3097 case 'U': case 'V': case 'W': case 'X':
3098 case 'Y': case 'Z':
3099 case '_':
3100 parse_ident_fast:
3101 p1 = p;
3102 h = TOK_HASH_INIT;
3103 h = TOK_HASH_FUNC(h, c);
3104 p++;
3105 for(;;) {
3106 c = *p;
3107 if (!isid(c) && !isnum(c))
3108 break;
3109 h = TOK_HASH_FUNC(h, c);
3110 p++;
3112 if (c != '\\') {
3113 TokenSym **pts;
3114 int len;
3116 /* fast case : no stray found, so we have the full token
3117 and we have already hashed it */
3118 len = p - p1;
3119 h &= (TOK_HASH_SIZE - 1);
3120 pts = &hash_ident[h];
3121 for(;;) {
3122 ts = *pts;
3123 if (!ts)
3124 break;
3125 if (ts->len == len && !memcmp(ts->str, p1, len))
3126 goto token_found;
3127 pts = &(ts->hash_next);
3129 ts = tok_alloc_new(pts, p1, len);
3130 token_found: ;
3131 } else {
3132 /* slower case */
3133 cstr_reset(&tokcstr);
3135 while (p1 < p) {
3136 cstr_ccat(&tokcstr, *p1);
3137 p1++;
3139 p--;
3140 PEEKC(c, p);
3141 parse_ident_slow:
3142 while (isid(c) || isnum(c)) {
3143 cstr_ccat(&tokcstr, c);
3144 PEEKC(c, p);
3146 ts = tok_alloc(tokcstr.data, tokcstr.size);
3148 tok = ts->tok;
3149 break;
3150 case 'L':
3151 t = p[1];
3152 if (t != '\\' && t != '\'' && t != '\"') {
3153 /* fast case */
3154 goto parse_ident_fast;
3155 } else {
3156 PEEKC(c, p);
3157 if (c == '\'') {
3158 tok = TOK_LCHAR;
3159 goto char_const;
3160 } else if (c == '\"') {
3161 tok = TOK_LSTR;
3162 goto str_const;
3163 } else {
3164 cstr_reset(&tokcstr);
3165 cstr_ccat(&tokcstr, 'L');
3166 goto parse_ident_slow;
3169 break;
3170 case '0': case '1': case '2': case '3':
3171 case '4': case '5': case '6': case '7':
3172 case '8': case '9':
3174 cstr_reset(&tokcstr);
3175 /* after the first digit, accept digits, alpha, '.' or sign if
3176 prefixed by 'eEpP' */
3177 parse_num:
3178 for(;;) {
3179 t = c;
3180 cstr_ccat(&tokcstr, c);
3181 PEEKC(c, p);
3182 if (!(isnum(c) || isid(c) || c == '.' ||
3183 ((c == '+' || c == '-') &&
3184 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
3185 break;
3187 /* We add a trailing '\0' to ease parsing */
3188 cstr_ccat(&tokcstr, '\0');
3189 tokc.cstr = &tokcstr;
3190 tok = TOK_PPNUM;
3191 break;
3192 case '.':
3193 /* special dot handling because it can also start a number */
3194 PEEKC(c, p);
3195 if (isnum(c)) {
3196 cstr_reset(&tokcstr);
3197 cstr_ccat(&tokcstr, '.');
3198 goto parse_num;
3199 } else if (c == '.') {
3200 PEEKC(c, p);
3201 if (c != '.')
3202 expect("'.'");
3203 PEEKC(c, p);
3204 tok = TOK_DOTS;
3205 } else {
3206 tok = '.';
3208 break;
3209 case '\'':
3210 tok = TOK_CCHAR;
3211 char_const:
3212 file->buf_ptr = p;
3213 inp();
3214 b = getq();
3215 /* this cast is needed if >= 128 */
3216 if (tok == TOK_CCHAR)
3217 b = (char)b;
3218 tokc.i = b;
3219 if (ch != '\'')
3220 error("unterminated character constant");
3221 p = file->buf_ptr;
3222 p++;
3223 break;
3224 case '\"':
3225 tok = TOK_STR;
3226 str_const:
3227 file->buf_ptr = p;
3228 inp();
3229 cstr_reset(&tokcstr);
3230 while (ch != '\"') {
3231 b = getq();
3232 if (ch == CH_EOF)
3233 error("unterminated string");
3234 if (tok == TOK_STR)
3235 cstr_ccat(&tokcstr, b);
3236 else
3237 cstr_wccat(&tokcstr, b);
3239 if (tok == TOK_STR)
3240 cstr_ccat(&tokcstr, '\0');
3241 else
3242 cstr_wccat(&tokcstr, '\0');
3243 tokc.cstr = &tokcstr;
3244 p = file->buf_ptr;
3245 p++;
3246 break;
3248 case '<':
3249 PEEKC(c, p);
3250 if (c == '=') {
3251 p++;
3252 tok = TOK_LE;
3253 } else if (c == '<') {
3254 PEEKC(c, p);
3255 if (c == '=') {
3256 p++;
3257 tok = TOK_A_SHL;
3258 } else {
3259 tok = TOK_SHL;
3261 } else {
3262 tok = TOK_LT;
3264 break;
3266 case '>':
3267 PEEKC(c, p);
3268 if (c == '=') {
3269 p++;
3270 tok = TOK_GE;
3271 } else if (c == '>') {
3272 PEEKC(c, p);
3273 if (c == '=') {
3274 p++;
3275 tok = TOK_A_SAR;
3276 } else {
3277 tok = TOK_SAR;
3279 } else {
3280 tok = TOK_GT;
3282 break;
3284 case '&':
3285 PEEKC(c, p);
3286 if (c == '&') {
3287 p++;
3288 tok = TOK_LAND;
3289 } else if (c == '=') {
3290 p++;
3291 tok = TOK_A_AND;
3292 } else {
3293 tok = '&';
3295 break;
3297 case '|':
3298 PEEKC(c, p);
3299 if (c == '|') {
3300 p++;
3301 tok = TOK_LOR;
3302 } else if (c == '=') {
3303 p++;
3304 tok = TOK_A_OR;
3305 } else {
3306 tok = '|';
3308 break;
3310 case '+':
3311 PEEKC(c, p);
3312 if (c == '+') {
3313 p++;
3314 tok = TOK_INC;
3315 } else if (c == '=') {
3316 p++;
3317 tok = TOK_A_ADD;
3318 } else {
3319 tok = '+';
3321 break;
3323 case '-':
3324 PEEKC(c, p);
3325 if (c == '-') {
3326 p++;
3327 tok = TOK_DEC;
3328 } else if (c == '=') {
3329 p++;
3330 tok = TOK_A_SUB;
3331 } else if (c == '>') {
3332 p++;
3333 tok = TOK_ARROW;
3334 } else {
3335 tok = '-';
3337 break;
3339 PARSE2('!', '!', '=', TOK_NE)
3340 PARSE2('=', '=', '=', TOK_EQ)
3341 PARSE2('*', '*', '=', TOK_A_MUL)
3342 PARSE2('%', '%', '=', TOK_A_MOD)
3343 PARSE2('^', '^', '=', TOK_A_XOR)
3345 /* comments or operator */
3346 case '/':
3347 PEEKC(c, p);
3348 if (c == '*') {
3349 file->buf_ptr = p;
3350 parse_comment();
3351 p = file->buf_ptr;
3352 goto redo_no_start;
3353 } else if (c == '/') {
3354 file->buf_ptr = p;
3355 parse_line_comment();
3356 p = file->buf_ptr;
3357 goto redo_no_start;
3358 } else if (c == '=') {
3359 p++;
3360 tok = TOK_A_DIV;
3361 } else {
3362 tok = '/';
3364 break;
3366 /* simple tokens */
3367 case '(':
3368 case ')':
3369 case '[':
3370 case ']':
3371 case '{':
3372 case '}':
3373 case ',':
3374 case ';':
3375 case ':':
3376 case '?':
3377 case '~':
3378 tok = c;
3379 p++;
3380 break;
3381 default:
3382 error("unrecognized character \\x%02x", c);
3383 break;
3385 file->buf_ptr = p;
3386 tok_flags = 0;
3387 #if defined(PARSE_DEBUG)
3388 printf("token = %s\n", get_tok_str(tok, &tokc));
3389 #endif
3392 /* return next token without macro substitution. Can read input from
3393 macro_ptr buffer */
3394 static void next_nomacro(void)
3396 if (macro_ptr) {
3397 redo:
3398 tok = *macro_ptr;
3399 if (tok) {
3400 TOK_GET(tok, macro_ptr, tokc);
3401 if (tok == TOK_LINENUM) {
3402 file->line_num = tokc.i;
3403 goto redo;
3406 } else {
3407 next_nomacro1();
3411 /* substitute args in macro_str and return allocated string */
3412 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
3414 int *st, last_tok, t, notfirst;
3415 Sym *s;
3416 CValue cval;
3417 TokenString str;
3418 CString cstr;
3420 tok_str_new(&str);
3421 last_tok = 0;
3422 while(1) {
3423 TOK_GET(t, macro_str, cval);
3424 if (!t)
3425 break;
3426 if (t == '#') {
3427 /* stringize */
3428 TOK_GET(t, macro_str, cval);
3429 if (!t)
3430 break;
3431 s = sym_find2(args, t);
3432 if (s) {
3433 cstr_new(&cstr);
3434 st = (int *)s->c;
3435 notfirst = 0;
3436 while (*st) {
3437 if (notfirst)
3438 cstr_ccat(&cstr, ' ');
3439 TOK_GET(t, st, cval);
3440 cstr_cat(&cstr, get_tok_str(t, &cval));
3441 notfirst = 1;
3443 cstr_ccat(&cstr, '\0');
3444 #ifdef PP_DEBUG
3445 printf("stringize: %s\n", (char *)cstr.data);
3446 #endif
3447 /* add string */
3448 cval.cstr = &cstr;
3449 tok_str_add2(&str, TOK_STR, &cval);
3450 cstr_free(&cstr);
3451 } else {
3452 tok_str_add2(&str, t, &cval);
3454 } else if (t >= TOK_IDENT) {
3455 s = sym_find2(args, t);
3456 if (s) {
3457 st = (int *)s->c;
3458 /* if '##' is present before or after, no arg substitution */
3459 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
3460 /* special case for var arg macros : ## eats the
3461 ',' if empty VA_ARGS variable. */
3462 /* XXX: test of the ',' is not 100%
3463 reliable. should fix it to avoid security
3464 problems */
3465 if (gnu_ext && s->type.t &&
3466 last_tok == TOK_TWOSHARPS &&
3467 str.len >= 2 && str.str[str.len - 2] == ',') {
3468 if (*st == 0) {
3469 /* suppress ',' '##' */
3470 str.len -= 2;
3471 } else {
3472 /* suppress '##' and add variable */
3473 str.len--;
3474 goto add_var;
3476 } else {
3477 int t1;
3478 add_var:
3479 for(;;) {
3480 TOK_GET(t1, st, cval);
3481 if (!t1)
3482 break;
3483 tok_str_add2(&str, t1, &cval);
3486 } else {
3487 macro_subst(&str, nested_list, st);
3489 } else {
3490 tok_str_add(&str, t);
3492 } else {
3493 tok_str_add2(&str, t, &cval);
3495 last_tok = t;
3497 tok_str_add(&str, 0);
3498 return str.str;
3501 /* handle the '##' operator */
3502 static int *macro_twosharps(void)
3504 TokenSym *ts;
3505 int *macro_ptr1;
3506 int t;
3507 const char *p1, *p2;
3508 CValue cval;
3509 TokenString macro_str1;
3510 CString cstr;
3512 cstr_new(&cstr);
3513 tok_str_new(&macro_str1);
3514 tok = 0;
3515 while (1) {
3516 next_nomacro();
3517 if (tok == 0)
3518 break;
3519 while (*macro_ptr == TOK_TWOSHARPS) {
3520 macro_ptr++;
3521 macro_ptr1 = macro_ptr;
3522 t = *macro_ptr;
3523 if (t) {
3524 TOK_GET(t, macro_ptr, cval);
3526 /* We concatenate the two tokens if we have an
3527 identifier or a preprocessing number */
3528 cstr_reset(&cstr);
3529 p1 = get_tok_str(tok, &tokc);
3530 cstr_cat(&cstr, p1);
3531 p2 = get_tok_str(t, &cval);
3532 cstr_cat(&cstr, p2);
3533 cstr_ccat(&cstr, '\0');
3535 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
3536 (t >= TOK_IDENT || t == TOK_PPNUM)) {
3537 if (tok == TOK_PPNUM) {
3538 /* if number, then create a number token */
3539 /* NOTE: no need to allocate because
3540 tok_str_add2() does it */
3541 tokc.cstr = &cstr;
3542 } else {
3543 /* if identifier, we must do a test to
3544 validate we have a correct identifier */
3545 if (t == TOK_PPNUM) {
3546 const char *p;
3547 int c;
3549 p = p2;
3550 for(;;) {
3551 c = *p;
3552 if (c == '\0')
3553 break;
3554 p++;
3555 if (!isnum(c) && !isid(c))
3556 goto error_pasting;
3559 ts = tok_alloc(cstr.data, strlen(cstr.data));
3560 tok = ts->tok; /* modify current token */
3562 } else {
3563 const char *str = cstr.data;
3564 const unsigned char *q;
3566 /* we look for a valid token */
3567 /* XXX: do more extensive checks */
3568 if (!strcmp(str, ">>=")) {
3569 tok = TOK_A_SAR;
3570 } else if (!strcmp(str, "<<=")) {
3571 tok = TOK_A_SHL;
3572 } else if (strlen(str) == 2) {
3573 /* search in two bytes table */
3574 q = tok_two_chars;
3575 for(;;) {
3576 if (!*q)
3577 goto error_pasting;
3578 if (q[0] == str[0] && q[1] == str[1])
3579 break;
3580 q += 3;
3582 tok = q[2];
3583 } else {
3584 error_pasting:
3585 /* NOTE: because get_tok_str use a static buffer,
3586 we must save it */
3587 cstr_reset(&cstr);
3588 p1 = get_tok_str(tok, &tokc);
3589 cstr_cat(&cstr, p1);
3590 cstr_ccat(&cstr, '\0');
3591 p2 = get_tok_str(t, &cval);
3592 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
3593 /* cannot merge tokens: just add them separately */
3594 tok_str_add2(&macro_str1, tok, &tokc);
3595 /* XXX: free associated memory ? */
3596 tok = t;
3597 tokc = cval;
3602 tok_str_add2(&macro_str1, tok, &tokc);
3604 cstr_free(&cstr);
3605 tok_str_add(&macro_str1, 0);
3606 return macro_str1.str;
3610 /* do macro substitution of current token with macro 's' and add
3611 result to (tok_str,tok_len). 'nested_list' is the list of all
3612 macros we got inside to avoid recursing. Return non zero if no
3613 substitution needs to be done */
3614 static int macro_subst_tok(TokenString *tok_str,
3615 Sym **nested_list, Sym *s)
3617 Sym *args, *sa, *sa1;
3618 int mstr_allocated, parlevel, *mstr, t;
3619 TokenString str;
3620 char *cstrval;
3621 CValue cval;
3622 CString cstr;
3624 /* if symbol is a macro, prepare substitution */
3625 /* if nested substitution, do nothing */
3626 if (sym_find2(*nested_list, tok))
3627 return -1;
3629 /* special macros */
3630 if (tok == TOK___LINE__) {
3631 cval.i = file->line_num;
3632 tok_str_add2(tok_str, TOK_CINT, &cval);
3633 } else if (tok == TOK___FILE__) {
3634 cstrval = file->filename;
3635 goto add_cstr;
3636 tok_str_add2(tok_str, TOK_STR, &cval);
3637 } else if (tok == TOK___DATE__) {
3638 cstrval = "Jan 1 2002";
3639 goto add_cstr;
3640 } else if (tok == TOK___TIME__) {
3641 cstrval = "00:00:00";
3642 add_cstr:
3643 cstr_new(&cstr);
3644 cstr_cat(&cstr, cstrval);
3645 cstr_ccat(&cstr, '\0');
3646 cval.cstr = &cstr;
3647 tok_str_add2(tok_str, TOK_STR, &cval);
3648 cstr_free(&cstr);
3649 } else {
3650 mstr = (int *)s->c;
3651 mstr_allocated = 0;
3652 if (s->type.t == MACRO_FUNC) {
3653 /* NOTE: we do not use next_nomacro to avoid eating the
3654 next token. XXX: find better solution */
3655 if (macro_ptr) {
3656 t = *macro_ptr;
3657 } else {
3658 /* XXX: incorrect with comments */
3659 ch = file->buf_ptr[0];
3660 while (is_space(ch) || ch == '\n')
3661 cinp();
3662 t = ch;
3664 if (t != '(') /* no macro subst */
3665 return -1;
3667 /* argument macro */
3668 next_nomacro();
3669 next_nomacro();
3670 args = NULL;
3671 sa = s->next;
3672 /* NOTE: empty args are allowed, except if no args */
3673 for(;;) {
3674 /* handle '()' case */
3675 if (!args && tok == ')')
3676 break;
3677 if (!sa)
3678 error("macro '%s' used with too many args",
3679 get_tok_str(s->v, 0));
3680 tok_str_new(&str);
3681 parlevel = 0;
3682 /* NOTE: non zero sa->t indicates VA_ARGS */
3683 while ((parlevel > 0 ||
3684 (tok != ')' &&
3685 (tok != ',' || sa->type.t))) &&
3686 tok != -1) {
3687 if (tok == '(')
3688 parlevel++;
3689 else if (tok == ')')
3690 parlevel--;
3691 tok_str_add2(&str, tok, &tokc);
3692 next_nomacro();
3694 tok_str_add(&str, 0);
3695 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str);
3696 sa = sa->next;
3697 if (tok == ')') {
3698 /* special case for gcc var args: add an empty
3699 var arg argument if it is omitted */
3700 if (sa && sa->type.t && gnu_ext)
3701 continue;
3702 else
3703 break;
3705 if (tok != ',')
3706 expect(",");
3707 next_nomacro();
3709 if (sa) {
3710 error("macro '%s' used with too few args",
3711 get_tok_str(s->v, 0));
3714 /* now subst each arg */
3715 mstr = macro_arg_subst(nested_list, mstr, args);
3716 /* free memory */
3717 sa = args;
3718 while (sa) {
3719 sa1 = sa->prev;
3720 tok_str_free((int *)sa->c);
3721 tcc_free(sa);
3722 sa = sa1;
3724 mstr_allocated = 1;
3726 sym_push2(nested_list, s->v, 0, 0);
3727 macro_subst(tok_str, nested_list, mstr);
3728 /* pop nested defined symbol */
3729 sa1 = *nested_list;
3730 *nested_list = sa1->prev;
3731 tcc_free(sa1);
3732 if (mstr_allocated)
3733 tok_str_free(mstr);
3735 return 0;
3738 /* do macro substitution of macro_str and add result to
3739 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3740 inside to avoid recursing. */
3741 static void macro_subst(TokenString *tok_str,
3742 Sym **nested_list, int *macro_str)
3744 Sym *s;
3745 int *saved_macro_ptr;
3746 int *macro_str1;
3748 saved_macro_ptr = macro_ptr;
3749 macro_ptr = macro_str;
3750 /* first scan for '##' operator handling */
3751 macro_str1 = macro_twosharps();
3752 macro_ptr = macro_str1;
3754 while (1) {
3755 next_nomacro();
3756 if (tok == 0)
3757 break;
3758 s = define_find(tok);
3759 if (s != NULL) {
3760 if (macro_subst_tok(tok_str, nested_list, s) != 0)
3761 goto no_subst;
3762 } else {
3763 no_subst:
3764 tok_str_add2(tok_str, tok, &tokc);
3767 macro_ptr = saved_macro_ptr;
3768 tok_str_free(macro_str1);
3771 /* return next token with macro substitution */
3772 static void next(void)
3774 Sym *nested_list, *s;
3775 TokenString str;
3777 /* special 'ungettok' case for label parsing */
3778 if (tok1) {
3779 tok = tok1;
3780 tokc = tok1c;
3781 tok1 = 0;
3782 } else {
3783 redo:
3784 next_nomacro();
3785 if (!macro_ptr) {
3786 /* if not reading from macro substituted string, then try
3787 to substitute macros */
3788 if (tok >= TOK_IDENT) {
3789 s = define_find(tok);
3790 if (s) {
3791 /* we have a macro: we try to substitute */
3792 tok_str_new(&str);
3793 nested_list = NULL;
3794 if (macro_subst_tok(&str, &nested_list, s) == 0) {
3795 /* substitution done, NOTE: maybe empty */
3796 tok_str_add(&str, 0);
3797 macro_ptr = str.str;
3798 macro_ptr_allocated = str.str;
3799 goto redo;
3803 } else {
3804 if (tok == 0) {
3805 /* end of macro string: free it */
3806 tok_str_free(macro_ptr_allocated);
3807 macro_ptr = NULL;
3808 goto redo;
3812 /* convert preprocessor tokens into C tokens */
3813 if (tok == TOK_PPNUM) {
3814 parse_number((char *)tokc.cstr->data);
3819 void swap(int *p, int *q)
3821 int t;
3822 t = *p;
3823 *p = *q;
3824 *q = t;
3827 void vsetc(CType *type, int r, CValue *vc)
3829 int v;
3831 if (vtop >= vstack + VSTACK_SIZE)
3832 error("memory full");
3833 /* cannot let cpu flags if other instruction are generated. Also
3834 avoid leaving VT_JMP anywhere except on the top of the stack
3835 because it would complicate the code generator. */
3836 if (vtop >= vstack) {
3837 v = vtop->r & VT_VALMASK;
3838 if (v == VT_CMP || (v & ~1) == VT_JMP)
3839 gv(RC_INT);
3841 vtop++;
3842 vtop->type = *type;
3843 vtop->r = r;
3844 vtop->r2 = VT_CONST;
3845 vtop->c = *vc;
3848 /* push integer constant */
3849 void vpushi(int v)
3851 CValue cval;
3852 cval.i = v;
3853 vsetc(&int_type, VT_CONST, &cval);
3856 /* Return a static symbol pointing to a section */
3857 static Sym *get_sym_ref(CType *type, Section *sec,
3858 unsigned long offset, unsigned long size)
3860 int v;
3861 Sym *sym;
3863 v = anon_sym++;
3864 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
3865 sym->type.ref = type->ref;
3866 sym->r = VT_CONST | VT_SYM;
3867 put_extern_sym(sym, sec, offset, size);
3868 return sym;
3871 /* push a reference to a section offset by adding a dummy symbol */
3872 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
3874 CValue cval;
3876 cval.ul = 0;
3877 vsetc(type, VT_CONST | VT_SYM, &cval);
3878 vtop->sym = get_sym_ref(type, sec, offset, size);
3881 /* define a new external reference to a symbol 'v' of type 'u' */
3882 static Sym *external_global_sym(int v, CType *type, int r)
3884 Sym *s;
3886 s = sym_find(v);
3887 if (!s) {
3888 /* push forward reference */
3889 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
3890 s->type.ref = type->ref;
3891 s->r = r | VT_CONST | VT_SYM;
3893 return s;
3896 /* define a new external reference to a symbol 'v' of type 'u' */
3897 static Sym *external_sym(int v, CType *type, int r)
3899 Sym *s;
3901 s = sym_find(v);
3902 if (!s) {
3903 /* push forward reference */
3904 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
3905 s->type.t |= VT_EXTERN;
3907 return s;
3910 /* push a reference to global symbol v */
3911 static void vpush_global_sym(CType *type, int v)
3913 Sym *sym;
3914 CValue cval;
3916 sym = external_global_sym(v, type, 0);
3917 cval.ul = 0;
3918 vsetc(type, VT_CONST | VT_SYM, &cval);
3919 vtop->sym = sym;
3922 void vset(CType *type, int r, int v)
3924 CValue cval;
3926 cval.i = v;
3927 vsetc(type, r, &cval);
3930 void vseti(int r, int v)
3932 CType type;
3933 type.t = VT_INT;
3934 vset(&type, r, v);
3937 void vswap(void)
3939 SValue tmp;
3941 tmp = vtop[0];
3942 vtop[0] = vtop[-1];
3943 vtop[-1] = tmp;
3946 void vpushv(SValue *v)
3948 if (vtop >= vstack + VSTACK_SIZE)
3949 error("memory full");
3950 vtop++;
3951 *vtop = *v;
3954 void vdup(void)
3956 vpushv(vtop);
3959 /* save r to the memory stack, and mark it as being free */
3960 void save_reg(int r)
3962 int l, saved, size, align;
3963 SValue *p, sv;
3964 CType *type;
3966 /* modify all stack values */
3967 saved = 0;
3968 l = 0;
3969 for(p=vstack;p<=vtop;p++) {
3970 if ((p->r & VT_VALMASK) == r ||
3971 (p->r2 & VT_VALMASK) == r) {
3972 /* must save value on stack if not already done */
3973 if (!saved) {
3974 /* NOTE: must reload 'r' because r might be equal to r2 */
3975 r = p->r & VT_VALMASK;
3976 /* store register in the stack */
3977 type = &p->type;
3978 if ((p->r & VT_LVAL) ||
3979 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
3980 type = &int_type;
3981 size = type_size(type, &align);
3982 loc = (loc - size) & -align;
3983 sv.type.t = type->t;
3984 sv.r = VT_LOCAL | VT_LVAL;
3985 sv.c.ul = loc;
3986 store(r, &sv);
3987 #ifdef TCC_TARGET_I386
3988 /* x86 specific: need to pop fp register ST0 if saved */
3989 if (r == TREG_ST0) {
3990 o(0xd9dd); /* fstp %st(1) */
3992 #endif
3993 /* special long long case */
3994 if ((type->t & VT_BTYPE) == VT_LLONG) {
3995 sv.c.ul += 4;
3996 store(p->r2, &sv);
3998 l = loc;
3999 saved = 1;
4001 /* mark that stack entry as being saved on the stack */
4002 if (p->r & VT_LVAL) {
4003 /* also suppress the bounded flag because the
4004 relocation address of the function was stored in
4005 p->c.ul */
4006 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
4007 } else {
4008 p->r = lvalue_type(p->type.t) | VT_LOCAL;
4010 p->r2 = VT_CONST;
4011 p->c.ul = l;
4016 /* find a free register of class 'rc'. If none, save one register */
4017 int get_reg(int rc)
4019 int r;
4020 SValue *p;
4022 /* find a free register */
4023 for(r=0;r<NB_REGS;r++) {
4024 if (reg_classes[r] & rc) {
4025 for(p=vstack;p<=vtop;p++) {
4026 if ((p->r & VT_VALMASK) == r ||
4027 (p->r2 & VT_VALMASK) == r)
4028 goto notfound;
4030 return r;
4032 notfound: ;
4035 /* no register left : free the first one on the stack (VERY
4036 IMPORTANT to start from the bottom to ensure that we don't
4037 spill registers used in gen_opi()) */
4038 for(p=vstack;p<=vtop;p++) {
4039 r = p->r & VT_VALMASK;
4040 if (r < VT_CONST && (reg_classes[r] & rc))
4041 goto save_found;
4042 /* also look at second register (if long long) */
4043 r = p->r2 & VT_VALMASK;
4044 if (r < VT_CONST && (reg_classes[r] & rc)) {
4045 save_found:
4046 save_reg(r);
4047 return r;
4050 /* Should never comes here */
4051 return -1;
4054 /* save registers up to (vtop - n) stack entry */
4055 void save_regs(int n)
4057 int r;
4058 SValue *p, *p1;
4059 p1 = vtop - n;
4060 for(p = vstack;p <= p1; p++) {
4061 r = p->r & VT_VALMASK;
4062 if (r < VT_CONST) {
4063 save_reg(r);
4068 /* move register 's' to 'r', and flush previous value of r to memory
4069 if needed */
4070 void move_reg(int r, int s)
4072 SValue sv;
4074 if (r != s) {
4075 save_reg(r);
4076 sv.type.t = VT_INT;
4077 sv.r = s;
4078 sv.c.ul = 0;
4079 load(r, &sv);
4083 /* get address of vtop (vtop MUST BE an lvalue) */
4084 void gaddrof(void)
4086 vtop->r &= ~VT_LVAL;
4087 /* tricky: if saved lvalue, then we can go back to lvalue */
4088 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
4089 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
4092 #ifdef CONFIG_TCC_BCHECK
4093 /* generate lvalue bound code */
4094 void gbound(void)
4096 int lval_type;
4097 CType type1;
4099 vtop->r &= ~VT_MUSTBOUND;
4100 /* if lvalue, then use checking code before dereferencing */
4101 if (vtop->r & VT_LVAL) {
4102 /* if not VT_BOUNDED value, then make one */
4103 if (!(vtop->r & VT_BOUNDED)) {
4104 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
4105 /* must save type because we must set it to int to get pointer */
4106 type1 = vtop->type;
4107 vtop->type.t = VT_INT;
4108 gaddrof();
4109 vpushi(0);
4110 gen_bounded_ptr_add();
4111 vtop->r |= lval_type;
4112 vtop->type = type1;
4114 /* then check for dereferencing */
4115 gen_bounded_ptr_deref();
4118 #endif
4120 /* store vtop a register belonging to class 'rc'. lvalues are
4121 converted to values. Cannot be used if cannot be converted to
4122 register value (such as structures). */
4123 int gv(int rc)
4125 int r, r2, rc2, bit_pos, bit_size, size, align, i;
4126 unsigned long long ll;
4128 /* NOTE: get_reg can modify vstack[] */
4129 if (vtop->type.t & VT_BITFIELD) {
4130 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4131 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4132 /* remove bit field info to avoid loops */
4133 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4134 /* generate shifts */
4135 vpushi(32 - (bit_pos + bit_size));
4136 gen_op(TOK_SHL);
4137 vpushi(32 - bit_size);
4138 /* NOTE: transformed to SHR if unsigned */
4139 gen_op(TOK_SAR);
4140 r = gv(rc);
4141 } else {
4142 if (is_float(vtop->type.t) &&
4143 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4144 Sym *sym;
4145 int *ptr;
4146 unsigned long offset;
4148 /* XXX: unify with initializers handling ? */
4149 /* CPUs usually cannot use float constants, so we store them
4150 generically in data segment */
4151 size = type_size(&vtop->type, &align);
4152 offset = (data_section->data_offset + align - 1) & -align;
4153 data_section->data_offset = offset;
4154 /* XXX: not portable yet */
4155 ptr = section_ptr_add(data_section, size);
4156 size = size >> 2;
4157 for(i=0;i<size;i++)
4158 ptr[i] = vtop->c.tab[i];
4159 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
4160 vtop->r |= VT_LVAL | VT_SYM;
4161 vtop->sym = sym;
4162 vtop->c.ul = 0;
4164 #ifdef CONFIG_TCC_BCHECK
4165 if (vtop->r & VT_MUSTBOUND)
4166 gbound();
4167 #endif
4169 r = vtop->r & VT_VALMASK;
4170 /* need to reload if:
4171 - constant
4172 - lvalue (need to dereference pointer)
4173 - already a register, but not in the right class */
4174 if (r >= VT_CONST ||
4175 (vtop->r & VT_LVAL) ||
4176 !(reg_classes[r] & rc) ||
4177 ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
4178 !(reg_classes[vtop->r2] & rc))) {
4179 r = get_reg(rc);
4180 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
4181 /* two register type load : expand to two words
4182 temporarily */
4183 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4184 /* load constant */
4185 ll = vtop->c.ull;
4186 vtop->c.ui = ll; /* first word */
4187 load(r, vtop);
4188 vtop->r = r; /* save register value */
4189 vpushi(ll >> 32); /* second word */
4190 } else if (r >= VT_CONST ||
4191 (vtop->r & VT_LVAL)) {
4192 /* load from memory */
4193 load(r, vtop);
4194 vdup();
4195 vtop[-1].r = r; /* save register value */
4196 /* increment pointer to get second word */
4197 vtop->type.t = VT_INT;
4198 gaddrof();
4199 vpushi(4);
4200 gen_op('+');
4201 vtop->r |= VT_LVAL;
4202 } else {
4203 /* move registers */
4204 load(r, vtop);
4205 vdup();
4206 vtop[-1].r = r; /* save register value */
4207 vtop->r = vtop[-1].r2;
4209 /* allocate second register */
4210 rc2 = RC_INT;
4211 if (rc == RC_IRET)
4212 rc2 = RC_LRET;
4213 r2 = get_reg(rc2);
4214 load(r2, vtop);
4215 vpop();
4216 /* write second register */
4217 vtop->r2 = r2;
4218 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
4219 int t1, t;
4220 /* lvalue of scalar type : need to use lvalue type
4221 because of possible cast */
4222 t = vtop->type.t;
4223 t1 = t;
4224 /* compute memory access type */
4225 if (vtop->r & VT_LVAL_BYTE)
4226 t = VT_BYTE;
4227 else if (vtop->r & VT_LVAL_SHORT)
4228 t = VT_SHORT;
4229 if (vtop->r & VT_LVAL_UNSIGNED)
4230 t |= VT_UNSIGNED;
4231 vtop->type.t = t;
4232 load(r, vtop);
4233 /* restore wanted type */
4234 vtop->type.t = t1;
4235 } else {
4236 /* one register type load */
4237 load(r, vtop);
4240 vtop->r = r;
4242 return r;
4245 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4246 void gv2(int rc1, int rc2)
4248 int v;
4250 /* generate more generic register first. But VT_JMP or VT_CMP
4251 values must be generated first in all cases to avoid possible
4252 reload errors */
4253 v = vtop[0].r & VT_VALMASK;
4254 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
4255 vswap();
4256 gv(rc1);
4257 vswap();
4258 gv(rc2);
4259 /* test if reload is needed for first register */
4260 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
4261 vswap();
4262 gv(rc1);
4263 vswap();
4265 } else {
4266 gv(rc2);
4267 vswap();
4268 gv(rc1);
4269 vswap();
4270 /* test if reload is needed for first register */
4271 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
4272 gv(rc2);
4277 /* expand long long on stack in two int registers */
4278 void lexpand(void)
4280 int u;
4282 u = vtop->type.t & VT_UNSIGNED;
4283 gv(RC_INT);
4284 vdup();
4285 vtop[0].r = vtop[-1].r2;
4286 vtop[0].r2 = VT_CONST;
4287 vtop[-1].r2 = VT_CONST;
4288 vtop[0].type.t = VT_INT | u;
4289 vtop[-1].type.t = VT_INT | u;
4292 /* build a long long from two ints */
4293 void lbuild(int t)
4295 gv2(RC_INT, RC_INT);
4296 vtop[-1].r2 = vtop[0].r;
4297 vtop[-1].type.t = t;
4298 vpop();
4301 /* rotate n first stack elements to the bottom */
4302 void vrotb(int n)
4304 int i;
4305 SValue tmp;
4307 tmp = vtop[-n + 1];
4308 for(i=-n+1;i!=0;i++)
4309 vtop[i] = vtop[i+1];
4310 vtop[0] = tmp;
4313 /* pop stack value */
4314 void vpop(void)
4316 int v;
4317 v = vtop->r & VT_VALMASK;
4318 #ifdef TCC_TARGET_I386
4319 /* for x86, we need to pop the FP stack */
4320 if (v == TREG_ST0 && !nocode_wanted) {
4321 o(0xd9dd); /* fstp %st(1) */
4322 } else
4323 #endif
4324 if (v == VT_JMP || v == VT_JMPI) {
4325 /* need to put correct jump if && or || without test */
4326 gsym(vtop->c.ul);
4328 vtop--;
4331 /* convert stack entry to register and duplicate its value in another
4332 register */
4333 void gv_dup(void)
4335 int rc, t, r, r1;
4336 SValue sv;
4338 t = vtop->type.t;
4339 if ((t & VT_BTYPE) == VT_LLONG) {
4340 lexpand();
4341 gv_dup();
4342 vswap();
4343 vrotb(3);
4344 gv_dup();
4345 vrotb(4);
4346 /* stack: H L L1 H1 */
4347 lbuild(t);
4348 vrotb(3);
4349 vrotb(3);
4350 vswap();
4351 lbuild(t);
4352 vswap();
4353 } else {
4354 /* duplicate value */
4355 rc = RC_INT;
4356 sv.type.t = VT_INT;
4357 if (is_float(t)) {
4358 rc = RC_FLOAT;
4359 sv.type.t = t;
4361 r = gv(rc);
4362 r1 = get_reg(rc);
4363 sv.r = r;
4364 sv.c.ul = 0;
4365 load(r1, &sv); /* move r to r1 */
4366 vdup();
4367 /* duplicates value */
4368 vtop->r = r1;
4372 /* generate CPU independent (unsigned) long long operations */
4373 void gen_opl(int op)
4375 int t, a, b, op1, c, i;
4376 int func;
4377 GFuncContext gf;
4378 SValue tmp;
4380 switch(op) {
4381 case '/':
4382 case TOK_PDIV:
4383 func = TOK___divdi3;
4384 goto gen_func;
4385 case TOK_UDIV:
4386 func = TOK___udivdi3;
4387 goto gen_func;
4388 case '%':
4389 func = TOK___moddi3;
4390 goto gen_func;
4391 case TOK_UMOD:
4392 func = TOK___umoddi3;
4393 gen_func:
4394 /* call generic long long function */
4395 gfunc_start(&gf, FUNC_CDECL);
4396 gfunc_param(&gf);
4397 gfunc_param(&gf);
4398 vpush_global_sym(&func_old_type, func);
4399 gfunc_call(&gf);
4400 vpushi(0);
4401 vtop->r = REG_IRET;
4402 vtop->r2 = REG_LRET;
4403 break;
4404 case '^':
4405 case '&':
4406 case '|':
4407 case '*':
4408 case '+':
4409 case '-':
4410 t = vtop->type.t;
4411 vswap();
4412 lexpand();
4413 vrotb(3);
4414 lexpand();
4415 /* stack: L1 H1 L2 H2 */
4416 tmp = vtop[0];
4417 vtop[0] = vtop[-3];
4418 vtop[-3] = tmp;
4419 tmp = vtop[-2];
4420 vtop[-2] = vtop[-3];
4421 vtop[-3] = tmp;
4422 vswap();
4423 /* stack: H1 H2 L1 L2 */
4424 if (op == '*') {
4425 vpushv(vtop - 1);
4426 vpushv(vtop - 1);
4427 gen_op(TOK_UMULL);
4428 lexpand();
4429 /* stack: H1 H2 L1 L2 ML MH */
4430 for(i=0;i<4;i++)
4431 vrotb(6);
4432 /* stack: ML MH H1 H2 L1 L2 */
4433 tmp = vtop[0];
4434 vtop[0] = vtop[-2];
4435 vtop[-2] = tmp;
4436 /* stack: ML MH H1 L2 H2 L1 */
4437 gen_op('*');
4438 vrotb(3);
4439 vrotb(3);
4440 gen_op('*');
4441 /* stack: ML MH M1 M2 */
4442 gen_op('+');
4443 gen_op('+');
4444 } else if (op == '+' || op == '-') {
4445 /* XXX: add non carry method too (for MIPS or alpha) */
4446 if (op == '+')
4447 op1 = TOK_ADDC1;
4448 else
4449 op1 = TOK_SUBC1;
4450 gen_op(op1);
4451 /* stack: H1 H2 (L1 op L2) */
4452 vrotb(3);
4453 vrotb(3);
4454 gen_op(op1 + 1); /* TOK_xxxC2 */
4455 } else {
4456 gen_op(op);
4457 /* stack: H1 H2 (L1 op L2) */
4458 vrotb(3);
4459 vrotb(3);
4460 /* stack: (L1 op L2) H1 H2 */
4461 gen_op(op);
4462 /* stack: (L1 op L2) (H1 op H2) */
4464 /* stack: L H */
4465 lbuild(t);
4466 break;
4467 case TOK_SAR:
4468 case TOK_SHR:
4469 case TOK_SHL:
4470 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4471 t = vtop[-1].type.t;
4472 vswap();
4473 lexpand();
4474 vrotb(3);
4475 /* stack: L H shift */
4476 c = (int)vtop->c.i;
4477 /* constant: simpler */
4478 /* NOTE: all comments are for SHL. the other cases are
4479 done by swaping words */
4480 vpop();
4481 if (op != TOK_SHL)
4482 vswap();
4483 if (c >= 32) {
4484 /* stack: L H */
4485 vpop();
4486 if (c > 32) {
4487 vpushi(c - 32);
4488 gen_op(op);
4490 if (op != TOK_SAR) {
4491 vpushi(0);
4492 } else {
4493 gv_dup();
4494 vpushi(31);
4495 gen_op(TOK_SAR);
4497 vswap();
4498 } else {
4499 vswap();
4500 gv_dup();
4501 /* stack: H L L */
4502 vpushi(c);
4503 gen_op(op);
4504 vswap();
4505 vpushi(32 - c);
4506 if (op == TOK_SHL)
4507 gen_op(TOK_SHR);
4508 else
4509 gen_op(TOK_SHL);
4510 vrotb(3);
4511 /* stack: L L H */
4512 vpushi(c);
4513 if (op == TOK_SHL)
4514 gen_op(TOK_SHL);
4515 else
4516 gen_op(TOK_SHR);
4517 gen_op('|');
4519 if (op != TOK_SHL)
4520 vswap();
4521 lbuild(t);
4522 } else {
4523 /* XXX: should provide a faster fallback on x86 ? */
4524 switch(op) {
4525 case TOK_SAR:
4526 func = TOK___sardi3;
4527 goto gen_func;
4528 case TOK_SHR:
4529 func = TOK___shrdi3;
4530 goto gen_func;
4531 case TOK_SHL:
4532 func = TOK___shldi3;
4533 goto gen_func;
4536 break;
4537 default:
4538 /* compare operations */
4539 t = vtop->type.t;
4540 vswap();
4541 lexpand();
4542 vrotb(3);
4543 lexpand();
4544 /* stack: L1 H1 L2 H2 */
4545 tmp = vtop[-1];
4546 vtop[-1] = vtop[-2];
4547 vtop[-2] = tmp;
4548 /* stack: L1 L2 H1 H2 */
4549 /* compare high */
4550 op1 = op;
4551 /* when values are equal, we need to compare low words. since
4552 the jump is inverted, we invert the test too. */
4553 if (op1 == TOK_LT)
4554 op1 = TOK_LE;
4555 else if (op1 == TOK_GT)
4556 op1 = TOK_GE;
4557 else if (op1 == TOK_ULT)
4558 op1 = TOK_ULE;
4559 else if (op1 == TOK_UGT)
4560 op1 = TOK_UGE;
4561 a = 0;
4562 b = 0;
4563 gen_op(op1);
4564 if (op1 != TOK_NE) {
4565 a = gtst(1, 0);
4567 if (op != TOK_EQ) {
4568 /* generate non equal test */
4569 /* XXX: NOT PORTABLE yet */
4570 if (a == 0) {
4571 b = gtst(0, 0);
4572 } else {
4573 #ifdef TCC_TARGET_I386
4574 b = psym(0x850f, 0);
4575 #else
4576 error("not implemented");
4577 #endif
4580 /* compare low. Always unsigned */
4581 op1 = op;
4582 if (op1 == TOK_LT)
4583 op1 = TOK_ULT;
4584 else if (op1 == TOK_LE)
4585 op1 = TOK_ULE;
4586 else if (op1 == TOK_GT)
4587 op1 = TOK_UGT;
4588 else if (op1 == TOK_GE)
4589 op1 = TOK_UGE;
4590 gen_op(op1);
4591 a = gtst(1, a);
4592 gsym(b);
4593 vseti(VT_JMPI, a);
4594 break;
4598 /* handle integer constant optimizations and various machine
4599 independant opt */
4600 void gen_opic(int op)
4602 int fc, c1, c2, n;
4603 SValue *v1, *v2;
4605 v1 = vtop - 1;
4606 v2 = vtop;
4607 /* currently, we cannot do computations with forward symbols */
4608 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4609 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4610 if (c1 && c2) {
4611 fc = v2->c.i;
4612 switch(op) {
4613 case '+': v1->c.i += fc; break;
4614 case '-': v1->c.i -= fc; break;
4615 case '&': v1->c.i &= fc; break;
4616 case '^': v1->c.i ^= fc; break;
4617 case '|': v1->c.i |= fc; break;
4618 case '*': v1->c.i *= fc; break;
4620 case TOK_PDIV:
4621 case '/':
4622 case '%':
4623 case TOK_UDIV:
4624 case TOK_UMOD:
4625 /* if division by zero, generate explicit division */
4626 if (fc == 0) {
4627 if (const_wanted)
4628 error("division by zero in constant");
4629 goto general_case;
4631 switch(op) {
4632 default: v1->c.i /= fc; break;
4633 case '%': v1->c.i %= fc; break;
4634 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
4635 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
4637 break;
4638 case TOK_SHL: v1->c.i <<= fc; break;
4639 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
4640 case TOK_SAR: v1->c.i >>= fc; break;
4641 /* tests */
4642 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
4643 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
4644 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
4645 case TOK_NE: v1->c.i = v1->c.i != fc; break;
4646 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
4647 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
4648 case TOK_LT: v1->c.i = v1->c.i < fc; break;
4649 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
4650 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
4651 case TOK_GT: v1->c.i = v1->c.i > fc; break;
4652 /* logical */
4653 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
4654 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
4655 default:
4656 goto general_case;
4658 vtop--;
4659 } else {
4660 /* if commutative ops, put c2 as constant */
4661 if (c1 && (op == '+' || op == '&' || op == '^' ||
4662 op == '|' || op == '*')) {
4663 vswap();
4664 swap(&c1, &c2);
4666 fc = vtop->c.i;
4667 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
4668 op == TOK_PDIV) &&
4669 fc == 1) ||
4670 ((op == '+' || op == '-' || op == '|' || op == '^' ||
4671 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
4672 fc == 0) ||
4673 (op == '&' &&
4674 fc == -1))) {
4675 /* nothing to do */
4676 vtop--;
4677 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
4678 /* try to use shifts instead of muls or divs */
4679 if (fc > 0 && (fc & (fc - 1)) == 0) {
4680 n = -1;
4681 while (fc) {
4682 fc >>= 1;
4683 n++;
4685 vtop->c.i = n;
4686 if (op == '*')
4687 op = TOK_SHL;
4688 else if (op == TOK_PDIV)
4689 op = TOK_SAR;
4690 else
4691 op = TOK_SHR;
4693 goto general_case;
4694 } else if (c2 && (op == '+' || op == '-') &&
4695 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
4696 (VT_CONST | VT_SYM)) {
4697 /* symbol + constant case */
4698 if (op == '-')
4699 fc = -fc;
4700 vtop--;
4701 vtop->c.i += fc;
4702 } else {
4703 general_case:
4704 if (!nocode_wanted) {
4705 /* call low level op generator */
4706 gen_opi(op);
4707 } else {
4708 vtop--;
4714 /* generate a floating point operation with constant propagation */
4715 void gen_opif(int op)
4717 int c1, c2;
4718 SValue *v1, *v2;
4719 long double f1, f2;
4721 v1 = vtop - 1;
4722 v2 = vtop;
4723 /* currently, we cannot do computations with forward symbols */
4724 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4725 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4726 if (c1 && c2) {
4727 if (v1->type.t == VT_FLOAT) {
4728 f1 = v1->c.f;
4729 f2 = v2->c.f;
4730 } else if (v1->type.t == VT_DOUBLE) {
4731 f1 = v1->c.d;
4732 f2 = v2->c.d;
4733 } else {
4734 f1 = v1->c.ld;
4735 f2 = v2->c.ld;
4738 /* NOTE: we only do constant propagation if finite number (not
4739 NaN or infinity) (ANSI spec) */
4740 if (!ieee_finite(f1) || !ieee_finite(f2))
4741 goto general_case;
4743 switch(op) {
4744 case '+': f1 += f2; break;
4745 case '-': f1 -= f2; break;
4746 case '*': f1 *= f2; break;
4747 case '/':
4748 if (f2 == 0.0) {
4749 if (const_wanted)
4750 error("division by zero in constant");
4751 goto general_case;
4753 f1 /= f2;
4754 break;
4755 /* XXX: also handles tests ? */
4756 default:
4757 goto general_case;
4759 /* XXX: overflow test ? */
4760 if (v1->type.t == VT_FLOAT) {
4761 v1->c.f = f1;
4762 } else if (v1->type.t == VT_DOUBLE) {
4763 v1->c.d = f1;
4764 } else {
4765 v1->c.ld = f1;
4767 vtop--;
4768 } else {
4769 general_case:
4770 if (!nocode_wanted) {
4771 gen_opf(op);
4772 } else {
4773 vtop--;
4778 static int pointed_size(CType *type)
4780 int align;
4781 return type_size(pointed_type(type), &align);
4784 #if 0
4785 void check_pointer_types(SValue *p1, SValue *p2)
4787 char buf1[256], buf2[256];
4788 int t1, t2;
4789 t1 = p1->t;
4790 t2 = p2->t;
4791 if (!is_compatible_types(t1, t2)) {
4792 type_to_str(buf1, sizeof(buf1), t1, NULL);
4793 type_to_str(buf2, sizeof(buf2), t2, NULL);
4794 error("incompatible pointers '%s' and '%s'", buf1, buf2);
4797 #endif
4799 /* generic gen_op: handles types problems */
4800 void gen_op(int op)
4802 int u, t1, t2, bt1, bt2, t;
4803 CType type1;
4805 t1 = vtop[-1].type.t;
4806 t2 = vtop[0].type.t;
4807 bt1 = t1 & VT_BTYPE;
4808 bt2 = t2 & VT_BTYPE;
4810 if (bt1 == VT_PTR || bt2 == VT_PTR) {
4811 /* at least one operand is a pointer */
4812 /* relationnal op: must be both pointers */
4813 if (op >= TOK_ULT && op <= TOK_GT) {
4814 // check_pointer_types(vtop, vtop - 1);
4815 /* pointers are handled are unsigned */
4816 t = VT_INT | VT_UNSIGNED;
4817 goto std_op;
4819 /* if both pointers, then it must be the '-' op */
4820 if (bt1 == VT_PTR && bt2 == VT_PTR) {
4821 if (op != '-')
4822 error("cannot use pointers here");
4823 // check_pointer_types(vtop - 1, vtop);
4824 /* XXX: check that types are compatible */
4825 u = pointed_size(&vtop[-1].type);
4826 gen_opic(op);
4827 /* set to integer type */
4828 vtop->type.t = VT_INT;
4829 vpushi(u);
4830 gen_op(TOK_PDIV);
4831 } else {
4832 /* exactly one pointer : must be '+' or '-'. */
4833 if (op != '-' && op != '+')
4834 error("cannot use pointers here");
4835 /* Put pointer as first operand */
4836 if (bt2 == VT_PTR) {
4837 vswap();
4838 swap(&t1, &t2);
4840 type1 = vtop[-1].type;
4841 /* XXX: cast to int ? (long long case) */
4842 vpushi(pointed_size(&vtop[-1].type));
4843 gen_op('*');
4844 #ifdef CONFIG_TCC_BCHECK
4845 /* if evaluating constant expression, no code should be
4846 generated, so no bound check */
4847 if (do_bounds_check && !const_wanted) {
4848 /* if bounded pointers, we generate a special code to
4849 test bounds */
4850 if (op == '-') {
4851 vpushi(0);
4852 vswap();
4853 gen_op('-');
4855 gen_bounded_ptr_add();
4856 } else
4857 #endif
4859 gen_opic(op);
4861 /* put again type if gen_opic() swaped operands */
4862 vtop->type = type1;
4864 } else if (is_float(bt1) || is_float(bt2)) {
4865 /* compute bigger type and do implicit casts */
4866 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4867 t = VT_LDOUBLE;
4868 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4869 t = VT_DOUBLE;
4870 } else {
4871 t = VT_FLOAT;
4873 /* floats can only be used for a few operations */
4874 if (op != '+' && op != '-' && op != '*' && op != '/' &&
4875 (op < TOK_ULT || op > TOK_GT))
4876 error("invalid operands for binary operation");
4877 goto std_op;
4878 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4879 /* cast to biggest op */
4880 t = VT_LLONG;
4881 /* convert to unsigned if it does not fit in a long long */
4882 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4883 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4884 t |= VT_UNSIGNED;
4885 goto std_op;
4886 } else {
4887 /* integer operations */
4888 t = VT_INT;
4889 /* convert to unsigned if it does not fit in an integer */
4890 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4891 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4892 t |= VT_UNSIGNED;
4893 std_op:
4894 /* XXX: currently, some unsigned operations are explicit, so
4895 we modify them here */
4896 if (t & VT_UNSIGNED) {
4897 if (op == TOK_SAR)
4898 op = TOK_SHR;
4899 else if (op == '/')
4900 op = TOK_UDIV;
4901 else if (op == '%')
4902 op = TOK_UMOD;
4903 else if (op == TOK_LT)
4904 op = TOK_ULT;
4905 else if (op == TOK_GT)
4906 op = TOK_UGT;
4907 else if (op == TOK_LE)
4908 op = TOK_ULE;
4909 else if (op == TOK_GE)
4910 op = TOK_UGE;
4912 vswap();
4913 type1.t = t;
4914 gen_cast(&type1);
4915 vswap();
4916 /* special case for shifts and long long: we keep the shift as
4917 an integer */
4918 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
4919 type1.t = VT_INT;
4920 gen_cast(&type1);
4921 if (is_float(t))
4922 gen_opif(op);
4923 else if ((t & VT_BTYPE) == VT_LLONG)
4924 gen_opl(op);
4925 else
4926 gen_opic(op);
4927 if (op >= TOK_ULT && op <= TOK_GT) {
4928 /* relationnal op: the result is an int */
4929 vtop->type.t = VT_INT;
4930 } else {
4931 vtop->type.t = t;
4936 /* generic itof for unsigned long long case */
4937 void gen_cvt_itof1(int t)
4939 GFuncContext gf;
4941 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
4942 (VT_LLONG | VT_UNSIGNED)) {
4944 gfunc_start(&gf, FUNC_CDECL);
4945 gfunc_param(&gf);
4946 if (t == VT_FLOAT)
4947 vpush_global_sym(&func_old_type, TOK___ulltof);
4948 else if (t == VT_DOUBLE)
4949 vpush_global_sym(&func_old_type, TOK___ulltod);
4950 else
4951 vpush_global_sym(&func_old_type, TOK___ulltold);
4952 gfunc_call(&gf);
4953 vpushi(0);
4954 vtop->r = REG_FRET;
4955 } else {
4956 gen_cvt_itof(t);
4960 /* generic ftoi for unsigned long long case */
4961 void gen_cvt_ftoi1(int t)
4963 GFuncContext gf;
4964 int st;
4966 if (t == (VT_LLONG | VT_UNSIGNED)) {
4967 /* not handled natively */
4968 gfunc_start(&gf, FUNC_CDECL);
4969 st = vtop->type.t & VT_BTYPE;
4970 gfunc_param(&gf);
4971 if (st == VT_FLOAT)
4972 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
4973 else if (st == VT_DOUBLE)
4974 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
4975 else
4976 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
4977 gfunc_call(&gf);
4978 vpushi(0);
4979 vtop->r = REG_IRET;
4980 vtop->r2 = REG_LRET;
4981 } else {
4982 gen_cvt_ftoi(t);
4986 /* force char or short cast */
4987 void force_charshort_cast(int t)
4989 int bits, dbt;
4990 dbt = t & VT_BTYPE;
4991 /* XXX: add optimization if lvalue : just change type and offset */
4992 if (dbt == VT_BYTE)
4993 bits = 8;
4994 else
4995 bits = 16;
4996 if (t & VT_UNSIGNED) {
4997 vpushi((1 << bits) - 1);
4998 gen_op('&');
4999 } else {
5000 bits = 32 - bits;
5001 vpushi(bits);
5002 gen_op(TOK_SHL);
5003 vpushi(bits);
5004 gen_op(TOK_SAR);
5008 /* cast 'vtop' to 'type' */
5009 static void gen_cast(CType *type)
5011 int sbt, dbt, sf, df, c;
5013 /* special delayed cast for char/short */
5014 /* XXX: in some cases (multiple cascaded casts), it may still
5015 be incorrect */
5016 if (vtop->r & VT_MUSTCAST) {
5017 vtop->r &= ~VT_MUSTCAST;
5018 force_charshort_cast(vtop->type.t);
5021 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
5022 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
5024 if (sbt != dbt && !nocode_wanted) {
5025 sf = is_float(sbt);
5026 df = is_float(dbt);
5027 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5028 if (sf && df) {
5029 /* convert from fp to fp */
5030 if (c) {
5031 /* constant case: we can do it now */
5032 /* XXX: in ISOC, cannot do it if error in convert */
5033 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
5034 vtop->c.f = (float)vtop->c.d;
5035 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
5036 vtop->c.f = (float)vtop->c.ld;
5037 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
5038 vtop->c.d = (double)vtop->c.f;
5039 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
5040 vtop->c.d = (double)vtop->c.ld;
5041 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
5042 vtop->c.ld = (long double)vtop->c.f;
5043 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
5044 vtop->c.ld = (long double)vtop->c.d;
5045 } else {
5046 /* non constant case: generate code */
5047 gen_cvt_ftof(dbt);
5049 } else if (df) {
5050 /* convert int to fp */
5051 if (c) {
5052 switch(sbt) {
5053 case VT_LLONG | VT_UNSIGNED:
5054 case VT_LLONG:
5055 /* XXX: add const cases for long long */
5056 goto do_itof;
5057 case VT_INT | VT_UNSIGNED:
5058 switch(dbt) {
5059 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
5060 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
5061 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
5063 break;
5064 default:
5065 switch(dbt) {
5066 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
5067 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
5068 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
5070 break;
5072 } else {
5073 do_itof:
5074 gen_cvt_itof1(dbt);
5076 } else if (sf) {
5077 /* convert fp to int */
5078 /* we handle char/short/etc... with generic code */
5079 if (dbt != (VT_INT | VT_UNSIGNED) &&
5080 dbt != (VT_LLONG | VT_UNSIGNED) &&
5081 dbt != VT_LLONG)
5082 dbt = VT_INT;
5083 if (c) {
5084 switch(dbt) {
5085 case VT_LLONG | VT_UNSIGNED:
5086 case VT_LLONG:
5087 /* XXX: add const cases for long long */
5088 goto do_ftoi;
5089 case VT_INT | VT_UNSIGNED:
5090 switch(sbt) {
5091 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
5092 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5093 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5095 break;
5096 default:
5097 /* int case */
5098 switch(sbt) {
5099 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
5100 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
5101 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
5103 break;
5105 } else {
5106 do_ftoi:
5107 gen_cvt_ftoi1(dbt);
5109 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
5110 /* additionnal cast for char/short/bool... */
5111 vtop->type.t = dbt;
5112 gen_cast(type);
5114 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
5115 if ((sbt & VT_BTYPE) != VT_LLONG) {
5116 /* scalar to long long */
5117 if (c) {
5118 if (sbt == (VT_INT | VT_UNSIGNED))
5119 vtop->c.ll = vtop->c.ui;
5120 else
5121 vtop->c.ll = vtop->c.i;
5122 } else {
5123 /* machine independant conversion */
5124 gv(RC_INT);
5125 /* generate high word */
5126 if (sbt == (VT_INT | VT_UNSIGNED)) {
5127 vpushi(0);
5128 gv(RC_INT);
5129 } else {
5130 gv_dup();
5131 vpushi(31);
5132 gen_op(TOK_SAR);
5134 /* patch second register */
5135 vtop[-1].r2 = vtop->r;
5136 vpop();
5139 } else if (dbt == VT_BOOL) {
5140 /* scalar to bool */
5141 vpushi(0);
5142 gen_op(TOK_NE);
5143 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
5144 (dbt & VT_BTYPE) == VT_SHORT) {
5145 force_charshort_cast(dbt);
5146 } else if ((dbt & VT_BTYPE) == VT_INT) {
5147 /* scalar to int */
5148 if (sbt == VT_LLONG) {
5149 /* from long long: just take low order word */
5150 lexpand();
5151 vpop();
5153 /* if lvalue and single word type, nothing to do because
5154 the lvalue already contains the real type size (see
5155 VT_LVAL_xxx constants) */
5158 vtop->type = *type;
5161 /* return type size. Put alignment at 'a' */
5162 static int type_size(CType *type, int *a)
5164 Sym *s;
5165 int bt;
5167 bt = type->t & VT_BTYPE;
5168 if (bt == VT_STRUCT) {
5169 /* struct/union */
5170 s = type->ref;
5171 *a = s->r;
5172 return s->c;
5173 } else if (bt == VT_PTR) {
5174 if (type->t & VT_ARRAY) {
5175 s = type->ref;
5176 return type_size(&s->type, a) * s->c;
5177 } else {
5178 *a = PTR_SIZE;
5179 return PTR_SIZE;
5181 } else if (bt == VT_LDOUBLE) {
5182 *a = LDOUBLE_ALIGN;
5183 return LDOUBLE_SIZE;
5184 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
5185 *a = 4; /* XXX: i386 specific */
5186 return 8;
5187 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
5188 *a = 4;
5189 return 4;
5190 } else if (bt == VT_SHORT) {
5191 *a = 2;
5192 return 2;
5193 } else {
5194 /* char, void, function, _Bool */
5195 *a = 1;
5196 return 1;
5200 /* return the pointed type of t */
5201 static inline CType *pointed_type(CType *type)
5203 return &type->ref->type;
5206 /* modify type so that its it is a pointer to type. */
5207 static void mk_pointer(CType *type)
5209 Sym *s;
5210 s = sym_push(SYM_FIELD, type, 0, -1);
5211 type->t = VT_PTR | (type->t & ~VT_TYPE);
5212 type->ref = s;
5215 static int is_compatible_types(CType *type1, CType *type2)
5217 Sym *s1, *s2;
5218 int bt1, bt2, t1, t2;
5220 t1 = type1->t & VT_TYPE;
5221 t2 = type2->t & VT_TYPE;
5222 bt1 = t1 & VT_BTYPE;
5223 bt2 = t2 & VT_BTYPE;
5224 if (bt1 == VT_PTR) {
5225 type1 = pointed_type(type1);
5226 /* if function, then convert implicitely to function pointer */
5227 if (bt2 != VT_FUNC) {
5228 if (bt2 != VT_PTR)
5229 return 0;
5230 type2 = pointed_type(type2);
5232 /* void matches everything */
5233 /* XXX: not fully compliant */
5234 if ((type1->t & VT_TYPE) == VT_VOID || (type2->t & VT_TYPE) == VT_VOID)
5235 return 1;
5236 return is_compatible_types(type1, type2);
5237 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5238 return (type1->ref == type2->ref);
5239 } else if (bt1 == VT_FUNC) {
5240 if (bt2 != VT_FUNC)
5241 return 0;
5242 s1 = type1->ref;
5243 s2 = type2->ref;
5244 if (!is_compatible_types(&s1->type, &s2->type))
5245 return 0;
5246 /* XXX: not complete */
5247 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
5248 return 1;
5249 if (s1->c != s2->c)
5250 return 0;
5251 while (s1 != NULL) {
5252 if (s2 == NULL)
5253 return 0;
5254 if (!is_compatible_types(&s1->type, &s2->type))
5255 return 0;
5256 s1 = s1->next;
5257 s2 = s2->next;
5259 if (s2)
5260 return 0;
5261 return 1;
5262 } else {
5263 /* XXX: not complete */
5264 return 1;
5268 /* print a type. If 'varstr' is not NULL, then the variable is also
5269 printed in the type */
5270 /* XXX: union */
5271 /* XXX: add array and function pointers */
5272 void type_to_str(char *buf, int buf_size,
5273 CType *type, const char *varstr)
5275 int bt, v, t;
5276 Sym *s, *sa;
5277 char buf1[256];
5278 const char *tstr;
5280 t = type->t & VT_TYPE;
5281 bt = t & VT_BTYPE;
5282 buf[0] = '\0';
5283 if (t & VT_UNSIGNED)
5284 pstrcat(buf, buf_size, "unsigned ");
5285 switch(bt) {
5286 case VT_VOID:
5287 tstr = "void";
5288 goto add_tstr;
5289 case VT_BOOL:
5290 tstr = "_Bool";
5291 goto add_tstr;
5292 case VT_BYTE:
5293 tstr = "char";
5294 goto add_tstr;
5295 case VT_SHORT:
5296 tstr = "short";
5297 goto add_tstr;
5298 case VT_INT:
5299 tstr = "int";
5300 goto add_tstr;
5301 case VT_LONG:
5302 tstr = "long";
5303 goto add_tstr;
5304 case VT_LLONG:
5305 tstr = "long long";
5306 goto add_tstr;
5307 case VT_FLOAT:
5308 tstr = "float";
5309 goto add_tstr;
5310 case VT_DOUBLE:
5311 tstr = "double";
5312 goto add_tstr;
5313 case VT_LDOUBLE:
5314 tstr = "long double";
5315 add_tstr:
5316 pstrcat(buf, buf_size, tstr);
5317 break;
5318 case VT_ENUM:
5319 case VT_STRUCT:
5320 if (bt == VT_STRUCT)
5321 tstr = "struct ";
5322 else
5323 tstr = "enum ";
5324 pstrcat(buf, buf_size, tstr);
5325 v = type->ref->v & ~SYM_STRUCT;
5326 if (v >= SYM_FIRST_ANOM)
5327 pstrcat(buf, buf_size, "<anonymous>");
5328 else
5329 pstrcat(buf, buf_size, get_tok_str(v, NULL));
5330 break;
5331 case VT_FUNC:
5332 s = type->ref;
5333 type_to_str(buf, buf_size, &s->type, varstr);
5334 pstrcat(buf, buf_size, "(");
5335 sa = s->next;
5336 while (sa != NULL) {
5337 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
5338 pstrcat(buf, buf_size, buf1);
5339 sa = sa->next;
5340 if (sa)
5341 pstrcat(buf, buf_size, ", ");
5343 pstrcat(buf, buf_size, ")");
5344 goto no_var;
5345 case VT_PTR:
5346 s = type->ref;
5347 pstrcpy(buf1, sizeof(buf1), "*");
5348 if (varstr)
5349 pstrcat(buf1, sizeof(buf1), varstr);
5350 type_to_str(buf, buf_size, &s->type, buf1);
5351 goto no_var;
5353 if (varstr) {
5354 pstrcat(buf, buf_size, " ");
5355 pstrcat(buf, buf_size, varstr);
5357 no_var: ;
5360 /* verify type compatibility to store vtop in 'dt' type, and generate
5361 casts if needed. */
5362 static void gen_assign_cast(CType *dt)
5364 CType *st;
5365 char buf1[256], buf2[256];
5366 int dbt, sbt;
5368 st = &vtop->type; /* source type */
5369 dbt = dt->t & VT_BTYPE;
5370 sbt = st->t & VT_BTYPE;
5371 if (dbt == VT_PTR) {
5372 /* special cases for pointers */
5373 /* a function is implicitely a function pointer */
5374 if (sbt == VT_FUNC) {
5375 if (!is_compatible_types(pointed_type(dt), st))
5376 goto error;
5377 else
5378 goto type_ok;
5380 /* '0' can also be a pointer */
5381 if (sbt == VT_INT &&
5382 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
5383 vtop->c.i == 0)
5384 goto type_ok;
5385 /* accept implicit pointer to integer cast with warning */
5386 if (sbt == VT_BYTE || sbt == VT_SHORT ||
5387 sbt == VT_INT || sbt == VT_LLONG) {
5388 warning("assignment makes pointer from integer without a cast");
5389 goto type_ok;
5391 } else if (dbt == VT_BYTE || dbt == VT_SHORT ||
5392 dbt == VT_INT || dbt == VT_LLONG) {
5393 if (sbt == VT_PTR || sbt == VT_FUNC) {
5394 warning("assignment makes integer from pointer without a cast");
5395 goto type_ok;
5398 if (!is_compatible_types(dt, st)) {
5399 error:
5400 type_to_str(buf1, sizeof(buf1), st, NULL);
5401 type_to_str(buf2, sizeof(buf2), dt, NULL);
5402 error("cannot cast '%s' to '%s'", buf1, buf2);
5404 type_ok:
5405 gen_cast(dt);
5408 /* store vtop in lvalue pushed on stack */
5409 void vstore(void)
5411 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
5412 GFuncContext gf;
5414 ft = vtop[-1].type.t;
5415 sbt = vtop->type.t & VT_BTYPE;
5416 dbt = ft & VT_BTYPE;
5417 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
5418 (sbt == VT_INT && dbt == VT_SHORT)) {
5419 /* optimize char/short casts */
5420 delayed_cast = VT_MUSTCAST;
5421 vtop->type.t = ft & VT_TYPE;
5422 } else {
5423 delayed_cast = 0;
5424 gen_assign_cast(&vtop[-1].type);
5427 if (sbt == VT_STRUCT) {
5428 /* if structure, only generate pointer */
5429 /* structure assignment : generate memcpy */
5430 /* XXX: optimize if small size */
5431 if (!nocode_wanted) {
5432 vdup();
5433 gfunc_start(&gf, FUNC_CDECL);
5434 /* type size */
5435 size = type_size(&vtop->type, &align);
5436 vpushi(size);
5437 gfunc_param(&gf);
5438 /* source */
5439 vtop->type.t = VT_INT;
5440 gaddrof();
5441 gfunc_param(&gf);
5442 /* destination */
5443 vswap();
5444 vtop->type.t = VT_INT;
5445 gaddrof();
5446 gfunc_param(&gf);
5448 save_regs(0);
5449 vpush_global_sym(&func_old_type, TOK_memcpy);
5450 gfunc_call(&gf);
5451 } else {
5452 vswap();
5453 vpop();
5455 /* leave source on stack */
5456 } else if (ft & VT_BITFIELD) {
5457 /* bitfield store handling */
5458 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
5459 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5460 /* remove bit field info to avoid loops */
5461 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
5463 /* duplicate destination */
5464 vdup();
5465 vtop[-1] = vtop[-2];
5467 /* mask and shift source */
5468 vpushi((1 << bit_size) - 1);
5469 gen_op('&');
5470 vpushi(bit_pos);
5471 gen_op(TOK_SHL);
5472 /* load destination, mask and or with source */
5473 vswap();
5474 vpushi(~(((1 << bit_size) - 1) << bit_pos));
5475 gen_op('&');
5476 gen_op('|');
5477 /* store result */
5478 vstore();
5479 } else {
5480 #ifdef CONFIG_TCC_BCHECK
5481 /* bound check case */
5482 if (vtop[-1].r & VT_MUSTBOUND) {
5483 vswap();
5484 gbound();
5485 vswap();
5487 #endif
5488 if (!nocode_wanted) {
5489 rc = RC_INT;
5490 if (is_float(ft))
5491 rc = RC_FLOAT;
5492 r = gv(rc); /* generate value */
5493 /* if lvalue was saved on stack, must read it */
5494 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
5495 SValue sv;
5496 t = get_reg(RC_INT);
5497 sv.type.t = VT_INT;
5498 sv.r = VT_LOCAL | VT_LVAL;
5499 sv.c.ul = vtop[-1].c.ul;
5500 load(t, &sv);
5501 vtop[-1].r = t | VT_LVAL;
5503 store(r, vtop - 1);
5504 /* two word case handling : store second register at word + 4 */
5505 if ((ft & VT_BTYPE) == VT_LLONG) {
5506 vswap();
5507 /* convert to int to increment easily */
5508 vtop->type.t = VT_INT;
5509 gaddrof();
5510 vpushi(4);
5511 gen_op('+');
5512 vtop->r |= VT_LVAL;
5513 vswap();
5514 /* XXX: it works because r2 is spilled last ! */
5515 store(vtop->r2, vtop - 1);
5518 vswap();
5519 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5520 vtop->r |= delayed_cast;
5524 /* post defines POST/PRE add. c is the token ++ or -- */
5525 void inc(int post, int c)
5527 test_lvalue();
5528 vdup(); /* save lvalue */
5529 if (post) {
5530 gv_dup(); /* duplicate value */
5531 vrotb(3);
5532 vrotb(3);
5534 /* add constant */
5535 vpushi(c - TOK_MID);
5536 gen_op('+');
5537 vstore(); /* store value */
5538 if (post)
5539 vpop(); /* if post op, return saved value */
5542 /* Parse GNUC __attribute__ extension. Currently, the following
5543 extensions are recognized:
5544 - aligned(n) : set data/function alignment.
5545 - section(x) : generate data/code in this section.
5546 - unused : currently ignored, but may be used someday.
5548 void parse_attribute(AttributeDef *ad)
5550 int t, n;
5552 next();
5553 skip('(');
5554 skip('(');
5555 while (tok != ')') {
5556 if (tok < TOK_IDENT)
5557 expect("attribute name");
5558 t = tok;
5559 next();
5560 switch(t) {
5561 case TOK_SECTION:
5562 case TOK___SECTION__:
5563 skip('(');
5564 if (tok != TOK_STR)
5565 expect("section name");
5566 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
5567 next();
5568 skip(')');
5569 break;
5570 case TOK_ALIGNED:
5571 case TOK___ALIGNED__:
5572 if (tok == '(') {
5573 next();
5574 n = expr_const();
5575 if (n <= 0 || (n & (n - 1)) != 0)
5576 error("alignment must be a positive power of two");
5577 skip(')');
5578 } else {
5579 n = MAX_ALIGN;
5581 ad->aligned = n;
5582 break;
5583 case TOK_UNUSED:
5584 case TOK___UNUSED__:
5585 /* currently, no need to handle it because tcc does not
5586 track unused objects */
5587 break;
5588 case TOK_NORETURN:
5589 case TOK___NORETURN__:
5590 /* currently, no need to handle it because tcc does not
5591 track unused objects */
5592 break;
5593 case TOK_CDECL:
5594 case TOK___CDECL:
5595 case TOK___CDECL__:
5596 ad->func_call = FUNC_CDECL;
5597 break;
5598 case TOK_STDCALL:
5599 case TOK___STDCALL:
5600 case TOK___STDCALL__:
5601 ad->func_call = FUNC_STDCALL;
5602 break;
5603 default:
5604 warning("'%s' attribute ignored", get_tok_str(t, NULL));
5605 /* skip parameters */
5606 /* XXX: skip parenthesis too */
5607 if (tok == '(') {
5608 next();
5609 while (tok != ')' && tok != -1)
5610 next();
5611 next();
5613 break;
5615 if (tok != ',')
5616 break;
5617 next();
5619 skip(')');
5620 skip(')');
5623 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5624 static void struct_decl(CType *type, int u)
5626 int a, v, size, align, maxalign, c, offset;
5627 int bit_size, bit_pos, bsize, bt, lbit_pos;
5628 Sym *s, *ss, **ps;
5629 AttributeDef ad;
5630 CType type1, btype;
5632 a = tok; /* save decl type */
5633 next();
5634 if (tok != '{') {
5635 v = tok;
5636 next();
5637 /* struct already defined ? return it */
5638 /* XXX: check consistency */
5639 s = struct_find(v);
5640 if (s) {
5641 if (s->type.t != a)
5642 error("invalid type");
5643 goto do_decl;
5645 } else {
5646 v = anon_sym++;
5648 type1.t = a;
5649 s = sym_push(v | SYM_STRUCT, &type1, 0, 0);
5650 /* put struct/union/enum name in type */
5651 do_decl:
5652 type->t = u;
5653 type->ref = s;
5655 if (tok == '{') {
5656 next();
5657 if (s->c)
5658 error("struct/union/enum already defined");
5659 /* cannot be empty */
5660 c = 0;
5661 /* non empty enums are not allowed */
5662 if (a == TOK_ENUM) {
5663 for(;;) {
5664 v = tok;
5665 if (v < TOK_UIDENT)
5666 expect("identifier");
5667 next();
5668 if (tok == '=') {
5669 next();
5670 c = expr_const();
5672 /* enum symbols have static storage */
5673 ss = sym_push(v, &int_type, VT_CONST, c);
5674 ss->type.t |= VT_STATIC;
5675 if (tok != ',')
5676 break;
5677 next();
5678 c++;
5679 /* NOTE: we accept a trailing comma */
5680 if (tok == '}')
5681 break;
5683 skip('}');
5684 } else {
5685 maxalign = 1;
5686 ps = &s->next;
5687 bit_pos = 0;
5688 offset = 0;
5689 while (tok != '}') {
5690 parse_btype(&btype, &ad);
5691 while (1) {
5692 bit_size = -1;
5693 v = 0;
5694 type1 = btype;
5695 if (tok != ':') {
5696 type_decl(&type1, &ad, &v, TYPE_DIRECT);
5697 if ((type1.t & VT_BTYPE) == VT_FUNC ||
5698 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
5699 error("invalid type for '%s'",
5700 get_tok_str(v, NULL));
5702 if (tok == ':') {
5703 next();
5704 bit_size = expr_const();
5705 /* XXX: handle v = 0 case for messages */
5706 if (bit_size < 0)
5707 error("negative width in bit-field '%s'",
5708 get_tok_str(v, NULL));
5709 if (v && bit_size == 0)
5710 error("zero width for bit-field '%s'",
5711 get_tok_str(v, NULL));
5713 size = type_size(&type1, &align);
5714 lbit_pos = 0;
5715 if (bit_size >= 0) {
5716 bt = type1.t & VT_BTYPE;
5717 if (bt != VT_INT &&
5718 bt != VT_BYTE &&
5719 bt != VT_SHORT &&
5720 bt != VT_ENUM)
5721 error("bitfields must have scalar type");
5722 bsize = size * 8;
5723 if (bit_size > bsize) {
5724 error("width of '%s' exceeds its type",
5725 get_tok_str(v, NULL));
5726 } else if (bit_size == bsize) {
5727 /* no need for bit fields */
5728 bit_pos = 0;
5729 } else if (bit_size == 0) {
5730 /* XXX: what to do if only padding in a
5731 structure ? */
5732 /* zero size: means to pad */
5733 if (bit_pos > 0)
5734 bit_pos = bsize;
5735 } else {
5736 /* we do not have enough room ? */
5737 if ((bit_pos + bit_size) > bsize)
5738 bit_pos = 0;
5739 lbit_pos = bit_pos;
5740 /* XXX: handle LSB first */
5741 type1.t |= VT_BITFIELD |
5742 (bit_pos << VT_STRUCT_SHIFT) |
5743 (bit_size << (VT_STRUCT_SHIFT + 6));
5744 bit_pos += bit_size;
5746 } else {
5747 bit_pos = 0;
5749 if (v) {
5750 /* add new memory data only if starting
5751 bit field */
5752 if (lbit_pos == 0) {
5753 if (a == TOK_STRUCT) {
5754 c = (c + align - 1) & -align;
5755 offset = c;
5756 c += size;
5757 } else {
5758 offset = 0;
5759 if (size > c)
5760 c = size;
5762 if (align > maxalign)
5763 maxalign = align;
5765 #if 0
5766 printf("add field %s offset=%d",
5767 get_tok_str(v, NULL), offset);
5768 if (type1.t & VT_BITFIELD) {
5769 printf(" pos=%d size=%d",
5770 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
5771 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
5773 printf("\n");
5774 #endif
5775 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
5776 *ps = ss;
5777 ps = &ss->next;
5779 if (tok == ';' || tok == TOK_EOF)
5780 break;
5781 skip(',');
5783 skip(';');
5785 skip('}');
5786 /* store size and alignment */
5787 s->c = (c + maxalign - 1) & -maxalign;
5788 s->r = maxalign;
5793 /* return 0 if no type declaration. otherwise, return the basic type
5794 and skip it.
5796 static int parse_btype(CType *type, AttributeDef *ad)
5798 int t, u, type_found;
5799 Sym *s;
5800 CType type1;
5802 memset(ad, 0, sizeof(AttributeDef));
5803 type_found = 0;
5804 t = 0;
5805 while(1) {
5806 switch(tok) {
5807 /* basic types */
5808 case TOK_CHAR:
5809 u = VT_BYTE;
5810 basic_type:
5811 next();
5812 basic_type1:
5813 if ((t & VT_BTYPE) != 0)
5814 error("too many basic types");
5815 t |= u;
5816 break;
5817 case TOK_VOID:
5818 u = VT_VOID;
5819 goto basic_type;
5820 case TOK_SHORT:
5821 u = VT_SHORT;
5822 goto basic_type;
5823 case TOK_INT:
5824 next();
5825 break;
5826 case TOK_LONG:
5827 next();
5828 if ((t & VT_BTYPE) == VT_DOUBLE) {
5829 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5830 } else if ((t & VT_BTYPE) == VT_LONG) {
5831 t = (t & ~VT_BTYPE) | VT_LLONG;
5832 } else {
5833 u = VT_LONG;
5834 goto basic_type1;
5836 break;
5837 case TOK_BOOL:
5838 u = VT_BOOL;
5839 goto basic_type;
5840 case TOK_FLOAT:
5841 u = VT_FLOAT;
5842 goto basic_type;
5843 case TOK_DOUBLE:
5844 next();
5845 if ((t & VT_BTYPE) == VT_LONG) {
5846 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5847 } else {
5848 u = VT_DOUBLE;
5849 goto basic_type1;
5851 break;
5852 case TOK_ENUM:
5853 struct_decl(&type1, VT_ENUM);
5854 basic_type2:
5855 u = type1.t;
5856 type->ref = type1.ref;
5857 goto basic_type1;
5858 case TOK_STRUCT:
5859 case TOK_UNION:
5860 struct_decl(&type1, VT_STRUCT);
5861 goto basic_type2;
5863 /* type modifiers */
5864 case TOK_CONST:
5865 case TOK_VOLATILE:
5866 case TOK_REGISTER:
5867 case TOK_SIGNED:
5868 case TOK___SIGNED__:
5869 case TOK_AUTO:
5870 case TOK_INLINE:
5871 case TOK___INLINE__:
5872 case TOK_RESTRICT:
5873 next();
5874 break;
5875 case TOK_UNSIGNED:
5876 t |= VT_UNSIGNED;
5877 next();
5878 break;
5880 /* storage */
5881 case TOK_EXTERN:
5882 t |= VT_EXTERN;
5883 next();
5884 break;
5885 case TOK_STATIC:
5886 t |= VT_STATIC;
5887 next();
5888 break;
5889 case TOK_TYPEDEF:
5890 t |= VT_TYPEDEF;
5891 next();
5892 break;
5893 /* GNUC attribute */
5894 case TOK___ATTRIBUTE__:
5895 parse_attribute(ad);
5896 break;
5897 /* GNUC typeof */
5898 case TOK_TYPEOF:
5899 next();
5900 parse_expr_type(&type1);
5901 goto basic_type2;
5902 default:
5903 s = sym_find(tok);
5904 if (!s || !(s->type.t & VT_TYPEDEF))
5905 goto the_end;
5906 t |= (s->type.t & ~VT_TYPEDEF);
5907 type->ref = s->type.ref;
5908 next();
5909 break;
5911 type_found = 1;
5913 the_end:
5914 /* long is never used as type */
5915 if ((t & VT_BTYPE) == VT_LONG)
5916 t = (t & ~VT_BTYPE) | VT_INT;
5917 type->t = t;
5918 return type_found;
5921 static void post_type(CType *type, AttributeDef *ad)
5923 int n, l, t1;
5924 Sym **plast, *s, *first;
5925 AttributeDef ad1;
5926 CType pt;
5928 if (tok == '(') {
5929 /* function declaration */
5930 next();
5931 l = 0;
5932 first = NULL;
5933 plast = &first;
5934 while (tok != ')') {
5935 /* read param name and compute offset */
5936 if (l != FUNC_OLD) {
5937 if (!parse_btype(&pt, &ad1)) {
5938 if (l) {
5939 error("invalid type");
5940 } else {
5941 l = FUNC_OLD;
5942 goto old_proto;
5945 l = FUNC_NEW;
5946 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
5947 break;
5948 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
5949 if ((pt.t & VT_BTYPE) == VT_VOID)
5950 error("parameter declared as void");
5951 } else {
5952 old_proto:
5953 n = tok;
5954 pt.t = VT_INT;
5955 next();
5957 /* array must be transformed to pointer according to ANSI C */
5958 pt.t &= ~VT_ARRAY;
5959 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
5960 *plast = s;
5961 plast = &s->next;
5962 if (tok == ',') {
5963 next();
5964 if (l == FUNC_NEW && tok == TOK_DOTS) {
5965 l = FUNC_ELLIPSIS;
5966 next();
5967 break;
5971 /* if no parameters, then old type prototype */
5972 if (l == 0)
5973 l = FUNC_OLD;
5974 skip(')');
5975 t1 = type->t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5976 type->t &= ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5977 post_type(type, ad);
5978 /* we push a anonymous symbol which will contain the function prototype */
5979 s = sym_push(SYM_FIELD, type, ad->func_call, l);
5980 s->next = first;
5981 type->t = t1 | VT_FUNC;
5982 type->ref = s;
5983 } else if (tok == '[') {
5984 /* array definition */
5985 next();
5986 n = -1;
5987 if (tok != ']') {
5988 n = expr_const();
5989 if (n < 0)
5990 error("invalid array size");
5992 skip(']');
5993 /* parse next post type */
5994 t1 = type->t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5995 type->t &= ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5996 post_type(type, ad);
5998 /* we push a anonymous symbol which will contain the array
5999 element type */
6000 s = sym_push(SYM_FIELD, type, 0, n);
6001 type->t = t1 | VT_ARRAY | VT_PTR;
6002 type->ref = s;
6006 /* Parse a type declaration (except basic type), and return the type
6007 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6008 expected. 'type' should contain the basic type. 'ad' is the
6009 attribute definition of the basic type. It can be modified by
6010 type_decl().
6012 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
6014 Sym *s;
6015 CType type1, *type2;
6017 while (tok == '*') {
6018 next();
6019 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
6020 next();
6021 mk_pointer(type);
6024 /* recursive type */
6025 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6026 type1.t = 0; /* XXX: same as int */
6027 if (tok == '(') {
6028 next();
6029 /* XXX: this is not correct to modify 'ad' at this point, but
6030 the syntax is not clear */
6031 if (tok == TOK___ATTRIBUTE__)
6032 parse_attribute(ad);
6033 type_decl(&type1, ad, v, td);
6034 skip(')');
6035 } else {
6036 /* type identifier */
6037 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
6038 *v = tok;
6039 next();
6040 } else {
6041 if (!(td & TYPE_ABSTRACT))
6042 expect("identifier");
6043 *v = 0;
6046 post_type(type, ad);
6047 if (tok == TOK___ATTRIBUTE__)
6048 parse_attribute(ad);
6049 if (!type1.t)
6050 return;
6051 /* append type at the end of type1 */
6052 type2 = &type1;
6053 for(;;) {
6054 s = type2->ref;
6055 type2 = &s->type;
6056 if (!type2->t) {
6057 *type2 = *type;
6058 break;
6061 *type = type1;
6064 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6065 static int lvalue_type(int t)
6067 int bt, r;
6068 r = VT_LVAL;
6069 bt = t & VT_BTYPE;
6070 if (bt == VT_BYTE)
6071 r |= VT_LVAL_BYTE;
6072 else if (bt == VT_SHORT)
6073 r |= VT_LVAL_SHORT;
6074 else
6075 return r;
6076 if (t & VT_UNSIGNED)
6077 r |= VT_LVAL_UNSIGNED;
6078 return r;
6081 /* indirection with full error checking and bound check */
6082 static void indir(void)
6084 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6085 expect("pointer");
6086 if ((vtop->r & VT_LVAL) && !nocode_wanted)
6087 gv(RC_INT);
6088 vtop->type = *pointed_type(&vtop->type);
6089 /* an array is never an lvalue */
6090 if (!(vtop->type.t & VT_ARRAY)) {
6091 vtop->r |= lvalue_type(vtop->type.t);
6092 /* if bound checking, the referenced pointer must be checked */
6093 if (do_bounds_check)
6094 vtop->r |= VT_MUSTBOUND;
6098 /* pass a parameter to a function and do type checking and casting */
6099 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
6101 int func_type;
6102 CType type;
6104 func_type = func->c;
6105 if (func_type == FUNC_OLD ||
6106 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
6107 /* default casting : only need to convert float to double */
6108 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
6109 type.t = VT_DOUBLE;
6110 gen_cast(&type);
6112 } else if (arg == NULL) {
6113 error("too many arguments to function");
6114 } else {
6115 gen_assign_cast(&arg->type);
6117 if (!nocode_wanted) {
6118 gfunc_param(gf);
6119 } else {
6120 vpop();
6124 /* parse an expression of the form '(type)' or '(expr)' and return its
6125 type */
6126 static void parse_expr_type(CType *type)
6128 int n;
6129 AttributeDef ad;
6131 skip('(');
6132 if (parse_btype(type, &ad)) {
6133 type_decl(type, &ad, &n, TYPE_ABSTRACT);
6134 } else {
6135 expr_type(type);
6137 skip(')');
6140 static void vpush_tokc(int t)
6142 CType type;
6143 type.t = t;
6144 vsetc(&type, VT_CONST, &tokc);
6147 static void unary(void)
6149 int n, t, align, size, r;
6150 CType type;
6151 Sym *s;
6152 GFuncContext gf;
6153 AttributeDef ad;
6155 /* XXX: GCC 2.95.3 does not generate a table although it should be
6156 better here */
6157 switch(tok) {
6158 case TOK_CINT:
6159 case TOK_CCHAR:
6160 case TOK_LCHAR:
6161 vpushi(tokc.i);
6162 next();
6163 break;
6164 case TOK_CUINT:
6165 vpush_tokc(VT_INT | VT_UNSIGNED);
6166 next();
6167 break;
6168 case TOK_CLLONG:
6169 vpush_tokc(VT_LLONG);
6170 next();
6171 break;
6172 case TOK_CULLONG:
6173 vpush_tokc(VT_LLONG | VT_UNSIGNED);
6174 next();
6175 break;
6176 case TOK_CFLOAT:
6177 vpush_tokc(VT_FLOAT);
6178 next();
6179 break;
6180 case TOK_CDOUBLE:
6181 vpush_tokc(VT_DOUBLE);
6182 next();
6183 break;
6184 case TOK_CLDOUBLE:
6185 vpush_tokc(VT_LDOUBLE);
6186 next();
6187 break;
6188 case TOK___FUNCTION__:
6189 if (!gnu_ext)
6190 goto tok_identifier;
6191 /* fall thru */
6192 case TOK___FUNC__:
6194 void *ptr;
6195 int len;
6196 /* special function name identifier */
6197 len = strlen(funcname) + 1;
6198 /* generate char[len] type */
6199 type.t = VT_BYTE;
6200 mk_pointer(&type);
6201 type.t |= VT_ARRAY;
6202 type.ref->c = len;
6203 vpush_ref(&type, data_section, data_section->data_offset, len);
6204 ptr = section_ptr_add(data_section, len);
6205 memcpy(ptr, funcname, len);
6206 next();
6208 break;
6209 case TOK_LSTR:
6210 t = VT_INT;
6211 goto str_init;
6212 case TOK_STR:
6213 /* string parsing */
6214 t = VT_BYTE;
6215 str_init:
6216 type.t = t;
6217 mk_pointer(&type);
6218 type.t |= VT_ARRAY;
6219 memset(&ad, 0, sizeof(AttributeDef));
6220 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
6221 break;
6222 case '(':
6223 next();
6224 /* cast ? */
6225 if (parse_btype(&type, &ad)) {
6226 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
6227 skip(')');
6228 /* check ISOC99 compound literal */
6229 if (tok == '{') {
6230 /* data is allocated locally by default */
6231 if (global_expr)
6232 r = VT_CONST;
6233 else
6234 r = VT_LOCAL;
6235 /* all except arrays are lvalues */
6236 if (!(type.t & VT_ARRAY))
6237 r |= lvalue_type(type.t);
6238 memset(&ad, 0, sizeof(AttributeDef));
6239 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
6240 } else {
6241 unary();
6242 gen_cast(&type);
6244 } else {
6245 gexpr();
6246 skip(')');
6248 break;
6249 case '*':
6250 next();
6251 unary();
6252 indir();
6253 break;
6254 case '&':
6255 next();
6256 unary();
6257 /* functions names must be treated as function pointers,
6258 except for unary '&' and sizeof. Since we consider that
6259 functions are not lvalues, we only have to handle it
6260 there and in function calls. */
6261 /* arrays can also be used although they are not lvalues */
6262 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
6263 !(vtop->type.t & VT_ARRAY))
6264 test_lvalue();
6265 mk_pointer(&vtop->type);
6266 gaddrof();
6267 break;
6268 case '!':
6269 next();
6270 unary();
6271 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
6272 vtop->c.i = !vtop->c.i;
6273 else if ((vtop->r & VT_VALMASK) == VT_CMP)
6274 vtop->c.i = vtop->c.i ^ 1;
6275 else
6276 vseti(VT_JMP, gtst(1, 0));
6277 break;
6278 case '~':
6279 next();
6280 unary();
6281 vpushi(-1);
6282 gen_op('^');
6283 break;
6284 case '+':
6285 next();
6286 /* in order to force cast, we add zero */
6287 unary();
6288 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
6289 error("pointer not accepted for unary plus");
6290 vpushi(0);
6291 gen_op('+');
6292 break;
6293 case TOK_SIZEOF:
6294 case TOK_ALIGNOF:
6295 t = tok;
6296 next();
6297 if (tok == '(') {
6298 parse_expr_type(&type);
6299 } else {
6300 unary_type(&type);
6302 size = type_size(&type, &align);
6303 if (t == TOK_SIZEOF)
6304 vpushi(size);
6305 else
6306 vpushi(align);
6307 break;
6309 case TOK_INC:
6310 case TOK_DEC:
6311 t = tok;
6312 next();
6313 unary();
6314 inc(0, t);
6315 break;
6316 case '-':
6317 next();
6318 vpushi(0);
6319 unary();
6320 gen_op('-');
6321 break;
6322 case TOK_LAND:
6323 if (!gnu_ext)
6324 goto tok_identifier;
6325 next();
6326 /* allow to take the address of a label */
6327 if (tok < TOK_UIDENT)
6328 expect("label identifier");
6329 s = label_find(tok);
6330 if (!s) {
6331 s = label_push(tok, LABEL_FORWARD);
6333 if (!s->type.t) {
6334 s->type.t = VT_VOID;
6335 mk_pointer(&s->type);
6336 s->type.t |= VT_STATIC;
6338 vset(&s->type, VT_CONST | VT_SYM, 0);
6339 vtop->sym = s;
6340 next();
6341 break;
6342 default:
6343 tok_identifier:
6344 t = tok;
6345 next();
6346 if (t < TOK_UIDENT)
6347 expect("identifier");
6348 s = sym_find(t);
6349 if (!s) {
6350 if (tok != '(')
6351 error("'%s' undeclared", get_tok_str(t, NULL));
6352 /* for simple function calls, we tolerate undeclared
6353 external reference to int() function */
6354 s = external_global_sym(t, &func_old_type, 0);
6356 vset(&s->type, s->r, s->c);
6357 /* if forward reference, we must point to s */
6358 if (vtop->r & VT_SYM) {
6359 vtop->sym = s;
6360 vtop->c.ul = 0;
6362 break;
6365 /* post operations */
6366 while (1) {
6367 if (tok == TOK_INC || tok == TOK_DEC) {
6368 inc(1, tok);
6369 next();
6370 } else if (tok == '.' || tok == TOK_ARROW) {
6371 /* field */
6372 if (tok == TOK_ARROW)
6373 indir();
6374 test_lvalue();
6375 gaddrof();
6376 next();
6377 /* expect pointer on structure */
6378 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
6379 expect("struct or union");
6380 s = vtop->type.ref;
6381 /* find field */
6382 tok |= SYM_FIELD;
6383 while ((s = s->next) != NULL) {
6384 if (s->v == tok)
6385 break;
6387 if (!s)
6388 error("field not found");
6389 /* add field offset to pointer */
6390 vtop->type = char_pointer_type; /* change type to 'char *' */
6391 vpushi(s->c);
6392 gen_op('+');
6393 /* change type to field type, and set to lvalue */
6394 vtop->type = s->type;
6395 /* an array is never an lvalue */
6396 if (!(vtop->type.t & VT_ARRAY)) {
6397 vtop->r |= lvalue_type(vtop->type.t);
6398 /* if bound checking, the referenced pointer must be checked */
6399 if (do_bounds_check)
6400 vtop->r |= VT_MUSTBOUND;
6402 next();
6403 } else if (tok == '[') {
6404 next();
6405 gexpr();
6406 gen_op('+');
6407 indir();
6408 skip(']');
6409 } else if (tok == '(') {
6410 SValue ret;
6411 Sym *sa;
6413 /* function call */
6414 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
6415 /* pointer test (no array accepted) */
6416 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
6417 vtop->type = *pointed_type(&vtop->type);
6418 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
6419 goto error_func;
6420 } else {
6421 error_func:
6422 expect("function pointer");
6424 } else {
6425 vtop->r &= ~VT_LVAL; /* no lvalue */
6427 /* get return type */
6428 s = vtop->type.ref;
6429 if (!nocode_wanted) {
6430 save_regs(0); /* save used temporary registers */
6431 gfunc_start(&gf, s->r);
6433 next();
6434 sa = s->next; /* first parameter */
6435 #ifdef INVERT_FUNC_PARAMS
6437 int parlevel;
6438 Sym *args, *s1;
6439 ParseState saved_parse_state;
6440 TokenString str;
6442 /* read each argument and store it on a stack */
6443 args = NULL;
6444 if (tok != ')') {
6445 for(;;) {
6446 tok_str_new(&str);
6447 parlevel = 0;
6448 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
6449 tok != TOK_EOF) {
6450 if (tok == '(')
6451 parlevel++;
6452 else if (tok == ')')
6453 parlevel--;
6454 tok_str_add_tok(&str);
6455 next();
6457 tok_str_add(&str, -1); /* end of file added */
6458 tok_str_add(&str, 0);
6459 s1 = sym_push2(&args, 0, 0, (int)str.str);
6460 s1->next = sa; /* add reference to argument */
6461 if (sa)
6462 sa = sa->next;
6463 if (tok == ')')
6464 break;
6465 skip(',');
6469 /* now generate code in reverse order by reading the stack */
6470 save_parse_state(&saved_parse_state);
6471 while (args) {
6472 macro_ptr = (int *)args->c;
6473 next();
6474 expr_eq();
6475 if (tok != -1)
6476 expect("',' or ')'");
6477 gfunc_param_typed(&gf, s, args->next);
6478 s1 = args->prev;
6479 tok_str_free((int *)args->c);
6480 tcc_free(args);
6481 args = s1;
6483 restore_parse_state(&saved_parse_state);
6485 #endif
6486 /* compute first implicit argument if a structure is returned */
6487 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6488 /* get some space for the returned structure */
6489 size = type_size(&s->type, &align);
6490 loc = (loc - size) & -align;
6491 ret.type = s->type;
6492 ret.r = VT_LOCAL | VT_LVAL;
6493 /* pass it as 'int' to avoid structure arg passing
6494 problems */
6495 vseti(VT_LOCAL, loc);
6496 ret.c = vtop->c;
6497 if (!nocode_wanted)
6498 gfunc_param(&gf);
6499 else
6500 vtop--;
6501 } else {
6502 ret.type = s->type;
6503 ret.r2 = VT_CONST;
6504 /* return in register */
6505 if (is_float(ret.type.t)) {
6506 ret.r = REG_FRET;
6507 } else {
6508 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
6509 ret.r2 = REG_LRET;
6510 ret.r = REG_IRET;
6512 ret.c.i = 0;
6514 #ifndef INVERT_FUNC_PARAMS
6515 if (tok != ')') {
6516 for(;;) {
6517 expr_eq();
6518 gfunc_param_typed(&gf, s, sa);
6519 if (sa)
6520 sa = sa->next;
6521 if (tok == ')')
6522 break;
6523 skip(',');
6526 #endif
6527 if (sa)
6528 error("too few arguments to function");
6529 skip(')');
6530 if (!nocode_wanted)
6531 gfunc_call(&gf);
6532 else
6533 vtop--;
6534 /* return value */
6535 vsetc(&ret.type, ret.r, &ret.c);
6536 vtop->r2 = ret.r2;
6537 } else {
6538 break;
6543 static void uneq(void)
6545 int t;
6547 unary();
6548 if (tok == '=' ||
6549 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
6550 tok == TOK_A_XOR || tok == TOK_A_OR ||
6551 tok == TOK_A_SHL || tok == TOK_A_SAR) {
6552 test_lvalue();
6553 t = tok;
6554 next();
6555 if (t == '=') {
6556 expr_eq();
6557 } else {
6558 vdup();
6559 expr_eq();
6560 gen_op(t & 0x7f);
6562 vstore();
6566 static void expr_prod(void)
6568 int t;
6570 uneq();
6571 while (tok == '*' || tok == '/' || tok == '%') {
6572 t = tok;
6573 next();
6574 uneq();
6575 gen_op(t);
6579 static void expr_sum(void)
6581 int t;
6583 expr_prod();
6584 while (tok == '+' || tok == '-') {
6585 t = tok;
6586 next();
6587 expr_prod();
6588 gen_op(t);
6592 static void expr_shift(void)
6594 int t;
6596 expr_sum();
6597 while (tok == TOK_SHL || tok == TOK_SAR) {
6598 t = tok;
6599 next();
6600 expr_sum();
6601 gen_op(t);
6605 static void expr_cmp(void)
6607 int t;
6609 expr_shift();
6610 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
6611 tok == TOK_ULT || tok == TOK_UGE) {
6612 t = tok;
6613 next();
6614 expr_shift();
6615 gen_op(t);
6619 static void expr_cmpeq(void)
6621 int t;
6623 expr_cmp();
6624 while (tok == TOK_EQ || tok == TOK_NE) {
6625 t = tok;
6626 next();
6627 expr_cmp();
6628 gen_op(t);
6632 static void expr_and(void)
6634 expr_cmpeq();
6635 while (tok == '&') {
6636 next();
6637 expr_cmpeq();
6638 gen_op('&');
6642 static void expr_xor(void)
6644 expr_and();
6645 while (tok == '^') {
6646 next();
6647 expr_and();
6648 gen_op('^');
6652 static void expr_or(void)
6654 expr_xor();
6655 while (tok == '|') {
6656 next();
6657 expr_xor();
6658 gen_op('|');
6662 /* XXX: suppress this mess */
6663 static void expr_land_const(void)
6665 expr_or();
6666 while (tok == TOK_LAND) {
6667 next();
6668 expr_or();
6669 gen_op(TOK_LAND);
6673 /* XXX: suppress this mess */
6674 static void expr_lor_const(void)
6676 expr_land_const();
6677 while (tok == TOK_LOR) {
6678 next();
6679 expr_land_const();
6680 gen_op(TOK_LOR);
6684 /* only used if non constant */
6685 static void expr_land(void)
6687 int t;
6689 expr_or();
6690 if (tok == TOK_LAND) {
6691 t = 0;
6692 for(;;) {
6693 t = gtst(1, t);
6694 if (tok != TOK_LAND) {
6695 vseti(VT_JMPI, t);
6696 break;
6698 next();
6699 expr_or();
6704 static void expr_lor(void)
6706 int t;
6708 expr_land();
6709 if (tok == TOK_LOR) {
6710 t = 0;
6711 for(;;) {
6712 t = gtst(0, t);
6713 if (tok != TOK_LOR) {
6714 vseti(VT_JMP, t);
6715 break;
6717 next();
6718 expr_land();
6723 /* XXX: better constant handling */
6724 static void expr_eq(void)
6726 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
6727 SValue sv;
6728 CType type, type1, type2;
6730 if (const_wanted) {
6731 int c1, c;
6732 expr_lor_const();
6733 if (tok == '?') {
6734 c = vtop->c.i;
6735 vpop();
6736 next();
6737 gexpr();
6738 c1 = vtop->c.i;
6739 vpop();
6740 skip(':');
6741 expr_eq();
6742 if (c)
6743 vtop->c.i = c1;
6745 } else {
6746 expr_lor();
6747 if (tok == '?') {
6748 next();
6749 if (vtop != vstack) {
6750 /* needed to avoid having different registers saved in
6751 each branch */
6752 if (is_float(vtop->type.t))
6753 rc = RC_FLOAT;
6754 else
6755 rc = RC_INT;
6756 gv(rc);
6757 save_regs(1);
6759 tt = gtst(1, 0);
6760 gexpr();
6761 type1 = vtop->type;
6762 sv = *vtop; /* save value to handle it later */
6763 vtop--; /* no vpop so that FP stack is not flushed */
6764 skip(':');
6765 u = gjmp(0);
6766 gsym(tt);
6767 expr_eq();
6768 type2 = vtop->type;
6770 t1 = type1.t;
6771 bt1 = t1 & VT_BTYPE;
6772 t2 = type2.t;
6773 bt2 = t2 & VT_BTYPE;
6774 /* cast operands to correct type according to ISOC rules */
6775 if (is_float(bt1) || is_float(bt2)) {
6776 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
6777 type.t = VT_LDOUBLE;
6778 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
6779 type.t = VT_DOUBLE;
6780 } else {
6781 type.t = VT_FLOAT;
6783 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
6784 /* cast to biggest op */
6785 type.t = VT_LLONG;
6786 /* convert to unsigned if it does not fit in a long long */
6787 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
6788 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
6789 type.t |= VT_UNSIGNED;
6790 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
6791 /* XXX: test pointer compatibility */
6792 type = type1;
6793 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
6794 /* XXX: test structure compatibility */
6795 type = type1;
6796 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
6797 /* NOTE: as an extension, we accept void on only one side */
6798 type.t = VT_VOID;
6799 } else {
6800 /* integer operations */
6801 type.t = VT_INT;
6802 /* convert to unsigned if it does not fit in an integer */
6803 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
6804 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
6805 type.t |= VT_UNSIGNED;
6808 /* now we convert second operand */
6809 gen_cast(&type);
6810 rc = RC_INT;
6811 if (is_float(type.t)) {
6812 rc = RC_FLOAT;
6813 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
6814 /* for long longs, we use fixed registers to avoid having
6815 to handle a complicated move */
6816 rc = RC_IRET;
6819 r2 = gv(rc);
6820 /* this is horrible, but we must also convert first
6821 operand */
6822 tt = gjmp(0);
6823 gsym(u);
6824 /* put again first value and cast it */
6825 *vtop = sv;
6826 gen_cast(&type);
6827 r1 = gv(rc);
6828 move_reg(r2, r1);
6829 vtop->r = r2;
6830 gsym(tt);
6835 static void gexpr(void)
6837 while (1) {
6838 expr_eq();
6839 if (tok != ',')
6840 break;
6841 vpop();
6842 next();
6846 /* parse an expression and return its type without any side effect. */
6847 static void expr_type(CType *type)
6849 int a;
6851 a = nocode_wanted;
6852 nocode_wanted = 1;
6853 gexpr();
6854 *type = vtop->type;
6855 vpop();
6856 nocode_wanted = a;
6859 /* parse a unary expression and return its type without any side
6860 effect. */
6861 static void unary_type(CType *type)
6863 int a;
6865 a = nocode_wanted;
6866 nocode_wanted = 1;
6867 unary();
6868 *type = vtop->type;
6869 vpop();
6870 nocode_wanted = a;
6873 /* parse a constant expression and return value in vtop. */
6874 static void expr_const1(void)
6876 int a;
6877 a = const_wanted;
6878 const_wanted = 1;
6879 expr_eq();
6880 const_wanted = a;
6883 /* parse an integer constant and return its value. */
6884 static int expr_const(void)
6886 int c;
6887 expr_const1();
6888 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
6889 expect("constant expression");
6890 c = vtop->c.i;
6891 vpop();
6892 return c;
6895 /* return the label token if current token is a label, otherwise
6896 return zero */
6897 static int is_label(void)
6899 int t;
6900 CValue c;
6902 /* fast test first */
6903 if (tok < TOK_UIDENT)
6904 return 0;
6905 /* no need to save tokc since we expect an identifier */
6906 t = tok;
6907 c = tokc;
6908 next();
6909 if (tok == ':') {
6910 next();
6911 return t;
6912 } else {
6913 /* XXX: may not work in all cases (macros ?) */
6914 tok1 = tok;
6915 tok1c = tokc;
6916 tok = t;
6917 tokc = c;
6918 return 0;
6922 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
6924 int a, b, c, d;
6925 Sym *s;
6927 /* generate line number info */
6928 if (do_debug &&
6929 (last_line_num != file->line_num || last_ind != ind)) {
6930 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
6931 last_ind = ind;
6932 last_line_num = file->line_num;
6935 if (tok == TOK_IF) {
6936 /* if test */
6937 next();
6938 skip('(');
6939 gexpr();
6940 skip(')');
6941 a = gtst(1, 0);
6942 block(bsym, csym, case_sym, def_sym, case_reg);
6943 c = tok;
6944 if (c == TOK_ELSE) {
6945 next();
6946 d = gjmp(0);
6947 gsym(a);
6948 block(bsym, csym, case_sym, def_sym, case_reg);
6949 gsym(d); /* patch else jmp */
6950 } else
6951 gsym(a);
6952 } else if (tok == TOK_WHILE) {
6953 next();
6954 d = ind;
6955 skip('(');
6956 gexpr();
6957 skip(')');
6958 a = gtst(1, 0);
6959 b = 0;
6960 block(&a, &b, case_sym, def_sym, case_reg);
6961 gjmp_addr(d);
6962 gsym(a);
6963 gsym_addr(b, d);
6964 } else if (tok == '{') {
6965 next();
6966 /* declarations */
6967 s = local_stack;
6968 while (tok != '}') {
6969 decl(VT_LOCAL);
6970 if (tok != '}')
6971 block(bsym, csym, case_sym, def_sym, case_reg);
6973 /* pop locally defined symbols */
6974 sym_pop(&local_stack, s);
6975 next();
6976 } else if (tok == TOK_RETURN) {
6977 next();
6978 if (tok != ';') {
6979 gexpr();
6980 gen_assign_cast(&func_vt);
6981 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
6982 CType type;
6983 /* if returning structure, must copy it to implicit
6984 first pointer arg location */
6985 type = func_vt;
6986 mk_pointer(&type);
6987 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
6988 indir();
6989 vswap();
6990 /* copy structure value to pointer */
6991 vstore();
6992 } else if (is_float(func_vt.t)) {
6993 gv(RC_FRET);
6994 } else {
6995 gv(RC_IRET);
6997 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
6999 skip(';');
7000 rsym = gjmp(rsym); /* jmp */
7001 } else if (tok == TOK_BREAK) {
7002 /* compute jump */
7003 if (!bsym)
7004 error("cannot break");
7005 *bsym = gjmp(*bsym);
7006 next();
7007 skip(';');
7008 } else if (tok == TOK_CONTINUE) {
7009 /* compute jump */
7010 if (!csym)
7011 error("cannot continue");
7012 *csym = gjmp(*csym);
7013 next();
7014 skip(';');
7015 } else if (tok == TOK_FOR) {
7016 int e;
7017 next();
7018 skip('(');
7019 if (tok != ';') {
7020 gexpr();
7021 vpop();
7023 skip(';');
7024 d = ind;
7025 c = ind;
7026 a = 0;
7027 b = 0;
7028 if (tok != ';') {
7029 gexpr();
7030 a = gtst(1, 0);
7032 skip(';');
7033 if (tok != ')') {
7034 e = gjmp(0);
7035 c = ind;
7036 gexpr();
7037 vpop();
7038 gjmp_addr(d);
7039 gsym(e);
7041 skip(')');
7042 block(&a, &b, case_sym, def_sym, case_reg);
7043 gjmp_addr(c);
7044 gsym(a);
7045 gsym_addr(b, c);
7046 } else
7047 if (tok == TOK_DO) {
7048 next();
7049 a = 0;
7050 b = 0;
7051 d = ind;
7052 block(&a, &b, case_sym, def_sym, case_reg);
7053 skip(TOK_WHILE);
7054 skip('(');
7055 gsym(b);
7056 gexpr();
7057 c = gtst(0, 0);
7058 gsym_addr(c, d);
7059 skip(')');
7060 gsym(a);
7061 skip(';');
7062 } else
7063 if (tok == TOK_SWITCH) {
7064 next();
7065 skip('(');
7066 gexpr();
7067 /* XXX: other types than integer */
7068 case_reg = gv(RC_INT);
7069 vpop();
7070 skip(')');
7071 a = 0;
7072 b = gjmp(0); /* jump to first case */
7073 c = 0;
7074 block(&a, csym, &b, &c, case_reg);
7075 /* if no default, jmp after switch */
7076 if (c == 0)
7077 c = ind;
7078 /* default label */
7079 gsym_addr(b, c);
7080 /* break label */
7081 gsym(a);
7082 } else
7083 if (tok == TOK_CASE) {
7084 int v1, v2;
7085 if (!case_sym)
7086 expect("switch");
7087 next();
7088 v1 = expr_const();
7089 v2 = v1;
7090 if (gnu_ext && tok == TOK_DOTS) {
7091 next();
7092 v2 = expr_const();
7093 if (v2 < v1)
7094 warning("empty case range");
7096 /* since a case is like a label, we must skip it with a jmp */
7097 b = gjmp(0);
7098 gsym(*case_sym);
7099 vseti(case_reg, 0);
7100 vpushi(v1);
7101 if (v1 == v2) {
7102 gen_op(TOK_EQ);
7103 *case_sym = gtst(1, 0);
7104 } else {
7105 gen_op(TOK_GE);
7106 *case_sym = gtst(1, 0);
7107 vseti(case_reg, 0);
7108 vpushi(v2);
7109 gen_op(TOK_LE);
7110 *case_sym = gtst(1, *case_sym);
7112 gsym(b);
7113 skip(':');
7114 block(bsym, csym, case_sym, def_sym, case_reg);
7115 } else
7116 if (tok == TOK_DEFAULT) {
7117 next();
7118 skip(':');
7119 if (!def_sym)
7120 expect("switch");
7121 if (*def_sym)
7122 error("too many 'default'");
7123 *def_sym = ind;
7124 block(bsym, csym, case_sym, def_sym, case_reg);
7125 } else
7126 if (tok == TOK_GOTO) {
7127 next();
7128 if (tok == '*' && gnu_ext) {
7129 /* computed goto */
7130 next();
7131 gexpr();
7132 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
7133 expect("pointer");
7134 ggoto();
7135 } else if (tok >= TOK_UIDENT) {
7136 s = label_find(tok);
7137 /* put forward definition if needed */
7138 if (!s) {
7139 s = label_push(tok, LABEL_FORWARD);
7141 /* label already defined */
7142 if (s->r & LABEL_FORWARD)
7143 s->next = (void *)gjmp((long)s->next);
7144 else
7145 gjmp_addr((long)s->next);
7146 next();
7147 } else {
7148 expect("label identifier");
7150 skip(';');
7151 } else {
7152 b = is_label();
7153 if (b) {
7154 /* label case */
7155 s = label_find(b);
7156 if (s) {
7157 if (!(s->r & LABEL_FORWARD))
7158 error("multiple defined label");
7159 gsym((long)s->next);
7160 } else {
7161 s = label_push(b, 0);
7163 s->next = (void *)ind;
7164 s->r = 0;
7165 /* we accept this, but it is a mistake */
7166 if (tok == '}')
7167 warning("deprecated use of label at end of compound statement");
7168 else
7169 block(bsym, csym, case_sym, def_sym, case_reg);
7170 } else {
7171 /* expression case */
7172 if (tok != ';') {
7173 gexpr();
7174 vpop();
7176 skip(';');
7181 /* t is the array or struct type. c is the array or struct
7182 address. cur_index/cur_field is the pointer to the current
7183 value. 'size_only' is true if only size info is needed (only used
7184 in arrays) */
7185 static void decl_designator(CType *type, Section *sec, unsigned long c,
7186 int *cur_index, Sym **cur_field,
7187 int size_only)
7189 Sym *s, *f;
7190 int notfirst, index, align, l;
7191 CType type1;
7193 notfirst = 0;
7194 if (gnu_ext && (l = is_label()) != 0)
7195 goto struct_field;
7197 while (tok == '[' || tok == '.') {
7198 if (tok == '[') {
7199 if (!(type->t & VT_ARRAY))
7200 expect("array type");
7201 s = type->ref;
7202 next();
7203 index = expr_const();
7204 if (index < 0 || (s->c >= 0 && index >= s->c))
7205 expect("invalid index");
7206 skip(']');
7207 if (!notfirst)
7208 *cur_index = index;
7209 type = pointed_type(type);
7210 c += index * type_size(type, &align);
7211 } else {
7212 next();
7213 l = tok;
7214 next();
7215 struct_field:
7216 if ((type->t & VT_BTYPE) != VT_STRUCT)
7217 expect("struct/union type");
7218 s = type->ref;
7219 l |= SYM_FIELD;
7220 f = s->next;
7221 while (f) {
7222 if (f->v == l)
7223 break;
7224 f = f->next;
7226 if (!f)
7227 expect("field");
7228 if (!notfirst)
7229 *cur_field = f;
7230 /* XXX: suppress this mess by using explicit storage field */
7231 type1 = f->type;
7232 type1.t |= (type->t & ~VT_TYPE);
7233 type = &type1;
7234 c += f->c;
7236 notfirst = 1;
7238 if (notfirst) {
7239 if (tok == '=') {
7240 next();
7241 } else {
7242 if (!gnu_ext)
7243 expect("=");
7245 } else {
7246 if (type->t & VT_ARRAY) {
7247 index = *cur_index;
7248 type = pointed_type(type);
7249 c += index * type_size(type, &align);
7250 } else {
7251 f = *cur_field;
7252 if (!f)
7253 error("too many field init");
7254 /* XXX: suppress this mess by using explicit storage field */
7255 type1 = f->type;
7256 type1.t |= (type->t & ~VT_TYPE);
7257 type = &type1;
7258 c += f->c;
7261 decl_initializer(type, sec, c, 0, size_only);
7264 #define EXPR_VAL 0
7265 #define EXPR_CONST 1
7266 #define EXPR_ANY 2
7268 /* store a value or an expression directly in global data or in local array */
7269 static void init_putv(CType *type, Section *sec, unsigned long c,
7270 int v, int expr_type)
7272 int saved_global_expr, bt, bit_pos, bit_size;
7273 void *ptr;
7274 unsigned long long bit_mask;
7276 switch(expr_type) {
7277 case EXPR_VAL:
7278 vpushi(v);
7279 break;
7280 case EXPR_CONST:
7281 /* compound literals must be allocated globally in this case */
7282 saved_global_expr = global_expr;
7283 global_expr = 1;
7284 expr_const1();
7285 global_expr = saved_global_expr;
7286 /* NOTE: symbols are accepted */
7287 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
7288 error("initializer element is not constant");
7289 break;
7290 case EXPR_ANY:
7291 expr_eq();
7292 break;
7295 if (sec) {
7296 /* XXX: not portable */
7297 /* XXX: generate error if incorrect relocation */
7298 gen_assign_cast(type);
7299 bt = type->t & VT_BTYPE;
7300 ptr = sec->data + c;
7301 /* XXX: make code faster ? */
7302 if (!(type->t & VT_BITFIELD)) {
7303 bit_pos = 0;
7304 bit_size = 32;
7305 bit_mask = -1LL;
7306 } else {
7307 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
7308 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
7309 bit_mask = (1LL << bit_size) - 1;
7311 if ((vtop->r & VT_SYM) &&
7312 (bt == VT_BYTE ||
7313 bt == VT_SHORT ||
7314 bt == VT_DOUBLE ||
7315 bt == VT_LDOUBLE ||
7316 bt == VT_LLONG ||
7317 (bt == VT_INT && bit_size != 32)))
7318 error("initializer element is not computable at load time");
7319 switch(bt) {
7320 case VT_BYTE:
7321 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7322 break;
7323 case VT_SHORT:
7324 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7325 break;
7326 case VT_DOUBLE:
7327 *(double *)ptr = vtop->c.d;
7328 break;
7329 case VT_LDOUBLE:
7330 *(long double *)ptr = vtop->c.ld;
7331 break;
7332 case VT_LLONG:
7333 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
7334 break;
7335 default:
7336 if (vtop->r & VT_SYM) {
7337 greloc(sec, vtop->sym, c, R_DATA_32);
7339 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7340 break;
7342 vtop--;
7343 } else {
7344 vset(type, VT_LOCAL, c);
7345 vswap();
7346 vstore();
7347 vpop();
7351 /* put zeros for variable based init */
7352 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
7354 GFuncContext gf;
7356 if (sec) {
7357 /* nothing to do because globals are already set to zero */
7358 } else {
7359 gfunc_start(&gf, FUNC_CDECL);
7360 vpushi(size);
7361 gfunc_param(&gf);
7362 vpushi(0);
7363 gfunc_param(&gf);
7364 vseti(VT_LOCAL, c);
7365 gfunc_param(&gf);
7366 vpush_global_sym(&func_old_type, TOK_memset);
7367 gfunc_call(&gf);
7371 /* 't' contains the type and storage info. 'c' is the offset of the
7372 object in section 'sec'. If 'sec' is NULL, it means stack based
7373 allocation. 'first' is true if array '{' must be read (multi
7374 dimension implicit array init handling). 'size_only' is true if
7375 size only evaluation is wanted (only for arrays). */
7376 static void decl_initializer(CType *type, Section *sec, unsigned long c,
7377 int first, int size_only)
7379 int index, array_length, n, no_oblock, nb, parlevel, i;
7380 int size1, align1, expr_type;
7381 Sym *s, *f;
7382 CType *t1;
7384 if (type->t & VT_ARRAY) {
7385 s = type->ref;
7386 n = s->c;
7387 array_length = 0;
7388 t1 = pointed_type(type);
7389 size1 = type_size(t1, &align1);
7391 no_oblock = 1;
7392 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
7393 tok == '{') {
7394 skip('{');
7395 no_oblock = 0;
7398 /* only parse strings here if correct type (otherwise: handle
7399 them as ((w)char *) expressions */
7400 if ((tok == TOK_LSTR &&
7401 (t1->t & VT_BTYPE) == VT_INT) ||
7402 (tok == TOK_STR &&
7403 (t1->t & VT_BTYPE) == VT_BYTE)) {
7404 while (tok == TOK_STR || tok == TOK_LSTR) {
7405 int cstr_len, ch;
7406 CString *cstr;
7408 cstr = tokc.cstr;
7409 /* compute maximum number of chars wanted */
7410 if (tok == TOK_STR)
7411 cstr_len = cstr->size;
7412 else
7413 cstr_len = cstr->size / sizeof(int);
7414 cstr_len--;
7415 nb = cstr_len;
7416 if (n >= 0 && nb > (n - array_length))
7417 nb = n - array_length;
7418 if (!size_only) {
7419 if (cstr_len > nb)
7420 warning("initializer-string for array is too long");
7421 /* in order to go faster for common case (char
7422 string in global variable, we handle it
7423 specifically */
7424 if (sec && tok == TOK_STR && size1 == 1) {
7425 memcpy(sec->data + c + array_length, cstr->data, nb);
7426 } else {
7427 for(i=0;i<nb;i++) {
7428 if (tok == TOK_STR)
7429 ch = ((unsigned char *)cstr->data)[i];
7430 else
7431 ch = ((int *)cstr->data)[i];
7432 init_putv(t1, sec, c + (array_length + i) * size1,
7433 ch, EXPR_VAL);
7437 array_length += nb;
7438 next();
7440 /* only add trailing zero if enough storage (no
7441 warning in this case since it is standard) */
7442 if (n < 0 || array_length < n) {
7443 if (!size_only) {
7444 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
7446 array_length++;
7448 } else {
7449 index = 0;
7450 while (tok != '}') {
7451 decl_designator(type, sec, c, &index, NULL, size_only);
7452 if (n >= 0 && index >= n)
7453 error("index too large");
7454 /* must put zero in holes (note that doing it that way
7455 ensures that it even works with designators) */
7456 if (!size_only && array_length < index) {
7457 init_putz(t1, sec, c + array_length * size1,
7458 (index - array_length) * size1);
7460 index++;
7461 if (index > array_length)
7462 array_length = index;
7463 /* special test for multi dimensional arrays (may not
7464 be strictly correct if designators are used at the
7465 same time) */
7466 if (index >= n && no_oblock)
7467 break;
7468 if (tok == '}')
7469 break;
7470 skip(',');
7473 if (!no_oblock)
7474 skip('}');
7475 /* put zeros at the end */
7476 if (!size_only && n >= 0 && array_length < n) {
7477 init_putz(t1, sec, c + array_length * size1,
7478 (n - array_length) * size1);
7480 /* patch type size if needed */
7481 if (n < 0)
7482 s->c = array_length;
7483 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
7484 (sec || !first || tok == '{')) {
7485 /* NOTE: the previous test is a specific case for automatic
7486 struct/union init */
7487 /* XXX: union needs only one init */
7488 no_oblock = 1;
7489 if (first || tok == '{') {
7490 skip('{');
7491 no_oblock = 0;
7493 s = type->ref;
7494 f = s->next;
7495 array_length = 0;
7496 index = 0;
7497 n = s->c;
7498 while (tok != '}') {
7499 decl_designator(type, sec, c, NULL, &f, size_only);
7500 index = f->c;
7501 if (!size_only && array_length < index) {
7502 init_putz(type, sec, c + array_length,
7503 index - array_length);
7505 index = index + type_size(&f->type, &align1);
7506 if (index > array_length)
7507 array_length = index;
7508 f = f->next;
7509 if (no_oblock && f == NULL)
7510 break;
7511 if (tok == '}')
7512 break;
7513 skip(',');
7515 /* put zeros at the end */
7516 if (!size_only && array_length < n) {
7517 init_putz(type, sec, c + array_length,
7518 n - array_length);
7520 if (!no_oblock)
7521 skip('}');
7522 } else if (tok == '{') {
7523 next();
7524 decl_initializer(type, sec, c, first, size_only);
7525 skip('}');
7526 } else if (size_only) {
7527 /* just skip expression */
7528 parlevel = 0;
7529 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
7530 tok != -1) {
7531 if (tok == '(')
7532 parlevel++;
7533 else if (tok == ')')
7534 parlevel--;
7535 next();
7537 } else {
7538 /* currently, we always use constant expression for globals
7539 (may change for scripting case) */
7540 expr_type = EXPR_CONST;
7541 if (!sec)
7542 expr_type = EXPR_ANY;
7543 init_putv(type, sec, c, 0, expr_type);
7547 /* parse an initializer for type 't' if 'has_init' is non zero, and
7548 allocate space in local or global data space ('r' is either
7549 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7550 variable 'v' of scope 'scope' is declared before initializers are
7551 parsed. If 'v' is zero, then a reference to the new object is put
7552 in the value stack. If 'has_init' is 2, a special parsing is done
7553 to handle string constants. */
7554 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
7555 int has_init, int v, int scope)
7557 int size, align, addr, data_offset;
7558 int level;
7559 ParseState saved_parse_state;
7560 TokenString init_str;
7561 Section *sec;
7563 size = type_size(type, &align);
7564 /* If unknown size, we must evaluate it before
7565 evaluating initializers because
7566 initializers can generate global data too
7567 (e.g. string pointers or ISOC99 compound
7568 literals). It also simplifies local
7569 initializers handling */
7570 tok_str_new(&init_str);
7571 if (size < 0) {
7572 if (!has_init)
7573 error("unknown type size");
7574 /* get all init string */
7575 if (has_init == 2) {
7576 /* only get strings */
7577 while (tok == TOK_STR || tok == TOK_LSTR) {
7578 tok_str_add_tok(&init_str);
7579 next();
7581 } else {
7582 level = 0;
7583 while (level > 0 || (tok != ',' && tok != ';')) {
7584 if (tok < 0)
7585 error("unexpected end of file in initializer");
7586 tok_str_add_tok(&init_str);
7587 if (tok == '{')
7588 level++;
7589 else if (tok == '}') {
7590 if (level == 0)
7591 break;
7592 level--;
7594 next();
7597 tok_str_add(&init_str, -1);
7598 tok_str_add(&init_str, 0);
7600 /* compute size */
7601 save_parse_state(&saved_parse_state);
7603 macro_ptr = init_str.str;
7604 next();
7605 decl_initializer(type, NULL, 0, 1, 1);
7606 /* prepare second initializer parsing */
7607 macro_ptr = init_str.str;
7608 next();
7610 /* if still unknown size, error */
7611 size = type_size(type, &align);
7612 if (size < 0)
7613 error("unknown type size");
7615 /* take into account specified alignment if bigger */
7616 if (ad->aligned > align)
7617 align = ad->aligned;
7618 if ((r & VT_VALMASK) == VT_LOCAL) {
7619 sec = NULL;
7620 if (do_bounds_check && (type->t & VT_ARRAY))
7621 loc--;
7622 #ifdef TCC_TARGET_IL
7623 /* XXX: ugly patch to allocate local variables for IL, just
7624 for testing */
7625 addr = loc;
7626 loc++;
7627 #else
7628 loc = (loc - size) & -align;
7629 addr = loc;
7630 #endif
7631 /* handles bounds */
7632 /* XXX: currently, since we do only one pass, we cannot track
7633 '&' operators, so we add only arrays */
7634 if (do_bounds_check && (type->t & VT_ARRAY)) {
7635 unsigned long *bounds_ptr;
7636 /* add padding between regions */
7637 loc--;
7638 /* then add local bound info */
7639 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
7640 bounds_ptr[0] = addr;
7641 bounds_ptr[1] = size;
7643 } else {
7644 /* compute section */
7645 sec = ad->section;
7646 if (!sec) {
7647 if (has_init)
7648 sec = data_section;
7649 else
7650 sec = bss_section;
7652 data_offset = sec->data_offset;
7653 data_offset = (data_offset + align - 1) & -align;
7654 addr = data_offset;
7655 /* very important to increment global pointer at this time
7656 because initializers themselves can create new initializers */
7657 data_offset += size;
7658 /* add padding if bound check */
7659 if (do_bounds_check)
7660 data_offset++;
7661 sec->data_offset = data_offset;
7662 /* allocate section space to put the data */
7663 if (sec->sh_type != SHT_NOBITS &&
7664 data_offset > sec->data_allocated)
7665 section_realloc(sec, data_offset);
7667 if (!sec) {
7668 if (v) {
7669 /* local variable */
7670 sym_push(v, type, r, addr);
7671 } else {
7672 /* push local reference */
7673 vset(type, r, addr);
7675 } else {
7676 Sym *sym;
7678 if (v) {
7679 if (scope == VT_CONST) {
7680 /* global scope: see if already defined */
7681 sym = sym_find(v);
7682 if (!sym)
7683 goto do_def;
7684 if (!is_compatible_types(&sym->type, type))
7685 error("incompatible types for redefinition of '%s'",
7686 get_tok_str(v, NULL));
7687 if (!(sym->type.t & VT_EXTERN))
7688 error("redefinition of '%s'", get_tok_str(v, NULL));
7689 sym->type.t &= ~VT_EXTERN;
7690 } else {
7691 do_def:
7692 sym = sym_push(v, type, r | VT_SYM, 0);
7694 put_extern_sym(sym, sec, addr, size);
7695 } else {
7696 CValue cval;
7698 /* push global reference */
7699 sym = get_sym_ref(type, sec, addr, size);
7700 cval.ul = 0;
7701 vsetc(type, VT_CONST | VT_SYM, &cval);
7702 vtop->sym = sym;
7705 /* handles bounds now because the symbol must be defined
7706 before for the relocation */
7707 if (do_bounds_check) {
7708 unsigned long *bounds_ptr;
7710 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
7711 /* then add global bound info */
7712 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
7713 bounds_ptr[0] = 0; /* relocated */
7714 bounds_ptr[1] = size;
7717 if (has_init) {
7718 decl_initializer(type, sec, addr, 1, 0);
7719 /* restore parse state if needed */
7720 if (init_str.str) {
7721 tok_str_free(init_str.str);
7722 restore_parse_state(&saved_parse_state);
7727 void put_func_debug(Sym *sym)
7729 char buf[512];
7731 /* stabs info */
7732 /* XXX: we put here a dummy type */
7733 snprintf(buf, sizeof(buf), "%s:%c1",
7734 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
7735 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
7736 cur_text_section, sym->c);
7737 last_ind = 0;
7738 last_line_num = 0;
7741 /* not finished : try to put some local vars in registers */
7742 //#define CONFIG_REG_VARS
7744 #ifdef CONFIG_REG_VARS
7745 void add_var_ref(int t)
7747 printf("%s:%d: &%s\n",
7748 file->filename, file->line_num,
7749 get_tok_str(t, NULL));
7752 /* first pass on a function with heuristic to extract variable usage
7753 and pointer references to local variables for register allocation */
7754 void analyse_function(void)
7756 int level, t;
7758 for(;;) {
7759 if (tok == -1)
7760 break;
7761 /* any symbol coming after '&' is considered as being a
7762 variable whose reference is taken. It is highly unaccurate
7763 but it is difficult to do better without a complete parse */
7764 if (tok == '&') {
7765 next();
7766 /* if '& number', then no need to examine next tokens */
7767 if (tok == TOK_CINT ||
7768 tok == TOK_CUINT ||
7769 tok == TOK_CLLONG ||
7770 tok == TOK_CULLONG) {
7771 continue;
7772 } else if (tok >= TOK_UIDENT) {
7773 /* if '& ident [' or '& ident ->', then ident address
7774 is not needed */
7775 t = tok;
7776 next();
7777 if (tok != '[' && tok != TOK_ARROW)
7778 add_var_ref(t);
7779 } else {
7780 level = 0;
7781 while (tok != '}' && tok != ';' &&
7782 !((tok == ',' || tok == ')') && level == 0)) {
7783 if (tok >= TOK_UIDENT) {
7784 add_var_ref(tok);
7785 } else if (tok == '(') {
7786 level++;
7787 } else if (tok == ')') {
7788 level--;
7790 next();
7793 } else {
7794 next();
7798 #endif
7800 /* parse an old style function declaration list */
7801 /* XXX: check multiple parameter */
7802 static void func_decl_list(Sym *func_sym)
7804 AttributeDef ad;
7805 int v;
7806 Sym *s;
7807 CType btype, type;
7809 /* parse each declaration */
7810 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
7811 if (!parse_btype(&btype, &ad))
7812 expect("declaration list");
7813 if (((btype.t & VT_BTYPE) == VT_ENUM ||
7814 (btype.t & VT_BTYPE) == VT_STRUCT) &&
7815 tok == ';') {
7816 /* we accept no variable after */
7817 } else {
7818 for(;;) {
7819 type = btype;
7820 type_decl(&type, &ad, &v, TYPE_DIRECT);
7821 /* find parameter in function parameter list */
7822 s = func_sym->next;
7823 while (s != NULL) {
7824 if ((s->v & ~SYM_FIELD) == v)
7825 goto found;
7826 s = s->next;
7828 error("declaration for parameter '%s' but no such parameter",
7829 get_tok_str(v, NULL));
7830 found:
7831 /* check that no storage specifier except 'register' was given */
7832 if (type.t & (VT_EXTERN | VT_STATIC | VT_TYPEDEF))
7833 error("storage class specified for '%s'", get_tok_str(v, NULL));
7834 /* we can add the type (NOTE: it could be local to the function) */
7835 s->type = type;
7836 /* accept other parameters */
7837 if (tok == ',')
7838 next();
7839 else
7840 break;
7843 skip(';');
7847 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
7848 static void decl(int l)
7850 int v, has_init, r;
7851 CType type, btype;
7852 Sym *sym;
7853 AttributeDef ad;
7855 while (1) {
7856 if (!parse_btype(&btype, &ad)) {
7857 /* skip redundant ';' */
7858 /* XXX: find more elegant solution */
7859 if (tok == ';') {
7860 next();
7861 continue;
7863 /* special test for old K&R protos without explicit int
7864 type. Only accepted when defining global data */
7865 if (l == VT_LOCAL || tok < TOK_DEFINE)
7866 break;
7867 btype.t = VT_INT;
7869 if (((btype.t & VT_BTYPE) == VT_ENUM ||
7870 (btype.t & VT_BTYPE) == VT_STRUCT) &&
7871 tok == ';') {
7872 /* we accept no variable after */
7873 next();
7874 continue;
7876 while (1) { /* iterate thru each declaration */
7877 type = btype;
7878 type_decl(&type, &ad, &v, TYPE_DIRECT);
7879 #if 0
7881 char buf[500];
7882 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
7883 printf("type = '%s'\n", buf);
7885 #endif
7886 if ((type.t & VT_BTYPE) == VT_FUNC) {
7887 /* if old style function prototype, we accept a
7888 declaration list */
7889 sym = type.ref;
7890 if (sym->c == FUNC_OLD)
7891 func_decl_list(sym);
7894 if (tok == '{') {
7895 #ifdef CONFIG_REG_VARS
7896 TokenString func_str;
7897 ParseState saved_parse_state;
7898 int block_level;
7899 #endif
7901 if (l == VT_LOCAL)
7902 error("cannot use local functions");
7903 if (!(type.t & VT_FUNC))
7904 expect("function definition");
7906 #ifdef CONFIG_REG_VARS
7907 /* parse all function code and record it */
7909 tok_str_new(&func_str);
7911 block_level = 0;
7912 for(;;) {
7913 int t;
7914 if (tok == -1)
7915 error("unexpected end of file");
7916 tok_str_add_tok(&func_str);
7917 t = tok;
7918 next();
7919 if (t == '{') {
7920 block_level++;
7921 } else if (t == '}') {
7922 block_level--;
7923 if (block_level == 0)
7924 break;
7927 tok_str_add(&func_str, -1);
7928 tok_str_add(&func_str, 0);
7930 save_parse_state(&saved_parse_state);
7932 macro_ptr = func_str.str;
7933 next();
7934 analyse_function();
7935 #endif
7937 /* compute text section */
7938 cur_text_section = ad.section;
7939 if (!cur_text_section)
7940 cur_text_section = text_section;
7941 ind = cur_text_section->data_offset;
7942 funcname = get_tok_str(v, NULL);
7943 sym = sym_find(v);
7944 if (sym) {
7945 /* if symbol is already defined, then put complete type */
7946 sym->type = type;
7947 } else {
7948 /* put function symbol */
7949 sym = global_identifier_push(v, type.t, 0);
7950 sym->type.ref = type.ref;
7952 /* NOTE: we patch the symbol size later */
7953 put_extern_sym(sym, cur_text_section, ind, 0);
7954 func_ind = ind;
7955 sym->r = VT_SYM | VT_CONST;
7956 /* put debug symbol */
7957 if (do_debug)
7958 put_func_debug(sym);
7959 /* push a dummy symbol to enable local sym storage */
7960 sym_push2(&local_stack, SYM_FIELD, 0, 0);
7961 gfunc_prolog(&type);
7962 loc = 0;
7963 rsym = 0;
7964 #ifdef CONFIG_REG_VARS
7965 macro_ptr = func_str.str;
7966 next();
7967 #endif
7968 block(NULL, NULL, NULL, NULL, 0);
7969 gsym(rsym);
7970 gfunc_epilog();
7971 cur_text_section->data_offset = ind;
7972 /* look if any labels are undefined. Define symbols if
7973 '&&label' was used. */
7975 Sym *s, *s1;
7976 for(s = label_stack; s != NULL; s = s1) {
7977 s1 = s->prev;
7978 if (s->r & LABEL_FORWARD) {
7979 error("label '%s' used but not defined",
7980 get_tok_str(s->v, NULL));
7982 if (s->c) {
7983 /* define corresponding symbol. A size of
7984 1 is put. */
7985 put_extern_sym(s, cur_text_section, (long)s->next, 1);
7987 /* remove label */
7988 table_ident[s->v - TOK_IDENT]->sym_label = NULL;
7989 tcc_free(s);
7991 label_stack = NULL;
7993 sym_pop(&local_stack, NULL); /* reset local stack */
7994 /* end of function */
7995 /* patch symbol size */
7996 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
7997 ind - func_ind;
7998 if (do_debug) {
7999 put_stabn(N_FUN, 0, 0, ind - func_ind);
8001 funcname = ""; /* for safety */
8002 func_vt.t = VT_VOID; /* for safety */
8003 ind = 0; /* for safety */
8005 #ifdef CONFIG_REG_VARS
8006 tok_str_free(func_str.str);
8007 restore_parse_state(&saved_parse_state);
8008 #endif
8009 break;
8010 } else {
8011 if (btype.t & VT_TYPEDEF) {
8012 /* save typedefed type */
8013 /* XXX: test storage specifiers ? */
8014 sym = sym_push(v, &type, 0, 0);
8015 sym->type.t |= VT_TYPEDEF;
8016 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
8017 /* external function definition */
8018 external_sym(v, &type, 0);
8019 } else {
8020 /* not lvalue if array */
8021 r = 0;
8022 if (!(type.t & VT_ARRAY))
8023 r |= lvalue_type(type.t);
8024 if (btype.t & VT_EXTERN) {
8025 /* external variable */
8026 external_sym(v, &type, r);
8027 } else {
8028 if (type.t & VT_STATIC)
8029 r |= VT_CONST;
8030 else
8031 r |= l;
8032 has_init = (tok == '=');
8033 if (has_init)
8034 next();
8035 decl_initializer_alloc(&type, &ad, r,
8036 has_init, v, l);
8039 if (tok != ',') {
8040 skip(';');
8041 break;
8043 next();
8049 /* compile the C file opened in 'file'. Return non zero if errors. */
8050 static int tcc_compile(TCCState *s1)
8052 Sym *define_start;
8053 char buf[512];
8054 volatile int section_sym;
8056 #ifdef INC_DEBUG
8057 printf("%s: **** new file\n", file->filename);
8058 #endif
8059 funcname = "";
8060 s1->include_stack_ptr = s1->include_stack;
8061 /* XXX: move that before to avoid having to initialize
8062 file->ifdef_stack_ptr ? */
8063 s1->ifdef_stack_ptr = s1->ifdef_stack;
8064 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
8066 /* XXX: not ANSI compliant: bound checking says error */
8067 vtop = vstack - 1;
8068 anon_sym = SYM_FIRST_ANOM;
8070 /* file info: full path + filename */
8071 section_sym = 0; /* avoid warning */
8072 if (do_debug) {
8073 section_sym = put_elf_sym(symtab_section, 0, 0,
8074 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
8075 text_section->sh_num, NULL);
8076 getcwd(buf, sizeof(buf));
8077 pstrcat(buf, sizeof(buf), "/");
8078 put_stabs_r(buf, N_SO, 0, 0,
8079 text_section->data_offset, text_section, section_sym);
8080 put_stabs_r(file->filename, N_SO, 0, 0,
8081 text_section->data_offset, text_section, section_sym);
8083 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8084 symbols can be safely used */
8085 put_elf_sym(symtab_section, 0, 0,
8086 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
8087 SHN_ABS, file->filename);
8089 /* define some often used types */
8090 int_type.t = VT_INT;
8092 char_pointer_type.t = VT_BYTE;
8093 mk_pointer(&char_pointer_type);
8095 func_old_type.t = VT_FUNC;
8096 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
8098 #if 0
8099 /* define 'void *alloca(unsigned int)' builtin function */
8101 Sym *s1;
8103 p = anon_sym++;
8104 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
8105 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
8106 s1->next = NULL;
8107 sym->next = s1;
8108 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
8110 #endif
8112 define_start = define_stack;
8114 if (setjmp(s1->error_jmp_buf) == 0) {
8115 s1->nb_errors = 0;
8116 s1->error_set_jmp_enabled = 1;
8118 ch = file->buf_ptr[0];
8119 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
8120 next();
8121 decl(VT_CONST);
8122 if (tok != -1)
8123 expect("declaration");
8125 /* end of translation unit info */
8126 if (do_debug) {
8127 put_stabs_r(NULL, N_SO, 0, 0,
8128 text_section->data_offset, text_section, section_sym);
8131 s1->error_set_jmp_enabled = 0;
8133 /* reset define stack, but leave -Dsymbols (may be incorrect if
8134 they are undefined) */
8135 free_defines(define_start);
8137 sym_pop(&global_stack, NULL);
8139 return s1->nb_errors != 0 ? -1 : 0;
8142 #ifdef LIBTCC
8143 int tcc_compile_string(TCCState *s, const char *str)
8145 BufferedFile bf1, *bf = &bf1;
8146 int ret, len;
8147 char *buf;
8149 /* init file structure */
8150 bf->fd = -1;
8151 /* XXX: avoid copying */
8152 len = strlen(str);
8153 buf = tcc_malloc(len + 1);
8154 if (!buf)
8155 return -1;
8156 memcpy(buf, str, len);
8157 buf[len] = CH_EOB;
8158 bf->buf_ptr = buf;
8159 bf->buf_end = buf + len;
8160 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
8161 bf->line_num = 1;
8162 file = bf;
8164 ret = tcc_compile(s);
8166 tcc_free(buf);
8168 /* currently, no need to close */
8169 return ret;
8171 #endif
8173 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8174 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
8176 BufferedFile bf1, *bf = &bf1;
8178 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
8179 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
8180 /* default value */
8181 if (!value)
8182 value = "1";
8183 pstrcat(bf->buffer, IO_BUF_SIZE, value);
8185 /* init file structure */
8186 bf->fd = -1;
8187 bf->buf_ptr = bf->buffer;
8188 bf->buf_end = bf->buffer + strlen(bf->buffer);
8189 *bf->buf_end = CH_EOB;
8190 bf->filename[0] = '\0';
8191 bf->line_num = 1;
8192 file = bf;
8194 s1->include_stack_ptr = s1->include_stack;
8196 /* parse with define parser */
8197 ch = file->buf_ptr[0];
8198 next_nomacro();
8199 parse_define();
8200 file = NULL;
8203 /* undefine a preprocessor symbol */
8204 void tcc_undefine_symbol(TCCState *s1, const char *sym)
8206 TokenSym *ts;
8207 Sym *s;
8208 ts = tok_alloc(sym, strlen(sym));
8209 s = define_find(ts->tok);
8210 /* undefine symbol by putting an invalid name */
8211 if (s)
8212 define_undef(s);
8215 #include "tccelf.c"
8217 /* print the position in the source file of PC value 'pc' by reading
8218 the stabs debug information */
8219 static void rt_printline(unsigned long wanted_pc)
8221 Stab_Sym *sym, *sym_end;
8222 char func_name[128], last_func_name[128];
8223 unsigned long func_addr, last_pc, pc;
8224 const char *incl_files[INCLUDE_STACK_SIZE];
8225 int incl_index, len, last_line_num, i;
8226 const char *str, *p;
8228 fprintf(stderr, "0x%08lx:", wanted_pc);
8230 func_name[0] = '\0';
8231 func_addr = 0;
8232 incl_index = 0;
8233 last_func_name[0] = '\0';
8234 last_pc = 0xffffffff;
8235 last_line_num = 1;
8236 sym = (Stab_Sym *)stab_section->data + 1;
8237 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
8238 while (sym < sym_end) {
8239 switch(sym->n_type) {
8240 /* function start or end */
8241 case N_FUN:
8242 if (sym->n_strx == 0) {
8243 /* we test if between last line and end of function */
8244 pc = sym->n_value + func_addr;
8245 if (wanted_pc >= last_pc && wanted_pc < pc)
8246 goto found;
8247 func_name[0] = '\0';
8248 func_addr = 0;
8249 } else {
8250 str = stabstr_section->data + sym->n_strx;
8251 p = strchr(str, ':');
8252 if (!p) {
8253 pstrcpy(func_name, sizeof(func_name), str);
8254 } else {
8255 len = p - str;
8256 if (len > sizeof(func_name) - 1)
8257 len = sizeof(func_name) - 1;
8258 memcpy(func_name, str, len);
8259 func_name[len] = '\0';
8261 func_addr = sym->n_value;
8263 break;
8264 /* line number info */
8265 case N_SLINE:
8266 pc = sym->n_value + func_addr;
8267 if (wanted_pc >= last_pc && wanted_pc < pc)
8268 goto found;
8269 last_pc = pc;
8270 last_line_num = sym->n_desc;
8271 /* XXX: slow! */
8272 strcpy(last_func_name, func_name);
8273 break;
8274 /* include files */
8275 case N_BINCL:
8276 str = stabstr_section->data + sym->n_strx;
8277 add_incl:
8278 if (incl_index < INCLUDE_STACK_SIZE) {
8279 incl_files[incl_index++] = str;
8281 break;
8282 case N_EINCL:
8283 if (incl_index > 1)
8284 incl_index--;
8285 break;
8286 case N_SO:
8287 if (sym->n_strx == 0) {
8288 incl_index = 0; /* end of translation unit */
8289 } else {
8290 str = stabstr_section->data + sym->n_strx;
8291 /* do not add path */
8292 len = strlen(str);
8293 if (len > 0 && str[len - 1] != '/')
8294 goto add_incl;
8296 break;
8298 sym++;
8301 /* second pass: we try symtab symbols (no line number info) */
8302 incl_index = 0;
8304 Elf32_Sym *sym, *sym_end;
8305 int type;
8307 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
8308 for(sym = (Elf32_Sym *)symtab_section->data + 1;
8309 sym < sym_end;
8310 sym++) {
8311 type = ELF32_ST_TYPE(sym->st_info);
8312 if (type == STT_FUNC) {
8313 if (wanted_pc >= sym->st_value &&
8314 wanted_pc < sym->st_value + sym->st_size) {
8315 pstrcpy(last_func_name, sizeof(last_func_name),
8316 strtab_section->data + sym->st_name);
8317 goto found;
8322 /* did not find any info: */
8323 fprintf(stderr, " ???\n");
8324 return;
8325 found:
8326 if (last_func_name[0] != '\0') {
8327 fprintf(stderr, " %s()", last_func_name);
8329 if (incl_index > 0) {
8330 fprintf(stderr, " (%s:%d",
8331 incl_files[incl_index - 1], last_line_num);
8332 for(i = incl_index - 2; i >= 0; i--)
8333 fprintf(stderr, ", included from %s", incl_files[i]);
8334 fprintf(stderr, ")");
8336 fprintf(stderr, "\n");
8339 #ifndef WIN32
8341 #ifdef __i386__
8343 /* fix for glibc 2.1 */
8344 #ifndef REG_EIP
8345 #define REG_EIP EIP
8346 #define REG_EBP EBP
8347 #endif
8349 /* return the PC at frame level 'level'. Return non zero if not found */
8350 static int rt_get_caller_pc(unsigned long *paddr,
8351 ucontext_t *uc, int level)
8353 unsigned long fp;
8354 int i;
8356 if (level == 0) {
8357 #ifdef __FreeBSD__
8358 *paddr = uc->uc_mcontext.mc_eip;
8359 #else
8360 *paddr = uc->uc_mcontext.gregs[REG_EIP];
8361 #endif
8362 return 0;
8363 } else {
8364 #ifdef __FreeBSD__
8365 fp = uc->uc_mcontext.mc_ebp;
8366 #else
8367 fp = uc->uc_mcontext.gregs[REG_EBP];
8368 #endif
8369 for(i=1;i<level;i++) {
8370 /* XXX: check address validity with program info */
8371 if (fp <= 0x1000 || fp >= 0xc0000000)
8372 return -1;
8373 fp = ((unsigned long *)fp)[0];
8375 *paddr = ((unsigned long *)fp)[1];
8376 return 0;
8379 #else
8380 #error add arch specific rt_get_caller_pc()
8381 #endif
8383 /* emit a run time error at position 'pc' */
8384 void rt_error(ucontext_t *uc, const char *fmt, ...)
8386 va_list ap;
8387 unsigned long pc;
8388 int i;
8390 va_start(ap, fmt);
8391 fprintf(stderr, "Runtime error: ");
8392 vfprintf(stderr, fmt, ap);
8393 fprintf(stderr, "\n");
8394 for(i=0;i<num_callers;i++) {
8395 if (rt_get_caller_pc(&pc, uc, i) < 0)
8396 break;
8397 if (i == 0)
8398 fprintf(stderr, "at ");
8399 else
8400 fprintf(stderr, "by ");
8401 rt_printline(pc);
8403 exit(255);
8404 va_end(ap);
8407 /* signal handler for fatal errors */
8408 static void sig_error(int signum, siginfo_t *siginf, void *puc)
8410 ucontext_t *uc = puc;
8412 switch(signum) {
8413 case SIGFPE:
8414 switch(siginf->si_code) {
8415 case FPE_INTDIV:
8416 case FPE_FLTDIV:
8417 rt_error(uc, "division by zero");
8418 break;
8419 default:
8420 rt_error(uc, "floating point exception");
8421 break;
8423 break;
8424 case SIGBUS:
8425 case SIGSEGV:
8426 if (rt_bound_error_msg && *rt_bound_error_msg)
8427 rt_error(uc, *rt_bound_error_msg);
8428 else
8429 rt_error(uc, "dereferencing invalid pointer");
8430 break;
8431 case SIGILL:
8432 rt_error(uc, "illegal instruction");
8433 break;
8434 case SIGABRT:
8435 rt_error(uc, "abort() called");
8436 break;
8437 default:
8438 rt_error(uc, "caught signal %d", signum);
8439 break;
8441 exit(255);
8443 #endif
8445 /* do all relocations (needed before using tcc_get_symbol()) */
8446 int tcc_relocate(TCCState *s1)
8448 Section *s;
8449 int i;
8451 s1->nb_errors = 0;
8453 tcc_add_runtime(s1);
8455 relocate_common_syms();
8457 /* compute relocation address : section are relocated in place. We
8458 also alloc the bss space */
8459 for(i = 1; i < s1->nb_sections; i++) {
8460 s = s1->sections[i];
8461 if (s->sh_flags & SHF_ALLOC) {
8462 if (s->sh_type == SHT_NOBITS)
8463 s->data = tcc_mallocz(s->data_offset);
8464 s->sh_addr = (unsigned long)s->data;
8468 relocate_syms(s1, 1);
8470 if (s1->nb_errors != 0)
8471 return -1;
8473 /* relocate each section */
8474 for(i = 1; i < s1->nb_sections; i++) {
8475 s = s1->sections[i];
8476 if (s->reloc)
8477 relocate_section(s1, s);
8479 return 0;
8482 /* launch the compiled program with the given arguments */
8483 int tcc_run(TCCState *s1, int argc, char **argv)
8485 int (*prog_main)(int, char **);
8487 if (tcc_relocate(s1) < 0)
8488 return -1;
8490 prog_main = tcc_get_symbol(s1, "main");
8492 if (do_debug) {
8493 #ifdef WIN32
8494 error("debug mode currently not available for Windows");
8495 #else
8496 struct sigaction sigact;
8497 /* install TCC signal handlers to print debug info on fatal
8498 runtime errors */
8499 sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
8500 sigact.sa_sigaction = sig_error;
8501 sigemptyset(&sigact.sa_mask);
8502 sigaction(SIGFPE, &sigact, NULL);
8503 sigaction(SIGILL, &sigact, NULL);
8504 sigaction(SIGSEGV, &sigact, NULL);
8505 sigaction(SIGBUS, &sigact, NULL);
8506 sigaction(SIGABRT, &sigact, NULL);
8507 #endif
8510 #ifdef CONFIG_TCC_BCHECK
8511 if (do_bounds_check) {
8512 void (*bound_init)(void);
8514 /* set error function */
8515 rt_bound_error_msg = (void *)tcc_get_symbol(s1, "__bound_error_msg");
8517 /* XXX: use .init section so that it also work in binary ? */
8518 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
8519 bound_init();
8521 #endif
8522 return (*prog_main)(argc, argv);
8525 TCCState *tcc_new(void)
8527 const char *p, *r;
8528 TCCState *s;
8530 s = tcc_mallocz(sizeof(TCCState));
8531 if (!s)
8532 return NULL;
8533 tcc_state = s;
8534 s->output_type = TCC_OUTPUT_MEMORY;
8536 /* default include paths */
8537 tcc_add_sysinclude_path(s, "/usr/local/include");
8538 tcc_add_sysinclude_path(s, "/usr/include");
8539 tcc_add_sysinclude_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
8541 /* add all tokens */
8542 table_ident = NULL;
8543 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
8545 tok_ident = TOK_IDENT;
8546 p = tcc_keywords;
8547 while (*p) {
8548 r = p;
8549 while (*r++);
8550 tok_alloc(p, r - p - 1);
8551 p = r;
8554 /* we add dummy defines for some special macros to speed up tests
8555 and to have working defined() */
8556 define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
8557 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
8558 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
8559 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
8561 /* standard defines */
8562 tcc_define_symbol(s, "__STDC__", NULL);
8563 #if defined(TCC_TARGET_I386)
8564 tcc_define_symbol(s, "__i386__", NULL);
8565 #endif
8566 #if defined(linux)
8567 tcc_define_symbol(s, "linux", NULL);
8568 #endif
8569 /* tiny C specific defines */
8570 tcc_define_symbol(s, "__TINYC__", NULL);
8572 /* tiny C & gcc defines */
8573 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
8574 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
8575 tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
8577 /* default library paths */
8578 tcc_add_library_path(s, "/usr/local/lib");
8579 tcc_add_library_path(s, "/usr/lib");
8580 tcc_add_library_path(s, "/lib");
8582 /* no section zero */
8583 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
8585 /* create standard sections */
8586 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
8587 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
8588 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
8590 /* symbols are always generated for linking stage */
8591 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
8592 ".strtab",
8593 ".hashtab", SHF_PRIVATE);
8594 strtab_section = symtab_section->link;
8596 /* private symbol table for dynamic symbols */
8597 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
8598 ".dynstrtab",
8599 ".dynhashtab", SHF_PRIVATE);
8600 return s;
8603 void tcc_delete(TCCState *s1)
8605 int i, n;
8607 /* free -D defines */
8608 free_defines(NULL);
8610 /* free tokens */
8611 n = tok_ident - TOK_IDENT;
8612 for(i = 0; i < n; i++)
8613 tcc_free(table_ident[i]);
8614 tcc_free(table_ident);
8616 /* free all sections */
8618 free_section(symtab_section->hash);
8620 free_section(s1->dynsymtab_section->hash);
8621 free_section(s1->dynsymtab_section->link);
8622 free_section(s1->dynsymtab_section);
8624 for(i = 1; i < s1->nb_sections; i++)
8625 free_section(s1->sections[i]);
8626 tcc_free(s1->sections);
8628 /* free loaded dlls array */
8629 for(i = 0; i < s1->nb_loaded_dlls; i++)
8630 tcc_free(s1->loaded_dlls[i]);
8631 tcc_free(s1->loaded_dlls);
8633 /* library paths */
8634 for(i = 0; i < s1->nb_library_paths; i++)
8635 tcc_free(s1->library_paths[i]);
8636 tcc_free(s1->library_paths);
8638 /* cached includes */
8639 for(i = 0; i < s1->nb_cached_includes; i++)
8640 tcc_free(s1->cached_includes[i]);
8641 tcc_free(s1->cached_includes);
8643 for(i = 0; i < s1->nb_include_paths; i++)
8644 tcc_free(s1->include_paths[i]);
8645 tcc_free(s1->include_paths);
8647 for(i = 0; i < s1->nb_sysinclude_paths; i++)
8648 tcc_free(s1->sysinclude_paths[i]);
8649 tcc_free(s1->sysinclude_paths);
8651 tcc_free(s1);
8654 int tcc_add_include_path(TCCState *s1, const char *pathname)
8656 char *pathname1;
8658 pathname1 = tcc_strdup(pathname);
8659 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
8660 return 0;
8663 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
8665 char *pathname1;
8667 pathname1 = tcc_strdup(pathname);
8668 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
8669 return 0;
8672 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
8674 const char *ext, *filename1;
8675 Elf32_Ehdr ehdr;
8676 int fd, ret;
8677 BufferedFile *saved_file;
8679 /* find source file type with extension */
8680 filename1 = strrchr(filename, '/');
8681 if (filename1)
8682 filename1++;
8683 else
8684 filename1 = filename;
8685 ext = strrchr(filename1, '.');
8686 if (ext)
8687 ext++;
8689 /* open the file */
8690 saved_file = file;
8691 file = tcc_open(s1, filename);
8692 if (!file) {
8693 if (flags & AFF_PRINT_ERROR) {
8694 error_noabort("file '%s' not found", filename);
8696 ret = -1;
8697 goto fail1;
8700 if (!ext || !strcmp(ext, "c")) {
8701 /* C file assumed */
8702 ret = tcc_compile(s1);
8703 } else {
8704 fd = file->fd;
8705 /* assume executable format: auto guess file type */
8706 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
8707 error_noabort("could not read header");
8708 goto fail;
8710 lseek(fd, 0, SEEK_SET);
8712 if (ehdr.e_ident[0] == ELFMAG0 &&
8713 ehdr.e_ident[1] == ELFMAG1 &&
8714 ehdr.e_ident[2] == ELFMAG2 &&
8715 ehdr.e_ident[3] == ELFMAG3) {
8716 file->line_num = 0; /* do not display line number if error */
8717 if (ehdr.e_type == ET_REL) {
8718 ret = tcc_load_object_file(s1, fd, 0);
8719 } else if (ehdr.e_type == ET_DYN) {
8720 ret = tcc_load_dll(s1, fd, filename,
8721 (flags & AFF_REFERENCED_DLL) != 0);
8722 } else {
8723 error_noabort("unrecognized ELF file");
8724 goto fail;
8726 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
8727 file->line_num = 0; /* do not display line number if error */
8728 ret = tcc_load_archive(s1, fd);
8729 } else {
8730 /* as GNU ld, consider it is an ld script if not recognized */
8731 ret = tcc_load_ldscript(s1);
8732 if (ret < 0) {
8733 error_noabort("unrecognized file type");
8734 goto fail;
8738 the_end:
8739 tcc_close(file);
8740 fail1:
8741 file = saved_file;
8742 return ret;
8743 fail:
8744 ret = -1;
8745 goto the_end;
8748 int tcc_add_file(TCCState *s, const char *filename)
8750 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
8753 int tcc_add_library_path(TCCState *s, const char *pathname)
8755 char *pathname1;
8757 pathname1 = tcc_strdup(pathname);
8758 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
8759 return 0;
8762 /* find and load a dll. Return non zero if not found */
8763 /* XXX: add '-rpath' option support ? */
8764 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
8766 char buf[1024];
8767 int i;
8769 for(i = 0; i < s->nb_library_paths; i++) {
8770 snprintf(buf, sizeof(buf), "%s/%s",
8771 s->library_paths[i], filename);
8772 if (tcc_add_file_internal(s, buf, flags) == 0)
8773 return 0;
8775 return -1;
8778 /* the library name is the same as the argument of the '-l' option */
8779 int tcc_add_library(TCCState *s, const char *libraryname)
8781 char buf[1024];
8782 int i;
8783 void *h;
8785 /* first we look for the dynamic library if not static linking */
8786 if (!s->static_link) {
8787 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
8788 /* if we output to memory, then we simply we dlopen(). */
8789 if (s->output_type == TCC_OUTPUT_MEMORY) {
8790 /* Since the libc is already loaded, we don't need to load it again */
8791 if (!strcmp(libraryname, "c"))
8792 return 0;
8793 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
8794 if (h)
8795 return 0;
8796 } else {
8797 if (tcc_add_dll(s, buf, 0) == 0)
8798 return 0;
8802 /* then we look for the static library */
8803 for(i = 0; i < s->nb_library_paths; i++) {
8804 snprintf(buf, sizeof(buf), "%s/lib%s.a",
8805 s->library_paths[i], libraryname);
8806 if (tcc_add_file_internal(s, buf, 0) == 0)
8807 return 0;
8809 return -1;
8812 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
8814 add_elf_sym(symtab_section, val, 0,
8815 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
8816 SHN_ABS, name);
8817 return 0;
8820 int tcc_set_output_type(TCCState *s, int output_type)
8822 s->output_type = output_type;
8824 /* if bound checking, then add corresponding sections */
8825 #ifdef CONFIG_TCC_BCHECK
8826 if (do_bounds_check) {
8827 /* define symbol */
8828 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
8829 /* create bounds sections */
8830 bounds_section = new_section(s, ".bounds",
8831 SHT_PROGBITS, SHF_ALLOC);
8832 lbounds_section = new_section(s, ".lbounds",
8833 SHT_PROGBITS, SHF_ALLOC);
8835 #endif
8837 /* add debug sections */
8838 if (do_debug) {
8839 /* stab symbols */
8840 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
8841 stab_section->sh_entsize = sizeof(Stab_Sym);
8842 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
8843 put_elf_str(stabstr_section, "");
8844 stab_section->link = stabstr_section;
8845 /* put first entry */
8846 put_stabs("", 0, 0, 0, 0);
8849 /* add libc crt1/crti objects */
8850 if (output_type == TCC_OUTPUT_EXE ||
8851 output_type == TCC_OUTPUT_DLL) {
8852 if (output_type != TCC_OUTPUT_DLL)
8853 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
8854 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
8856 return 0;
8859 #if !defined(LIBTCC)
8861 static int64_t getclock_us(void)
8863 #ifdef WIN32
8864 struct _timeb tb;
8865 _ftime(&tb);
8866 return (tb.time * 1000LL + tb.millitm) * 1000LL;
8867 #else
8868 struct timeval tv;
8869 gettimeofday(&tv, NULL);
8870 return tv.tv_sec * 1000000LL + tv.tv_usec;
8871 #endif
8874 void help(void)
8876 printf("tcc version 0.9.15 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8877 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8878 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
8879 " [--] infile1 [infile2... --] [infile_args...]\n"
8880 "\n"
8881 "General options:\n"
8882 " -c compile only - generate an object file\n"
8883 " -o outfile set output filename\n"
8884 " -- allows multiples input files if no -o option given. Also\n"
8885 " separate input files from runtime arguments\n"
8886 " -Bdir set tcc internal library path\n"
8887 " -bench output compilation statistics\n"
8888 "Preprocessor options:\n"
8889 " -Idir add include path 'dir'\n"
8890 " -Dsym[=val] define 'sym' with value 'val'\n"
8891 " -Usym undefine 'sym'\n"
8892 "Linker options:\n"
8893 " -Ldir add library path 'dir'\n"
8894 " -llib link with dynamic or static library 'lib'\n"
8895 " -shared generate a shared library\n"
8896 " -static static linking\n"
8897 " -r relocatable output\n"
8898 "Debugger options:\n"
8899 " -g generate runtime debug info\n"
8900 #ifdef CONFIG_TCC_BCHECK
8901 " -b compile with built-in memory and bounds checker (implies -g)\n"
8902 #endif
8903 " -bt N show N callers in stack traces\n"
8907 int main(int argc, char **argv)
8909 char *r, *outfile;
8910 int optind, output_type, multiple_files, i, reloc_output;
8911 TCCState *s;
8912 char **files;
8913 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
8914 char objfilename[1024];
8915 int64_t start_time = 0;
8917 s = tcc_new();
8918 output_type = TCC_OUTPUT_MEMORY;
8920 optind = 1;
8921 outfile = NULL;
8922 multiple_files = 0;
8923 dminus = 0;
8924 files = NULL;
8925 nb_files = 0;
8926 nb_libraries = 0;
8927 reloc_output = 0;
8928 while (1) {
8929 if (optind >= argc) {
8930 if (nb_files == 0)
8931 goto show_help;
8932 else
8933 break;
8935 r = argv[optind++];
8936 if (r[0] != '-') {
8937 /* add a new file */
8938 dynarray_add((void ***)&files, &nb_files, r);
8939 if (!multiple_files) {
8940 optind--;
8941 /* argv[0] will be this file */
8942 break;
8944 } else if (r[1] == '-') {
8945 /* '--' enables multiple files input and also ends several file input */
8946 if (dminus && multiple_files) {
8947 optind--; /* argv[0] will be '--' */
8948 break;
8950 dminus = 1;
8951 multiple_files = 1;
8952 } else if (r[1] == 'h' || r[1] == '?') {
8953 show_help:
8954 help();
8955 return 1;
8956 } else if (r[1] == 'I') {
8957 if (tcc_add_include_path(s, r + 2) < 0)
8958 error("too many include paths");
8959 } else if (r[1] == 'D') {
8960 char *sym, *value;
8961 sym = r + 2;
8962 value = strchr(sym, '=');
8963 if (value) {
8964 *value = '\0';
8965 value++;
8967 tcc_define_symbol(s, sym, value);
8968 } else if (r[1] == 'U') {
8969 tcc_undefine_symbol(s, r + 2);
8970 } else if (r[1] == 'L') {
8971 tcc_add_library_path(s, r + 2);
8972 } else if (r[1] == 'B') {
8973 /* set tcc utilities path (mainly for tcc development) */
8974 tcc_lib_path = r + 2;
8975 } else if (r[1] == 'l') {
8976 dynarray_add((void ***)&files, &nb_files, r);
8977 nb_libraries++;
8978 } else if (!strcmp(r + 1, "bench")) {
8979 do_bench = 1;
8980 } else if (!strcmp(r + 1, "bt")) {
8981 num_callers = atoi(argv[optind++]);
8982 } else
8983 #ifdef CONFIG_TCC_BCHECK
8984 if (r[1] == 'b') {
8985 do_bounds_check = 1;
8986 do_debug = 1;
8987 } else
8988 #endif
8989 if (r[1] == 'g') {
8990 do_debug = 1;
8991 } else if (r[1] == 'c') {
8992 multiple_files = 1;
8993 output_type = TCC_OUTPUT_OBJ;
8994 } else if (!strcmp(r + 1, "static")) {
8995 s->static_link = 1;
8996 } else if (!strcmp(r + 1, "shared")) {
8997 output_type = TCC_OUTPUT_DLL;
8998 } else if (r[1] == 'o') {
8999 if (optind >= argc)
9000 goto show_help;
9001 multiple_files = 1;
9002 outfile = argv[optind++];
9003 } else if (r[1] == 'r') {
9004 /* generate a .o merging several output files */
9005 reloc_output = 1;
9006 output_type = TCC_OUTPUT_OBJ;
9007 } else if (r[1] == 'W' || r[1] == 'O' || r[1] == 'm' || r[1] == 'f') {
9008 /* ignore those options to be a drop-in replacement for gcc */
9009 } else {
9010 error("invalid option -- '%s'", r);
9014 nb_objfiles = nb_files - nb_libraries;
9016 /* if outfile provided without other options, we output an
9017 executable */
9018 if (outfile && output_type == TCC_OUTPUT_MEMORY)
9019 output_type = TCC_OUTPUT_EXE;
9021 /* check -c consistency : only single file handled. XXX: checks file type */
9022 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9023 /* accepts only a single input file */
9024 if (nb_objfiles != 1)
9025 error("cannot specify multiple files with -c");
9026 if (nb_libraries != 0)
9027 error("cannot specify libraries with -c");
9030 /* compute default outfile name */
9031 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
9032 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9033 char *ext;
9034 /* add .o extension */
9035 pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
9036 ext = strrchr(objfilename, '.');
9037 if (!ext)
9038 goto default_outfile;
9039 strcpy(ext + 1, "o");
9040 } else {
9041 default_outfile:
9042 pstrcpy(objfilename, sizeof(objfilename), "a.out");
9044 outfile = objfilename;
9047 if (do_bench) {
9048 start_time = getclock_us();
9051 tcc_set_output_type(s, output_type);
9053 /* compile or add each files or library */
9054 for(i = 0;i < nb_files; i++) {
9055 const char *filename;
9057 filename = files[i];
9058 if (filename[0] == '-') {
9059 if (tcc_add_library(s, filename + 2) < 0)
9060 error("cannot find %s", filename);
9061 } else {
9062 if (tcc_add_file(s, filename) < 0) {
9063 ret = 1;
9064 goto the_end;
9069 /* free all files */
9070 tcc_free(files);
9072 if (do_bench) {
9073 double total_time;
9074 total_time = (double)(getclock_us() - start_time) / 1000000.0;
9075 if (total_time < 0.001)
9076 total_time = 0.001;
9077 if (total_bytes < 1)
9078 total_bytes = 1;
9079 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
9080 tok_ident - TOK_IDENT, total_lines, total_bytes,
9081 total_time, (int)(total_lines / total_time),
9082 total_bytes / total_time / 1000000.0);
9085 if (s->output_type != TCC_OUTPUT_MEMORY) {
9086 tcc_output_file(s, outfile);
9087 ret = 0;
9088 } else {
9089 ret = tcc_run(s, argc - optind, argv + optind);
9091 the_end:
9092 /* XXX: cannot do it with bound checking because of the malloc hooks */
9093 if (!do_bounds_check)
9094 tcc_delete(s);
9096 #ifdef MEM_DEBUG
9097 if (do_bench) {
9098 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
9100 #endif
9101 return ret;
9104 #endif