asm number parsing (thanks to Dave Long)
[tinycc.git] / tcc.c
blobf9ad3d01663e83e791e032680a35b754c5785295
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define _GNU_SOURCE
21 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <math.h>
29 #include <unistd.h>
30 #include <signal.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <setjmp.h>
34 #include <time.h>
35 #ifdef WIN32
36 #include <sys/timeb.h>
37 #endif
38 #ifndef WIN32
39 #include <sys/time.h>
40 #include <sys/ucontext.h>
41 #endif
42 #include "elf.h"
43 #include "stab.h"
44 #ifndef CONFIG_TCC_STATIC
45 #include <dlfcn.h>
46 #endif
48 #include "libtcc.h"
50 /* parser debug */
51 //#define PARSE_DEBUG
52 /* preprocessor debug */
53 //#define PP_DEBUG
54 /* include file debug */
55 //#define INC_DEBUG
57 //#define MEM_DEBUG
59 /* assembler debug */
60 //#define ASM_DEBUG
62 /* target selection */
63 //#define TCC_TARGET_I386 /* i386 code generator */
65 /* default target is I386 */
66 #if !defined(TCC_TARGET_I386)
67 #define TCC_TARGET_I386
68 #endif
70 #if !defined(WIN32) && !defined(TCC_UCLIBC)
71 #define CONFIG_TCC_BCHECK /* enable bound checking code */
72 #endif
74 /* define it to include assembler support */
75 #define CONFIG_TCC_ASM
77 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
78 executables or dlls */
79 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
81 #define INCLUDE_STACK_SIZE 32
82 #define IFDEF_STACK_SIZE 64
83 #define VSTACK_SIZE 64
84 #define STRING_MAX_SIZE 1024
86 #define TOK_HASH_SIZE 2048 /* must be a power of two */
87 #define TOK_ALLOC_INCR 512 /* must be a power of two */
88 #define TOK_STR_ALLOC_INCR_BITS 6
89 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
90 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
92 /* token symbol management */
93 typedef struct TokenSym {
94 struct TokenSym *hash_next;
95 struct Sym *sym_define; /* direct pointer to define */
96 struct Sym *sym_label; /* direct pointer to label */
97 struct Sym *sym_struct; /* direct pointer to structure */
98 struct Sym *sym_identifier; /* direct pointer to identifier */
99 int tok; /* token number */
100 int len;
101 char str[1];
102 } TokenSym;
104 typedef struct CString {
105 int size; /* size in bytes */
106 void *data; /* either 'char *' or 'int *' */
107 int size_allocated;
108 void *data_allocated; /* if non NULL, data has been malloced */
109 } CString;
111 /* type definition */
112 typedef struct CType {
113 int t;
114 struct Sym *ref;
115 } CType;
117 /* constant value */
118 typedef union CValue {
119 long double ld;
120 double d;
121 float f;
122 int i;
123 unsigned int ui;
124 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
125 long long ll;
126 unsigned long long ull;
127 struct CString *cstr;
128 void *ptr;
129 int tab[1];
130 } CValue;
132 /* value on stack */
133 typedef struct SValue {
134 CType type; /* type */
135 unsigned short r; /* register + flags */
136 unsigned short r2; /* second register, used for 'long long'
137 type. If not used, set to VT_CONST */
138 CValue c; /* constant, if VT_CONST */
139 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
140 } SValue;
142 /* symbol management */
143 typedef struct Sym {
144 int v; /* symbol token */
145 int r; /* associated register */
146 int c; /* associated number */
147 CType type; /* associated type */
148 struct Sym *next; /* next related symbol */
149 struct Sym *prev; /* prev symbol in stack */
150 struct Sym *prev_tok; /* previous symbol for this token */
151 } Sym;
153 /* section definition */
154 /* XXX: use directly ELF structure for parameters ? */
155 /* special flag to indicate that the section should not be linked to
156 the other ones */
157 #define SHF_PRIVATE 0x80000000
159 typedef struct Section {
160 unsigned long data_offset; /* current data offset */
161 unsigned char *data; /* section data */
162 unsigned long data_allocated; /* used for realloc() handling */
163 int sh_name; /* elf section name (only used during output) */
164 int sh_num; /* elf section number */
165 int sh_type; /* elf section type */
166 int sh_flags; /* elf section flags */
167 int sh_info; /* elf section info */
168 int sh_addralign; /* elf section alignment */
169 int sh_entsize; /* elf entry size */
170 unsigned long sh_size; /* section size (only used during output) */
171 unsigned long sh_addr; /* address at which the section is relocated */
172 unsigned long sh_offset; /* address at which the section is relocated */
173 int nb_hashed_syms; /* used to resize the hash table */
174 struct Section *link; /* link to another section */
175 struct Section *reloc; /* corresponding section for relocation, if any */
176 struct Section *hash; /* hash table for symbols */
177 struct Section *next;
178 char name[64]; /* section name */
179 } Section;
181 typedef struct DLLReference {
182 int level;
183 char name[1];
184 } DLLReference;
186 /* GNUC attribute definition */
187 typedef struct AttributeDef {
188 int aligned;
189 Section *section;
190 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
191 } AttributeDef;
193 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
194 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
195 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
197 /* stored in 'Sym.c' field */
198 #define FUNC_NEW 1 /* ansi function prototype */
199 #define FUNC_OLD 2 /* old function prototype */
200 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
202 /* stored in 'Sym.r' field */
203 #define FUNC_CDECL 0 /* standard c call */
204 #define FUNC_STDCALL 1 /* pascal c call */
206 /* field 'Sym.t' for macros */
207 #define MACRO_OBJ 0 /* object like macro */
208 #define MACRO_FUNC 1 /* function like macro */
210 /* field 'Sym.r' for C labels */
211 #define LABEL_DEFINED 0 /* label is defined */
212 #define LABEL_FORWARD 1 /* label is forward defined */
213 #define LABEL_DECLARED 2 /* label is declared but never used */
215 /* type_decl() types */
216 #define TYPE_ABSTRACT 1 /* type without variable */
217 #define TYPE_DIRECT 2 /* type with variable */
219 #define IO_BUF_SIZE 8192
221 typedef struct BufferedFile {
222 uint8_t *buf_ptr;
223 uint8_t *buf_end;
224 int fd;
225 int line_num; /* current line number - here to simplify code */
226 int ifndef_macro; /* #ifndef macro / #endif search */
227 int ifndef_macro_saved; /* saved ifndef_macro */
228 int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
229 char inc_type; /* type of include */
230 char inc_filename[512]; /* filename specified by the user */
231 char filename[1024]; /* current filename - here to simplify code */
232 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
233 } BufferedFile;
235 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
236 #define CH_EOF (-1) /* end of file */
238 /* parsing state (used to save parser state to reparse part of the
239 source several times) */
240 typedef struct ParseState {
241 int *macro_ptr;
242 int line_num;
243 int tok;
244 CValue tokc;
245 } ParseState;
247 /* used to record tokens */
248 typedef struct TokenString {
249 int *str;
250 int len;
251 int allocated_len;
252 int last_line_num;
253 } TokenString;
255 /* include file cache, used to find files faster and also to eliminate
256 inclusion if the include file is protected by #ifndef ... #endif */
257 typedef struct CachedInclude {
258 int ifndef_macro;
259 char type; /* '"' or '>' to give include type */
260 char filename[1]; /* path specified in #include */
261 } CachedInclude;
263 /* parser */
264 static struct BufferedFile *file;
265 static int ch, tok;
266 static CValue tokc;
267 static CString tokcstr; /* current parsed string, if any */
268 /* additional informations about token */
269 static int tok_flags;
270 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
271 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
272 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
274 static int *macro_ptr, *macro_ptr_allocated;
275 static int *unget_saved_macro_ptr;
276 static int unget_saved_buffer[TOK_MAX_SIZE + 1];
277 static int unget_buffer_enabled;
278 static int parse_flags;
279 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
280 #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
281 #define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
282 token. line feed is also
283 returned at eof */
285 static Section *text_section, *data_section, *bss_section; /* predefined sections */
286 static Section *cur_text_section; /* current section where function code is
287 generated */
288 /* bound check related sections */
289 static Section *bounds_section; /* contains global data bound description */
290 static Section *lbounds_section; /* contains local data bound description */
291 /* symbol sections */
292 static Section *symtab_section, *strtab_section;
294 /* debug sections */
295 static Section *stab_section, *stabstr_section;
297 /* loc : local variable index
298 ind : output code index
299 rsym: return symbol
300 anon_sym: anonymous symbol index
302 static int rsym, anon_sym, ind, loc;
303 /* expression generation modifiers */
304 static int const_wanted; /* true if constant wanted */
305 static int nocode_wanted; /* true if no code generation wanted for an expression */
306 static int global_expr; /* true if compound literals must be allocated
307 globally (used during initializers parsing */
308 static CType func_vt; /* current function return type (used by return
309 instruction) */
310 static int func_vc;
311 static int last_line_num, last_ind, func_ind; /* debug last line number and pc */
312 static int tok_ident;
313 static TokenSym **table_ident;
314 static TokenSym *hash_ident[TOK_HASH_SIZE];
315 static char token_buf[STRING_MAX_SIZE + 1];
316 static char *funcname;
317 static Sym *global_stack, *local_stack;
318 static Sym *define_stack;
319 static Sym *global_label_stack, *local_label_stack;
321 static SValue vstack[VSTACK_SIZE], *vtop;
322 /* some predefined types */
323 static CType char_pointer_type, func_old_type, int_type;
324 /* true if isid(c) || isnum(c) */
325 static unsigned char isidnum_table[256];
327 /* compile with debug symbol (and use them if error during execution) */
328 static int do_debug = 0;
330 /* compile with built-in memory and bounds checker */
331 static int do_bounds_check = 0;
333 /* display benchmark infos */
334 #if !defined(LIBTCC)
335 static int do_bench = 0;
336 #endif
337 static int total_lines;
338 static int total_bytes;
340 /* use GNU C extensions */
341 static int gnu_ext = 1;
343 /* use Tiny C extensions */
344 static int tcc_ext = 1;
346 /* max number of callers shown if error */
347 static int num_callers = 6;
348 static const char **rt_bound_error_msg;
350 /* XXX: get rid of this ASAP */
351 static struct TCCState *tcc_state;
353 /* give the path of the tcc libraries */
354 static const char *tcc_lib_path = CONFIG_TCC_LIBDIR "/tcc";
356 struct TCCState {
357 int output_type;
359 BufferedFile **include_stack_ptr;
360 int *ifdef_stack_ptr;
362 /* include file handling */
363 char **include_paths;
364 int nb_include_paths;
365 char **sysinclude_paths;
366 int nb_sysinclude_paths;
367 CachedInclude **cached_includes;
368 int nb_cached_includes;
370 char **library_paths;
371 int nb_library_paths;
373 /* array of all loaded dlls (including those referenced by loaded
374 dlls) */
375 DLLReference **loaded_dlls;
376 int nb_loaded_dlls;
378 /* sections */
379 Section **sections;
380 int nb_sections; /* number of sections, including first dummy section */
382 /* got handling */
383 Section *got;
384 Section *plt;
385 unsigned long *got_offsets;
386 int nb_got_offsets;
387 /* give the correspondance from symtab indexes to dynsym indexes */
388 int *symtab_to_dynsym;
390 /* temporary dynamic symbol sections (for dll loading) */
391 Section *dynsymtab_section;
392 /* exported dynamic symbol section */
393 Section *dynsym;
395 /* if true, no standard headers are added */
396 int nostdinc;
398 /* if true, static linking is performed */
399 int static_link;
401 /* error handling */
402 void *error_opaque;
403 void (*error_func)(void *opaque, const char *msg);
404 int error_set_jmp_enabled;
405 jmp_buf error_jmp_buf;
406 int nb_errors;
408 /* tiny assembler state */
409 Sym *asm_labels;
411 /* see include_stack_ptr */
412 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
414 /* see ifdef_stack_ptr */
415 int ifdef_stack[IFDEF_STACK_SIZE];
418 /* The current value can be: */
419 #define VT_VALMASK 0x00ff
420 #define VT_CONST 0x00f0 /* constant in vc
421 (must be first non register value) */
422 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
423 #define VT_LOCAL 0x00f2 /* offset on stack */
424 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
425 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
426 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
427 #define VT_LVAL 0x0100 /* var is an lvalue */
428 #define VT_SYM 0x0200 /* a symbol value is added */
429 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
430 char/short stored in integer registers) */
431 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
432 dereferencing value */
433 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
434 bounding function call point is in vc */
435 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
436 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
437 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
438 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
440 /* types */
441 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
443 #define VT_INT 0 /* integer type */
444 #define VT_BYTE 1 /* signed byte type */
445 #define VT_SHORT 2 /* short type */
446 #define VT_VOID 3 /* void type */
447 #define VT_PTR 4 /* pointer */
448 #define VT_ENUM 5 /* enum definition */
449 #define VT_FUNC 6 /* function type */
450 #define VT_STRUCT 7 /* struct/union definition */
451 #define VT_FLOAT 8 /* IEEE float */
452 #define VT_DOUBLE 9 /* IEEE double */
453 #define VT_LDOUBLE 10 /* IEEE long double */
454 #define VT_BOOL 11 /* ISOC99 boolean type */
455 #define VT_LLONG 12 /* 64 bit integer */
456 #define VT_LONG 13 /* long integer (NEVER USED as type, only
457 during parsing) */
458 #define VT_BTYPE 0x000f /* mask for basic type */
459 #define VT_UNSIGNED 0x0010 /* unsigned type */
460 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
461 #define VT_BITFIELD 0x0040 /* bitfield modifier */
463 /* storage */
464 #define VT_EXTERN 0x00000080 /* extern definition */
465 #define VT_STATIC 0x00000100 /* static variable */
466 #define VT_TYPEDEF 0x00000200 /* typedef definition */
467 #define VT_INLINE 0x00000400 /* inline definition */
469 /* type mask (except storage) */
470 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
471 #define VT_TYPE (~(VT_STORAGE))
473 /* token values */
475 /* warning: the following compare tokens depend on i386 asm code */
476 #define TOK_ULT 0x92
477 #define TOK_UGE 0x93
478 #define TOK_EQ 0x94
479 #define TOK_NE 0x95
480 #define TOK_ULE 0x96
481 #define TOK_UGT 0x97
482 #define TOK_LT 0x9c
483 #define TOK_GE 0x9d
484 #define TOK_LE 0x9e
485 #define TOK_GT 0x9f
487 #define TOK_LAND 0xa0
488 #define TOK_LOR 0xa1
490 #define TOK_DEC 0xa2
491 #define TOK_MID 0xa3 /* inc/dec, to void constant */
492 #define TOK_INC 0xa4
493 #define TOK_UDIV 0xb0 /* unsigned division */
494 #define TOK_UMOD 0xb1 /* unsigned modulo */
495 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
496 #define TOK_CINT 0xb3 /* number in tokc */
497 #define TOK_CCHAR 0xb4 /* char constant in tokc */
498 #define TOK_STR 0xb5 /* pointer to string in tokc */
499 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
500 #define TOK_LCHAR 0xb7
501 #define TOK_LSTR 0xb8
502 #define TOK_CFLOAT 0xb9 /* float constant */
503 #define TOK_LINENUM 0xba /* line number info */
504 #define TOK_CDOUBLE 0xc0 /* double constant */
505 #define TOK_CLDOUBLE 0xc1 /* long double constant */
506 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
507 #define TOK_ADDC1 0xc3 /* add with carry generation */
508 #define TOK_ADDC2 0xc4 /* add with carry use */
509 #define TOK_SUBC1 0xc5 /* add with carry generation */
510 #define TOK_SUBC2 0xc6 /* add with carry use */
511 #define TOK_CUINT 0xc8 /* unsigned int constant */
512 #define TOK_CLLONG 0xc9 /* long long constant */
513 #define TOK_CULLONG 0xca /* unsigned long long constant */
514 #define TOK_ARROW 0xcb
515 #define TOK_DOTS 0xcc /* three dots */
516 #define TOK_SHR 0xcd /* unsigned shift right */
517 #define TOK_PPNUM 0xce /* preprocessor number */
519 #define TOK_SHL 0x01 /* shift left */
520 #define TOK_SAR 0x02 /* signed shift right */
522 /* assignement operators : normal operator or 0x80 */
523 #define TOK_A_MOD 0xa5
524 #define TOK_A_AND 0xa6
525 #define TOK_A_MUL 0xaa
526 #define TOK_A_ADD 0xab
527 #define TOK_A_SUB 0xad
528 #define TOK_A_DIV 0xaf
529 #define TOK_A_XOR 0xde
530 #define TOK_A_OR 0xfc
531 #define TOK_A_SHL 0x81
532 #define TOK_A_SAR 0x82
534 /* WARNING: the content of this string encodes token numbers */
535 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";
537 #define TOK_EOF (-1) /* end of file */
538 #define TOK_LINEFEED 10 /* line feed */
540 /* all identificators and strings have token above that */
541 #define TOK_IDENT 256
543 /* only used for i386 asm opcodes definitions */
544 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
546 #define DEF_BWL(x) \
547 DEF(TOK_ASM_ ## x ## b, #x "b") \
548 DEF(TOK_ASM_ ## x ## w, #x "w") \
549 DEF(TOK_ASM_ ## x ## l, #x "l") \
550 DEF(TOK_ASM_ ## x, #x)
552 #define DEF_WL(x) \
553 DEF(TOK_ASM_ ## x ## w, #x "w") \
554 DEF(TOK_ASM_ ## x ## l, #x "l") \
555 DEF(TOK_ASM_ ## x, #x)
557 #define DEF_FP1(x) \
558 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
559 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
560 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
561 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
563 #define DEF_FP(x) \
564 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
565 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
566 DEF_FP1(x)
568 #define DEF_ASMTEST(x) \
569 DEF_ASM(x ## o) \
570 DEF_ASM(x ## no) \
571 DEF_ASM(x ## b) \
572 DEF_ASM(x ## c) \
573 DEF_ASM(x ## nae) \
574 DEF_ASM(x ## nb) \
575 DEF_ASM(x ## nc) \
576 DEF_ASM(x ## ae) \
577 DEF_ASM(x ## e) \
578 DEF_ASM(x ## z) \
579 DEF_ASM(x ## ne) \
580 DEF_ASM(x ## nz) \
581 DEF_ASM(x ## be) \
582 DEF_ASM(x ## na) \
583 DEF_ASM(x ## nbe) \
584 DEF_ASM(x ## a) \
585 DEF_ASM(x ## s) \
586 DEF_ASM(x ## ns) \
587 DEF_ASM(x ## p) \
588 DEF_ASM(x ## pe) \
589 DEF_ASM(x ## np) \
590 DEF_ASM(x ## po) \
591 DEF_ASM(x ## l) \
592 DEF_ASM(x ## nge) \
593 DEF_ASM(x ## nl) \
594 DEF_ASM(x ## ge) \
595 DEF_ASM(x ## le) \
596 DEF_ASM(x ## ng) \
597 DEF_ASM(x ## nle) \
598 DEF_ASM(x ## g)
600 #define TOK_ASM_int TOK_INT
602 enum {
603 TOK_LAST = TOK_IDENT - 1,
604 #define DEF(id, str) id,
605 #include "tcctok.h"
606 #undef DEF
609 static const char tcc_keywords[] =
610 #define DEF(id, str) str "\0"
611 #include "tcctok.h"
612 #undef DEF
615 #define TOK_UIDENT TOK_DEFINE
617 #ifdef WIN32
618 #define snprintf _snprintf
619 #define vsnprintf _vsnprintf
620 #endif
622 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
623 /* currently incorrect */
624 long double strtold(const char *nptr, char **endptr)
626 return (long double)strtod(nptr, endptr);
628 float strtof(const char *nptr, char **endptr)
630 return (float)strtod(nptr, endptr);
632 #else
633 /* XXX: need to define this to use them in non ISOC99 context */
634 extern float strtof (const char *__nptr, char **__endptr);
635 extern long double strtold (const char *__nptr, char **__endptr);
636 #endif
638 static char *pstrcpy(char *buf, int buf_size, const char *s);
639 static char *pstrcat(char *buf, int buf_size, const char *s);
641 static void next(void);
642 static void next_nomacro(void);
643 static void parse_expr_type(CType *type);
644 static void expr_type(CType *type);
645 static void unary_type(CType *type);
646 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
647 int case_reg, int is_expr);
648 static int expr_const(void);
649 static void expr_eq(void);
650 static void gexpr(void);
651 static void decl(int l);
652 static void decl_initializer(CType *type, Section *sec, unsigned long c,
653 int first, int size_only);
654 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
655 int has_init, int v, int scope);
656 int gv(int rc);
657 void gv2(int rc1, int rc2);
658 void move_reg(int r, int s);
659 void save_regs(int n);
660 void save_reg(int r);
661 void vpop(void);
662 void vswap(void);
663 void vdup(void);
664 int get_reg(int rc);
666 static void macro_subst(TokenString *tok_str,
667 Sym **nested_list, const int *macro_str);
668 int save_reg_forced(int r);
669 void gen_op(int op);
670 void force_charshort_cast(int t);
671 static void gen_cast(CType *type);
672 void vstore(void);
673 static Sym *sym_find(int v);
674 static Sym *sym_push(int v, CType *type, int r, int c);
676 /* type handling */
677 static int type_size(CType *type, int *a);
678 static inline CType *pointed_type(CType *type);
679 static int pointed_size(CType *type);
680 static int lvalue_type(int t);
681 static int is_compatible_types(CType *type1, CType *type2);
682 static int parse_btype(CType *type, AttributeDef *ad);
683 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
685 void error(const char *fmt, ...);
686 void vpushi(int v);
687 void vset(CType *type, int r, int v);
688 void type_to_str(char *buf, int buf_size,
689 CType *type, const char *varstr);
690 char *get_tok_str(int v, CValue *cv);
691 static Sym *get_sym_ref(CType *type, Section *sec,
692 unsigned long offset, unsigned long size);
693 static Sym *external_global_sym(int v, CType *type, int r);
695 /* section generation */
696 static void section_realloc(Section *sec, unsigned long new_size);
697 static void *section_ptr_add(Section *sec, unsigned long size);
698 static void put_extern_sym(Sym *sym, Section *section,
699 unsigned long value, unsigned long size);
700 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
701 static int put_elf_str(Section *s, const char *sym);
702 static int put_elf_sym(Section *s,
703 unsigned long value, unsigned long size,
704 int info, int other, int shndx, const char *name);
705 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
706 int info, int sh_num, const char *name);
707 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
708 int type, int symbol);
709 static void put_stabs(const char *str, int type, int other, int desc,
710 unsigned long value);
711 static void put_stabs_r(const char *str, int type, int other, int desc,
712 unsigned long value, Section *sec, int sym_index);
713 static void put_stabn(int type, int other, int desc, int value);
714 static void put_stabd(int type, int other, int desc);
715 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
717 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
718 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
719 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
721 /* tccasm.c */
723 #ifdef CONFIG_TCC_ASM
725 typedef struct ExprValue {
726 uint32_t v;
727 Sym *sym;
728 } ExprValue;
730 #define MAX_ASM_OPERANDS 30
732 typedef struct ASMOperand {
733 int id; /* GCC 3 optionnal identifier (0 if number only supported */
734 char *constraint;
735 char asm_str[16]; /* computed asm string for operand */
736 SValue *vt; /* C value of the expression */
737 int ref_index; /* if >= 0, gives reference to a output constraint */
738 int priority; /* priority, used to assign registers */
739 int reg; /* if >= 0, register number used for this operand */
740 int is_llong; /* true if double register value */
741 } ASMOperand;
743 static void asm_expr(TCCState *s1, ExprValue *pe);
744 static int asm_int_expr(TCCState *s1);
745 static int find_constraint(ASMOperand *operands, int nb_operands,
746 const char *name, const char **pp);
748 static int tcc_assemble(TCCState *s1, int do_preprocess);
750 #endif
752 static void asm_instr(void);
754 /* true if float/double/long double type */
755 static inline int is_float(int t)
757 int bt;
758 bt = t & VT_BTYPE;
759 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
762 #ifdef TCC_TARGET_I386
763 #include "i386-gen.c"
764 #endif
766 #ifdef CONFIG_TCC_STATIC
768 #define RTLD_LAZY 0x001
769 #define RTLD_NOW 0x002
770 #define RTLD_GLOBAL 0x100
771 #define RTLD_DEFAULT NULL
773 /* dummy function for profiling */
774 void *dlopen(const char *filename, int flag)
776 return NULL;
779 const char *dlerror(void)
781 return "error";
784 typedef struct TCCSyms {
785 char *str;
786 void *ptr;
787 } TCCSyms;
789 #define TCCSYM(a) { #a, &a, },
791 /* add the symbol you want here if no dynamic linking is done */
792 static TCCSyms tcc_syms[] = {
793 TCCSYM(printf)
794 TCCSYM(fprintf)
795 TCCSYM(fopen)
796 TCCSYM(fclose)
797 { NULL, NULL },
800 void *dlsym(void *handle, const char *symbol)
802 TCCSyms *p;
803 p = tcc_syms;
804 while (p->str != NULL) {
805 if (!strcmp(p->str, symbol))
806 return p->ptr;
807 p++;
809 return NULL;
812 #endif
814 /********************************************************/
816 /* we use our own 'finite' function to avoid potential problems with
817 non standard math libs */
818 /* XXX: endianness dependent */
819 int ieee_finite(double d)
821 int *p = (int *)&d;
822 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
825 /* copy a string and truncate it. */
826 static char *pstrcpy(char *buf, int buf_size, const char *s)
828 char *q, *q_end;
829 int c;
831 if (buf_size > 0) {
832 q = buf;
833 q_end = buf + buf_size - 1;
834 while (q < q_end) {
835 c = *s++;
836 if (c == '\0')
837 break;
838 *q++ = c;
840 *q = '\0';
842 return buf;
845 /* strcat and truncate. */
846 static char *pstrcat(char *buf, int buf_size, const char *s)
848 int len;
849 len = strlen(buf);
850 if (len < buf_size)
851 pstrcpy(buf + len, buf_size - len, s);
852 return buf;
855 /* memory management */
856 #ifdef MEM_DEBUG
857 int mem_cur_size;
858 int mem_max_size;
859 #endif
861 static inline void tcc_free(void *ptr)
863 #ifdef MEM_DEBUG
864 mem_cur_size -= malloc_usable_size(ptr);
865 #endif
866 free(ptr);
869 static void *tcc_malloc(unsigned long size)
871 void *ptr;
872 ptr = malloc(size);
873 if (!ptr && size)
874 error("memory full");
875 #ifdef MEM_DEBUG
876 mem_cur_size += malloc_usable_size(ptr);
877 if (mem_cur_size > mem_max_size)
878 mem_max_size = mem_cur_size;
879 #endif
880 return ptr;
883 static void *tcc_mallocz(unsigned long size)
885 void *ptr;
886 ptr = tcc_malloc(size);
887 memset(ptr, 0, size);
888 return ptr;
891 static inline void *tcc_realloc(void *ptr, unsigned long size)
893 void *ptr1;
894 #ifdef MEM_DEBUG
895 mem_cur_size -= malloc_usable_size(ptr);
896 #endif
897 ptr1 = realloc(ptr, size);
898 #ifdef MEM_DEBUG
899 /* NOTE: count not correct if alloc error, but not critical */
900 mem_cur_size += malloc_usable_size(ptr1);
901 if (mem_cur_size > mem_max_size)
902 mem_max_size = mem_cur_size;
903 #endif
904 return ptr1;
907 static char *tcc_strdup(const char *str)
909 char *ptr;
910 ptr = tcc_malloc(strlen(str) + 1);
911 strcpy(ptr, str);
912 return ptr;
915 #define free(p) use_tcc_free(p)
916 #define malloc(s) use_tcc_malloc(s)
917 #define realloc(p, s) use_tcc_realloc(p, s)
919 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
921 int nb, nb_alloc;
922 void **pp;
924 nb = *nb_ptr;
925 pp = *ptab;
926 /* every power of two we double array size */
927 if ((nb & (nb - 1)) == 0) {
928 if (!nb)
929 nb_alloc = 1;
930 else
931 nb_alloc = nb * 2;
932 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
933 if (!pp)
934 error("memory full");
935 *ptab = pp;
937 pp[nb++] = data;
938 *nb_ptr = nb;
941 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
943 Section *sec;
945 sec = tcc_mallocz(sizeof(Section));
946 pstrcpy(sec->name, sizeof(sec->name), name);
947 sec->sh_type = sh_type;
948 sec->sh_flags = sh_flags;
949 switch(sh_type) {
950 case SHT_HASH:
951 case SHT_REL:
952 case SHT_DYNSYM:
953 case SHT_SYMTAB:
954 case SHT_DYNAMIC:
955 sec->sh_addralign = 4;
956 break;
957 case SHT_STRTAB:
958 sec->sh_addralign = 1;
959 break;
960 default:
961 sec->sh_addralign = 32; /* default conservative alignment */
962 break;
965 /* only add section if not private */
966 if (!(sh_flags & SHF_PRIVATE)) {
967 sec->sh_num = s1->nb_sections;
968 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
970 return sec;
973 static void free_section(Section *s)
975 tcc_free(s->data);
976 tcc_free(s);
979 /* realloc section and set its content to zero */
980 static void section_realloc(Section *sec, unsigned long new_size)
982 unsigned long size;
983 unsigned char *data;
985 size = sec->data_allocated;
986 if (size == 0)
987 size = 1;
988 while (size < new_size)
989 size = size * 2;
990 data = tcc_realloc(sec->data, size);
991 if (!data)
992 error("memory full");
993 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
994 sec->data = data;
995 sec->data_allocated = size;
998 /* reserve at least 'size' bytes in section 'sec' from
999 sec->data_offset. */
1000 static void *section_ptr_add(Section *sec, unsigned long size)
1002 unsigned long offset, offset1;
1004 offset = sec->data_offset;
1005 offset1 = offset + size;
1006 if (offset1 > sec->data_allocated)
1007 section_realloc(sec, offset1);
1008 sec->data_offset = offset1;
1009 return sec->data + offset;
1012 /* return a reference to a section, and create it if it does not
1013 exists */
1014 Section *find_section(TCCState *s1, const char *name)
1016 Section *sec;
1017 int i;
1018 for(i = 1; i < s1->nb_sections; i++) {
1019 sec = s1->sections[i];
1020 if (!strcmp(name, sec->name))
1021 return sec;
1023 /* sections are created as PROGBITS */
1024 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
1027 /* update sym->c so that it points to an external symbol in section
1028 'section' with value 'value' */
1029 static void put_extern_sym(Sym *sym, Section *section,
1030 unsigned long value, unsigned long size)
1032 int sym_type, sym_bind, sh_num, info;
1033 Elf32_Sym *esym;
1034 const char *name;
1036 if (section)
1037 sh_num = section->sh_num;
1038 else
1039 sh_num = SHN_UNDEF;
1040 if (!sym->c) {
1041 if ((sym->type.t & VT_BTYPE) == VT_FUNC)
1042 sym_type = STT_FUNC;
1043 else
1044 sym_type = STT_OBJECT;
1045 if (sym->type.t & VT_STATIC)
1046 sym_bind = STB_LOCAL;
1047 else
1048 sym_bind = STB_GLOBAL;
1050 name = get_tok_str(sym->v, NULL);
1051 #ifdef CONFIG_TCC_BCHECK
1052 if (do_bounds_check) {
1053 char buf[32];
1055 /* XXX: avoid doing that for statics ? */
1056 /* if bound checking is activated, we change some function
1057 names by adding the "__bound" prefix */
1058 switch(sym->v) {
1059 #if 0
1060 /* XXX: we rely only on malloc hooks */
1061 case TOK_malloc:
1062 case TOK_free:
1063 case TOK_realloc:
1064 case TOK_memalign:
1065 case TOK_calloc:
1066 #endif
1067 case TOK_memcpy:
1068 case TOK_memmove:
1069 case TOK_memset:
1070 case TOK_strlen:
1071 case TOK_strcpy:
1072 strcpy(buf, "__bound_");
1073 strcat(buf, name);
1074 name = buf;
1075 break;
1078 #endif
1079 info = ELF32_ST_INFO(sym_bind, sym_type);
1080 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
1081 } else {
1082 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
1083 esym->st_value = value;
1084 esym->st_size = size;
1085 esym->st_shndx = sh_num;
1089 /* add a new relocation entry to symbol 'sym' in section 's' */
1090 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
1092 if (!sym->c)
1093 put_extern_sym(sym, NULL, 0, 0);
1094 /* now we can add ELF relocation info */
1095 put_elf_reloc(symtab_section, s, offset, type, sym->c);
1098 static inline int isid(int c)
1100 return (c >= 'a' && c <= 'z') ||
1101 (c >= 'A' && c <= 'Z') ||
1102 c == '_';
1105 static inline int isnum(int c)
1107 return c >= '0' && c <= '9';
1110 static inline int isoct(int c)
1112 return c >= '0' && c <= '7';
1115 static inline int toup(int c)
1117 if (c >= 'a' && c <= 'z')
1118 return c - 'a' + 'A';
1119 else
1120 return c;
1123 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
1125 int len;
1126 len = strlen(buf);
1127 vsnprintf(buf + len, buf_size - len, fmt, ap);
1130 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
1132 va_list ap;
1133 va_start(ap, fmt);
1134 strcat_vprintf(buf, buf_size, fmt, ap);
1135 va_end(ap);
1138 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
1140 char buf[2048];
1141 BufferedFile **f;
1143 buf[0] = '\0';
1144 if (file) {
1145 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1146 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1147 (*f)->filename, (*f)->line_num);
1148 if (file->line_num > 0) {
1149 strcat_printf(buf, sizeof(buf),
1150 "%s:%d: ", file->filename, file->line_num);
1151 } else {
1152 strcat_printf(buf, sizeof(buf),
1153 "%s: ", file->filename);
1155 } else {
1156 strcat_printf(buf, sizeof(buf),
1157 "tcc: ");
1159 if (is_warning)
1160 strcat_printf(buf, sizeof(buf), "warning: ");
1161 strcat_vprintf(buf, sizeof(buf), fmt, ap);
1163 if (!s1->error_func) {
1164 /* default case: stderr */
1165 fprintf(stderr, "%s\n", buf);
1166 } else {
1167 s1->error_func(s1->error_opaque, buf);
1169 if (!is_warning)
1170 s1->nb_errors++;
1173 #ifdef LIBTCC
1174 void tcc_set_error_func(TCCState *s, void *error_opaque,
1175 void (*error_func)(void *opaque, const char *msg))
1177 s->error_opaque = error_opaque;
1178 s->error_func = error_func;
1180 #endif
1182 /* error without aborting current compilation */
1183 void error_noabort(const char *fmt, ...)
1185 TCCState *s1 = tcc_state;
1186 va_list ap;
1188 va_start(ap, fmt);
1189 error1(s1, 0, fmt, ap);
1190 va_end(ap);
1193 void error(const char *fmt, ...)
1195 TCCState *s1 = tcc_state;
1196 va_list ap;
1198 va_start(ap, fmt);
1199 error1(s1, 0, fmt, ap);
1200 va_end(ap);
1201 /* better than nothing: in some cases, we accept to handle errors */
1202 if (s1->error_set_jmp_enabled) {
1203 longjmp(s1->error_jmp_buf, 1);
1204 } else {
1205 /* XXX: eliminate this someday */
1206 exit(1);
1210 void expect(const char *msg)
1212 error("%s expected", msg);
1215 void warning(const char *fmt, ...)
1217 TCCState *s1 = tcc_state;
1218 va_list ap;
1220 va_start(ap, fmt);
1221 error1(s1, 1, fmt, ap);
1222 va_end(ap);
1225 void skip(int c)
1227 if (tok != c)
1228 error("'%c' expected", c);
1229 next();
1232 static void test_lvalue(void)
1234 if (!(vtop->r & VT_LVAL))
1235 expect("lvalue");
1238 /* allocate a new token */
1239 static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
1241 TokenSym *ts, **ptable;
1242 int i;
1244 if (tok_ident >= SYM_FIRST_ANOM)
1245 error("memory full");
1247 /* expand token table if needed */
1248 i = tok_ident - TOK_IDENT;
1249 if ((i % TOK_ALLOC_INCR) == 0) {
1250 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1251 if (!ptable)
1252 error("memory full");
1253 table_ident = ptable;
1256 ts = tcc_malloc(sizeof(TokenSym) + len);
1257 table_ident[i] = ts;
1258 ts->tok = tok_ident++;
1259 ts->sym_define = NULL;
1260 ts->sym_label = NULL;
1261 ts->sym_struct = NULL;
1262 ts->sym_identifier = NULL;
1263 ts->len = len;
1264 ts->hash_next = NULL;
1265 memcpy(ts->str, str, len);
1266 ts->str[len] = '\0';
1267 *pts = ts;
1268 return ts;
1271 #define TOK_HASH_INIT 1
1272 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1274 /* find a token and add it if not found */
1275 static TokenSym *tok_alloc(const char *str, int len)
1277 TokenSym *ts, **pts;
1278 int i;
1279 unsigned int h;
1281 h = TOK_HASH_INIT;
1282 for(i=0;i<len;i++)
1283 h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
1284 h &= (TOK_HASH_SIZE - 1);
1286 pts = &hash_ident[h];
1287 for(;;) {
1288 ts = *pts;
1289 if (!ts)
1290 break;
1291 if (ts->len == len && !memcmp(ts->str, str, len))
1292 return ts;
1293 pts = &(ts->hash_next);
1295 return tok_alloc_new(pts, str, len);
1298 /* CString handling */
1300 static void cstr_realloc(CString *cstr, int new_size)
1302 int size;
1303 void *data;
1305 size = cstr->size_allocated;
1306 if (size == 0)
1307 size = 8; /* no need to allocate a too small first string */
1308 while (size < new_size)
1309 size = size * 2;
1310 data = tcc_realloc(cstr->data_allocated, size);
1311 if (!data)
1312 error("memory full");
1313 cstr->data_allocated = data;
1314 cstr->size_allocated = size;
1315 cstr->data = data;
1318 /* add a byte */
1319 static void cstr_ccat(CString *cstr, int ch)
1321 int size;
1322 size = cstr->size + 1;
1323 if (size > cstr->size_allocated)
1324 cstr_realloc(cstr, size);
1325 ((unsigned char *)cstr->data)[size - 1] = ch;
1326 cstr->size = size;
1329 static void cstr_cat(CString *cstr, const char *str)
1331 int c;
1332 for(;;) {
1333 c = *str;
1334 if (c == '\0')
1335 break;
1336 cstr_ccat(cstr, c);
1337 str++;
1341 /* add a wide char */
1342 static void cstr_wccat(CString *cstr, int ch)
1344 int size;
1345 size = cstr->size + sizeof(int);
1346 if (size > cstr->size_allocated)
1347 cstr_realloc(cstr, size);
1348 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1349 cstr->size = size;
1352 static void cstr_new(CString *cstr)
1354 memset(cstr, 0, sizeof(CString));
1357 /* free string and reset it to NULL */
1358 static void cstr_free(CString *cstr)
1360 tcc_free(cstr->data_allocated);
1361 cstr_new(cstr);
1364 #define cstr_reset(cstr) cstr_free(cstr)
1366 static CString *cstr_dup(CString *cstr1)
1368 CString *cstr;
1369 int size;
1371 cstr = tcc_malloc(sizeof(CString));
1372 size = cstr1->size;
1373 cstr->size = size;
1374 cstr->size_allocated = size;
1375 cstr->data_allocated = tcc_malloc(size);
1376 cstr->data = cstr->data_allocated;
1377 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1378 return cstr;
1381 /* XXX: unicode ? */
1382 static void add_char(CString *cstr, int c)
1384 if (c == '\'' || c == '\"' || c == '\\') {
1385 /* XXX: could be more precise if char or string */
1386 cstr_ccat(cstr, '\\');
1388 if (c >= 32 && c <= 126) {
1389 cstr_ccat(cstr, c);
1390 } else {
1391 cstr_ccat(cstr, '\\');
1392 if (c == '\n') {
1393 cstr_ccat(cstr, 'n');
1394 } else {
1395 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1396 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1397 cstr_ccat(cstr, '0' + (c & 7));
1402 /* XXX: buffer overflow */
1403 /* XXX: float tokens */
1404 char *get_tok_str(int v, CValue *cv)
1406 static char buf[STRING_MAX_SIZE + 1];
1407 static CString cstr_buf;
1408 CString *cstr;
1409 unsigned char *q;
1410 char *p;
1411 int i, len;
1413 /* NOTE: to go faster, we give a fixed buffer for small strings */
1414 cstr_reset(&cstr_buf);
1415 cstr_buf.data = buf;
1416 cstr_buf.size_allocated = sizeof(buf);
1417 p = buf;
1419 switch(v) {
1420 case TOK_CINT:
1421 case TOK_CUINT:
1422 /* XXX: not quite exact, but only useful for testing */
1423 sprintf(p, "%u", cv->ui);
1424 break;
1425 case TOK_CLLONG:
1426 case TOK_CULLONG:
1427 /* XXX: not quite exact, but only useful for testing */
1428 sprintf(p, "%Lu", cv->ull);
1429 break;
1430 case TOK_CCHAR:
1431 case TOK_LCHAR:
1432 cstr_ccat(&cstr_buf, '\'');
1433 add_char(&cstr_buf, cv->i);
1434 cstr_ccat(&cstr_buf, '\'');
1435 cstr_ccat(&cstr_buf, '\0');
1436 break;
1437 case TOK_PPNUM:
1438 cstr = cv->cstr;
1439 len = cstr->size - 1;
1440 for(i=0;i<len;i++)
1441 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1442 cstr_ccat(&cstr_buf, '\0');
1443 break;
1444 case TOK_STR:
1445 case TOK_LSTR:
1446 cstr = cv->cstr;
1447 cstr_ccat(&cstr_buf, '\"');
1448 if (v == TOK_STR) {
1449 len = cstr->size - 1;
1450 for(i=0;i<len;i++)
1451 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1452 } else {
1453 len = (cstr->size / sizeof(int)) - 1;
1454 for(i=0;i<len;i++)
1455 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1457 cstr_ccat(&cstr_buf, '\"');
1458 cstr_ccat(&cstr_buf, '\0');
1459 break;
1460 case TOK_LT:
1461 v = '<';
1462 goto addv;
1463 case TOK_GT:
1464 v = '>';
1465 goto addv;
1466 case TOK_A_SHL:
1467 return strcpy(p, "<<=");
1468 case TOK_A_SAR:
1469 return strcpy(p, ">>=");
1470 default:
1471 if (v < TOK_IDENT) {
1472 /* search in two bytes table */
1473 q = tok_two_chars;
1474 while (*q) {
1475 if (q[2] == v) {
1476 *p++ = q[0];
1477 *p++ = q[1];
1478 *p = '\0';
1479 return buf;
1481 q += 3;
1483 addv:
1484 *p++ = v;
1485 *p = '\0';
1486 } else if (v < tok_ident) {
1487 return table_ident[v - TOK_IDENT]->str;
1488 } else if (v >= SYM_FIRST_ANOM) {
1489 /* special name for anonymous symbol */
1490 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1491 } else {
1492 /* should never happen */
1493 return NULL;
1495 break;
1497 return cstr_buf.data;
1500 /* push, without hashing */
1501 static Sym *sym_push2(Sym **ps, int v, int t, int c)
1503 Sym *s;
1504 s = tcc_malloc(sizeof(Sym));
1505 s->v = v;
1506 s->type.t = t;
1507 s->c = c;
1508 s->next = NULL;
1509 /* add in stack */
1510 s->prev = *ps;
1511 *ps = s;
1512 return s;
1515 /* find a symbol and return its associated structure. 's' is the top
1516 of the symbol stack */
1517 static Sym *sym_find2(Sym *s, int v)
1519 while (s) {
1520 if (s->v == v)
1521 return s;
1522 s = s->prev;
1524 return NULL;
1527 /* structure lookup */
1528 static inline Sym *struct_find(int v)
1530 v -= TOK_IDENT;
1531 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1532 return NULL;
1533 return table_ident[v]->sym_struct;
1536 /* find an identifier */
1537 static inline Sym *sym_find(int v)
1539 v -= TOK_IDENT;
1540 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1541 return NULL;
1542 return table_ident[v]->sym_identifier;
1545 /* push a given symbol on the symbol stack */
1546 static Sym *sym_push(int v, CType *type, int r, int c)
1548 Sym *s, **ps;
1549 TokenSym *ts;
1551 if (local_stack)
1552 ps = &local_stack;
1553 else
1554 ps = &global_stack;
1555 s = sym_push2(ps, v, type->t, c);
1556 s->type.ref = type->ref;
1557 s->r = r;
1558 /* don't record fields or anonymous symbols */
1559 /* XXX: simplify */
1560 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1561 /* record symbol in token array */
1562 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1563 if (v & SYM_STRUCT)
1564 ps = &ts->sym_struct;
1565 else
1566 ps = &ts->sym_identifier;
1567 s->prev_tok = *ps;
1568 *ps = s;
1570 return s;
1573 /* push a global identifier */
1574 static Sym *global_identifier_push(int v, int t, int c)
1576 Sym *s, **ps;
1577 s = sym_push2(&global_stack, v, t, c);
1578 /* don't record anonymous symbol */
1579 if (v < SYM_FIRST_ANOM) {
1580 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1581 /* modify the top most local identifier, so that
1582 sym_identifier will point to 's' when popped */
1583 while (*ps != NULL)
1584 ps = &(*ps)->prev_tok;
1585 s->prev_tok = NULL;
1586 *ps = s;
1588 return s;
1591 /* pop symbols until top reaches 'b' */
1592 static void sym_pop(Sym **ptop, Sym *b)
1594 Sym *s, *ss, **ps;
1595 TokenSym *ts;
1596 int v;
1598 s = *ptop;
1599 while(s != b) {
1600 ss = s->prev;
1601 v = s->v;
1602 /* remove symbol in token array */
1603 /* XXX: simplify */
1604 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1605 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1606 if (v & SYM_STRUCT)
1607 ps = &ts->sym_struct;
1608 else
1609 ps = &ts->sym_identifier;
1610 *ps = s->prev_tok;
1612 tcc_free(s);
1613 s = ss;
1615 *ptop = b;
1618 /* I/O layer */
1620 BufferedFile *tcc_open(TCCState *s1, const char *filename)
1622 int fd;
1623 BufferedFile *bf;
1625 fd = open(filename, O_RDONLY);
1626 if (fd < 0)
1627 return NULL;
1628 bf = tcc_malloc(sizeof(BufferedFile));
1629 if (!bf) {
1630 close(fd);
1631 return NULL;
1633 bf->fd = fd;
1634 bf->buf_ptr = bf->buffer;
1635 bf->buf_end = bf->buffer;
1636 bf->buffer[0] = CH_EOB; /* put eob symbol */
1637 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1638 bf->line_num = 1;
1639 bf->ifndef_macro = 0;
1640 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1641 // printf("opening '%s'\n", filename);
1642 return bf;
1645 void tcc_close(BufferedFile *bf)
1647 total_lines += bf->line_num;
1648 close(bf->fd);
1649 tcc_free(bf);
1652 /* fill input buffer and peek next char */
1653 static int tcc_peekc_slow(BufferedFile *bf)
1655 int len;
1656 /* only tries to read if really end of buffer */
1657 if (bf->buf_ptr >= bf->buf_end) {
1658 if (bf->fd != -1) {
1659 #if defined(PARSE_DEBUG)
1660 len = 8;
1661 #else
1662 len = IO_BUF_SIZE;
1663 #endif
1664 len = read(bf->fd, bf->buffer, len);
1665 if (len < 0)
1666 len = 0;
1667 } else {
1668 len = 0;
1670 total_bytes += len;
1671 bf->buf_ptr = bf->buffer;
1672 bf->buf_end = bf->buffer + len;
1673 *bf->buf_end = CH_EOB;
1675 if (bf->buf_ptr < bf->buf_end) {
1676 return bf->buf_ptr[0];
1677 } else {
1678 bf->buf_ptr = bf->buf_end;
1679 return CH_EOF;
1683 /* return the current character, handling end of block if necessary
1684 (but not stray) */
1685 static int handle_eob(void)
1687 return tcc_peekc_slow(file);
1690 /* read next char from current input file and handle end of input buffer */
1691 static inline void inp(void)
1693 ch = *(++(file->buf_ptr));
1694 /* end of buffer/file handling */
1695 if (ch == CH_EOB)
1696 ch = handle_eob();
1699 /* handle '\[\r]\n' */
1700 static void handle_stray(void)
1702 while (ch == '\\') {
1703 inp();
1704 if (ch == '\n') {
1705 file->line_num++;
1706 inp();
1707 } else if (ch == '\r') {
1708 inp();
1709 if (ch != '\n')
1710 goto fail;
1711 file->line_num++;
1712 inp();
1713 } else {
1714 fail:
1715 error("stray '\\' in program");
1720 /* skip the stray and handle the \\n case. Output an error if
1721 incorrect char after the stray */
1722 static int handle_stray1(uint8_t *p)
1724 int c;
1726 if (p >= file->buf_end) {
1727 file->buf_ptr = p;
1728 c = handle_eob();
1729 p = file->buf_ptr;
1730 if (c == '\\')
1731 goto parse_stray;
1732 } else {
1733 parse_stray:
1734 file->buf_ptr = p;
1735 ch = *p;
1736 handle_stray();
1737 p = file->buf_ptr;
1738 c = *p;
1740 return c;
1743 /* handle just the EOB case, but not stray */
1744 #define PEEKC_EOB(c, p)\
1746 p++;\
1747 c = *p;\
1748 if (c == '\\') {\
1749 file->buf_ptr = p;\
1750 c = handle_eob();\
1751 p = file->buf_ptr;\
1755 /* handle the complicated stray case */
1756 #define PEEKC(c, p)\
1758 p++;\
1759 c = *p;\
1760 if (c == '\\') {\
1761 c = handle_stray1(p);\
1762 p = file->buf_ptr;\
1766 /* input with '\[\r]\n' handling. Note that this function cannot
1767 handle other characters after '\', so you cannot call it inside
1768 strings or comments */
1769 static void minp(void)
1771 inp();
1772 if (ch == '\\')
1773 handle_stray();
1777 /* single line C++ comments */
1778 static uint8_t *parse_line_comment(uint8_t *p)
1780 int c;
1782 p++;
1783 for(;;) {
1784 c = *p;
1785 if (c == '\n' || c == CH_EOF) {
1786 break;
1787 } else if (c == '\\') {
1788 PEEKC_EOB(c, p);
1789 if (c == '\n') {
1790 file->line_num++;
1791 PEEKC_EOB(c, p);
1792 } else if (c == '\r') {
1793 PEEKC_EOB(c, p);
1794 if (c == '\n') {
1795 file->line_num++;
1796 PEEKC_EOB(c, p);
1799 } else {
1800 p++;
1803 return p;
1806 /* C comments */
1807 static uint8_t *parse_comment(uint8_t *p)
1809 int c;
1811 p++;
1812 for(;;) {
1813 /* fast skip loop */
1814 for(;;) {
1815 c = *p;
1816 if (c == '\n' || c == '*' || c == '\\')
1817 break;
1818 p++;
1819 c = *p;
1820 if (c == '\n' || c == '*' || c == '\\')
1821 break;
1822 p++;
1824 /* now we can handle all the cases */
1825 if (c == '\n') {
1826 file->line_num++;
1827 p++;
1828 } else if (c == '*') {
1829 p++;
1830 for(;;) {
1831 c = *p;
1832 if (c == '*') {
1833 p++;
1834 } else if (c == '/') {
1835 goto end_of_comment;
1836 } else if (c == '\\') {
1837 file->buf_ptr = p;
1838 c = handle_eob();
1839 p = file->buf_ptr;
1840 if (c == '\\') {
1841 /* skip '\[\r]\n', otherwise just skip the stray */
1842 while (c == '\\') {
1843 PEEKC_EOB(c, p);
1844 if (c == '\n') {
1845 file->line_num++;
1846 PEEKC_EOB(c, p);
1847 } else if (c == '\r') {
1848 PEEKC_EOB(c, p);
1849 if (c == '\n') {
1850 file->line_num++;
1851 PEEKC_EOB(c, p);
1853 } else {
1854 goto after_star;
1858 } else {
1859 break;
1862 after_star: ;
1863 } else {
1864 /* stray, eob or eof */
1865 file->buf_ptr = p;
1866 c = handle_eob();
1867 p = file->buf_ptr;
1868 if (c == CH_EOF) {
1869 error("unexpected end of file in comment");
1870 } else if (c == '\\') {
1871 p++;
1875 end_of_comment:
1876 p++;
1877 return p;
1880 #define cinp minp
1882 /* space exlcuding newline */
1883 static inline int is_space(int ch)
1885 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1888 static inline void skip_spaces(void)
1890 while (is_space(ch))
1891 cinp();
1894 /* parse a string without interpreting escapes */
1895 static uint8_t *parse_pp_string(uint8_t *p,
1896 int sep, CString *str)
1898 int c;
1899 p++;
1900 for(;;) {
1901 c = *p;
1902 if (c == sep) {
1903 break;
1904 } else if (c == '\\') {
1905 file->buf_ptr = p;
1906 c = handle_eob();
1907 p = file->buf_ptr;
1908 if (c == CH_EOF) {
1909 unterminated_string:
1910 /* XXX: indicate line number of start of string */
1911 error("missing terminating %c character", sep);
1912 } else if (c == '\\') {
1913 /* escape : just skip \[\r]\n */
1914 PEEKC_EOB(c, p);
1915 if (c == '\n') {
1916 file->line_num++;
1917 p++;
1918 } else if (c == '\r') {
1919 PEEKC_EOB(c, p);
1920 if (c != '\n')
1921 expect("'\n' after '\r'");
1922 file->line_num++;
1923 p++;
1924 } else if (c == CH_EOF) {
1925 goto unterminated_string;
1926 } else {
1927 if (str) {
1928 cstr_ccat(str, '\\');
1929 cstr_ccat(str, c);
1931 p++;
1934 } else if (c == '\n') {
1935 file->line_num++;
1936 goto add_char;
1937 } else if (c == '\r') {
1938 PEEKC_EOB(c, p);
1939 if (c != '\n') {
1940 cstr_ccat(str, '\r');
1941 } else {
1942 file->line_num++;
1943 goto add_char;
1945 } else {
1946 add_char:
1947 if (str)
1948 cstr_ccat(str, c);
1949 p++;
1952 p++;
1953 return p;
1956 /* skip block of text until #else, #elif or #endif. skip also pairs of
1957 #if/#endif */
1958 void preprocess_skip(void)
1960 int a, start_of_line, c;
1961 uint8_t *p;
1963 p = file->buf_ptr;
1964 start_of_line = 1;
1965 a = 0;
1966 for(;;) {
1967 redo_no_start:
1968 c = *p;
1969 switch(c) {
1970 case ' ':
1971 case '\t':
1972 case '\f':
1973 case '\v':
1974 case '\r':
1975 p++;
1976 goto redo_no_start;
1977 case '\n':
1978 start_of_line = 1;
1979 file->line_num++;
1980 p++;
1981 goto redo_no_start;
1982 case '\\':
1983 file->buf_ptr = p;
1984 c = handle_eob();
1985 if (c == CH_EOF) {
1986 expect("#endif");
1987 } else if (c == '\\') {
1988 /* XXX: incorrect: should not give an error */
1989 ch = file->buf_ptr[0];
1990 handle_stray();
1992 p = file->buf_ptr;
1993 goto redo_no_start;
1994 /* skip strings */
1995 case '\"':
1996 case '\'':
1997 p = parse_pp_string(p, c, NULL);
1998 break;
1999 /* skip comments */
2000 case '/':
2001 file->buf_ptr = p;
2002 ch = *p;
2003 minp();
2004 p = file->buf_ptr;
2005 if (ch == '*') {
2006 p = parse_comment(p);
2007 } else if (ch == '/') {
2008 p = parse_line_comment(p);
2010 break;
2012 case '#':
2013 p++;
2014 if (start_of_line) {
2015 file->buf_ptr = p;
2016 next_nomacro();
2017 p = file->buf_ptr;
2018 if (a == 0 &&
2019 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
2020 goto the_end;
2021 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
2022 a++;
2023 else if (tok == TOK_ENDIF)
2024 a--;
2026 break;
2027 default:
2028 p++;
2029 break;
2031 start_of_line = 0;
2033 the_end: ;
2034 file->buf_ptr = p;
2037 /* ParseState handling */
2039 /* XXX: currently, no include file info is stored. Thus, we cannot display
2040 accurate messages if the function or data definition spans multiple
2041 files */
2043 /* save current parse state in 's' */
2044 void save_parse_state(ParseState *s)
2046 s->line_num = file->line_num;
2047 s->macro_ptr = macro_ptr;
2048 s->tok = tok;
2049 s->tokc = tokc;
2052 /* restore parse state from 's' */
2053 void restore_parse_state(ParseState *s)
2055 file->line_num = s->line_num;
2056 macro_ptr = s->macro_ptr;
2057 tok = s->tok;
2058 tokc = s->tokc;
2061 /* return the number of additional 'ints' necessary to store the
2062 token */
2063 static inline int tok_ext_size(int t)
2065 switch(t) {
2066 /* 4 bytes */
2067 case TOK_CINT:
2068 case TOK_CUINT:
2069 case TOK_CCHAR:
2070 case TOK_LCHAR:
2071 case TOK_STR:
2072 case TOK_LSTR:
2073 case TOK_CFLOAT:
2074 case TOK_LINENUM:
2075 case TOK_PPNUM:
2076 return 1;
2077 case TOK_CDOUBLE:
2078 case TOK_CLLONG:
2079 case TOK_CULLONG:
2080 return 2;
2081 case TOK_CLDOUBLE:
2082 return LDOUBLE_SIZE / 4;
2083 default:
2084 return 0;
2088 /* token string handling */
2090 static inline void tok_str_new(TokenString *s)
2092 s->str = NULL;
2093 s->len = 0;
2094 s->allocated_len = 0;
2095 s->last_line_num = -1;
2098 static void tok_str_free(int *str)
2100 const int *p;
2101 CString *cstr;
2102 int t;
2104 p = str;
2105 for(;;) {
2106 t = *p;
2107 /* NOTE: we test zero separately so that GCC can generate a
2108 table for the following switch */
2109 if (t == 0)
2110 break;
2111 switch(t) {
2112 case TOK_CINT:
2113 case TOK_CUINT:
2114 case TOK_CCHAR:
2115 case TOK_LCHAR:
2116 case TOK_CFLOAT:
2117 case TOK_LINENUM:
2118 p += 2;
2119 break;
2120 case TOK_PPNUM:
2121 case TOK_STR:
2122 case TOK_LSTR:
2123 /* XXX: use a macro to be portable on 64 bit ? */
2124 cstr = (CString *)p[1];
2125 cstr_free(cstr);
2126 tcc_free(cstr);
2127 p += 2;
2128 break;
2129 case TOK_CDOUBLE:
2130 case TOK_CLLONG:
2131 case TOK_CULLONG:
2132 p += 3;
2133 break;
2134 case TOK_CLDOUBLE:
2135 p += 1 + (LDOUBLE_SIZE / 4);
2136 break;
2137 default:
2138 p++;
2139 break;
2142 tcc_free(str);
2145 static int *tok_str_realloc(TokenString *s)
2147 int *str, len;
2149 len = s->allocated_len + TOK_STR_ALLOC_INCR;
2150 str = tcc_realloc(s->str, len * sizeof(int));
2151 if (!str)
2152 error("memory full");
2153 s->allocated_len = len;
2154 s->str = str;
2155 return str;
2158 static void tok_str_add(TokenString *s, int t)
2160 int len, *str;
2162 len = s->len;
2163 str = s->str;
2164 if (len >= s->allocated_len)
2165 str = tok_str_realloc(s);
2166 str[len++] = t;
2167 s->len = len;
2170 static void tok_str_add2(TokenString *s, int t, CValue *cv)
2172 int len, *str;
2174 len = s->len;
2175 str = s->str;
2177 /* allocate space for worst case */
2178 if (len + TOK_MAX_SIZE > s->allocated_len)
2179 str = tok_str_realloc(s);
2180 str[len++] = t;
2181 switch(t) {
2182 case TOK_CINT:
2183 case TOK_CUINT:
2184 case TOK_CCHAR:
2185 case TOK_LCHAR:
2186 case TOK_CFLOAT:
2187 case TOK_LINENUM:
2188 str[len++] = cv->tab[0];
2189 break;
2190 case TOK_PPNUM:
2191 case TOK_STR:
2192 case TOK_LSTR:
2193 str[len++] = (int)cstr_dup(cv->cstr);
2194 break;
2195 case TOK_CDOUBLE:
2196 case TOK_CLLONG:
2197 case TOK_CULLONG:
2198 str[len++] = cv->tab[0];
2199 str[len++] = cv->tab[1];
2200 break;
2201 case TOK_CLDOUBLE:
2202 #if LDOUBLE_SIZE == 12
2203 str[len++] = cv->tab[0];
2204 str[len++] = cv->tab[1];
2205 str[len++] = cv->tab[2];
2206 #else
2207 #error add long double size support
2208 #endif
2209 break;
2210 default:
2211 break;
2213 s->len = len;
2216 /* add the current parse token in token string 's' */
2217 static void tok_str_add_tok(TokenString *s)
2219 CValue cval;
2221 /* save line number info */
2222 if (file->line_num != s->last_line_num) {
2223 s->last_line_num = file->line_num;
2224 cval.i = s->last_line_num;
2225 tok_str_add2(s, TOK_LINENUM, &cval);
2227 tok_str_add2(s, tok, &tokc);
2230 #if LDOUBLE_SIZE == 12
2231 #define LDOUBLE_GET(p, cv) \
2232 cv.tab[0] = p[0]; \
2233 cv.tab[1] = p[1]; \
2234 cv.tab[2] = p[2];
2235 #else
2236 #error add long double size support
2237 #endif
2240 /* get a token from an integer array and increment pointer
2241 accordingly. we code it as a macro to avoid pointer aliasing. */
2242 #define TOK_GET(t, p, cv) \
2244 t = *p++; \
2245 switch(t) { \
2246 case TOK_CINT: \
2247 case TOK_CUINT: \
2248 case TOK_CCHAR: \
2249 case TOK_LCHAR: \
2250 case TOK_CFLOAT: \
2251 case TOK_LINENUM: \
2252 case TOK_STR: \
2253 case TOK_LSTR: \
2254 case TOK_PPNUM: \
2255 cv.tab[0] = *p++; \
2256 break; \
2257 case TOK_CDOUBLE: \
2258 case TOK_CLLONG: \
2259 case TOK_CULLONG: \
2260 cv.tab[0] = p[0]; \
2261 cv.tab[1] = p[1]; \
2262 p += 2; \
2263 break; \
2264 case TOK_CLDOUBLE: \
2265 LDOUBLE_GET(p, cv); \
2266 p += LDOUBLE_SIZE / 4; \
2267 break; \
2268 default: \
2269 break; \
2273 /* defines handling */
2274 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
2276 Sym *s;
2278 s = sym_push2(&define_stack, v, macro_type, (int)str);
2279 s->next = first_arg;
2280 table_ident[v - TOK_IDENT]->sym_define = s;
2283 /* undefined a define symbol. Its name is just set to zero */
2284 static void define_undef(Sym *s)
2286 int v;
2287 v = s->v;
2288 if (v >= TOK_IDENT && v < tok_ident)
2289 table_ident[v - TOK_IDENT]->sym_define = NULL;
2290 s->v = 0;
2293 static inline Sym *define_find(int v)
2295 v -= TOK_IDENT;
2296 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2297 return NULL;
2298 return table_ident[v]->sym_define;
2301 /* free define stack until top reaches 'b' */
2302 static void free_defines(Sym *b)
2304 Sym *top, *top1;
2305 int v;
2307 top = define_stack;
2308 while (top != b) {
2309 top1 = top->prev;
2310 /* do not free args or predefined defines */
2311 if (top->c)
2312 tok_str_free((int *)top->c);
2313 v = top->v;
2314 if (v >= TOK_IDENT && v < tok_ident)
2315 table_ident[v - TOK_IDENT]->sym_define = NULL;
2316 tcc_free(top);
2317 top = top1;
2319 define_stack = b;
2322 /* label lookup */
2323 static Sym *label_find(int v)
2325 v -= TOK_IDENT;
2326 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2327 return NULL;
2328 return table_ident[v]->sym_label;
2331 static Sym *label_push(Sym **ptop, int v, int flags)
2333 Sym *s, **ps;
2334 s = sym_push2(ptop, v, 0, 0);
2335 s->r = flags;
2336 ps = &table_ident[v - TOK_IDENT]->sym_label;
2337 if (ptop == &global_label_stack) {
2338 /* modify the top most local identifier, so that
2339 sym_identifier will point to 's' when popped */
2340 while (*ps != NULL)
2341 ps = &(*ps)->prev_tok;
2343 s->prev_tok = *ps;
2344 *ps = s;
2345 return s;
2348 /* pop labels until element last is reached. Look if any labels are
2349 undefined. Define symbols if '&&label' was used. */
2350 static void label_pop(Sym **ptop, Sym *slast)
2352 Sym *s, *s1;
2353 for(s = *ptop; s != slast; s = s1) {
2354 s1 = s->prev;
2355 if (s->r == LABEL_DECLARED) {
2356 warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
2357 } else if (s->r == LABEL_FORWARD) {
2358 error("label '%s' used but not defined",
2359 get_tok_str(s->v, NULL));
2360 } else {
2361 if (s->c) {
2362 /* define corresponding symbol. A size of
2363 1 is put. */
2364 put_extern_sym(s, cur_text_section, (long)s->next, 1);
2367 /* remove label */
2368 table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
2369 tcc_free(s);
2371 *ptop = slast;
2374 /* eval an expression for #if/#elif */
2375 static int expr_preprocess(void)
2377 int c, t;
2378 TokenString str;
2380 tok_str_new(&str);
2381 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2382 next(); /* do macro subst */
2383 if (tok == TOK_DEFINED) {
2384 next_nomacro();
2385 t = tok;
2386 if (t == '(')
2387 next_nomacro();
2388 c = define_find(tok) != 0;
2389 if (t == '(')
2390 next_nomacro();
2391 tok = TOK_CINT;
2392 tokc.i = c;
2393 } else if (tok >= TOK_IDENT) {
2394 /* if undefined macro */
2395 tok = TOK_CINT;
2396 tokc.i = 0;
2398 tok_str_add_tok(&str);
2400 tok_str_add(&str, -1); /* simulate end of file */
2401 tok_str_add(&str, 0);
2402 /* now evaluate C constant expression */
2403 macro_ptr = str.str;
2404 next();
2405 c = expr_const();
2406 macro_ptr = NULL;
2407 tok_str_free(str.str);
2408 return c != 0;
2411 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2412 static void tok_print(int *str)
2414 int t;
2415 CValue cval;
2417 while (1) {
2418 TOK_GET(t, str, cval);
2419 if (!t)
2420 break;
2421 printf(" %s", get_tok_str(t, &cval));
2423 printf("\n");
2425 #endif
2427 /* parse after #define */
2428 static void parse_define(void)
2430 Sym *s, *first, **ps;
2431 int v, t, varg, is_vaargs, c;
2432 TokenString str;
2434 v = tok;
2435 if (v < TOK_IDENT)
2436 error("invalid macro name '%s'", get_tok_str(tok, &tokc));
2437 /* XXX: should check if same macro (ANSI) */
2438 first = NULL;
2439 t = MACRO_OBJ;
2440 /* '(' must be just after macro definition for MACRO_FUNC */
2441 c = file->buf_ptr[0];
2442 if (c == '\\')
2443 c = handle_stray1(file->buf_ptr);
2444 if (c == '(') {
2445 next_nomacro();
2446 next_nomacro();
2447 ps = &first;
2448 while (tok != ')') {
2449 varg = tok;
2450 next_nomacro();
2451 is_vaargs = 0;
2452 if (varg == TOK_DOTS) {
2453 varg = TOK___VA_ARGS__;
2454 is_vaargs = 1;
2455 } else if (tok == TOK_DOTS && gnu_ext) {
2456 is_vaargs = 1;
2457 next_nomacro();
2459 if (varg < TOK_IDENT)
2460 error("badly punctuated parameter list");
2461 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
2462 *ps = s;
2463 ps = &s->next;
2464 if (tok != ',')
2465 break;
2466 next_nomacro();
2468 t = MACRO_FUNC;
2470 tok_str_new(&str);
2471 next_nomacro();
2472 /* EOF testing necessary for '-D' handling */
2473 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2474 tok_str_add2(&str, tok, &tokc);
2475 next_nomacro();
2477 tok_str_add(&str, 0);
2478 #ifdef PP_DEBUG
2479 printf("define %s %d: ", get_tok_str(v, NULL), t);
2480 tok_print(str.str);
2481 #endif
2482 define_push(v, t, str.str, first);
2485 /* XXX: use a token or a hash table to accelerate matching ? */
2486 static CachedInclude *search_cached_include(TCCState *s1,
2487 int type, const char *filename)
2489 CachedInclude *e;
2490 int i;
2492 for(i = 0;i < s1->nb_cached_includes; i++) {
2493 e = s1->cached_includes[i];
2494 if (e->type == type && !strcmp(e->filename, filename))
2495 return e;
2497 return NULL;
2500 static inline void add_cached_include(TCCState *s1, int type,
2501 const char *filename, int ifndef_macro)
2503 CachedInclude *e;
2505 if (search_cached_include(s1, type, filename))
2506 return;
2507 #ifdef INC_DEBUG
2508 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
2509 #endif
2510 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
2511 if (!e)
2512 return;
2513 e->type = type;
2514 strcpy(e->filename, filename);
2515 e->ifndef_macro = ifndef_macro;
2516 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
2519 /* is_bof is true if first non space token at beginning of file */
2520 static void preprocess(int is_bof)
2522 TCCState *s1 = tcc_state;
2523 int size, i, c, n, saved_parse_flags;
2524 char buf[1024], *q, *p;
2525 char buf1[1024];
2526 BufferedFile *f;
2527 Sym *s;
2528 CachedInclude *e;
2530 saved_parse_flags = parse_flags;
2531 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
2532 PARSE_FLAG_LINEFEED;
2533 next_nomacro();
2534 redo:
2535 switch(tok) {
2536 case TOK_DEFINE:
2537 next_nomacro();
2538 parse_define();
2539 break;
2540 case TOK_UNDEF:
2541 next_nomacro();
2542 s = define_find(tok);
2543 /* undefine symbol by putting an invalid name */
2544 if (s)
2545 define_undef(s);
2546 break;
2547 case TOK_INCLUDE:
2548 ch = file->buf_ptr[0];
2549 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2550 skip_spaces();
2551 if (ch == '<') {
2552 c = '>';
2553 goto read_name;
2554 } else if (ch == '\"') {
2555 c = ch;
2556 read_name:
2557 /* XXX: better stray handling */
2558 minp();
2559 q = buf;
2560 while (ch != c && ch != '\n' && ch != CH_EOF) {
2561 if ((q - buf) < sizeof(buf) - 1)
2562 *q++ = ch;
2563 minp();
2565 *q = '\0';
2566 minp();
2567 #if 0
2568 /* eat all spaces and comments after include */
2569 /* XXX: slightly incorrect */
2570 while (ch1 != '\n' && ch1 != CH_EOF)
2571 inp();
2572 #endif
2573 } else {
2574 /* computed #include : either we have only strings or
2575 we have anything enclosed in '<>' */
2576 next();
2577 buf[0] = '\0';
2578 if (tok == TOK_STR) {
2579 while (tok != TOK_LINEFEED) {
2580 if (tok != TOK_STR) {
2581 include_syntax:
2582 error("'#include' expects \"FILENAME\" or <FILENAME>");
2584 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2585 next();
2587 c = '\"';
2588 } else {
2589 int len;
2590 while (tok != TOK_LINEFEED) {
2591 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2592 next();
2594 len = strlen(buf);
2595 /* check syntax and remove '<>' */
2596 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2597 goto include_syntax;
2598 memmove(buf, buf + 1, len - 2);
2599 buf[len - 2] = '\0';
2600 c = '>';
2604 e = search_cached_include(s1, c, buf);
2605 if (e && define_find(e->ifndef_macro)) {
2606 /* no need to parse the include because the 'ifndef macro'
2607 is defined */
2608 #ifdef INC_DEBUG
2609 printf("%s: skipping %s\n", file->filename, buf);
2610 #endif
2611 } else {
2612 if (c == '\"') {
2613 /* first search in current dir if "header.h" */
2614 size = 0;
2615 p = strrchr(file->filename, '/');
2616 if (p)
2617 size = p + 1 - file->filename;
2618 if (size > sizeof(buf1) - 1)
2619 size = sizeof(buf1) - 1;
2620 memcpy(buf1, file->filename, size);
2621 buf1[size] = '\0';
2622 pstrcat(buf1, sizeof(buf1), buf);
2623 f = tcc_open(s1, buf1);
2624 if (f)
2625 goto found;
2627 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2628 error("#include recursion too deep");
2629 /* now search in all the include paths */
2630 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2631 for(i = 0; i < n; i++) {
2632 const char *path;
2633 if (i < s1->nb_include_paths)
2634 path = s1->include_paths[i];
2635 else
2636 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2637 pstrcpy(buf1, sizeof(buf1), path);
2638 pstrcat(buf1, sizeof(buf1), "/");
2639 pstrcat(buf1, sizeof(buf1), buf);
2640 f = tcc_open(s1, buf1);
2641 if (f)
2642 goto found;
2644 error("include file '%s' not found", buf);
2645 f = NULL;
2646 found:
2647 #ifdef INC_DEBUG
2648 printf("%s: including %s\n", file->filename, buf1);
2649 #endif
2650 f->inc_type = c;
2651 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2652 /* push current file in stack */
2653 /* XXX: fix current line init */
2654 *s1->include_stack_ptr++ = file;
2655 file = f;
2656 /* add include file debug info */
2657 if (do_debug) {
2658 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2660 tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
2661 ch = file->buf_ptr[0];
2662 goto the_end;
2664 break;
2665 case TOK_IFNDEF:
2666 c = 1;
2667 goto do_ifdef;
2668 case TOK_IF:
2669 c = expr_preprocess();
2670 goto do_if;
2671 case TOK_IFDEF:
2672 c = 0;
2673 do_ifdef:
2674 next_nomacro();
2675 if (tok < TOK_IDENT)
2676 error("invalid argument for '#if%sdef'", c ? "n" : "");
2677 if (is_bof) {
2678 if (c) {
2679 #ifdef INC_DEBUG
2680 printf("#ifndef %s\n", get_tok_str(tok, NULL));
2681 #endif
2682 file->ifndef_macro = tok;
2685 c = (define_find(tok) != 0) ^ c;
2686 do_if:
2687 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2688 error("memory full");
2689 *s1->ifdef_stack_ptr++ = c;
2690 goto test_skip;
2691 case TOK_ELSE:
2692 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2693 error("#else without matching #if");
2694 if (s1->ifdef_stack_ptr[-1] & 2)
2695 error("#else after #else");
2696 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2697 goto test_skip;
2698 case TOK_ELIF:
2699 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2700 error("#elif without matching #if");
2701 c = s1->ifdef_stack_ptr[-1];
2702 if (c > 1)
2703 error("#elif after #else");
2704 /* last #if/#elif expression was true: we skip */
2705 if (c == 1)
2706 goto skip;
2707 c = expr_preprocess();
2708 s1->ifdef_stack_ptr[-1] = c;
2709 test_skip:
2710 if (!(c & 1)) {
2711 skip:
2712 preprocess_skip();
2713 is_bof = 0;
2714 goto redo;
2716 break;
2717 case TOK_ENDIF:
2718 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2719 error("#endif without matching #if");
2720 s1->ifdef_stack_ptr--;
2721 /* '#ifndef macro' was at the start of file. Now we check if
2722 an '#endif' is exactly at the end of file */
2723 if (file->ifndef_macro &&
2724 s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
2725 file->ifndef_macro_saved = file->ifndef_macro;
2726 /* need to set to zero to avoid false matches if another
2727 #ifndef at middle of file */
2728 file->ifndef_macro = 0;
2729 while (tok != TOK_LINEFEED)
2730 next_nomacro();
2731 tok_flags |= TOK_FLAG_ENDIF;
2732 goto the_end;
2734 break;
2735 case TOK_LINE:
2736 next();
2737 if (tok != TOK_CINT)
2738 error("#line");
2739 file->line_num = tokc.i - 1; /* the line number will be incremented after */
2740 next();
2741 if (tok != TOK_LINEFEED) {
2742 if (tok != TOK_STR)
2743 error("#line");
2744 pstrcpy(file->filename, sizeof(file->filename),
2745 (char *)tokc.cstr->data);
2747 break;
2748 case TOK_ERROR:
2749 case TOK_WARNING:
2750 c = tok;
2751 ch = file->buf_ptr[0];
2752 skip_spaces();
2753 q = buf;
2754 while (ch != '\n' && ch != CH_EOF) {
2755 if ((q - buf) < sizeof(buf) - 1)
2756 *q++ = ch;
2757 minp();
2759 *q = '\0';
2760 if (c == TOK_ERROR)
2761 error("#error %s", buf);
2762 else
2763 warning("#warning %s", buf);
2764 break;
2765 case TOK_PRAGMA:
2766 /* ignored */
2767 break;
2768 default:
2769 if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
2770 /* '!' is ignored to allow C scripts. numbers are ignored
2771 to emulate cpp behaviour */
2772 } else {
2773 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
2775 break;
2777 /* ignore other preprocess commands or #! for C scripts */
2778 while (tok != TOK_LINEFEED)
2779 next_nomacro();
2780 the_end:
2781 parse_flags = saved_parse_flags;
2784 /* evaluate escape codes in a string. */
2785 static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
2787 int c, n;
2788 const char *p;
2790 p = buf;
2791 for(;;) {
2792 c = *p;
2793 if (c == '\0')
2794 break;
2795 if (c == '\\') {
2796 p++;
2797 /* escape */
2798 c = *p;
2799 switch(c) {
2800 case '0': case '1': case '2': case '3':
2801 case '4': case '5': case '6': case '7':
2802 /* at most three octal digits */
2803 n = c - '0';
2804 p++;
2805 c = *p;
2806 if (isoct(c)) {
2807 n = n * 8 + c - '0';
2808 p++;
2809 c = *p;
2810 if (isoct(c)) {
2811 n = n * 8 + c - '0';
2812 p++;
2815 c = n;
2816 goto add_char_nonext;
2817 case 'x':
2818 p++;
2819 n = 0;
2820 for(;;) {
2821 c = *p;
2822 if (c >= 'a' && c <= 'f')
2823 c = c - 'a' + 10;
2824 else if (c >= 'A' && c <= 'F')
2825 c = c - 'A' + 10;
2826 else if (isnum(c))
2827 c = c - '0';
2828 else
2829 break;
2830 n = n * 16 + c;
2831 p++;
2833 c = n;
2834 goto add_char_nonext;
2835 case 'a':
2836 c = '\a';
2837 break;
2838 case 'b':
2839 c = '\b';
2840 break;
2841 case 'f':
2842 c = '\f';
2843 break;
2844 case 'n':
2845 c = '\n';
2846 break;
2847 case 'r':
2848 c = '\r';
2849 break;
2850 case 't':
2851 c = '\t';
2852 break;
2853 case 'v':
2854 c = '\v';
2855 break;
2856 case 'e':
2857 if (!gnu_ext)
2858 goto invalid_escape;
2859 c = 27;
2860 break;
2861 case '\'':
2862 case '\"':
2863 case '\\':
2864 case '?':
2865 break;
2866 default:
2867 invalid_escape:
2868 error("invalid escaped char");
2871 p++;
2872 add_char_nonext:
2873 if (!is_long)
2874 cstr_ccat(outstr, c);
2875 else
2876 cstr_wccat(outstr, c);
2878 /* add a trailing '\0' */
2879 if (!is_long)
2880 cstr_ccat(outstr, '\0');
2881 else
2882 cstr_wccat(outstr, '\0');
2885 /* we use 64 bit numbers */
2886 #define BN_SIZE 2
2888 /* bn = (bn << shift) | or_val */
2889 void bn_lshift(unsigned int *bn, int shift, int or_val)
2891 int i;
2892 unsigned int v;
2893 for(i=0;i<BN_SIZE;i++) {
2894 v = bn[i];
2895 bn[i] = (v << shift) | or_val;
2896 or_val = v >> (32 - shift);
2900 void bn_zero(unsigned int *bn)
2902 int i;
2903 for(i=0;i<BN_SIZE;i++) {
2904 bn[i] = 0;
2908 /* parse number in null terminated string 'p' and return it in the
2909 current token */
2910 void parse_number(const char *p)
2912 int b, t, shift, frac_bits, s, exp_val, ch;
2913 char *q;
2914 unsigned int bn[BN_SIZE];
2915 double d;
2917 /* number */
2918 q = token_buf;
2919 ch = *p++;
2920 t = ch;
2921 ch = *p++;
2922 *q++ = t;
2923 b = 10;
2924 if (t == '.') {
2925 goto float_frac_parse;
2926 } else if (t == '0') {
2927 if (ch == 'x' || ch == 'X') {
2928 q--;
2929 ch = *p++;
2930 b = 16;
2931 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2932 q--;
2933 ch = *p++;
2934 b = 2;
2937 /* parse all digits. cannot check octal numbers at this stage
2938 because of floating point constants */
2939 while (1) {
2940 if (ch >= 'a' && ch <= 'f')
2941 t = ch - 'a' + 10;
2942 else if (ch >= 'A' && ch <= 'F')
2943 t = ch - 'A' + 10;
2944 else if (isnum(ch))
2945 t = ch - '0';
2946 else
2947 break;
2948 if (t >= b)
2949 break;
2950 if (q >= token_buf + STRING_MAX_SIZE) {
2951 num_too_long:
2952 error("number too long");
2954 *q++ = ch;
2955 ch = *p++;
2957 if (ch == '.' ||
2958 ((ch == 'e' || ch == 'E') && b == 10) ||
2959 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2960 if (b != 10) {
2961 /* NOTE: strtox should support that for hexa numbers, but
2962 non ISOC99 libcs do not support it, so we prefer to do
2963 it by hand */
2964 /* hexadecimal or binary floats */
2965 /* XXX: handle overflows */
2966 *q = '\0';
2967 if (b == 16)
2968 shift = 4;
2969 else
2970 shift = 2;
2971 bn_zero(bn);
2972 q = token_buf;
2973 while (1) {
2974 t = *q++;
2975 if (t == '\0') {
2976 break;
2977 } else if (t >= 'a') {
2978 t = t - 'a' + 10;
2979 } else if (t >= 'A') {
2980 t = t - 'A' + 10;
2981 } else {
2982 t = t - '0';
2984 bn_lshift(bn, shift, t);
2986 frac_bits = 0;
2987 if (ch == '.') {
2988 ch = *p++;
2989 while (1) {
2990 t = ch;
2991 if (t >= 'a' && t <= 'f') {
2992 t = t - 'a' + 10;
2993 } else if (t >= 'A' && t <= 'F') {
2994 t = t - 'A' + 10;
2995 } else if (t >= '0' && t <= '9') {
2996 t = t - '0';
2997 } else {
2998 break;
3000 if (t >= b)
3001 error("invalid digit");
3002 bn_lshift(bn, shift, t);
3003 frac_bits += shift;
3004 ch = *p++;
3007 if (ch != 'p' && ch != 'P')
3008 expect("exponent");
3009 ch = *p++;
3010 s = 1;
3011 exp_val = 0;
3012 if (ch == '+') {
3013 ch = *p++;
3014 } else if (ch == '-') {
3015 s = -1;
3016 ch = *p++;
3018 if (ch < '0' || ch > '9')
3019 expect("exponent digits");
3020 while (ch >= '0' && ch <= '9') {
3021 exp_val = exp_val * 10 + ch - '0';
3022 ch = *p++;
3024 exp_val = exp_val * s;
3026 /* now we can generate the number */
3027 /* XXX: should patch directly float number */
3028 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
3029 d = ldexp(d, exp_val - frac_bits);
3030 t = toup(ch);
3031 if (t == 'F') {
3032 ch = *p++;
3033 tok = TOK_CFLOAT;
3034 /* float : should handle overflow */
3035 tokc.f = (float)d;
3036 } else if (t == 'L') {
3037 ch = *p++;
3038 tok = TOK_CLDOUBLE;
3039 /* XXX: not large enough */
3040 tokc.ld = (long double)d;
3041 } else {
3042 tok = TOK_CDOUBLE;
3043 tokc.d = d;
3045 } else {
3046 /* decimal floats */
3047 if (ch == '.') {
3048 if (q >= token_buf + STRING_MAX_SIZE)
3049 goto num_too_long;
3050 *q++ = ch;
3051 ch = *p++;
3052 float_frac_parse:
3053 while (ch >= '0' && ch <= '9') {
3054 if (q >= token_buf + STRING_MAX_SIZE)
3055 goto num_too_long;
3056 *q++ = ch;
3057 ch = *p++;
3060 if (ch == 'e' || ch == 'E') {
3061 if (q >= token_buf + STRING_MAX_SIZE)
3062 goto num_too_long;
3063 *q++ = ch;
3064 ch = *p++;
3065 if (ch == '-' || ch == '+') {
3066 if (q >= token_buf + STRING_MAX_SIZE)
3067 goto num_too_long;
3068 *q++ = ch;
3069 ch = *p++;
3071 if (ch < '0' || ch > '9')
3072 expect("exponent digits");
3073 while (ch >= '0' && ch <= '9') {
3074 if (q >= token_buf + STRING_MAX_SIZE)
3075 goto num_too_long;
3076 *q++ = ch;
3077 ch = *p++;
3080 *q = '\0';
3081 t = toup(ch);
3082 errno = 0;
3083 if (t == 'F') {
3084 ch = *p++;
3085 tok = TOK_CFLOAT;
3086 tokc.f = strtof(token_buf, NULL);
3087 } else if (t == 'L') {
3088 ch = *p++;
3089 tok = TOK_CLDOUBLE;
3090 tokc.ld = strtold(token_buf, NULL);
3091 } else {
3092 tok = TOK_CDOUBLE;
3093 tokc.d = strtod(token_buf, NULL);
3096 } else {
3097 unsigned long long n, n1;
3098 int lcount, ucount;
3100 /* integer number */
3101 *q = '\0';
3102 q = token_buf;
3103 if (b == 10 && *q == '0') {
3104 b = 8;
3105 q++;
3107 n = 0;
3108 while(1) {
3109 t = *q++;
3110 /* no need for checks except for base 10 / 8 errors */
3111 if (t == '\0') {
3112 break;
3113 } else if (t >= 'a') {
3114 t = t - 'a' + 10;
3115 } else if (t >= 'A') {
3116 t = t - 'A' + 10;
3117 } else {
3118 t = t - '0';
3119 if (t >= b)
3120 error("invalid digit");
3122 n1 = n;
3123 n = n * b + t;
3124 /* detect overflow */
3125 /* XXX: this test is not reliable */
3126 if (n < n1)
3127 error("integer constant overflow");
3130 /* XXX: not exactly ANSI compliant */
3131 if ((n & 0xffffffff00000000LL) != 0) {
3132 if ((n >> 63) != 0)
3133 tok = TOK_CULLONG;
3134 else
3135 tok = TOK_CLLONG;
3136 } else if (n > 0x7fffffff) {
3137 tok = TOK_CUINT;
3138 } else {
3139 tok = TOK_CINT;
3141 lcount = 0;
3142 ucount = 0;
3143 for(;;) {
3144 t = toup(ch);
3145 if (t == 'L') {
3146 if (lcount >= 2)
3147 error("three 'l's in integer constant");
3148 lcount++;
3149 if (lcount == 2) {
3150 if (tok == TOK_CINT)
3151 tok = TOK_CLLONG;
3152 else if (tok == TOK_CUINT)
3153 tok = TOK_CULLONG;
3155 ch = *p++;
3156 } else if (t == 'U') {
3157 if (ucount >= 1)
3158 error("two 'u's in integer constant");
3159 ucount++;
3160 if (tok == TOK_CINT)
3161 tok = TOK_CUINT;
3162 else if (tok == TOK_CLLONG)
3163 tok = TOK_CULLONG;
3164 ch = *p++;
3165 } else {
3166 break;
3169 if (tok == TOK_CINT || tok == TOK_CUINT)
3170 tokc.ui = n;
3171 else
3172 tokc.ull = n;
3177 #define PARSE2(c1, tok1, c2, tok2) \
3178 case c1: \
3179 PEEKC(c, p); \
3180 if (c == c2) { \
3181 p++; \
3182 tok = tok2; \
3183 } else { \
3184 tok = tok1; \
3186 break;
3188 /* return next token without macro substitution */
3189 static inline void next_nomacro1(void)
3191 int t, c, is_long;
3192 TokenSym *ts;
3193 uint8_t *p, *p1;
3194 unsigned int h;
3196 p = file->buf_ptr;
3197 redo_no_start:
3198 c = *p;
3199 switch(c) {
3200 case ' ':
3201 case '\t':
3202 case '\f':
3203 case '\v':
3204 case '\r':
3205 p++;
3206 goto redo_no_start;
3208 case '\\':
3209 /* first look if it is in fact an end of buffer */
3210 if (p >= file->buf_end) {
3211 file->buf_ptr = p;
3212 handle_eob();
3213 p = file->buf_ptr;
3214 if (p >= file->buf_end)
3215 goto parse_eof;
3216 else
3217 goto redo_no_start;
3218 } else {
3219 file->buf_ptr = p;
3220 ch = *p;
3221 handle_stray();
3222 p = file->buf_ptr;
3223 goto redo_no_start;
3225 parse_eof:
3227 TCCState *s1 = tcc_state;
3228 if (parse_flags & PARSE_FLAG_LINEFEED) {
3229 tok = TOK_LINEFEED;
3230 } else if (s1->include_stack_ptr == s1->include_stack ||
3231 !(parse_flags & PARSE_FLAG_PREPROCESS)) {
3232 /* no include left : end of file. */
3233 tok = TOK_EOF;
3234 } else {
3235 /* pop include file */
3237 /* test if previous '#endif' was after a #ifdef at
3238 start of file */
3239 if (tok_flags & TOK_FLAG_ENDIF) {
3240 #ifdef INC_DEBUG
3241 printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
3242 #endif
3243 add_cached_include(s1, file->inc_type, file->inc_filename,
3244 file->ifndef_macro_saved);
3247 /* add end of include file debug info */
3248 if (do_debug) {
3249 put_stabd(N_EINCL, 0, 0);
3251 /* pop include stack */
3252 tcc_close(file);
3253 s1->include_stack_ptr--;
3254 file = *s1->include_stack_ptr;
3255 p = file->buf_ptr;
3256 goto redo_no_start;
3259 break;
3261 case '\n':
3262 if (parse_flags & PARSE_FLAG_LINEFEED) {
3263 tok = TOK_LINEFEED;
3264 } else {
3265 file->line_num++;
3266 tok_flags |= TOK_FLAG_BOL;
3267 p++;
3268 goto redo_no_start;
3270 break;
3272 case '#':
3273 /* XXX: simplify */
3274 PEEKC(c, p);
3275 if ((tok_flags & TOK_FLAG_BOL) &&
3276 (parse_flags & PARSE_FLAG_PREPROCESS)) {
3277 file->buf_ptr = p;
3278 preprocess(tok_flags & TOK_FLAG_BOF);
3279 p = file->buf_ptr;
3280 goto redo_no_start;
3281 } else {
3282 if (c == '#') {
3283 p++;
3284 tok = TOK_TWOSHARPS;
3285 } else {
3286 tok = '#';
3289 break;
3291 case 'a': case 'b': case 'c': case 'd':
3292 case 'e': case 'f': case 'g': case 'h':
3293 case 'i': case 'j': case 'k': case 'l':
3294 case 'm': case 'n': case 'o': case 'p':
3295 case 'q': case 'r': case 's': case 't':
3296 case 'u': case 'v': case 'w': case 'x':
3297 case 'y': case 'z':
3298 case 'A': case 'B': case 'C': case 'D':
3299 case 'E': case 'F': case 'G': case 'H':
3300 case 'I': case 'J': case 'K':
3301 case 'M': case 'N': case 'O': case 'P':
3302 case 'Q': case 'R': case 'S': case 'T':
3303 case 'U': case 'V': case 'W': case 'X':
3304 case 'Y': case 'Z':
3305 case '_':
3306 parse_ident_fast:
3307 p1 = p;
3308 h = TOK_HASH_INIT;
3309 h = TOK_HASH_FUNC(h, c);
3310 p++;
3311 for(;;) {
3312 c = *p;
3313 if (!isidnum_table[c])
3314 break;
3315 h = TOK_HASH_FUNC(h, c);
3316 p++;
3318 if (c != '\\') {
3319 TokenSym **pts;
3320 int len;
3322 /* fast case : no stray found, so we have the full token
3323 and we have already hashed it */
3324 len = p - p1;
3325 h &= (TOK_HASH_SIZE - 1);
3326 pts = &hash_ident[h];
3327 for(;;) {
3328 ts = *pts;
3329 if (!ts)
3330 break;
3331 if (ts->len == len && !memcmp(ts->str, p1, len))
3332 goto token_found;
3333 pts = &(ts->hash_next);
3335 ts = tok_alloc_new(pts, p1, len);
3336 token_found: ;
3337 } else {
3338 /* slower case */
3339 cstr_reset(&tokcstr);
3341 while (p1 < p) {
3342 cstr_ccat(&tokcstr, *p1);
3343 p1++;
3345 p--;
3346 PEEKC(c, p);
3347 parse_ident_slow:
3348 while (isidnum_table[c]) {
3349 cstr_ccat(&tokcstr, c);
3350 PEEKC(c, p);
3352 ts = tok_alloc(tokcstr.data, tokcstr.size);
3354 tok = ts->tok;
3355 break;
3356 case 'L':
3357 t = p[1];
3358 if (t != '\\' && t != '\'' && t != '\"') {
3359 /* fast case */
3360 goto parse_ident_fast;
3361 } else {
3362 PEEKC(c, p);
3363 if (c == '\'' || c == '\"') {
3364 is_long = 1;
3365 goto str_const;
3366 } else {
3367 cstr_reset(&tokcstr);
3368 cstr_ccat(&tokcstr, 'L');
3369 goto parse_ident_slow;
3372 break;
3373 case '0': case '1': case '2': case '3':
3374 case '4': case '5': case '6': case '7':
3375 case '8': case '9':
3377 cstr_reset(&tokcstr);
3378 /* after the first digit, accept digits, alpha, '.' or sign if
3379 prefixed by 'eEpP' */
3380 parse_num:
3381 for(;;) {
3382 t = c;
3383 cstr_ccat(&tokcstr, c);
3384 PEEKC(c, p);
3385 if (!(isnum(c) || isid(c) || c == '.' ||
3386 ((c == '+' || c == '-') &&
3387 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
3388 break;
3390 /* We add a trailing '\0' to ease parsing */
3391 cstr_ccat(&tokcstr, '\0');
3392 tokc.cstr = &tokcstr;
3393 tok = TOK_PPNUM;
3394 break;
3395 case '.':
3396 /* special dot handling because it can also start a number */
3397 PEEKC(c, p);
3398 if (isnum(c)) {
3399 cstr_reset(&tokcstr);
3400 cstr_ccat(&tokcstr, '.');
3401 goto parse_num;
3402 } else if (c == '.') {
3403 PEEKC(c, p);
3404 if (c != '.')
3405 expect("'.'");
3406 PEEKC(c, p);
3407 tok = TOK_DOTS;
3408 } else {
3409 tok = '.';
3411 break;
3412 case '\'':
3413 case '\"':
3414 is_long = 0;
3415 str_const:
3417 CString str;
3418 int sep;
3420 sep = c;
3422 /* parse the string */
3423 cstr_new(&str);
3424 p = parse_pp_string(p, sep, &str);
3425 cstr_ccat(&str, '\0');
3427 /* eval the escape (should be done as TOK_PPNUM) */
3428 cstr_reset(&tokcstr);
3429 parse_escape_string(&tokcstr, str.data, is_long);
3430 cstr_free(&str);
3432 if (sep == '\'') {
3433 int char_size;
3434 /* XXX: make it portable */
3435 if (!is_long)
3436 char_size = 1;
3437 else
3438 char_size = sizeof(int);
3439 if (tokcstr.size <= char_size)
3440 error("empty character constant");
3441 if (tokcstr.size > 2 * char_size)
3442 warning("multi-character character constant");
3443 if (!is_long) {
3444 tokc.i = *(int8_t *)tokcstr.data;
3445 tok = TOK_CCHAR;
3446 } else {
3447 tokc.i = *(int *)tokcstr.data;
3448 tok = TOK_LCHAR;
3450 } else {
3451 tokc.cstr = &tokcstr;
3452 if (!is_long)
3453 tok = TOK_STR;
3454 else
3455 tok = TOK_LSTR;
3458 break;
3460 case '<':
3461 PEEKC(c, p);
3462 if (c == '=') {
3463 p++;
3464 tok = TOK_LE;
3465 } else if (c == '<') {
3466 PEEKC(c, p);
3467 if (c == '=') {
3468 p++;
3469 tok = TOK_A_SHL;
3470 } else {
3471 tok = TOK_SHL;
3473 } else {
3474 tok = TOK_LT;
3476 break;
3478 case '>':
3479 PEEKC(c, p);
3480 if (c == '=') {
3481 p++;
3482 tok = TOK_GE;
3483 } else if (c == '>') {
3484 PEEKC(c, p);
3485 if (c == '=') {
3486 p++;
3487 tok = TOK_A_SAR;
3488 } else {
3489 tok = TOK_SAR;
3491 } else {
3492 tok = TOK_GT;
3494 break;
3496 case '&':
3497 PEEKC(c, p);
3498 if (c == '&') {
3499 p++;
3500 tok = TOK_LAND;
3501 } else if (c == '=') {
3502 p++;
3503 tok = TOK_A_AND;
3504 } else {
3505 tok = '&';
3507 break;
3509 case '|':
3510 PEEKC(c, p);
3511 if (c == '|') {
3512 p++;
3513 tok = TOK_LOR;
3514 } else if (c == '=') {
3515 p++;
3516 tok = TOK_A_OR;
3517 } else {
3518 tok = '|';
3520 break;
3522 case '+':
3523 PEEKC(c, p);
3524 if (c == '+') {
3525 p++;
3526 tok = TOK_INC;
3527 } else if (c == '=') {
3528 p++;
3529 tok = TOK_A_ADD;
3530 } else {
3531 tok = '+';
3533 break;
3535 case '-':
3536 PEEKC(c, p);
3537 if (c == '-') {
3538 p++;
3539 tok = TOK_DEC;
3540 } else if (c == '=') {
3541 p++;
3542 tok = TOK_A_SUB;
3543 } else if (c == '>') {
3544 p++;
3545 tok = TOK_ARROW;
3546 } else {
3547 tok = '-';
3549 break;
3551 PARSE2('!', '!', '=', TOK_NE)
3552 PARSE2('=', '=', '=', TOK_EQ)
3553 PARSE2('*', '*', '=', TOK_A_MUL)
3554 PARSE2('%', '%', '=', TOK_A_MOD)
3555 PARSE2('^', '^', '=', TOK_A_XOR)
3557 /* comments or operator */
3558 case '/':
3559 PEEKC(c, p);
3560 if (c == '*') {
3561 p = parse_comment(p);
3562 goto redo_no_start;
3563 } else if (c == '/') {
3564 p = parse_line_comment(p);
3565 goto redo_no_start;
3566 } else if (c == '=') {
3567 p++;
3568 tok = TOK_A_DIV;
3569 } else {
3570 tok = '/';
3572 break;
3574 /* simple tokens */
3575 case '(':
3576 case ')':
3577 case '[':
3578 case ']':
3579 case '{':
3580 case '}':
3581 case ',':
3582 case ';':
3583 case ':':
3584 case '?':
3585 case '~':
3586 case '$': /* only used in assembler */
3587 tok = c;
3588 p++;
3589 break;
3590 default:
3591 error("unrecognized character \\x%02x", c);
3592 break;
3594 file->buf_ptr = p;
3595 tok_flags = 0;
3596 #if defined(PARSE_DEBUG)
3597 printf("token = %s\n", get_tok_str(tok, &tokc));
3598 #endif
3601 /* return next token without macro substitution. Can read input from
3602 macro_ptr buffer */
3603 static void next_nomacro(void)
3605 if (macro_ptr) {
3606 redo:
3607 tok = *macro_ptr;
3608 if (tok) {
3609 TOK_GET(tok, macro_ptr, tokc);
3610 if (tok == TOK_LINENUM) {
3611 file->line_num = tokc.i;
3612 goto redo;
3615 } else {
3616 next_nomacro1();
3620 /* substitute args in macro_str and return allocated string */
3621 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
3623 int *st, last_tok, t, notfirst;
3624 Sym *s;
3625 CValue cval;
3626 TokenString str;
3627 CString cstr;
3629 tok_str_new(&str);
3630 last_tok = 0;
3631 while(1) {
3632 TOK_GET(t, macro_str, cval);
3633 if (!t)
3634 break;
3635 if (t == '#') {
3636 /* stringize */
3637 TOK_GET(t, macro_str, cval);
3638 if (!t)
3639 break;
3640 s = sym_find2(args, t);
3641 if (s) {
3642 cstr_new(&cstr);
3643 st = (int *)s->c;
3644 notfirst = 0;
3645 while (*st) {
3646 if (notfirst)
3647 cstr_ccat(&cstr, ' ');
3648 TOK_GET(t, st, cval);
3649 cstr_cat(&cstr, get_tok_str(t, &cval));
3650 notfirst = 1;
3652 cstr_ccat(&cstr, '\0');
3653 #ifdef PP_DEBUG
3654 printf("stringize: %s\n", (char *)cstr.data);
3655 #endif
3656 /* add string */
3657 cval.cstr = &cstr;
3658 tok_str_add2(&str, TOK_STR, &cval);
3659 cstr_free(&cstr);
3660 } else {
3661 tok_str_add2(&str, t, &cval);
3663 } else if (t >= TOK_IDENT) {
3664 s = sym_find2(args, t);
3665 if (s) {
3666 st = (int *)s->c;
3667 /* if '##' is present before or after, no arg substitution */
3668 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
3669 /* special case for var arg macros : ## eats the
3670 ',' if empty VA_ARGS variable. */
3671 /* XXX: test of the ',' is not 100%
3672 reliable. should fix it to avoid security
3673 problems */
3674 if (gnu_ext && s->type.t &&
3675 last_tok == TOK_TWOSHARPS &&
3676 str.len >= 2 && str.str[str.len - 2] == ',') {
3677 if (*st == 0) {
3678 /* suppress ',' '##' */
3679 str.len -= 2;
3680 } else {
3681 /* suppress '##' and add variable */
3682 str.len--;
3683 goto add_var;
3685 } else {
3686 int t1;
3687 add_var:
3688 for(;;) {
3689 TOK_GET(t1, st, cval);
3690 if (!t1)
3691 break;
3692 tok_str_add2(&str, t1, &cval);
3695 } else {
3696 macro_subst(&str, nested_list, st);
3698 } else {
3699 tok_str_add(&str, t);
3701 } else {
3702 tok_str_add2(&str, t, &cval);
3704 last_tok = t;
3706 tok_str_add(&str, 0);
3707 return str.str;
3710 static char const ab_month_name[12][4] =
3712 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
3713 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
3716 /* do macro substitution of current token with macro 's' and add
3717 result to (tok_str,tok_len). 'nested_list' is the list of all
3718 macros we got inside to avoid recursing. Return non zero if no
3719 substitution needs to be done */
3720 static int macro_subst_tok(TokenString *tok_str,
3721 Sym **nested_list, Sym *s)
3723 Sym *args, *sa, *sa1;
3724 int mstr_allocated, parlevel, *mstr, t;
3725 TokenString str;
3726 char *cstrval;
3727 CValue cval;
3728 CString cstr;
3730 /* if symbol is a macro, prepare substitution */
3732 /* special macros */
3733 if (tok == TOK___LINE__) {
3734 cval.i = file->line_num;
3735 tok_str_add2(tok_str, TOK_CINT, &cval);
3736 } else if (tok == TOK___FILE__) {
3737 cstrval = file->filename;
3738 goto add_cstr;
3739 tok_str_add2(tok_str, TOK_STR, &cval);
3740 } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
3741 time_t ti;
3742 struct tm *tm;
3743 char buf[64];
3745 time(&ti);
3746 tm = localtime(&ti);
3747 if (tok == TOK___DATE__) {
3748 snprintf(buf, sizeof(buf), "%s %2d %d",
3749 ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
3750 } else {
3751 snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
3752 tm->tm_hour, tm->tm_min, tm->tm_sec);
3754 cstrval = buf;
3755 add_cstr:
3756 cstr_new(&cstr);
3757 cstr_cat(&cstr, cstrval);
3758 cstr_ccat(&cstr, '\0');
3759 cval.cstr = &cstr;
3760 tok_str_add2(tok_str, TOK_STR, &cval);
3761 cstr_free(&cstr);
3762 } else {
3763 mstr = (int *)s->c;
3764 mstr_allocated = 0;
3765 if (s->type.t == MACRO_FUNC) {
3766 /* NOTE: we do not use next_nomacro to avoid eating the
3767 next token. XXX: find better solution */
3768 if (macro_ptr) {
3769 t = *macro_ptr;
3770 if (t == 0) {
3771 /* end of macro stream: we must look at the token
3772 after in the file */
3773 macro_ptr = NULL;
3774 goto parse_stream;
3776 } else {
3777 parse_stream:
3778 /* XXX: incorrect with comments */
3779 ch = file->buf_ptr[0];
3780 while (is_space(ch) || ch == '\n')
3781 cinp();
3782 t = ch;
3784 if (t != '(') /* no macro subst */
3785 return -1;
3787 /* argument macro */
3788 next_nomacro();
3789 next_nomacro();
3790 args = NULL;
3791 sa = s->next;
3792 /* NOTE: empty args are allowed, except if no args */
3793 for(;;) {
3794 /* handle '()' case */
3795 if (!args && tok == ')')
3796 break;
3797 if (!sa)
3798 error("macro '%s' used with too many args",
3799 get_tok_str(s->v, 0));
3800 tok_str_new(&str);
3801 parlevel = 0;
3802 /* NOTE: non zero sa->t indicates VA_ARGS */
3803 while ((parlevel > 0 ||
3804 (tok != ')' &&
3805 (tok != ',' || sa->type.t))) &&
3806 tok != -1) {
3807 if (tok == '(')
3808 parlevel++;
3809 else if (tok == ')')
3810 parlevel--;
3811 tok_str_add2(&str, tok, &tokc);
3812 next_nomacro();
3814 tok_str_add(&str, 0);
3815 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str);
3816 sa = sa->next;
3817 if (tok == ')') {
3818 /* special case for gcc var args: add an empty
3819 var arg argument if it is omitted */
3820 if (sa && sa->type.t && gnu_ext)
3821 continue;
3822 else
3823 break;
3825 if (tok != ',')
3826 expect(",");
3827 next_nomacro();
3829 if (sa) {
3830 error("macro '%s' used with too few args",
3831 get_tok_str(s->v, 0));
3834 /* now subst each arg */
3835 mstr = macro_arg_subst(nested_list, mstr, args);
3836 /* free memory */
3837 sa = args;
3838 while (sa) {
3839 sa1 = sa->prev;
3840 tok_str_free((int *)sa->c);
3841 tcc_free(sa);
3842 sa = sa1;
3844 mstr_allocated = 1;
3846 sym_push2(nested_list, s->v, 0, 0);
3847 macro_subst(tok_str, nested_list, mstr);
3848 /* pop nested defined symbol */
3849 sa1 = *nested_list;
3850 *nested_list = sa1->prev;
3851 tcc_free(sa1);
3852 if (mstr_allocated)
3853 tok_str_free(mstr);
3855 return 0;
3858 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
3859 return the resulting string (which must be freed). */
3860 static inline int *macro_twosharps(const int *macro_str)
3862 TokenSym *ts;
3863 const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr;
3864 int t;
3865 const char *p1, *p2;
3866 CValue cval;
3867 TokenString macro_str1;
3868 CString cstr;
3870 start_macro_ptr = macro_str;
3871 /* we search the first '##' */
3872 for(;;) {
3873 macro_ptr1 = macro_str;
3874 TOK_GET(t, macro_str, cval);
3875 /* nothing more to do if end of string */
3876 if (t == 0)
3877 return NULL;
3878 if (*macro_str == TOK_TWOSHARPS)
3879 break;
3882 /* we saw '##', so we need more processing to handle it */
3883 cstr_new(&cstr);
3884 tok_str_new(&macro_str1);
3885 tok = t;
3886 tokc = cval;
3888 /* add all tokens seen so far */
3889 for(ptr = start_macro_ptr; ptr < macro_ptr1;) {
3890 TOK_GET(t, ptr, cval);
3891 tok_str_add2(&macro_str1, t, &cval);
3893 saved_macro_ptr = macro_ptr;
3894 /* XXX: get rid of the use of macro_ptr here */
3895 macro_ptr = (int *)macro_str;
3896 for(;;) {
3897 while (*macro_ptr == TOK_TWOSHARPS) {
3898 macro_ptr++;
3899 macro_ptr1 = macro_ptr;
3900 t = *macro_ptr;
3901 if (t) {
3902 TOK_GET(t, macro_ptr, cval);
3903 /* We concatenate the two tokens if we have an
3904 identifier or a preprocessing number */
3905 cstr_reset(&cstr);
3906 p1 = get_tok_str(tok, &tokc);
3907 cstr_cat(&cstr, p1);
3908 p2 = get_tok_str(t, &cval);
3909 cstr_cat(&cstr, p2);
3910 cstr_ccat(&cstr, '\0');
3912 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
3913 (t >= TOK_IDENT || t == TOK_PPNUM)) {
3914 if (tok == TOK_PPNUM) {
3915 /* if number, then create a number token */
3916 /* NOTE: no need to allocate because
3917 tok_str_add2() does it */
3918 tokc.cstr = &cstr;
3919 } else {
3920 /* if identifier, we must do a test to
3921 validate we have a correct identifier */
3922 if (t == TOK_PPNUM) {
3923 const char *p;
3924 int c;
3926 p = p2;
3927 for(;;) {
3928 c = *p;
3929 if (c == '\0')
3930 break;
3931 p++;
3932 if (!isnum(c) && !isid(c))
3933 goto error_pasting;
3936 ts = tok_alloc(cstr.data, strlen(cstr.data));
3937 tok = ts->tok; /* modify current token */
3939 } else {
3940 const char *str = cstr.data;
3941 const unsigned char *q;
3943 /* we look for a valid token */
3944 /* XXX: do more extensive checks */
3945 if (!strcmp(str, ">>=")) {
3946 tok = TOK_A_SAR;
3947 } else if (!strcmp(str, "<<=")) {
3948 tok = TOK_A_SHL;
3949 } else if (strlen(str) == 2) {
3950 /* search in two bytes table */
3951 q = tok_two_chars;
3952 for(;;) {
3953 if (!*q)
3954 goto error_pasting;
3955 if (q[0] == str[0] && q[1] == str[1])
3956 break;
3957 q += 3;
3959 tok = q[2];
3960 } else {
3961 error_pasting:
3962 /* NOTE: because get_tok_str use a static buffer,
3963 we must save it */
3964 cstr_reset(&cstr);
3965 p1 = get_tok_str(tok, &tokc);
3966 cstr_cat(&cstr, p1);
3967 cstr_ccat(&cstr, '\0');
3968 p2 = get_tok_str(t, &cval);
3969 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
3970 /* cannot merge tokens: just add them separately */
3971 tok_str_add2(&macro_str1, tok, &tokc);
3972 /* XXX: free associated memory ? */
3973 tok = t;
3974 tokc = cval;
3979 tok_str_add2(&macro_str1, tok, &tokc);
3980 next_nomacro();
3981 if (tok == 0)
3982 break;
3984 macro_ptr = (int *)saved_macro_ptr;
3985 cstr_free(&cstr);
3986 tok_str_add(&macro_str1, 0);
3987 return macro_str1.str;
3991 /* do macro substitution of macro_str and add result to
3992 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3993 inside to avoid recursing. */
3994 static void macro_subst(TokenString *tok_str,
3995 Sym **nested_list, const int *macro_str)
3997 Sym *s;
3998 int *saved_macro_ptr, *macro_str1;
3999 const int *ptr;
4000 int t, ret;
4001 CValue cval;
4003 /* first scan for '##' operator handling */
4004 ptr = macro_str;
4005 macro_str1 = macro_twosharps(ptr);
4006 if (macro_str1)
4007 ptr = macro_str1;
4008 while (1) {
4009 /* NOTE: ptr == NULL can only happen if tokens are read from
4010 file stream due to a macro function call */
4011 if (ptr == NULL)
4012 break;
4013 TOK_GET(t, ptr, cval);
4014 if (t == 0)
4015 break;
4016 s = define_find(t);
4017 if (s != NULL) {
4018 /* if nested substitution, do nothing */
4019 if (sym_find2(*nested_list, t))
4020 goto no_subst;
4021 saved_macro_ptr = macro_ptr;
4022 macro_ptr = (int *)ptr;
4023 tok = t;
4024 ret = macro_subst_tok(tok_str, nested_list, s);
4025 ptr = (int *)macro_ptr;
4026 macro_ptr = saved_macro_ptr;
4027 if (ret != 0)
4028 goto no_subst;
4029 } else {
4030 no_subst:
4031 tok_str_add2(tok_str, t, &cval);
4034 if (macro_str1)
4035 tok_str_free(macro_str1);
4038 /* return next token with macro substitution */
4039 static void next(void)
4041 Sym *nested_list, *s;
4042 TokenString str;
4044 redo:
4045 next_nomacro();
4046 if (!macro_ptr) {
4047 /* if not reading from macro substituted string, then try
4048 to substitute macros */
4049 if (tok >= TOK_IDENT &&
4050 (parse_flags & PARSE_FLAG_PREPROCESS)) {
4051 s = define_find(tok);
4052 if (s) {
4053 /* we have a macro: we try to substitute */
4054 tok_str_new(&str);
4055 nested_list = NULL;
4056 if (macro_subst_tok(&str, &nested_list, s) == 0) {
4057 /* substitution done, NOTE: maybe empty */
4058 tok_str_add(&str, 0);
4059 macro_ptr = str.str;
4060 macro_ptr_allocated = str.str;
4061 goto redo;
4065 } else {
4066 if (tok == 0) {
4067 /* end of macro or end of unget buffer */
4068 if (unget_buffer_enabled) {
4069 macro_ptr = unget_saved_macro_ptr;
4070 unget_buffer_enabled = 0;
4071 } else {
4072 /* end of macro string: free it */
4073 tok_str_free(macro_ptr_allocated);
4074 macro_ptr = NULL;
4076 goto redo;
4080 /* convert preprocessor tokens into C tokens */
4081 if (tok == TOK_PPNUM &&
4082 (parse_flags & PARSE_FLAG_TOK_NUM)) {
4083 parse_number((char *)tokc.cstr->data);
4087 /* push back current token and set current token to 'last_tok'. Only
4088 identifier case handled for labels. */
4089 static inline void unget_tok(int last_tok)
4091 int i, n;
4092 int *q;
4093 unget_saved_macro_ptr = macro_ptr;
4094 unget_buffer_enabled = 1;
4095 q = unget_saved_buffer;
4096 macro_ptr = q;
4097 *q++ = tok;
4098 n = tok_ext_size(tok) - 1;
4099 for(i=0;i<n;i++)
4100 *q++ = tokc.tab[i];
4101 *q = 0; /* end of token string */
4102 tok = last_tok;
4106 void swap(int *p, int *q)
4108 int t;
4109 t = *p;
4110 *p = *q;
4111 *q = t;
4114 void vsetc(CType *type, int r, CValue *vc)
4116 int v;
4118 if (vtop >= vstack + VSTACK_SIZE)
4119 error("memory full");
4120 /* cannot let cpu flags if other instruction are generated. Also
4121 avoid leaving VT_JMP anywhere except on the top of the stack
4122 because it would complicate the code generator. */
4123 if (vtop >= vstack) {
4124 v = vtop->r & VT_VALMASK;
4125 if (v == VT_CMP || (v & ~1) == VT_JMP)
4126 gv(RC_INT);
4128 vtop++;
4129 vtop->type = *type;
4130 vtop->r = r;
4131 vtop->r2 = VT_CONST;
4132 vtop->c = *vc;
4135 /* push integer constant */
4136 void vpushi(int v)
4138 CValue cval;
4139 cval.i = v;
4140 vsetc(&int_type, VT_CONST, &cval);
4143 /* Return a static symbol pointing to a section */
4144 static Sym *get_sym_ref(CType *type, Section *sec,
4145 unsigned long offset, unsigned long size)
4147 int v;
4148 Sym *sym;
4150 v = anon_sym++;
4151 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
4152 sym->type.ref = type->ref;
4153 sym->r = VT_CONST | VT_SYM;
4154 put_extern_sym(sym, sec, offset, size);
4155 return sym;
4158 /* push a reference to a section offset by adding a dummy symbol */
4159 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
4161 CValue cval;
4163 cval.ul = 0;
4164 vsetc(type, VT_CONST | VT_SYM, &cval);
4165 vtop->sym = get_sym_ref(type, sec, offset, size);
4168 /* define a new external reference to a symbol 'v' of type 'u' */
4169 static Sym *external_global_sym(int v, CType *type, int r)
4171 Sym *s;
4173 s = sym_find(v);
4174 if (!s) {
4175 /* push forward reference */
4176 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
4177 s->type.ref = type->ref;
4178 s->r = r | VT_CONST | VT_SYM;
4180 return s;
4183 /* define a new external reference to a symbol 'v' of type 'u' */
4184 static Sym *external_sym(int v, CType *type, int r)
4186 Sym *s;
4188 s = sym_find(v);
4189 if (!s) {
4190 /* push forward reference */
4191 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
4192 s->type.t |= VT_EXTERN;
4193 } else {
4194 if (!is_compatible_types(&s->type, type))
4195 error("incompatible types for redefinition of '%s'",
4196 get_tok_str(v, NULL));
4198 return s;
4201 /* push a reference to global symbol v */
4202 static void vpush_global_sym(CType *type, int v)
4204 Sym *sym;
4205 CValue cval;
4207 sym = external_global_sym(v, type, 0);
4208 cval.ul = 0;
4209 vsetc(type, VT_CONST | VT_SYM, &cval);
4210 vtop->sym = sym;
4213 void vset(CType *type, int r, int v)
4215 CValue cval;
4217 cval.i = v;
4218 vsetc(type, r, &cval);
4221 void vseti(int r, int v)
4223 CType type;
4224 type.t = VT_INT;
4225 vset(&type, r, v);
4228 void vswap(void)
4230 SValue tmp;
4232 tmp = vtop[0];
4233 vtop[0] = vtop[-1];
4234 vtop[-1] = tmp;
4237 void vpushv(SValue *v)
4239 if (vtop >= vstack + VSTACK_SIZE)
4240 error("memory full");
4241 vtop++;
4242 *vtop = *v;
4245 void vdup(void)
4247 vpushv(vtop);
4250 /* save r to the memory stack, and mark it as being free */
4251 void save_reg(int r)
4253 int l, saved, size, align;
4254 SValue *p, sv;
4255 CType *type;
4257 /* modify all stack values */
4258 saved = 0;
4259 l = 0;
4260 for(p=vstack;p<=vtop;p++) {
4261 if ((p->r & VT_VALMASK) == r ||
4262 (p->r2 & VT_VALMASK) == r) {
4263 /* must save value on stack if not already done */
4264 if (!saved) {
4265 /* NOTE: must reload 'r' because r might be equal to r2 */
4266 r = p->r & VT_VALMASK;
4267 /* store register in the stack */
4268 type = &p->type;
4269 if ((p->r & VT_LVAL) ||
4270 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
4271 type = &int_type;
4272 size = type_size(type, &align);
4273 loc = (loc - size) & -align;
4274 sv.type.t = type->t;
4275 sv.r = VT_LOCAL | VT_LVAL;
4276 sv.c.ul = loc;
4277 store(r, &sv);
4278 #ifdef TCC_TARGET_I386
4279 /* x86 specific: need to pop fp register ST0 if saved */
4280 if (r == TREG_ST0) {
4281 o(0xd9dd); /* fstp %st(1) */
4283 #endif
4284 /* special long long case */
4285 if ((type->t & VT_BTYPE) == VT_LLONG) {
4286 sv.c.ul += 4;
4287 store(p->r2, &sv);
4289 l = loc;
4290 saved = 1;
4292 /* mark that stack entry as being saved on the stack */
4293 if (p->r & VT_LVAL) {
4294 /* also clear the bounded flag because the
4295 relocation address of the function was stored in
4296 p->c.ul */
4297 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
4298 } else {
4299 p->r = lvalue_type(p->type.t) | VT_LOCAL;
4301 p->r2 = VT_CONST;
4302 p->c.ul = l;
4307 /* find a free register of class 'rc'. If none, save one register */
4308 int get_reg(int rc)
4310 int r;
4311 SValue *p;
4313 /* find a free register */
4314 for(r=0;r<NB_REGS;r++) {
4315 if (reg_classes[r] & rc) {
4316 for(p=vstack;p<=vtop;p++) {
4317 if ((p->r & VT_VALMASK) == r ||
4318 (p->r2 & VT_VALMASK) == r)
4319 goto notfound;
4321 return r;
4323 notfound: ;
4326 /* no register left : free the first one on the stack (VERY
4327 IMPORTANT to start from the bottom to ensure that we don't
4328 spill registers used in gen_opi()) */
4329 for(p=vstack;p<=vtop;p++) {
4330 r = p->r & VT_VALMASK;
4331 if (r < VT_CONST && (reg_classes[r] & rc))
4332 goto save_found;
4333 /* also look at second register (if long long) */
4334 r = p->r2 & VT_VALMASK;
4335 if (r < VT_CONST && (reg_classes[r] & rc)) {
4336 save_found:
4337 save_reg(r);
4338 return r;
4341 /* Should never comes here */
4342 return -1;
4345 /* save registers up to (vtop - n) stack entry */
4346 void save_regs(int n)
4348 int r;
4349 SValue *p, *p1;
4350 p1 = vtop - n;
4351 for(p = vstack;p <= p1; p++) {
4352 r = p->r & VT_VALMASK;
4353 if (r < VT_CONST) {
4354 save_reg(r);
4359 /* move register 's' to 'r', and flush previous value of r to memory
4360 if needed */
4361 void move_reg(int r, int s)
4363 SValue sv;
4365 if (r != s) {
4366 save_reg(r);
4367 sv.type.t = VT_INT;
4368 sv.r = s;
4369 sv.c.ul = 0;
4370 load(r, &sv);
4374 /* get address of vtop (vtop MUST BE an lvalue) */
4375 void gaddrof(void)
4377 vtop->r &= ~VT_LVAL;
4378 /* tricky: if saved lvalue, then we can go back to lvalue */
4379 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
4380 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
4383 #ifdef CONFIG_TCC_BCHECK
4384 /* generate lvalue bound code */
4385 void gbound(void)
4387 int lval_type;
4388 CType type1;
4390 vtop->r &= ~VT_MUSTBOUND;
4391 /* if lvalue, then use checking code before dereferencing */
4392 if (vtop->r & VT_LVAL) {
4393 /* if not VT_BOUNDED value, then make one */
4394 if (!(vtop->r & VT_BOUNDED)) {
4395 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
4396 /* must save type because we must set it to int to get pointer */
4397 type1 = vtop->type;
4398 vtop->type.t = VT_INT;
4399 gaddrof();
4400 vpushi(0);
4401 gen_bounded_ptr_add();
4402 vtop->r |= lval_type;
4403 vtop->type = type1;
4405 /* then check for dereferencing */
4406 gen_bounded_ptr_deref();
4409 #endif
4411 /* store vtop a register belonging to class 'rc'. lvalues are
4412 converted to values. Cannot be used if cannot be converted to
4413 register value (such as structures). */
4414 int gv(int rc)
4416 int r, r2, rc2, bit_pos, bit_size, size, align, i;
4417 unsigned long long ll;
4419 /* NOTE: get_reg can modify vstack[] */
4420 if (vtop->type.t & VT_BITFIELD) {
4421 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4422 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4423 /* remove bit field info to avoid loops */
4424 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4425 /* generate shifts */
4426 vpushi(32 - (bit_pos + bit_size));
4427 gen_op(TOK_SHL);
4428 vpushi(32 - bit_size);
4429 /* NOTE: transformed to SHR if unsigned */
4430 gen_op(TOK_SAR);
4431 r = gv(rc);
4432 } else {
4433 if (is_float(vtop->type.t) &&
4434 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4435 Sym *sym;
4436 int *ptr;
4437 unsigned long offset;
4439 /* XXX: unify with initializers handling ? */
4440 /* CPUs usually cannot use float constants, so we store them
4441 generically in data segment */
4442 size = type_size(&vtop->type, &align);
4443 offset = (data_section->data_offset + align - 1) & -align;
4444 data_section->data_offset = offset;
4445 /* XXX: not portable yet */
4446 ptr = section_ptr_add(data_section, size);
4447 size = size >> 2;
4448 for(i=0;i<size;i++)
4449 ptr[i] = vtop->c.tab[i];
4450 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
4451 vtop->r |= VT_LVAL | VT_SYM;
4452 vtop->sym = sym;
4453 vtop->c.ul = 0;
4455 #ifdef CONFIG_TCC_BCHECK
4456 if (vtop->r & VT_MUSTBOUND)
4457 gbound();
4458 #endif
4460 r = vtop->r & VT_VALMASK;
4461 /* need to reload if:
4462 - constant
4463 - lvalue (need to dereference pointer)
4464 - already a register, but not in the right class */
4465 if (r >= VT_CONST ||
4466 (vtop->r & VT_LVAL) ||
4467 !(reg_classes[r] & rc) ||
4468 ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
4469 !(reg_classes[vtop->r2] & rc))) {
4470 r = get_reg(rc);
4471 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
4472 /* two register type load : expand to two words
4473 temporarily */
4474 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4475 /* load constant */
4476 ll = vtop->c.ull;
4477 vtop->c.ui = ll; /* first word */
4478 load(r, vtop);
4479 vtop->r = r; /* save register value */
4480 vpushi(ll >> 32); /* second word */
4481 } else if (r >= VT_CONST ||
4482 (vtop->r & VT_LVAL)) {
4483 /* load from memory */
4484 load(r, vtop);
4485 vdup();
4486 vtop[-1].r = r; /* save register value */
4487 /* increment pointer to get second word */
4488 vtop->type.t = VT_INT;
4489 gaddrof();
4490 vpushi(4);
4491 gen_op('+');
4492 vtop->r |= VT_LVAL;
4493 } else {
4494 /* move registers */
4495 load(r, vtop);
4496 vdup();
4497 vtop[-1].r = r; /* save register value */
4498 vtop->r = vtop[-1].r2;
4500 /* allocate second register */
4501 rc2 = RC_INT;
4502 if (rc == RC_IRET)
4503 rc2 = RC_LRET;
4504 r2 = get_reg(rc2);
4505 load(r2, vtop);
4506 vpop();
4507 /* write second register */
4508 vtop->r2 = r2;
4509 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
4510 int t1, t;
4511 /* lvalue of scalar type : need to use lvalue type
4512 because of possible cast */
4513 t = vtop->type.t;
4514 t1 = t;
4515 /* compute memory access type */
4516 if (vtop->r & VT_LVAL_BYTE)
4517 t = VT_BYTE;
4518 else if (vtop->r & VT_LVAL_SHORT)
4519 t = VT_SHORT;
4520 if (vtop->r & VT_LVAL_UNSIGNED)
4521 t |= VT_UNSIGNED;
4522 vtop->type.t = t;
4523 load(r, vtop);
4524 /* restore wanted type */
4525 vtop->type.t = t1;
4526 } else {
4527 /* one register type load */
4528 load(r, vtop);
4531 vtop->r = r;
4533 return r;
4536 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4537 void gv2(int rc1, int rc2)
4539 int v;
4541 /* generate more generic register first. But VT_JMP or VT_CMP
4542 values must be generated first in all cases to avoid possible
4543 reload errors */
4544 v = vtop[0].r & VT_VALMASK;
4545 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
4546 vswap();
4547 gv(rc1);
4548 vswap();
4549 gv(rc2);
4550 /* test if reload is needed for first register */
4551 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
4552 vswap();
4553 gv(rc1);
4554 vswap();
4556 } else {
4557 gv(rc2);
4558 vswap();
4559 gv(rc1);
4560 vswap();
4561 /* test if reload is needed for first register */
4562 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
4563 gv(rc2);
4568 /* expand long long on stack in two int registers */
4569 void lexpand(void)
4571 int u;
4573 u = vtop->type.t & VT_UNSIGNED;
4574 gv(RC_INT);
4575 vdup();
4576 vtop[0].r = vtop[-1].r2;
4577 vtop[0].r2 = VT_CONST;
4578 vtop[-1].r2 = VT_CONST;
4579 vtop[0].type.t = VT_INT | u;
4580 vtop[-1].type.t = VT_INT | u;
4583 /* build a long long from two ints */
4584 void lbuild(int t)
4586 gv2(RC_INT, RC_INT);
4587 vtop[-1].r2 = vtop[0].r;
4588 vtop[-1].type.t = t;
4589 vpop();
4592 /* rotate n first stack elements to the bottom
4593 I1 ... In -> I2 ... In I1 [top is right]
4595 void vrotb(int n)
4597 int i;
4598 SValue tmp;
4600 tmp = vtop[-n + 1];
4601 for(i=-n+1;i!=0;i++)
4602 vtop[i] = vtop[i+1];
4603 vtop[0] = tmp;
4606 /* rotate n first stack elements to the top
4607 I1 ... In -> In I1 ... I(n-1) [top is right]
4609 void vrott(int n)
4611 int i;
4612 SValue tmp;
4614 tmp = vtop[0];
4615 for(i = 0;i < n - 1; i++)
4616 vtop[-i] = vtop[-i - 1];
4617 vtop[-n + 1] = tmp;
4620 /* pop stack value */
4621 void vpop(void)
4623 int v;
4624 v = vtop->r & VT_VALMASK;
4625 #ifdef TCC_TARGET_I386
4626 /* for x86, we need to pop the FP stack */
4627 if (v == TREG_ST0 && !nocode_wanted) {
4628 o(0xd9dd); /* fstp %st(1) */
4629 } else
4630 #endif
4631 if (v == VT_JMP || v == VT_JMPI) {
4632 /* need to put correct jump if && or || without test */
4633 gsym(vtop->c.ul);
4635 vtop--;
4638 /* convert stack entry to register and duplicate its value in another
4639 register */
4640 void gv_dup(void)
4642 int rc, t, r, r1;
4643 SValue sv;
4645 t = vtop->type.t;
4646 if ((t & VT_BTYPE) == VT_LLONG) {
4647 lexpand();
4648 gv_dup();
4649 vswap();
4650 vrotb(3);
4651 gv_dup();
4652 vrotb(4);
4653 /* stack: H L L1 H1 */
4654 lbuild(t);
4655 vrotb(3);
4656 vrotb(3);
4657 vswap();
4658 lbuild(t);
4659 vswap();
4660 } else {
4661 /* duplicate value */
4662 rc = RC_INT;
4663 sv.type.t = VT_INT;
4664 if (is_float(t)) {
4665 rc = RC_FLOAT;
4666 sv.type.t = t;
4668 r = gv(rc);
4669 r1 = get_reg(rc);
4670 sv.r = r;
4671 sv.c.ul = 0;
4672 load(r1, &sv); /* move r to r1 */
4673 vdup();
4674 /* duplicates value */
4675 vtop->r = r1;
4679 /* generate CPU independent (unsigned) long long operations */
4680 void gen_opl(int op)
4682 int t, a, b, op1, c, i;
4683 int func;
4684 SValue tmp;
4686 switch(op) {
4687 case '/':
4688 case TOK_PDIV:
4689 func = TOK___divdi3;
4690 goto gen_func;
4691 case TOK_UDIV:
4692 func = TOK___udivdi3;
4693 goto gen_func;
4694 case '%':
4695 func = TOK___moddi3;
4696 goto gen_func;
4697 case TOK_UMOD:
4698 func = TOK___umoddi3;
4699 gen_func:
4700 /* call generic long long function */
4701 vpush_global_sym(&func_old_type, func);
4702 vrott(3);
4703 gfunc_call(2);
4704 vpushi(0);
4705 vtop->r = REG_IRET;
4706 vtop->r2 = REG_LRET;
4707 break;
4708 case '^':
4709 case '&':
4710 case '|':
4711 case '*':
4712 case '+':
4713 case '-':
4714 t = vtop->type.t;
4715 vswap();
4716 lexpand();
4717 vrotb(3);
4718 lexpand();
4719 /* stack: L1 H1 L2 H2 */
4720 tmp = vtop[0];
4721 vtop[0] = vtop[-3];
4722 vtop[-3] = tmp;
4723 tmp = vtop[-2];
4724 vtop[-2] = vtop[-3];
4725 vtop[-3] = tmp;
4726 vswap();
4727 /* stack: H1 H2 L1 L2 */
4728 if (op == '*') {
4729 vpushv(vtop - 1);
4730 vpushv(vtop - 1);
4731 gen_op(TOK_UMULL);
4732 lexpand();
4733 /* stack: H1 H2 L1 L2 ML MH */
4734 for(i=0;i<4;i++)
4735 vrotb(6);
4736 /* stack: ML MH H1 H2 L1 L2 */
4737 tmp = vtop[0];
4738 vtop[0] = vtop[-2];
4739 vtop[-2] = tmp;
4740 /* stack: ML MH H1 L2 H2 L1 */
4741 gen_op('*');
4742 vrotb(3);
4743 vrotb(3);
4744 gen_op('*');
4745 /* stack: ML MH M1 M2 */
4746 gen_op('+');
4747 gen_op('+');
4748 } else if (op == '+' || op == '-') {
4749 /* XXX: add non carry method too (for MIPS or alpha) */
4750 if (op == '+')
4751 op1 = TOK_ADDC1;
4752 else
4753 op1 = TOK_SUBC1;
4754 gen_op(op1);
4755 /* stack: H1 H2 (L1 op L2) */
4756 vrotb(3);
4757 vrotb(3);
4758 gen_op(op1 + 1); /* TOK_xxxC2 */
4759 } else {
4760 gen_op(op);
4761 /* stack: H1 H2 (L1 op L2) */
4762 vrotb(3);
4763 vrotb(3);
4764 /* stack: (L1 op L2) H1 H2 */
4765 gen_op(op);
4766 /* stack: (L1 op L2) (H1 op H2) */
4768 /* stack: L H */
4769 lbuild(t);
4770 break;
4771 case TOK_SAR:
4772 case TOK_SHR:
4773 case TOK_SHL:
4774 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4775 t = vtop[-1].type.t;
4776 vswap();
4777 lexpand();
4778 vrotb(3);
4779 /* stack: L H shift */
4780 c = (int)vtop->c.i;
4781 /* constant: simpler */
4782 /* NOTE: all comments are for SHL. the other cases are
4783 done by swaping words */
4784 vpop();
4785 if (op != TOK_SHL)
4786 vswap();
4787 if (c >= 32) {
4788 /* stack: L H */
4789 vpop();
4790 if (c > 32) {
4791 vpushi(c - 32);
4792 gen_op(op);
4794 if (op != TOK_SAR) {
4795 vpushi(0);
4796 } else {
4797 gv_dup();
4798 vpushi(31);
4799 gen_op(TOK_SAR);
4801 vswap();
4802 } else {
4803 vswap();
4804 gv_dup();
4805 /* stack: H L L */
4806 vpushi(c);
4807 gen_op(op);
4808 vswap();
4809 vpushi(32 - c);
4810 if (op == TOK_SHL)
4811 gen_op(TOK_SHR);
4812 else
4813 gen_op(TOK_SHL);
4814 vrotb(3);
4815 /* stack: L L H */
4816 vpushi(c);
4817 if (op == TOK_SHL)
4818 gen_op(TOK_SHL);
4819 else
4820 gen_op(TOK_SHR);
4821 gen_op('|');
4823 if (op != TOK_SHL)
4824 vswap();
4825 lbuild(t);
4826 } else {
4827 /* XXX: should provide a faster fallback on x86 ? */
4828 switch(op) {
4829 case TOK_SAR:
4830 func = TOK___sardi3;
4831 goto gen_func;
4832 case TOK_SHR:
4833 func = TOK___shrdi3;
4834 goto gen_func;
4835 case TOK_SHL:
4836 func = TOK___shldi3;
4837 goto gen_func;
4840 break;
4841 default:
4842 /* compare operations */
4843 t = vtop->type.t;
4844 vswap();
4845 lexpand();
4846 vrotb(3);
4847 lexpand();
4848 /* stack: L1 H1 L2 H2 */
4849 tmp = vtop[-1];
4850 vtop[-1] = vtop[-2];
4851 vtop[-2] = tmp;
4852 /* stack: L1 L2 H1 H2 */
4853 /* compare high */
4854 op1 = op;
4855 /* when values are equal, we need to compare low words. since
4856 the jump is inverted, we invert the test too. */
4857 if (op1 == TOK_LT)
4858 op1 = TOK_LE;
4859 else if (op1 == TOK_GT)
4860 op1 = TOK_GE;
4861 else if (op1 == TOK_ULT)
4862 op1 = TOK_ULE;
4863 else if (op1 == TOK_UGT)
4864 op1 = TOK_UGE;
4865 a = 0;
4866 b = 0;
4867 gen_op(op1);
4868 if (op1 != TOK_NE) {
4869 a = gtst(1, 0);
4871 if (op != TOK_EQ) {
4872 /* generate non equal test */
4873 /* XXX: NOT PORTABLE yet */
4874 if (a == 0) {
4875 b = gtst(0, 0);
4876 } else {
4877 #ifdef TCC_TARGET_I386
4878 b = psym(0x850f, 0);
4879 #else
4880 error("not implemented");
4881 #endif
4884 /* compare low. Always unsigned */
4885 op1 = op;
4886 if (op1 == TOK_LT)
4887 op1 = TOK_ULT;
4888 else if (op1 == TOK_LE)
4889 op1 = TOK_ULE;
4890 else if (op1 == TOK_GT)
4891 op1 = TOK_UGT;
4892 else if (op1 == TOK_GE)
4893 op1 = TOK_UGE;
4894 gen_op(op1);
4895 a = gtst(1, a);
4896 gsym(b);
4897 vseti(VT_JMPI, a);
4898 break;
4902 /* handle integer constant optimizations and various machine
4903 independent opt */
4904 void gen_opic(int op)
4906 int fc, c1, c2, n;
4907 SValue *v1, *v2;
4909 v1 = vtop - 1;
4910 v2 = vtop;
4911 /* currently, we cannot do computations with forward symbols */
4912 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4913 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4914 if (c1 && c2) {
4915 fc = v2->c.i;
4916 switch(op) {
4917 case '+': v1->c.i += fc; break;
4918 case '-': v1->c.i -= fc; break;
4919 case '&': v1->c.i &= fc; break;
4920 case '^': v1->c.i ^= fc; break;
4921 case '|': v1->c.i |= fc; break;
4922 case '*': v1->c.i *= fc; break;
4924 case TOK_PDIV:
4925 case '/':
4926 case '%':
4927 case TOK_UDIV:
4928 case TOK_UMOD:
4929 /* if division by zero, generate explicit division */
4930 if (fc == 0) {
4931 if (const_wanted)
4932 error("division by zero in constant");
4933 goto general_case;
4935 switch(op) {
4936 default: v1->c.i /= fc; break;
4937 case '%': v1->c.i %= fc; break;
4938 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
4939 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
4941 break;
4942 case TOK_SHL: v1->c.i <<= fc; break;
4943 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
4944 case TOK_SAR: v1->c.i >>= fc; break;
4945 /* tests */
4946 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
4947 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
4948 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
4949 case TOK_NE: v1->c.i = v1->c.i != fc; break;
4950 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
4951 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
4952 case TOK_LT: v1->c.i = v1->c.i < fc; break;
4953 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
4954 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
4955 case TOK_GT: v1->c.i = v1->c.i > fc; break;
4956 /* logical */
4957 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
4958 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
4959 default:
4960 goto general_case;
4962 vtop--;
4963 } else {
4964 /* if commutative ops, put c2 as constant */
4965 if (c1 && (op == '+' || op == '&' || op == '^' ||
4966 op == '|' || op == '*')) {
4967 vswap();
4968 swap(&c1, &c2);
4970 fc = vtop->c.i;
4971 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
4972 op == TOK_PDIV) &&
4973 fc == 1) ||
4974 ((op == '+' || op == '-' || op == '|' || op == '^' ||
4975 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
4976 fc == 0) ||
4977 (op == '&' &&
4978 fc == -1))) {
4979 /* nothing to do */
4980 vtop--;
4981 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
4982 /* try to use shifts instead of muls or divs */
4983 if (fc > 0 && (fc & (fc - 1)) == 0) {
4984 n = -1;
4985 while (fc) {
4986 fc >>= 1;
4987 n++;
4989 vtop->c.i = n;
4990 if (op == '*')
4991 op = TOK_SHL;
4992 else if (op == TOK_PDIV)
4993 op = TOK_SAR;
4994 else
4995 op = TOK_SHR;
4997 goto general_case;
4998 } else if (c2 && (op == '+' || op == '-') &&
4999 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
5000 (VT_CONST | VT_SYM)) {
5001 /* symbol + constant case */
5002 if (op == '-')
5003 fc = -fc;
5004 vtop--;
5005 vtop->c.i += fc;
5006 } else {
5007 general_case:
5008 if (!nocode_wanted) {
5009 /* call low level op generator */
5010 gen_opi(op);
5011 } else {
5012 vtop--;
5018 /* generate a floating point operation with constant propagation */
5019 void gen_opif(int op)
5021 int c1, c2;
5022 SValue *v1, *v2;
5023 long double f1, f2;
5025 v1 = vtop - 1;
5026 v2 = vtop;
5027 /* currently, we cannot do computations with forward symbols */
5028 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5029 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5030 if (c1 && c2) {
5031 if (v1->type.t == VT_FLOAT) {
5032 f1 = v1->c.f;
5033 f2 = v2->c.f;
5034 } else if (v1->type.t == VT_DOUBLE) {
5035 f1 = v1->c.d;
5036 f2 = v2->c.d;
5037 } else {
5038 f1 = v1->c.ld;
5039 f2 = v2->c.ld;
5042 /* NOTE: we only do constant propagation if finite number (not
5043 NaN or infinity) (ANSI spec) */
5044 if (!ieee_finite(f1) || !ieee_finite(f2))
5045 goto general_case;
5047 switch(op) {
5048 case '+': f1 += f2; break;
5049 case '-': f1 -= f2; break;
5050 case '*': f1 *= f2; break;
5051 case '/':
5052 if (f2 == 0.0) {
5053 if (const_wanted)
5054 error("division by zero in constant");
5055 goto general_case;
5057 f1 /= f2;
5058 break;
5059 /* XXX: also handles tests ? */
5060 default:
5061 goto general_case;
5063 /* XXX: overflow test ? */
5064 if (v1->type.t == VT_FLOAT) {
5065 v1->c.f = f1;
5066 } else if (v1->type.t == VT_DOUBLE) {
5067 v1->c.d = f1;
5068 } else {
5069 v1->c.ld = f1;
5071 vtop--;
5072 } else {
5073 general_case:
5074 if (!nocode_wanted) {
5075 gen_opf(op);
5076 } else {
5077 vtop--;
5082 static int pointed_size(CType *type)
5084 int align;
5085 return type_size(pointed_type(type), &align);
5088 #if 0
5089 void check_pointer_types(SValue *p1, SValue *p2)
5091 char buf1[256], buf2[256];
5092 int t1, t2;
5093 t1 = p1->t;
5094 t2 = p2->t;
5095 if (!is_compatible_types(t1, t2)) {
5096 type_to_str(buf1, sizeof(buf1), t1, NULL);
5097 type_to_str(buf2, sizeof(buf2), t2, NULL);
5098 error("incompatible pointers '%s' and '%s'", buf1, buf2);
5101 #endif
5103 /* generic gen_op: handles types problems */
5104 void gen_op(int op)
5106 int u, t1, t2, bt1, bt2, t;
5107 CType type1;
5109 t1 = vtop[-1].type.t;
5110 t2 = vtop[0].type.t;
5111 bt1 = t1 & VT_BTYPE;
5112 bt2 = t2 & VT_BTYPE;
5114 if (bt1 == VT_PTR || bt2 == VT_PTR) {
5115 /* at least one operand is a pointer */
5116 /* relationnal op: must be both pointers */
5117 if (op >= TOK_ULT && op <= TOK_GT) {
5118 // check_pointer_types(vtop, vtop - 1);
5119 /* pointers are handled are unsigned */
5120 t = VT_INT | VT_UNSIGNED;
5121 goto std_op;
5123 /* if both pointers, then it must be the '-' op */
5124 if (bt1 == VT_PTR && bt2 == VT_PTR) {
5125 if (op != '-')
5126 error("cannot use pointers here");
5127 // check_pointer_types(vtop - 1, vtop);
5128 /* XXX: check that types are compatible */
5129 u = pointed_size(&vtop[-1].type);
5130 gen_opic(op);
5131 /* set to integer type */
5132 vtop->type.t = VT_INT;
5133 vpushi(u);
5134 gen_op(TOK_PDIV);
5135 } else {
5136 /* exactly one pointer : must be '+' or '-'. */
5137 if (op != '-' && op != '+')
5138 error("cannot use pointers here");
5139 /* Put pointer as first operand */
5140 if (bt2 == VT_PTR) {
5141 vswap();
5142 swap(&t1, &t2);
5144 type1 = vtop[-1].type;
5145 /* XXX: cast to int ? (long long case) */
5146 vpushi(pointed_size(&vtop[-1].type));
5147 gen_op('*');
5148 #ifdef CONFIG_TCC_BCHECK
5149 /* if evaluating constant expression, no code should be
5150 generated, so no bound check */
5151 if (do_bounds_check && !const_wanted) {
5152 /* if bounded pointers, we generate a special code to
5153 test bounds */
5154 if (op == '-') {
5155 vpushi(0);
5156 vswap();
5157 gen_op('-');
5159 gen_bounded_ptr_add();
5160 } else
5161 #endif
5163 gen_opic(op);
5165 /* put again type if gen_opic() swaped operands */
5166 vtop->type = type1;
5168 } else if (is_float(bt1) || is_float(bt2)) {
5169 /* compute bigger type and do implicit casts */
5170 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
5171 t = VT_LDOUBLE;
5172 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
5173 t = VT_DOUBLE;
5174 } else {
5175 t = VT_FLOAT;
5177 /* floats can only be used for a few operations */
5178 if (op != '+' && op != '-' && op != '*' && op != '/' &&
5179 (op < TOK_ULT || op > TOK_GT))
5180 error("invalid operands for binary operation");
5181 goto std_op;
5182 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
5183 /* cast to biggest op */
5184 t = VT_LLONG;
5185 /* convert to unsigned if it does not fit in a long long */
5186 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
5187 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
5188 t |= VT_UNSIGNED;
5189 goto std_op;
5190 } else {
5191 /* integer operations */
5192 t = VT_INT;
5193 /* convert to unsigned if it does not fit in an integer */
5194 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
5195 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
5196 t |= VT_UNSIGNED;
5197 std_op:
5198 /* XXX: currently, some unsigned operations are explicit, so
5199 we modify them here */
5200 if (t & VT_UNSIGNED) {
5201 if (op == TOK_SAR)
5202 op = TOK_SHR;
5203 else if (op == '/')
5204 op = TOK_UDIV;
5205 else if (op == '%')
5206 op = TOK_UMOD;
5207 else if (op == TOK_LT)
5208 op = TOK_ULT;
5209 else if (op == TOK_GT)
5210 op = TOK_UGT;
5211 else if (op == TOK_LE)
5212 op = TOK_ULE;
5213 else if (op == TOK_GE)
5214 op = TOK_UGE;
5216 vswap();
5217 type1.t = t;
5218 gen_cast(&type1);
5219 vswap();
5220 /* special case for shifts and long long: we keep the shift as
5221 an integer */
5222 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
5223 type1.t = VT_INT;
5224 gen_cast(&type1);
5225 if (is_float(t))
5226 gen_opif(op);
5227 else if ((t & VT_BTYPE) == VT_LLONG)
5228 gen_opl(op);
5229 else
5230 gen_opic(op);
5231 if (op >= TOK_ULT && op <= TOK_GT) {
5232 /* relationnal op: the result is an int */
5233 vtop->type.t = VT_INT;
5234 } else {
5235 vtop->type.t = t;
5240 /* generic itof for unsigned long long case */
5241 void gen_cvt_itof1(int t)
5243 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
5244 (VT_LLONG | VT_UNSIGNED)) {
5246 if (t == VT_FLOAT)
5247 vpush_global_sym(&func_old_type, TOK___ulltof);
5248 else if (t == VT_DOUBLE)
5249 vpush_global_sym(&func_old_type, TOK___ulltod);
5250 else
5251 vpush_global_sym(&func_old_type, TOK___ulltold);
5252 vrott(2);
5253 gfunc_call(1);
5254 vpushi(0);
5255 vtop->r = REG_FRET;
5256 } else {
5257 gen_cvt_itof(t);
5261 /* generic ftoi for unsigned long long case */
5262 void gen_cvt_ftoi1(int t)
5264 int st;
5266 if (t == (VT_LLONG | VT_UNSIGNED)) {
5267 /* not handled natively */
5268 st = vtop->type.t & VT_BTYPE;
5269 if (st == VT_FLOAT)
5270 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
5271 else if (st == VT_DOUBLE)
5272 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
5273 else
5274 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
5275 vrott(2);
5276 gfunc_call(1);
5277 vpushi(0);
5278 vtop->r = REG_IRET;
5279 vtop->r2 = REG_LRET;
5280 } else {
5281 gen_cvt_ftoi(t);
5285 /* force char or short cast */
5286 void force_charshort_cast(int t)
5288 int bits, dbt;
5289 dbt = t & VT_BTYPE;
5290 /* XXX: add optimization if lvalue : just change type and offset */
5291 if (dbt == VT_BYTE)
5292 bits = 8;
5293 else
5294 bits = 16;
5295 if (t & VT_UNSIGNED) {
5296 vpushi((1 << bits) - 1);
5297 gen_op('&');
5298 } else {
5299 bits = 32 - bits;
5300 vpushi(bits);
5301 gen_op(TOK_SHL);
5302 vpushi(bits);
5303 gen_op(TOK_SAR);
5307 /* cast 'vtop' to 'type' */
5308 static void gen_cast(CType *type)
5310 int sbt, dbt, sf, df, c;
5312 /* special delayed cast for char/short */
5313 /* XXX: in some cases (multiple cascaded casts), it may still
5314 be incorrect */
5315 if (vtop->r & VT_MUSTCAST) {
5316 vtop->r &= ~VT_MUSTCAST;
5317 force_charshort_cast(vtop->type.t);
5320 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
5321 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
5323 if (sbt != dbt && !nocode_wanted) {
5324 sf = is_float(sbt);
5325 df = is_float(dbt);
5326 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5327 if (sf && df) {
5328 /* convert from fp to fp */
5329 if (c) {
5330 /* constant case: we can do it now */
5331 /* XXX: in ISOC, cannot do it if error in convert */
5332 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
5333 vtop->c.f = (float)vtop->c.d;
5334 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
5335 vtop->c.f = (float)vtop->c.ld;
5336 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
5337 vtop->c.d = (double)vtop->c.f;
5338 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
5339 vtop->c.d = (double)vtop->c.ld;
5340 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
5341 vtop->c.ld = (long double)vtop->c.f;
5342 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
5343 vtop->c.ld = (long double)vtop->c.d;
5344 } else {
5345 /* non constant case: generate code */
5346 gen_cvt_ftof(dbt);
5348 } else if (df) {
5349 /* convert int to fp */
5350 if (c) {
5351 switch(sbt) {
5352 case VT_LLONG | VT_UNSIGNED:
5353 case VT_LLONG:
5354 /* XXX: add const cases for long long */
5355 goto do_itof;
5356 case VT_INT | VT_UNSIGNED:
5357 switch(dbt) {
5358 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
5359 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
5360 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
5362 break;
5363 default:
5364 switch(dbt) {
5365 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
5366 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
5367 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
5369 break;
5371 } else {
5372 do_itof:
5373 gen_cvt_itof1(dbt);
5375 } else if (sf) {
5376 /* convert fp to int */
5377 /* we handle char/short/etc... with generic code */
5378 if (dbt != (VT_INT | VT_UNSIGNED) &&
5379 dbt != (VT_LLONG | VT_UNSIGNED) &&
5380 dbt != VT_LLONG)
5381 dbt = VT_INT;
5382 if (c) {
5383 switch(dbt) {
5384 case VT_LLONG | VT_UNSIGNED:
5385 case VT_LLONG:
5386 /* XXX: add const cases for long long */
5387 goto do_ftoi;
5388 case VT_INT | VT_UNSIGNED:
5389 switch(sbt) {
5390 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
5391 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5392 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5394 break;
5395 default:
5396 /* int case */
5397 switch(sbt) {
5398 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
5399 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
5400 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
5402 break;
5404 } else {
5405 do_ftoi:
5406 gen_cvt_ftoi1(dbt);
5408 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
5409 /* additional cast for char/short/bool... */
5410 vtop->type.t = dbt;
5411 gen_cast(type);
5413 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
5414 if ((sbt & VT_BTYPE) != VT_LLONG) {
5415 /* scalar to long long */
5416 if (c) {
5417 if (sbt == (VT_INT | VT_UNSIGNED))
5418 vtop->c.ll = vtop->c.ui;
5419 else
5420 vtop->c.ll = vtop->c.i;
5421 } else {
5422 /* machine independent conversion */
5423 gv(RC_INT);
5424 /* generate high word */
5425 if (sbt == (VT_INT | VT_UNSIGNED)) {
5426 vpushi(0);
5427 gv(RC_INT);
5428 } else {
5429 gv_dup();
5430 vpushi(31);
5431 gen_op(TOK_SAR);
5433 /* patch second register */
5434 vtop[-1].r2 = vtop->r;
5435 vpop();
5438 } else if (dbt == VT_BOOL) {
5439 /* scalar to bool */
5440 vpushi(0);
5441 gen_op(TOK_NE);
5442 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
5443 (dbt & VT_BTYPE) == VT_SHORT) {
5444 force_charshort_cast(dbt);
5445 } else if ((dbt & VT_BTYPE) == VT_INT) {
5446 /* scalar to int */
5447 if (sbt == VT_LLONG) {
5448 /* from long long: just take low order word */
5449 lexpand();
5450 vpop();
5452 /* if lvalue and single word type, nothing to do because
5453 the lvalue already contains the real type size (see
5454 VT_LVAL_xxx constants) */
5457 vtop->type = *type;
5460 /* return type size. Put alignment at 'a' */
5461 static int type_size(CType *type, int *a)
5463 Sym *s;
5464 int bt;
5466 bt = type->t & VT_BTYPE;
5467 if (bt == VT_STRUCT) {
5468 /* struct/union */
5469 s = type->ref;
5470 *a = s->r;
5471 return s->c;
5472 } else if (bt == VT_PTR) {
5473 if (type->t & VT_ARRAY) {
5474 s = type->ref;
5475 return type_size(&s->type, a) * s->c;
5476 } else {
5477 *a = PTR_SIZE;
5478 return PTR_SIZE;
5480 } else if (bt == VT_LDOUBLE) {
5481 *a = LDOUBLE_ALIGN;
5482 return LDOUBLE_SIZE;
5483 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
5484 *a = 4; /* XXX: i386 specific */
5485 return 8;
5486 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
5487 *a = 4;
5488 return 4;
5489 } else if (bt == VT_SHORT) {
5490 *a = 2;
5491 return 2;
5492 } else {
5493 /* char, void, function, _Bool */
5494 *a = 1;
5495 return 1;
5499 /* return the pointed type of t */
5500 static inline CType *pointed_type(CType *type)
5502 return &type->ref->type;
5505 /* modify type so that its it is a pointer to type. */
5506 static void mk_pointer(CType *type)
5508 Sym *s;
5509 s = sym_push(SYM_FIELD, type, 0, -1);
5510 type->t = VT_PTR | (type->t & ~VT_TYPE);
5511 type->ref = s;
5514 static int is_compatible_types(CType *type1, CType *type2)
5516 Sym *s1, *s2;
5517 int bt1, bt2, t1, t2;
5519 t1 = type1->t & VT_TYPE;
5520 t2 = type2->t & VT_TYPE;
5521 bt1 = t1 & VT_BTYPE;
5522 bt2 = t2 & VT_BTYPE;
5523 if (bt1 == VT_PTR) {
5524 type1 = pointed_type(type1);
5525 /* if function, then convert implicitely to function pointer */
5526 if (bt2 != VT_FUNC) {
5527 if (bt2 != VT_PTR)
5528 return 0;
5529 type2 = pointed_type(type2);
5531 /* void matches everything */
5532 /* XXX: not fully compliant */
5533 if ((type1->t & VT_TYPE) == VT_VOID || (type2->t & VT_TYPE) == VT_VOID)
5534 return 1;
5535 return is_compatible_types(type1, type2);
5536 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5537 return (type1->ref == type2->ref);
5538 } else if (bt1 == VT_FUNC) {
5539 if (bt2 != VT_FUNC)
5540 return 0;
5541 s1 = type1->ref;
5542 s2 = type2->ref;
5543 if (!is_compatible_types(&s1->type, &s2->type))
5544 return 0;
5545 /* XXX: not complete */
5546 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
5547 return 1;
5548 if (s1->c != s2->c)
5549 return 0;
5550 while (s1 != NULL) {
5551 if (s2 == NULL)
5552 return 0;
5553 if (!is_compatible_types(&s1->type, &s2->type))
5554 return 0;
5555 s1 = s1->next;
5556 s2 = s2->next;
5558 if (s2)
5559 return 0;
5560 return 1;
5561 } else {
5562 /* XXX: not complete */
5563 return 1;
5567 /* print a type. If 'varstr' is not NULL, then the variable is also
5568 printed in the type */
5569 /* XXX: union */
5570 /* XXX: add array and function pointers */
5571 void type_to_str(char *buf, int buf_size,
5572 CType *type, const char *varstr)
5574 int bt, v, t;
5575 Sym *s, *sa;
5576 char buf1[256];
5577 const char *tstr;
5579 t = type->t & VT_TYPE;
5580 bt = t & VT_BTYPE;
5581 buf[0] = '\0';
5582 if (t & VT_UNSIGNED)
5583 pstrcat(buf, buf_size, "unsigned ");
5584 switch(bt) {
5585 case VT_VOID:
5586 tstr = "void";
5587 goto add_tstr;
5588 case VT_BOOL:
5589 tstr = "_Bool";
5590 goto add_tstr;
5591 case VT_BYTE:
5592 tstr = "char";
5593 goto add_tstr;
5594 case VT_SHORT:
5595 tstr = "short";
5596 goto add_tstr;
5597 case VT_INT:
5598 tstr = "int";
5599 goto add_tstr;
5600 case VT_LONG:
5601 tstr = "long";
5602 goto add_tstr;
5603 case VT_LLONG:
5604 tstr = "long long";
5605 goto add_tstr;
5606 case VT_FLOAT:
5607 tstr = "float";
5608 goto add_tstr;
5609 case VT_DOUBLE:
5610 tstr = "double";
5611 goto add_tstr;
5612 case VT_LDOUBLE:
5613 tstr = "long double";
5614 add_tstr:
5615 pstrcat(buf, buf_size, tstr);
5616 break;
5617 case VT_ENUM:
5618 case VT_STRUCT:
5619 if (bt == VT_STRUCT)
5620 tstr = "struct ";
5621 else
5622 tstr = "enum ";
5623 pstrcat(buf, buf_size, tstr);
5624 v = type->ref->v & ~SYM_STRUCT;
5625 if (v >= SYM_FIRST_ANOM)
5626 pstrcat(buf, buf_size, "<anonymous>");
5627 else
5628 pstrcat(buf, buf_size, get_tok_str(v, NULL));
5629 break;
5630 case VT_FUNC:
5631 s = type->ref;
5632 type_to_str(buf, buf_size, &s->type, varstr);
5633 pstrcat(buf, buf_size, "(");
5634 sa = s->next;
5635 while (sa != NULL) {
5636 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
5637 pstrcat(buf, buf_size, buf1);
5638 sa = sa->next;
5639 if (sa)
5640 pstrcat(buf, buf_size, ", ");
5642 pstrcat(buf, buf_size, ")");
5643 goto no_var;
5644 case VT_PTR:
5645 s = type->ref;
5646 pstrcpy(buf1, sizeof(buf1), "*");
5647 if (varstr)
5648 pstrcat(buf1, sizeof(buf1), varstr);
5649 type_to_str(buf, buf_size, &s->type, buf1);
5650 goto no_var;
5652 if (varstr) {
5653 pstrcat(buf, buf_size, " ");
5654 pstrcat(buf, buf_size, varstr);
5656 no_var: ;
5659 /* verify type compatibility to store vtop in 'dt' type, and generate
5660 casts if needed. */
5661 static void gen_assign_cast(CType *dt)
5663 CType *st;
5664 char buf1[256], buf2[256];
5665 int dbt, sbt;
5667 st = &vtop->type; /* source type */
5668 dbt = dt->t & VT_BTYPE;
5669 sbt = st->t & VT_BTYPE;
5670 if (dbt == VT_PTR) {
5671 /* special cases for pointers */
5672 /* a function is implicitely a function pointer */
5673 if (sbt == VT_FUNC) {
5674 if (!is_compatible_types(pointed_type(dt), st))
5675 goto error;
5676 else
5677 goto type_ok;
5679 /* '0' can also be a pointer */
5680 if (sbt == VT_INT &&
5681 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
5682 vtop->c.i == 0)
5683 goto type_ok;
5684 /* accept implicit pointer to integer cast with warning */
5685 if (sbt == VT_BYTE || sbt == VT_SHORT ||
5686 sbt == VT_INT || sbt == VT_LLONG) {
5687 warning("assignment makes pointer from integer without a cast");
5688 goto type_ok;
5690 } else if (dbt == VT_BYTE || dbt == VT_SHORT ||
5691 dbt == VT_INT || dbt == VT_LLONG) {
5692 if (sbt == VT_PTR || sbt == VT_FUNC) {
5693 warning("assignment makes integer from pointer without a cast");
5694 goto type_ok;
5697 if (!is_compatible_types(dt, st)) {
5698 error:
5699 type_to_str(buf1, sizeof(buf1), st, NULL);
5700 type_to_str(buf2, sizeof(buf2), dt, NULL);
5701 error("cannot cast '%s' to '%s'", buf1, buf2);
5703 type_ok:
5704 gen_cast(dt);
5707 /* store vtop in lvalue pushed on stack */
5708 void vstore(void)
5710 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
5712 ft = vtop[-1].type.t;
5713 sbt = vtop->type.t & VT_BTYPE;
5714 dbt = ft & VT_BTYPE;
5715 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
5716 (sbt == VT_INT && dbt == VT_SHORT)) {
5717 /* optimize char/short casts */
5718 delayed_cast = VT_MUSTCAST;
5719 vtop->type.t = ft & VT_TYPE;
5720 } else {
5721 delayed_cast = 0;
5722 gen_assign_cast(&vtop[-1].type);
5725 if (sbt == VT_STRUCT) {
5726 /* if structure, only generate pointer */
5727 /* structure assignment : generate memcpy */
5728 /* XXX: optimize if small size */
5729 if (!nocode_wanted) {
5730 size = type_size(&vtop->type, &align);
5732 vpush_global_sym(&func_old_type, TOK_memcpy);
5734 /* destination */
5735 vpushv(vtop - 2);
5736 vtop->type.t = VT_INT;
5737 gaddrof();
5738 /* source */
5739 vpushv(vtop - 2);
5740 vtop->type.t = VT_INT;
5741 gaddrof();
5742 /* type size */
5743 vpushi(size);
5744 gfunc_call(3);
5746 vswap();
5747 vpop();
5748 } else {
5749 vswap();
5750 vpop();
5752 /* leave source on stack */
5753 } else if (ft & VT_BITFIELD) {
5754 /* bitfield store handling */
5755 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
5756 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5757 /* remove bit field info to avoid loops */
5758 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
5760 /* duplicate destination */
5761 vdup();
5762 vtop[-1] = vtop[-2];
5764 /* mask and shift source */
5765 vpushi((1 << bit_size) - 1);
5766 gen_op('&');
5767 vpushi(bit_pos);
5768 gen_op(TOK_SHL);
5769 /* load destination, mask and or with source */
5770 vswap();
5771 vpushi(~(((1 << bit_size) - 1) << bit_pos));
5772 gen_op('&');
5773 gen_op('|');
5774 /* store result */
5775 vstore();
5776 } else {
5777 #ifdef CONFIG_TCC_BCHECK
5778 /* bound check case */
5779 if (vtop[-1].r & VT_MUSTBOUND) {
5780 vswap();
5781 gbound();
5782 vswap();
5784 #endif
5785 if (!nocode_wanted) {
5786 rc = RC_INT;
5787 if (is_float(ft))
5788 rc = RC_FLOAT;
5789 r = gv(rc); /* generate value */
5790 /* if lvalue was saved on stack, must read it */
5791 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
5792 SValue sv;
5793 t = get_reg(RC_INT);
5794 sv.type.t = VT_INT;
5795 sv.r = VT_LOCAL | VT_LVAL;
5796 sv.c.ul = vtop[-1].c.ul;
5797 load(t, &sv);
5798 vtop[-1].r = t | VT_LVAL;
5800 store(r, vtop - 1);
5801 /* two word case handling : store second register at word + 4 */
5802 if ((ft & VT_BTYPE) == VT_LLONG) {
5803 vswap();
5804 /* convert to int to increment easily */
5805 vtop->type.t = VT_INT;
5806 gaddrof();
5807 vpushi(4);
5808 gen_op('+');
5809 vtop->r |= VT_LVAL;
5810 vswap();
5811 /* XXX: it works because r2 is spilled last ! */
5812 store(vtop->r2, vtop - 1);
5815 vswap();
5816 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5817 vtop->r |= delayed_cast;
5821 /* post defines POST/PRE add. c is the token ++ or -- */
5822 void inc(int post, int c)
5824 test_lvalue();
5825 vdup(); /* save lvalue */
5826 if (post) {
5827 gv_dup(); /* duplicate value */
5828 vrotb(3);
5829 vrotb(3);
5831 /* add constant */
5832 vpushi(c - TOK_MID);
5833 gen_op('+');
5834 vstore(); /* store value */
5835 if (post)
5836 vpop(); /* if post op, return saved value */
5839 /* Parse GNUC __attribute__ extension. Currently, the following
5840 extensions are recognized:
5841 - aligned(n) : set data/function alignment.
5842 - section(x) : generate data/code in this section.
5843 - unused : currently ignored, but may be used someday.
5845 static void parse_attribute(AttributeDef *ad)
5847 int t, n;
5849 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
5850 next();
5851 skip('(');
5852 skip('(');
5853 while (tok != ')') {
5854 if (tok < TOK_IDENT)
5855 expect("attribute name");
5856 t = tok;
5857 next();
5858 switch(t) {
5859 case TOK_SECTION1:
5860 case TOK_SECTION2:
5861 skip('(');
5862 if (tok != TOK_STR)
5863 expect("section name");
5864 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
5865 next();
5866 skip(')');
5867 break;
5868 case TOK_ALIGNED1:
5869 case TOK_ALIGNED2:
5870 if (tok == '(') {
5871 next();
5872 n = expr_const();
5873 if (n <= 0 || (n & (n - 1)) != 0)
5874 error("alignment must be a positive power of two");
5875 skip(')');
5876 } else {
5877 n = MAX_ALIGN;
5879 ad->aligned = n;
5880 break;
5881 case TOK_UNUSED1:
5882 case TOK_UNUSED2:
5883 /* currently, no need to handle it because tcc does not
5884 track unused objects */
5885 break;
5886 case TOK_NORETURN1:
5887 case TOK_NORETURN2:
5888 /* currently, no need to handle it because tcc does not
5889 track unused objects */
5890 break;
5891 case TOK_CDECL1:
5892 case TOK_CDECL2:
5893 case TOK_CDECL3:
5894 ad->func_call = FUNC_CDECL;
5895 break;
5896 case TOK_STDCALL1:
5897 case TOK_STDCALL2:
5898 case TOK_STDCALL3:
5899 ad->func_call = FUNC_STDCALL;
5900 break;
5901 default:
5902 // warning("'%s' attribute ignored", get_tok_str(t, NULL));
5903 /* skip parameters */
5904 /* XXX: skip parenthesis too */
5905 if (tok == '(') {
5906 next();
5907 while (tok != ')' && tok != -1)
5908 next();
5909 next();
5911 break;
5913 if (tok != ',')
5914 break;
5915 next();
5917 skip(')');
5918 skip(')');
5922 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5923 static void struct_decl(CType *type, int u)
5925 int a, v, size, align, maxalign, c, offset;
5926 int bit_size, bit_pos, bsize, bt, lbit_pos;
5927 Sym *s, *ss, **ps;
5928 AttributeDef ad;
5929 CType type1, btype;
5931 a = tok; /* save decl type */
5932 next();
5933 if (tok != '{') {
5934 v = tok;
5935 next();
5936 /* struct already defined ? return it */
5937 if (v < TOK_IDENT)
5938 expect("struct/union/enum name");
5939 s = struct_find(v);
5940 if (s) {
5941 if (s->type.t != a)
5942 error("invalid type");
5943 goto do_decl;
5945 } else {
5946 v = anon_sym++;
5948 type1.t = a;
5949 s = sym_push(v | SYM_STRUCT, &type1, 0, 0);
5950 /* put struct/union/enum name in type */
5951 do_decl:
5952 type->t = u;
5953 type->ref = s;
5955 if (tok == '{') {
5956 next();
5957 if (s->c)
5958 error("struct/union/enum already defined");
5959 /* cannot be empty */
5960 c = 0;
5961 /* non empty enums are not allowed */
5962 if (a == TOK_ENUM) {
5963 for(;;) {
5964 v = tok;
5965 if (v < TOK_UIDENT)
5966 expect("identifier");
5967 next();
5968 if (tok == '=') {
5969 next();
5970 c = expr_const();
5972 /* enum symbols have static storage */
5973 ss = sym_push(v, &int_type, VT_CONST, c);
5974 ss->type.t |= VT_STATIC;
5975 if (tok != ',')
5976 break;
5977 next();
5978 c++;
5979 /* NOTE: we accept a trailing comma */
5980 if (tok == '}')
5981 break;
5983 skip('}');
5984 } else {
5985 maxalign = 1;
5986 ps = &s->next;
5987 bit_pos = 0;
5988 offset = 0;
5989 while (tok != '}') {
5990 parse_btype(&btype, &ad);
5991 while (1) {
5992 bit_size = -1;
5993 v = 0;
5994 type1 = btype;
5995 if (tok != ':') {
5996 type_decl(&type1, &ad, &v, TYPE_DIRECT);
5997 if ((type1.t & VT_BTYPE) == VT_FUNC ||
5998 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
5999 error("invalid type for '%s'",
6000 get_tok_str(v, NULL));
6002 if (tok == ':') {
6003 next();
6004 bit_size = expr_const();
6005 /* XXX: handle v = 0 case for messages */
6006 if (bit_size < 0)
6007 error("negative width in bit-field '%s'",
6008 get_tok_str(v, NULL));
6009 if (v && bit_size == 0)
6010 error("zero width for bit-field '%s'",
6011 get_tok_str(v, NULL));
6013 size = type_size(&type1, &align);
6014 lbit_pos = 0;
6015 if (bit_size >= 0) {
6016 bt = type1.t & VT_BTYPE;
6017 if (bt != VT_INT &&
6018 bt != VT_BYTE &&
6019 bt != VT_SHORT &&
6020 bt != VT_ENUM)
6021 error("bitfields must have scalar type");
6022 bsize = size * 8;
6023 if (bit_size > bsize) {
6024 error("width of '%s' exceeds its type",
6025 get_tok_str(v, NULL));
6026 } else if (bit_size == bsize) {
6027 /* no need for bit fields */
6028 bit_pos = 0;
6029 } else if (bit_size == 0) {
6030 /* XXX: what to do if only padding in a
6031 structure ? */
6032 /* zero size: means to pad */
6033 if (bit_pos > 0)
6034 bit_pos = bsize;
6035 } else {
6036 /* we do not have enough room ? */
6037 if ((bit_pos + bit_size) > bsize)
6038 bit_pos = 0;
6039 lbit_pos = bit_pos;
6040 /* XXX: handle LSB first */
6041 type1.t |= VT_BITFIELD |
6042 (bit_pos << VT_STRUCT_SHIFT) |
6043 (bit_size << (VT_STRUCT_SHIFT + 6));
6044 bit_pos += bit_size;
6046 } else {
6047 bit_pos = 0;
6049 if (v) {
6050 /* add new memory data only if starting
6051 bit field */
6052 if (lbit_pos == 0) {
6053 if (a == TOK_STRUCT) {
6054 c = (c + align - 1) & -align;
6055 offset = c;
6056 c += size;
6057 } else {
6058 offset = 0;
6059 if (size > c)
6060 c = size;
6062 if (align > maxalign)
6063 maxalign = align;
6065 #if 0
6066 printf("add field %s offset=%d",
6067 get_tok_str(v, NULL), offset);
6068 if (type1.t & VT_BITFIELD) {
6069 printf(" pos=%d size=%d",
6070 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
6071 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
6073 printf("\n");
6074 #endif
6075 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
6076 *ps = ss;
6077 ps = &ss->next;
6079 if (tok == ';' || tok == TOK_EOF)
6080 break;
6081 skip(',');
6083 skip(';');
6085 skip('}');
6086 /* store size and alignment */
6087 s->c = (c + maxalign - 1) & -maxalign;
6088 s->r = maxalign;
6093 /* return 0 if no type declaration. otherwise, return the basic type
6094 and skip it.
6096 static int parse_btype(CType *type, AttributeDef *ad)
6098 int t, u, type_found;
6099 Sym *s;
6100 CType type1;
6102 memset(ad, 0, sizeof(AttributeDef));
6103 type_found = 0;
6104 t = 0;
6105 while(1) {
6106 switch(tok) {
6107 case TOK_EXTENSION:
6108 /* currently, we really ignore extension */
6109 next();
6110 continue;
6112 /* basic types */
6113 case TOK_CHAR:
6114 u = VT_BYTE;
6115 basic_type:
6116 next();
6117 basic_type1:
6118 if ((t & VT_BTYPE) != 0)
6119 error("too many basic types");
6120 t |= u;
6121 break;
6122 case TOK_VOID:
6123 u = VT_VOID;
6124 goto basic_type;
6125 case TOK_SHORT:
6126 u = VT_SHORT;
6127 goto basic_type;
6128 case TOK_INT:
6129 next();
6130 break;
6131 case TOK_LONG:
6132 next();
6133 if ((t & VT_BTYPE) == VT_DOUBLE) {
6134 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
6135 } else if ((t & VT_BTYPE) == VT_LONG) {
6136 t = (t & ~VT_BTYPE) | VT_LLONG;
6137 } else {
6138 u = VT_LONG;
6139 goto basic_type1;
6141 break;
6142 case TOK_BOOL:
6143 u = VT_BOOL;
6144 goto basic_type;
6145 case TOK_FLOAT:
6146 u = VT_FLOAT;
6147 goto basic_type;
6148 case TOK_DOUBLE:
6149 next();
6150 if ((t & VT_BTYPE) == VT_LONG) {
6151 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
6152 } else {
6153 u = VT_DOUBLE;
6154 goto basic_type1;
6156 break;
6157 case TOK_ENUM:
6158 struct_decl(&type1, VT_ENUM);
6159 basic_type2:
6160 u = type1.t;
6161 type->ref = type1.ref;
6162 goto basic_type1;
6163 case TOK_STRUCT:
6164 case TOK_UNION:
6165 struct_decl(&type1, VT_STRUCT);
6166 goto basic_type2;
6168 /* type modifiers */
6169 case TOK_CONST1:
6170 case TOK_CONST2:
6171 case TOK_CONST3:
6172 case TOK_VOLATILE1:
6173 case TOK_VOLATILE2:
6174 case TOK_VOLATILE3:
6175 case TOK_REGISTER:
6176 case TOK_SIGNED1:
6177 case TOK_SIGNED2:
6178 case TOK_SIGNED3:
6179 case TOK_AUTO:
6180 case TOK_RESTRICT1:
6181 case TOK_RESTRICT2:
6182 case TOK_RESTRICT3:
6183 next();
6184 break;
6185 case TOK_UNSIGNED:
6186 t |= VT_UNSIGNED;
6187 next();
6188 break;
6190 /* storage */
6191 case TOK_EXTERN:
6192 t |= VT_EXTERN;
6193 next();
6194 break;
6195 case TOK_STATIC:
6196 t |= VT_STATIC;
6197 next();
6198 break;
6199 case TOK_TYPEDEF:
6200 t |= VT_TYPEDEF;
6201 next();
6202 break;
6203 case TOK_INLINE1:
6204 case TOK_INLINE2:
6205 case TOK_INLINE3:
6206 t |= VT_INLINE;
6207 next();
6208 break;
6210 /* GNUC attribute */
6211 case TOK_ATTRIBUTE1:
6212 case TOK_ATTRIBUTE2:
6213 parse_attribute(ad);
6214 break;
6215 /* GNUC typeof */
6216 case TOK_TYPEOF1:
6217 case TOK_TYPEOF2:
6218 case TOK_TYPEOF3:
6219 next();
6220 parse_expr_type(&type1);
6221 goto basic_type2;
6222 default:
6223 s = sym_find(tok);
6224 if (!s || !(s->type.t & VT_TYPEDEF))
6225 goto the_end;
6226 t |= (s->type.t & ~VT_TYPEDEF);
6227 type->ref = s->type.ref;
6228 next();
6229 break;
6231 type_found = 1;
6233 the_end:
6234 /* long is never used as type */
6235 if ((t & VT_BTYPE) == VT_LONG)
6236 t = (t & ~VT_BTYPE) | VT_INT;
6237 type->t = t;
6238 return type_found;
6241 /* convert a function parameter type (array to pointer and function to
6242 function pointer) */
6243 static inline void convert_parameter_type(CType *pt)
6245 /* array must be transformed to pointer according to ANSI C */
6246 pt->t &= ~VT_ARRAY;
6247 if ((pt->t & VT_BTYPE) == VT_FUNC) {
6248 mk_pointer(pt);
6252 static void post_type(CType *type, AttributeDef *ad)
6254 int n, l, t1;
6255 Sym **plast, *s, *first;
6256 AttributeDef ad1;
6257 CType pt;
6259 if (tok == '(') {
6260 /* function declaration */
6261 next();
6262 l = 0;
6263 first = NULL;
6264 plast = &first;
6265 while (tok != ')') {
6266 /* read param name and compute offset */
6267 if (l != FUNC_OLD) {
6268 if (!parse_btype(&pt, &ad1)) {
6269 if (l) {
6270 error("invalid type");
6271 } else {
6272 l = FUNC_OLD;
6273 goto old_proto;
6276 l = FUNC_NEW;
6277 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
6278 break;
6279 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
6280 if ((pt.t & VT_BTYPE) == VT_VOID)
6281 error("parameter declared as void");
6282 } else {
6283 old_proto:
6284 n = tok;
6285 pt.t = VT_INT;
6286 next();
6288 convert_parameter_type(&pt);
6289 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
6290 *plast = s;
6291 plast = &s->next;
6292 if (tok == ',') {
6293 next();
6294 if (l == FUNC_NEW && tok == TOK_DOTS) {
6295 l = FUNC_ELLIPSIS;
6296 next();
6297 break;
6301 /* if no parameters, then old type prototype */
6302 if (l == 0)
6303 l = FUNC_OLD;
6304 skip(')');
6305 t1 = type->t & VT_STORAGE;
6306 type->t &= ~VT_STORAGE;
6307 post_type(type, ad);
6308 /* we push a anonymous symbol which will contain the function prototype */
6309 s = sym_push(SYM_FIELD, type, ad->func_call, l);
6310 s->next = first;
6311 type->t = t1 | VT_FUNC;
6312 type->ref = s;
6313 } else if (tok == '[') {
6314 /* array definition */
6315 next();
6316 n = -1;
6317 if (tok != ']') {
6318 n = expr_const();
6319 if (n < 0)
6320 error("invalid array size");
6322 skip(']');
6323 /* parse next post type */
6324 t1 = type->t & VT_STORAGE;
6325 type->t &= ~VT_STORAGE;
6326 post_type(type, ad);
6328 /* we push a anonymous symbol which will contain the array
6329 element type */
6330 s = sym_push(SYM_FIELD, type, 0, n);
6331 type->t = t1 | VT_ARRAY | VT_PTR;
6332 type->ref = s;
6336 /* Parse a type declaration (except basic type), and return the type
6337 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6338 expected. 'type' should contain the basic type. 'ad' is the
6339 attribute definition of the basic type. It can be modified by
6340 type_decl().
6342 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
6344 Sym *s;
6345 CType type1, *type2;
6347 while (tok == '*') {
6348 next();
6349 redo:
6350 switch(tok) {
6351 case TOK_CONST1:
6352 case TOK_CONST2:
6353 case TOK_CONST3:
6354 case TOK_VOLATILE1:
6355 case TOK_VOLATILE2:
6356 case TOK_VOLATILE3:
6357 case TOK_RESTRICT1:
6358 case TOK_RESTRICT2:
6359 case TOK_RESTRICT3:
6360 next();
6361 goto redo;
6363 mk_pointer(type);
6366 /* XXX: clarify attribute handling */
6367 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6368 parse_attribute(ad);
6370 /* recursive type */
6371 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6372 type1.t = 0; /* XXX: same as int */
6373 if (tok == '(') {
6374 next();
6375 /* XXX: this is not correct to modify 'ad' at this point, but
6376 the syntax is not clear */
6377 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6378 parse_attribute(ad);
6379 type_decl(&type1, ad, v, td);
6380 skip(')');
6381 } else {
6382 /* type identifier */
6383 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
6384 *v = tok;
6385 next();
6386 } else {
6387 if (!(td & TYPE_ABSTRACT))
6388 expect("identifier");
6389 *v = 0;
6392 post_type(type, ad);
6393 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6394 parse_attribute(ad);
6395 if (!type1.t)
6396 return;
6397 /* append type at the end of type1 */
6398 type2 = &type1;
6399 for(;;) {
6400 s = type2->ref;
6401 type2 = &s->type;
6402 if (!type2->t) {
6403 *type2 = *type;
6404 break;
6407 *type = type1;
6410 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6411 static int lvalue_type(int t)
6413 int bt, r;
6414 r = VT_LVAL;
6415 bt = t & VT_BTYPE;
6416 if (bt == VT_BYTE || bt == VT_BOOL)
6417 r |= VT_LVAL_BYTE;
6418 else if (bt == VT_SHORT)
6419 r |= VT_LVAL_SHORT;
6420 else
6421 return r;
6422 if (t & VT_UNSIGNED)
6423 r |= VT_LVAL_UNSIGNED;
6424 return r;
6427 /* indirection with full error checking and bound check */
6428 static void indir(void)
6430 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6431 expect("pointer");
6432 if ((vtop->r & VT_LVAL) && !nocode_wanted)
6433 gv(RC_INT);
6434 vtop->type = *pointed_type(&vtop->type);
6435 /* an array is never an lvalue */
6436 if (!(vtop->type.t & VT_ARRAY)) {
6437 vtop->r |= lvalue_type(vtop->type.t);
6438 /* if bound checking, the referenced pointer must be checked */
6439 if (do_bounds_check)
6440 vtop->r |= VT_MUSTBOUND;
6444 /* pass a parameter to a function and do type checking and casting */
6445 static void gfunc_param_typed(Sym *func, Sym *arg)
6447 int func_type;
6448 CType type;
6450 func_type = func->c;
6451 if (func_type == FUNC_OLD ||
6452 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
6453 /* default casting : only need to convert float to double */
6454 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
6455 type.t = VT_DOUBLE;
6456 gen_cast(&type);
6458 } else if (arg == NULL) {
6459 error("too many arguments to function");
6460 } else {
6461 gen_assign_cast(&arg->type);
6465 /* parse an expression of the form '(type)' or '(expr)' and return its
6466 type */
6467 static void parse_expr_type(CType *type)
6469 int n;
6470 AttributeDef ad;
6472 skip('(');
6473 if (parse_btype(type, &ad)) {
6474 type_decl(type, &ad, &n, TYPE_ABSTRACT);
6475 } else {
6476 expr_type(type);
6478 skip(')');
6481 static void vpush_tokc(int t)
6483 CType type;
6484 type.t = t;
6485 vsetc(&type, VT_CONST, &tokc);
6488 static void unary(void)
6490 int n, t, align, size, r;
6491 CType type;
6492 Sym *s;
6493 AttributeDef ad;
6495 /* XXX: GCC 2.95.3 does not generate a table although it should be
6496 better here */
6497 tok_next:
6498 switch(tok) {
6499 case TOK_EXTENSION:
6500 next();
6501 goto tok_next;
6502 case TOK_CINT:
6503 case TOK_CCHAR:
6504 case TOK_LCHAR:
6505 vpushi(tokc.i);
6506 next();
6507 break;
6508 case TOK_CUINT:
6509 vpush_tokc(VT_INT | VT_UNSIGNED);
6510 next();
6511 break;
6512 case TOK_CLLONG:
6513 vpush_tokc(VT_LLONG);
6514 next();
6515 break;
6516 case TOK_CULLONG:
6517 vpush_tokc(VT_LLONG | VT_UNSIGNED);
6518 next();
6519 break;
6520 case TOK_CFLOAT:
6521 vpush_tokc(VT_FLOAT);
6522 next();
6523 break;
6524 case TOK_CDOUBLE:
6525 vpush_tokc(VT_DOUBLE);
6526 next();
6527 break;
6528 case TOK_CLDOUBLE:
6529 vpush_tokc(VT_LDOUBLE);
6530 next();
6531 break;
6532 case TOK___FUNCTION__:
6533 if (!gnu_ext)
6534 goto tok_identifier;
6535 /* fall thru */
6536 case TOK___FUNC__:
6538 void *ptr;
6539 int len;
6540 /* special function name identifier */
6541 len = strlen(funcname) + 1;
6542 /* generate char[len] type */
6543 type.t = VT_BYTE;
6544 mk_pointer(&type);
6545 type.t |= VT_ARRAY;
6546 type.ref->c = len;
6547 vpush_ref(&type, data_section, data_section->data_offset, len);
6548 ptr = section_ptr_add(data_section, len);
6549 memcpy(ptr, funcname, len);
6550 next();
6552 break;
6553 case TOK_LSTR:
6554 t = VT_INT;
6555 goto str_init;
6556 case TOK_STR:
6557 /* string parsing */
6558 t = VT_BYTE;
6559 str_init:
6560 type.t = t;
6561 mk_pointer(&type);
6562 type.t |= VT_ARRAY;
6563 memset(&ad, 0, sizeof(AttributeDef));
6564 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
6565 break;
6566 case '(':
6567 next();
6568 /* cast ? */
6569 if (parse_btype(&type, &ad)) {
6570 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
6571 skip(')');
6572 /* check ISOC99 compound literal */
6573 if (tok == '{') {
6574 /* data is allocated locally by default */
6575 if (global_expr)
6576 r = VT_CONST;
6577 else
6578 r = VT_LOCAL;
6579 /* all except arrays are lvalues */
6580 if (!(type.t & VT_ARRAY))
6581 r |= lvalue_type(type.t);
6582 memset(&ad, 0, sizeof(AttributeDef));
6583 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
6584 } else {
6585 unary();
6586 gen_cast(&type);
6588 } else if (tok == '{') {
6589 /* save all registers */
6590 save_regs(0);
6591 /* statement expression : we do not accept break/continue
6592 inside as GCC does */
6593 block(NULL, NULL, NULL, NULL, 0, 1);
6594 skip(')');
6595 } else {
6596 gexpr();
6597 skip(')');
6599 break;
6600 case '*':
6601 next();
6602 unary();
6603 indir();
6604 break;
6605 case '&':
6606 next();
6607 unary();
6608 /* functions names must be treated as function pointers,
6609 except for unary '&' and sizeof. Since we consider that
6610 functions are not lvalues, we only have to handle it
6611 there and in function calls. */
6612 /* arrays can also be used although they are not lvalues */
6613 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
6614 !(vtop->type.t & VT_ARRAY))
6615 test_lvalue();
6616 mk_pointer(&vtop->type);
6617 gaddrof();
6618 break;
6619 case '!':
6620 next();
6621 unary();
6622 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
6623 vtop->c.i = !vtop->c.i;
6624 else if ((vtop->r & VT_VALMASK) == VT_CMP)
6625 vtop->c.i = vtop->c.i ^ 1;
6626 else
6627 vseti(VT_JMP, gtst(1, 0));
6628 break;
6629 case '~':
6630 next();
6631 unary();
6632 vpushi(-1);
6633 gen_op('^');
6634 break;
6635 case '+':
6636 next();
6637 /* in order to force cast, we add zero */
6638 unary();
6639 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
6640 error("pointer not accepted for unary plus");
6641 vpushi(0);
6642 gen_op('+');
6643 break;
6644 case TOK_SIZEOF:
6645 case TOK_ALIGNOF1:
6646 case TOK_ALIGNOF2:
6647 t = tok;
6648 next();
6649 if (tok == '(') {
6650 parse_expr_type(&type);
6651 } else {
6652 unary_type(&type);
6654 size = type_size(&type, &align);
6655 if (t == TOK_SIZEOF)
6656 vpushi(size);
6657 else
6658 vpushi(align);
6659 break;
6661 case TOK_INC:
6662 case TOK_DEC:
6663 t = tok;
6664 next();
6665 unary();
6666 inc(0, t);
6667 break;
6668 case '-':
6669 next();
6670 vpushi(0);
6671 unary();
6672 gen_op('-');
6673 break;
6674 case TOK_LAND:
6675 if (!gnu_ext)
6676 goto tok_identifier;
6677 next();
6678 /* allow to take the address of a label */
6679 if (tok < TOK_UIDENT)
6680 expect("label identifier");
6681 s = label_find(tok);
6682 if (!s) {
6683 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
6684 } else {
6685 if (s->r == LABEL_DECLARED)
6686 s->r = LABEL_FORWARD;
6688 if (!s->type.t) {
6689 s->type.t = VT_VOID;
6690 mk_pointer(&s->type);
6691 s->type.t |= VT_STATIC;
6693 vset(&s->type, VT_CONST | VT_SYM, 0);
6694 vtop->sym = s;
6695 next();
6696 break;
6697 default:
6698 tok_identifier:
6699 t = tok;
6700 next();
6701 if (t < TOK_UIDENT)
6702 expect("identifier");
6703 s = sym_find(t);
6704 if (!s) {
6705 if (tok != '(')
6706 error("'%s' undeclared", get_tok_str(t, NULL));
6707 /* for simple function calls, we tolerate undeclared
6708 external reference to int() function */
6709 s = external_global_sym(t, &func_old_type, 0);
6711 vset(&s->type, s->r, s->c);
6712 /* if forward reference, we must point to s */
6713 if (vtop->r & VT_SYM) {
6714 vtop->sym = s;
6715 vtop->c.ul = 0;
6717 break;
6720 /* post operations */
6721 while (1) {
6722 if (tok == TOK_INC || tok == TOK_DEC) {
6723 inc(1, tok);
6724 next();
6725 } else if (tok == '.' || tok == TOK_ARROW) {
6726 /* field */
6727 if (tok == TOK_ARROW)
6728 indir();
6729 test_lvalue();
6730 gaddrof();
6731 next();
6732 /* expect pointer on structure */
6733 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
6734 expect("struct or union");
6735 s = vtop->type.ref;
6736 /* find field */
6737 tok |= SYM_FIELD;
6738 while ((s = s->next) != NULL) {
6739 if (s->v == tok)
6740 break;
6742 if (!s)
6743 error("field not found");
6744 /* add field offset to pointer */
6745 vtop->type = char_pointer_type; /* change type to 'char *' */
6746 vpushi(s->c);
6747 gen_op('+');
6748 /* change type to field type, and set to lvalue */
6749 vtop->type = s->type;
6750 /* an array is never an lvalue */
6751 if (!(vtop->type.t & VT_ARRAY)) {
6752 vtop->r |= lvalue_type(vtop->type.t);
6753 /* if bound checking, the referenced pointer must be checked */
6754 if (do_bounds_check)
6755 vtop->r |= VT_MUSTBOUND;
6757 next();
6758 } else if (tok == '[') {
6759 next();
6760 gexpr();
6761 gen_op('+');
6762 indir();
6763 skip(']');
6764 } else if (tok == '(') {
6765 SValue ret;
6766 Sym *sa;
6767 int nb_args;
6769 /* function call */
6770 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
6771 /* pointer test (no array accepted) */
6772 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
6773 vtop->type = *pointed_type(&vtop->type);
6774 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
6775 goto error_func;
6776 } else {
6777 error_func:
6778 expect("function pointer");
6780 } else {
6781 vtop->r &= ~VT_LVAL; /* no lvalue */
6783 /* get return type */
6784 s = vtop->type.ref;
6785 next();
6786 sa = s->next; /* first parameter */
6787 nb_args = 0;
6788 /* compute first implicit argument if a structure is returned */
6789 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6790 /* get some space for the returned structure */
6791 size = type_size(&s->type, &align);
6792 loc = (loc - size) & -align;
6793 ret.type = s->type;
6794 ret.r = VT_LOCAL | VT_LVAL;
6795 /* pass it as 'int' to avoid structure arg passing
6796 problems */
6797 vseti(VT_LOCAL, loc);
6798 ret.c = vtop->c;
6799 nb_args++;
6800 } else {
6801 ret.type = s->type;
6802 ret.r2 = VT_CONST;
6803 /* return in register */
6804 if (is_float(ret.type.t)) {
6805 ret.r = REG_FRET;
6806 } else {
6807 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
6808 ret.r2 = REG_LRET;
6809 ret.r = REG_IRET;
6811 ret.c.i = 0;
6813 if (tok != ')') {
6814 for(;;) {
6815 expr_eq();
6816 gfunc_param_typed(s, sa);
6817 nb_args++;
6818 if (sa)
6819 sa = sa->next;
6820 if (tok == ')')
6821 break;
6822 skip(',');
6825 if (sa)
6826 error("too few arguments to function");
6827 skip(')');
6828 if (!nocode_wanted) {
6829 gfunc_call(nb_args);
6830 } else {
6831 vtop -= (nb_args + 1);
6833 /* return value */
6834 vsetc(&ret.type, ret.r, &ret.c);
6835 vtop->r2 = ret.r2;
6836 } else {
6837 break;
6842 static void uneq(void)
6844 int t;
6846 unary();
6847 if (tok == '=' ||
6848 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
6849 tok == TOK_A_XOR || tok == TOK_A_OR ||
6850 tok == TOK_A_SHL || tok == TOK_A_SAR) {
6851 test_lvalue();
6852 t = tok;
6853 next();
6854 if (t == '=') {
6855 expr_eq();
6856 } else {
6857 vdup();
6858 expr_eq();
6859 gen_op(t & 0x7f);
6861 vstore();
6865 static void expr_prod(void)
6867 int t;
6869 uneq();
6870 while (tok == '*' || tok == '/' || tok == '%') {
6871 t = tok;
6872 next();
6873 uneq();
6874 gen_op(t);
6878 static void expr_sum(void)
6880 int t;
6882 expr_prod();
6883 while (tok == '+' || tok == '-') {
6884 t = tok;
6885 next();
6886 expr_prod();
6887 gen_op(t);
6891 static void expr_shift(void)
6893 int t;
6895 expr_sum();
6896 while (tok == TOK_SHL || tok == TOK_SAR) {
6897 t = tok;
6898 next();
6899 expr_sum();
6900 gen_op(t);
6904 static void expr_cmp(void)
6906 int t;
6908 expr_shift();
6909 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
6910 tok == TOK_ULT || tok == TOK_UGE) {
6911 t = tok;
6912 next();
6913 expr_shift();
6914 gen_op(t);
6918 static void expr_cmpeq(void)
6920 int t;
6922 expr_cmp();
6923 while (tok == TOK_EQ || tok == TOK_NE) {
6924 t = tok;
6925 next();
6926 expr_cmp();
6927 gen_op(t);
6931 static void expr_and(void)
6933 expr_cmpeq();
6934 while (tok == '&') {
6935 next();
6936 expr_cmpeq();
6937 gen_op('&');
6941 static void expr_xor(void)
6943 expr_and();
6944 while (tok == '^') {
6945 next();
6946 expr_and();
6947 gen_op('^');
6951 static void expr_or(void)
6953 expr_xor();
6954 while (tok == '|') {
6955 next();
6956 expr_xor();
6957 gen_op('|');
6961 /* XXX: fix this mess */
6962 static void expr_land_const(void)
6964 expr_or();
6965 while (tok == TOK_LAND) {
6966 next();
6967 expr_or();
6968 gen_op(TOK_LAND);
6972 /* XXX: fix this mess */
6973 static void expr_lor_const(void)
6975 expr_land_const();
6976 while (tok == TOK_LOR) {
6977 next();
6978 expr_land_const();
6979 gen_op(TOK_LOR);
6983 /* only used if non constant */
6984 static void expr_land(void)
6986 int t;
6988 expr_or();
6989 if (tok == TOK_LAND) {
6990 t = 0;
6991 for(;;) {
6992 t = gtst(1, t);
6993 if (tok != TOK_LAND) {
6994 vseti(VT_JMPI, t);
6995 break;
6997 next();
6998 expr_or();
7003 static void expr_lor(void)
7005 int t;
7007 expr_land();
7008 if (tok == TOK_LOR) {
7009 t = 0;
7010 for(;;) {
7011 t = gtst(0, t);
7012 if (tok != TOK_LOR) {
7013 vseti(VT_JMP, t);
7014 break;
7016 next();
7017 expr_land();
7022 /* XXX: better constant handling */
7023 static void expr_eq(void)
7025 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
7026 SValue sv;
7027 CType type, type1, type2;
7029 if (const_wanted) {
7030 int c1, c;
7031 expr_lor_const();
7032 if (tok == '?') {
7033 c = vtop->c.i;
7034 vpop();
7035 next();
7036 if (tok == ':' && gnu_ext) {
7037 c1 = c;
7038 } else {
7039 gexpr();
7040 c1 = vtop->c.i;
7041 vpop();
7043 skip(':');
7044 expr_eq();
7045 if (c)
7046 vtop->c.i = c1;
7048 } else {
7049 expr_lor();
7050 if (tok == '?') {
7051 next();
7052 if (vtop != vstack) {
7053 /* needed to avoid having different registers saved in
7054 each branch */
7055 if (is_float(vtop->type.t))
7056 rc = RC_FLOAT;
7057 else
7058 rc = RC_INT;
7059 gv(rc);
7060 save_regs(1);
7062 if (tok == ':' && gnu_ext) {
7063 gv_dup();
7064 tt = gtst(1, 0);
7065 } else {
7066 tt = gtst(1, 0);
7067 gexpr();
7069 type1 = vtop->type;
7070 sv = *vtop; /* save value to handle it later */
7071 vtop--; /* no vpop so that FP stack is not flushed */
7072 skip(':');
7073 u = gjmp(0);
7074 gsym(tt);
7075 expr_eq();
7076 type2 = vtop->type;
7078 t1 = type1.t;
7079 bt1 = t1 & VT_BTYPE;
7080 t2 = type2.t;
7081 bt2 = t2 & VT_BTYPE;
7082 /* cast operands to correct type according to ISOC rules */
7083 if (is_float(bt1) || is_float(bt2)) {
7084 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
7085 type.t = VT_LDOUBLE;
7086 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
7087 type.t = VT_DOUBLE;
7088 } else {
7089 type.t = VT_FLOAT;
7091 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
7092 /* cast to biggest op */
7093 type.t = VT_LLONG;
7094 /* convert to unsigned if it does not fit in a long long */
7095 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
7096 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
7097 type.t |= VT_UNSIGNED;
7098 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
7099 /* XXX: test pointer compatibility */
7100 type = type1;
7101 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
7102 /* XXX: test structure compatibility */
7103 type = type1;
7104 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
7105 /* NOTE: as an extension, we accept void on only one side */
7106 type.t = VT_VOID;
7107 } else {
7108 /* integer operations */
7109 type.t = VT_INT;
7110 /* convert to unsigned if it does not fit in an integer */
7111 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
7112 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
7113 type.t |= VT_UNSIGNED;
7116 /* now we convert second operand */
7117 gen_cast(&type);
7118 rc = RC_INT;
7119 if (is_float(type.t)) {
7120 rc = RC_FLOAT;
7121 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
7122 /* for long longs, we use fixed registers to avoid having
7123 to handle a complicated move */
7124 rc = RC_IRET;
7127 r2 = gv(rc);
7128 /* this is horrible, but we must also convert first
7129 operand */
7130 tt = gjmp(0);
7131 gsym(u);
7132 /* put again first value and cast it */
7133 *vtop = sv;
7134 gen_cast(&type);
7135 r1 = gv(rc);
7136 move_reg(r2, r1);
7137 vtop->r = r2;
7138 gsym(tt);
7143 static void gexpr(void)
7145 while (1) {
7146 expr_eq();
7147 if (tok != ',')
7148 break;
7149 vpop();
7150 next();
7154 /* parse an expression and return its type without any side effect. */
7155 static void expr_type(CType *type)
7157 int a;
7159 a = nocode_wanted;
7160 nocode_wanted = 1;
7161 gexpr();
7162 *type = vtop->type;
7163 vpop();
7164 nocode_wanted = a;
7167 /* parse a unary expression and return its type without any side
7168 effect. */
7169 static void unary_type(CType *type)
7171 int a;
7173 a = nocode_wanted;
7174 nocode_wanted = 1;
7175 unary();
7176 *type = vtop->type;
7177 vpop();
7178 nocode_wanted = a;
7181 /* parse a constant expression and return value in vtop. */
7182 static void expr_const1(void)
7184 int a;
7185 a = const_wanted;
7186 const_wanted = 1;
7187 expr_eq();
7188 const_wanted = a;
7191 /* parse an integer constant and return its value. */
7192 static int expr_const(void)
7194 int c;
7195 expr_const1();
7196 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
7197 expect("constant expression");
7198 c = vtop->c.i;
7199 vpop();
7200 return c;
7203 /* return the label token if current token is a label, otherwise
7204 return zero */
7205 static int is_label(void)
7207 int last_tok;
7209 /* fast test first */
7210 if (tok < TOK_UIDENT)
7211 return 0;
7212 /* no need to save tokc because tok is an identifier */
7213 last_tok = tok;
7214 next();
7215 if (tok == ':') {
7216 next();
7217 return last_tok;
7218 } else {
7219 unget_tok(last_tok);
7220 return 0;
7224 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
7225 int case_reg, int is_expr)
7227 int a, b, c, d;
7228 Sym *s;
7230 /* generate line number info */
7231 if (do_debug &&
7232 (last_line_num != file->line_num || last_ind != ind)) {
7233 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
7234 last_ind = ind;
7235 last_line_num = file->line_num;
7238 if (is_expr) {
7239 /* default return value is (void) */
7240 vpushi(0);
7241 vtop->type.t = VT_VOID;
7244 if (tok == TOK_IF) {
7245 /* if test */
7246 next();
7247 skip('(');
7248 gexpr();
7249 skip(')');
7250 a = gtst(1, 0);
7251 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7252 c = tok;
7253 if (c == TOK_ELSE) {
7254 next();
7255 d = gjmp(0);
7256 gsym(a);
7257 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7258 gsym(d); /* patch else jmp */
7259 } else
7260 gsym(a);
7261 } else if (tok == TOK_WHILE) {
7262 next();
7263 d = ind;
7264 skip('(');
7265 gexpr();
7266 skip(')');
7267 a = gtst(1, 0);
7268 b = 0;
7269 block(&a, &b, case_sym, def_sym, case_reg, 0);
7270 gjmp_addr(d);
7271 gsym(a);
7272 gsym_addr(b, d);
7273 } else if (tok == '{') {
7274 Sym *llabel;
7276 next();
7277 /* record local declaration stack position */
7278 s = local_stack;
7279 llabel = local_label_stack;
7280 /* handle local labels declarations */
7281 if (tok == TOK_LABEL) {
7282 next();
7283 for(;;) {
7284 if (tok < TOK_UIDENT)
7285 expect("label identifier");
7286 label_push(&local_label_stack, tok, LABEL_DECLARED);
7287 next();
7288 if (tok == ',') {
7289 next();
7290 } else {
7291 skip(';');
7292 break;
7296 while (tok != '}') {
7297 decl(VT_LOCAL);
7298 if (tok != '}') {
7299 if (is_expr)
7300 vpop();
7301 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
7304 /* pop locally defined labels */
7305 label_pop(&local_label_stack, llabel);
7306 /* pop locally defined symbols */
7307 sym_pop(&local_stack, s);
7308 next();
7309 } else if (tok == TOK_RETURN) {
7310 next();
7311 if (tok != ';') {
7312 gexpr();
7313 gen_assign_cast(&func_vt);
7314 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
7315 CType type;
7316 /* if returning structure, must copy it to implicit
7317 first pointer arg location */
7318 type = func_vt;
7319 mk_pointer(&type);
7320 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
7321 indir();
7322 vswap();
7323 /* copy structure value to pointer */
7324 vstore();
7325 } else if (is_float(func_vt.t)) {
7326 gv(RC_FRET);
7327 } else {
7328 gv(RC_IRET);
7330 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
7332 skip(';');
7333 rsym = gjmp(rsym); /* jmp */
7334 } else if (tok == TOK_BREAK) {
7335 /* compute jump */
7336 if (!bsym)
7337 error("cannot break");
7338 *bsym = gjmp(*bsym);
7339 next();
7340 skip(';');
7341 } else if (tok == TOK_CONTINUE) {
7342 /* compute jump */
7343 if (!csym)
7344 error("cannot continue");
7345 *csym = gjmp(*csym);
7346 next();
7347 skip(';');
7348 } else if (tok == TOK_FOR) {
7349 int e;
7350 next();
7351 skip('(');
7352 if (tok != ';') {
7353 gexpr();
7354 vpop();
7356 skip(';');
7357 d = ind;
7358 c = ind;
7359 a = 0;
7360 b = 0;
7361 if (tok != ';') {
7362 gexpr();
7363 a = gtst(1, 0);
7365 skip(';');
7366 if (tok != ')') {
7367 e = gjmp(0);
7368 c = ind;
7369 gexpr();
7370 vpop();
7371 gjmp_addr(d);
7372 gsym(e);
7374 skip(')');
7375 block(&a, &b, case_sym, def_sym, case_reg, 0);
7376 gjmp_addr(c);
7377 gsym(a);
7378 gsym_addr(b, c);
7379 } else
7380 if (tok == TOK_DO) {
7381 next();
7382 a = 0;
7383 b = 0;
7384 d = ind;
7385 block(&a, &b, case_sym, def_sym, case_reg, 0);
7386 skip(TOK_WHILE);
7387 skip('(');
7388 gsym(b);
7389 gexpr();
7390 c = gtst(0, 0);
7391 gsym_addr(c, d);
7392 skip(')');
7393 gsym(a);
7394 skip(';');
7395 } else
7396 if (tok == TOK_SWITCH) {
7397 next();
7398 skip('(');
7399 gexpr();
7400 /* XXX: other types than integer */
7401 case_reg = gv(RC_INT);
7402 vpop();
7403 skip(')');
7404 a = 0;
7405 b = gjmp(0); /* jump to first case */
7406 c = 0;
7407 block(&a, csym, &b, &c, case_reg, 0);
7408 /* if no default, jmp after switch */
7409 if (c == 0)
7410 c = ind;
7411 /* default label */
7412 gsym_addr(b, c);
7413 /* break label */
7414 gsym(a);
7415 } else
7416 if (tok == TOK_CASE) {
7417 int v1, v2;
7418 if (!case_sym)
7419 expect("switch");
7420 next();
7421 v1 = expr_const();
7422 v2 = v1;
7423 if (gnu_ext && tok == TOK_DOTS) {
7424 next();
7425 v2 = expr_const();
7426 if (v2 < v1)
7427 warning("empty case range");
7429 /* since a case is like a label, we must skip it with a jmp */
7430 b = gjmp(0);
7431 gsym(*case_sym);
7432 vseti(case_reg, 0);
7433 vpushi(v1);
7434 if (v1 == v2) {
7435 gen_op(TOK_EQ);
7436 *case_sym = gtst(1, 0);
7437 } else {
7438 gen_op(TOK_GE);
7439 *case_sym = gtst(1, 0);
7440 vseti(case_reg, 0);
7441 vpushi(v2);
7442 gen_op(TOK_LE);
7443 *case_sym = gtst(1, *case_sym);
7445 gsym(b);
7446 skip(':');
7447 is_expr = 0;
7448 goto block_after_label;
7449 } else
7450 if (tok == TOK_DEFAULT) {
7451 next();
7452 skip(':');
7453 if (!def_sym)
7454 expect("switch");
7455 if (*def_sym)
7456 error("too many 'default'");
7457 *def_sym = ind;
7458 is_expr = 0;
7459 goto block_after_label;
7460 } else
7461 if (tok == TOK_GOTO) {
7462 next();
7463 if (tok == '*' && gnu_ext) {
7464 /* computed goto */
7465 next();
7466 gexpr();
7467 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
7468 expect("pointer");
7469 ggoto();
7470 } else if (tok >= TOK_UIDENT) {
7471 s = label_find(tok);
7472 /* put forward definition if needed */
7473 if (!s) {
7474 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
7475 } else {
7476 if (s->r == LABEL_DECLARED)
7477 s->r = LABEL_FORWARD;
7479 /* label already defined */
7480 if (s->r & LABEL_FORWARD)
7481 s->next = (void *)gjmp((long)s->next);
7482 else
7483 gjmp_addr((long)s->next);
7484 next();
7485 } else {
7486 expect("label identifier");
7488 skip(';');
7489 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
7490 asm_instr();
7491 } else {
7492 b = is_label();
7493 if (b) {
7494 /* label case */
7495 s = label_find(b);
7496 if (s) {
7497 if (s->r == LABEL_DEFINED)
7498 error("duplicate label '%s'", get_tok_str(s->v, NULL));
7499 gsym((long)s->next);
7500 s->r = LABEL_DEFINED;
7501 } else {
7502 s = label_push(&global_label_stack, b, LABEL_DEFINED);
7504 s->next = (void *)ind;
7505 /* we accept this, but it is a mistake */
7506 block_after_label:
7507 if (tok == '}') {
7508 warning("deprecated use of label at end of compound statement");
7509 } else {
7510 if (is_expr)
7511 vpop();
7512 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
7514 } else {
7515 /* expression case */
7516 if (tok != ';') {
7517 if (is_expr) {
7518 vpop();
7519 gexpr();
7520 } else {
7521 gexpr();
7522 vpop();
7525 skip(';');
7530 /* t is the array or struct type. c is the array or struct
7531 address. cur_index/cur_field is the pointer to the current
7532 value. 'size_only' is true if only size info is needed (only used
7533 in arrays) */
7534 static void decl_designator(CType *type, Section *sec, unsigned long c,
7535 int *cur_index, Sym **cur_field,
7536 int size_only)
7538 Sym *s, *f;
7539 int notfirst, index, index_last, align, l, nb_elems, elem_size;
7540 CType type1;
7542 notfirst = 0;
7543 elem_size = 0;
7544 nb_elems = 1;
7545 if (gnu_ext && (l = is_label()) != 0)
7546 goto struct_field;
7547 while (tok == '[' || tok == '.') {
7548 if (tok == '[') {
7549 if (!(type->t & VT_ARRAY))
7550 expect("array type");
7551 s = type->ref;
7552 next();
7553 index = expr_const();
7554 if (index < 0 || (s->c >= 0 && index >= s->c))
7555 expect("invalid index");
7556 if (tok == TOK_DOTS && gnu_ext) {
7557 next();
7558 index_last = expr_const();
7559 if (index_last < 0 ||
7560 (s->c >= 0 && index_last >= s->c) ||
7561 index_last < index)
7562 expect("invalid index");
7563 } else {
7564 index_last = index;
7566 skip(']');
7567 if (!notfirst)
7568 *cur_index = index_last;
7569 type = pointed_type(type);
7570 elem_size = type_size(type, &align);
7571 c += index * elem_size;
7572 /* NOTE: we only support ranges for last designator */
7573 nb_elems = index_last - index + 1;
7574 if (nb_elems != 1) {
7575 notfirst = 1;
7576 break;
7578 } else {
7579 next();
7580 l = tok;
7581 next();
7582 struct_field:
7583 if ((type->t & VT_BTYPE) != VT_STRUCT)
7584 expect("struct/union type");
7585 s = type->ref;
7586 l |= SYM_FIELD;
7587 f = s->next;
7588 while (f) {
7589 if (f->v == l)
7590 break;
7591 f = f->next;
7593 if (!f)
7594 expect("field");
7595 if (!notfirst)
7596 *cur_field = f;
7597 /* XXX: fix this mess by using explicit storage field */
7598 type1 = f->type;
7599 type1.t |= (type->t & ~VT_TYPE);
7600 type = &type1;
7601 c += f->c;
7603 notfirst = 1;
7605 if (notfirst) {
7606 if (tok == '=') {
7607 next();
7608 } else {
7609 if (!gnu_ext)
7610 expect("=");
7612 } else {
7613 if (type->t & VT_ARRAY) {
7614 index = *cur_index;
7615 type = pointed_type(type);
7616 c += index * type_size(type, &align);
7617 } else {
7618 f = *cur_field;
7619 if (!f)
7620 error("too many field init");
7621 /* XXX: fix this mess by using explicit storage field */
7622 type1 = f->type;
7623 type1.t |= (type->t & ~VT_TYPE);
7624 type = &type1;
7625 c += f->c;
7628 decl_initializer(type, sec, c, 0, size_only);
7630 /* XXX: make it more general */
7631 if (!size_only && nb_elems > 1) {
7632 unsigned long c_end;
7633 uint8_t *src, *dst;
7634 int i;
7636 if (!sec)
7637 error("range init not supported yet for dynamic storage");
7638 c_end = c + nb_elems * elem_size;
7639 if (c_end > sec->data_allocated)
7640 section_realloc(sec, c_end);
7641 src = sec->data + c;
7642 dst = src;
7643 for(i = 1; i < nb_elems; i++) {
7644 dst += elem_size;
7645 memcpy(dst, src, elem_size);
7650 #define EXPR_VAL 0
7651 #define EXPR_CONST 1
7652 #define EXPR_ANY 2
7654 /* store a value or an expression directly in global data or in local array */
7655 static void init_putv(CType *type, Section *sec, unsigned long c,
7656 int v, int expr_type)
7658 int saved_global_expr, bt, bit_pos, bit_size;
7659 void *ptr;
7660 unsigned long long bit_mask;
7662 switch(expr_type) {
7663 case EXPR_VAL:
7664 vpushi(v);
7665 break;
7666 case EXPR_CONST:
7667 /* compound literals must be allocated globally in this case */
7668 saved_global_expr = global_expr;
7669 global_expr = 1;
7670 expr_const1();
7671 global_expr = saved_global_expr;
7672 /* NOTE: symbols are accepted */
7673 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
7674 error("initializer element is not constant");
7675 break;
7676 case EXPR_ANY:
7677 expr_eq();
7678 break;
7681 if (sec) {
7682 /* XXX: not portable */
7683 /* XXX: generate error if incorrect relocation */
7684 gen_assign_cast(type);
7685 bt = type->t & VT_BTYPE;
7686 ptr = sec->data + c;
7687 /* XXX: make code faster ? */
7688 if (!(type->t & VT_BITFIELD)) {
7689 bit_pos = 0;
7690 bit_size = 32;
7691 bit_mask = -1LL;
7692 } else {
7693 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
7694 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
7695 bit_mask = (1LL << bit_size) - 1;
7697 if ((vtop->r & VT_SYM) &&
7698 (bt == VT_BYTE ||
7699 bt == VT_SHORT ||
7700 bt == VT_DOUBLE ||
7701 bt == VT_LDOUBLE ||
7702 bt == VT_LLONG ||
7703 (bt == VT_INT && bit_size != 32)))
7704 error("initializer element is not computable at load time");
7705 switch(bt) {
7706 case VT_BYTE:
7707 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7708 break;
7709 case VT_SHORT:
7710 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7711 break;
7712 case VT_DOUBLE:
7713 *(double *)ptr = vtop->c.d;
7714 break;
7715 case VT_LDOUBLE:
7716 *(long double *)ptr = vtop->c.ld;
7717 break;
7718 case VT_LLONG:
7719 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
7720 break;
7721 default:
7722 if (vtop->r & VT_SYM) {
7723 greloc(sec, vtop->sym, c, R_DATA_32);
7725 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7726 break;
7728 vtop--;
7729 } else {
7730 vset(type, VT_LOCAL, c);
7731 vswap();
7732 vstore();
7733 vpop();
7737 /* put zeros for variable based init */
7738 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
7740 if (sec) {
7741 /* nothing to do because globals are already set to zero */
7742 } else {
7743 vpush_global_sym(&func_old_type, TOK_memset);
7744 vseti(VT_LOCAL, c);
7745 vpushi(0);
7746 vpushi(size);
7747 gfunc_call(3);
7751 /* 't' contains the type and storage info. 'c' is the offset of the
7752 object in section 'sec'. If 'sec' is NULL, it means stack based
7753 allocation. 'first' is true if array '{' must be read (multi
7754 dimension implicit array init handling). 'size_only' is true if
7755 size only evaluation is wanted (only for arrays). */
7756 static void decl_initializer(CType *type, Section *sec, unsigned long c,
7757 int first, int size_only)
7759 int index, array_length, n, no_oblock, nb, parlevel, i;
7760 int size1, align1, expr_type;
7761 Sym *s, *f;
7762 CType *t1;
7764 if (type->t & VT_ARRAY) {
7765 s = type->ref;
7766 n = s->c;
7767 array_length = 0;
7768 t1 = pointed_type(type);
7769 size1 = type_size(t1, &align1);
7771 no_oblock = 1;
7772 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
7773 tok == '{') {
7774 skip('{');
7775 no_oblock = 0;
7778 /* only parse strings here if correct type (otherwise: handle
7779 them as ((w)char *) expressions */
7780 if ((tok == TOK_LSTR &&
7781 (t1->t & VT_BTYPE) == VT_INT) ||
7782 (tok == TOK_STR &&
7783 (t1->t & VT_BTYPE) == VT_BYTE)) {
7784 while (tok == TOK_STR || tok == TOK_LSTR) {
7785 int cstr_len, ch;
7786 CString *cstr;
7788 cstr = tokc.cstr;
7789 /* compute maximum number of chars wanted */
7790 if (tok == TOK_STR)
7791 cstr_len = cstr->size;
7792 else
7793 cstr_len = cstr->size / sizeof(int);
7794 cstr_len--;
7795 nb = cstr_len;
7796 if (n >= 0 && nb > (n - array_length))
7797 nb = n - array_length;
7798 if (!size_only) {
7799 if (cstr_len > nb)
7800 warning("initializer-string for array is too long");
7801 /* in order to go faster for common case (char
7802 string in global variable, we handle it
7803 specifically */
7804 if (sec && tok == TOK_STR && size1 == 1) {
7805 memcpy(sec->data + c + array_length, cstr->data, nb);
7806 } else {
7807 for(i=0;i<nb;i++) {
7808 if (tok == TOK_STR)
7809 ch = ((unsigned char *)cstr->data)[i];
7810 else
7811 ch = ((int *)cstr->data)[i];
7812 init_putv(t1, sec, c + (array_length + i) * size1,
7813 ch, EXPR_VAL);
7817 array_length += nb;
7818 next();
7820 /* only add trailing zero if enough storage (no
7821 warning in this case since it is standard) */
7822 if (n < 0 || array_length < n) {
7823 if (!size_only) {
7824 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
7826 array_length++;
7828 } else {
7829 index = 0;
7830 while (tok != '}') {
7831 decl_designator(type, sec, c, &index, NULL, size_only);
7832 if (n >= 0 && index >= n)
7833 error("index too large");
7834 /* must put zero in holes (note that doing it that way
7835 ensures that it even works with designators) */
7836 if (!size_only && array_length < index) {
7837 init_putz(t1, sec, c + array_length * size1,
7838 (index - array_length) * size1);
7840 index++;
7841 if (index > array_length)
7842 array_length = index;
7843 /* special test for multi dimensional arrays (may not
7844 be strictly correct if designators are used at the
7845 same time) */
7846 if (index >= n && no_oblock)
7847 break;
7848 if (tok == '}')
7849 break;
7850 skip(',');
7853 if (!no_oblock)
7854 skip('}');
7855 /* put zeros at the end */
7856 if (!size_only && n >= 0 && array_length < n) {
7857 init_putz(t1, sec, c + array_length * size1,
7858 (n - array_length) * size1);
7860 /* patch type size if needed */
7861 if (n < 0)
7862 s->c = array_length;
7863 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
7864 (sec || !first || tok == '{')) {
7865 int par_count;
7867 /* NOTE: the previous test is a specific case for automatic
7868 struct/union init */
7869 /* XXX: union needs only one init */
7871 /* XXX: this test is incorrect for local initializers
7872 beginning with ( without {. It would be much more difficult
7873 to do it correctly (ideally, the expression parser should
7874 be used in all cases) */
7875 par_count = 0;
7876 if (tok == '(') {
7877 AttributeDef ad1;
7878 CType type1;
7879 next();
7880 while (tok == '(') {
7881 par_count++;
7882 next();
7884 if (!parse_btype(&type1, &ad1))
7885 expect("cast");
7886 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
7887 if (!is_compatible_types(type, &type1))
7888 error("invalid type for cast");
7889 skip(')');
7891 no_oblock = 1;
7892 if (first || tok == '{') {
7893 skip('{');
7894 no_oblock = 0;
7896 s = type->ref;
7897 f = s->next;
7898 array_length = 0;
7899 index = 0;
7900 n = s->c;
7901 while (tok != '}') {
7902 decl_designator(type, sec, c, NULL, &f, size_only);
7903 index = f->c;
7904 if (!size_only && array_length < index) {
7905 init_putz(type, sec, c + array_length,
7906 index - array_length);
7908 index = index + type_size(&f->type, &align1);
7909 if (index > array_length)
7910 array_length = index;
7911 f = f->next;
7912 if (no_oblock && f == NULL)
7913 break;
7914 if (tok == '}')
7915 break;
7916 skip(',');
7918 /* put zeros at the end */
7919 if (!size_only && array_length < n) {
7920 init_putz(type, sec, c + array_length,
7921 n - array_length);
7923 if (!no_oblock)
7924 skip('}');
7925 while (par_count) {
7926 skip(')');
7927 par_count--;
7929 } else if (tok == '{') {
7930 next();
7931 decl_initializer(type, sec, c, first, size_only);
7932 skip('}');
7933 } else if (size_only) {
7934 /* just skip expression */
7935 parlevel = 0;
7936 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
7937 tok != -1) {
7938 if (tok == '(')
7939 parlevel++;
7940 else if (tok == ')')
7941 parlevel--;
7942 next();
7944 } else {
7945 /* currently, we always use constant expression for globals
7946 (may change for scripting case) */
7947 expr_type = EXPR_CONST;
7948 if (!sec)
7949 expr_type = EXPR_ANY;
7950 init_putv(type, sec, c, 0, expr_type);
7954 /* parse an initializer for type 't' if 'has_init' is non zero, and
7955 allocate space in local or global data space ('r' is either
7956 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7957 variable 'v' of scope 'scope' is declared before initializers are
7958 parsed. If 'v' is zero, then a reference to the new object is put
7959 in the value stack. If 'has_init' is 2, a special parsing is done
7960 to handle string constants. */
7961 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
7962 int has_init, int v, int scope)
7964 int size, align, addr, data_offset;
7965 int level;
7966 ParseState saved_parse_state;
7967 TokenString init_str;
7968 Section *sec;
7970 size = type_size(type, &align);
7971 /* If unknown size, we must evaluate it before
7972 evaluating initializers because
7973 initializers can generate global data too
7974 (e.g. string pointers or ISOC99 compound
7975 literals). It also simplifies local
7976 initializers handling */
7977 tok_str_new(&init_str);
7978 if (size < 0) {
7979 if (!has_init)
7980 error("unknown type size");
7981 /* get all init string */
7982 if (has_init == 2) {
7983 /* only get strings */
7984 while (tok == TOK_STR || tok == TOK_LSTR) {
7985 tok_str_add_tok(&init_str);
7986 next();
7988 } else {
7989 level = 0;
7990 while (level > 0 || (tok != ',' && tok != ';')) {
7991 if (tok < 0)
7992 error("unexpected end of file in initializer");
7993 tok_str_add_tok(&init_str);
7994 if (tok == '{')
7995 level++;
7996 else if (tok == '}') {
7997 if (level == 0)
7998 break;
7999 level--;
8001 next();
8004 tok_str_add(&init_str, -1);
8005 tok_str_add(&init_str, 0);
8007 /* compute size */
8008 save_parse_state(&saved_parse_state);
8010 macro_ptr = init_str.str;
8011 next();
8012 decl_initializer(type, NULL, 0, 1, 1);
8013 /* prepare second initializer parsing */
8014 macro_ptr = init_str.str;
8015 next();
8017 /* if still unknown size, error */
8018 size = type_size(type, &align);
8019 if (size < 0)
8020 error("unknown type size");
8022 /* take into account specified alignment if bigger */
8023 if (ad->aligned > align)
8024 align = ad->aligned;
8025 if ((r & VT_VALMASK) == VT_LOCAL) {
8026 sec = NULL;
8027 if (do_bounds_check && (type->t & VT_ARRAY))
8028 loc--;
8029 loc = (loc - size) & -align;
8030 addr = loc;
8031 /* handles bounds */
8032 /* XXX: currently, since we do only one pass, we cannot track
8033 '&' operators, so we add only arrays */
8034 if (do_bounds_check && (type->t & VT_ARRAY)) {
8035 unsigned long *bounds_ptr;
8036 /* add padding between regions */
8037 loc--;
8038 /* then add local bound info */
8039 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
8040 bounds_ptr[0] = addr;
8041 bounds_ptr[1] = size;
8043 if (v) {
8044 /* local variable */
8045 sym_push(v, type, r, addr);
8046 } else {
8047 /* push local reference */
8048 vset(type, r, addr);
8050 } else {
8051 Sym *sym;
8053 sym = NULL;
8054 if (v && scope == VT_CONST) {
8055 /* see if the symbol was already defined */
8056 sym = sym_find(v);
8057 if (sym) {
8058 if (!is_compatible_types(&sym->type, type))
8059 error("incompatible types for redefinition of '%s'",
8060 get_tok_str(v, NULL));
8061 if (sym->type.t & VT_EXTERN) {
8062 /* if the variable is extern, it was not allocated */
8063 sym->type.t &= ~VT_EXTERN;
8064 } else {
8065 /* we accept several definitions of the same
8066 global variable. this is tricky, because we
8067 must play with the SHN_COMMON type of the symbol */
8068 /* XXX: should check if the variable was already
8069 initialized. It is incorrect to initialized it
8070 twice */
8071 /* no init data, we won't add more to the symbol */
8072 if (!has_init)
8073 goto no_alloc;
8078 /* allocate symbol in corresponding section */
8079 sec = ad->section;
8080 if (!sec) {
8081 if (has_init)
8082 sec = data_section;
8084 if (sec) {
8085 data_offset = sec->data_offset;
8086 data_offset = (data_offset + align - 1) & -align;
8087 addr = data_offset;
8088 /* very important to increment global pointer at this time
8089 because initializers themselves can create new initializers */
8090 data_offset += size;
8091 /* add padding if bound check */
8092 if (do_bounds_check)
8093 data_offset++;
8094 sec->data_offset = data_offset;
8095 /* allocate section space to put the data */
8096 if (sec->sh_type != SHT_NOBITS &&
8097 data_offset > sec->data_allocated)
8098 section_realloc(sec, data_offset);
8099 } else {
8100 addr = 0; /* avoid warning */
8103 if (v) {
8104 if (scope == VT_CONST) {
8105 if (!sym)
8106 goto do_def;
8107 } else {
8108 do_def:
8109 sym = sym_push(v, type, r | VT_SYM, 0);
8111 /* update symbol definition */
8112 if (sec) {
8113 put_extern_sym(sym, sec, addr, size);
8114 } else {
8115 Elf32_Sym *esym;
8116 /* put a common area */
8117 put_extern_sym(sym, NULL, align, size);
8118 /* XXX: find a nicer way */
8119 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
8120 esym->st_shndx = SHN_COMMON;
8122 } else {
8123 CValue cval;
8125 /* push global reference */
8126 sym = get_sym_ref(type, sec, addr, size);
8127 cval.ul = 0;
8128 vsetc(type, VT_CONST | VT_SYM, &cval);
8129 vtop->sym = sym;
8132 /* handles bounds now because the symbol must be defined
8133 before for the relocation */
8134 if (do_bounds_check) {
8135 unsigned long *bounds_ptr;
8137 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
8138 /* then add global bound info */
8139 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
8140 bounds_ptr[0] = 0; /* relocated */
8141 bounds_ptr[1] = size;
8144 if (has_init) {
8145 decl_initializer(type, sec, addr, 1, 0);
8146 /* restore parse state if needed */
8147 if (init_str.str) {
8148 tok_str_free(init_str.str);
8149 restore_parse_state(&saved_parse_state);
8152 no_alloc: ;
8155 void put_func_debug(Sym *sym)
8157 char buf[512];
8159 /* stabs info */
8160 /* XXX: we put here a dummy type */
8161 snprintf(buf, sizeof(buf), "%s:%c1",
8162 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
8163 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
8164 cur_text_section, sym->c);
8165 last_ind = 0;
8166 last_line_num = 0;
8169 /* not finished : try to put some local vars in registers */
8170 //#define CONFIG_REG_VARS
8172 #ifdef CONFIG_REG_VARS
8173 void add_var_ref(int t)
8175 printf("%s:%d: &%s\n",
8176 file->filename, file->line_num,
8177 get_tok_str(t, NULL));
8180 /* first pass on a function with heuristic to extract variable usage
8181 and pointer references to local variables for register allocation */
8182 void analyse_function(void)
8184 int level, t;
8186 for(;;) {
8187 if (tok == -1)
8188 break;
8189 /* any symbol coming after '&' is considered as being a
8190 variable whose reference is taken. It is highly unaccurate
8191 but it is difficult to do better without a complete parse */
8192 if (tok == '&') {
8193 next();
8194 /* if '& number', then no need to examine next tokens */
8195 if (tok == TOK_CINT ||
8196 tok == TOK_CUINT ||
8197 tok == TOK_CLLONG ||
8198 tok == TOK_CULLONG) {
8199 continue;
8200 } else if (tok >= TOK_UIDENT) {
8201 /* if '& ident [' or '& ident ->', then ident address
8202 is not needed */
8203 t = tok;
8204 next();
8205 if (tok != '[' && tok != TOK_ARROW)
8206 add_var_ref(t);
8207 } else {
8208 level = 0;
8209 while (tok != '}' && tok != ';' &&
8210 !((tok == ',' || tok == ')') && level == 0)) {
8211 if (tok >= TOK_UIDENT) {
8212 add_var_ref(tok);
8213 } else if (tok == '(') {
8214 level++;
8215 } else if (tok == ')') {
8216 level--;
8218 next();
8221 } else {
8222 next();
8226 #endif
8228 /* parse an old style function declaration list */
8229 /* XXX: check multiple parameter */
8230 static void func_decl_list(Sym *func_sym)
8232 AttributeDef ad;
8233 int v;
8234 Sym *s;
8235 CType btype, type;
8237 /* parse each declaration */
8238 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
8239 if (!parse_btype(&btype, &ad))
8240 expect("declaration list");
8241 if (((btype.t & VT_BTYPE) == VT_ENUM ||
8242 (btype.t & VT_BTYPE) == VT_STRUCT) &&
8243 tok == ';') {
8244 /* we accept no variable after */
8245 } else {
8246 for(;;) {
8247 type = btype;
8248 type_decl(&type, &ad, &v, TYPE_DIRECT);
8249 /* find parameter in function parameter list */
8250 s = func_sym->next;
8251 while (s != NULL) {
8252 if ((s->v & ~SYM_FIELD) == v)
8253 goto found;
8254 s = s->next;
8256 error("declaration for parameter '%s' but no such parameter",
8257 get_tok_str(v, NULL));
8258 found:
8259 /* check that no storage specifier except 'register' was given */
8260 if (type.t & VT_STORAGE)
8261 error("storage class specified for '%s'", get_tok_str(v, NULL));
8262 convert_parameter_type(&type);
8263 /* we can add the type (NOTE: it could be local to the function) */
8264 s->type = type;
8265 /* accept other parameters */
8266 if (tok == ',')
8267 next();
8268 else
8269 break;
8272 skip(';');
8276 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
8277 static void decl(int l)
8279 int v, has_init, r;
8280 CType type, btype;
8281 Sym *sym;
8282 AttributeDef ad;
8284 while (1) {
8285 if (!parse_btype(&btype, &ad)) {
8286 /* skip redundant ';' */
8287 /* XXX: find more elegant solution */
8288 if (tok == ';') {
8289 next();
8290 continue;
8292 /* special test for old K&R protos without explicit int
8293 type. Only accepted when defining global data */
8294 if (l == VT_LOCAL || tok < TOK_DEFINE)
8295 break;
8296 btype.t = VT_INT;
8298 if (((btype.t & VT_BTYPE) == VT_ENUM ||
8299 (btype.t & VT_BTYPE) == VT_STRUCT) &&
8300 tok == ';') {
8301 /* we accept no variable after */
8302 next();
8303 continue;
8305 while (1) { /* iterate thru each declaration */
8306 type = btype;
8307 type_decl(&type, &ad, &v, TYPE_DIRECT);
8308 #if 0
8310 char buf[500];
8311 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
8312 printf("type = '%s'\n", buf);
8314 #endif
8315 if ((type.t & VT_BTYPE) == VT_FUNC) {
8316 /* if old style function prototype, we accept a
8317 declaration list */
8318 sym = type.ref;
8319 if (sym->c == FUNC_OLD)
8320 func_decl_list(sym);
8323 if (tok == '{') {
8324 #ifdef CONFIG_REG_VARS
8325 TokenString func_str;
8326 ParseState saved_parse_state;
8327 int block_level;
8328 #endif
8330 if (l == VT_LOCAL)
8331 error("cannot use local functions");
8332 if (!(type.t & VT_FUNC))
8333 expect("function definition");
8334 /* XXX: cannot do better now: convert extern line to static inline */
8335 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
8336 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
8338 #ifdef CONFIG_REG_VARS
8339 /* parse all function code and record it */
8341 tok_str_new(&func_str);
8343 block_level = 0;
8344 for(;;) {
8345 int t;
8346 if (tok == -1)
8347 error("unexpected end of file");
8348 tok_str_add_tok(&func_str);
8349 t = tok;
8350 next();
8351 if (t == '{') {
8352 block_level++;
8353 } else if (t == '}') {
8354 block_level--;
8355 if (block_level == 0)
8356 break;
8359 tok_str_add(&func_str, -1);
8360 tok_str_add(&func_str, 0);
8362 save_parse_state(&saved_parse_state);
8364 macro_ptr = func_str.str;
8365 next();
8366 analyse_function();
8367 #endif
8369 /* compute text section */
8370 cur_text_section = ad.section;
8371 if (!cur_text_section)
8372 cur_text_section = text_section;
8373 ind = cur_text_section->data_offset;
8374 funcname = get_tok_str(v, NULL);
8375 sym = sym_find(v);
8376 if (sym) {
8377 /* if symbol is already defined, then put complete type */
8378 sym->type = type;
8379 } else {
8380 /* put function symbol */
8381 sym = global_identifier_push(v, type.t, 0);
8382 sym->type.ref = type.ref;
8384 /* NOTE: we patch the symbol size later */
8385 put_extern_sym(sym, cur_text_section, ind, 0);
8386 func_ind = ind;
8387 sym->r = VT_SYM | VT_CONST;
8388 /* put debug symbol */
8389 if (do_debug)
8390 put_func_debug(sym);
8391 /* push a dummy symbol to enable local sym storage */
8392 sym_push2(&local_stack, SYM_FIELD, 0, 0);
8393 gfunc_prolog(&type);
8394 loc = 0;
8395 rsym = 0;
8396 #ifdef CONFIG_REG_VARS
8397 macro_ptr = func_str.str;
8398 next();
8399 #endif
8400 block(NULL, NULL, NULL, NULL, 0, 0);
8401 gsym(rsym);
8402 gfunc_epilog();
8403 cur_text_section->data_offset = ind;
8404 label_pop(&global_label_stack, NULL);
8405 sym_pop(&local_stack, NULL); /* reset local stack */
8406 /* end of function */
8407 /* patch symbol size */
8408 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
8409 ind - func_ind;
8410 if (do_debug) {
8411 put_stabn(N_FUN, 0, 0, ind - func_ind);
8413 funcname = ""; /* for safety */
8414 func_vt.t = VT_VOID; /* for safety */
8415 ind = 0; /* for safety */
8417 #ifdef CONFIG_REG_VARS
8418 tok_str_free(func_str.str);
8419 restore_parse_state(&saved_parse_state);
8420 #endif
8421 break;
8422 } else {
8423 if (btype.t & VT_TYPEDEF) {
8424 /* save typedefed type */
8425 /* XXX: test storage specifiers ? */
8426 sym = sym_push(v, &type, 0, 0);
8427 sym->type.t |= VT_TYPEDEF;
8428 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
8429 /* external function definition */
8430 external_sym(v, &type, 0);
8431 } else {
8432 /* not lvalue if array */
8433 r = 0;
8434 if (!(type.t & VT_ARRAY))
8435 r |= lvalue_type(type.t);
8436 has_init = (tok == '=');
8437 if ((btype.t & VT_EXTERN) ||
8438 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
8439 !has_init && l == VT_CONST && type.ref->c < 0)) {
8440 /* external variable */
8441 /* NOTE: as GCC, uninitialized global static
8442 arrays of null size are considered as
8443 extern */
8444 external_sym(v, &type, r);
8445 } else {
8446 if (type.t & VT_STATIC)
8447 r |= VT_CONST;
8448 else
8449 r |= l;
8450 if (has_init)
8451 next();
8452 decl_initializer_alloc(&type, &ad, r,
8453 has_init, v, l);
8456 if (tok != ',') {
8457 skip(';');
8458 break;
8460 next();
8466 /* better than nothing, but needs extension to handle '-E' option
8467 correctly too */
8468 static void preprocess_init(TCCState *s1)
8470 s1->include_stack_ptr = s1->include_stack;
8471 /* XXX: move that before to avoid having to initialize
8472 file->ifdef_stack_ptr ? */
8473 s1->ifdef_stack_ptr = s1->ifdef_stack;
8474 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
8476 /* XXX: not ANSI compliant: bound checking says error */
8477 vtop = vstack - 1;
8480 /* compile the C file opened in 'file'. Return non zero if errors. */
8481 static int tcc_compile(TCCState *s1)
8483 Sym *define_start;
8484 char buf[512];
8485 volatile int section_sym;
8487 #ifdef INC_DEBUG
8488 printf("%s: **** new file\n", file->filename);
8489 #endif
8490 preprocess_init(s1);
8492 funcname = "";
8493 anon_sym = SYM_FIRST_ANOM;
8495 /* file info: full path + filename */
8496 section_sym = 0; /* avoid warning */
8497 if (do_debug) {
8498 section_sym = put_elf_sym(symtab_section, 0, 0,
8499 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
8500 text_section->sh_num, NULL);
8501 getcwd(buf, sizeof(buf));
8502 pstrcat(buf, sizeof(buf), "/");
8503 put_stabs_r(buf, N_SO, 0, 0,
8504 text_section->data_offset, text_section, section_sym);
8505 put_stabs_r(file->filename, N_SO, 0, 0,
8506 text_section->data_offset, text_section, section_sym);
8508 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8509 symbols can be safely used */
8510 put_elf_sym(symtab_section, 0, 0,
8511 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
8512 SHN_ABS, file->filename);
8514 /* define some often used types */
8515 int_type.t = VT_INT;
8517 char_pointer_type.t = VT_BYTE;
8518 mk_pointer(&char_pointer_type);
8520 func_old_type.t = VT_FUNC;
8521 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
8523 #if 0
8524 /* define 'void *alloca(unsigned int)' builtin function */
8526 Sym *s1;
8528 p = anon_sym++;
8529 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
8530 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
8531 s1->next = NULL;
8532 sym->next = s1;
8533 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
8535 #endif
8537 define_start = define_stack;
8539 if (setjmp(s1->error_jmp_buf) == 0) {
8540 s1->nb_errors = 0;
8541 s1->error_set_jmp_enabled = 1;
8543 ch = file->buf_ptr[0];
8544 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
8545 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
8546 next();
8547 decl(VT_CONST);
8548 if (tok != -1)
8549 expect("declaration");
8551 /* end of translation unit info */
8552 if (do_debug) {
8553 put_stabs_r(NULL, N_SO, 0, 0,
8554 text_section->data_offset, text_section, section_sym);
8557 s1->error_set_jmp_enabled = 0;
8559 /* reset define stack, but leave -Dsymbols (may be incorrect if
8560 they are undefined) */
8561 free_defines(define_start);
8563 sym_pop(&global_stack, NULL);
8565 return s1->nb_errors != 0 ? -1 : 0;
8568 #ifdef LIBTCC
8569 int tcc_compile_string(TCCState *s, const char *str)
8571 BufferedFile bf1, *bf = &bf1;
8572 int ret, len;
8573 char *buf;
8575 /* init file structure */
8576 bf->fd = -1;
8577 /* XXX: avoid copying */
8578 len = strlen(str);
8579 buf = tcc_malloc(len + 1);
8580 if (!buf)
8581 return -1;
8582 memcpy(buf, str, len);
8583 buf[len] = CH_EOB;
8584 bf->buf_ptr = buf;
8585 bf->buf_end = buf + len;
8586 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
8587 bf->line_num = 1;
8588 file = bf;
8590 ret = tcc_compile(s);
8592 tcc_free(buf);
8594 /* currently, no need to close */
8595 return ret;
8597 #endif
8599 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8600 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
8602 BufferedFile bf1, *bf = &bf1;
8604 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
8605 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
8606 /* default value */
8607 if (!value)
8608 value = "1";
8609 pstrcat(bf->buffer, IO_BUF_SIZE, value);
8611 /* init file structure */
8612 bf->fd = -1;
8613 bf->buf_ptr = bf->buffer;
8614 bf->buf_end = bf->buffer + strlen(bf->buffer);
8615 *bf->buf_end = CH_EOB;
8616 bf->filename[0] = '\0';
8617 bf->line_num = 1;
8618 file = bf;
8620 s1->include_stack_ptr = s1->include_stack;
8622 /* parse with define parser */
8623 ch = file->buf_ptr[0];
8624 next_nomacro();
8625 parse_define();
8626 file = NULL;
8629 /* undefine a preprocessor symbol */
8630 void tcc_undefine_symbol(TCCState *s1, const char *sym)
8632 TokenSym *ts;
8633 Sym *s;
8634 ts = tok_alloc(sym, strlen(sym));
8635 s = define_find(ts->tok);
8636 /* undefine symbol by putting an invalid name */
8637 if (s)
8638 define_undef(s);
8641 #ifdef CONFIG_TCC_ASM
8643 #include "i386-asm.c"
8644 #include "tccasm.c"
8646 #else
8647 static void asm_instr(void)
8649 error("inline asm() not supported");
8651 #endif
8653 #include "tccelf.c"
8655 /* print the position in the source file of PC value 'pc' by reading
8656 the stabs debug information */
8657 static void rt_printline(unsigned long wanted_pc)
8659 Stab_Sym *sym, *sym_end;
8660 char func_name[128], last_func_name[128];
8661 unsigned long func_addr, last_pc, pc;
8662 const char *incl_files[INCLUDE_STACK_SIZE];
8663 int incl_index, len, last_line_num, i;
8664 const char *str, *p;
8666 fprintf(stderr, "0x%08lx:", wanted_pc);
8668 func_name[0] = '\0';
8669 func_addr = 0;
8670 incl_index = 0;
8671 last_func_name[0] = '\0';
8672 last_pc = 0xffffffff;
8673 last_line_num = 1;
8674 sym = (Stab_Sym *)stab_section->data + 1;
8675 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
8676 while (sym < sym_end) {
8677 switch(sym->n_type) {
8678 /* function start or end */
8679 case N_FUN:
8680 if (sym->n_strx == 0) {
8681 /* we test if between last line and end of function */
8682 pc = sym->n_value + func_addr;
8683 if (wanted_pc >= last_pc && wanted_pc < pc)
8684 goto found;
8685 func_name[0] = '\0';
8686 func_addr = 0;
8687 } else {
8688 str = stabstr_section->data + sym->n_strx;
8689 p = strchr(str, ':');
8690 if (!p) {
8691 pstrcpy(func_name, sizeof(func_name), str);
8692 } else {
8693 len = p - str;
8694 if (len > sizeof(func_name) - 1)
8695 len = sizeof(func_name) - 1;
8696 memcpy(func_name, str, len);
8697 func_name[len] = '\0';
8699 func_addr = sym->n_value;
8701 break;
8702 /* line number info */
8703 case N_SLINE:
8704 pc = sym->n_value + func_addr;
8705 if (wanted_pc >= last_pc && wanted_pc < pc)
8706 goto found;
8707 last_pc = pc;
8708 last_line_num = sym->n_desc;
8709 /* XXX: slow! */
8710 strcpy(last_func_name, func_name);
8711 break;
8712 /* include files */
8713 case N_BINCL:
8714 str = stabstr_section->data + sym->n_strx;
8715 add_incl:
8716 if (incl_index < INCLUDE_STACK_SIZE) {
8717 incl_files[incl_index++] = str;
8719 break;
8720 case N_EINCL:
8721 if (incl_index > 1)
8722 incl_index--;
8723 break;
8724 case N_SO:
8725 if (sym->n_strx == 0) {
8726 incl_index = 0; /* end of translation unit */
8727 } else {
8728 str = stabstr_section->data + sym->n_strx;
8729 /* do not add path */
8730 len = strlen(str);
8731 if (len > 0 && str[len - 1] != '/')
8732 goto add_incl;
8734 break;
8736 sym++;
8739 /* second pass: we try symtab symbols (no line number info) */
8740 incl_index = 0;
8742 Elf32_Sym *sym, *sym_end;
8743 int type;
8745 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
8746 for(sym = (Elf32_Sym *)symtab_section->data + 1;
8747 sym < sym_end;
8748 sym++) {
8749 type = ELF32_ST_TYPE(sym->st_info);
8750 if (type == STT_FUNC) {
8751 if (wanted_pc >= sym->st_value &&
8752 wanted_pc < sym->st_value + sym->st_size) {
8753 pstrcpy(last_func_name, sizeof(last_func_name),
8754 strtab_section->data + sym->st_name);
8755 goto found;
8760 /* did not find any info: */
8761 fprintf(stderr, " ???\n");
8762 return;
8763 found:
8764 if (last_func_name[0] != '\0') {
8765 fprintf(stderr, " %s()", last_func_name);
8767 if (incl_index > 0) {
8768 fprintf(stderr, " (%s:%d",
8769 incl_files[incl_index - 1], last_line_num);
8770 for(i = incl_index - 2; i >= 0; i--)
8771 fprintf(stderr, ", included from %s", incl_files[i]);
8772 fprintf(stderr, ")");
8774 fprintf(stderr, "\n");
8777 #ifndef WIN32
8779 #ifdef __i386__
8781 /* fix for glibc 2.1 */
8782 #ifndef REG_EIP
8783 #define REG_EIP EIP
8784 #define REG_EBP EBP
8785 #endif
8787 /* return the PC at frame level 'level'. Return non zero if not found */
8788 static int rt_get_caller_pc(unsigned long *paddr,
8789 ucontext_t *uc, int level)
8791 unsigned long fp;
8792 int i;
8794 if (level == 0) {
8795 #ifdef __FreeBSD__
8796 *paddr = uc->uc_mcontext.mc_eip;
8797 #else
8798 *paddr = uc->uc_mcontext.gregs[REG_EIP];
8799 #endif
8800 return 0;
8801 } else {
8802 #ifdef __FreeBSD__
8803 fp = uc->uc_mcontext.mc_ebp;
8804 #else
8805 fp = uc->uc_mcontext.gregs[REG_EBP];
8806 #endif
8807 for(i=1;i<level;i++) {
8808 /* XXX: check address validity with program info */
8809 if (fp <= 0x1000 || fp >= 0xc0000000)
8810 return -1;
8811 fp = ((unsigned long *)fp)[0];
8813 *paddr = ((unsigned long *)fp)[1];
8814 return 0;
8817 #else
8818 #error add arch specific rt_get_caller_pc()
8819 #endif
8821 /* emit a run time error at position 'pc' */
8822 void rt_error(ucontext_t *uc, const char *fmt, ...)
8824 va_list ap;
8825 unsigned long pc;
8826 int i;
8828 va_start(ap, fmt);
8829 fprintf(stderr, "Runtime error: ");
8830 vfprintf(stderr, fmt, ap);
8831 fprintf(stderr, "\n");
8832 for(i=0;i<num_callers;i++) {
8833 if (rt_get_caller_pc(&pc, uc, i) < 0)
8834 break;
8835 if (i == 0)
8836 fprintf(stderr, "at ");
8837 else
8838 fprintf(stderr, "by ");
8839 rt_printline(pc);
8841 exit(255);
8842 va_end(ap);
8845 /* signal handler for fatal errors */
8846 static void sig_error(int signum, siginfo_t *siginf, void *puc)
8848 ucontext_t *uc = puc;
8850 switch(signum) {
8851 case SIGFPE:
8852 switch(siginf->si_code) {
8853 case FPE_INTDIV:
8854 case FPE_FLTDIV:
8855 rt_error(uc, "division by zero");
8856 break;
8857 default:
8858 rt_error(uc, "floating point exception");
8859 break;
8861 break;
8862 case SIGBUS:
8863 case SIGSEGV:
8864 if (rt_bound_error_msg && *rt_bound_error_msg)
8865 rt_error(uc, *rt_bound_error_msg);
8866 else
8867 rt_error(uc, "dereferencing invalid pointer");
8868 break;
8869 case SIGILL:
8870 rt_error(uc, "illegal instruction");
8871 break;
8872 case SIGABRT:
8873 rt_error(uc, "abort() called");
8874 break;
8875 default:
8876 rt_error(uc, "caught signal %d", signum);
8877 break;
8879 exit(255);
8881 #endif
8883 /* do all relocations (needed before using tcc_get_symbol()) */
8884 int tcc_relocate(TCCState *s1)
8886 Section *s;
8887 int i;
8889 s1->nb_errors = 0;
8891 tcc_add_runtime(s1);
8893 relocate_common_syms();
8895 /* compute relocation address : section are relocated in place. We
8896 also alloc the bss space */
8897 for(i = 1; i < s1->nb_sections; i++) {
8898 s = s1->sections[i];
8899 if (s->sh_flags & SHF_ALLOC) {
8900 if (s->sh_type == SHT_NOBITS)
8901 s->data = tcc_mallocz(s->data_offset);
8902 s->sh_addr = (unsigned long)s->data;
8906 relocate_syms(s1, 1);
8908 if (s1->nb_errors != 0)
8909 return -1;
8911 /* relocate each section */
8912 for(i = 1; i < s1->nb_sections; i++) {
8913 s = s1->sections[i];
8914 if (s->reloc)
8915 relocate_section(s1, s);
8917 return 0;
8920 /* launch the compiled program with the given arguments */
8921 int tcc_run(TCCState *s1, int argc, char **argv)
8923 int (*prog_main)(int, char **);
8925 if (tcc_relocate(s1) < 0)
8926 return -1;
8928 prog_main = tcc_get_symbol(s1, "main");
8930 if (do_debug) {
8931 #ifdef WIN32
8932 error("debug mode currently not available for Windows");
8933 #else
8934 struct sigaction sigact;
8935 /* install TCC signal handlers to print debug info on fatal
8936 runtime errors */
8937 sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
8938 sigact.sa_sigaction = sig_error;
8939 sigemptyset(&sigact.sa_mask);
8940 sigaction(SIGFPE, &sigact, NULL);
8941 sigaction(SIGILL, &sigact, NULL);
8942 sigaction(SIGSEGV, &sigact, NULL);
8943 sigaction(SIGBUS, &sigact, NULL);
8944 sigaction(SIGABRT, &sigact, NULL);
8945 #endif
8948 #ifdef CONFIG_TCC_BCHECK
8949 if (do_bounds_check) {
8950 void (*bound_init)(void);
8952 /* set error function */
8953 rt_bound_error_msg = (void *)tcc_get_symbol(s1, "__bound_error_msg");
8955 /* XXX: use .init section so that it also work in binary ? */
8956 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
8957 bound_init();
8959 #endif
8960 return (*prog_main)(argc, argv);
8963 TCCState *tcc_new(void)
8965 const char *p, *r;
8966 TCCState *s;
8967 TokenSym *ts;
8968 int i, c;
8970 s = tcc_mallocz(sizeof(TCCState));
8971 if (!s)
8972 return NULL;
8973 tcc_state = s;
8974 s->output_type = TCC_OUTPUT_MEMORY;
8976 /* init isid table */
8977 for(i=0;i<256;i++)
8978 isidnum_table[i] = isid(i) || isnum(i);
8980 /* add all tokens */
8981 table_ident = NULL;
8982 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
8984 tok_ident = TOK_IDENT;
8985 p = tcc_keywords;
8986 while (*p) {
8987 r = p;
8988 for(;;) {
8989 c = *r++;
8990 if (c == '\0')
8991 break;
8993 ts = tok_alloc(p, r - p - 1);
8994 p = r;
8997 /* we add dummy defines for some special macros to speed up tests
8998 and to have working defined() */
8999 define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
9000 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
9001 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
9002 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
9004 /* standard defines */
9005 tcc_define_symbol(s, "__STDC__", NULL);
9006 #if defined(TCC_TARGET_I386)
9007 tcc_define_symbol(s, "__i386__", NULL);
9008 #endif
9009 #if defined(linux)
9010 tcc_define_symbol(s, "__linux__", NULL);
9011 tcc_define_symbol(s, "linux", NULL);
9012 #endif
9013 /* tiny C specific defines */
9014 tcc_define_symbol(s, "__TINYC__", NULL);
9016 /* tiny C & gcc defines */
9017 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
9018 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
9019 tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
9021 /* default library paths */
9022 tcc_add_library_path(s, "/usr/local/lib");
9023 tcc_add_library_path(s, "/usr/lib");
9024 tcc_add_library_path(s, "/lib");
9026 /* no section zero */
9027 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
9029 /* create standard sections */
9030 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
9031 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
9032 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
9034 /* symbols are always generated for linking stage */
9035 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
9036 ".strtab",
9037 ".hashtab", SHF_PRIVATE);
9038 strtab_section = symtab_section->link;
9040 /* private symbol table for dynamic symbols */
9041 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
9042 ".dynstrtab",
9043 ".dynhashtab", SHF_PRIVATE);
9044 return s;
9047 void tcc_delete(TCCState *s1)
9049 int i, n;
9051 /* free -D defines */
9052 free_defines(NULL);
9054 /* free tokens */
9055 n = tok_ident - TOK_IDENT;
9056 for(i = 0; i < n; i++)
9057 tcc_free(table_ident[i]);
9058 tcc_free(table_ident);
9060 /* free all sections */
9062 free_section(symtab_section->hash);
9064 free_section(s1->dynsymtab_section->hash);
9065 free_section(s1->dynsymtab_section->link);
9066 free_section(s1->dynsymtab_section);
9068 for(i = 1; i < s1->nb_sections; i++)
9069 free_section(s1->sections[i]);
9070 tcc_free(s1->sections);
9072 /* free loaded dlls array */
9073 for(i = 0; i < s1->nb_loaded_dlls; i++)
9074 tcc_free(s1->loaded_dlls[i]);
9075 tcc_free(s1->loaded_dlls);
9077 /* library paths */
9078 for(i = 0; i < s1->nb_library_paths; i++)
9079 tcc_free(s1->library_paths[i]);
9080 tcc_free(s1->library_paths);
9082 /* cached includes */
9083 for(i = 0; i < s1->nb_cached_includes; i++)
9084 tcc_free(s1->cached_includes[i]);
9085 tcc_free(s1->cached_includes);
9087 for(i = 0; i < s1->nb_include_paths; i++)
9088 tcc_free(s1->include_paths[i]);
9089 tcc_free(s1->include_paths);
9091 for(i = 0; i < s1->nb_sysinclude_paths; i++)
9092 tcc_free(s1->sysinclude_paths[i]);
9093 tcc_free(s1->sysinclude_paths);
9095 tcc_free(s1);
9098 int tcc_add_include_path(TCCState *s1, const char *pathname)
9100 char *pathname1;
9102 pathname1 = tcc_strdup(pathname);
9103 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
9104 return 0;
9107 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
9109 char *pathname1;
9111 pathname1 = tcc_strdup(pathname);
9112 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
9113 return 0;
9116 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
9118 const char *ext, *filename1;
9119 Elf32_Ehdr ehdr;
9120 int fd, ret;
9121 BufferedFile *saved_file;
9123 /* find source file type with extension */
9124 filename1 = strrchr(filename, '/');
9125 if (filename1)
9126 filename1++;
9127 else
9128 filename1 = filename;
9129 ext = strrchr(filename1, '.');
9130 if (ext)
9131 ext++;
9133 /* open the file */
9134 saved_file = file;
9135 file = tcc_open(s1, filename);
9136 if (!file) {
9137 if (flags & AFF_PRINT_ERROR) {
9138 error_noabort("file '%s' not found", filename);
9140 ret = -1;
9141 goto fail1;
9144 if (!ext || !strcmp(ext, "c")) {
9145 /* C file assumed */
9146 ret = tcc_compile(s1);
9147 } else
9148 #ifdef CONFIG_TCC_ASM
9149 if (!strcmp(ext, "S")) {
9150 /* preprocessed assembler */
9151 ret = tcc_assemble(s1, 1);
9152 } else if (!strcmp(ext, "s")) {
9153 /* non preprocessed assembler */
9154 ret = tcc_assemble(s1, 0);
9155 } else
9156 #endif
9158 fd = file->fd;
9159 /* assume executable format: auto guess file type */
9160 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
9161 error_noabort("could not read header");
9162 goto fail;
9164 lseek(fd, 0, SEEK_SET);
9166 if (ehdr.e_ident[0] == ELFMAG0 &&
9167 ehdr.e_ident[1] == ELFMAG1 &&
9168 ehdr.e_ident[2] == ELFMAG2 &&
9169 ehdr.e_ident[3] == ELFMAG3) {
9170 file->line_num = 0; /* do not display line number if error */
9171 if (ehdr.e_type == ET_REL) {
9172 ret = tcc_load_object_file(s1, fd, 0);
9173 } else if (ehdr.e_type == ET_DYN) {
9174 ret = tcc_load_dll(s1, fd, filename,
9175 (flags & AFF_REFERENCED_DLL) != 0);
9176 } else {
9177 error_noabort("unrecognized ELF file");
9178 goto fail;
9180 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
9181 file->line_num = 0; /* do not display line number if error */
9182 ret = tcc_load_archive(s1, fd);
9183 } else {
9184 /* as GNU ld, consider it is an ld script if not recognized */
9185 ret = tcc_load_ldscript(s1);
9186 if (ret < 0) {
9187 error_noabort("unrecognized file type");
9188 goto fail;
9192 the_end:
9193 tcc_close(file);
9194 fail1:
9195 file = saved_file;
9196 return ret;
9197 fail:
9198 ret = -1;
9199 goto the_end;
9202 int tcc_add_file(TCCState *s, const char *filename)
9204 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
9207 int tcc_add_library_path(TCCState *s, const char *pathname)
9209 char *pathname1;
9211 pathname1 = tcc_strdup(pathname);
9212 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
9213 return 0;
9216 /* find and load a dll. Return non zero if not found */
9217 /* XXX: add '-rpath' option support ? */
9218 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
9220 char buf[1024];
9221 int i;
9223 for(i = 0; i < s->nb_library_paths; i++) {
9224 snprintf(buf, sizeof(buf), "%s/%s",
9225 s->library_paths[i], filename);
9226 if (tcc_add_file_internal(s, buf, flags) == 0)
9227 return 0;
9229 return -1;
9232 /* the library name is the same as the argument of the '-l' option */
9233 int tcc_add_library(TCCState *s, const char *libraryname)
9235 char buf[1024];
9236 int i;
9237 void *h;
9239 /* first we look for the dynamic library if not static linking */
9240 if (!s->static_link) {
9241 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
9242 /* if we output to memory, then we simply we dlopen(). */
9243 if (s->output_type == TCC_OUTPUT_MEMORY) {
9244 /* Since the libc is already loaded, we don't need to load it again */
9245 if (!strcmp(libraryname, "c"))
9246 return 0;
9247 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
9248 if (h)
9249 return 0;
9250 } else {
9251 if (tcc_add_dll(s, buf, 0) == 0)
9252 return 0;
9256 /* then we look for the static library */
9257 for(i = 0; i < s->nb_library_paths; i++) {
9258 snprintf(buf, sizeof(buf), "%s/lib%s.a",
9259 s->library_paths[i], libraryname);
9260 if (tcc_add_file_internal(s, buf, 0) == 0)
9261 return 0;
9263 return -1;
9266 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
9268 add_elf_sym(symtab_section, val, 0,
9269 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
9270 SHN_ABS, name);
9271 return 0;
9274 int tcc_set_output_type(TCCState *s, int output_type)
9276 char buf[1024];
9278 s->output_type = output_type;
9280 if (!s->nostdinc) {
9281 /* default include paths */
9282 /* XXX: reverse order needed if -isystem support */
9283 tcc_add_sysinclude_path(s, "/usr/local/include");
9284 tcc_add_sysinclude_path(s, "/usr/include");
9285 snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path);
9286 tcc_add_sysinclude_path(s, buf);
9289 /* if bound checking, then add corresponding sections */
9290 #ifdef CONFIG_TCC_BCHECK
9291 if (do_bounds_check) {
9292 /* define symbol */
9293 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
9294 /* create bounds sections */
9295 bounds_section = new_section(s, ".bounds",
9296 SHT_PROGBITS, SHF_ALLOC);
9297 lbounds_section = new_section(s, ".lbounds",
9298 SHT_PROGBITS, SHF_ALLOC);
9300 #endif
9302 /* add debug sections */
9303 if (do_debug) {
9304 /* stab symbols */
9305 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
9306 stab_section->sh_entsize = sizeof(Stab_Sym);
9307 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
9308 put_elf_str(stabstr_section, "");
9309 stab_section->link = stabstr_section;
9310 /* put first entry */
9311 put_stabs("", 0, 0, 0, 0);
9314 /* add libc crt1/crti objects */
9315 if (output_type == TCC_OUTPUT_EXE ||
9316 output_type == TCC_OUTPUT_DLL) {
9317 if (output_type != TCC_OUTPUT_DLL)
9318 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
9319 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
9321 return 0;
9324 #if !defined(LIBTCC)
9326 /* extract the basename of a file */
9327 static const char *tcc_basename(const char *name)
9329 const char *p;
9330 p = strrchr(name, '/');
9331 #ifdef WIN32
9332 if (!p)
9333 p = strrchr(name, '\\');
9334 #endif
9335 if (!p)
9336 p = name;
9337 else
9338 p++;
9339 return p;
9342 static int64_t getclock_us(void)
9344 #ifdef WIN32
9345 struct _timeb tb;
9346 _ftime(&tb);
9347 return (tb.time * 1000LL + tb.millitm) * 1000LL;
9348 #else
9349 struct timeval tv;
9350 gettimeofday(&tv, NULL);
9351 return tv.tv_sec * 1000000LL + tv.tv_usec;
9352 #endif
9355 void help(void)
9357 printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
9358 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
9359 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
9360 " [infile1 infile2...] [-run infile args...]\n"
9361 "\n"
9362 "General options:\n"
9363 " -v display current version\n"
9364 " -c compile only - generate an object file\n"
9365 " -o outfile set output filename\n"
9366 " -Bdir set tcc internal library path\n"
9367 " -bench output compilation statistics\n"
9368 " -run run compiled source\n"
9369 "Preprocessor options:\n"
9370 " -Idir add include path 'dir'\n"
9371 " -Dsym[=val] define 'sym' with value 'val'\n"
9372 " -Usym undefine 'sym'\n"
9373 "Linker options:\n"
9374 " -Ldir add library path 'dir'\n"
9375 " -llib link with dynamic or static library 'lib'\n"
9376 " -shared generate a shared library\n"
9377 " -static static linking\n"
9378 " -r relocatable output\n"
9379 "Debugger options:\n"
9380 " -g generate runtime debug info\n"
9381 #ifdef CONFIG_TCC_BCHECK
9382 " -b compile with built-in memory and bounds checker (implies -g)\n"
9383 #endif
9384 " -bt N show N callers in stack traces\n"
9388 #define TCC_OPTION_HAS_ARG 0x0001
9389 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
9391 typedef struct TCCOption {
9392 const char *name;
9393 uint16_t index;
9394 uint16_t flags;
9395 } TCCOption;
9397 enum {
9398 TCC_OPTION_HELP,
9399 TCC_OPTION_I,
9400 TCC_OPTION_D,
9401 TCC_OPTION_U,
9402 TCC_OPTION_L,
9403 TCC_OPTION_B,
9404 TCC_OPTION_l,
9405 TCC_OPTION_bench,
9406 TCC_OPTION_bt,
9407 TCC_OPTION_b,
9408 TCC_OPTION_g,
9409 TCC_OPTION_c,
9410 TCC_OPTION_static,
9411 TCC_OPTION_shared,
9412 TCC_OPTION_o,
9413 TCC_OPTION_r,
9414 TCC_OPTION_W,
9415 TCC_OPTION_O,
9416 TCC_OPTION_m,
9417 TCC_OPTION_f,
9418 TCC_OPTION_nostdinc,
9419 TCC_OPTION_print_search_dirs,
9420 TCC_OPTION_rdynamic,
9421 TCC_OPTION_run,
9422 TCC_OPTION_v,
9425 static const TCCOption tcc_options[] = {
9426 { "h", TCC_OPTION_HELP, 0 },
9427 { "?", TCC_OPTION_HELP, 0 },
9428 { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
9429 { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
9430 { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
9431 { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
9432 { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
9433 { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9434 { "bench", TCC_OPTION_bench, 0 },
9435 { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
9436 #ifdef CONFIG_TCC_BCHECK
9437 { "b", TCC_OPTION_b, 0 },
9438 #endif
9439 { "g", TCC_OPTION_g, 0 },
9440 { "c", TCC_OPTION_c, 0 },
9441 { "static", TCC_OPTION_static, 0 },
9442 { "shared", TCC_OPTION_shared, 0 },
9443 { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
9444 { "run", TCC_OPTION_run, 0 },
9445 { "rdynamic", TCC_OPTION_rdynamic, 0 }, /* currently ignored */
9446 { "r", TCC_OPTION_r, 0 },
9447 { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9448 { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9449 { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
9450 { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9451 { "nostdinc", TCC_OPTION_nostdinc, 0 },
9452 { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
9453 { "v", TCC_OPTION_v, 0 },
9454 { NULL },
9457 int main(int argc, char **argv)
9459 char *r;
9460 int optind, output_type, multiple_files, i, reloc_output;
9461 TCCState *s;
9462 char **files;
9463 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
9464 char objfilename[1024];
9465 int64_t start_time = 0;
9466 const TCCOption *popt;
9467 const char *optarg, *p1, *r1, *outfile;
9468 int print_search_dirs;
9470 s = tcc_new();
9471 output_type = TCC_OUTPUT_EXE;
9473 optind = 1;
9474 outfile = NULL;
9475 multiple_files = 1;
9476 dminus = 0;
9477 files = NULL;
9478 nb_files = 0;
9479 nb_libraries = 0;
9480 reloc_output = 0;
9481 print_search_dirs = 0;
9482 while (1) {
9483 if (optind >= argc) {
9484 if (nb_files == 0 && !print_search_dirs)
9485 goto show_help;
9486 else
9487 break;
9489 r = argv[optind++];
9490 if (r[0] != '-') {
9491 /* add a new file */
9492 dynarray_add((void ***)&files, &nb_files, r);
9493 if (!multiple_files) {
9494 optind--;
9495 /* argv[0] will be this file */
9496 break;
9498 } else {
9499 /* find option in table (match only the first chars */
9500 popt = tcc_options;
9501 for(;;) {
9502 p1 = popt->name;
9503 if (p1 == NULL)
9504 error("invalid option -- '%s'", r);
9505 r1 = r + 1;
9506 for(;;) {
9507 if (*p1 == '\0')
9508 goto option_found;
9509 if (*r1 != *p1)
9510 break;
9511 p1++;
9512 r1++;
9514 popt++;
9516 option_found:
9517 if (popt->flags & TCC_OPTION_HAS_ARG) {
9518 if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) {
9519 optarg = r1;
9520 } else {
9521 if (optind >= argc)
9522 error("argument to '%s' is missing", r);
9523 optarg = argv[optind++];
9525 } else {
9526 if (*r1 != '\0')
9527 goto show_help;
9528 optarg = NULL;
9531 switch(popt->index) {
9532 case TCC_OPTION_HELP:
9533 show_help:
9534 help();
9535 return 1;
9536 case TCC_OPTION_I:
9537 if (tcc_add_include_path(s, optarg) < 0)
9538 error("too many include paths");
9539 break;
9540 case TCC_OPTION_D:
9542 char *sym, *value;
9543 sym = (char *)optarg;
9544 value = strchr(sym, '=');
9545 if (value) {
9546 *value = '\0';
9547 value++;
9549 tcc_define_symbol(s, sym, value);
9551 break;
9552 case TCC_OPTION_U:
9553 tcc_undefine_symbol(s, optarg);
9554 break;
9555 case TCC_OPTION_L:
9556 tcc_add_library_path(s, optarg);
9557 break;
9558 case TCC_OPTION_B:
9559 /* set tcc utilities path (mainly for tcc development) */
9560 tcc_lib_path = optarg;
9561 break;
9562 case TCC_OPTION_l:
9563 dynarray_add((void ***)&files, &nb_files, r);
9564 nb_libraries++;
9565 break;
9566 case TCC_OPTION_bench:
9567 do_bench = 1;
9568 break;
9569 case TCC_OPTION_bt:
9570 num_callers = atoi(optarg);
9571 break;
9572 #ifdef CONFIG_TCC_BCHECK
9573 case TCC_OPTION_b:
9574 do_bounds_check = 1;
9575 do_debug = 1;
9576 break;
9577 #endif
9578 case TCC_OPTION_g:
9579 do_debug = 1;
9580 break;
9581 case TCC_OPTION_c:
9582 multiple_files = 1;
9583 output_type = TCC_OUTPUT_OBJ;
9584 break;
9585 case TCC_OPTION_static:
9586 s->static_link = 1;
9587 break;
9588 case TCC_OPTION_shared:
9589 output_type = TCC_OUTPUT_DLL;
9590 break;
9591 case TCC_OPTION_o:
9592 multiple_files = 1;
9593 outfile = optarg;
9594 break;
9595 case TCC_OPTION_r:
9596 /* generate a .o merging several output files */
9597 reloc_output = 1;
9598 output_type = TCC_OUTPUT_OBJ;
9599 break;
9600 case TCC_OPTION_nostdinc:
9601 s->nostdinc = 1;
9602 break;
9603 case TCC_OPTION_print_search_dirs:
9604 print_search_dirs = 1;
9605 break;
9606 case TCC_OPTION_run:
9607 multiple_files = 0;
9608 output_type = TCC_OUTPUT_MEMORY;
9609 break;
9610 case TCC_OPTION_v:
9611 printf("tcc version %s\n", TCC_VERSION);
9612 return 0;
9613 default:
9614 break;
9618 if (print_search_dirs) {
9619 /* enough for Linux kernel */
9620 printf("install: %s/\n", tcc_lib_path);
9621 return 0;
9624 nb_objfiles = nb_files - nb_libraries;
9626 /* if outfile provided without other options, we output an
9627 executable */
9628 if (outfile && output_type == TCC_OUTPUT_MEMORY)
9629 output_type = TCC_OUTPUT_EXE;
9631 /* check -c consistency : only single file handled. XXX: checks file type */
9632 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9633 /* accepts only a single input file */
9634 if (nb_objfiles != 1)
9635 error("cannot specify multiple files with -c");
9636 if (nb_libraries != 0)
9637 error("cannot specify libraries with -c");
9640 /* compute default outfile name */
9641 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
9642 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9643 char *ext;
9644 /* strip path */
9645 pstrcpy(objfilename, sizeof(objfilename) - 1,
9646 tcc_basename(files[0]));
9647 /* add .o extension */
9648 ext = strrchr(objfilename, '.');
9649 if (!ext)
9650 goto default_outfile;
9651 strcpy(ext + 1, "o");
9652 } else {
9653 default_outfile:
9654 pstrcpy(objfilename, sizeof(objfilename), "a.out");
9656 outfile = objfilename;
9659 if (do_bench) {
9660 start_time = getclock_us();
9663 tcc_set_output_type(s, output_type);
9665 /* compile or add each files or library */
9666 for(i = 0;i < nb_files; i++) {
9667 const char *filename;
9669 filename = files[i];
9670 if (filename[0] == '-') {
9671 if (tcc_add_library(s, filename + 2) < 0)
9672 error("cannot find %s", filename);
9673 } else {
9674 if (tcc_add_file(s, filename) < 0) {
9675 ret = 1;
9676 goto the_end;
9681 /* free all files */
9682 tcc_free(files);
9684 if (do_bench) {
9685 double total_time;
9686 total_time = (double)(getclock_us() - start_time) / 1000000.0;
9687 if (total_time < 0.001)
9688 total_time = 0.001;
9689 if (total_bytes < 1)
9690 total_bytes = 1;
9691 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
9692 tok_ident - TOK_IDENT, total_lines, total_bytes,
9693 total_time, (int)(total_lines / total_time),
9694 total_bytes / total_time / 1000000.0);
9697 if (s->output_type != TCC_OUTPUT_MEMORY) {
9698 tcc_output_file(s, outfile);
9699 ret = 0;
9700 } else {
9701 ret = tcc_run(s, argc - optind, argv + optind);
9703 the_end:
9704 /* XXX: cannot do it with bound checking because of the malloc hooks */
9705 if (!do_bounds_check)
9706 tcc_delete(s);
9708 #ifdef MEM_DEBUG
9709 if (do_bench) {
9710 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
9712 #endif
9713 return ret;
9716 #endif