renamed registers
[tinycc.git] / tcc.c
blob07fa7c3c4bbc2234048f3d95acd43b6621194c6e
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <math.h>
26 #include <unistd.h>
27 #include <signal.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <setjmp.h>
31 #ifdef WIN32
32 #include <sys/timeb.h>
33 #endif
34 #ifndef WIN32
35 #include <sys/time.h>
36 #include <sys/ucontext.h>
37 #endif
38 #include "elf.h"
39 #include "stab.h"
40 #ifndef CONFIG_TCC_STATIC
41 #include <dlfcn.h>
42 #endif
44 #include "libtcc.h"
46 /* parser debug */
47 //#define PARSE_DEBUG
48 /* preprocessor debug */
49 //#define PP_DEBUG
50 /* include file debug */
51 //#define INC_DEBUG
53 //#define MEM_DEBUG
55 /* target selection */
56 //#define TCC_TARGET_I386 /* i386 code generator */
57 //#define TCC_TARGET_IL /* .NET CLI generator */
59 /* default target is I386 */
60 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
61 #define TCC_TARGET_I386
62 #endif
64 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
65 #define CONFIG_TCC_BCHECK /* enable bound checking code */
66 #endif
68 #ifndef CONFIG_TCC_PREFIX
69 #define CONFIG_TCC_PREFIX "/usr/local"
70 #endif
72 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
73 executables or dlls */
74 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
76 #define INCLUDE_STACK_SIZE 32
77 #define IFDEF_STACK_SIZE 64
78 #define VSTACK_SIZE 64
79 #define STRING_MAX_SIZE 1024
81 #define TOK_HASH_SIZE 2048 /* must be a power of two */
82 #define TOK_ALLOC_INCR 512 /* must be a power of two */
83 #define TOK_STR_ALLOC_INCR_BITS 6
84 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
85 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
87 /* token symbol management */
88 typedef struct TokenSym {
89 struct TokenSym *hash_next;
90 struct Sym *sym_define; /* direct pointer to define */
91 struct Sym *sym_label; /* direct pointer to label */
92 struct Sym *sym_struct; /* direct pointer to structure */
93 struct Sym *sym_identifier; /* direct pointer to identifier */
94 int tok; /* token number */
95 int len;
96 char str[1];
97 } TokenSym;
99 typedef struct CString {
100 int size; /* size in bytes */
101 void *data; /* either 'char *' or 'int *' */
102 int size_allocated;
103 void *data_allocated; /* if non NULL, data has been malloced */
104 } CString;
106 /* type definition */
107 typedef struct CType {
108 int t;
109 struct Sym *ref;
110 } CType;
112 /* constant value */
113 typedef union CValue {
114 long double ld;
115 double d;
116 float f;
117 int i;
118 unsigned int ui;
119 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
120 long long ll;
121 unsigned long long ull;
122 struct CString *cstr;
123 void *ptr;
124 int tab[1];
125 } CValue;
127 /* value on stack */
128 typedef struct SValue {
129 CType type; /* type */
130 unsigned short r; /* register + flags */
131 unsigned short r2; /* second register, used for 'long long'
132 type. If not used, set to VT_CONST */
133 CValue c; /* constant, if VT_CONST */
134 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
135 } SValue;
137 /* symbol management */
138 typedef struct Sym {
139 int v; /* symbol token */
140 int r; /* associated register */
141 int c; /* associated number */
142 CType type; /* associated type */
143 struct Sym *next; /* next related symbol */
144 struct Sym *prev; /* prev symbol in stack */
145 struct Sym *prev_tok; /* previous symbol for this token */
146 } Sym;
148 /* section definition */
149 /* XXX: use directly ELF structure for parameters ? */
150 /* special flag to indicate that the section should not be linked to
151 the other ones */
152 #define SHF_PRIVATE 0x80000000
154 typedef struct Section {
155 unsigned long data_offset; /* current data offset */
156 unsigned char *data; /* section data */
157 unsigned long data_allocated; /* used for realloc() handling */
158 int sh_name; /* elf section name (only used during output) */
159 int sh_num; /* elf section number */
160 int sh_type; /* elf section type */
161 int sh_flags; /* elf section flags */
162 int sh_info; /* elf section info */
163 int sh_addralign; /* elf section alignment */
164 int sh_entsize; /* elf entry size */
165 unsigned long sh_size; /* section size (only used during output) */
166 unsigned long sh_addr; /* address at which the section is relocated */
167 unsigned long sh_offset; /* address at which the section is relocated */
168 int nb_hashed_syms; /* used to resize the hash table */
169 struct Section *link; /* link to another section */
170 struct Section *reloc; /* corresponding section for relocation, if any */
171 struct Section *hash; /* hash table for symbols */
172 struct Section *next;
173 char name[64]; /* section name */
174 } Section;
176 typedef struct DLLReference {
177 int level;
178 char name[1];
179 } DLLReference;
181 /* GNUC attribute definition */
182 typedef struct AttributeDef {
183 int aligned;
184 Section *section;
185 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
186 } AttributeDef;
188 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
189 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
190 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
192 /* stored in 'Sym.c' field */
193 #define FUNC_NEW 1 /* ansi function prototype */
194 #define FUNC_OLD 2 /* old function prototype */
195 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
197 /* stored in 'Sym.r' field */
198 #define FUNC_CDECL 0 /* standard c call */
199 #define FUNC_STDCALL 1 /* pascal c call */
201 /* field 'Sym.t' for macros */
202 #define MACRO_OBJ 0 /* object like macro */
203 #define MACRO_FUNC 1 /* function like macro */
205 /* field 'Sym.r' for labels */
206 #define LABEL_FORWARD 1 /* label is forward defined */
208 /* type_decl() types */
209 #define TYPE_ABSTRACT 1 /* type without variable */
210 #define TYPE_DIRECT 2 /* type with variable */
212 #define IO_BUF_SIZE 8192
214 typedef struct BufferedFile {
215 uint8_t *buf_ptr;
216 uint8_t *buf_end;
217 int fd;
218 int line_num; /* current line number - here to simply code */
219 int ifndef_macro; /* #ifndef macro / #endif search */
220 int ifndef_macro_saved; /* saved ifndef_macro */
221 int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
222 char inc_type; /* type of include */
223 char inc_filename[512]; /* filename specified by the user */
224 char filename[1024]; /* current filename - here to simplify code */
225 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
226 } BufferedFile;
228 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
229 #define CH_EOF (-1) /* end of file */
231 /* parsing state (used to save parser state to reparse part of the
232 source several times) */
233 typedef struct ParseState {
234 int *macro_ptr;
235 int line_num;
236 int tok;
237 CValue tokc;
238 } ParseState;
240 /* used to record tokens */
241 typedef struct TokenString {
242 int *str;
243 int len;
244 int allocated_len;
245 int last_line_num;
246 } TokenString;
248 /* include file cache, used to find files faster and also to eliminate
249 inclusion if the include file is protected by #ifndef ... #endif */
250 typedef struct CachedInclude {
251 int ifndef_macro;
252 char type; /* '"' or '>' to give include type */
253 char filename[1]; /* path specified in #include */
254 } CachedInclude;
256 /* parser */
257 static struct BufferedFile *file;
258 static int ch, tok, tok1;
259 static CValue tokc, tok1c;
260 static CString tokcstr; /* current parsed string, if any */
261 /* additionnal informations about token */
262 static int tok_flags;
263 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
264 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
265 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
267 /* if true, line feed is returned as a token. line feed is also
268 returned at eof */
269 static int return_linefeed;
270 static Section *text_section, *data_section, *bss_section; /* predefined sections */
271 static Section *cur_text_section; /* current section where function code is
272 generated */
273 /* bound check related sections */
274 static Section *bounds_section; /* contains global data bound description */
275 static Section *lbounds_section; /* contains local data bound description */
276 /* symbol sections */
277 static Section *symtab_section, *strtab_section;
279 /* debug sections */
280 static Section *stab_section, *stabstr_section;
282 /* loc : local variable index
283 ind : output code index
284 rsym: return symbol
285 anon_sym: anonymous symbol index
287 static int rsym, anon_sym, ind, loc;
288 /* expression generation modifiers */
289 static int const_wanted; /* true if constant wanted */
290 static int nocode_wanted; /* true if no code generation wanted for an expression */
291 static int global_expr; /* true if compound literals must be allocated
292 globally (used during initializers parsing */
293 static CType func_vt; /* current function return type (used by return
294 instruction) */
295 static int func_vc;
296 static int last_line_num, last_ind, func_ind; /* debug last line number and pc */
297 static int tok_ident;
298 static TokenSym **table_ident;
299 static TokenSym *hash_ident[TOK_HASH_SIZE];
300 static char token_buf[STRING_MAX_SIZE + 1];
301 static char *funcname;
302 static Sym *global_stack, *local_stack;
303 static Sym *define_stack;
304 static Sym *label_stack;
306 static SValue vstack[VSTACK_SIZE], *vtop;
307 static int *macro_ptr, *macro_ptr_allocated;
308 /* some predefined types */
309 static CType char_pointer_type, func_old_type, int_type;
311 /* compile with debug symbol (and use them if error during execution) */
312 static int do_debug = 0;
314 /* compile with built-in memory and bounds checker */
315 static int do_bounds_check = 0;
317 /* display benchmark infos */
318 static int do_bench = 0;
319 static int total_lines;
320 static int total_bytes;
322 /* use GNU C extensions */
323 static int gnu_ext = 1;
325 /* use Tiny C extensions */
326 static int tcc_ext = 1;
328 /* max number of callers shown if error */
329 static int num_callers = 6;
330 static const char **rt_bound_error_msg;
332 /* XXX: suppress that ASAP */
333 static struct TCCState *tcc_state;
335 /* give the path of the tcc libraries */
336 static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc";
338 struct TCCState {
339 int output_type;
341 BufferedFile **include_stack_ptr;
342 int *ifdef_stack_ptr;
344 /* include file handling */
345 char **include_paths;
346 int nb_include_paths;
347 char **sysinclude_paths;
348 int nb_sysinclude_paths;
349 CachedInclude **cached_includes;
350 int nb_cached_includes;
352 char **library_paths;
353 int nb_library_paths;
355 /* array of all loaded dlls (including those referenced by loaded
356 dlls) */
357 DLLReference **loaded_dlls;
358 int nb_loaded_dlls;
360 /* sections */
361 Section **sections;
362 int nb_sections; /* number of sections, including first dummy section */
364 /* got handling */
365 Section *got;
366 unsigned long *got_offsets;
367 int nb_got_offsets;
368 int nb_plt_entries;
369 /* give the correspondance from symtab indexes to dynsym indexes */
370 int *symtab_to_dynsym;
372 /* temporary dynamic symbol sections (for dll loading) */
373 Section *dynsymtab_section;
374 /* exported dynamic symbol section */
375 Section *dynsym;
377 /* if true, static linking is performed */
378 int static_link;
380 /* error handling */
381 void *error_opaque;
382 void (*error_func)(void *opaque, const char *msg);
383 int error_set_jmp_enabled;
384 jmp_buf error_jmp_buf;
385 int nb_errors;
387 /* see include_stack_ptr */
388 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
390 /* see ifdef_stack_ptr */
391 int ifdef_stack[IFDEF_STACK_SIZE];
394 /* The current value can be: */
395 #define VT_VALMASK 0x00ff
396 #define VT_CONST 0x00f0 /* constant in vc
397 (must be first non register value) */
398 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
399 #define VT_LOCAL 0x00f2 /* offset on stack */
400 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
401 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
402 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
403 #define VT_LVAL 0x0100 /* var is an lvalue */
404 #define VT_SYM 0x0200 /* a symbol value is added */
405 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
406 char/short stored in integer registers) */
407 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
408 dereferencing value */
409 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
410 bounding function call point is in vc */
411 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
412 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
413 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
414 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
416 /* types */
417 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
419 #define VT_INT 0 /* integer type */
420 #define VT_BYTE 1 /* signed byte type */
421 #define VT_SHORT 2 /* short type */
422 #define VT_VOID 3 /* void type */
423 #define VT_PTR 4 /* pointer */
424 #define VT_ENUM 5 /* enum definition */
425 #define VT_FUNC 6 /* function type */
426 #define VT_STRUCT 7 /* struct/union definition */
427 #define VT_FLOAT 8 /* IEEE float */
428 #define VT_DOUBLE 9 /* IEEE double */
429 #define VT_LDOUBLE 10 /* IEEE long double */
430 #define VT_BOOL 11 /* ISOC99 boolean type */
431 #define VT_LLONG 12 /* 64 bit integer */
432 #define VT_LONG 13 /* long integer (NEVER USED as type, only
433 during parsing) */
434 #define VT_BTYPE 0x000f /* mask for basic type */
435 #define VT_UNSIGNED 0x0010 /* unsigned type */
436 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
437 #define VT_BITFIELD 0x0040 /* bitfield modifier */
439 /* storage */
440 #define VT_EXTERN 0x00000080 /* extern definition */
441 #define VT_STATIC 0x00000100 /* static variable */
442 #define VT_TYPEDEF 0x00000200 /* typedef definition */
444 /* type mask (except storage) */
445 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
447 /* token values */
449 /* warning: the following compare tokens depend on i386 asm code */
450 #define TOK_ULT 0x92
451 #define TOK_UGE 0x93
452 #define TOK_EQ 0x94
453 #define TOK_NE 0x95
454 #define TOK_ULE 0x96
455 #define TOK_UGT 0x97
456 #define TOK_LT 0x9c
457 #define TOK_GE 0x9d
458 #define TOK_LE 0x9e
459 #define TOK_GT 0x9f
461 #define TOK_LAND 0xa0
462 #define TOK_LOR 0xa1
464 #define TOK_DEC 0xa2
465 #define TOK_MID 0xa3 /* inc/dec, to void constant */
466 #define TOK_INC 0xa4
467 #define TOK_UDIV 0xb0 /* unsigned division */
468 #define TOK_UMOD 0xb1 /* unsigned modulo */
469 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
470 #define TOK_CINT 0xb3 /* number in tokc */
471 #define TOK_CCHAR 0xb4 /* char constant in tokc */
472 #define TOK_STR 0xb5 /* pointer to string in tokc */
473 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
474 #define TOK_LCHAR 0xb7
475 #define TOK_LSTR 0xb8
476 #define TOK_CFLOAT 0xb9 /* float constant */
477 #define TOK_LINENUM 0xba /* line number info */
478 #define TOK_CDOUBLE 0xc0 /* double constant */
479 #define TOK_CLDOUBLE 0xc1 /* long double constant */
480 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
481 #define TOK_ADDC1 0xc3 /* add with carry generation */
482 #define TOK_ADDC2 0xc4 /* add with carry use */
483 #define TOK_SUBC1 0xc5 /* add with carry generation */
484 #define TOK_SUBC2 0xc6 /* add with carry use */
485 #define TOK_CUINT 0xc8 /* unsigned int constant */
486 #define TOK_CLLONG 0xc9 /* long long constant */
487 #define TOK_CULLONG 0xca /* unsigned long long constant */
488 #define TOK_ARROW 0xcb
489 #define TOK_DOTS 0xcc /* three dots */
490 #define TOK_SHR 0xcd /* unsigned shift right */
491 #define TOK_PPNUM 0xce /* preprocessor number */
493 #define TOK_SHL 0x01 /* shift left */
494 #define TOK_SAR 0x02 /* signed shift right */
496 /* assignement operators : normal operator or 0x80 */
497 #define TOK_A_MOD 0xa5
498 #define TOK_A_AND 0xa6
499 #define TOK_A_MUL 0xaa
500 #define TOK_A_ADD 0xab
501 #define TOK_A_SUB 0xad
502 #define TOK_A_DIV 0xaf
503 #define TOK_A_XOR 0xde
504 #define TOK_A_OR 0xfc
505 #define TOK_A_SHL 0x81
506 #define TOK_A_SAR 0x82
508 /* WARNING: the content of this string encodes token numbers */
509 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";
511 #define TOK_EOF (-1) /* end of file */
512 #define TOK_LINEFEED 10 /* line feed */
514 /* all identificators and strings have token above that */
515 #define TOK_IDENT 256
517 enum {
518 TOK_LAST = TOK_IDENT - 1,
519 #define DEF(id, str) id,
520 #include "tcctok.h"
521 #undef DEF
524 static const char *tcc_keywords =
525 #define DEF(id, str) str "\0"
526 #include "tcctok.h"
527 #undef DEF
530 #define TOK_UIDENT TOK_DEFINE
532 #ifdef WIN32
533 #define snprintf _snprintf
534 #define vsnprintf _vsnprintf
535 #endif
537 #if defined(WIN32) || defined(TCC_UCLIBC)
538 /* currently incorrect */
539 long double strtold(const char *nptr, char **endptr)
541 return (long double)strtod(nptr, endptr);
543 float strtof(const char *nptr, char **endptr)
545 return (float)strtod(nptr, endptr);
547 #else
548 /* XXX: need to define this to use them in non ISOC99 context */
549 extern float strtof (const char *__nptr, char **__endptr);
550 extern long double strtold (const char *__nptr, char **__endptr);
551 #endif
553 static char *pstrcpy(char *buf, int buf_size, const char *s);
554 static char *pstrcat(char *buf, int buf_size, const char *s);
556 static void next(void);
557 static void next_nomacro(void);
558 static void parse_expr_type(CType *type);
559 static void expr_type(CType *type);
560 static void unary_type(CType *type);
561 static int expr_const(void);
562 static void expr_eq(void);
563 static void gexpr(void);
564 static void decl(int l);
565 static void decl_initializer(CType *type, Section *sec, unsigned long c,
566 int first, int size_only);
567 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
568 int has_init, int v, int scope);
569 int gv(int rc);
570 void gv2(int rc1, int rc2);
571 void move_reg(int r, int s);
572 void save_regs(int n);
573 void save_reg(int r);
574 void vpop(void);
575 void vswap(void);
576 void vdup(void);
577 int get_reg(int rc);
579 static void macro_subst(TokenString *tok_str,
580 Sym **nested_list, int *macro_str);
581 int save_reg_forced(int r);
582 void gen_op(int op);
583 void force_charshort_cast(int t);
584 static void gen_cast(CType *type);
585 void vstore(void);
586 static Sym *sym_find(int v);
587 static Sym *sym_push(int v, CType *type, int r, int c);
589 /* type handling */
590 static int type_size(CType *type, int *a);
591 static inline CType *pointed_type(CType *type);
592 static int pointed_size(CType *type);
593 static int lvalue_type(int t);
594 static int is_compatible_types(CType *type1, CType *type2);
595 static int parse_btype(CType *type, AttributeDef *ad);
596 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
598 void error(const char *fmt, ...);
599 void vpushi(int v);
600 void vset(CType *type, int r, int v);
601 void type_to_str(char *buf, int buf_size,
602 CType *type, const char *varstr);
603 char *get_tok_str(int v, CValue *cv);
604 static Sym *get_sym_ref(CType *type, Section *sec,
605 unsigned long offset, unsigned long size);
606 static Sym *external_global_sym(int v, CType *type, int r);
608 /* section generation */
609 static void section_realloc(Section *sec, unsigned long new_size);
610 static void *section_ptr_add(Section *sec, unsigned long size);
611 static void put_extern_sym(Sym *sym, Section *section,
612 unsigned long value, unsigned long size);
613 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
614 static int put_elf_str(Section *s, const char *sym);
615 static int put_elf_sym(Section *s,
616 unsigned long value, unsigned long size,
617 int info, int other, int shndx, const char *name);
618 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
619 int info, int sh_num, const char *name);
620 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
621 int type, int symbol);
622 static void put_stabs(const char *str, int type, int other, int desc,
623 unsigned long value);
624 static void put_stabs_r(const char *str, int type, int other, int desc,
625 unsigned long value, Section *sec, int sym_index);
626 static void put_stabn(int type, int other, int desc, int value);
627 static void put_stabd(int type, int other, int desc);
628 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
630 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
631 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
632 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
634 /* true if float/double/long double type */
635 static inline int is_float(int t)
637 int bt;
638 bt = t & VT_BTYPE;
639 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
642 #ifdef TCC_TARGET_I386
643 #include "i386-gen.c"
644 #endif
645 #ifdef TCC_TARGET_IL
646 #include "il-gen.c"
647 #endif
649 #ifdef CONFIG_TCC_STATIC
651 #define RTLD_LAZY 0x001
652 #define RTLD_NOW 0x002
653 #define RTLD_GLOBAL 0x100
654 #define RTLD_DEFAULT NULL
656 /* dummy function for profiling */
657 void *dlopen(const char *filename, int flag)
659 return NULL;
662 const char *dlerror(void)
664 return "error";
667 typedef struct TCCSyms {
668 char *str;
669 void *ptr;
670 } TCCSyms;
672 #define TCCSYM(a) { #a, &a, },
674 /* add the symbol you want here if no dynamic linking is done */
675 static TCCSyms tcc_syms[] = {
676 TCCSYM(printf)
677 TCCSYM(fprintf)
678 TCCSYM(fopen)
679 TCCSYM(fclose)
680 { NULL, NULL },
683 void *dlsym(void *handle, const char *symbol)
685 TCCSyms *p;
686 p = tcc_syms;
687 while (p->str != NULL) {
688 if (!strcmp(p->str, symbol))
689 return p->ptr;
690 p++;
692 return NULL;
695 #endif
697 /********************************************************/
699 /* we use our own 'finite' function to avoid potential problems with
700 non standard math libs */
701 /* XXX: endianness dependant */
702 int ieee_finite(double d)
704 int *p = (int *)&d;
705 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
708 /* copy a string and truncate it. */
709 static char *pstrcpy(char *buf, int buf_size, const char *s)
711 char *q, *q_end;
712 int c;
714 if (buf_size > 0) {
715 q = buf;
716 q_end = buf + buf_size - 1;
717 while (q < q_end) {
718 c = *s++;
719 if (c == '\0')
720 break;
721 *q++ = c;
723 *q = '\0';
725 return buf;
728 /* strcat and truncate. */
729 static char *pstrcat(char *buf, int buf_size, const char *s)
731 int len;
732 len = strlen(buf);
733 if (len < buf_size)
734 pstrcpy(buf + len, buf_size - len, s);
735 return buf;
738 /* memory management */
739 #ifdef MEM_DEBUG
740 int mem_cur_size;
741 int mem_max_size;
742 #endif
744 static inline void tcc_free(void *ptr)
746 #ifdef MEM_DEBUG
747 mem_cur_size -= malloc_usable_size(ptr);
748 #endif
749 free(ptr);
752 static void *tcc_malloc(unsigned long size)
754 void *ptr;
755 ptr = malloc(size);
756 if (!ptr && size)
757 error("memory full");
758 #ifdef MEM_DEBUG
759 mem_cur_size += malloc_usable_size(ptr);
760 if (mem_cur_size > mem_max_size)
761 mem_max_size = mem_cur_size;
762 #endif
763 return ptr;
766 static void *tcc_mallocz(unsigned long size)
768 void *ptr;
769 ptr = tcc_malloc(size);
770 memset(ptr, 0, size);
771 return ptr;
774 static inline void *tcc_realloc(void *ptr, unsigned long size)
776 void *ptr1;
777 #ifdef MEM_DEBUG
778 mem_cur_size -= malloc_usable_size(ptr);
779 #endif
780 ptr1 = realloc(ptr, size);
781 #ifdef MEM_DEBUG
782 /* NOTE: count not correct if alloc error, but not critical */
783 mem_cur_size += malloc_usable_size(ptr1);
784 if (mem_cur_size > mem_max_size)
785 mem_max_size = mem_cur_size;
786 #endif
787 return ptr1;
790 static char *tcc_strdup(const char *str)
792 char *ptr;
793 ptr = tcc_malloc(strlen(str) + 1);
794 strcpy(ptr, str);
795 return ptr;
798 #define free(p) use_tcc_free(p)
799 #define malloc(s) use_tcc_malloc(s)
800 #define realloc(p, s) use_tcc_realloc(p, s)
802 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
804 int nb, nb_alloc;
805 void **pp;
807 nb = *nb_ptr;
808 pp = *ptab;
809 /* every power of two we double array size */
810 if ((nb & (nb - 1)) == 0) {
811 if (!nb)
812 nb_alloc = 1;
813 else
814 nb_alloc = nb * 2;
815 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
816 if (!pp)
817 error("memory full");
818 *ptab = pp;
820 pp[nb++] = data;
821 *nb_ptr = nb;
824 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
826 Section *sec;
828 sec = tcc_mallocz(sizeof(Section));
829 pstrcpy(sec->name, sizeof(sec->name), name);
830 sec->sh_type = sh_type;
831 sec->sh_flags = sh_flags;
832 switch(sh_type) {
833 case SHT_HASH:
834 case SHT_REL:
835 case SHT_DYNSYM:
836 case SHT_SYMTAB:
837 case SHT_DYNAMIC:
838 sec->sh_addralign = 4;
839 break;
840 case SHT_STRTAB:
841 sec->sh_addralign = 1;
842 break;
843 default:
844 sec->sh_addralign = 32; /* default conservative alignment */
845 break;
848 /* only add section if not private */
849 if (!(sh_flags & SHF_PRIVATE)) {
850 sec->sh_num = s1->nb_sections;
851 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
853 return sec;
856 static void free_section(Section *s)
858 tcc_free(s->data);
859 tcc_free(s);
862 /* realloc section and set its content to zero */
863 static void section_realloc(Section *sec, unsigned long new_size)
865 unsigned long size;
866 unsigned char *data;
868 size = sec->data_allocated;
869 if (size == 0)
870 size = 1;
871 while (size < new_size)
872 size = size * 2;
873 data = tcc_realloc(sec->data, size);
874 if (!data)
875 error("memory full");
876 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
877 sec->data = data;
878 sec->data_allocated = size;
881 /* reserve at least 'size' bytes in section 'sec' from
882 sec->data_offset. */
883 static void *section_ptr_add(Section *sec, unsigned long size)
885 unsigned long offset, offset1;
887 offset = sec->data_offset;
888 offset1 = offset + size;
889 if (offset1 > sec->data_allocated)
890 section_realloc(sec, offset1);
891 sec->data_offset = offset1;
892 return sec->data + offset;
895 /* return a reference to a section, and create it if it does not
896 exists */
897 Section *find_section(TCCState *s1, const char *name)
899 Section *sec;
900 int i;
901 for(i = 1; i < s1->nb_sections; i++) {
902 sec = s1->sections[i];
903 if (!strcmp(name, sec->name))
904 return sec;
906 /* sections are created as PROGBITS */
907 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
910 /* update sym->c so that it points to an external symbol in section
911 'section' with value 'value' */
912 static void put_extern_sym(Sym *sym, Section *section,
913 unsigned long value, unsigned long size)
915 int sym_type, sym_bind, sh_num, info;
916 Elf32_Sym *esym;
917 const char *name;
919 if (section)
920 sh_num = section->sh_num;
921 else
922 sh_num = SHN_UNDEF;
923 if (!sym->c) {
924 if ((sym->type.t & VT_BTYPE) == VT_FUNC)
925 sym_type = STT_FUNC;
926 else
927 sym_type = STT_OBJECT;
928 if (sym->type.t & VT_STATIC)
929 sym_bind = STB_LOCAL;
930 else
931 sym_bind = STB_GLOBAL;
933 name = get_tok_str(sym->v, NULL);
934 #ifdef CONFIG_TCC_BCHECK
935 if (do_bounds_check) {
936 char buf[32];
938 /* XXX: avoid doing that for statics ? */
939 /* if bound checking is activated, we change some function
940 names by adding the "__bound" prefix */
941 switch(sym->v) {
942 #if 0
943 /* XXX: we rely only on malloc hooks */
944 case TOK_malloc:
945 case TOK_free:
946 case TOK_realloc:
947 case TOK_memalign:
948 case TOK_calloc:
949 #endif
950 case TOK_memcpy:
951 case TOK_memmove:
952 case TOK_memset:
953 case TOK_strlen:
954 case TOK_strcpy:
955 strcpy(buf, "__bound_");
956 strcat(buf, name);
957 name = buf;
958 break;
961 #endif
962 info = ELF32_ST_INFO(sym_bind, sym_type);
963 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
964 } else {
965 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
966 esym->st_value = value;
967 esym->st_size = size;
968 esym->st_shndx = sh_num;
972 /* add a new relocation entry to symbol 'sym' in section 's' */
973 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
975 if (!sym->c)
976 put_extern_sym(sym, NULL, 0, 0);
977 /* now we can add ELF relocation info */
978 put_elf_reloc(symtab_section, s, offset, type, sym->c);
981 static inline int isid(int c)
983 return (c >= 'a' && c <= 'z') ||
984 (c >= 'A' && c <= 'Z') ||
985 c == '_';
988 static inline int isnum(int c)
990 return c >= '0' && c <= '9';
993 static inline int isoct(int c)
995 return c >= '0' && c <= '7';
998 static inline int toup(int c)
1000 if (c >= 'a' && c <= 'z')
1001 return c - 'a' + 'A';
1002 else
1003 return c;
1006 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
1008 int len;
1009 len = strlen(buf);
1010 vsnprintf(buf + len, buf_size - len, fmt, ap);
1013 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
1015 va_list ap;
1016 va_start(ap, fmt);
1017 strcat_vprintf(buf, buf_size, fmt, ap);
1018 va_end(ap);
1021 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
1023 char buf[2048];
1024 BufferedFile **f;
1026 buf[0] = '\0';
1027 if (file) {
1028 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1029 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1030 (*f)->filename, (*f)->line_num);
1031 if (file->line_num > 0) {
1032 strcat_printf(buf, sizeof(buf),
1033 "%s:%d: ", file->filename, file->line_num);
1034 } else {
1035 strcat_printf(buf, sizeof(buf),
1036 "%s: ", file->filename);
1038 } else {
1039 strcat_printf(buf, sizeof(buf),
1040 "tcc: ");
1042 if (is_warning)
1043 strcat_printf(buf, sizeof(buf), "warning: ");
1044 strcat_vprintf(buf, sizeof(buf), fmt, ap);
1046 if (!s1->error_func) {
1047 /* default case: stderr */
1048 fprintf(stderr, "%s\n", buf);
1049 } else {
1050 s1->error_func(s1->error_opaque, buf);
1052 if (!is_warning)
1053 s1->nb_errors++;
1056 #ifdef LIBTCC
1057 void tcc_set_error_func(TCCState *s, void *error_opaque,
1058 void (*error_func)(void *opaque, const char *msg))
1060 s->error_opaque = error_opaque;
1061 s->error_func = error_func;
1063 #endif
1065 /* error without aborting current compilation */
1066 void error_noabort(const char *fmt, ...)
1068 TCCState *s1 = tcc_state;
1069 va_list ap;
1071 va_start(ap, fmt);
1072 error1(s1, 0, fmt, ap);
1073 va_end(ap);
1076 void error(const char *fmt, ...)
1078 TCCState *s1 = tcc_state;
1079 va_list ap;
1081 va_start(ap, fmt);
1082 error1(s1, 0, fmt, ap);
1083 va_end(ap);
1084 /* better than nothing: in some cases, we accept to handle errors */
1085 if (s1->error_set_jmp_enabled) {
1086 longjmp(s1->error_jmp_buf, 1);
1087 } else {
1088 /* XXX: suppress it someday */
1089 exit(1);
1093 void expect(const char *msg)
1095 error("%s expected", msg);
1098 void warning(const char *fmt, ...)
1100 TCCState *s1 = tcc_state;
1101 va_list ap;
1103 va_start(ap, fmt);
1104 error1(s1, 1, fmt, ap);
1105 va_end(ap);
1108 void skip(int c)
1110 if (tok != c)
1111 error("'%c' expected", c);
1112 next();
1115 void test_lvalue(void)
1117 if (!(vtop->r & VT_LVAL))
1118 expect("lvalue");
1121 /* allocate a new token */
1122 static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
1124 TokenSym *ts, **ptable;
1125 int i;
1127 if (tok_ident >= SYM_FIRST_ANOM)
1128 error("memory full");
1130 /* expand token table if needed */
1131 i = tok_ident - TOK_IDENT;
1132 if ((i % TOK_ALLOC_INCR) == 0) {
1133 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1134 if (!ptable)
1135 error("memory full");
1136 table_ident = ptable;
1139 ts = tcc_malloc(sizeof(TokenSym) + len);
1140 table_ident[i] = ts;
1141 ts->tok = tok_ident++;
1142 ts->sym_define = NULL;
1143 ts->sym_label = NULL;
1144 ts->sym_struct = NULL;
1145 ts->sym_identifier = NULL;
1146 ts->len = len;
1147 ts->hash_next = NULL;
1148 memcpy(ts->str, str, len);
1149 ts->str[len] = '\0';
1150 *pts = ts;
1151 return ts;
1154 #define TOK_HASH_INIT 1
1155 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1157 /* find a token and add it if not found */
1158 static TokenSym *tok_alloc(const char *str, int len)
1160 TokenSym *ts, **pts;
1161 int i;
1162 unsigned int h;
1164 h = TOK_HASH_INIT;
1165 for(i=0;i<len;i++)
1166 h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
1167 h &= (TOK_HASH_SIZE - 1);
1169 pts = &hash_ident[h];
1170 for(;;) {
1171 ts = *pts;
1172 if (!ts)
1173 break;
1174 if (ts->len == len && !memcmp(ts->str, str, len))
1175 return ts;
1176 pts = &(ts->hash_next);
1178 return tok_alloc_new(pts, str, len);
1181 /* CString handling */
1183 static void cstr_realloc(CString *cstr, int new_size)
1185 int size;
1186 void *data;
1188 size = cstr->size_allocated;
1189 if (size == 0)
1190 size = 8; /* no need to allocate a too small first string */
1191 while (size < new_size)
1192 size = size * 2;
1193 data = tcc_realloc(cstr->data_allocated, size);
1194 if (!data)
1195 error("memory full");
1196 cstr->data_allocated = data;
1197 cstr->size_allocated = size;
1198 cstr->data = data;
1201 /* add a byte */
1202 static void cstr_ccat(CString *cstr, int ch)
1204 int size;
1205 size = cstr->size + 1;
1206 if (size > cstr->size_allocated)
1207 cstr_realloc(cstr, size);
1208 ((unsigned char *)cstr->data)[size - 1] = ch;
1209 cstr->size = size;
1212 static void cstr_cat(CString *cstr, const char *str)
1214 int c;
1215 for(;;) {
1216 c = *str;
1217 if (c == '\0')
1218 break;
1219 cstr_ccat(cstr, c);
1220 str++;
1224 /* add a wide char */
1225 static void cstr_wccat(CString *cstr, int ch)
1227 int size;
1228 size = cstr->size + sizeof(int);
1229 if (size > cstr->size_allocated)
1230 cstr_realloc(cstr, size);
1231 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1232 cstr->size = size;
1235 static void cstr_new(CString *cstr)
1237 memset(cstr, 0, sizeof(CString));
1240 /* free string and reset it to NULL */
1241 static void cstr_free(CString *cstr)
1243 tcc_free(cstr->data_allocated);
1244 cstr_new(cstr);
1247 #define cstr_reset(cstr) cstr_free(cstr)
1249 static CString *cstr_dup(CString *cstr1)
1251 CString *cstr;
1252 int size;
1254 cstr = tcc_malloc(sizeof(CString));
1255 size = cstr1->size;
1256 cstr->size = size;
1257 cstr->size_allocated = size;
1258 cstr->data_allocated = tcc_malloc(size);
1259 cstr->data = cstr->data_allocated;
1260 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1261 return cstr;
1264 /* XXX: unicode ? */
1265 static void add_char(CString *cstr, int c)
1267 if (c == '\'' || c == '\"' || c == '\\') {
1268 /* XXX: could be more precise if char or string */
1269 cstr_ccat(cstr, '\\');
1271 if (c >= 32 && c <= 126) {
1272 cstr_ccat(cstr, c);
1273 } else {
1274 cstr_ccat(cstr, '\\');
1275 if (c == '\n') {
1276 cstr_ccat(cstr, 'n');
1277 } else {
1278 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1279 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1280 cstr_ccat(cstr, '0' + (c & 7));
1285 /* XXX: buffer overflow */
1286 /* XXX: float tokens */
1287 char *get_tok_str(int v, CValue *cv)
1289 static char buf[STRING_MAX_SIZE + 1];
1290 static CString cstr_buf;
1291 CString *cstr;
1292 unsigned char *q;
1293 char *p;
1294 int i, len;
1296 /* NOTE: to go faster, we give a fixed buffer for small strings */
1297 cstr_reset(&cstr_buf);
1298 cstr_buf.data = buf;
1299 cstr_buf.size_allocated = sizeof(buf);
1300 p = buf;
1302 switch(v) {
1303 case TOK_CINT:
1304 case TOK_CUINT:
1305 /* XXX: not quite exact, but only useful for testing */
1306 sprintf(p, "%u", cv->ui);
1307 break;
1308 case TOK_CLLONG:
1309 case TOK_CULLONG:
1310 /* XXX: not quite exact, but only useful for testing */
1311 sprintf(p, "%Lu", cv->ull);
1312 break;
1313 case TOK_CCHAR:
1314 case TOK_LCHAR:
1315 cstr_ccat(&cstr_buf, '\'');
1316 add_char(&cstr_buf, cv->i);
1317 cstr_ccat(&cstr_buf, '\'');
1318 cstr_ccat(&cstr_buf, '\0');
1319 break;
1320 case TOK_PPNUM:
1321 cstr = cv->cstr;
1322 len = cstr->size - 1;
1323 for(i=0;i<len;i++)
1324 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1325 cstr_ccat(&cstr_buf, '\0');
1326 break;
1327 case TOK_STR:
1328 case TOK_LSTR:
1329 cstr = cv->cstr;
1330 cstr_ccat(&cstr_buf, '\"');
1331 if (v == TOK_STR) {
1332 len = cstr->size - 1;
1333 for(i=0;i<len;i++)
1334 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1335 } else {
1336 len = (cstr->size / sizeof(int)) - 1;
1337 for(i=0;i<len;i++)
1338 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1340 cstr_ccat(&cstr_buf, '\"');
1341 cstr_ccat(&cstr_buf, '\0');
1342 break;
1343 case TOK_LT:
1344 v = '<';
1345 goto addv;
1346 case TOK_GT:
1347 v = '>';
1348 goto addv;
1349 case TOK_A_SHL:
1350 return strcpy(p, "<<=");
1351 case TOK_A_SAR:
1352 return strcpy(p, ">>=");
1353 default:
1354 if (v < TOK_IDENT) {
1355 /* search in two bytes table */
1356 q = tok_two_chars;
1357 while (*q) {
1358 if (q[2] == v) {
1359 *p++ = q[0];
1360 *p++ = q[1];
1361 *p = '\0';
1362 return buf;
1364 q += 3;
1366 addv:
1367 *p++ = v;
1368 *p = '\0';
1369 } else if (v < tok_ident) {
1370 return table_ident[v - TOK_IDENT]->str;
1371 } else if (v >= SYM_FIRST_ANOM) {
1372 /* special name for anonymous symbol */
1373 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1374 } else {
1375 /* should never happen */
1376 return NULL;
1378 break;
1380 return cstr_buf.data;
1383 /* push, without hashing */
1384 static Sym *sym_push2(Sym **ps, int v, int t, int c)
1386 Sym *s;
1387 s = tcc_malloc(sizeof(Sym));
1388 s->v = v;
1389 s->type.t = t;
1390 s->c = c;
1391 s->next = NULL;
1392 /* add in stack */
1393 s->prev = *ps;
1394 *ps = s;
1395 return s;
1398 /* find a symbol and return its associated structure. 's' is the top
1399 of the symbol stack */
1400 static Sym *sym_find2(Sym *s, int v)
1402 while (s) {
1403 if (s->v == v)
1404 return s;
1405 s = s->prev;
1407 return NULL;
1410 /* structure lookup */
1411 static Sym *struct_find(int v)
1413 v -= TOK_IDENT;
1414 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1415 return NULL;
1416 return table_ident[v]->sym_struct;
1419 /* find an identifier */
1420 static inline Sym *sym_find(int v)
1422 v -= TOK_IDENT;
1423 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1424 return NULL;
1425 return table_ident[v]->sym_identifier;
1428 /* push a given symbol on the symbol stack */
1429 static Sym *sym_push(int v, CType *type, int r, int c)
1431 Sym *s, **ps;
1432 TokenSym *ts;
1434 if (local_stack)
1435 ps = &local_stack;
1436 else
1437 ps = &global_stack;
1438 s = sym_push2(ps, v, type->t, c);
1439 s->type.ref = type->ref;
1440 s->r = r;
1441 /* don't record fields or anonymous symbols */
1442 /* XXX: simplify */
1443 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1444 /* record symbol in token array */
1445 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1446 if (v & SYM_STRUCT)
1447 ps = &ts->sym_struct;
1448 else
1449 ps = &ts->sym_identifier;
1450 s->prev_tok = *ps;
1451 *ps = s;
1453 return s;
1456 /* push a global identifier */
1457 static Sym *global_identifier_push(int v, int t, int c)
1459 Sym *s, **ps;
1460 s = sym_push2(&global_stack, v, t, c);
1461 /* don't record anonymous symbol */
1462 if (v < SYM_FIRST_ANOM) {
1463 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1464 /* modify the top most local identifier, so that
1465 sym_identifier will point to 's' when popped */
1466 while (*ps != NULL)
1467 ps = &(*ps)->prev_tok;
1468 s->prev_tok = NULL;
1469 *ps = s;
1471 return s;
1474 /* pop symbols until top reaches 'b' */
1475 static void sym_pop(Sym **ptop, Sym *b)
1477 Sym *s, *ss, **ps;
1478 TokenSym *ts;
1479 int v;
1481 s = *ptop;
1482 while(s != b) {
1483 ss = s->prev;
1484 v = s->v;
1485 /* remove symbol in token array */
1486 /* XXX: simplify */
1487 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1488 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1489 if (v & SYM_STRUCT)
1490 ps = &ts->sym_struct;
1491 else
1492 ps = &ts->sym_identifier;
1493 *ps = s->prev_tok;
1495 tcc_free(s);
1496 s = ss;
1498 *ptop = b;
1501 /* I/O layer */
1503 BufferedFile *tcc_open(TCCState *s1, const char *filename)
1505 int fd;
1506 BufferedFile *bf;
1508 fd = open(filename, O_RDONLY);
1509 if (fd < 0)
1510 return NULL;
1511 bf = tcc_malloc(sizeof(BufferedFile));
1512 if (!bf) {
1513 close(fd);
1514 return NULL;
1516 bf->fd = fd;
1517 bf->buf_ptr = bf->buffer;
1518 bf->buf_end = bf->buffer;
1519 bf->buffer[0] = CH_EOB; /* put eob symbol */
1520 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1521 bf->line_num = 1;
1522 bf->ifndef_macro = 0;
1523 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1524 // printf("opening '%s'\n", filename);
1525 return bf;
1528 void tcc_close(BufferedFile *bf)
1530 total_lines += bf->line_num;
1531 close(bf->fd);
1532 tcc_free(bf);
1535 /* fill input buffer and peek next char */
1536 static int tcc_peekc_slow(BufferedFile *bf)
1538 int len;
1539 /* only tries to read if really end of buffer */
1540 if (bf->buf_ptr >= bf->buf_end) {
1541 if (bf->fd != -1) {
1542 #if defined(PARSE_DEBUG)
1543 len = 8;
1544 #else
1545 len = IO_BUF_SIZE;
1546 #endif
1547 len = read(bf->fd, bf->buffer, len);
1548 if (len < 0)
1549 len = 0;
1550 } else {
1551 len = 0;
1553 total_bytes += len;
1554 bf->buf_ptr = bf->buffer;
1555 bf->buf_end = bf->buffer + len;
1556 *bf->buf_end = CH_EOB;
1558 if (bf->buf_ptr < bf->buf_end) {
1559 return bf->buf_ptr[0];
1560 } else {
1561 bf->buf_ptr = bf->buf_end;
1562 return CH_EOF;
1566 /* return the current character, handling end of block if necessary
1567 (but not stray) */
1568 static int handle_eob(void)
1570 return tcc_peekc_slow(file);
1573 /* read next char from current input file and handle end of input buffer */
1574 static inline void inp(void)
1576 ch = *(++(file->buf_ptr));
1577 /* end of buffer/file handling */
1578 if (ch == CH_EOB)
1579 ch = handle_eob();
1582 /* handle '\[\r]\n' */
1583 static void handle_stray(void)
1585 while (ch == '\\') {
1586 inp();
1587 if (ch == '\n') {
1588 file->line_num++;
1589 inp();
1590 } else if (ch == '\r') {
1591 inp();
1592 if (ch != '\n')
1593 goto fail;
1594 file->line_num++;
1595 inp();
1596 } else {
1597 fail:
1598 error("stray '\\' in program");
1603 /* skip the stray and handle the \\n case. Output an error if
1604 incorrect char after the stray */
1605 static int handle_stray1(uint8_t *p)
1607 int c;
1609 if (p >= file->buf_end) {
1610 file->buf_ptr = p;
1611 c = handle_eob();
1612 p = file->buf_ptr;
1613 if (c == '\\')
1614 goto parse_stray;
1615 } else {
1616 parse_stray:
1617 file->buf_ptr = p;
1618 ch = *p;
1619 handle_stray();
1620 p = file->buf_ptr;
1621 c = *p;
1623 return c;
1626 /* handle the complicated stray case */
1627 #define PEEKC(c, p)\
1629 p++;\
1630 c = *p;\
1631 if (c == '\\') {\
1632 c = handle_stray1(p);\
1633 p = file->buf_ptr;\
1637 /* input with '\[\r]\n' handling. Note that this function cannot
1638 handle other characters after '\', so you cannot call it inside
1639 strings or comments */
1640 static void minp(void)
1642 inp();
1643 if (ch == '\\')
1644 handle_stray();
1648 static void parse_line_comment(void)
1650 /* single line C++ comments */
1651 /* XXX: accept '\\\n' ? */
1652 inp();
1653 while (ch != '\n' && ch != CH_EOF)
1654 inp();
1657 static void parse_comment(void)
1659 uint8_t *p;
1660 int c;
1662 /* C comments */
1663 p = file->buf_ptr;
1664 p++;
1665 for(;;) {
1666 /* fast skip loop */
1667 for(;;) {
1668 c = *p;
1669 if (c == '\n' || c == '*' || c == '\\')
1670 break;
1671 p++;
1672 c = *p;
1673 if (c == '\n' || c == '*' || c == '\\')
1674 break;
1675 p++;
1677 /* now we can handle all the cases */
1678 if (c == '\n') {
1679 file->line_num++;
1680 p++;
1681 } else if (c == '*') {
1682 p++;
1683 for(;;) {
1684 c = *p;
1685 if (c == '*') {
1686 p++;
1687 } else if (c == '/') {
1688 goto end_of_comment;
1689 } else if (c == '\\') {
1690 file->buf_ptr = p;
1691 c = handle_eob();
1692 if (c == '\\') {
1693 /* skip '\\n', but if '\' followed but another
1694 char, behave asif a stray was parsed */
1695 ch = file->buf_ptr[0];
1696 while (ch == '\\') {
1697 inp();
1698 if (ch == '\n') {
1699 file->line_num++;
1700 inp();
1701 } else if (ch == '\r') {
1702 inp();
1703 if (ch == '\n') {
1704 file->line_num++;
1705 inp();
1707 } else {
1708 p = file->buf_ptr;
1709 break;
1713 p = file->buf_ptr;
1714 } else {
1715 break;
1718 } else {
1719 /* stray, eob or eof */
1720 file->buf_ptr = p;
1721 c = handle_eob();
1722 p = file->buf_ptr;
1723 if (c == CH_EOF) {
1724 error("unexpected end of file in comment");
1725 } else if (c == '\\') {
1726 p++;
1730 end_of_comment:
1731 p++;
1732 file->buf_ptr = p;
1733 ch = *p;
1736 #define cinp minp
1738 /* space exlcuding newline */
1739 static inline int is_space(int ch)
1741 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1744 static inline void skip_spaces(void)
1746 while (is_space(ch))
1747 cinp();
1750 /* skip block of text until #else, #elif or #endif. skip also pairs of
1751 #if/#endif */
1752 void preprocess_skip(void)
1754 int a, start_of_line, sep, c;
1755 uint8_t *p;
1757 p = file->buf_ptr;
1758 start_of_line = 1;
1759 a = 0;
1760 for(;;) {
1761 redo_no_start:
1762 c = *p;
1763 switch(c) {
1764 case ' ':
1765 case '\t':
1766 case '\f':
1767 case '\v':
1768 case '\r':
1769 p++;
1770 goto redo_no_start;
1771 case '\n':
1772 start_of_line = 1;
1773 file->line_num++;
1774 p++;
1775 goto redo_no_start;
1776 case '\\':
1777 file->buf_ptr = p;
1778 c = handle_eob();
1779 if (c == CH_EOF) {
1780 expect("#endif");
1781 } else if (c == '\\') {
1782 /* XXX: incorrect: should not give an error */
1783 ch = file->buf_ptr[0];
1784 handle_stray();
1786 p = file->buf_ptr;
1787 goto redo_no_start;
1788 /* skip strings */
1789 case '\"':
1790 case '\'':
1791 sep = c;
1792 p++;
1793 for(;;) {
1794 c = *p;
1795 if (c == sep) {
1796 break;
1797 } else if (c == '\\') {
1798 file->buf_ptr = p;
1799 c = handle_eob();
1800 p = file->buf_ptr;
1801 if (c == CH_EOF) {
1802 /* XXX: better error message */
1803 error("unterminated string");
1804 } else if (c == '\\') {
1805 /* ignore next char */
1806 p++;
1807 c = *p;
1808 if (c == '\\') {
1809 file->buf_ptr = p;
1810 c = handle_eob();
1811 p = file->buf_ptr;
1813 if (c == '\n')
1814 file->line_num++;
1815 else if (c != CH_EOF)
1816 p++;
1818 } else if (c == '\n') {
1819 file->line_num++;
1820 p++;
1821 } else {
1822 p++;
1825 p++;
1826 break;
1827 /* skip comments */
1828 case '/':
1829 file->buf_ptr = p;
1830 ch = *p;
1831 minp();
1832 if (ch == '*') {
1833 parse_comment();
1834 } else if (ch == '/') {
1835 parse_line_comment();
1837 p = file->buf_ptr;
1838 break;
1840 case '#':
1841 p++;
1842 if (start_of_line) {
1843 file->buf_ptr = p;
1844 next_nomacro();
1845 p = file->buf_ptr;
1846 if (a == 0 &&
1847 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1848 goto the_end;
1849 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1850 a++;
1851 else if (tok == TOK_ENDIF)
1852 a--;
1854 break;
1855 default:
1856 p++;
1857 break;
1859 start_of_line = 0;
1861 the_end: ;
1862 file->buf_ptr = p;
1865 /* ParseState handling */
1867 /* XXX: currently, no include file info is stored. Thus, we cannot display
1868 accurate messages if the function or data definition spans multiple
1869 files */
1871 /* save current parse state in 's' */
1872 void save_parse_state(ParseState *s)
1874 s->line_num = file->line_num;
1875 s->macro_ptr = macro_ptr;
1876 s->tok = tok;
1877 s->tokc = tokc;
1880 /* restore parse state from 's' */
1881 void restore_parse_state(ParseState *s)
1883 file->line_num = s->line_num;
1884 macro_ptr = s->macro_ptr;
1885 tok = s->tok;
1886 tokc = s->tokc;
1889 /* return the number of additionnal 'ints' necessary to store the
1890 token */
1891 static inline int tok_ext_size(int t)
1893 switch(t) {
1894 /* 4 bytes */
1895 case TOK_CINT:
1896 case TOK_CUINT:
1897 case TOK_CCHAR:
1898 case TOK_LCHAR:
1899 case TOK_STR:
1900 case TOK_LSTR:
1901 case TOK_CFLOAT:
1902 case TOK_LINENUM:
1903 case TOK_PPNUM:
1904 return 1;
1905 case TOK_CDOUBLE:
1906 case TOK_CLLONG:
1907 case TOK_CULLONG:
1908 return 2;
1909 case TOK_CLDOUBLE:
1910 return LDOUBLE_SIZE / 4;
1911 default:
1912 return 0;
1916 /* token string handling */
1918 static inline void tok_str_new(TokenString *s)
1920 s->str = NULL;
1921 s->len = 0;
1922 s->allocated_len = 0;
1923 s->last_line_num = -1;
1926 static void tok_str_free(int *str)
1928 const int *p;
1929 CString *cstr;
1930 int t;
1932 p = str;
1933 for(;;) {
1934 t = *p;
1935 /* NOTE: we test zero separately so that GCC can generate a
1936 table for the following switch */
1937 if (t == 0)
1938 break;
1939 switch(t) {
1940 case TOK_CINT:
1941 case TOK_CUINT:
1942 case TOK_CCHAR:
1943 case TOK_LCHAR:
1944 case TOK_CFLOAT:
1945 case TOK_LINENUM:
1946 p += 2;
1947 break;
1948 case TOK_PPNUM:
1949 case TOK_STR:
1950 case TOK_LSTR:
1951 /* XXX: use a macro to be portable on 64 bit ? */
1952 cstr = (CString *)p[1];
1953 cstr_free(cstr);
1954 tcc_free(cstr);
1955 p += 2;
1956 break;
1957 case TOK_CDOUBLE:
1958 case TOK_CLLONG:
1959 case TOK_CULLONG:
1960 p += 3;
1961 break;
1962 case TOK_CLDOUBLE:
1963 p += 1 + (LDOUBLE_SIZE / 4);
1964 break;
1965 default:
1966 p++;
1967 break;
1970 tcc_free(str);
1973 static int *tok_str_realloc(TokenString *s)
1975 int *str, len;
1977 len = s->allocated_len + TOK_STR_ALLOC_INCR;
1978 str = tcc_realloc(s->str, len * sizeof(int));
1979 if (!str)
1980 error("memory full");
1981 s->allocated_len = len;
1982 s->str = str;
1983 return str;
1986 static void tok_str_add(TokenString *s, int t)
1988 int len, *str;
1990 len = s->len;
1991 str = s->str;
1992 if (len >= s->allocated_len)
1993 str = tok_str_realloc(s);
1994 str[len++] = t;
1995 s->len = len;
1998 static void tok_str_add2(TokenString *s, int t, CValue *cv)
2000 int len, *str;
2002 len = s->len;
2003 str = s->str;
2005 /* allocate space for worst case */
2006 if (len + TOK_MAX_SIZE > s->allocated_len)
2007 str = tok_str_realloc(s);
2008 str[len++] = t;
2009 switch(t) {
2010 case TOK_CINT:
2011 case TOK_CUINT:
2012 case TOK_CCHAR:
2013 case TOK_LCHAR:
2014 case TOK_CFLOAT:
2015 case TOK_LINENUM:
2016 str[len++] = cv->tab[0];
2017 break;
2018 case TOK_PPNUM:
2019 case TOK_STR:
2020 case TOK_LSTR:
2021 str[len++] = (int)cstr_dup(cv->cstr);
2022 break;
2023 case TOK_CDOUBLE:
2024 case TOK_CLLONG:
2025 case TOK_CULLONG:
2026 str[len++] = cv->tab[0];
2027 str[len++] = cv->tab[1];
2028 break;
2029 case TOK_CLDOUBLE:
2030 #if LDOUBLE_SIZE == 12
2031 str[len++] = cv->tab[0];
2032 str[len++] = cv->tab[1];
2033 str[len++] = cv->tab[2];
2034 #else
2035 #error add long double size support
2036 #endif
2037 break;
2038 default:
2039 break;
2041 s->len = len;
2044 /* add the current parse token in token string 's' */
2045 static void tok_str_add_tok(TokenString *s)
2047 CValue cval;
2049 /* save line number info */
2050 if (file->line_num != s->last_line_num) {
2051 s->last_line_num = file->line_num;
2052 cval.i = s->last_line_num;
2053 tok_str_add2(s, TOK_LINENUM, &cval);
2055 tok_str_add2(s, tok, &tokc);
2058 #if LDOUBLE_SIZE == 12
2059 #define LDOUBLE_GET(p, cv) \
2060 cv.tab[0] = p[0]; \
2061 cv.tab[1] = p[1]; \
2062 cv.tab[2] = p[2];
2063 #else
2064 #error add long double size support
2065 #endif
2068 /* get a token from an integer array and increment pointer
2069 accordingly. we code it as a macro to avoid pointer aliasing. */
2070 #define TOK_GET(t, p, cv) \
2072 t = *p++; \
2073 switch(t) { \
2074 case TOK_CINT: \
2075 case TOK_CUINT: \
2076 case TOK_CCHAR: \
2077 case TOK_LCHAR: \
2078 case TOK_CFLOAT: \
2079 case TOK_LINENUM: \
2080 case TOK_STR: \
2081 case TOK_LSTR: \
2082 case TOK_PPNUM: \
2083 cv.tab[0] = *p++; \
2084 break; \
2085 case TOK_CDOUBLE: \
2086 case TOK_CLLONG: \
2087 case TOK_CULLONG: \
2088 cv.tab[0] = p[0]; \
2089 cv.tab[1] = p[1]; \
2090 p += 2; \
2091 break; \
2092 case TOK_CLDOUBLE: \
2093 LDOUBLE_GET(p, cv); \
2094 p += LDOUBLE_SIZE / 4; \
2095 break; \
2096 default: \
2097 break; \
2101 /* defines handling */
2102 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
2104 Sym *s;
2106 s = sym_push2(&define_stack, v, macro_type, (int)str);
2107 s->next = first_arg;
2108 table_ident[v - TOK_IDENT]->sym_define = s;
2111 /* undefined a define symbol. Its name is just set to zero */
2112 static void define_undef(Sym *s)
2114 int v;
2115 v = s->v;
2116 if (v >= TOK_IDENT && v < tok_ident)
2117 table_ident[v - TOK_IDENT]->sym_define = NULL;
2118 s->v = 0;
2121 static inline Sym *define_find(int v)
2123 v -= TOK_IDENT;
2124 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2125 return NULL;
2126 return table_ident[v]->sym_define;
2129 /* free define stack until top reaches 'b' */
2130 static void free_defines(Sym *b)
2132 Sym *top, *top1;
2133 int v;
2135 top = define_stack;
2136 while (top != b) {
2137 top1 = top->prev;
2138 /* do not free args or predefined defines */
2139 if (top->c)
2140 tok_str_free((int *)top->c);
2141 v = top->v;
2142 if (v >= TOK_IDENT && v < tok_ident)
2143 table_ident[v - TOK_IDENT]->sym_define = NULL;
2144 tcc_free(top);
2145 top = top1;
2147 define_stack = b;
2150 /* label lookup */
2151 static Sym *label_find(int v)
2153 v -= TOK_IDENT;
2154 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2155 return NULL;
2156 return table_ident[v]->sym_label;
2159 static Sym *label_push(int v, int flags)
2161 Sym *s;
2162 s = sym_push2(&label_stack, v, 0, 0);
2163 s->r = flags;
2164 table_ident[v - TOK_IDENT]->sym_label = s;
2165 return s;
2168 /* eval an expression for #if/#elif */
2169 static int expr_preprocess(void)
2171 int c, t;
2172 TokenString str;
2174 tok_str_new(&str);
2175 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2176 next(); /* do macro subst */
2177 if (tok == TOK_DEFINED) {
2178 next_nomacro();
2179 t = tok;
2180 if (t == '(')
2181 next_nomacro();
2182 c = define_find(tok) != 0;
2183 if (t == '(')
2184 next_nomacro();
2185 tok = TOK_CINT;
2186 tokc.i = c;
2187 } else if (tok >= TOK_IDENT) {
2188 /* if undefined macro */
2189 tok = TOK_CINT;
2190 tokc.i = 0;
2192 tok_str_add_tok(&str);
2194 tok_str_add(&str, -1); /* simulate end of file */
2195 tok_str_add(&str, 0);
2196 /* now evaluate C constant expression */
2197 macro_ptr = str.str;
2198 next();
2199 c = expr_const();
2200 macro_ptr = NULL;
2201 tok_str_free(str.str);
2202 return c != 0;
2205 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2206 static void tok_print(int *str)
2208 int t;
2209 CValue cval;
2211 while (1) {
2212 TOK_GET(t, str, cval);
2213 if (!t)
2214 break;
2215 printf(" %s", get_tok_str(t, &cval));
2217 printf("\n");
2219 #endif
2221 /* parse after #define */
2222 static void parse_define(void)
2224 Sym *s, *first, **ps;
2225 int v, t, varg, is_vaargs, c;
2226 TokenString str;
2228 v = tok;
2229 if (v < TOK_IDENT)
2230 error("invalid macro name '%s'", get_tok_str(tok, &tokc));
2231 /* XXX: should check if same macro (ANSI) */
2232 first = NULL;
2233 t = MACRO_OBJ;
2234 /* '(' must be just after macro definition for MACRO_FUNC */
2235 c = file->buf_ptr[0];
2236 if (c == '\\')
2237 c = handle_stray1(file->buf_ptr);
2238 if (c == '(') {
2239 next_nomacro();
2240 next_nomacro();
2241 ps = &first;
2242 while (tok != ')') {
2243 varg = tok;
2244 next_nomacro();
2245 is_vaargs = 0;
2246 if (varg == TOK_DOTS) {
2247 varg = TOK___VA_ARGS__;
2248 is_vaargs = 1;
2249 } else if (tok == TOK_DOTS && gnu_ext) {
2250 is_vaargs = 1;
2251 next_nomacro();
2253 if (varg < TOK_IDENT)
2254 error("badly punctuated parameter list");
2255 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
2256 *ps = s;
2257 ps = &s->next;
2258 if (tok != ',')
2259 break;
2260 next_nomacro();
2262 t = MACRO_FUNC;
2264 tok_str_new(&str);
2265 next_nomacro();
2266 /* EOF testing necessary for '-D' handling */
2267 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2268 tok_str_add2(&str, tok, &tokc);
2269 next_nomacro();
2271 tok_str_add(&str, 0);
2272 #ifdef PP_DEBUG
2273 printf("define %s %d: ", get_tok_str(v, NULL), t);
2274 tok_print(str.str);
2275 #endif
2276 define_push(v, t, str.str, first);
2279 /* XXX: use a token or a hash table to accelerate matching ? */
2280 static CachedInclude *search_cached_include(TCCState *s1,
2281 int type, const char *filename)
2283 CachedInclude *e;
2284 int i;
2286 for(i = 0;i < s1->nb_cached_includes; i++) {
2287 e = s1->cached_includes[i];
2288 if (e->type == type && !strcmp(e->filename, filename))
2289 return e;
2291 return NULL;
2294 static inline void add_cached_include(TCCState *s1, int type,
2295 const char *filename, int ifndef_macro)
2297 CachedInclude *e;
2299 if (search_cached_include(s1, type, filename))
2300 return;
2301 #ifdef INC_DEBUG
2302 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
2303 #endif
2304 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
2305 if (!e)
2306 return;
2307 e->type = type;
2308 strcpy(e->filename, filename);
2309 e->ifndef_macro = ifndef_macro;
2310 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
2313 /* is_bof is true if first non space token at beginning of file */
2314 static void preprocess(int is_bof)
2316 TCCState *s1 = tcc_state;
2317 int size, i, c, n;
2318 char buf[1024], *q, *p;
2319 char buf1[1024];
2320 BufferedFile *f;
2321 Sym *s;
2322 CachedInclude *e;
2324 return_linefeed = 1; /* linefeed will be returned as a
2325 token. EOF is also returned as line feed */
2326 next_nomacro();
2327 redo:
2328 switch(tok) {
2329 case TOK_DEFINE:
2330 next_nomacro();
2331 parse_define();
2332 break;
2333 case TOK_UNDEF:
2334 next_nomacro();
2335 s = define_find(tok);
2336 /* undefine symbol by putting an invalid name */
2337 if (s)
2338 define_undef(s);
2339 break;
2340 case TOK_INCLUDE:
2341 ch = file->buf_ptr[0];
2342 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2343 skip_spaces();
2344 if (ch == '<') {
2345 c = '>';
2346 goto read_name;
2347 } else if (ch == '\"') {
2348 c = ch;
2349 read_name:
2350 /* XXX: better stray handling */
2351 minp();
2352 q = buf;
2353 while (ch != c && ch != '\n' && ch != CH_EOF) {
2354 if ((q - buf) < sizeof(buf) - 1)
2355 *q++ = ch;
2356 minp();
2358 *q = '\0';
2359 minp();
2360 #if 0
2361 /* eat all spaces and comments after include */
2362 /* XXX: slightly incorrect */
2363 while (ch1 != '\n' && ch1 != CH_EOF)
2364 inp();
2365 #endif
2366 } else {
2367 /* computed #include : either we have only strings or
2368 we have anything enclosed in '<>' */
2369 next();
2370 buf[0] = '\0';
2371 if (tok == TOK_STR) {
2372 while (tok != TOK_LINEFEED) {
2373 if (tok != TOK_STR) {
2374 include_syntax:
2375 error("'#include' expects \"FILENAME\" or <FILENAME>");
2377 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2378 next();
2380 c = '\"';
2381 } else {
2382 int len;
2383 while (tok != TOK_LINEFEED) {
2384 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2385 next();
2387 len = strlen(buf);
2388 /* check syntax and remove '<>' */
2389 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2390 goto include_syntax;
2391 memmove(buf, buf + 1, len - 2);
2392 buf[len - 2] = '\0';
2393 c = '>';
2397 e = search_cached_include(s1, c, buf);
2398 if (e && define_find(e->ifndef_macro)) {
2399 /* no need to parse the include because the 'ifndef macro'
2400 is defined */
2401 #ifdef INC_DEBUG
2402 printf("%s: skipping %s\n", file->filename, buf);
2403 #endif
2404 } else {
2405 if (c == '\"') {
2406 /* first search in current dir if "header.h" */
2407 size = 0;
2408 p = strrchr(file->filename, '/');
2409 if (p)
2410 size = p + 1 - file->filename;
2411 if (size > sizeof(buf1) - 1)
2412 size = sizeof(buf1) - 1;
2413 memcpy(buf1, file->filename, size);
2414 buf1[size] = '\0';
2415 pstrcat(buf1, sizeof(buf1), buf);
2416 f = tcc_open(s1, buf1);
2417 if (f)
2418 goto found;
2420 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2421 error("#include recursion too deep");
2422 /* now search in all the include paths */
2423 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2424 for(i = 0; i < n; i++) {
2425 const char *path;
2426 if (i < s1->nb_include_paths)
2427 path = s1->include_paths[i];
2428 else
2429 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2430 pstrcpy(buf1, sizeof(buf1), path);
2431 pstrcat(buf1, sizeof(buf1), "/");
2432 pstrcat(buf1, sizeof(buf1), buf);
2433 f = tcc_open(s1, buf1);
2434 if (f)
2435 goto found;
2437 error("include file '%s' not found", buf);
2438 f = NULL;
2439 found:
2440 #ifdef INC_DEBUG
2441 printf("%s: including %s\n", file->filename, buf1);
2442 #endif
2443 f->inc_type = c;
2444 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2445 /* push current file in stack */
2446 /* XXX: fix current line init */
2447 *s1->include_stack_ptr++ = file;
2448 file = f;
2449 /* add include file debug info */
2450 if (do_debug) {
2451 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2453 tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
2454 ch = file->buf_ptr[0];
2455 goto the_end;
2457 break;
2458 case TOK_IFNDEF:
2459 c = 1;
2460 goto do_ifdef;
2461 case TOK_IF:
2462 c = expr_preprocess();
2463 goto do_if;
2464 case TOK_IFDEF:
2465 c = 0;
2466 do_ifdef:
2467 next_nomacro();
2468 if (tok < TOK_IDENT)
2469 error("invalid argument for '#if%sdef'", c ? "n" : "");
2470 if (is_bof) {
2471 if (c) {
2472 #ifdef INC_DEBUG
2473 printf("#ifndef %s\n", get_tok_str(tok, NULL));
2474 #endif
2475 file->ifndef_macro = tok;
2478 c = (define_find(tok) != 0) ^ c;
2479 do_if:
2480 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2481 error("memory full");
2482 *s1->ifdef_stack_ptr++ = c;
2483 goto test_skip;
2484 case TOK_ELSE:
2485 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2486 error("#else without matching #if");
2487 if (s1->ifdef_stack_ptr[-1] & 2)
2488 error("#else after #else");
2489 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2490 goto test_skip;
2491 case TOK_ELIF:
2492 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2493 error("#elif without matching #if");
2494 c = s1->ifdef_stack_ptr[-1];
2495 if (c > 1)
2496 error("#elif after #else");
2497 /* last #if/#elif expression was true: we skip */
2498 if (c == 1)
2499 goto skip;
2500 c = expr_preprocess();
2501 s1->ifdef_stack_ptr[-1] = c;
2502 test_skip:
2503 if (!(c & 1)) {
2504 skip:
2505 preprocess_skip();
2506 is_bof = 0;
2507 goto redo;
2509 break;
2510 case TOK_ENDIF:
2511 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2512 error("#endif without matching #if");
2513 s1->ifdef_stack_ptr--;
2514 /* '#ifndef macro' was at the start of file. Now we check if
2515 an '#endif' is exactly at the end of file */
2516 if (file->ifndef_macro &&
2517 s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
2518 file->ifndef_macro_saved = file->ifndef_macro;
2519 /* need to set to zero to avoid false matches if another
2520 #ifndef at middle of file */
2521 file->ifndef_macro = 0;
2522 while (tok != TOK_LINEFEED)
2523 next_nomacro();
2524 tok_flags |= TOK_FLAG_ENDIF;
2525 goto the_end;
2527 break;
2528 case TOK_LINE:
2529 next();
2530 if (tok != TOK_CINT)
2531 error("#line");
2532 file->line_num = tokc.i - 1; /* the line number will be incremented after */
2533 next();
2534 if (tok != TOK_LINEFEED) {
2535 if (tok != TOK_STR)
2536 error("#line");
2537 pstrcpy(file->filename, sizeof(file->filename),
2538 (char *)tokc.cstr->data);
2540 break;
2541 case TOK_ERROR:
2542 case TOK_WARNING:
2543 c = tok;
2544 ch = file->buf_ptr[0];
2545 skip_spaces();
2546 q = buf;
2547 while (ch != '\n' && ch != CH_EOF) {
2548 if ((q - buf) < sizeof(buf) - 1)
2549 *q++ = ch;
2550 minp();
2552 *q = '\0';
2553 if (c == TOK_ERROR)
2554 error("#error %s", buf);
2555 else
2556 warning("#warning %s", buf);
2557 break;
2558 case TOK_PRAGMA:
2559 /* ignored */
2560 break;
2561 default:
2562 if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
2563 /* '!' is ignored to allow C scripts. numbers are ignored
2564 to emulate cpp behaviour */
2565 } else {
2566 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
2568 break;
2570 /* ignore other preprocess commands or #! for C scripts */
2571 while (tok != TOK_LINEFEED)
2572 next_nomacro();
2573 the_end:
2574 return_linefeed = 0;
2577 /* read a number in base b */
2578 static int getn(int b)
2580 int n, t;
2581 n = 0;
2582 while (1) {
2583 if (ch >= 'a' && ch <= 'f')
2584 t = ch - 'a' + 10;
2585 else if (ch >= 'A' && ch <= 'F')
2586 t = ch - 'A' + 10;
2587 else if (isnum(ch))
2588 t = ch - '0';
2589 else
2590 break;
2591 if (t < 0 || t >= b)
2592 break;
2593 n = n * b + t;
2594 inp();
2596 return n;
2599 /* read a character for string or char constant and eval escape codes */
2600 static int getq(void)
2602 int c;
2604 redo:
2605 c = ch;
2606 inp();
2607 if (c == '\\') {
2608 switch(ch) {
2609 case '0': case '1': case '2': case '3':
2610 case '4': case '5': case '6': case '7':
2611 /* at most three octal digits */
2612 c = ch - '0';
2613 inp();
2614 if (isoct(ch)) {
2615 c = c * 8 + ch - '0';
2616 inp();
2617 if (isoct(ch)) {
2618 c = c * 8 + ch - '0';
2619 inp();
2622 return c;
2623 case 'x':
2624 inp();
2625 return getn(16);
2626 case 'a':
2627 c = '\a';
2628 break;
2629 case 'b':
2630 c = '\b';
2631 break;
2632 case 'f':
2633 c = '\f';
2634 break;
2635 case 'n':
2636 c = '\n';
2637 break;
2638 case 'r':
2639 c = '\r';
2640 break;
2641 case 't':
2642 c = '\t';
2643 break;
2644 case 'v':
2645 c = '\v';
2646 break;
2647 case 'e':
2648 if (!gnu_ext)
2649 goto invalid_escape;
2650 c = 27;
2651 break;
2652 case '\'':
2653 case '\"':
2654 case '\\':
2655 case '?':
2656 c = ch;
2657 break;
2658 case '\n':
2659 inp();
2660 goto redo;
2661 case '\r':
2662 inp();
2663 if (ch != '\n')
2664 goto invalid_escape;
2665 inp();
2666 goto redo;
2667 default:
2668 invalid_escape:
2669 error("invalid escaped char");
2671 inp();
2672 } else if (c == '\r' && ch == '\n') {
2673 inp();
2674 c = '\n';
2676 return c;
2679 /* we use 64 bit numbers */
2680 #define BN_SIZE 2
2682 /* bn = (bn << shift) | or_val */
2683 void bn_lshift(unsigned int *bn, int shift, int or_val)
2685 int i;
2686 unsigned int v;
2687 for(i=0;i<BN_SIZE;i++) {
2688 v = bn[i];
2689 bn[i] = (v << shift) | or_val;
2690 or_val = v >> (32 - shift);
2694 void bn_zero(unsigned int *bn)
2696 int i;
2697 for(i=0;i<BN_SIZE;i++) {
2698 bn[i] = 0;
2702 /* parse number in null terminated string 'p' and return it in the
2703 current token */
2704 void parse_number(const char *p)
2706 int b, t, shift, frac_bits, s, exp_val, ch;
2707 char *q;
2708 unsigned int bn[BN_SIZE];
2709 double d;
2711 /* number */
2712 q = token_buf;
2713 ch = *p++;
2714 t = ch;
2715 ch = *p++;
2716 *q++ = t;
2717 b = 10;
2718 if (t == '.') {
2719 goto float_frac_parse;
2720 } else if (t == '0') {
2721 if (ch == 'x' || ch == 'X') {
2722 q--;
2723 ch = *p++;
2724 b = 16;
2725 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2726 q--;
2727 ch = *p++;
2728 b = 2;
2731 /* parse all digits. cannot check octal numbers at this stage
2732 because of floating point constants */
2733 while (1) {
2734 if (ch >= 'a' && ch <= 'f')
2735 t = ch - 'a' + 10;
2736 else if (ch >= 'A' && ch <= 'F')
2737 t = ch - 'A' + 10;
2738 else if (isnum(ch))
2739 t = ch - '0';
2740 else
2741 break;
2742 if (t >= b)
2743 break;
2744 if (q >= token_buf + STRING_MAX_SIZE) {
2745 num_too_long:
2746 error("number too long");
2748 *q++ = ch;
2749 ch = *p++;
2751 if (ch == '.' ||
2752 ((ch == 'e' || ch == 'E') && b == 10) ||
2753 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2754 if (b != 10) {
2755 /* NOTE: strtox should support that for hexa numbers, but
2756 non ISOC99 libcs do not support it, so we prefer to do
2757 it by hand */
2758 /* hexadecimal or binary floats */
2759 /* XXX: handle overflows */
2760 *q = '\0';
2761 if (b == 16)
2762 shift = 4;
2763 else
2764 shift = 2;
2765 bn_zero(bn);
2766 q = token_buf;
2767 while (1) {
2768 t = *q++;
2769 if (t == '\0') {
2770 break;
2771 } else if (t >= 'a') {
2772 t = t - 'a' + 10;
2773 } else if (t >= 'A') {
2774 t = t - 'A' + 10;
2775 } else {
2776 t = t - '0';
2778 bn_lshift(bn, shift, t);
2780 frac_bits = 0;
2781 if (ch == '.') {
2782 ch = *p++;
2783 while (1) {
2784 t = ch;
2785 if (t >= 'a' && t <= 'f') {
2786 t = t - 'a' + 10;
2787 } else if (t >= 'A' && t <= 'F') {
2788 t = t - 'A' + 10;
2789 } else if (t >= '0' && t <= '9') {
2790 t = t - '0';
2791 } else {
2792 break;
2794 if (t >= b)
2795 error("invalid digit");
2796 bn_lshift(bn, shift, t);
2797 frac_bits += shift;
2798 ch = *p++;
2801 if (ch != 'p' && ch != 'P')
2802 expect("exponent");
2803 ch = *p++;
2804 s = 1;
2805 exp_val = 0;
2806 if (ch == '+') {
2807 ch = *p++;
2808 } else if (ch == '-') {
2809 s = -1;
2810 ch = *p++;
2812 if (ch < '0' || ch > '9')
2813 expect("exponent digits");
2814 while (ch >= '0' && ch <= '9') {
2815 exp_val = exp_val * 10 + ch - '0';
2816 ch = *p++;
2818 exp_val = exp_val * s;
2820 /* now we can generate the number */
2821 /* XXX: should patch directly float number */
2822 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
2823 d = ldexp(d, exp_val - frac_bits);
2824 t = toup(ch);
2825 if (t == 'F') {
2826 ch = *p++;
2827 tok = TOK_CFLOAT;
2828 /* float : should handle overflow */
2829 tokc.f = (float)d;
2830 } else if (t == 'L') {
2831 ch = *p++;
2832 tok = TOK_CLDOUBLE;
2833 /* XXX: not large enough */
2834 tokc.ld = (long double)d;
2835 } else {
2836 tok = TOK_CDOUBLE;
2837 tokc.d = d;
2839 } else {
2840 /* decimal floats */
2841 if (ch == '.') {
2842 if (q >= token_buf + STRING_MAX_SIZE)
2843 goto num_too_long;
2844 *q++ = ch;
2845 ch = *p++;
2846 float_frac_parse:
2847 while (ch >= '0' && ch <= '9') {
2848 if (q >= token_buf + STRING_MAX_SIZE)
2849 goto num_too_long;
2850 *q++ = ch;
2851 ch = *p++;
2854 if (ch == 'e' || ch == 'E') {
2855 if (q >= token_buf + STRING_MAX_SIZE)
2856 goto num_too_long;
2857 *q++ = ch;
2858 ch = *p++;
2859 if (ch == '-' || ch == '+') {
2860 if (q >= token_buf + STRING_MAX_SIZE)
2861 goto num_too_long;
2862 *q++ = ch;
2863 ch = *p++;
2865 if (ch < '0' || ch > '9')
2866 expect("exponent digits");
2867 while (ch >= '0' && ch <= '9') {
2868 if (q >= token_buf + STRING_MAX_SIZE)
2869 goto num_too_long;
2870 *q++ = ch;
2871 ch = *p++;
2874 *q = '\0';
2875 t = toup(ch);
2876 errno = 0;
2877 if (t == 'F') {
2878 ch = *p++;
2879 tok = TOK_CFLOAT;
2880 tokc.f = strtof(token_buf, NULL);
2881 } else if (t == 'L') {
2882 ch = *p++;
2883 tok = TOK_CLDOUBLE;
2884 tokc.ld = strtold(token_buf, NULL);
2885 } else {
2886 tok = TOK_CDOUBLE;
2887 tokc.d = strtod(token_buf, NULL);
2890 } else {
2891 unsigned long long n, n1;
2892 int lcount, ucount;
2894 /* integer number */
2895 *q = '\0';
2896 q = token_buf;
2897 if (b == 10 && *q == '0') {
2898 b = 8;
2899 q++;
2901 n = 0;
2902 while(1) {
2903 t = *q++;
2904 /* no need for checks except for base 10 / 8 errors */
2905 if (t == '\0') {
2906 break;
2907 } else if (t >= 'a') {
2908 t = t - 'a' + 10;
2909 } else if (t >= 'A') {
2910 t = t - 'A' + 10;
2911 } else {
2912 t = t - '0';
2913 if (t >= b)
2914 error("invalid digit");
2916 n1 = n;
2917 n = n * b + t;
2918 /* detect overflow */
2919 /* XXX: this test is not reliable */
2920 if (n < n1)
2921 error("integer constant overflow");
2924 /* XXX: not exactly ANSI compliant */
2925 if ((n & 0xffffffff00000000LL) != 0) {
2926 if ((n >> 63) != 0)
2927 tok = TOK_CULLONG;
2928 else
2929 tok = TOK_CLLONG;
2930 } else if (n > 0x7fffffff) {
2931 tok = TOK_CUINT;
2932 } else {
2933 tok = TOK_CINT;
2935 lcount = 0;
2936 ucount = 0;
2937 for(;;) {
2938 t = toup(ch);
2939 if (t == 'L') {
2940 if (lcount >= 2)
2941 error("three 'l's in integer constant");
2942 lcount++;
2943 if (lcount == 2) {
2944 if (tok == TOK_CINT)
2945 tok = TOK_CLLONG;
2946 else if (tok == TOK_CUINT)
2947 tok = TOK_CULLONG;
2949 ch = *p++;
2950 } else if (t == 'U') {
2951 if (ucount >= 1)
2952 error("two 'u's in integer constant");
2953 ucount++;
2954 if (tok == TOK_CINT)
2955 tok = TOK_CUINT;
2956 else if (tok == TOK_CLLONG)
2957 tok = TOK_CULLONG;
2958 ch = *p++;
2959 } else {
2960 break;
2963 if (tok == TOK_CINT || tok == TOK_CUINT)
2964 tokc.ui = n;
2965 else
2966 tokc.ull = n;
2971 #define PARSE2(c1, tok1, c2, tok2) \
2972 case c1: \
2973 PEEKC(c, p); \
2974 if (c == c2) { \
2975 p++; \
2976 tok = tok2; \
2977 } else { \
2978 tok = tok1; \
2980 break;
2982 /* return next token without macro substitution */
2983 static inline void next_nomacro1(void)
2985 int b, t, c;
2986 TokenSym *ts;
2987 uint8_t *p, *p1;
2988 unsigned int h;
2990 p = file->buf_ptr;
2991 redo_no_start:
2992 c = *p;
2993 switch(c) {
2994 case ' ':
2995 case '\t':
2996 case '\f':
2997 case '\v':
2998 case '\r':
2999 p++;
3000 goto redo_no_start;
3002 case '\\':
3003 /* first look if it is in fact an end of buffer */
3004 if (p >= file->buf_end) {
3005 file->buf_ptr = p;
3006 handle_eob();
3007 p = file->buf_ptr;
3008 if (p >= file->buf_end)
3009 goto parse_eof;
3010 else
3011 goto redo_no_start;
3012 } else {
3013 file->buf_ptr = p;
3014 ch = *p;
3015 handle_stray();
3016 p = file->buf_ptr;
3017 goto redo_no_start;
3019 parse_eof:
3021 TCCState *s1 = tcc_state;
3023 if (return_linefeed) {
3024 tok = TOK_LINEFEED;
3025 } else if (s1->include_stack_ptr == s1->include_stack) {
3026 /* no include left : end of file */
3027 tok = TOK_EOF;
3028 } else {
3029 /* pop include file */
3031 /* test if previous '#endif' was after a #ifdef at
3032 start of file */
3033 if (tok_flags & TOK_FLAG_ENDIF) {
3034 #ifdef INC_DEBUG
3035 printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
3036 #endif
3037 add_cached_include(s1, file->inc_type, file->inc_filename,
3038 file->ifndef_macro_saved);
3041 /* add end of include file debug info */
3042 if (do_debug) {
3043 put_stabd(N_EINCL, 0, 0);
3045 /* pop include stack */
3046 tcc_close(file);
3047 s1->include_stack_ptr--;
3048 file = *s1->include_stack_ptr;
3049 p = file->buf_ptr;
3050 goto redo_no_start;
3053 break;
3055 case '\n':
3056 if (return_linefeed) {
3057 tok = TOK_LINEFEED;
3058 } else {
3059 file->line_num++;
3060 tok_flags |= TOK_FLAG_BOL;
3061 p++;
3062 goto redo_no_start;
3064 break;
3066 case '#':
3067 /* XXX: simplify */
3068 PEEKC(c, p);
3069 if (tok_flags & TOK_FLAG_BOL) {
3070 file->buf_ptr = p;
3071 preprocess(tok_flags & TOK_FLAG_BOF);
3072 p = file->buf_ptr;
3073 goto redo_no_start;
3074 } else {
3075 if (c == '#') {
3076 p++;
3077 tok = TOK_TWOSHARPS;
3078 } else {
3079 tok = '#';
3082 break;
3084 case 'a': case 'b': case 'c': case 'd':
3085 case 'e': case 'f': case 'g': case 'h':
3086 case 'i': case 'j': case 'k': case 'l':
3087 case 'm': case 'n': case 'o': case 'p':
3088 case 'q': case 'r': case 's': case 't':
3089 case 'u': case 'v': case 'w': case 'x':
3090 case 'y': case 'z':
3091 case 'A': case 'B': case 'C': case 'D':
3092 case 'E': case 'F': case 'G': case 'H':
3093 case 'I': case 'J': case 'K':
3094 case 'M': case 'N': case 'O': case 'P':
3095 case 'Q': case 'R': case 'S': case 'T':
3096 case 'U': case 'V': case 'W': case 'X':
3097 case 'Y': case 'Z':
3098 case '_':
3099 parse_ident_fast:
3100 p1 = p;
3101 h = TOK_HASH_INIT;
3102 h = TOK_HASH_FUNC(h, c);
3103 p++;
3104 for(;;) {
3105 c = *p;
3106 if (!isid(c) && !isnum(c))
3107 break;
3108 h = TOK_HASH_FUNC(h, c);
3109 p++;
3111 if (c != '\\') {
3112 TokenSym **pts;
3113 int len;
3115 /* fast case : no stray found, so we have the full token
3116 and we have already hashed it */
3117 len = p - p1;
3118 h &= (TOK_HASH_SIZE - 1);
3119 pts = &hash_ident[h];
3120 for(;;) {
3121 ts = *pts;
3122 if (!ts)
3123 break;
3124 if (ts->len == len && !memcmp(ts->str, p1, len))
3125 goto token_found;
3126 pts = &(ts->hash_next);
3128 ts = tok_alloc_new(pts, p1, len);
3129 token_found: ;
3130 } else {
3131 /* slower case */
3132 cstr_reset(&tokcstr);
3134 while (p1 < p) {
3135 cstr_ccat(&tokcstr, *p1);
3136 p1++;
3138 p--;
3139 PEEKC(c, p);
3140 parse_ident_slow:
3141 while (isid(c) || isnum(c)) {
3142 cstr_ccat(&tokcstr, c);
3143 PEEKC(c, p);
3145 ts = tok_alloc(tokcstr.data, tokcstr.size);
3147 tok = ts->tok;
3148 break;
3149 case 'L':
3150 t = p[1];
3151 if (t != '\\' && t != '\'' && t != '\"') {
3152 /* fast case */
3153 goto parse_ident_fast;
3154 } else {
3155 PEEKC(c, p);
3156 if (c == '\'') {
3157 tok = TOK_LCHAR;
3158 goto char_const;
3159 } else if (c == '\"') {
3160 tok = TOK_LSTR;
3161 goto str_const;
3162 } else {
3163 cstr_reset(&tokcstr);
3164 cstr_ccat(&tokcstr, 'L');
3165 goto parse_ident_slow;
3168 break;
3169 case '0': case '1': case '2': case '3':
3170 case '4': case '5': case '6': case '7':
3171 case '8': case '9':
3173 cstr_reset(&tokcstr);
3174 /* after the first digit, accept digits, alpha, '.' or sign if
3175 prefixed by 'eEpP' */
3176 parse_num:
3177 for(;;) {
3178 t = c;
3179 cstr_ccat(&tokcstr, c);
3180 PEEKC(c, p);
3181 if (!(isnum(c) || isid(c) || c == '.' ||
3182 ((c == '+' || c == '-') &&
3183 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
3184 break;
3186 /* We add a trailing '\0' to ease parsing */
3187 cstr_ccat(&tokcstr, '\0');
3188 tokc.cstr = &tokcstr;
3189 tok = TOK_PPNUM;
3190 break;
3191 case '.':
3192 /* special dot handling because it can also start a number */
3193 PEEKC(c, p);
3194 if (isnum(c)) {
3195 cstr_reset(&tokcstr);
3196 cstr_ccat(&tokcstr, '.');
3197 goto parse_num;
3198 } else if (c == '.') {
3199 PEEKC(c, p);
3200 if (c != '.')
3201 expect("'.'");
3202 PEEKC(c, p);
3203 tok = TOK_DOTS;
3204 } else {
3205 tok = '.';
3207 break;
3208 case '\'':
3209 tok = TOK_CCHAR;
3210 char_const:
3211 file->buf_ptr = p;
3212 inp();
3213 b = getq();
3214 /* this cast is needed if >= 128 */
3215 if (tok == TOK_CCHAR)
3216 b = (char)b;
3217 tokc.i = b;
3218 if (ch != '\'')
3219 error("unterminated character constant");
3220 p = file->buf_ptr;
3221 p++;
3222 break;
3223 case '\"':
3224 tok = TOK_STR;
3225 str_const:
3226 file->buf_ptr = p;
3227 inp();
3228 cstr_reset(&tokcstr);
3229 while (ch != '\"') {
3230 b = getq();
3231 if (ch == CH_EOF)
3232 error("unterminated string");
3233 if (tok == TOK_STR)
3234 cstr_ccat(&tokcstr, b);
3235 else
3236 cstr_wccat(&tokcstr, b);
3238 if (tok == TOK_STR)
3239 cstr_ccat(&tokcstr, '\0');
3240 else
3241 cstr_wccat(&tokcstr, '\0');
3242 tokc.cstr = &tokcstr;
3243 p = file->buf_ptr;
3244 p++;
3245 break;
3247 case '<':
3248 PEEKC(c, p);
3249 if (c == '=') {
3250 p++;
3251 tok = TOK_LE;
3252 } else if (c == '<') {
3253 PEEKC(c, p);
3254 if (c == '=') {
3255 p++;
3256 tok = TOK_A_SHL;
3257 } else {
3258 tok = TOK_SHL;
3260 } else {
3261 tok = TOK_LT;
3263 break;
3265 case '>':
3266 PEEKC(c, p);
3267 if (c == '=') {
3268 p++;
3269 tok = TOK_GE;
3270 } else if (c == '>') {
3271 PEEKC(c, p);
3272 if (c == '=') {
3273 p++;
3274 tok = TOK_A_SAR;
3275 } else {
3276 tok = TOK_SAR;
3278 } else {
3279 tok = TOK_GT;
3281 break;
3283 case '&':
3284 PEEKC(c, p);
3285 if (c == '&') {
3286 p++;
3287 tok = TOK_LAND;
3288 } else if (c == '=') {
3289 p++;
3290 tok = TOK_A_AND;
3291 } else {
3292 tok = '&';
3294 break;
3296 case '|':
3297 PEEKC(c, p);
3298 if (c == '|') {
3299 p++;
3300 tok = TOK_LOR;
3301 } else if (c == '=') {
3302 p++;
3303 tok = TOK_A_OR;
3304 } else {
3305 tok = '|';
3307 break;
3309 case '+':
3310 PEEKC(c, p);
3311 if (c == '+') {
3312 p++;
3313 tok = TOK_INC;
3314 } else if (c == '=') {
3315 p++;
3316 tok = TOK_A_ADD;
3317 } else {
3318 tok = '+';
3320 break;
3322 case '-':
3323 PEEKC(c, p);
3324 if (c == '-') {
3325 p++;
3326 tok = TOK_DEC;
3327 } else if (c == '=') {
3328 p++;
3329 tok = TOK_A_SUB;
3330 } else if (c == '>') {
3331 p++;
3332 tok = TOK_ARROW;
3333 } else {
3334 tok = '-';
3336 break;
3338 PARSE2('!', '!', '=', TOK_NE)
3339 PARSE2('=', '=', '=', TOK_EQ)
3340 PARSE2('*', '*', '=', TOK_A_MUL)
3341 PARSE2('%', '%', '=', TOK_A_MOD)
3342 PARSE2('^', '^', '=', TOK_A_XOR)
3344 /* comments or operator */
3345 case '/':
3346 PEEKC(c, p);
3347 if (c == '*') {
3348 file->buf_ptr = p;
3349 parse_comment();
3350 p = file->buf_ptr;
3351 goto redo_no_start;
3352 } else if (c == '/') {
3353 file->buf_ptr = p;
3354 parse_line_comment();
3355 p = file->buf_ptr;
3356 goto redo_no_start;
3357 } else if (c == '=') {
3358 p++;
3359 tok = TOK_A_DIV;
3360 } else {
3361 tok = '/';
3363 break;
3365 /* simple tokens */
3366 case '(':
3367 case ')':
3368 case '[':
3369 case ']':
3370 case '{':
3371 case '}':
3372 case ',':
3373 case ';':
3374 case ':':
3375 case '?':
3376 case '~':
3377 tok = c;
3378 p++;
3379 break;
3380 default:
3381 error("unrecognized character \\x%02x", c);
3382 break;
3384 file->buf_ptr = p;
3385 tok_flags = 0;
3386 #if defined(PARSE_DEBUG)
3387 printf("token = %s\n", get_tok_str(tok, &tokc));
3388 #endif
3391 /* return next token without macro substitution. Can read input from
3392 macro_ptr buffer */
3393 static void next_nomacro(void)
3395 if (macro_ptr) {
3396 redo:
3397 tok = *macro_ptr;
3398 if (tok) {
3399 TOK_GET(tok, macro_ptr, tokc);
3400 if (tok == TOK_LINENUM) {
3401 file->line_num = tokc.i;
3402 goto redo;
3405 } else {
3406 next_nomacro1();
3410 /* substitute args in macro_str and return allocated string */
3411 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
3413 int *st, last_tok, t, notfirst;
3414 Sym *s;
3415 CValue cval;
3416 TokenString str;
3417 CString cstr;
3419 tok_str_new(&str);
3420 last_tok = 0;
3421 while(1) {
3422 TOK_GET(t, macro_str, cval);
3423 if (!t)
3424 break;
3425 if (t == '#') {
3426 /* stringize */
3427 TOK_GET(t, macro_str, cval);
3428 if (!t)
3429 break;
3430 s = sym_find2(args, t);
3431 if (s) {
3432 cstr_new(&cstr);
3433 st = (int *)s->c;
3434 notfirst = 0;
3435 while (*st) {
3436 if (notfirst)
3437 cstr_ccat(&cstr, ' ');
3438 TOK_GET(t, st, cval);
3439 cstr_cat(&cstr, get_tok_str(t, &cval));
3440 notfirst = 1;
3442 cstr_ccat(&cstr, '\0');
3443 #ifdef PP_DEBUG
3444 printf("stringize: %s\n", (char *)cstr.data);
3445 #endif
3446 /* add string */
3447 cval.cstr = &cstr;
3448 tok_str_add2(&str, TOK_STR, &cval);
3449 cstr_free(&cstr);
3450 } else {
3451 tok_str_add2(&str, t, &cval);
3453 } else if (t >= TOK_IDENT) {
3454 s = sym_find2(args, t);
3455 if (s) {
3456 st = (int *)s->c;
3457 /* if '##' is present before or after, no arg substitution */
3458 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
3459 /* special case for var arg macros : ## eats the
3460 ',' if empty VA_ARGS variable. */
3461 /* XXX: test of the ',' is not 100%
3462 reliable. should fix it to avoid security
3463 problems */
3464 if (gnu_ext && s->type.t &&
3465 last_tok == TOK_TWOSHARPS &&
3466 str.len >= 2 && str.str[str.len - 2] == ',') {
3467 if (*st == 0) {
3468 /* suppress ',' '##' */
3469 str.len -= 2;
3470 } else {
3471 /* suppress '##' and add variable */
3472 str.len--;
3473 goto add_var;
3475 } else {
3476 int t1;
3477 add_var:
3478 for(;;) {
3479 TOK_GET(t1, st, cval);
3480 if (!t1)
3481 break;
3482 tok_str_add2(&str, t1, &cval);
3485 } else {
3486 macro_subst(&str, nested_list, st);
3488 } else {
3489 tok_str_add(&str, t);
3491 } else {
3492 tok_str_add2(&str, t, &cval);
3494 last_tok = t;
3496 tok_str_add(&str, 0);
3497 return str.str;
3500 /* handle the '##' operator */
3501 static int *macro_twosharps(void)
3503 TokenSym *ts;
3504 int *macro_ptr1;
3505 int t;
3506 const char *p1, *p2;
3507 CValue cval;
3508 TokenString macro_str1;
3509 CString cstr;
3511 cstr_new(&cstr);
3512 tok_str_new(&macro_str1);
3513 tok = 0;
3514 while (1) {
3515 next_nomacro();
3516 if (tok == 0)
3517 break;
3518 while (*macro_ptr == TOK_TWOSHARPS) {
3519 macro_ptr++;
3520 macro_ptr1 = macro_ptr;
3521 t = *macro_ptr;
3522 if (t) {
3523 TOK_GET(t, macro_ptr, cval);
3525 /* We concatenate the two tokens if we have an
3526 identifier or a preprocessing number */
3527 cstr_reset(&cstr);
3528 p1 = get_tok_str(tok, &tokc);
3529 cstr_cat(&cstr, p1);
3530 p2 = get_tok_str(t, &cval);
3531 cstr_cat(&cstr, p2);
3532 cstr_ccat(&cstr, '\0');
3534 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
3535 (t >= TOK_IDENT || t == TOK_PPNUM)) {
3536 if (tok == TOK_PPNUM) {
3537 /* if number, then create a number token */
3538 /* NOTE: no need to allocate because
3539 tok_str_add2() does it */
3540 tokc.cstr = &cstr;
3541 } else {
3542 /* if identifier, we must do a test to
3543 validate we have a correct identifier */
3544 if (t == TOK_PPNUM) {
3545 const char *p;
3546 int c;
3548 p = p2;
3549 for(;;) {
3550 c = *p;
3551 if (c == '\0')
3552 break;
3553 p++;
3554 if (!isnum(c) && !isid(c))
3555 goto error_pasting;
3558 ts = tok_alloc(cstr.data, strlen(cstr.data));
3559 tok = ts->tok; /* modify current token */
3561 } else {
3562 const char *str = cstr.data;
3563 const unsigned char *q;
3565 /* we look for a valid token */
3566 /* XXX: do more extensive checks */
3567 if (!strcmp(str, ">>=")) {
3568 tok = TOK_A_SAR;
3569 } else if (!strcmp(str, "<<=")) {
3570 tok = TOK_A_SHL;
3571 } else if (strlen(str) == 2) {
3572 /* search in two bytes table */
3573 q = tok_two_chars;
3574 for(;;) {
3575 if (!*q)
3576 goto error_pasting;
3577 if (q[0] == str[0] && q[1] == str[1])
3578 break;
3579 q += 3;
3581 tok = q[2];
3582 } else {
3583 error_pasting:
3584 /* NOTE: because get_tok_str use a static buffer,
3585 we must save it */
3586 cstr_reset(&cstr);
3587 p1 = get_tok_str(tok, &tokc);
3588 cstr_cat(&cstr, p1);
3589 cstr_ccat(&cstr, '\0');
3590 p2 = get_tok_str(t, &cval);
3591 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
3592 /* cannot merge tokens: just add them separately */
3593 tok_str_add2(&macro_str1, tok, &tokc);
3594 /* XXX: free associated memory ? */
3595 tok = t;
3596 tokc = cval;
3601 tok_str_add2(&macro_str1, tok, &tokc);
3603 cstr_free(&cstr);
3604 tok_str_add(&macro_str1, 0);
3605 return macro_str1.str;
3609 /* do macro substitution of current token with macro 's' and add
3610 result to (tok_str,tok_len). 'nested_list' is the list of all
3611 macros we got inside to avoid recursing. Return non zero if no
3612 substitution needs to be done */
3613 static int macro_subst_tok(TokenString *tok_str,
3614 Sym **nested_list, Sym *s)
3616 Sym *args, *sa, *sa1;
3617 int mstr_allocated, parlevel, *mstr, t;
3618 TokenString str;
3619 char *cstrval;
3620 CValue cval;
3621 CString cstr;
3623 /* if symbol is a macro, prepare substitution */
3624 /* if nested substitution, do nothing */
3625 if (sym_find2(*nested_list, tok))
3626 return -1;
3628 /* special macros */
3629 if (tok == TOK___LINE__) {
3630 cval.i = file->line_num;
3631 tok_str_add2(tok_str, TOK_CINT, &cval);
3632 } else if (tok == TOK___FILE__) {
3633 cstrval = file->filename;
3634 goto add_cstr;
3635 tok_str_add2(tok_str, TOK_STR, &cval);
3636 } else if (tok == TOK___DATE__) {
3637 cstrval = "Jan 1 2002";
3638 goto add_cstr;
3639 } else if (tok == TOK___TIME__) {
3640 cstrval = "00:00:00";
3641 add_cstr:
3642 cstr_new(&cstr);
3643 cstr_cat(&cstr, cstrval);
3644 cstr_ccat(&cstr, '\0');
3645 cval.cstr = &cstr;
3646 tok_str_add2(tok_str, TOK_STR, &cval);
3647 cstr_free(&cstr);
3648 } else {
3649 mstr = (int *)s->c;
3650 mstr_allocated = 0;
3651 if (s->type.t == MACRO_FUNC) {
3652 /* NOTE: we do not use next_nomacro to avoid eating the
3653 next token. XXX: find better solution */
3654 if (macro_ptr) {
3655 t = *macro_ptr;
3656 } else {
3657 /* XXX: incorrect with comments */
3658 ch = file->buf_ptr[0];
3659 while (is_space(ch) || ch == '\n')
3660 cinp();
3661 t = ch;
3663 if (t != '(') /* no macro subst */
3664 return -1;
3666 /* argument macro */
3667 next_nomacro();
3668 next_nomacro();
3669 args = NULL;
3670 sa = s->next;
3671 /* NOTE: empty args are allowed, except if no args */
3672 for(;;) {
3673 /* handle '()' case */
3674 if (!args && tok == ')')
3675 break;
3676 if (!sa)
3677 error("macro '%s' used with too many args",
3678 get_tok_str(s->v, 0));
3679 tok_str_new(&str);
3680 parlevel = 0;
3681 /* NOTE: non zero sa->t indicates VA_ARGS */
3682 while ((parlevel > 0 ||
3683 (tok != ')' &&
3684 (tok != ',' || sa->type.t))) &&
3685 tok != -1) {
3686 if (tok == '(')
3687 parlevel++;
3688 else if (tok == ')')
3689 parlevel--;
3690 tok_str_add2(&str, tok, &tokc);
3691 next_nomacro();
3693 tok_str_add(&str, 0);
3694 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str);
3695 sa = sa->next;
3696 if (tok == ')') {
3697 /* special case for gcc var args: add an empty
3698 var arg argument if it is omitted */
3699 if (sa && sa->type.t && gnu_ext)
3700 continue;
3701 else
3702 break;
3704 if (tok != ',')
3705 expect(",");
3706 next_nomacro();
3708 if (sa) {
3709 error("macro '%s' used with too few args",
3710 get_tok_str(s->v, 0));
3713 /* now subst each arg */
3714 mstr = macro_arg_subst(nested_list, mstr, args);
3715 /* free memory */
3716 sa = args;
3717 while (sa) {
3718 sa1 = sa->prev;
3719 tok_str_free((int *)sa->c);
3720 tcc_free(sa);
3721 sa = sa1;
3723 mstr_allocated = 1;
3725 sym_push2(nested_list, s->v, 0, 0);
3726 macro_subst(tok_str, nested_list, mstr);
3727 /* pop nested defined symbol */
3728 sa1 = *nested_list;
3729 *nested_list = sa1->prev;
3730 tcc_free(sa1);
3731 if (mstr_allocated)
3732 tok_str_free(mstr);
3734 return 0;
3737 /* do macro substitution of macro_str and add result to
3738 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3739 inside to avoid recursing. */
3740 static void macro_subst(TokenString *tok_str,
3741 Sym **nested_list, int *macro_str)
3743 Sym *s;
3744 int *saved_macro_ptr;
3745 int *macro_str1;
3747 saved_macro_ptr = macro_ptr;
3748 macro_ptr = macro_str;
3749 /* first scan for '##' operator handling */
3750 macro_str1 = macro_twosharps();
3751 macro_ptr = macro_str1;
3753 while (1) {
3754 next_nomacro();
3755 if (tok == 0)
3756 break;
3757 s = define_find(tok);
3758 if (s != NULL) {
3759 if (macro_subst_tok(tok_str, nested_list, s) != 0)
3760 goto no_subst;
3761 } else {
3762 no_subst:
3763 tok_str_add2(tok_str, tok, &tokc);
3766 macro_ptr = saved_macro_ptr;
3767 tok_str_free(macro_str1);
3770 /* return next token with macro substitution */
3771 static void next(void)
3773 Sym *nested_list, *s;
3774 TokenString str;
3776 /* special 'ungettok' case for label parsing */
3777 if (tok1) {
3778 tok = tok1;
3779 tokc = tok1c;
3780 tok1 = 0;
3781 } else {
3782 redo:
3783 next_nomacro();
3784 if (!macro_ptr) {
3785 /* if not reading from macro substituted string, then try
3786 to substitute macros */
3787 if (tok >= TOK_IDENT) {
3788 s = define_find(tok);
3789 if (s) {
3790 /* we have a macro: we try to substitute */
3791 tok_str_new(&str);
3792 nested_list = NULL;
3793 if (macro_subst_tok(&str, &nested_list, s) == 0) {
3794 /* substitution done, NOTE: maybe empty */
3795 tok_str_add(&str, 0);
3796 macro_ptr = str.str;
3797 macro_ptr_allocated = str.str;
3798 goto redo;
3802 } else {
3803 if (tok == 0) {
3804 /* end of macro string: free it */
3805 tok_str_free(macro_ptr_allocated);
3806 macro_ptr = NULL;
3807 goto redo;
3811 /* convert preprocessor tokens into C tokens */
3812 if (tok == TOK_PPNUM) {
3813 parse_number((char *)tokc.cstr->data);
3818 void swap(int *p, int *q)
3820 int t;
3821 t = *p;
3822 *p = *q;
3823 *q = t;
3826 void vsetc(CType *type, int r, CValue *vc)
3828 int v;
3830 if (vtop >= vstack + VSTACK_SIZE)
3831 error("memory full");
3832 /* cannot let cpu flags if other instruction are generated. Also
3833 avoid leaving VT_JMP anywhere except on the top of the stack
3834 because it would complicate the code generator. */
3835 if (vtop >= vstack) {
3836 v = vtop->r & VT_VALMASK;
3837 if (v == VT_CMP || (v & ~1) == VT_JMP)
3838 gv(RC_INT);
3840 vtop++;
3841 vtop->type = *type;
3842 vtop->r = r;
3843 vtop->r2 = VT_CONST;
3844 vtop->c = *vc;
3847 /* push integer constant */
3848 void vpushi(int v)
3850 CValue cval;
3851 cval.i = v;
3852 vsetc(&int_type, VT_CONST, &cval);
3855 /* Return a static symbol pointing to a section */
3856 static Sym *get_sym_ref(CType *type, Section *sec,
3857 unsigned long offset, unsigned long size)
3859 int v;
3860 Sym *sym;
3862 v = anon_sym++;
3863 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
3864 sym->type.ref = type->ref;
3865 sym->r = VT_CONST | VT_SYM;
3866 put_extern_sym(sym, sec, offset, size);
3867 return sym;
3870 /* push a reference to a section offset by adding a dummy symbol */
3871 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
3873 CValue cval;
3875 cval.ul = 0;
3876 vsetc(type, VT_CONST | VT_SYM, &cval);
3877 vtop->sym = get_sym_ref(type, sec, offset, size);
3880 /* define a new external reference to a symbol 'v' of type 'u' */
3881 static Sym *external_global_sym(int v, CType *type, int r)
3883 Sym *s;
3885 s = sym_find(v);
3886 if (!s) {
3887 /* push forward reference */
3888 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
3889 s->type.ref = type->ref;
3890 s->r = r | VT_CONST | VT_SYM;
3892 return s;
3895 /* define a new external reference to a symbol 'v' of type 'u' */
3896 static Sym *external_sym(int v, CType *type, int r)
3898 Sym *s;
3900 s = sym_find(v);
3901 if (!s) {
3902 /* push forward reference */
3903 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
3904 s->type.t |= VT_EXTERN;
3906 return s;
3909 /* push a reference to global symbol v */
3910 static void vpush_global_sym(CType *type, int v)
3912 Sym *sym;
3913 CValue cval;
3915 sym = external_global_sym(v, type, 0);
3916 cval.ul = 0;
3917 vsetc(type, VT_CONST | VT_SYM, &cval);
3918 vtop->sym = sym;
3921 void vset(CType *type, int r, int v)
3923 CValue cval;
3925 cval.i = v;
3926 vsetc(type, r, &cval);
3929 void vseti(int r, int v)
3931 CType type;
3932 type.t = VT_INT;
3933 vset(&type, r, v);
3936 void vswap(void)
3938 SValue tmp;
3940 tmp = vtop[0];
3941 vtop[0] = vtop[-1];
3942 vtop[-1] = tmp;
3945 void vpushv(SValue *v)
3947 if (vtop >= vstack + VSTACK_SIZE)
3948 error("memory full");
3949 vtop++;
3950 *vtop = *v;
3953 void vdup(void)
3955 vpushv(vtop);
3958 /* save r to the memory stack, and mark it as being free */
3959 void save_reg(int r)
3961 int l, saved, size, align;
3962 SValue *p, sv;
3963 CType *type;
3965 /* modify all stack values */
3966 saved = 0;
3967 l = 0;
3968 for(p=vstack;p<=vtop;p++) {
3969 if ((p->r & VT_VALMASK) == r ||
3970 (p->r2 & VT_VALMASK) == r) {
3971 /* must save value on stack if not already done */
3972 if (!saved) {
3973 /* NOTE: must reload 'r' because r might be equal to r2 */
3974 r = p->r & VT_VALMASK;
3975 /* store register in the stack */
3976 type = &p->type;
3977 if ((p->r & VT_LVAL) ||
3978 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
3979 type = &int_type;
3980 size = type_size(type, &align);
3981 loc = (loc - size) & -align;
3982 sv.type.t = type->t;
3983 sv.r = VT_LOCAL | VT_LVAL;
3984 sv.c.ul = loc;
3985 store(r, &sv);
3986 #ifdef TCC_TARGET_I386
3987 /* x86 specific: need to pop fp register ST0 if saved */
3988 if (r == REG_ST0) {
3989 o(0xd9dd); /* fstp %st(1) */
3991 #endif
3992 /* special long long case */
3993 if ((type->t & VT_BTYPE) == VT_LLONG) {
3994 sv.c.ul += 4;
3995 store(p->r2, &sv);
3997 l = loc;
3998 saved = 1;
4000 /* mark that stack entry as being saved on the stack */
4001 if (p->r & VT_LVAL) {
4002 /* also suppress the bounded flag because the
4003 relocation address of the function was stored in
4004 p->c.ul */
4005 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
4006 } else {
4007 p->r = lvalue_type(p->type.t) | VT_LOCAL;
4009 p->r2 = VT_CONST;
4010 p->c.ul = l;
4015 /* find a free register of class 'rc'. If none, save one register */
4016 int get_reg(int rc)
4018 int r;
4019 SValue *p;
4021 /* find a free register */
4022 for(r=0;r<NB_REGS;r++) {
4023 if (reg_classes[r] & rc) {
4024 for(p=vstack;p<=vtop;p++) {
4025 if ((p->r & VT_VALMASK) == r ||
4026 (p->r2 & VT_VALMASK) == r)
4027 goto notfound;
4029 return r;
4031 notfound: ;
4034 /* no register left : free the first one on the stack (VERY
4035 IMPORTANT to start from the bottom to ensure that we don't
4036 spill registers used in gen_opi()) */
4037 for(p=vstack;p<=vtop;p++) {
4038 r = p->r & VT_VALMASK;
4039 if (r < VT_CONST && (reg_classes[r] & rc))
4040 goto save_found;
4041 /* also look at second register (if long long) */
4042 r = p->r2 & VT_VALMASK;
4043 if (r < VT_CONST && (reg_classes[r] & rc)) {
4044 save_found:
4045 save_reg(r);
4046 return r;
4049 /* Should never comes here */
4050 return -1;
4053 /* save registers up to (vtop - n) stack entry */
4054 void save_regs(int n)
4056 int r;
4057 SValue *p, *p1;
4058 p1 = vtop - n;
4059 for(p = vstack;p <= p1; p++) {
4060 r = p->r & VT_VALMASK;
4061 if (r < VT_CONST) {
4062 save_reg(r);
4067 /* move register 's' to 'r', and flush previous value of r to memory
4068 if needed */
4069 void move_reg(int r, int s)
4071 SValue sv;
4073 if (r != s) {
4074 save_reg(r);
4075 sv.type.t = VT_INT;
4076 sv.r = s;
4077 sv.c.ul = 0;
4078 load(r, &sv);
4082 /* get address of vtop (vtop MUST BE an lvalue) */
4083 void gaddrof(void)
4085 vtop->r &= ~VT_LVAL;
4086 /* tricky: if saved lvalue, then we can go back to lvalue */
4087 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
4088 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
4091 #ifdef CONFIG_TCC_BCHECK
4092 /* generate lvalue bound code */
4093 void gbound(void)
4095 int lval_type;
4096 CType type1;
4098 vtop->r &= ~VT_MUSTBOUND;
4099 /* if lvalue, then use checking code before dereferencing */
4100 if (vtop->r & VT_LVAL) {
4101 /* if not VT_BOUNDED value, then make one */
4102 if (!(vtop->r & VT_BOUNDED)) {
4103 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
4104 /* must save type because we must set it to int to get pointer */
4105 type1 = vtop->type;
4106 vtop->type.t = VT_INT;
4107 gaddrof();
4108 vpushi(0);
4109 gen_bounded_ptr_add();
4110 vtop->r |= lval_type;
4111 vtop->type = type1;
4113 /* then check for dereferencing */
4114 gen_bounded_ptr_deref();
4117 #endif
4119 /* store vtop a register belonging to class 'rc'. lvalues are
4120 converted to values. Cannot be used if cannot be converted to
4121 register value (such as structures). */
4122 int gv(int rc)
4124 int r, r2, rc2, bit_pos, bit_size, size, align, i;
4125 unsigned long long ll;
4127 /* NOTE: get_reg can modify vstack[] */
4128 if (vtop->type.t & VT_BITFIELD) {
4129 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4130 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4131 /* remove bit field info to avoid loops */
4132 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4133 /* generate shifts */
4134 vpushi(32 - (bit_pos + bit_size));
4135 gen_op(TOK_SHL);
4136 vpushi(32 - bit_size);
4137 /* NOTE: transformed to SHR if unsigned */
4138 gen_op(TOK_SAR);
4139 r = gv(rc);
4140 } else {
4141 if (is_float(vtop->type.t) &&
4142 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4143 Sym *sym;
4144 int *ptr;
4145 unsigned long offset;
4147 /* XXX: unify with initializers handling ? */
4148 /* CPUs usually cannot use float constants, so we store them
4149 generically in data segment */
4150 size = type_size(&vtop->type, &align);
4151 offset = (data_section->data_offset + align - 1) & -align;
4152 data_section->data_offset = offset;
4153 /* XXX: not portable yet */
4154 ptr = section_ptr_add(data_section, size);
4155 size = size >> 2;
4156 for(i=0;i<size;i++)
4157 ptr[i] = vtop->c.tab[i];
4158 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
4159 vtop->r |= VT_LVAL | VT_SYM;
4160 vtop->sym = sym;
4161 vtop->c.ul = 0;
4163 #ifdef CONFIG_TCC_BCHECK
4164 if (vtop->r & VT_MUSTBOUND)
4165 gbound();
4166 #endif
4168 r = vtop->r & VT_VALMASK;
4169 /* need to reload if:
4170 - constant
4171 - lvalue (need to dereference pointer)
4172 - already a register, but not in the right class */
4173 if (r >= VT_CONST ||
4174 (vtop->r & VT_LVAL) ||
4175 !(reg_classes[r] & rc) ||
4176 ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
4177 !(reg_classes[vtop->r2] & rc))) {
4178 r = get_reg(rc);
4179 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
4180 /* two register type load : expand to two words
4181 temporarily */
4182 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4183 /* load constant */
4184 ll = vtop->c.ull;
4185 vtop->c.ui = ll; /* first word */
4186 load(r, vtop);
4187 vtop->r = r; /* save register value */
4188 vpushi(ll >> 32); /* second word */
4189 } else if (r >= VT_CONST ||
4190 (vtop->r & VT_LVAL)) {
4191 /* load from memory */
4192 load(r, vtop);
4193 vdup();
4194 vtop[-1].r = r; /* save register value */
4195 /* increment pointer to get second word */
4196 vtop->type.t = VT_INT;
4197 gaddrof();
4198 vpushi(4);
4199 gen_op('+');
4200 vtop->r |= VT_LVAL;
4201 } else {
4202 /* move registers */
4203 load(r, vtop);
4204 vdup();
4205 vtop[-1].r = r; /* save register value */
4206 vtop->r = vtop[-1].r2;
4208 /* allocate second register */
4209 rc2 = RC_INT;
4210 if (rc == RC_IRET)
4211 rc2 = RC_LRET;
4212 r2 = get_reg(rc2);
4213 load(r2, vtop);
4214 vpop();
4215 /* write second register */
4216 vtop->r2 = r2;
4217 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
4218 int t1, t;
4219 /* lvalue of scalar type : need to use lvalue type
4220 because of possible cast */
4221 t = vtop->type.t;
4222 t1 = t;
4223 /* compute memory access type */
4224 if (vtop->r & VT_LVAL_BYTE)
4225 t = VT_BYTE;
4226 else if (vtop->r & VT_LVAL_SHORT)
4227 t = VT_SHORT;
4228 if (vtop->r & VT_LVAL_UNSIGNED)
4229 t |= VT_UNSIGNED;
4230 vtop->type.t = t;
4231 load(r, vtop);
4232 /* restore wanted type */
4233 vtop->type.t = t1;
4234 } else {
4235 /* one register type load */
4236 load(r, vtop);
4239 vtop->r = r;
4241 return r;
4244 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4245 void gv2(int rc1, int rc2)
4247 int v;
4249 /* generate more generic register first. But VT_JMP or VT_CMP
4250 values must be generated first in all cases to avoid possible
4251 reload errors */
4252 v = vtop[0].r & VT_VALMASK;
4253 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
4254 vswap();
4255 gv(rc1);
4256 vswap();
4257 gv(rc2);
4258 /* test if reload is needed for first register */
4259 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
4260 vswap();
4261 gv(rc1);
4262 vswap();
4264 } else {
4265 gv(rc2);
4266 vswap();
4267 gv(rc1);
4268 vswap();
4269 /* test if reload is needed for first register */
4270 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
4271 gv(rc2);
4276 /* expand long long on stack in two int registers */
4277 void lexpand(void)
4279 int u;
4281 u = vtop->type.t & VT_UNSIGNED;
4282 gv(RC_INT);
4283 vdup();
4284 vtop[0].r = vtop[-1].r2;
4285 vtop[0].r2 = VT_CONST;
4286 vtop[-1].r2 = VT_CONST;
4287 vtop[0].type.t = VT_INT | u;
4288 vtop[-1].type.t = VT_INT | u;
4291 /* build a long long from two ints */
4292 void lbuild(int t)
4294 gv2(RC_INT, RC_INT);
4295 vtop[-1].r2 = vtop[0].r;
4296 vtop[-1].type.t = t;
4297 vpop();
4300 /* rotate n first stack elements to the bottom */
4301 void vrotb(int n)
4303 int i;
4304 SValue tmp;
4306 tmp = vtop[-n + 1];
4307 for(i=-n+1;i!=0;i++)
4308 vtop[i] = vtop[i+1];
4309 vtop[0] = tmp;
4312 /* pop stack value */
4313 void vpop(void)
4315 int v;
4316 v = vtop->r & VT_VALMASK;
4317 #ifdef TCC_TARGET_I386
4318 /* for x86, we need to pop the FP stack */
4319 if (v == REG_ST0 && !nocode_wanted) {
4320 o(0xd9dd); /* fstp %st(1) */
4321 } else
4322 #endif
4323 if (v == VT_JMP || v == VT_JMPI) {
4324 /* need to put correct jump if && or || without test */
4325 gsym(vtop->c.ul);
4327 vtop--;
4330 /* convert stack entry to register and duplicate its value in another
4331 register */
4332 void gv_dup(void)
4334 int rc, t, r, r1;
4335 SValue sv;
4337 t = vtop->type.t;
4338 if ((t & VT_BTYPE) == VT_LLONG) {
4339 lexpand();
4340 gv_dup();
4341 vswap();
4342 vrotb(3);
4343 gv_dup();
4344 vrotb(4);
4345 /* stack: H L L1 H1 */
4346 lbuild(t);
4347 vrotb(3);
4348 vrotb(3);
4349 vswap();
4350 lbuild(t);
4351 vswap();
4352 } else {
4353 /* duplicate value */
4354 rc = RC_INT;
4355 sv.type.t = VT_INT;
4356 if (is_float(t)) {
4357 rc = RC_FLOAT;
4358 sv.type.t = t;
4360 r = gv(rc);
4361 r1 = get_reg(rc);
4362 sv.r = r;
4363 sv.c.ul = 0;
4364 load(r1, &sv); /* move r to r1 */
4365 vdup();
4366 /* duplicates value */
4367 vtop->r = r1;
4371 /* generate CPU independent (unsigned) long long operations */
4372 void gen_opl(int op)
4374 int t, a, b, op1, c, i;
4375 int func;
4376 GFuncContext gf;
4377 SValue tmp;
4379 switch(op) {
4380 case '/':
4381 case TOK_PDIV:
4382 func = TOK___divdi3;
4383 goto gen_func;
4384 case TOK_UDIV:
4385 func = TOK___udivdi3;
4386 goto gen_func;
4387 case '%':
4388 func = TOK___moddi3;
4389 goto gen_func;
4390 case TOK_UMOD:
4391 func = TOK___umoddi3;
4392 gen_func:
4393 /* call generic long long function */
4394 gfunc_start(&gf, FUNC_CDECL);
4395 gfunc_param(&gf);
4396 gfunc_param(&gf);
4397 vpush_global_sym(&func_old_type, func);
4398 gfunc_call(&gf);
4399 vpushi(0);
4400 vtop->r = REG_IRET;
4401 vtop->r2 = REG_LRET;
4402 break;
4403 case '^':
4404 case '&':
4405 case '|':
4406 case '*':
4407 case '+':
4408 case '-':
4409 t = vtop->type.t;
4410 vswap();
4411 lexpand();
4412 vrotb(3);
4413 lexpand();
4414 /* stack: L1 H1 L2 H2 */
4415 tmp = vtop[0];
4416 vtop[0] = vtop[-3];
4417 vtop[-3] = tmp;
4418 tmp = vtop[-2];
4419 vtop[-2] = vtop[-3];
4420 vtop[-3] = tmp;
4421 vswap();
4422 /* stack: H1 H2 L1 L2 */
4423 if (op == '*') {
4424 vpushv(vtop - 1);
4425 vpushv(vtop - 1);
4426 gen_op(TOK_UMULL);
4427 lexpand();
4428 /* stack: H1 H2 L1 L2 ML MH */
4429 for(i=0;i<4;i++)
4430 vrotb(6);
4431 /* stack: ML MH H1 H2 L1 L2 */
4432 tmp = vtop[0];
4433 vtop[0] = vtop[-2];
4434 vtop[-2] = tmp;
4435 /* stack: ML MH H1 L2 H2 L1 */
4436 gen_op('*');
4437 vrotb(3);
4438 vrotb(3);
4439 gen_op('*');
4440 /* stack: ML MH M1 M2 */
4441 gen_op('+');
4442 gen_op('+');
4443 } else if (op == '+' || op == '-') {
4444 /* XXX: add non carry method too (for MIPS or alpha) */
4445 if (op == '+')
4446 op1 = TOK_ADDC1;
4447 else
4448 op1 = TOK_SUBC1;
4449 gen_op(op1);
4450 /* stack: H1 H2 (L1 op L2) */
4451 vrotb(3);
4452 vrotb(3);
4453 gen_op(op1 + 1); /* TOK_xxxC2 */
4454 } else {
4455 gen_op(op);
4456 /* stack: H1 H2 (L1 op L2) */
4457 vrotb(3);
4458 vrotb(3);
4459 /* stack: (L1 op L2) H1 H2 */
4460 gen_op(op);
4461 /* stack: (L1 op L2) (H1 op H2) */
4463 /* stack: L H */
4464 lbuild(t);
4465 break;
4466 case TOK_SAR:
4467 case TOK_SHR:
4468 case TOK_SHL:
4469 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4470 t = vtop[-1].type.t;
4471 vswap();
4472 lexpand();
4473 vrotb(3);
4474 /* stack: L H shift */
4475 c = (int)vtop->c.i;
4476 /* constant: simpler */
4477 /* NOTE: all comments are for SHL. the other cases are
4478 done by swaping words */
4479 vpop();
4480 if (op != TOK_SHL)
4481 vswap();
4482 if (c >= 32) {
4483 /* stack: L H */
4484 vpop();
4485 if (c > 32) {
4486 vpushi(c - 32);
4487 gen_op(op);
4489 if (op != TOK_SAR) {
4490 vpushi(0);
4491 } else {
4492 gv_dup();
4493 vpushi(31);
4494 gen_op(TOK_SAR);
4496 vswap();
4497 } else {
4498 vswap();
4499 gv_dup();
4500 /* stack: H L L */
4501 vpushi(c);
4502 gen_op(op);
4503 vswap();
4504 vpushi(32 - c);
4505 if (op == TOK_SHL)
4506 gen_op(TOK_SHR);
4507 else
4508 gen_op(TOK_SHL);
4509 vrotb(3);
4510 /* stack: L L H */
4511 vpushi(c);
4512 if (op == TOK_SHL)
4513 gen_op(TOK_SHL);
4514 else
4515 gen_op(TOK_SHR);
4516 gen_op('|');
4518 if (op != TOK_SHL)
4519 vswap();
4520 lbuild(t);
4521 } else {
4522 /* XXX: should provide a faster fallback on x86 ? */
4523 switch(op) {
4524 case TOK_SAR:
4525 func = TOK___sardi3;
4526 goto gen_func;
4527 case TOK_SHR:
4528 func = TOK___shrdi3;
4529 goto gen_func;
4530 case TOK_SHL:
4531 func = TOK___shldi3;
4532 goto gen_func;
4535 break;
4536 default:
4537 /* compare operations */
4538 t = vtop->type.t;
4539 vswap();
4540 lexpand();
4541 vrotb(3);
4542 lexpand();
4543 /* stack: L1 H1 L2 H2 */
4544 tmp = vtop[-1];
4545 vtop[-1] = vtop[-2];
4546 vtop[-2] = tmp;
4547 /* stack: L1 L2 H1 H2 */
4548 /* compare high */
4549 op1 = op;
4550 /* when values are equal, we need to compare low words. since
4551 the jump is inverted, we invert the test too. */
4552 if (op1 == TOK_LT)
4553 op1 = TOK_LE;
4554 else if (op1 == TOK_GT)
4555 op1 = TOK_GE;
4556 else if (op1 == TOK_ULT)
4557 op1 = TOK_ULE;
4558 else if (op1 == TOK_UGT)
4559 op1 = TOK_UGE;
4560 a = 0;
4561 b = 0;
4562 gen_op(op1);
4563 if (op1 != TOK_NE) {
4564 a = gtst(1, 0);
4566 if (op != TOK_EQ) {
4567 /* generate non equal test */
4568 /* XXX: NOT PORTABLE yet */
4569 if (a == 0) {
4570 b = gtst(0, 0);
4571 } else {
4572 #ifdef TCC_TARGET_I386
4573 b = psym(0x850f, 0);
4574 #else
4575 error("not implemented");
4576 #endif
4579 /* compare low. Always unsigned */
4580 op1 = op;
4581 if (op1 == TOK_LT)
4582 op1 = TOK_ULT;
4583 else if (op1 == TOK_LE)
4584 op1 = TOK_ULE;
4585 else if (op1 == TOK_GT)
4586 op1 = TOK_UGT;
4587 else if (op1 == TOK_GE)
4588 op1 = TOK_UGE;
4589 gen_op(op1);
4590 a = gtst(1, a);
4591 gsym(b);
4592 vseti(VT_JMPI, a);
4593 break;
4597 /* handle integer constant optimizations and various machine
4598 independant opt */
4599 void gen_opic(int op)
4601 int fc, c1, c2, n;
4602 SValue *v1, *v2;
4604 v1 = vtop - 1;
4605 v2 = vtop;
4606 /* currently, we cannot do computations with forward symbols */
4607 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4608 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4609 if (c1 && c2) {
4610 fc = v2->c.i;
4611 switch(op) {
4612 case '+': v1->c.i += fc; break;
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;
4619 case TOK_PDIV:
4620 case '/':
4621 case '%':
4622 case TOK_UDIV:
4623 case TOK_UMOD:
4624 /* if division by zero, generate explicit division */
4625 if (fc == 0) {
4626 if (const_wanted)
4627 error("division by zero in constant");
4628 goto general_case;
4630 switch(op) {
4631 default: v1->c.i /= fc; break;
4632 case '%': v1->c.i %= fc; break;
4633 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
4634 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
4636 break;
4637 case TOK_SHL: v1->c.i <<= fc; break;
4638 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
4639 case TOK_SAR: v1->c.i >>= fc; break;
4640 /* tests */
4641 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
4642 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
4643 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
4644 case TOK_NE: v1->c.i = v1->c.i != fc; break;
4645 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
4646 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
4647 case TOK_LT: v1->c.i = v1->c.i < fc; break;
4648 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
4649 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
4650 case TOK_GT: v1->c.i = v1->c.i > fc; break;
4651 /* logical */
4652 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
4653 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
4654 default:
4655 goto general_case;
4657 vtop--;
4658 } else {
4659 /* if commutative ops, put c2 as constant */
4660 if (c1 && (op == '+' || op == '&' || op == '^' ||
4661 op == '|' || op == '*')) {
4662 vswap();
4663 swap(&c1, &c2);
4665 fc = vtop->c.i;
4666 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
4667 op == TOK_PDIV) &&
4668 fc == 1) ||
4669 ((op == '+' || op == '-' || op == '|' || op == '^' ||
4670 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
4671 fc == 0) ||
4672 (op == '&' &&
4673 fc == -1))) {
4674 /* nothing to do */
4675 vtop--;
4676 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
4677 /* try to use shifts instead of muls or divs */
4678 if (fc > 0 && (fc & (fc - 1)) == 0) {
4679 n = -1;
4680 while (fc) {
4681 fc >>= 1;
4682 n++;
4684 vtop->c.i = n;
4685 if (op == '*')
4686 op = TOK_SHL;
4687 else if (op == TOK_PDIV)
4688 op = TOK_SAR;
4689 else
4690 op = TOK_SHR;
4692 goto general_case;
4693 } else if (c2 && (op == '+' || op == '-') &&
4694 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
4695 (VT_CONST | VT_SYM)) {
4696 /* symbol + constant case */
4697 if (op == '-')
4698 fc = -fc;
4699 vtop--;
4700 vtop->c.i += fc;
4701 } else {
4702 general_case:
4703 if (!nocode_wanted) {
4704 /* call low level op generator */
4705 gen_opi(op);
4706 } else {
4707 vtop--;
4713 /* generate a floating point operation with constant propagation */
4714 void gen_opif(int op)
4716 int c1, c2;
4717 SValue *v1, *v2;
4718 long double f1, f2;
4720 v1 = vtop - 1;
4721 v2 = vtop;
4722 /* currently, we cannot do computations with forward symbols */
4723 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4724 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4725 if (c1 && c2) {
4726 if (v1->type.t == VT_FLOAT) {
4727 f1 = v1->c.f;
4728 f2 = v2->c.f;
4729 } else if (v1->type.t == VT_DOUBLE) {
4730 f1 = v1->c.d;
4731 f2 = v2->c.d;
4732 } else {
4733 f1 = v1->c.ld;
4734 f2 = v2->c.ld;
4737 /* NOTE: we only do constant propagation if finite number (not
4738 NaN or infinity) (ANSI spec) */
4739 if (!ieee_finite(f1) || !ieee_finite(f2))
4740 goto general_case;
4742 switch(op) {
4743 case '+': f1 += f2; break;
4744 case '-': f1 -= f2; break;
4745 case '*': f1 *= f2; break;
4746 case '/':
4747 if (f2 == 0.0) {
4748 if (const_wanted)
4749 error("division by zero in constant");
4750 goto general_case;
4752 f1 /= f2;
4753 break;
4754 /* XXX: also handles tests ? */
4755 default:
4756 goto general_case;
4758 /* XXX: overflow test ? */
4759 if (v1->type.t == VT_FLOAT) {
4760 v1->c.f = f1;
4761 } else if (v1->type.t == VT_DOUBLE) {
4762 v1->c.d = f1;
4763 } else {
4764 v1->c.ld = f1;
4766 vtop--;
4767 } else {
4768 general_case:
4769 if (!nocode_wanted) {
4770 gen_opf(op);
4771 } else {
4772 vtop--;
4777 static int pointed_size(CType *type)
4779 int align;
4780 return type_size(pointed_type(type), &align);
4783 #if 0
4784 void check_pointer_types(SValue *p1, SValue *p2)
4786 char buf1[256], buf2[256];
4787 int t1, t2;
4788 t1 = p1->t;
4789 t2 = p2->t;
4790 if (!is_compatible_types(t1, t2)) {
4791 type_to_str(buf1, sizeof(buf1), t1, NULL);
4792 type_to_str(buf2, sizeof(buf2), t2, NULL);
4793 error("incompatible pointers '%s' and '%s'", buf1, buf2);
4796 #endif
4798 /* generic gen_op: handles types problems */
4799 void gen_op(int op)
4801 int u, t1, t2, bt1, bt2, t;
4802 CType type1;
4804 t1 = vtop[-1].type.t;
4805 t2 = vtop[0].type.t;
4806 bt1 = t1 & VT_BTYPE;
4807 bt2 = t2 & VT_BTYPE;
4809 if (bt1 == VT_PTR || bt2 == VT_PTR) {
4810 /* at least one operand is a pointer */
4811 /* relationnal op: must be both pointers */
4812 if (op >= TOK_ULT && op <= TOK_GT) {
4813 // check_pointer_types(vtop, vtop - 1);
4814 /* pointers are handled are unsigned */
4815 t = VT_INT | VT_UNSIGNED;
4816 goto std_op;
4818 /* if both pointers, then it must be the '-' op */
4819 if (bt1 == VT_PTR && bt2 == VT_PTR) {
4820 if (op != '-')
4821 error("cannot use pointers here");
4822 // check_pointer_types(vtop - 1, vtop);
4823 /* XXX: check that types are compatible */
4824 u = pointed_size(&vtop[-1].type);
4825 gen_opic(op);
4826 /* set to integer type */
4827 vtop->type.t = VT_INT;
4828 vpushi(u);
4829 gen_op(TOK_PDIV);
4830 } else {
4831 /* exactly one pointer : must be '+' or '-'. */
4832 if (op != '-' && op != '+')
4833 error("cannot use pointers here");
4834 /* Put pointer as first operand */
4835 if (bt2 == VT_PTR) {
4836 vswap();
4837 swap(&t1, &t2);
4839 type1 = vtop[-1].type;
4840 /* XXX: cast to int ? (long long case) */
4841 vpushi(pointed_size(&vtop[-1].type));
4842 gen_op('*');
4843 #ifdef CONFIG_TCC_BCHECK
4844 /* if evaluating constant expression, no code should be
4845 generated, so no bound check */
4846 if (do_bounds_check && !const_wanted) {
4847 /* if bounded pointers, we generate a special code to
4848 test bounds */
4849 if (op == '-') {
4850 vpushi(0);
4851 vswap();
4852 gen_op('-');
4854 gen_bounded_ptr_add();
4855 } else
4856 #endif
4858 gen_opic(op);
4860 /* put again type if gen_opic() swaped operands */
4861 vtop->type = type1;
4863 } else if (is_float(bt1) || is_float(bt2)) {
4864 /* compute bigger type and do implicit casts */
4865 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4866 t = VT_LDOUBLE;
4867 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4868 t = VT_DOUBLE;
4869 } else {
4870 t = VT_FLOAT;
4872 /* floats can only be used for a few operations */
4873 if (op != '+' && op != '-' && op != '*' && op != '/' &&
4874 (op < TOK_ULT || op > TOK_GT))
4875 error("invalid operands for binary operation");
4876 goto std_op;
4877 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4878 /* cast to biggest op */
4879 t = VT_LLONG;
4880 /* convert to unsigned if it does not fit in a long long */
4881 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4882 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4883 t |= VT_UNSIGNED;
4884 goto std_op;
4885 } else {
4886 /* integer operations */
4887 t = VT_INT;
4888 /* convert to unsigned if it does not fit in an integer */
4889 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4890 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4891 t |= VT_UNSIGNED;
4892 std_op:
4893 /* XXX: currently, some unsigned operations are explicit, so
4894 we modify them here */
4895 if (t & VT_UNSIGNED) {
4896 if (op == TOK_SAR)
4897 op = TOK_SHR;
4898 else if (op == '/')
4899 op = TOK_UDIV;
4900 else if (op == '%')
4901 op = TOK_UMOD;
4902 else if (op == TOK_LT)
4903 op = TOK_ULT;
4904 else if (op == TOK_GT)
4905 op = TOK_UGT;
4906 else if (op == TOK_LE)
4907 op = TOK_ULE;
4908 else if (op == TOK_GE)
4909 op = TOK_UGE;
4911 vswap();
4912 type1.t = t;
4913 gen_cast(&type1);
4914 vswap();
4915 /* special case for shifts and long long: we keep the shift as
4916 an integer */
4917 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
4918 type1.t = VT_INT;
4919 gen_cast(&type1);
4920 if (is_float(t))
4921 gen_opif(op);
4922 else if ((t & VT_BTYPE) == VT_LLONG)
4923 gen_opl(op);
4924 else
4925 gen_opic(op);
4926 if (op >= TOK_ULT && op <= TOK_GT) {
4927 /* relationnal op: the result is an int */
4928 vtop->type.t = VT_INT;
4929 } else {
4930 vtop->type.t = t;
4935 /* generic itof for unsigned long long case */
4936 void gen_cvt_itof1(int t)
4938 GFuncContext gf;
4940 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
4941 (VT_LLONG | VT_UNSIGNED)) {
4943 gfunc_start(&gf, FUNC_CDECL);
4944 gfunc_param(&gf);
4945 if (t == VT_FLOAT)
4946 vpush_global_sym(&func_old_type, TOK___ulltof);
4947 else if (t == VT_DOUBLE)
4948 vpush_global_sym(&func_old_type, TOK___ulltod);
4949 else
4950 vpush_global_sym(&func_old_type, TOK___ulltold);
4951 gfunc_call(&gf);
4952 vpushi(0);
4953 vtop->r = REG_FRET;
4954 } else {
4955 gen_cvt_itof(t);
4959 /* generic ftoi for unsigned long long case */
4960 void gen_cvt_ftoi1(int t)
4962 GFuncContext gf;
4963 int st;
4965 if (t == (VT_LLONG | VT_UNSIGNED)) {
4966 /* not handled natively */
4967 gfunc_start(&gf, FUNC_CDECL);
4968 st = vtop->type.t & VT_BTYPE;
4969 gfunc_param(&gf);
4970 if (st == VT_FLOAT)
4971 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
4972 else if (st == VT_DOUBLE)
4973 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
4974 else
4975 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
4976 gfunc_call(&gf);
4977 vpushi(0);
4978 vtop->r = REG_IRET;
4979 vtop->r2 = REG_LRET;
4980 } else {
4981 gen_cvt_ftoi(t);
4985 /* force char or short cast */
4986 void force_charshort_cast(int t)
4988 int bits, dbt;
4989 dbt = t & VT_BTYPE;
4990 /* XXX: add optimization if lvalue : just change type and offset */
4991 if (dbt == VT_BYTE)
4992 bits = 8;
4993 else
4994 bits = 16;
4995 if (t & VT_UNSIGNED) {
4996 vpushi((1 << bits) - 1);
4997 gen_op('&');
4998 } else {
4999 bits = 32 - bits;
5000 vpushi(bits);
5001 gen_op(TOK_SHL);
5002 vpushi(bits);
5003 gen_op(TOK_SAR);
5007 /* cast 'vtop' to 'type' */
5008 static void gen_cast(CType *type)
5010 int sbt, dbt, sf, df, c;
5012 /* special delayed cast for char/short */
5013 /* XXX: in some cases (multiple cascaded casts), it may still
5014 be incorrect */
5015 if (vtop->r & VT_MUSTCAST) {
5016 vtop->r &= ~VT_MUSTCAST;
5017 force_charshort_cast(vtop->type.t);
5020 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
5021 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
5023 if (sbt != dbt && !nocode_wanted) {
5024 sf = is_float(sbt);
5025 df = is_float(dbt);
5026 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5027 if (sf && df) {
5028 /* convert from fp to fp */
5029 if (c) {
5030 /* constant case: we can do it now */
5031 /* XXX: in ISOC, cannot do it if error in convert */
5032 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
5033 vtop->c.f = (float)vtop->c.d;
5034 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
5035 vtop->c.f = (float)vtop->c.ld;
5036 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
5037 vtop->c.d = (double)vtop->c.f;
5038 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
5039 vtop->c.d = (double)vtop->c.ld;
5040 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
5041 vtop->c.ld = (long double)vtop->c.f;
5042 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
5043 vtop->c.ld = (long double)vtop->c.d;
5044 } else {
5045 /* non constant case: generate code */
5046 gen_cvt_ftof(dbt);
5048 } else if (df) {
5049 /* convert int to fp */
5050 if (c) {
5051 switch(sbt) {
5052 case VT_LLONG | VT_UNSIGNED:
5053 case VT_LLONG:
5054 /* XXX: add const cases for long long */
5055 goto do_itof;
5056 case VT_INT | VT_UNSIGNED:
5057 switch(dbt) {
5058 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
5059 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
5060 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
5062 break;
5063 default:
5064 switch(dbt) {
5065 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
5066 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
5067 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
5069 break;
5071 } else {
5072 do_itof:
5073 gen_cvt_itof1(dbt);
5075 } else if (sf) {
5076 /* convert fp to int */
5077 /* we handle char/short/etc... with generic code */
5078 if (dbt != (VT_INT | VT_UNSIGNED) &&
5079 dbt != (VT_LLONG | VT_UNSIGNED) &&
5080 dbt != VT_LLONG)
5081 dbt = VT_INT;
5082 if (c) {
5083 switch(dbt) {
5084 case VT_LLONG | VT_UNSIGNED:
5085 case VT_LLONG:
5086 /* XXX: add const cases for long long */
5087 goto do_ftoi;
5088 case VT_INT | VT_UNSIGNED:
5089 switch(sbt) {
5090 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
5091 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5092 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5094 break;
5095 default:
5096 /* int case */
5097 switch(sbt) {
5098 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
5099 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
5100 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
5102 break;
5104 } else {
5105 do_ftoi:
5106 gen_cvt_ftoi1(dbt);
5108 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
5109 /* additionnal cast for char/short/bool... */
5110 vtop->type.t = dbt;
5111 gen_cast(type);
5113 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
5114 if ((sbt & VT_BTYPE) != VT_LLONG) {
5115 /* scalar to long long */
5116 if (c) {
5117 if (sbt == (VT_INT | VT_UNSIGNED))
5118 vtop->c.ll = vtop->c.ui;
5119 else
5120 vtop->c.ll = vtop->c.i;
5121 } else {
5122 /* machine independant conversion */
5123 gv(RC_INT);
5124 /* generate high word */
5125 if (sbt == (VT_INT | VT_UNSIGNED)) {
5126 vpushi(0);
5127 gv(RC_INT);
5128 } else {
5129 gv_dup();
5130 vpushi(31);
5131 gen_op(TOK_SAR);
5133 /* patch second register */
5134 vtop[-1].r2 = vtop->r;
5135 vpop();
5138 } else if (dbt == VT_BOOL) {
5139 /* scalar to bool */
5140 vpushi(0);
5141 gen_op(TOK_NE);
5142 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
5143 (dbt & VT_BTYPE) == VT_SHORT) {
5144 force_charshort_cast(dbt);
5145 } else if ((dbt & VT_BTYPE) == VT_INT) {
5146 /* scalar to int */
5147 if (sbt == VT_LLONG) {
5148 /* from long long: just take low order word */
5149 lexpand();
5150 vpop();
5152 /* if lvalue and single word type, nothing to do because
5153 the lvalue already contains the real type size (see
5154 VT_LVAL_xxx constants) */
5157 vtop->type = *type;
5160 /* return type size. Put alignment at 'a' */
5161 static int type_size(CType *type, int *a)
5163 Sym *s;
5164 int bt;
5166 bt = type->t & VT_BTYPE;
5167 if (bt == VT_STRUCT) {
5168 /* struct/union */
5169 s = type->ref;
5170 *a = s->r;
5171 return s->c;
5172 } else if (bt == VT_PTR) {
5173 if (type->t & VT_ARRAY) {
5174 s = type->ref;
5175 return type_size(&s->type, a) * s->c;
5176 } else {
5177 *a = PTR_SIZE;
5178 return PTR_SIZE;
5180 } else if (bt == VT_LDOUBLE) {
5181 *a = LDOUBLE_ALIGN;
5182 return LDOUBLE_SIZE;
5183 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
5184 *a = 4; /* XXX: i386 specific */
5185 return 8;
5186 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
5187 *a = 4;
5188 return 4;
5189 } else if (bt == VT_SHORT) {
5190 *a = 2;
5191 return 2;
5192 } else {
5193 /* char, void, function, _Bool */
5194 *a = 1;
5195 return 1;
5199 /* return the pointed type of t */
5200 static inline CType *pointed_type(CType *type)
5202 return &type->ref->type;
5205 /* modify type so that its it is a pointer to type. */
5206 static void mk_pointer(CType *type)
5208 Sym *s;
5209 s = sym_push(SYM_FIELD, type, 0, -1);
5210 type->t = VT_PTR | (type->t & ~VT_TYPE);
5211 type->ref = s;
5214 static int is_compatible_types(CType *type1, CType *type2)
5216 Sym *s1, *s2;
5217 int bt1, bt2, t1, t2;
5219 t1 = type1->t & VT_TYPE;
5220 t2 = type2->t & VT_TYPE;
5221 bt1 = t1 & VT_BTYPE;
5222 bt2 = t2 & VT_BTYPE;
5223 if (bt1 == VT_PTR) {
5224 type1 = pointed_type(type1);
5225 /* if function, then convert implicitely to function pointer */
5226 if (bt2 != VT_FUNC) {
5227 if (bt2 != VT_PTR)
5228 return 0;
5229 type2 = pointed_type(type2);
5231 /* void matches everything */
5232 /* XXX: not fully compliant */
5233 if ((type1->t & VT_TYPE) == VT_VOID || (type2->t & VT_TYPE) == VT_VOID)
5234 return 1;
5235 return is_compatible_types(type1, type2);
5236 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5237 return (type1->ref == type2->ref);
5238 } else if (bt1 == VT_FUNC) {
5239 if (bt2 != VT_FUNC)
5240 return 0;
5241 s1 = type1->ref;
5242 s2 = type2->ref;
5243 if (!is_compatible_types(&s1->type, &s2->type))
5244 return 0;
5245 /* XXX: not complete */
5246 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
5247 return 1;
5248 if (s1->c != s2->c)
5249 return 0;
5250 while (s1 != NULL) {
5251 if (s2 == NULL)
5252 return 0;
5253 if (!is_compatible_types(&s1->type, &s2->type))
5254 return 0;
5255 s1 = s1->next;
5256 s2 = s2->next;
5258 if (s2)
5259 return 0;
5260 return 1;
5261 } else {
5262 /* XXX: not complete */
5263 return 1;
5267 /* print a type. If 'varstr' is not NULL, then the variable is also
5268 printed in the type */
5269 /* XXX: union */
5270 /* XXX: add array and function pointers */
5271 void type_to_str(char *buf, int buf_size,
5272 CType *type, const char *varstr)
5274 int bt, v, t;
5275 Sym *s, *sa;
5276 char buf1[256];
5277 const char *tstr;
5279 t = type->t & VT_TYPE;
5280 bt = t & VT_BTYPE;
5281 buf[0] = '\0';
5282 if (t & VT_UNSIGNED)
5283 pstrcat(buf, buf_size, "unsigned ");
5284 switch(bt) {
5285 case VT_VOID:
5286 tstr = "void";
5287 goto add_tstr;
5288 case VT_BOOL:
5289 tstr = "_Bool";
5290 goto add_tstr;
5291 case VT_BYTE:
5292 tstr = "char";
5293 goto add_tstr;
5294 case VT_SHORT:
5295 tstr = "short";
5296 goto add_tstr;
5297 case VT_INT:
5298 tstr = "int";
5299 goto add_tstr;
5300 case VT_LONG:
5301 tstr = "long";
5302 goto add_tstr;
5303 case VT_LLONG:
5304 tstr = "long long";
5305 goto add_tstr;
5306 case VT_FLOAT:
5307 tstr = "float";
5308 goto add_tstr;
5309 case VT_DOUBLE:
5310 tstr = "double";
5311 goto add_tstr;
5312 case VT_LDOUBLE:
5313 tstr = "long double";
5314 add_tstr:
5315 pstrcat(buf, buf_size, tstr);
5316 break;
5317 case VT_ENUM:
5318 case VT_STRUCT:
5319 if (bt == VT_STRUCT)
5320 tstr = "struct ";
5321 else
5322 tstr = "enum ";
5323 pstrcat(buf, buf_size, tstr);
5324 v = type->ref->v & ~SYM_STRUCT;
5325 if (v >= SYM_FIRST_ANOM)
5326 pstrcat(buf, buf_size, "<anonymous>");
5327 else
5328 pstrcat(buf, buf_size, get_tok_str(v, NULL));
5329 break;
5330 case VT_FUNC:
5331 s = type->ref;
5332 type_to_str(buf, buf_size, &s->type, varstr);
5333 pstrcat(buf, buf_size, "(");
5334 sa = s->next;
5335 while (sa != NULL) {
5336 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
5337 pstrcat(buf, buf_size, buf1);
5338 sa = sa->next;
5339 if (sa)
5340 pstrcat(buf, buf_size, ", ");
5342 pstrcat(buf, buf_size, ")");
5343 goto no_var;
5344 case VT_PTR:
5345 s = type->ref;
5346 pstrcpy(buf1, sizeof(buf1), "*");
5347 if (varstr)
5348 pstrcat(buf1, sizeof(buf1), varstr);
5349 type_to_str(buf, buf_size, &s->type, buf1);
5350 goto no_var;
5352 if (varstr) {
5353 pstrcat(buf, buf_size, " ");
5354 pstrcat(buf, buf_size, varstr);
5356 no_var: ;
5359 /* verify type compatibility to store vtop in 'dt' type, and generate
5360 casts if needed. */
5361 static void gen_assign_cast(CType *dt)
5363 CType *st;
5364 char buf1[256], buf2[256];
5365 int dbt, sbt;
5367 st = &vtop->type; /* source type */
5368 dbt = dt->t & VT_BTYPE;
5369 sbt = st->t & VT_BTYPE;
5370 if (dbt == VT_PTR) {
5371 /* special cases for pointers */
5372 /* a function is implicitely a function pointer */
5373 if (sbt == VT_FUNC) {
5374 if (!is_compatible_types(pointed_type(dt), st))
5375 goto error;
5376 else
5377 goto type_ok;
5379 /* '0' can also be a pointer */
5380 if (sbt == VT_INT &&
5381 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
5382 vtop->c.i == 0)
5383 goto type_ok;
5384 /* accept implicit pointer to integer cast with warning */
5385 if (sbt == VT_BYTE || sbt == VT_SHORT ||
5386 sbt == VT_INT || sbt == VT_LLONG) {
5387 warning("assignment makes pointer from integer without a cast");
5388 goto type_ok;
5390 } else if (dbt == VT_BYTE || dbt == VT_SHORT ||
5391 dbt == VT_INT || dbt == VT_LLONG) {
5392 if (sbt == VT_PTR || sbt == VT_FUNC) {
5393 warning("assignment makes integer from pointer without a cast");
5394 goto type_ok;
5397 if (!is_compatible_types(dt, st)) {
5398 error:
5399 type_to_str(buf1, sizeof(buf1), st, NULL);
5400 type_to_str(buf2, sizeof(buf2), dt, NULL);
5401 error("cannot cast '%s' to '%s'", buf1, buf2);
5403 type_ok:
5404 gen_cast(dt);
5407 /* store vtop in lvalue pushed on stack */
5408 void vstore(void)
5410 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
5411 GFuncContext gf;
5413 ft = vtop[-1].type.t;
5414 sbt = vtop->type.t & VT_BTYPE;
5415 dbt = ft & VT_BTYPE;
5416 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
5417 (sbt == VT_INT && dbt == VT_SHORT)) {
5418 /* optimize char/short casts */
5419 delayed_cast = VT_MUSTCAST;
5420 vtop->type.t = ft & VT_TYPE;
5421 } else {
5422 delayed_cast = 0;
5423 gen_assign_cast(&vtop[-1].type);
5426 if (sbt == VT_STRUCT) {
5427 /* if structure, only generate pointer */
5428 /* structure assignment : generate memcpy */
5429 /* XXX: optimize if small size */
5430 if (!nocode_wanted) {
5431 vdup();
5432 gfunc_start(&gf, FUNC_CDECL);
5433 /* type size */
5434 size = type_size(&vtop->type, &align);
5435 vpushi(size);
5436 gfunc_param(&gf);
5437 /* source */
5438 vtop->type.t = VT_INT;
5439 gaddrof();
5440 gfunc_param(&gf);
5441 /* destination */
5442 vswap();
5443 vtop->type.t = VT_INT;
5444 gaddrof();
5445 gfunc_param(&gf);
5447 save_regs(0);
5448 vpush_global_sym(&func_old_type, TOK_memcpy);
5449 gfunc_call(&gf);
5450 } else {
5451 vswap();
5452 vpop();
5454 /* leave source on stack */
5455 } else if (ft & VT_BITFIELD) {
5456 /* bitfield store handling */
5457 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
5458 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5459 /* remove bit field info to avoid loops */
5460 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
5462 /* duplicate destination */
5463 vdup();
5464 vtop[-1] = vtop[-2];
5466 /* mask and shift source */
5467 vpushi((1 << bit_size) - 1);
5468 gen_op('&');
5469 vpushi(bit_pos);
5470 gen_op(TOK_SHL);
5471 /* load destination, mask and or with source */
5472 vswap();
5473 vpushi(~(((1 << bit_size) - 1) << bit_pos));
5474 gen_op('&');
5475 gen_op('|');
5476 /* store result */
5477 vstore();
5478 } else {
5479 #ifdef CONFIG_TCC_BCHECK
5480 /* bound check case */
5481 if (vtop[-1].r & VT_MUSTBOUND) {
5482 vswap();
5483 gbound();
5484 vswap();
5486 #endif
5487 if (!nocode_wanted) {
5488 rc = RC_INT;
5489 if (is_float(ft))
5490 rc = RC_FLOAT;
5491 r = gv(rc); /* generate value */
5492 /* if lvalue was saved on stack, must read it */
5493 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
5494 SValue sv;
5495 t = get_reg(RC_INT);
5496 sv.type.t = VT_INT;
5497 sv.r = VT_LOCAL | VT_LVAL;
5498 sv.c.ul = vtop[-1].c.ul;
5499 load(t, &sv);
5500 vtop[-1].r = t | VT_LVAL;
5502 store(r, vtop - 1);
5503 /* two word case handling : store second register at word + 4 */
5504 if ((ft & VT_BTYPE) == VT_LLONG) {
5505 vswap();
5506 /* convert to int to increment easily */
5507 vtop->type.t = VT_INT;
5508 gaddrof();
5509 vpushi(4);
5510 gen_op('+');
5511 vtop->r |= VT_LVAL;
5512 vswap();
5513 /* XXX: it works because r2 is spilled last ! */
5514 store(vtop->r2, vtop - 1);
5517 vswap();
5518 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5519 vtop->r |= delayed_cast;
5523 /* post defines POST/PRE add. c is the token ++ or -- */
5524 void inc(int post, int c)
5526 test_lvalue();
5527 vdup(); /* save lvalue */
5528 if (post) {
5529 gv_dup(); /* duplicate value */
5530 vrotb(3);
5531 vrotb(3);
5533 /* add constant */
5534 vpushi(c - TOK_MID);
5535 gen_op('+');
5536 vstore(); /* store value */
5537 if (post)
5538 vpop(); /* if post op, return saved value */
5541 /* Parse GNUC __attribute__ extension. Currently, the following
5542 extensions are recognized:
5543 - aligned(n) : set data/function alignment.
5544 - section(x) : generate data/code in this section.
5545 - unused : currently ignored, but may be used someday.
5547 void parse_attribute(AttributeDef *ad)
5549 int t, n;
5551 next();
5552 skip('(');
5553 skip('(');
5554 while (tok != ')') {
5555 if (tok < TOK_IDENT)
5556 expect("attribute name");
5557 t = tok;
5558 next();
5559 switch(t) {
5560 case TOK_SECTION:
5561 case TOK___SECTION__:
5562 skip('(');
5563 if (tok != TOK_STR)
5564 expect("section name");
5565 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
5566 next();
5567 skip(')');
5568 break;
5569 case TOK_ALIGNED:
5570 case TOK___ALIGNED__:
5571 if (tok == '(') {
5572 next();
5573 n = expr_const();
5574 if (n <= 0 || (n & (n - 1)) != 0)
5575 error("alignment must be a positive power of two");
5576 skip(')');
5577 } else {
5578 n = MAX_ALIGN;
5580 ad->aligned = n;
5581 break;
5582 case TOK_UNUSED:
5583 case TOK___UNUSED__:
5584 /* currently, no need to handle it because tcc does not
5585 track unused objects */
5586 break;
5587 case TOK_NORETURN:
5588 case TOK___NORETURN__:
5589 /* currently, no need to handle it because tcc does not
5590 track unused objects */
5591 break;
5592 case TOK_CDECL:
5593 case TOK___CDECL:
5594 case TOK___CDECL__:
5595 ad->func_call = FUNC_CDECL;
5596 break;
5597 case TOK_STDCALL:
5598 case TOK___STDCALL:
5599 case TOK___STDCALL__:
5600 ad->func_call = FUNC_STDCALL;
5601 break;
5602 default:
5603 warning("'%s' attribute ignored", get_tok_str(t, NULL));
5604 /* skip parameters */
5605 /* XXX: skip parenthesis too */
5606 if (tok == '(') {
5607 next();
5608 while (tok != ')' && tok != -1)
5609 next();
5610 next();
5612 break;
5614 if (tok != ',')
5615 break;
5616 next();
5618 skip(')');
5619 skip(')');
5622 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5623 static void struct_decl(CType *type, int u)
5625 int a, v, size, align, maxalign, c, offset;
5626 int bit_size, bit_pos, bsize, bt, lbit_pos;
5627 Sym *s, *ss, **ps;
5628 AttributeDef ad;
5629 CType type1, btype;
5631 a = tok; /* save decl type */
5632 next();
5633 if (tok != '{') {
5634 v = tok;
5635 next();
5636 /* struct already defined ? return it */
5637 /* XXX: check consistency */
5638 s = struct_find(v);
5639 if (s) {
5640 if (s->type.t != a)
5641 error("invalid type");
5642 goto do_decl;
5644 } else {
5645 v = anon_sym++;
5647 type1.t = a;
5648 s = sym_push(v | SYM_STRUCT, &type1, 0, 0);
5649 /* put struct/union/enum name in type */
5650 do_decl:
5651 type->t = u;
5652 type->ref = s;
5654 if (tok == '{') {
5655 next();
5656 if (s->c)
5657 error("struct/union/enum already defined");
5658 /* cannot be empty */
5659 c = 0;
5660 /* non empty enums are not allowed */
5661 if (a == TOK_ENUM) {
5662 for(;;) {
5663 v = tok;
5664 if (v < TOK_UIDENT)
5665 expect("identifier");
5666 next();
5667 if (tok == '=') {
5668 next();
5669 c = expr_const();
5671 /* enum symbols have static storage */
5672 ss = sym_push(v, &int_type, VT_CONST, c);
5673 ss->type.t |= VT_STATIC;
5674 if (tok != ',')
5675 break;
5676 next();
5677 c++;
5678 /* NOTE: we accept a trailing comma */
5679 if (tok == '}')
5680 break;
5682 skip('}');
5683 } else {
5684 maxalign = 1;
5685 ps = &s->next;
5686 bit_pos = 0;
5687 offset = 0;
5688 while (tok != '}') {
5689 parse_btype(&btype, &ad);
5690 while (1) {
5691 bit_size = -1;
5692 v = 0;
5693 type1 = btype;
5694 if (tok != ':') {
5695 type_decl(&type1, &ad, &v, TYPE_DIRECT);
5696 if ((type1.t & VT_BTYPE) == VT_FUNC ||
5697 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
5698 error("invalid type for '%s'",
5699 get_tok_str(v, NULL));
5701 if (tok == ':') {
5702 next();
5703 bit_size = expr_const();
5704 /* XXX: handle v = 0 case for messages */
5705 if (bit_size < 0)
5706 error("negative width in bit-field '%s'",
5707 get_tok_str(v, NULL));
5708 if (v && bit_size == 0)
5709 error("zero width for bit-field '%s'",
5710 get_tok_str(v, NULL));
5712 size = type_size(&type1, &align);
5713 lbit_pos = 0;
5714 if (bit_size >= 0) {
5715 bt = type1.t & VT_BTYPE;
5716 if (bt != VT_INT &&
5717 bt != VT_BYTE &&
5718 bt != VT_SHORT &&
5719 bt != VT_ENUM)
5720 error("bitfields must have scalar type");
5721 bsize = size * 8;
5722 if (bit_size > bsize) {
5723 error("width of '%s' exceeds its type",
5724 get_tok_str(v, NULL));
5725 } else if (bit_size == bsize) {
5726 /* no need for bit fields */
5727 bit_pos = 0;
5728 } else if (bit_size == 0) {
5729 /* XXX: what to do if only padding in a
5730 structure ? */
5731 /* zero size: means to pad */
5732 if (bit_pos > 0)
5733 bit_pos = bsize;
5734 } else {
5735 /* we do not have enough room ? */
5736 if ((bit_pos + bit_size) > bsize)
5737 bit_pos = 0;
5738 lbit_pos = bit_pos;
5739 /* XXX: handle LSB first */
5740 type1.t |= VT_BITFIELD |
5741 (bit_pos << VT_STRUCT_SHIFT) |
5742 (bit_size << (VT_STRUCT_SHIFT + 6));
5743 bit_pos += bit_size;
5745 } else {
5746 bit_pos = 0;
5748 if (v) {
5749 /* add new memory data only if starting
5750 bit field */
5751 if (lbit_pos == 0) {
5752 if (a == TOK_STRUCT) {
5753 c = (c + align - 1) & -align;
5754 offset = c;
5755 c += size;
5756 } else {
5757 offset = 0;
5758 if (size > c)
5759 c = size;
5761 if (align > maxalign)
5762 maxalign = align;
5764 #if 0
5765 printf("add field %s offset=%d",
5766 get_tok_str(v, NULL), offset);
5767 if (type1.t & VT_BITFIELD) {
5768 printf(" pos=%d size=%d",
5769 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
5770 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
5772 printf("\n");
5773 #endif
5774 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
5775 *ps = ss;
5776 ps = &ss->next;
5778 if (tok == ';' || tok == TOK_EOF)
5779 break;
5780 skip(',');
5782 skip(';');
5784 skip('}');
5785 /* store size and alignment */
5786 s->c = (c + maxalign - 1) & -maxalign;
5787 s->r = maxalign;
5792 /* return 0 if no type declaration. otherwise, return the basic type
5793 and skip it.
5795 static int parse_btype(CType *type, AttributeDef *ad)
5797 int t, u, type_found;
5798 Sym *s;
5799 CType type1;
5801 memset(ad, 0, sizeof(AttributeDef));
5802 type_found = 0;
5803 t = 0;
5804 while(1) {
5805 switch(tok) {
5806 /* basic types */
5807 case TOK_CHAR:
5808 u = VT_BYTE;
5809 basic_type:
5810 next();
5811 basic_type1:
5812 if ((t & VT_BTYPE) != 0)
5813 error("too many basic types");
5814 t |= u;
5815 break;
5816 case TOK_VOID:
5817 u = VT_VOID;
5818 goto basic_type;
5819 case TOK_SHORT:
5820 u = VT_SHORT;
5821 goto basic_type;
5822 case TOK_INT:
5823 next();
5824 break;
5825 case TOK_LONG:
5826 next();
5827 if ((t & VT_BTYPE) == VT_DOUBLE) {
5828 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5829 } else if ((t & VT_BTYPE) == VT_LONG) {
5830 t = (t & ~VT_BTYPE) | VT_LLONG;
5831 } else {
5832 u = VT_LONG;
5833 goto basic_type1;
5835 break;
5836 case TOK_BOOL:
5837 u = VT_BOOL;
5838 goto basic_type;
5839 case TOK_FLOAT:
5840 u = VT_FLOAT;
5841 goto basic_type;
5842 case TOK_DOUBLE:
5843 next();
5844 if ((t & VT_BTYPE) == VT_LONG) {
5845 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5846 } else {
5847 u = VT_DOUBLE;
5848 goto basic_type1;
5850 break;
5851 case TOK_ENUM:
5852 struct_decl(&type1, VT_ENUM);
5853 basic_type2:
5854 u = type1.t;
5855 type->ref = type1.ref;
5856 goto basic_type1;
5857 case TOK_STRUCT:
5858 case TOK_UNION:
5859 struct_decl(&type1, VT_STRUCT);
5860 goto basic_type2;
5862 /* type modifiers */
5863 case TOK_CONST:
5864 case TOK_VOLATILE:
5865 case TOK_REGISTER:
5866 case TOK_SIGNED:
5867 case TOK___SIGNED__:
5868 case TOK_AUTO:
5869 case TOK_INLINE:
5870 case TOK___INLINE__:
5871 case TOK_RESTRICT:
5872 next();
5873 break;
5874 case TOK_UNSIGNED:
5875 t |= VT_UNSIGNED;
5876 next();
5877 break;
5879 /* storage */
5880 case TOK_EXTERN:
5881 t |= VT_EXTERN;
5882 next();
5883 break;
5884 case TOK_STATIC:
5885 t |= VT_STATIC;
5886 next();
5887 break;
5888 case TOK_TYPEDEF:
5889 t |= VT_TYPEDEF;
5890 next();
5891 break;
5892 /* GNUC attribute */
5893 case TOK___ATTRIBUTE__:
5894 parse_attribute(ad);
5895 break;
5896 /* GNUC typeof */
5897 case TOK_TYPEOF:
5898 next();
5899 parse_expr_type(&type1);
5900 goto basic_type2;
5901 default:
5902 s = sym_find(tok);
5903 if (!s || !(s->type.t & VT_TYPEDEF))
5904 goto the_end;
5905 t |= (s->type.t & ~VT_TYPEDEF);
5906 type->ref = s->type.ref;
5907 next();
5908 break;
5910 type_found = 1;
5912 the_end:
5913 /* long is never used as type */
5914 if ((t & VT_BTYPE) == VT_LONG)
5915 t = (t & ~VT_BTYPE) | VT_INT;
5916 type->t = t;
5917 return type_found;
5920 static void post_type(CType *type, AttributeDef *ad)
5922 int n, l, t1;
5923 Sym **plast, *s, *first;
5924 AttributeDef ad1;
5925 CType pt;
5927 if (tok == '(') {
5928 /* function declaration */
5929 next();
5930 l = 0;
5931 first = NULL;
5932 plast = &first;
5933 while (tok != ')') {
5934 /* read param name and compute offset */
5935 if (l != FUNC_OLD) {
5936 if (!parse_btype(&pt, &ad1)) {
5937 if (l) {
5938 error("invalid type");
5939 } else {
5940 l = FUNC_OLD;
5941 goto old_proto;
5944 l = FUNC_NEW;
5945 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
5946 break;
5947 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
5948 if ((pt.t & VT_BTYPE) == VT_VOID)
5949 error("parameter declared as void");
5950 } else {
5951 old_proto:
5952 n = tok;
5953 pt.t = VT_INT;
5954 next();
5956 /* array must be transformed to pointer according to ANSI C */
5957 pt.t &= ~VT_ARRAY;
5958 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
5959 *plast = s;
5960 plast = &s->next;
5961 if (tok == ',') {
5962 next();
5963 if (l == FUNC_NEW && tok == TOK_DOTS) {
5964 l = FUNC_ELLIPSIS;
5965 next();
5966 break;
5970 /* if no parameters, then old type prototype */
5971 if (l == 0)
5972 l = FUNC_OLD;
5973 skip(')');
5974 t1 = type->t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5975 type->t &= ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5976 post_type(type, ad);
5977 /* we push a anonymous symbol which will contain the function prototype */
5978 s = sym_push(SYM_FIELD, type, ad->func_call, l);
5979 s->next = first;
5980 type->t = t1 | VT_FUNC;
5981 type->ref = s;
5982 } else if (tok == '[') {
5983 /* array definition */
5984 next();
5985 n = -1;
5986 if (tok != ']') {
5987 n = expr_const();
5988 if (n < 0)
5989 error("invalid array size");
5991 skip(']');
5992 /* parse next post type */
5993 t1 = type->t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5994 type->t &= ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5995 post_type(type, ad);
5997 /* we push a anonymous symbol which will contain the array
5998 element type */
5999 s = sym_push(SYM_FIELD, type, 0, n);
6000 type->t = t1 | VT_ARRAY | VT_PTR;
6001 type->ref = s;
6005 /* Parse a type declaration (except basic type), and return the type
6006 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6007 expected. 'type' should contain the basic type. 'ad' is the
6008 attribute definition of the basic type. It can be modified by
6009 type_decl().
6011 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
6013 Sym *s;
6014 CType type1, *type2;
6016 while (tok == '*') {
6017 next();
6018 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
6019 next();
6020 mk_pointer(type);
6023 /* recursive type */
6024 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6025 type1.t = 0; /* XXX: same as int */
6026 if (tok == '(') {
6027 next();
6028 /* XXX: this is not correct to modify 'ad' at this point, but
6029 the syntax is not clear */
6030 if (tok == TOK___ATTRIBUTE__)
6031 parse_attribute(ad);
6032 type_decl(&type1, ad, v, td);
6033 skip(')');
6034 } else {
6035 /* type identifier */
6036 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
6037 *v = tok;
6038 next();
6039 } else {
6040 if (!(td & TYPE_ABSTRACT))
6041 expect("identifier");
6042 *v = 0;
6045 post_type(type, ad);
6046 if (tok == TOK___ATTRIBUTE__)
6047 parse_attribute(ad);
6048 if (!type1.t)
6049 return;
6050 /* append type at the end of type1 */
6051 type2 = &type1;
6052 for(;;) {
6053 s = type2->ref;
6054 type2 = &s->type;
6055 if (!type2->t) {
6056 *type2 = *type;
6057 break;
6060 *type = type1;
6063 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6064 static int lvalue_type(int t)
6066 int bt, r;
6067 r = VT_LVAL;
6068 bt = t & VT_BTYPE;
6069 if (bt == VT_BYTE)
6070 r |= VT_LVAL_BYTE;
6071 else if (bt == VT_SHORT)
6072 r |= VT_LVAL_SHORT;
6073 else
6074 return r;
6075 if (t & VT_UNSIGNED)
6076 r |= VT_LVAL_UNSIGNED;
6077 return r;
6080 /* indirection with full error checking and bound check */
6081 static void indir(void)
6083 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6084 expect("pointer");
6085 if ((vtop->r & VT_LVAL) && !nocode_wanted)
6086 gv(RC_INT);
6087 vtop->type = *pointed_type(&vtop->type);
6088 /* an array is never an lvalue */
6089 if (!(vtop->type.t & VT_ARRAY)) {
6090 vtop->r |= lvalue_type(vtop->type.t);
6091 /* if bound checking, the referenced pointer must be checked */
6092 if (do_bounds_check)
6093 vtop->r |= VT_MUSTBOUND;
6097 /* pass a parameter to a function and do type checking and casting */
6098 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
6100 int func_type;
6101 CType type;
6103 func_type = func->c;
6104 if (func_type == FUNC_OLD ||
6105 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
6106 /* default casting : only need to convert float to double */
6107 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
6108 type.t = VT_DOUBLE;
6109 gen_cast(&type);
6111 } else if (arg == NULL) {
6112 error("too many arguments to function");
6113 } else {
6114 gen_assign_cast(&arg->type);
6116 if (!nocode_wanted) {
6117 gfunc_param(gf);
6118 } else {
6119 vpop();
6123 /* parse an expression of the form '(type)' or '(expr)' and return its
6124 type */
6125 static void parse_expr_type(CType *type)
6127 int n;
6128 AttributeDef ad;
6130 skip('(');
6131 if (parse_btype(type, &ad)) {
6132 type_decl(type, &ad, &n, TYPE_ABSTRACT);
6133 } else {
6134 expr_type(type);
6136 skip(')');
6139 static void vpush_tokc(int t)
6141 CType type;
6142 type.t = t;
6143 vsetc(&type, VT_CONST, &tokc);
6146 static void unary(void)
6148 int n, t, align, size, r;
6149 CType type;
6150 Sym *s;
6151 GFuncContext gf;
6152 AttributeDef ad;
6154 /* XXX: GCC 2.95.3 does not generate a table although it should be
6155 better here */
6156 switch(tok) {
6157 case TOK_CINT:
6158 case TOK_CCHAR:
6159 case TOK_LCHAR:
6160 vpushi(tokc.i);
6161 next();
6162 break;
6163 case TOK_CUINT:
6164 vpush_tokc(VT_INT | VT_UNSIGNED);
6165 next();
6166 break;
6167 case TOK_CLLONG:
6168 vpush_tokc(VT_LLONG);
6169 next();
6170 break;
6171 case TOK_CULLONG:
6172 vpush_tokc(VT_LLONG | VT_UNSIGNED);
6173 next();
6174 break;
6175 case TOK_CFLOAT:
6176 vpush_tokc(VT_FLOAT);
6177 next();
6178 break;
6179 case TOK_CDOUBLE:
6180 vpush_tokc(VT_DOUBLE);
6181 next();
6182 break;
6183 case TOK_CLDOUBLE:
6184 vpush_tokc(VT_LDOUBLE);
6185 next();
6186 break;
6187 case TOK___FUNCTION__:
6188 if (!gnu_ext)
6189 goto tok_identifier;
6190 /* fall thru */
6191 case TOK___FUNC__:
6193 void *ptr;
6194 int len;
6195 /* special function name identifier */
6196 len = strlen(funcname) + 1;
6197 /* generate char[len] type */
6198 type.t = VT_BYTE;
6199 mk_pointer(&type);
6200 type.t |= VT_ARRAY;
6201 type.ref->c = len;
6202 vpush_ref(&type, data_section, data_section->data_offset, len);
6203 ptr = section_ptr_add(data_section, len);
6204 memcpy(ptr, funcname, len);
6205 next();
6207 break;
6208 case TOK_LSTR:
6209 t = VT_INT;
6210 goto str_init;
6211 case TOK_STR:
6212 /* string parsing */
6213 t = VT_BYTE;
6214 str_init:
6215 type.t = t;
6216 mk_pointer(&type);
6217 type.t |= VT_ARRAY;
6218 memset(&ad, 0, sizeof(AttributeDef));
6219 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
6220 break;
6221 case '(':
6222 next();
6223 /* cast ? */
6224 if (parse_btype(&type, &ad)) {
6225 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
6226 skip(')');
6227 /* check ISOC99 compound literal */
6228 if (tok == '{') {
6229 /* data is allocated locally by default */
6230 if (global_expr)
6231 r = VT_CONST;
6232 else
6233 r = VT_LOCAL;
6234 /* all except arrays are lvalues */
6235 if (!(type.t & VT_ARRAY))
6236 r |= lvalue_type(type.t);
6237 memset(&ad, 0, sizeof(AttributeDef));
6238 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
6239 } else {
6240 unary();
6241 gen_cast(&type);
6243 } else {
6244 gexpr();
6245 skip(')');
6247 break;
6248 case '*':
6249 next();
6250 unary();
6251 indir();
6252 break;
6253 case '&':
6254 next();
6255 unary();
6256 /* functions names must be treated as function pointers,
6257 except for unary '&' and sizeof. Since we consider that
6258 functions are not lvalues, we only have to handle it
6259 there and in function calls. */
6260 /* arrays can also be used although they are not lvalues */
6261 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
6262 !(vtop->type.t & VT_ARRAY))
6263 test_lvalue();
6264 mk_pointer(&vtop->type);
6265 gaddrof();
6266 break;
6267 case '!':
6268 next();
6269 unary();
6270 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
6271 vtop->c.i = !vtop->c.i;
6272 else if ((vtop->r & VT_VALMASK) == VT_CMP)
6273 vtop->c.i = vtop->c.i ^ 1;
6274 else
6275 vseti(VT_JMP, gtst(1, 0));
6276 break;
6277 case '~':
6278 next();
6279 unary();
6280 vpushi(-1);
6281 gen_op('^');
6282 break;
6283 case '+':
6284 next();
6285 /* in order to force cast, we add zero */
6286 unary();
6287 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
6288 error("pointer not accepted for unary plus");
6289 vpushi(0);
6290 gen_op('+');
6291 break;
6292 case TOK_SIZEOF:
6293 case TOK_ALIGNOF:
6294 t = tok;
6295 next();
6296 if (tok == '(') {
6297 parse_expr_type(&type);
6298 } else {
6299 unary_type(&type);
6301 size = type_size(&type, &align);
6302 if (t == TOK_SIZEOF)
6303 vpushi(size);
6304 else
6305 vpushi(align);
6306 break;
6308 case TOK_INC:
6309 case TOK_DEC:
6310 t = tok;
6311 next();
6312 unary();
6313 inc(0, t);
6314 break;
6315 case '-':
6316 next();
6317 vpushi(0);
6318 unary();
6319 gen_op('-');
6320 break;
6321 case TOK_LAND:
6322 if (!gnu_ext)
6323 goto tok_identifier;
6324 next();
6325 /* allow to take the address of a label */
6326 if (tok < TOK_UIDENT)
6327 expect("label identifier");
6328 s = label_find(tok);
6329 if (!s) {
6330 s = label_push(tok, LABEL_FORWARD);
6332 if (!s->type.t) {
6333 s->type.t = VT_VOID;
6334 mk_pointer(&s->type);
6335 s->type.t |= VT_STATIC;
6337 vset(&s->type, VT_CONST | VT_SYM, 0);
6338 vtop->sym = s;
6339 next();
6340 break;
6341 default:
6342 tok_identifier:
6343 t = tok;
6344 next();
6345 if (t < TOK_UIDENT)
6346 expect("identifier");
6347 s = sym_find(t);
6348 if (!s) {
6349 if (tok != '(')
6350 error("'%s' undeclared", get_tok_str(t, NULL));
6351 /* for simple function calls, we tolerate undeclared
6352 external reference to int() function */
6353 s = external_global_sym(t, &func_old_type, 0);
6355 vset(&s->type, s->r, s->c);
6356 /* if forward reference, we must point to s */
6357 if (vtop->r & VT_SYM) {
6358 vtop->sym = s;
6359 vtop->c.ul = 0;
6361 break;
6364 /* post operations */
6365 while (1) {
6366 if (tok == TOK_INC || tok == TOK_DEC) {
6367 inc(1, tok);
6368 next();
6369 } else if (tok == '.' || tok == TOK_ARROW) {
6370 /* field */
6371 if (tok == TOK_ARROW)
6372 indir();
6373 test_lvalue();
6374 gaddrof();
6375 next();
6376 /* expect pointer on structure */
6377 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
6378 expect("struct or union");
6379 s = vtop->type.ref;
6380 /* find field */
6381 tok |= SYM_FIELD;
6382 while ((s = s->next) != NULL) {
6383 if (s->v == tok)
6384 break;
6386 if (!s)
6387 error("field not found");
6388 /* add field offset to pointer */
6389 vtop->type = char_pointer_type; /* change type to 'char *' */
6390 vpushi(s->c);
6391 gen_op('+');
6392 /* change type to field type, and set to lvalue */
6393 vtop->type = s->type;
6394 /* an array is never an lvalue */
6395 if (!(vtop->type.t & VT_ARRAY)) {
6396 vtop->r |= lvalue_type(vtop->type.t);
6397 /* if bound checking, the referenced pointer must be checked */
6398 if (do_bounds_check)
6399 vtop->r |= VT_MUSTBOUND;
6401 next();
6402 } else if (tok == '[') {
6403 next();
6404 gexpr();
6405 gen_op('+');
6406 indir();
6407 skip(']');
6408 } else if (tok == '(') {
6409 SValue ret;
6410 Sym *sa;
6412 /* function call */
6413 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
6414 /* pointer test (no array accepted) */
6415 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
6416 vtop->type = *pointed_type(&vtop->type);
6417 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
6418 goto error_func;
6419 } else {
6420 error_func:
6421 expect("function pointer");
6423 } else {
6424 vtop->r &= ~VT_LVAL; /* no lvalue */
6426 /* get return type */
6427 s = vtop->type.ref;
6428 if (!nocode_wanted) {
6429 save_regs(0); /* save used temporary registers */
6430 gfunc_start(&gf, s->r);
6432 next();
6433 sa = s->next; /* first parameter */
6434 #ifdef INVERT_FUNC_PARAMS
6436 int parlevel;
6437 Sym *args, *s1;
6438 ParseState saved_parse_state;
6439 TokenString str;
6441 /* read each argument and store it on a stack */
6442 args = NULL;
6443 if (tok != ')') {
6444 for(;;) {
6445 tok_str_new(&str);
6446 parlevel = 0;
6447 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
6448 tok != TOK_EOF) {
6449 if (tok == '(')
6450 parlevel++;
6451 else if (tok == ')')
6452 parlevel--;
6453 tok_str_add_tok(&str);
6454 next();
6456 tok_str_add(&str, -1); /* end of file added */
6457 tok_str_add(&str, 0);
6458 s1 = sym_push2(&args, 0, 0, (int)str.str);
6459 s1->next = sa; /* add reference to argument */
6460 if (sa)
6461 sa = sa->next;
6462 if (tok == ')')
6463 break;
6464 skip(',');
6468 /* now generate code in reverse order by reading the stack */
6469 save_parse_state(&saved_parse_state);
6470 while (args) {
6471 macro_ptr = (int *)args->c;
6472 next();
6473 expr_eq();
6474 if (tok != -1)
6475 expect("',' or ')'");
6476 gfunc_param_typed(&gf, s, args->next);
6477 s1 = args->prev;
6478 tok_str_free((int *)args->c);
6479 tcc_free(args);
6480 args = s1;
6482 restore_parse_state(&saved_parse_state);
6484 #endif
6485 /* compute first implicit argument if a structure is returned */
6486 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6487 /* get some space for the returned structure */
6488 size = type_size(&s->type, &align);
6489 loc = (loc - size) & -align;
6490 ret.type = s->type;
6491 ret.r = VT_LOCAL | VT_LVAL;
6492 /* pass it as 'int' to avoid structure arg passing
6493 problems */
6494 vseti(VT_LOCAL, loc);
6495 ret.c = vtop->c;
6496 if (!nocode_wanted)
6497 gfunc_param(&gf);
6498 else
6499 vtop--;
6500 } else {
6501 ret.type = s->type;
6502 ret.r2 = VT_CONST;
6503 /* return in register */
6504 if (is_float(ret.type.t)) {
6505 ret.r = REG_FRET;
6506 } else {
6507 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
6508 ret.r2 = REG_LRET;
6509 ret.r = REG_IRET;
6511 ret.c.i = 0;
6513 #ifndef INVERT_FUNC_PARAMS
6514 if (tok != ')') {
6515 for(;;) {
6516 expr_eq();
6517 gfunc_param_typed(&gf, s, sa);
6518 if (sa)
6519 sa = sa->next;
6520 if (tok == ')')
6521 break;
6522 skip(',');
6525 #endif
6526 if (sa)
6527 error("too few arguments to function");
6528 skip(')');
6529 if (!nocode_wanted)
6530 gfunc_call(&gf);
6531 else
6532 vtop--;
6533 /* return value */
6534 vsetc(&ret.type, ret.r, &ret.c);
6535 vtop->r2 = ret.r2;
6536 } else {
6537 break;
6542 static void uneq(void)
6544 int t;
6546 unary();
6547 if (tok == '=' ||
6548 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
6549 tok == TOK_A_XOR || tok == TOK_A_OR ||
6550 tok == TOK_A_SHL || tok == TOK_A_SAR) {
6551 test_lvalue();
6552 t = tok;
6553 next();
6554 if (t == '=') {
6555 expr_eq();
6556 } else {
6557 vdup();
6558 expr_eq();
6559 gen_op(t & 0x7f);
6561 vstore();
6565 static void expr_prod(void)
6567 int t;
6569 uneq();
6570 while (tok == '*' || tok == '/' || tok == '%') {
6571 t = tok;
6572 next();
6573 uneq();
6574 gen_op(t);
6578 static void expr_sum(void)
6580 int t;
6582 expr_prod();
6583 while (tok == '+' || tok == '-') {
6584 t = tok;
6585 next();
6586 expr_prod();
6587 gen_op(t);
6591 static void expr_shift(void)
6593 int t;
6595 expr_sum();
6596 while (tok == TOK_SHL || tok == TOK_SAR) {
6597 t = tok;
6598 next();
6599 expr_sum();
6600 gen_op(t);
6604 static void expr_cmp(void)
6606 int t;
6608 expr_shift();
6609 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
6610 tok == TOK_ULT || tok == TOK_UGE) {
6611 t = tok;
6612 next();
6613 expr_shift();
6614 gen_op(t);
6618 static void expr_cmpeq(void)
6620 int t;
6622 expr_cmp();
6623 while (tok == TOK_EQ || tok == TOK_NE) {
6624 t = tok;
6625 next();
6626 expr_cmp();
6627 gen_op(t);
6631 static void expr_and(void)
6633 expr_cmpeq();
6634 while (tok == '&') {
6635 next();
6636 expr_cmpeq();
6637 gen_op('&');
6641 static void expr_xor(void)
6643 expr_and();
6644 while (tok == '^') {
6645 next();
6646 expr_and();
6647 gen_op('^');
6651 static void expr_or(void)
6653 expr_xor();
6654 while (tok == '|') {
6655 next();
6656 expr_xor();
6657 gen_op('|');
6661 /* XXX: suppress this mess */
6662 static void expr_land_const(void)
6664 expr_or();
6665 while (tok == TOK_LAND) {
6666 next();
6667 expr_or();
6668 gen_op(TOK_LAND);
6672 /* XXX: suppress this mess */
6673 static void expr_lor_const(void)
6675 expr_land_const();
6676 while (tok == TOK_LOR) {
6677 next();
6678 expr_land_const();
6679 gen_op(TOK_LOR);
6683 /* only used if non constant */
6684 static void expr_land(void)
6686 int t;
6688 expr_or();
6689 if (tok == TOK_LAND) {
6690 t = 0;
6691 for(;;) {
6692 t = gtst(1, t);
6693 if (tok != TOK_LAND) {
6694 vseti(VT_JMPI, t);
6695 break;
6697 next();
6698 expr_or();
6703 static void expr_lor(void)
6705 int t;
6707 expr_land();
6708 if (tok == TOK_LOR) {
6709 t = 0;
6710 for(;;) {
6711 t = gtst(0, t);
6712 if (tok != TOK_LOR) {
6713 vseti(VT_JMP, t);
6714 break;
6716 next();
6717 expr_land();
6722 /* XXX: better constant handling */
6723 static void expr_eq(void)
6725 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
6726 SValue sv;
6727 CType type, type1, type2;
6729 if (const_wanted) {
6730 int c1, c;
6731 expr_lor_const();
6732 if (tok == '?') {
6733 c = vtop->c.i;
6734 vpop();
6735 next();
6736 gexpr();
6737 c1 = vtop->c.i;
6738 vpop();
6739 skip(':');
6740 expr_eq();
6741 if (c)
6742 vtop->c.i = c1;
6744 } else {
6745 expr_lor();
6746 if (tok == '?') {
6747 next();
6748 if (vtop != vstack) {
6749 /* needed to avoid having different registers saved in
6750 each branch */
6751 if (is_float(vtop->type.t))
6752 rc = RC_FLOAT;
6753 else
6754 rc = RC_INT;
6755 gv(rc);
6756 save_regs(1);
6758 tt = gtst(1, 0);
6759 gexpr();
6760 type1 = vtop->type;
6761 sv = *vtop; /* save value to handle it later */
6762 vtop--; /* no vpop so that FP stack is not flushed */
6763 skip(':');
6764 u = gjmp(0);
6765 gsym(tt);
6766 expr_eq();
6767 type2 = vtop->type;
6769 t1 = type1.t;
6770 bt1 = t1 & VT_BTYPE;
6771 t2 = type2.t;
6772 bt2 = t2 & VT_BTYPE;
6773 /* cast operands to correct type according to ISOC rules */
6774 if (is_float(bt1) || is_float(bt2)) {
6775 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
6776 type.t = VT_LDOUBLE;
6777 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
6778 type.t = VT_DOUBLE;
6779 } else {
6780 type.t = VT_FLOAT;
6782 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
6783 /* cast to biggest op */
6784 type.t = VT_LLONG;
6785 /* convert to unsigned if it does not fit in a long long */
6786 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
6787 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
6788 type.t |= VT_UNSIGNED;
6789 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
6790 /* XXX: test pointer compatibility */
6791 type = type1;
6792 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
6793 /* XXX: test structure compatibility */
6794 type = type1;
6795 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
6796 /* NOTE: as an extension, we accept void on only one side */
6797 type.t = VT_VOID;
6798 } else {
6799 /* integer operations */
6800 type.t = VT_INT;
6801 /* convert to unsigned if it does not fit in an integer */
6802 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
6803 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
6804 type.t |= VT_UNSIGNED;
6807 /* now we convert second operand */
6808 gen_cast(&type);
6809 rc = RC_INT;
6810 if (is_float(type.t)) {
6811 rc = RC_FLOAT;
6812 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
6813 /* for long longs, we use fixed registers to avoid having
6814 to handle a complicated move */
6815 rc = RC_IRET;
6818 r2 = gv(rc);
6819 /* this is horrible, but we must also convert first
6820 operand */
6821 tt = gjmp(0);
6822 gsym(u);
6823 /* put again first value and cast it */
6824 *vtop = sv;
6825 gen_cast(&type);
6826 r1 = gv(rc);
6827 move_reg(r2, r1);
6828 vtop->r = r2;
6829 gsym(tt);
6834 static void gexpr(void)
6836 while (1) {
6837 expr_eq();
6838 if (tok != ',')
6839 break;
6840 vpop();
6841 next();
6845 /* parse an expression and return its type without any side effect. */
6846 static void expr_type(CType *type)
6848 int a;
6850 a = nocode_wanted;
6851 nocode_wanted = 1;
6852 gexpr();
6853 *type = vtop->type;
6854 vpop();
6855 nocode_wanted = a;
6858 /* parse a unary expression and return its type without any side
6859 effect. */
6860 static void unary_type(CType *type)
6862 int a;
6864 a = nocode_wanted;
6865 nocode_wanted = 1;
6866 unary();
6867 *type = vtop->type;
6868 vpop();
6869 nocode_wanted = a;
6872 /* parse a constant expression and return value in vtop. */
6873 static void expr_const1(void)
6875 int a;
6876 a = const_wanted;
6877 const_wanted = 1;
6878 expr_eq();
6879 const_wanted = a;
6882 /* parse an integer constant and return its value. */
6883 static int expr_const(void)
6885 int c;
6886 expr_const1();
6887 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
6888 expect("constant expression");
6889 c = vtop->c.i;
6890 vpop();
6891 return c;
6894 /* return the label token if current token is a label, otherwise
6895 return zero */
6896 static int is_label(void)
6898 int t;
6899 CValue c;
6901 /* fast test first */
6902 if (tok < TOK_UIDENT)
6903 return 0;
6904 /* no need to save tokc since we expect an identifier */
6905 t = tok;
6906 c = tokc;
6907 next();
6908 if (tok == ':') {
6909 next();
6910 return t;
6911 } else {
6912 /* XXX: may not work in all cases (macros ?) */
6913 tok1 = tok;
6914 tok1c = tokc;
6915 tok = t;
6916 tokc = c;
6917 return 0;
6921 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
6923 int a, b, c, d;
6924 Sym *s;
6926 /* generate line number info */
6927 if (do_debug &&
6928 (last_line_num != file->line_num || last_ind != ind)) {
6929 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
6930 last_ind = ind;
6931 last_line_num = file->line_num;
6934 if (tok == TOK_IF) {
6935 /* if test */
6936 next();
6937 skip('(');
6938 gexpr();
6939 skip(')');
6940 a = gtst(1, 0);
6941 block(bsym, csym, case_sym, def_sym, case_reg);
6942 c = tok;
6943 if (c == TOK_ELSE) {
6944 next();
6945 d = gjmp(0);
6946 gsym(a);
6947 block(bsym, csym, case_sym, def_sym, case_reg);
6948 gsym(d); /* patch else jmp */
6949 } else
6950 gsym(a);
6951 } else if (tok == TOK_WHILE) {
6952 next();
6953 d = ind;
6954 skip('(');
6955 gexpr();
6956 skip(')');
6957 a = gtst(1, 0);
6958 b = 0;
6959 block(&a, &b, case_sym, def_sym, case_reg);
6960 gjmp_addr(d);
6961 gsym(a);
6962 gsym_addr(b, d);
6963 } else if (tok == '{') {
6964 next();
6965 /* declarations */
6966 s = local_stack;
6967 while (tok != '}') {
6968 decl(VT_LOCAL);
6969 if (tok != '}')
6970 block(bsym, csym, case_sym, def_sym, case_reg);
6972 /* pop locally defined symbols */
6973 sym_pop(&local_stack, s);
6974 next();
6975 } else if (tok == TOK_RETURN) {
6976 next();
6977 if (tok != ';') {
6978 gexpr();
6979 gen_assign_cast(&func_vt);
6980 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
6981 CType type;
6982 /* if returning structure, must copy it to implicit
6983 first pointer arg location */
6984 type = func_vt;
6985 mk_pointer(&type);
6986 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
6987 indir();
6988 vswap();
6989 /* copy structure value to pointer */
6990 vstore();
6991 } else if (is_float(func_vt.t)) {
6992 gv(RC_FRET);
6993 } else {
6994 gv(RC_IRET);
6996 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
6998 skip(';');
6999 rsym = gjmp(rsym); /* jmp */
7000 } else if (tok == TOK_BREAK) {
7001 /* compute jump */
7002 if (!bsym)
7003 error("cannot break");
7004 *bsym = gjmp(*bsym);
7005 next();
7006 skip(';');
7007 } else if (tok == TOK_CONTINUE) {
7008 /* compute jump */
7009 if (!csym)
7010 error("cannot continue");
7011 *csym = gjmp(*csym);
7012 next();
7013 skip(';');
7014 } else if (tok == TOK_FOR) {
7015 int e;
7016 next();
7017 skip('(');
7018 if (tok != ';') {
7019 gexpr();
7020 vpop();
7022 skip(';');
7023 d = ind;
7024 c = ind;
7025 a = 0;
7026 b = 0;
7027 if (tok != ';') {
7028 gexpr();
7029 a = gtst(1, 0);
7031 skip(';');
7032 if (tok != ')') {
7033 e = gjmp(0);
7034 c = ind;
7035 gexpr();
7036 vpop();
7037 gjmp_addr(d);
7038 gsym(e);
7040 skip(')');
7041 block(&a, &b, case_sym, def_sym, case_reg);
7042 gjmp_addr(c);
7043 gsym(a);
7044 gsym_addr(b, c);
7045 } else
7046 if (tok == TOK_DO) {
7047 next();
7048 a = 0;
7049 b = 0;
7050 d = ind;
7051 block(&a, &b, case_sym, def_sym, case_reg);
7052 skip(TOK_WHILE);
7053 skip('(');
7054 gsym(b);
7055 gexpr();
7056 c = gtst(0, 0);
7057 gsym_addr(c, d);
7058 skip(')');
7059 gsym(a);
7060 skip(';');
7061 } else
7062 if (tok == TOK_SWITCH) {
7063 next();
7064 skip('(');
7065 gexpr();
7066 /* XXX: other types than integer */
7067 case_reg = gv(RC_INT);
7068 vpop();
7069 skip(')');
7070 a = 0;
7071 b = gjmp(0); /* jump to first case */
7072 c = 0;
7073 block(&a, csym, &b, &c, case_reg);
7074 /* if no default, jmp after switch */
7075 if (c == 0)
7076 c = ind;
7077 /* default label */
7078 gsym_addr(b, c);
7079 /* break label */
7080 gsym(a);
7081 } else
7082 if (tok == TOK_CASE) {
7083 int v1, v2;
7084 if (!case_sym)
7085 expect("switch");
7086 next();
7087 v1 = expr_const();
7088 v2 = v1;
7089 if (gnu_ext && tok == TOK_DOTS) {
7090 next();
7091 v2 = expr_const();
7092 if (v2 < v1)
7093 warning("empty case range");
7095 /* since a case is like a label, we must skip it with a jmp */
7096 b = gjmp(0);
7097 gsym(*case_sym);
7098 vseti(case_reg, 0);
7099 vpushi(v1);
7100 if (v1 == v2) {
7101 gen_op(TOK_EQ);
7102 *case_sym = gtst(1, 0);
7103 } else {
7104 gen_op(TOK_GE);
7105 *case_sym = gtst(1, 0);
7106 vseti(case_reg, 0);
7107 vpushi(v2);
7108 gen_op(TOK_LE);
7109 *case_sym = gtst(1, *case_sym);
7111 gsym(b);
7112 skip(':');
7113 block(bsym, csym, case_sym, def_sym, case_reg);
7114 } else
7115 if (tok == TOK_DEFAULT) {
7116 next();
7117 skip(':');
7118 if (!def_sym)
7119 expect("switch");
7120 if (*def_sym)
7121 error("too many 'default'");
7122 *def_sym = ind;
7123 block(bsym, csym, case_sym, def_sym, case_reg);
7124 } else
7125 if (tok == TOK_GOTO) {
7126 next();
7127 if (tok == '*' && gnu_ext) {
7128 /* computed goto */
7129 next();
7130 gexpr();
7131 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
7132 expect("pointer");
7133 ggoto();
7134 } else if (tok >= TOK_UIDENT) {
7135 s = label_find(tok);
7136 /* put forward definition if needed */
7137 if (!s) {
7138 s = label_push(tok, LABEL_FORWARD);
7140 /* label already defined */
7141 if (s->r & LABEL_FORWARD)
7142 s->next = (void *)gjmp((long)s->next);
7143 else
7144 gjmp_addr((long)s->next);
7145 next();
7146 } else {
7147 expect("label identifier");
7149 skip(';');
7150 } else {
7151 b = is_label();
7152 if (b) {
7153 /* label case */
7154 s = label_find(b);
7155 if (s) {
7156 if (!(s->r & LABEL_FORWARD))
7157 error("multiple defined label");
7158 gsym((long)s->next);
7159 } else {
7160 s = label_push(b, 0);
7162 s->next = (void *)ind;
7163 s->r = 0;
7164 /* we accept this, but it is a mistake */
7165 if (tok == '}')
7166 warning("deprecated use of label at end of compound statement");
7167 else
7168 block(bsym, csym, case_sym, def_sym, case_reg);
7169 } else {
7170 /* expression case */
7171 if (tok != ';') {
7172 gexpr();
7173 vpop();
7175 skip(';');
7180 /* t is the array or struct type. c is the array or struct
7181 address. cur_index/cur_field is the pointer to the current
7182 value. 'size_only' is true if only size info is needed (only used
7183 in arrays) */
7184 static void decl_designator(CType *type, Section *sec, unsigned long c,
7185 int *cur_index, Sym **cur_field,
7186 int size_only)
7188 Sym *s, *f;
7189 int notfirst, index, align, l;
7190 CType type1;
7192 notfirst = 0;
7193 if (gnu_ext && (l = is_label()) != 0)
7194 goto struct_field;
7196 while (tok == '[' || tok == '.') {
7197 if (tok == '[') {
7198 if (!(type->t & VT_ARRAY))
7199 expect("array type");
7200 s = type->ref;
7201 next();
7202 index = expr_const();
7203 if (index < 0 || (s->c >= 0 && index >= s->c))
7204 expect("invalid index");
7205 skip(']');
7206 if (!notfirst)
7207 *cur_index = index;
7208 type = pointed_type(type);
7209 c += index * type_size(type, &align);
7210 } else {
7211 next();
7212 l = tok;
7213 next();
7214 struct_field:
7215 if ((type->t & VT_BTYPE) != VT_STRUCT)
7216 expect("struct/union type");
7217 s = type->ref;
7218 l |= SYM_FIELD;
7219 f = s->next;
7220 while (f) {
7221 if (f->v == l)
7222 break;
7223 f = f->next;
7225 if (!f)
7226 expect("field");
7227 if (!notfirst)
7228 *cur_field = f;
7229 /* XXX: suppress this mess by using explicit storage field */
7230 type1 = f->type;
7231 type1.t |= (type->t & ~VT_TYPE);
7232 type = &type1;
7233 c += f->c;
7235 notfirst = 1;
7237 if (notfirst) {
7238 if (tok == '=') {
7239 next();
7240 } else {
7241 if (!gnu_ext)
7242 expect("=");
7244 } else {
7245 if (type->t & VT_ARRAY) {
7246 index = *cur_index;
7247 type = pointed_type(type);
7248 c += index * type_size(type, &align);
7249 } else {
7250 f = *cur_field;
7251 if (!f)
7252 error("too many field init");
7253 /* XXX: suppress this mess by using explicit storage field */
7254 type1 = f->type;
7255 type1.t |= (type->t & ~VT_TYPE);
7256 type = &type1;
7257 c += f->c;
7260 decl_initializer(type, sec, c, 0, size_only);
7263 #define EXPR_VAL 0
7264 #define EXPR_CONST 1
7265 #define EXPR_ANY 2
7267 /* store a value or an expression directly in global data or in local array */
7268 static void init_putv(CType *type, Section *sec, unsigned long c,
7269 int v, int expr_type)
7271 int saved_global_expr, bt, bit_pos, bit_size;
7272 void *ptr;
7273 unsigned long long bit_mask;
7275 switch(expr_type) {
7276 case EXPR_VAL:
7277 vpushi(v);
7278 break;
7279 case EXPR_CONST:
7280 /* compound literals must be allocated globally in this case */
7281 saved_global_expr = global_expr;
7282 global_expr = 1;
7283 expr_const1();
7284 global_expr = saved_global_expr;
7285 /* NOTE: symbols are accepted */
7286 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
7287 error("initializer element is not constant");
7288 break;
7289 case EXPR_ANY:
7290 expr_eq();
7291 break;
7294 if (sec) {
7295 /* XXX: not portable */
7296 /* XXX: generate error if incorrect relocation */
7297 gen_assign_cast(type);
7298 bt = type->t & VT_BTYPE;
7299 ptr = sec->data + c;
7300 /* XXX: make code faster ? */
7301 if (!(type->t & VT_BITFIELD)) {
7302 bit_pos = 0;
7303 bit_size = 32;
7304 bit_mask = -1LL;
7305 } else {
7306 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
7307 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
7308 bit_mask = (1LL << bit_size) - 1;
7310 if ((vtop->r & VT_SYM) &&
7311 (bt == VT_BYTE ||
7312 bt == VT_SHORT ||
7313 bt == VT_DOUBLE ||
7314 bt == VT_LDOUBLE ||
7315 bt == VT_LLONG ||
7316 (bt == VT_INT && bit_size != 32)))
7317 error("initializer element is not computable at load time");
7318 switch(bt) {
7319 case VT_BYTE:
7320 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7321 break;
7322 case VT_SHORT:
7323 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7324 break;
7325 case VT_DOUBLE:
7326 *(double *)ptr = vtop->c.d;
7327 break;
7328 case VT_LDOUBLE:
7329 *(long double *)ptr = vtop->c.ld;
7330 break;
7331 case VT_LLONG:
7332 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
7333 break;
7334 default:
7335 if (vtop->r & VT_SYM) {
7336 greloc(sec, vtop->sym, c, R_DATA_32);
7338 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7339 break;
7341 vtop--;
7342 } else {
7343 vset(type, VT_LOCAL, c);
7344 vswap();
7345 vstore();
7346 vpop();
7350 /* put zeros for variable based init */
7351 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
7353 GFuncContext gf;
7355 if (sec) {
7356 /* nothing to do because globals are already set to zero */
7357 } else {
7358 gfunc_start(&gf, FUNC_CDECL);
7359 vpushi(size);
7360 gfunc_param(&gf);
7361 vpushi(0);
7362 gfunc_param(&gf);
7363 vseti(VT_LOCAL, c);
7364 gfunc_param(&gf);
7365 vpush_global_sym(&func_old_type, TOK_memset);
7366 gfunc_call(&gf);
7370 /* 't' contains the type and storage info. 'c' is the offset of the
7371 object in section 'sec'. If 'sec' is NULL, it means stack based
7372 allocation. 'first' is true if array '{' must be read (multi
7373 dimension implicit array init handling). 'size_only' is true if
7374 size only evaluation is wanted (only for arrays). */
7375 static void decl_initializer(CType *type, Section *sec, unsigned long c,
7376 int first, int size_only)
7378 int index, array_length, n, no_oblock, nb, parlevel, i;
7379 int size1, align1, expr_type;
7380 Sym *s, *f;
7381 CType *t1;
7383 if (type->t & VT_ARRAY) {
7384 s = type->ref;
7385 n = s->c;
7386 array_length = 0;
7387 t1 = pointed_type(type);
7388 size1 = type_size(t1, &align1);
7390 no_oblock = 1;
7391 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
7392 tok == '{') {
7393 skip('{');
7394 no_oblock = 0;
7397 /* only parse strings here if correct type (otherwise: handle
7398 them as ((w)char *) expressions */
7399 if ((tok == TOK_LSTR &&
7400 (t1->t & VT_BTYPE) == VT_INT) ||
7401 (tok == TOK_STR &&
7402 (t1->t & VT_BTYPE) == VT_BYTE)) {
7403 while (tok == TOK_STR || tok == TOK_LSTR) {
7404 int cstr_len, ch;
7405 CString *cstr;
7407 cstr = tokc.cstr;
7408 /* compute maximum number of chars wanted */
7409 if (tok == TOK_STR)
7410 cstr_len = cstr->size;
7411 else
7412 cstr_len = cstr->size / sizeof(int);
7413 cstr_len--;
7414 nb = cstr_len;
7415 if (n >= 0 && nb > (n - array_length))
7416 nb = n - array_length;
7417 if (!size_only) {
7418 if (cstr_len > nb)
7419 warning("initializer-string for array is too long");
7420 /* in order to go faster for common case (char
7421 string in global variable, we handle it
7422 specifically */
7423 if (sec && tok == TOK_STR && size1 == 1) {
7424 memcpy(sec->data + c + array_length, cstr->data, nb);
7425 } else {
7426 for(i=0;i<nb;i++) {
7427 if (tok == TOK_STR)
7428 ch = ((unsigned char *)cstr->data)[i];
7429 else
7430 ch = ((int *)cstr->data)[i];
7431 init_putv(t1, sec, c + (array_length + i) * size1,
7432 ch, EXPR_VAL);
7436 array_length += nb;
7437 next();
7439 /* only add trailing zero if enough storage (no
7440 warning in this case since it is standard) */
7441 if (n < 0 || array_length < n) {
7442 if (!size_only) {
7443 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
7445 array_length++;
7447 } else {
7448 index = 0;
7449 while (tok != '}') {
7450 decl_designator(type, sec, c, &index, NULL, size_only);
7451 if (n >= 0 && index >= n)
7452 error("index too large");
7453 /* must put zero in holes (note that doing it that way
7454 ensures that it even works with designators) */
7455 if (!size_only && array_length < index) {
7456 init_putz(t1, sec, c + array_length * size1,
7457 (index - array_length) * size1);
7459 index++;
7460 if (index > array_length)
7461 array_length = index;
7462 /* special test for multi dimensional arrays (may not
7463 be strictly correct if designators are used at the
7464 same time) */
7465 if (index >= n && no_oblock)
7466 break;
7467 if (tok == '}')
7468 break;
7469 skip(',');
7472 if (!no_oblock)
7473 skip('}');
7474 /* put zeros at the end */
7475 if (!size_only && n >= 0 && array_length < n) {
7476 init_putz(t1, sec, c + array_length * size1,
7477 (n - array_length) * size1);
7479 /* patch type size if needed */
7480 if (n < 0)
7481 s->c = array_length;
7482 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
7483 (sec || !first || tok == '{')) {
7484 /* NOTE: the previous test is a specific case for automatic
7485 struct/union init */
7486 /* XXX: union needs only one init */
7487 no_oblock = 1;
7488 if (first || tok == '{') {
7489 skip('{');
7490 no_oblock = 0;
7492 s = type->ref;
7493 f = s->next;
7494 array_length = 0;
7495 index = 0;
7496 n = s->c;
7497 while (tok != '}') {
7498 decl_designator(type, sec, c, NULL, &f, size_only);
7499 index = f->c;
7500 if (!size_only && array_length < index) {
7501 init_putz(type, sec, c + array_length,
7502 index - array_length);
7504 index = index + type_size(&f->type, &align1);
7505 if (index > array_length)
7506 array_length = index;
7507 f = f->next;
7508 if (no_oblock && f == NULL)
7509 break;
7510 if (tok == '}')
7511 break;
7512 skip(',');
7514 /* put zeros at the end */
7515 if (!size_only && array_length < n) {
7516 init_putz(type, sec, c + array_length,
7517 n - array_length);
7519 if (!no_oblock)
7520 skip('}');
7521 } else if (tok == '{') {
7522 next();
7523 decl_initializer(type, sec, c, first, size_only);
7524 skip('}');
7525 } else if (size_only) {
7526 /* just skip expression */
7527 parlevel = 0;
7528 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
7529 tok != -1) {
7530 if (tok == '(')
7531 parlevel++;
7532 else if (tok == ')')
7533 parlevel--;
7534 next();
7536 } else {
7537 /* currently, we always use constant expression for globals
7538 (may change for scripting case) */
7539 expr_type = EXPR_CONST;
7540 if (!sec)
7541 expr_type = EXPR_ANY;
7542 init_putv(type, sec, c, 0, expr_type);
7546 /* parse an initializer for type 't' if 'has_init' is non zero, and
7547 allocate space in local or global data space ('r' is either
7548 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7549 variable 'v' of scope 'scope' is declared before initializers are
7550 parsed. If 'v' is zero, then a reference to the new object is put
7551 in the value stack. If 'has_init' is 2, a special parsing is done
7552 to handle string constants. */
7553 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
7554 int has_init, int v, int scope)
7556 int size, align, addr, data_offset;
7557 int level;
7558 ParseState saved_parse_state;
7559 TokenString init_str;
7560 Section *sec;
7562 size = type_size(type, &align);
7563 /* If unknown size, we must evaluate it before
7564 evaluating initializers because
7565 initializers can generate global data too
7566 (e.g. string pointers or ISOC99 compound
7567 literals). It also simplifies local
7568 initializers handling */
7569 tok_str_new(&init_str);
7570 if (size < 0) {
7571 if (!has_init)
7572 error("unknown type size");
7573 /* get all init string */
7574 if (has_init == 2) {
7575 /* only get strings */
7576 while (tok == TOK_STR || tok == TOK_LSTR) {
7577 tok_str_add_tok(&init_str);
7578 next();
7580 } else {
7581 level = 0;
7582 while (level > 0 || (tok != ',' && tok != ';')) {
7583 if (tok < 0)
7584 error("unexpected end of file in initializer");
7585 tok_str_add_tok(&init_str);
7586 if (tok == '{')
7587 level++;
7588 else if (tok == '}') {
7589 if (level == 0)
7590 break;
7591 level--;
7593 next();
7596 tok_str_add(&init_str, -1);
7597 tok_str_add(&init_str, 0);
7599 /* compute size */
7600 save_parse_state(&saved_parse_state);
7602 macro_ptr = init_str.str;
7603 next();
7604 decl_initializer(type, NULL, 0, 1, 1);
7605 /* prepare second initializer parsing */
7606 macro_ptr = init_str.str;
7607 next();
7609 /* if still unknown size, error */
7610 size = type_size(type, &align);
7611 if (size < 0)
7612 error("unknown type size");
7614 /* take into account specified alignment if bigger */
7615 if (ad->aligned > align)
7616 align = ad->aligned;
7617 if ((r & VT_VALMASK) == VT_LOCAL) {
7618 sec = NULL;
7619 if (do_bounds_check && (type->t & VT_ARRAY))
7620 loc--;
7621 #ifdef TCC_TARGET_IL
7622 /* XXX: ugly patch to allocate local variables for IL, just
7623 for testing */
7624 addr = loc;
7625 loc++;
7626 #else
7627 loc = (loc - size) & -align;
7628 addr = loc;
7629 #endif
7630 /* handles bounds */
7631 /* XXX: currently, since we do only one pass, we cannot track
7632 '&' operators, so we add only arrays */
7633 if (do_bounds_check && (type->t & VT_ARRAY)) {
7634 unsigned long *bounds_ptr;
7635 /* add padding between regions */
7636 loc--;
7637 /* then add local bound info */
7638 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
7639 bounds_ptr[0] = addr;
7640 bounds_ptr[1] = size;
7642 } else {
7643 /* compute section */
7644 sec = ad->section;
7645 if (!sec) {
7646 if (has_init)
7647 sec = data_section;
7648 else
7649 sec = bss_section;
7651 data_offset = sec->data_offset;
7652 data_offset = (data_offset + align - 1) & -align;
7653 addr = data_offset;
7654 /* very important to increment global pointer at this time
7655 because initializers themselves can create new initializers */
7656 data_offset += size;
7657 /* add padding if bound check */
7658 if (do_bounds_check)
7659 data_offset++;
7660 sec->data_offset = data_offset;
7661 /* allocate section space to put the data */
7662 if (sec->sh_type != SHT_NOBITS &&
7663 data_offset > sec->data_allocated)
7664 section_realloc(sec, data_offset);
7666 if (!sec) {
7667 if (v) {
7668 /* local variable */
7669 sym_push(v, type, r, addr);
7670 } else {
7671 /* push local reference */
7672 vset(type, r, addr);
7674 } else {
7675 Sym *sym;
7677 if (v) {
7678 if (scope == VT_CONST) {
7679 /* global scope: see if already defined */
7680 sym = sym_find(v);
7681 if (!sym)
7682 goto do_def;
7683 if (!is_compatible_types(&sym->type, type))
7684 error("incompatible types for redefinition of '%s'",
7685 get_tok_str(v, NULL));
7686 if (!(sym->type.t & VT_EXTERN))
7687 error("redefinition of '%s'", get_tok_str(v, NULL));
7688 sym->type.t &= ~VT_EXTERN;
7689 } else {
7690 do_def:
7691 sym = sym_push(v, type, r | VT_SYM, 0);
7693 put_extern_sym(sym, sec, addr, size);
7694 } else {
7695 CValue cval;
7697 /* push global reference */
7698 sym = get_sym_ref(type, sec, addr, size);
7699 cval.ul = 0;
7700 vsetc(type, VT_CONST | VT_SYM, &cval);
7701 vtop->sym = sym;
7704 /* handles bounds now because the symbol must be defined
7705 before for the relocation */
7706 if (do_bounds_check) {
7707 unsigned long *bounds_ptr;
7709 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
7710 /* then add global bound info */
7711 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
7712 bounds_ptr[0] = 0; /* relocated */
7713 bounds_ptr[1] = size;
7716 if (has_init) {
7717 decl_initializer(type, sec, addr, 1, 0);
7718 /* restore parse state if needed */
7719 if (init_str.str) {
7720 tok_str_free(init_str.str);
7721 restore_parse_state(&saved_parse_state);
7726 void put_func_debug(Sym *sym)
7728 char buf[512];
7730 /* stabs info */
7731 /* XXX: we put here a dummy type */
7732 snprintf(buf, sizeof(buf), "%s:%c1",
7733 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
7734 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
7735 cur_text_section, sym->c);
7736 last_ind = 0;
7737 last_line_num = 0;
7740 /* not finished : try to put some local vars in registers */
7741 //#define CONFIG_REG_VARS
7743 #ifdef CONFIG_REG_VARS
7744 void add_var_ref(int t)
7746 printf("%s:%d: &%s\n",
7747 file->filename, file->line_num,
7748 get_tok_str(t, NULL));
7751 /* first pass on a function with heuristic to extract variable usage
7752 and pointer references to local variables for register allocation */
7753 void analyse_function(void)
7755 int level, t;
7757 for(;;) {
7758 if (tok == -1)
7759 break;
7760 /* any symbol coming after '&' is considered as being a
7761 variable whose reference is taken. It is highly unaccurate
7762 but it is difficult to do better without a complete parse */
7763 if (tok == '&') {
7764 next();
7765 /* if '& number', then no need to examine next tokens */
7766 if (tok == TOK_CINT ||
7767 tok == TOK_CUINT ||
7768 tok == TOK_CLLONG ||
7769 tok == TOK_CULLONG) {
7770 continue;
7771 } else if (tok >= TOK_UIDENT) {
7772 /* if '& ident [' or '& ident ->', then ident address
7773 is not needed */
7774 t = tok;
7775 next();
7776 if (tok != '[' && tok != TOK_ARROW)
7777 add_var_ref(t);
7778 } else {
7779 level = 0;
7780 while (tok != '}' && tok != ';' &&
7781 !((tok == ',' || tok == ')') && level == 0)) {
7782 if (tok >= TOK_UIDENT) {
7783 add_var_ref(tok);
7784 } else if (tok == '(') {
7785 level++;
7786 } else if (tok == ')') {
7787 level--;
7789 next();
7792 } else {
7793 next();
7797 #endif
7799 /* parse an old style function declaration list */
7800 /* XXX: check multiple parameter */
7801 static void func_decl_list(Sym *func_sym)
7803 AttributeDef ad;
7804 int v;
7805 Sym *s;
7806 CType btype, type;
7808 /* parse each declaration */
7809 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
7810 if (!parse_btype(&btype, &ad))
7811 expect("declaration list");
7812 if (((btype.t & VT_BTYPE) == VT_ENUM ||
7813 (btype.t & VT_BTYPE) == VT_STRUCT) &&
7814 tok == ';') {
7815 /* we accept no variable after */
7816 } else {
7817 for(;;) {
7818 type = btype;
7819 type_decl(&type, &ad, &v, TYPE_DIRECT);
7820 /* find parameter in function parameter list */
7821 s = func_sym->next;
7822 while (s != NULL) {
7823 if ((s->v & ~SYM_FIELD) == v)
7824 goto found;
7825 s = s->next;
7827 error("declaration for parameter '%s' but no such parameter",
7828 get_tok_str(v, NULL));
7829 found:
7830 /* check that no storage specifier except 'register' was given */
7831 if (type.t & (VT_EXTERN | VT_STATIC | VT_TYPEDEF))
7832 error("storage class specified for '%s'", get_tok_str(v, NULL));
7833 /* we can add the type (NOTE: it could be local to the function) */
7834 s->type = type;
7835 /* accept other parameters */
7836 if (tok == ',')
7837 next();
7838 else
7839 break;
7842 skip(';');
7846 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
7847 static void decl(int l)
7849 int v, has_init, r;
7850 CType type, btype;
7851 Sym *sym;
7852 AttributeDef ad;
7854 while (1) {
7855 if (!parse_btype(&btype, &ad)) {
7856 /* skip redundant ';' */
7857 /* XXX: find more elegant solution */
7858 if (tok == ';') {
7859 next();
7860 continue;
7862 /* special test for old K&R protos without explicit int
7863 type. Only accepted when defining global data */
7864 if (l == VT_LOCAL || tok < TOK_DEFINE)
7865 break;
7866 btype.t = VT_INT;
7868 if (((btype.t & VT_BTYPE) == VT_ENUM ||
7869 (btype.t & VT_BTYPE) == VT_STRUCT) &&
7870 tok == ';') {
7871 /* we accept no variable after */
7872 next();
7873 continue;
7875 while (1) { /* iterate thru each declaration */
7876 type = btype;
7877 type_decl(&type, &ad, &v, TYPE_DIRECT);
7878 #if 0
7880 char buf[500];
7881 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
7882 printf("type = '%s'\n", buf);
7884 #endif
7885 if ((type.t & VT_BTYPE) == VT_FUNC) {
7886 /* if old style function prototype, we accept a
7887 declaration list */
7888 sym = type.ref;
7889 if (sym->c == FUNC_OLD)
7890 func_decl_list(sym);
7893 if (tok == '{') {
7894 #ifdef CONFIG_REG_VARS
7895 TokenString func_str;
7896 ParseState saved_parse_state;
7897 int block_level;
7898 #endif
7900 if (l == VT_LOCAL)
7901 error("cannot use local functions");
7902 if (!(type.t & VT_FUNC))
7903 expect("function definition");
7905 #ifdef CONFIG_REG_VARS
7906 /* parse all function code and record it */
7908 tok_str_new(&func_str);
7910 block_level = 0;
7911 for(;;) {
7912 int t;
7913 if (tok == -1)
7914 error("unexpected end of file");
7915 tok_str_add_tok(&func_str);
7916 t = tok;
7917 next();
7918 if (t == '{') {
7919 block_level++;
7920 } else if (t == '}') {
7921 block_level--;
7922 if (block_level == 0)
7923 break;
7926 tok_str_add(&func_str, -1);
7927 tok_str_add(&func_str, 0);
7929 save_parse_state(&saved_parse_state);
7931 macro_ptr = func_str.str;
7932 next();
7933 analyse_function();
7934 #endif
7936 /* compute text section */
7937 cur_text_section = ad.section;
7938 if (!cur_text_section)
7939 cur_text_section = text_section;
7940 ind = cur_text_section->data_offset;
7941 funcname = get_tok_str(v, NULL);
7942 sym = sym_find(v);
7943 if (sym) {
7944 /* if symbol is already defined, then put complete type */
7945 sym->type = type;
7946 } else {
7947 /* put function symbol */
7948 sym = global_identifier_push(v, type.t, 0);
7949 sym->type.ref = type.ref;
7951 /* NOTE: we patch the symbol size later */
7952 put_extern_sym(sym, cur_text_section, ind, 0);
7953 func_ind = ind;
7954 sym->r = VT_SYM | VT_CONST;
7955 /* put debug symbol */
7956 if (do_debug)
7957 put_func_debug(sym);
7958 /* push a dummy symbol to enable local sym storage */
7959 sym_push2(&local_stack, SYM_FIELD, 0, 0);
7960 gfunc_prolog(&type);
7961 loc = 0;
7962 rsym = 0;
7963 #ifdef CONFIG_REG_VARS
7964 macro_ptr = func_str.str;
7965 next();
7966 #endif
7967 block(NULL, NULL, NULL, NULL, 0);
7968 gsym(rsym);
7969 gfunc_epilog();
7970 cur_text_section->data_offset = ind;
7971 /* look if any labels are undefined. Define symbols if
7972 '&&label' was used. */
7974 Sym *s, *s1;
7975 for(s = label_stack; s != NULL; s = s1) {
7976 s1 = s->prev;
7977 if (s->r & LABEL_FORWARD) {
7978 error("label '%s' used but not defined",
7979 get_tok_str(s->v, NULL));
7981 if (s->c) {
7982 /* define corresponding symbol. A size of
7983 1 is put. */
7984 put_extern_sym(s, cur_text_section, (long)s->next, 1);
7986 /* remove label */
7987 table_ident[s->v - TOK_IDENT]->sym_label = NULL;
7988 tcc_free(s);
7990 label_stack = NULL;
7992 sym_pop(&local_stack, NULL); /* reset local stack */
7993 /* end of function */
7994 /* patch symbol size */
7995 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
7996 ind - func_ind;
7997 if (do_debug) {
7998 put_stabn(N_FUN, 0, 0, ind - func_ind);
8000 funcname = ""; /* for safety */
8001 func_vt.t = VT_VOID; /* for safety */
8002 ind = 0; /* for safety */
8004 #ifdef CONFIG_REG_VARS
8005 tok_str_free(func_str.str);
8006 restore_parse_state(&saved_parse_state);
8007 #endif
8008 break;
8009 } else {
8010 if (btype.t & VT_TYPEDEF) {
8011 /* save typedefed type */
8012 /* XXX: test storage specifiers ? */
8013 sym = sym_push(v, &type, 0, 0);
8014 sym->type.t |= VT_TYPEDEF;
8015 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
8016 /* external function definition */
8017 external_sym(v, &type, 0);
8018 } else {
8019 /* not lvalue if array */
8020 r = 0;
8021 if (!(type.t & VT_ARRAY))
8022 r |= lvalue_type(type.t);
8023 if (btype.t & VT_EXTERN) {
8024 /* external variable */
8025 external_sym(v, &type, r);
8026 } else {
8027 if (type.t & VT_STATIC)
8028 r |= VT_CONST;
8029 else
8030 r |= l;
8031 has_init = (tok == '=');
8032 if (has_init)
8033 next();
8034 decl_initializer_alloc(&type, &ad, r,
8035 has_init, v, l);
8038 if (tok != ',') {
8039 skip(';');
8040 break;
8042 next();
8048 /* compile the C file opened in 'file'. Return non zero if errors. */
8049 static int tcc_compile(TCCState *s1)
8051 Sym *define_start;
8052 char buf[512];
8053 volatile int section_sym;
8055 #ifdef INC_DEBUG
8056 printf("%s: **** new file\n", file->filename);
8057 #endif
8058 funcname = "";
8059 s1->include_stack_ptr = s1->include_stack;
8060 /* XXX: move that before to avoid having to initialize
8061 file->ifdef_stack_ptr ? */
8062 s1->ifdef_stack_ptr = s1->ifdef_stack;
8063 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
8065 /* XXX: not ANSI compliant: bound checking says error */
8066 vtop = vstack - 1;
8067 anon_sym = SYM_FIRST_ANOM;
8069 /* file info: full path + filename */
8070 section_sym = 0; /* avoid warning */
8071 if (do_debug) {
8072 section_sym = put_elf_sym(symtab_section, 0, 0,
8073 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
8074 text_section->sh_num, NULL);
8075 getcwd(buf, sizeof(buf));
8076 pstrcat(buf, sizeof(buf), "/");
8077 put_stabs_r(buf, N_SO, 0, 0,
8078 text_section->data_offset, text_section, section_sym);
8079 put_stabs_r(file->filename, N_SO, 0, 0,
8080 text_section->data_offset, text_section, section_sym);
8082 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8083 symbols can be safely used */
8084 put_elf_sym(symtab_section, 0, 0,
8085 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
8086 SHN_ABS, file->filename);
8088 /* define some often used types */
8089 int_type.t = VT_INT;
8091 char_pointer_type.t = VT_BYTE;
8092 mk_pointer(&char_pointer_type);
8094 func_old_type.t = VT_FUNC;
8095 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
8097 #if 0
8098 /* define 'void *alloca(unsigned int)' builtin function */
8100 Sym *s1;
8102 p = anon_sym++;
8103 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
8104 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
8105 s1->next = NULL;
8106 sym->next = s1;
8107 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
8109 #endif
8111 define_start = define_stack;
8113 if (setjmp(s1->error_jmp_buf) == 0) {
8114 s1->nb_errors = 0;
8115 s1->error_set_jmp_enabled = 1;
8117 ch = file->buf_ptr[0];
8118 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
8119 next();
8120 decl(VT_CONST);
8121 if (tok != -1)
8122 expect("declaration");
8124 /* end of translation unit info */
8125 if (do_debug) {
8126 put_stabs_r(NULL, N_SO, 0, 0,
8127 text_section->data_offset, text_section, section_sym);
8130 s1->error_set_jmp_enabled = 0;
8132 /* reset define stack, but leave -Dsymbols (may be incorrect if
8133 they are undefined) */
8134 free_defines(define_start);
8136 sym_pop(&global_stack, NULL);
8138 return s1->nb_errors != 0 ? -1 : 0;
8141 #ifdef LIBTCC
8142 int tcc_compile_string(TCCState *s, const char *str)
8144 BufferedFile bf1, *bf = &bf1;
8145 int ret, len;
8146 char *buf;
8148 /* init file structure */
8149 bf->fd = -1;
8150 /* XXX: avoid copying */
8151 len = strlen(str);
8152 buf = tcc_malloc(len + 1);
8153 if (!buf)
8154 return -1;
8155 buf[len] = CH_EOB;
8156 bf->buf_ptr = buf;
8157 bf->buf_end = buf + len;
8158 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
8159 bf->line_num = 1;
8160 file = bf;
8162 ret = tcc_compile(s);
8164 tcc_free(buf);
8166 /* currently, no need to close */
8167 return ret;
8169 #endif
8171 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8172 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
8174 BufferedFile bf1, *bf = &bf1;
8176 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
8177 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
8178 /* default value */
8179 if (!value)
8180 value = "1";
8181 pstrcat(bf->buffer, IO_BUF_SIZE, value);
8183 /* init file structure */
8184 bf->fd = -1;
8185 bf->buf_ptr = bf->buffer;
8186 bf->buf_end = bf->buffer + strlen(bf->buffer);
8187 *bf->buf_end = CH_EOB;
8188 bf->filename[0] = '\0';
8189 bf->line_num = 1;
8190 file = bf;
8192 s1->include_stack_ptr = s1->include_stack;
8194 /* parse with define parser */
8195 ch = file->buf_ptr[0];
8196 next_nomacro();
8197 parse_define();
8198 file = NULL;
8201 /* undefine a preprocessor symbol */
8202 void tcc_undefine_symbol(TCCState *s1, const char *sym)
8204 TokenSym *ts;
8205 Sym *s;
8206 ts = tok_alloc(sym, strlen(sym));
8207 s = define_find(ts->tok);
8208 /* undefine symbol by putting an invalid name */
8209 if (s)
8210 define_undef(s);
8213 #include "tccelf.c"
8215 /* print the position in the source file of PC value 'pc' by reading
8216 the stabs debug information */
8217 static void rt_printline(unsigned long wanted_pc)
8219 Stab_Sym *sym, *sym_end;
8220 char func_name[128], last_func_name[128];
8221 unsigned long func_addr, last_pc, pc;
8222 const char *incl_files[INCLUDE_STACK_SIZE];
8223 int incl_index, len, last_line_num, i;
8224 const char *str, *p;
8226 fprintf(stderr, "0x%08lx:", wanted_pc);
8228 func_name[0] = '\0';
8229 func_addr = 0;
8230 incl_index = 0;
8231 last_func_name[0] = '\0';
8232 last_pc = 0xffffffff;
8233 last_line_num = 1;
8234 sym = (Stab_Sym *)stab_section->data + 1;
8235 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
8236 while (sym < sym_end) {
8237 switch(sym->n_type) {
8238 /* function start or end */
8239 case N_FUN:
8240 if (sym->n_strx == 0) {
8241 /* we test if between last line and end of function */
8242 pc = sym->n_value + func_addr;
8243 if (wanted_pc >= last_pc && wanted_pc < pc)
8244 goto found;
8245 func_name[0] = '\0';
8246 func_addr = 0;
8247 } else {
8248 str = stabstr_section->data + sym->n_strx;
8249 p = strchr(str, ':');
8250 if (!p) {
8251 pstrcpy(func_name, sizeof(func_name), str);
8252 } else {
8253 len = p - str;
8254 if (len > sizeof(func_name) - 1)
8255 len = sizeof(func_name) - 1;
8256 memcpy(func_name, str, len);
8257 func_name[len] = '\0';
8259 func_addr = sym->n_value;
8261 break;
8262 /* line number info */
8263 case N_SLINE:
8264 pc = sym->n_value + func_addr;
8265 if (wanted_pc >= last_pc && wanted_pc < pc)
8266 goto found;
8267 last_pc = pc;
8268 last_line_num = sym->n_desc;
8269 /* XXX: slow! */
8270 strcpy(last_func_name, func_name);
8271 break;
8272 /* include files */
8273 case N_BINCL:
8274 str = stabstr_section->data + sym->n_strx;
8275 add_incl:
8276 if (incl_index < INCLUDE_STACK_SIZE) {
8277 incl_files[incl_index++] = str;
8279 break;
8280 case N_EINCL:
8281 if (incl_index > 1)
8282 incl_index--;
8283 break;
8284 case N_SO:
8285 if (sym->n_strx == 0) {
8286 incl_index = 0; /* end of translation unit */
8287 } else {
8288 str = stabstr_section->data + sym->n_strx;
8289 /* do not add path */
8290 len = strlen(str);
8291 if (len > 0 && str[len - 1] != '/')
8292 goto add_incl;
8294 break;
8296 sym++;
8299 /* second pass: we try symtab symbols (no line number info) */
8300 incl_index = 0;
8302 Elf32_Sym *sym, *sym_end;
8303 int type;
8305 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
8306 for(sym = (Elf32_Sym *)symtab_section->data + 1;
8307 sym < sym_end;
8308 sym++) {
8309 type = ELF32_ST_TYPE(sym->st_info);
8310 if (type == STT_FUNC) {
8311 if (wanted_pc >= sym->st_value &&
8312 wanted_pc < sym->st_value + sym->st_size) {
8313 pstrcpy(last_func_name, sizeof(last_func_name),
8314 strtab_section->data + sym->st_name);
8315 goto found;
8320 /* did not find any info: */
8321 fprintf(stderr, " ???\n");
8322 return;
8323 found:
8324 if (last_func_name[0] != '\0') {
8325 fprintf(stderr, " %s()", last_func_name);
8327 if (incl_index > 0) {
8328 fprintf(stderr, " (%s:%d",
8329 incl_files[incl_index - 1], last_line_num);
8330 for(i = incl_index - 2; i >= 0; i--)
8331 fprintf(stderr, ", included from %s", incl_files[i]);
8332 fprintf(stderr, ")");
8334 fprintf(stderr, "\n");
8337 #ifndef WIN32
8339 #ifdef __i386__
8341 #ifndef EIP
8342 #define EIP 14
8343 #define EBP 6
8344 #endif
8346 /* return the PC at frame level 'level'. Return non zero if not found */
8347 static int rt_get_caller_pc(unsigned long *paddr,
8348 struct ucontext *uc, int level)
8350 unsigned long fp;
8351 int i;
8353 if (level == 0) {
8354 *paddr = uc->uc_mcontext.gregs[EIP];
8355 return 0;
8356 } else {
8357 fp = uc->uc_mcontext.gregs[EBP];
8358 for(i=1;i<level;i++) {
8359 /* XXX: check address validity with program info */
8360 if (fp <= 0x1000 || fp >= 0xc0000000)
8361 return -1;
8362 fp = ((unsigned long *)fp)[0];
8364 *paddr = ((unsigned long *)fp)[1];
8365 return 0;
8368 #else
8369 #error add arch specific rt_get_caller_pc()
8370 #endif
8372 /* emit a run time error at position 'pc' */
8373 void rt_error(struct ucontext *uc, const char *fmt, ...)
8375 va_list ap;
8376 unsigned long pc;
8377 int i;
8379 va_start(ap, fmt);
8380 fprintf(stderr, "Runtime error: ");
8381 vfprintf(stderr, fmt, ap);
8382 fprintf(stderr, "\n");
8383 for(i=0;i<num_callers;i++) {
8384 if (rt_get_caller_pc(&pc, uc, i) < 0)
8385 break;
8386 if (i == 0)
8387 fprintf(stderr, "at ");
8388 else
8389 fprintf(stderr, "by ");
8390 rt_printline(pc);
8392 exit(255);
8393 va_end(ap);
8396 /* signal handler for fatal errors */
8397 static void sig_error(int signum, siginfo_t *siginf, void *puc)
8399 struct ucontext *uc = puc;
8401 switch(signum) {
8402 case SIGFPE:
8403 switch(siginf->si_code) {
8404 case FPE_INTDIV:
8405 case FPE_FLTDIV:
8406 rt_error(uc, "division by zero");
8407 break;
8408 default:
8409 rt_error(uc, "floating point exception");
8410 break;
8412 break;
8413 case SIGBUS:
8414 case SIGSEGV:
8415 if (rt_bound_error_msg && *rt_bound_error_msg)
8416 rt_error(uc, *rt_bound_error_msg);
8417 else
8418 rt_error(uc, "dereferencing invalid pointer");
8419 break;
8420 case SIGILL:
8421 rt_error(uc, "illegal instruction");
8422 break;
8423 case SIGABRT:
8424 rt_error(uc, "abort() called");
8425 break;
8426 default:
8427 rt_error(uc, "caught signal %d", signum);
8428 break;
8430 exit(255);
8432 #endif
8434 /* do all relocations (needed before using tcc_get_symbol()) */
8435 int tcc_relocate(TCCState *s1)
8437 Section *s;
8438 int i;
8440 s1->nb_errors = 0;
8442 tcc_add_runtime(s1);
8444 relocate_common_syms();
8446 /* compute relocation address : section are relocated in place. We
8447 also alloc the bss space */
8448 for(i = 1; i < s1->nb_sections; i++) {
8449 s = s1->sections[i];
8450 if (s->sh_flags & SHF_ALLOC) {
8451 if (s->sh_type == SHT_NOBITS)
8452 s->data = tcc_mallocz(s->data_offset);
8453 s->sh_addr = (unsigned long)s->data;
8457 relocate_syms(s1, 1);
8459 if (s1->nb_errors != 0)
8460 return -1;
8462 /* relocate each section */
8463 for(i = 1; i < s1->nb_sections; i++) {
8464 s = s1->sections[i];
8465 if (s->reloc)
8466 relocate_section(s1, s);
8468 return 0;
8471 /* launch the compiled program with the given arguments */
8472 int tcc_run(TCCState *s1, int argc, char **argv)
8474 int (*prog_main)(int, char **);
8476 if (tcc_relocate(s1) < 0)
8477 return -1;
8479 prog_main = tcc_get_symbol(s1, "main");
8481 if (do_debug) {
8482 #ifdef WIN32
8483 error("debug mode currently not available for Windows");
8484 #else
8485 struct sigaction sigact;
8486 /* install TCC signal handlers to print debug info on fatal
8487 runtime errors */
8488 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
8489 sigact.sa_sigaction = sig_error;
8490 sigemptyset(&sigact.sa_mask);
8491 sigaction(SIGFPE, &sigact, NULL);
8492 sigaction(SIGILL, &sigact, NULL);
8493 sigaction(SIGSEGV, &sigact, NULL);
8494 sigaction(SIGBUS, &sigact, NULL);
8495 sigaction(SIGABRT, &sigact, NULL);
8496 #endif
8499 #ifdef CONFIG_TCC_BCHECK
8500 if (do_bounds_check) {
8501 void (*bound_init)(void);
8503 /* set error function */
8504 rt_bound_error_msg = (void *)tcc_get_symbol(s1, "__bound_error_msg");
8506 /* XXX: use .init section so that it also work in binary ? */
8507 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
8508 bound_init();
8510 #endif
8511 return (*prog_main)(argc, argv);
8514 TCCState *tcc_new(void)
8516 const char *p, *r;
8517 TCCState *s;
8519 s = tcc_mallocz(sizeof(TCCState));
8520 if (!s)
8521 return NULL;
8522 tcc_state = s;
8523 s->output_type = TCC_OUTPUT_MEMORY;
8525 /* default include paths */
8526 tcc_add_sysinclude_path(s, "/usr/local/include");
8527 tcc_add_sysinclude_path(s, "/usr/include");
8528 tcc_add_sysinclude_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
8530 /* add all tokens */
8531 table_ident = NULL;
8532 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
8534 tok_ident = TOK_IDENT;
8535 p = tcc_keywords;
8536 while (*p) {
8537 r = p;
8538 while (*r++);
8539 tok_alloc(p, r - p - 1);
8540 p = r;
8543 /* we add dummy defines for some special macros to speed up tests
8544 and to have working defined() */
8545 define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
8546 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
8547 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
8548 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
8550 /* standard defines */
8551 tcc_define_symbol(s, "__STDC__", NULL);
8552 #if defined(TCC_TARGET_I386)
8553 tcc_define_symbol(s, "__i386__", NULL);
8554 #endif
8555 #if defined(linux)
8556 tcc_define_symbol(s, "linux", NULL);
8557 #endif
8558 /* tiny C specific defines */
8559 tcc_define_symbol(s, "__TINYC__", NULL);
8561 /* tiny C & gcc defines */
8562 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
8563 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
8564 tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
8566 /* default library paths */
8567 tcc_add_library_path(s, "/usr/local/lib");
8568 tcc_add_library_path(s, "/usr/lib");
8569 tcc_add_library_path(s, "/lib");
8571 /* no section zero */
8572 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
8574 /* create standard sections */
8575 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
8576 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
8577 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
8579 /* symbols are always generated for linking stage */
8580 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
8581 ".strtab",
8582 ".hashtab", SHF_PRIVATE);
8583 strtab_section = symtab_section->link;
8585 /* private symbol table for dynamic symbols */
8586 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
8587 ".dynstrtab",
8588 ".dynhashtab", SHF_PRIVATE);
8589 return s;
8592 void tcc_delete(TCCState *s1)
8594 int i, n;
8596 /* free -D defines */
8597 free_defines(NULL);
8599 /* free tokens */
8600 n = tok_ident - TOK_IDENT;
8601 for(i = 0; i < n; i++)
8602 tcc_free(table_ident[i]);
8603 tcc_free(table_ident);
8605 /* free all sections */
8607 free_section(symtab_section->hash);
8609 free_section(s1->dynsymtab_section->hash);
8610 free_section(s1->dynsymtab_section->link);
8611 free_section(s1->dynsymtab_section);
8613 for(i = 1; i < s1->nb_sections; i++)
8614 free_section(s1->sections[i]);
8615 tcc_free(s1->sections);
8617 /* free loaded dlls array */
8618 for(i = 0; i < s1->nb_loaded_dlls; i++)
8619 tcc_free(s1->loaded_dlls[i]);
8620 tcc_free(s1->loaded_dlls);
8622 /* library paths */
8623 for(i = 0; i < s1->nb_library_paths; i++)
8624 tcc_free(s1->library_paths[i]);
8625 tcc_free(s1->library_paths);
8627 /* cached includes */
8628 for(i = 0; i < s1->nb_cached_includes; i++)
8629 tcc_free(s1->cached_includes[i]);
8630 tcc_free(s1->cached_includes);
8632 for(i = 0; i < s1->nb_include_paths; i++)
8633 tcc_free(s1->include_paths[i]);
8634 tcc_free(s1->include_paths);
8636 for(i = 0; i < s1->nb_sysinclude_paths; i++)
8637 tcc_free(s1->sysinclude_paths[i]);
8638 tcc_free(s1->sysinclude_paths);
8640 tcc_free(s1);
8643 int tcc_add_include_path(TCCState *s1, const char *pathname)
8645 char *pathname1;
8647 pathname1 = tcc_strdup(pathname);
8648 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
8649 return 0;
8652 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
8654 char *pathname1;
8656 pathname1 = tcc_strdup(pathname);
8657 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
8658 return 0;
8661 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
8663 const char *ext;
8664 Elf32_Ehdr ehdr;
8665 int fd, ret;
8666 BufferedFile *saved_file;
8668 /* find source file type with extension */
8669 ext = strrchr(filename, '.');
8670 if (ext)
8671 ext++;
8673 /* open the file */
8674 saved_file = file;
8675 file = tcc_open(s1, filename);
8676 if (!file) {
8677 if (flags & AFF_PRINT_ERROR) {
8678 error_noabort("file '%s' not found", filename);
8680 ret = -1;
8681 goto fail1;
8684 if (!ext || !strcmp(ext, "c")) {
8685 /* C file assumed */
8686 ret = tcc_compile(s1);
8687 } else {
8688 fd = file->fd;
8689 /* assume executable format: auto guess file type */
8690 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
8691 error_noabort("could not read header");
8692 goto fail;
8694 lseek(fd, 0, SEEK_SET);
8696 if (ehdr.e_ident[0] == ELFMAG0 &&
8697 ehdr.e_ident[1] == ELFMAG1 &&
8698 ehdr.e_ident[2] == ELFMAG2 &&
8699 ehdr.e_ident[3] == ELFMAG3) {
8700 file->line_num = 0; /* do not display line number if error */
8701 if (ehdr.e_type == ET_REL) {
8702 ret = tcc_load_object_file(s1, fd, 0);
8703 } else if (ehdr.e_type == ET_DYN) {
8704 ret = tcc_load_dll(s1, fd, filename,
8705 (flags & AFF_REFERENCED_DLL) != 0);
8706 } else {
8707 error_noabort("unrecognized ELF file");
8708 goto fail;
8710 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
8711 file->line_num = 0; /* do not display line number if error */
8712 ret = tcc_load_archive(s1, fd);
8713 } else {
8714 /* as GNU ld, consider it is an ld script if not recognized */
8715 ret = tcc_load_ldscript(s1);
8716 if (ret < 0) {
8717 error_noabort("unrecognized file type");
8718 goto fail;
8722 the_end:
8723 tcc_close(file);
8724 fail1:
8725 file = saved_file;
8726 return ret;
8727 fail:
8728 ret = -1;
8729 goto the_end;
8732 int tcc_add_file(TCCState *s, const char *filename)
8734 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
8737 int tcc_add_library_path(TCCState *s, const char *pathname)
8739 char *pathname1;
8741 pathname1 = tcc_strdup(pathname);
8742 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
8743 return 0;
8746 /* find and load a dll. Return non zero if not found */
8747 /* XXX: add '-rpath' option support ? */
8748 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
8750 char buf[1024];
8751 int i;
8753 for(i = 0; i < s->nb_library_paths; i++) {
8754 snprintf(buf, sizeof(buf), "%s/%s",
8755 s->library_paths[i], filename);
8756 if (tcc_add_file_internal(s, buf, flags) == 0)
8757 return 0;
8759 return -1;
8762 /* the library name is the same as the argument of the '-l' option */
8763 int tcc_add_library(TCCState *s, const char *libraryname)
8765 char buf[1024];
8766 int i;
8767 void *h;
8769 /* first we look for the dynamic library if not static linking */
8770 if (!s->static_link) {
8771 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
8772 /* if we output to memory, then we simply we dlopen(). */
8773 if (s->output_type == TCC_OUTPUT_MEMORY) {
8774 /* Since the libc is already loaded, we don't need to load it again */
8775 if (!strcmp(libraryname, "c"))
8776 return 0;
8777 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
8778 if (h)
8779 return 0;
8780 } else {
8781 if (tcc_add_dll(s, buf, 0) == 0)
8782 return 0;
8786 /* then we look for the static library */
8787 for(i = 0; i < s->nb_library_paths; i++) {
8788 snprintf(buf, sizeof(buf), "%s/lib%s.a",
8789 s->library_paths[i], libraryname);
8790 if (tcc_add_file_internal(s, buf, 0) == 0)
8791 return 0;
8793 return -1;
8796 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
8798 add_elf_sym(symtab_section, val, 0,
8799 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
8800 SHN_ABS, name);
8801 return 0;
8804 int tcc_set_output_type(TCCState *s, int output_type)
8806 s->output_type = output_type;
8808 /* if bound checking, then add corresponding sections */
8809 #ifdef CONFIG_TCC_BCHECK
8810 if (do_bounds_check) {
8811 /* define symbol */
8812 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
8813 /* create bounds sections */
8814 bounds_section = new_section(s, ".bounds",
8815 SHT_PROGBITS, SHF_ALLOC);
8816 lbounds_section = new_section(s, ".lbounds",
8817 SHT_PROGBITS, SHF_ALLOC);
8819 #endif
8821 /* add debug sections */
8822 if (do_debug) {
8823 /* stab symbols */
8824 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
8825 stab_section->sh_entsize = sizeof(Stab_Sym);
8826 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
8827 put_elf_str(stabstr_section, "");
8828 stab_section->link = stabstr_section;
8829 /* put first entry */
8830 put_stabs("", 0, 0, 0, 0);
8833 /* add libc crt1/crti objects */
8834 if (output_type == TCC_OUTPUT_EXE ||
8835 output_type == TCC_OUTPUT_DLL) {
8836 if (output_type != TCC_OUTPUT_DLL)
8837 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
8838 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
8840 return 0;
8843 #if !defined(LIBTCC)
8845 static int64_t getclock_us(void)
8847 #ifdef WIN32
8848 struct _timeb tb;
8849 _ftime(&tb);
8850 return (tb.time * 1000LL + tb.millitm) * 1000LL;
8851 #else
8852 struct timeval tv;
8853 gettimeofday(&tv, NULL);
8854 return tv.tv_sec * 1000000LL + tv.tv_usec;
8855 #endif
8858 void help(void)
8860 printf("tcc version 0.9.14 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8861 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8862 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
8863 " [--] infile1 [infile2... --] [infile_args...]\n"
8864 "\n"
8865 "General options:\n"
8866 " -c compile only - generate an object file\n"
8867 " -o outfile set output filename\n"
8868 " -- allows multiples input files if no -o option given. Also\n"
8869 " separate input files from runtime arguments\n"
8870 " -Bdir set tcc internal library path\n"
8871 " -bench output compilation statistics\n"
8872 "Preprocessor options:\n"
8873 " -Idir add include path 'dir'\n"
8874 " -Dsym[=val] define 'sym' with value 'val'\n"
8875 " -Usym undefine 'sym'\n"
8876 "Linker options:\n"
8877 " -Ldir add library path 'dir'\n"
8878 " -llib link with dynamic or static library 'lib'\n"
8879 " -shared generate a shared library\n"
8880 " -static static linking\n"
8881 " -r relocatable output\n"
8882 "Debugger options:\n"
8883 " -g generate runtime debug info\n"
8884 #ifdef CONFIG_TCC_BCHECK
8885 " -b compile with built-in memory and bounds checker (implies -g)\n"
8886 #endif
8887 " -bt N show N callers in stack traces\n"
8891 int main(int argc, char **argv)
8893 char *r, *outfile;
8894 int optind, output_type, multiple_files, i, reloc_output;
8895 TCCState *s;
8896 char **files;
8897 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
8898 char objfilename[1024];
8899 int64_t start_time = 0;
8901 s = tcc_new();
8902 output_type = TCC_OUTPUT_MEMORY;
8904 optind = 1;
8905 outfile = NULL;
8906 multiple_files = 0;
8907 dminus = 0;
8908 files = NULL;
8909 nb_files = 0;
8910 nb_libraries = 0;
8911 reloc_output = 0;
8912 while (1) {
8913 if (optind >= argc) {
8914 if (nb_files == 0)
8915 goto show_help;
8916 else
8917 break;
8919 r = argv[optind++];
8920 if (r[0] != '-') {
8921 /* add a new file */
8922 dynarray_add((void ***)&files, &nb_files, r);
8923 if (!multiple_files) {
8924 optind--;
8925 /* argv[0] will be this file */
8926 break;
8928 } else if (r[1] == '-') {
8929 /* '--' enables multiple files input and also ends several file input */
8930 if (dminus && multiple_files) {
8931 optind--; /* argv[0] will be '--' */
8932 break;
8934 dminus = 1;
8935 multiple_files = 1;
8936 } else if (r[1] == 'h' || r[1] == '?') {
8937 show_help:
8938 help();
8939 return 1;
8940 } else if (r[1] == 'I') {
8941 if (tcc_add_include_path(s, r + 2) < 0)
8942 error("too many include paths");
8943 } else if (r[1] == 'D') {
8944 char *sym, *value;
8945 sym = r + 2;
8946 value = strchr(sym, '=');
8947 if (value) {
8948 *value = '\0';
8949 value++;
8951 tcc_define_symbol(s, sym, value);
8952 } else if (r[1] == 'U') {
8953 tcc_undefine_symbol(s, r + 2);
8954 } else if (r[1] == 'L') {
8955 tcc_add_library_path(s, r + 2);
8956 } else if (r[1] == 'B') {
8957 /* set tcc utilities path (mainly for tcc development) */
8958 tcc_lib_path = r + 2;
8959 } else if (r[1] == 'l') {
8960 dynarray_add((void ***)&files, &nb_files, r);
8961 nb_libraries++;
8962 } else if (!strcmp(r + 1, "bench")) {
8963 do_bench = 1;
8964 } else if (!strcmp(r + 1, "bt")) {
8965 num_callers = atoi(argv[optind++]);
8966 } else
8967 #ifdef CONFIG_TCC_BCHECK
8968 if (r[1] == 'b') {
8969 do_bounds_check = 1;
8970 do_debug = 1;
8971 } else
8972 #endif
8973 if (r[1] == 'g') {
8974 do_debug = 1;
8975 } else if (r[1] == 'c') {
8976 multiple_files = 1;
8977 output_type = TCC_OUTPUT_OBJ;
8978 } else if (!strcmp(r + 1, "static")) {
8979 s->static_link = 1;
8980 } else if (!strcmp(r + 1, "shared")) {
8981 output_type = TCC_OUTPUT_DLL;
8982 } else if (r[1] == 'o') {
8983 if (optind >= argc)
8984 goto show_help;
8985 multiple_files = 1;
8986 outfile = argv[optind++];
8987 } else if (r[1] == 'r') {
8988 /* generate a .o merging several output files */
8989 reloc_output = 1;
8990 output_type = TCC_OUTPUT_OBJ;
8991 } else if (r[1] == 'W' || r[1] == 'O' || r[1] == 'm' || r[1] == 'f') {
8992 /* ignore those options to be a drop-in replacement for gcc */
8993 } else {
8994 error("invalid option -- '%s'", r);
8998 nb_objfiles = nb_files - nb_libraries;
9000 /* if outfile provided without other options, we output an
9001 executable */
9002 if (outfile && output_type == TCC_OUTPUT_MEMORY)
9003 output_type = TCC_OUTPUT_EXE;
9005 /* check -c consistency : only single file handled. XXX: checks file type */
9006 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9007 /* accepts only a single input file */
9008 if (nb_objfiles != 1)
9009 error("cannot specify multiple files with -c");
9010 if (nb_libraries != 0)
9011 error("cannot specify libraries with -c");
9014 /* compute default outfile name */
9015 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
9016 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9017 char *ext;
9018 /* add .o extension */
9019 pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
9020 ext = strrchr(objfilename, '.');
9021 if (!ext)
9022 goto default_outfile;
9023 strcpy(ext + 1, "o");
9024 } else {
9025 default_outfile:
9026 pstrcpy(objfilename, sizeof(objfilename), "a.out");
9028 outfile = objfilename;
9031 if (do_bench) {
9032 start_time = getclock_us();
9035 tcc_set_output_type(s, output_type);
9037 /* compile or add each files or library */
9038 for(i = 0;i < nb_files; i++) {
9039 const char *filename;
9041 filename = files[i];
9042 if (filename[0] == '-') {
9043 if (tcc_add_library(s, filename + 2) < 0)
9044 error("cannot find %s", filename);
9045 } else {
9046 if (tcc_add_file(s, filename) < 0) {
9047 ret = 1;
9048 goto the_end;
9053 /* free all files */
9054 tcc_free(files);
9056 if (do_bench) {
9057 double total_time;
9058 total_time = (double)(getclock_us() - start_time) / 1000000.0;
9059 if (total_time < 0.001)
9060 total_time = 0.001;
9061 if (total_bytes < 1)
9062 total_bytes = 1;
9063 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
9064 tok_ident - TOK_IDENT, total_lines, total_bytes,
9065 total_time, (int)(total_lines / total_time),
9066 total_bytes / total_time / 1000000.0);
9069 if (s->output_type != TCC_OUTPUT_MEMORY) {
9070 tcc_output_file(s, outfile);
9071 ret = 0;
9072 } else {
9073 ret = tcc_run(s, argc - optind, argv + optind);
9075 the_end:
9076 /* XXX: cannot do it with bound checking because of the malloc hooks */
9077 if (!do_bounds_check)
9078 tcc_delete(s);
9080 #ifdef MEM_DEBUG
9081 if (do_bench) {
9082 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
9084 #endif
9085 return ret;
9088 #endif