added asm tokens - suppressed synonims (avoid potential bugs in preprocessing)
[tinycc.git] / tcc.c
blob012dc3e34aea36744bd8ea83c9c4cc7814e2693b
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define _GNU_SOURCE
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <math.h>
27 #include <unistd.h>
28 #include <signal.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <setjmp.h>
32 #ifdef WIN32
33 #include <sys/timeb.h>
34 #endif
35 #ifndef WIN32
36 #include <sys/time.h>
37 #include <sys/ucontext.h>
38 #endif
39 #include "elf.h"
40 #include "stab.h"
41 #ifndef CONFIG_TCC_STATIC
42 #include <dlfcn.h>
43 #endif
45 #include "libtcc.h"
47 /* parser debug */
48 //#define PARSE_DEBUG
49 /* preprocessor debug */
50 //#define PP_DEBUG
51 /* include file debug */
52 //#define INC_DEBUG
54 //#define MEM_DEBUG
56 /* assembler debug */
57 //#define ASM_DEBUG
59 /* target selection */
60 //#define TCC_TARGET_I386 /* i386 code generator */
62 /* default target is I386 */
63 #if !defined(TCC_TARGET_I386)
64 #define TCC_TARGET_I386
65 #endif
67 #if !defined(WIN32) && !defined(TCC_UCLIBC)
68 #define CONFIG_TCC_BCHECK /* enable bound checking code */
69 #endif
71 /* define it to include assembler support */
72 #define CONFIG_TCC_ASM
74 #ifndef CONFIG_TCC_PREFIX
75 #define CONFIG_TCC_PREFIX "/usr/local"
76 #endif
78 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
79 executables or dlls */
80 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
82 #define INCLUDE_STACK_SIZE 32
83 #define IFDEF_STACK_SIZE 64
84 #define VSTACK_SIZE 64
85 #define STRING_MAX_SIZE 1024
87 #define TOK_HASH_SIZE 2048 /* must be a power of two */
88 #define TOK_ALLOC_INCR 512 /* must be a power of two */
89 #define TOK_STR_ALLOC_INCR_BITS 6
90 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
91 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
93 /* token symbol management */
94 typedef struct TokenSym {
95 struct TokenSym *hash_next;
96 struct Sym *sym_define; /* direct pointer to define */
97 struct Sym *sym_label; /* direct pointer to label */
98 struct Sym *sym_struct; /* direct pointer to structure */
99 struct Sym *sym_identifier; /* direct pointer to identifier */
100 int tok; /* token number */
101 int len;
102 char str[1];
103 } TokenSym;
105 typedef struct CString {
106 int size; /* size in bytes */
107 void *data; /* either 'char *' or 'int *' */
108 int size_allocated;
109 void *data_allocated; /* if non NULL, data has been malloced */
110 } CString;
112 /* type definition */
113 typedef struct CType {
114 int t;
115 struct Sym *ref;
116 } CType;
118 /* constant value */
119 typedef union CValue {
120 long double ld;
121 double d;
122 float f;
123 int i;
124 unsigned int ui;
125 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
126 long long ll;
127 unsigned long long ull;
128 struct CString *cstr;
129 void *ptr;
130 int tab[1];
131 } CValue;
133 /* value on stack */
134 typedef struct SValue {
135 CType type; /* type */
136 unsigned short r; /* register + flags */
137 unsigned short r2; /* second register, used for 'long long'
138 type. If not used, set to VT_CONST */
139 CValue c; /* constant, if VT_CONST */
140 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
141 } SValue;
143 /* symbol management */
144 typedef struct Sym {
145 int v; /* symbol token */
146 int r; /* associated register */
147 int c; /* associated number */
148 CType type; /* associated type */
149 struct Sym *next; /* next related symbol */
150 struct Sym *prev; /* prev symbol in stack */
151 struct Sym *prev_tok; /* previous symbol for this token */
152 } Sym;
154 /* section definition */
155 /* XXX: use directly ELF structure for parameters ? */
156 /* special flag to indicate that the section should not be linked to
157 the other ones */
158 #define SHF_PRIVATE 0x80000000
160 typedef struct Section {
161 unsigned long data_offset; /* current data offset */
162 unsigned char *data; /* section data */
163 unsigned long data_allocated; /* used for realloc() handling */
164 int sh_name; /* elf section name (only used during output) */
165 int sh_num; /* elf section number */
166 int sh_type; /* elf section type */
167 int sh_flags; /* elf section flags */
168 int sh_info; /* elf section info */
169 int sh_addralign; /* elf section alignment */
170 int sh_entsize; /* elf entry size */
171 unsigned long sh_size; /* section size (only used during output) */
172 unsigned long sh_addr; /* address at which the section is relocated */
173 unsigned long sh_offset; /* address at which the section is relocated */
174 int nb_hashed_syms; /* used to resize the hash table */
175 struct Section *link; /* link to another section */
176 struct Section *reloc; /* corresponding section for relocation, if any */
177 struct Section *hash; /* hash table for symbols */
178 struct Section *next;
179 char name[64]; /* section name */
180 } Section;
182 typedef struct DLLReference {
183 int level;
184 char name[1];
185 } DLLReference;
187 /* GNUC attribute definition */
188 typedef struct AttributeDef {
189 int aligned;
190 Section *section;
191 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
192 } AttributeDef;
194 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
195 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
196 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
198 /* stored in 'Sym.c' field */
199 #define FUNC_NEW 1 /* ansi function prototype */
200 #define FUNC_OLD 2 /* old function prototype */
201 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
203 /* stored in 'Sym.r' field */
204 #define FUNC_CDECL 0 /* standard c call */
205 #define FUNC_STDCALL 1 /* pascal c call */
207 /* field 'Sym.t' for macros */
208 #define MACRO_OBJ 0 /* object like macro */
209 #define MACRO_FUNC 1 /* function like macro */
211 /* field 'Sym.r' for C labels */
212 #define LABEL_DEFINED 0 /* label is defined */
213 #define LABEL_FORWARD 1 /* label is forward defined */
214 #define LABEL_DECLARED 2 /* label is declared but never used */
216 /* type_decl() types */
217 #define TYPE_ABSTRACT 1 /* type without variable */
218 #define TYPE_DIRECT 2 /* type with variable */
220 #define IO_BUF_SIZE 8192
222 typedef struct BufferedFile {
223 uint8_t *buf_ptr;
224 uint8_t *buf_end;
225 int fd;
226 int line_num; /* current line number - here to simply code */
227 int ifndef_macro; /* #ifndef macro / #endif search */
228 int ifndef_macro_saved; /* saved ifndef_macro */
229 int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
230 char inc_type; /* type of include */
231 char inc_filename[512]; /* filename specified by the user */
232 char filename[1024]; /* current filename - here to simplify code */
233 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
234 } BufferedFile;
236 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
237 #define CH_EOF (-1) /* end of file */
239 /* parsing state (used to save parser state to reparse part of the
240 source several times) */
241 typedef struct ParseState {
242 int *macro_ptr;
243 int line_num;
244 int tok;
245 CValue tokc;
246 } ParseState;
248 /* used to record tokens */
249 typedef struct TokenString {
250 int *str;
251 int len;
252 int allocated_len;
253 int last_line_num;
254 } TokenString;
256 /* include file cache, used to find files faster and also to eliminate
257 inclusion if the include file is protected by #ifndef ... #endif */
258 typedef struct CachedInclude {
259 int ifndef_macro;
260 char type; /* '"' or '>' to give include type */
261 char filename[1]; /* path specified in #include */
262 } CachedInclude;
264 /* parser */
265 static struct BufferedFile *file;
266 static int ch, tok;
267 static CValue tokc;
268 static CString tokcstr; /* current parsed string, if any */
269 /* additionnal informations about token */
270 static int tok_flags;
271 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
272 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
273 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
275 static int *macro_ptr, *macro_ptr_allocated;
276 static int *unget_saved_macro_ptr;
277 static int unget_saved_buffer[TOK_MAX_SIZE + 1];
278 static int unget_buffer_enabled;
279 static int parse_flags;
280 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
281 #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
282 #define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
283 token. line feed is also
284 returned at eof */
286 static Section *text_section, *data_section, *bss_section; /* predefined sections */
287 static Section *cur_text_section; /* current section where function code is
288 generated */
289 /* bound check related sections */
290 static Section *bounds_section; /* contains global data bound description */
291 static Section *lbounds_section; /* contains local data bound description */
292 /* symbol sections */
293 static Section *symtab_section, *strtab_section;
295 /* debug sections */
296 static Section *stab_section, *stabstr_section;
298 /* loc : local variable index
299 ind : output code index
300 rsym: return symbol
301 anon_sym: anonymous symbol index
303 static int rsym, anon_sym, ind, loc;
304 /* expression generation modifiers */
305 static int const_wanted; /* true if constant wanted */
306 static int nocode_wanted; /* true if no code generation wanted for an expression */
307 static int global_expr; /* true if compound literals must be allocated
308 globally (used during initializers parsing */
309 static CType func_vt; /* current function return type (used by return
310 instruction) */
311 static int func_vc;
312 static int last_line_num, last_ind, func_ind; /* debug last line number and pc */
313 static int tok_ident;
314 static TokenSym **table_ident;
315 static TokenSym *hash_ident[TOK_HASH_SIZE];
316 static char token_buf[STRING_MAX_SIZE + 1];
317 static char *funcname;
318 static Sym *global_stack, *local_stack;
319 static Sym *define_stack;
320 static Sym *global_label_stack, *local_label_stack;
322 static SValue vstack[VSTACK_SIZE], *vtop;
323 /* some predefined types */
324 static CType char_pointer_type, func_old_type, int_type;
325 /* true if isid(c) || isnum(c) */
326 static unsigned char isidnum_table[256];
328 /* compile with debug symbol (and use them if error during execution) */
329 static int do_debug = 0;
331 /* compile with built-in memory and bounds checker */
332 static int do_bounds_check = 0;
334 /* display benchmark infos */
335 static int do_bench = 0;
336 static int total_lines;
337 static int total_bytes;
339 /* use GNU C extensions */
340 static int gnu_ext = 1;
342 /* use Tiny C extensions */
343 static int tcc_ext = 1;
345 /* max number of callers shown if error */
346 static int num_callers = 6;
347 static const char **rt_bound_error_msg;
349 /* XXX: suppress that ASAP */
350 static struct TCCState *tcc_state;
352 /* give the path of the tcc libraries */
353 static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc";
355 struct TCCState {
356 int output_type;
358 BufferedFile **include_stack_ptr;
359 int *ifdef_stack_ptr;
361 /* include file handling */
362 char **include_paths;
363 int nb_include_paths;
364 char **sysinclude_paths;
365 int nb_sysinclude_paths;
366 CachedInclude **cached_includes;
367 int nb_cached_includes;
369 char **library_paths;
370 int nb_library_paths;
372 /* array of all loaded dlls (including those referenced by loaded
373 dlls) */
374 DLLReference **loaded_dlls;
375 int nb_loaded_dlls;
377 /* sections */
378 Section **sections;
379 int nb_sections; /* number of sections, including first dummy section */
381 /* got handling */
382 Section *got;
383 Section *plt;
384 unsigned long *got_offsets;
385 int nb_got_offsets;
386 /* give the correspondance from symtab indexes to dynsym indexes */
387 int *symtab_to_dynsym;
389 /* temporary dynamic symbol sections (for dll loading) */
390 Section *dynsymtab_section;
391 /* exported dynamic symbol section */
392 Section *dynsym;
394 /* if true, no standard headers are added */
395 int nostdinc;
397 /* if true, static linking is performed */
398 int static_link;
400 /* error handling */
401 void *error_opaque;
402 void (*error_func)(void *opaque, const char *msg);
403 int error_set_jmp_enabled;
404 jmp_buf error_jmp_buf;
405 int nb_errors;
407 /* tiny assembler state */
408 Sym *asm_labels;
410 /* see include_stack_ptr */
411 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
413 /* see ifdef_stack_ptr */
414 int ifdef_stack[IFDEF_STACK_SIZE];
417 /* The current value can be: */
418 #define VT_VALMASK 0x00ff
419 #define VT_CONST 0x00f0 /* constant in vc
420 (must be first non register value) */
421 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
422 #define VT_LOCAL 0x00f2 /* offset on stack */
423 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
424 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
425 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
426 #define VT_LVAL 0x0100 /* var is an lvalue */
427 #define VT_SYM 0x0200 /* a symbol value is added */
428 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
429 char/short stored in integer registers) */
430 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
431 dereferencing value */
432 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
433 bounding function call point is in vc */
434 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
435 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
436 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
437 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
439 /* types */
440 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
442 #define VT_INT 0 /* integer type */
443 #define VT_BYTE 1 /* signed byte type */
444 #define VT_SHORT 2 /* short type */
445 #define VT_VOID 3 /* void type */
446 #define VT_PTR 4 /* pointer */
447 #define VT_ENUM 5 /* enum definition */
448 #define VT_FUNC 6 /* function type */
449 #define VT_STRUCT 7 /* struct/union definition */
450 #define VT_FLOAT 8 /* IEEE float */
451 #define VT_DOUBLE 9 /* IEEE double */
452 #define VT_LDOUBLE 10 /* IEEE long double */
453 #define VT_BOOL 11 /* ISOC99 boolean type */
454 #define VT_LLONG 12 /* 64 bit integer */
455 #define VT_LONG 13 /* long integer (NEVER USED as type, only
456 during parsing) */
457 #define VT_BTYPE 0x000f /* mask for basic type */
458 #define VT_UNSIGNED 0x0010 /* unsigned type */
459 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
460 #define VT_BITFIELD 0x0040 /* bitfield modifier */
462 /* storage */
463 #define VT_EXTERN 0x00000080 /* extern definition */
464 #define VT_STATIC 0x00000100 /* static variable */
465 #define VT_TYPEDEF 0x00000200 /* typedef definition */
466 #define VT_INLINE 0x00000400 /* inline definition */
468 /* type mask (except storage) */
469 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
470 #define VT_TYPE (~(VT_STORAGE))
472 /* token values */
474 /* warning: the following compare tokens depend on i386 asm code */
475 #define TOK_ULT 0x92
476 #define TOK_UGE 0x93
477 #define TOK_EQ 0x94
478 #define TOK_NE 0x95
479 #define TOK_ULE 0x96
480 #define TOK_UGT 0x97
481 #define TOK_LT 0x9c
482 #define TOK_GE 0x9d
483 #define TOK_LE 0x9e
484 #define TOK_GT 0x9f
486 #define TOK_LAND 0xa0
487 #define TOK_LOR 0xa1
489 #define TOK_DEC 0xa2
490 #define TOK_MID 0xa3 /* inc/dec, to void constant */
491 #define TOK_INC 0xa4
492 #define TOK_UDIV 0xb0 /* unsigned division */
493 #define TOK_UMOD 0xb1 /* unsigned modulo */
494 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
495 #define TOK_CINT 0xb3 /* number in tokc */
496 #define TOK_CCHAR 0xb4 /* char constant in tokc */
497 #define TOK_STR 0xb5 /* pointer to string in tokc */
498 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
499 #define TOK_LCHAR 0xb7
500 #define TOK_LSTR 0xb8
501 #define TOK_CFLOAT 0xb9 /* float constant */
502 #define TOK_LINENUM 0xba /* line number info */
503 #define TOK_CDOUBLE 0xc0 /* double constant */
504 #define TOK_CLDOUBLE 0xc1 /* long double constant */
505 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
506 #define TOK_ADDC1 0xc3 /* add with carry generation */
507 #define TOK_ADDC2 0xc4 /* add with carry use */
508 #define TOK_SUBC1 0xc5 /* add with carry generation */
509 #define TOK_SUBC2 0xc6 /* add with carry use */
510 #define TOK_CUINT 0xc8 /* unsigned int constant */
511 #define TOK_CLLONG 0xc9 /* long long constant */
512 #define TOK_CULLONG 0xca /* unsigned long long constant */
513 #define TOK_ARROW 0xcb
514 #define TOK_DOTS 0xcc /* three dots */
515 #define TOK_SHR 0xcd /* unsigned shift right */
516 #define TOK_PPNUM 0xce /* preprocessor number */
518 #define TOK_SHL 0x01 /* shift left */
519 #define TOK_SAR 0x02 /* signed shift right */
521 /* assignement operators : normal operator or 0x80 */
522 #define TOK_A_MOD 0xa5
523 #define TOK_A_AND 0xa6
524 #define TOK_A_MUL 0xaa
525 #define TOK_A_ADD 0xab
526 #define TOK_A_SUB 0xad
527 #define TOK_A_DIV 0xaf
528 #define TOK_A_XOR 0xde
529 #define TOK_A_OR 0xfc
530 #define TOK_A_SHL 0x81
531 #define TOK_A_SAR 0x82
533 /* WARNING: the content of this string encodes token numbers */
534 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";
536 #define TOK_EOF (-1) /* end of file */
537 #define TOK_LINEFEED 10 /* line feed */
539 /* all identificators and strings have token above that */
540 #define TOK_IDENT 256
542 /* only used for i386 asm opcodes definitions */
543 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
545 #define DEF_BWL(x) \
546 DEF(TOK_ASM_ ## x ## b, #x "b") \
547 DEF(TOK_ASM_ ## x ## w, #x "w") \
548 DEF(TOK_ASM_ ## x ## l, #x "l") \
549 DEF(TOK_ASM_ ## x, #x)
551 #define DEF_WL(x) \
552 DEF(TOK_ASM_ ## x ## w, #x "w") \
553 DEF(TOK_ASM_ ## x ## l, #x "l") \
554 DEF(TOK_ASM_ ## x, #x)
556 #define DEF_FP1(x) \
557 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
558 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
559 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
560 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
562 #define DEF_FP(x) \
563 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
564 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
565 DEF_FP1(x)
567 #define DEF_ASMTEST(x) \
568 DEF_ASM(x ## o) \
569 DEF_ASM(x ## no) \
570 DEF_ASM(x ## b) \
571 DEF_ASM(x ## c) \
572 DEF_ASM(x ## nae) \
573 DEF_ASM(x ## nb) \
574 DEF_ASM(x ## nc) \
575 DEF_ASM(x ## ae) \
576 DEF_ASM(x ## e) \
577 DEF_ASM(x ## z) \
578 DEF_ASM(x ## ne) \
579 DEF_ASM(x ## nz) \
580 DEF_ASM(x ## be) \
581 DEF_ASM(x ## na) \
582 DEF_ASM(x ## nbe) \
583 DEF_ASM(x ## a) \
584 DEF_ASM(x ## s) \
585 DEF_ASM(x ## ns) \
586 DEF_ASM(x ## p) \
587 DEF_ASM(x ## pe) \
588 DEF_ASM(x ## np) \
589 DEF_ASM(x ## po) \
590 DEF_ASM(x ## l) \
591 DEF_ASM(x ## nge) \
592 DEF_ASM(x ## nl) \
593 DEF_ASM(x ## ge) \
594 DEF_ASM(x ## le) \
595 DEF_ASM(x ## ng) \
596 DEF_ASM(x ## nle) \
597 DEF_ASM(x ## g)
599 #define TOK_ASM_int TOK_INT
601 enum {
602 TOK_LAST = TOK_IDENT - 1,
603 #define DEF(id, str) id,
604 #include "tcctok.h"
605 #undef DEF
608 static const char tcc_keywords[] =
609 #define DEF(id, str) str "\0"
610 #include "tcctok.h"
611 #undef DEF
614 #define TOK_UIDENT TOK_DEFINE
616 #ifdef WIN32
617 #define snprintf _snprintf
618 #define vsnprintf _vsnprintf
619 #endif
621 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
622 /* currently incorrect */
623 long double strtold(const char *nptr, char **endptr)
625 return (long double)strtod(nptr, endptr);
627 float strtof(const char *nptr, char **endptr)
629 return (float)strtod(nptr, endptr);
631 #else
632 /* XXX: need to define this to use them in non ISOC99 context */
633 extern float strtof (const char *__nptr, char **__endptr);
634 extern long double strtold (const char *__nptr, char **__endptr);
635 #endif
637 static char *pstrcpy(char *buf, int buf_size, const char *s);
638 static char *pstrcat(char *buf, int buf_size, const char *s);
640 static void next(void);
641 static void next_nomacro(void);
642 static void parse_expr_type(CType *type);
643 static void expr_type(CType *type);
644 static void unary_type(CType *type);
645 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
646 int case_reg, int is_expr);
647 static int expr_const(void);
648 static void expr_eq(void);
649 static void gexpr(void);
650 static void decl(int l);
651 static void decl_initializer(CType *type, Section *sec, unsigned long c,
652 int first, int size_only);
653 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
654 int has_init, int v, int scope);
655 int gv(int rc);
656 void gv2(int rc1, int rc2);
657 void move_reg(int r, int s);
658 void save_regs(int n);
659 void save_reg(int r);
660 void vpop(void);
661 void vswap(void);
662 void vdup(void);
663 int get_reg(int rc);
665 static void macro_subst(TokenString *tok_str,
666 Sym **nested_list, const int *macro_str);
667 int save_reg_forced(int r);
668 void gen_op(int op);
669 void force_charshort_cast(int t);
670 static void gen_cast(CType *type);
671 void vstore(void);
672 static Sym *sym_find(int v);
673 static Sym *sym_push(int v, CType *type, int r, int c);
675 /* type handling */
676 static int type_size(CType *type, int *a);
677 static inline CType *pointed_type(CType *type);
678 static int pointed_size(CType *type);
679 static int lvalue_type(int t);
680 static int is_compatible_types(CType *type1, CType *type2);
681 static int parse_btype(CType *type, AttributeDef *ad);
682 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
684 void error(const char *fmt, ...);
685 void vpushi(int v);
686 void vset(CType *type, int r, int v);
687 void type_to_str(char *buf, int buf_size,
688 CType *type, const char *varstr);
689 char *get_tok_str(int v, CValue *cv);
690 static Sym *get_sym_ref(CType *type, Section *sec,
691 unsigned long offset, unsigned long size);
692 static Sym *external_global_sym(int v, CType *type, int r);
694 /* section generation */
695 static void section_realloc(Section *sec, unsigned long new_size);
696 static void *section_ptr_add(Section *sec, unsigned long size);
697 static void put_extern_sym(Sym *sym, Section *section,
698 unsigned long value, unsigned long size);
699 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
700 static int put_elf_str(Section *s, const char *sym);
701 static int put_elf_sym(Section *s,
702 unsigned long value, unsigned long size,
703 int info, int other, int shndx, const char *name);
704 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
705 int info, int sh_num, const char *name);
706 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
707 int type, int symbol);
708 static void put_stabs(const char *str, int type, int other, int desc,
709 unsigned long value);
710 static void put_stabs_r(const char *str, int type, int other, int desc,
711 unsigned long value, Section *sec, int sym_index);
712 static void put_stabn(int type, int other, int desc, int value);
713 static void put_stabd(int type, int other, int desc);
714 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
716 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
717 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
718 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
720 /* tccasm.c */
722 #ifdef CONFIG_TCC_ASM
724 typedef struct ExprValue {
725 uint32_t v;
726 Sym *sym;
727 } ExprValue;
729 #define MAX_ASM_OPERANDS 30
731 typedef struct ASMOperand {
732 int id; /* GCC 3 optionnal identifier (0 if number only supported */
733 char *constraint;
734 char asm_str[16]; /* computed asm string for operand */
735 SValue *vt; /* C value of the expression */
736 int ref_index; /* if >= 0, gives reference to a output constraint */
737 int priority; /* priority, used to assign registers */
738 int reg; /* if >= 0, register number used for this operand */
739 } ASMOperand;
741 static void asm_expr(TCCState *s1, ExprValue *pe);
742 static int asm_int_expr(TCCState *s1);
743 static int find_constraint(ASMOperand *operands, int nb_operands,
744 const char *name, const char **pp);
746 static int tcc_assemble(TCCState *s1, int do_preprocess);
748 #endif
750 static void asm_instr(void);
752 /* true if float/double/long double type */
753 static inline int is_float(int t)
755 int bt;
756 bt = t & VT_BTYPE;
757 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
760 #ifdef TCC_TARGET_I386
761 #include "i386-gen.c"
762 #endif
764 #ifdef CONFIG_TCC_STATIC
766 #define RTLD_LAZY 0x001
767 #define RTLD_NOW 0x002
768 #define RTLD_GLOBAL 0x100
769 #define RTLD_DEFAULT NULL
771 /* dummy function for profiling */
772 void *dlopen(const char *filename, int flag)
774 return NULL;
777 const char *dlerror(void)
779 return "error";
782 typedef struct TCCSyms {
783 char *str;
784 void *ptr;
785 } TCCSyms;
787 #define TCCSYM(a) { #a, &a, },
789 /* add the symbol you want here if no dynamic linking is done */
790 static TCCSyms tcc_syms[] = {
791 TCCSYM(printf)
792 TCCSYM(fprintf)
793 TCCSYM(fopen)
794 TCCSYM(fclose)
795 { NULL, NULL },
798 void *dlsym(void *handle, const char *symbol)
800 TCCSyms *p;
801 p = tcc_syms;
802 while (p->str != NULL) {
803 if (!strcmp(p->str, symbol))
804 return p->ptr;
805 p++;
807 return NULL;
810 #endif
812 /********************************************************/
814 /* we use our own 'finite' function to avoid potential problems with
815 non standard math libs */
816 /* XXX: endianness dependant */
817 int ieee_finite(double d)
819 int *p = (int *)&d;
820 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
823 /* copy a string and truncate it. */
824 static char *pstrcpy(char *buf, int buf_size, const char *s)
826 char *q, *q_end;
827 int c;
829 if (buf_size > 0) {
830 q = buf;
831 q_end = buf + buf_size - 1;
832 while (q < q_end) {
833 c = *s++;
834 if (c == '\0')
835 break;
836 *q++ = c;
838 *q = '\0';
840 return buf;
843 /* strcat and truncate. */
844 static char *pstrcat(char *buf, int buf_size, const char *s)
846 int len;
847 len = strlen(buf);
848 if (len < buf_size)
849 pstrcpy(buf + len, buf_size - len, s);
850 return buf;
853 /* memory management */
854 #ifdef MEM_DEBUG
855 int mem_cur_size;
856 int mem_max_size;
857 #endif
859 static inline void tcc_free(void *ptr)
861 #ifdef MEM_DEBUG
862 mem_cur_size -= malloc_usable_size(ptr);
863 #endif
864 free(ptr);
867 static void *tcc_malloc(unsigned long size)
869 void *ptr;
870 ptr = malloc(size);
871 if (!ptr && size)
872 error("memory full");
873 #ifdef MEM_DEBUG
874 mem_cur_size += malloc_usable_size(ptr);
875 if (mem_cur_size > mem_max_size)
876 mem_max_size = mem_cur_size;
877 #endif
878 return ptr;
881 static void *tcc_mallocz(unsigned long size)
883 void *ptr;
884 ptr = tcc_malloc(size);
885 memset(ptr, 0, size);
886 return ptr;
889 static inline void *tcc_realloc(void *ptr, unsigned long size)
891 void *ptr1;
892 #ifdef MEM_DEBUG
893 mem_cur_size -= malloc_usable_size(ptr);
894 #endif
895 ptr1 = realloc(ptr, size);
896 #ifdef MEM_DEBUG
897 /* NOTE: count not correct if alloc error, but not critical */
898 mem_cur_size += malloc_usable_size(ptr1);
899 if (mem_cur_size > mem_max_size)
900 mem_max_size = mem_cur_size;
901 #endif
902 return ptr1;
905 static char *tcc_strdup(const char *str)
907 char *ptr;
908 ptr = tcc_malloc(strlen(str) + 1);
909 strcpy(ptr, str);
910 return ptr;
913 #define free(p) use_tcc_free(p)
914 #define malloc(s) use_tcc_malloc(s)
915 #define realloc(p, s) use_tcc_realloc(p, s)
917 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
919 int nb, nb_alloc;
920 void **pp;
922 nb = *nb_ptr;
923 pp = *ptab;
924 /* every power of two we double array size */
925 if ((nb & (nb - 1)) == 0) {
926 if (!nb)
927 nb_alloc = 1;
928 else
929 nb_alloc = nb * 2;
930 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
931 if (!pp)
932 error("memory full");
933 *ptab = pp;
935 pp[nb++] = data;
936 *nb_ptr = nb;
939 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
941 Section *sec;
943 sec = tcc_mallocz(sizeof(Section));
944 pstrcpy(sec->name, sizeof(sec->name), name);
945 sec->sh_type = sh_type;
946 sec->sh_flags = sh_flags;
947 switch(sh_type) {
948 case SHT_HASH:
949 case SHT_REL:
950 case SHT_DYNSYM:
951 case SHT_SYMTAB:
952 case SHT_DYNAMIC:
953 sec->sh_addralign = 4;
954 break;
955 case SHT_STRTAB:
956 sec->sh_addralign = 1;
957 break;
958 default:
959 sec->sh_addralign = 32; /* default conservative alignment */
960 break;
963 /* only add section if not private */
964 if (!(sh_flags & SHF_PRIVATE)) {
965 sec->sh_num = s1->nb_sections;
966 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
968 return sec;
971 static void free_section(Section *s)
973 tcc_free(s->data);
974 tcc_free(s);
977 /* realloc section and set its content to zero */
978 static void section_realloc(Section *sec, unsigned long new_size)
980 unsigned long size;
981 unsigned char *data;
983 size = sec->data_allocated;
984 if (size == 0)
985 size = 1;
986 while (size < new_size)
987 size = size * 2;
988 data = tcc_realloc(sec->data, size);
989 if (!data)
990 error("memory full");
991 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
992 sec->data = data;
993 sec->data_allocated = size;
996 /* reserve at least 'size' bytes in section 'sec' from
997 sec->data_offset. */
998 static void *section_ptr_add(Section *sec, unsigned long size)
1000 unsigned long offset, offset1;
1002 offset = sec->data_offset;
1003 offset1 = offset + size;
1004 if (offset1 > sec->data_allocated)
1005 section_realloc(sec, offset1);
1006 sec->data_offset = offset1;
1007 return sec->data + offset;
1010 /* return a reference to a section, and create it if it does not
1011 exists */
1012 Section *find_section(TCCState *s1, const char *name)
1014 Section *sec;
1015 int i;
1016 for(i = 1; i < s1->nb_sections; i++) {
1017 sec = s1->sections[i];
1018 if (!strcmp(name, sec->name))
1019 return sec;
1021 /* sections are created as PROGBITS */
1022 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
1025 /* update sym->c so that it points to an external symbol in section
1026 'section' with value 'value' */
1027 static void put_extern_sym(Sym *sym, Section *section,
1028 unsigned long value, unsigned long size)
1030 int sym_type, sym_bind, sh_num, info;
1031 Elf32_Sym *esym;
1032 const char *name;
1034 if (section)
1035 sh_num = section->sh_num;
1036 else
1037 sh_num = SHN_UNDEF;
1038 if (!sym->c) {
1039 if ((sym->type.t & VT_BTYPE) == VT_FUNC)
1040 sym_type = STT_FUNC;
1041 else
1042 sym_type = STT_OBJECT;
1043 if (sym->type.t & VT_STATIC)
1044 sym_bind = STB_LOCAL;
1045 else
1046 sym_bind = STB_GLOBAL;
1048 name = get_tok_str(sym->v, NULL);
1049 #ifdef CONFIG_TCC_BCHECK
1050 if (do_bounds_check) {
1051 char buf[32];
1053 /* XXX: avoid doing that for statics ? */
1054 /* if bound checking is activated, we change some function
1055 names by adding the "__bound" prefix */
1056 switch(sym->v) {
1057 #if 0
1058 /* XXX: we rely only on malloc hooks */
1059 case TOK_malloc:
1060 case TOK_free:
1061 case TOK_realloc:
1062 case TOK_memalign:
1063 case TOK_calloc:
1064 #endif
1065 case TOK_memcpy:
1066 case TOK_memmove:
1067 case TOK_memset:
1068 case TOK_strlen:
1069 case TOK_strcpy:
1070 strcpy(buf, "__bound_");
1071 strcat(buf, name);
1072 name = buf;
1073 break;
1076 #endif
1077 info = ELF32_ST_INFO(sym_bind, sym_type);
1078 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
1079 } else {
1080 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
1081 esym->st_value = value;
1082 esym->st_size = size;
1083 esym->st_shndx = sh_num;
1087 /* add a new relocation entry to symbol 'sym' in section 's' */
1088 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
1090 if (!sym->c)
1091 put_extern_sym(sym, NULL, 0, 0);
1092 /* now we can add ELF relocation info */
1093 put_elf_reloc(symtab_section, s, offset, type, sym->c);
1096 static inline int isid(int c)
1098 return (c >= 'a' && c <= 'z') ||
1099 (c >= 'A' && c <= 'Z') ||
1100 c == '_';
1103 static inline int isnum(int c)
1105 return c >= '0' && c <= '9';
1108 static inline int isoct(int c)
1110 return c >= '0' && c <= '7';
1113 static inline int toup(int c)
1115 if (c >= 'a' && c <= 'z')
1116 return c - 'a' + 'A';
1117 else
1118 return c;
1121 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
1123 int len;
1124 len = strlen(buf);
1125 vsnprintf(buf + len, buf_size - len, fmt, ap);
1128 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
1130 va_list ap;
1131 va_start(ap, fmt);
1132 strcat_vprintf(buf, buf_size, fmt, ap);
1133 va_end(ap);
1136 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
1138 char buf[2048];
1139 BufferedFile **f;
1141 buf[0] = '\0';
1142 if (file) {
1143 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1144 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1145 (*f)->filename, (*f)->line_num);
1146 if (file->line_num > 0) {
1147 strcat_printf(buf, sizeof(buf),
1148 "%s:%d: ", file->filename, file->line_num);
1149 } else {
1150 strcat_printf(buf, sizeof(buf),
1151 "%s: ", file->filename);
1153 } else {
1154 strcat_printf(buf, sizeof(buf),
1155 "tcc: ");
1157 if (is_warning)
1158 strcat_printf(buf, sizeof(buf), "warning: ");
1159 strcat_vprintf(buf, sizeof(buf), fmt, ap);
1161 if (!s1->error_func) {
1162 /* default case: stderr */
1163 fprintf(stderr, "%s\n", buf);
1164 } else {
1165 s1->error_func(s1->error_opaque, buf);
1167 if (!is_warning)
1168 s1->nb_errors++;
1171 #ifdef LIBTCC
1172 void tcc_set_error_func(TCCState *s, void *error_opaque,
1173 void (*error_func)(void *opaque, const char *msg))
1175 s->error_opaque = error_opaque;
1176 s->error_func = error_func;
1178 #endif
1180 /* error without aborting current compilation */
1181 void error_noabort(const char *fmt, ...)
1183 TCCState *s1 = tcc_state;
1184 va_list ap;
1186 va_start(ap, fmt);
1187 error1(s1, 0, fmt, ap);
1188 va_end(ap);
1191 void error(const char *fmt, ...)
1193 TCCState *s1 = tcc_state;
1194 va_list ap;
1196 va_start(ap, fmt);
1197 error1(s1, 0, fmt, ap);
1198 va_end(ap);
1199 /* better than nothing: in some cases, we accept to handle errors */
1200 if (s1->error_set_jmp_enabled) {
1201 longjmp(s1->error_jmp_buf, 1);
1202 } else {
1203 /* XXX: suppress it someday */
1204 exit(1);
1208 void expect(const char *msg)
1210 error("%s expected", msg);
1213 void warning(const char *fmt, ...)
1215 TCCState *s1 = tcc_state;
1216 va_list ap;
1218 va_start(ap, fmt);
1219 error1(s1, 1, fmt, ap);
1220 va_end(ap);
1223 void skip(int c)
1225 if (tok != c)
1226 error("'%c' expected", c);
1227 next();
1230 static void test_lvalue(void)
1232 if (!(vtop->r & VT_LVAL))
1233 expect("lvalue");
1236 /* allocate a new token */
1237 static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
1239 TokenSym *ts, **ptable;
1240 int i;
1242 if (tok_ident >= SYM_FIRST_ANOM)
1243 error("memory full");
1245 /* expand token table if needed */
1246 i = tok_ident - TOK_IDENT;
1247 if ((i % TOK_ALLOC_INCR) == 0) {
1248 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1249 if (!ptable)
1250 error("memory full");
1251 table_ident = ptable;
1254 ts = tcc_malloc(sizeof(TokenSym) + len);
1255 table_ident[i] = ts;
1256 ts->tok = tok_ident++;
1257 ts->sym_define = NULL;
1258 ts->sym_label = NULL;
1259 ts->sym_struct = NULL;
1260 ts->sym_identifier = NULL;
1261 ts->len = len;
1262 ts->hash_next = NULL;
1263 memcpy(ts->str, str, len);
1264 ts->str[len] = '\0';
1265 *pts = ts;
1266 return ts;
1269 #define TOK_HASH_INIT 1
1270 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1272 /* find a token and add it if not found */
1273 static TokenSym *tok_alloc(const char *str, int len)
1275 TokenSym *ts, **pts;
1276 int i;
1277 unsigned int h;
1279 h = TOK_HASH_INIT;
1280 for(i=0;i<len;i++)
1281 h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
1282 h &= (TOK_HASH_SIZE - 1);
1284 pts = &hash_ident[h];
1285 for(;;) {
1286 ts = *pts;
1287 if (!ts)
1288 break;
1289 if (ts->len == len && !memcmp(ts->str, str, len))
1290 return ts;
1291 pts = &(ts->hash_next);
1293 return tok_alloc_new(pts, str, len);
1296 /* CString handling */
1298 static void cstr_realloc(CString *cstr, int new_size)
1300 int size;
1301 void *data;
1303 size = cstr->size_allocated;
1304 if (size == 0)
1305 size = 8; /* no need to allocate a too small first string */
1306 while (size < new_size)
1307 size = size * 2;
1308 data = tcc_realloc(cstr->data_allocated, size);
1309 if (!data)
1310 error("memory full");
1311 cstr->data_allocated = data;
1312 cstr->size_allocated = size;
1313 cstr->data = data;
1316 /* add a byte */
1317 static void cstr_ccat(CString *cstr, int ch)
1319 int size;
1320 size = cstr->size + 1;
1321 if (size > cstr->size_allocated)
1322 cstr_realloc(cstr, size);
1323 ((unsigned char *)cstr->data)[size - 1] = ch;
1324 cstr->size = size;
1327 static void cstr_cat(CString *cstr, const char *str)
1329 int c;
1330 for(;;) {
1331 c = *str;
1332 if (c == '\0')
1333 break;
1334 cstr_ccat(cstr, c);
1335 str++;
1339 /* add a wide char */
1340 static void cstr_wccat(CString *cstr, int ch)
1342 int size;
1343 size = cstr->size + sizeof(int);
1344 if (size > cstr->size_allocated)
1345 cstr_realloc(cstr, size);
1346 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1347 cstr->size = size;
1350 static void cstr_new(CString *cstr)
1352 memset(cstr, 0, sizeof(CString));
1355 /* free string and reset it to NULL */
1356 static void cstr_free(CString *cstr)
1358 tcc_free(cstr->data_allocated);
1359 cstr_new(cstr);
1362 #define cstr_reset(cstr) cstr_free(cstr)
1364 static CString *cstr_dup(CString *cstr1)
1366 CString *cstr;
1367 int size;
1369 cstr = tcc_malloc(sizeof(CString));
1370 size = cstr1->size;
1371 cstr->size = size;
1372 cstr->size_allocated = size;
1373 cstr->data_allocated = tcc_malloc(size);
1374 cstr->data = cstr->data_allocated;
1375 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1376 return cstr;
1379 /* XXX: unicode ? */
1380 static void add_char(CString *cstr, int c)
1382 if (c == '\'' || c == '\"' || c == '\\') {
1383 /* XXX: could be more precise if char or string */
1384 cstr_ccat(cstr, '\\');
1386 if (c >= 32 && c <= 126) {
1387 cstr_ccat(cstr, c);
1388 } else {
1389 cstr_ccat(cstr, '\\');
1390 if (c == '\n') {
1391 cstr_ccat(cstr, 'n');
1392 } else {
1393 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1394 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1395 cstr_ccat(cstr, '0' + (c & 7));
1400 /* XXX: buffer overflow */
1401 /* XXX: float tokens */
1402 char *get_tok_str(int v, CValue *cv)
1404 static char buf[STRING_MAX_SIZE + 1];
1405 static CString cstr_buf;
1406 CString *cstr;
1407 unsigned char *q;
1408 char *p;
1409 int i, len;
1411 /* NOTE: to go faster, we give a fixed buffer for small strings */
1412 cstr_reset(&cstr_buf);
1413 cstr_buf.data = buf;
1414 cstr_buf.size_allocated = sizeof(buf);
1415 p = buf;
1417 switch(v) {
1418 case TOK_CINT:
1419 case TOK_CUINT:
1420 /* XXX: not quite exact, but only useful for testing */
1421 sprintf(p, "%u", cv->ui);
1422 break;
1423 case TOK_CLLONG:
1424 case TOK_CULLONG:
1425 /* XXX: not quite exact, but only useful for testing */
1426 sprintf(p, "%Lu", cv->ull);
1427 break;
1428 case TOK_CCHAR:
1429 case TOK_LCHAR:
1430 cstr_ccat(&cstr_buf, '\'');
1431 add_char(&cstr_buf, cv->i);
1432 cstr_ccat(&cstr_buf, '\'');
1433 cstr_ccat(&cstr_buf, '\0');
1434 break;
1435 case TOK_PPNUM:
1436 cstr = cv->cstr;
1437 len = cstr->size - 1;
1438 for(i=0;i<len;i++)
1439 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1440 cstr_ccat(&cstr_buf, '\0');
1441 break;
1442 case TOK_STR:
1443 case TOK_LSTR:
1444 cstr = cv->cstr;
1445 cstr_ccat(&cstr_buf, '\"');
1446 if (v == TOK_STR) {
1447 len = cstr->size - 1;
1448 for(i=0;i<len;i++)
1449 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1450 } else {
1451 len = (cstr->size / sizeof(int)) - 1;
1452 for(i=0;i<len;i++)
1453 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1455 cstr_ccat(&cstr_buf, '\"');
1456 cstr_ccat(&cstr_buf, '\0');
1457 break;
1458 case TOK_LT:
1459 v = '<';
1460 goto addv;
1461 case TOK_GT:
1462 v = '>';
1463 goto addv;
1464 case TOK_A_SHL:
1465 return strcpy(p, "<<=");
1466 case TOK_A_SAR:
1467 return strcpy(p, ">>=");
1468 default:
1469 if (v < TOK_IDENT) {
1470 /* search in two bytes table */
1471 q = tok_two_chars;
1472 while (*q) {
1473 if (q[2] == v) {
1474 *p++ = q[0];
1475 *p++ = q[1];
1476 *p = '\0';
1477 return buf;
1479 q += 3;
1481 addv:
1482 *p++ = v;
1483 *p = '\0';
1484 } else if (v < tok_ident) {
1485 return table_ident[v - TOK_IDENT]->str;
1486 } else if (v >= SYM_FIRST_ANOM) {
1487 /* special name for anonymous symbol */
1488 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1489 } else {
1490 /* should never happen */
1491 return NULL;
1493 break;
1495 return cstr_buf.data;
1498 /* push, without hashing */
1499 static Sym *sym_push2(Sym **ps, int v, int t, int c)
1501 Sym *s;
1502 s = tcc_malloc(sizeof(Sym));
1503 s->v = v;
1504 s->type.t = t;
1505 s->c = c;
1506 s->next = NULL;
1507 /* add in stack */
1508 s->prev = *ps;
1509 *ps = s;
1510 return s;
1513 /* find a symbol and return its associated structure. 's' is the top
1514 of the symbol stack */
1515 static Sym *sym_find2(Sym *s, int v)
1517 while (s) {
1518 if (s->v == v)
1519 return s;
1520 s = s->prev;
1522 return NULL;
1525 /* structure lookup */
1526 static Sym *struct_find(int v)
1528 v -= TOK_IDENT;
1529 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1530 return NULL;
1531 return table_ident[v]->sym_struct;
1534 /* find an identifier */
1535 static inline Sym *sym_find(int v)
1537 v -= TOK_IDENT;
1538 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1539 return NULL;
1540 return table_ident[v]->sym_identifier;
1543 /* push a given symbol on the symbol stack */
1544 static Sym *sym_push(int v, CType *type, int r, int c)
1546 Sym *s, **ps;
1547 TokenSym *ts;
1549 if (local_stack)
1550 ps = &local_stack;
1551 else
1552 ps = &global_stack;
1553 s = sym_push2(ps, v, type->t, c);
1554 s->type.ref = type->ref;
1555 s->r = r;
1556 /* don't record fields or anonymous symbols */
1557 /* XXX: simplify */
1558 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1559 /* record symbol in token array */
1560 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1561 if (v & SYM_STRUCT)
1562 ps = &ts->sym_struct;
1563 else
1564 ps = &ts->sym_identifier;
1565 s->prev_tok = *ps;
1566 *ps = s;
1568 return s;
1571 /* push a global identifier */
1572 static Sym *global_identifier_push(int v, int t, int c)
1574 Sym *s, **ps;
1575 s = sym_push2(&global_stack, v, t, c);
1576 /* don't record anonymous symbol */
1577 if (v < SYM_FIRST_ANOM) {
1578 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1579 /* modify the top most local identifier, so that
1580 sym_identifier will point to 's' when popped */
1581 while (*ps != NULL)
1582 ps = &(*ps)->prev_tok;
1583 s->prev_tok = NULL;
1584 *ps = s;
1586 return s;
1589 /* pop symbols until top reaches 'b' */
1590 static void sym_pop(Sym **ptop, Sym *b)
1592 Sym *s, *ss, **ps;
1593 TokenSym *ts;
1594 int v;
1596 s = *ptop;
1597 while(s != b) {
1598 ss = s->prev;
1599 v = s->v;
1600 /* remove symbol in token array */
1601 /* XXX: simplify */
1602 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1603 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1604 if (v & SYM_STRUCT)
1605 ps = &ts->sym_struct;
1606 else
1607 ps = &ts->sym_identifier;
1608 *ps = s->prev_tok;
1610 tcc_free(s);
1611 s = ss;
1613 *ptop = b;
1616 /* I/O layer */
1618 BufferedFile *tcc_open(TCCState *s1, const char *filename)
1620 int fd;
1621 BufferedFile *bf;
1623 fd = open(filename, O_RDONLY);
1624 if (fd < 0)
1625 return NULL;
1626 bf = tcc_malloc(sizeof(BufferedFile));
1627 if (!bf) {
1628 close(fd);
1629 return NULL;
1631 bf->fd = fd;
1632 bf->buf_ptr = bf->buffer;
1633 bf->buf_end = bf->buffer;
1634 bf->buffer[0] = CH_EOB; /* put eob symbol */
1635 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1636 bf->line_num = 1;
1637 bf->ifndef_macro = 0;
1638 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1639 // printf("opening '%s'\n", filename);
1640 return bf;
1643 void tcc_close(BufferedFile *bf)
1645 total_lines += bf->line_num;
1646 close(bf->fd);
1647 tcc_free(bf);
1650 /* fill input buffer and peek next char */
1651 static int tcc_peekc_slow(BufferedFile *bf)
1653 int len;
1654 /* only tries to read if really end of buffer */
1655 if (bf->buf_ptr >= bf->buf_end) {
1656 if (bf->fd != -1) {
1657 #if defined(PARSE_DEBUG)
1658 len = 8;
1659 #else
1660 len = IO_BUF_SIZE;
1661 #endif
1662 len = read(bf->fd, bf->buffer, len);
1663 if (len < 0)
1664 len = 0;
1665 } else {
1666 len = 0;
1668 total_bytes += len;
1669 bf->buf_ptr = bf->buffer;
1670 bf->buf_end = bf->buffer + len;
1671 *bf->buf_end = CH_EOB;
1673 if (bf->buf_ptr < bf->buf_end) {
1674 return bf->buf_ptr[0];
1675 } else {
1676 bf->buf_ptr = bf->buf_end;
1677 return CH_EOF;
1681 /* return the current character, handling end of block if necessary
1682 (but not stray) */
1683 static int handle_eob(void)
1685 return tcc_peekc_slow(file);
1688 /* read next char from current input file and handle end of input buffer */
1689 static inline void inp(void)
1691 ch = *(++(file->buf_ptr));
1692 /* end of buffer/file handling */
1693 if (ch == CH_EOB)
1694 ch = handle_eob();
1697 /* handle '\[\r]\n' */
1698 static void handle_stray(void)
1700 while (ch == '\\') {
1701 inp();
1702 if (ch == '\n') {
1703 file->line_num++;
1704 inp();
1705 } else if (ch == '\r') {
1706 inp();
1707 if (ch != '\n')
1708 goto fail;
1709 file->line_num++;
1710 inp();
1711 } else {
1712 fail:
1713 error("stray '\\' in program");
1718 /* skip the stray and handle the \\n case. Output an error if
1719 incorrect char after the stray */
1720 static int handle_stray1(uint8_t *p)
1722 int c;
1724 if (p >= file->buf_end) {
1725 file->buf_ptr = p;
1726 c = handle_eob();
1727 p = file->buf_ptr;
1728 if (c == '\\')
1729 goto parse_stray;
1730 } else {
1731 parse_stray:
1732 file->buf_ptr = p;
1733 ch = *p;
1734 handle_stray();
1735 p = file->buf_ptr;
1736 c = *p;
1738 return c;
1741 /* handle the complicated stray case */
1742 #define PEEKC(c, p)\
1744 p++;\
1745 c = *p;\
1746 if (c == '\\') {\
1747 c = handle_stray1(p);\
1748 p = file->buf_ptr;\
1752 /* input with '\[\r]\n' handling. Note that this function cannot
1753 handle other characters after '\', so you cannot call it inside
1754 strings or comments */
1755 static void minp(void)
1757 inp();
1758 if (ch == '\\')
1759 handle_stray();
1763 static void parse_line_comment(void)
1765 /* single line C++ comments */
1766 /* XXX: accept '\\\n' ? */
1767 inp();
1768 while (ch != '\n' && ch != CH_EOF)
1769 inp();
1772 static void parse_comment(void)
1774 uint8_t *p;
1775 int c;
1777 /* C comments */
1778 p = file->buf_ptr;
1779 p++;
1780 for(;;) {
1781 /* fast skip loop */
1782 for(;;) {
1783 c = *p;
1784 if (c == '\n' || c == '*' || c == '\\')
1785 break;
1786 p++;
1787 c = *p;
1788 if (c == '\n' || c == '*' || c == '\\')
1789 break;
1790 p++;
1792 /* now we can handle all the cases */
1793 if (c == '\n') {
1794 file->line_num++;
1795 p++;
1796 } else if (c == '*') {
1797 p++;
1798 for(;;) {
1799 c = *p;
1800 if (c == '*') {
1801 p++;
1802 } else if (c == '/') {
1803 goto end_of_comment;
1804 } else if (c == '\\') {
1805 file->buf_ptr = p;
1806 c = handle_eob();
1807 if (c == '\\') {
1808 /* skip '\\n', but if '\' followed but another
1809 char, behave asif a stray was parsed */
1810 ch = file->buf_ptr[0];
1811 while (ch == '\\') {
1812 inp();
1813 if (ch == '\n') {
1814 file->line_num++;
1815 inp();
1816 } else if (ch == '\r') {
1817 inp();
1818 if (ch == '\n') {
1819 file->line_num++;
1820 inp();
1822 } else {
1823 p = file->buf_ptr;
1824 break;
1828 p = file->buf_ptr;
1829 } else {
1830 break;
1833 } else {
1834 /* stray, eob or eof */
1835 file->buf_ptr = p;
1836 c = handle_eob();
1837 p = file->buf_ptr;
1838 if (c == CH_EOF) {
1839 error("unexpected end of file in comment");
1840 } else if (c == '\\') {
1841 p++;
1845 end_of_comment:
1846 p++;
1847 file->buf_ptr = p;
1848 ch = *p;
1851 #define cinp minp
1853 /* space exlcuding newline */
1854 static inline int is_space(int ch)
1856 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1859 static inline void skip_spaces(void)
1861 while (is_space(ch))
1862 cinp();
1865 /* skip block of text until #else, #elif or #endif. skip also pairs of
1866 #if/#endif */
1867 void preprocess_skip(void)
1869 int a, start_of_line, sep, c;
1870 uint8_t *p;
1872 p = file->buf_ptr;
1873 start_of_line = 1;
1874 a = 0;
1875 for(;;) {
1876 redo_no_start:
1877 c = *p;
1878 switch(c) {
1879 case ' ':
1880 case '\t':
1881 case '\f':
1882 case '\v':
1883 case '\r':
1884 p++;
1885 goto redo_no_start;
1886 case '\n':
1887 start_of_line = 1;
1888 file->line_num++;
1889 p++;
1890 goto redo_no_start;
1891 case '\\':
1892 file->buf_ptr = p;
1893 c = handle_eob();
1894 if (c == CH_EOF) {
1895 expect("#endif");
1896 } else if (c == '\\') {
1897 /* XXX: incorrect: should not give an error */
1898 ch = file->buf_ptr[0];
1899 handle_stray();
1901 p = file->buf_ptr;
1902 goto redo_no_start;
1903 /* skip strings */
1904 case '\"':
1905 case '\'':
1906 sep = c;
1907 p++;
1908 for(;;) {
1909 c = *p;
1910 if (c == sep) {
1911 break;
1912 } else if (c == '\\') {
1913 file->buf_ptr = p;
1914 c = handle_eob();
1915 p = file->buf_ptr;
1916 if (c == CH_EOF) {
1917 /* XXX: better error message */
1918 error("unterminated string");
1919 } else if (c == '\\') {
1920 /* ignore next char */
1921 p++;
1922 c = *p;
1923 if (c == '\\') {
1924 file->buf_ptr = p;
1925 c = handle_eob();
1926 p = file->buf_ptr;
1928 if (c == '\n')
1929 file->line_num++;
1930 else if (c != CH_EOF)
1931 p++;
1933 } else if (c == '\n') {
1934 file->line_num++;
1935 p++;
1936 } else {
1937 p++;
1940 p++;
1941 break;
1942 /* skip comments */
1943 case '/':
1944 file->buf_ptr = p;
1945 ch = *p;
1946 minp();
1947 if (ch == '*') {
1948 parse_comment();
1949 } else if (ch == '/') {
1950 parse_line_comment();
1952 p = file->buf_ptr;
1953 break;
1955 case '#':
1956 p++;
1957 if (start_of_line) {
1958 file->buf_ptr = p;
1959 next_nomacro();
1960 p = file->buf_ptr;
1961 if (a == 0 &&
1962 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1963 goto the_end;
1964 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1965 a++;
1966 else if (tok == TOK_ENDIF)
1967 a--;
1969 break;
1970 default:
1971 p++;
1972 break;
1974 start_of_line = 0;
1976 the_end: ;
1977 file->buf_ptr = p;
1980 /* ParseState handling */
1982 /* XXX: currently, no include file info is stored. Thus, we cannot display
1983 accurate messages if the function or data definition spans multiple
1984 files */
1986 /* save current parse state in 's' */
1987 void save_parse_state(ParseState *s)
1989 s->line_num = file->line_num;
1990 s->macro_ptr = macro_ptr;
1991 s->tok = tok;
1992 s->tokc = tokc;
1995 /* restore parse state from 's' */
1996 void restore_parse_state(ParseState *s)
1998 file->line_num = s->line_num;
1999 macro_ptr = s->macro_ptr;
2000 tok = s->tok;
2001 tokc = s->tokc;
2004 /* return the number of additionnal 'ints' necessary to store the
2005 token */
2006 static inline int tok_ext_size(int t)
2008 switch(t) {
2009 /* 4 bytes */
2010 case TOK_CINT:
2011 case TOK_CUINT:
2012 case TOK_CCHAR:
2013 case TOK_LCHAR:
2014 case TOK_STR:
2015 case TOK_LSTR:
2016 case TOK_CFLOAT:
2017 case TOK_LINENUM:
2018 case TOK_PPNUM:
2019 return 1;
2020 case TOK_CDOUBLE:
2021 case TOK_CLLONG:
2022 case TOK_CULLONG:
2023 return 2;
2024 case TOK_CLDOUBLE:
2025 return LDOUBLE_SIZE / 4;
2026 default:
2027 return 0;
2031 /* token string handling */
2033 static inline void tok_str_new(TokenString *s)
2035 s->str = NULL;
2036 s->len = 0;
2037 s->allocated_len = 0;
2038 s->last_line_num = -1;
2041 static void tok_str_free(int *str)
2043 const int *p;
2044 CString *cstr;
2045 int t;
2047 p = str;
2048 for(;;) {
2049 t = *p;
2050 /* NOTE: we test zero separately so that GCC can generate a
2051 table for the following switch */
2052 if (t == 0)
2053 break;
2054 switch(t) {
2055 case TOK_CINT:
2056 case TOK_CUINT:
2057 case TOK_CCHAR:
2058 case TOK_LCHAR:
2059 case TOK_CFLOAT:
2060 case TOK_LINENUM:
2061 p += 2;
2062 break;
2063 case TOK_PPNUM:
2064 case TOK_STR:
2065 case TOK_LSTR:
2066 /* XXX: use a macro to be portable on 64 bit ? */
2067 cstr = (CString *)p[1];
2068 cstr_free(cstr);
2069 tcc_free(cstr);
2070 p += 2;
2071 break;
2072 case TOK_CDOUBLE:
2073 case TOK_CLLONG:
2074 case TOK_CULLONG:
2075 p += 3;
2076 break;
2077 case TOK_CLDOUBLE:
2078 p += 1 + (LDOUBLE_SIZE / 4);
2079 break;
2080 default:
2081 p++;
2082 break;
2085 tcc_free(str);
2088 static int *tok_str_realloc(TokenString *s)
2090 int *str, len;
2092 len = s->allocated_len + TOK_STR_ALLOC_INCR;
2093 str = tcc_realloc(s->str, len * sizeof(int));
2094 if (!str)
2095 error("memory full");
2096 s->allocated_len = len;
2097 s->str = str;
2098 return str;
2101 static void tok_str_add(TokenString *s, int t)
2103 int len, *str;
2105 len = s->len;
2106 str = s->str;
2107 if (len >= s->allocated_len)
2108 str = tok_str_realloc(s);
2109 str[len++] = t;
2110 s->len = len;
2113 static void tok_str_add2(TokenString *s, int t, CValue *cv)
2115 int len, *str;
2117 len = s->len;
2118 str = s->str;
2120 /* allocate space for worst case */
2121 if (len + TOK_MAX_SIZE > s->allocated_len)
2122 str = tok_str_realloc(s);
2123 str[len++] = t;
2124 switch(t) {
2125 case TOK_CINT:
2126 case TOK_CUINT:
2127 case TOK_CCHAR:
2128 case TOK_LCHAR:
2129 case TOK_CFLOAT:
2130 case TOK_LINENUM:
2131 str[len++] = cv->tab[0];
2132 break;
2133 case TOK_PPNUM:
2134 case TOK_STR:
2135 case TOK_LSTR:
2136 str[len++] = (int)cstr_dup(cv->cstr);
2137 break;
2138 case TOK_CDOUBLE:
2139 case TOK_CLLONG:
2140 case TOK_CULLONG:
2141 str[len++] = cv->tab[0];
2142 str[len++] = cv->tab[1];
2143 break;
2144 case TOK_CLDOUBLE:
2145 #if LDOUBLE_SIZE == 12
2146 str[len++] = cv->tab[0];
2147 str[len++] = cv->tab[1];
2148 str[len++] = cv->tab[2];
2149 #else
2150 #error add long double size support
2151 #endif
2152 break;
2153 default:
2154 break;
2156 s->len = len;
2159 /* add the current parse token in token string 's' */
2160 static void tok_str_add_tok(TokenString *s)
2162 CValue cval;
2164 /* save line number info */
2165 if (file->line_num != s->last_line_num) {
2166 s->last_line_num = file->line_num;
2167 cval.i = s->last_line_num;
2168 tok_str_add2(s, TOK_LINENUM, &cval);
2170 tok_str_add2(s, tok, &tokc);
2173 #if LDOUBLE_SIZE == 12
2174 #define LDOUBLE_GET(p, cv) \
2175 cv.tab[0] = p[0]; \
2176 cv.tab[1] = p[1]; \
2177 cv.tab[2] = p[2];
2178 #else
2179 #error add long double size support
2180 #endif
2183 /* get a token from an integer array and increment pointer
2184 accordingly. we code it as a macro to avoid pointer aliasing. */
2185 #define TOK_GET(t, p, cv) \
2187 t = *p++; \
2188 switch(t) { \
2189 case TOK_CINT: \
2190 case TOK_CUINT: \
2191 case TOK_CCHAR: \
2192 case TOK_LCHAR: \
2193 case TOK_CFLOAT: \
2194 case TOK_LINENUM: \
2195 case TOK_STR: \
2196 case TOK_LSTR: \
2197 case TOK_PPNUM: \
2198 cv.tab[0] = *p++; \
2199 break; \
2200 case TOK_CDOUBLE: \
2201 case TOK_CLLONG: \
2202 case TOK_CULLONG: \
2203 cv.tab[0] = p[0]; \
2204 cv.tab[1] = p[1]; \
2205 p += 2; \
2206 break; \
2207 case TOK_CLDOUBLE: \
2208 LDOUBLE_GET(p, cv); \
2209 p += LDOUBLE_SIZE / 4; \
2210 break; \
2211 default: \
2212 break; \
2216 /* defines handling */
2217 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
2219 Sym *s;
2221 s = sym_push2(&define_stack, v, macro_type, (int)str);
2222 s->next = first_arg;
2223 table_ident[v - TOK_IDENT]->sym_define = s;
2226 /* undefined a define symbol. Its name is just set to zero */
2227 static void define_undef(Sym *s)
2229 int v;
2230 v = s->v;
2231 if (v >= TOK_IDENT && v < tok_ident)
2232 table_ident[v - TOK_IDENT]->sym_define = NULL;
2233 s->v = 0;
2236 static inline Sym *define_find(int v)
2238 v -= TOK_IDENT;
2239 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2240 return NULL;
2241 return table_ident[v]->sym_define;
2244 /* free define stack until top reaches 'b' */
2245 static void free_defines(Sym *b)
2247 Sym *top, *top1;
2248 int v;
2250 top = define_stack;
2251 while (top != b) {
2252 top1 = top->prev;
2253 /* do not free args or predefined defines */
2254 if (top->c)
2255 tok_str_free((int *)top->c);
2256 v = top->v;
2257 if (v >= TOK_IDENT && v < tok_ident)
2258 table_ident[v - TOK_IDENT]->sym_define = NULL;
2259 tcc_free(top);
2260 top = top1;
2262 define_stack = b;
2265 /* label lookup */
2266 static Sym *label_find(int v)
2268 v -= TOK_IDENT;
2269 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2270 return NULL;
2271 return table_ident[v]->sym_label;
2274 static Sym *label_push(Sym **ptop, int v, int flags)
2276 Sym *s, **ps;
2277 s = sym_push2(ptop, v, 0, 0);
2278 s->r = flags;
2279 ps = &table_ident[v - TOK_IDENT]->sym_label;
2280 if (ptop == &global_label_stack) {
2281 /* modify the top most local identifier, so that
2282 sym_identifier will point to 's' when popped */
2283 while (*ps != NULL)
2284 ps = &(*ps)->prev_tok;
2286 s->prev_tok = *ps;
2287 *ps = s;
2288 return s;
2291 /* pop labels until element last is reached. Look if any labels are
2292 undefined. Define symbols if '&&label' was used. */
2293 static void label_pop(Sym **ptop, Sym *slast)
2295 Sym *s, *s1;
2296 for(s = *ptop; s != slast; s = s1) {
2297 s1 = s->prev;
2298 if (s->r == LABEL_DECLARED) {
2299 warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
2300 } else if (s->r == LABEL_FORWARD) {
2301 error("label '%s' used but not defined",
2302 get_tok_str(s->v, NULL));
2303 } else {
2304 if (s->c) {
2305 /* define corresponding symbol. A size of
2306 1 is put. */
2307 put_extern_sym(s, cur_text_section, (long)s->next, 1);
2310 /* remove label */
2311 table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
2312 tcc_free(s);
2314 *ptop = slast;
2317 /* eval an expression for #if/#elif */
2318 static int expr_preprocess(void)
2320 int c, t;
2321 TokenString str;
2323 tok_str_new(&str);
2324 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2325 next(); /* do macro subst */
2326 if (tok == TOK_DEFINED) {
2327 next_nomacro();
2328 t = tok;
2329 if (t == '(')
2330 next_nomacro();
2331 c = define_find(tok) != 0;
2332 if (t == '(')
2333 next_nomacro();
2334 tok = TOK_CINT;
2335 tokc.i = c;
2336 } else if (tok >= TOK_IDENT) {
2337 /* if undefined macro */
2338 tok = TOK_CINT;
2339 tokc.i = 0;
2341 tok_str_add_tok(&str);
2343 tok_str_add(&str, -1); /* simulate end of file */
2344 tok_str_add(&str, 0);
2345 /* now evaluate C constant expression */
2346 macro_ptr = str.str;
2347 next();
2348 c = expr_const();
2349 macro_ptr = NULL;
2350 tok_str_free(str.str);
2351 return c != 0;
2354 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2355 static void tok_print(int *str)
2357 int t;
2358 CValue cval;
2360 while (1) {
2361 TOK_GET(t, str, cval);
2362 if (!t)
2363 break;
2364 printf(" %s", get_tok_str(t, &cval));
2366 printf("\n");
2368 #endif
2370 /* parse after #define */
2371 static void parse_define(void)
2373 Sym *s, *first, **ps;
2374 int v, t, varg, is_vaargs, c;
2375 TokenString str;
2377 v = tok;
2378 if (v < TOK_IDENT)
2379 error("invalid macro name '%s'", get_tok_str(tok, &tokc));
2380 /* XXX: should check if same macro (ANSI) */
2381 first = NULL;
2382 t = MACRO_OBJ;
2383 /* '(' must be just after macro definition for MACRO_FUNC */
2384 c = file->buf_ptr[0];
2385 if (c == '\\')
2386 c = handle_stray1(file->buf_ptr);
2387 if (c == '(') {
2388 next_nomacro();
2389 next_nomacro();
2390 ps = &first;
2391 while (tok != ')') {
2392 varg = tok;
2393 next_nomacro();
2394 is_vaargs = 0;
2395 if (varg == TOK_DOTS) {
2396 varg = TOK___VA_ARGS__;
2397 is_vaargs = 1;
2398 } else if (tok == TOK_DOTS && gnu_ext) {
2399 is_vaargs = 1;
2400 next_nomacro();
2402 if (varg < TOK_IDENT)
2403 error("badly punctuated parameter list");
2404 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
2405 *ps = s;
2406 ps = &s->next;
2407 if (tok != ',')
2408 break;
2409 next_nomacro();
2411 t = MACRO_FUNC;
2413 tok_str_new(&str);
2414 next_nomacro();
2415 /* EOF testing necessary for '-D' handling */
2416 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2417 tok_str_add2(&str, tok, &tokc);
2418 next_nomacro();
2420 tok_str_add(&str, 0);
2421 #ifdef PP_DEBUG
2422 printf("define %s %d: ", get_tok_str(v, NULL), t);
2423 tok_print(str.str);
2424 #endif
2425 define_push(v, t, str.str, first);
2428 /* XXX: use a token or a hash table to accelerate matching ? */
2429 static CachedInclude *search_cached_include(TCCState *s1,
2430 int type, const char *filename)
2432 CachedInclude *e;
2433 int i;
2435 for(i = 0;i < s1->nb_cached_includes; i++) {
2436 e = s1->cached_includes[i];
2437 if (e->type == type && !strcmp(e->filename, filename))
2438 return e;
2440 return NULL;
2443 static inline void add_cached_include(TCCState *s1, int type,
2444 const char *filename, int ifndef_macro)
2446 CachedInclude *e;
2448 if (search_cached_include(s1, type, filename))
2449 return;
2450 #ifdef INC_DEBUG
2451 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
2452 #endif
2453 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
2454 if (!e)
2455 return;
2456 e->type = type;
2457 strcpy(e->filename, filename);
2458 e->ifndef_macro = ifndef_macro;
2459 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
2462 /* is_bof is true if first non space token at beginning of file */
2463 static void preprocess(int is_bof)
2465 TCCState *s1 = tcc_state;
2466 int size, i, c, n, saved_parse_flags;
2467 char buf[1024], *q, *p;
2468 char buf1[1024];
2469 BufferedFile *f;
2470 Sym *s;
2471 CachedInclude *e;
2473 saved_parse_flags = parse_flags;
2474 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
2475 PARSE_FLAG_LINEFEED;
2476 next_nomacro();
2477 redo:
2478 switch(tok) {
2479 case TOK_DEFINE:
2480 next_nomacro();
2481 parse_define();
2482 break;
2483 case TOK_UNDEF:
2484 next_nomacro();
2485 s = define_find(tok);
2486 /* undefine symbol by putting an invalid name */
2487 if (s)
2488 define_undef(s);
2489 break;
2490 case TOK_INCLUDE:
2491 ch = file->buf_ptr[0];
2492 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2493 skip_spaces();
2494 if (ch == '<') {
2495 c = '>';
2496 goto read_name;
2497 } else if (ch == '\"') {
2498 c = ch;
2499 read_name:
2500 /* XXX: better stray handling */
2501 minp();
2502 q = buf;
2503 while (ch != c && ch != '\n' && ch != CH_EOF) {
2504 if ((q - buf) < sizeof(buf) - 1)
2505 *q++ = ch;
2506 minp();
2508 *q = '\0';
2509 minp();
2510 #if 0
2511 /* eat all spaces and comments after include */
2512 /* XXX: slightly incorrect */
2513 while (ch1 != '\n' && ch1 != CH_EOF)
2514 inp();
2515 #endif
2516 } else {
2517 /* computed #include : either we have only strings or
2518 we have anything enclosed in '<>' */
2519 next();
2520 buf[0] = '\0';
2521 if (tok == TOK_STR) {
2522 while (tok != TOK_LINEFEED) {
2523 if (tok != TOK_STR) {
2524 include_syntax:
2525 error("'#include' expects \"FILENAME\" or <FILENAME>");
2527 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2528 next();
2530 c = '\"';
2531 } else {
2532 int len;
2533 while (tok != TOK_LINEFEED) {
2534 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2535 next();
2537 len = strlen(buf);
2538 /* check syntax and remove '<>' */
2539 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2540 goto include_syntax;
2541 memmove(buf, buf + 1, len - 2);
2542 buf[len - 2] = '\0';
2543 c = '>';
2547 e = search_cached_include(s1, c, buf);
2548 if (e && define_find(e->ifndef_macro)) {
2549 /* no need to parse the include because the 'ifndef macro'
2550 is defined */
2551 #ifdef INC_DEBUG
2552 printf("%s: skipping %s\n", file->filename, buf);
2553 #endif
2554 } else {
2555 if (c == '\"') {
2556 /* first search in current dir if "header.h" */
2557 size = 0;
2558 p = strrchr(file->filename, '/');
2559 if (p)
2560 size = p + 1 - file->filename;
2561 if (size > sizeof(buf1) - 1)
2562 size = sizeof(buf1) - 1;
2563 memcpy(buf1, file->filename, size);
2564 buf1[size] = '\0';
2565 pstrcat(buf1, sizeof(buf1), buf);
2566 f = tcc_open(s1, buf1);
2567 if (f)
2568 goto found;
2570 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2571 error("#include recursion too deep");
2572 /* now search in all the include paths */
2573 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2574 for(i = 0; i < n; i++) {
2575 const char *path;
2576 if (i < s1->nb_include_paths)
2577 path = s1->include_paths[i];
2578 else
2579 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2580 pstrcpy(buf1, sizeof(buf1), path);
2581 pstrcat(buf1, sizeof(buf1), "/");
2582 pstrcat(buf1, sizeof(buf1), buf);
2583 f = tcc_open(s1, buf1);
2584 if (f)
2585 goto found;
2587 error("include file '%s' not found", buf);
2588 f = NULL;
2589 found:
2590 #ifdef INC_DEBUG
2591 printf("%s: including %s\n", file->filename, buf1);
2592 #endif
2593 f->inc_type = c;
2594 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2595 /* push current file in stack */
2596 /* XXX: fix current line init */
2597 *s1->include_stack_ptr++ = file;
2598 file = f;
2599 /* add include file debug info */
2600 if (do_debug) {
2601 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2603 tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
2604 ch = file->buf_ptr[0];
2605 goto the_end;
2607 break;
2608 case TOK_IFNDEF:
2609 c = 1;
2610 goto do_ifdef;
2611 case TOK_IF:
2612 c = expr_preprocess();
2613 goto do_if;
2614 case TOK_IFDEF:
2615 c = 0;
2616 do_ifdef:
2617 next_nomacro();
2618 if (tok < TOK_IDENT)
2619 error("invalid argument for '#if%sdef'", c ? "n" : "");
2620 if (is_bof) {
2621 if (c) {
2622 #ifdef INC_DEBUG
2623 printf("#ifndef %s\n", get_tok_str(tok, NULL));
2624 #endif
2625 file->ifndef_macro = tok;
2628 c = (define_find(tok) != 0) ^ c;
2629 do_if:
2630 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2631 error("memory full");
2632 *s1->ifdef_stack_ptr++ = c;
2633 goto test_skip;
2634 case TOK_ELSE:
2635 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2636 error("#else without matching #if");
2637 if (s1->ifdef_stack_ptr[-1] & 2)
2638 error("#else after #else");
2639 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2640 goto test_skip;
2641 case TOK_ELIF:
2642 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2643 error("#elif without matching #if");
2644 c = s1->ifdef_stack_ptr[-1];
2645 if (c > 1)
2646 error("#elif after #else");
2647 /* last #if/#elif expression was true: we skip */
2648 if (c == 1)
2649 goto skip;
2650 c = expr_preprocess();
2651 s1->ifdef_stack_ptr[-1] = c;
2652 test_skip:
2653 if (!(c & 1)) {
2654 skip:
2655 preprocess_skip();
2656 is_bof = 0;
2657 goto redo;
2659 break;
2660 case TOK_ENDIF:
2661 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2662 error("#endif without matching #if");
2663 s1->ifdef_stack_ptr--;
2664 /* '#ifndef macro' was at the start of file. Now we check if
2665 an '#endif' is exactly at the end of file */
2666 if (file->ifndef_macro &&
2667 s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
2668 file->ifndef_macro_saved = file->ifndef_macro;
2669 /* need to set to zero to avoid false matches if another
2670 #ifndef at middle of file */
2671 file->ifndef_macro = 0;
2672 while (tok != TOK_LINEFEED)
2673 next_nomacro();
2674 tok_flags |= TOK_FLAG_ENDIF;
2675 goto the_end;
2677 break;
2678 case TOK_LINE:
2679 next();
2680 if (tok != TOK_CINT)
2681 error("#line");
2682 file->line_num = tokc.i - 1; /* the line number will be incremented after */
2683 next();
2684 if (tok != TOK_LINEFEED) {
2685 if (tok != TOK_STR)
2686 error("#line");
2687 pstrcpy(file->filename, sizeof(file->filename),
2688 (char *)tokc.cstr->data);
2690 break;
2691 case TOK_ERROR:
2692 case TOK_WARNING:
2693 c = tok;
2694 ch = file->buf_ptr[0];
2695 skip_spaces();
2696 q = buf;
2697 while (ch != '\n' && ch != CH_EOF) {
2698 if ((q - buf) < sizeof(buf) - 1)
2699 *q++ = ch;
2700 minp();
2702 *q = '\0';
2703 if (c == TOK_ERROR)
2704 error("#error %s", buf);
2705 else
2706 warning("#warning %s", buf);
2707 break;
2708 case TOK_PRAGMA:
2709 /* ignored */
2710 break;
2711 default:
2712 if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
2713 /* '!' is ignored to allow C scripts. numbers are ignored
2714 to emulate cpp behaviour */
2715 } else {
2716 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
2718 break;
2720 /* ignore other preprocess commands or #! for C scripts */
2721 while (tok != TOK_LINEFEED)
2722 next_nomacro();
2723 the_end:
2724 parse_flags = saved_parse_flags;
2727 /* read a number in base b */
2728 static int getn(int b)
2730 int n, t;
2731 n = 0;
2732 while (1) {
2733 if (ch >= 'a' && ch <= 'f')
2734 t = ch - 'a' + 10;
2735 else if (ch >= 'A' && ch <= 'F')
2736 t = ch - 'A' + 10;
2737 else if (isnum(ch))
2738 t = ch - '0';
2739 else
2740 break;
2741 if (t < 0 || t >= b)
2742 break;
2743 n = n * b + t;
2744 inp();
2746 return n;
2749 /* read a character for string or char constant and eval escape codes */
2750 static int getq(void)
2752 int c;
2754 redo:
2755 c = ch;
2756 inp();
2757 if (c == '\\') {
2758 switch(ch) {
2759 case '0': case '1': case '2': case '3':
2760 case '4': case '5': case '6': case '7':
2761 /* at most three octal digits */
2762 c = ch - '0';
2763 inp();
2764 if (isoct(ch)) {
2765 c = c * 8 + ch - '0';
2766 inp();
2767 if (isoct(ch)) {
2768 c = c * 8 + ch - '0';
2769 inp();
2772 return c;
2773 case 'x':
2774 inp();
2775 return getn(16);
2776 case 'a':
2777 c = '\a';
2778 break;
2779 case 'b':
2780 c = '\b';
2781 break;
2782 case 'f':
2783 c = '\f';
2784 break;
2785 case 'n':
2786 c = '\n';
2787 break;
2788 case 'r':
2789 c = '\r';
2790 break;
2791 case 't':
2792 c = '\t';
2793 break;
2794 case 'v':
2795 c = '\v';
2796 break;
2797 case 'e':
2798 if (!gnu_ext)
2799 goto invalid_escape;
2800 c = 27;
2801 break;
2802 case '\'':
2803 case '\"':
2804 case '\\':
2805 case '?':
2806 c = ch;
2807 break;
2808 case '\n':
2809 inp();
2810 goto redo;
2811 case '\r':
2812 inp();
2813 if (ch != '\n')
2814 goto invalid_escape;
2815 inp();
2816 goto redo;
2817 default:
2818 invalid_escape:
2819 error("invalid escaped char");
2821 inp();
2822 } else if (c == '\r' && ch == '\n') {
2823 inp();
2824 c = '\n';
2826 return c;
2829 /* we use 64 bit numbers */
2830 #define BN_SIZE 2
2832 /* bn = (bn << shift) | or_val */
2833 void bn_lshift(unsigned int *bn, int shift, int or_val)
2835 int i;
2836 unsigned int v;
2837 for(i=0;i<BN_SIZE;i++) {
2838 v = bn[i];
2839 bn[i] = (v << shift) | or_val;
2840 or_val = v >> (32 - shift);
2844 void bn_zero(unsigned int *bn)
2846 int i;
2847 for(i=0;i<BN_SIZE;i++) {
2848 bn[i] = 0;
2852 /* parse number in null terminated string 'p' and return it in the
2853 current token */
2854 void parse_number(const char *p)
2856 int b, t, shift, frac_bits, s, exp_val, ch;
2857 char *q;
2858 unsigned int bn[BN_SIZE];
2859 double d;
2861 /* number */
2862 q = token_buf;
2863 ch = *p++;
2864 t = ch;
2865 ch = *p++;
2866 *q++ = t;
2867 b = 10;
2868 if (t == '.') {
2869 goto float_frac_parse;
2870 } else if (t == '0') {
2871 if (ch == 'x' || ch == 'X') {
2872 q--;
2873 ch = *p++;
2874 b = 16;
2875 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2876 q--;
2877 ch = *p++;
2878 b = 2;
2881 /* parse all digits. cannot check octal numbers at this stage
2882 because of floating point constants */
2883 while (1) {
2884 if (ch >= 'a' && ch <= 'f')
2885 t = ch - 'a' + 10;
2886 else if (ch >= 'A' && ch <= 'F')
2887 t = ch - 'A' + 10;
2888 else if (isnum(ch))
2889 t = ch - '0';
2890 else
2891 break;
2892 if (t >= b)
2893 break;
2894 if (q >= token_buf + STRING_MAX_SIZE) {
2895 num_too_long:
2896 error("number too long");
2898 *q++ = ch;
2899 ch = *p++;
2901 if (ch == '.' ||
2902 ((ch == 'e' || ch == 'E') && b == 10) ||
2903 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2904 if (b != 10) {
2905 /* NOTE: strtox should support that for hexa numbers, but
2906 non ISOC99 libcs do not support it, so we prefer to do
2907 it by hand */
2908 /* hexadecimal or binary floats */
2909 /* XXX: handle overflows */
2910 *q = '\0';
2911 if (b == 16)
2912 shift = 4;
2913 else
2914 shift = 2;
2915 bn_zero(bn);
2916 q = token_buf;
2917 while (1) {
2918 t = *q++;
2919 if (t == '\0') {
2920 break;
2921 } else if (t >= 'a') {
2922 t = t - 'a' + 10;
2923 } else if (t >= 'A') {
2924 t = t - 'A' + 10;
2925 } else {
2926 t = t - '0';
2928 bn_lshift(bn, shift, t);
2930 frac_bits = 0;
2931 if (ch == '.') {
2932 ch = *p++;
2933 while (1) {
2934 t = ch;
2935 if (t >= 'a' && t <= 'f') {
2936 t = t - 'a' + 10;
2937 } else if (t >= 'A' && t <= 'F') {
2938 t = t - 'A' + 10;
2939 } else if (t >= '0' && t <= '9') {
2940 t = t - '0';
2941 } else {
2942 break;
2944 if (t >= b)
2945 error("invalid digit");
2946 bn_lshift(bn, shift, t);
2947 frac_bits += shift;
2948 ch = *p++;
2951 if (ch != 'p' && ch != 'P')
2952 expect("exponent");
2953 ch = *p++;
2954 s = 1;
2955 exp_val = 0;
2956 if (ch == '+') {
2957 ch = *p++;
2958 } else if (ch == '-') {
2959 s = -1;
2960 ch = *p++;
2962 if (ch < '0' || ch > '9')
2963 expect("exponent digits");
2964 while (ch >= '0' && ch <= '9') {
2965 exp_val = exp_val * 10 + ch - '0';
2966 ch = *p++;
2968 exp_val = exp_val * s;
2970 /* now we can generate the number */
2971 /* XXX: should patch directly float number */
2972 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
2973 d = ldexp(d, exp_val - frac_bits);
2974 t = toup(ch);
2975 if (t == 'F') {
2976 ch = *p++;
2977 tok = TOK_CFLOAT;
2978 /* float : should handle overflow */
2979 tokc.f = (float)d;
2980 } else if (t == 'L') {
2981 ch = *p++;
2982 tok = TOK_CLDOUBLE;
2983 /* XXX: not large enough */
2984 tokc.ld = (long double)d;
2985 } else {
2986 tok = TOK_CDOUBLE;
2987 tokc.d = d;
2989 } else {
2990 /* decimal floats */
2991 if (ch == '.') {
2992 if (q >= token_buf + STRING_MAX_SIZE)
2993 goto num_too_long;
2994 *q++ = ch;
2995 ch = *p++;
2996 float_frac_parse:
2997 while (ch >= '0' && ch <= '9') {
2998 if (q >= token_buf + STRING_MAX_SIZE)
2999 goto num_too_long;
3000 *q++ = ch;
3001 ch = *p++;
3004 if (ch == 'e' || ch == 'E') {
3005 if (q >= token_buf + STRING_MAX_SIZE)
3006 goto num_too_long;
3007 *q++ = ch;
3008 ch = *p++;
3009 if (ch == '-' || ch == '+') {
3010 if (q >= token_buf + STRING_MAX_SIZE)
3011 goto num_too_long;
3012 *q++ = ch;
3013 ch = *p++;
3015 if (ch < '0' || ch > '9')
3016 expect("exponent digits");
3017 while (ch >= '0' && ch <= '9') {
3018 if (q >= token_buf + STRING_MAX_SIZE)
3019 goto num_too_long;
3020 *q++ = ch;
3021 ch = *p++;
3024 *q = '\0';
3025 t = toup(ch);
3026 errno = 0;
3027 if (t == 'F') {
3028 ch = *p++;
3029 tok = TOK_CFLOAT;
3030 tokc.f = strtof(token_buf, NULL);
3031 } else if (t == 'L') {
3032 ch = *p++;
3033 tok = TOK_CLDOUBLE;
3034 tokc.ld = strtold(token_buf, NULL);
3035 } else {
3036 tok = TOK_CDOUBLE;
3037 tokc.d = strtod(token_buf, NULL);
3040 } else {
3041 unsigned long long n, n1;
3042 int lcount, ucount;
3044 /* integer number */
3045 *q = '\0';
3046 q = token_buf;
3047 if (b == 10 && *q == '0') {
3048 b = 8;
3049 q++;
3051 n = 0;
3052 while(1) {
3053 t = *q++;
3054 /* no need for checks except for base 10 / 8 errors */
3055 if (t == '\0') {
3056 break;
3057 } else if (t >= 'a') {
3058 t = t - 'a' + 10;
3059 } else if (t >= 'A') {
3060 t = t - 'A' + 10;
3061 } else {
3062 t = t - '0';
3063 if (t >= b)
3064 error("invalid digit");
3066 n1 = n;
3067 n = n * b + t;
3068 /* detect overflow */
3069 /* XXX: this test is not reliable */
3070 if (n < n1)
3071 error("integer constant overflow");
3074 /* XXX: not exactly ANSI compliant */
3075 if ((n & 0xffffffff00000000LL) != 0) {
3076 if ((n >> 63) != 0)
3077 tok = TOK_CULLONG;
3078 else
3079 tok = TOK_CLLONG;
3080 } else if (n > 0x7fffffff) {
3081 tok = TOK_CUINT;
3082 } else {
3083 tok = TOK_CINT;
3085 lcount = 0;
3086 ucount = 0;
3087 for(;;) {
3088 t = toup(ch);
3089 if (t == 'L') {
3090 if (lcount >= 2)
3091 error("three 'l's in integer constant");
3092 lcount++;
3093 if (lcount == 2) {
3094 if (tok == TOK_CINT)
3095 tok = TOK_CLLONG;
3096 else if (tok == TOK_CUINT)
3097 tok = TOK_CULLONG;
3099 ch = *p++;
3100 } else if (t == 'U') {
3101 if (ucount >= 1)
3102 error("two 'u's in integer constant");
3103 ucount++;
3104 if (tok == TOK_CINT)
3105 tok = TOK_CUINT;
3106 else if (tok == TOK_CLLONG)
3107 tok = TOK_CULLONG;
3108 ch = *p++;
3109 } else {
3110 break;
3113 if (tok == TOK_CINT || tok == TOK_CUINT)
3114 tokc.ui = n;
3115 else
3116 tokc.ull = n;
3121 #define PARSE2(c1, tok1, c2, tok2) \
3122 case c1: \
3123 PEEKC(c, p); \
3124 if (c == c2) { \
3125 p++; \
3126 tok = tok2; \
3127 } else { \
3128 tok = tok1; \
3130 break;
3132 /* return next token without macro substitution */
3133 static inline void next_nomacro1(void)
3135 int b, t, c;
3136 TokenSym *ts;
3137 uint8_t *p, *p1;
3138 unsigned int h;
3140 p = file->buf_ptr;
3141 redo_no_start:
3142 c = *p;
3143 switch(c) {
3144 case ' ':
3145 case '\t':
3146 case '\f':
3147 case '\v':
3148 case '\r':
3149 p++;
3150 goto redo_no_start;
3152 case '\\':
3153 /* first look if it is in fact an end of buffer */
3154 if (p >= file->buf_end) {
3155 file->buf_ptr = p;
3156 handle_eob();
3157 p = file->buf_ptr;
3158 if (p >= file->buf_end)
3159 goto parse_eof;
3160 else
3161 goto redo_no_start;
3162 } else {
3163 file->buf_ptr = p;
3164 ch = *p;
3165 handle_stray();
3166 p = file->buf_ptr;
3167 goto redo_no_start;
3169 parse_eof:
3171 TCCState *s1 = tcc_state;
3172 if (parse_flags & PARSE_FLAG_LINEFEED) {
3173 tok = TOK_LINEFEED;
3174 } else if (s1->include_stack_ptr == s1->include_stack ||
3175 !(parse_flags & PARSE_FLAG_PREPROCESS)) {
3176 /* no include left : end of file. */
3177 tok = TOK_EOF;
3178 } else {
3179 /* pop include file */
3181 /* test if previous '#endif' was after a #ifdef at
3182 start of file */
3183 if (tok_flags & TOK_FLAG_ENDIF) {
3184 #ifdef INC_DEBUG
3185 printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
3186 #endif
3187 add_cached_include(s1, file->inc_type, file->inc_filename,
3188 file->ifndef_macro_saved);
3191 /* add end of include file debug info */
3192 if (do_debug) {
3193 put_stabd(N_EINCL, 0, 0);
3195 /* pop include stack */
3196 tcc_close(file);
3197 s1->include_stack_ptr--;
3198 file = *s1->include_stack_ptr;
3199 p = file->buf_ptr;
3200 goto redo_no_start;
3203 break;
3205 case '\n':
3206 if (parse_flags & PARSE_FLAG_LINEFEED) {
3207 tok = TOK_LINEFEED;
3208 } else {
3209 file->line_num++;
3210 tok_flags |= TOK_FLAG_BOL;
3211 p++;
3212 goto redo_no_start;
3214 break;
3216 case '#':
3217 /* XXX: simplify */
3218 PEEKC(c, p);
3219 if ((tok_flags & TOK_FLAG_BOL) &&
3220 (parse_flags & PARSE_FLAG_PREPROCESS)) {
3221 file->buf_ptr = p;
3222 preprocess(tok_flags & TOK_FLAG_BOF);
3223 p = file->buf_ptr;
3224 goto redo_no_start;
3225 } else {
3226 if (c == '#') {
3227 p++;
3228 tok = TOK_TWOSHARPS;
3229 } else {
3230 tok = '#';
3233 break;
3235 case 'a': case 'b': case 'c': case 'd':
3236 case 'e': case 'f': case 'g': case 'h':
3237 case 'i': case 'j': case 'k': case 'l':
3238 case 'm': case 'n': case 'o': case 'p':
3239 case 'q': case 'r': case 's': case 't':
3240 case 'u': case 'v': case 'w': case 'x':
3241 case 'y': case 'z':
3242 case 'A': case 'B': case 'C': case 'D':
3243 case 'E': case 'F': case 'G': case 'H':
3244 case 'I': case 'J': case 'K':
3245 case 'M': case 'N': case 'O': case 'P':
3246 case 'Q': case 'R': case 'S': case 'T':
3247 case 'U': case 'V': case 'W': case 'X':
3248 case 'Y': case 'Z':
3249 case '_':
3250 parse_ident_fast:
3251 p1 = p;
3252 h = TOK_HASH_INIT;
3253 h = TOK_HASH_FUNC(h, c);
3254 p++;
3255 for(;;) {
3256 c = *p;
3257 if (!isidnum_table[c])
3258 break;
3259 h = TOK_HASH_FUNC(h, c);
3260 p++;
3262 if (c != '\\') {
3263 TokenSym **pts;
3264 int len;
3266 /* fast case : no stray found, so we have the full token
3267 and we have already hashed it */
3268 len = p - p1;
3269 h &= (TOK_HASH_SIZE - 1);
3270 pts = &hash_ident[h];
3271 for(;;) {
3272 ts = *pts;
3273 if (!ts)
3274 break;
3275 if (ts->len == len && !memcmp(ts->str, p1, len))
3276 goto token_found;
3277 pts = &(ts->hash_next);
3279 ts = tok_alloc_new(pts, p1, len);
3280 token_found: ;
3281 } else {
3282 /* slower case */
3283 cstr_reset(&tokcstr);
3285 while (p1 < p) {
3286 cstr_ccat(&tokcstr, *p1);
3287 p1++;
3289 p--;
3290 PEEKC(c, p);
3291 parse_ident_slow:
3292 while (isidnum_table[c]) {
3293 cstr_ccat(&tokcstr, c);
3294 PEEKC(c, p);
3296 ts = tok_alloc(tokcstr.data, tokcstr.size);
3298 tok = ts->tok;
3299 break;
3300 case 'L':
3301 t = p[1];
3302 if (t != '\\' && t != '\'' && t != '\"') {
3303 /* fast case */
3304 goto parse_ident_fast;
3305 } else {
3306 PEEKC(c, p);
3307 if (c == '\'') {
3308 tok = TOK_LCHAR;
3309 goto char_const;
3310 } else if (c == '\"') {
3311 tok = TOK_LSTR;
3312 goto str_const;
3313 } else {
3314 cstr_reset(&tokcstr);
3315 cstr_ccat(&tokcstr, 'L');
3316 goto parse_ident_slow;
3319 break;
3320 case '0': case '1': case '2': case '3':
3321 case '4': case '5': case '6': case '7':
3322 case '8': case '9':
3324 cstr_reset(&tokcstr);
3325 /* after the first digit, accept digits, alpha, '.' or sign if
3326 prefixed by 'eEpP' */
3327 parse_num:
3328 for(;;) {
3329 t = c;
3330 cstr_ccat(&tokcstr, c);
3331 PEEKC(c, p);
3332 if (!(isnum(c) || isid(c) || c == '.' ||
3333 ((c == '+' || c == '-') &&
3334 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
3335 break;
3337 /* We add a trailing '\0' to ease parsing */
3338 cstr_ccat(&tokcstr, '\0');
3339 tokc.cstr = &tokcstr;
3340 tok = TOK_PPNUM;
3341 break;
3342 case '.':
3343 /* special dot handling because it can also start a number */
3344 PEEKC(c, p);
3345 if (isnum(c)) {
3346 cstr_reset(&tokcstr);
3347 cstr_ccat(&tokcstr, '.');
3348 goto parse_num;
3349 } else if (c == '.') {
3350 PEEKC(c, p);
3351 if (c != '.')
3352 expect("'.'");
3353 PEEKC(c, p);
3354 tok = TOK_DOTS;
3355 } else {
3356 tok = '.';
3358 break;
3359 case '\'':
3360 tok = TOK_CCHAR;
3361 char_const:
3362 file->buf_ptr = p;
3363 inp();
3364 b = getq();
3365 /* this cast is needed if >= 128 */
3366 if (tok == TOK_CCHAR)
3367 b = (char)b;
3368 tokc.i = b;
3369 if (ch != '\'')
3370 error("unterminated character constant");
3371 p = file->buf_ptr;
3372 p++;
3373 break;
3374 case '\"':
3375 tok = TOK_STR;
3376 str_const:
3377 file->buf_ptr = p;
3378 inp();
3379 cstr_reset(&tokcstr);
3380 while (ch != '\"') {
3381 b = getq();
3382 if (ch == CH_EOF)
3383 error("unterminated string");
3384 if (tok == TOK_STR)
3385 cstr_ccat(&tokcstr, b);
3386 else
3387 cstr_wccat(&tokcstr, b);
3389 if (tok == TOK_STR)
3390 cstr_ccat(&tokcstr, '\0');
3391 else
3392 cstr_wccat(&tokcstr, '\0');
3393 tokc.cstr = &tokcstr;
3394 p = file->buf_ptr;
3395 p++;
3396 break;
3398 case '<':
3399 PEEKC(c, p);
3400 if (c == '=') {
3401 p++;
3402 tok = TOK_LE;
3403 } else if (c == '<') {
3404 PEEKC(c, p);
3405 if (c == '=') {
3406 p++;
3407 tok = TOK_A_SHL;
3408 } else {
3409 tok = TOK_SHL;
3411 } else {
3412 tok = TOK_LT;
3414 break;
3416 case '>':
3417 PEEKC(c, p);
3418 if (c == '=') {
3419 p++;
3420 tok = TOK_GE;
3421 } else if (c == '>') {
3422 PEEKC(c, p);
3423 if (c == '=') {
3424 p++;
3425 tok = TOK_A_SAR;
3426 } else {
3427 tok = TOK_SAR;
3429 } else {
3430 tok = TOK_GT;
3432 break;
3434 case '&':
3435 PEEKC(c, p);
3436 if (c == '&') {
3437 p++;
3438 tok = TOK_LAND;
3439 } else if (c == '=') {
3440 p++;
3441 tok = TOK_A_AND;
3442 } else {
3443 tok = '&';
3445 break;
3447 case '|':
3448 PEEKC(c, p);
3449 if (c == '|') {
3450 p++;
3451 tok = TOK_LOR;
3452 } else if (c == '=') {
3453 p++;
3454 tok = TOK_A_OR;
3455 } else {
3456 tok = '|';
3458 break;
3460 case '+':
3461 PEEKC(c, p);
3462 if (c == '+') {
3463 p++;
3464 tok = TOK_INC;
3465 } else if (c == '=') {
3466 p++;
3467 tok = TOK_A_ADD;
3468 } else {
3469 tok = '+';
3471 break;
3473 case '-':
3474 PEEKC(c, p);
3475 if (c == '-') {
3476 p++;
3477 tok = TOK_DEC;
3478 } else if (c == '=') {
3479 p++;
3480 tok = TOK_A_SUB;
3481 } else if (c == '>') {
3482 p++;
3483 tok = TOK_ARROW;
3484 } else {
3485 tok = '-';
3487 break;
3489 PARSE2('!', '!', '=', TOK_NE)
3490 PARSE2('=', '=', '=', TOK_EQ)
3491 PARSE2('*', '*', '=', TOK_A_MUL)
3492 PARSE2('%', '%', '=', TOK_A_MOD)
3493 PARSE2('^', '^', '=', TOK_A_XOR)
3495 /* comments or operator */
3496 case '/':
3497 PEEKC(c, p);
3498 if (c == '*') {
3499 file->buf_ptr = p;
3500 parse_comment();
3501 p = file->buf_ptr;
3502 goto redo_no_start;
3503 } else if (c == '/') {
3504 file->buf_ptr = p;
3505 parse_line_comment();
3506 p = file->buf_ptr;
3507 goto redo_no_start;
3508 } else if (c == '=') {
3509 p++;
3510 tok = TOK_A_DIV;
3511 } else {
3512 tok = '/';
3514 break;
3516 /* simple tokens */
3517 case '(':
3518 case ')':
3519 case '[':
3520 case ']':
3521 case '{':
3522 case '}':
3523 case ',':
3524 case ';':
3525 case ':':
3526 case '?':
3527 case '~':
3528 case '$': /* only used in assembler */
3529 tok = c;
3530 p++;
3531 break;
3532 default:
3533 error("unrecognized character \\x%02x", c);
3534 break;
3536 file->buf_ptr = p;
3537 tok_flags = 0;
3538 #if defined(PARSE_DEBUG)
3539 printf("token = %s\n", get_tok_str(tok, &tokc));
3540 #endif
3543 /* return next token without macro substitution. Can read input from
3544 macro_ptr buffer */
3545 static void next_nomacro(void)
3547 if (macro_ptr) {
3548 redo:
3549 tok = *macro_ptr;
3550 if (tok) {
3551 TOK_GET(tok, macro_ptr, tokc);
3552 if (tok == TOK_LINENUM) {
3553 file->line_num = tokc.i;
3554 goto redo;
3557 } else {
3558 next_nomacro1();
3562 /* substitute args in macro_str and return allocated string */
3563 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
3565 int *st, last_tok, t, notfirst;
3566 Sym *s;
3567 CValue cval;
3568 TokenString str;
3569 CString cstr;
3571 tok_str_new(&str);
3572 last_tok = 0;
3573 while(1) {
3574 TOK_GET(t, macro_str, cval);
3575 if (!t)
3576 break;
3577 if (t == '#') {
3578 /* stringize */
3579 TOK_GET(t, macro_str, cval);
3580 if (!t)
3581 break;
3582 s = sym_find2(args, t);
3583 if (s) {
3584 cstr_new(&cstr);
3585 st = (int *)s->c;
3586 notfirst = 0;
3587 while (*st) {
3588 if (notfirst)
3589 cstr_ccat(&cstr, ' ');
3590 TOK_GET(t, st, cval);
3591 cstr_cat(&cstr, get_tok_str(t, &cval));
3592 notfirst = 1;
3594 cstr_ccat(&cstr, '\0');
3595 #ifdef PP_DEBUG
3596 printf("stringize: %s\n", (char *)cstr.data);
3597 #endif
3598 /* add string */
3599 cval.cstr = &cstr;
3600 tok_str_add2(&str, TOK_STR, &cval);
3601 cstr_free(&cstr);
3602 } else {
3603 tok_str_add2(&str, t, &cval);
3605 } else if (t >= TOK_IDENT) {
3606 s = sym_find2(args, t);
3607 if (s) {
3608 st = (int *)s->c;
3609 /* if '##' is present before or after, no arg substitution */
3610 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
3611 /* special case for var arg macros : ## eats the
3612 ',' if empty VA_ARGS variable. */
3613 /* XXX: test of the ',' is not 100%
3614 reliable. should fix it to avoid security
3615 problems */
3616 if (gnu_ext && s->type.t &&
3617 last_tok == TOK_TWOSHARPS &&
3618 str.len >= 2 && str.str[str.len - 2] == ',') {
3619 if (*st == 0) {
3620 /* suppress ',' '##' */
3621 str.len -= 2;
3622 } else {
3623 /* suppress '##' and add variable */
3624 str.len--;
3625 goto add_var;
3627 } else {
3628 int t1;
3629 add_var:
3630 for(;;) {
3631 TOK_GET(t1, st, cval);
3632 if (!t1)
3633 break;
3634 tok_str_add2(&str, t1, &cval);
3637 } else {
3638 macro_subst(&str, nested_list, st);
3640 } else {
3641 tok_str_add(&str, t);
3643 } else {
3644 tok_str_add2(&str, t, &cval);
3646 last_tok = t;
3648 tok_str_add(&str, 0);
3649 return str.str;
3652 /* do macro substitution of current token with macro 's' and add
3653 result to (tok_str,tok_len). 'nested_list' is the list of all
3654 macros we got inside to avoid recursing. Return non zero if no
3655 substitution needs to be done */
3656 static int macro_subst_tok(TokenString *tok_str,
3657 Sym **nested_list, Sym *s)
3659 Sym *args, *sa, *sa1;
3660 int mstr_allocated, parlevel, *mstr, t;
3661 TokenString str;
3662 char *cstrval;
3663 CValue cval;
3664 CString cstr;
3666 /* if symbol is a macro, prepare substitution */
3668 /* special macros */
3669 if (tok == TOK___LINE__) {
3670 cval.i = file->line_num;
3671 tok_str_add2(tok_str, TOK_CINT, &cval);
3672 } else if (tok == TOK___FILE__) {
3673 cstrval = file->filename;
3674 goto add_cstr;
3675 tok_str_add2(tok_str, TOK_STR, &cval);
3676 } else if (tok == TOK___DATE__) {
3677 cstrval = "Jan 1 2002";
3678 goto add_cstr;
3679 } else if (tok == TOK___TIME__) {
3680 cstrval = "00:00:00";
3681 add_cstr:
3682 cstr_new(&cstr);
3683 cstr_cat(&cstr, cstrval);
3684 cstr_ccat(&cstr, '\0');
3685 cval.cstr = &cstr;
3686 tok_str_add2(tok_str, TOK_STR, &cval);
3687 cstr_free(&cstr);
3688 } else {
3689 mstr = (int *)s->c;
3690 mstr_allocated = 0;
3691 if (s->type.t == MACRO_FUNC) {
3692 /* NOTE: we do not use next_nomacro to avoid eating the
3693 next token. XXX: find better solution */
3694 if (macro_ptr) {
3695 t = *macro_ptr;
3696 } else {
3697 /* XXX: incorrect with comments */
3698 ch = file->buf_ptr[0];
3699 while (is_space(ch) || ch == '\n')
3700 cinp();
3701 t = ch;
3703 if (t != '(') /* no macro subst */
3704 return -1;
3706 /* argument macro */
3707 next_nomacro();
3708 next_nomacro();
3709 args = NULL;
3710 sa = s->next;
3711 /* NOTE: empty args are allowed, except if no args */
3712 for(;;) {
3713 /* handle '()' case */
3714 if (!args && tok == ')')
3715 break;
3716 if (!sa)
3717 error("macro '%s' used with too many args",
3718 get_tok_str(s->v, 0));
3719 tok_str_new(&str);
3720 parlevel = 0;
3721 /* NOTE: non zero sa->t indicates VA_ARGS */
3722 while ((parlevel > 0 ||
3723 (tok != ')' &&
3724 (tok != ',' || sa->type.t))) &&
3725 tok != -1) {
3726 if (tok == '(')
3727 parlevel++;
3728 else if (tok == ')')
3729 parlevel--;
3730 tok_str_add2(&str, tok, &tokc);
3731 next_nomacro();
3733 tok_str_add(&str, 0);
3734 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str);
3735 sa = sa->next;
3736 if (tok == ')') {
3737 /* special case for gcc var args: add an empty
3738 var arg argument if it is omitted */
3739 if (sa && sa->type.t && gnu_ext)
3740 continue;
3741 else
3742 break;
3744 if (tok != ',')
3745 expect(",");
3746 next_nomacro();
3748 if (sa) {
3749 error("macro '%s' used with too few args",
3750 get_tok_str(s->v, 0));
3753 /* now subst each arg */
3754 mstr = macro_arg_subst(nested_list, mstr, args);
3755 /* free memory */
3756 sa = args;
3757 while (sa) {
3758 sa1 = sa->prev;
3759 tok_str_free((int *)sa->c);
3760 tcc_free(sa);
3761 sa = sa1;
3763 mstr_allocated = 1;
3765 sym_push2(nested_list, s->v, 0, 0);
3766 macro_subst(tok_str, nested_list, mstr);
3767 /* pop nested defined symbol */
3768 sa1 = *nested_list;
3769 *nested_list = sa1->prev;
3770 tcc_free(sa1);
3771 if (mstr_allocated)
3772 tok_str_free(mstr);
3774 return 0;
3777 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
3778 return the resulting string (which must be freed). */
3779 static inline int *macro_twosharps(const int *macro_str)
3781 TokenSym *ts;
3782 const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr;
3783 int t;
3784 const char *p1, *p2;
3785 CValue cval;
3786 TokenString macro_str1;
3787 CString cstr;
3789 start_macro_ptr = macro_str;
3790 /* we search the first '##' */
3791 for(;;) {
3792 macro_ptr1 = macro_str;
3793 TOK_GET(t, macro_str, cval);
3794 /* nothing more to do if end of string */
3795 if (t == 0)
3796 return NULL;
3797 if (*macro_str == TOK_TWOSHARPS)
3798 break;
3801 /* we saw '##', so we need more processing to handle it */
3802 cstr_new(&cstr);
3803 tok_str_new(&macro_str1);
3804 tok = t;
3805 tokc = cval;
3807 /* add all tokens seen so far */
3808 for(ptr = start_macro_ptr; ptr < macro_ptr1;) {
3809 TOK_GET(t, ptr, cval);
3810 tok_str_add2(&macro_str1, t, &cval);
3812 saved_macro_ptr = macro_ptr;
3813 /* XXX: suppress the use of macro_ptr here */
3814 macro_ptr = (int *)macro_str;
3815 for(;;) {
3816 while (*macro_ptr == TOK_TWOSHARPS) {
3817 macro_ptr++;
3818 macro_ptr1 = macro_ptr;
3819 t = *macro_ptr;
3820 if (t) {
3821 TOK_GET(t, macro_ptr, cval);
3822 /* We concatenate the two tokens if we have an
3823 identifier or a preprocessing number */
3824 cstr_reset(&cstr);
3825 p1 = get_tok_str(tok, &tokc);
3826 cstr_cat(&cstr, p1);
3827 p2 = get_tok_str(t, &cval);
3828 cstr_cat(&cstr, p2);
3829 cstr_ccat(&cstr, '\0');
3831 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
3832 (t >= TOK_IDENT || t == TOK_PPNUM)) {
3833 if (tok == TOK_PPNUM) {
3834 /* if number, then create a number token */
3835 /* NOTE: no need to allocate because
3836 tok_str_add2() does it */
3837 tokc.cstr = &cstr;
3838 } else {
3839 /* if identifier, we must do a test to
3840 validate we have a correct identifier */
3841 if (t == TOK_PPNUM) {
3842 const char *p;
3843 int c;
3845 p = p2;
3846 for(;;) {
3847 c = *p;
3848 if (c == '\0')
3849 break;
3850 p++;
3851 if (!isnum(c) && !isid(c))
3852 goto error_pasting;
3855 ts = tok_alloc(cstr.data, strlen(cstr.data));
3856 tok = ts->tok; /* modify current token */
3858 } else {
3859 const char *str = cstr.data;
3860 const unsigned char *q;
3862 /* we look for a valid token */
3863 /* XXX: do more extensive checks */
3864 if (!strcmp(str, ">>=")) {
3865 tok = TOK_A_SAR;
3866 } else if (!strcmp(str, "<<=")) {
3867 tok = TOK_A_SHL;
3868 } else if (strlen(str) == 2) {
3869 /* search in two bytes table */
3870 q = tok_two_chars;
3871 for(;;) {
3872 if (!*q)
3873 goto error_pasting;
3874 if (q[0] == str[0] && q[1] == str[1])
3875 break;
3876 q += 3;
3878 tok = q[2];
3879 } else {
3880 error_pasting:
3881 /* NOTE: because get_tok_str use a static buffer,
3882 we must save it */
3883 cstr_reset(&cstr);
3884 p1 = get_tok_str(tok, &tokc);
3885 cstr_cat(&cstr, p1);
3886 cstr_ccat(&cstr, '\0');
3887 p2 = get_tok_str(t, &cval);
3888 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
3889 /* cannot merge tokens: just add them separately */
3890 tok_str_add2(&macro_str1, tok, &tokc);
3891 /* XXX: free associated memory ? */
3892 tok = t;
3893 tokc = cval;
3898 tok_str_add2(&macro_str1, tok, &tokc);
3899 next_nomacro();
3900 if (tok == 0)
3901 break;
3903 macro_ptr = (int *)saved_macro_ptr;
3904 cstr_free(&cstr);
3905 tok_str_add(&macro_str1, 0);
3906 return macro_str1.str;
3910 /* do macro substitution of macro_str and add result to
3911 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3912 inside to avoid recursing. */
3913 static void macro_subst(TokenString *tok_str,
3914 Sym **nested_list, const int *macro_str)
3916 Sym *s;
3917 int *saved_macro_ptr, *macro_str1;
3918 const int *ptr;
3919 int t, ret;
3920 CValue cval;
3922 /* first scan for '##' operator handling */
3923 ptr = macro_str;
3924 macro_str1 = macro_twosharps(ptr);
3925 if (macro_str1)
3926 ptr = macro_str1;
3927 while (1) {
3928 TOK_GET(t, ptr, cval);
3929 if (t == 0)
3930 break;
3931 s = define_find(t);
3932 if (s != NULL) {
3933 /* if nested substitution, do nothing */
3934 if (sym_find2(*nested_list, t))
3935 goto no_subst;
3936 saved_macro_ptr = macro_ptr;
3937 macro_ptr = (int *)ptr;
3938 tok = t;
3939 ret = macro_subst_tok(tok_str, nested_list, s);
3940 ptr = (int *)macro_ptr;
3941 macro_ptr = saved_macro_ptr;
3942 if (ret != 0)
3943 goto no_subst;
3944 } else {
3945 no_subst:
3946 tok_str_add2(tok_str, t, &cval);
3949 if (macro_str1)
3950 tok_str_free(macro_str1);
3953 /* return next token with macro substitution */
3954 static void next(void)
3956 Sym *nested_list, *s;
3957 TokenString str;
3959 redo:
3960 next_nomacro();
3961 if (!macro_ptr) {
3962 /* if not reading from macro substituted string, then try
3963 to substitute macros */
3964 if (tok >= TOK_IDENT &&
3965 (parse_flags & PARSE_FLAG_PREPROCESS)) {
3966 s = define_find(tok);
3967 if (s) {
3968 /* we have a macro: we try to substitute */
3969 tok_str_new(&str);
3970 nested_list = NULL;
3971 if (macro_subst_tok(&str, &nested_list, s) == 0) {
3972 /* substitution done, NOTE: maybe empty */
3973 tok_str_add(&str, 0);
3974 macro_ptr = str.str;
3975 macro_ptr_allocated = str.str;
3976 goto redo;
3980 } else {
3981 if (tok == 0) {
3982 /* end of macro or end of unget buffer */
3983 if (unget_buffer_enabled) {
3984 macro_ptr = unget_saved_macro_ptr;
3985 unget_buffer_enabled = 0;
3986 } else {
3987 /* end of macro string: free it */
3988 tok_str_free(macro_ptr_allocated);
3989 macro_ptr = NULL;
3991 goto redo;
3995 /* convert preprocessor tokens into C tokens */
3996 if (tok == TOK_PPNUM &&
3997 (parse_flags & PARSE_FLAG_TOK_NUM)) {
3998 parse_number((char *)tokc.cstr->data);
4002 /* push back current token and set current token to 'last_tok'. Only
4003 identifier case handled for labels. */
4004 static inline void unget_tok(int last_tok)
4006 int i, n;
4007 int *q;
4008 unget_saved_macro_ptr = macro_ptr;
4009 unget_buffer_enabled = 1;
4010 q = unget_saved_buffer;
4011 macro_ptr = q;
4012 *q++ = tok;
4013 n = tok_ext_size(tok) - 1;
4014 for(i=0;i<n;i++)
4015 *q++ = tokc.tab[i];
4016 *q = 0; /* end of token string */
4017 tok = last_tok;
4021 void swap(int *p, int *q)
4023 int t;
4024 t = *p;
4025 *p = *q;
4026 *q = t;
4029 void vsetc(CType *type, int r, CValue *vc)
4031 int v;
4033 if (vtop >= vstack + VSTACK_SIZE)
4034 error("memory full");
4035 /* cannot let cpu flags if other instruction are generated. Also
4036 avoid leaving VT_JMP anywhere except on the top of the stack
4037 because it would complicate the code generator. */
4038 if (vtop >= vstack) {
4039 v = vtop->r & VT_VALMASK;
4040 if (v == VT_CMP || (v & ~1) == VT_JMP)
4041 gv(RC_INT);
4043 vtop++;
4044 vtop->type = *type;
4045 vtop->r = r;
4046 vtop->r2 = VT_CONST;
4047 vtop->c = *vc;
4050 /* push integer constant */
4051 void vpushi(int v)
4053 CValue cval;
4054 cval.i = v;
4055 vsetc(&int_type, VT_CONST, &cval);
4058 /* Return a static symbol pointing to a section */
4059 static Sym *get_sym_ref(CType *type, Section *sec,
4060 unsigned long offset, unsigned long size)
4062 int v;
4063 Sym *sym;
4065 v = anon_sym++;
4066 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
4067 sym->type.ref = type->ref;
4068 sym->r = VT_CONST | VT_SYM;
4069 put_extern_sym(sym, sec, offset, size);
4070 return sym;
4073 /* push a reference to a section offset by adding a dummy symbol */
4074 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
4076 CValue cval;
4078 cval.ul = 0;
4079 vsetc(type, VT_CONST | VT_SYM, &cval);
4080 vtop->sym = get_sym_ref(type, sec, offset, size);
4083 /* define a new external reference to a symbol 'v' of type 'u' */
4084 static Sym *external_global_sym(int v, CType *type, int r)
4086 Sym *s;
4088 s = sym_find(v);
4089 if (!s) {
4090 /* push forward reference */
4091 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
4092 s->type.ref = type->ref;
4093 s->r = r | VT_CONST | VT_SYM;
4095 return s;
4098 /* define a new external reference to a symbol 'v' of type 'u' */
4099 static Sym *external_sym(int v, CType *type, int r)
4101 Sym *s;
4103 s = sym_find(v);
4104 if (!s) {
4105 /* push forward reference */
4106 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
4107 s->type.t |= VT_EXTERN;
4108 } else {
4109 if (!is_compatible_types(&s->type, type))
4110 error("incompatible types for redefinition of '%s'",
4111 get_tok_str(v, NULL));
4113 return s;
4116 /* push a reference to global symbol v */
4117 static void vpush_global_sym(CType *type, int v)
4119 Sym *sym;
4120 CValue cval;
4122 sym = external_global_sym(v, type, 0);
4123 cval.ul = 0;
4124 vsetc(type, VT_CONST | VT_SYM, &cval);
4125 vtop->sym = sym;
4128 void vset(CType *type, int r, int v)
4130 CValue cval;
4132 cval.i = v;
4133 vsetc(type, r, &cval);
4136 void vseti(int r, int v)
4138 CType type;
4139 type.t = VT_INT;
4140 vset(&type, r, v);
4143 void vswap(void)
4145 SValue tmp;
4147 tmp = vtop[0];
4148 vtop[0] = vtop[-1];
4149 vtop[-1] = tmp;
4152 void vpushv(SValue *v)
4154 if (vtop >= vstack + VSTACK_SIZE)
4155 error("memory full");
4156 vtop++;
4157 *vtop = *v;
4160 void vdup(void)
4162 vpushv(vtop);
4165 /* save r to the memory stack, and mark it as being free */
4166 void save_reg(int r)
4168 int l, saved, size, align;
4169 SValue *p, sv;
4170 CType *type;
4172 /* modify all stack values */
4173 saved = 0;
4174 l = 0;
4175 for(p=vstack;p<=vtop;p++) {
4176 if ((p->r & VT_VALMASK) == r ||
4177 (p->r2 & VT_VALMASK) == r) {
4178 /* must save value on stack if not already done */
4179 if (!saved) {
4180 /* NOTE: must reload 'r' because r might be equal to r2 */
4181 r = p->r & VT_VALMASK;
4182 /* store register in the stack */
4183 type = &p->type;
4184 if ((p->r & VT_LVAL) ||
4185 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
4186 type = &int_type;
4187 size = type_size(type, &align);
4188 loc = (loc - size) & -align;
4189 sv.type.t = type->t;
4190 sv.r = VT_LOCAL | VT_LVAL;
4191 sv.c.ul = loc;
4192 store(r, &sv);
4193 #ifdef TCC_TARGET_I386
4194 /* x86 specific: need to pop fp register ST0 if saved */
4195 if (r == TREG_ST0) {
4196 o(0xd9dd); /* fstp %st(1) */
4198 #endif
4199 /* special long long case */
4200 if ((type->t & VT_BTYPE) == VT_LLONG) {
4201 sv.c.ul += 4;
4202 store(p->r2, &sv);
4204 l = loc;
4205 saved = 1;
4207 /* mark that stack entry as being saved on the stack */
4208 if (p->r & VT_LVAL) {
4209 /* also suppress the bounded flag because the
4210 relocation address of the function was stored in
4211 p->c.ul */
4212 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
4213 } else {
4214 p->r = lvalue_type(p->type.t) | VT_LOCAL;
4216 p->r2 = VT_CONST;
4217 p->c.ul = l;
4222 /* find a free register of class 'rc'. If none, save one register */
4223 int get_reg(int rc)
4225 int r;
4226 SValue *p;
4228 /* find a free register */
4229 for(r=0;r<NB_REGS;r++) {
4230 if (reg_classes[r] & rc) {
4231 for(p=vstack;p<=vtop;p++) {
4232 if ((p->r & VT_VALMASK) == r ||
4233 (p->r2 & VT_VALMASK) == r)
4234 goto notfound;
4236 return r;
4238 notfound: ;
4241 /* no register left : free the first one on the stack (VERY
4242 IMPORTANT to start from the bottom to ensure that we don't
4243 spill registers used in gen_opi()) */
4244 for(p=vstack;p<=vtop;p++) {
4245 r = p->r & VT_VALMASK;
4246 if (r < VT_CONST && (reg_classes[r] & rc))
4247 goto save_found;
4248 /* also look at second register (if long long) */
4249 r = p->r2 & VT_VALMASK;
4250 if (r < VT_CONST && (reg_classes[r] & rc)) {
4251 save_found:
4252 save_reg(r);
4253 return r;
4256 /* Should never comes here */
4257 return -1;
4260 /* save registers up to (vtop - n) stack entry */
4261 void save_regs(int n)
4263 int r;
4264 SValue *p, *p1;
4265 p1 = vtop - n;
4266 for(p = vstack;p <= p1; p++) {
4267 r = p->r & VT_VALMASK;
4268 if (r < VT_CONST) {
4269 save_reg(r);
4274 /* move register 's' to 'r', and flush previous value of r to memory
4275 if needed */
4276 void move_reg(int r, int s)
4278 SValue sv;
4280 if (r != s) {
4281 save_reg(r);
4282 sv.type.t = VT_INT;
4283 sv.r = s;
4284 sv.c.ul = 0;
4285 load(r, &sv);
4289 /* get address of vtop (vtop MUST BE an lvalue) */
4290 void gaddrof(void)
4292 vtop->r &= ~VT_LVAL;
4293 /* tricky: if saved lvalue, then we can go back to lvalue */
4294 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
4295 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
4298 #ifdef CONFIG_TCC_BCHECK
4299 /* generate lvalue bound code */
4300 void gbound(void)
4302 int lval_type;
4303 CType type1;
4305 vtop->r &= ~VT_MUSTBOUND;
4306 /* if lvalue, then use checking code before dereferencing */
4307 if (vtop->r & VT_LVAL) {
4308 /* if not VT_BOUNDED value, then make one */
4309 if (!(vtop->r & VT_BOUNDED)) {
4310 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
4311 /* must save type because we must set it to int to get pointer */
4312 type1 = vtop->type;
4313 vtop->type.t = VT_INT;
4314 gaddrof();
4315 vpushi(0);
4316 gen_bounded_ptr_add();
4317 vtop->r |= lval_type;
4318 vtop->type = type1;
4320 /* then check for dereferencing */
4321 gen_bounded_ptr_deref();
4324 #endif
4326 /* store vtop a register belonging to class 'rc'. lvalues are
4327 converted to values. Cannot be used if cannot be converted to
4328 register value (such as structures). */
4329 int gv(int rc)
4331 int r, r2, rc2, bit_pos, bit_size, size, align, i;
4332 unsigned long long ll;
4334 /* NOTE: get_reg can modify vstack[] */
4335 if (vtop->type.t & VT_BITFIELD) {
4336 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4337 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4338 /* remove bit field info to avoid loops */
4339 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4340 /* generate shifts */
4341 vpushi(32 - (bit_pos + bit_size));
4342 gen_op(TOK_SHL);
4343 vpushi(32 - bit_size);
4344 /* NOTE: transformed to SHR if unsigned */
4345 gen_op(TOK_SAR);
4346 r = gv(rc);
4347 } else {
4348 if (is_float(vtop->type.t) &&
4349 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4350 Sym *sym;
4351 int *ptr;
4352 unsigned long offset;
4354 /* XXX: unify with initializers handling ? */
4355 /* CPUs usually cannot use float constants, so we store them
4356 generically in data segment */
4357 size = type_size(&vtop->type, &align);
4358 offset = (data_section->data_offset + align - 1) & -align;
4359 data_section->data_offset = offset;
4360 /* XXX: not portable yet */
4361 ptr = section_ptr_add(data_section, size);
4362 size = size >> 2;
4363 for(i=0;i<size;i++)
4364 ptr[i] = vtop->c.tab[i];
4365 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
4366 vtop->r |= VT_LVAL | VT_SYM;
4367 vtop->sym = sym;
4368 vtop->c.ul = 0;
4370 #ifdef CONFIG_TCC_BCHECK
4371 if (vtop->r & VT_MUSTBOUND)
4372 gbound();
4373 #endif
4375 r = vtop->r & VT_VALMASK;
4376 /* need to reload if:
4377 - constant
4378 - lvalue (need to dereference pointer)
4379 - already a register, but not in the right class */
4380 if (r >= VT_CONST ||
4381 (vtop->r & VT_LVAL) ||
4382 !(reg_classes[r] & rc) ||
4383 ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
4384 !(reg_classes[vtop->r2] & rc))) {
4385 r = get_reg(rc);
4386 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
4387 /* two register type load : expand to two words
4388 temporarily */
4389 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4390 /* load constant */
4391 ll = vtop->c.ull;
4392 vtop->c.ui = ll; /* first word */
4393 load(r, vtop);
4394 vtop->r = r; /* save register value */
4395 vpushi(ll >> 32); /* second word */
4396 } else if (r >= VT_CONST ||
4397 (vtop->r & VT_LVAL)) {
4398 /* load from memory */
4399 load(r, vtop);
4400 vdup();
4401 vtop[-1].r = r; /* save register value */
4402 /* increment pointer to get second word */
4403 vtop->type.t = VT_INT;
4404 gaddrof();
4405 vpushi(4);
4406 gen_op('+');
4407 vtop->r |= VT_LVAL;
4408 } else {
4409 /* move registers */
4410 load(r, vtop);
4411 vdup();
4412 vtop[-1].r = r; /* save register value */
4413 vtop->r = vtop[-1].r2;
4415 /* allocate second register */
4416 rc2 = RC_INT;
4417 if (rc == RC_IRET)
4418 rc2 = RC_LRET;
4419 r2 = get_reg(rc2);
4420 load(r2, vtop);
4421 vpop();
4422 /* write second register */
4423 vtop->r2 = r2;
4424 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
4425 int t1, t;
4426 /* lvalue of scalar type : need to use lvalue type
4427 because of possible cast */
4428 t = vtop->type.t;
4429 t1 = t;
4430 /* compute memory access type */
4431 if (vtop->r & VT_LVAL_BYTE)
4432 t = VT_BYTE;
4433 else if (vtop->r & VT_LVAL_SHORT)
4434 t = VT_SHORT;
4435 if (vtop->r & VT_LVAL_UNSIGNED)
4436 t |= VT_UNSIGNED;
4437 vtop->type.t = t;
4438 load(r, vtop);
4439 /* restore wanted type */
4440 vtop->type.t = t1;
4441 } else {
4442 /* one register type load */
4443 load(r, vtop);
4446 vtop->r = r;
4448 return r;
4451 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4452 void gv2(int rc1, int rc2)
4454 int v;
4456 /* generate more generic register first. But VT_JMP or VT_CMP
4457 values must be generated first in all cases to avoid possible
4458 reload errors */
4459 v = vtop[0].r & VT_VALMASK;
4460 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
4461 vswap();
4462 gv(rc1);
4463 vswap();
4464 gv(rc2);
4465 /* test if reload is needed for first register */
4466 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
4467 vswap();
4468 gv(rc1);
4469 vswap();
4471 } else {
4472 gv(rc2);
4473 vswap();
4474 gv(rc1);
4475 vswap();
4476 /* test if reload is needed for first register */
4477 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
4478 gv(rc2);
4483 /* expand long long on stack in two int registers */
4484 void lexpand(void)
4486 int u;
4488 u = vtop->type.t & VT_UNSIGNED;
4489 gv(RC_INT);
4490 vdup();
4491 vtop[0].r = vtop[-1].r2;
4492 vtop[0].r2 = VT_CONST;
4493 vtop[-1].r2 = VT_CONST;
4494 vtop[0].type.t = VT_INT | u;
4495 vtop[-1].type.t = VT_INT | u;
4498 /* build a long long from two ints */
4499 void lbuild(int t)
4501 gv2(RC_INT, RC_INT);
4502 vtop[-1].r2 = vtop[0].r;
4503 vtop[-1].type.t = t;
4504 vpop();
4507 /* rotate n first stack elements to the bottom */
4508 void vrotb(int n)
4510 int i;
4511 SValue tmp;
4513 tmp = vtop[-n + 1];
4514 for(i=-n+1;i!=0;i++)
4515 vtop[i] = vtop[i+1];
4516 vtop[0] = tmp;
4519 /* pop stack value */
4520 void vpop(void)
4522 int v;
4523 v = vtop->r & VT_VALMASK;
4524 #ifdef TCC_TARGET_I386
4525 /* for x86, we need to pop the FP stack */
4526 if (v == TREG_ST0 && !nocode_wanted) {
4527 o(0xd9dd); /* fstp %st(1) */
4528 } else
4529 #endif
4530 if (v == VT_JMP || v == VT_JMPI) {
4531 /* need to put correct jump if && or || without test */
4532 gsym(vtop->c.ul);
4534 vtop--;
4537 /* convert stack entry to register and duplicate its value in another
4538 register */
4539 void gv_dup(void)
4541 int rc, t, r, r1;
4542 SValue sv;
4544 t = vtop->type.t;
4545 if ((t & VT_BTYPE) == VT_LLONG) {
4546 lexpand();
4547 gv_dup();
4548 vswap();
4549 vrotb(3);
4550 gv_dup();
4551 vrotb(4);
4552 /* stack: H L L1 H1 */
4553 lbuild(t);
4554 vrotb(3);
4555 vrotb(3);
4556 vswap();
4557 lbuild(t);
4558 vswap();
4559 } else {
4560 /* duplicate value */
4561 rc = RC_INT;
4562 sv.type.t = VT_INT;
4563 if (is_float(t)) {
4564 rc = RC_FLOAT;
4565 sv.type.t = t;
4567 r = gv(rc);
4568 r1 = get_reg(rc);
4569 sv.r = r;
4570 sv.c.ul = 0;
4571 load(r1, &sv); /* move r to r1 */
4572 vdup();
4573 /* duplicates value */
4574 vtop->r = r1;
4578 /* generate CPU independent (unsigned) long long operations */
4579 void gen_opl(int op)
4581 int t, a, b, op1, c, i;
4582 int func;
4583 GFuncContext gf;
4584 SValue tmp;
4586 switch(op) {
4587 case '/':
4588 case TOK_PDIV:
4589 func = TOK___divdi3;
4590 goto gen_func;
4591 case TOK_UDIV:
4592 func = TOK___udivdi3;
4593 goto gen_func;
4594 case '%':
4595 func = TOK___moddi3;
4596 goto gen_func;
4597 case TOK_UMOD:
4598 func = TOK___umoddi3;
4599 gen_func:
4600 /* call generic long long function */
4601 gfunc_start(&gf, FUNC_CDECL);
4602 gfunc_param(&gf);
4603 gfunc_param(&gf);
4604 vpush_global_sym(&func_old_type, func);
4605 gfunc_call(&gf);
4606 vpushi(0);
4607 vtop->r = REG_IRET;
4608 vtop->r2 = REG_LRET;
4609 break;
4610 case '^':
4611 case '&':
4612 case '|':
4613 case '*':
4614 case '+':
4615 case '-':
4616 t = vtop->type.t;
4617 vswap();
4618 lexpand();
4619 vrotb(3);
4620 lexpand();
4621 /* stack: L1 H1 L2 H2 */
4622 tmp = vtop[0];
4623 vtop[0] = vtop[-3];
4624 vtop[-3] = tmp;
4625 tmp = vtop[-2];
4626 vtop[-2] = vtop[-3];
4627 vtop[-3] = tmp;
4628 vswap();
4629 /* stack: H1 H2 L1 L2 */
4630 if (op == '*') {
4631 vpushv(vtop - 1);
4632 vpushv(vtop - 1);
4633 gen_op(TOK_UMULL);
4634 lexpand();
4635 /* stack: H1 H2 L1 L2 ML MH */
4636 for(i=0;i<4;i++)
4637 vrotb(6);
4638 /* stack: ML MH H1 H2 L1 L2 */
4639 tmp = vtop[0];
4640 vtop[0] = vtop[-2];
4641 vtop[-2] = tmp;
4642 /* stack: ML MH H1 L2 H2 L1 */
4643 gen_op('*');
4644 vrotb(3);
4645 vrotb(3);
4646 gen_op('*');
4647 /* stack: ML MH M1 M2 */
4648 gen_op('+');
4649 gen_op('+');
4650 } else if (op == '+' || op == '-') {
4651 /* XXX: add non carry method too (for MIPS or alpha) */
4652 if (op == '+')
4653 op1 = TOK_ADDC1;
4654 else
4655 op1 = TOK_SUBC1;
4656 gen_op(op1);
4657 /* stack: H1 H2 (L1 op L2) */
4658 vrotb(3);
4659 vrotb(3);
4660 gen_op(op1 + 1); /* TOK_xxxC2 */
4661 } else {
4662 gen_op(op);
4663 /* stack: H1 H2 (L1 op L2) */
4664 vrotb(3);
4665 vrotb(3);
4666 /* stack: (L1 op L2) H1 H2 */
4667 gen_op(op);
4668 /* stack: (L1 op L2) (H1 op H2) */
4670 /* stack: L H */
4671 lbuild(t);
4672 break;
4673 case TOK_SAR:
4674 case TOK_SHR:
4675 case TOK_SHL:
4676 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4677 t = vtop[-1].type.t;
4678 vswap();
4679 lexpand();
4680 vrotb(3);
4681 /* stack: L H shift */
4682 c = (int)vtop->c.i;
4683 /* constant: simpler */
4684 /* NOTE: all comments are for SHL. the other cases are
4685 done by swaping words */
4686 vpop();
4687 if (op != TOK_SHL)
4688 vswap();
4689 if (c >= 32) {
4690 /* stack: L H */
4691 vpop();
4692 if (c > 32) {
4693 vpushi(c - 32);
4694 gen_op(op);
4696 if (op != TOK_SAR) {
4697 vpushi(0);
4698 } else {
4699 gv_dup();
4700 vpushi(31);
4701 gen_op(TOK_SAR);
4703 vswap();
4704 } else {
4705 vswap();
4706 gv_dup();
4707 /* stack: H L L */
4708 vpushi(c);
4709 gen_op(op);
4710 vswap();
4711 vpushi(32 - c);
4712 if (op == TOK_SHL)
4713 gen_op(TOK_SHR);
4714 else
4715 gen_op(TOK_SHL);
4716 vrotb(3);
4717 /* stack: L L H */
4718 vpushi(c);
4719 if (op == TOK_SHL)
4720 gen_op(TOK_SHL);
4721 else
4722 gen_op(TOK_SHR);
4723 gen_op('|');
4725 if (op != TOK_SHL)
4726 vswap();
4727 lbuild(t);
4728 } else {
4729 /* XXX: should provide a faster fallback on x86 ? */
4730 switch(op) {
4731 case TOK_SAR:
4732 func = TOK___sardi3;
4733 goto gen_func;
4734 case TOK_SHR:
4735 func = TOK___shrdi3;
4736 goto gen_func;
4737 case TOK_SHL:
4738 func = TOK___shldi3;
4739 goto gen_func;
4742 break;
4743 default:
4744 /* compare operations */
4745 t = vtop->type.t;
4746 vswap();
4747 lexpand();
4748 vrotb(3);
4749 lexpand();
4750 /* stack: L1 H1 L2 H2 */
4751 tmp = vtop[-1];
4752 vtop[-1] = vtop[-2];
4753 vtop[-2] = tmp;
4754 /* stack: L1 L2 H1 H2 */
4755 /* compare high */
4756 op1 = op;
4757 /* when values are equal, we need to compare low words. since
4758 the jump is inverted, we invert the test too. */
4759 if (op1 == TOK_LT)
4760 op1 = TOK_LE;
4761 else if (op1 == TOK_GT)
4762 op1 = TOK_GE;
4763 else if (op1 == TOK_ULT)
4764 op1 = TOK_ULE;
4765 else if (op1 == TOK_UGT)
4766 op1 = TOK_UGE;
4767 a = 0;
4768 b = 0;
4769 gen_op(op1);
4770 if (op1 != TOK_NE) {
4771 a = gtst(1, 0);
4773 if (op != TOK_EQ) {
4774 /* generate non equal test */
4775 /* XXX: NOT PORTABLE yet */
4776 if (a == 0) {
4777 b = gtst(0, 0);
4778 } else {
4779 #ifdef TCC_TARGET_I386
4780 b = psym(0x850f, 0);
4781 #else
4782 error("not implemented");
4783 #endif
4786 /* compare low. Always unsigned */
4787 op1 = op;
4788 if (op1 == TOK_LT)
4789 op1 = TOK_ULT;
4790 else if (op1 == TOK_LE)
4791 op1 = TOK_ULE;
4792 else if (op1 == TOK_GT)
4793 op1 = TOK_UGT;
4794 else if (op1 == TOK_GE)
4795 op1 = TOK_UGE;
4796 gen_op(op1);
4797 a = gtst(1, a);
4798 gsym(b);
4799 vseti(VT_JMPI, a);
4800 break;
4804 /* handle integer constant optimizations and various machine
4805 independant opt */
4806 void gen_opic(int op)
4808 int fc, c1, c2, n;
4809 SValue *v1, *v2;
4811 v1 = vtop - 1;
4812 v2 = vtop;
4813 /* currently, we cannot do computations with forward symbols */
4814 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4815 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4816 if (c1 && c2) {
4817 fc = v2->c.i;
4818 switch(op) {
4819 case '+': v1->c.i += fc; break;
4820 case '-': v1->c.i -= fc; break;
4821 case '&': v1->c.i &= fc; break;
4822 case '^': v1->c.i ^= fc; break;
4823 case '|': v1->c.i |= fc; break;
4824 case '*': v1->c.i *= fc; break;
4826 case TOK_PDIV:
4827 case '/':
4828 case '%':
4829 case TOK_UDIV:
4830 case TOK_UMOD:
4831 /* if division by zero, generate explicit division */
4832 if (fc == 0) {
4833 if (const_wanted)
4834 error("division by zero in constant");
4835 goto general_case;
4837 switch(op) {
4838 default: v1->c.i /= fc; break;
4839 case '%': v1->c.i %= fc; break;
4840 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
4841 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
4843 break;
4844 case TOK_SHL: v1->c.i <<= fc; break;
4845 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
4846 case TOK_SAR: v1->c.i >>= fc; break;
4847 /* tests */
4848 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
4849 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
4850 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
4851 case TOK_NE: v1->c.i = v1->c.i != fc; break;
4852 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
4853 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
4854 case TOK_LT: v1->c.i = v1->c.i < fc; break;
4855 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
4856 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
4857 case TOK_GT: v1->c.i = v1->c.i > fc; break;
4858 /* logical */
4859 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
4860 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
4861 default:
4862 goto general_case;
4864 vtop--;
4865 } else {
4866 /* if commutative ops, put c2 as constant */
4867 if (c1 && (op == '+' || op == '&' || op == '^' ||
4868 op == '|' || op == '*')) {
4869 vswap();
4870 swap(&c1, &c2);
4872 fc = vtop->c.i;
4873 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
4874 op == TOK_PDIV) &&
4875 fc == 1) ||
4876 ((op == '+' || op == '-' || op == '|' || op == '^' ||
4877 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
4878 fc == 0) ||
4879 (op == '&' &&
4880 fc == -1))) {
4881 /* nothing to do */
4882 vtop--;
4883 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
4884 /* try to use shifts instead of muls or divs */
4885 if (fc > 0 && (fc & (fc - 1)) == 0) {
4886 n = -1;
4887 while (fc) {
4888 fc >>= 1;
4889 n++;
4891 vtop->c.i = n;
4892 if (op == '*')
4893 op = TOK_SHL;
4894 else if (op == TOK_PDIV)
4895 op = TOK_SAR;
4896 else
4897 op = TOK_SHR;
4899 goto general_case;
4900 } else if (c2 && (op == '+' || op == '-') &&
4901 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
4902 (VT_CONST | VT_SYM)) {
4903 /* symbol + constant case */
4904 if (op == '-')
4905 fc = -fc;
4906 vtop--;
4907 vtop->c.i += fc;
4908 } else {
4909 general_case:
4910 if (!nocode_wanted) {
4911 /* call low level op generator */
4912 gen_opi(op);
4913 } else {
4914 vtop--;
4920 /* generate a floating point operation with constant propagation */
4921 void gen_opif(int op)
4923 int c1, c2;
4924 SValue *v1, *v2;
4925 long double f1, f2;
4927 v1 = vtop - 1;
4928 v2 = vtop;
4929 /* currently, we cannot do computations with forward symbols */
4930 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4931 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4932 if (c1 && c2) {
4933 if (v1->type.t == VT_FLOAT) {
4934 f1 = v1->c.f;
4935 f2 = v2->c.f;
4936 } else if (v1->type.t == VT_DOUBLE) {
4937 f1 = v1->c.d;
4938 f2 = v2->c.d;
4939 } else {
4940 f1 = v1->c.ld;
4941 f2 = v2->c.ld;
4944 /* NOTE: we only do constant propagation if finite number (not
4945 NaN or infinity) (ANSI spec) */
4946 if (!ieee_finite(f1) || !ieee_finite(f2))
4947 goto general_case;
4949 switch(op) {
4950 case '+': f1 += f2; break;
4951 case '-': f1 -= f2; break;
4952 case '*': f1 *= f2; break;
4953 case '/':
4954 if (f2 == 0.0) {
4955 if (const_wanted)
4956 error("division by zero in constant");
4957 goto general_case;
4959 f1 /= f2;
4960 break;
4961 /* XXX: also handles tests ? */
4962 default:
4963 goto general_case;
4965 /* XXX: overflow test ? */
4966 if (v1->type.t == VT_FLOAT) {
4967 v1->c.f = f1;
4968 } else if (v1->type.t == VT_DOUBLE) {
4969 v1->c.d = f1;
4970 } else {
4971 v1->c.ld = f1;
4973 vtop--;
4974 } else {
4975 general_case:
4976 if (!nocode_wanted) {
4977 gen_opf(op);
4978 } else {
4979 vtop--;
4984 static int pointed_size(CType *type)
4986 int align;
4987 return type_size(pointed_type(type), &align);
4990 #if 0
4991 void check_pointer_types(SValue *p1, SValue *p2)
4993 char buf1[256], buf2[256];
4994 int t1, t2;
4995 t1 = p1->t;
4996 t2 = p2->t;
4997 if (!is_compatible_types(t1, t2)) {
4998 type_to_str(buf1, sizeof(buf1), t1, NULL);
4999 type_to_str(buf2, sizeof(buf2), t2, NULL);
5000 error("incompatible pointers '%s' and '%s'", buf1, buf2);
5003 #endif
5005 /* generic gen_op: handles types problems */
5006 void gen_op(int op)
5008 int u, t1, t2, bt1, bt2, t;
5009 CType type1;
5011 t1 = vtop[-1].type.t;
5012 t2 = vtop[0].type.t;
5013 bt1 = t1 & VT_BTYPE;
5014 bt2 = t2 & VT_BTYPE;
5016 if (bt1 == VT_PTR || bt2 == VT_PTR) {
5017 /* at least one operand is a pointer */
5018 /* relationnal op: must be both pointers */
5019 if (op >= TOK_ULT && op <= TOK_GT) {
5020 // check_pointer_types(vtop, vtop - 1);
5021 /* pointers are handled are unsigned */
5022 t = VT_INT | VT_UNSIGNED;
5023 goto std_op;
5025 /* if both pointers, then it must be the '-' op */
5026 if (bt1 == VT_PTR && bt2 == VT_PTR) {
5027 if (op != '-')
5028 error("cannot use pointers here");
5029 // check_pointer_types(vtop - 1, vtop);
5030 /* XXX: check that types are compatible */
5031 u = pointed_size(&vtop[-1].type);
5032 gen_opic(op);
5033 /* set to integer type */
5034 vtop->type.t = VT_INT;
5035 vpushi(u);
5036 gen_op(TOK_PDIV);
5037 } else {
5038 /* exactly one pointer : must be '+' or '-'. */
5039 if (op != '-' && op != '+')
5040 error("cannot use pointers here");
5041 /* Put pointer as first operand */
5042 if (bt2 == VT_PTR) {
5043 vswap();
5044 swap(&t1, &t2);
5046 type1 = vtop[-1].type;
5047 /* XXX: cast to int ? (long long case) */
5048 vpushi(pointed_size(&vtop[-1].type));
5049 gen_op('*');
5050 #ifdef CONFIG_TCC_BCHECK
5051 /* if evaluating constant expression, no code should be
5052 generated, so no bound check */
5053 if (do_bounds_check && !const_wanted) {
5054 /* if bounded pointers, we generate a special code to
5055 test bounds */
5056 if (op == '-') {
5057 vpushi(0);
5058 vswap();
5059 gen_op('-');
5061 gen_bounded_ptr_add();
5062 } else
5063 #endif
5065 gen_opic(op);
5067 /* put again type if gen_opic() swaped operands */
5068 vtop->type = type1;
5070 } else if (is_float(bt1) || is_float(bt2)) {
5071 /* compute bigger type and do implicit casts */
5072 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
5073 t = VT_LDOUBLE;
5074 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
5075 t = VT_DOUBLE;
5076 } else {
5077 t = VT_FLOAT;
5079 /* floats can only be used for a few operations */
5080 if (op != '+' && op != '-' && op != '*' && op != '/' &&
5081 (op < TOK_ULT || op > TOK_GT))
5082 error("invalid operands for binary operation");
5083 goto std_op;
5084 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
5085 /* cast to biggest op */
5086 t = VT_LLONG;
5087 /* convert to unsigned if it does not fit in a long long */
5088 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
5089 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
5090 t |= VT_UNSIGNED;
5091 goto std_op;
5092 } else {
5093 /* integer operations */
5094 t = VT_INT;
5095 /* convert to unsigned if it does not fit in an integer */
5096 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
5097 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
5098 t |= VT_UNSIGNED;
5099 std_op:
5100 /* XXX: currently, some unsigned operations are explicit, so
5101 we modify them here */
5102 if (t & VT_UNSIGNED) {
5103 if (op == TOK_SAR)
5104 op = TOK_SHR;
5105 else if (op == '/')
5106 op = TOK_UDIV;
5107 else if (op == '%')
5108 op = TOK_UMOD;
5109 else if (op == TOK_LT)
5110 op = TOK_ULT;
5111 else if (op == TOK_GT)
5112 op = TOK_UGT;
5113 else if (op == TOK_LE)
5114 op = TOK_ULE;
5115 else if (op == TOK_GE)
5116 op = TOK_UGE;
5118 vswap();
5119 type1.t = t;
5120 gen_cast(&type1);
5121 vswap();
5122 /* special case for shifts and long long: we keep the shift as
5123 an integer */
5124 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
5125 type1.t = VT_INT;
5126 gen_cast(&type1);
5127 if (is_float(t))
5128 gen_opif(op);
5129 else if ((t & VT_BTYPE) == VT_LLONG)
5130 gen_opl(op);
5131 else
5132 gen_opic(op);
5133 if (op >= TOK_ULT && op <= TOK_GT) {
5134 /* relationnal op: the result is an int */
5135 vtop->type.t = VT_INT;
5136 } else {
5137 vtop->type.t = t;
5142 /* generic itof for unsigned long long case */
5143 void gen_cvt_itof1(int t)
5145 GFuncContext gf;
5147 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
5148 (VT_LLONG | VT_UNSIGNED)) {
5150 gfunc_start(&gf, FUNC_CDECL);
5151 gfunc_param(&gf);
5152 if (t == VT_FLOAT)
5153 vpush_global_sym(&func_old_type, TOK___ulltof);
5154 else if (t == VT_DOUBLE)
5155 vpush_global_sym(&func_old_type, TOK___ulltod);
5156 else
5157 vpush_global_sym(&func_old_type, TOK___ulltold);
5158 gfunc_call(&gf);
5159 vpushi(0);
5160 vtop->r = REG_FRET;
5161 } else {
5162 gen_cvt_itof(t);
5166 /* generic ftoi for unsigned long long case */
5167 void gen_cvt_ftoi1(int t)
5169 GFuncContext gf;
5170 int st;
5172 if (t == (VT_LLONG | VT_UNSIGNED)) {
5173 /* not handled natively */
5174 gfunc_start(&gf, FUNC_CDECL);
5175 st = vtop->type.t & VT_BTYPE;
5176 gfunc_param(&gf);
5177 if (st == VT_FLOAT)
5178 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
5179 else if (st == VT_DOUBLE)
5180 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
5181 else
5182 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
5183 gfunc_call(&gf);
5184 vpushi(0);
5185 vtop->r = REG_IRET;
5186 vtop->r2 = REG_LRET;
5187 } else {
5188 gen_cvt_ftoi(t);
5192 /* force char or short cast */
5193 void force_charshort_cast(int t)
5195 int bits, dbt;
5196 dbt = t & VT_BTYPE;
5197 /* XXX: add optimization if lvalue : just change type and offset */
5198 if (dbt == VT_BYTE)
5199 bits = 8;
5200 else
5201 bits = 16;
5202 if (t & VT_UNSIGNED) {
5203 vpushi((1 << bits) - 1);
5204 gen_op('&');
5205 } else {
5206 bits = 32 - bits;
5207 vpushi(bits);
5208 gen_op(TOK_SHL);
5209 vpushi(bits);
5210 gen_op(TOK_SAR);
5214 /* cast 'vtop' to 'type' */
5215 static void gen_cast(CType *type)
5217 int sbt, dbt, sf, df, c;
5219 /* special delayed cast for char/short */
5220 /* XXX: in some cases (multiple cascaded casts), it may still
5221 be incorrect */
5222 if (vtop->r & VT_MUSTCAST) {
5223 vtop->r &= ~VT_MUSTCAST;
5224 force_charshort_cast(vtop->type.t);
5227 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
5228 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
5230 if (sbt != dbt && !nocode_wanted) {
5231 sf = is_float(sbt);
5232 df = is_float(dbt);
5233 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5234 if (sf && df) {
5235 /* convert from fp to fp */
5236 if (c) {
5237 /* constant case: we can do it now */
5238 /* XXX: in ISOC, cannot do it if error in convert */
5239 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
5240 vtop->c.f = (float)vtop->c.d;
5241 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
5242 vtop->c.f = (float)vtop->c.ld;
5243 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
5244 vtop->c.d = (double)vtop->c.f;
5245 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
5246 vtop->c.d = (double)vtop->c.ld;
5247 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
5248 vtop->c.ld = (long double)vtop->c.f;
5249 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
5250 vtop->c.ld = (long double)vtop->c.d;
5251 } else {
5252 /* non constant case: generate code */
5253 gen_cvt_ftof(dbt);
5255 } else if (df) {
5256 /* convert int to fp */
5257 if (c) {
5258 switch(sbt) {
5259 case VT_LLONG | VT_UNSIGNED:
5260 case VT_LLONG:
5261 /* XXX: add const cases for long long */
5262 goto do_itof;
5263 case VT_INT | VT_UNSIGNED:
5264 switch(dbt) {
5265 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
5266 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
5267 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
5269 break;
5270 default:
5271 switch(dbt) {
5272 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
5273 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
5274 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
5276 break;
5278 } else {
5279 do_itof:
5280 gen_cvt_itof1(dbt);
5282 } else if (sf) {
5283 /* convert fp to int */
5284 /* we handle char/short/etc... with generic code */
5285 if (dbt != (VT_INT | VT_UNSIGNED) &&
5286 dbt != (VT_LLONG | VT_UNSIGNED) &&
5287 dbt != VT_LLONG)
5288 dbt = VT_INT;
5289 if (c) {
5290 switch(dbt) {
5291 case VT_LLONG | VT_UNSIGNED:
5292 case VT_LLONG:
5293 /* XXX: add const cases for long long */
5294 goto do_ftoi;
5295 case VT_INT | VT_UNSIGNED:
5296 switch(sbt) {
5297 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
5298 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5299 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5301 break;
5302 default:
5303 /* int case */
5304 switch(sbt) {
5305 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
5306 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
5307 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
5309 break;
5311 } else {
5312 do_ftoi:
5313 gen_cvt_ftoi1(dbt);
5315 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
5316 /* additionnal cast for char/short/bool... */
5317 vtop->type.t = dbt;
5318 gen_cast(type);
5320 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
5321 if ((sbt & VT_BTYPE) != VT_LLONG) {
5322 /* scalar to long long */
5323 if (c) {
5324 if (sbt == (VT_INT | VT_UNSIGNED))
5325 vtop->c.ll = vtop->c.ui;
5326 else
5327 vtop->c.ll = vtop->c.i;
5328 } else {
5329 /* machine independant conversion */
5330 gv(RC_INT);
5331 /* generate high word */
5332 if (sbt == (VT_INT | VT_UNSIGNED)) {
5333 vpushi(0);
5334 gv(RC_INT);
5335 } else {
5336 gv_dup();
5337 vpushi(31);
5338 gen_op(TOK_SAR);
5340 /* patch second register */
5341 vtop[-1].r2 = vtop->r;
5342 vpop();
5345 } else if (dbt == VT_BOOL) {
5346 /* scalar to bool */
5347 vpushi(0);
5348 gen_op(TOK_NE);
5349 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
5350 (dbt & VT_BTYPE) == VT_SHORT) {
5351 force_charshort_cast(dbt);
5352 } else if ((dbt & VT_BTYPE) == VT_INT) {
5353 /* scalar to int */
5354 if (sbt == VT_LLONG) {
5355 /* from long long: just take low order word */
5356 lexpand();
5357 vpop();
5359 /* if lvalue and single word type, nothing to do because
5360 the lvalue already contains the real type size (see
5361 VT_LVAL_xxx constants) */
5364 vtop->type = *type;
5367 /* return type size. Put alignment at 'a' */
5368 static int type_size(CType *type, int *a)
5370 Sym *s;
5371 int bt;
5373 bt = type->t & VT_BTYPE;
5374 if (bt == VT_STRUCT) {
5375 /* struct/union */
5376 s = type->ref;
5377 *a = s->r;
5378 return s->c;
5379 } else if (bt == VT_PTR) {
5380 if (type->t & VT_ARRAY) {
5381 s = type->ref;
5382 return type_size(&s->type, a) * s->c;
5383 } else {
5384 *a = PTR_SIZE;
5385 return PTR_SIZE;
5387 } else if (bt == VT_LDOUBLE) {
5388 *a = LDOUBLE_ALIGN;
5389 return LDOUBLE_SIZE;
5390 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
5391 *a = 4; /* XXX: i386 specific */
5392 return 8;
5393 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
5394 *a = 4;
5395 return 4;
5396 } else if (bt == VT_SHORT) {
5397 *a = 2;
5398 return 2;
5399 } else {
5400 /* char, void, function, _Bool */
5401 *a = 1;
5402 return 1;
5406 /* return the pointed type of t */
5407 static inline CType *pointed_type(CType *type)
5409 return &type->ref->type;
5412 /* modify type so that its it is a pointer to type. */
5413 static void mk_pointer(CType *type)
5415 Sym *s;
5416 s = sym_push(SYM_FIELD, type, 0, -1);
5417 type->t = VT_PTR | (type->t & ~VT_TYPE);
5418 type->ref = s;
5421 static int is_compatible_types(CType *type1, CType *type2)
5423 Sym *s1, *s2;
5424 int bt1, bt2, t1, t2;
5426 t1 = type1->t & VT_TYPE;
5427 t2 = type2->t & VT_TYPE;
5428 bt1 = t1 & VT_BTYPE;
5429 bt2 = t2 & VT_BTYPE;
5430 if (bt1 == VT_PTR) {
5431 type1 = pointed_type(type1);
5432 /* if function, then convert implicitely to function pointer */
5433 if (bt2 != VT_FUNC) {
5434 if (bt2 != VT_PTR)
5435 return 0;
5436 type2 = pointed_type(type2);
5438 /* void matches everything */
5439 /* XXX: not fully compliant */
5440 if ((type1->t & VT_TYPE) == VT_VOID || (type2->t & VT_TYPE) == VT_VOID)
5441 return 1;
5442 return is_compatible_types(type1, type2);
5443 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5444 return (type1->ref == type2->ref);
5445 } else if (bt1 == VT_FUNC) {
5446 if (bt2 != VT_FUNC)
5447 return 0;
5448 s1 = type1->ref;
5449 s2 = type2->ref;
5450 if (!is_compatible_types(&s1->type, &s2->type))
5451 return 0;
5452 /* XXX: not complete */
5453 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
5454 return 1;
5455 if (s1->c != s2->c)
5456 return 0;
5457 while (s1 != NULL) {
5458 if (s2 == NULL)
5459 return 0;
5460 if (!is_compatible_types(&s1->type, &s2->type))
5461 return 0;
5462 s1 = s1->next;
5463 s2 = s2->next;
5465 if (s2)
5466 return 0;
5467 return 1;
5468 } else {
5469 /* XXX: not complete */
5470 return 1;
5474 /* print a type. If 'varstr' is not NULL, then the variable is also
5475 printed in the type */
5476 /* XXX: union */
5477 /* XXX: add array and function pointers */
5478 void type_to_str(char *buf, int buf_size,
5479 CType *type, const char *varstr)
5481 int bt, v, t;
5482 Sym *s, *sa;
5483 char buf1[256];
5484 const char *tstr;
5486 t = type->t & VT_TYPE;
5487 bt = t & VT_BTYPE;
5488 buf[0] = '\0';
5489 if (t & VT_UNSIGNED)
5490 pstrcat(buf, buf_size, "unsigned ");
5491 switch(bt) {
5492 case VT_VOID:
5493 tstr = "void";
5494 goto add_tstr;
5495 case VT_BOOL:
5496 tstr = "_Bool";
5497 goto add_tstr;
5498 case VT_BYTE:
5499 tstr = "char";
5500 goto add_tstr;
5501 case VT_SHORT:
5502 tstr = "short";
5503 goto add_tstr;
5504 case VT_INT:
5505 tstr = "int";
5506 goto add_tstr;
5507 case VT_LONG:
5508 tstr = "long";
5509 goto add_tstr;
5510 case VT_LLONG:
5511 tstr = "long long";
5512 goto add_tstr;
5513 case VT_FLOAT:
5514 tstr = "float";
5515 goto add_tstr;
5516 case VT_DOUBLE:
5517 tstr = "double";
5518 goto add_tstr;
5519 case VT_LDOUBLE:
5520 tstr = "long double";
5521 add_tstr:
5522 pstrcat(buf, buf_size, tstr);
5523 break;
5524 case VT_ENUM:
5525 case VT_STRUCT:
5526 if (bt == VT_STRUCT)
5527 tstr = "struct ";
5528 else
5529 tstr = "enum ";
5530 pstrcat(buf, buf_size, tstr);
5531 v = type->ref->v & ~SYM_STRUCT;
5532 if (v >= SYM_FIRST_ANOM)
5533 pstrcat(buf, buf_size, "<anonymous>");
5534 else
5535 pstrcat(buf, buf_size, get_tok_str(v, NULL));
5536 break;
5537 case VT_FUNC:
5538 s = type->ref;
5539 type_to_str(buf, buf_size, &s->type, varstr);
5540 pstrcat(buf, buf_size, "(");
5541 sa = s->next;
5542 while (sa != NULL) {
5543 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
5544 pstrcat(buf, buf_size, buf1);
5545 sa = sa->next;
5546 if (sa)
5547 pstrcat(buf, buf_size, ", ");
5549 pstrcat(buf, buf_size, ")");
5550 goto no_var;
5551 case VT_PTR:
5552 s = type->ref;
5553 pstrcpy(buf1, sizeof(buf1), "*");
5554 if (varstr)
5555 pstrcat(buf1, sizeof(buf1), varstr);
5556 type_to_str(buf, buf_size, &s->type, buf1);
5557 goto no_var;
5559 if (varstr) {
5560 pstrcat(buf, buf_size, " ");
5561 pstrcat(buf, buf_size, varstr);
5563 no_var: ;
5566 /* verify type compatibility to store vtop in 'dt' type, and generate
5567 casts if needed. */
5568 static void gen_assign_cast(CType *dt)
5570 CType *st;
5571 char buf1[256], buf2[256];
5572 int dbt, sbt;
5574 st = &vtop->type; /* source type */
5575 dbt = dt->t & VT_BTYPE;
5576 sbt = st->t & VT_BTYPE;
5577 if (dbt == VT_PTR) {
5578 /* special cases for pointers */
5579 /* a function is implicitely a function pointer */
5580 if (sbt == VT_FUNC) {
5581 if (!is_compatible_types(pointed_type(dt), st))
5582 goto error;
5583 else
5584 goto type_ok;
5586 /* '0' can also be a pointer */
5587 if (sbt == VT_INT &&
5588 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
5589 vtop->c.i == 0)
5590 goto type_ok;
5591 /* accept implicit pointer to integer cast with warning */
5592 if (sbt == VT_BYTE || sbt == VT_SHORT ||
5593 sbt == VT_INT || sbt == VT_LLONG) {
5594 warning("assignment makes pointer from integer without a cast");
5595 goto type_ok;
5597 } else if (dbt == VT_BYTE || dbt == VT_SHORT ||
5598 dbt == VT_INT || dbt == VT_LLONG) {
5599 if (sbt == VT_PTR || sbt == VT_FUNC) {
5600 warning("assignment makes integer from pointer without a cast");
5601 goto type_ok;
5604 if (!is_compatible_types(dt, st)) {
5605 error:
5606 type_to_str(buf1, sizeof(buf1), st, NULL);
5607 type_to_str(buf2, sizeof(buf2), dt, NULL);
5608 error("cannot cast '%s' to '%s'", buf1, buf2);
5610 type_ok:
5611 gen_cast(dt);
5614 /* store vtop in lvalue pushed on stack */
5615 void vstore(void)
5617 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
5618 GFuncContext gf;
5620 ft = vtop[-1].type.t;
5621 sbt = vtop->type.t & VT_BTYPE;
5622 dbt = ft & VT_BTYPE;
5623 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
5624 (sbt == VT_INT && dbt == VT_SHORT)) {
5625 /* optimize char/short casts */
5626 delayed_cast = VT_MUSTCAST;
5627 vtop->type.t = ft & VT_TYPE;
5628 } else {
5629 delayed_cast = 0;
5630 gen_assign_cast(&vtop[-1].type);
5633 if (sbt == VT_STRUCT) {
5634 /* if structure, only generate pointer */
5635 /* structure assignment : generate memcpy */
5636 /* XXX: optimize if small size */
5637 if (!nocode_wanted) {
5638 vdup();
5639 gfunc_start(&gf, FUNC_CDECL);
5640 /* type size */
5641 size = type_size(&vtop->type, &align);
5642 vpushi(size);
5643 gfunc_param(&gf);
5644 /* source */
5645 vtop->type.t = VT_INT;
5646 gaddrof();
5647 gfunc_param(&gf);
5648 /* destination */
5649 vswap();
5650 vtop->type.t = VT_INT;
5651 gaddrof();
5652 gfunc_param(&gf);
5654 save_regs(0);
5655 vpush_global_sym(&func_old_type, TOK_memcpy);
5656 gfunc_call(&gf);
5657 } else {
5658 vswap();
5659 vpop();
5661 /* leave source on stack */
5662 } else if (ft & VT_BITFIELD) {
5663 /* bitfield store handling */
5664 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
5665 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5666 /* remove bit field info to avoid loops */
5667 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
5669 /* duplicate destination */
5670 vdup();
5671 vtop[-1] = vtop[-2];
5673 /* mask and shift source */
5674 vpushi((1 << bit_size) - 1);
5675 gen_op('&');
5676 vpushi(bit_pos);
5677 gen_op(TOK_SHL);
5678 /* load destination, mask and or with source */
5679 vswap();
5680 vpushi(~(((1 << bit_size) - 1) << bit_pos));
5681 gen_op('&');
5682 gen_op('|');
5683 /* store result */
5684 vstore();
5685 } else {
5686 #ifdef CONFIG_TCC_BCHECK
5687 /* bound check case */
5688 if (vtop[-1].r & VT_MUSTBOUND) {
5689 vswap();
5690 gbound();
5691 vswap();
5693 #endif
5694 if (!nocode_wanted) {
5695 rc = RC_INT;
5696 if (is_float(ft))
5697 rc = RC_FLOAT;
5698 r = gv(rc); /* generate value */
5699 /* if lvalue was saved on stack, must read it */
5700 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
5701 SValue sv;
5702 t = get_reg(RC_INT);
5703 sv.type.t = VT_INT;
5704 sv.r = VT_LOCAL | VT_LVAL;
5705 sv.c.ul = vtop[-1].c.ul;
5706 load(t, &sv);
5707 vtop[-1].r = t | VT_LVAL;
5709 store(r, vtop - 1);
5710 /* two word case handling : store second register at word + 4 */
5711 if ((ft & VT_BTYPE) == VT_LLONG) {
5712 vswap();
5713 /* convert to int to increment easily */
5714 vtop->type.t = VT_INT;
5715 gaddrof();
5716 vpushi(4);
5717 gen_op('+');
5718 vtop->r |= VT_LVAL;
5719 vswap();
5720 /* XXX: it works because r2 is spilled last ! */
5721 store(vtop->r2, vtop - 1);
5724 vswap();
5725 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5726 vtop->r |= delayed_cast;
5730 /* post defines POST/PRE add. c is the token ++ or -- */
5731 void inc(int post, int c)
5733 test_lvalue();
5734 vdup(); /* save lvalue */
5735 if (post) {
5736 gv_dup(); /* duplicate value */
5737 vrotb(3);
5738 vrotb(3);
5740 /* add constant */
5741 vpushi(c - TOK_MID);
5742 gen_op('+');
5743 vstore(); /* store value */
5744 if (post)
5745 vpop(); /* if post op, return saved value */
5748 /* Parse GNUC __attribute__ extension. Currently, the following
5749 extensions are recognized:
5750 - aligned(n) : set data/function alignment.
5751 - section(x) : generate data/code in this section.
5752 - unused : currently ignored, but may be used someday.
5754 static void parse_attribute(AttributeDef *ad)
5756 int t, n;
5758 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
5759 next();
5760 skip('(');
5761 skip('(');
5762 while (tok != ')') {
5763 if (tok < TOK_IDENT)
5764 expect("attribute name");
5765 t = tok;
5766 next();
5767 switch(t) {
5768 case TOK_SECTION1:
5769 case TOK_SECTION2:
5770 skip('(');
5771 if (tok != TOK_STR)
5772 expect("section name");
5773 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
5774 next();
5775 skip(')');
5776 break;
5777 case TOK_ALIGNED1:
5778 case TOK_ALIGNED2:
5779 if (tok == '(') {
5780 next();
5781 n = expr_const();
5782 if (n <= 0 || (n & (n - 1)) != 0)
5783 error("alignment must be a positive power of two");
5784 skip(')');
5785 } else {
5786 n = MAX_ALIGN;
5788 ad->aligned = n;
5789 break;
5790 case TOK_UNUSED1:
5791 case TOK_UNUSED2:
5792 /* currently, no need to handle it because tcc does not
5793 track unused objects */
5794 break;
5795 case TOK_NORETURN1:
5796 case TOK_NORETURN2:
5797 /* currently, no need to handle it because tcc does not
5798 track unused objects */
5799 break;
5800 case TOK_CDECL1:
5801 case TOK_CDECL2:
5802 case TOK_CDECL3:
5803 ad->func_call = FUNC_CDECL;
5804 break;
5805 case TOK_STDCALL1:
5806 case TOK_STDCALL2:
5807 case TOK_STDCALL3:
5808 ad->func_call = FUNC_STDCALL;
5809 break;
5810 default:
5811 // warning("'%s' attribute ignored", get_tok_str(t, NULL));
5812 /* skip parameters */
5813 /* XXX: skip parenthesis too */
5814 if (tok == '(') {
5815 next();
5816 while (tok != ')' && tok != -1)
5817 next();
5818 next();
5820 break;
5822 if (tok != ',')
5823 break;
5824 next();
5826 skip(')');
5827 skip(')');
5831 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5832 static void struct_decl(CType *type, int u)
5834 int a, v, size, align, maxalign, c, offset;
5835 int bit_size, bit_pos, bsize, bt, lbit_pos;
5836 Sym *s, *ss, **ps;
5837 AttributeDef ad;
5838 CType type1, btype;
5840 a = tok; /* save decl type */
5841 next();
5842 if (tok != '{') {
5843 v = tok;
5844 next();
5845 /* struct already defined ? return it */
5846 /* XXX: check consistency */
5847 s = struct_find(v);
5848 if (s) {
5849 if (s->type.t != a)
5850 error("invalid type");
5851 goto do_decl;
5853 } else {
5854 v = anon_sym++;
5856 type1.t = a;
5857 s = sym_push(v | SYM_STRUCT, &type1, 0, 0);
5858 /* put struct/union/enum name in type */
5859 do_decl:
5860 type->t = u;
5861 type->ref = s;
5863 if (tok == '{') {
5864 next();
5865 if (s->c)
5866 error("struct/union/enum already defined");
5867 /* cannot be empty */
5868 c = 0;
5869 /* non empty enums are not allowed */
5870 if (a == TOK_ENUM) {
5871 for(;;) {
5872 v = tok;
5873 if (v < TOK_UIDENT)
5874 expect("identifier");
5875 next();
5876 if (tok == '=') {
5877 next();
5878 c = expr_const();
5880 /* enum symbols have static storage */
5881 ss = sym_push(v, &int_type, VT_CONST, c);
5882 ss->type.t |= VT_STATIC;
5883 if (tok != ',')
5884 break;
5885 next();
5886 c++;
5887 /* NOTE: we accept a trailing comma */
5888 if (tok == '}')
5889 break;
5891 skip('}');
5892 } else {
5893 maxalign = 1;
5894 ps = &s->next;
5895 bit_pos = 0;
5896 offset = 0;
5897 while (tok != '}') {
5898 parse_btype(&btype, &ad);
5899 while (1) {
5900 bit_size = -1;
5901 v = 0;
5902 type1 = btype;
5903 if (tok != ':') {
5904 type_decl(&type1, &ad, &v, TYPE_DIRECT);
5905 if ((type1.t & VT_BTYPE) == VT_FUNC ||
5906 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
5907 error("invalid type for '%s'",
5908 get_tok_str(v, NULL));
5910 if (tok == ':') {
5911 next();
5912 bit_size = expr_const();
5913 /* XXX: handle v = 0 case for messages */
5914 if (bit_size < 0)
5915 error("negative width in bit-field '%s'",
5916 get_tok_str(v, NULL));
5917 if (v && bit_size == 0)
5918 error("zero width for bit-field '%s'",
5919 get_tok_str(v, NULL));
5921 size = type_size(&type1, &align);
5922 lbit_pos = 0;
5923 if (bit_size >= 0) {
5924 bt = type1.t & VT_BTYPE;
5925 if (bt != VT_INT &&
5926 bt != VT_BYTE &&
5927 bt != VT_SHORT &&
5928 bt != VT_ENUM)
5929 error("bitfields must have scalar type");
5930 bsize = size * 8;
5931 if (bit_size > bsize) {
5932 error("width of '%s' exceeds its type",
5933 get_tok_str(v, NULL));
5934 } else if (bit_size == bsize) {
5935 /* no need for bit fields */
5936 bit_pos = 0;
5937 } else if (bit_size == 0) {
5938 /* XXX: what to do if only padding in a
5939 structure ? */
5940 /* zero size: means to pad */
5941 if (bit_pos > 0)
5942 bit_pos = bsize;
5943 } else {
5944 /* we do not have enough room ? */
5945 if ((bit_pos + bit_size) > bsize)
5946 bit_pos = 0;
5947 lbit_pos = bit_pos;
5948 /* XXX: handle LSB first */
5949 type1.t |= VT_BITFIELD |
5950 (bit_pos << VT_STRUCT_SHIFT) |
5951 (bit_size << (VT_STRUCT_SHIFT + 6));
5952 bit_pos += bit_size;
5954 } else {
5955 bit_pos = 0;
5957 if (v) {
5958 /* add new memory data only if starting
5959 bit field */
5960 if (lbit_pos == 0) {
5961 if (a == TOK_STRUCT) {
5962 c = (c + align - 1) & -align;
5963 offset = c;
5964 c += size;
5965 } else {
5966 offset = 0;
5967 if (size > c)
5968 c = size;
5970 if (align > maxalign)
5971 maxalign = align;
5973 #if 0
5974 printf("add field %s offset=%d",
5975 get_tok_str(v, NULL), offset);
5976 if (type1.t & VT_BITFIELD) {
5977 printf(" pos=%d size=%d",
5978 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
5979 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
5981 printf("\n");
5982 #endif
5983 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
5984 *ps = ss;
5985 ps = &ss->next;
5987 if (tok == ';' || tok == TOK_EOF)
5988 break;
5989 skip(',');
5991 skip(';');
5993 skip('}');
5994 /* store size and alignment */
5995 s->c = (c + maxalign - 1) & -maxalign;
5996 s->r = maxalign;
6001 /* return 0 if no type declaration. otherwise, return the basic type
6002 and skip it.
6004 static int parse_btype(CType *type, AttributeDef *ad)
6006 int t, u, type_found;
6007 Sym *s;
6008 CType type1;
6010 memset(ad, 0, sizeof(AttributeDef));
6011 type_found = 0;
6012 t = 0;
6013 while(1) {
6014 switch(tok) {
6015 case TOK_EXTENSION:
6016 /* currently, we really ignore extension */
6017 next();
6018 continue;
6020 /* basic types */
6021 case TOK_CHAR:
6022 u = VT_BYTE;
6023 basic_type:
6024 next();
6025 basic_type1:
6026 if ((t & VT_BTYPE) != 0)
6027 error("too many basic types");
6028 t |= u;
6029 break;
6030 case TOK_VOID:
6031 u = VT_VOID;
6032 goto basic_type;
6033 case TOK_SHORT:
6034 u = VT_SHORT;
6035 goto basic_type;
6036 case TOK_INT:
6037 next();
6038 break;
6039 case TOK_LONG:
6040 next();
6041 if ((t & VT_BTYPE) == VT_DOUBLE) {
6042 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
6043 } else if ((t & VT_BTYPE) == VT_LONG) {
6044 t = (t & ~VT_BTYPE) | VT_LLONG;
6045 } else {
6046 u = VT_LONG;
6047 goto basic_type1;
6049 break;
6050 case TOK_BOOL:
6051 u = VT_BOOL;
6052 goto basic_type;
6053 case TOK_FLOAT:
6054 u = VT_FLOAT;
6055 goto basic_type;
6056 case TOK_DOUBLE:
6057 next();
6058 if ((t & VT_BTYPE) == VT_LONG) {
6059 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
6060 } else {
6061 u = VT_DOUBLE;
6062 goto basic_type1;
6064 break;
6065 case TOK_ENUM:
6066 struct_decl(&type1, VT_ENUM);
6067 basic_type2:
6068 u = type1.t;
6069 type->ref = type1.ref;
6070 goto basic_type1;
6071 case TOK_STRUCT:
6072 case TOK_UNION:
6073 struct_decl(&type1, VT_STRUCT);
6074 goto basic_type2;
6076 /* type modifiers */
6077 case TOK_CONST1:
6078 case TOK_CONST2:
6079 case TOK_CONST3:
6080 case TOK_VOLATILE1:
6081 case TOK_VOLATILE2:
6082 case TOK_VOLATILE3:
6083 case TOK_REGISTER:
6084 case TOK_SIGNED1:
6085 case TOK_SIGNED2:
6086 case TOK_SIGNED3:
6087 case TOK_AUTO:
6088 case TOK_RESTRICT1:
6089 case TOK_RESTRICT2:
6090 case TOK_RESTRICT3:
6091 next();
6092 break;
6093 case TOK_UNSIGNED:
6094 t |= VT_UNSIGNED;
6095 next();
6096 break;
6098 /* storage */
6099 case TOK_EXTERN:
6100 t |= VT_EXTERN;
6101 next();
6102 break;
6103 case TOK_STATIC:
6104 t |= VT_STATIC;
6105 next();
6106 break;
6107 case TOK_TYPEDEF:
6108 t |= VT_TYPEDEF;
6109 next();
6110 break;
6111 case TOK_INLINE1:
6112 case TOK_INLINE2:
6113 case TOK_INLINE3:
6114 t |= VT_INLINE;
6115 next();
6116 break;
6118 /* GNUC attribute */
6119 case TOK_ATTRIBUTE1:
6120 case TOK_ATTRIBUTE2:
6121 parse_attribute(ad);
6122 break;
6123 /* GNUC typeof */
6124 case TOK_TYPEOF1:
6125 case TOK_TYPEOF2:
6126 case TOK_TYPEOF3:
6127 next();
6128 parse_expr_type(&type1);
6129 goto basic_type2;
6130 default:
6131 s = sym_find(tok);
6132 if (!s || !(s->type.t & VT_TYPEDEF))
6133 goto the_end;
6134 t |= (s->type.t & ~VT_TYPEDEF);
6135 type->ref = s->type.ref;
6136 next();
6137 break;
6139 type_found = 1;
6141 the_end:
6142 /* long is never used as type */
6143 if ((t & VT_BTYPE) == VT_LONG)
6144 t = (t & ~VT_BTYPE) | VT_INT;
6145 type->t = t;
6146 return type_found;
6149 static void post_type(CType *type, AttributeDef *ad)
6151 int n, l, t1;
6152 Sym **plast, *s, *first;
6153 AttributeDef ad1;
6154 CType pt;
6156 if (tok == '(') {
6157 /* function declaration */
6158 next();
6159 l = 0;
6160 first = NULL;
6161 plast = &first;
6162 while (tok != ')') {
6163 /* read param name and compute offset */
6164 if (l != FUNC_OLD) {
6165 if (!parse_btype(&pt, &ad1)) {
6166 if (l) {
6167 error("invalid type");
6168 } else {
6169 l = FUNC_OLD;
6170 goto old_proto;
6173 l = FUNC_NEW;
6174 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
6175 break;
6176 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
6177 if ((pt.t & VT_BTYPE) == VT_VOID)
6178 error("parameter declared as void");
6179 } else {
6180 old_proto:
6181 n = tok;
6182 pt.t = VT_INT;
6183 next();
6185 /* array must be transformed to pointer according to ANSI C */
6186 pt.t &= ~VT_ARRAY;
6187 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
6188 *plast = s;
6189 plast = &s->next;
6190 if (tok == ',') {
6191 next();
6192 if (l == FUNC_NEW && tok == TOK_DOTS) {
6193 l = FUNC_ELLIPSIS;
6194 next();
6195 break;
6199 /* if no parameters, then old type prototype */
6200 if (l == 0)
6201 l = FUNC_OLD;
6202 skip(')');
6203 t1 = type->t & VT_STORAGE;
6204 type->t &= ~VT_STORAGE;
6205 post_type(type, ad);
6206 /* we push a anonymous symbol which will contain the function prototype */
6207 s = sym_push(SYM_FIELD, type, ad->func_call, l);
6208 s->next = first;
6209 type->t = t1 | VT_FUNC;
6210 type->ref = s;
6211 } else if (tok == '[') {
6212 /* array definition */
6213 next();
6214 n = -1;
6215 if (tok != ']') {
6216 n = expr_const();
6217 if (n < 0)
6218 error("invalid array size");
6220 skip(']');
6221 /* parse next post type */
6222 t1 = type->t & VT_STORAGE;
6223 type->t &= ~VT_STORAGE;
6224 post_type(type, ad);
6226 /* we push a anonymous symbol which will contain the array
6227 element type */
6228 s = sym_push(SYM_FIELD, type, 0, n);
6229 type->t = t1 | VT_ARRAY | VT_PTR;
6230 type->ref = s;
6234 /* Parse a type declaration (except basic type), and return the type
6235 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6236 expected. 'type' should contain the basic type. 'ad' is the
6237 attribute definition of the basic type. It can be modified by
6238 type_decl().
6240 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
6242 Sym *s;
6243 CType type1, *type2;
6245 while (tok == '*') {
6246 next();
6247 redo:
6248 switch(tok) {
6249 case TOK_CONST1:
6250 case TOK_CONST2:
6251 case TOK_CONST3:
6252 case TOK_VOLATILE1:
6253 case TOK_VOLATILE2:
6254 case TOK_VOLATILE3:
6255 case TOK_RESTRICT1:
6256 case TOK_RESTRICT2:
6257 case TOK_RESTRICT3:
6258 next();
6259 goto redo;
6261 mk_pointer(type);
6264 /* XXX: clarify attribute handling */
6265 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6266 parse_attribute(ad);
6268 /* recursive type */
6269 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6270 type1.t = 0; /* XXX: same as int */
6271 if (tok == '(') {
6272 next();
6273 /* XXX: this is not correct to modify 'ad' at this point, but
6274 the syntax is not clear */
6275 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6276 parse_attribute(ad);
6277 type_decl(&type1, ad, v, td);
6278 skip(')');
6279 } else {
6280 /* type identifier */
6281 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
6282 *v = tok;
6283 next();
6284 } else {
6285 if (!(td & TYPE_ABSTRACT))
6286 expect("identifier");
6287 *v = 0;
6290 post_type(type, ad);
6291 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6292 parse_attribute(ad);
6293 if (!type1.t)
6294 return;
6295 /* append type at the end of type1 */
6296 type2 = &type1;
6297 for(;;) {
6298 s = type2->ref;
6299 type2 = &s->type;
6300 if (!type2->t) {
6301 *type2 = *type;
6302 break;
6305 *type = type1;
6308 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6309 static int lvalue_type(int t)
6311 int bt, r;
6312 r = VT_LVAL;
6313 bt = t & VT_BTYPE;
6314 if (bt == VT_BYTE)
6315 r |= VT_LVAL_BYTE;
6316 else if (bt == VT_SHORT)
6317 r |= VT_LVAL_SHORT;
6318 else
6319 return r;
6320 if (t & VT_UNSIGNED)
6321 r |= VT_LVAL_UNSIGNED;
6322 return r;
6325 /* indirection with full error checking and bound check */
6326 static void indir(void)
6328 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6329 expect("pointer");
6330 if ((vtop->r & VT_LVAL) && !nocode_wanted)
6331 gv(RC_INT);
6332 vtop->type = *pointed_type(&vtop->type);
6333 /* an array is never an lvalue */
6334 if (!(vtop->type.t & VT_ARRAY)) {
6335 vtop->r |= lvalue_type(vtop->type.t);
6336 /* if bound checking, the referenced pointer must be checked */
6337 if (do_bounds_check)
6338 vtop->r |= VT_MUSTBOUND;
6342 /* pass a parameter to a function and do type checking and casting */
6343 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
6345 int func_type;
6346 CType type;
6348 func_type = func->c;
6349 if (func_type == FUNC_OLD ||
6350 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
6351 /* default casting : only need to convert float to double */
6352 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
6353 type.t = VT_DOUBLE;
6354 gen_cast(&type);
6356 } else if (arg == NULL) {
6357 error("too many arguments to function");
6358 } else {
6359 gen_assign_cast(&arg->type);
6361 if (!nocode_wanted) {
6362 gfunc_param(gf);
6363 } else {
6364 vpop();
6368 /* parse an expression of the form '(type)' or '(expr)' and return its
6369 type */
6370 static void parse_expr_type(CType *type)
6372 int n;
6373 AttributeDef ad;
6375 skip('(');
6376 if (parse_btype(type, &ad)) {
6377 type_decl(type, &ad, &n, TYPE_ABSTRACT);
6378 } else {
6379 expr_type(type);
6381 skip(')');
6384 static void vpush_tokc(int t)
6386 CType type;
6387 type.t = t;
6388 vsetc(&type, VT_CONST, &tokc);
6391 static void unary(void)
6393 int n, t, align, size, r;
6394 CType type;
6395 Sym *s;
6396 GFuncContext gf;
6397 AttributeDef ad;
6399 /* XXX: GCC 2.95.3 does not generate a table although it should be
6400 better here */
6401 tok_next:
6402 switch(tok) {
6403 case TOK_EXTENSION:
6404 next();
6405 goto tok_next;
6406 case TOK_CINT:
6407 case TOK_CCHAR:
6408 case TOK_LCHAR:
6409 vpushi(tokc.i);
6410 next();
6411 break;
6412 case TOK_CUINT:
6413 vpush_tokc(VT_INT | VT_UNSIGNED);
6414 next();
6415 break;
6416 case TOK_CLLONG:
6417 vpush_tokc(VT_LLONG);
6418 next();
6419 break;
6420 case TOK_CULLONG:
6421 vpush_tokc(VT_LLONG | VT_UNSIGNED);
6422 next();
6423 break;
6424 case TOK_CFLOAT:
6425 vpush_tokc(VT_FLOAT);
6426 next();
6427 break;
6428 case TOK_CDOUBLE:
6429 vpush_tokc(VT_DOUBLE);
6430 next();
6431 break;
6432 case TOK_CLDOUBLE:
6433 vpush_tokc(VT_LDOUBLE);
6434 next();
6435 break;
6436 case TOK___FUNCTION__:
6437 if (!gnu_ext)
6438 goto tok_identifier;
6439 /* fall thru */
6440 case TOK___FUNC__:
6442 void *ptr;
6443 int len;
6444 /* special function name identifier */
6445 len = strlen(funcname) + 1;
6446 /* generate char[len] type */
6447 type.t = VT_BYTE;
6448 mk_pointer(&type);
6449 type.t |= VT_ARRAY;
6450 type.ref->c = len;
6451 vpush_ref(&type, data_section, data_section->data_offset, len);
6452 ptr = section_ptr_add(data_section, len);
6453 memcpy(ptr, funcname, len);
6454 next();
6456 break;
6457 case TOK_LSTR:
6458 t = VT_INT;
6459 goto str_init;
6460 case TOK_STR:
6461 /* string parsing */
6462 t = VT_BYTE;
6463 str_init:
6464 type.t = t;
6465 mk_pointer(&type);
6466 type.t |= VT_ARRAY;
6467 memset(&ad, 0, sizeof(AttributeDef));
6468 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
6469 break;
6470 case '(':
6471 next();
6472 /* cast ? */
6473 if (parse_btype(&type, &ad)) {
6474 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
6475 skip(')');
6476 /* check ISOC99 compound literal */
6477 if (tok == '{') {
6478 /* data is allocated locally by default */
6479 if (global_expr)
6480 r = VT_CONST;
6481 else
6482 r = VT_LOCAL;
6483 /* all except arrays are lvalues */
6484 if (!(type.t & VT_ARRAY))
6485 r |= lvalue_type(type.t);
6486 memset(&ad, 0, sizeof(AttributeDef));
6487 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
6488 } else {
6489 unary();
6490 gen_cast(&type);
6492 } else if (tok == '{') {
6493 /* save all registers */
6494 save_regs(0);
6495 /* statement expression : we do not accept break/continue
6496 inside as GCC does */
6497 block(NULL, NULL, NULL, NULL, 0, 1);
6498 skip(')');
6499 } else {
6500 gexpr();
6501 skip(')');
6503 break;
6504 case '*':
6505 next();
6506 unary();
6507 indir();
6508 break;
6509 case '&':
6510 next();
6511 unary();
6512 /* functions names must be treated as function pointers,
6513 except for unary '&' and sizeof. Since we consider that
6514 functions are not lvalues, we only have to handle it
6515 there and in function calls. */
6516 /* arrays can also be used although they are not lvalues */
6517 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
6518 !(vtop->type.t & VT_ARRAY))
6519 test_lvalue();
6520 mk_pointer(&vtop->type);
6521 gaddrof();
6522 break;
6523 case '!':
6524 next();
6525 unary();
6526 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
6527 vtop->c.i = !vtop->c.i;
6528 else if ((vtop->r & VT_VALMASK) == VT_CMP)
6529 vtop->c.i = vtop->c.i ^ 1;
6530 else
6531 vseti(VT_JMP, gtst(1, 0));
6532 break;
6533 case '~':
6534 next();
6535 unary();
6536 vpushi(-1);
6537 gen_op('^');
6538 break;
6539 case '+':
6540 next();
6541 /* in order to force cast, we add zero */
6542 unary();
6543 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
6544 error("pointer not accepted for unary plus");
6545 vpushi(0);
6546 gen_op('+');
6547 break;
6548 case TOK_SIZEOF:
6549 case TOK_ALIGNOF1:
6550 case TOK_ALIGNOF2:
6551 t = tok;
6552 next();
6553 if (tok == '(') {
6554 parse_expr_type(&type);
6555 } else {
6556 unary_type(&type);
6558 size = type_size(&type, &align);
6559 if (t == TOK_SIZEOF)
6560 vpushi(size);
6561 else
6562 vpushi(align);
6563 break;
6565 case TOK_INC:
6566 case TOK_DEC:
6567 t = tok;
6568 next();
6569 unary();
6570 inc(0, t);
6571 break;
6572 case '-':
6573 next();
6574 vpushi(0);
6575 unary();
6576 gen_op('-');
6577 break;
6578 case TOK_LAND:
6579 if (!gnu_ext)
6580 goto tok_identifier;
6581 next();
6582 /* allow to take the address of a label */
6583 if (tok < TOK_UIDENT)
6584 expect("label identifier");
6585 s = label_find(tok);
6586 if (!s) {
6587 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
6588 } else {
6589 if (s->r == LABEL_DECLARED)
6590 s->r = LABEL_FORWARD;
6592 if (!s->type.t) {
6593 s->type.t = VT_VOID;
6594 mk_pointer(&s->type);
6595 s->type.t |= VT_STATIC;
6597 vset(&s->type, VT_CONST | VT_SYM, 0);
6598 vtop->sym = s;
6599 next();
6600 break;
6601 default:
6602 tok_identifier:
6603 t = tok;
6604 next();
6605 if (t < TOK_UIDENT)
6606 expect("identifier");
6607 s = sym_find(t);
6608 if (!s) {
6609 if (tok != '(')
6610 error("'%s' undeclared", get_tok_str(t, NULL));
6611 /* for simple function calls, we tolerate undeclared
6612 external reference to int() function */
6613 s = external_global_sym(t, &func_old_type, 0);
6615 vset(&s->type, s->r, s->c);
6616 /* if forward reference, we must point to s */
6617 if (vtop->r & VT_SYM) {
6618 vtop->sym = s;
6619 vtop->c.ul = 0;
6621 break;
6624 /* post operations */
6625 while (1) {
6626 if (tok == TOK_INC || tok == TOK_DEC) {
6627 inc(1, tok);
6628 next();
6629 } else if (tok == '.' || tok == TOK_ARROW) {
6630 /* field */
6631 if (tok == TOK_ARROW)
6632 indir();
6633 test_lvalue();
6634 gaddrof();
6635 next();
6636 /* expect pointer on structure */
6637 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
6638 expect("struct or union");
6639 s = vtop->type.ref;
6640 /* find field */
6641 tok |= SYM_FIELD;
6642 while ((s = s->next) != NULL) {
6643 if (s->v == tok)
6644 break;
6646 if (!s)
6647 error("field not found");
6648 /* add field offset to pointer */
6649 vtop->type = char_pointer_type; /* change type to 'char *' */
6650 vpushi(s->c);
6651 gen_op('+');
6652 /* change type to field type, and set to lvalue */
6653 vtop->type = s->type;
6654 /* an array is never an lvalue */
6655 if (!(vtop->type.t & VT_ARRAY)) {
6656 vtop->r |= lvalue_type(vtop->type.t);
6657 /* if bound checking, the referenced pointer must be checked */
6658 if (do_bounds_check)
6659 vtop->r |= VT_MUSTBOUND;
6661 next();
6662 } else if (tok == '[') {
6663 next();
6664 gexpr();
6665 gen_op('+');
6666 indir();
6667 skip(']');
6668 } else if (tok == '(') {
6669 SValue ret;
6670 Sym *sa;
6672 /* function call */
6673 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
6674 /* pointer test (no array accepted) */
6675 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
6676 vtop->type = *pointed_type(&vtop->type);
6677 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
6678 goto error_func;
6679 } else {
6680 error_func:
6681 expect("function pointer");
6683 } else {
6684 vtop->r &= ~VT_LVAL; /* no lvalue */
6686 /* get return type */
6687 s = vtop->type.ref;
6688 if (!nocode_wanted) {
6689 save_regs(0); /* save used temporary registers */
6690 gfunc_start(&gf, s->r);
6692 next();
6693 sa = s->next; /* first parameter */
6694 #ifdef INVERT_FUNC_PARAMS
6696 int parlevel;
6697 Sym *args, *s1;
6698 ParseState saved_parse_state;
6699 TokenString str;
6701 /* read each argument and store it on a stack */
6702 args = NULL;
6703 if (tok != ')') {
6704 for(;;) {
6705 tok_str_new(&str);
6706 parlevel = 0;
6707 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
6708 tok != TOK_EOF) {
6709 if (tok == '(')
6710 parlevel++;
6711 else if (tok == ')')
6712 parlevel--;
6713 tok_str_add_tok(&str);
6714 next();
6716 tok_str_add(&str, -1); /* end of file added */
6717 tok_str_add(&str, 0);
6718 s1 = sym_push2(&args, 0, 0, (int)str.str);
6719 s1->next = sa; /* add reference to argument */
6720 if (sa)
6721 sa = sa->next;
6722 if (tok == ')')
6723 break;
6724 skip(',');
6728 /* now generate code in reverse order by reading the stack */
6729 save_parse_state(&saved_parse_state);
6730 while (args) {
6731 macro_ptr = (int *)args->c;
6732 next();
6733 expr_eq();
6734 if (tok != -1)
6735 expect("',' or ')'");
6736 gfunc_param_typed(&gf, s, args->next);
6737 s1 = args->prev;
6738 tok_str_free((int *)args->c);
6739 tcc_free(args);
6740 args = s1;
6742 restore_parse_state(&saved_parse_state);
6744 #endif
6745 /* compute first implicit argument if a structure is returned */
6746 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6747 /* get some space for the returned structure */
6748 size = type_size(&s->type, &align);
6749 loc = (loc - size) & -align;
6750 ret.type = s->type;
6751 ret.r = VT_LOCAL | VT_LVAL;
6752 /* pass it as 'int' to avoid structure arg passing
6753 problems */
6754 vseti(VT_LOCAL, loc);
6755 ret.c = vtop->c;
6756 if (!nocode_wanted)
6757 gfunc_param(&gf);
6758 else
6759 vtop--;
6760 } else {
6761 ret.type = s->type;
6762 ret.r2 = VT_CONST;
6763 /* return in register */
6764 if (is_float(ret.type.t)) {
6765 ret.r = REG_FRET;
6766 } else {
6767 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
6768 ret.r2 = REG_LRET;
6769 ret.r = REG_IRET;
6771 ret.c.i = 0;
6773 #ifndef INVERT_FUNC_PARAMS
6774 if (tok != ')') {
6775 for(;;) {
6776 expr_eq();
6777 gfunc_param_typed(&gf, s, sa);
6778 if (sa)
6779 sa = sa->next;
6780 if (tok == ')')
6781 break;
6782 skip(',');
6785 #endif
6786 if (sa)
6787 error("too few arguments to function");
6788 skip(')');
6789 if (!nocode_wanted)
6790 gfunc_call(&gf);
6791 else
6792 vtop--;
6793 /* return value */
6794 vsetc(&ret.type, ret.r, &ret.c);
6795 vtop->r2 = ret.r2;
6796 } else {
6797 break;
6802 static void uneq(void)
6804 int t;
6806 unary();
6807 if (tok == '=' ||
6808 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
6809 tok == TOK_A_XOR || tok == TOK_A_OR ||
6810 tok == TOK_A_SHL || tok == TOK_A_SAR) {
6811 test_lvalue();
6812 t = tok;
6813 next();
6814 if (t == '=') {
6815 expr_eq();
6816 } else {
6817 vdup();
6818 expr_eq();
6819 gen_op(t & 0x7f);
6821 vstore();
6825 static void expr_prod(void)
6827 int t;
6829 uneq();
6830 while (tok == '*' || tok == '/' || tok == '%') {
6831 t = tok;
6832 next();
6833 uneq();
6834 gen_op(t);
6838 static void expr_sum(void)
6840 int t;
6842 expr_prod();
6843 while (tok == '+' || tok == '-') {
6844 t = tok;
6845 next();
6846 expr_prod();
6847 gen_op(t);
6851 static void expr_shift(void)
6853 int t;
6855 expr_sum();
6856 while (tok == TOK_SHL || tok == TOK_SAR) {
6857 t = tok;
6858 next();
6859 expr_sum();
6860 gen_op(t);
6864 static void expr_cmp(void)
6866 int t;
6868 expr_shift();
6869 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
6870 tok == TOK_ULT || tok == TOK_UGE) {
6871 t = tok;
6872 next();
6873 expr_shift();
6874 gen_op(t);
6878 static void expr_cmpeq(void)
6880 int t;
6882 expr_cmp();
6883 while (tok == TOK_EQ || tok == TOK_NE) {
6884 t = tok;
6885 next();
6886 expr_cmp();
6887 gen_op(t);
6891 static void expr_and(void)
6893 expr_cmpeq();
6894 while (tok == '&') {
6895 next();
6896 expr_cmpeq();
6897 gen_op('&');
6901 static void expr_xor(void)
6903 expr_and();
6904 while (tok == '^') {
6905 next();
6906 expr_and();
6907 gen_op('^');
6911 static void expr_or(void)
6913 expr_xor();
6914 while (tok == '|') {
6915 next();
6916 expr_xor();
6917 gen_op('|');
6921 /* XXX: suppress this mess */
6922 static void expr_land_const(void)
6924 expr_or();
6925 while (tok == TOK_LAND) {
6926 next();
6927 expr_or();
6928 gen_op(TOK_LAND);
6932 /* XXX: suppress this mess */
6933 static void expr_lor_const(void)
6935 expr_land_const();
6936 while (tok == TOK_LOR) {
6937 next();
6938 expr_land_const();
6939 gen_op(TOK_LOR);
6943 /* only used if non constant */
6944 static void expr_land(void)
6946 int t;
6948 expr_or();
6949 if (tok == TOK_LAND) {
6950 t = 0;
6951 for(;;) {
6952 t = gtst(1, t);
6953 if (tok != TOK_LAND) {
6954 vseti(VT_JMPI, t);
6955 break;
6957 next();
6958 expr_or();
6963 static void expr_lor(void)
6965 int t;
6967 expr_land();
6968 if (tok == TOK_LOR) {
6969 t = 0;
6970 for(;;) {
6971 t = gtst(0, t);
6972 if (tok != TOK_LOR) {
6973 vseti(VT_JMP, t);
6974 break;
6976 next();
6977 expr_land();
6982 /* XXX: better constant handling */
6983 static void expr_eq(void)
6985 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
6986 SValue sv;
6987 CType type, type1, type2;
6989 if (const_wanted) {
6990 int c1, c;
6991 expr_lor_const();
6992 if (tok == '?') {
6993 c = vtop->c.i;
6994 vpop();
6995 next();
6996 if (tok == ':' && gnu_ext) {
6997 c1 = c;
6998 } else {
6999 gexpr();
7000 c1 = vtop->c.i;
7001 vpop();
7003 skip(':');
7004 expr_eq();
7005 if (c)
7006 vtop->c.i = c1;
7008 } else {
7009 expr_lor();
7010 if (tok == '?') {
7011 next();
7012 if (vtop != vstack) {
7013 /* needed to avoid having different registers saved in
7014 each branch */
7015 if (is_float(vtop->type.t))
7016 rc = RC_FLOAT;
7017 else
7018 rc = RC_INT;
7019 gv(rc);
7020 save_regs(1);
7022 if (tok == ':' && gnu_ext) {
7023 gv_dup();
7024 tt = gtst(1, 0);
7025 } else {
7026 tt = gtst(1, 0);
7027 gexpr();
7029 type1 = vtop->type;
7030 sv = *vtop; /* save value to handle it later */
7031 vtop--; /* no vpop so that FP stack is not flushed */
7032 skip(':');
7033 u = gjmp(0);
7034 gsym(tt);
7035 expr_eq();
7036 type2 = vtop->type;
7038 t1 = type1.t;
7039 bt1 = t1 & VT_BTYPE;
7040 t2 = type2.t;
7041 bt2 = t2 & VT_BTYPE;
7042 /* cast operands to correct type according to ISOC rules */
7043 if (is_float(bt1) || is_float(bt2)) {
7044 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
7045 type.t = VT_LDOUBLE;
7046 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
7047 type.t = VT_DOUBLE;
7048 } else {
7049 type.t = VT_FLOAT;
7051 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
7052 /* cast to biggest op */
7053 type.t = VT_LLONG;
7054 /* convert to unsigned if it does not fit in a long long */
7055 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
7056 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
7057 type.t |= VT_UNSIGNED;
7058 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
7059 /* XXX: test pointer compatibility */
7060 type = type1;
7061 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
7062 /* XXX: test structure compatibility */
7063 type = type1;
7064 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
7065 /* NOTE: as an extension, we accept void on only one side */
7066 type.t = VT_VOID;
7067 } else {
7068 /* integer operations */
7069 type.t = VT_INT;
7070 /* convert to unsigned if it does not fit in an integer */
7071 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
7072 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
7073 type.t |= VT_UNSIGNED;
7076 /* now we convert second operand */
7077 gen_cast(&type);
7078 rc = RC_INT;
7079 if (is_float(type.t)) {
7080 rc = RC_FLOAT;
7081 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
7082 /* for long longs, we use fixed registers to avoid having
7083 to handle a complicated move */
7084 rc = RC_IRET;
7087 r2 = gv(rc);
7088 /* this is horrible, but we must also convert first
7089 operand */
7090 tt = gjmp(0);
7091 gsym(u);
7092 /* put again first value and cast it */
7093 *vtop = sv;
7094 gen_cast(&type);
7095 r1 = gv(rc);
7096 move_reg(r2, r1);
7097 vtop->r = r2;
7098 gsym(tt);
7103 static void gexpr(void)
7105 while (1) {
7106 expr_eq();
7107 if (tok != ',')
7108 break;
7109 vpop();
7110 next();
7114 /* parse an expression and return its type without any side effect. */
7115 static void expr_type(CType *type)
7117 int a;
7119 a = nocode_wanted;
7120 nocode_wanted = 1;
7121 gexpr();
7122 *type = vtop->type;
7123 vpop();
7124 nocode_wanted = a;
7127 /* parse a unary expression and return its type without any side
7128 effect. */
7129 static void unary_type(CType *type)
7131 int a;
7133 a = nocode_wanted;
7134 nocode_wanted = 1;
7135 unary();
7136 *type = vtop->type;
7137 vpop();
7138 nocode_wanted = a;
7141 /* parse a constant expression and return value in vtop. */
7142 static void expr_const1(void)
7144 int a;
7145 a = const_wanted;
7146 const_wanted = 1;
7147 expr_eq();
7148 const_wanted = a;
7151 /* parse an integer constant and return its value. */
7152 static int expr_const(void)
7154 int c;
7155 expr_const1();
7156 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
7157 expect("constant expression");
7158 c = vtop->c.i;
7159 vpop();
7160 return c;
7163 /* return the label token if current token is a label, otherwise
7164 return zero */
7165 static int is_label(void)
7167 int last_tok;
7169 /* fast test first */
7170 if (tok < TOK_UIDENT)
7171 return 0;
7172 /* no need to save tokc because tok is an identifier */
7173 last_tok = tok;
7174 next();
7175 if (tok == ':') {
7176 next();
7177 return last_tok;
7178 } else {
7179 unget_tok(last_tok);
7180 return 0;
7184 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
7185 int case_reg, int is_expr)
7187 int a, b, c, d;
7188 Sym *s;
7190 /* generate line number info */
7191 if (do_debug &&
7192 (last_line_num != file->line_num || last_ind != ind)) {
7193 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
7194 last_ind = ind;
7195 last_line_num = file->line_num;
7198 if (is_expr) {
7199 /* default return value is (void) */
7200 vpushi(0);
7201 vtop->type.t = VT_VOID;
7204 if (tok == TOK_IF) {
7205 /* if test */
7206 next();
7207 skip('(');
7208 gexpr();
7209 skip(')');
7210 a = gtst(1, 0);
7211 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7212 c = tok;
7213 if (c == TOK_ELSE) {
7214 next();
7215 d = gjmp(0);
7216 gsym(a);
7217 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7218 gsym(d); /* patch else jmp */
7219 } else
7220 gsym(a);
7221 } else if (tok == TOK_WHILE) {
7222 next();
7223 d = ind;
7224 skip('(');
7225 gexpr();
7226 skip(')');
7227 a = gtst(1, 0);
7228 b = 0;
7229 block(&a, &b, case_sym, def_sym, case_reg, 0);
7230 gjmp_addr(d);
7231 gsym(a);
7232 gsym_addr(b, d);
7233 } else if (tok == '{') {
7234 Sym *llabel;
7236 next();
7237 /* record local declaration stack position */
7238 s = local_stack;
7239 llabel = local_label_stack;
7240 /* handle local labels declarations */
7241 if (tok == TOK_LABEL) {
7242 next();
7243 for(;;) {
7244 if (tok < TOK_UIDENT)
7245 expect("label identifier");
7246 label_push(&local_label_stack, tok, LABEL_DECLARED);
7247 next();
7248 if (tok == ',') {
7249 next();
7250 } else {
7251 skip(';');
7252 break;
7256 while (tok != '}') {
7257 decl(VT_LOCAL);
7258 if (tok != '}') {
7259 if (is_expr)
7260 vpop();
7261 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
7264 /* pop locally defined labels */
7265 label_pop(&local_label_stack, llabel);
7266 /* pop locally defined symbols */
7267 sym_pop(&local_stack, s);
7268 next();
7269 } else if (tok == TOK_RETURN) {
7270 next();
7271 if (tok != ';') {
7272 gexpr();
7273 gen_assign_cast(&func_vt);
7274 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
7275 CType type;
7276 /* if returning structure, must copy it to implicit
7277 first pointer arg location */
7278 type = func_vt;
7279 mk_pointer(&type);
7280 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
7281 indir();
7282 vswap();
7283 /* copy structure value to pointer */
7284 vstore();
7285 } else if (is_float(func_vt.t)) {
7286 gv(RC_FRET);
7287 } else {
7288 gv(RC_IRET);
7290 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
7292 skip(';');
7293 rsym = gjmp(rsym); /* jmp */
7294 } else if (tok == TOK_BREAK) {
7295 /* compute jump */
7296 if (!bsym)
7297 error("cannot break");
7298 *bsym = gjmp(*bsym);
7299 next();
7300 skip(';');
7301 } else if (tok == TOK_CONTINUE) {
7302 /* compute jump */
7303 if (!csym)
7304 error("cannot continue");
7305 *csym = gjmp(*csym);
7306 next();
7307 skip(';');
7308 } else if (tok == TOK_FOR) {
7309 int e;
7310 next();
7311 skip('(');
7312 if (tok != ';') {
7313 gexpr();
7314 vpop();
7316 skip(';');
7317 d = ind;
7318 c = ind;
7319 a = 0;
7320 b = 0;
7321 if (tok != ';') {
7322 gexpr();
7323 a = gtst(1, 0);
7325 skip(';');
7326 if (tok != ')') {
7327 e = gjmp(0);
7328 c = ind;
7329 gexpr();
7330 vpop();
7331 gjmp_addr(d);
7332 gsym(e);
7334 skip(')');
7335 block(&a, &b, case_sym, def_sym, case_reg, 0);
7336 gjmp_addr(c);
7337 gsym(a);
7338 gsym_addr(b, c);
7339 } else
7340 if (tok == TOK_DO) {
7341 next();
7342 a = 0;
7343 b = 0;
7344 d = ind;
7345 block(&a, &b, case_sym, def_sym, case_reg, 0);
7346 skip(TOK_WHILE);
7347 skip('(');
7348 gsym(b);
7349 gexpr();
7350 c = gtst(0, 0);
7351 gsym_addr(c, d);
7352 skip(')');
7353 gsym(a);
7354 skip(';');
7355 } else
7356 if (tok == TOK_SWITCH) {
7357 next();
7358 skip('(');
7359 gexpr();
7360 /* XXX: other types than integer */
7361 case_reg = gv(RC_INT);
7362 vpop();
7363 skip(')');
7364 a = 0;
7365 b = gjmp(0); /* jump to first case */
7366 c = 0;
7367 block(&a, csym, &b, &c, case_reg, 0);
7368 /* if no default, jmp after switch */
7369 if (c == 0)
7370 c = ind;
7371 /* default label */
7372 gsym_addr(b, c);
7373 /* break label */
7374 gsym(a);
7375 } else
7376 if (tok == TOK_CASE) {
7377 int v1, v2;
7378 if (!case_sym)
7379 expect("switch");
7380 next();
7381 v1 = expr_const();
7382 v2 = v1;
7383 if (gnu_ext && tok == TOK_DOTS) {
7384 next();
7385 v2 = expr_const();
7386 if (v2 < v1)
7387 warning("empty case range");
7389 /* since a case is like a label, we must skip it with a jmp */
7390 b = gjmp(0);
7391 gsym(*case_sym);
7392 vseti(case_reg, 0);
7393 vpushi(v1);
7394 if (v1 == v2) {
7395 gen_op(TOK_EQ);
7396 *case_sym = gtst(1, 0);
7397 } else {
7398 gen_op(TOK_GE);
7399 *case_sym = gtst(1, 0);
7400 vseti(case_reg, 0);
7401 vpushi(v2);
7402 gen_op(TOK_LE);
7403 *case_sym = gtst(1, *case_sym);
7405 gsym(b);
7406 skip(':');
7407 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7408 } else
7409 if (tok == TOK_DEFAULT) {
7410 next();
7411 skip(':');
7412 if (!def_sym)
7413 expect("switch");
7414 if (*def_sym)
7415 error("too many 'default'");
7416 *def_sym = ind;
7417 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7418 } else
7419 if (tok == TOK_GOTO) {
7420 next();
7421 if (tok == '*' && gnu_ext) {
7422 /* computed goto */
7423 next();
7424 gexpr();
7425 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
7426 expect("pointer");
7427 ggoto();
7428 } else if (tok >= TOK_UIDENT) {
7429 s = label_find(tok);
7430 /* put forward definition if needed */
7431 if (!s) {
7432 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
7433 } else {
7434 if (s->r == LABEL_DECLARED)
7435 s->r = LABEL_FORWARD;
7437 /* label already defined */
7438 if (s->r & LABEL_FORWARD)
7439 s->next = (void *)gjmp((long)s->next);
7440 else
7441 gjmp_addr((long)s->next);
7442 next();
7443 } else {
7444 expect("label identifier");
7446 skip(';');
7447 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
7448 asm_instr();
7449 } else {
7450 b = is_label();
7451 if (b) {
7452 /* label case */
7453 s = label_find(b);
7454 if (s) {
7455 if (s->r == LABEL_DEFINED)
7456 error("duplicate label '%s'", get_tok_str(s->v, NULL));
7457 gsym((long)s->next);
7458 s->r = LABEL_DEFINED;
7459 } else {
7460 s = label_push(&global_label_stack, b, LABEL_DEFINED);
7462 s->next = (void *)ind;
7463 /* we accept this, but it is a mistake */
7464 if (tok == '}') {
7465 warning("deprecated use of label at end of compound statement");
7466 } else {
7467 if (is_expr)
7468 vpop();
7469 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
7471 } else {
7472 /* expression case */
7473 if (tok != ';') {
7474 if (is_expr) {
7475 vpop();
7476 gexpr();
7477 } else {
7478 gexpr();
7479 vpop();
7482 skip(';');
7487 /* t is the array or struct type. c is the array or struct
7488 address. cur_index/cur_field is the pointer to the current
7489 value. 'size_only' is true if only size info is needed (only used
7490 in arrays) */
7491 static void decl_designator(CType *type, Section *sec, unsigned long c,
7492 int *cur_index, Sym **cur_field,
7493 int size_only)
7495 Sym *s, *f;
7496 int notfirst, index, index_last, align, l, nb_elems, elem_size;
7497 CType type1;
7499 notfirst = 0;
7500 elem_size = 0;
7501 nb_elems = 1;
7502 if (gnu_ext && (l = is_label()) != 0)
7503 goto struct_field;
7504 while (tok == '[' || tok == '.') {
7505 if (tok == '[') {
7506 if (!(type->t & VT_ARRAY))
7507 expect("array type");
7508 s = type->ref;
7509 next();
7510 index = expr_const();
7511 if (index < 0 || (s->c >= 0 && index >= s->c))
7512 expect("invalid index");
7513 if (tok == TOK_DOTS && gnu_ext) {
7514 next();
7515 index_last = expr_const();
7516 if (index_last < 0 ||
7517 (s->c >= 0 && index_last >= s->c) ||
7518 index_last < index)
7519 expect("invalid index");
7520 } else {
7521 index_last = index;
7523 skip(']');
7524 if (!notfirst)
7525 *cur_index = index_last;
7526 type = pointed_type(type);
7527 elem_size = type_size(type, &align);
7528 c += index * elem_size;
7529 /* NOTE: we only support ranges for last designator */
7530 nb_elems = index_last - index + 1;
7531 if (nb_elems != 1) {
7532 notfirst = 1;
7533 break;
7535 } else {
7536 next();
7537 l = tok;
7538 next();
7539 struct_field:
7540 if ((type->t & VT_BTYPE) != VT_STRUCT)
7541 expect("struct/union type");
7542 s = type->ref;
7543 l |= SYM_FIELD;
7544 f = s->next;
7545 while (f) {
7546 if (f->v == l)
7547 break;
7548 f = f->next;
7550 if (!f)
7551 expect("field");
7552 if (!notfirst)
7553 *cur_field = f;
7554 /* XXX: suppress this mess by using explicit storage field */
7555 type1 = f->type;
7556 type1.t |= (type->t & ~VT_TYPE);
7557 type = &type1;
7558 c += f->c;
7560 notfirst = 1;
7562 if (notfirst) {
7563 if (tok == '=') {
7564 next();
7565 } else {
7566 if (!gnu_ext)
7567 expect("=");
7569 } else {
7570 if (type->t & VT_ARRAY) {
7571 index = *cur_index;
7572 type = pointed_type(type);
7573 c += index * type_size(type, &align);
7574 } else {
7575 f = *cur_field;
7576 if (!f)
7577 error("too many field init");
7578 /* XXX: suppress this mess by using explicit storage field */
7579 type1 = f->type;
7580 type1.t |= (type->t & ~VT_TYPE);
7581 type = &type1;
7582 c += f->c;
7585 decl_initializer(type, sec, c, 0, size_only);
7587 /* XXX: make it more general */
7588 if (!size_only && nb_elems > 1) {
7589 unsigned long c_end;
7590 uint8_t *src, *dst;
7591 int i;
7593 if (!sec)
7594 error("range init not supported yet for dynamic storage");
7595 c_end = c + nb_elems * elem_size;
7596 if (c_end > sec->data_allocated)
7597 section_realloc(sec, c_end);
7598 src = sec->data + c;
7599 dst = src;
7600 for(i = 1; i < nb_elems; i++) {
7601 dst += elem_size;
7602 memcpy(dst, src, elem_size);
7607 #define EXPR_VAL 0
7608 #define EXPR_CONST 1
7609 #define EXPR_ANY 2
7611 /* store a value or an expression directly in global data or in local array */
7612 static void init_putv(CType *type, Section *sec, unsigned long c,
7613 int v, int expr_type)
7615 int saved_global_expr, bt, bit_pos, bit_size;
7616 void *ptr;
7617 unsigned long long bit_mask;
7619 switch(expr_type) {
7620 case EXPR_VAL:
7621 vpushi(v);
7622 break;
7623 case EXPR_CONST:
7624 /* compound literals must be allocated globally in this case */
7625 saved_global_expr = global_expr;
7626 global_expr = 1;
7627 expr_const1();
7628 global_expr = saved_global_expr;
7629 /* NOTE: symbols are accepted */
7630 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
7631 error("initializer element is not constant");
7632 break;
7633 case EXPR_ANY:
7634 expr_eq();
7635 break;
7638 if (sec) {
7639 /* XXX: not portable */
7640 /* XXX: generate error if incorrect relocation */
7641 gen_assign_cast(type);
7642 bt = type->t & VT_BTYPE;
7643 ptr = sec->data + c;
7644 /* XXX: make code faster ? */
7645 if (!(type->t & VT_BITFIELD)) {
7646 bit_pos = 0;
7647 bit_size = 32;
7648 bit_mask = -1LL;
7649 } else {
7650 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
7651 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
7652 bit_mask = (1LL << bit_size) - 1;
7654 if ((vtop->r & VT_SYM) &&
7655 (bt == VT_BYTE ||
7656 bt == VT_SHORT ||
7657 bt == VT_DOUBLE ||
7658 bt == VT_LDOUBLE ||
7659 bt == VT_LLONG ||
7660 (bt == VT_INT && bit_size != 32)))
7661 error("initializer element is not computable at load time");
7662 switch(bt) {
7663 case VT_BYTE:
7664 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7665 break;
7666 case VT_SHORT:
7667 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7668 break;
7669 case VT_DOUBLE:
7670 *(double *)ptr = vtop->c.d;
7671 break;
7672 case VT_LDOUBLE:
7673 *(long double *)ptr = vtop->c.ld;
7674 break;
7675 case VT_LLONG:
7676 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
7677 break;
7678 default:
7679 if (vtop->r & VT_SYM) {
7680 greloc(sec, vtop->sym, c, R_DATA_32);
7682 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7683 break;
7685 vtop--;
7686 } else {
7687 vset(type, VT_LOCAL, c);
7688 vswap();
7689 vstore();
7690 vpop();
7694 /* put zeros for variable based init */
7695 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
7697 GFuncContext gf;
7699 if (sec) {
7700 /* nothing to do because globals are already set to zero */
7701 } else {
7702 gfunc_start(&gf, FUNC_CDECL);
7703 vpushi(size);
7704 gfunc_param(&gf);
7705 vpushi(0);
7706 gfunc_param(&gf);
7707 vseti(VT_LOCAL, c);
7708 gfunc_param(&gf);
7709 vpush_global_sym(&func_old_type, TOK_memset);
7710 gfunc_call(&gf);
7714 /* 't' contains the type and storage info. 'c' is the offset of the
7715 object in section 'sec'. If 'sec' is NULL, it means stack based
7716 allocation. 'first' is true if array '{' must be read (multi
7717 dimension implicit array init handling). 'size_only' is true if
7718 size only evaluation is wanted (only for arrays). */
7719 static void decl_initializer(CType *type, Section *sec, unsigned long c,
7720 int first, int size_only)
7722 int index, array_length, n, no_oblock, nb, parlevel, i;
7723 int size1, align1, expr_type;
7724 Sym *s, *f;
7725 CType *t1;
7727 if (type->t & VT_ARRAY) {
7728 s = type->ref;
7729 n = s->c;
7730 array_length = 0;
7731 t1 = pointed_type(type);
7732 size1 = type_size(t1, &align1);
7734 no_oblock = 1;
7735 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
7736 tok == '{') {
7737 skip('{');
7738 no_oblock = 0;
7741 /* only parse strings here if correct type (otherwise: handle
7742 them as ((w)char *) expressions */
7743 if ((tok == TOK_LSTR &&
7744 (t1->t & VT_BTYPE) == VT_INT) ||
7745 (tok == TOK_STR &&
7746 (t1->t & VT_BTYPE) == VT_BYTE)) {
7747 while (tok == TOK_STR || tok == TOK_LSTR) {
7748 int cstr_len, ch;
7749 CString *cstr;
7751 cstr = tokc.cstr;
7752 /* compute maximum number of chars wanted */
7753 if (tok == TOK_STR)
7754 cstr_len = cstr->size;
7755 else
7756 cstr_len = cstr->size / sizeof(int);
7757 cstr_len--;
7758 nb = cstr_len;
7759 if (n >= 0 && nb > (n - array_length))
7760 nb = n - array_length;
7761 if (!size_only) {
7762 if (cstr_len > nb)
7763 warning("initializer-string for array is too long");
7764 /* in order to go faster for common case (char
7765 string in global variable, we handle it
7766 specifically */
7767 if (sec && tok == TOK_STR && size1 == 1) {
7768 memcpy(sec->data + c + array_length, cstr->data, nb);
7769 } else {
7770 for(i=0;i<nb;i++) {
7771 if (tok == TOK_STR)
7772 ch = ((unsigned char *)cstr->data)[i];
7773 else
7774 ch = ((int *)cstr->data)[i];
7775 init_putv(t1, sec, c + (array_length + i) * size1,
7776 ch, EXPR_VAL);
7780 array_length += nb;
7781 next();
7783 /* only add trailing zero if enough storage (no
7784 warning in this case since it is standard) */
7785 if (n < 0 || array_length < n) {
7786 if (!size_only) {
7787 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
7789 array_length++;
7791 } else {
7792 index = 0;
7793 while (tok != '}') {
7794 decl_designator(type, sec, c, &index, NULL, size_only);
7795 if (n >= 0 && index >= n)
7796 error("index too large");
7797 /* must put zero in holes (note that doing it that way
7798 ensures that it even works with designators) */
7799 if (!size_only && array_length < index) {
7800 init_putz(t1, sec, c + array_length * size1,
7801 (index - array_length) * size1);
7803 index++;
7804 if (index > array_length)
7805 array_length = index;
7806 /* special test for multi dimensional arrays (may not
7807 be strictly correct if designators are used at the
7808 same time) */
7809 if (index >= n && no_oblock)
7810 break;
7811 if (tok == '}')
7812 break;
7813 skip(',');
7816 if (!no_oblock)
7817 skip('}');
7818 /* put zeros at the end */
7819 if (!size_only && n >= 0 && array_length < n) {
7820 init_putz(t1, sec, c + array_length * size1,
7821 (n - array_length) * size1);
7823 /* patch type size if needed */
7824 if (n < 0)
7825 s->c = array_length;
7826 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
7827 (sec || !first || tok == '{')) {
7828 int par_count;
7830 /* NOTE: the previous test is a specific case for automatic
7831 struct/union init */
7832 /* XXX: union needs only one init */
7834 /* XXX: this test is incorrect for local initializers
7835 beginning with ( without {. It would be much more difficult
7836 to do it correctly (ideally, the expression parser should
7837 be used in all cases) */
7838 par_count = 0;
7839 if (tok == '(') {
7840 AttributeDef ad1;
7841 CType type1;
7842 next();
7843 while (tok == '(') {
7844 par_count++;
7845 next();
7847 if (!parse_btype(&type1, &ad1))
7848 expect("cast");
7849 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
7850 if (!is_compatible_types(type, &type1))
7851 error("invalid type for cast");
7852 skip(')');
7854 no_oblock = 1;
7855 if (first || tok == '{') {
7856 skip('{');
7857 no_oblock = 0;
7859 s = type->ref;
7860 f = s->next;
7861 array_length = 0;
7862 index = 0;
7863 n = s->c;
7864 while (tok != '}') {
7865 decl_designator(type, sec, c, NULL, &f, size_only);
7866 index = f->c;
7867 if (!size_only && array_length < index) {
7868 init_putz(type, sec, c + array_length,
7869 index - array_length);
7871 index = index + type_size(&f->type, &align1);
7872 if (index > array_length)
7873 array_length = index;
7874 f = f->next;
7875 if (no_oblock && f == NULL)
7876 break;
7877 if (tok == '}')
7878 break;
7879 skip(',');
7881 /* put zeros at the end */
7882 if (!size_only && array_length < n) {
7883 init_putz(type, sec, c + array_length,
7884 n - array_length);
7886 if (!no_oblock)
7887 skip('}');
7888 while (par_count) {
7889 skip(')');
7890 par_count--;
7892 } else if (tok == '{') {
7893 next();
7894 decl_initializer(type, sec, c, first, size_only);
7895 skip('}');
7896 } else if (size_only) {
7897 /* just skip expression */
7898 parlevel = 0;
7899 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
7900 tok != -1) {
7901 if (tok == '(')
7902 parlevel++;
7903 else if (tok == ')')
7904 parlevel--;
7905 next();
7907 } else {
7908 /* currently, we always use constant expression for globals
7909 (may change for scripting case) */
7910 expr_type = EXPR_CONST;
7911 if (!sec)
7912 expr_type = EXPR_ANY;
7913 init_putv(type, sec, c, 0, expr_type);
7917 /* parse an initializer for type 't' if 'has_init' is non zero, and
7918 allocate space in local or global data space ('r' is either
7919 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7920 variable 'v' of scope 'scope' is declared before initializers are
7921 parsed. If 'v' is zero, then a reference to the new object is put
7922 in the value stack. If 'has_init' is 2, a special parsing is done
7923 to handle string constants. */
7924 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
7925 int has_init, int v, int scope)
7927 int size, align, addr, data_offset;
7928 int level;
7929 ParseState saved_parse_state;
7930 TokenString init_str;
7931 Section *sec;
7933 size = type_size(type, &align);
7934 /* If unknown size, we must evaluate it before
7935 evaluating initializers because
7936 initializers can generate global data too
7937 (e.g. string pointers or ISOC99 compound
7938 literals). It also simplifies local
7939 initializers handling */
7940 tok_str_new(&init_str);
7941 if (size < 0) {
7942 if (!has_init)
7943 error("unknown type size");
7944 /* get all init string */
7945 if (has_init == 2) {
7946 /* only get strings */
7947 while (tok == TOK_STR || tok == TOK_LSTR) {
7948 tok_str_add_tok(&init_str);
7949 next();
7951 } else {
7952 level = 0;
7953 while (level > 0 || (tok != ',' && tok != ';')) {
7954 if (tok < 0)
7955 error("unexpected end of file in initializer");
7956 tok_str_add_tok(&init_str);
7957 if (tok == '{')
7958 level++;
7959 else if (tok == '}') {
7960 if (level == 0)
7961 break;
7962 level--;
7964 next();
7967 tok_str_add(&init_str, -1);
7968 tok_str_add(&init_str, 0);
7970 /* compute size */
7971 save_parse_state(&saved_parse_state);
7973 macro_ptr = init_str.str;
7974 next();
7975 decl_initializer(type, NULL, 0, 1, 1);
7976 /* prepare second initializer parsing */
7977 macro_ptr = init_str.str;
7978 next();
7980 /* if still unknown size, error */
7981 size = type_size(type, &align);
7982 if (size < 0)
7983 error("unknown type size");
7985 /* take into account specified alignment if bigger */
7986 if (ad->aligned > align)
7987 align = ad->aligned;
7988 if ((r & VT_VALMASK) == VT_LOCAL) {
7989 sec = NULL;
7990 if (do_bounds_check && (type->t & VT_ARRAY))
7991 loc--;
7992 loc = (loc - size) & -align;
7993 addr = loc;
7994 /* handles bounds */
7995 /* XXX: currently, since we do only one pass, we cannot track
7996 '&' operators, so we add only arrays */
7997 if (do_bounds_check && (type->t & VT_ARRAY)) {
7998 unsigned long *bounds_ptr;
7999 /* add padding between regions */
8000 loc--;
8001 /* then add local bound info */
8002 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
8003 bounds_ptr[0] = addr;
8004 bounds_ptr[1] = size;
8006 if (v) {
8007 /* local variable */
8008 sym_push(v, type, r, addr);
8009 } else {
8010 /* push local reference */
8011 vset(type, r, addr);
8013 } else {
8014 Sym *sym;
8016 sym = NULL;
8017 if (v && scope == VT_CONST) {
8018 /* see if the symbol was already defined */
8019 sym = sym_find(v);
8020 if (sym) {
8021 if (!is_compatible_types(&sym->type, type))
8022 error("incompatible types for redefinition of '%s'",
8023 get_tok_str(v, NULL));
8024 if (sym->type.t & VT_EXTERN) {
8025 /* if the variable is extern, it was not allocated */
8026 sym->type.t &= ~VT_EXTERN;
8027 } else {
8028 /* we accept several definitions of the same
8029 global variable. this is tricky, because we
8030 must play with the SHN_COMMON type of the symbol */
8031 /* XXX: should check if the variable was already
8032 initialized. It is incorrect to initialized it
8033 twice */
8034 /* no init data, we won't add more to the symbol */
8035 if (!has_init)
8036 goto no_alloc;
8041 /* allocate symbol in corresponding section */
8042 sec = ad->section;
8043 if (!sec) {
8044 if (has_init)
8045 sec = data_section;
8047 if (sec) {
8048 data_offset = sec->data_offset;
8049 data_offset = (data_offset + align - 1) & -align;
8050 addr = data_offset;
8051 /* very important to increment global pointer at this time
8052 because initializers themselves can create new initializers */
8053 data_offset += size;
8054 /* add padding if bound check */
8055 if (do_bounds_check)
8056 data_offset++;
8057 sec->data_offset = data_offset;
8058 /* allocate section space to put the data */
8059 if (sec->sh_type != SHT_NOBITS &&
8060 data_offset > sec->data_allocated)
8061 section_realloc(sec, data_offset);
8062 } else {
8063 addr = 0; /* avoid warning */
8066 if (v) {
8067 if (scope == VT_CONST) {
8068 if (!sym)
8069 goto do_def;
8070 } else {
8071 do_def:
8072 sym = sym_push(v, type, r | VT_SYM, 0);
8074 /* update symbol definition */
8075 if (sec) {
8076 put_extern_sym(sym, sec, addr, size);
8077 } else {
8078 Elf32_Sym *esym;
8079 /* put a common area */
8080 put_extern_sym(sym, NULL, align, size);
8081 /* XXX: find a nicer way */
8082 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
8083 esym->st_shndx = SHN_COMMON;
8085 } else {
8086 CValue cval;
8088 /* push global reference */
8089 sym = get_sym_ref(type, sec, addr, size);
8090 cval.ul = 0;
8091 vsetc(type, VT_CONST | VT_SYM, &cval);
8092 vtop->sym = sym;
8095 /* handles bounds now because the symbol must be defined
8096 before for the relocation */
8097 if (do_bounds_check) {
8098 unsigned long *bounds_ptr;
8100 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
8101 /* then add global bound info */
8102 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
8103 bounds_ptr[0] = 0; /* relocated */
8104 bounds_ptr[1] = size;
8107 if (has_init) {
8108 decl_initializer(type, sec, addr, 1, 0);
8109 /* restore parse state if needed */
8110 if (init_str.str) {
8111 tok_str_free(init_str.str);
8112 restore_parse_state(&saved_parse_state);
8115 no_alloc: ;
8118 void put_func_debug(Sym *sym)
8120 char buf[512];
8122 /* stabs info */
8123 /* XXX: we put here a dummy type */
8124 snprintf(buf, sizeof(buf), "%s:%c1",
8125 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
8126 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
8127 cur_text_section, sym->c);
8128 last_ind = 0;
8129 last_line_num = 0;
8132 /* not finished : try to put some local vars in registers */
8133 //#define CONFIG_REG_VARS
8135 #ifdef CONFIG_REG_VARS
8136 void add_var_ref(int t)
8138 printf("%s:%d: &%s\n",
8139 file->filename, file->line_num,
8140 get_tok_str(t, NULL));
8143 /* first pass on a function with heuristic to extract variable usage
8144 and pointer references to local variables for register allocation */
8145 void analyse_function(void)
8147 int level, t;
8149 for(;;) {
8150 if (tok == -1)
8151 break;
8152 /* any symbol coming after '&' is considered as being a
8153 variable whose reference is taken. It is highly unaccurate
8154 but it is difficult to do better without a complete parse */
8155 if (tok == '&') {
8156 next();
8157 /* if '& number', then no need to examine next tokens */
8158 if (tok == TOK_CINT ||
8159 tok == TOK_CUINT ||
8160 tok == TOK_CLLONG ||
8161 tok == TOK_CULLONG) {
8162 continue;
8163 } else if (tok >= TOK_UIDENT) {
8164 /* if '& ident [' or '& ident ->', then ident address
8165 is not needed */
8166 t = tok;
8167 next();
8168 if (tok != '[' && tok != TOK_ARROW)
8169 add_var_ref(t);
8170 } else {
8171 level = 0;
8172 while (tok != '}' && tok != ';' &&
8173 !((tok == ',' || tok == ')') && level == 0)) {
8174 if (tok >= TOK_UIDENT) {
8175 add_var_ref(tok);
8176 } else if (tok == '(') {
8177 level++;
8178 } else if (tok == ')') {
8179 level--;
8181 next();
8184 } else {
8185 next();
8189 #endif
8191 /* parse an old style function declaration list */
8192 /* XXX: check multiple parameter */
8193 static void func_decl_list(Sym *func_sym)
8195 AttributeDef ad;
8196 int v;
8197 Sym *s;
8198 CType btype, type;
8200 /* parse each declaration */
8201 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
8202 if (!parse_btype(&btype, &ad))
8203 expect("declaration list");
8204 if (((btype.t & VT_BTYPE) == VT_ENUM ||
8205 (btype.t & VT_BTYPE) == VT_STRUCT) &&
8206 tok == ';') {
8207 /* we accept no variable after */
8208 } else {
8209 for(;;) {
8210 type = btype;
8211 type_decl(&type, &ad, &v, TYPE_DIRECT);
8212 /* find parameter in function parameter list */
8213 s = func_sym->next;
8214 while (s != NULL) {
8215 if ((s->v & ~SYM_FIELD) == v)
8216 goto found;
8217 s = s->next;
8219 error("declaration for parameter '%s' but no such parameter",
8220 get_tok_str(v, NULL));
8221 found:
8222 /* check that no storage specifier except 'register' was given */
8223 if (type.t & VT_STORAGE)
8224 error("storage class specified for '%s'", get_tok_str(v, NULL));
8225 /* array must be transformed to pointer according to ANSI C */
8226 type.t &= ~VT_ARRAY;
8227 /* we can add the type (NOTE: it could be local to the function) */
8228 s->type = type;
8229 /* accept other parameters */
8230 if (tok == ',')
8231 next();
8232 else
8233 break;
8236 skip(';');
8240 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
8241 static void decl(int l)
8243 int v, has_init, r;
8244 CType type, btype;
8245 Sym *sym;
8246 AttributeDef ad;
8248 while (1) {
8249 if (!parse_btype(&btype, &ad)) {
8250 /* skip redundant ';' */
8251 /* XXX: find more elegant solution */
8252 if (tok == ';') {
8253 next();
8254 continue;
8256 /* special test for old K&R protos without explicit int
8257 type. Only accepted when defining global data */
8258 if (l == VT_LOCAL || tok < TOK_DEFINE)
8259 break;
8260 btype.t = VT_INT;
8262 if (((btype.t & VT_BTYPE) == VT_ENUM ||
8263 (btype.t & VT_BTYPE) == VT_STRUCT) &&
8264 tok == ';') {
8265 /* we accept no variable after */
8266 next();
8267 continue;
8269 while (1) { /* iterate thru each declaration */
8270 type = btype;
8271 type_decl(&type, &ad, &v, TYPE_DIRECT);
8272 #if 0
8274 char buf[500];
8275 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
8276 printf("type = '%s'\n", buf);
8278 #endif
8279 if ((type.t & VT_BTYPE) == VT_FUNC) {
8280 /* if old style function prototype, we accept a
8281 declaration list */
8282 sym = type.ref;
8283 if (sym->c == FUNC_OLD)
8284 func_decl_list(sym);
8287 if (tok == '{') {
8288 #ifdef CONFIG_REG_VARS
8289 TokenString func_str;
8290 ParseState saved_parse_state;
8291 int block_level;
8292 #endif
8294 if (l == VT_LOCAL)
8295 error("cannot use local functions");
8296 if (!(type.t & VT_FUNC))
8297 expect("function definition");
8298 /* XXX: cannot do better now: convert extern line to static inline */
8299 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
8300 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
8302 #ifdef CONFIG_REG_VARS
8303 /* parse all function code and record it */
8305 tok_str_new(&func_str);
8307 block_level = 0;
8308 for(;;) {
8309 int t;
8310 if (tok == -1)
8311 error("unexpected end of file");
8312 tok_str_add_tok(&func_str);
8313 t = tok;
8314 next();
8315 if (t == '{') {
8316 block_level++;
8317 } else if (t == '}') {
8318 block_level--;
8319 if (block_level == 0)
8320 break;
8323 tok_str_add(&func_str, -1);
8324 tok_str_add(&func_str, 0);
8326 save_parse_state(&saved_parse_state);
8328 macro_ptr = func_str.str;
8329 next();
8330 analyse_function();
8331 #endif
8333 /* compute text section */
8334 cur_text_section = ad.section;
8335 if (!cur_text_section)
8336 cur_text_section = text_section;
8337 ind = cur_text_section->data_offset;
8338 funcname = get_tok_str(v, NULL);
8339 sym = sym_find(v);
8340 if (sym) {
8341 /* if symbol is already defined, then put complete type */
8342 sym->type = type;
8343 } else {
8344 /* put function symbol */
8345 sym = global_identifier_push(v, type.t, 0);
8346 sym->type.ref = type.ref;
8348 /* NOTE: we patch the symbol size later */
8349 put_extern_sym(sym, cur_text_section, ind, 0);
8350 func_ind = ind;
8351 sym->r = VT_SYM | VT_CONST;
8352 /* put debug symbol */
8353 if (do_debug)
8354 put_func_debug(sym);
8355 /* push a dummy symbol to enable local sym storage */
8356 sym_push2(&local_stack, SYM_FIELD, 0, 0);
8357 gfunc_prolog(&type);
8358 loc = 0;
8359 rsym = 0;
8360 #ifdef CONFIG_REG_VARS
8361 macro_ptr = func_str.str;
8362 next();
8363 #endif
8364 block(NULL, NULL, NULL, NULL, 0, 0);
8365 gsym(rsym);
8366 gfunc_epilog();
8367 cur_text_section->data_offset = ind;
8368 label_pop(&global_label_stack, NULL);
8369 sym_pop(&local_stack, NULL); /* reset local stack */
8370 /* end of function */
8371 /* patch symbol size */
8372 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
8373 ind - func_ind;
8374 if (do_debug) {
8375 put_stabn(N_FUN, 0, 0, ind - func_ind);
8377 funcname = ""; /* for safety */
8378 func_vt.t = VT_VOID; /* for safety */
8379 ind = 0; /* for safety */
8381 #ifdef CONFIG_REG_VARS
8382 tok_str_free(func_str.str);
8383 restore_parse_state(&saved_parse_state);
8384 #endif
8385 break;
8386 } else {
8387 if (btype.t & VT_TYPEDEF) {
8388 /* save typedefed type */
8389 /* XXX: test storage specifiers ? */
8390 sym = sym_push(v, &type, 0, 0);
8391 sym->type.t |= VT_TYPEDEF;
8392 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
8393 /* external function definition */
8394 external_sym(v, &type, 0);
8395 } else {
8396 /* not lvalue if array */
8397 r = 0;
8398 if (!(type.t & VT_ARRAY))
8399 r |= lvalue_type(type.t);
8400 has_init = (tok == '=');
8401 if ((btype.t & VT_EXTERN) ||
8402 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
8403 !has_init && l == VT_CONST && type.ref->c < 0)) {
8404 /* external variable */
8405 /* NOTE: as GCC, uninitialized global static
8406 arrays of null size are considered as
8407 extern */
8408 external_sym(v, &type, r);
8409 } else {
8410 if (type.t & VT_STATIC)
8411 r |= VT_CONST;
8412 else
8413 r |= l;
8414 if (has_init)
8415 next();
8416 decl_initializer_alloc(&type, &ad, r,
8417 has_init, v, l);
8420 if (tok != ',') {
8421 skip(';');
8422 break;
8424 next();
8430 /* better than nothing, but needs extension to handle '-E' option
8431 correctly too */
8432 static void preprocess_init(TCCState *s1)
8434 s1->include_stack_ptr = s1->include_stack;
8435 /* XXX: move that before to avoid having to initialize
8436 file->ifdef_stack_ptr ? */
8437 s1->ifdef_stack_ptr = s1->ifdef_stack;
8438 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
8440 /* XXX: not ANSI compliant: bound checking says error */
8441 vtop = vstack - 1;
8444 /* compile the C file opened in 'file'. Return non zero if errors. */
8445 static int tcc_compile(TCCState *s1)
8447 Sym *define_start;
8448 char buf[512];
8449 volatile int section_sym;
8451 #ifdef INC_DEBUG
8452 printf("%s: **** new file\n", file->filename);
8453 #endif
8454 preprocess_init(s1);
8456 funcname = "";
8457 anon_sym = SYM_FIRST_ANOM;
8459 /* file info: full path + filename */
8460 section_sym = 0; /* avoid warning */
8461 if (do_debug) {
8462 section_sym = put_elf_sym(symtab_section, 0, 0,
8463 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
8464 text_section->sh_num, NULL);
8465 getcwd(buf, sizeof(buf));
8466 pstrcat(buf, sizeof(buf), "/");
8467 put_stabs_r(buf, N_SO, 0, 0,
8468 text_section->data_offset, text_section, section_sym);
8469 put_stabs_r(file->filename, N_SO, 0, 0,
8470 text_section->data_offset, text_section, section_sym);
8472 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8473 symbols can be safely used */
8474 put_elf_sym(symtab_section, 0, 0,
8475 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
8476 SHN_ABS, file->filename);
8478 /* define some often used types */
8479 int_type.t = VT_INT;
8481 char_pointer_type.t = VT_BYTE;
8482 mk_pointer(&char_pointer_type);
8484 func_old_type.t = VT_FUNC;
8485 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
8487 #if 0
8488 /* define 'void *alloca(unsigned int)' builtin function */
8490 Sym *s1;
8492 p = anon_sym++;
8493 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
8494 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
8495 s1->next = NULL;
8496 sym->next = s1;
8497 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
8499 #endif
8501 define_start = define_stack;
8503 if (setjmp(s1->error_jmp_buf) == 0) {
8504 s1->nb_errors = 0;
8505 s1->error_set_jmp_enabled = 1;
8507 ch = file->buf_ptr[0];
8508 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
8509 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
8510 next();
8511 decl(VT_CONST);
8512 if (tok != -1)
8513 expect("declaration");
8515 /* end of translation unit info */
8516 if (do_debug) {
8517 put_stabs_r(NULL, N_SO, 0, 0,
8518 text_section->data_offset, text_section, section_sym);
8521 s1->error_set_jmp_enabled = 0;
8523 /* reset define stack, but leave -Dsymbols (may be incorrect if
8524 they are undefined) */
8525 free_defines(define_start);
8527 sym_pop(&global_stack, NULL);
8529 return s1->nb_errors != 0 ? -1 : 0;
8532 #ifdef LIBTCC
8533 int tcc_compile_string(TCCState *s, const char *str)
8535 BufferedFile bf1, *bf = &bf1;
8536 int ret, len;
8537 char *buf;
8539 /* init file structure */
8540 bf->fd = -1;
8541 /* XXX: avoid copying */
8542 len = strlen(str);
8543 buf = tcc_malloc(len + 1);
8544 if (!buf)
8545 return -1;
8546 memcpy(buf, str, len);
8547 buf[len] = CH_EOB;
8548 bf->buf_ptr = buf;
8549 bf->buf_end = buf + len;
8550 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
8551 bf->line_num = 1;
8552 file = bf;
8554 ret = tcc_compile(s);
8556 tcc_free(buf);
8558 /* currently, no need to close */
8559 return ret;
8561 #endif
8563 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8564 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
8566 BufferedFile bf1, *bf = &bf1;
8568 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
8569 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
8570 /* default value */
8571 if (!value)
8572 value = "1";
8573 pstrcat(bf->buffer, IO_BUF_SIZE, value);
8575 /* init file structure */
8576 bf->fd = -1;
8577 bf->buf_ptr = bf->buffer;
8578 bf->buf_end = bf->buffer + strlen(bf->buffer);
8579 *bf->buf_end = CH_EOB;
8580 bf->filename[0] = '\0';
8581 bf->line_num = 1;
8582 file = bf;
8584 s1->include_stack_ptr = s1->include_stack;
8586 /* parse with define parser */
8587 ch = file->buf_ptr[0];
8588 next_nomacro();
8589 parse_define();
8590 file = NULL;
8593 /* undefine a preprocessor symbol */
8594 void tcc_undefine_symbol(TCCState *s1, const char *sym)
8596 TokenSym *ts;
8597 Sym *s;
8598 ts = tok_alloc(sym, strlen(sym));
8599 s = define_find(ts->tok);
8600 /* undefine symbol by putting an invalid name */
8601 if (s)
8602 define_undef(s);
8605 #ifdef CONFIG_TCC_ASM
8607 #include "i386-asm.c"
8608 #include "tccasm.c"
8610 #else
8611 static void asm_instr(void)
8613 error("inline asm() not supported");
8615 #endif
8617 #include "tccelf.c"
8619 /* print the position in the source file of PC value 'pc' by reading
8620 the stabs debug information */
8621 static void rt_printline(unsigned long wanted_pc)
8623 Stab_Sym *sym, *sym_end;
8624 char func_name[128], last_func_name[128];
8625 unsigned long func_addr, last_pc, pc;
8626 const char *incl_files[INCLUDE_STACK_SIZE];
8627 int incl_index, len, last_line_num, i;
8628 const char *str, *p;
8630 fprintf(stderr, "0x%08lx:", wanted_pc);
8632 func_name[0] = '\0';
8633 func_addr = 0;
8634 incl_index = 0;
8635 last_func_name[0] = '\0';
8636 last_pc = 0xffffffff;
8637 last_line_num = 1;
8638 sym = (Stab_Sym *)stab_section->data + 1;
8639 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
8640 while (sym < sym_end) {
8641 switch(sym->n_type) {
8642 /* function start or end */
8643 case N_FUN:
8644 if (sym->n_strx == 0) {
8645 /* we test if between last line and end of function */
8646 pc = sym->n_value + func_addr;
8647 if (wanted_pc >= last_pc && wanted_pc < pc)
8648 goto found;
8649 func_name[0] = '\0';
8650 func_addr = 0;
8651 } else {
8652 str = stabstr_section->data + sym->n_strx;
8653 p = strchr(str, ':');
8654 if (!p) {
8655 pstrcpy(func_name, sizeof(func_name), str);
8656 } else {
8657 len = p - str;
8658 if (len > sizeof(func_name) - 1)
8659 len = sizeof(func_name) - 1;
8660 memcpy(func_name, str, len);
8661 func_name[len] = '\0';
8663 func_addr = sym->n_value;
8665 break;
8666 /* line number info */
8667 case N_SLINE:
8668 pc = sym->n_value + func_addr;
8669 if (wanted_pc >= last_pc && wanted_pc < pc)
8670 goto found;
8671 last_pc = pc;
8672 last_line_num = sym->n_desc;
8673 /* XXX: slow! */
8674 strcpy(last_func_name, func_name);
8675 break;
8676 /* include files */
8677 case N_BINCL:
8678 str = stabstr_section->data + sym->n_strx;
8679 add_incl:
8680 if (incl_index < INCLUDE_STACK_SIZE) {
8681 incl_files[incl_index++] = str;
8683 break;
8684 case N_EINCL:
8685 if (incl_index > 1)
8686 incl_index--;
8687 break;
8688 case N_SO:
8689 if (sym->n_strx == 0) {
8690 incl_index = 0; /* end of translation unit */
8691 } else {
8692 str = stabstr_section->data + sym->n_strx;
8693 /* do not add path */
8694 len = strlen(str);
8695 if (len > 0 && str[len - 1] != '/')
8696 goto add_incl;
8698 break;
8700 sym++;
8703 /* second pass: we try symtab symbols (no line number info) */
8704 incl_index = 0;
8706 Elf32_Sym *sym, *sym_end;
8707 int type;
8709 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
8710 for(sym = (Elf32_Sym *)symtab_section->data + 1;
8711 sym < sym_end;
8712 sym++) {
8713 type = ELF32_ST_TYPE(sym->st_info);
8714 if (type == STT_FUNC) {
8715 if (wanted_pc >= sym->st_value &&
8716 wanted_pc < sym->st_value + sym->st_size) {
8717 pstrcpy(last_func_name, sizeof(last_func_name),
8718 strtab_section->data + sym->st_name);
8719 goto found;
8724 /* did not find any info: */
8725 fprintf(stderr, " ???\n");
8726 return;
8727 found:
8728 if (last_func_name[0] != '\0') {
8729 fprintf(stderr, " %s()", last_func_name);
8731 if (incl_index > 0) {
8732 fprintf(stderr, " (%s:%d",
8733 incl_files[incl_index - 1], last_line_num);
8734 for(i = incl_index - 2; i >= 0; i--)
8735 fprintf(stderr, ", included from %s", incl_files[i]);
8736 fprintf(stderr, ")");
8738 fprintf(stderr, "\n");
8741 #ifndef WIN32
8743 #ifdef __i386__
8745 /* fix for glibc 2.1 */
8746 #ifndef REG_EIP
8747 #define REG_EIP EIP
8748 #define REG_EBP EBP
8749 #endif
8751 /* return the PC at frame level 'level'. Return non zero if not found */
8752 static int rt_get_caller_pc(unsigned long *paddr,
8753 ucontext_t *uc, int level)
8755 unsigned long fp;
8756 int i;
8758 if (level == 0) {
8759 #ifdef __FreeBSD__
8760 *paddr = uc->uc_mcontext.mc_eip;
8761 #else
8762 *paddr = uc->uc_mcontext.gregs[REG_EIP];
8763 #endif
8764 return 0;
8765 } else {
8766 #ifdef __FreeBSD__
8767 fp = uc->uc_mcontext.mc_ebp;
8768 #else
8769 fp = uc->uc_mcontext.gregs[REG_EBP];
8770 #endif
8771 for(i=1;i<level;i++) {
8772 /* XXX: check address validity with program info */
8773 if (fp <= 0x1000 || fp >= 0xc0000000)
8774 return -1;
8775 fp = ((unsigned long *)fp)[0];
8777 *paddr = ((unsigned long *)fp)[1];
8778 return 0;
8781 #else
8782 #error add arch specific rt_get_caller_pc()
8783 #endif
8785 /* emit a run time error at position 'pc' */
8786 void rt_error(ucontext_t *uc, const char *fmt, ...)
8788 va_list ap;
8789 unsigned long pc;
8790 int i;
8792 va_start(ap, fmt);
8793 fprintf(stderr, "Runtime error: ");
8794 vfprintf(stderr, fmt, ap);
8795 fprintf(stderr, "\n");
8796 for(i=0;i<num_callers;i++) {
8797 if (rt_get_caller_pc(&pc, uc, i) < 0)
8798 break;
8799 if (i == 0)
8800 fprintf(stderr, "at ");
8801 else
8802 fprintf(stderr, "by ");
8803 rt_printline(pc);
8805 exit(255);
8806 va_end(ap);
8809 /* signal handler for fatal errors */
8810 static void sig_error(int signum, siginfo_t *siginf, void *puc)
8812 ucontext_t *uc = puc;
8814 switch(signum) {
8815 case SIGFPE:
8816 switch(siginf->si_code) {
8817 case FPE_INTDIV:
8818 case FPE_FLTDIV:
8819 rt_error(uc, "division by zero");
8820 break;
8821 default:
8822 rt_error(uc, "floating point exception");
8823 break;
8825 break;
8826 case SIGBUS:
8827 case SIGSEGV:
8828 if (rt_bound_error_msg && *rt_bound_error_msg)
8829 rt_error(uc, *rt_bound_error_msg);
8830 else
8831 rt_error(uc, "dereferencing invalid pointer");
8832 break;
8833 case SIGILL:
8834 rt_error(uc, "illegal instruction");
8835 break;
8836 case SIGABRT:
8837 rt_error(uc, "abort() called");
8838 break;
8839 default:
8840 rt_error(uc, "caught signal %d", signum);
8841 break;
8843 exit(255);
8845 #endif
8847 /* do all relocations (needed before using tcc_get_symbol()) */
8848 int tcc_relocate(TCCState *s1)
8850 Section *s;
8851 int i;
8853 s1->nb_errors = 0;
8855 tcc_add_runtime(s1);
8857 relocate_common_syms();
8859 /* compute relocation address : section are relocated in place. We
8860 also alloc the bss space */
8861 for(i = 1; i < s1->nb_sections; i++) {
8862 s = s1->sections[i];
8863 if (s->sh_flags & SHF_ALLOC) {
8864 if (s->sh_type == SHT_NOBITS)
8865 s->data = tcc_mallocz(s->data_offset);
8866 s->sh_addr = (unsigned long)s->data;
8870 relocate_syms(s1, 1);
8872 if (s1->nb_errors != 0)
8873 return -1;
8875 /* relocate each section */
8876 for(i = 1; i < s1->nb_sections; i++) {
8877 s = s1->sections[i];
8878 if (s->reloc)
8879 relocate_section(s1, s);
8881 return 0;
8884 /* launch the compiled program with the given arguments */
8885 int tcc_run(TCCState *s1, int argc, char **argv)
8887 int (*prog_main)(int, char **);
8889 if (tcc_relocate(s1) < 0)
8890 return -1;
8892 prog_main = tcc_get_symbol(s1, "main");
8894 if (do_debug) {
8895 #ifdef WIN32
8896 error("debug mode currently not available for Windows");
8897 #else
8898 struct sigaction sigact;
8899 /* install TCC signal handlers to print debug info on fatal
8900 runtime errors */
8901 sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
8902 sigact.sa_sigaction = sig_error;
8903 sigemptyset(&sigact.sa_mask);
8904 sigaction(SIGFPE, &sigact, NULL);
8905 sigaction(SIGILL, &sigact, NULL);
8906 sigaction(SIGSEGV, &sigact, NULL);
8907 sigaction(SIGBUS, &sigact, NULL);
8908 sigaction(SIGABRT, &sigact, NULL);
8909 #endif
8912 #ifdef CONFIG_TCC_BCHECK
8913 if (do_bounds_check) {
8914 void (*bound_init)(void);
8916 /* set error function */
8917 rt_bound_error_msg = (void *)tcc_get_symbol(s1, "__bound_error_msg");
8919 /* XXX: use .init section so that it also work in binary ? */
8920 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
8921 bound_init();
8923 #endif
8924 return (*prog_main)(argc, argv);
8927 TCCState *tcc_new(void)
8929 const char *p, *r;
8930 TCCState *s;
8931 TokenSym *ts;
8932 int i, c;
8934 s = tcc_mallocz(sizeof(TCCState));
8935 if (!s)
8936 return NULL;
8937 tcc_state = s;
8938 s->output_type = TCC_OUTPUT_MEMORY;
8940 /* init isid table */
8941 for(i=0;i<256;i++)
8942 isidnum_table[i] = isid(i) || isnum(i);
8944 /* add all tokens */
8945 table_ident = NULL;
8946 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
8948 tok_ident = TOK_IDENT;
8949 p = tcc_keywords;
8950 while (*p) {
8951 r = p;
8952 for(;;) {
8953 c = *r++;
8954 if (c == '\0')
8955 break;
8957 ts = tok_alloc(p, r - p - 1);
8958 p = r;
8961 /* we add dummy defines for some special macros to speed up tests
8962 and to have working defined() */
8963 define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
8964 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
8965 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
8966 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
8968 /* standard defines */
8969 tcc_define_symbol(s, "__STDC__", NULL);
8970 #if defined(TCC_TARGET_I386)
8971 tcc_define_symbol(s, "__i386__", NULL);
8972 #endif
8973 #if defined(linux)
8974 tcc_define_symbol(s, "__linux__", NULL);
8975 tcc_define_symbol(s, "linux", NULL);
8976 #endif
8977 /* tiny C specific defines */
8978 tcc_define_symbol(s, "__TINYC__", NULL);
8980 /* tiny C & gcc defines */
8981 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
8982 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
8983 tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
8985 /* default library paths */
8986 tcc_add_library_path(s, "/usr/local/lib");
8987 tcc_add_library_path(s, "/usr/lib");
8988 tcc_add_library_path(s, "/lib");
8990 /* no section zero */
8991 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
8993 /* create standard sections */
8994 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
8995 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
8996 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
8998 /* symbols are always generated for linking stage */
8999 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
9000 ".strtab",
9001 ".hashtab", SHF_PRIVATE);
9002 strtab_section = symtab_section->link;
9004 /* private symbol table for dynamic symbols */
9005 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
9006 ".dynstrtab",
9007 ".dynhashtab", SHF_PRIVATE);
9008 return s;
9011 void tcc_delete(TCCState *s1)
9013 int i, n;
9015 /* free -D defines */
9016 free_defines(NULL);
9018 /* free tokens */
9019 n = tok_ident - TOK_IDENT;
9020 for(i = 0; i < n; i++)
9021 tcc_free(table_ident[i]);
9022 tcc_free(table_ident);
9024 /* free all sections */
9026 free_section(symtab_section->hash);
9028 free_section(s1->dynsymtab_section->hash);
9029 free_section(s1->dynsymtab_section->link);
9030 free_section(s1->dynsymtab_section);
9032 for(i = 1; i < s1->nb_sections; i++)
9033 free_section(s1->sections[i]);
9034 tcc_free(s1->sections);
9036 /* free loaded dlls array */
9037 for(i = 0; i < s1->nb_loaded_dlls; i++)
9038 tcc_free(s1->loaded_dlls[i]);
9039 tcc_free(s1->loaded_dlls);
9041 /* library paths */
9042 for(i = 0; i < s1->nb_library_paths; i++)
9043 tcc_free(s1->library_paths[i]);
9044 tcc_free(s1->library_paths);
9046 /* cached includes */
9047 for(i = 0; i < s1->nb_cached_includes; i++)
9048 tcc_free(s1->cached_includes[i]);
9049 tcc_free(s1->cached_includes);
9051 for(i = 0; i < s1->nb_include_paths; i++)
9052 tcc_free(s1->include_paths[i]);
9053 tcc_free(s1->include_paths);
9055 for(i = 0; i < s1->nb_sysinclude_paths; i++)
9056 tcc_free(s1->sysinclude_paths[i]);
9057 tcc_free(s1->sysinclude_paths);
9059 tcc_free(s1);
9062 int tcc_add_include_path(TCCState *s1, const char *pathname)
9064 char *pathname1;
9066 pathname1 = tcc_strdup(pathname);
9067 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
9068 return 0;
9071 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
9073 char *pathname1;
9075 pathname1 = tcc_strdup(pathname);
9076 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
9077 return 0;
9080 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
9082 const char *ext, *filename1;
9083 Elf32_Ehdr ehdr;
9084 int fd, ret;
9085 BufferedFile *saved_file;
9087 /* find source file type with extension */
9088 filename1 = strrchr(filename, '/');
9089 if (filename1)
9090 filename1++;
9091 else
9092 filename1 = filename;
9093 ext = strrchr(filename1, '.');
9094 if (ext)
9095 ext++;
9097 /* open the file */
9098 saved_file = file;
9099 file = tcc_open(s1, filename);
9100 if (!file) {
9101 if (flags & AFF_PRINT_ERROR) {
9102 error_noabort("file '%s' not found", filename);
9104 ret = -1;
9105 goto fail1;
9108 if (!ext || !strcmp(ext, "c")) {
9109 /* C file assumed */
9110 ret = tcc_compile(s1);
9111 } else
9112 #ifdef CONFIG_TCC_ASM
9113 if (!strcmp(ext, "S")) {
9114 /* preprocessed assembler */
9115 ret = tcc_assemble(s1, 1);
9116 } else if (!strcmp(ext, "s")) {
9117 /* non preprocessed assembler */
9118 ret = tcc_assemble(s1, 0);
9119 } else
9120 #endif
9122 fd = file->fd;
9123 /* assume executable format: auto guess file type */
9124 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
9125 error_noabort("could not read header");
9126 goto fail;
9128 lseek(fd, 0, SEEK_SET);
9130 if (ehdr.e_ident[0] == ELFMAG0 &&
9131 ehdr.e_ident[1] == ELFMAG1 &&
9132 ehdr.e_ident[2] == ELFMAG2 &&
9133 ehdr.e_ident[3] == ELFMAG3) {
9134 file->line_num = 0; /* do not display line number if error */
9135 if (ehdr.e_type == ET_REL) {
9136 ret = tcc_load_object_file(s1, fd, 0);
9137 } else if (ehdr.e_type == ET_DYN) {
9138 ret = tcc_load_dll(s1, fd, filename,
9139 (flags & AFF_REFERENCED_DLL) != 0);
9140 } else {
9141 error_noabort("unrecognized ELF file");
9142 goto fail;
9144 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
9145 file->line_num = 0; /* do not display line number if error */
9146 ret = tcc_load_archive(s1, fd);
9147 } else {
9148 /* as GNU ld, consider it is an ld script if not recognized */
9149 ret = tcc_load_ldscript(s1);
9150 if (ret < 0) {
9151 error_noabort("unrecognized file type");
9152 goto fail;
9156 the_end:
9157 tcc_close(file);
9158 fail1:
9159 file = saved_file;
9160 return ret;
9161 fail:
9162 ret = -1;
9163 goto the_end;
9166 int tcc_add_file(TCCState *s, const char *filename)
9168 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
9171 int tcc_add_library_path(TCCState *s, const char *pathname)
9173 char *pathname1;
9175 pathname1 = tcc_strdup(pathname);
9176 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
9177 return 0;
9180 /* find and load a dll. Return non zero if not found */
9181 /* XXX: add '-rpath' option support ? */
9182 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
9184 char buf[1024];
9185 int i;
9187 for(i = 0; i < s->nb_library_paths; i++) {
9188 snprintf(buf, sizeof(buf), "%s/%s",
9189 s->library_paths[i], filename);
9190 if (tcc_add_file_internal(s, buf, flags) == 0)
9191 return 0;
9193 return -1;
9196 /* the library name is the same as the argument of the '-l' option */
9197 int tcc_add_library(TCCState *s, const char *libraryname)
9199 char buf[1024];
9200 int i;
9201 void *h;
9203 /* first we look for the dynamic library if not static linking */
9204 if (!s->static_link) {
9205 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
9206 /* if we output to memory, then we simply we dlopen(). */
9207 if (s->output_type == TCC_OUTPUT_MEMORY) {
9208 /* Since the libc is already loaded, we don't need to load it again */
9209 if (!strcmp(libraryname, "c"))
9210 return 0;
9211 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
9212 if (h)
9213 return 0;
9214 } else {
9215 if (tcc_add_dll(s, buf, 0) == 0)
9216 return 0;
9220 /* then we look for the static library */
9221 for(i = 0; i < s->nb_library_paths; i++) {
9222 snprintf(buf, sizeof(buf), "%s/lib%s.a",
9223 s->library_paths[i], libraryname);
9224 if (tcc_add_file_internal(s, buf, 0) == 0)
9225 return 0;
9227 return -1;
9230 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
9232 add_elf_sym(symtab_section, val, 0,
9233 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
9234 SHN_ABS, name);
9235 return 0;
9238 int tcc_set_output_type(TCCState *s, int output_type)
9240 char buf[1024];
9242 s->output_type = output_type;
9244 if (!s->nostdinc) {
9245 /* default include paths */
9246 /* XXX: reverse order needed if -isystem support */
9247 tcc_add_sysinclude_path(s, "/usr/local/include");
9248 tcc_add_sysinclude_path(s, "/usr/include");
9249 snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path);
9250 tcc_add_sysinclude_path(s, buf);
9253 /* if bound checking, then add corresponding sections */
9254 #ifdef CONFIG_TCC_BCHECK
9255 if (do_bounds_check) {
9256 /* define symbol */
9257 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
9258 /* create bounds sections */
9259 bounds_section = new_section(s, ".bounds",
9260 SHT_PROGBITS, SHF_ALLOC);
9261 lbounds_section = new_section(s, ".lbounds",
9262 SHT_PROGBITS, SHF_ALLOC);
9264 #endif
9266 /* add debug sections */
9267 if (do_debug) {
9268 /* stab symbols */
9269 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
9270 stab_section->sh_entsize = sizeof(Stab_Sym);
9271 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
9272 put_elf_str(stabstr_section, "");
9273 stab_section->link = stabstr_section;
9274 /* put first entry */
9275 put_stabs("", 0, 0, 0, 0);
9278 /* add libc crt1/crti objects */
9279 if (output_type == TCC_OUTPUT_EXE ||
9280 output_type == TCC_OUTPUT_DLL) {
9281 if (output_type != TCC_OUTPUT_DLL)
9282 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
9283 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
9285 return 0;
9288 #if !defined(LIBTCC)
9290 static int64_t getclock_us(void)
9292 #ifdef WIN32
9293 struct _timeb tb;
9294 _ftime(&tb);
9295 return (tb.time * 1000LL + tb.millitm) * 1000LL;
9296 #else
9297 struct timeval tv;
9298 gettimeofday(&tv, NULL);
9299 return tv.tv_sec * 1000000LL + tv.tv_usec;
9300 #endif
9303 void help(void)
9305 printf("tcc version 0.9.16 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
9306 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
9307 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
9308 " [--] infile1 [infile2... --] [infile_args...]\n"
9309 "\n"
9310 "General options:\n"
9311 " -c compile only - generate an object file\n"
9312 " -o outfile set output filename\n"
9313 " -- allows multiples input files if no -o option given. Also\n"
9314 " separate input files from runtime arguments\n"
9315 " -Bdir set tcc internal library path\n"
9316 " -bench output compilation statistics\n"
9317 "Preprocessor options:\n"
9318 " -Idir add include path 'dir'\n"
9319 " -Dsym[=val] define 'sym' with value 'val'\n"
9320 " -Usym undefine 'sym'\n"
9321 "Linker options:\n"
9322 " -Ldir add library path 'dir'\n"
9323 " -llib link with dynamic or static library 'lib'\n"
9324 " -shared generate a shared library\n"
9325 " -static static linking\n"
9326 " -r relocatable output\n"
9327 "Debugger options:\n"
9328 " -g generate runtime debug info\n"
9329 #ifdef CONFIG_TCC_BCHECK
9330 " -b compile with built-in memory and bounds checker (implies -g)\n"
9331 #endif
9332 " -bt N show N callers in stack traces\n"
9336 #define TCC_OPTION_HAS_ARG 0x0001
9337 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
9339 typedef struct TCCOption {
9340 const char *name;
9341 uint16_t index;
9342 uint16_t flags;
9343 } TCCOption;
9345 enum {
9346 TCC_OPTION_HELP,
9347 TCC_OPTION_MARKER,
9348 TCC_OPTION_I,
9349 TCC_OPTION_D,
9350 TCC_OPTION_U,
9351 TCC_OPTION_L,
9352 TCC_OPTION_B,
9353 TCC_OPTION_l,
9354 TCC_OPTION_bench,
9355 TCC_OPTION_bt,
9356 TCC_OPTION_b,
9357 TCC_OPTION_g,
9358 TCC_OPTION_c,
9359 TCC_OPTION_static,
9360 TCC_OPTION_shared,
9361 TCC_OPTION_o,
9362 TCC_OPTION_r,
9363 TCC_OPTION_W,
9364 TCC_OPTION_O,
9365 TCC_OPTION_m,
9366 TCC_OPTION_f,
9367 TCC_OPTION_nostdinc,
9368 TCC_OPTION_print_search_dirs,
9369 TCC_OPTION_rdynamic,
9372 static const TCCOption tcc_options[] = {
9373 { "h", TCC_OPTION_HELP, 0 },
9374 { "?", TCC_OPTION_HELP, 0 },
9375 { "-", TCC_OPTION_MARKER, 0 },
9376 { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
9377 { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
9378 { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
9379 { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
9380 { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
9381 { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9382 { "bench", TCC_OPTION_bench, 0 },
9383 { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
9384 #ifdef CONFIG_TCC_BCHECK
9385 { "b", TCC_OPTION_b, 0 },
9386 #endif
9387 { "g", TCC_OPTION_g, 0 },
9388 { "c", TCC_OPTION_c, 0 },
9389 { "static", TCC_OPTION_static, 0 },
9390 { "shared", TCC_OPTION_shared, 0 },
9391 { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
9392 { "rdynamic", TCC_OPTION_rdynamic, 0 }, /* currently ignored */
9393 { "r", TCC_OPTION_r, 0 },
9394 { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9395 { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9396 { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
9397 { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9398 { "nostdinc", TCC_OPTION_nostdinc, 0 },
9399 { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
9400 { NULL },
9403 int main(int argc, char **argv)
9405 char *r;
9406 int optind, output_type, multiple_files, i, reloc_output;
9407 TCCState *s;
9408 char **files;
9409 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
9410 char objfilename[1024];
9411 int64_t start_time = 0;
9412 const TCCOption *popt;
9413 const char *optarg, *p1, *r1, *outfile;
9414 int print_search_dirs;
9416 s = tcc_new();
9417 output_type = TCC_OUTPUT_MEMORY;
9419 optind = 1;
9420 outfile = NULL;
9421 multiple_files = 0;
9422 dminus = 0;
9423 files = NULL;
9424 nb_files = 0;
9425 nb_libraries = 0;
9426 reloc_output = 0;
9427 print_search_dirs = 0;
9428 while (1) {
9429 if (optind >= argc) {
9430 if (nb_files == 0 && !print_search_dirs)
9431 goto show_help;
9432 else
9433 break;
9435 r = argv[optind++];
9436 if (r[0] != '-') {
9437 /* add a new file */
9438 dynarray_add((void ***)&files, &nb_files, r);
9439 if (!multiple_files) {
9440 optind--;
9441 /* argv[0] will be this file */
9442 break;
9444 } else {
9445 /* find option in table (match only the first chars */
9446 popt = tcc_options;
9447 for(;;) {
9448 p1 = popt->name;
9449 if (p1 == NULL)
9450 error("invalid option -- '%s'", r);
9451 r1 = r + 1;
9452 for(;;) {
9453 if (*p1 == '\0')
9454 goto option_found;
9455 if (*r1 != *p1)
9456 break;
9457 p1++;
9458 r1++;
9460 popt++;
9462 option_found:
9463 if (popt->flags & TCC_OPTION_HAS_ARG) {
9464 if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) {
9465 optarg = r1;
9466 } else {
9467 if (optind >= argc)
9468 error("argument to '%s' is missing", r);
9469 optarg = argv[optind++];
9471 } else {
9472 if (*r1 != '\0')
9473 goto show_help;
9474 optarg = NULL;
9477 switch(popt->index) {
9478 case TCC_OPTION_HELP:
9479 show_help:
9480 help();
9481 return 1;
9482 case TCC_OPTION_MARKER:
9483 /* '--' enables multiple files input and also ends several
9484 file input */
9485 if (dminus && multiple_files) {
9486 optind--; /* argv[0] will be '--' */
9487 goto end_parse;
9489 dminus = 1;
9490 multiple_files = 1;
9491 case TCC_OPTION_I:
9492 if (tcc_add_include_path(s, optarg) < 0)
9493 error("too many include paths");
9494 break;
9495 case TCC_OPTION_D:
9497 char *sym, *value;
9498 sym = (char *)optarg;
9499 value = strchr(sym, '=');
9500 if (value) {
9501 *value = '\0';
9502 value++;
9504 tcc_define_symbol(s, sym, value);
9506 break;
9507 case TCC_OPTION_U:
9508 tcc_undefine_symbol(s, optarg);
9509 break;
9510 case TCC_OPTION_L:
9511 tcc_add_library_path(s, optarg);
9512 break;
9513 case TCC_OPTION_B:
9514 /* set tcc utilities path (mainly for tcc development) */
9515 tcc_lib_path = optarg;
9516 break;
9517 case TCC_OPTION_l:
9518 dynarray_add((void ***)&files, &nb_files, r);
9519 nb_libraries++;
9520 break;
9521 case TCC_OPTION_bench:
9522 do_bench = 1;
9523 break;
9524 case TCC_OPTION_bt:
9525 num_callers = atoi(optarg);
9526 break;
9527 #ifdef CONFIG_TCC_BCHECK
9528 case TCC_OPTION_b:
9529 do_bounds_check = 1;
9530 do_debug = 1;
9531 break;
9532 #endif
9533 case TCC_OPTION_g:
9534 do_debug = 1;
9535 break;
9536 case TCC_OPTION_c:
9537 multiple_files = 1;
9538 output_type = TCC_OUTPUT_OBJ;
9539 break;
9540 case TCC_OPTION_static:
9541 s->static_link = 1;
9542 break;
9543 case TCC_OPTION_shared:
9544 output_type = TCC_OUTPUT_DLL;
9545 break;
9546 case TCC_OPTION_o:
9547 multiple_files = 1;
9548 outfile = optarg;
9549 break;
9550 case TCC_OPTION_r:
9551 /* generate a .o merging several output files */
9552 reloc_output = 1;
9553 output_type = TCC_OUTPUT_OBJ;
9554 break;
9555 case TCC_OPTION_nostdinc:
9556 s->nostdinc = 1;
9557 break;
9558 case TCC_OPTION_print_search_dirs:
9559 print_search_dirs = 1;
9560 break;
9561 default:
9562 break;
9566 end_parse:
9567 if (print_search_dirs) {
9568 /* enough for Linux kernel */
9569 printf("install: %s/\n", tcc_lib_path);
9570 return 0;
9573 nb_objfiles = nb_files - nb_libraries;
9575 /* if outfile provided without other options, we output an
9576 executable */
9577 if (outfile && output_type == TCC_OUTPUT_MEMORY)
9578 output_type = TCC_OUTPUT_EXE;
9580 /* check -c consistency : only single file handled. XXX: checks file type */
9581 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9582 /* accepts only a single input file */
9583 if (nb_objfiles != 1)
9584 error("cannot specify multiple files with -c");
9585 if (nb_libraries != 0)
9586 error("cannot specify libraries with -c");
9589 /* compute default outfile name */
9590 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
9591 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9592 char *ext;
9593 /* add .o extension */
9594 pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
9595 ext = strrchr(objfilename, '.');
9596 if (!ext)
9597 goto default_outfile;
9598 strcpy(ext + 1, "o");
9599 } else {
9600 default_outfile:
9601 pstrcpy(objfilename, sizeof(objfilename), "a.out");
9603 outfile = objfilename;
9606 if (do_bench) {
9607 start_time = getclock_us();
9610 tcc_set_output_type(s, output_type);
9612 /* compile or add each files or library */
9613 for(i = 0;i < nb_files; i++) {
9614 const char *filename;
9616 filename = files[i];
9617 if (filename[0] == '-') {
9618 if (tcc_add_library(s, filename + 2) < 0)
9619 error("cannot find %s", filename);
9620 } else {
9621 if (tcc_add_file(s, filename) < 0) {
9622 ret = 1;
9623 goto the_end;
9628 /* free all files */
9629 tcc_free(files);
9631 if (do_bench) {
9632 double total_time;
9633 total_time = (double)(getclock_us() - start_time) / 1000000.0;
9634 if (total_time < 0.001)
9635 total_time = 0.001;
9636 if (total_bytes < 1)
9637 total_bytes = 1;
9638 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
9639 tok_ident - TOK_IDENT, total_lines, total_bytes,
9640 total_time, (int)(total_lines / total_time),
9641 total_bytes / total_time / 1000000.0);
9644 if (s->output_type != TCC_OUTPUT_MEMORY) {
9645 tcc_output_file(s, outfile);
9646 ret = 0;
9647 } else {
9648 ret = tcc_run(s, argc - optind, argv + optind);
9650 the_end:
9651 /* XXX: cannot do it with bound checking because of the malloc hooks */
9652 if (!do_bounds_check)
9653 tcc_delete(s);
9655 #ifdef MEM_DEBUG
9656 if (do_bench) {
9657 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
9659 #endif
9660 return ret;
9663 #endif