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