automatic man page generation from tcc-doc.texi
[tinycc.git] / tcc.c
blob6ef7e85acd6b2868e044995001151dfba416b4a8
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 int nostdinc; /* if true, no standard headers are added */
396 int nostdlib; /* if true, no standard libraries are added */
398 /* if true, static linking is performed */
399 int static_link;
401 /* if true, only link in referenced objects from archive */
402 int alacarte_link;
404 /* warning switches */
405 int warn_write_strings;
406 int warn_unsupported;
407 int warn_error;
409 /* error handling */
410 void *error_opaque;
411 void (*error_func)(void *opaque, const char *msg);
412 int error_set_jmp_enabled;
413 jmp_buf error_jmp_buf;
414 int nb_errors;
416 /* tiny assembler state */
417 Sym *asm_labels;
419 /* see include_stack_ptr */
420 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
422 /* see ifdef_stack_ptr */
423 int ifdef_stack[IFDEF_STACK_SIZE];
426 /* The current value can be: */
427 #define VT_VALMASK 0x00ff
428 #define VT_CONST 0x00f0 /* constant in vc
429 (must be first non register value) */
430 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
431 #define VT_LOCAL 0x00f2 /* offset on stack */
432 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
433 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
434 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
435 #define VT_LVAL 0x0100 /* var is an lvalue */
436 #define VT_SYM 0x0200 /* a symbol value is added */
437 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
438 char/short stored in integer registers) */
439 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
440 dereferencing value */
441 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
442 bounding function call point is in vc */
443 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
444 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
445 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
446 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
448 /* types */
449 #define VT_INT 0 /* integer type */
450 #define VT_BYTE 1 /* signed byte type */
451 #define VT_SHORT 2 /* short type */
452 #define VT_VOID 3 /* void type */
453 #define VT_PTR 4 /* pointer */
454 #define VT_ENUM 5 /* enum definition */
455 #define VT_FUNC 6 /* function type */
456 #define VT_STRUCT 7 /* struct/union definition */
457 #define VT_FLOAT 8 /* IEEE float */
458 #define VT_DOUBLE 9 /* IEEE double */
459 #define VT_LDOUBLE 10 /* IEEE long double */
460 #define VT_BOOL 11 /* ISOC99 boolean type */
461 #define VT_LLONG 12 /* 64 bit integer */
462 #define VT_LONG 13 /* long integer (NEVER USED as type, only
463 during parsing) */
464 #define VT_BTYPE 0x000f /* mask for basic type */
465 #define VT_UNSIGNED 0x0010 /* unsigned type */
466 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
467 #define VT_BITFIELD 0x0040 /* bitfield modifier */
468 #define VT_CONSTANT 0x0800 /* const modifier */
469 #define VT_VOLATILE 0x1000 /* volatile modifier */
471 /* storage */
472 #define VT_EXTERN 0x00000080 /* extern definition */
473 #define VT_STATIC 0x00000100 /* static variable */
474 #define VT_TYPEDEF 0x00000200 /* typedef definition */
475 #define VT_INLINE 0x00000400 /* inline definition */
477 #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */
479 /* type mask (except storage) */
480 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
481 #define VT_TYPE (~(VT_STORAGE))
483 /* token values */
485 /* warning: the following compare tokens depend on i386 asm code */
486 #define TOK_ULT 0x92
487 #define TOK_UGE 0x93
488 #define TOK_EQ 0x94
489 #define TOK_NE 0x95
490 #define TOK_ULE 0x96
491 #define TOK_UGT 0x97
492 #define TOK_LT 0x9c
493 #define TOK_GE 0x9d
494 #define TOK_LE 0x9e
495 #define TOK_GT 0x9f
497 #define TOK_LAND 0xa0
498 #define TOK_LOR 0xa1
500 #define TOK_DEC 0xa2
501 #define TOK_MID 0xa3 /* inc/dec, to void constant */
502 #define TOK_INC 0xa4
503 #define TOK_UDIV 0xb0 /* unsigned division */
504 #define TOK_UMOD 0xb1 /* unsigned modulo */
505 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
506 #define TOK_CINT 0xb3 /* number in tokc */
507 #define TOK_CCHAR 0xb4 /* char constant in tokc */
508 #define TOK_STR 0xb5 /* pointer to string in tokc */
509 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
510 #define TOK_LCHAR 0xb7
511 #define TOK_LSTR 0xb8
512 #define TOK_CFLOAT 0xb9 /* float constant */
513 #define TOK_LINENUM 0xba /* line number info */
514 #define TOK_CDOUBLE 0xc0 /* double constant */
515 #define TOK_CLDOUBLE 0xc1 /* long double constant */
516 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
517 #define TOK_ADDC1 0xc3 /* add with carry generation */
518 #define TOK_ADDC2 0xc4 /* add with carry use */
519 #define TOK_SUBC1 0xc5 /* add with carry generation */
520 #define TOK_SUBC2 0xc6 /* add with carry use */
521 #define TOK_CUINT 0xc8 /* unsigned int constant */
522 #define TOK_CLLONG 0xc9 /* long long constant */
523 #define TOK_CULLONG 0xca /* unsigned long long constant */
524 #define TOK_ARROW 0xcb
525 #define TOK_DOTS 0xcc /* three dots */
526 #define TOK_SHR 0xcd /* unsigned shift right */
527 #define TOK_PPNUM 0xce /* preprocessor number */
529 #define TOK_SHL 0x01 /* shift left */
530 #define TOK_SAR 0x02 /* signed shift right */
532 /* assignement operators : normal operator or 0x80 */
533 #define TOK_A_MOD 0xa5
534 #define TOK_A_AND 0xa6
535 #define TOK_A_MUL 0xaa
536 #define TOK_A_ADD 0xab
537 #define TOK_A_SUB 0xad
538 #define TOK_A_DIV 0xaf
539 #define TOK_A_XOR 0xde
540 #define TOK_A_OR 0xfc
541 #define TOK_A_SHL 0x81
542 #define TOK_A_SAR 0x82
544 #ifndef offsetof
545 #define offsetof(type, field) ((size_t) &((type *)0)->field)
546 #endif
548 #ifndef countof
549 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
550 #endif
552 /* WARNING: the content of this string encodes token numbers */
553 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";
555 #define TOK_EOF (-1) /* end of file */
556 #define TOK_LINEFEED 10 /* line feed */
558 /* all identificators and strings have token above that */
559 #define TOK_IDENT 256
561 /* only used for i386 asm opcodes definitions */
562 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
564 #define DEF_BWL(x) \
565 DEF(TOK_ASM_ ## x ## b, #x "b") \
566 DEF(TOK_ASM_ ## x ## w, #x "w") \
567 DEF(TOK_ASM_ ## x ## l, #x "l") \
568 DEF(TOK_ASM_ ## x, #x)
570 #define DEF_WL(x) \
571 DEF(TOK_ASM_ ## x ## w, #x "w") \
572 DEF(TOK_ASM_ ## x ## l, #x "l") \
573 DEF(TOK_ASM_ ## x, #x)
575 #define DEF_FP1(x) \
576 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
577 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
578 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
579 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
581 #define DEF_FP(x) \
582 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
583 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
584 DEF_FP1(x)
586 #define DEF_ASMTEST(x) \
587 DEF_ASM(x ## o) \
588 DEF_ASM(x ## no) \
589 DEF_ASM(x ## b) \
590 DEF_ASM(x ## c) \
591 DEF_ASM(x ## nae) \
592 DEF_ASM(x ## nb) \
593 DEF_ASM(x ## nc) \
594 DEF_ASM(x ## ae) \
595 DEF_ASM(x ## e) \
596 DEF_ASM(x ## z) \
597 DEF_ASM(x ## ne) \
598 DEF_ASM(x ## nz) \
599 DEF_ASM(x ## be) \
600 DEF_ASM(x ## na) \
601 DEF_ASM(x ## nbe) \
602 DEF_ASM(x ## a) \
603 DEF_ASM(x ## s) \
604 DEF_ASM(x ## ns) \
605 DEF_ASM(x ## p) \
606 DEF_ASM(x ## pe) \
607 DEF_ASM(x ## np) \
608 DEF_ASM(x ## po) \
609 DEF_ASM(x ## l) \
610 DEF_ASM(x ## nge) \
611 DEF_ASM(x ## nl) \
612 DEF_ASM(x ## ge) \
613 DEF_ASM(x ## le) \
614 DEF_ASM(x ## ng) \
615 DEF_ASM(x ## nle) \
616 DEF_ASM(x ## g)
618 #define TOK_ASM_int TOK_INT
620 enum {
621 TOK_LAST = TOK_IDENT - 1,
622 #define DEF(id, str) id,
623 #include "tcctok.h"
624 #undef DEF
627 static const char tcc_keywords[] =
628 #define DEF(id, str) str "\0"
629 #include "tcctok.h"
630 #undef DEF
633 #define TOK_UIDENT TOK_DEFINE
635 #ifdef WIN32
636 #define snprintf _snprintf
637 #define vsnprintf _vsnprintf
638 #endif
640 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
641 /* currently incorrect */
642 long double strtold(const char *nptr, char **endptr)
644 return (long double)strtod(nptr, endptr);
646 float strtof(const char *nptr, char **endptr)
648 return (float)strtod(nptr, endptr);
650 #else
651 /* XXX: need to define this to use them in non ISOC99 context */
652 extern float strtof (const char *__nptr, char **__endptr);
653 extern long double strtold (const char *__nptr, char **__endptr);
654 #endif
656 static char *pstrcpy(char *buf, int buf_size, const char *s);
657 static char *pstrcat(char *buf, int buf_size, const char *s);
659 static void next(void);
660 static void next_nomacro(void);
661 static void parse_expr_type(CType *type);
662 static void expr_type(CType *type);
663 static void unary_type(CType *type);
664 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
665 int case_reg, int is_expr);
666 static int expr_const(void);
667 static void expr_eq(void);
668 static void gexpr(void);
669 static void decl(int l);
670 static void decl_initializer(CType *type, Section *sec, unsigned long c,
671 int first, int size_only);
672 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
673 int has_init, int v, int scope);
674 int gv(int rc);
675 void gv2(int rc1, int rc2);
676 void move_reg(int r, int s);
677 void save_regs(int n);
678 void save_reg(int r);
679 void vpop(void);
680 void vswap(void);
681 void vdup(void);
682 int get_reg(int rc);
684 static void macro_subst(TokenString *tok_str, Sym **nested_list,
685 const int *macro_str, int can_read_stream);
686 int save_reg_forced(int r);
687 void gen_op(int op);
688 void force_charshort_cast(int t);
689 static void gen_cast(CType *type);
690 void vstore(void);
691 static Sym *sym_find(int v);
692 static Sym *sym_push(int v, CType *type, int r, int c);
694 /* type handling */
695 static int type_size(CType *type, int *a);
696 static inline CType *pointed_type(CType *type);
697 static int pointed_size(CType *type);
698 static int lvalue_type(int t);
699 static int parse_btype(CType *type, AttributeDef *ad);
700 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
701 static int is_compatible_types(CType *type1, CType *type2);
703 void error(const char *fmt, ...);
704 void vpushi(int v);
705 void vset(CType *type, int r, int v);
706 void type_to_str(char *buf, int buf_size,
707 CType *type, const char *varstr);
708 char *get_tok_str(int v, CValue *cv);
709 static Sym *get_sym_ref(CType *type, Section *sec,
710 unsigned long offset, unsigned long size);
711 static Sym *external_global_sym(int v, CType *type, int r);
713 /* section generation */
714 static void section_realloc(Section *sec, unsigned long new_size);
715 static void *section_ptr_add(Section *sec, unsigned long size);
716 static void put_extern_sym(Sym *sym, Section *section,
717 unsigned long value, unsigned long size);
718 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
719 static int put_elf_str(Section *s, const char *sym);
720 static int put_elf_sym(Section *s,
721 unsigned long value, unsigned long size,
722 int info, int other, int shndx, const char *name);
723 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
724 int info, int sh_num, const char *name);
725 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
726 int type, int symbol);
727 static void put_stabs(const char *str, int type, int other, int desc,
728 unsigned long value);
729 static void put_stabs_r(const char *str, int type, int other, int desc,
730 unsigned long value, Section *sec, int sym_index);
731 static void put_stabn(int type, int other, int desc, int value);
732 static void put_stabd(int type, int other, int desc);
733 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
735 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
736 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
737 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
739 /* tccasm.c */
741 #ifdef CONFIG_TCC_ASM
743 typedef struct ExprValue {
744 uint32_t v;
745 Sym *sym;
746 } ExprValue;
748 #define MAX_ASM_OPERANDS 30
750 typedef struct ASMOperand {
751 int id; /* GCC 3 optionnal identifier (0 if number only supported */
752 char *constraint;
753 char asm_str[16]; /* computed asm string for operand */
754 SValue *vt; /* C value of the expression */
755 int ref_index; /* if >= 0, gives reference to a output constraint */
756 int priority; /* priority, used to assign registers */
757 int reg; /* if >= 0, register number used for this operand */
758 int is_llong; /* true if double register value */
759 } ASMOperand;
761 static void asm_expr(TCCState *s1, ExprValue *pe);
762 static int asm_int_expr(TCCState *s1);
763 static int find_constraint(ASMOperand *operands, int nb_operands,
764 const char *name, const char **pp);
766 static int tcc_assemble(TCCState *s1, int do_preprocess);
768 #endif
770 static void asm_instr(void);
772 /* true if float/double/long double type */
773 static inline int is_float(int t)
775 int bt;
776 bt = t & VT_BTYPE;
777 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
780 #ifdef TCC_TARGET_I386
781 #include "i386-gen.c"
782 #endif
784 #ifdef CONFIG_TCC_STATIC
786 #define RTLD_LAZY 0x001
787 #define RTLD_NOW 0x002
788 #define RTLD_GLOBAL 0x100
789 #define RTLD_DEFAULT NULL
791 /* dummy function for profiling */
792 void *dlopen(const char *filename, int flag)
794 return NULL;
797 const char *dlerror(void)
799 return "error";
802 typedef struct TCCSyms {
803 char *str;
804 void *ptr;
805 } TCCSyms;
807 #define TCCSYM(a) { #a, &a, },
809 /* add the symbol you want here if no dynamic linking is done */
810 static TCCSyms tcc_syms[] = {
811 TCCSYM(printf)
812 TCCSYM(fprintf)
813 TCCSYM(fopen)
814 TCCSYM(fclose)
815 { NULL, NULL },
818 void *dlsym(void *handle, const char *symbol)
820 TCCSyms *p;
821 p = tcc_syms;
822 while (p->str != NULL) {
823 if (!strcmp(p->str, symbol))
824 return p->ptr;
825 p++;
827 return NULL;
830 #endif
832 /********************************************************/
834 /* we use our own 'finite' function to avoid potential problems with
835 non standard math libs */
836 /* XXX: endianness dependent */
837 int ieee_finite(double d)
839 int *p = (int *)&d;
840 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
843 /* copy a string and truncate it. */
844 static char *pstrcpy(char *buf, int buf_size, const char *s)
846 char *q, *q_end;
847 int c;
849 if (buf_size > 0) {
850 q = buf;
851 q_end = buf + buf_size - 1;
852 while (q < q_end) {
853 c = *s++;
854 if (c == '\0')
855 break;
856 *q++ = c;
858 *q = '\0';
860 return buf;
863 /* strcat and truncate. */
864 static char *pstrcat(char *buf, int buf_size, const char *s)
866 int len;
867 len = strlen(buf);
868 if (len < buf_size)
869 pstrcpy(buf + len, buf_size - len, s);
870 return buf;
873 /* memory management */
874 #ifdef MEM_DEBUG
875 int mem_cur_size;
876 int mem_max_size;
877 #endif
879 static inline void tcc_free(void *ptr)
881 #ifdef MEM_DEBUG
882 mem_cur_size -= malloc_usable_size(ptr);
883 #endif
884 free(ptr);
887 static void *tcc_malloc(unsigned long size)
889 void *ptr;
890 ptr = malloc(size);
891 if (!ptr && size)
892 error("memory full");
893 #ifdef MEM_DEBUG
894 mem_cur_size += malloc_usable_size(ptr);
895 if (mem_cur_size > mem_max_size)
896 mem_max_size = mem_cur_size;
897 #endif
898 return ptr;
901 static void *tcc_mallocz(unsigned long size)
903 void *ptr;
904 ptr = tcc_malloc(size);
905 memset(ptr, 0, size);
906 return ptr;
909 static inline void *tcc_realloc(void *ptr, unsigned long size)
911 void *ptr1;
912 #ifdef MEM_DEBUG
913 mem_cur_size -= malloc_usable_size(ptr);
914 #endif
915 ptr1 = realloc(ptr, size);
916 #ifdef MEM_DEBUG
917 /* NOTE: count not correct if alloc error, but not critical */
918 mem_cur_size += malloc_usable_size(ptr1);
919 if (mem_cur_size > mem_max_size)
920 mem_max_size = mem_cur_size;
921 #endif
922 return ptr1;
925 static char *tcc_strdup(const char *str)
927 char *ptr;
928 ptr = tcc_malloc(strlen(str) + 1);
929 strcpy(ptr, str);
930 return ptr;
933 #define free(p) use_tcc_free(p)
934 #define malloc(s) use_tcc_malloc(s)
935 #define realloc(p, s) use_tcc_realloc(p, s)
937 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
939 int nb, nb_alloc;
940 void **pp;
942 nb = *nb_ptr;
943 pp = *ptab;
944 /* every power of two we double array size */
945 if ((nb & (nb - 1)) == 0) {
946 if (!nb)
947 nb_alloc = 1;
948 else
949 nb_alloc = nb * 2;
950 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
951 if (!pp)
952 error("memory full");
953 *ptab = pp;
955 pp[nb++] = data;
956 *nb_ptr = nb;
959 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
961 Section *sec;
963 sec = tcc_mallocz(sizeof(Section));
964 pstrcpy(sec->name, sizeof(sec->name), name);
965 sec->sh_type = sh_type;
966 sec->sh_flags = sh_flags;
967 switch(sh_type) {
968 case SHT_HASH:
969 case SHT_REL:
970 case SHT_DYNSYM:
971 case SHT_SYMTAB:
972 case SHT_DYNAMIC:
973 sec->sh_addralign = 4;
974 break;
975 case SHT_STRTAB:
976 sec->sh_addralign = 1;
977 break;
978 default:
979 sec->sh_addralign = 32; /* default conservative alignment */
980 break;
983 /* only add section if not private */
984 if (!(sh_flags & SHF_PRIVATE)) {
985 sec->sh_num = s1->nb_sections;
986 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
988 return sec;
991 static void free_section(Section *s)
993 tcc_free(s->data);
994 tcc_free(s);
997 /* realloc section and set its content to zero */
998 static void section_realloc(Section *sec, unsigned long new_size)
1000 unsigned long size;
1001 unsigned char *data;
1003 size = sec->data_allocated;
1004 if (size == 0)
1005 size = 1;
1006 while (size < new_size)
1007 size = size * 2;
1008 data = tcc_realloc(sec->data, size);
1009 if (!data)
1010 error("memory full");
1011 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
1012 sec->data = data;
1013 sec->data_allocated = size;
1016 /* reserve at least 'size' bytes in section 'sec' from
1017 sec->data_offset. */
1018 static void *section_ptr_add(Section *sec, unsigned long size)
1020 unsigned long offset, offset1;
1022 offset = sec->data_offset;
1023 offset1 = offset + size;
1024 if (offset1 > sec->data_allocated)
1025 section_realloc(sec, offset1);
1026 sec->data_offset = offset1;
1027 return sec->data + offset;
1030 /* return a reference to a section, and create it if it does not
1031 exists */
1032 Section *find_section(TCCState *s1, const char *name)
1034 Section *sec;
1035 int i;
1036 for(i = 1; i < s1->nb_sections; i++) {
1037 sec = s1->sections[i];
1038 if (!strcmp(name, sec->name))
1039 return sec;
1041 /* sections are created as PROGBITS */
1042 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
1045 /* update sym->c so that it points to an external symbol in section
1046 'section' with value 'value' */
1047 static void put_extern_sym(Sym *sym, Section *section,
1048 unsigned long value, unsigned long size)
1050 int sym_type, sym_bind, sh_num, info;
1051 Elf32_Sym *esym;
1052 const char *name;
1054 if (section)
1055 sh_num = section->sh_num;
1056 else
1057 sh_num = SHN_UNDEF;
1058 if (!sym->c) {
1059 if ((sym->type.t & VT_BTYPE) == VT_FUNC)
1060 sym_type = STT_FUNC;
1061 else
1062 sym_type = STT_OBJECT;
1063 if (sym->type.t & VT_STATIC)
1064 sym_bind = STB_LOCAL;
1065 else
1066 sym_bind = STB_GLOBAL;
1068 name = get_tok_str(sym->v, NULL);
1069 #ifdef CONFIG_TCC_BCHECK
1070 if (do_bounds_check) {
1071 char buf[32];
1073 /* XXX: avoid doing that for statics ? */
1074 /* if bound checking is activated, we change some function
1075 names by adding the "__bound" prefix */
1076 switch(sym->v) {
1077 #if 0
1078 /* XXX: we rely only on malloc hooks */
1079 case TOK_malloc:
1080 case TOK_free:
1081 case TOK_realloc:
1082 case TOK_memalign:
1083 case TOK_calloc:
1084 #endif
1085 case TOK_memcpy:
1086 case TOK_memmove:
1087 case TOK_memset:
1088 case TOK_strlen:
1089 case TOK_strcpy:
1090 strcpy(buf, "__bound_");
1091 strcat(buf, name);
1092 name = buf;
1093 break;
1096 #endif
1097 info = ELF32_ST_INFO(sym_bind, sym_type);
1098 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
1099 } else {
1100 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
1101 esym->st_value = value;
1102 esym->st_size = size;
1103 esym->st_shndx = sh_num;
1107 /* add a new relocation entry to symbol 'sym' in section 's' */
1108 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
1110 if (!sym->c)
1111 put_extern_sym(sym, NULL, 0, 0);
1112 /* now we can add ELF relocation info */
1113 put_elf_reloc(symtab_section, s, offset, type, sym->c);
1116 static inline int isid(int c)
1118 return (c >= 'a' && c <= 'z') ||
1119 (c >= 'A' && c <= 'Z') ||
1120 c == '_';
1123 static inline int isnum(int c)
1125 return c >= '0' && c <= '9';
1128 static inline int isoct(int c)
1130 return c >= '0' && c <= '7';
1133 static inline int toup(int c)
1135 if (c >= 'a' && c <= 'z')
1136 return c - 'a' + 'A';
1137 else
1138 return c;
1141 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
1143 int len;
1144 len = strlen(buf);
1145 vsnprintf(buf + len, buf_size - len, fmt, ap);
1148 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
1150 va_list ap;
1151 va_start(ap, fmt);
1152 strcat_vprintf(buf, buf_size, fmt, ap);
1153 va_end(ap);
1156 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
1158 char buf[2048];
1159 BufferedFile **f;
1161 buf[0] = '\0';
1162 if (file) {
1163 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1164 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1165 (*f)->filename, (*f)->line_num);
1166 if (file->line_num > 0) {
1167 strcat_printf(buf, sizeof(buf),
1168 "%s:%d: ", file->filename, file->line_num);
1169 } else {
1170 strcat_printf(buf, sizeof(buf),
1171 "%s: ", file->filename);
1173 } else {
1174 strcat_printf(buf, sizeof(buf),
1175 "tcc: ");
1177 if (is_warning)
1178 strcat_printf(buf, sizeof(buf), "warning: ");
1179 strcat_vprintf(buf, sizeof(buf), fmt, ap);
1181 if (!s1->error_func) {
1182 /* default case: stderr */
1183 fprintf(stderr, "%s\n", buf);
1184 } else {
1185 s1->error_func(s1->error_opaque, buf);
1187 if (!is_warning || s1->warn_error)
1188 s1->nb_errors++;
1191 #ifdef LIBTCC
1192 void tcc_set_error_func(TCCState *s, void *error_opaque,
1193 void (*error_func)(void *opaque, const char *msg))
1195 s->error_opaque = error_opaque;
1196 s->error_func = error_func;
1198 #endif
1200 /* error without aborting current compilation */
1201 void error_noabort(const char *fmt, ...)
1203 TCCState *s1 = tcc_state;
1204 va_list ap;
1206 va_start(ap, fmt);
1207 error1(s1, 0, fmt, ap);
1208 va_end(ap);
1211 void error(const char *fmt, ...)
1213 TCCState *s1 = tcc_state;
1214 va_list ap;
1216 va_start(ap, fmt);
1217 error1(s1, 0, fmt, ap);
1218 va_end(ap);
1219 /* better than nothing: in some cases, we accept to handle errors */
1220 if (s1->error_set_jmp_enabled) {
1221 longjmp(s1->error_jmp_buf, 1);
1222 } else {
1223 /* XXX: eliminate this someday */
1224 exit(1);
1228 void expect(const char *msg)
1230 error("%s expected", msg);
1233 void warning(const char *fmt, ...)
1235 TCCState *s1 = tcc_state;
1236 va_list ap;
1238 va_start(ap, fmt);
1239 error1(s1, 1, fmt, ap);
1240 va_end(ap);
1243 void skip(int c)
1245 if (tok != c)
1246 error("'%c' expected", c);
1247 next();
1250 static void test_lvalue(void)
1252 if (!(vtop->r & VT_LVAL))
1253 expect("lvalue");
1256 /* allocate a new token */
1257 static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
1259 TokenSym *ts, **ptable;
1260 int i;
1262 if (tok_ident >= SYM_FIRST_ANOM)
1263 error("memory full");
1265 /* expand token table if needed */
1266 i = tok_ident - TOK_IDENT;
1267 if ((i % TOK_ALLOC_INCR) == 0) {
1268 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1269 if (!ptable)
1270 error("memory full");
1271 table_ident = ptable;
1274 ts = tcc_malloc(sizeof(TokenSym) + len);
1275 table_ident[i] = ts;
1276 ts->tok = tok_ident++;
1277 ts->sym_define = NULL;
1278 ts->sym_label = NULL;
1279 ts->sym_struct = NULL;
1280 ts->sym_identifier = NULL;
1281 ts->len = len;
1282 ts->hash_next = NULL;
1283 memcpy(ts->str, str, len);
1284 ts->str[len] = '\0';
1285 *pts = ts;
1286 return ts;
1289 #define TOK_HASH_INIT 1
1290 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1292 /* find a token and add it if not found */
1293 static TokenSym *tok_alloc(const char *str, int len)
1295 TokenSym *ts, **pts;
1296 int i;
1297 unsigned int h;
1299 h = TOK_HASH_INIT;
1300 for(i=0;i<len;i++)
1301 h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
1302 h &= (TOK_HASH_SIZE - 1);
1304 pts = &hash_ident[h];
1305 for(;;) {
1306 ts = *pts;
1307 if (!ts)
1308 break;
1309 if (ts->len == len && !memcmp(ts->str, str, len))
1310 return ts;
1311 pts = &(ts->hash_next);
1313 return tok_alloc_new(pts, str, len);
1316 /* CString handling */
1318 static void cstr_realloc(CString *cstr, int new_size)
1320 int size;
1321 void *data;
1323 size = cstr->size_allocated;
1324 if (size == 0)
1325 size = 8; /* no need to allocate a too small first string */
1326 while (size < new_size)
1327 size = size * 2;
1328 data = tcc_realloc(cstr->data_allocated, size);
1329 if (!data)
1330 error("memory full");
1331 cstr->data_allocated = data;
1332 cstr->size_allocated = size;
1333 cstr->data = data;
1336 /* add a byte */
1337 static void cstr_ccat(CString *cstr, int ch)
1339 int size;
1340 size = cstr->size + 1;
1341 if (size > cstr->size_allocated)
1342 cstr_realloc(cstr, size);
1343 ((unsigned char *)cstr->data)[size - 1] = ch;
1344 cstr->size = size;
1347 static void cstr_cat(CString *cstr, const char *str)
1349 int c;
1350 for(;;) {
1351 c = *str;
1352 if (c == '\0')
1353 break;
1354 cstr_ccat(cstr, c);
1355 str++;
1359 /* add a wide char */
1360 static void cstr_wccat(CString *cstr, int ch)
1362 int size;
1363 size = cstr->size + sizeof(int);
1364 if (size > cstr->size_allocated)
1365 cstr_realloc(cstr, size);
1366 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1367 cstr->size = size;
1370 static void cstr_new(CString *cstr)
1372 memset(cstr, 0, sizeof(CString));
1375 /* free string and reset it to NULL */
1376 static void cstr_free(CString *cstr)
1378 tcc_free(cstr->data_allocated);
1379 cstr_new(cstr);
1382 #define cstr_reset(cstr) cstr_free(cstr)
1384 static CString *cstr_dup(CString *cstr1)
1386 CString *cstr;
1387 int size;
1389 cstr = tcc_malloc(sizeof(CString));
1390 size = cstr1->size;
1391 cstr->size = size;
1392 cstr->size_allocated = size;
1393 cstr->data_allocated = tcc_malloc(size);
1394 cstr->data = cstr->data_allocated;
1395 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1396 return cstr;
1399 /* XXX: unicode ? */
1400 static void add_char(CString *cstr, int c)
1402 if (c == '\'' || c == '\"' || c == '\\') {
1403 /* XXX: could be more precise if char or string */
1404 cstr_ccat(cstr, '\\');
1406 if (c >= 32 && c <= 126) {
1407 cstr_ccat(cstr, c);
1408 } else {
1409 cstr_ccat(cstr, '\\');
1410 if (c == '\n') {
1411 cstr_ccat(cstr, 'n');
1412 } else {
1413 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1414 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1415 cstr_ccat(cstr, '0' + (c & 7));
1420 /* XXX: buffer overflow */
1421 /* XXX: float tokens */
1422 char *get_tok_str(int v, CValue *cv)
1424 static char buf[STRING_MAX_SIZE + 1];
1425 static CString cstr_buf;
1426 CString *cstr;
1427 unsigned char *q;
1428 char *p;
1429 int i, len;
1431 /* NOTE: to go faster, we give a fixed buffer for small strings */
1432 cstr_reset(&cstr_buf);
1433 cstr_buf.data = buf;
1434 cstr_buf.size_allocated = sizeof(buf);
1435 p = buf;
1437 switch(v) {
1438 case TOK_CINT:
1439 case TOK_CUINT:
1440 /* XXX: not quite exact, but only useful for testing */
1441 sprintf(p, "%u", cv->ui);
1442 break;
1443 case TOK_CLLONG:
1444 case TOK_CULLONG:
1445 /* XXX: not quite exact, but only useful for testing */
1446 sprintf(p, "%Lu", cv->ull);
1447 break;
1448 case TOK_CCHAR:
1449 case TOK_LCHAR:
1450 cstr_ccat(&cstr_buf, '\'');
1451 add_char(&cstr_buf, cv->i);
1452 cstr_ccat(&cstr_buf, '\'');
1453 cstr_ccat(&cstr_buf, '\0');
1454 break;
1455 case TOK_PPNUM:
1456 cstr = cv->cstr;
1457 len = cstr->size - 1;
1458 for(i=0;i<len;i++)
1459 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1460 cstr_ccat(&cstr_buf, '\0');
1461 break;
1462 case TOK_STR:
1463 case TOK_LSTR:
1464 cstr = cv->cstr;
1465 cstr_ccat(&cstr_buf, '\"');
1466 if (v == TOK_STR) {
1467 len = cstr->size - 1;
1468 for(i=0;i<len;i++)
1469 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1470 } else {
1471 len = (cstr->size / sizeof(int)) - 1;
1472 for(i=0;i<len;i++)
1473 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1475 cstr_ccat(&cstr_buf, '\"');
1476 cstr_ccat(&cstr_buf, '\0');
1477 break;
1478 case TOK_LT:
1479 v = '<';
1480 goto addv;
1481 case TOK_GT:
1482 v = '>';
1483 goto addv;
1484 case TOK_A_SHL:
1485 return strcpy(p, "<<=");
1486 case TOK_A_SAR:
1487 return strcpy(p, ">>=");
1488 default:
1489 if (v < TOK_IDENT) {
1490 /* search in two bytes table */
1491 q = tok_two_chars;
1492 while (*q) {
1493 if (q[2] == v) {
1494 *p++ = q[0];
1495 *p++ = q[1];
1496 *p = '\0';
1497 return buf;
1499 q += 3;
1501 addv:
1502 *p++ = v;
1503 *p = '\0';
1504 } else if (v < tok_ident) {
1505 return table_ident[v - TOK_IDENT]->str;
1506 } else if (v >= SYM_FIRST_ANOM) {
1507 /* special name for anonymous symbol */
1508 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1509 } else {
1510 /* should never happen */
1511 return NULL;
1513 break;
1515 return cstr_buf.data;
1518 /* push, without hashing */
1519 static Sym *sym_push2(Sym **ps, int v, int t, int c)
1521 Sym *s;
1522 s = tcc_malloc(sizeof(Sym));
1523 s->v = v;
1524 s->type.t = t;
1525 s->c = c;
1526 s->next = NULL;
1527 /* add in stack */
1528 s->prev = *ps;
1529 *ps = s;
1530 return s;
1533 /* find a symbol and return its associated structure. 's' is the top
1534 of the symbol stack */
1535 static Sym *sym_find2(Sym *s, int v)
1537 while (s) {
1538 if (s->v == v)
1539 return s;
1540 s = s->prev;
1542 return NULL;
1545 /* structure lookup */
1546 static inline Sym *struct_find(int v)
1548 v -= TOK_IDENT;
1549 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1550 return NULL;
1551 return table_ident[v]->sym_struct;
1554 /* find an identifier */
1555 static inline Sym *sym_find(int v)
1557 v -= TOK_IDENT;
1558 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1559 return NULL;
1560 return table_ident[v]->sym_identifier;
1563 /* push a given symbol on the symbol stack */
1564 static Sym *sym_push(int v, CType *type, int r, int c)
1566 Sym *s, **ps;
1567 TokenSym *ts;
1569 if (local_stack)
1570 ps = &local_stack;
1571 else
1572 ps = &global_stack;
1573 s = sym_push2(ps, v, type->t, c);
1574 s->type.ref = type->ref;
1575 s->r = r;
1576 /* don't record fields or anonymous symbols */
1577 /* XXX: simplify */
1578 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1579 /* record symbol in token array */
1580 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1581 if (v & SYM_STRUCT)
1582 ps = &ts->sym_struct;
1583 else
1584 ps = &ts->sym_identifier;
1585 s->prev_tok = *ps;
1586 *ps = s;
1588 return s;
1591 /* push a global identifier */
1592 static Sym *global_identifier_push(int v, int t, int c)
1594 Sym *s, **ps;
1595 s = sym_push2(&global_stack, v, t, c);
1596 /* don't record anonymous symbol */
1597 if (v < SYM_FIRST_ANOM) {
1598 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1599 /* modify the top most local identifier, so that
1600 sym_identifier will point to 's' when popped */
1601 while (*ps != NULL)
1602 ps = &(*ps)->prev_tok;
1603 s->prev_tok = NULL;
1604 *ps = s;
1606 return s;
1609 /* pop symbols until top reaches 'b' */
1610 static void sym_pop(Sym **ptop, Sym *b)
1612 Sym *s, *ss, **ps;
1613 TokenSym *ts;
1614 int v;
1616 s = *ptop;
1617 while(s != b) {
1618 ss = s->prev;
1619 v = s->v;
1620 /* remove symbol in token array */
1621 /* XXX: simplify */
1622 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1623 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1624 if (v & SYM_STRUCT)
1625 ps = &ts->sym_struct;
1626 else
1627 ps = &ts->sym_identifier;
1628 *ps = s->prev_tok;
1630 tcc_free(s);
1631 s = ss;
1633 *ptop = b;
1636 /* I/O layer */
1638 BufferedFile *tcc_open(TCCState *s1, const char *filename)
1640 int fd;
1641 BufferedFile *bf;
1643 fd = open(filename, O_RDONLY);
1644 if (fd < 0)
1645 return NULL;
1646 bf = tcc_malloc(sizeof(BufferedFile));
1647 if (!bf) {
1648 close(fd);
1649 return NULL;
1651 bf->fd = fd;
1652 bf->buf_ptr = bf->buffer;
1653 bf->buf_end = bf->buffer;
1654 bf->buffer[0] = CH_EOB; /* put eob symbol */
1655 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1656 bf->line_num = 1;
1657 bf->ifndef_macro = 0;
1658 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1659 // printf("opening '%s'\n", filename);
1660 return bf;
1663 void tcc_close(BufferedFile *bf)
1665 total_lines += bf->line_num;
1666 close(bf->fd);
1667 tcc_free(bf);
1670 /* fill input buffer and peek next char */
1671 static int tcc_peekc_slow(BufferedFile *bf)
1673 int len;
1674 /* only tries to read if really end of buffer */
1675 if (bf->buf_ptr >= bf->buf_end) {
1676 if (bf->fd != -1) {
1677 #if defined(PARSE_DEBUG)
1678 len = 8;
1679 #else
1680 len = IO_BUF_SIZE;
1681 #endif
1682 len = read(bf->fd, bf->buffer, len);
1683 if (len < 0)
1684 len = 0;
1685 } else {
1686 len = 0;
1688 total_bytes += len;
1689 bf->buf_ptr = bf->buffer;
1690 bf->buf_end = bf->buffer + len;
1691 *bf->buf_end = CH_EOB;
1693 if (bf->buf_ptr < bf->buf_end) {
1694 return bf->buf_ptr[0];
1695 } else {
1696 bf->buf_ptr = bf->buf_end;
1697 return CH_EOF;
1701 /* return the current character, handling end of block if necessary
1702 (but not stray) */
1703 static int handle_eob(void)
1705 return tcc_peekc_slow(file);
1708 /* read next char from current input file and handle end of input buffer */
1709 static inline void inp(void)
1711 ch = *(++(file->buf_ptr));
1712 /* end of buffer/file handling */
1713 if (ch == CH_EOB)
1714 ch = handle_eob();
1717 /* handle '\[\r]\n' */
1718 static void handle_stray(void)
1720 while (ch == '\\') {
1721 inp();
1722 if (ch == '\n') {
1723 file->line_num++;
1724 inp();
1725 } else if (ch == '\r') {
1726 inp();
1727 if (ch != '\n')
1728 goto fail;
1729 file->line_num++;
1730 inp();
1731 } else {
1732 fail:
1733 error("stray '\\' in program");
1738 /* skip the stray and handle the \\n case. Output an error if
1739 incorrect char after the stray */
1740 static int handle_stray1(uint8_t *p)
1742 int c;
1744 if (p >= file->buf_end) {
1745 file->buf_ptr = p;
1746 c = handle_eob();
1747 p = file->buf_ptr;
1748 if (c == '\\')
1749 goto parse_stray;
1750 } else {
1751 parse_stray:
1752 file->buf_ptr = p;
1753 ch = *p;
1754 handle_stray();
1755 p = file->buf_ptr;
1756 c = *p;
1758 return c;
1761 /* handle just the EOB case, but not stray */
1762 #define PEEKC_EOB(c, p)\
1764 p++;\
1765 c = *p;\
1766 if (c == '\\') {\
1767 file->buf_ptr = p;\
1768 c = handle_eob();\
1769 p = file->buf_ptr;\
1773 /* handle the complicated stray case */
1774 #define PEEKC(c, p)\
1776 p++;\
1777 c = *p;\
1778 if (c == '\\') {\
1779 c = handle_stray1(p);\
1780 p = file->buf_ptr;\
1784 /* input with '\[\r]\n' handling. Note that this function cannot
1785 handle other characters after '\', so you cannot call it inside
1786 strings or comments */
1787 static void minp(void)
1789 inp();
1790 if (ch == '\\')
1791 handle_stray();
1795 /* single line C++ comments */
1796 static uint8_t *parse_line_comment(uint8_t *p)
1798 int c;
1800 p++;
1801 for(;;) {
1802 c = *p;
1803 if (c == '\n' || c == CH_EOF) {
1804 break;
1805 } else if (c == '\\') {
1806 PEEKC_EOB(c, p);
1807 if (c == '\n') {
1808 file->line_num++;
1809 PEEKC_EOB(c, p);
1810 } else if (c == '\r') {
1811 PEEKC_EOB(c, p);
1812 if (c == '\n') {
1813 file->line_num++;
1814 PEEKC_EOB(c, p);
1817 } else {
1818 p++;
1821 return p;
1824 /* C comments */
1825 static uint8_t *parse_comment(uint8_t *p)
1827 int c;
1829 p++;
1830 for(;;) {
1831 /* fast skip loop */
1832 for(;;) {
1833 c = *p;
1834 if (c == '\n' || c == '*' || c == '\\')
1835 break;
1836 p++;
1837 c = *p;
1838 if (c == '\n' || c == '*' || c == '\\')
1839 break;
1840 p++;
1842 /* now we can handle all the cases */
1843 if (c == '\n') {
1844 file->line_num++;
1845 p++;
1846 } else if (c == '*') {
1847 p++;
1848 for(;;) {
1849 c = *p;
1850 if (c == '*') {
1851 p++;
1852 } else if (c == '/') {
1853 goto end_of_comment;
1854 } else if (c == '\\') {
1855 file->buf_ptr = p;
1856 c = handle_eob();
1857 p = file->buf_ptr;
1858 if (c == '\\') {
1859 /* skip '\[\r]\n', otherwise just skip the stray */
1860 while (c == '\\') {
1861 PEEKC_EOB(c, p);
1862 if (c == '\n') {
1863 file->line_num++;
1864 PEEKC_EOB(c, p);
1865 } else if (c == '\r') {
1866 PEEKC_EOB(c, p);
1867 if (c == '\n') {
1868 file->line_num++;
1869 PEEKC_EOB(c, p);
1871 } else {
1872 goto after_star;
1876 } else {
1877 break;
1880 after_star: ;
1881 } else {
1882 /* stray, eob or eof */
1883 file->buf_ptr = p;
1884 c = handle_eob();
1885 p = file->buf_ptr;
1886 if (c == CH_EOF) {
1887 error("unexpected end of file in comment");
1888 } else if (c == '\\') {
1889 p++;
1893 end_of_comment:
1894 p++;
1895 return p;
1898 #define cinp minp
1900 /* space exlcuding newline */
1901 static inline int is_space(int ch)
1903 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1906 static inline void skip_spaces(void)
1908 while (is_space(ch))
1909 cinp();
1912 /* parse a string without interpreting escapes */
1913 static uint8_t *parse_pp_string(uint8_t *p,
1914 int sep, CString *str)
1916 int c;
1917 p++;
1918 for(;;) {
1919 c = *p;
1920 if (c == sep) {
1921 break;
1922 } else if (c == '\\') {
1923 file->buf_ptr = p;
1924 c = handle_eob();
1925 p = file->buf_ptr;
1926 if (c == CH_EOF) {
1927 unterminated_string:
1928 /* XXX: indicate line number of start of string */
1929 error("missing terminating %c character", sep);
1930 } else if (c == '\\') {
1931 /* escape : just skip \[\r]\n */
1932 PEEKC_EOB(c, p);
1933 if (c == '\n') {
1934 file->line_num++;
1935 p++;
1936 } else if (c == '\r') {
1937 PEEKC_EOB(c, p);
1938 if (c != '\n')
1939 expect("'\n' after '\r'");
1940 file->line_num++;
1941 p++;
1942 } else if (c == CH_EOF) {
1943 goto unterminated_string;
1944 } else {
1945 if (str) {
1946 cstr_ccat(str, '\\');
1947 cstr_ccat(str, c);
1949 p++;
1952 } else if (c == '\n') {
1953 file->line_num++;
1954 goto add_char;
1955 } else if (c == '\r') {
1956 PEEKC_EOB(c, p);
1957 if (c != '\n') {
1958 cstr_ccat(str, '\r');
1959 } else {
1960 file->line_num++;
1961 goto add_char;
1963 } else {
1964 add_char:
1965 if (str)
1966 cstr_ccat(str, c);
1967 p++;
1970 p++;
1971 return p;
1974 /* skip block of text until #else, #elif or #endif. skip also pairs of
1975 #if/#endif */
1976 void preprocess_skip(void)
1978 int a, start_of_line, c;
1979 uint8_t *p;
1981 p = file->buf_ptr;
1982 start_of_line = 1;
1983 a = 0;
1984 for(;;) {
1985 redo_no_start:
1986 c = *p;
1987 switch(c) {
1988 case ' ':
1989 case '\t':
1990 case '\f':
1991 case '\v':
1992 case '\r':
1993 p++;
1994 goto redo_no_start;
1995 case '\n':
1996 start_of_line = 1;
1997 file->line_num++;
1998 p++;
1999 goto redo_no_start;
2000 case '\\':
2001 file->buf_ptr = p;
2002 c = handle_eob();
2003 if (c == CH_EOF) {
2004 expect("#endif");
2005 } else if (c == '\\') {
2006 /* XXX: incorrect: should not give an error */
2007 ch = file->buf_ptr[0];
2008 handle_stray();
2010 p = file->buf_ptr;
2011 goto redo_no_start;
2012 /* skip strings */
2013 case '\"':
2014 case '\'':
2015 p = parse_pp_string(p, c, NULL);
2016 break;
2017 /* skip comments */
2018 case '/':
2019 file->buf_ptr = p;
2020 ch = *p;
2021 minp();
2022 p = file->buf_ptr;
2023 if (ch == '*') {
2024 p = parse_comment(p);
2025 } else if (ch == '/') {
2026 p = parse_line_comment(p);
2028 break;
2030 case '#':
2031 p++;
2032 if (start_of_line) {
2033 file->buf_ptr = p;
2034 next_nomacro();
2035 p = file->buf_ptr;
2036 if (a == 0 &&
2037 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
2038 goto the_end;
2039 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
2040 a++;
2041 else if (tok == TOK_ENDIF)
2042 a--;
2044 break;
2045 default:
2046 p++;
2047 break;
2049 start_of_line = 0;
2051 the_end: ;
2052 file->buf_ptr = p;
2055 /* ParseState handling */
2057 /* XXX: currently, no include file info is stored. Thus, we cannot display
2058 accurate messages if the function or data definition spans multiple
2059 files */
2061 /* save current parse state in 's' */
2062 void save_parse_state(ParseState *s)
2064 s->line_num = file->line_num;
2065 s->macro_ptr = macro_ptr;
2066 s->tok = tok;
2067 s->tokc = tokc;
2070 /* restore parse state from 's' */
2071 void restore_parse_state(ParseState *s)
2073 file->line_num = s->line_num;
2074 macro_ptr = s->macro_ptr;
2075 tok = s->tok;
2076 tokc = s->tokc;
2079 /* return the number of additional 'ints' necessary to store the
2080 token */
2081 static inline int tok_ext_size(int t)
2083 switch(t) {
2084 /* 4 bytes */
2085 case TOK_CINT:
2086 case TOK_CUINT:
2087 case TOK_CCHAR:
2088 case TOK_LCHAR:
2089 case TOK_STR:
2090 case TOK_LSTR:
2091 case TOK_CFLOAT:
2092 case TOK_LINENUM:
2093 case TOK_PPNUM:
2094 return 1;
2095 case TOK_CDOUBLE:
2096 case TOK_CLLONG:
2097 case TOK_CULLONG:
2098 return 2;
2099 case TOK_CLDOUBLE:
2100 return LDOUBLE_SIZE / 4;
2101 default:
2102 return 0;
2106 /* token string handling */
2108 static inline void tok_str_new(TokenString *s)
2110 s->str = NULL;
2111 s->len = 0;
2112 s->allocated_len = 0;
2113 s->last_line_num = -1;
2116 static void tok_str_free(int *str)
2118 const int *p;
2119 CString *cstr;
2120 int t;
2122 p = str;
2123 for(;;) {
2124 t = *p;
2125 /* NOTE: we test zero separately so that GCC can generate a
2126 table for the following switch */
2127 if (t == 0)
2128 break;
2129 switch(t) {
2130 case TOK_CINT:
2131 case TOK_CUINT:
2132 case TOK_CCHAR:
2133 case TOK_LCHAR:
2134 case TOK_CFLOAT:
2135 case TOK_LINENUM:
2136 p += 2;
2137 break;
2138 case TOK_PPNUM:
2139 case TOK_STR:
2140 case TOK_LSTR:
2141 /* XXX: use a macro to be portable on 64 bit ? */
2142 cstr = (CString *)p[1];
2143 cstr_free(cstr);
2144 tcc_free(cstr);
2145 p += 2;
2146 break;
2147 case TOK_CDOUBLE:
2148 case TOK_CLLONG:
2149 case TOK_CULLONG:
2150 p += 3;
2151 break;
2152 case TOK_CLDOUBLE:
2153 p += 1 + (LDOUBLE_SIZE / 4);
2154 break;
2155 default:
2156 p++;
2157 break;
2160 tcc_free(str);
2163 static int *tok_str_realloc(TokenString *s)
2165 int *str, len;
2167 len = s->allocated_len + TOK_STR_ALLOC_INCR;
2168 str = tcc_realloc(s->str, len * sizeof(int));
2169 if (!str)
2170 error("memory full");
2171 s->allocated_len = len;
2172 s->str = str;
2173 return str;
2176 static void tok_str_add(TokenString *s, int t)
2178 int len, *str;
2180 len = s->len;
2181 str = s->str;
2182 if (len >= s->allocated_len)
2183 str = tok_str_realloc(s);
2184 str[len++] = t;
2185 s->len = len;
2188 static void tok_str_add2(TokenString *s, int t, CValue *cv)
2190 int len, *str;
2192 len = s->len;
2193 str = s->str;
2195 /* allocate space for worst case */
2196 if (len + TOK_MAX_SIZE > s->allocated_len)
2197 str = tok_str_realloc(s);
2198 str[len++] = t;
2199 switch(t) {
2200 case TOK_CINT:
2201 case TOK_CUINT:
2202 case TOK_CCHAR:
2203 case TOK_LCHAR:
2204 case TOK_CFLOAT:
2205 case TOK_LINENUM:
2206 str[len++] = cv->tab[0];
2207 break;
2208 case TOK_PPNUM:
2209 case TOK_STR:
2210 case TOK_LSTR:
2211 str[len++] = (int)cstr_dup(cv->cstr);
2212 break;
2213 case TOK_CDOUBLE:
2214 case TOK_CLLONG:
2215 case TOK_CULLONG:
2216 str[len++] = cv->tab[0];
2217 str[len++] = cv->tab[1];
2218 break;
2219 case TOK_CLDOUBLE:
2220 #if LDOUBLE_SIZE == 12
2221 str[len++] = cv->tab[0];
2222 str[len++] = cv->tab[1];
2223 str[len++] = cv->tab[2];
2224 #else
2225 #error add long double size support
2226 #endif
2227 break;
2228 default:
2229 break;
2231 s->len = len;
2234 /* add the current parse token in token string 's' */
2235 static void tok_str_add_tok(TokenString *s)
2237 CValue cval;
2239 /* save line number info */
2240 if (file->line_num != s->last_line_num) {
2241 s->last_line_num = file->line_num;
2242 cval.i = s->last_line_num;
2243 tok_str_add2(s, TOK_LINENUM, &cval);
2245 tok_str_add2(s, tok, &tokc);
2248 #if LDOUBLE_SIZE == 12
2249 #define LDOUBLE_GET(p, cv) \
2250 cv.tab[0] = p[0]; \
2251 cv.tab[1] = p[1]; \
2252 cv.tab[2] = p[2];
2253 #else
2254 #error add long double size support
2255 #endif
2258 /* get a token from an integer array and increment pointer
2259 accordingly. we code it as a macro to avoid pointer aliasing. */
2260 #define TOK_GET(t, p, cv) \
2262 t = *p++; \
2263 switch(t) { \
2264 case TOK_CINT: \
2265 case TOK_CUINT: \
2266 case TOK_CCHAR: \
2267 case TOK_LCHAR: \
2268 case TOK_CFLOAT: \
2269 case TOK_LINENUM: \
2270 case TOK_STR: \
2271 case TOK_LSTR: \
2272 case TOK_PPNUM: \
2273 cv.tab[0] = *p++; \
2274 break; \
2275 case TOK_CDOUBLE: \
2276 case TOK_CLLONG: \
2277 case TOK_CULLONG: \
2278 cv.tab[0] = p[0]; \
2279 cv.tab[1] = p[1]; \
2280 p += 2; \
2281 break; \
2282 case TOK_CLDOUBLE: \
2283 LDOUBLE_GET(p, cv); \
2284 p += LDOUBLE_SIZE / 4; \
2285 break; \
2286 default: \
2287 break; \
2291 /* defines handling */
2292 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
2294 Sym *s;
2296 s = sym_push2(&define_stack, v, macro_type, (int)str);
2297 s->next = first_arg;
2298 table_ident[v - TOK_IDENT]->sym_define = s;
2301 /* undefined a define symbol. Its name is just set to zero */
2302 static void define_undef(Sym *s)
2304 int v;
2305 v = s->v;
2306 if (v >= TOK_IDENT && v < tok_ident)
2307 table_ident[v - TOK_IDENT]->sym_define = NULL;
2308 s->v = 0;
2311 static inline Sym *define_find(int v)
2313 v -= TOK_IDENT;
2314 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2315 return NULL;
2316 return table_ident[v]->sym_define;
2319 /* free define stack until top reaches 'b' */
2320 static void free_defines(Sym *b)
2322 Sym *top, *top1;
2323 int v;
2325 top = define_stack;
2326 while (top != b) {
2327 top1 = top->prev;
2328 /* do not free args or predefined defines */
2329 if (top->c)
2330 tok_str_free((int *)top->c);
2331 v = top->v;
2332 if (v >= TOK_IDENT && v < tok_ident)
2333 table_ident[v - TOK_IDENT]->sym_define = NULL;
2334 tcc_free(top);
2335 top = top1;
2337 define_stack = b;
2340 /* label lookup */
2341 static Sym *label_find(int v)
2343 v -= TOK_IDENT;
2344 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2345 return NULL;
2346 return table_ident[v]->sym_label;
2349 static Sym *label_push(Sym **ptop, int v, int flags)
2351 Sym *s, **ps;
2352 s = sym_push2(ptop, v, 0, 0);
2353 s->r = flags;
2354 ps = &table_ident[v - TOK_IDENT]->sym_label;
2355 if (ptop == &global_label_stack) {
2356 /* modify the top most local identifier, so that
2357 sym_identifier will point to 's' when popped */
2358 while (*ps != NULL)
2359 ps = &(*ps)->prev_tok;
2361 s->prev_tok = *ps;
2362 *ps = s;
2363 return s;
2366 /* pop labels until element last is reached. Look if any labels are
2367 undefined. Define symbols if '&&label' was used. */
2368 static void label_pop(Sym **ptop, Sym *slast)
2370 Sym *s, *s1;
2371 for(s = *ptop; s != slast; s = s1) {
2372 s1 = s->prev;
2373 if (s->r == LABEL_DECLARED) {
2374 warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
2375 } else if (s->r == LABEL_FORWARD) {
2376 error("label '%s' used but not defined",
2377 get_tok_str(s->v, NULL));
2378 } else {
2379 if (s->c) {
2380 /* define corresponding symbol. A size of
2381 1 is put. */
2382 put_extern_sym(s, cur_text_section, (long)s->next, 1);
2385 /* remove label */
2386 table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
2387 tcc_free(s);
2389 *ptop = slast;
2392 /* eval an expression for #if/#elif */
2393 static int expr_preprocess(void)
2395 int c, t;
2396 TokenString str;
2398 tok_str_new(&str);
2399 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2400 next(); /* do macro subst */
2401 if (tok == TOK_DEFINED) {
2402 next_nomacro();
2403 t = tok;
2404 if (t == '(')
2405 next_nomacro();
2406 c = define_find(tok) != 0;
2407 if (t == '(')
2408 next_nomacro();
2409 tok = TOK_CINT;
2410 tokc.i = c;
2411 } else if (tok >= TOK_IDENT) {
2412 /* if undefined macro */
2413 tok = TOK_CINT;
2414 tokc.i = 0;
2416 tok_str_add_tok(&str);
2418 tok_str_add(&str, -1); /* simulate end of file */
2419 tok_str_add(&str, 0);
2420 /* now evaluate C constant expression */
2421 macro_ptr = str.str;
2422 next();
2423 c = expr_const();
2424 macro_ptr = NULL;
2425 tok_str_free(str.str);
2426 return c != 0;
2429 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2430 static void tok_print(int *str)
2432 int t;
2433 CValue cval;
2435 while (1) {
2436 TOK_GET(t, str, cval);
2437 if (!t)
2438 break;
2439 printf(" %s", get_tok_str(t, &cval));
2441 printf("\n");
2443 #endif
2445 /* parse after #define */
2446 static void parse_define(void)
2448 Sym *s, *first, **ps;
2449 int v, t, varg, is_vaargs, c;
2450 TokenString str;
2452 v = tok;
2453 if (v < TOK_IDENT)
2454 error("invalid macro name '%s'", get_tok_str(tok, &tokc));
2455 /* XXX: should check if same macro (ANSI) */
2456 first = NULL;
2457 t = MACRO_OBJ;
2458 /* '(' must be just after macro definition for MACRO_FUNC */
2459 c = file->buf_ptr[0];
2460 if (c == '\\')
2461 c = handle_stray1(file->buf_ptr);
2462 if (c == '(') {
2463 next_nomacro();
2464 next_nomacro();
2465 ps = &first;
2466 while (tok != ')') {
2467 varg = tok;
2468 next_nomacro();
2469 is_vaargs = 0;
2470 if (varg == TOK_DOTS) {
2471 varg = TOK___VA_ARGS__;
2472 is_vaargs = 1;
2473 } else if (tok == TOK_DOTS && gnu_ext) {
2474 is_vaargs = 1;
2475 next_nomacro();
2477 if (varg < TOK_IDENT)
2478 error("badly punctuated parameter list");
2479 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
2480 *ps = s;
2481 ps = &s->next;
2482 if (tok != ',')
2483 break;
2484 next_nomacro();
2486 t = MACRO_FUNC;
2488 tok_str_new(&str);
2489 next_nomacro();
2490 /* EOF testing necessary for '-D' handling */
2491 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2492 tok_str_add2(&str, tok, &tokc);
2493 next_nomacro();
2495 tok_str_add(&str, 0);
2496 #ifdef PP_DEBUG
2497 printf("define %s %d: ", get_tok_str(v, NULL), t);
2498 tok_print(str.str);
2499 #endif
2500 define_push(v, t, str.str, first);
2503 /* XXX: use a token or a hash table to accelerate matching ? */
2504 static CachedInclude *search_cached_include(TCCState *s1,
2505 int type, const char *filename)
2507 CachedInclude *e;
2508 int i;
2510 for(i = 0;i < s1->nb_cached_includes; i++) {
2511 e = s1->cached_includes[i];
2512 if (e->type == type && !strcmp(e->filename, filename))
2513 return e;
2515 return NULL;
2518 static inline void add_cached_include(TCCState *s1, int type,
2519 const char *filename, int ifndef_macro)
2521 CachedInclude *e;
2523 if (search_cached_include(s1, type, filename))
2524 return;
2525 #ifdef INC_DEBUG
2526 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
2527 #endif
2528 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
2529 if (!e)
2530 return;
2531 e->type = type;
2532 strcpy(e->filename, filename);
2533 e->ifndef_macro = ifndef_macro;
2534 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
2537 /* is_bof is true if first non space token at beginning of file */
2538 static void preprocess(int is_bof)
2540 TCCState *s1 = tcc_state;
2541 int size, i, c, n, saved_parse_flags;
2542 char buf[1024], *q, *p;
2543 char buf1[1024];
2544 BufferedFile *f;
2545 Sym *s;
2546 CachedInclude *e;
2548 saved_parse_flags = parse_flags;
2549 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
2550 PARSE_FLAG_LINEFEED;
2551 next_nomacro();
2552 redo:
2553 switch(tok) {
2554 case TOK_DEFINE:
2555 next_nomacro();
2556 parse_define();
2557 break;
2558 case TOK_UNDEF:
2559 next_nomacro();
2560 s = define_find(tok);
2561 /* undefine symbol by putting an invalid name */
2562 if (s)
2563 define_undef(s);
2564 break;
2565 case TOK_INCLUDE:
2566 ch = file->buf_ptr[0];
2567 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2568 skip_spaces();
2569 if (ch == '<') {
2570 c = '>';
2571 goto read_name;
2572 } else if (ch == '\"') {
2573 c = ch;
2574 read_name:
2575 /* XXX: better stray handling */
2576 minp();
2577 q = buf;
2578 while (ch != c && ch != '\n' && ch != CH_EOF) {
2579 if ((q - buf) < sizeof(buf) - 1)
2580 *q++ = ch;
2581 minp();
2583 *q = '\0';
2584 minp();
2585 #if 0
2586 /* eat all spaces and comments after include */
2587 /* XXX: slightly incorrect */
2588 while (ch1 != '\n' && ch1 != CH_EOF)
2589 inp();
2590 #endif
2591 } else {
2592 /* computed #include : either we have only strings or
2593 we have anything enclosed in '<>' */
2594 next();
2595 buf[0] = '\0';
2596 if (tok == TOK_STR) {
2597 while (tok != TOK_LINEFEED) {
2598 if (tok != TOK_STR) {
2599 include_syntax:
2600 error("'#include' expects \"FILENAME\" or <FILENAME>");
2602 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2603 next();
2605 c = '\"';
2606 } else {
2607 int len;
2608 while (tok != TOK_LINEFEED) {
2609 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2610 next();
2612 len = strlen(buf);
2613 /* check syntax and remove '<>' */
2614 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2615 goto include_syntax;
2616 memmove(buf, buf + 1, len - 2);
2617 buf[len - 2] = '\0';
2618 c = '>';
2622 e = search_cached_include(s1, c, buf);
2623 if (e && define_find(e->ifndef_macro)) {
2624 /* no need to parse the include because the 'ifndef macro'
2625 is defined */
2626 #ifdef INC_DEBUG
2627 printf("%s: skipping %s\n", file->filename, buf);
2628 #endif
2629 } else {
2630 if (c == '\"') {
2631 /* first search in current dir if "header.h" */
2632 size = 0;
2633 p = strrchr(file->filename, '/');
2634 if (p)
2635 size = p + 1 - file->filename;
2636 if (size > sizeof(buf1) - 1)
2637 size = sizeof(buf1) - 1;
2638 memcpy(buf1, file->filename, size);
2639 buf1[size] = '\0';
2640 pstrcat(buf1, sizeof(buf1), buf);
2641 f = tcc_open(s1, buf1);
2642 if (f)
2643 goto found;
2645 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2646 error("#include recursion too deep");
2647 /* now search in all the include paths */
2648 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2649 for(i = 0; i < n; i++) {
2650 const char *path;
2651 if (i < s1->nb_include_paths)
2652 path = s1->include_paths[i];
2653 else
2654 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2655 pstrcpy(buf1, sizeof(buf1), path);
2656 pstrcat(buf1, sizeof(buf1), "/");
2657 pstrcat(buf1, sizeof(buf1), buf);
2658 f = tcc_open(s1, buf1);
2659 if (f)
2660 goto found;
2662 error("include file '%s' not found", buf);
2663 f = NULL;
2664 found:
2665 #ifdef INC_DEBUG
2666 printf("%s: including %s\n", file->filename, buf1);
2667 #endif
2668 f->inc_type = c;
2669 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2670 /* push current file in stack */
2671 /* XXX: fix current line init */
2672 *s1->include_stack_ptr++ = file;
2673 file = f;
2674 /* add include file debug info */
2675 if (do_debug) {
2676 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2678 tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
2679 ch = file->buf_ptr[0];
2680 goto the_end;
2682 break;
2683 case TOK_IFNDEF:
2684 c = 1;
2685 goto do_ifdef;
2686 case TOK_IF:
2687 c = expr_preprocess();
2688 goto do_if;
2689 case TOK_IFDEF:
2690 c = 0;
2691 do_ifdef:
2692 next_nomacro();
2693 if (tok < TOK_IDENT)
2694 error("invalid argument for '#if%sdef'", c ? "n" : "");
2695 if (is_bof) {
2696 if (c) {
2697 #ifdef INC_DEBUG
2698 printf("#ifndef %s\n", get_tok_str(tok, NULL));
2699 #endif
2700 file->ifndef_macro = tok;
2703 c = (define_find(tok) != 0) ^ c;
2704 do_if:
2705 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2706 error("memory full");
2707 *s1->ifdef_stack_ptr++ = c;
2708 goto test_skip;
2709 case TOK_ELSE:
2710 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2711 error("#else without matching #if");
2712 if (s1->ifdef_stack_ptr[-1] & 2)
2713 error("#else after #else");
2714 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2715 goto test_skip;
2716 case TOK_ELIF:
2717 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2718 error("#elif without matching #if");
2719 c = s1->ifdef_stack_ptr[-1];
2720 if (c > 1)
2721 error("#elif after #else");
2722 /* last #if/#elif expression was true: we skip */
2723 if (c == 1)
2724 goto skip;
2725 c = expr_preprocess();
2726 s1->ifdef_stack_ptr[-1] = c;
2727 test_skip:
2728 if (!(c & 1)) {
2729 skip:
2730 preprocess_skip();
2731 is_bof = 0;
2732 goto redo;
2734 break;
2735 case TOK_ENDIF:
2736 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2737 error("#endif without matching #if");
2738 s1->ifdef_stack_ptr--;
2739 /* '#ifndef macro' was at the start of file. Now we check if
2740 an '#endif' is exactly at the end of file */
2741 if (file->ifndef_macro &&
2742 s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
2743 file->ifndef_macro_saved = file->ifndef_macro;
2744 /* need to set to zero to avoid false matches if another
2745 #ifndef at middle of file */
2746 file->ifndef_macro = 0;
2747 while (tok != TOK_LINEFEED)
2748 next_nomacro();
2749 tok_flags |= TOK_FLAG_ENDIF;
2750 goto the_end;
2752 break;
2753 case TOK_LINE:
2754 next();
2755 if (tok != TOK_CINT)
2756 error("#line");
2757 file->line_num = tokc.i - 1; /* the line number will be incremented after */
2758 next();
2759 if (tok != TOK_LINEFEED) {
2760 if (tok != TOK_STR)
2761 error("#line");
2762 pstrcpy(file->filename, sizeof(file->filename),
2763 (char *)tokc.cstr->data);
2765 break;
2766 case TOK_ERROR:
2767 case TOK_WARNING:
2768 c = tok;
2769 ch = file->buf_ptr[0];
2770 skip_spaces();
2771 q = buf;
2772 while (ch != '\n' && ch != CH_EOF) {
2773 if ((q - buf) < sizeof(buf) - 1)
2774 *q++ = ch;
2775 minp();
2777 *q = '\0';
2778 if (c == TOK_ERROR)
2779 error("#error %s", buf);
2780 else
2781 warning("#warning %s", buf);
2782 break;
2783 case TOK_PRAGMA:
2784 /* ignored */
2785 break;
2786 default:
2787 if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
2788 /* '!' is ignored to allow C scripts. numbers are ignored
2789 to emulate cpp behaviour */
2790 } else {
2791 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
2793 break;
2795 /* ignore other preprocess commands or #! for C scripts */
2796 while (tok != TOK_LINEFEED)
2797 next_nomacro();
2798 the_end:
2799 parse_flags = saved_parse_flags;
2802 /* evaluate escape codes in a string. */
2803 static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
2805 int c, n;
2806 const char *p;
2808 p = buf;
2809 for(;;) {
2810 c = *p;
2811 if (c == '\0')
2812 break;
2813 if (c == '\\') {
2814 p++;
2815 /* escape */
2816 c = *p;
2817 switch(c) {
2818 case '0': case '1': case '2': case '3':
2819 case '4': case '5': case '6': case '7':
2820 /* at most three octal digits */
2821 n = c - '0';
2822 p++;
2823 c = *p;
2824 if (isoct(c)) {
2825 n = n * 8 + c - '0';
2826 p++;
2827 c = *p;
2828 if (isoct(c)) {
2829 n = n * 8 + c - '0';
2830 p++;
2833 c = n;
2834 goto add_char_nonext;
2835 case 'x':
2836 p++;
2837 n = 0;
2838 for(;;) {
2839 c = *p;
2840 if (c >= 'a' && c <= 'f')
2841 c = c - 'a' + 10;
2842 else if (c >= 'A' && c <= 'F')
2843 c = c - 'A' + 10;
2844 else if (isnum(c))
2845 c = c - '0';
2846 else
2847 break;
2848 n = n * 16 + c;
2849 p++;
2851 c = n;
2852 goto add_char_nonext;
2853 case 'a':
2854 c = '\a';
2855 break;
2856 case 'b':
2857 c = '\b';
2858 break;
2859 case 'f':
2860 c = '\f';
2861 break;
2862 case 'n':
2863 c = '\n';
2864 break;
2865 case 'r':
2866 c = '\r';
2867 break;
2868 case 't':
2869 c = '\t';
2870 break;
2871 case 'v':
2872 c = '\v';
2873 break;
2874 case 'e':
2875 if (!gnu_ext)
2876 goto invalid_escape;
2877 c = 27;
2878 break;
2879 case '\'':
2880 case '\"':
2881 case '\\':
2882 case '?':
2883 break;
2884 default:
2885 invalid_escape:
2886 error("invalid escaped char");
2889 p++;
2890 add_char_nonext:
2891 if (!is_long)
2892 cstr_ccat(outstr, c);
2893 else
2894 cstr_wccat(outstr, c);
2896 /* add a trailing '\0' */
2897 if (!is_long)
2898 cstr_ccat(outstr, '\0');
2899 else
2900 cstr_wccat(outstr, '\0');
2903 /* we use 64 bit numbers */
2904 #define BN_SIZE 2
2906 /* bn = (bn << shift) | or_val */
2907 void bn_lshift(unsigned int *bn, int shift, int or_val)
2909 int i;
2910 unsigned int v;
2911 for(i=0;i<BN_SIZE;i++) {
2912 v = bn[i];
2913 bn[i] = (v << shift) | or_val;
2914 or_val = v >> (32 - shift);
2918 void bn_zero(unsigned int *bn)
2920 int i;
2921 for(i=0;i<BN_SIZE;i++) {
2922 bn[i] = 0;
2926 /* parse number in null terminated string 'p' and return it in the
2927 current token */
2928 void parse_number(const char *p)
2930 int b, t, shift, frac_bits, s, exp_val, ch;
2931 char *q;
2932 unsigned int bn[BN_SIZE];
2933 double d;
2935 /* number */
2936 q = token_buf;
2937 ch = *p++;
2938 t = ch;
2939 ch = *p++;
2940 *q++ = t;
2941 b = 10;
2942 if (t == '.') {
2943 goto float_frac_parse;
2944 } else if (t == '0') {
2945 if (ch == 'x' || ch == 'X') {
2946 q--;
2947 ch = *p++;
2948 b = 16;
2949 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2950 q--;
2951 ch = *p++;
2952 b = 2;
2955 /* parse all digits. cannot check octal numbers at this stage
2956 because of floating point constants */
2957 while (1) {
2958 if (ch >= 'a' && ch <= 'f')
2959 t = ch - 'a' + 10;
2960 else if (ch >= 'A' && ch <= 'F')
2961 t = ch - 'A' + 10;
2962 else if (isnum(ch))
2963 t = ch - '0';
2964 else
2965 break;
2966 if (t >= b)
2967 break;
2968 if (q >= token_buf + STRING_MAX_SIZE) {
2969 num_too_long:
2970 error("number too long");
2972 *q++ = ch;
2973 ch = *p++;
2975 if (ch == '.' ||
2976 ((ch == 'e' || ch == 'E') && b == 10) ||
2977 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2978 if (b != 10) {
2979 /* NOTE: strtox should support that for hexa numbers, but
2980 non ISOC99 libcs do not support it, so we prefer to do
2981 it by hand */
2982 /* hexadecimal or binary floats */
2983 /* XXX: handle overflows */
2984 *q = '\0';
2985 if (b == 16)
2986 shift = 4;
2987 else
2988 shift = 2;
2989 bn_zero(bn);
2990 q = token_buf;
2991 while (1) {
2992 t = *q++;
2993 if (t == '\0') {
2994 break;
2995 } else if (t >= 'a') {
2996 t = t - 'a' + 10;
2997 } else if (t >= 'A') {
2998 t = t - 'A' + 10;
2999 } else {
3000 t = t - '0';
3002 bn_lshift(bn, shift, t);
3004 frac_bits = 0;
3005 if (ch == '.') {
3006 ch = *p++;
3007 while (1) {
3008 t = ch;
3009 if (t >= 'a' && t <= 'f') {
3010 t = t - 'a' + 10;
3011 } else if (t >= 'A' && t <= 'F') {
3012 t = t - 'A' + 10;
3013 } else if (t >= '0' && t <= '9') {
3014 t = t - '0';
3015 } else {
3016 break;
3018 if (t >= b)
3019 error("invalid digit");
3020 bn_lshift(bn, shift, t);
3021 frac_bits += shift;
3022 ch = *p++;
3025 if (ch != 'p' && ch != 'P')
3026 expect("exponent");
3027 ch = *p++;
3028 s = 1;
3029 exp_val = 0;
3030 if (ch == '+') {
3031 ch = *p++;
3032 } else if (ch == '-') {
3033 s = -1;
3034 ch = *p++;
3036 if (ch < '0' || ch > '9')
3037 expect("exponent digits");
3038 while (ch >= '0' && ch <= '9') {
3039 exp_val = exp_val * 10 + ch - '0';
3040 ch = *p++;
3042 exp_val = exp_val * s;
3044 /* now we can generate the number */
3045 /* XXX: should patch directly float number */
3046 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
3047 d = ldexp(d, exp_val - frac_bits);
3048 t = toup(ch);
3049 if (t == 'F') {
3050 ch = *p++;
3051 tok = TOK_CFLOAT;
3052 /* float : should handle overflow */
3053 tokc.f = (float)d;
3054 } else if (t == 'L') {
3055 ch = *p++;
3056 tok = TOK_CLDOUBLE;
3057 /* XXX: not large enough */
3058 tokc.ld = (long double)d;
3059 } else {
3060 tok = TOK_CDOUBLE;
3061 tokc.d = d;
3063 } else {
3064 /* decimal floats */
3065 if (ch == '.') {
3066 if (q >= token_buf + STRING_MAX_SIZE)
3067 goto num_too_long;
3068 *q++ = ch;
3069 ch = *p++;
3070 float_frac_parse:
3071 while (ch >= '0' && ch <= '9') {
3072 if (q >= token_buf + STRING_MAX_SIZE)
3073 goto num_too_long;
3074 *q++ = ch;
3075 ch = *p++;
3078 if (ch == 'e' || ch == 'E') {
3079 if (q >= token_buf + STRING_MAX_SIZE)
3080 goto num_too_long;
3081 *q++ = ch;
3082 ch = *p++;
3083 if (ch == '-' || ch == '+') {
3084 if (q >= token_buf + STRING_MAX_SIZE)
3085 goto num_too_long;
3086 *q++ = ch;
3087 ch = *p++;
3089 if (ch < '0' || ch > '9')
3090 expect("exponent digits");
3091 while (ch >= '0' && ch <= '9') {
3092 if (q >= token_buf + STRING_MAX_SIZE)
3093 goto num_too_long;
3094 *q++ = ch;
3095 ch = *p++;
3098 *q = '\0';
3099 t = toup(ch);
3100 errno = 0;
3101 if (t == 'F') {
3102 ch = *p++;
3103 tok = TOK_CFLOAT;
3104 tokc.f = strtof(token_buf, NULL);
3105 } else if (t == 'L') {
3106 ch = *p++;
3107 tok = TOK_CLDOUBLE;
3108 tokc.ld = strtold(token_buf, NULL);
3109 } else {
3110 tok = TOK_CDOUBLE;
3111 tokc.d = strtod(token_buf, NULL);
3114 } else {
3115 unsigned long long n, n1;
3116 int lcount, ucount;
3118 /* integer number */
3119 *q = '\0';
3120 q = token_buf;
3121 if (b == 10 && *q == '0') {
3122 b = 8;
3123 q++;
3125 n = 0;
3126 while(1) {
3127 t = *q++;
3128 /* no need for checks except for base 10 / 8 errors */
3129 if (t == '\0') {
3130 break;
3131 } else if (t >= 'a') {
3132 t = t - 'a' + 10;
3133 } else if (t >= 'A') {
3134 t = t - 'A' + 10;
3135 } else {
3136 t = t - '0';
3137 if (t >= b)
3138 error("invalid digit");
3140 n1 = n;
3141 n = n * b + t;
3142 /* detect overflow */
3143 /* XXX: this test is not reliable */
3144 if (n < n1)
3145 error("integer constant overflow");
3148 /* XXX: not exactly ANSI compliant */
3149 if ((n & 0xffffffff00000000LL) != 0) {
3150 if ((n >> 63) != 0)
3151 tok = TOK_CULLONG;
3152 else
3153 tok = TOK_CLLONG;
3154 } else if (n > 0x7fffffff) {
3155 tok = TOK_CUINT;
3156 } else {
3157 tok = TOK_CINT;
3159 lcount = 0;
3160 ucount = 0;
3161 for(;;) {
3162 t = toup(ch);
3163 if (t == 'L') {
3164 if (lcount >= 2)
3165 error("three 'l's in integer constant");
3166 lcount++;
3167 if (lcount == 2) {
3168 if (tok == TOK_CINT)
3169 tok = TOK_CLLONG;
3170 else if (tok == TOK_CUINT)
3171 tok = TOK_CULLONG;
3173 ch = *p++;
3174 } else if (t == 'U') {
3175 if (ucount >= 1)
3176 error("two 'u's in integer constant");
3177 ucount++;
3178 if (tok == TOK_CINT)
3179 tok = TOK_CUINT;
3180 else if (tok == TOK_CLLONG)
3181 tok = TOK_CULLONG;
3182 ch = *p++;
3183 } else {
3184 break;
3187 if (tok == TOK_CINT || tok == TOK_CUINT)
3188 tokc.ui = n;
3189 else
3190 tokc.ull = n;
3195 #define PARSE2(c1, tok1, c2, tok2) \
3196 case c1: \
3197 PEEKC(c, p); \
3198 if (c == c2) { \
3199 p++; \
3200 tok = tok2; \
3201 } else { \
3202 tok = tok1; \
3204 break;
3206 /* return next token without macro substitution */
3207 static inline void next_nomacro1(void)
3209 int t, c, is_long;
3210 TokenSym *ts;
3211 uint8_t *p, *p1;
3212 unsigned int h;
3214 p = file->buf_ptr;
3215 redo_no_start:
3216 c = *p;
3217 switch(c) {
3218 case ' ':
3219 case '\t':
3220 case '\f':
3221 case '\v':
3222 case '\r':
3223 p++;
3224 goto redo_no_start;
3226 case '\\':
3227 /* first look if it is in fact an end of buffer */
3228 if (p >= file->buf_end) {
3229 file->buf_ptr = p;
3230 handle_eob();
3231 p = file->buf_ptr;
3232 if (p >= file->buf_end)
3233 goto parse_eof;
3234 else
3235 goto redo_no_start;
3236 } else {
3237 file->buf_ptr = p;
3238 ch = *p;
3239 handle_stray();
3240 p = file->buf_ptr;
3241 goto redo_no_start;
3243 parse_eof:
3245 TCCState *s1 = tcc_state;
3246 if (parse_flags & PARSE_FLAG_LINEFEED) {
3247 tok = TOK_LINEFEED;
3248 } else if (s1->include_stack_ptr == s1->include_stack ||
3249 !(parse_flags & PARSE_FLAG_PREPROCESS)) {
3250 /* no include left : end of file. */
3251 tok = TOK_EOF;
3252 } else {
3253 /* pop include file */
3255 /* test if previous '#endif' was after a #ifdef at
3256 start of file */
3257 if (tok_flags & TOK_FLAG_ENDIF) {
3258 #ifdef INC_DEBUG
3259 printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
3260 #endif
3261 add_cached_include(s1, file->inc_type, file->inc_filename,
3262 file->ifndef_macro_saved);
3265 /* add end of include file debug info */
3266 if (do_debug) {
3267 put_stabd(N_EINCL, 0, 0);
3269 /* pop include stack */
3270 tcc_close(file);
3271 s1->include_stack_ptr--;
3272 file = *s1->include_stack_ptr;
3273 p = file->buf_ptr;
3274 goto redo_no_start;
3277 break;
3279 case '\n':
3280 if (parse_flags & PARSE_FLAG_LINEFEED) {
3281 tok = TOK_LINEFEED;
3282 } else {
3283 file->line_num++;
3284 tok_flags |= TOK_FLAG_BOL;
3285 p++;
3286 goto redo_no_start;
3288 break;
3290 case '#':
3291 /* XXX: simplify */
3292 PEEKC(c, p);
3293 if ((tok_flags & TOK_FLAG_BOL) &&
3294 (parse_flags & PARSE_FLAG_PREPROCESS)) {
3295 file->buf_ptr = p;
3296 preprocess(tok_flags & TOK_FLAG_BOF);
3297 p = file->buf_ptr;
3298 goto redo_no_start;
3299 } else {
3300 if (c == '#') {
3301 p++;
3302 tok = TOK_TWOSHARPS;
3303 } else {
3304 tok = '#';
3307 break;
3309 case 'a': case 'b': case 'c': case 'd':
3310 case 'e': case 'f': case 'g': case 'h':
3311 case 'i': case 'j': case 'k': case 'l':
3312 case 'm': case 'n': case 'o': case 'p':
3313 case 'q': case 'r': case 's': case 't':
3314 case 'u': case 'v': case 'w': case 'x':
3315 case 'y': case 'z':
3316 case 'A': case 'B': case 'C': case 'D':
3317 case 'E': case 'F': case 'G': case 'H':
3318 case 'I': case 'J': case 'K':
3319 case 'M': case 'N': case 'O': case 'P':
3320 case 'Q': case 'R': case 'S': case 'T':
3321 case 'U': case 'V': case 'W': case 'X':
3322 case 'Y': case 'Z':
3323 case '_':
3324 parse_ident_fast:
3325 p1 = p;
3326 h = TOK_HASH_INIT;
3327 h = TOK_HASH_FUNC(h, c);
3328 p++;
3329 for(;;) {
3330 c = *p;
3331 if (!isidnum_table[c])
3332 break;
3333 h = TOK_HASH_FUNC(h, c);
3334 p++;
3336 if (c != '\\') {
3337 TokenSym **pts;
3338 int len;
3340 /* fast case : no stray found, so we have the full token
3341 and we have already hashed it */
3342 len = p - p1;
3343 h &= (TOK_HASH_SIZE - 1);
3344 pts = &hash_ident[h];
3345 for(;;) {
3346 ts = *pts;
3347 if (!ts)
3348 break;
3349 if (ts->len == len && !memcmp(ts->str, p1, len))
3350 goto token_found;
3351 pts = &(ts->hash_next);
3353 ts = tok_alloc_new(pts, p1, len);
3354 token_found: ;
3355 } else {
3356 /* slower case */
3357 cstr_reset(&tokcstr);
3359 while (p1 < p) {
3360 cstr_ccat(&tokcstr, *p1);
3361 p1++;
3363 p--;
3364 PEEKC(c, p);
3365 parse_ident_slow:
3366 while (isidnum_table[c]) {
3367 cstr_ccat(&tokcstr, c);
3368 PEEKC(c, p);
3370 ts = tok_alloc(tokcstr.data, tokcstr.size);
3372 tok = ts->tok;
3373 break;
3374 case 'L':
3375 t = p[1];
3376 if (t != '\\' && t != '\'' && t != '\"') {
3377 /* fast case */
3378 goto parse_ident_fast;
3379 } else {
3380 PEEKC(c, p);
3381 if (c == '\'' || c == '\"') {
3382 is_long = 1;
3383 goto str_const;
3384 } else {
3385 cstr_reset(&tokcstr);
3386 cstr_ccat(&tokcstr, 'L');
3387 goto parse_ident_slow;
3390 break;
3391 case '0': case '1': case '2': case '3':
3392 case '4': case '5': case '6': case '7':
3393 case '8': case '9':
3395 cstr_reset(&tokcstr);
3396 /* after the first digit, accept digits, alpha, '.' or sign if
3397 prefixed by 'eEpP' */
3398 parse_num:
3399 for(;;) {
3400 t = c;
3401 cstr_ccat(&tokcstr, c);
3402 PEEKC(c, p);
3403 if (!(isnum(c) || isid(c) || c == '.' ||
3404 ((c == '+' || c == '-') &&
3405 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
3406 break;
3408 /* We add a trailing '\0' to ease parsing */
3409 cstr_ccat(&tokcstr, '\0');
3410 tokc.cstr = &tokcstr;
3411 tok = TOK_PPNUM;
3412 break;
3413 case '.':
3414 /* special dot handling because it can also start a number */
3415 PEEKC(c, p);
3416 if (isnum(c)) {
3417 cstr_reset(&tokcstr);
3418 cstr_ccat(&tokcstr, '.');
3419 goto parse_num;
3420 } else if (c == '.') {
3421 PEEKC(c, p);
3422 if (c != '.')
3423 expect("'.'");
3424 PEEKC(c, p);
3425 tok = TOK_DOTS;
3426 } else {
3427 tok = '.';
3429 break;
3430 case '\'':
3431 case '\"':
3432 is_long = 0;
3433 str_const:
3435 CString str;
3436 int sep;
3438 sep = c;
3440 /* parse the string */
3441 cstr_new(&str);
3442 p = parse_pp_string(p, sep, &str);
3443 cstr_ccat(&str, '\0');
3445 /* eval the escape (should be done as TOK_PPNUM) */
3446 cstr_reset(&tokcstr);
3447 parse_escape_string(&tokcstr, str.data, is_long);
3448 cstr_free(&str);
3450 if (sep == '\'') {
3451 int char_size;
3452 /* XXX: make it portable */
3453 if (!is_long)
3454 char_size = 1;
3455 else
3456 char_size = sizeof(int);
3457 if (tokcstr.size <= char_size)
3458 error("empty character constant");
3459 if (tokcstr.size > 2 * char_size)
3460 warning("multi-character character constant");
3461 if (!is_long) {
3462 tokc.i = *(int8_t *)tokcstr.data;
3463 tok = TOK_CCHAR;
3464 } else {
3465 tokc.i = *(int *)tokcstr.data;
3466 tok = TOK_LCHAR;
3468 } else {
3469 tokc.cstr = &tokcstr;
3470 if (!is_long)
3471 tok = TOK_STR;
3472 else
3473 tok = TOK_LSTR;
3476 break;
3478 case '<':
3479 PEEKC(c, p);
3480 if (c == '=') {
3481 p++;
3482 tok = TOK_LE;
3483 } else if (c == '<') {
3484 PEEKC(c, p);
3485 if (c == '=') {
3486 p++;
3487 tok = TOK_A_SHL;
3488 } else {
3489 tok = TOK_SHL;
3491 } else {
3492 tok = TOK_LT;
3494 break;
3496 case '>':
3497 PEEKC(c, p);
3498 if (c == '=') {
3499 p++;
3500 tok = TOK_GE;
3501 } else if (c == '>') {
3502 PEEKC(c, p);
3503 if (c == '=') {
3504 p++;
3505 tok = TOK_A_SAR;
3506 } else {
3507 tok = TOK_SAR;
3509 } else {
3510 tok = TOK_GT;
3512 break;
3514 case '&':
3515 PEEKC(c, p);
3516 if (c == '&') {
3517 p++;
3518 tok = TOK_LAND;
3519 } else if (c == '=') {
3520 p++;
3521 tok = TOK_A_AND;
3522 } else {
3523 tok = '&';
3525 break;
3527 case '|':
3528 PEEKC(c, p);
3529 if (c == '|') {
3530 p++;
3531 tok = TOK_LOR;
3532 } else if (c == '=') {
3533 p++;
3534 tok = TOK_A_OR;
3535 } else {
3536 tok = '|';
3538 break;
3540 case '+':
3541 PEEKC(c, p);
3542 if (c == '+') {
3543 p++;
3544 tok = TOK_INC;
3545 } else if (c == '=') {
3546 p++;
3547 tok = TOK_A_ADD;
3548 } else {
3549 tok = '+';
3551 break;
3553 case '-':
3554 PEEKC(c, p);
3555 if (c == '-') {
3556 p++;
3557 tok = TOK_DEC;
3558 } else if (c == '=') {
3559 p++;
3560 tok = TOK_A_SUB;
3561 } else if (c == '>') {
3562 p++;
3563 tok = TOK_ARROW;
3564 } else {
3565 tok = '-';
3567 break;
3569 PARSE2('!', '!', '=', TOK_NE)
3570 PARSE2('=', '=', '=', TOK_EQ)
3571 PARSE2('*', '*', '=', TOK_A_MUL)
3572 PARSE2('%', '%', '=', TOK_A_MOD)
3573 PARSE2('^', '^', '=', TOK_A_XOR)
3575 /* comments or operator */
3576 case '/':
3577 PEEKC(c, p);
3578 if (c == '*') {
3579 p = parse_comment(p);
3580 goto redo_no_start;
3581 } else if (c == '/') {
3582 p = parse_line_comment(p);
3583 goto redo_no_start;
3584 } else if (c == '=') {
3585 p++;
3586 tok = TOK_A_DIV;
3587 } else {
3588 tok = '/';
3590 break;
3592 /* simple tokens */
3593 case '(':
3594 case ')':
3595 case '[':
3596 case ']':
3597 case '{':
3598 case '}':
3599 case ',':
3600 case ';':
3601 case ':':
3602 case '?':
3603 case '~':
3604 case '$': /* only used in assembler */
3605 tok = c;
3606 p++;
3607 break;
3608 default:
3609 error("unrecognized character \\x%02x", c);
3610 break;
3612 file->buf_ptr = p;
3613 tok_flags = 0;
3614 #if defined(PARSE_DEBUG)
3615 printf("token = %s\n", get_tok_str(tok, &tokc));
3616 #endif
3619 /* return next token without macro substitution. Can read input from
3620 macro_ptr buffer */
3621 static void next_nomacro(void)
3623 if (macro_ptr) {
3624 redo:
3625 tok = *macro_ptr;
3626 if (tok) {
3627 TOK_GET(tok, macro_ptr, tokc);
3628 if (tok == TOK_LINENUM) {
3629 file->line_num = tokc.i;
3630 goto redo;
3633 } else {
3634 next_nomacro1();
3638 /* substitute args in macro_str and return allocated string */
3639 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
3641 int *st, last_tok, t, notfirst;
3642 Sym *s;
3643 CValue cval;
3644 TokenString str;
3645 CString cstr;
3647 tok_str_new(&str);
3648 last_tok = 0;
3649 while(1) {
3650 TOK_GET(t, macro_str, cval);
3651 if (!t)
3652 break;
3653 if (t == '#') {
3654 /* stringize */
3655 TOK_GET(t, macro_str, cval);
3656 if (!t)
3657 break;
3658 s = sym_find2(args, t);
3659 if (s) {
3660 cstr_new(&cstr);
3661 st = (int *)s->c;
3662 notfirst = 0;
3663 while (*st) {
3664 if (notfirst)
3665 cstr_ccat(&cstr, ' ');
3666 TOK_GET(t, st, cval);
3667 cstr_cat(&cstr, get_tok_str(t, &cval));
3668 notfirst = 1;
3670 cstr_ccat(&cstr, '\0');
3671 #ifdef PP_DEBUG
3672 printf("stringize: %s\n", (char *)cstr.data);
3673 #endif
3674 /* add string */
3675 cval.cstr = &cstr;
3676 tok_str_add2(&str, TOK_STR, &cval);
3677 cstr_free(&cstr);
3678 } else {
3679 tok_str_add2(&str, t, &cval);
3681 } else if (t >= TOK_IDENT) {
3682 s = sym_find2(args, t);
3683 if (s) {
3684 st = (int *)s->c;
3685 /* if '##' is present before or after, no arg substitution */
3686 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
3687 /* special case for var arg macros : ## eats the
3688 ',' if empty VA_ARGS variable. */
3689 /* XXX: test of the ',' is not 100%
3690 reliable. should fix it to avoid security
3691 problems */
3692 if (gnu_ext && s->type.t &&
3693 last_tok == TOK_TWOSHARPS &&
3694 str.len >= 2 && str.str[str.len - 2] == ',') {
3695 if (*st == 0) {
3696 /* suppress ',' '##' */
3697 str.len -= 2;
3698 } else {
3699 /* suppress '##' and add variable */
3700 str.len--;
3701 goto add_var;
3703 } else {
3704 int t1;
3705 add_var:
3706 for(;;) {
3707 TOK_GET(t1, st, cval);
3708 if (!t1)
3709 break;
3710 tok_str_add2(&str, t1, &cval);
3713 } else {
3714 /* NOTE: the stream cannot be read when macro
3715 substituing an argument */
3716 macro_subst(&str, nested_list, st, 0);
3718 } else {
3719 tok_str_add(&str, t);
3721 } else {
3722 tok_str_add2(&str, t, &cval);
3724 last_tok = t;
3726 tok_str_add(&str, 0);
3727 return str.str;
3730 static char const ab_month_name[12][4] =
3732 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
3733 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
3736 /* do macro substitution of current token with macro 's' and add
3737 result to (tok_str,tok_len). 'nested_list' is the list of all
3738 macros we got inside to avoid recursing. Return non zero if no
3739 substitution needs to be done */
3740 static int macro_subst_tok(TokenString *tok_str,
3741 Sym **nested_list, Sym *s, int can_read_stream)
3743 Sym *args, *sa, *sa1;
3744 int mstr_allocated, parlevel, *mstr, t;
3745 TokenString str;
3746 char *cstrval;
3747 CValue cval;
3748 CString cstr;
3750 /* if symbol is a macro, prepare substitution */
3752 /* special macros */
3753 if (tok == TOK___LINE__) {
3754 cval.i = file->line_num;
3755 tok_str_add2(tok_str, TOK_CINT, &cval);
3756 } else if (tok == TOK___FILE__) {
3757 cstrval = file->filename;
3758 goto add_cstr;
3759 tok_str_add2(tok_str, TOK_STR, &cval);
3760 } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
3761 time_t ti;
3762 struct tm *tm;
3763 char buf[64];
3765 time(&ti);
3766 tm = localtime(&ti);
3767 if (tok == TOK___DATE__) {
3768 snprintf(buf, sizeof(buf), "%s %2d %d",
3769 ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
3770 } else {
3771 snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
3772 tm->tm_hour, tm->tm_min, tm->tm_sec);
3774 cstrval = buf;
3775 add_cstr:
3776 cstr_new(&cstr);
3777 cstr_cat(&cstr, cstrval);
3778 cstr_ccat(&cstr, '\0');
3779 cval.cstr = &cstr;
3780 tok_str_add2(tok_str, TOK_STR, &cval);
3781 cstr_free(&cstr);
3782 } else {
3783 mstr = (int *)s->c;
3784 mstr_allocated = 0;
3785 if (s->type.t == MACRO_FUNC) {
3786 /* NOTE: we do not use next_nomacro to avoid eating the
3787 next token. XXX: find better solution */
3788 if (macro_ptr) {
3789 t = *macro_ptr;
3790 if (t == 0 && can_read_stream) {
3791 /* end of macro stream: we must look at the token
3792 after in the file */
3793 macro_ptr = NULL;
3794 goto parse_stream;
3796 } else {
3797 parse_stream:
3798 /* XXX: incorrect with comments */
3799 ch = file->buf_ptr[0];
3800 while (is_space(ch) || ch == '\n')
3801 cinp();
3802 t = ch;
3804 if (t != '(') /* no macro subst */
3805 return -1;
3807 /* argument macro */
3808 next_nomacro();
3809 next_nomacro();
3810 args = NULL;
3811 sa = s->next;
3812 /* NOTE: empty args are allowed, except if no args */
3813 for(;;) {
3814 /* handle '()' case */
3815 if (!args && tok == ')')
3816 break;
3817 if (!sa)
3818 error("macro '%s' used with too many args",
3819 get_tok_str(s->v, 0));
3820 tok_str_new(&str);
3821 parlevel = 0;
3822 /* NOTE: non zero sa->t indicates VA_ARGS */
3823 while ((parlevel > 0 ||
3824 (tok != ')' &&
3825 (tok != ',' || sa->type.t))) &&
3826 tok != -1) {
3827 if (tok == '(')
3828 parlevel++;
3829 else if (tok == ')')
3830 parlevel--;
3831 tok_str_add2(&str, tok, &tokc);
3832 next_nomacro();
3834 tok_str_add(&str, 0);
3835 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str);
3836 sa = sa->next;
3837 if (tok == ')') {
3838 /* special case for gcc var args: add an empty
3839 var arg argument if it is omitted */
3840 if (sa && sa->type.t && gnu_ext)
3841 continue;
3842 else
3843 break;
3845 if (tok != ',')
3846 expect(",");
3847 next_nomacro();
3849 if (sa) {
3850 error("macro '%s' used with too few args",
3851 get_tok_str(s->v, 0));
3854 /* now subst each arg */
3855 mstr = macro_arg_subst(nested_list, mstr, args);
3856 /* free memory */
3857 sa = args;
3858 while (sa) {
3859 sa1 = sa->prev;
3860 tok_str_free((int *)sa->c);
3861 tcc_free(sa);
3862 sa = sa1;
3864 mstr_allocated = 1;
3866 sym_push2(nested_list, s->v, 0, 0);
3867 macro_subst(tok_str, nested_list, mstr, 1);
3868 /* pop nested defined symbol */
3869 sa1 = *nested_list;
3870 *nested_list = sa1->prev;
3871 tcc_free(sa1);
3872 if (mstr_allocated)
3873 tok_str_free(mstr);
3875 return 0;
3878 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
3879 return the resulting string (which must be freed). */
3880 static inline int *macro_twosharps(const int *macro_str)
3882 TokenSym *ts;
3883 const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr;
3884 int t;
3885 const char *p1, *p2;
3886 CValue cval;
3887 TokenString macro_str1;
3888 CString cstr;
3890 start_macro_ptr = macro_str;
3891 /* we search the first '##' */
3892 for(;;) {
3893 macro_ptr1 = macro_str;
3894 TOK_GET(t, macro_str, cval);
3895 /* nothing more to do if end of string */
3896 if (t == 0)
3897 return NULL;
3898 if (*macro_str == TOK_TWOSHARPS)
3899 break;
3902 /* we saw '##', so we need more processing to handle it */
3903 cstr_new(&cstr);
3904 tok_str_new(&macro_str1);
3905 tok = t;
3906 tokc = cval;
3908 /* add all tokens seen so far */
3909 for(ptr = start_macro_ptr; ptr < macro_ptr1;) {
3910 TOK_GET(t, ptr, cval);
3911 tok_str_add2(&macro_str1, t, &cval);
3913 saved_macro_ptr = macro_ptr;
3914 /* XXX: get rid of the use of macro_ptr here */
3915 macro_ptr = (int *)macro_str;
3916 for(;;) {
3917 while (*macro_ptr == TOK_TWOSHARPS) {
3918 macro_ptr++;
3919 macro_ptr1 = macro_ptr;
3920 t = *macro_ptr;
3921 if (t) {
3922 TOK_GET(t, macro_ptr, cval);
3923 /* We concatenate the two tokens if we have an
3924 identifier or a preprocessing number */
3925 cstr_reset(&cstr);
3926 p1 = get_tok_str(tok, &tokc);
3927 cstr_cat(&cstr, p1);
3928 p2 = get_tok_str(t, &cval);
3929 cstr_cat(&cstr, p2);
3930 cstr_ccat(&cstr, '\0');
3932 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
3933 (t >= TOK_IDENT || t == TOK_PPNUM)) {
3934 if (tok == TOK_PPNUM) {
3935 /* if number, then create a number token */
3936 /* NOTE: no need to allocate because
3937 tok_str_add2() does it */
3938 tokc.cstr = &cstr;
3939 } else {
3940 /* if identifier, we must do a test to
3941 validate we have a correct identifier */
3942 if (t == TOK_PPNUM) {
3943 const char *p;
3944 int c;
3946 p = p2;
3947 for(;;) {
3948 c = *p;
3949 if (c == '\0')
3950 break;
3951 p++;
3952 if (!isnum(c) && !isid(c))
3953 goto error_pasting;
3956 ts = tok_alloc(cstr.data, strlen(cstr.data));
3957 tok = ts->tok; /* modify current token */
3959 } else {
3960 const char *str = cstr.data;
3961 const unsigned char *q;
3963 /* we look for a valid token */
3964 /* XXX: do more extensive checks */
3965 if (!strcmp(str, ">>=")) {
3966 tok = TOK_A_SAR;
3967 } else if (!strcmp(str, "<<=")) {
3968 tok = TOK_A_SHL;
3969 } else if (strlen(str) == 2) {
3970 /* search in two bytes table */
3971 q = tok_two_chars;
3972 for(;;) {
3973 if (!*q)
3974 goto error_pasting;
3975 if (q[0] == str[0] && q[1] == str[1])
3976 break;
3977 q += 3;
3979 tok = q[2];
3980 } else {
3981 error_pasting:
3982 /* NOTE: because get_tok_str use a static buffer,
3983 we must save it */
3984 cstr_reset(&cstr);
3985 p1 = get_tok_str(tok, &tokc);
3986 cstr_cat(&cstr, p1);
3987 cstr_ccat(&cstr, '\0');
3988 p2 = get_tok_str(t, &cval);
3989 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
3990 /* cannot merge tokens: just add them separately */
3991 tok_str_add2(&macro_str1, tok, &tokc);
3992 /* XXX: free associated memory ? */
3993 tok = t;
3994 tokc = cval;
3999 tok_str_add2(&macro_str1, tok, &tokc);
4000 next_nomacro();
4001 if (tok == 0)
4002 break;
4004 macro_ptr = (int *)saved_macro_ptr;
4005 cstr_free(&cstr);
4006 tok_str_add(&macro_str1, 0);
4007 return macro_str1.str;
4011 /* do macro substitution of macro_str and add result to
4012 (tok_str,tok_len). 'nested_list' is the list of all macros we got
4013 inside to avoid recursing. */
4014 static void macro_subst(TokenString *tok_str, Sym **nested_list,
4015 const int *macro_str, int can_read_stream)
4017 Sym *s;
4018 int *saved_macro_ptr, *macro_str1;
4019 const int *ptr;
4020 int t, ret;
4021 CValue cval;
4023 /* first scan for '##' operator handling */
4024 ptr = macro_str;
4025 macro_str1 = macro_twosharps(ptr);
4026 if (macro_str1)
4027 ptr = macro_str1;
4028 while (1) {
4029 /* NOTE: ptr == NULL can only happen if tokens are read from
4030 file stream due to a macro function call */
4031 if (ptr == NULL)
4032 break;
4033 TOK_GET(t, ptr, cval);
4034 if (t == 0)
4035 break;
4036 s = define_find(t);
4037 if (s != NULL) {
4038 /* if nested substitution, do nothing */
4039 if (sym_find2(*nested_list, t))
4040 goto no_subst;
4041 saved_macro_ptr = macro_ptr;
4042 macro_ptr = (int *)ptr;
4043 tok = t;
4044 ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream);
4045 ptr = (int *)macro_ptr;
4046 macro_ptr = saved_macro_ptr;
4047 if (ret != 0)
4048 goto no_subst;
4049 } else {
4050 no_subst:
4051 tok_str_add2(tok_str, t, &cval);
4054 if (macro_str1)
4055 tok_str_free(macro_str1);
4058 /* return next token with macro substitution */
4059 static void next(void)
4061 Sym *nested_list, *s;
4062 TokenString str;
4064 redo:
4065 next_nomacro();
4066 if (!macro_ptr) {
4067 /* if not reading from macro substituted string, then try
4068 to substitute macros */
4069 if (tok >= TOK_IDENT &&
4070 (parse_flags & PARSE_FLAG_PREPROCESS)) {
4071 s = define_find(tok);
4072 if (s) {
4073 /* we have a macro: we try to substitute */
4074 tok_str_new(&str);
4075 nested_list = NULL;
4076 if (macro_subst_tok(&str, &nested_list, s, 1) == 0) {
4077 /* substitution done, NOTE: maybe empty */
4078 tok_str_add(&str, 0);
4079 macro_ptr = str.str;
4080 macro_ptr_allocated = str.str;
4081 goto redo;
4085 } else {
4086 if (tok == 0) {
4087 /* end of macro or end of unget buffer */
4088 if (unget_buffer_enabled) {
4089 macro_ptr = unget_saved_macro_ptr;
4090 unget_buffer_enabled = 0;
4091 } else {
4092 /* end of macro string: free it */
4093 tok_str_free(macro_ptr_allocated);
4094 macro_ptr = NULL;
4096 goto redo;
4100 /* convert preprocessor tokens into C tokens */
4101 if (tok == TOK_PPNUM &&
4102 (parse_flags & PARSE_FLAG_TOK_NUM)) {
4103 parse_number((char *)tokc.cstr->data);
4107 /* push back current token and set current token to 'last_tok'. Only
4108 identifier case handled for labels. */
4109 static inline void unget_tok(int last_tok)
4111 int i, n;
4112 int *q;
4113 unget_saved_macro_ptr = macro_ptr;
4114 unget_buffer_enabled = 1;
4115 q = unget_saved_buffer;
4116 macro_ptr = q;
4117 *q++ = tok;
4118 n = tok_ext_size(tok) - 1;
4119 for(i=0;i<n;i++)
4120 *q++ = tokc.tab[i];
4121 *q = 0; /* end of token string */
4122 tok = last_tok;
4126 void swap(int *p, int *q)
4128 int t;
4129 t = *p;
4130 *p = *q;
4131 *q = t;
4134 void vsetc(CType *type, int r, CValue *vc)
4136 int v;
4138 if (vtop >= vstack + VSTACK_SIZE)
4139 error("memory full");
4140 /* cannot let cpu flags if other instruction are generated. Also
4141 avoid leaving VT_JMP anywhere except on the top of the stack
4142 because it would complicate the code generator. */
4143 if (vtop >= vstack) {
4144 v = vtop->r & VT_VALMASK;
4145 if (v == VT_CMP || (v & ~1) == VT_JMP)
4146 gv(RC_INT);
4148 vtop++;
4149 vtop->type = *type;
4150 vtop->r = r;
4151 vtop->r2 = VT_CONST;
4152 vtop->c = *vc;
4155 /* push integer constant */
4156 void vpushi(int v)
4158 CValue cval;
4159 cval.i = v;
4160 vsetc(&int_type, VT_CONST, &cval);
4163 /* Return a static symbol pointing to a section */
4164 static Sym *get_sym_ref(CType *type, Section *sec,
4165 unsigned long offset, unsigned long size)
4167 int v;
4168 Sym *sym;
4170 v = anon_sym++;
4171 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
4172 sym->type.ref = type->ref;
4173 sym->r = VT_CONST | VT_SYM;
4174 put_extern_sym(sym, sec, offset, size);
4175 return sym;
4178 /* push a reference to a section offset by adding a dummy symbol */
4179 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
4181 CValue cval;
4183 cval.ul = 0;
4184 vsetc(type, VT_CONST | VT_SYM, &cval);
4185 vtop->sym = get_sym_ref(type, sec, offset, size);
4188 /* define a new external reference to a symbol 'v' of type 'u' */
4189 static Sym *external_global_sym(int v, CType *type, int r)
4191 Sym *s;
4193 s = sym_find(v);
4194 if (!s) {
4195 /* push forward reference */
4196 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
4197 s->type.ref = type->ref;
4198 s->r = r | VT_CONST | VT_SYM;
4200 return s;
4203 /* define a new external reference to a symbol 'v' of type 'u' */
4204 static Sym *external_sym(int v, CType *type, int r)
4206 Sym *s;
4208 s = sym_find(v);
4209 if (!s) {
4210 /* push forward reference */
4211 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
4212 s->type.t |= VT_EXTERN;
4213 } else {
4214 if (!is_compatible_types(&s->type, type))
4215 error("incompatible types for redefinition of '%s'",
4216 get_tok_str(v, NULL));
4218 return s;
4221 /* push a reference to global symbol v */
4222 static void vpush_global_sym(CType *type, int v)
4224 Sym *sym;
4225 CValue cval;
4227 sym = external_global_sym(v, type, 0);
4228 cval.ul = 0;
4229 vsetc(type, VT_CONST | VT_SYM, &cval);
4230 vtop->sym = sym;
4233 void vset(CType *type, int r, int v)
4235 CValue cval;
4237 cval.i = v;
4238 vsetc(type, r, &cval);
4241 void vseti(int r, int v)
4243 CType type;
4244 type.t = VT_INT;
4245 vset(&type, r, v);
4248 void vswap(void)
4250 SValue tmp;
4252 tmp = vtop[0];
4253 vtop[0] = vtop[-1];
4254 vtop[-1] = tmp;
4257 void vpushv(SValue *v)
4259 if (vtop >= vstack + VSTACK_SIZE)
4260 error("memory full");
4261 vtop++;
4262 *vtop = *v;
4265 void vdup(void)
4267 vpushv(vtop);
4270 /* save r to the memory stack, and mark it as being free */
4271 void save_reg(int r)
4273 int l, saved, size, align;
4274 SValue *p, sv;
4275 CType *type;
4277 /* modify all stack values */
4278 saved = 0;
4279 l = 0;
4280 for(p=vstack;p<=vtop;p++) {
4281 if ((p->r & VT_VALMASK) == r ||
4282 (p->r2 & VT_VALMASK) == r) {
4283 /* must save value on stack if not already done */
4284 if (!saved) {
4285 /* NOTE: must reload 'r' because r might be equal to r2 */
4286 r = p->r & VT_VALMASK;
4287 /* store register in the stack */
4288 type = &p->type;
4289 if ((p->r & VT_LVAL) ||
4290 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
4291 type = &int_type;
4292 size = type_size(type, &align);
4293 loc = (loc - size) & -align;
4294 sv.type.t = type->t;
4295 sv.r = VT_LOCAL | VT_LVAL;
4296 sv.c.ul = loc;
4297 store(r, &sv);
4298 #ifdef TCC_TARGET_I386
4299 /* x86 specific: need to pop fp register ST0 if saved */
4300 if (r == TREG_ST0) {
4301 o(0xd9dd); /* fstp %st(1) */
4303 #endif
4304 /* special long long case */
4305 if ((type->t & VT_BTYPE) == VT_LLONG) {
4306 sv.c.ul += 4;
4307 store(p->r2, &sv);
4309 l = loc;
4310 saved = 1;
4312 /* mark that stack entry as being saved on the stack */
4313 if (p->r & VT_LVAL) {
4314 /* also clear the bounded flag because the
4315 relocation address of the function was stored in
4316 p->c.ul */
4317 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
4318 } else {
4319 p->r = lvalue_type(p->type.t) | VT_LOCAL;
4321 p->r2 = VT_CONST;
4322 p->c.ul = l;
4327 /* find a free register of class 'rc'. If none, save one register */
4328 int get_reg(int rc)
4330 int r;
4331 SValue *p;
4333 /* find a free register */
4334 for(r=0;r<NB_REGS;r++) {
4335 if (reg_classes[r] & rc) {
4336 for(p=vstack;p<=vtop;p++) {
4337 if ((p->r & VT_VALMASK) == r ||
4338 (p->r2 & VT_VALMASK) == r)
4339 goto notfound;
4341 return r;
4343 notfound: ;
4346 /* no register left : free the first one on the stack (VERY
4347 IMPORTANT to start from the bottom to ensure that we don't
4348 spill registers used in gen_opi()) */
4349 for(p=vstack;p<=vtop;p++) {
4350 r = p->r & VT_VALMASK;
4351 if (r < VT_CONST && (reg_classes[r] & rc))
4352 goto save_found;
4353 /* also look at second register (if long long) */
4354 r = p->r2 & VT_VALMASK;
4355 if (r < VT_CONST && (reg_classes[r] & rc)) {
4356 save_found:
4357 save_reg(r);
4358 return r;
4361 /* Should never comes here */
4362 return -1;
4365 /* save registers up to (vtop - n) stack entry */
4366 void save_regs(int n)
4368 int r;
4369 SValue *p, *p1;
4370 p1 = vtop - n;
4371 for(p = vstack;p <= p1; p++) {
4372 r = p->r & VT_VALMASK;
4373 if (r < VT_CONST) {
4374 save_reg(r);
4379 /* move register 's' to 'r', and flush previous value of r to memory
4380 if needed */
4381 void move_reg(int r, int s)
4383 SValue sv;
4385 if (r != s) {
4386 save_reg(r);
4387 sv.type.t = VT_INT;
4388 sv.r = s;
4389 sv.c.ul = 0;
4390 load(r, &sv);
4394 /* get address of vtop (vtop MUST BE an lvalue) */
4395 void gaddrof(void)
4397 vtop->r &= ~VT_LVAL;
4398 /* tricky: if saved lvalue, then we can go back to lvalue */
4399 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
4400 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
4403 #ifdef CONFIG_TCC_BCHECK
4404 /* generate lvalue bound code */
4405 void gbound(void)
4407 int lval_type;
4408 CType type1;
4410 vtop->r &= ~VT_MUSTBOUND;
4411 /* if lvalue, then use checking code before dereferencing */
4412 if (vtop->r & VT_LVAL) {
4413 /* if not VT_BOUNDED value, then make one */
4414 if (!(vtop->r & VT_BOUNDED)) {
4415 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
4416 /* must save type because we must set it to int to get pointer */
4417 type1 = vtop->type;
4418 vtop->type.t = VT_INT;
4419 gaddrof();
4420 vpushi(0);
4421 gen_bounded_ptr_add();
4422 vtop->r |= lval_type;
4423 vtop->type = type1;
4425 /* then check for dereferencing */
4426 gen_bounded_ptr_deref();
4429 #endif
4431 /* store vtop a register belonging to class 'rc'. lvalues are
4432 converted to values. Cannot be used if cannot be converted to
4433 register value (such as structures). */
4434 int gv(int rc)
4436 int r, r2, rc2, bit_pos, bit_size, size, align, i;
4437 unsigned long long ll;
4439 /* NOTE: get_reg can modify vstack[] */
4440 if (vtop->type.t & VT_BITFIELD) {
4441 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4442 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4443 /* remove bit field info to avoid loops */
4444 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4445 /* generate shifts */
4446 vpushi(32 - (bit_pos + bit_size));
4447 gen_op(TOK_SHL);
4448 vpushi(32 - bit_size);
4449 /* NOTE: transformed to SHR if unsigned */
4450 gen_op(TOK_SAR);
4451 r = gv(rc);
4452 } else {
4453 if (is_float(vtop->type.t) &&
4454 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4455 Sym *sym;
4456 int *ptr;
4457 unsigned long offset;
4459 /* XXX: unify with initializers handling ? */
4460 /* CPUs usually cannot use float constants, so we store them
4461 generically in data segment */
4462 size = type_size(&vtop->type, &align);
4463 offset = (data_section->data_offset + align - 1) & -align;
4464 data_section->data_offset = offset;
4465 /* XXX: not portable yet */
4466 ptr = section_ptr_add(data_section, size);
4467 size = size >> 2;
4468 for(i=0;i<size;i++)
4469 ptr[i] = vtop->c.tab[i];
4470 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
4471 vtop->r |= VT_LVAL | VT_SYM;
4472 vtop->sym = sym;
4473 vtop->c.ul = 0;
4475 #ifdef CONFIG_TCC_BCHECK
4476 if (vtop->r & VT_MUSTBOUND)
4477 gbound();
4478 #endif
4480 r = vtop->r & VT_VALMASK;
4481 /* need to reload if:
4482 - constant
4483 - lvalue (need to dereference pointer)
4484 - already a register, but not in the right class */
4485 if (r >= VT_CONST ||
4486 (vtop->r & VT_LVAL) ||
4487 !(reg_classes[r] & rc) ||
4488 ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
4489 !(reg_classes[vtop->r2] & rc))) {
4490 r = get_reg(rc);
4491 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
4492 /* two register type load : expand to two words
4493 temporarily */
4494 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4495 /* load constant */
4496 ll = vtop->c.ull;
4497 vtop->c.ui = ll; /* first word */
4498 load(r, vtop);
4499 vtop->r = r; /* save register value */
4500 vpushi(ll >> 32); /* second word */
4501 } else if (r >= VT_CONST ||
4502 (vtop->r & VT_LVAL)) {
4503 /* load from memory */
4504 load(r, vtop);
4505 vdup();
4506 vtop[-1].r = r; /* save register value */
4507 /* increment pointer to get second word */
4508 vtop->type.t = VT_INT;
4509 gaddrof();
4510 vpushi(4);
4511 gen_op('+');
4512 vtop->r |= VT_LVAL;
4513 } else {
4514 /* move registers */
4515 load(r, vtop);
4516 vdup();
4517 vtop[-1].r = r; /* save register value */
4518 vtop->r = vtop[-1].r2;
4520 /* allocate second register */
4521 rc2 = RC_INT;
4522 if (rc == RC_IRET)
4523 rc2 = RC_LRET;
4524 r2 = get_reg(rc2);
4525 load(r2, vtop);
4526 vpop();
4527 /* write second register */
4528 vtop->r2 = r2;
4529 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
4530 int t1, t;
4531 /* lvalue of scalar type : need to use lvalue type
4532 because of possible cast */
4533 t = vtop->type.t;
4534 t1 = t;
4535 /* compute memory access type */
4536 if (vtop->r & VT_LVAL_BYTE)
4537 t = VT_BYTE;
4538 else if (vtop->r & VT_LVAL_SHORT)
4539 t = VT_SHORT;
4540 if (vtop->r & VT_LVAL_UNSIGNED)
4541 t |= VT_UNSIGNED;
4542 vtop->type.t = t;
4543 load(r, vtop);
4544 /* restore wanted type */
4545 vtop->type.t = t1;
4546 } else {
4547 /* one register type load */
4548 load(r, vtop);
4551 vtop->r = r;
4553 return r;
4556 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4557 void gv2(int rc1, int rc2)
4559 int v;
4561 /* generate more generic register first. But VT_JMP or VT_CMP
4562 values must be generated first in all cases to avoid possible
4563 reload errors */
4564 v = vtop[0].r & VT_VALMASK;
4565 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
4566 vswap();
4567 gv(rc1);
4568 vswap();
4569 gv(rc2);
4570 /* test if reload is needed for first register */
4571 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
4572 vswap();
4573 gv(rc1);
4574 vswap();
4576 } else {
4577 gv(rc2);
4578 vswap();
4579 gv(rc1);
4580 vswap();
4581 /* test if reload is needed for first register */
4582 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
4583 gv(rc2);
4588 /* expand long long on stack in two int registers */
4589 void lexpand(void)
4591 int u;
4593 u = vtop->type.t & VT_UNSIGNED;
4594 gv(RC_INT);
4595 vdup();
4596 vtop[0].r = vtop[-1].r2;
4597 vtop[0].r2 = VT_CONST;
4598 vtop[-1].r2 = VT_CONST;
4599 vtop[0].type.t = VT_INT | u;
4600 vtop[-1].type.t = VT_INT | u;
4603 /* build a long long from two ints */
4604 void lbuild(int t)
4606 gv2(RC_INT, RC_INT);
4607 vtop[-1].r2 = vtop[0].r;
4608 vtop[-1].type.t = t;
4609 vpop();
4612 /* rotate n first stack elements to the bottom
4613 I1 ... In -> I2 ... In I1 [top is right]
4615 void vrotb(int n)
4617 int i;
4618 SValue tmp;
4620 tmp = vtop[-n + 1];
4621 for(i=-n+1;i!=0;i++)
4622 vtop[i] = vtop[i+1];
4623 vtop[0] = tmp;
4626 /* rotate n first stack elements to the top
4627 I1 ... In -> In I1 ... I(n-1) [top is right]
4629 void vrott(int n)
4631 int i;
4632 SValue tmp;
4634 tmp = vtop[0];
4635 for(i = 0;i < n - 1; i++)
4636 vtop[-i] = vtop[-i - 1];
4637 vtop[-n + 1] = tmp;
4640 /* pop stack value */
4641 void vpop(void)
4643 int v;
4644 v = vtop->r & VT_VALMASK;
4645 #ifdef TCC_TARGET_I386
4646 /* for x86, we need to pop the FP stack */
4647 if (v == TREG_ST0 && !nocode_wanted) {
4648 o(0xd9dd); /* fstp %st(1) */
4649 } else
4650 #endif
4651 if (v == VT_JMP || v == VT_JMPI) {
4652 /* need to put correct jump if && or || without test */
4653 gsym(vtop->c.ul);
4655 vtop--;
4658 /* convert stack entry to register and duplicate its value in another
4659 register */
4660 void gv_dup(void)
4662 int rc, t, r, r1;
4663 SValue sv;
4665 t = vtop->type.t;
4666 if ((t & VT_BTYPE) == VT_LLONG) {
4667 lexpand();
4668 gv_dup();
4669 vswap();
4670 vrotb(3);
4671 gv_dup();
4672 vrotb(4);
4673 /* stack: H L L1 H1 */
4674 lbuild(t);
4675 vrotb(3);
4676 vrotb(3);
4677 vswap();
4678 lbuild(t);
4679 vswap();
4680 } else {
4681 /* duplicate value */
4682 rc = RC_INT;
4683 sv.type.t = VT_INT;
4684 if (is_float(t)) {
4685 rc = RC_FLOAT;
4686 sv.type.t = t;
4688 r = gv(rc);
4689 r1 = get_reg(rc);
4690 sv.r = r;
4691 sv.c.ul = 0;
4692 load(r1, &sv); /* move r to r1 */
4693 vdup();
4694 /* duplicates value */
4695 vtop->r = r1;
4699 /* generate CPU independent (unsigned) long long operations */
4700 void gen_opl(int op)
4702 int t, a, b, op1, c, i;
4703 int func;
4704 SValue tmp;
4706 switch(op) {
4707 case '/':
4708 case TOK_PDIV:
4709 func = TOK___divdi3;
4710 goto gen_func;
4711 case TOK_UDIV:
4712 func = TOK___udivdi3;
4713 goto gen_func;
4714 case '%':
4715 func = TOK___moddi3;
4716 goto gen_func;
4717 case TOK_UMOD:
4718 func = TOK___umoddi3;
4719 gen_func:
4720 /* call generic long long function */
4721 vpush_global_sym(&func_old_type, func);
4722 vrott(3);
4723 gfunc_call(2);
4724 vpushi(0);
4725 vtop->r = REG_IRET;
4726 vtop->r2 = REG_LRET;
4727 break;
4728 case '^':
4729 case '&':
4730 case '|':
4731 case '*':
4732 case '+':
4733 case '-':
4734 t = vtop->type.t;
4735 vswap();
4736 lexpand();
4737 vrotb(3);
4738 lexpand();
4739 /* stack: L1 H1 L2 H2 */
4740 tmp = vtop[0];
4741 vtop[0] = vtop[-3];
4742 vtop[-3] = tmp;
4743 tmp = vtop[-2];
4744 vtop[-2] = vtop[-3];
4745 vtop[-3] = tmp;
4746 vswap();
4747 /* stack: H1 H2 L1 L2 */
4748 if (op == '*') {
4749 vpushv(vtop - 1);
4750 vpushv(vtop - 1);
4751 gen_op(TOK_UMULL);
4752 lexpand();
4753 /* stack: H1 H2 L1 L2 ML MH */
4754 for(i=0;i<4;i++)
4755 vrotb(6);
4756 /* stack: ML MH H1 H2 L1 L2 */
4757 tmp = vtop[0];
4758 vtop[0] = vtop[-2];
4759 vtop[-2] = tmp;
4760 /* stack: ML MH H1 L2 H2 L1 */
4761 gen_op('*');
4762 vrotb(3);
4763 vrotb(3);
4764 gen_op('*');
4765 /* stack: ML MH M1 M2 */
4766 gen_op('+');
4767 gen_op('+');
4768 } else if (op == '+' || op == '-') {
4769 /* XXX: add non carry method too (for MIPS or alpha) */
4770 if (op == '+')
4771 op1 = TOK_ADDC1;
4772 else
4773 op1 = TOK_SUBC1;
4774 gen_op(op1);
4775 /* stack: H1 H2 (L1 op L2) */
4776 vrotb(3);
4777 vrotb(3);
4778 gen_op(op1 + 1); /* TOK_xxxC2 */
4779 } else {
4780 gen_op(op);
4781 /* stack: H1 H2 (L1 op L2) */
4782 vrotb(3);
4783 vrotb(3);
4784 /* stack: (L1 op L2) H1 H2 */
4785 gen_op(op);
4786 /* stack: (L1 op L2) (H1 op H2) */
4788 /* stack: L H */
4789 lbuild(t);
4790 break;
4791 case TOK_SAR:
4792 case TOK_SHR:
4793 case TOK_SHL:
4794 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4795 t = vtop[-1].type.t;
4796 vswap();
4797 lexpand();
4798 vrotb(3);
4799 /* stack: L H shift */
4800 c = (int)vtop->c.i;
4801 /* constant: simpler */
4802 /* NOTE: all comments are for SHL. the other cases are
4803 done by swaping words */
4804 vpop();
4805 if (op != TOK_SHL)
4806 vswap();
4807 if (c >= 32) {
4808 /* stack: L H */
4809 vpop();
4810 if (c > 32) {
4811 vpushi(c - 32);
4812 gen_op(op);
4814 if (op != TOK_SAR) {
4815 vpushi(0);
4816 } else {
4817 gv_dup();
4818 vpushi(31);
4819 gen_op(TOK_SAR);
4821 vswap();
4822 } else {
4823 vswap();
4824 gv_dup();
4825 /* stack: H L L */
4826 vpushi(c);
4827 gen_op(op);
4828 vswap();
4829 vpushi(32 - c);
4830 if (op == TOK_SHL)
4831 gen_op(TOK_SHR);
4832 else
4833 gen_op(TOK_SHL);
4834 vrotb(3);
4835 /* stack: L L H */
4836 vpushi(c);
4837 if (op == TOK_SHL)
4838 gen_op(TOK_SHL);
4839 else
4840 gen_op(TOK_SHR);
4841 gen_op('|');
4843 if (op != TOK_SHL)
4844 vswap();
4845 lbuild(t);
4846 } else {
4847 /* XXX: should provide a faster fallback on x86 ? */
4848 switch(op) {
4849 case TOK_SAR:
4850 func = TOK___sardi3;
4851 goto gen_func;
4852 case TOK_SHR:
4853 func = TOK___shrdi3;
4854 goto gen_func;
4855 case TOK_SHL:
4856 func = TOK___shldi3;
4857 goto gen_func;
4860 break;
4861 default:
4862 /* compare operations */
4863 t = vtop->type.t;
4864 vswap();
4865 lexpand();
4866 vrotb(3);
4867 lexpand();
4868 /* stack: L1 H1 L2 H2 */
4869 tmp = vtop[-1];
4870 vtop[-1] = vtop[-2];
4871 vtop[-2] = tmp;
4872 /* stack: L1 L2 H1 H2 */
4873 /* compare high */
4874 op1 = op;
4875 /* when values are equal, we need to compare low words. since
4876 the jump is inverted, we invert the test too. */
4877 if (op1 == TOK_LT)
4878 op1 = TOK_LE;
4879 else if (op1 == TOK_GT)
4880 op1 = TOK_GE;
4881 else if (op1 == TOK_ULT)
4882 op1 = TOK_ULE;
4883 else if (op1 == TOK_UGT)
4884 op1 = TOK_UGE;
4885 a = 0;
4886 b = 0;
4887 gen_op(op1);
4888 if (op1 != TOK_NE) {
4889 a = gtst(1, 0);
4891 if (op != TOK_EQ) {
4892 /* generate non equal test */
4893 /* XXX: NOT PORTABLE yet */
4894 if (a == 0) {
4895 b = gtst(0, 0);
4896 } else {
4897 #ifdef TCC_TARGET_I386
4898 b = psym(0x850f, 0);
4899 #else
4900 error("not implemented");
4901 #endif
4904 /* compare low. Always unsigned */
4905 op1 = op;
4906 if (op1 == TOK_LT)
4907 op1 = TOK_ULT;
4908 else if (op1 == TOK_LE)
4909 op1 = TOK_ULE;
4910 else if (op1 == TOK_GT)
4911 op1 = TOK_UGT;
4912 else if (op1 == TOK_GE)
4913 op1 = TOK_UGE;
4914 gen_op(op1);
4915 a = gtst(1, a);
4916 gsym(b);
4917 vseti(VT_JMPI, a);
4918 break;
4922 /* handle integer constant optimizations and various machine
4923 independent opt */
4924 void gen_opic(int op)
4926 int fc, c1, c2, n;
4927 SValue *v1, *v2;
4929 v1 = vtop - 1;
4930 v2 = vtop;
4931 /* currently, we cannot do computations with forward symbols */
4932 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4933 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4934 if (c1 && c2) {
4935 fc = v2->c.i;
4936 switch(op) {
4937 case '+': v1->c.i += fc; break;
4938 case '-': v1->c.i -= fc; break;
4939 case '&': v1->c.i &= fc; break;
4940 case '^': v1->c.i ^= fc; break;
4941 case '|': v1->c.i |= fc; break;
4942 case '*': v1->c.i *= fc; break;
4944 case TOK_PDIV:
4945 case '/':
4946 case '%':
4947 case TOK_UDIV:
4948 case TOK_UMOD:
4949 /* if division by zero, generate explicit division */
4950 if (fc == 0) {
4951 if (const_wanted)
4952 error("division by zero in constant");
4953 goto general_case;
4955 switch(op) {
4956 default: v1->c.i /= fc; break;
4957 case '%': v1->c.i %= fc; break;
4958 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
4959 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
4961 break;
4962 case TOK_SHL: v1->c.i <<= fc; break;
4963 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
4964 case TOK_SAR: v1->c.i >>= fc; break;
4965 /* tests */
4966 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
4967 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
4968 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
4969 case TOK_NE: v1->c.i = v1->c.i != fc; break;
4970 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
4971 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
4972 case TOK_LT: v1->c.i = v1->c.i < fc; break;
4973 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
4974 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
4975 case TOK_GT: v1->c.i = v1->c.i > fc; break;
4976 /* logical */
4977 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
4978 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
4979 default:
4980 goto general_case;
4982 vtop--;
4983 } else {
4984 /* if commutative ops, put c2 as constant */
4985 if (c1 && (op == '+' || op == '&' || op == '^' ||
4986 op == '|' || op == '*')) {
4987 vswap();
4988 swap(&c1, &c2);
4990 fc = vtop->c.i;
4991 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
4992 op == TOK_PDIV) &&
4993 fc == 1) ||
4994 ((op == '+' || op == '-' || op == '|' || op == '^' ||
4995 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
4996 fc == 0) ||
4997 (op == '&' &&
4998 fc == -1))) {
4999 /* nothing to do */
5000 vtop--;
5001 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
5002 /* try to use shifts instead of muls or divs */
5003 if (fc > 0 && (fc & (fc - 1)) == 0) {
5004 n = -1;
5005 while (fc) {
5006 fc >>= 1;
5007 n++;
5009 vtop->c.i = n;
5010 if (op == '*')
5011 op = TOK_SHL;
5012 else if (op == TOK_PDIV)
5013 op = TOK_SAR;
5014 else
5015 op = TOK_SHR;
5017 goto general_case;
5018 } else if (c2 && (op == '+' || op == '-') &&
5019 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
5020 (VT_CONST | VT_SYM)) {
5021 /* symbol + constant case */
5022 if (op == '-')
5023 fc = -fc;
5024 vtop--;
5025 vtop->c.i += fc;
5026 } else {
5027 general_case:
5028 if (!nocode_wanted) {
5029 /* call low level op generator */
5030 gen_opi(op);
5031 } else {
5032 vtop--;
5038 /* generate a floating point operation with constant propagation */
5039 void gen_opif(int op)
5041 int c1, c2;
5042 SValue *v1, *v2;
5043 long double f1, f2;
5045 v1 = vtop - 1;
5046 v2 = vtop;
5047 /* currently, we cannot do computations with forward symbols */
5048 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5049 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5050 if (c1 && c2) {
5051 if (v1->type.t == VT_FLOAT) {
5052 f1 = v1->c.f;
5053 f2 = v2->c.f;
5054 } else if (v1->type.t == VT_DOUBLE) {
5055 f1 = v1->c.d;
5056 f2 = v2->c.d;
5057 } else {
5058 f1 = v1->c.ld;
5059 f2 = v2->c.ld;
5062 /* NOTE: we only do constant propagation if finite number (not
5063 NaN or infinity) (ANSI spec) */
5064 if (!ieee_finite(f1) || !ieee_finite(f2))
5065 goto general_case;
5067 switch(op) {
5068 case '+': f1 += f2; break;
5069 case '-': f1 -= f2; break;
5070 case '*': f1 *= f2; break;
5071 case '/':
5072 if (f2 == 0.0) {
5073 if (const_wanted)
5074 error("division by zero in constant");
5075 goto general_case;
5077 f1 /= f2;
5078 break;
5079 /* XXX: also handles tests ? */
5080 default:
5081 goto general_case;
5083 /* XXX: overflow test ? */
5084 if (v1->type.t == VT_FLOAT) {
5085 v1->c.f = f1;
5086 } else if (v1->type.t == VT_DOUBLE) {
5087 v1->c.d = f1;
5088 } else {
5089 v1->c.ld = f1;
5091 vtop--;
5092 } else {
5093 general_case:
5094 if (!nocode_wanted) {
5095 gen_opf(op);
5096 } else {
5097 vtop--;
5102 static int pointed_size(CType *type)
5104 int align;
5105 return type_size(pointed_type(type), &align);
5108 static inline int is_null_pointer(SValue *p)
5110 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
5111 return 0;
5112 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
5113 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
5116 static inline int is_integer_btype(int bt)
5118 return (bt == VT_BYTE || bt == VT_SHORT ||
5119 bt == VT_INT || bt == VT_LLONG);
5122 /* check types for comparison or substraction of pointers */
5123 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
5125 CType *type1, *type2, tmp_type1, tmp_type2;
5126 int bt1, bt2;
5128 /* null pointers are accepted for all comparisons as gcc */
5129 if (is_null_pointer(p1) || is_null_pointer(p2))
5130 return;
5131 type1 = &p1->type;
5132 type2 = &p2->type;
5133 bt1 = type1->t & VT_BTYPE;
5134 bt2 = type2->t & VT_BTYPE;
5135 /* accept comparison between pointer and integer with a warning */
5136 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
5137 warning("comparison between pointer and integer");
5138 return;
5141 /* both must be pointers or implicit function pointers */
5142 if (bt1 == VT_PTR) {
5143 type1 = pointed_type(type1);
5144 } else if (bt1 != VT_FUNC)
5145 goto invalid_operands;
5147 if (bt2 == VT_PTR) {
5148 type2 = pointed_type(type2);
5149 } else if (bt2 != VT_FUNC) {
5150 invalid_operands:
5151 error("invalid operands to binary %s", get_tok_str(op, NULL));
5153 if ((type1->t & VT_BTYPE) == VT_VOID ||
5154 (type2->t & VT_BTYPE) == VT_VOID)
5155 return;
5156 tmp_type1 = *type1;
5157 tmp_type2 = *type2;
5158 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
5159 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
5160 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
5161 /* gcc-like error if '-' is used */
5162 if (op == '-')
5163 goto invalid_operands;
5164 else
5165 warning("comparison of distinct pointer types lacks a cast");
5169 /* generic gen_op: handles types problems */
5170 void gen_op(int op)
5172 int u, t1, t2, bt1, bt2, t;
5173 CType type1;
5175 t1 = vtop[-1].type.t;
5176 t2 = vtop[0].type.t;
5177 bt1 = t1 & VT_BTYPE;
5178 bt2 = t2 & VT_BTYPE;
5180 if (bt1 == VT_PTR || bt2 == VT_PTR) {
5181 /* at least one operand is a pointer */
5182 /* relationnal op: must be both pointers */
5183 if (op >= TOK_ULT && op <= TOK_GT) {
5184 check_comparison_pointer_types(vtop - 1, vtop, op);
5185 /* pointers are handled are unsigned */
5186 t = VT_INT | VT_UNSIGNED;
5187 goto std_op;
5189 /* if both pointers, then it must be the '-' op */
5190 if (bt1 == VT_PTR && bt2 == VT_PTR) {
5191 if (op != '-')
5192 error("cannot use pointers here");
5193 check_comparison_pointer_types(vtop - 1, vtop, op);
5194 /* XXX: check that types are compatible */
5195 u = pointed_size(&vtop[-1].type);
5196 gen_opic(op);
5197 /* set to integer type */
5198 vtop->type.t = VT_INT;
5199 vpushi(u);
5200 gen_op(TOK_PDIV);
5201 } else {
5202 /* exactly one pointer : must be '+' or '-'. */
5203 if (op != '-' && op != '+')
5204 error("cannot use pointers here");
5205 /* Put pointer as first operand */
5206 if (bt2 == VT_PTR) {
5207 vswap();
5208 swap(&t1, &t2);
5210 type1 = vtop[-1].type;
5211 /* XXX: cast to int ? (long long case) */
5212 vpushi(pointed_size(&vtop[-1].type));
5213 gen_op('*');
5214 #ifdef CONFIG_TCC_BCHECK
5215 /* if evaluating constant expression, no code should be
5216 generated, so no bound check */
5217 if (do_bounds_check && !const_wanted) {
5218 /* if bounded pointers, we generate a special code to
5219 test bounds */
5220 if (op == '-') {
5221 vpushi(0);
5222 vswap();
5223 gen_op('-');
5225 gen_bounded_ptr_add();
5226 } else
5227 #endif
5229 gen_opic(op);
5231 /* put again type if gen_opic() swaped operands */
5232 vtop->type = type1;
5234 } else if (is_float(bt1) || is_float(bt2)) {
5235 /* compute bigger type and do implicit casts */
5236 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
5237 t = VT_LDOUBLE;
5238 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
5239 t = VT_DOUBLE;
5240 } else {
5241 t = VT_FLOAT;
5243 /* floats can only be used for a few operations */
5244 if (op != '+' && op != '-' && op != '*' && op != '/' &&
5245 (op < TOK_ULT || op > TOK_GT))
5246 error("invalid operands for binary operation");
5247 goto std_op;
5248 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
5249 /* cast to biggest op */
5250 t = VT_LLONG;
5251 /* convert to unsigned if it does not fit in a long long */
5252 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
5253 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
5254 t |= VT_UNSIGNED;
5255 goto std_op;
5256 } else {
5257 /* integer operations */
5258 t = VT_INT;
5259 /* convert to unsigned if it does not fit in an integer */
5260 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
5261 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
5262 t |= VT_UNSIGNED;
5263 std_op:
5264 /* XXX: currently, some unsigned operations are explicit, so
5265 we modify them here */
5266 if (t & VT_UNSIGNED) {
5267 if (op == TOK_SAR)
5268 op = TOK_SHR;
5269 else if (op == '/')
5270 op = TOK_UDIV;
5271 else if (op == '%')
5272 op = TOK_UMOD;
5273 else if (op == TOK_LT)
5274 op = TOK_ULT;
5275 else if (op == TOK_GT)
5276 op = TOK_UGT;
5277 else if (op == TOK_LE)
5278 op = TOK_ULE;
5279 else if (op == TOK_GE)
5280 op = TOK_UGE;
5282 vswap();
5283 type1.t = t;
5284 gen_cast(&type1);
5285 vswap();
5286 /* special case for shifts and long long: we keep the shift as
5287 an integer */
5288 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
5289 type1.t = VT_INT;
5290 gen_cast(&type1);
5291 if (is_float(t))
5292 gen_opif(op);
5293 else if ((t & VT_BTYPE) == VT_LLONG)
5294 gen_opl(op);
5295 else
5296 gen_opic(op);
5297 if (op >= TOK_ULT && op <= TOK_GT) {
5298 /* relationnal op: the result is an int */
5299 vtop->type.t = VT_INT;
5300 } else {
5301 vtop->type.t = t;
5306 /* generic itof for unsigned long long case */
5307 void gen_cvt_itof1(int t)
5309 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
5310 (VT_LLONG | VT_UNSIGNED)) {
5312 if (t == VT_FLOAT)
5313 vpush_global_sym(&func_old_type, TOK___ulltof);
5314 else if (t == VT_DOUBLE)
5315 vpush_global_sym(&func_old_type, TOK___ulltod);
5316 else
5317 vpush_global_sym(&func_old_type, TOK___ulltold);
5318 vrott(2);
5319 gfunc_call(1);
5320 vpushi(0);
5321 vtop->r = REG_FRET;
5322 } else {
5323 gen_cvt_itof(t);
5327 /* generic ftoi for unsigned long long case */
5328 void gen_cvt_ftoi1(int t)
5330 int st;
5332 if (t == (VT_LLONG | VT_UNSIGNED)) {
5333 /* not handled natively */
5334 st = vtop->type.t & VT_BTYPE;
5335 if (st == VT_FLOAT)
5336 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
5337 else if (st == VT_DOUBLE)
5338 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
5339 else
5340 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
5341 vrott(2);
5342 gfunc_call(1);
5343 vpushi(0);
5344 vtop->r = REG_IRET;
5345 vtop->r2 = REG_LRET;
5346 } else {
5347 gen_cvt_ftoi(t);
5351 /* force char or short cast */
5352 void force_charshort_cast(int t)
5354 int bits, dbt;
5355 dbt = t & VT_BTYPE;
5356 /* XXX: add optimization if lvalue : just change type and offset */
5357 if (dbt == VT_BYTE)
5358 bits = 8;
5359 else
5360 bits = 16;
5361 if (t & VT_UNSIGNED) {
5362 vpushi((1 << bits) - 1);
5363 gen_op('&');
5364 } else {
5365 bits = 32 - bits;
5366 vpushi(bits);
5367 gen_op(TOK_SHL);
5368 vpushi(bits);
5369 gen_op(TOK_SAR);
5373 /* cast 'vtop' to 'type' */
5374 static void gen_cast(CType *type)
5376 int sbt, dbt, sf, df, c;
5378 /* special delayed cast for char/short */
5379 /* XXX: in some cases (multiple cascaded casts), it may still
5380 be incorrect */
5381 if (vtop->r & VT_MUSTCAST) {
5382 vtop->r &= ~VT_MUSTCAST;
5383 force_charshort_cast(vtop->type.t);
5386 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
5387 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
5389 if (sbt != dbt && !nocode_wanted) {
5390 sf = is_float(sbt);
5391 df = is_float(dbt);
5392 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5393 if (sf && df) {
5394 /* convert from fp to fp */
5395 if (c) {
5396 /* constant case: we can do it now */
5397 /* XXX: in ISOC, cannot do it if error in convert */
5398 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
5399 vtop->c.f = (float)vtop->c.d;
5400 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
5401 vtop->c.f = (float)vtop->c.ld;
5402 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
5403 vtop->c.d = (double)vtop->c.f;
5404 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
5405 vtop->c.d = (double)vtop->c.ld;
5406 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
5407 vtop->c.ld = (long double)vtop->c.f;
5408 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
5409 vtop->c.ld = (long double)vtop->c.d;
5410 } else {
5411 /* non constant case: generate code */
5412 gen_cvt_ftof(dbt);
5414 } else if (df) {
5415 /* convert int to fp */
5416 if (c) {
5417 switch(sbt) {
5418 case VT_LLONG | VT_UNSIGNED:
5419 case VT_LLONG:
5420 /* XXX: add const cases for long long */
5421 goto do_itof;
5422 case VT_INT | VT_UNSIGNED:
5423 switch(dbt) {
5424 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
5425 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
5426 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
5428 break;
5429 default:
5430 switch(dbt) {
5431 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
5432 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
5433 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
5435 break;
5437 } else {
5438 do_itof:
5439 gen_cvt_itof1(dbt);
5441 } else if (sf) {
5442 /* convert fp to int */
5443 /* we handle char/short/etc... with generic code */
5444 if (dbt != (VT_INT | VT_UNSIGNED) &&
5445 dbt != (VT_LLONG | VT_UNSIGNED) &&
5446 dbt != VT_LLONG)
5447 dbt = VT_INT;
5448 if (c) {
5449 switch(dbt) {
5450 case VT_LLONG | VT_UNSIGNED:
5451 case VT_LLONG:
5452 /* XXX: add const cases for long long */
5453 goto do_ftoi;
5454 case VT_INT | VT_UNSIGNED:
5455 switch(sbt) {
5456 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
5457 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5458 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5460 break;
5461 default:
5462 /* int case */
5463 switch(sbt) {
5464 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
5465 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
5466 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
5468 break;
5470 } else {
5471 do_ftoi:
5472 gen_cvt_ftoi1(dbt);
5474 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
5475 /* additional cast for char/short/bool... */
5476 vtop->type.t = dbt;
5477 gen_cast(type);
5479 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
5480 if ((sbt & VT_BTYPE) != VT_LLONG) {
5481 /* scalar to long long */
5482 if (c) {
5483 if (sbt == (VT_INT | VT_UNSIGNED))
5484 vtop->c.ll = vtop->c.ui;
5485 else
5486 vtop->c.ll = vtop->c.i;
5487 } else {
5488 /* machine independent conversion */
5489 gv(RC_INT);
5490 /* generate high word */
5491 if (sbt == (VT_INT | VT_UNSIGNED)) {
5492 vpushi(0);
5493 gv(RC_INT);
5494 } else {
5495 gv_dup();
5496 vpushi(31);
5497 gen_op(TOK_SAR);
5499 /* patch second register */
5500 vtop[-1].r2 = vtop->r;
5501 vpop();
5504 } else if (dbt == VT_BOOL) {
5505 /* scalar to bool */
5506 vpushi(0);
5507 gen_op(TOK_NE);
5508 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
5509 (dbt & VT_BTYPE) == VT_SHORT) {
5510 force_charshort_cast(dbt);
5511 } else if ((dbt & VT_BTYPE) == VT_INT) {
5512 /* scalar to int */
5513 if (sbt == VT_LLONG) {
5514 /* from long long: just take low order word */
5515 lexpand();
5516 vpop();
5518 /* if lvalue and single word type, nothing to do because
5519 the lvalue already contains the real type size (see
5520 VT_LVAL_xxx constants) */
5523 vtop->type = *type;
5526 /* return type size. Put alignment at 'a' */
5527 static int type_size(CType *type, int *a)
5529 Sym *s;
5530 int bt;
5532 bt = type->t & VT_BTYPE;
5533 if (bt == VT_STRUCT) {
5534 /* struct/union */
5535 s = type->ref;
5536 *a = s->r;
5537 return s->c;
5538 } else if (bt == VT_PTR) {
5539 if (type->t & VT_ARRAY) {
5540 s = type->ref;
5541 return type_size(&s->type, a) * s->c;
5542 } else {
5543 *a = PTR_SIZE;
5544 return PTR_SIZE;
5546 } else if (bt == VT_LDOUBLE) {
5547 *a = LDOUBLE_ALIGN;
5548 return LDOUBLE_SIZE;
5549 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
5550 *a = 4; /* XXX: i386 specific */
5551 return 8;
5552 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
5553 *a = 4;
5554 return 4;
5555 } else if (bt == VT_SHORT) {
5556 *a = 2;
5557 return 2;
5558 } else {
5559 /* char, void, function, _Bool */
5560 *a = 1;
5561 return 1;
5565 /* return the pointed type of t */
5566 static inline CType *pointed_type(CType *type)
5568 return &type->ref->type;
5571 /* modify type so that its it is a pointer to type. */
5572 static void mk_pointer(CType *type)
5574 Sym *s;
5575 s = sym_push(SYM_FIELD, type, 0, -1);
5576 type->t = VT_PTR | (type->t & ~VT_TYPE);
5577 type->ref = s;
5580 /* compare function types. OLD functions match any new functions */
5581 static int is_compatible_func(CType *type1, CType *type2)
5583 Sym *s1, *s2;
5585 s1 = type1->ref;
5586 s2 = type2->ref;
5587 if (!is_compatible_types(&s1->type, &s2->type))
5588 return 0;
5589 /* XXX: not complete */
5590 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
5591 return 1;
5592 if (s1->c != s2->c)
5593 return 0;
5594 while (s1 != NULL) {
5595 if (s2 == NULL)
5596 return 0;
5597 if (!is_compatible_types(&s1->type, &s2->type))
5598 return 0;
5599 s1 = s1->next;
5600 s2 = s2->next;
5602 if (s2)
5603 return 0;
5604 return 1;
5607 /* return true if type1 and type2 are exactly the same (including
5608 qualifiers).
5610 - enums are not checked as gcc __builtin_types_compatible_p ()
5612 static int is_compatible_types(CType *type1, CType *type2)
5614 int bt1, t1, t2;
5616 t1 = type1->t & VT_TYPE;
5617 t2 = type2->t & VT_TYPE;
5618 /* XXX: bitfields ? */
5619 if (t1 != t2)
5620 return 0;
5621 /* test more complicated cases */
5622 bt1 = t1 & VT_BTYPE;
5623 if (bt1 == VT_PTR) {
5624 type1 = pointed_type(type1);
5625 type2 = pointed_type(type2);
5626 return is_compatible_types(type1, type2);
5627 } else if (bt1 == VT_STRUCT) {
5628 return (type1->ref == type2->ref);
5629 } else if (bt1 == VT_FUNC) {
5630 return is_compatible_func(type1, type2);
5631 } else {
5632 return 1;
5636 /* print a type. If 'varstr' is not NULL, then the variable is also
5637 printed in the type */
5638 /* XXX: union */
5639 /* XXX: add array and function pointers */
5640 void type_to_str(char *buf, int buf_size,
5641 CType *type, const char *varstr)
5643 int bt, v, t;
5644 Sym *s, *sa;
5645 char buf1[256];
5646 const char *tstr;
5648 t = type->t & VT_TYPE;
5649 bt = t & VT_BTYPE;
5650 buf[0] = '\0';
5651 if (t & VT_CONSTANT)
5652 pstrcat(buf, buf_size, "const ");
5653 if (t & VT_VOLATILE)
5654 pstrcat(buf, buf_size, "volatile ");
5655 if (t & VT_UNSIGNED)
5656 pstrcat(buf, buf_size, "unsigned ");
5657 switch(bt) {
5658 case VT_VOID:
5659 tstr = "void";
5660 goto add_tstr;
5661 case VT_BOOL:
5662 tstr = "_Bool";
5663 goto add_tstr;
5664 case VT_BYTE:
5665 tstr = "char";
5666 goto add_tstr;
5667 case VT_SHORT:
5668 tstr = "short";
5669 goto add_tstr;
5670 case VT_INT:
5671 tstr = "int";
5672 goto add_tstr;
5673 case VT_LONG:
5674 tstr = "long";
5675 goto add_tstr;
5676 case VT_LLONG:
5677 tstr = "long long";
5678 goto add_tstr;
5679 case VT_FLOAT:
5680 tstr = "float";
5681 goto add_tstr;
5682 case VT_DOUBLE:
5683 tstr = "double";
5684 goto add_tstr;
5685 case VT_LDOUBLE:
5686 tstr = "long double";
5687 add_tstr:
5688 pstrcat(buf, buf_size, tstr);
5689 break;
5690 case VT_ENUM:
5691 case VT_STRUCT:
5692 if (bt == VT_STRUCT)
5693 tstr = "struct ";
5694 else
5695 tstr = "enum ";
5696 pstrcat(buf, buf_size, tstr);
5697 v = type->ref->v & ~SYM_STRUCT;
5698 if (v >= SYM_FIRST_ANOM)
5699 pstrcat(buf, buf_size, "<anonymous>");
5700 else
5701 pstrcat(buf, buf_size, get_tok_str(v, NULL));
5702 break;
5703 case VT_FUNC:
5704 s = type->ref;
5705 type_to_str(buf, buf_size, &s->type, varstr);
5706 pstrcat(buf, buf_size, "(");
5707 sa = s->next;
5708 while (sa != NULL) {
5709 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
5710 pstrcat(buf, buf_size, buf1);
5711 sa = sa->next;
5712 if (sa)
5713 pstrcat(buf, buf_size, ", ");
5715 pstrcat(buf, buf_size, ")");
5716 goto no_var;
5717 case VT_PTR:
5718 s = type->ref;
5719 pstrcpy(buf1, sizeof(buf1), "*");
5720 if (varstr)
5721 pstrcat(buf1, sizeof(buf1), varstr);
5722 type_to_str(buf, buf_size, &s->type, buf1);
5723 goto no_var;
5725 if (varstr) {
5726 pstrcat(buf, buf_size, " ");
5727 pstrcat(buf, buf_size, varstr);
5729 no_var: ;
5732 /* verify type compatibility to store vtop in 'dt' type, and generate
5733 casts if needed. */
5734 static void gen_assign_cast(CType *dt)
5736 CType *st, *type1, *type2, tmp_type1, tmp_type2;
5737 char buf1[256], buf2[256];
5738 int dbt, sbt;
5740 st = &vtop->type; /* source type */
5741 dbt = dt->t & VT_BTYPE;
5742 sbt = st->t & VT_BTYPE;
5743 if (dt->t & VT_CONSTANT)
5744 warning("assignment of read-only location");
5745 switch(dbt) {
5746 case VT_PTR:
5747 /* special cases for pointers */
5748 /* '0' can also be a pointer */
5749 if (is_null_pointer(vtop))
5750 goto type_ok;
5751 /* accept implicit pointer to integer cast with warning */
5752 if (is_integer_btype(sbt)) {
5753 warning("assignment makes pointer from integer without a cast");
5754 goto type_ok;
5756 type1 = pointed_type(dt);
5757 /* a function is implicitely a function pointer */
5758 if (sbt == VT_FUNC) {
5759 if ((type1->t & VT_BTYPE) != VT_VOID &&
5760 !is_compatible_types(pointed_type(dt), st))
5761 goto error;
5762 else
5763 goto type_ok;
5765 if (sbt != VT_PTR)
5766 goto error;
5767 type2 = pointed_type(st);
5768 if ((type1->t & VT_BTYPE) == VT_VOID ||
5769 (type2->t & VT_BTYPE) == VT_VOID) {
5770 /* void * can match anything */
5771 } else {
5772 /* exact type match, except for unsigned */
5773 tmp_type1 = *type1;
5774 tmp_type2 = *type2;
5775 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
5776 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
5777 if (!is_compatible_types(&tmp_type1, &tmp_type2))
5778 goto error;
5780 /* check const and volatile */
5781 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
5782 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
5783 warning("assignment discards qualifiers from pointer target type");
5784 break;
5785 case VT_BYTE:
5786 case VT_SHORT:
5787 case VT_INT:
5788 case VT_LLONG:
5789 if (sbt == VT_PTR || sbt == VT_FUNC) {
5790 warning("assignment makes integer from pointer without a cast");
5792 /* XXX: more tests */
5793 break;
5794 case VT_STRUCT:
5795 if (!is_compatible_types(dt, st)) {
5796 error:
5797 type_to_str(buf1, sizeof(buf1), st, NULL);
5798 type_to_str(buf2, sizeof(buf2), dt, NULL);
5799 error("cannot cast '%s' to '%s'", buf1, buf2);
5801 break;
5803 type_ok:
5804 gen_cast(dt);
5807 /* store vtop in lvalue pushed on stack */
5808 void vstore(void)
5810 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
5812 ft = vtop[-1].type.t;
5813 sbt = vtop->type.t & VT_BTYPE;
5814 dbt = ft & VT_BTYPE;
5815 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
5816 (sbt == VT_INT && dbt == VT_SHORT)) {
5817 /* optimize char/short casts */
5818 delayed_cast = VT_MUSTCAST;
5819 vtop->type.t = ft & VT_TYPE;
5820 /* XXX: factorize */
5821 if (ft & VT_CONSTANT)
5822 warning("assignment of read-only location");
5823 } else {
5824 delayed_cast = 0;
5825 gen_assign_cast(&vtop[-1].type);
5828 if (sbt == VT_STRUCT) {
5829 /* if structure, only generate pointer */
5830 /* structure assignment : generate memcpy */
5831 /* XXX: optimize if small size */
5832 if (!nocode_wanted) {
5833 size = type_size(&vtop->type, &align);
5835 vpush_global_sym(&func_old_type, TOK_memcpy);
5837 /* destination */
5838 vpushv(vtop - 2);
5839 vtop->type.t = VT_INT;
5840 gaddrof();
5841 /* source */
5842 vpushv(vtop - 2);
5843 vtop->type.t = VT_INT;
5844 gaddrof();
5845 /* type size */
5846 vpushi(size);
5847 gfunc_call(3);
5849 vswap();
5850 vpop();
5851 } else {
5852 vswap();
5853 vpop();
5855 /* leave source on stack */
5856 } else if (ft & VT_BITFIELD) {
5857 /* bitfield store handling */
5858 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
5859 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5860 /* remove bit field info to avoid loops */
5861 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
5863 /* duplicate destination */
5864 vdup();
5865 vtop[-1] = vtop[-2];
5867 /* mask and shift source */
5868 vpushi((1 << bit_size) - 1);
5869 gen_op('&');
5870 vpushi(bit_pos);
5871 gen_op(TOK_SHL);
5872 /* load destination, mask and or with source */
5873 vswap();
5874 vpushi(~(((1 << bit_size) - 1) << bit_pos));
5875 gen_op('&');
5876 gen_op('|');
5877 /* store result */
5878 vstore();
5879 } else {
5880 #ifdef CONFIG_TCC_BCHECK
5881 /* bound check case */
5882 if (vtop[-1].r & VT_MUSTBOUND) {
5883 vswap();
5884 gbound();
5885 vswap();
5887 #endif
5888 if (!nocode_wanted) {
5889 rc = RC_INT;
5890 if (is_float(ft))
5891 rc = RC_FLOAT;
5892 r = gv(rc); /* generate value */
5893 /* if lvalue was saved on stack, must read it */
5894 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
5895 SValue sv;
5896 t = get_reg(RC_INT);
5897 sv.type.t = VT_INT;
5898 sv.r = VT_LOCAL | VT_LVAL;
5899 sv.c.ul = vtop[-1].c.ul;
5900 load(t, &sv);
5901 vtop[-1].r = t | VT_LVAL;
5903 store(r, vtop - 1);
5904 /* two word case handling : store second register at word + 4 */
5905 if ((ft & VT_BTYPE) == VT_LLONG) {
5906 vswap();
5907 /* convert to int to increment easily */
5908 vtop->type.t = VT_INT;
5909 gaddrof();
5910 vpushi(4);
5911 gen_op('+');
5912 vtop->r |= VT_LVAL;
5913 vswap();
5914 /* XXX: it works because r2 is spilled last ! */
5915 store(vtop->r2, vtop - 1);
5918 vswap();
5919 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5920 vtop->r |= delayed_cast;
5924 /* post defines POST/PRE add. c is the token ++ or -- */
5925 void inc(int post, int c)
5927 test_lvalue();
5928 vdup(); /* save lvalue */
5929 if (post) {
5930 gv_dup(); /* duplicate value */
5931 vrotb(3);
5932 vrotb(3);
5934 /* add constant */
5935 vpushi(c - TOK_MID);
5936 gen_op('+');
5937 vstore(); /* store value */
5938 if (post)
5939 vpop(); /* if post op, return saved value */
5942 /* Parse GNUC __attribute__ extension. Currently, the following
5943 extensions are recognized:
5944 - aligned(n) : set data/function alignment.
5945 - section(x) : generate data/code in this section.
5946 - unused : currently ignored, but may be used someday.
5948 static void parse_attribute(AttributeDef *ad)
5950 int t, n;
5952 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
5953 next();
5954 skip('(');
5955 skip('(');
5956 while (tok != ')') {
5957 if (tok < TOK_IDENT)
5958 expect("attribute name");
5959 t = tok;
5960 next();
5961 switch(t) {
5962 case TOK_SECTION1:
5963 case TOK_SECTION2:
5964 skip('(');
5965 if (tok != TOK_STR)
5966 expect("section name");
5967 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
5968 next();
5969 skip(')');
5970 break;
5971 case TOK_ALIGNED1:
5972 case TOK_ALIGNED2:
5973 if (tok == '(') {
5974 next();
5975 n = expr_const();
5976 if (n <= 0 || (n & (n - 1)) != 0)
5977 error("alignment must be a positive power of two");
5978 skip(')');
5979 } else {
5980 n = MAX_ALIGN;
5982 ad->aligned = n;
5983 break;
5984 case TOK_UNUSED1:
5985 case TOK_UNUSED2:
5986 /* currently, no need to handle it because tcc does not
5987 track unused objects */
5988 break;
5989 case TOK_NORETURN1:
5990 case TOK_NORETURN2:
5991 /* currently, no need to handle it because tcc does not
5992 track unused objects */
5993 break;
5994 case TOK_CDECL1:
5995 case TOK_CDECL2:
5996 case TOK_CDECL3:
5997 ad->func_call = FUNC_CDECL;
5998 break;
5999 case TOK_STDCALL1:
6000 case TOK_STDCALL2:
6001 case TOK_STDCALL3:
6002 ad->func_call = FUNC_STDCALL;
6003 break;
6004 default:
6005 if (tcc_state->warn_unsupported)
6006 warning("'%s' attribute ignored", get_tok_str(t, NULL));
6007 /* skip parameters */
6008 /* XXX: skip parenthesis too */
6009 if (tok == '(') {
6010 next();
6011 while (tok != ')' && tok != -1)
6012 next();
6013 next();
6015 break;
6017 if (tok != ',')
6018 break;
6019 next();
6021 skip(')');
6022 skip(')');
6026 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
6027 static void struct_decl(CType *type, int u)
6029 int a, v, size, align, maxalign, c, offset;
6030 int bit_size, bit_pos, bsize, bt, lbit_pos;
6031 Sym *s, *ss, **ps;
6032 AttributeDef ad;
6033 CType type1, btype;
6035 a = tok; /* save decl type */
6036 next();
6037 if (tok != '{') {
6038 v = tok;
6039 next();
6040 /* struct already defined ? return it */
6041 if (v < TOK_IDENT)
6042 expect("struct/union/enum name");
6043 s = struct_find(v);
6044 if (s) {
6045 if (s->type.t != a)
6046 error("invalid type");
6047 goto do_decl;
6049 } else {
6050 v = anon_sym++;
6052 type1.t = a;
6053 /* we put an undefined size for struct/union */
6054 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
6055 s->r = 0; /* default alignment is zero as gcc */
6056 /* put struct/union/enum name in type */
6057 do_decl:
6058 type->t = u;
6059 type->ref = s;
6061 if (tok == '{') {
6062 next();
6063 if (s->c != -1)
6064 error("struct/union/enum already defined");
6065 /* cannot be empty */
6066 c = 0;
6067 /* non empty enums are not allowed */
6068 if (a == TOK_ENUM) {
6069 for(;;) {
6070 v = tok;
6071 if (v < TOK_UIDENT)
6072 expect("identifier");
6073 next();
6074 if (tok == '=') {
6075 next();
6076 c = expr_const();
6078 /* enum symbols have static storage */
6079 ss = sym_push(v, &int_type, VT_CONST, c);
6080 ss->type.t |= VT_STATIC;
6081 if (tok != ',')
6082 break;
6083 next();
6084 c++;
6085 /* NOTE: we accept a trailing comma */
6086 if (tok == '}')
6087 break;
6089 skip('}');
6090 } else {
6091 maxalign = 1;
6092 ps = &s->next;
6093 bit_pos = 0;
6094 offset = 0;
6095 while (tok != '}') {
6096 parse_btype(&btype, &ad);
6097 while (1) {
6098 bit_size = -1;
6099 v = 0;
6100 type1 = btype;
6101 if (tok != ':') {
6102 type_decl(&type1, &ad, &v, TYPE_DIRECT);
6103 if ((type1.t & VT_BTYPE) == VT_FUNC ||
6104 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
6105 error("invalid type for '%s'",
6106 get_tok_str(v, NULL));
6108 if (tok == ':') {
6109 next();
6110 bit_size = expr_const();
6111 /* XXX: handle v = 0 case for messages */
6112 if (bit_size < 0)
6113 error("negative width in bit-field '%s'",
6114 get_tok_str(v, NULL));
6115 if (v && bit_size == 0)
6116 error("zero width for bit-field '%s'",
6117 get_tok_str(v, NULL));
6119 size = type_size(&type1, &align);
6120 lbit_pos = 0;
6121 if (bit_size >= 0) {
6122 bt = type1.t & VT_BTYPE;
6123 if (bt != VT_INT &&
6124 bt != VT_BYTE &&
6125 bt != VT_SHORT &&
6126 bt != VT_ENUM)
6127 error("bitfields must have scalar type");
6128 bsize = size * 8;
6129 if (bit_size > bsize) {
6130 error("width of '%s' exceeds its type",
6131 get_tok_str(v, NULL));
6132 } else if (bit_size == bsize) {
6133 /* no need for bit fields */
6134 bit_pos = 0;
6135 } else if (bit_size == 0) {
6136 /* XXX: what to do if only padding in a
6137 structure ? */
6138 /* zero size: means to pad */
6139 if (bit_pos > 0)
6140 bit_pos = bsize;
6141 } else {
6142 /* we do not have enough room ? */
6143 if ((bit_pos + bit_size) > bsize)
6144 bit_pos = 0;
6145 lbit_pos = bit_pos;
6146 /* XXX: handle LSB first */
6147 type1.t |= VT_BITFIELD |
6148 (bit_pos << VT_STRUCT_SHIFT) |
6149 (bit_size << (VT_STRUCT_SHIFT + 6));
6150 bit_pos += bit_size;
6152 } else {
6153 bit_pos = 0;
6155 if (v) {
6156 /* add new memory data only if starting
6157 bit field */
6158 if (lbit_pos == 0) {
6159 if (a == TOK_STRUCT) {
6160 c = (c + align - 1) & -align;
6161 offset = c;
6162 c += size;
6163 } else {
6164 offset = 0;
6165 if (size > c)
6166 c = size;
6168 if (align > maxalign)
6169 maxalign = align;
6171 #if 0
6172 printf("add field %s offset=%d",
6173 get_tok_str(v, NULL), offset);
6174 if (type1.t & VT_BITFIELD) {
6175 printf(" pos=%d size=%d",
6176 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
6177 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
6179 printf("\n");
6180 #endif
6181 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
6182 *ps = ss;
6183 ps = &ss->next;
6185 if (tok == ';' || tok == TOK_EOF)
6186 break;
6187 skip(',');
6189 skip(';');
6191 skip('}');
6192 /* store size and alignment */
6193 s->c = (c + maxalign - 1) & -maxalign;
6194 s->r = maxalign;
6199 /* return 0 if no type declaration. otherwise, return the basic type
6200 and skip it.
6202 static int parse_btype(CType *type, AttributeDef *ad)
6204 int t, u, type_found;
6205 Sym *s;
6206 CType type1;
6208 memset(ad, 0, sizeof(AttributeDef));
6209 type_found = 0;
6210 t = 0;
6211 while(1) {
6212 switch(tok) {
6213 case TOK_EXTENSION:
6214 /* currently, we really ignore extension */
6215 next();
6216 continue;
6218 /* basic types */
6219 case TOK_CHAR:
6220 u = VT_BYTE;
6221 basic_type:
6222 next();
6223 basic_type1:
6224 if ((t & VT_BTYPE) != 0)
6225 error("too many basic types");
6226 t |= u;
6227 break;
6228 case TOK_VOID:
6229 u = VT_VOID;
6230 goto basic_type;
6231 case TOK_SHORT:
6232 u = VT_SHORT;
6233 goto basic_type;
6234 case TOK_INT:
6235 next();
6236 break;
6237 case TOK_LONG:
6238 next();
6239 if ((t & VT_BTYPE) == VT_DOUBLE) {
6240 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
6241 } else if ((t & VT_BTYPE) == VT_LONG) {
6242 t = (t & ~VT_BTYPE) | VT_LLONG;
6243 } else {
6244 u = VT_LONG;
6245 goto basic_type1;
6247 break;
6248 case TOK_BOOL:
6249 u = VT_BOOL;
6250 goto basic_type;
6251 case TOK_FLOAT:
6252 u = VT_FLOAT;
6253 goto basic_type;
6254 case TOK_DOUBLE:
6255 next();
6256 if ((t & VT_BTYPE) == VT_LONG) {
6257 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
6258 } else {
6259 u = VT_DOUBLE;
6260 goto basic_type1;
6262 break;
6263 case TOK_ENUM:
6264 struct_decl(&type1, VT_ENUM);
6265 basic_type2:
6266 u = type1.t;
6267 type->ref = type1.ref;
6268 goto basic_type1;
6269 case TOK_STRUCT:
6270 case TOK_UNION:
6271 struct_decl(&type1, VT_STRUCT);
6272 goto basic_type2;
6274 /* type modifiers */
6275 case TOK_CONST1:
6276 case TOK_CONST2:
6277 case TOK_CONST3:
6278 t |= VT_CONSTANT;
6279 next();
6280 break;
6281 case TOK_VOLATILE1:
6282 case TOK_VOLATILE2:
6283 case TOK_VOLATILE3:
6284 t |= VT_VOLATILE;
6285 next();
6286 break;
6287 case TOK_REGISTER:
6288 case TOK_SIGNED1:
6289 case TOK_SIGNED2:
6290 case TOK_SIGNED3:
6291 case TOK_AUTO:
6292 case TOK_RESTRICT1:
6293 case TOK_RESTRICT2:
6294 case TOK_RESTRICT3:
6295 next();
6296 break;
6297 case TOK_UNSIGNED:
6298 t |= VT_UNSIGNED;
6299 next();
6300 break;
6302 /* storage */
6303 case TOK_EXTERN:
6304 t |= VT_EXTERN;
6305 next();
6306 break;
6307 case TOK_STATIC:
6308 t |= VT_STATIC;
6309 next();
6310 break;
6311 case TOK_TYPEDEF:
6312 t |= VT_TYPEDEF;
6313 next();
6314 break;
6315 case TOK_INLINE1:
6316 case TOK_INLINE2:
6317 case TOK_INLINE3:
6318 t |= VT_INLINE;
6319 next();
6320 break;
6322 /* GNUC attribute */
6323 case TOK_ATTRIBUTE1:
6324 case TOK_ATTRIBUTE2:
6325 parse_attribute(ad);
6326 break;
6327 /* GNUC typeof */
6328 case TOK_TYPEOF1:
6329 case TOK_TYPEOF2:
6330 case TOK_TYPEOF3:
6331 next();
6332 parse_expr_type(&type1);
6333 goto basic_type2;
6334 default:
6335 s = sym_find(tok);
6336 if (!s || !(s->type.t & VT_TYPEDEF))
6337 goto the_end;
6338 t |= (s->type.t & ~VT_TYPEDEF);
6339 type->ref = s->type.ref;
6340 next();
6341 break;
6343 type_found = 1;
6345 the_end:
6346 /* long is never used as type */
6347 if ((t & VT_BTYPE) == VT_LONG)
6348 t = (t & ~VT_BTYPE) | VT_INT;
6349 type->t = t;
6350 return type_found;
6353 /* convert a function parameter type (array to pointer and function to
6354 function pointer) */
6355 static inline void convert_parameter_type(CType *pt)
6357 /* array must be transformed to pointer according to ANSI C */
6358 pt->t &= ~VT_ARRAY;
6359 if ((pt->t & VT_BTYPE) == VT_FUNC) {
6360 mk_pointer(pt);
6364 static void post_type(CType *type, AttributeDef *ad)
6366 int n, l, t1;
6367 Sym **plast, *s, *first;
6368 AttributeDef ad1;
6369 CType pt;
6371 if (tok == '(') {
6372 /* function declaration */
6373 next();
6374 l = 0;
6375 first = NULL;
6376 plast = &first;
6377 while (tok != ')') {
6378 /* read param name and compute offset */
6379 if (l != FUNC_OLD) {
6380 if (!parse_btype(&pt, &ad1)) {
6381 if (l) {
6382 error("invalid type");
6383 } else {
6384 l = FUNC_OLD;
6385 goto old_proto;
6388 l = FUNC_NEW;
6389 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
6390 break;
6391 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
6392 if ((pt.t & VT_BTYPE) == VT_VOID)
6393 error("parameter declared as void");
6394 } else {
6395 old_proto:
6396 n = tok;
6397 pt.t = VT_INT;
6398 next();
6400 convert_parameter_type(&pt);
6401 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
6402 *plast = s;
6403 plast = &s->next;
6404 if (tok == ',') {
6405 next();
6406 if (l == FUNC_NEW && tok == TOK_DOTS) {
6407 l = FUNC_ELLIPSIS;
6408 next();
6409 break;
6413 /* if no parameters, then old type prototype */
6414 if (l == 0)
6415 l = FUNC_OLD;
6416 skip(')');
6417 t1 = type->t & VT_STORAGE;
6418 /* NOTE: const is ignored in returned type as it has a special
6419 meaning in gcc / C++ */
6420 type->t &= ~(VT_STORAGE | VT_CONSTANT);
6421 post_type(type, ad);
6422 /* we push a anonymous symbol which will contain the function prototype */
6423 s = sym_push(SYM_FIELD, type, ad->func_call, l);
6424 s->next = first;
6425 type->t = t1 | VT_FUNC;
6426 type->ref = s;
6427 } else if (tok == '[') {
6428 /* array definition */
6429 next();
6430 n = -1;
6431 if (tok != ']') {
6432 n = expr_const();
6433 if (n < 0)
6434 error("invalid array size");
6436 skip(']');
6437 /* parse next post type */
6438 t1 = type->t & VT_STORAGE;
6439 type->t &= ~VT_STORAGE;
6440 post_type(type, ad);
6442 /* we push a anonymous symbol which will contain the array
6443 element type */
6444 s = sym_push(SYM_FIELD, type, 0, n);
6445 type->t = t1 | VT_ARRAY | VT_PTR;
6446 type->ref = s;
6450 /* Parse a type declaration (except basic type), and return the type
6451 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6452 expected. 'type' should contain the basic type. 'ad' is the
6453 attribute definition of the basic type. It can be modified by
6454 type_decl().
6456 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
6458 Sym *s;
6459 CType type1, *type2;
6460 int qualifiers;
6462 while (tok == '*') {
6463 qualifiers = 0;
6464 redo:
6465 next();
6466 switch(tok) {
6467 case TOK_CONST1:
6468 case TOK_CONST2:
6469 case TOK_CONST3:
6470 qualifiers |= VT_CONSTANT;
6471 goto redo;
6472 case TOK_VOLATILE1:
6473 case TOK_VOLATILE2:
6474 case TOK_VOLATILE3:
6475 qualifiers |= VT_VOLATILE;
6476 goto redo;
6477 case TOK_RESTRICT1:
6478 case TOK_RESTRICT2:
6479 case TOK_RESTRICT3:
6480 goto redo;
6482 mk_pointer(type);
6483 type->t |= qualifiers;
6486 /* XXX: clarify attribute handling */
6487 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6488 parse_attribute(ad);
6490 /* recursive type */
6491 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6492 type1.t = 0; /* XXX: same as int */
6493 if (tok == '(') {
6494 next();
6495 /* XXX: this is not correct to modify 'ad' at this point, but
6496 the syntax is not clear */
6497 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6498 parse_attribute(ad);
6499 type_decl(&type1, ad, v, td);
6500 skip(')');
6501 } else {
6502 /* type identifier */
6503 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
6504 *v = tok;
6505 next();
6506 } else {
6507 if (!(td & TYPE_ABSTRACT))
6508 expect("identifier");
6509 *v = 0;
6512 post_type(type, ad);
6513 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6514 parse_attribute(ad);
6515 if (!type1.t)
6516 return;
6517 /* append type at the end of type1 */
6518 type2 = &type1;
6519 for(;;) {
6520 s = type2->ref;
6521 type2 = &s->type;
6522 if (!type2->t) {
6523 *type2 = *type;
6524 break;
6527 *type = type1;
6530 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6531 static int lvalue_type(int t)
6533 int bt, r;
6534 r = VT_LVAL;
6535 bt = t & VT_BTYPE;
6536 if (bt == VT_BYTE || bt == VT_BOOL)
6537 r |= VT_LVAL_BYTE;
6538 else if (bt == VT_SHORT)
6539 r |= VT_LVAL_SHORT;
6540 else
6541 return r;
6542 if (t & VT_UNSIGNED)
6543 r |= VT_LVAL_UNSIGNED;
6544 return r;
6547 /* indirection with full error checking and bound check */
6548 static void indir(void)
6550 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6551 expect("pointer");
6552 if ((vtop->r & VT_LVAL) && !nocode_wanted)
6553 gv(RC_INT);
6554 vtop->type = *pointed_type(&vtop->type);
6555 /* an array is never an lvalue */
6556 if (!(vtop->type.t & VT_ARRAY)) {
6557 vtop->r |= lvalue_type(vtop->type.t);
6558 /* if bound checking, the referenced pointer must be checked */
6559 if (do_bounds_check)
6560 vtop->r |= VT_MUSTBOUND;
6564 /* pass a parameter to a function and do type checking and casting */
6565 static void gfunc_param_typed(Sym *func, Sym *arg)
6567 int func_type;
6568 CType type;
6570 func_type = func->c;
6571 if (func_type == FUNC_OLD ||
6572 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
6573 /* default casting : only need to convert float to double */
6574 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
6575 type.t = VT_DOUBLE;
6576 gen_cast(&type);
6578 } else if (arg == NULL) {
6579 error("too many arguments to function");
6580 } else {
6581 gen_assign_cast(&arg->type);
6585 /* parse an expression of the form '(type)' or '(expr)' and return its
6586 type */
6587 static void parse_expr_type(CType *type)
6589 int n;
6590 AttributeDef ad;
6592 skip('(');
6593 if (parse_btype(type, &ad)) {
6594 type_decl(type, &ad, &n, TYPE_ABSTRACT);
6595 } else {
6596 expr_type(type);
6598 skip(')');
6601 static void parse_type(CType *type)
6603 AttributeDef ad;
6604 int n;
6606 if (!parse_btype(type, &ad)) {
6607 expect("type");
6609 type_decl(type, &ad, &n, TYPE_ABSTRACT);
6612 static void vpush_tokc(int t)
6614 CType type;
6615 type.t = t;
6616 vsetc(&type, VT_CONST, &tokc);
6619 static void unary(void)
6621 int n, t, align, size, r;
6622 CType type;
6623 Sym *s;
6624 AttributeDef ad;
6626 /* XXX: GCC 2.95.3 does not generate a table although it should be
6627 better here */
6628 tok_next:
6629 switch(tok) {
6630 case TOK_EXTENSION:
6631 next();
6632 goto tok_next;
6633 case TOK_CINT:
6634 case TOK_CCHAR:
6635 case TOK_LCHAR:
6636 vpushi(tokc.i);
6637 next();
6638 break;
6639 case TOK_CUINT:
6640 vpush_tokc(VT_INT | VT_UNSIGNED);
6641 next();
6642 break;
6643 case TOK_CLLONG:
6644 vpush_tokc(VT_LLONG);
6645 next();
6646 break;
6647 case TOK_CULLONG:
6648 vpush_tokc(VT_LLONG | VT_UNSIGNED);
6649 next();
6650 break;
6651 case TOK_CFLOAT:
6652 vpush_tokc(VT_FLOAT);
6653 next();
6654 break;
6655 case TOK_CDOUBLE:
6656 vpush_tokc(VT_DOUBLE);
6657 next();
6658 break;
6659 case TOK_CLDOUBLE:
6660 vpush_tokc(VT_LDOUBLE);
6661 next();
6662 break;
6663 case TOK___FUNCTION__:
6664 if (!gnu_ext)
6665 goto tok_identifier;
6666 /* fall thru */
6667 case TOK___FUNC__:
6669 void *ptr;
6670 int len;
6671 /* special function name identifier */
6672 len = strlen(funcname) + 1;
6673 /* generate char[len] type */
6674 type.t = VT_BYTE;
6675 mk_pointer(&type);
6676 type.t |= VT_ARRAY;
6677 type.ref->c = len;
6678 vpush_ref(&type, data_section, data_section->data_offset, len);
6679 ptr = section_ptr_add(data_section, len);
6680 memcpy(ptr, funcname, len);
6681 next();
6683 break;
6684 case TOK_LSTR:
6685 t = VT_INT;
6686 goto str_init;
6687 case TOK_STR:
6688 /* string parsing */
6689 t = VT_BYTE;
6690 str_init:
6691 if (tcc_state->warn_write_strings)
6692 t |= VT_CONSTANT;
6693 type.t = t;
6694 mk_pointer(&type);
6695 type.t |= VT_ARRAY;
6696 memset(&ad, 0, sizeof(AttributeDef));
6697 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
6698 break;
6699 case '(':
6700 next();
6701 /* cast ? */
6702 if (parse_btype(&type, &ad)) {
6703 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
6704 skip(')');
6705 /* check ISOC99 compound literal */
6706 if (tok == '{') {
6707 /* data is allocated locally by default */
6708 if (global_expr)
6709 r = VT_CONST;
6710 else
6711 r = VT_LOCAL;
6712 /* all except arrays are lvalues */
6713 if (!(type.t & VT_ARRAY))
6714 r |= lvalue_type(type.t);
6715 memset(&ad, 0, sizeof(AttributeDef));
6716 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
6717 } else {
6718 unary();
6719 gen_cast(&type);
6721 } else if (tok == '{') {
6722 /* save all registers */
6723 save_regs(0);
6724 /* statement expression : we do not accept break/continue
6725 inside as GCC does */
6726 block(NULL, NULL, NULL, NULL, 0, 1);
6727 skip(')');
6728 } else {
6729 gexpr();
6730 skip(')');
6732 break;
6733 case '*':
6734 next();
6735 unary();
6736 indir();
6737 break;
6738 case '&':
6739 next();
6740 unary();
6741 /* functions names must be treated as function pointers,
6742 except for unary '&' and sizeof. Since we consider that
6743 functions are not lvalues, we only have to handle it
6744 there and in function calls. */
6745 /* arrays can also be used although they are not lvalues */
6746 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
6747 !(vtop->type.t & VT_ARRAY))
6748 test_lvalue();
6749 mk_pointer(&vtop->type);
6750 gaddrof();
6751 break;
6752 case '!':
6753 next();
6754 unary();
6755 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
6756 vtop->c.i = !vtop->c.i;
6757 else if ((vtop->r & VT_VALMASK) == VT_CMP)
6758 vtop->c.i = vtop->c.i ^ 1;
6759 else
6760 vseti(VT_JMP, gtst(1, 0));
6761 break;
6762 case '~':
6763 next();
6764 unary();
6765 vpushi(-1);
6766 gen_op('^');
6767 break;
6768 case '+':
6769 next();
6770 /* in order to force cast, we add zero */
6771 unary();
6772 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
6773 error("pointer not accepted for unary plus");
6774 vpushi(0);
6775 gen_op('+');
6776 break;
6777 case TOK_SIZEOF:
6778 case TOK_ALIGNOF1:
6779 case TOK_ALIGNOF2:
6780 t = tok;
6781 next();
6782 if (tok == '(') {
6783 parse_expr_type(&type);
6784 } else {
6785 unary_type(&type);
6787 size = type_size(&type, &align);
6788 if (t == TOK_SIZEOF) {
6789 if (size < 0)
6790 error("sizeof applied to an incomplete type");
6791 vpushi(size);
6792 } else {
6793 vpushi(align);
6795 break;
6797 case TOK_builtin_types_compatible_p:
6799 CType type1, type2;
6800 next();
6801 skip('(');
6802 parse_type(&type1);
6803 skip(',');
6804 parse_type(&type2);
6805 skip(')');
6806 type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
6807 type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
6808 vpushi(is_compatible_types(&type1, &type2));
6810 break;
6811 case TOK_builtin_constant_p:
6813 int saved_nocode_wanted, res;
6814 next();
6815 skip('(');
6816 saved_nocode_wanted = nocode_wanted;
6817 nocode_wanted = 1;
6818 gexpr();
6819 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
6820 vpop();
6821 nocode_wanted = saved_nocode_wanted;
6822 skip(')');
6823 vpushi(res);
6825 break;
6826 case TOK_INC:
6827 case TOK_DEC:
6828 t = tok;
6829 next();
6830 unary();
6831 inc(0, t);
6832 break;
6833 case '-':
6834 next();
6835 vpushi(0);
6836 unary();
6837 gen_op('-');
6838 break;
6839 case TOK_LAND:
6840 if (!gnu_ext)
6841 goto tok_identifier;
6842 next();
6843 /* allow to take the address of a label */
6844 if (tok < TOK_UIDENT)
6845 expect("label identifier");
6846 s = label_find(tok);
6847 if (!s) {
6848 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
6849 } else {
6850 if (s->r == LABEL_DECLARED)
6851 s->r = LABEL_FORWARD;
6853 if (!s->type.t) {
6854 s->type.t = VT_VOID;
6855 mk_pointer(&s->type);
6856 s->type.t |= VT_STATIC;
6858 vset(&s->type, VT_CONST | VT_SYM, 0);
6859 vtop->sym = s;
6860 next();
6861 break;
6862 default:
6863 tok_identifier:
6864 t = tok;
6865 next();
6866 if (t < TOK_UIDENT)
6867 expect("identifier");
6868 s = sym_find(t);
6869 if (!s) {
6870 if (tok != '(')
6871 error("'%s' undeclared", get_tok_str(t, NULL));
6872 /* for simple function calls, we tolerate undeclared
6873 external reference to int() function */
6874 s = external_global_sym(t, &func_old_type, 0);
6876 vset(&s->type, s->r, s->c);
6877 /* if forward reference, we must point to s */
6878 if (vtop->r & VT_SYM) {
6879 vtop->sym = s;
6880 vtop->c.ul = 0;
6882 break;
6885 /* post operations */
6886 while (1) {
6887 if (tok == TOK_INC || tok == TOK_DEC) {
6888 inc(1, tok);
6889 next();
6890 } else if (tok == '.' || tok == TOK_ARROW) {
6891 /* field */
6892 if (tok == TOK_ARROW)
6893 indir();
6894 test_lvalue();
6895 gaddrof();
6896 next();
6897 /* expect pointer on structure */
6898 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
6899 expect("struct or union");
6900 s = vtop->type.ref;
6901 /* find field */
6902 tok |= SYM_FIELD;
6903 while ((s = s->next) != NULL) {
6904 if (s->v == tok)
6905 break;
6907 if (!s)
6908 error("field not found");
6909 /* add field offset to pointer */
6910 vtop->type = char_pointer_type; /* change type to 'char *' */
6911 vpushi(s->c);
6912 gen_op('+');
6913 /* change type to field type, and set to lvalue */
6914 vtop->type = s->type;
6915 /* an array is never an lvalue */
6916 if (!(vtop->type.t & VT_ARRAY)) {
6917 vtop->r |= lvalue_type(vtop->type.t);
6918 /* if bound checking, the referenced pointer must be checked */
6919 if (do_bounds_check)
6920 vtop->r |= VT_MUSTBOUND;
6922 next();
6923 } else if (tok == '[') {
6924 next();
6925 gexpr();
6926 gen_op('+');
6927 indir();
6928 skip(']');
6929 } else if (tok == '(') {
6930 SValue ret;
6931 Sym *sa;
6932 int nb_args;
6934 /* function call */
6935 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
6936 /* pointer test (no array accepted) */
6937 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
6938 vtop->type = *pointed_type(&vtop->type);
6939 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
6940 goto error_func;
6941 } else {
6942 error_func:
6943 expect("function pointer");
6945 } else {
6946 vtop->r &= ~VT_LVAL; /* no lvalue */
6948 /* get return type */
6949 s = vtop->type.ref;
6950 next();
6951 sa = s->next; /* first parameter */
6952 nb_args = 0;
6953 /* compute first implicit argument if a structure is returned */
6954 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6955 /* get some space for the returned structure */
6956 size = type_size(&s->type, &align);
6957 loc = (loc - size) & -align;
6958 ret.type = s->type;
6959 ret.r = VT_LOCAL | VT_LVAL;
6960 /* pass it as 'int' to avoid structure arg passing
6961 problems */
6962 vseti(VT_LOCAL, loc);
6963 ret.c = vtop->c;
6964 nb_args++;
6965 } else {
6966 ret.type = s->type;
6967 ret.r2 = VT_CONST;
6968 /* return in register */
6969 if (is_float(ret.type.t)) {
6970 ret.r = REG_FRET;
6971 } else {
6972 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
6973 ret.r2 = REG_LRET;
6974 ret.r = REG_IRET;
6976 ret.c.i = 0;
6978 if (tok != ')') {
6979 for(;;) {
6980 expr_eq();
6981 gfunc_param_typed(s, sa);
6982 nb_args++;
6983 if (sa)
6984 sa = sa->next;
6985 if (tok == ')')
6986 break;
6987 skip(',');
6990 if (sa)
6991 error("too few arguments to function");
6992 skip(')');
6993 if (!nocode_wanted) {
6994 gfunc_call(nb_args);
6995 } else {
6996 vtop -= (nb_args + 1);
6998 /* return value */
6999 vsetc(&ret.type, ret.r, &ret.c);
7000 vtop->r2 = ret.r2;
7001 } else {
7002 break;
7007 static void uneq(void)
7009 int t;
7011 unary();
7012 if (tok == '=' ||
7013 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
7014 tok == TOK_A_XOR || tok == TOK_A_OR ||
7015 tok == TOK_A_SHL || tok == TOK_A_SAR) {
7016 test_lvalue();
7017 t = tok;
7018 next();
7019 if (t == '=') {
7020 expr_eq();
7021 } else {
7022 vdup();
7023 expr_eq();
7024 gen_op(t & 0x7f);
7026 vstore();
7030 static void expr_prod(void)
7032 int t;
7034 uneq();
7035 while (tok == '*' || tok == '/' || tok == '%') {
7036 t = tok;
7037 next();
7038 uneq();
7039 gen_op(t);
7043 static void expr_sum(void)
7045 int t;
7047 expr_prod();
7048 while (tok == '+' || tok == '-') {
7049 t = tok;
7050 next();
7051 expr_prod();
7052 gen_op(t);
7056 static void expr_shift(void)
7058 int t;
7060 expr_sum();
7061 while (tok == TOK_SHL || tok == TOK_SAR) {
7062 t = tok;
7063 next();
7064 expr_sum();
7065 gen_op(t);
7069 static void expr_cmp(void)
7071 int t;
7073 expr_shift();
7074 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
7075 tok == TOK_ULT || tok == TOK_UGE) {
7076 t = tok;
7077 next();
7078 expr_shift();
7079 gen_op(t);
7083 static void expr_cmpeq(void)
7085 int t;
7087 expr_cmp();
7088 while (tok == TOK_EQ || tok == TOK_NE) {
7089 t = tok;
7090 next();
7091 expr_cmp();
7092 gen_op(t);
7096 static void expr_and(void)
7098 expr_cmpeq();
7099 while (tok == '&') {
7100 next();
7101 expr_cmpeq();
7102 gen_op('&');
7106 static void expr_xor(void)
7108 expr_and();
7109 while (tok == '^') {
7110 next();
7111 expr_and();
7112 gen_op('^');
7116 static void expr_or(void)
7118 expr_xor();
7119 while (tok == '|') {
7120 next();
7121 expr_xor();
7122 gen_op('|');
7126 /* XXX: fix this mess */
7127 static void expr_land_const(void)
7129 expr_or();
7130 while (tok == TOK_LAND) {
7131 next();
7132 expr_or();
7133 gen_op(TOK_LAND);
7137 /* XXX: fix this mess */
7138 static void expr_lor_const(void)
7140 expr_land_const();
7141 while (tok == TOK_LOR) {
7142 next();
7143 expr_land_const();
7144 gen_op(TOK_LOR);
7148 /* only used if non constant */
7149 static void expr_land(void)
7151 int t;
7153 expr_or();
7154 if (tok == TOK_LAND) {
7155 t = 0;
7156 for(;;) {
7157 t = gtst(1, t);
7158 if (tok != TOK_LAND) {
7159 vseti(VT_JMPI, t);
7160 break;
7162 next();
7163 expr_or();
7168 static void expr_lor(void)
7170 int t;
7172 expr_land();
7173 if (tok == TOK_LOR) {
7174 t = 0;
7175 for(;;) {
7176 t = gtst(0, t);
7177 if (tok != TOK_LOR) {
7178 vseti(VT_JMP, t);
7179 break;
7181 next();
7182 expr_land();
7187 /* XXX: better constant handling */
7188 static void expr_eq(void)
7190 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
7191 SValue sv;
7192 CType type, type1, type2;
7194 if (const_wanted) {
7195 int c1, c;
7196 expr_lor_const();
7197 if (tok == '?') {
7198 c = vtop->c.i;
7199 vpop();
7200 next();
7201 if (tok == ':' && gnu_ext) {
7202 c1 = c;
7203 } else {
7204 gexpr();
7205 c1 = vtop->c.i;
7206 vpop();
7208 skip(':');
7209 expr_eq();
7210 if (c)
7211 vtop->c.i = c1;
7213 } else {
7214 expr_lor();
7215 if (tok == '?') {
7216 next();
7217 if (vtop != vstack) {
7218 /* needed to avoid having different registers saved in
7219 each branch */
7220 if (is_float(vtop->type.t))
7221 rc = RC_FLOAT;
7222 else
7223 rc = RC_INT;
7224 gv(rc);
7225 save_regs(1);
7227 if (tok == ':' && gnu_ext) {
7228 gv_dup();
7229 tt = gtst(1, 0);
7230 } else {
7231 tt = gtst(1, 0);
7232 gexpr();
7234 type1 = vtop->type;
7235 sv = *vtop; /* save value to handle it later */
7236 vtop--; /* no vpop so that FP stack is not flushed */
7237 skip(':');
7238 u = gjmp(0);
7239 gsym(tt);
7240 expr_eq();
7241 type2 = vtop->type;
7243 t1 = type1.t;
7244 bt1 = t1 & VT_BTYPE;
7245 t2 = type2.t;
7246 bt2 = t2 & VT_BTYPE;
7247 /* cast operands to correct type according to ISOC rules */
7248 if (is_float(bt1) || is_float(bt2)) {
7249 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
7250 type.t = VT_LDOUBLE;
7251 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
7252 type.t = VT_DOUBLE;
7253 } else {
7254 type.t = VT_FLOAT;
7256 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
7257 /* cast to biggest op */
7258 type.t = VT_LLONG;
7259 /* convert to unsigned if it does not fit in a long long */
7260 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
7261 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
7262 type.t |= VT_UNSIGNED;
7263 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
7264 /* XXX: test pointer compatibility */
7265 type = type1;
7266 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
7267 /* XXX: test structure compatibility */
7268 type = type1;
7269 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
7270 /* NOTE: as an extension, we accept void on only one side */
7271 type.t = VT_VOID;
7272 } else {
7273 /* integer operations */
7274 type.t = VT_INT;
7275 /* convert to unsigned if it does not fit in an integer */
7276 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
7277 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
7278 type.t |= VT_UNSIGNED;
7281 /* now we convert second operand */
7282 gen_cast(&type);
7283 rc = RC_INT;
7284 if (is_float(type.t)) {
7285 rc = RC_FLOAT;
7286 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
7287 /* for long longs, we use fixed registers to avoid having
7288 to handle a complicated move */
7289 rc = RC_IRET;
7292 r2 = gv(rc);
7293 /* this is horrible, but we must also convert first
7294 operand */
7295 tt = gjmp(0);
7296 gsym(u);
7297 /* put again first value and cast it */
7298 *vtop = sv;
7299 gen_cast(&type);
7300 r1 = gv(rc);
7301 move_reg(r2, r1);
7302 vtop->r = r2;
7303 gsym(tt);
7308 static void gexpr(void)
7310 while (1) {
7311 expr_eq();
7312 if (tok != ',')
7313 break;
7314 vpop();
7315 next();
7319 /* parse an expression and return its type without any side effect. */
7320 static void expr_type(CType *type)
7322 int saved_nocode_wanted;
7324 saved_nocode_wanted = nocode_wanted;
7325 nocode_wanted = 1;
7326 gexpr();
7327 *type = vtop->type;
7328 vpop();
7329 nocode_wanted = saved_nocode_wanted;
7332 /* parse a unary expression and return its type without any side
7333 effect. */
7334 static void unary_type(CType *type)
7336 int a;
7338 a = nocode_wanted;
7339 nocode_wanted = 1;
7340 unary();
7341 *type = vtop->type;
7342 vpop();
7343 nocode_wanted = a;
7346 /* parse a constant expression and return value in vtop. */
7347 static void expr_const1(void)
7349 int a;
7350 a = const_wanted;
7351 const_wanted = 1;
7352 expr_eq();
7353 const_wanted = a;
7356 /* parse an integer constant and return its value. */
7357 static int expr_const(void)
7359 int c;
7360 expr_const1();
7361 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
7362 expect("constant expression");
7363 c = vtop->c.i;
7364 vpop();
7365 return c;
7368 /* return the label token if current token is a label, otherwise
7369 return zero */
7370 static int is_label(void)
7372 int last_tok;
7374 /* fast test first */
7375 if (tok < TOK_UIDENT)
7376 return 0;
7377 /* no need to save tokc because tok is an identifier */
7378 last_tok = tok;
7379 next();
7380 if (tok == ':') {
7381 next();
7382 return last_tok;
7383 } else {
7384 unget_tok(last_tok);
7385 return 0;
7389 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
7390 int case_reg, int is_expr)
7392 int a, b, c, d;
7393 Sym *s;
7395 /* generate line number info */
7396 if (do_debug &&
7397 (last_line_num != file->line_num || last_ind != ind)) {
7398 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
7399 last_ind = ind;
7400 last_line_num = file->line_num;
7403 if (is_expr) {
7404 /* default return value is (void) */
7405 vpushi(0);
7406 vtop->type.t = VT_VOID;
7409 if (tok == TOK_IF) {
7410 /* if test */
7411 next();
7412 skip('(');
7413 gexpr();
7414 skip(')');
7415 a = gtst(1, 0);
7416 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7417 c = tok;
7418 if (c == TOK_ELSE) {
7419 next();
7420 d = gjmp(0);
7421 gsym(a);
7422 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7423 gsym(d); /* patch else jmp */
7424 } else
7425 gsym(a);
7426 } else if (tok == TOK_WHILE) {
7427 next();
7428 d = ind;
7429 skip('(');
7430 gexpr();
7431 skip(')');
7432 a = gtst(1, 0);
7433 b = 0;
7434 block(&a, &b, case_sym, def_sym, case_reg, 0);
7435 gjmp_addr(d);
7436 gsym(a);
7437 gsym_addr(b, d);
7438 } else if (tok == '{') {
7439 Sym *llabel;
7441 next();
7442 /* record local declaration stack position */
7443 s = local_stack;
7444 llabel = local_label_stack;
7445 /* handle local labels declarations */
7446 if (tok == TOK_LABEL) {
7447 next();
7448 for(;;) {
7449 if (tok < TOK_UIDENT)
7450 expect("label identifier");
7451 label_push(&local_label_stack, tok, LABEL_DECLARED);
7452 next();
7453 if (tok == ',') {
7454 next();
7455 } else {
7456 skip(';');
7457 break;
7461 while (tok != '}') {
7462 decl(VT_LOCAL);
7463 if (tok != '}') {
7464 if (is_expr)
7465 vpop();
7466 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
7469 /* pop locally defined labels */
7470 label_pop(&local_label_stack, llabel);
7471 /* pop locally defined symbols */
7472 sym_pop(&local_stack, s);
7473 next();
7474 } else if (tok == TOK_RETURN) {
7475 next();
7476 if (tok != ';') {
7477 gexpr();
7478 gen_assign_cast(&func_vt);
7479 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
7480 CType type;
7481 /* if returning structure, must copy it to implicit
7482 first pointer arg location */
7483 type = func_vt;
7484 mk_pointer(&type);
7485 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
7486 indir();
7487 vswap();
7488 /* copy structure value to pointer */
7489 vstore();
7490 } else if (is_float(func_vt.t)) {
7491 gv(RC_FRET);
7492 } else {
7493 gv(RC_IRET);
7495 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
7497 skip(';');
7498 rsym = gjmp(rsym); /* jmp */
7499 } else if (tok == TOK_BREAK) {
7500 /* compute jump */
7501 if (!bsym)
7502 error("cannot break");
7503 *bsym = gjmp(*bsym);
7504 next();
7505 skip(';');
7506 } else if (tok == TOK_CONTINUE) {
7507 /* compute jump */
7508 if (!csym)
7509 error("cannot continue");
7510 *csym = gjmp(*csym);
7511 next();
7512 skip(';');
7513 } else if (tok == TOK_FOR) {
7514 int e;
7515 next();
7516 skip('(');
7517 if (tok != ';') {
7518 gexpr();
7519 vpop();
7521 skip(';');
7522 d = ind;
7523 c = ind;
7524 a = 0;
7525 b = 0;
7526 if (tok != ';') {
7527 gexpr();
7528 a = gtst(1, 0);
7530 skip(';');
7531 if (tok != ')') {
7532 e = gjmp(0);
7533 c = ind;
7534 gexpr();
7535 vpop();
7536 gjmp_addr(d);
7537 gsym(e);
7539 skip(')');
7540 block(&a, &b, case_sym, def_sym, case_reg, 0);
7541 gjmp_addr(c);
7542 gsym(a);
7543 gsym_addr(b, c);
7544 } else
7545 if (tok == TOK_DO) {
7546 next();
7547 a = 0;
7548 b = 0;
7549 d = ind;
7550 block(&a, &b, case_sym, def_sym, case_reg, 0);
7551 skip(TOK_WHILE);
7552 skip('(');
7553 gsym(b);
7554 gexpr();
7555 c = gtst(0, 0);
7556 gsym_addr(c, d);
7557 skip(')');
7558 gsym(a);
7559 skip(';');
7560 } else
7561 if (tok == TOK_SWITCH) {
7562 next();
7563 skip('(');
7564 gexpr();
7565 /* XXX: other types than integer */
7566 case_reg = gv(RC_INT);
7567 vpop();
7568 skip(')');
7569 a = 0;
7570 b = gjmp(0); /* jump to first case */
7571 c = 0;
7572 block(&a, csym, &b, &c, case_reg, 0);
7573 /* if no default, jmp after switch */
7574 if (c == 0)
7575 c = ind;
7576 /* default label */
7577 gsym_addr(b, c);
7578 /* break label */
7579 gsym(a);
7580 } else
7581 if (tok == TOK_CASE) {
7582 int v1, v2;
7583 if (!case_sym)
7584 expect("switch");
7585 next();
7586 v1 = expr_const();
7587 v2 = v1;
7588 if (gnu_ext && tok == TOK_DOTS) {
7589 next();
7590 v2 = expr_const();
7591 if (v2 < v1)
7592 warning("empty case range");
7594 /* since a case is like a label, we must skip it with a jmp */
7595 b = gjmp(0);
7596 gsym(*case_sym);
7597 vseti(case_reg, 0);
7598 vpushi(v1);
7599 if (v1 == v2) {
7600 gen_op(TOK_EQ);
7601 *case_sym = gtst(1, 0);
7602 } else {
7603 gen_op(TOK_GE);
7604 *case_sym = gtst(1, 0);
7605 vseti(case_reg, 0);
7606 vpushi(v2);
7607 gen_op(TOK_LE);
7608 *case_sym = gtst(1, *case_sym);
7610 gsym(b);
7611 skip(':');
7612 is_expr = 0;
7613 goto block_after_label;
7614 } else
7615 if (tok == TOK_DEFAULT) {
7616 next();
7617 skip(':');
7618 if (!def_sym)
7619 expect("switch");
7620 if (*def_sym)
7621 error("too many 'default'");
7622 *def_sym = ind;
7623 is_expr = 0;
7624 goto block_after_label;
7625 } else
7626 if (tok == TOK_GOTO) {
7627 next();
7628 if (tok == '*' && gnu_ext) {
7629 /* computed goto */
7630 next();
7631 gexpr();
7632 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
7633 expect("pointer");
7634 ggoto();
7635 } else if (tok >= TOK_UIDENT) {
7636 s = label_find(tok);
7637 /* put forward definition if needed */
7638 if (!s) {
7639 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
7640 } else {
7641 if (s->r == LABEL_DECLARED)
7642 s->r = LABEL_FORWARD;
7644 /* label already defined */
7645 if (s->r & LABEL_FORWARD)
7646 s->next = (void *)gjmp((long)s->next);
7647 else
7648 gjmp_addr((long)s->next);
7649 next();
7650 } else {
7651 expect("label identifier");
7653 skip(';');
7654 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
7655 asm_instr();
7656 } else {
7657 b = is_label();
7658 if (b) {
7659 /* label case */
7660 s = label_find(b);
7661 if (s) {
7662 if (s->r == LABEL_DEFINED)
7663 error("duplicate label '%s'", get_tok_str(s->v, NULL));
7664 gsym((long)s->next);
7665 s->r = LABEL_DEFINED;
7666 } else {
7667 s = label_push(&global_label_stack, b, LABEL_DEFINED);
7669 s->next = (void *)ind;
7670 /* we accept this, but it is a mistake */
7671 block_after_label:
7672 if (tok == '}') {
7673 warning("deprecated use of label at end of compound statement");
7674 } else {
7675 if (is_expr)
7676 vpop();
7677 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
7679 } else {
7680 /* expression case */
7681 if (tok != ';') {
7682 if (is_expr) {
7683 vpop();
7684 gexpr();
7685 } else {
7686 gexpr();
7687 vpop();
7690 skip(';');
7695 /* t is the array or struct type. c is the array or struct
7696 address. cur_index/cur_field is the pointer to the current
7697 value. 'size_only' is true if only size info is needed (only used
7698 in arrays) */
7699 static void decl_designator(CType *type, Section *sec, unsigned long c,
7700 int *cur_index, Sym **cur_field,
7701 int size_only)
7703 Sym *s, *f;
7704 int notfirst, index, index_last, align, l, nb_elems, elem_size;
7705 CType type1;
7707 notfirst = 0;
7708 elem_size = 0;
7709 nb_elems = 1;
7710 if (gnu_ext && (l = is_label()) != 0)
7711 goto struct_field;
7712 while (tok == '[' || tok == '.') {
7713 if (tok == '[') {
7714 if (!(type->t & VT_ARRAY))
7715 expect("array type");
7716 s = type->ref;
7717 next();
7718 index = expr_const();
7719 if (index < 0 || (s->c >= 0 && index >= s->c))
7720 expect("invalid index");
7721 if (tok == TOK_DOTS && gnu_ext) {
7722 next();
7723 index_last = expr_const();
7724 if (index_last < 0 ||
7725 (s->c >= 0 && index_last >= s->c) ||
7726 index_last < index)
7727 expect("invalid index");
7728 } else {
7729 index_last = index;
7731 skip(']');
7732 if (!notfirst)
7733 *cur_index = index_last;
7734 type = pointed_type(type);
7735 elem_size = type_size(type, &align);
7736 c += index * elem_size;
7737 /* NOTE: we only support ranges for last designator */
7738 nb_elems = index_last - index + 1;
7739 if (nb_elems != 1) {
7740 notfirst = 1;
7741 break;
7743 } else {
7744 next();
7745 l = tok;
7746 next();
7747 struct_field:
7748 if ((type->t & VT_BTYPE) != VT_STRUCT)
7749 expect("struct/union type");
7750 s = type->ref;
7751 l |= SYM_FIELD;
7752 f = s->next;
7753 while (f) {
7754 if (f->v == l)
7755 break;
7756 f = f->next;
7758 if (!f)
7759 expect("field");
7760 if (!notfirst)
7761 *cur_field = f;
7762 /* XXX: fix this mess by using explicit storage field */
7763 type1 = f->type;
7764 type1.t |= (type->t & ~VT_TYPE);
7765 type = &type1;
7766 c += f->c;
7768 notfirst = 1;
7770 if (notfirst) {
7771 if (tok == '=') {
7772 next();
7773 } else {
7774 if (!gnu_ext)
7775 expect("=");
7777 } else {
7778 if (type->t & VT_ARRAY) {
7779 index = *cur_index;
7780 type = pointed_type(type);
7781 c += index * type_size(type, &align);
7782 } else {
7783 f = *cur_field;
7784 if (!f)
7785 error("too many field init");
7786 /* XXX: fix this mess by using explicit storage field */
7787 type1 = f->type;
7788 type1.t |= (type->t & ~VT_TYPE);
7789 type = &type1;
7790 c += f->c;
7793 decl_initializer(type, sec, c, 0, size_only);
7795 /* XXX: make it more general */
7796 if (!size_only && nb_elems > 1) {
7797 unsigned long c_end;
7798 uint8_t *src, *dst;
7799 int i;
7801 if (!sec)
7802 error("range init not supported yet for dynamic storage");
7803 c_end = c + nb_elems * elem_size;
7804 if (c_end > sec->data_allocated)
7805 section_realloc(sec, c_end);
7806 src = sec->data + c;
7807 dst = src;
7808 for(i = 1; i < nb_elems; i++) {
7809 dst += elem_size;
7810 memcpy(dst, src, elem_size);
7815 #define EXPR_VAL 0
7816 #define EXPR_CONST 1
7817 #define EXPR_ANY 2
7819 /* store a value or an expression directly in global data or in local array */
7820 static void init_putv(CType *type, Section *sec, unsigned long c,
7821 int v, int expr_type)
7823 int saved_global_expr, bt, bit_pos, bit_size;
7824 void *ptr;
7825 unsigned long long bit_mask;
7826 CType dtype;
7828 switch(expr_type) {
7829 case EXPR_VAL:
7830 vpushi(v);
7831 break;
7832 case EXPR_CONST:
7833 /* compound literals must be allocated globally in this case */
7834 saved_global_expr = global_expr;
7835 global_expr = 1;
7836 expr_const1();
7837 global_expr = saved_global_expr;
7838 /* NOTE: symbols are accepted */
7839 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
7840 error("initializer element is not constant");
7841 break;
7842 case EXPR_ANY:
7843 expr_eq();
7844 break;
7847 dtype = *type;
7848 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
7850 if (sec) {
7851 /* XXX: not portable */
7852 /* XXX: generate error if incorrect relocation */
7853 gen_assign_cast(&dtype);
7854 bt = type->t & VT_BTYPE;
7855 ptr = sec->data + c;
7856 /* XXX: make code faster ? */
7857 if (!(type->t & VT_BITFIELD)) {
7858 bit_pos = 0;
7859 bit_size = 32;
7860 bit_mask = -1LL;
7861 } else {
7862 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
7863 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
7864 bit_mask = (1LL << bit_size) - 1;
7866 if ((vtop->r & VT_SYM) &&
7867 (bt == VT_BYTE ||
7868 bt == VT_SHORT ||
7869 bt == VT_DOUBLE ||
7870 bt == VT_LDOUBLE ||
7871 bt == VT_LLONG ||
7872 (bt == VT_INT && bit_size != 32)))
7873 error("initializer element is not computable at load time");
7874 switch(bt) {
7875 case VT_BYTE:
7876 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7877 break;
7878 case VT_SHORT:
7879 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7880 break;
7881 case VT_DOUBLE:
7882 *(double *)ptr = vtop->c.d;
7883 break;
7884 case VT_LDOUBLE:
7885 *(long double *)ptr = vtop->c.ld;
7886 break;
7887 case VT_LLONG:
7888 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
7889 break;
7890 default:
7891 if (vtop->r & VT_SYM) {
7892 greloc(sec, vtop->sym, c, R_DATA_32);
7894 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7895 break;
7897 vtop--;
7898 } else {
7899 vset(&dtype, VT_LOCAL, c);
7900 vswap();
7901 vstore();
7902 vpop();
7906 /* put zeros for variable based init */
7907 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
7909 if (sec) {
7910 /* nothing to do because globals are already set to zero */
7911 } else {
7912 vpush_global_sym(&func_old_type, TOK_memset);
7913 vseti(VT_LOCAL, c);
7914 vpushi(0);
7915 vpushi(size);
7916 gfunc_call(3);
7920 /* 't' contains the type and storage info. 'c' is the offset of the
7921 object in section 'sec'. If 'sec' is NULL, it means stack based
7922 allocation. 'first' is true if array '{' must be read (multi
7923 dimension implicit array init handling). 'size_only' is true if
7924 size only evaluation is wanted (only for arrays). */
7925 static void decl_initializer(CType *type, Section *sec, unsigned long c,
7926 int first, int size_only)
7928 int index, array_length, n, no_oblock, nb, parlevel, i;
7929 int size1, align1, expr_type;
7930 Sym *s, *f;
7931 CType *t1;
7933 if (type->t & VT_ARRAY) {
7934 s = type->ref;
7935 n = s->c;
7936 array_length = 0;
7937 t1 = pointed_type(type);
7938 size1 = type_size(t1, &align1);
7940 no_oblock = 1;
7941 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
7942 tok == '{') {
7943 skip('{');
7944 no_oblock = 0;
7947 /* only parse strings here if correct type (otherwise: handle
7948 them as ((w)char *) expressions */
7949 if ((tok == TOK_LSTR &&
7950 (t1->t & VT_BTYPE) == VT_INT) ||
7951 (tok == TOK_STR &&
7952 (t1->t & VT_BTYPE) == VT_BYTE)) {
7953 while (tok == TOK_STR || tok == TOK_LSTR) {
7954 int cstr_len, ch;
7955 CString *cstr;
7957 cstr = tokc.cstr;
7958 /* compute maximum number of chars wanted */
7959 if (tok == TOK_STR)
7960 cstr_len = cstr->size;
7961 else
7962 cstr_len = cstr->size / sizeof(int);
7963 cstr_len--;
7964 nb = cstr_len;
7965 if (n >= 0 && nb > (n - array_length))
7966 nb = n - array_length;
7967 if (!size_only) {
7968 if (cstr_len > nb)
7969 warning("initializer-string for array is too long");
7970 /* in order to go faster for common case (char
7971 string in global variable, we handle it
7972 specifically */
7973 if (sec && tok == TOK_STR && size1 == 1) {
7974 memcpy(sec->data + c + array_length, cstr->data, nb);
7975 } else {
7976 for(i=0;i<nb;i++) {
7977 if (tok == TOK_STR)
7978 ch = ((unsigned char *)cstr->data)[i];
7979 else
7980 ch = ((int *)cstr->data)[i];
7981 init_putv(t1, sec, c + (array_length + i) * size1,
7982 ch, EXPR_VAL);
7986 array_length += nb;
7987 next();
7989 /* only add trailing zero if enough storage (no
7990 warning in this case since it is standard) */
7991 if (n < 0 || array_length < n) {
7992 if (!size_only) {
7993 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
7995 array_length++;
7997 } else {
7998 index = 0;
7999 while (tok != '}') {
8000 decl_designator(type, sec, c, &index, NULL, size_only);
8001 if (n >= 0 && index >= n)
8002 error("index too large");
8003 /* must put zero in holes (note that doing it that way
8004 ensures that it even works with designators) */
8005 if (!size_only && array_length < index) {
8006 init_putz(t1, sec, c + array_length * size1,
8007 (index - array_length) * size1);
8009 index++;
8010 if (index > array_length)
8011 array_length = index;
8012 /* special test for multi dimensional arrays (may not
8013 be strictly correct if designators are used at the
8014 same time) */
8015 if (index >= n && no_oblock)
8016 break;
8017 if (tok == '}')
8018 break;
8019 skip(',');
8022 if (!no_oblock)
8023 skip('}');
8024 /* put zeros at the end */
8025 if (!size_only && n >= 0 && array_length < n) {
8026 init_putz(t1, sec, c + array_length * size1,
8027 (n - array_length) * size1);
8029 /* patch type size if needed */
8030 if (n < 0)
8031 s->c = array_length;
8032 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
8033 (sec || !first || tok == '{')) {
8034 int par_count;
8036 /* NOTE: the previous test is a specific case for automatic
8037 struct/union init */
8038 /* XXX: union needs only one init */
8040 /* XXX: this test is incorrect for local initializers
8041 beginning with ( without {. It would be much more difficult
8042 to do it correctly (ideally, the expression parser should
8043 be used in all cases) */
8044 par_count = 0;
8045 if (tok == '(') {
8046 AttributeDef ad1;
8047 CType type1;
8048 next();
8049 while (tok == '(') {
8050 par_count++;
8051 next();
8053 if (!parse_btype(&type1, &ad1))
8054 expect("cast");
8055 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
8056 #if 0
8057 if (!is_assignable_types(type, &type1))
8058 error("invalid type for cast");
8059 #endif
8060 skip(')');
8062 no_oblock = 1;
8063 if (first || tok == '{') {
8064 skip('{');
8065 no_oblock = 0;
8067 s = type->ref;
8068 f = s->next;
8069 array_length = 0;
8070 index = 0;
8071 n = s->c;
8072 while (tok != '}') {
8073 decl_designator(type, sec, c, NULL, &f, size_only);
8074 index = f->c;
8075 if (!size_only && array_length < index) {
8076 init_putz(type, sec, c + array_length,
8077 index - array_length);
8079 index = index + type_size(&f->type, &align1);
8080 if (index > array_length)
8081 array_length = index;
8082 f = f->next;
8083 if (no_oblock && f == NULL)
8084 break;
8085 if (tok == '}')
8086 break;
8087 skip(',');
8089 /* put zeros at the end */
8090 if (!size_only && array_length < n) {
8091 init_putz(type, sec, c + array_length,
8092 n - array_length);
8094 if (!no_oblock)
8095 skip('}');
8096 while (par_count) {
8097 skip(')');
8098 par_count--;
8100 } else if (tok == '{') {
8101 next();
8102 decl_initializer(type, sec, c, first, size_only);
8103 skip('}');
8104 } else if (size_only) {
8105 /* just skip expression */
8106 parlevel = 0;
8107 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
8108 tok != -1) {
8109 if (tok == '(')
8110 parlevel++;
8111 else if (tok == ')')
8112 parlevel--;
8113 next();
8115 } else {
8116 /* currently, we always use constant expression for globals
8117 (may change for scripting case) */
8118 expr_type = EXPR_CONST;
8119 if (!sec)
8120 expr_type = EXPR_ANY;
8121 init_putv(type, sec, c, 0, expr_type);
8125 /* parse an initializer for type 't' if 'has_init' is non zero, and
8126 allocate space in local or global data space ('r' is either
8127 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8128 variable 'v' of scope 'scope' is declared before initializers are
8129 parsed. If 'v' is zero, then a reference to the new object is put
8130 in the value stack. If 'has_init' is 2, a special parsing is done
8131 to handle string constants. */
8132 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
8133 int has_init, int v, int scope)
8135 int size, align, addr, data_offset;
8136 int level;
8137 ParseState saved_parse_state;
8138 TokenString init_str;
8139 Section *sec;
8141 size = type_size(type, &align);
8142 /* If unknown size, we must evaluate it before
8143 evaluating initializers because
8144 initializers can generate global data too
8145 (e.g. string pointers or ISOC99 compound
8146 literals). It also simplifies local
8147 initializers handling */
8148 tok_str_new(&init_str);
8149 if (size < 0) {
8150 if (!has_init)
8151 error("unknown type size");
8152 /* get all init string */
8153 if (has_init == 2) {
8154 /* only get strings */
8155 while (tok == TOK_STR || tok == TOK_LSTR) {
8156 tok_str_add_tok(&init_str);
8157 next();
8159 } else {
8160 level = 0;
8161 while (level > 0 || (tok != ',' && tok != ';')) {
8162 if (tok < 0)
8163 error("unexpected end of file in initializer");
8164 tok_str_add_tok(&init_str);
8165 if (tok == '{')
8166 level++;
8167 else if (tok == '}') {
8168 if (level == 0)
8169 break;
8170 level--;
8172 next();
8175 tok_str_add(&init_str, -1);
8176 tok_str_add(&init_str, 0);
8178 /* compute size */
8179 save_parse_state(&saved_parse_state);
8181 macro_ptr = init_str.str;
8182 next();
8183 decl_initializer(type, NULL, 0, 1, 1);
8184 /* prepare second initializer parsing */
8185 macro_ptr = init_str.str;
8186 next();
8188 /* if still unknown size, error */
8189 size = type_size(type, &align);
8190 if (size < 0)
8191 error("unknown type size");
8193 /* take into account specified alignment if bigger */
8194 if (ad->aligned > align)
8195 align = ad->aligned;
8196 if ((r & VT_VALMASK) == VT_LOCAL) {
8197 sec = NULL;
8198 if (do_bounds_check && (type->t & VT_ARRAY))
8199 loc--;
8200 loc = (loc - size) & -align;
8201 addr = loc;
8202 /* handles bounds */
8203 /* XXX: currently, since we do only one pass, we cannot track
8204 '&' operators, so we add only arrays */
8205 if (do_bounds_check && (type->t & VT_ARRAY)) {
8206 unsigned long *bounds_ptr;
8207 /* add padding between regions */
8208 loc--;
8209 /* then add local bound info */
8210 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
8211 bounds_ptr[0] = addr;
8212 bounds_ptr[1] = size;
8214 if (v) {
8215 /* local variable */
8216 sym_push(v, type, r, addr);
8217 } else {
8218 /* push local reference */
8219 vset(type, r, addr);
8221 } else {
8222 Sym *sym;
8224 sym = NULL;
8225 if (v && scope == VT_CONST) {
8226 /* see if the symbol was already defined */
8227 sym = sym_find(v);
8228 if (sym) {
8229 if (!is_compatible_types(&sym->type, type))
8230 error("incompatible types for redefinition of '%s'",
8231 get_tok_str(v, NULL));
8232 if (sym->type.t & VT_EXTERN) {
8233 /* if the variable is extern, it was not allocated */
8234 sym->type.t &= ~VT_EXTERN;
8235 } else {
8236 /* we accept several definitions of the same
8237 global variable. this is tricky, because we
8238 must play with the SHN_COMMON type of the symbol */
8239 /* XXX: should check if the variable was already
8240 initialized. It is incorrect to initialized it
8241 twice */
8242 /* no init data, we won't add more to the symbol */
8243 if (!has_init)
8244 goto no_alloc;
8249 /* allocate symbol in corresponding section */
8250 sec = ad->section;
8251 if (!sec) {
8252 if (has_init)
8253 sec = data_section;
8255 if (sec) {
8256 data_offset = sec->data_offset;
8257 data_offset = (data_offset + align - 1) & -align;
8258 addr = data_offset;
8259 /* very important to increment global pointer at this time
8260 because initializers themselves can create new initializers */
8261 data_offset += size;
8262 /* add padding if bound check */
8263 if (do_bounds_check)
8264 data_offset++;
8265 sec->data_offset = data_offset;
8266 /* allocate section space to put the data */
8267 if (sec->sh_type != SHT_NOBITS &&
8268 data_offset > sec->data_allocated)
8269 section_realloc(sec, data_offset);
8270 } else {
8271 addr = 0; /* avoid warning */
8274 if (v) {
8275 if (scope == VT_CONST) {
8276 if (!sym)
8277 goto do_def;
8278 } else {
8279 do_def:
8280 sym = sym_push(v, type, r | VT_SYM, 0);
8282 /* update symbol definition */
8283 if (sec) {
8284 put_extern_sym(sym, sec, addr, size);
8285 } else {
8286 Elf32_Sym *esym;
8287 /* put a common area */
8288 put_extern_sym(sym, NULL, align, size);
8289 /* XXX: find a nicer way */
8290 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
8291 esym->st_shndx = SHN_COMMON;
8293 } else {
8294 CValue cval;
8296 /* push global reference */
8297 sym = get_sym_ref(type, sec, addr, size);
8298 cval.ul = 0;
8299 vsetc(type, VT_CONST | VT_SYM, &cval);
8300 vtop->sym = sym;
8303 /* handles bounds now because the symbol must be defined
8304 before for the relocation */
8305 if (do_bounds_check) {
8306 unsigned long *bounds_ptr;
8308 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
8309 /* then add global bound info */
8310 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
8311 bounds_ptr[0] = 0; /* relocated */
8312 bounds_ptr[1] = size;
8315 if (has_init) {
8316 decl_initializer(type, sec, addr, 1, 0);
8317 /* restore parse state if needed */
8318 if (init_str.str) {
8319 tok_str_free(init_str.str);
8320 restore_parse_state(&saved_parse_state);
8323 no_alloc: ;
8326 void put_func_debug(Sym *sym)
8328 char buf[512];
8330 /* stabs info */
8331 /* XXX: we put here a dummy type */
8332 snprintf(buf, sizeof(buf), "%s:%c1",
8333 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
8334 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
8335 cur_text_section, sym->c);
8336 last_ind = 0;
8337 last_line_num = 0;
8340 /* not finished : try to put some local vars in registers */
8341 //#define CONFIG_REG_VARS
8343 #ifdef CONFIG_REG_VARS
8344 void add_var_ref(int t)
8346 printf("%s:%d: &%s\n",
8347 file->filename, file->line_num,
8348 get_tok_str(t, NULL));
8351 /* first pass on a function with heuristic to extract variable usage
8352 and pointer references to local variables for register allocation */
8353 void analyse_function(void)
8355 int level, t;
8357 for(;;) {
8358 if (tok == -1)
8359 break;
8360 /* any symbol coming after '&' is considered as being a
8361 variable whose reference is taken. It is highly unaccurate
8362 but it is difficult to do better without a complete parse */
8363 if (tok == '&') {
8364 next();
8365 /* if '& number', then no need to examine next tokens */
8366 if (tok == TOK_CINT ||
8367 tok == TOK_CUINT ||
8368 tok == TOK_CLLONG ||
8369 tok == TOK_CULLONG) {
8370 continue;
8371 } else if (tok >= TOK_UIDENT) {
8372 /* if '& ident [' or '& ident ->', then ident address
8373 is not needed */
8374 t = tok;
8375 next();
8376 if (tok != '[' && tok != TOK_ARROW)
8377 add_var_ref(t);
8378 } else {
8379 level = 0;
8380 while (tok != '}' && tok != ';' &&
8381 !((tok == ',' || tok == ')') && level == 0)) {
8382 if (tok >= TOK_UIDENT) {
8383 add_var_ref(tok);
8384 } else if (tok == '(') {
8385 level++;
8386 } else if (tok == ')') {
8387 level--;
8389 next();
8392 } else {
8393 next();
8397 #endif
8399 /* parse an old style function declaration list */
8400 /* XXX: check multiple parameter */
8401 static void func_decl_list(Sym *func_sym)
8403 AttributeDef ad;
8404 int v;
8405 Sym *s;
8406 CType btype, type;
8408 /* parse each declaration */
8409 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
8410 if (!parse_btype(&btype, &ad))
8411 expect("declaration list");
8412 if (((btype.t & VT_BTYPE) == VT_ENUM ||
8413 (btype.t & VT_BTYPE) == VT_STRUCT) &&
8414 tok == ';') {
8415 /* we accept no variable after */
8416 } else {
8417 for(;;) {
8418 type = btype;
8419 type_decl(&type, &ad, &v, TYPE_DIRECT);
8420 /* find parameter in function parameter list */
8421 s = func_sym->next;
8422 while (s != NULL) {
8423 if ((s->v & ~SYM_FIELD) == v)
8424 goto found;
8425 s = s->next;
8427 error("declaration for parameter '%s' but no such parameter",
8428 get_tok_str(v, NULL));
8429 found:
8430 /* check that no storage specifier except 'register' was given */
8431 if (type.t & VT_STORAGE)
8432 error("storage class specified for '%s'", get_tok_str(v, NULL));
8433 convert_parameter_type(&type);
8434 /* we can add the type (NOTE: it could be local to the function) */
8435 s->type = type;
8436 /* accept other parameters */
8437 if (tok == ',')
8438 next();
8439 else
8440 break;
8443 skip(';');
8447 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
8448 static void decl(int l)
8450 int v, has_init, r;
8451 CType type, btype;
8452 Sym *sym;
8453 AttributeDef ad;
8455 while (1) {
8456 if (!parse_btype(&btype, &ad)) {
8457 /* skip redundant ';' */
8458 /* XXX: find more elegant solution */
8459 if (tok == ';') {
8460 next();
8461 continue;
8463 /* special test for old K&R protos without explicit int
8464 type. Only accepted when defining global data */
8465 if (l == VT_LOCAL || tok < TOK_DEFINE)
8466 break;
8467 btype.t = VT_INT;
8469 if (((btype.t & VT_BTYPE) == VT_ENUM ||
8470 (btype.t & VT_BTYPE) == VT_STRUCT) &&
8471 tok == ';') {
8472 /* we accept no variable after */
8473 next();
8474 continue;
8476 while (1) { /* iterate thru each declaration */
8477 type = btype;
8478 type_decl(&type, &ad, &v, TYPE_DIRECT);
8479 #if 0
8481 char buf[500];
8482 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
8483 printf("type = '%s'\n", buf);
8485 #endif
8486 if ((type.t & VT_BTYPE) == VT_FUNC) {
8487 /* if old style function prototype, we accept a
8488 declaration list */
8489 sym = type.ref;
8490 if (sym->c == FUNC_OLD)
8491 func_decl_list(sym);
8494 if (tok == '{') {
8495 #ifdef CONFIG_REG_VARS
8496 TokenString func_str;
8497 ParseState saved_parse_state;
8498 int block_level;
8499 #endif
8501 if (l == VT_LOCAL)
8502 error("cannot use local functions");
8503 if (!(type.t & VT_FUNC))
8504 expect("function definition");
8505 /* XXX: cannot do better now: convert extern line to static inline */
8506 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
8507 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
8509 #ifdef CONFIG_REG_VARS
8510 /* parse all function code and record it */
8512 tok_str_new(&func_str);
8514 block_level = 0;
8515 for(;;) {
8516 int t;
8517 if (tok == -1)
8518 error("unexpected end of file");
8519 tok_str_add_tok(&func_str);
8520 t = tok;
8521 next();
8522 if (t == '{') {
8523 block_level++;
8524 } else if (t == '}') {
8525 block_level--;
8526 if (block_level == 0)
8527 break;
8530 tok_str_add(&func_str, -1);
8531 tok_str_add(&func_str, 0);
8533 save_parse_state(&saved_parse_state);
8535 macro_ptr = func_str.str;
8536 next();
8537 analyse_function();
8538 #endif
8540 /* compute text section */
8541 cur_text_section = ad.section;
8542 if (!cur_text_section)
8543 cur_text_section = text_section;
8544 ind = cur_text_section->data_offset;
8545 funcname = get_tok_str(v, NULL);
8546 sym = sym_find(v);
8547 if (sym) {
8548 /* if symbol is already defined, then put complete type */
8549 sym->type = type;
8550 } else {
8551 /* put function symbol */
8552 sym = global_identifier_push(v, type.t, 0);
8553 sym->type.ref = type.ref;
8555 /* NOTE: we patch the symbol size later */
8556 put_extern_sym(sym, cur_text_section, ind, 0);
8557 func_ind = ind;
8558 sym->r = VT_SYM | VT_CONST;
8559 /* put debug symbol */
8560 if (do_debug)
8561 put_func_debug(sym);
8562 /* push a dummy symbol to enable local sym storage */
8563 sym_push2(&local_stack, SYM_FIELD, 0, 0);
8564 gfunc_prolog(&type);
8565 loc = 0;
8566 rsym = 0;
8567 #ifdef CONFIG_REG_VARS
8568 macro_ptr = func_str.str;
8569 next();
8570 #endif
8571 block(NULL, NULL, NULL, NULL, 0, 0);
8572 gsym(rsym);
8573 gfunc_epilog();
8574 cur_text_section->data_offset = ind;
8575 label_pop(&global_label_stack, NULL);
8576 sym_pop(&local_stack, NULL); /* reset local stack */
8577 /* end of function */
8578 /* patch symbol size */
8579 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
8580 ind - func_ind;
8581 if (do_debug) {
8582 put_stabn(N_FUN, 0, 0, ind - func_ind);
8584 funcname = ""; /* for safety */
8585 func_vt.t = VT_VOID; /* for safety */
8586 ind = 0; /* for safety */
8588 #ifdef CONFIG_REG_VARS
8589 tok_str_free(func_str.str);
8590 restore_parse_state(&saved_parse_state);
8591 #endif
8592 break;
8593 } else {
8594 if (btype.t & VT_TYPEDEF) {
8595 /* save typedefed type */
8596 /* XXX: test storage specifiers ? */
8597 sym = sym_push(v, &type, 0, 0);
8598 sym->type.t |= VT_TYPEDEF;
8599 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
8600 /* external function definition */
8601 external_sym(v, &type, 0);
8602 } else {
8603 /* not lvalue if array */
8604 r = 0;
8605 if (!(type.t & VT_ARRAY))
8606 r |= lvalue_type(type.t);
8607 has_init = (tok == '=');
8608 if ((btype.t & VT_EXTERN) ||
8609 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
8610 !has_init && l == VT_CONST && type.ref->c < 0)) {
8611 /* external variable */
8612 /* NOTE: as GCC, uninitialized global static
8613 arrays of null size are considered as
8614 extern */
8615 external_sym(v, &type, r);
8616 } else {
8617 if (type.t & VT_STATIC)
8618 r |= VT_CONST;
8619 else
8620 r |= l;
8621 if (has_init)
8622 next();
8623 decl_initializer_alloc(&type, &ad, r,
8624 has_init, v, l);
8627 if (tok != ',') {
8628 skip(';');
8629 break;
8631 next();
8637 /* better than nothing, but needs extension to handle '-E' option
8638 correctly too */
8639 static void preprocess_init(TCCState *s1)
8641 s1->include_stack_ptr = s1->include_stack;
8642 /* XXX: move that before to avoid having to initialize
8643 file->ifdef_stack_ptr ? */
8644 s1->ifdef_stack_ptr = s1->ifdef_stack;
8645 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
8647 /* XXX: not ANSI compliant: bound checking says error */
8648 vtop = vstack - 1;
8651 /* compile the C file opened in 'file'. Return non zero if errors. */
8652 static int tcc_compile(TCCState *s1)
8654 Sym *define_start;
8655 char buf[512];
8656 volatile int section_sym;
8658 #ifdef INC_DEBUG
8659 printf("%s: **** new file\n", file->filename);
8660 #endif
8661 preprocess_init(s1);
8663 funcname = "";
8664 anon_sym = SYM_FIRST_ANOM;
8666 /* file info: full path + filename */
8667 section_sym = 0; /* avoid warning */
8668 if (do_debug) {
8669 section_sym = put_elf_sym(symtab_section, 0, 0,
8670 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
8671 text_section->sh_num, NULL);
8672 getcwd(buf, sizeof(buf));
8673 pstrcat(buf, sizeof(buf), "/");
8674 put_stabs_r(buf, N_SO, 0, 0,
8675 text_section->data_offset, text_section, section_sym);
8676 put_stabs_r(file->filename, N_SO, 0, 0,
8677 text_section->data_offset, text_section, section_sym);
8679 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8680 symbols can be safely used */
8681 put_elf_sym(symtab_section, 0, 0,
8682 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
8683 SHN_ABS, file->filename);
8685 /* define some often used types */
8686 int_type.t = VT_INT;
8688 char_pointer_type.t = VT_BYTE;
8689 mk_pointer(&char_pointer_type);
8691 func_old_type.t = VT_FUNC;
8692 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
8694 #if 0
8695 /* define 'void *alloca(unsigned int)' builtin function */
8697 Sym *s1;
8699 p = anon_sym++;
8700 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
8701 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
8702 s1->next = NULL;
8703 sym->next = s1;
8704 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
8706 #endif
8708 define_start = define_stack;
8710 if (setjmp(s1->error_jmp_buf) == 0) {
8711 s1->nb_errors = 0;
8712 s1->error_set_jmp_enabled = 1;
8714 ch = file->buf_ptr[0];
8715 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
8716 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
8717 next();
8718 decl(VT_CONST);
8719 if (tok != TOK_EOF)
8720 expect("declaration");
8722 /* end of translation unit info */
8723 if (do_debug) {
8724 put_stabs_r(NULL, N_SO, 0, 0,
8725 text_section->data_offset, text_section, section_sym);
8728 s1->error_set_jmp_enabled = 0;
8730 /* reset define stack, but leave -Dsymbols (may be incorrect if
8731 they are undefined) */
8732 free_defines(define_start);
8734 sym_pop(&global_stack, NULL);
8736 return s1->nb_errors != 0 ? -1 : 0;
8739 #ifdef LIBTCC
8740 int tcc_compile_string(TCCState *s, const char *str)
8742 BufferedFile bf1, *bf = &bf1;
8743 int ret, len;
8744 char *buf;
8746 /* init file structure */
8747 bf->fd = -1;
8748 /* XXX: avoid copying */
8749 len = strlen(str);
8750 buf = tcc_malloc(len + 1);
8751 if (!buf)
8752 return -1;
8753 memcpy(buf, str, len);
8754 buf[len] = CH_EOB;
8755 bf->buf_ptr = buf;
8756 bf->buf_end = buf + len;
8757 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
8758 bf->line_num = 1;
8759 file = bf;
8761 ret = tcc_compile(s);
8763 tcc_free(buf);
8765 /* currently, no need to close */
8766 return ret;
8768 #endif
8770 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8771 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
8773 BufferedFile bf1, *bf = &bf1;
8775 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
8776 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
8777 /* default value */
8778 if (!value)
8779 value = "1";
8780 pstrcat(bf->buffer, IO_BUF_SIZE, value);
8782 /* init file structure */
8783 bf->fd = -1;
8784 bf->buf_ptr = bf->buffer;
8785 bf->buf_end = bf->buffer + strlen(bf->buffer);
8786 *bf->buf_end = CH_EOB;
8787 bf->filename[0] = '\0';
8788 bf->line_num = 1;
8789 file = bf;
8791 s1->include_stack_ptr = s1->include_stack;
8793 /* parse with define parser */
8794 ch = file->buf_ptr[0];
8795 next_nomacro();
8796 parse_define();
8797 file = NULL;
8800 /* undefine a preprocessor symbol */
8801 void tcc_undefine_symbol(TCCState *s1, const char *sym)
8803 TokenSym *ts;
8804 Sym *s;
8805 ts = tok_alloc(sym, strlen(sym));
8806 s = define_find(ts->tok);
8807 /* undefine symbol by putting an invalid name */
8808 if (s)
8809 define_undef(s);
8812 #ifdef CONFIG_TCC_ASM
8814 #include "i386-asm.c"
8815 #include "tccasm.c"
8817 #else
8818 static void asm_instr(void)
8820 error("inline asm() not supported");
8822 #endif
8824 #include "tccelf.c"
8826 /* print the position in the source file of PC value 'pc' by reading
8827 the stabs debug information */
8828 static void rt_printline(unsigned long wanted_pc)
8830 Stab_Sym *sym, *sym_end;
8831 char func_name[128], last_func_name[128];
8832 unsigned long func_addr, last_pc, pc;
8833 const char *incl_files[INCLUDE_STACK_SIZE];
8834 int incl_index, len, last_line_num, i;
8835 const char *str, *p;
8837 fprintf(stderr, "0x%08lx:", wanted_pc);
8839 func_name[0] = '\0';
8840 func_addr = 0;
8841 incl_index = 0;
8842 last_func_name[0] = '\0';
8843 last_pc = 0xffffffff;
8844 last_line_num = 1;
8845 sym = (Stab_Sym *)stab_section->data + 1;
8846 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
8847 while (sym < sym_end) {
8848 switch(sym->n_type) {
8849 /* function start or end */
8850 case N_FUN:
8851 if (sym->n_strx == 0) {
8852 /* we test if between last line and end of function */
8853 pc = sym->n_value + func_addr;
8854 if (wanted_pc >= last_pc && wanted_pc < pc)
8855 goto found;
8856 func_name[0] = '\0';
8857 func_addr = 0;
8858 } else {
8859 str = stabstr_section->data + sym->n_strx;
8860 p = strchr(str, ':');
8861 if (!p) {
8862 pstrcpy(func_name, sizeof(func_name), str);
8863 } else {
8864 len = p - str;
8865 if (len > sizeof(func_name) - 1)
8866 len = sizeof(func_name) - 1;
8867 memcpy(func_name, str, len);
8868 func_name[len] = '\0';
8870 func_addr = sym->n_value;
8872 break;
8873 /* line number info */
8874 case N_SLINE:
8875 pc = sym->n_value + func_addr;
8876 if (wanted_pc >= last_pc && wanted_pc < pc)
8877 goto found;
8878 last_pc = pc;
8879 last_line_num = sym->n_desc;
8880 /* XXX: slow! */
8881 strcpy(last_func_name, func_name);
8882 break;
8883 /* include files */
8884 case N_BINCL:
8885 str = stabstr_section->data + sym->n_strx;
8886 add_incl:
8887 if (incl_index < INCLUDE_STACK_SIZE) {
8888 incl_files[incl_index++] = str;
8890 break;
8891 case N_EINCL:
8892 if (incl_index > 1)
8893 incl_index--;
8894 break;
8895 case N_SO:
8896 if (sym->n_strx == 0) {
8897 incl_index = 0; /* end of translation unit */
8898 } else {
8899 str = stabstr_section->data + sym->n_strx;
8900 /* do not add path */
8901 len = strlen(str);
8902 if (len > 0 && str[len - 1] != '/')
8903 goto add_incl;
8905 break;
8907 sym++;
8910 /* second pass: we try symtab symbols (no line number info) */
8911 incl_index = 0;
8913 Elf32_Sym *sym, *sym_end;
8914 int type;
8916 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
8917 for(sym = (Elf32_Sym *)symtab_section->data + 1;
8918 sym < sym_end;
8919 sym++) {
8920 type = ELF32_ST_TYPE(sym->st_info);
8921 if (type == STT_FUNC) {
8922 if (wanted_pc >= sym->st_value &&
8923 wanted_pc < sym->st_value + sym->st_size) {
8924 pstrcpy(last_func_name, sizeof(last_func_name),
8925 strtab_section->data + sym->st_name);
8926 goto found;
8931 /* did not find any info: */
8932 fprintf(stderr, " ???\n");
8933 return;
8934 found:
8935 if (last_func_name[0] != '\0') {
8936 fprintf(stderr, " %s()", last_func_name);
8938 if (incl_index > 0) {
8939 fprintf(stderr, " (%s:%d",
8940 incl_files[incl_index - 1], last_line_num);
8941 for(i = incl_index - 2; i >= 0; i--)
8942 fprintf(stderr, ", included from %s", incl_files[i]);
8943 fprintf(stderr, ")");
8945 fprintf(stderr, "\n");
8948 #ifndef WIN32
8950 #ifdef __i386__
8952 /* fix for glibc 2.1 */
8953 #ifndef REG_EIP
8954 #define REG_EIP EIP
8955 #define REG_EBP EBP
8956 #endif
8958 /* return the PC at frame level 'level'. Return non zero if not found */
8959 static int rt_get_caller_pc(unsigned long *paddr,
8960 ucontext_t *uc, int level)
8962 unsigned long fp;
8963 int i;
8965 if (level == 0) {
8966 #ifdef __FreeBSD__
8967 *paddr = uc->uc_mcontext.mc_eip;
8968 #else
8969 *paddr = uc->uc_mcontext.gregs[REG_EIP];
8970 #endif
8971 return 0;
8972 } else {
8973 #ifdef __FreeBSD__
8974 fp = uc->uc_mcontext.mc_ebp;
8975 #else
8976 fp = uc->uc_mcontext.gregs[REG_EBP];
8977 #endif
8978 for(i=1;i<level;i++) {
8979 /* XXX: check address validity with program info */
8980 if (fp <= 0x1000 || fp >= 0xc0000000)
8981 return -1;
8982 fp = ((unsigned long *)fp)[0];
8984 *paddr = ((unsigned long *)fp)[1];
8985 return 0;
8988 #else
8989 #error add arch specific rt_get_caller_pc()
8990 #endif
8992 /* emit a run time error at position 'pc' */
8993 void rt_error(ucontext_t *uc, const char *fmt, ...)
8995 va_list ap;
8996 unsigned long pc;
8997 int i;
8999 va_start(ap, fmt);
9000 fprintf(stderr, "Runtime error: ");
9001 vfprintf(stderr, fmt, ap);
9002 fprintf(stderr, "\n");
9003 for(i=0;i<num_callers;i++) {
9004 if (rt_get_caller_pc(&pc, uc, i) < 0)
9005 break;
9006 if (i == 0)
9007 fprintf(stderr, "at ");
9008 else
9009 fprintf(stderr, "by ");
9010 rt_printline(pc);
9012 exit(255);
9013 va_end(ap);
9016 /* signal handler for fatal errors */
9017 static void sig_error(int signum, siginfo_t *siginf, void *puc)
9019 ucontext_t *uc = puc;
9021 switch(signum) {
9022 case SIGFPE:
9023 switch(siginf->si_code) {
9024 case FPE_INTDIV:
9025 case FPE_FLTDIV:
9026 rt_error(uc, "division by zero");
9027 break;
9028 default:
9029 rt_error(uc, "floating point exception");
9030 break;
9032 break;
9033 case SIGBUS:
9034 case SIGSEGV:
9035 if (rt_bound_error_msg && *rt_bound_error_msg)
9036 rt_error(uc, *rt_bound_error_msg);
9037 else
9038 rt_error(uc, "dereferencing invalid pointer");
9039 break;
9040 case SIGILL:
9041 rt_error(uc, "illegal instruction");
9042 break;
9043 case SIGABRT:
9044 rt_error(uc, "abort() called");
9045 break;
9046 default:
9047 rt_error(uc, "caught signal %d", signum);
9048 break;
9050 exit(255);
9052 #endif
9054 /* do all relocations (needed before using tcc_get_symbol()) */
9055 int tcc_relocate(TCCState *s1)
9057 Section *s;
9058 int i;
9060 s1->nb_errors = 0;
9062 tcc_add_runtime(s1);
9064 relocate_common_syms();
9066 /* compute relocation address : section are relocated in place. We
9067 also alloc the bss space */
9068 for(i = 1; i < s1->nb_sections; i++) {
9069 s = s1->sections[i];
9070 if (s->sh_flags & SHF_ALLOC) {
9071 if (s->sh_type == SHT_NOBITS)
9072 s->data = tcc_mallocz(s->data_offset);
9073 s->sh_addr = (unsigned long)s->data;
9077 relocate_syms(s1, 1);
9079 if (s1->nb_errors != 0)
9080 return -1;
9082 /* relocate each section */
9083 for(i = 1; i < s1->nb_sections; i++) {
9084 s = s1->sections[i];
9085 if (s->reloc)
9086 relocate_section(s1, s);
9088 return 0;
9091 /* launch the compiled program with the given arguments */
9092 int tcc_run(TCCState *s1, int argc, char **argv)
9094 int (*prog_main)(int, char **);
9096 if (tcc_relocate(s1) < 0)
9097 return -1;
9099 prog_main = tcc_get_symbol(s1, "main");
9101 if (do_debug) {
9102 #ifdef WIN32
9103 error("debug mode currently not available for Windows");
9104 #else
9105 struct sigaction sigact;
9106 /* install TCC signal handlers to print debug info on fatal
9107 runtime errors */
9108 sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
9109 sigact.sa_sigaction = sig_error;
9110 sigemptyset(&sigact.sa_mask);
9111 sigaction(SIGFPE, &sigact, NULL);
9112 sigaction(SIGILL, &sigact, NULL);
9113 sigaction(SIGSEGV, &sigact, NULL);
9114 sigaction(SIGBUS, &sigact, NULL);
9115 sigaction(SIGABRT, &sigact, NULL);
9116 #endif
9119 #ifdef CONFIG_TCC_BCHECK
9120 if (do_bounds_check) {
9121 void (*bound_init)(void);
9123 /* set error function */
9124 rt_bound_error_msg = (void *)tcc_get_symbol(s1, "__bound_error_msg");
9126 /* XXX: use .init section so that it also work in binary ? */
9127 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
9128 bound_init();
9130 #endif
9131 return (*prog_main)(argc, argv);
9134 TCCState *tcc_new(void)
9136 const char *p, *r;
9137 TCCState *s;
9138 TokenSym *ts;
9139 int i, c;
9141 s = tcc_mallocz(sizeof(TCCState));
9142 if (!s)
9143 return NULL;
9144 tcc_state = s;
9145 s->output_type = TCC_OUTPUT_MEMORY;
9147 /* init isid table */
9148 for(i=0;i<256;i++)
9149 isidnum_table[i] = isid(i) || isnum(i);
9151 /* add all tokens */
9152 table_ident = NULL;
9153 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
9155 tok_ident = TOK_IDENT;
9156 p = tcc_keywords;
9157 while (*p) {
9158 r = p;
9159 for(;;) {
9160 c = *r++;
9161 if (c == '\0')
9162 break;
9164 ts = tok_alloc(p, r - p - 1);
9165 p = r;
9168 /* we add dummy defines for some special macros to speed up tests
9169 and to have working defined() */
9170 define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
9171 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
9172 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
9173 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
9175 /* standard defines */
9176 tcc_define_symbol(s, "__STDC__", NULL);
9177 #if defined(TCC_TARGET_I386)
9178 tcc_define_symbol(s, "__i386__", NULL);
9179 #endif
9180 #if defined(linux)
9181 tcc_define_symbol(s, "__linux__", NULL);
9182 tcc_define_symbol(s, "linux", NULL);
9183 #endif
9184 /* tiny C specific defines */
9185 tcc_define_symbol(s, "__TINYC__", NULL);
9187 /* tiny C & gcc defines */
9188 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
9189 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
9190 tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
9192 /* default library paths */
9193 tcc_add_library_path(s, "/usr/local/lib");
9194 tcc_add_library_path(s, "/usr/lib");
9195 tcc_add_library_path(s, "/lib");
9197 /* no section zero */
9198 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
9200 /* create standard sections */
9201 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
9202 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
9203 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
9205 /* symbols are always generated for linking stage */
9206 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
9207 ".strtab",
9208 ".hashtab", SHF_PRIVATE);
9209 strtab_section = symtab_section->link;
9211 /* private symbol table for dynamic symbols */
9212 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
9213 ".dynstrtab",
9214 ".dynhashtab", SHF_PRIVATE);
9215 s->alacarte_link = 1;
9216 return s;
9219 void tcc_delete(TCCState *s1)
9221 int i, n;
9223 /* free -D defines */
9224 free_defines(NULL);
9226 /* free tokens */
9227 n = tok_ident - TOK_IDENT;
9228 for(i = 0; i < n; i++)
9229 tcc_free(table_ident[i]);
9230 tcc_free(table_ident);
9232 /* free all sections */
9234 free_section(symtab_section->hash);
9236 free_section(s1->dynsymtab_section->hash);
9237 free_section(s1->dynsymtab_section->link);
9238 free_section(s1->dynsymtab_section);
9240 for(i = 1; i < s1->nb_sections; i++)
9241 free_section(s1->sections[i]);
9242 tcc_free(s1->sections);
9244 /* free loaded dlls array */
9245 for(i = 0; i < s1->nb_loaded_dlls; i++)
9246 tcc_free(s1->loaded_dlls[i]);
9247 tcc_free(s1->loaded_dlls);
9249 /* library paths */
9250 for(i = 0; i < s1->nb_library_paths; i++)
9251 tcc_free(s1->library_paths[i]);
9252 tcc_free(s1->library_paths);
9254 /* cached includes */
9255 for(i = 0; i < s1->nb_cached_includes; i++)
9256 tcc_free(s1->cached_includes[i]);
9257 tcc_free(s1->cached_includes);
9259 for(i = 0; i < s1->nb_include_paths; i++)
9260 tcc_free(s1->include_paths[i]);
9261 tcc_free(s1->include_paths);
9263 for(i = 0; i < s1->nb_sysinclude_paths; i++)
9264 tcc_free(s1->sysinclude_paths[i]);
9265 tcc_free(s1->sysinclude_paths);
9267 tcc_free(s1);
9270 int tcc_add_include_path(TCCState *s1, const char *pathname)
9272 char *pathname1;
9274 pathname1 = tcc_strdup(pathname);
9275 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
9276 return 0;
9279 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
9281 char *pathname1;
9283 pathname1 = tcc_strdup(pathname);
9284 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
9285 return 0;
9288 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
9290 const char *ext, *filename1;
9291 Elf32_Ehdr ehdr;
9292 int fd, ret;
9293 BufferedFile *saved_file;
9295 /* find source file type with extension */
9296 filename1 = strrchr(filename, '/');
9297 if (filename1)
9298 filename1++;
9299 else
9300 filename1 = filename;
9301 ext = strrchr(filename1, '.');
9302 if (ext)
9303 ext++;
9305 /* open the file */
9306 saved_file = file;
9307 file = tcc_open(s1, filename);
9308 if (!file) {
9309 if (flags & AFF_PRINT_ERROR) {
9310 error_noabort("file '%s' not found", filename);
9312 ret = -1;
9313 goto fail1;
9316 if (!ext || !strcmp(ext, "c")) {
9317 /* C file assumed */
9318 ret = tcc_compile(s1);
9319 } else
9320 #ifdef CONFIG_TCC_ASM
9321 if (!strcmp(ext, "S")) {
9322 /* preprocessed assembler */
9323 ret = tcc_assemble(s1, 1);
9324 } else if (!strcmp(ext, "s")) {
9325 /* non preprocessed assembler */
9326 ret = tcc_assemble(s1, 0);
9327 } else
9328 #endif
9330 fd = file->fd;
9331 /* assume executable format: auto guess file type */
9332 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
9333 error_noabort("could not read header");
9334 goto fail;
9336 lseek(fd, 0, SEEK_SET);
9338 if (ehdr.e_ident[0] == ELFMAG0 &&
9339 ehdr.e_ident[1] == ELFMAG1 &&
9340 ehdr.e_ident[2] == ELFMAG2 &&
9341 ehdr.e_ident[3] == ELFMAG3) {
9342 file->line_num = 0; /* do not display line number if error */
9343 if (ehdr.e_type == ET_REL) {
9344 ret = tcc_load_object_file(s1, fd, 0);
9345 } else if (ehdr.e_type == ET_DYN) {
9346 ret = tcc_load_dll(s1, fd, filename,
9347 (flags & AFF_REFERENCED_DLL) != 0);
9348 } else {
9349 error_noabort("unrecognized ELF file");
9350 goto fail;
9352 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
9353 file->line_num = 0; /* do not display line number if error */
9354 ret = tcc_load_archive(s1, fd);
9355 } else {
9356 /* as GNU ld, consider it is an ld script if not recognized */
9357 ret = tcc_load_ldscript(s1);
9358 if (ret < 0) {
9359 error_noabort("unrecognized file type");
9360 goto fail;
9364 the_end:
9365 tcc_close(file);
9366 fail1:
9367 file = saved_file;
9368 return ret;
9369 fail:
9370 ret = -1;
9371 goto the_end;
9374 int tcc_add_file(TCCState *s, const char *filename)
9376 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
9379 int tcc_add_library_path(TCCState *s, const char *pathname)
9381 char *pathname1;
9383 pathname1 = tcc_strdup(pathname);
9384 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
9385 return 0;
9388 /* find and load a dll. Return non zero if not found */
9389 /* XXX: add '-rpath' option support ? */
9390 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
9392 char buf[1024];
9393 int i;
9395 for(i = 0; i < s->nb_library_paths; i++) {
9396 snprintf(buf, sizeof(buf), "%s/%s",
9397 s->library_paths[i], filename);
9398 if (tcc_add_file_internal(s, buf, flags) == 0)
9399 return 0;
9401 return -1;
9404 /* the library name is the same as the argument of the '-l' option */
9405 int tcc_add_library(TCCState *s, const char *libraryname)
9407 char buf[1024];
9408 int i;
9409 void *h;
9411 /* first we look for the dynamic library if not static linking */
9412 if (!s->static_link) {
9413 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
9414 /* if we output to memory, then we simply we dlopen(). */
9415 if (s->output_type == TCC_OUTPUT_MEMORY) {
9416 /* Since the libc is already loaded, we don't need to load it again */
9417 if (!strcmp(libraryname, "c"))
9418 return 0;
9419 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
9420 if (h)
9421 return 0;
9422 } else {
9423 if (tcc_add_dll(s, buf, 0) == 0)
9424 return 0;
9428 /* then we look for the static library */
9429 for(i = 0; i < s->nb_library_paths; i++) {
9430 snprintf(buf, sizeof(buf), "%s/lib%s.a",
9431 s->library_paths[i], libraryname);
9432 if (tcc_add_file_internal(s, buf, 0) == 0)
9433 return 0;
9435 return -1;
9438 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
9440 add_elf_sym(symtab_section, val, 0,
9441 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
9442 SHN_ABS, name);
9443 return 0;
9446 int tcc_set_output_type(TCCState *s, int output_type)
9448 char buf[1024];
9450 s->output_type = output_type;
9452 if (!s->nostdinc) {
9453 /* default include paths */
9454 /* XXX: reverse order needed if -isystem support */
9455 tcc_add_sysinclude_path(s, "/usr/local/include");
9456 tcc_add_sysinclude_path(s, "/usr/include");
9457 snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path);
9458 tcc_add_sysinclude_path(s, buf);
9461 /* if bound checking, then add corresponding sections */
9462 #ifdef CONFIG_TCC_BCHECK
9463 if (do_bounds_check) {
9464 /* define symbol */
9465 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
9466 /* create bounds sections */
9467 bounds_section = new_section(s, ".bounds",
9468 SHT_PROGBITS, SHF_ALLOC);
9469 lbounds_section = new_section(s, ".lbounds",
9470 SHT_PROGBITS, SHF_ALLOC);
9472 #endif
9474 /* add debug sections */
9475 if (do_debug) {
9476 /* stab symbols */
9477 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
9478 stab_section->sh_entsize = sizeof(Stab_Sym);
9479 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
9480 put_elf_str(stabstr_section, "");
9481 stab_section->link = stabstr_section;
9482 /* put first entry */
9483 put_stabs("", 0, 0, 0, 0);
9486 /* add libc crt1/crti objects */
9487 if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
9488 !s->nostdlib) {
9489 if (output_type != TCC_OUTPUT_DLL)
9490 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
9491 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
9493 return 0;
9496 #define WD_ALL 0x0001 /* warning is activated when using -Wall */
9498 typedef struct WarningDef {
9499 int offset;
9500 int flags;
9501 const char *name;
9502 } WarningDef;
9504 static const WarningDef warning_defs[] = {
9505 { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
9506 { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
9507 { offsetof(TCCState, warn_error), 0, "error" },
9510 /* set/reset a warning */
9511 int tcc_set_warning(TCCState *s, const char *warning_name, int value)
9513 int i;
9514 const WarningDef *p;
9515 if (!strcmp(warning_name, "all")) {
9516 for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
9517 if (p->flags & WD_ALL)
9518 *(int *)((uint8_t *)s + p->offset) = 1;
9520 } else {
9521 for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
9522 if (!strcmp(warning_name, p->name))
9523 goto found;
9525 return -1;
9526 found:
9527 *(int *)((uint8_t *)s + p->offset) = value;
9529 return 0;
9533 #if !defined(LIBTCC)
9535 /* extract the basename of a file */
9536 static const char *tcc_basename(const char *name)
9538 const char *p;
9539 p = strrchr(name, '/');
9540 #ifdef WIN32
9541 if (!p)
9542 p = strrchr(name, '\\');
9543 #endif
9544 if (!p)
9545 p = name;
9546 else
9547 p++;
9548 return p;
9551 static int64_t getclock_us(void)
9553 #ifdef WIN32
9554 struct _timeb tb;
9555 _ftime(&tb);
9556 return (tb.time * 1000LL + tb.millitm) * 1000LL;
9557 #else
9558 struct timeval tv;
9559 gettimeofday(&tv, NULL);
9560 return tv.tv_sec * 1000000LL + tv.tv_usec;
9561 #endif
9564 void help(void)
9566 printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2003 Fabrice Bellard\n"
9567 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
9568 " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
9569 " [infile1 infile2...] [-run infile args...]\n"
9570 "\n"
9571 "General options:\n"
9572 " -v display current version\n"
9573 " -c compile only - generate an object file\n"
9574 " -o outfile set output filename\n"
9575 " -Bdir set tcc internal library path\n"
9576 " -bench output compilation statistics\n"
9577 " -run run compiled source\n"
9578 " -Wwarning set or reset (with 'no-' prefix) 'warning'\n"
9579 "Preprocessor options:\n"
9580 " -Idir add include path 'dir'\n"
9581 " -Dsym[=val] define 'sym' with value 'val'\n"
9582 " -Usym undefine 'sym'\n"
9583 "Linker options:\n"
9584 " -Ldir add library path 'dir'\n"
9585 " -llib link with dynamic or static library 'lib'\n"
9586 " -shared generate a shared library\n"
9587 " -static static linking\n"
9588 " -r relocatable output\n"
9589 "Debugger options:\n"
9590 " -g generate runtime debug info\n"
9591 #ifdef CONFIG_TCC_BCHECK
9592 " -b compile with built-in memory and bounds checker (implies -g)\n"
9593 #endif
9594 " -bt N show N callers in stack traces\n"
9598 #define TCC_OPTION_HAS_ARG 0x0001
9599 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
9601 typedef struct TCCOption {
9602 const char *name;
9603 uint16_t index;
9604 uint16_t flags;
9605 } TCCOption;
9607 enum {
9608 TCC_OPTION_HELP,
9609 TCC_OPTION_I,
9610 TCC_OPTION_D,
9611 TCC_OPTION_U,
9612 TCC_OPTION_L,
9613 TCC_OPTION_B,
9614 TCC_OPTION_l,
9615 TCC_OPTION_bench,
9616 TCC_OPTION_bt,
9617 TCC_OPTION_b,
9618 TCC_OPTION_g,
9619 TCC_OPTION_c,
9620 TCC_OPTION_static,
9621 TCC_OPTION_shared,
9622 TCC_OPTION_o,
9623 TCC_OPTION_r,
9624 TCC_OPTION_W,
9625 TCC_OPTION_O,
9626 TCC_OPTION_m,
9627 TCC_OPTION_f,
9628 TCC_OPTION_nostdinc,
9629 TCC_OPTION_nostdlib,
9630 TCC_OPTION_print_search_dirs,
9631 TCC_OPTION_rdynamic,
9632 TCC_OPTION_run,
9633 TCC_OPTION_v,
9636 static const TCCOption tcc_options[] = {
9637 { "h", TCC_OPTION_HELP, 0 },
9638 { "?", TCC_OPTION_HELP, 0 },
9639 { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
9640 { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
9641 { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
9642 { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
9643 { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
9644 { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9645 { "bench", TCC_OPTION_bench, 0 },
9646 { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
9647 #ifdef CONFIG_TCC_BCHECK
9648 { "b", TCC_OPTION_b, 0 },
9649 #endif
9650 { "g", TCC_OPTION_g, 0 },
9651 { "c", TCC_OPTION_c, 0 },
9652 { "static", TCC_OPTION_static, 0 },
9653 { "shared", TCC_OPTION_shared, 0 },
9654 { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
9655 { "run", TCC_OPTION_run, 0 },
9656 { "rdynamic", TCC_OPTION_rdynamic, 0 }, /* currently ignored */
9657 { "r", TCC_OPTION_r, 0 },
9658 { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9659 { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9660 { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
9661 { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9662 { "nostdinc", TCC_OPTION_nostdinc, 0 },
9663 { "nostdlib", TCC_OPTION_nostdlib, 0 },
9664 { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
9665 { "v", TCC_OPTION_v, 0 },
9666 { NULL },
9669 int main(int argc, char **argv)
9671 char *r;
9672 int optind, output_type, multiple_files, i, reloc_output;
9673 TCCState *s;
9674 char **files;
9675 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
9676 char objfilename[1024];
9677 int64_t start_time = 0;
9678 const TCCOption *popt;
9679 const char *optarg, *p1, *r1, *outfile;
9680 int print_search_dirs;
9682 s = tcc_new();
9683 output_type = TCC_OUTPUT_EXE;
9685 optind = 1;
9686 outfile = NULL;
9687 multiple_files = 1;
9688 dminus = 0;
9689 files = NULL;
9690 nb_files = 0;
9691 nb_libraries = 0;
9692 reloc_output = 0;
9693 print_search_dirs = 0;
9694 while (1) {
9695 if (optind >= argc) {
9696 if (nb_files == 0 && !print_search_dirs)
9697 goto show_help;
9698 else
9699 break;
9701 r = argv[optind++];
9702 if (r[0] != '-') {
9703 /* add a new file */
9704 dynarray_add((void ***)&files, &nb_files, r);
9705 if (!multiple_files) {
9706 optind--;
9707 /* argv[0] will be this file */
9708 break;
9710 } else {
9711 /* find option in table (match only the first chars */
9712 popt = tcc_options;
9713 for(;;) {
9714 p1 = popt->name;
9715 if (p1 == NULL)
9716 error("invalid option -- '%s'", r);
9717 r1 = r + 1;
9718 for(;;) {
9719 if (*p1 == '\0')
9720 goto option_found;
9721 if (*r1 != *p1)
9722 break;
9723 p1++;
9724 r1++;
9726 popt++;
9728 option_found:
9729 if (popt->flags & TCC_OPTION_HAS_ARG) {
9730 if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) {
9731 optarg = r1;
9732 } else {
9733 if (optind >= argc)
9734 error("argument to '%s' is missing", r);
9735 optarg = argv[optind++];
9737 } else {
9738 if (*r1 != '\0')
9739 goto show_help;
9740 optarg = NULL;
9743 switch(popt->index) {
9744 case TCC_OPTION_HELP:
9745 show_help:
9746 help();
9747 return 1;
9748 case TCC_OPTION_I:
9749 if (tcc_add_include_path(s, optarg) < 0)
9750 error("too many include paths");
9751 break;
9752 case TCC_OPTION_D:
9754 char *sym, *value;
9755 sym = (char *)optarg;
9756 value = strchr(sym, '=');
9757 if (value) {
9758 *value = '\0';
9759 value++;
9761 tcc_define_symbol(s, sym, value);
9763 break;
9764 case TCC_OPTION_U:
9765 tcc_undefine_symbol(s, optarg);
9766 break;
9767 case TCC_OPTION_L:
9768 tcc_add_library_path(s, optarg);
9769 break;
9770 case TCC_OPTION_B:
9771 /* set tcc utilities path (mainly for tcc development) */
9772 tcc_lib_path = optarg;
9773 break;
9774 case TCC_OPTION_l:
9775 dynarray_add((void ***)&files, &nb_files, r);
9776 nb_libraries++;
9777 break;
9778 case TCC_OPTION_bench:
9779 do_bench = 1;
9780 break;
9781 case TCC_OPTION_bt:
9782 num_callers = atoi(optarg);
9783 break;
9784 #ifdef CONFIG_TCC_BCHECK
9785 case TCC_OPTION_b:
9786 do_bounds_check = 1;
9787 do_debug = 1;
9788 break;
9789 #endif
9790 case TCC_OPTION_g:
9791 do_debug = 1;
9792 break;
9793 case TCC_OPTION_c:
9794 multiple_files = 1;
9795 output_type = TCC_OUTPUT_OBJ;
9796 break;
9797 case TCC_OPTION_static:
9798 s->static_link = 1;
9799 break;
9800 case TCC_OPTION_shared:
9801 output_type = TCC_OUTPUT_DLL;
9802 break;
9803 case TCC_OPTION_o:
9804 multiple_files = 1;
9805 outfile = optarg;
9806 break;
9807 case TCC_OPTION_r:
9808 /* generate a .o merging several output files */
9809 reloc_output = 1;
9810 output_type = TCC_OUTPUT_OBJ;
9811 break;
9812 case TCC_OPTION_nostdinc:
9813 s->nostdinc = 1;
9814 break;
9815 case TCC_OPTION_nostdlib:
9816 s->nostdlib = 1;
9817 break;
9818 case TCC_OPTION_print_search_dirs:
9819 print_search_dirs = 1;
9820 break;
9821 case TCC_OPTION_run:
9822 multiple_files = 0;
9823 output_type = TCC_OUTPUT_MEMORY;
9824 break;
9825 case TCC_OPTION_v:
9826 printf("tcc version %s\n", TCC_VERSION);
9827 return 0;
9828 case TCC_OPTION_W:
9830 const char *p = optarg;
9831 int value;
9832 value = 1;
9833 if (p[0] == 'n' && p[1] == 'o' && p[2] == '-') {
9834 p += 2;
9835 value = 0;
9837 if (tcc_set_warning(s, p, value) < 0 && s->warn_unsupported)
9838 goto unsupported_option;
9840 break;
9841 default:
9842 if (s->warn_unsupported) {
9843 unsupported_option:
9844 warning("unsupported option '%s'", r);
9846 break;
9850 if (print_search_dirs) {
9851 /* enough for Linux kernel */
9852 printf("install: %s/\n", tcc_lib_path);
9853 return 0;
9856 nb_objfiles = nb_files - nb_libraries;
9858 /* if outfile provided without other options, we output an
9859 executable */
9860 if (outfile && output_type == TCC_OUTPUT_MEMORY)
9861 output_type = TCC_OUTPUT_EXE;
9863 /* check -c consistency : only single file handled. XXX: checks file type */
9864 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9865 /* accepts only a single input file */
9866 if (nb_objfiles != 1)
9867 error("cannot specify multiple files with -c");
9868 if (nb_libraries != 0)
9869 error("cannot specify libraries with -c");
9872 /* compute default outfile name */
9873 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
9874 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9875 char *ext;
9876 /* strip path */
9877 pstrcpy(objfilename, sizeof(objfilename) - 1,
9878 tcc_basename(files[0]));
9879 /* add .o extension */
9880 ext = strrchr(objfilename, '.');
9881 if (!ext)
9882 goto default_outfile;
9883 strcpy(ext + 1, "o");
9884 } else {
9885 default_outfile:
9886 pstrcpy(objfilename, sizeof(objfilename), "a.out");
9888 outfile = objfilename;
9891 if (do_bench) {
9892 start_time = getclock_us();
9895 tcc_set_output_type(s, output_type);
9897 /* compile or add each files or library */
9898 for(i = 0;i < nb_files; i++) {
9899 const char *filename;
9901 filename = files[i];
9902 if (filename[0] == '-') {
9903 if (tcc_add_library(s, filename + 2) < 0)
9904 error("cannot find %s", filename);
9905 } else {
9906 if (tcc_add_file(s, filename) < 0) {
9907 ret = 1;
9908 goto the_end;
9913 /* free all files */
9914 tcc_free(files);
9916 if (do_bench) {
9917 double total_time;
9918 total_time = (double)(getclock_us() - start_time) / 1000000.0;
9919 if (total_time < 0.001)
9920 total_time = 0.001;
9921 if (total_bytes < 1)
9922 total_bytes = 1;
9923 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
9924 tok_ident - TOK_IDENT, total_lines, total_bytes,
9925 total_time, (int)(total_lines / total_time),
9926 total_bytes / total_time / 1000000.0);
9929 if (s->output_type != TCC_OUTPUT_MEMORY) {
9930 tcc_output_file(s, outfile);
9931 ret = 0;
9932 } else {
9933 ret = tcc_run(s, argc - optind, argv + optind);
9935 the_end:
9936 /* XXX: cannot do it with bound checking because of the malloc hooks */
9937 if (!do_bounds_check)
9938 tcc_delete(s);
9940 #ifdef MEM_DEBUG
9941 if (do_bench) {
9942 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
9944 #endif
9945 return ret;
9948 #endif