update
[tinycc.git] / tcc.c
blobcb14231b2e893f727eff5581778b4d8b416e313a
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define _GNU_SOURCE
21 #include "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 #ifdef WIN32
35 #include <sys/timeb.h>
36 #endif
37 #ifndef WIN32
38 #include <sys/time.h>
39 #include <sys/ucontext.h>
40 #endif
41 #include "elf.h"
42 #include "stab.h"
43 #ifndef CONFIG_TCC_STATIC
44 #include <dlfcn.h>
45 #endif
47 #include "libtcc.h"
49 /* parser debug */
50 //#define PARSE_DEBUG
51 /* preprocessor debug */
52 //#define PP_DEBUG
53 /* include file debug */
54 //#define INC_DEBUG
56 //#define MEM_DEBUG
58 /* assembler debug */
59 //#define ASM_DEBUG
61 /* target selection */
62 //#define TCC_TARGET_I386 /* i386 code generator */
64 /* default target is I386 */
65 #if !defined(TCC_TARGET_I386)
66 #define TCC_TARGET_I386
67 #endif
69 #if !defined(WIN32) && !defined(TCC_UCLIBC)
70 #define CONFIG_TCC_BCHECK /* enable bound checking code */
71 #endif
73 /* define it to include assembler support */
74 #define CONFIG_TCC_ASM
76 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
77 executables or dlls */
78 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
80 #define INCLUDE_STACK_SIZE 32
81 #define IFDEF_STACK_SIZE 64
82 #define VSTACK_SIZE 64
83 #define STRING_MAX_SIZE 1024
85 #define TOK_HASH_SIZE 2048 /* must be a power of two */
86 #define TOK_ALLOC_INCR 512 /* must be a power of two */
87 #define TOK_STR_ALLOC_INCR_BITS 6
88 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
89 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
91 /* token symbol management */
92 typedef struct TokenSym {
93 struct TokenSym *hash_next;
94 struct Sym *sym_define; /* direct pointer to define */
95 struct Sym *sym_label; /* direct pointer to label */
96 struct Sym *sym_struct; /* direct pointer to structure */
97 struct Sym *sym_identifier; /* direct pointer to identifier */
98 int tok; /* token number */
99 int len;
100 char str[1];
101 } TokenSym;
103 typedef struct CString {
104 int size; /* size in bytes */
105 void *data; /* either 'char *' or 'int *' */
106 int size_allocated;
107 void *data_allocated; /* if non NULL, data has been malloced */
108 } CString;
110 /* type definition */
111 typedef struct CType {
112 int t;
113 struct Sym *ref;
114 } CType;
116 /* constant value */
117 typedef union CValue {
118 long double ld;
119 double d;
120 float f;
121 int i;
122 unsigned int ui;
123 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
124 long long ll;
125 unsigned long long ull;
126 struct CString *cstr;
127 void *ptr;
128 int tab[1];
129 } CValue;
131 /* value on stack */
132 typedef struct SValue {
133 CType type; /* type */
134 unsigned short r; /* register + flags */
135 unsigned short r2; /* second register, used for 'long long'
136 type. If not used, set to VT_CONST */
137 CValue c; /* constant, if VT_CONST */
138 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
139 } SValue;
141 /* symbol management */
142 typedef struct Sym {
143 int v; /* symbol token */
144 int r; /* associated register */
145 int c; /* associated number */
146 CType type; /* associated type */
147 struct Sym *next; /* next related symbol */
148 struct Sym *prev; /* prev symbol in stack */
149 struct Sym *prev_tok; /* previous symbol for this token */
150 } Sym;
152 /* section definition */
153 /* XXX: use directly ELF structure for parameters ? */
154 /* special flag to indicate that the section should not be linked to
155 the other ones */
156 #define SHF_PRIVATE 0x80000000
158 typedef struct Section {
159 unsigned long data_offset; /* current data offset */
160 unsigned char *data; /* section data */
161 unsigned long data_allocated; /* used for realloc() handling */
162 int sh_name; /* elf section name (only used during output) */
163 int sh_num; /* elf section number */
164 int sh_type; /* elf section type */
165 int sh_flags; /* elf section flags */
166 int sh_info; /* elf section info */
167 int sh_addralign; /* elf section alignment */
168 int sh_entsize; /* elf entry size */
169 unsigned long sh_size; /* section size (only used during output) */
170 unsigned long sh_addr; /* address at which the section is relocated */
171 unsigned long sh_offset; /* address at which the section is relocated */
172 int nb_hashed_syms; /* used to resize the hash table */
173 struct Section *link; /* link to another section */
174 struct Section *reloc; /* corresponding section for relocation, if any */
175 struct Section *hash; /* hash table for symbols */
176 struct Section *next;
177 char name[64]; /* section name */
178 } Section;
180 typedef struct DLLReference {
181 int level;
182 char name[1];
183 } DLLReference;
185 /* GNUC attribute definition */
186 typedef struct AttributeDef {
187 int aligned;
188 Section *section;
189 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
190 } AttributeDef;
192 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
193 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
194 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
196 /* stored in 'Sym.c' field */
197 #define FUNC_NEW 1 /* ansi function prototype */
198 #define FUNC_OLD 2 /* old function prototype */
199 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
201 /* stored in 'Sym.r' field */
202 #define FUNC_CDECL 0 /* standard c call */
203 #define FUNC_STDCALL 1 /* pascal c call */
205 /* field 'Sym.t' for macros */
206 #define MACRO_OBJ 0 /* object like macro */
207 #define MACRO_FUNC 1 /* function like macro */
209 /* field 'Sym.r' for C labels */
210 #define LABEL_DEFINED 0 /* label is defined */
211 #define LABEL_FORWARD 1 /* label is forward defined */
212 #define LABEL_DECLARED 2 /* label is declared but never used */
214 /* type_decl() types */
215 #define TYPE_ABSTRACT 1 /* type without variable */
216 #define TYPE_DIRECT 2 /* type with variable */
218 #define IO_BUF_SIZE 8192
220 typedef struct BufferedFile {
221 uint8_t *buf_ptr;
222 uint8_t *buf_end;
223 int fd;
224 int line_num; /* current line number - here to simplify code */
225 int ifndef_macro; /* #ifndef macro / #endif search */
226 int ifndef_macro_saved; /* saved ifndef_macro */
227 int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
228 char inc_type; /* type of include */
229 char inc_filename[512]; /* filename specified by the user */
230 char filename[1024]; /* current filename - here to simplify code */
231 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
232 } BufferedFile;
234 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
235 #define CH_EOF (-1) /* end of file */
237 /* parsing state (used to save parser state to reparse part of the
238 source several times) */
239 typedef struct ParseState {
240 int *macro_ptr;
241 int line_num;
242 int tok;
243 CValue tokc;
244 } ParseState;
246 /* used to record tokens */
247 typedef struct TokenString {
248 int *str;
249 int len;
250 int allocated_len;
251 int last_line_num;
252 } TokenString;
254 /* include file cache, used to find files faster and also to eliminate
255 inclusion if the include file is protected by #ifndef ... #endif */
256 typedef struct CachedInclude {
257 int ifndef_macro;
258 char type; /* '"' or '>' to give include type */
259 char filename[1]; /* path specified in #include */
260 } CachedInclude;
262 /* parser */
263 static struct BufferedFile *file;
264 static int ch, tok;
265 static CValue tokc;
266 static CString tokcstr; /* current parsed string, if any */
267 /* additional informations about token */
268 static int tok_flags;
269 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
270 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
271 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
273 static int *macro_ptr, *macro_ptr_allocated;
274 static int *unget_saved_macro_ptr;
275 static int unget_saved_buffer[TOK_MAX_SIZE + 1];
276 static int unget_buffer_enabled;
277 static int parse_flags;
278 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
279 #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
280 #define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
281 token. line feed is also
282 returned at eof */
284 static Section *text_section, *data_section, *bss_section; /* predefined sections */
285 static Section *cur_text_section; /* current section where function code is
286 generated */
287 /* bound check related sections */
288 static Section *bounds_section; /* contains global data bound description */
289 static Section *lbounds_section; /* contains local data bound description */
290 /* symbol sections */
291 static Section *symtab_section, *strtab_section;
293 /* debug sections */
294 static Section *stab_section, *stabstr_section;
296 /* loc : local variable index
297 ind : output code index
298 rsym: return symbol
299 anon_sym: anonymous symbol index
301 static int rsym, anon_sym, ind, loc;
302 /* expression generation modifiers */
303 static int const_wanted; /* true if constant wanted */
304 static int nocode_wanted; /* true if no code generation wanted for an expression */
305 static int global_expr; /* true if compound literals must be allocated
306 globally (used during initializers parsing */
307 static CType func_vt; /* current function return type (used by return
308 instruction) */
309 static int func_vc;
310 static int last_line_num, last_ind, func_ind; /* debug last line number and pc */
311 static int tok_ident;
312 static TokenSym **table_ident;
313 static TokenSym *hash_ident[TOK_HASH_SIZE];
314 static char token_buf[STRING_MAX_SIZE + 1];
315 static char *funcname;
316 static Sym *global_stack, *local_stack;
317 static Sym *define_stack;
318 static Sym *global_label_stack, *local_label_stack;
320 static SValue vstack[VSTACK_SIZE], *vtop;
321 /* some predefined types */
322 static CType char_pointer_type, func_old_type, int_type;
323 /* true if isid(c) || isnum(c) */
324 static unsigned char isidnum_table[256];
326 /* compile with debug symbol (and use them if error during execution) */
327 static int do_debug = 0;
329 /* compile with built-in memory and bounds checker */
330 static int do_bounds_check = 0;
332 /* display benchmark infos */
333 #if !defined(LIBTCC)
334 static int do_bench = 0;
335 #endif
336 static int total_lines;
337 static int total_bytes;
339 /* use GNU C extensions */
340 static int gnu_ext = 1;
342 /* use Tiny C extensions */
343 static int tcc_ext = 1;
345 /* max number of callers shown if error */
346 static int num_callers = 6;
347 static const char **rt_bound_error_msg;
349 /* XXX: get rid of this ASAP */
350 static struct TCCState *tcc_state;
352 /* give the path of the tcc libraries */
353 static const char *tcc_lib_path = CONFIG_TCC_LIBDIR "/tcc";
355 struct TCCState {
356 int output_type;
358 BufferedFile **include_stack_ptr;
359 int *ifdef_stack_ptr;
361 /* include file handling */
362 char **include_paths;
363 int nb_include_paths;
364 char **sysinclude_paths;
365 int nb_sysinclude_paths;
366 CachedInclude **cached_includes;
367 int nb_cached_includes;
369 char **library_paths;
370 int nb_library_paths;
372 /* array of all loaded dlls (including those referenced by loaded
373 dlls) */
374 DLLReference **loaded_dlls;
375 int nb_loaded_dlls;
377 /* sections */
378 Section **sections;
379 int nb_sections; /* number of sections, including first dummy section */
381 /* got handling */
382 Section *got;
383 Section *plt;
384 unsigned long *got_offsets;
385 int nb_got_offsets;
386 /* give the correspondance from symtab indexes to dynsym indexes */
387 int *symtab_to_dynsym;
389 /* temporary dynamic symbol sections (for dll loading) */
390 Section *dynsymtab_section;
391 /* exported dynamic symbol section */
392 Section *dynsym;
394 /* if true, no standard headers are added */
395 int nostdinc;
397 /* if true, static linking is performed */
398 int static_link;
400 /* error handling */
401 void *error_opaque;
402 void (*error_func)(void *opaque, const char *msg);
403 int error_set_jmp_enabled;
404 jmp_buf error_jmp_buf;
405 int nb_errors;
407 /* tiny assembler state */
408 Sym *asm_labels;
410 /* see include_stack_ptr */
411 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
413 /* see ifdef_stack_ptr */
414 int ifdef_stack[IFDEF_STACK_SIZE];
417 /* The current value can be: */
418 #define VT_VALMASK 0x00ff
419 #define VT_CONST 0x00f0 /* constant in vc
420 (must be first non register value) */
421 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
422 #define VT_LOCAL 0x00f2 /* offset on stack */
423 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
424 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
425 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
426 #define VT_LVAL 0x0100 /* var is an lvalue */
427 #define VT_SYM 0x0200 /* a symbol value is added */
428 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
429 char/short stored in integer registers) */
430 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
431 dereferencing value */
432 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
433 bounding function call point is in vc */
434 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
435 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
436 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
437 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
439 /* types */
440 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
442 #define VT_INT 0 /* integer type */
443 #define VT_BYTE 1 /* signed byte type */
444 #define VT_SHORT 2 /* short type */
445 #define VT_VOID 3 /* void type */
446 #define VT_PTR 4 /* pointer */
447 #define VT_ENUM 5 /* enum definition */
448 #define VT_FUNC 6 /* function type */
449 #define VT_STRUCT 7 /* struct/union definition */
450 #define VT_FLOAT 8 /* IEEE float */
451 #define VT_DOUBLE 9 /* IEEE double */
452 #define VT_LDOUBLE 10 /* IEEE long double */
453 #define VT_BOOL 11 /* ISOC99 boolean type */
454 #define VT_LLONG 12 /* 64 bit integer */
455 #define VT_LONG 13 /* long integer (NEVER USED as type, only
456 during parsing) */
457 #define VT_BTYPE 0x000f /* mask for basic type */
458 #define VT_UNSIGNED 0x0010 /* unsigned type */
459 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
460 #define VT_BITFIELD 0x0040 /* bitfield modifier */
462 /* storage */
463 #define VT_EXTERN 0x00000080 /* extern definition */
464 #define VT_STATIC 0x00000100 /* static variable */
465 #define VT_TYPEDEF 0x00000200 /* typedef definition */
466 #define VT_INLINE 0x00000400 /* inline definition */
468 /* type mask (except storage) */
469 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
470 #define VT_TYPE (~(VT_STORAGE))
472 /* token values */
474 /* warning: the following compare tokens depend on i386 asm code */
475 #define TOK_ULT 0x92
476 #define TOK_UGE 0x93
477 #define TOK_EQ 0x94
478 #define TOK_NE 0x95
479 #define TOK_ULE 0x96
480 #define TOK_UGT 0x97
481 #define TOK_LT 0x9c
482 #define TOK_GE 0x9d
483 #define TOK_LE 0x9e
484 #define TOK_GT 0x9f
486 #define TOK_LAND 0xa0
487 #define TOK_LOR 0xa1
489 #define TOK_DEC 0xa2
490 #define TOK_MID 0xa3 /* inc/dec, to void constant */
491 #define TOK_INC 0xa4
492 #define TOK_UDIV 0xb0 /* unsigned division */
493 #define TOK_UMOD 0xb1 /* unsigned modulo */
494 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
495 #define TOK_CINT 0xb3 /* number in tokc */
496 #define TOK_CCHAR 0xb4 /* char constant in tokc */
497 #define TOK_STR 0xb5 /* pointer to string in tokc */
498 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
499 #define TOK_LCHAR 0xb7
500 #define TOK_LSTR 0xb8
501 #define TOK_CFLOAT 0xb9 /* float constant */
502 #define TOK_LINENUM 0xba /* line number info */
503 #define TOK_CDOUBLE 0xc0 /* double constant */
504 #define TOK_CLDOUBLE 0xc1 /* long double constant */
505 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
506 #define TOK_ADDC1 0xc3 /* add with carry generation */
507 #define TOK_ADDC2 0xc4 /* add with carry use */
508 #define TOK_SUBC1 0xc5 /* add with carry generation */
509 #define TOK_SUBC2 0xc6 /* add with carry use */
510 #define TOK_CUINT 0xc8 /* unsigned int constant */
511 #define TOK_CLLONG 0xc9 /* long long constant */
512 #define TOK_CULLONG 0xca /* unsigned long long constant */
513 #define TOK_ARROW 0xcb
514 #define TOK_DOTS 0xcc /* three dots */
515 #define TOK_SHR 0xcd /* unsigned shift right */
516 #define TOK_PPNUM 0xce /* preprocessor number */
518 #define TOK_SHL 0x01 /* shift left */
519 #define TOK_SAR 0x02 /* signed shift right */
521 /* assignement operators : normal operator or 0x80 */
522 #define TOK_A_MOD 0xa5
523 #define TOK_A_AND 0xa6
524 #define TOK_A_MUL 0xaa
525 #define TOK_A_ADD 0xab
526 #define TOK_A_SUB 0xad
527 #define TOK_A_DIV 0xaf
528 #define TOK_A_XOR 0xde
529 #define TOK_A_OR 0xfc
530 #define TOK_A_SHL 0x81
531 #define TOK_A_SAR 0x82
533 /* WARNING: the content of this string encodes token numbers */
534 static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
536 #define TOK_EOF (-1) /* end of file */
537 #define TOK_LINEFEED 10 /* line feed */
539 /* all identificators and strings have token above that */
540 #define TOK_IDENT 256
542 /* only used for i386 asm opcodes definitions */
543 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
545 #define DEF_BWL(x) \
546 DEF(TOK_ASM_ ## x ## b, #x "b") \
547 DEF(TOK_ASM_ ## x ## w, #x "w") \
548 DEF(TOK_ASM_ ## x ## l, #x "l") \
549 DEF(TOK_ASM_ ## x, #x)
551 #define DEF_WL(x) \
552 DEF(TOK_ASM_ ## x ## w, #x "w") \
553 DEF(TOK_ASM_ ## x ## l, #x "l") \
554 DEF(TOK_ASM_ ## x, #x)
556 #define DEF_FP1(x) \
557 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
558 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
559 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
560 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
562 #define DEF_FP(x) \
563 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
564 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
565 DEF_FP1(x)
567 #define DEF_ASMTEST(x) \
568 DEF_ASM(x ## o) \
569 DEF_ASM(x ## no) \
570 DEF_ASM(x ## b) \
571 DEF_ASM(x ## c) \
572 DEF_ASM(x ## nae) \
573 DEF_ASM(x ## nb) \
574 DEF_ASM(x ## nc) \
575 DEF_ASM(x ## ae) \
576 DEF_ASM(x ## e) \
577 DEF_ASM(x ## z) \
578 DEF_ASM(x ## ne) \
579 DEF_ASM(x ## nz) \
580 DEF_ASM(x ## be) \
581 DEF_ASM(x ## na) \
582 DEF_ASM(x ## nbe) \
583 DEF_ASM(x ## a) \
584 DEF_ASM(x ## s) \
585 DEF_ASM(x ## ns) \
586 DEF_ASM(x ## p) \
587 DEF_ASM(x ## pe) \
588 DEF_ASM(x ## np) \
589 DEF_ASM(x ## po) \
590 DEF_ASM(x ## l) \
591 DEF_ASM(x ## nge) \
592 DEF_ASM(x ## nl) \
593 DEF_ASM(x ## ge) \
594 DEF_ASM(x ## le) \
595 DEF_ASM(x ## ng) \
596 DEF_ASM(x ## nle) \
597 DEF_ASM(x ## g)
599 #define TOK_ASM_int TOK_INT
601 enum {
602 TOK_LAST = TOK_IDENT - 1,
603 #define DEF(id, str) id,
604 #include "tcctok.h"
605 #undef DEF
608 static const char tcc_keywords[] =
609 #define DEF(id, str) str "\0"
610 #include "tcctok.h"
611 #undef DEF
614 #define TOK_UIDENT TOK_DEFINE
616 #ifdef WIN32
617 #define snprintf _snprintf
618 #define vsnprintf _vsnprintf
619 #endif
621 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
622 /* currently incorrect */
623 long double strtold(const char *nptr, char **endptr)
625 return (long double)strtod(nptr, endptr);
627 float strtof(const char *nptr, char **endptr)
629 return (float)strtod(nptr, endptr);
631 #else
632 /* XXX: need to define this to use them in non ISOC99 context */
633 extern float strtof (const char *__nptr, char **__endptr);
634 extern long double strtold (const char *__nptr, char **__endptr);
635 #endif
637 static char *pstrcpy(char *buf, int buf_size, const char *s);
638 static char *pstrcat(char *buf, int buf_size, const char *s);
640 static void next(void);
641 static void next_nomacro(void);
642 static void parse_expr_type(CType *type);
643 static void expr_type(CType *type);
644 static void unary_type(CType *type);
645 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
646 int case_reg, int is_expr);
647 static int expr_const(void);
648 static void expr_eq(void);
649 static void gexpr(void);
650 static void decl(int l);
651 static void decl_initializer(CType *type, Section *sec, unsigned long c,
652 int first, int size_only);
653 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
654 int has_init, int v, int scope);
655 int gv(int rc);
656 void gv2(int rc1, int rc2);
657 void move_reg(int r, int s);
658 void save_regs(int n);
659 void save_reg(int r);
660 void vpop(void);
661 void vswap(void);
662 void vdup(void);
663 int get_reg(int rc);
665 static void macro_subst(TokenString *tok_str,
666 Sym **nested_list, const int *macro_str);
667 int save_reg_forced(int r);
668 void gen_op(int op);
669 void force_charshort_cast(int t);
670 static void gen_cast(CType *type);
671 void vstore(void);
672 static Sym *sym_find(int v);
673 static Sym *sym_push(int v, CType *type, int r, int c);
675 /* type handling */
676 static int type_size(CType *type, int *a);
677 static inline CType *pointed_type(CType *type);
678 static int pointed_size(CType *type);
679 static int lvalue_type(int t);
680 static int is_compatible_types(CType *type1, CType *type2);
681 static int parse_btype(CType *type, AttributeDef *ad);
682 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
684 void error(const char *fmt, ...);
685 void vpushi(int v);
686 void vset(CType *type, int r, int v);
687 void type_to_str(char *buf, int buf_size,
688 CType *type, const char *varstr);
689 char *get_tok_str(int v, CValue *cv);
690 static Sym *get_sym_ref(CType *type, Section *sec,
691 unsigned long offset, unsigned long size);
692 static Sym *external_global_sym(int v, CType *type, int r);
694 /* section generation */
695 static void section_realloc(Section *sec, unsigned long new_size);
696 static void *section_ptr_add(Section *sec, unsigned long size);
697 static void put_extern_sym(Sym *sym, Section *section,
698 unsigned long value, unsigned long size);
699 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
700 static int put_elf_str(Section *s, const char *sym);
701 static int put_elf_sym(Section *s,
702 unsigned long value, unsigned long size,
703 int info, int other, int shndx, const char *name);
704 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
705 int info, int sh_num, const char *name);
706 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
707 int type, int symbol);
708 static void put_stabs(const char *str, int type, int other, int desc,
709 unsigned long value);
710 static void put_stabs_r(const char *str, int type, int other, int desc,
711 unsigned long value, Section *sec, int sym_index);
712 static void put_stabn(int type, int other, int desc, int value);
713 static void put_stabd(int type, int other, int desc);
714 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
716 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
717 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
718 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
720 /* tccasm.c */
722 #ifdef CONFIG_TCC_ASM
724 typedef struct ExprValue {
725 uint32_t v;
726 Sym *sym;
727 } ExprValue;
729 #define MAX_ASM_OPERANDS 30
731 typedef struct ASMOperand {
732 int id; /* GCC 3 optionnal identifier (0 if number only supported */
733 char *constraint;
734 char asm_str[16]; /* computed asm string for operand */
735 SValue *vt; /* C value of the expression */
736 int ref_index; /* if >= 0, gives reference to a output constraint */
737 int priority; /* priority, used to assign registers */
738 int reg; /* if >= 0, register number used for this operand */
739 } ASMOperand;
741 static void asm_expr(TCCState *s1, ExprValue *pe);
742 static int asm_int_expr(TCCState *s1);
743 static int find_constraint(ASMOperand *operands, int nb_operands,
744 const char *name, const char **pp);
746 static int tcc_assemble(TCCState *s1, int do_preprocess);
748 #endif
750 static void asm_instr(void);
752 /* true if float/double/long double type */
753 static inline int is_float(int t)
755 int bt;
756 bt = t & VT_BTYPE;
757 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
760 #ifdef TCC_TARGET_I386
761 #include "i386-gen.c"
762 #endif
764 #ifdef CONFIG_TCC_STATIC
766 #define RTLD_LAZY 0x001
767 #define RTLD_NOW 0x002
768 #define RTLD_GLOBAL 0x100
769 #define RTLD_DEFAULT NULL
771 /* dummy function for profiling */
772 void *dlopen(const char *filename, int flag)
774 return NULL;
777 const char *dlerror(void)
779 return "error";
782 typedef struct TCCSyms {
783 char *str;
784 void *ptr;
785 } TCCSyms;
787 #define TCCSYM(a) { #a, &a, },
789 /* add the symbol you want here if no dynamic linking is done */
790 static TCCSyms tcc_syms[] = {
791 TCCSYM(printf)
792 TCCSYM(fprintf)
793 TCCSYM(fopen)
794 TCCSYM(fclose)
795 { NULL, NULL },
798 void *dlsym(void *handle, const char *symbol)
800 TCCSyms *p;
801 p = tcc_syms;
802 while (p->str != NULL) {
803 if (!strcmp(p->str, symbol))
804 return p->ptr;
805 p++;
807 return NULL;
810 #endif
812 /********************************************************/
814 /* we use our own 'finite' function to avoid potential problems with
815 non standard math libs */
816 /* XXX: endianness dependent */
817 int ieee_finite(double d)
819 int *p = (int *)&d;
820 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
823 /* copy a string and truncate it. */
824 static char *pstrcpy(char *buf, int buf_size, const char *s)
826 char *q, *q_end;
827 int c;
829 if (buf_size > 0) {
830 q = buf;
831 q_end = buf + buf_size - 1;
832 while (q < q_end) {
833 c = *s++;
834 if (c == '\0')
835 break;
836 *q++ = c;
838 *q = '\0';
840 return buf;
843 /* strcat and truncate. */
844 static char *pstrcat(char *buf, int buf_size, const char *s)
846 int len;
847 len = strlen(buf);
848 if (len < buf_size)
849 pstrcpy(buf + len, buf_size - len, s);
850 return buf;
853 /* memory management */
854 #ifdef MEM_DEBUG
855 int mem_cur_size;
856 int mem_max_size;
857 #endif
859 static inline void tcc_free(void *ptr)
861 #ifdef MEM_DEBUG
862 mem_cur_size -= malloc_usable_size(ptr);
863 #endif
864 free(ptr);
867 static void *tcc_malloc(unsigned long size)
869 void *ptr;
870 ptr = malloc(size);
871 if (!ptr && size)
872 error("memory full");
873 #ifdef MEM_DEBUG
874 mem_cur_size += malloc_usable_size(ptr);
875 if (mem_cur_size > mem_max_size)
876 mem_max_size = mem_cur_size;
877 #endif
878 return ptr;
881 static void *tcc_mallocz(unsigned long size)
883 void *ptr;
884 ptr = tcc_malloc(size);
885 memset(ptr, 0, size);
886 return ptr;
889 static inline void *tcc_realloc(void *ptr, unsigned long size)
891 void *ptr1;
892 #ifdef MEM_DEBUG
893 mem_cur_size -= malloc_usable_size(ptr);
894 #endif
895 ptr1 = realloc(ptr, size);
896 #ifdef MEM_DEBUG
897 /* NOTE: count not correct if alloc error, but not critical */
898 mem_cur_size += malloc_usable_size(ptr1);
899 if (mem_cur_size > mem_max_size)
900 mem_max_size = mem_cur_size;
901 #endif
902 return ptr1;
905 static char *tcc_strdup(const char *str)
907 char *ptr;
908 ptr = tcc_malloc(strlen(str) + 1);
909 strcpy(ptr, str);
910 return ptr;
913 #define free(p) use_tcc_free(p)
914 #define malloc(s) use_tcc_malloc(s)
915 #define realloc(p, s) use_tcc_realloc(p, s)
917 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
919 int nb, nb_alloc;
920 void **pp;
922 nb = *nb_ptr;
923 pp = *ptab;
924 /* every power of two we double array size */
925 if ((nb & (nb - 1)) == 0) {
926 if (!nb)
927 nb_alloc = 1;
928 else
929 nb_alloc = nb * 2;
930 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
931 if (!pp)
932 error("memory full");
933 *ptab = pp;
935 pp[nb++] = data;
936 *nb_ptr = nb;
939 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
941 Section *sec;
943 sec = tcc_mallocz(sizeof(Section));
944 pstrcpy(sec->name, sizeof(sec->name), name);
945 sec->sh_type = sh_type;
946 sec->sh_flags = sh_flags;
947 switch(sh_type) {
948 case SHT_HASH:
949 case SHT_REL:
950 case SHT_DYNSYM:
951 case SHT_SYMTAB:
952 case SHT_DYNAMIC:
953 sec->sh_addralign = 4;
954 break;
955 case SHT_STRTAB:
956 sec->sh_addralign = 1;
957 break;
958 default:
959 sec->sh_addralign = 32; /* default conservative alignment */
960 break;
963 /* only add section if not private */
964 if (!(sh_flags & SHF_PRIVATE)) {
965 sec->sh_num = s1->nb_sections;
966 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
968 return sec;
971 static void free_section(Section *s)
973 tcc_free(s->data);
974 tcc_free(s);
977 /* realloc section and set its content to zero */
978 static void section_realloc(Section *sec, unsigned long new_size)
980 unsigned long size;
981 unsigned char *data;
983 size = sec->data_allocated;
984 if (size == 0)
985 size = 1;
986 while (size < new_size)
987 size = size * 2;
988 data = tcc_realloc(sec->data, size);
989 if (!data)
990 error("memory full");
991 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
992 sec->data = data;
993 sec->data_allocated = size;
996 /* reserve at least 'size' bytes in section 'sec' from
997 sec->data_offset. */
998 static void *section_ptr_add(Section *sec, unsigned long size)
1000 unsigned long offset, offset1;
1002 offset = sec->data_offset;
1003 offset1 = offset + size;
1004 if (offset1 > sec->data_allocated)
1005 section_realloc(sec, offset1);
1006 sec->data_offset = offset1;
1007 return sec->data + offset;
1010 /* return a reference to a section, and create it if it does not
1011 exists */
1012 Section *find_section(TCCState *s1, const char *name)
1014 Section *sec;
1015 int i;
1016 for(i = 1; i < s1->nb_sections; i++) {
1017 sec = s1->sections[i];
1018 if (!strcmp(name, sec->name))
1019 return sec;
1021 /* sections are created as PROGBITS */
1022 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
1025 /* update sym->c so that it points to an external symbol in section
1026 'section' with value 'value' */
1027 static void put_extern_sym(Sym *sym, Section *section,
1028 unsigned long value, unsigned long size)
1030 int sym_type, sym_bind, sh_num, info;
1031 Elf32_Sym *esym;
1032 const char *name;
1034 if (section)
1035 sh_num = section->sh_num;
1036 else
1037 sh_num = SHN_UNDEF;
1038 if (!sym->c) {
1039 if ((sym->type.t & VT_BTYPE) == VT_FUNC)
1040 sym_type = STT_FUNC;
1041 else
1042 sym_type = STT_OBJECT;
1043 if (sym->type.t & VT_STATIC)
1044 sym_bind = STB_LOCAL;
1045 else
1046 sym_bind = STB_GLOBAL;
1048 name = get_tok_str(sym->v, NULL);
1049 #ifdef CONFIG_TCC_BCHECK
1050 if (do_bounds_check) {
1051 char buf[32];
1053 /* XXX: avoid doing that for statics ? */
1054 /* if bound checking is activated, we change some function
1055 names by adding the "__bound" prefix */
1056 switch(sym->v) {
1057 #if 0
1058 /* XXX: we rely only on malloc hooks */
1059 case TOK_malloc:
1060 case TOK_free:
1061 case TOK_realloc:
1062 case TOK_memalign:
1063 case TOK_calloc:
1064 #endif
1065 case TOK_memcpy:
1066 case TOK_memmove:
1067 case TOK_memset:
1068 case TOK_strlen:
1069 case TOK_strcpy:
1070 strcpy(buf, "__bound_");
1071 strcat(buf, name);
1072 name = buf;
1073 break;
1076 #endif
1077 info = ELF32_ST_INFO(sym_bind, sym_type);
1078 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
1079 } else {
1080 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
1081 esym->st_value = value;
1082 esym->st_size = size;
1083 esym->st_shndx = sh_num;
1087 /* add a new relocation entry to symbol 'sym' in section 's' */
1088 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
1090 if (!sym->c)
1091 put_extern_sym(sym, NULL, 0, 0);
1092 /* now we can add ELF relocation info */
1093 put_elf_reloc(symtab_section, s, offset, type, sym->c);
1096 static inline int isid(int c)
1098 return (c >= 'a' && c <= 'z') ||
1099 (c >= 'A' && c <= 'Z') ||
1100 c == '_';
1103 static inline int isnum(int c)
1105 return c >= '0' && c <= '9';
1108 static inline int isoct(int c)
1110 return c >= '0' && c <= '7';
1113 static inline int toup(int c)
1115 if (c >= 'a' && c <= 'z')
1116 return c - 'a' + 'A';
1117 else
1118 return c;
1121 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
1123 int len;
1124 len = strlen(buf);
1125 vsnprintf(buf + len, buf_size - len, fmt, ap);
1128 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
1130 va_list ap;
1131 va_start(ap, fmt);
1132 strcat_vprintf(buf, buf_size, fmt, ap);
1133 va_end(ap);
1136 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
1138 char buf[2048];
1139 BufferedFile **f;
1141 buf[0] = '\0';
1142 if (file) {
1143 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1144 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1145 (*f)->filename, (*f)->line_num);
1146 if (file->line_num > 0) {
1147 strcat_printf(buf, sizeof(buf),
1148 "%s:%d: ", file->filename, file->line_num);
1149 } else {
1150 strcat_printf(buf, sizeof(buf),
1151 "%s: ", file->filename);
1153 } else {
1154 strcat_printf(buf, sizeof(buf),
1155 "tcc: ");
1157 if (is_warning)
1158 strcat_printf(buf, sizeof(buf), "warning: ");
1159 strcat_vprintf(buf, sizeof(buf), fmt, ap);
1161 if (!s1->error_func) {
1162 /* default case: stderr */
1163 fprintf(stderr, "%s\n", buf);
1164 } else {
1165 s1->error_func(s1->error_opaque, buf);
1167 if (!is_warning)
1168 s1->nb_errors++;
1171 #ifdef LIBTCC
1172 void tcc_set_error_func(TCCState *s, void *error_opaque,
1173 void (*error_func)(void *opaque, const char *msg))
1175 s->error_opaque = error_opaque;
1176 s->error_func = error_func;
1178 #endif
1180 /* error without aborting current compilation */
1181 void error_noabort(const char *fmt, ...)
1183 TCCState *s1 = tcc_state;
1184 va_list ap;
1186 va_start(ap, fmt);
1187 error1(s1, 0, fmt, ap);
1188 va_end(ap);
1191 void error(const char *fmt, ...)
1193 TCCState *s1 = tcc_state;
1194 va_list ap;
1196 va_start(ap, fmt);
1197 error1(s1, 0, fmt, ap);
1198 va_end(ap);
1199 /* better than nothing: in some cases, we accept to handle errors */
1200 if (s1->error_set_jmp_enabled) {
1201 longjmp(s1->error_jmp_buf, 1);
1202 } else {
1203 /* XXX: eliminate this someday */
1204 exit(1);
1208 void expect(const char *msg)
1210 error("%s expected", msg);
1213 void warning(const char *fmt, ...)
1215 TCCState *s1 = tcc_state;
1216 va_list ap;
1218 va_start(ap, fmt);
1219 error1(s1, 1, fmt, ap);
1220 va_end(ap);
1223 void skip(int c)
1225 if (tok != c)
1226 error("'%c' expected", c);
1227 next();
1230 static void test_lvalue(void)
1232 if (!(vtop->r & VT_LVAL))
1233 expect("lvalue");
1236 /* allocate a new token */
1237 static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
1239 TokenSym *ts, **ptable;
1240 int i;
1242 if (tok_ident >= SYM_FIRST_ANOM)
1243 error("memory full");
1245 /* expand token table if needed */
1246 i = tok_ident - TOK_IDENT;
1247 if ((i % TOK_ALLOC_INCR) == 0) {
1248 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1249 if (!ptable)
1250 error("memory full");
1251 table_ident = ptable;
1254 ts = tcc_malloc(sizeof(TokenSym) + len);
1255 table_ident[i] = ts;
1256 ts->tok = tok_ident++;
1257 ts->sym_define = NULL;
1258 ts->sym_label = NULL;
1259 ts->sym_struct = NULL;
1260 ts->sym_identifier = NULL;
1261 ts->len = len;
1262 ts->hash_next = NULL;
1263 memcpy(ts->str, str, len);
1264 ts->str[len] = '\0';
1265 *pts = ts;
1266 return ts;
1269 #define TOK_HASH_INIT 1
1270 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1272 /* find a token and add it if not found */
1273 static TokenSym *tok_alloc(const char *str, int len)
1275 TokenSym *ts, **pts;
1276 int i;
1277 unsigned int h;
1279 h = TOK_HASH_INIT;
1280 for(i=0;i<len;i++)
1281 h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
1282 h &= (TOK_HASH_SIZE - 1);
1284 pts = &hash_ident[h];
1285 for(;;) {
1286 ts = *pts;
1287 if (!ts)
1288 break;
1289 if (ts->len == len && !memcmp(ts->str, str, len))
1290 return ts;
1291 pts = &(ts->hash_next);
1293 return tok_alloc_new(pts, str, len);
1296 /* CString handling */
1298 static void cstr_realloc(CString *cstr, int new_size)
1300 int size;
1301 void *data;
1303 size = cstr->size_allocated;
1304 if (size == 0)
1305 size = 8; /* no need to allocate a too small first string */
1306 while (size < new_size)
1307 size = size * 2;
1308 data = tcc_realloc(cstr->data_allocated, size);
1309 if (!data)
1310 error("memory full");
1311 cstr->data_allocated = data;
1312 cstr->size_allocated = size;
1313 cstr->data = data;
1316 /* add a byte */
1317 static void cstr_ccat(CString *cstr, int ch)
1319 int size;
1320 size = cstr->size + 1;
1321 if (size > cstr->size_allocated)
1322 cstr_realloc(cstr, size);
1323 ((unsigned char *)cstr->data)[size - 1] = ch;
1324 cstr->size = size;
1327 static void cstr_cat(CString *cstr, const char *str)
1329 int c;
1330 for(;;) {
1331 c = *str;
1332 if (c == '\0')
1333 break;
1334 cstr_ccat(cstr, c);
1335 str++;
1339 /* add a wide char */
1340 static void cstr_wccat(CString *cstr, int ch)
1342 int size;
1343 size = cstr->size + sizeof(int);
1344 if (size > cstr->size_allocated)
1345 cstr_realloc(cstr, size);
1346 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1347 cstr->size = size;
1350 static void cstr_new(CString *cstr)
1352 memset(cstr, 0, sizeof(CString));
1355 /* free string and reset it to NULL */
1356 static void cstr_free(CString *cstr)
1358 tcc_free(cstr->data_allocated);
1359 cstr_new(cstr);
1362 #define cstr_reset(cstr) cstr_free(cstr)
1364 static CString *cstr_dup(CString *cstr1)
1366 CString *cstr;
1367 int size;
1369 cstr = tcc_malloc(sizeof(CString));
1370 size = cstr1->size;
1371 cstr->size = size;
1372 cstr->size_allocated = size;
1373 cstr->data_allocated = tcc_malloc(size);
1374 cstr->data = cstr->data_allocated;
1375 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1376 return cstr;
1379 /* XXX: unicode ? */
1380 static void add_char(CString *cstr, int c)
1382 if (c == '\'' || c == '\"' || c == '\\') {
1383 /* XXX: could be more precise if char or string */
1384 cstr_ccat(cstr, '\\');
1386 if (c >= 32 && c <= 126) {
1387 cstr_ccat(cstr, c);
1388 } else {
1389 cstr_ccat(cstr, '\\');
1390 if (c == '\n') {
1391 cstr_ccat(cstr, 'n');
1392 } else {
1393 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1394 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1395 cstr_ccat(cstr, '0' + (c & 7));
1400 /* XXX: buffer overflow */
1401 /* XXX: float tokens */
1402 char *get_tok_str(int v, CValue *cv)
1404 static char buf[STRING_MAX_SIZE + 1];
1405 static CString cstr_buf;
1406 CString *cstr;
1407 unsigned char *q;
1408 char *p;
1409 int i, len;
1411 /* NOTE: to go faster, we give a fixed buffer for small strings */
1412 cstr_reset(&cstr_buf);
1413 cstr_buf.data = buf;
1414 cstr_buf.size_allocated = sizeof(buf);
1415 p = buf;
1417 switch(v) {
1418 case TOK_CINT:
1419 case TOK_CUINT:
1420 /* XXX: not quite exact, but only useful for testing */
1421 sprintf(p, "%u", cv->ui);
1422 break;
1423 case TOK_CLLONG:
1424 case TOK_CULLONG:
1425 /* XXX: not quite exact, but only useful for testing */
1426 sprintf(p, "%Lu", cv->ull);
1427 break;
1428 case TOK_CCHAR:
1429 case TOK_LCHAR:
1430 cstr_ccat(&cstr_buf, '\'');
1431 add_char(&cstr_buf, cv->i);
1432 cstr_ccat(&cstr_buf, '\'');
1433 cstr_ccat(&cstr_buf, '\0');
1434 break;
1435 case TOK_PPNUM:
1436 cstr = cv->cstr;
1437 len = cstr->size - 1;
1438 for(i=0;i<len;i++)
1439 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1440 cstr_ccat(&cstr_buf, '\0');
1441 break;
1442 case TOK_STR:
1443 case TOK_LSTR:
1444 cstr = cv->cstr;
1445 cstr_ccat(&cstr_buf, '\"');
1446 if (v == TOK_STR) {
1447 len = cstr->size - 1;
1448 for(i=0;i<len;i++)
1449 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1450 } else {
1451 len = (cstr->size / sizeof(int)) - 1;
1452 for(i=0;i<len;i++)
1453 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1455 cstr_ccat(&cstr_buf, '\"');
1456 cstr_ccat(&cstr_buf, '\0');
1457 break;
1458 case TOK_LT:
1459 v = '<';
1460 goto addv;
1461 case TOK_GT:
1462 v = '>';
1463 goto addv;
1464 case TOK_A_SHL:
1465 return strcpy(p, "<<=");
1466 case TOK_A_SAR:
1467 return strcpy(p, ">>=");
1468 default:
1469 if (v < TOK_IDENT) {
1470 /* search in two bytes table */
1471 q = tok_two_chars;
1472 while (*q) {
1473 if (q[2] == v) {
1474 *p++ = q[0];
1475 *p++ = q[1];
1476 *p = '\0';
1477 return buf;
1479 q += 3;
1481 addv:
1482 *p++ = v;
1483 *p = '\0';
1484 } else if (v < tok_ident) {
1485 return table_ident[v - TOK_IDENT]->str;
1486 } else if (v >= SYM_FIRST_ANOM) {
1487 /* special name for anonymous symbol */
1488 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1489 } else {
1490 /* should never happen */
1491 return NULL;
1493 break;
1495 return cstr_buf.data;
1498 /* push, without hashing */
1499 static Sym *sym_push2(Sym **ps, int v, int t, int c)
1501 Sym *s;
1502 s = tcc_malloc(sizeof(Sym));
1503 s->v = v;
1504 s->type.t = t;
1505 s->c = c;
1506 s->next = NULL;
1507 /* add in stack */
1508 s->prev = *ps;
1509 *ps = s;
1510 return s;
1513 /* find a symbol and return its associated structure. 's' is the top
1514 of the symbol stack */
1515 static Sym *sym_find2(Sym *s, int v)
1517 while (s) {
1518 if (s->v == v)
1519 return s;
1520 s = s->prev;
1522 return NULL;
1525 /* structure lookup */
1526 static inline Sym *struct_find(int v)
1528 v -= TOK_IDENT;
1529 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1530 return NULL;
1531 return table_ident[v]->sym_struct;
1534 /* find an identifier */
1535 static inline Sym *sym_find(int v)
1537 v -= TOK_IDENT;
1538 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1539 return NULL;
1540 return table_ident[v]->sym_identifier;
1543 /* push a given symbol on the symbol stack */
1544 static Sym *sym_push(int v, CType *type, int r, int c)
1546 Sym *s, **ps;
1547 TokenSym *ts;
1549 if (local_stack)
1550 ps = &local_stack;
1551 else
1552 ps = &global_stack;
1553 s = sym_push2(ps, v, type->t, c);
1554 s->type.ref = type->ref;
1555 s->r = r;
1556 /* don't record fields or anonymous symbols */
1557 /* XXX: simplify */
1558 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1559 /* record symbol in token array */
1560 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1561 if (v & SYM_STRUCT)
1562 ps = &ts->sym_struct;
1563 else
1564 ps = &ts->sym_identifier;
1565 s->prev_tok = *ps;
1566 *ps = s;
1568 return s;
1571 /* push a global identifier */
1572 static Sym *global_identifier_push(int v, int t, int c)
1574 Sym *s, **ps;
1575 s = sym_push2(&global_stack, v, t, c);
1576 /* don't record anonymous symbol */
1577 if (v < SYM_FIRST_ANOM) {
1578 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1579 /* modify the top most local identifier, so that
1580 sym_identifier will point to 's' when popped */
1581 while (*ps != NULL)
1582 ps = &(*ps)->prev_tok;
1583 s->prev_tok = NULL;
1584 *ps = s;
1586 return s;
1589 /* pop symbols until top reaches 'b' */
1590 static void sym_pop(Sym **ptop, Sym *b)
1592 Sym *s, *ss, **ps;
1593 TokenSym *ts;
1594 int v;
1596 s = *ptop;
1597 while(s != b) {
1598 ss = s->prev;
1599 v = s->v;
1600 /* remove symbol in token array */
1601 /* XXX: simplify */
1602 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1603 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1604 if (v & SYM_STRUCT)
1605 ps = &ts->sym_struct;
1606 else
1607 ps = &ts->sym_identifier;
1608 *ps = s->prev_tok;
1610 tcc_free(s);
1611 s = ss;
1613 *ptop = b;
1616 /* I/O layer */
1618 BufferedFile *tcc_open(TCCState *s1, const char *filename)
1620 int fd;
1621 BufferedFile *bf;
1623 fd = open(filename, O_RDONLY);
1624 if (fd < 0)
1625 return NULL;
1626 bf = tcc_malloc(sizeof(BufferedFile));
1627 if (!bf) {
1628 close(fd);
1629 return NULL;
1631 bf->fd = fd;
1632 bf->buf_ptr = bf->buffer;
1633 bf->buf_end = bf->buffer;
1634 bf->buffer[0] = CH_EOB; /* put eob symbol */
1635 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1636 bf->line_num = 1;
1637 bf->ifndef_macro = 0;
1638 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1639 // printf("opening '%s'\n", filename);
1640 return bf;
1643 void tcc_close(BufferedFile *bf)
1645 total_lines += bf->line_num;
1646 close(bf->fd);
1647 tcc_free(bf);
1650 /* fill input buffer and peek next char */
1651 static int tcc_peekc_slow(BufferedFile *bf)
1653 int len;
1654 /* only tries to read if really end of buffer */
1655 if (bf->buf_ptr >= bf->buf_end) {
1656 if (bf->fd != -1) {
1657 #if defined(PARSE_DEBUG)
1658 len = 8;
1659 #else
1660 len = IO_BUF_SIZE;
1661 #endif
1662 len = read(bf->fd, bf->buffer, len);
1663 if (len < 0)
1664 len = 0;
1665 } else {
1666 len = 0;
1668 total_bytes += len;
1669 bf->buf_ptr = bf->buffer;
1670 bf->buf_end = bf->buffer + len;
1671 *bf->buf_end = CH_EOB;
1673 if (bf->buf_ptr < bf->buf_end) {
1674 return bf->buf_ptr[0];
1675 } else {
1676 bf->buf_ptr = bf->buf_end;
1677 return CH_EOF;
1681 /* return the current character, handling end of block if necessary
1682 (but not stray) */
1683 static int handle_eob(void)
1685 return tcc_peekc_slow(file);
1688 /* read next char from current input file and handle end of input buffer */
1689 static inline void inp(void)
1691 ch = *(++(file->buf_ptr));
1692 /* end of buffer/file handling */
1693 if (ch == CH_EOB)
1694 ch = handle_eob();
1697 /* handle '\[\r]\n' */
1698 static void handle_stray(void)
1700 while (ch == '\\') {
1701 inp();
1702 if (ch == '\n') {
1703 file->line_num++;
1704 inp();
1705 } else if (ch == '\r') {
1706 inp();
1707 if (ch != '\n')
1708 goto fail;
1709 file->line_num++;
1710 inp();
1711 } else {
1712 fail:
1713 error("stray '\\' in program");
1718 /* skip the stray and handle the \\n case. Output an error if
1719 incorrect char after the stray */
1720 static int handle_stray1(uint8_t *p)
1722 int c;
1724 if (p >= file->buf_end) {
1725 file->buf_ptr = p;
1726 c = handle_eob();
1727 p = file->buf_ptr;
1728 if (c == '\\')
1729 goto parse_stray;
1730 } else {
1731 parse_stray:
1732 file->buf_ptr = p;
1733 ch = *p;
1734 handle_stray();
1735 p = file->buf_ptr;
1736 c = *p;
1738 return c;
1741 /* handle just the EOB case, but not stray */
1742 #define PEEKC_EOB(c, p)\
1744 p++;\
1745 c = *p;\
1746 if (c == '\\') {\
1747 file->buf_ptr = p;\
1748 c = handle_eob();\
1749 p = file->buf_ptr;\
1753 /* handle the complicated stray case */
1754 #define PEEKC(c, p)\
1756 p++;\
1757 c = *p;\
1758 if (c == '\\') {\
1759 c = handle_stray1(p);\
1760 p = file->buf_ptr;\
1764 /* input with '\[\r]\n' handling. Note that this function cannot
1765 handle other characters after '\', so you cannot call it inside
1766 strings or comments */
1767 static void minp(void)
1769 inp();
1770 if (ch == '\\')
1771 handle_stray();
1775 /* single line C++ comments */
1776 static uint8_t *parse_line_comment(uint8_t *p)
1778 int c;
1780 p++;
1781 for(;;) {
1782 c = *p;
1783 if (c == '\n' || c == CH_EOF) {
1784 break;
1785 } else if (c == '\\') {
1786 PEEKC_EOB(c, p);
1787 if (c == '\n') {
1788 file->line_num++;
1789 PEEKC_EOB(c, p);
1790 } else if (c == '\r') {
1791 PEEKC_EOB(c, p);
1792 if (c == '\n') {
1793 file->line_num++;
1794 PEEKC_EOB(c, p);
1797 } else {
1798 p++;
1801 return p;
1804 /* C comments */
1805 static uint8_t *parse_comment(uint8_t *p)
1807 int c;
1809 p++;
1810 for(;;) {
1811 /* fast skip loop */
1812 for(;;) {
1813 c = *p;
1814 if (c == '\n' || c == '*' || c == '\\')
1815 break;
1816 p++;
1817 c = *p;
1818 if (c == '\n' || c == '*' || c == '\\')
1819 break;
1820 p++;
1822 /* now we can handle all the cases */
1823 if (c == '\n') {
1824 file->line_num++;
1825 p++;
1826 } else if (c == '*') {
1827 p++;
1828 for(;;) {
1829 c = *p;
1830 if (c == '*') {
1831 p++;
1832 } else if (c == '/') {
1833 goto end_of_comment;
1834 } else if (c == '\\') {
1835 file->buf_ptr = p;
1836 c = handle_eob();
1837 p = file->buf_ptr;
1838 if (c == '\\') {
1839 /* skip '\[\r]\n', otherwise just skip the stray */
1840 while (c == '\\') {
1841 PEEKC_EOB(c, p);
1842 if (c == '\n') {
1843 file->line_num++;
1844 PEEKC_EOB(c, p);
1845 } else if (c == '\r') {
1846 PEEKC_EOB(c, p);
1847 if (c == '\n') {
1848 file->line_num++;
1849 PEEKC_EOB(c, p);
1851 } else {
1852 goto after_star;
1856 } else {
1857 break;
1860 after_star: ;
1861 } else {
1862 /* stray, eob or eof */
1863 file->buf_ptr = p;
1864 c = handle_eob();
1865 p = file->buf_ptr;
1866 if (c == CH_EOF) {
1867 error("unexpected end of file in comment");
1868 } else if (c == '\\') {
1869 p++;
1873 end_of_comment:
1874 p++;
1875 return p;
1878 #define cinp minp
1880 /* space exlcuding newline */
1881 static inline int is_space(int ch)
1883 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1886 static inline void skip_spaces(void)
1888 while (is_space(ch))
1889 cinp();
1892 /* parse a string without interpreting escapes */
1893 static uint8_t *parse_pp_string(uint8_t *p,
1894 int sep, CString *str)
1896 int c;
1897 p++;
1898 for(;;) {
1899 c = *p;
1900 if (c == sep) {
1901 break;
1902 } else if (c == '\\') {
1903 file->buf_ptr = p;
1904 c = handle_eob();
1905 p = file->buf_ptr;
1906 if (c == CH_EOF) {
1907 unterminated_string:
1908 /* XXX: indicate line number of start of string */
1909 error("missing terminating %c character", sep);
1910 } else if (c == '\\') {
1911 /* escape : just skip \[\r]\n */
1912 PEEKC_EOB(c, p);
1913 if (c == '\n') {
1914 file->line_num++;
1915 p++;
1916 } else if (c == '\r') {
1917 PEEKC_EOB(c, p);
1918 if (c != '\n')
1919 expect("'\n' after '\r'");
1920 file->line_num++;
1921 p++;
1922 } else if (c == CH_EOF) {
1923 goto unterminated_string;
1924 } else {
1925 if (str) {
1926 cstr_ccat(str, '\\');
1927 cstr_ccat(str, c);
1929 p++;
1932 } else if (c == '\n') {
1933 file->line_num++;
1934 goto add_char;
1935 } else if (c == '\r') {
1936 PEEKC_EOB(c, p);
1937 if (c != '\n') {
1938 cstr_ccat(str, '\r');
1939 } else {
1940 file->line_num++;
1941 goto add_char;
1943 } else {
1944 add_char:
1945 if (str)
1946 cstr_ccat(str, c);
1947 p++;
1950 p++;
1951 return p;
1954 /* skip block of text until #else, #elif or #endif. skip also pairs of
1955 #if/#endif */
1956 void preprocess_skip(void)
1958 int a, start_of_line, c;
1959 uint8_t *p;
1961 p = file->buf_ptr;
1962 start_of_line = 1;
1963 a = 0;
1964 for(;;) {
1965 redo_no_start:
1966 c = *p;
1967 switch(c) {
1968 case ' ':
1969 case '\t':
1970 case '\f':
1971 case '\v':
1972 case '\r':
1973 p++;
1974 goto redo_no_start;
1975 case '\n':
1976 start_of_line = 1;
1977 file->line_num++;
1978 p++;
1979 goto redo_no_start;
1980 case '\\':
1981 file->buf_ptr = p;
1982 c = handle_eob();
1983 if (c == CH_EOF) {
1984 expect("#endif");
1985 } else if (c == '\\') {
1986 /* XXX: incorrect: should not give an error */
1987 ch = file->buf_ptr[0];
1988 handle_stray();
1990 p = file->buf_ptr;
1991 goto redo_no_start;
1992 /* skip strings */
1993 case '\"':
1994 case '\'':
1995 p = parse_pp_string(p, c, NULL);
1996 break;
1997 /* skip comments */
1998 case '/':
1999 file->buf_ptr = p;
2000 ch = *p;
2001 minp();
2002 p = file->buf_ptr;
2003 if (ch == '*') {
2004 p = parse_comment(p);
2005 } else if (ch == '/') {
2006 p = parse_line_comment(p);
2008 break;
2010 case '#':
2011 p++;
2012 if (start_of_line) {
2013 file->buf_ptr = p;
2014 next_nomacro();
2015 p = file->buf_ptr;
2016 if (a == 0 &&
2017 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
2018 goto the_end;
2019 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
2020 a++;
2021 else if (tok == TOK_ENDIF)
2022 a--;
2024 break;
2025 default:
2026 p++;
2027 break;
2029 start_of_line = 0;
2031 the_end: ;
2032 file->buf_ptr = p;
2035 /* ParseState handling */
2037 /* XXX: currently, no include file info is stored. Thus, we cannot display
2038 accurate messages if the function or data definition spans multiple
2039 files */
2041 /* save current parse state in 's' */
2042 void save_parse_state(ParseState *s)
2044 s->line_num = file->line_num;
2045 s->macro_ptr = macro_ptr;
2046 s->tok = tok;
2047 s->tokc = tokc;
2050 /* restore parse state from 's' */
2051 void restore_parse_state(ParseState *s)
2053 file->line_num = s->line_num;
2054 macro_ptr = s->macro_ptr;
2055 tok = s->tok;
2056 tokc = s->tokc;
2059 /* return the number of additional 'ints' necessary to store the
2060 token */
2061 static inline int tok_ext_size(int t)
2063 switch(t) {
2064 /* 4 bytes */
2065 case TOK_CINT:
2066 case TOK_CUINT:
2067 case TOK_CCHAR:
2068 case TOK_LCHAR:
2069 case TOK_STR:
2070 case TOK_LSTR:
2071 case TOK_CFLOAT:
2072 case TOK_LINENUM:
2073 case TOK_PPNUM:
2074 return 1;
2075 case TOK_CDOUBLE:
2076 case TOK_CLLONG:
2077 case TOK_CULLONG:
2078 return 2;
2079 case TOK_CLDOUBLE:
2080 return LDOUBLE_SIZE / 4;
2081 default:
2082 return 0;
2086 /* token string handling */
2088 static inline void tok_str_new(TokenString *s)
2090 s->str = NULL;
2091 s->len = 0;
2092 s->allocated_len = 0;
2093 s->last_line_num = -1;
2096 static void tok_str_free(int *str)
2098 const int *p;
2099 CString *cstr;
2100 int t;
2102 p = str;
2103 for(;;) {
2104 t = *p;
2105 /* NOTE: we test zero separately so that GCC can generate a
2106 table for the following switch */
2107 if (t == 0)
2108 break;
2109 switch(t) {
2110 case TOK_CINT:
2111 case TOK_CUINT:
2112 case TOK_CCHAR:
2113 case TOK_LCHAR:
2114 case TOK_CFLOAT:
2115 case TOK_LINENUM:
2116 p += 2;
2117 break;
2118 case TOK_PPNUM:
2119 case TOK_STR:
2120 case TOK_LSTR:
2121 /* XXX: use a macro to be portable on 64 bit ? */
2122 cstr = (CString *)p[1];
2123 cstr_free(cstr);
2124 tcc_free(cstr);
2125 p += 2;
2126 break;
2127 case TOK_CDOUBLE:
2128 case TOK_CLLONG:
2129 case TOK_CULLONG:
2130 p += 3;
2131 break;
2132 case TOK_CLDOUBLE:
2133 p += 1 + (LDOUBLE_SIZE / 4);
2134 break;
2135 default:
2136 p++;
2137 break;
2140 tcc_free(str);
2143 static int *tok_str_realloc(TokenString *s)
2145 int *str, len;
2147 len = s->allocated_len + TOK_STR_ALLOC_INCR;
2148 str = tcc_realloc(s->str, len * sizeof(int));
2149 if (!str)
2150 error("memory full");
2151 s->allocated_len = len;
2152 s->str = str;
2153 return str;
2156 static void tok_str_add(TokenString *s, int t)
2158 int len, *str;
2160 len = s->len;
2161 str = s->str;
2162 if (len >= s->allocated_len)
2163 str = tok_str_realloc(s);
2164 str[len++] = t;
2165 s->len = len;
2168 static void tok_str_add2(TokenString *s, int t, CValue *cv)
2170 int len, *str;
2172 len = s->len;
2173 str = s->str;
2175 /* allocate space for worst case */
2176 if (len + TOK_MAX_SIZE > s->allocated_len)
2177 str = tok_str_realloc(s);
2178 str[len++] = t;
2179 switch(t) {
2180 case TOK_CINT:
2181 case TOK_CUINT:
2182 case TOK_CCHAR:
2183 case TOK_LCHAR:
2184 case TOK_CFLOAT:
2185 case TOK_LINENUM:
2186 str[len++] = cv->tab[0];
2187 break;
2188 case TOK_PPNUM:
2189 case TOK_STR:
2190 case TOK_LSTR:
2191 str[len++] = (int)cstr_dup(cv->cstr);
2192 break;
2193 case TOK_CDOUBLE:
2194 case TOK_CLLONG:
2195 case TOK_CULLONG:
2196 str[len++] = cv->tab[0];
2197 str[len++] = cv->tab[1];
2198 break;
2199 case TOK_CLDOUBLE:
2200 #if LDOUBLE_SIZE == 12
2201 str[len++] = cv->tab[0];
2202 str[len++] = cv->tab[1];
2203 str[len++] = cv->tab[2];
2204 #else
2205 #error add long double size support
2206 #endif
2207 break;
2208 default:
2209 break;
2211 s->len = len;
2214 /* add the current parse token in token string 's' */
2215 static void tok_str_add_tok(TokenString *s)
2217 CValue cval;
2219 /* save line number info */
2220 if (file->line_num != s->last_line_num) {
2221 s->last_line_num = file->line_num;
2222 cval.i = s->last_line_num;
2223 tok_str_add2(s, TOK_LINENUM, &cval);
2225 tok_str_add2(s, tok, &tokc);
2228 #if LDOUBLE_SIZE == 12
2229 #define LDOUBLE_GET(p, cv) \
2230 cv.tab[0] = p[0]; \
2231 cv.tab[1] = p[1]; \
2232 cv.tab[2] = p[2];
2233 #else
2234 #error add long double size support
2235 #endif
2238 /* get a token from an integer array and increment pointer
2239 accordingly. we code it as a macro to avoid pointer aliasing. */
2240 #define TOK_GET(t, p, cv) \
2242 t = *p++; \
2243 switch(t) { \
2244 case TOK_CINT: \
2245 case TOK_CUINT: \
2246 case TOK_CCHAR: \
2247 case TOK_LCHAR: \
2248 case TOK_CFLOAT: \
2249 case TOK_LINENUM: \
2250 case TOK_STR: \
2251 case TOK_LSTR: \
2252 case TOK_PPNUM: \
2253 cv.tab[0] = *p++; \
2254 break; \
2255 case TOK_CDOUBLE: \
2256 case TOK_CLLONG: \
2257 case TOK_CULLONG: \
2258 cv.tab[0] = p[0]; \
2259 cv.tab[1] = p[1]; \
2260 p += 2; \
2261 break; \
2262 case TOK_CLDOUBLE: \
2263 LDOUBLE_GET(p, cv); \
2264 p += LDOUBLE_SIZE / 4; \
2265 break; \
2266 default: \
2267 break; \
2271 /* defines handling */
2272 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
2274 Sym *s;
2276 s = sym_push2(&define_stack, v, macro_type, (int)str);
2277 s->next = first_arg;
2278 table_ident[v - TOK_IDENT]->sym_define = s;
2281 /* undefined a define symbol. Its name is just set to zero */
2282 static void define_undef(Sym *s)
2284 int v;
2285 v = s->v;
2286 if (v >= TOK_IDENT && v < tok_ident)
2287 table_ident[v - TOK_IDENT]->sym_define = NULL;
2288 s->v = 0;
2291 static inline Sym *define_find(int v)
2293 v -= TOK_IDENT;
2294 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2295 return NULL;
2296 return table_ident[v]->sym_define;
2299 /* free define stack until top reaches 'b' */
2300 static void free_defines(Sym *b)
2302 Sym *top, *top1;
2303 int v;
2305 top = define_stack;
2306 while (top != b) {
2307 top1 = top->prev;
2308 /* do not free args or predefined defines */
2309 if (top->c)
2310 tok_str_free((int *)top->c);
2311 v = top->v;
2312 if (v >= TOK_IDENT && v < tok_ident)
2313 table_ident[v - TOK_IDENT]->sym_define = NULL;
2314 tcc_free(top);
2315 top = top1;
2317 define_stack = b;
2320 /* label lookup */
2321 static Sym *label_find(int v)
2323 v -= TOK_IDENT;
2324 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2325 return NULL;
2326 return table_ident[v]->sym_label;
2329 static Sym *label_push(Sym **ptop, int v, int flags)
2331 Sym *s, **ps;
2332 s = sym_push2(ptop, v, 0, 0);
2333 s->r = flags;
2334 ps = &table_ident[v - TOK_IDENT]->sym_label;
2335 if (ptop == &global_label_stack) {
2336 /* modify the top most local identifier, so that
2337 sym_identifier will point to 's' when popped */
2338 while (*ps != NULL)
2339 ps = &(*ps)->prev_tok;
2341 s->prev_tok = *ps;
2342 *ps = s;
2343 return s;
2346 /* pop labels until element last is reached. Look if any labels are
2347 undefined. Define symbols if '&&label' was used. */
2348 static void label_pop(Sym **ptop, Sym *slast)
2350 Sym *s, *s1;
2351 for(s = *ptop; s != slast; s = s1) {
2352 s1 = s->prev;
2353 if (s->r == LABEL_DECLARED) {
2354 warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
2355 } else if (s->r == LABEL_FORWARD) {
2356 error("label '%s' used but not defined",
2357 get_tok_str(s->v, NULL));
2358 } else {
2359 if (s->c) {
2360 /* define corresponding symbol. A size of
2361 1 is put. */
2362 put_extern_sym(s, cur_text_section, (long)s->next, 1);
2365 /* remove label */
2366 table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
2367 tcc_free(s);
2369 *ptop = slast;
2372 /* eval an expression for #if/#elif */
2373 static int expr_preprocess(void)
2375 int c, t;
2376 TokenString str;
2378 tok_str_new(&str);
2379 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2380 next(); /* do macro subst */
2381 if (tok == TOK_DEFINED) {
2382 next_nomacro();
2383 t = tok;
2384 if (t == '(')
2385 next_nomacro();
2386 c = define_find(tok) != 0;
2387 if (t == '(')
2388 next_nomacro();
2389 tok = TOK_CINT;
2390 tokc.i = c;
2391 } else if (tok >= TOK_IDENT) {
2392 /* if undefined macro */
2393 tok = TOK_CINT;
2394 tokc.i = 0;
2396 tok_str_add_tok(&str);
2398 tok_str_add(&str, -1); /* simulate end of file */
2399 tok_str_add(&str, 0);
2400 /* now evaluate C constant expression */
2401 macro_ptr = str.str;
2402 next();
2403 c = expr_const();
2404 macro_ptr = NULL;
2405 tok_str_free(str.str);
2406 return c != 0;
2409 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2410 static void tok_print(int *str)
2412 int t;
2413 CValue cval;
2415 while (1) {
2416 TOK_GET(t, str, cval);
2417 if (!t)
2418 break;
2419 printf(" %s", get_tok_str(t, &cval));
2421 printf("\n");
2423 #endif
2425 /* parse after #define */
2426 static void parse_define(void)
2428 Sym *s, *first, **ps;
2429 int v, t, varg, is_vaargs, c;
2430 TokenString str;
2432 v = tok;
2433 if (v < TOK_IDENT)
2434 error("invalid macro name '%s'", get_tok_str(tok, &tokc));
2435 /* XXX: should check if same macro (ANSI) */
2436 first = NULL;
2437 t = MACRO_OBJ;
2438 /* '(' must be just after macro definition for MACRO_FUNC */
2439 c = file->buf_ptr[0];
2440 if (c == '\\')
2441 c = handle_stray1(file->buf_ptr);
2442 if (c == '(') {
2443 next_nomacro();
2444 next_nomacro();
2445 ps = &first;
2446 while (tok != ')') {
2447 varg = tok;
2448 next_nomacro();
2449 is_vaargs = 0;
2450 if (varg == TOK_DOTS) {
2451 varg = TOK___VA_ARGS__;
2452 is_vaargs = 1;
2453 } else if (tok == TOK_DOTS && gnu_ext) {
2454 is_vaargs = 1;
2455 next_nomacro();
2457 if (varg < TOK_IDENT)
2458 error("badly punctuated parameter list");
2459 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
2460 *ps = s;
2461 ps = &s->next;
2462 if (tok != ',')
2463 break;
2464 next_nomacro();
2466 t = MACRO_FUNC;
2468 tok_str_new(&str);
2469 next_nomacro();
2470 /* EOF testing necessary for '-D' handling */
2471 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2472 tok_str_add2(&str, tok, &tokc);
2473 next_nomacro();
2475 tok_str_add(&str, 0);
2476 #ifdef PP_DEBUG
2477 printf("define %s %d: ", get_tok_str(v, NULL), t);
2478 tok_print(str.str);
2479 #endif
2480 define_push(v, t, str.str, first);
2483 /* XXX: use a token or a hash table to accelerate matching ? */
2484 static CachedInclude *search_cached_include(TCCState *s1,
2485 int type, const char *filename)
2487 CachedInclude *e;
2488 int i;
2490 for(i = 0;i < s1->nb_cached_includes; i++) {
2491 e = s1->cached_includes[i];
2492 if (e->type == type && !strcmp(e->filename, filename))
2493 return e;
2495 return NULL;
2498 static inline void add_cached_include(TCCState *s1, int type,
2499 const char *filename, int ifndef_macro)
2501 CachedInclude *e;
2503 if (search_cached_include(s1, type, filename))
2504 return;
2505 #ifdef INC_DEBUG
2506 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
2507 #endif
2508 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
2509 if (!e)
2510 return;
2511 e->type = type;
2512 strcpy(e->filename, filename);
2513 e->ifndef_macro = ifndef_macro;
2514 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
2517 /* is_bof is true if first non space token at beginning of file */
2518 static void preprocess(int is_bof)
2520 TCCState *s1 = tcc_state;
2521 int size, i, c, n, saved_parse_flags;
2522 char buf[1024], *q, *p;
2523 char buf1[1024];
2524 BufferedFile *f;
2525 Sym *s;
2526 CachedInclude *e;
2528 saved_parse_flags = parse_flags;
2529 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
2530 PARSE_FLAG_LINEFEED;
2531 next_nomacro();
2532 redo:
2533 switch(tok) {
2534 case TOK_DEFINE:
2535 next_nomacro();
2536 parse_define();
2537 break;
2538 case TOK_UNDEF:
2539 next_nomacro();
2540 s = define_find(tok);
2541 /* undefine symbol by putting an invalid name */
2542 if (s)
2543 define_undef(s);
2544 break;
2545 case TOK_INCLUDE:
2546 ch = file->buf_ptr[0];
2547 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2548 skip_spaces();
2549 if (ch == '<') {
2550 c = '>';
2551 goto read_name;
2552 } else if (ch == '\"') {
2553 c = ch;
2554 read_name:
2555 /* XXX: better stray handling */
2556 minp();
2557 q = buf;
2558 while (ch != c && ch != '\n' && ch != CH_EOF) {
2559 if ((q - buf) < sizeof(buf) - 1)
2560 *q++ = ch;
2561 minp();
2563 *q = '\0';
2564 minp();
2565 #if 0
2566 /* eat all spaces and comments after include */
2567 /* XXX: slightly incorrect */
2568 while (ch1 != '\n' && ch1 != CH_EOF)
2569 inp();
2570 #endif
2571 } else {
2572 /* computed #include : either we have only strings or
2573 we have anything enclosed in '<>' */
2574 next();
2575 buf[0] = '\0';
2576 if (tok == TOK_STR) {
2577 while (tok != TOK_LINEFEED) {
2578 if (tok != TOK_STR) {
2579 include_syntax:
2580 error("'#include' expects \"FILENAME\" or <FILENAME>");
2582 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2583 next();
2585 c = '\"';
2586 } else {
2587 int len;
2588 while (tok != TOK_LINEFEED) {
2589 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2590 next();
2592 len = strlen(buf);
2593 /* check syntax and remove '<>' */
2594 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2595 goto include_syntax;
2596 memmove(buf, buf + 1, len - 2);
2597 buf[len - 2] = '\0';
2598 c = '>';
2602 e = search_cached_include(s1, c, buf);
2603 if (e && define_find(e->ifndef_macro)) {
2604 /* no need to parse the include because the 'ifndef macro'
2605 is defined */
2606 #ifdef INC_DEBUG
2607 printf("%s: skipping %s\n", file->filename, buf);
2608 #endif
2609 } else {
2610 if (c == '\"') {
2611 /* first search in current dir if "header.h" */
2612 size = 0;
2613 p = strrchr(file->filename, '/');
2614 if (p)
2615 size = p + 1 - file->filename;
2616 if (size > sizeof(buf1) - 1)
2617 size = sizeof(buf1) - 1;
2618 memcpy(buf1, file->filename, size);
2619 buf1[size] = '\0';
2620 pstrcat(buf1, sizeof(buf1), buf);
2621 f = tcc_open(s1, buf1);
2622 if (f)
2623 goto found;
2625 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2626 error("#include recursion too deep");
2627 /* now search in all the include paths */
2628 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2629 for(i = 0; i < n; i++) {
2630 const char *path;
2631 if (i < s1->nb_include_paths)
2632 path = s1->include_paths[i];
2633 else
2634 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2635 pstrcpy(buf1, sizeof(buf1), path);
2636 pstrcat(buf1, sizeof(buf1), "/");
2637 pstrcat(buf1, sizeof(buf1), buf);
2638 f = tcc_open(s1, buf1);
2639 if (f)
2640 goto found;
2642 error("include file '%s' not found", buf);
2643 f = NULL;
2644 found:
2645 #ifdef INC_DEBUG
2646 printf("%s: including %s\n", file->filename, buf1);
2647 #endif
2648 f->inc_type = c;
2649 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2650 /* push current file in stack */
2651 /* XXX: fix current line init */
2652 *s1->include_stack_ptr++ = file;
2653 file = f;
2654 /* add include file debug info */
2655 if (do_debug) {
2656 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2658 tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
2659 ch = file->buf_ptr[0];
2660 goto the_end;
2662 break;
2663 case TOK_IFNDEF:
2664 c = 1;
2665 goto do_ifdef;
2666 case TOK_IF:
2667 c = expr_preprocess();
2668 goto do_if;
2669 case TOK_IFDEF:
2670 c = 0;
2671 do_ifdef:
2672 next_nomacro();
2673 if (tok < TOK_IDENT)
2674 error("invalid argument for '#if%sdef'", c ? "n" : "");
2675 if (is_bof) {
2676 if (c) {
2677 #ifdef INC_DEBUG
2678 printf("#ifndef %s\n", get_tok_str(tok, NULL));
2679 #endif
2680 file->ifndef_macro = tok;
2683 c = (define_find(tok) != 0) ^ c;
2684 do_if:
2685 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2686 error("memory full");
2687 *s1->ifdef_stack_ptr++ = c;
2688 goto test_skip;
2689 case TOK_ELSE:
2690 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2691 error("#else without matching #if");
2692 if (s1->ifdef_stack_ptr[-1] & 2)
2693 error("#else after #else");
2694 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2695 goto test_skip;
2696 case TOK_ELIF:
2697 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2698 error("#elif without matching #if");
2699 c = s1->ifdef_stack_ptr[-1];
2700 if (c > 1)
2701 error("#elif after #else");
2702 /* last #if/#elif expression was true: we skip */
2703 if (c == 1)
2704 goto skip;
2705 c = expr_preprocess();
2706 s1->ifdef_stack_ptr[-1] = c;
2707 test_skip:
2708 if (!(c & 1)) {
2709 skip:
2710 preprocess_skip();
2711 is_bof = 0;
2712 goto redo;
2714 break;
2715 case TOK_ENDIF:
2716 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2717 error("#endif without matching #if");
2718 s1->ifdef_stack_ptr--;
2719 /* '#ifndef macro' was at the start of file. Now we check if
2720 an '#endif' is exactly at the end of file */
2721 if (file->ifndef_macro &&
2722 s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
2723 file->ifndef_macro_saved = file->ifndef_macro;
2724 /* need to set to zero to avoid false matches if another
2725 #ifndef at middle of file */
2726 file->ifndef_macro = 0;
2727 while (tok != TOK_LINEFEED)
2728 next_nomacro();
2729 tok_flags |= TOK_FLAG_ENDIF;
2730 goto the_end;
2732 break;
2733 case TOK_LINE:
2734 next();
2735 if (tok != TOK_CINT)
2736 error("#line");
2737 file->line_num = tokc.i - 1; /* the line number will be incremented after */
2738 next();
2739 if (tok != TOK_LINEFEED) {
2740 if (tok != TOK_STR)
2741 error("#line");
2742 pstrcpy(file->filename, sizeof(file->filename),
2743 (char *)tokc.cstr->data);
2745 break;
2746 case TOK_ERROR:
2747 case TOK_WARNING:
2748 c = tok;
2749 ch = file->buf_ptr[0];
2750 skip_spaces();
2751 q = buf;
2752 while (ch != '\n' && ch != CH_EOF) {
2753 if ((q - buf) < sizeof(buf) - 1)
2754 *q++ = ch;
2755 minp();
2757 *q = '\0';
2758 if (c == TOK_ERROR)
2759 error("#error %s", buf);
2760 else
2761 warning("#warning %s", buf);
2762 break;
2763 case TOK_PRAGMA:
2764 /* ignored */
2765 break;
2766 default:
2767 if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
2768 /* '!' is ignored to allow C scripts. numbers are ignored
2769 to emulate cpp behaviour */
2770 } else {
2771 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
2773 break;
2775 /* ignore other preprocess commands or #! for C scripts */
2776 while (tok != TOK_LINEFEED)
2777 next_nomacro();
2778 the_end:
2779 parse_flags = saved_parse_flags;
2782 /* evaluate escape codes in a string. */
2783 static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
2785 int c, n;
2786 const char *p;
2788 p = buf;
2789 for(;;) {
2790 c = *p;
2791 if (c == '\0')
2792 break;
2793 if (c == '\\') {
2794 p++;
2795 /* escape */
2796 c = *p;
2797 switch(c) {
2798 case '0': case '1': case '2': case '3':
2799 case '4': case '5': case '6': case '7':
2800 /* at most three octal digits */
2801 n = c - '0';
2802 p++;
2803 c = *p;
2804 if (isoct(c)) {
2805 n = n * 8 + c - '0';
2806 p++;
2807 c = *p;
2808 if (isoct(c)) {
2809 n = n * 8 + c - '0';
2810 p++;
2813 c = n;
2814 goto add_char_nonext;
2815 case 'x':
2816 p++;
2817 n = 0;
2818 for(;;) {
2819 c = *p;
2820 if (c >= 'a' && c <= 'f')
2821 c = c - 'a' + 10;
2822 else if (c >= 'A' && c <= 'F')
2823 c = c - 'A' + 10;
2824 else if (isnum(c))
2825 c = c - '0';
2826 else
2827 break;
2828 n = n * 16 + c;
2829 p++;
2831 c = n;
2832 goto add_char_nonext;
2833 case 'a':
2834 c = '\a';
2835 break;
2836 case 'b':
2837 c = '\b';
2838 break;
2839 case 'f':
2840 c = '\f';
2841 break;
2842 case 'n':
2843 c = '\n';
2844 break;
2845 case 'r':
2846 c = '\r';
2847 break;
2848 case 't':
2849 c = '\t';
2850 break;
2851 case 'v':
2852 c = '\v';
2853 break;
2854 case 'e':
2855 if (!gnu_ext)
2856 goto invalid_escape;
2857 c = 27;
2858 break;
2859 case '\'':
2860 case '\"':
2861 case '\\':
2862 case '?':
2863 break;
2864 default:
2865 invalid_escape:
2866 error("invalid escaped char");
2869 p++;
2870 add_char_nonext:
2871 if (!is_long)
2872 cstr_ccat(outstr, c);
2873 else
2874 cstr_wccat(outstr, c);
2876 /* add a trailing '\0' */
2877 if (!is_long)
2878 cstr_ccat(outstr, '\0');
2879 else
2880 cstr_wccat(outstr, '\0');
2883 /* we use 64 bit numbers */
2884 #define BN_SIZE 2
2886 /* bn = (bn << shift) | or_val */
2887 void bn_lshift(unsigned int *bn, int shift, int or_val)
2889 int i;
2890 unsigned int v;
2891 for(i=0;i<BN_SIZE;i++) {
2892 v = bn[i];
2893 bn[i] = (v << shift) | or_val;
2894 or_val = v >> (32 - shift);
2898 void bn_zero(unsigned int *bn)
2900 int i;
2901 for(i=0;i<BN_SIZE;i++) {
2902 bn[i] = 0;
2906 /* parse number in null terminated string 'p' and return it in the
2907 current token */
2908 void parse_number(const char *p)
2910 int b, t, shift, frac_bits, s, exp_val, ch;
2911 char *q;
2912 unsigned int bn[BN_SIZE];
2913 double d;
2915 /* number */
2916 q = token_buf;
2917 ch = *p++;
2918 t = ch;
2919 ch = *p++;
2920 *q++ = t;
2921 b = 10;
2922 if (t == '.') {
2923 goto float_frac_parse;
2924 } else if (t == '0') {
2925 if (ch == 'x' || ch == 'X') {
2926 q--;
2927 ch = *p++;
2928 b = 16;
2929 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2930 q--;
2931 ch = *p++;
2932 b = 2;
2935 /* parse all digits. cannot check octal numbers at this stage
2936 because of floating point constants */
2937 while (1) {
2938 if (ch >= 'a' && ch <= 'f')
2939 t = ch - 'a' + 10;
2940 else if (ch >= 'A' && ch <= 'F')
2941 t = ch - 'A' + 10;
2942 else if (isnum(ch))
2943 t = ch - '0';
2944 else
2945 break;
2946 if (t >= b)
2947 break;
2948 if (q >= token_buf + STRING_MAX_SIZE) {
2949 num_too_long:
2950 error("number too long");
2952 *q++ = ch;
2953 ch = *p++;
2955 if (ch == '.' ||
2956 ((ch == 'e' || ch == 'E') && b == 10) ||
2957 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2958 if (b != 10) {
2959 /* NOTE: strtox should support that for hexa numbers, but
2960 non ISOC99 libcs do not support it, so we prefer to do
2961 it by hand */
2962 /* hexadecimal or binary floats */
2963 /* XXX: handle overflows */
2964 *q = '\0';
2965 if (b == 16)
2966 shift = 4;
2967 else
2968 shift = 2;
2969 bn_zero(bn);
2970 q = token_buf;
2971 while (1) {
2972 t = *q++;
2973 if (t == '\0') {
2974 break;
2975 } else if (t >= 'a') {
2976 t = t - 'a' + 10;
2977 } else if (t >= 'A') {
2978 t = t - 'A' + 10;
2979 } else {
2980 t = t - '0';
2982 bn_lshift(bn, shift, t);
2984 frac_bits = 0;
2985 if (ch == '.') {
2986 ch = *p++;
2987 while (1) {
2988 t = ch;
2989 if (t >= 'a' && t <= 'f') {
2990 t = t - 'a' + 10;
2991 } else if (t >= 'A' && t <= 'F') {
2992 t = t - 'A' + 10;
2993 } else if (t >= '0' && t <= '9') {
2994 t = t - '0';
2995 } else {
2996 break;
2998 if (t >= b)
2999 error("invalid digit");
3000 bn_lshift(bn, shift, t);
3001 frac_bits += shift;
3002 ch = *p++;
3005 if (ch != 'p' && ch != 'P')
3006 expect("exponent");
3007 ch = *p++;
3008 s = 1;
3009 exp_val = 0;
3010 if (ch == '+') {
3011 ch = *p++;
3012 } else if (ch == '-') {
3013 s = -1;
3014 ch = *p++;
3016 if (ch < '0' || ch > '9')
3017 expect("exponent digits");
3018 while (ch >= '0' && ch <= '9') {
3019 exp_val = exp_val * 10 + ch - '0';
3020 ch = *p++;
3022 exp_val = exp_val * s;
3024 /* now we can generate the number */
3025 /* XXX: should patch directly float number */
3026 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
3027 d = ldexp(d, exp_val - frac_bits);
3028 t = toup(ch);
3029 if (t == 'F') {
3030 ch = *p++;
3031 tok = TOK_CFLOAT;
3032 /* float : should handle overflow */
3033 tokc.f = (float)d;
3034 } else if (t == 'L') {
3035 ch = *p++;
3036 tok = TOK_CLDOUBLE;
3037 /* XXX: not large enough */
3038 tokc.ld = (long double)d;
3039 } else {
3040 tok = TOK_CDOUBLE;
3041 tokc.d = d;
3043 } else {
3044 /* decimal floats */
3045 if (ch == '.') {
3046 if (q >= token_buf + STRING_MAX_SIZE)
3047 goto num_too_long;
3048 *q++ = ch;
3049 ch = *p++;
3050 float_frac_parse:
3051 while (ch >= '0' && ch <= '9') {
3052 if (q >= token_buf + STRING_MAX_SIZE)
3053 goto num_too_long;
3054 *q++ = ch;
3055 ch = *p++;
3058 if (ch == 'e' || ch == 'E') {
3059 if (q >= token_buf + STRING_MAX_SIZE)
3060 goto num_too_long;
3061 *q++ = ch;
3062 ch = *p++;
3063 if (ch == '-' || ch == '+') {
3064 if (q >= token_buf + STRING_MAX_SIZE)
3065 goto num_too_long;
3066 *q++ = ch;
3067 ch = *p++;
3069 if (ch < '0' || ch > '9')
3070 expect("exponent digits");
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 *q = '\0';
3079 t = toup(ch);
3080 errno = 0;
3081 if (t == 'F') {
3082 ch = *p++;
3083 tok = TOK_CFLOAT;
3084 tokc.f = strtof(token_buf, NULL);
3085 } else if (t == 'L') {
3086 ch = *p++;
3087 tok = TOK_CLDOUBLE;
3088 tokc.ld = strtold(token_buf, NULL);
3089 } else {
3090 tok = TOK_CDOUBLE;
3091 tokc.d = strtod(token_buf, NULL);
3094 } else {
3095 unsigned long long n, n1;
3096 int lcount, ucount;
3098 /* integer number */
3099 *q = '\0';
3100 q = token_buf;
3101 if (b == 10 && *q == '0') {
3102 b = 8;
3103 q++;
3105 n = 0;
3106 while(1) {
3107 t = *q++;
3108 /* no need for checks except for base 10 / 8 errors */
3109 if (t == '\0') {
3110 break;
3111 } else if (t >= 'a') {
3112 t = t - 'a' + 10;
3113 } else if (t >= 'A') {
3114 t = t - 'A' + 10;
3115 } else {
3116 t = t - '0';
3117 if (t >= b)
3118 error("invalid digit");
3120 n1 = n;
3121 n = n * b + t;
3122 /* detect overflow */
3123 /* XXX: this test is not reliable */
3124 if (n < n1)
3125 error("integer constant overflow");
3128 /* XXX: not exactly ANSI compliant */
3129 if ((n & 0xffffffff00000000LL) != 0) {
3130 if ((n >> 63) != 0)
3131 tok = TOK_CULLONG;
3132 else
3133 tok = TOK_CLLONG;
3134 } else if (n > 0x7fffffff) {
3135 tok = TOK_CUINT;
3136 } else {
3137 tok = TOK_CINT;
3139 lcount = 0;
3140 ucount = 0;
3141 for(;;) {
3142 t = toup(ch);
3143 if (t == 'L') {
3144 if (lcount >= 2)
3145 error("three 'l's in integer constant");
3146 lcount++;
3147 if (lcount == 2) {
3148 if (tok == TOK_CINT)
3149 tok = TOK_CLLONG;
3150 else if (tok == TOK_CUINT)
3151 tok = TOK_CULLONG;
3153 ch = *p++;
3154 } else if (t == 'U') {
3155 if (ucount >= 1)
3156 error("two 'u's in integer constant");
3157 ucount++;
3158 if (tok == TOK_CINT)
3159 tok = TOK_CUINT;
3160 else if (tok == TOK_CLLONG)
3161 tok = TOK_CULLONG;
3162 ch = *p++;
3163 } else {
3164 break;
3167 if (tok == TOK_CINT || tok == TOK_CUINT)
3168 tokc.ui = n;
3169 else
3170 tokc.ull = n;
3175 #define PARSE2(c1, tok1, c2, tok2) \
3176 case c1: \
3177 PEEKC(c, p); \
3178 if (c == c2) { \
3179 p++; \
3180 tok = tok2; \
3181 } else { \
3182 tok = tok1; \
3184 break;
3186 /* return next token without macro substitution */
3187 static inline void next_nomacro1(void)
3189 int t, c, is_long;
3190 TokenSym *ts;
3191 uint8_t *p, *p1;
3192 unsigned int h;
3194 p = file->buf_ptr;
3195 redo_no_start:
3196 c = *p;
3197 switch(c) {
3198 case ' ':
3199 case '\t':
3200 case '\f':
3201 case '\v':
3202 case '\r':
3203 p++;
3204 goto redo_no_start;
3206 case '\\':
3207 /* first look if it is in fact an end of buffer */
3208 if (p >= file->buf_end) {
3209 file->buf_ptr = p;
3210 handle_eob();
3211 p = file->buf_ptr;
3212 if (p >= file->buf_end)
3213 goto parse_eof;
3214 else
3215 goto redo_no_start;
3216 } else {
3217 file->buf_ptr = p;
3218 ch = *p;
3219 handle_stray();
3220 p = file->buf_ptr;
3221 goto redo_no_start;
3223 parse_eof:
3225 TCCState *s1 = tcc_state;
3226 if (parse_flags & PARSE_FLAG_LINEFEED) {
3227 tok = TOK_LINEFEED;
3228 } else if (s1->include_stack_ptr == s1->include_stack ||
3229 !(parse_flags & PARSE_FLAG_PREPROCESS)) {
3230 /* no include left : end of file. */
3231 tok = TOK_EOF;
3232 } else {
3233 /* pop include file */
3235 /* test if previous '#endif' was after a #ifdef at
3236 start of file */
3237 if (tok_flags & TOK_FLAG_ENDIF) {
3238 #ifdef INC_DEBUG
3239 printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
3240 #endif
3241 add_cached_include(s1, file->inc_type, file->inc_filename,
3242 file->ifndef_macro_saved);
3245 /* add end of include file debug info */
3246 if (do_debug) {
3247 put_stabd(N_EINCL, 0, 0);
3249 /* pop include stack */
3250 tcc_close(file);
3251 s1->include_stack_ptr--;
3252 file = *s1->include_stack_ptr;
3253 p = file->buf_ptr;
3254 goto redo_no_start;
3257 break;
3259 case '\n':
3260 if (parse_flags & PARSE_FLAG_LINEFEED) {
3261 tok = TOK_LINEFEED;
3262 } else {
3263 file->line_num++;
3264 tok_flags |= TOK_FLAG_BOL;
3265 p++;
3266 goto redo_no_start;
3268 break;
3270 case '#':
3271 /* XXX: simplify */
3272 PEEKC(c, p);
3273 if ((tok_flags & TOK_FLAG_BOL) &&
3274 (parse_flags & PARSE_FLAG_PREPROCESS)) {
3275 file->buf_ptr = p;
3276 preprocess(tok_flags & TOK_FLAG_BOF);
3277 p = file->buf_ptr;
3278 goto redo_no_start;
3279 } else {
3280 if (c == '#') {
3281 p++;
3282 tok = TOK_TWOSHARPS;
3283 } else {
3284 tok = '#';
3287 break;
3289 case 'a': case 'b': case 'c': case 'd':
3290 case 'e': case 'f': case 'g': case 'h':
3291 case 'i': case 'j': case 'k': case 'l':
3292 case 'm': case 'n': case 'o': case 'p':
3293 case 'q': case 'r': case 's': case 't':
3294 case 'u': case 'v': case 'w': case 'x':
3295 case 'y': case 'z':
3296 case 'A': case 'B': case 'C': case 'D':
3297 case 'E': case 'F': case 'G': case 'H':
3298 case 'I': case 'J': case 'K':
3299 case 'M': case 'N': case 'O': case 'P':
3300 case 'Q': case 'R': case 'S': case 'T':
3301 case 'U': case 'V': case 'W': case 'X':
3302 case 'Y': case 'Z':
3303 case '_':
3304 parse_ident_fast:
3305 p1 = p;
3306 h = TOK_HASH_INIT;
3307 h = TOK_HASH_FUNC(h, c);
3308 p++;
3309 for(;;) {
3310 c = *p;
3311 if (!isidnum_table[c])
3312 break;
3313 h = TOK_HASH_FUNC(h, c);
3314 p++;
3316 if (c != '\\') {
3317 TokenSym **pts;
3318 int len;
3320 /* fast case : no stray found, so we have the full token
3321 and we have already hashed it */
3322 len = p - p1;
3323 h &= (TOK_HASH_SIZE - 1);
3324 pts = &hash_ident[h];
3325 for(;;) {
3326 ts = *pts;
3327 if (!ts)
3328 break;
3329 if (ts->len == len && !memcmp(ts->str, p1, len))
3330 goto token_found;
3331 pts = &(ts->hash_next);
3333 ts = tok_alloc_new(pts, p1, len);
3334 token_found: ;
3335 } else {
3336 /* slower case */
3337 cstr_reset(&tokcstr);
3339 while (p1 < p) {
3340 cstr_ccat(&tokcstr, *p1);
3341 p1++;
3343 p--;
3344 PEEKC(c, p);
3345 parse_ident_slow:
3346 while (isidnum_table[c]) {
3347 cstr_ccat(&tokcstr, c);
3348 PEEKC(c, p);
3350 ts = tok_alloc(tokcstr.data, tokcstr.size);
3352 tok = ts->tok;
3353 break;
3354 case 'L':
3355 t = p[1];
3356 if (t != '\\' && t != '\'' && t != '\"') {
3357 /* fast case */
3358 goto parse_ident_fast;
3359 } else {
3360 PEEKC(c, p);
3361 if (c == '\'' || c == '\"') {
3362 is_long = 1;
3363 goto str_const;
3364 } else {
3365 cstr_reset(&tokcstr);
3366 cstr_ccat(&tokcstr, 'L');
3367 goto parse_ident_slow;
3370 break;
3371 case '0': case '1': case '2': case '3':
3372 case '4': case '5': case '6': case '7':
3373 case '8': case '9':
3375 cstr_reset(&tokcstr);
3376 /* after the first digit, accept digits, alpha, '.' or sign if
3377 prefixed by 'eEpP' */
3378 parse_num:
3379 for(;;) {
3380 t = c;
3381 cstr_ccat(&tokcstr, c);
3382 PEEKC(c, p);
3383 if (!(isnum(c) || isid(c) || c == '.' ||
3384 ((c == '+' || c == '-') &&
3385 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
3386 break;
3388 /* We add a trailing '\0' to ease parsing */
3389 cstr_ccat(&tokcstr, '\0');
3390 tokc.cstr = &tokcstr;
3391 tok = TOK_PPNUM;
3392 break;
3393 case '.':
3394 /* special dot handling because it can also start a number */
3395 PEEKC(c, p);
3396 if (isnum(c)) {
3397 cstr_reset(&tokcstr);
3398 cstr_ccat(&tokcstr, '.');
3399 goto parse_num;
3400 } else if (c == '.') {
3401 PEEKC(c, p);
3402 if (c != '.')
3403 expect("'.'");
3404 PEEKC(c, p);
3405 tok = TOK_DOTS;
3406 } else {
3407 tok = '.';
3409 break;
3410 case '\'':
3411 case '\"':
3412 is_long = 0;
3413 str_const:
3415 CString str;
3416 int sep;
3418 sep = c;
3420 /* parse the string */
3421 cstr_new(&str);
3422 p = parse_pp_string(p, sep, &str);
3423 cstr_ccat(&str, '\0');
3425 /* eval the escape (should be done as TOK_PPNUM) */
3426 cstr_reset(&tokcstr);
3427 parse_escape_string(&tokcstr, str.data, is_long);
3428 cstr_free(&str);
3430 if (sep == '\'') {
3431 int char_size;
3432 /* XXX: make it portable */
3433 if (!is_long)
3434 char_size = 1;
3435 else
3436 char_size = sizeof(int);
3437 if (tokcstr.size <= char_size)
3438 error("empty character constant");
3439 if (tokcstr.size > 2 * char_size)
3440 warning("multi-character character constant");
3441 if (!is_long) {
3442 tokc.i = *(int8_t *)tokcstr.data;
3443 tok = TOK_CCHAR;
3444 } else {
3445 tokc.i = *(int *)tokcstr.data;
3446 tok = TOK_LCHAR;
3448 } else {
3449 tokc.cstr = &tokcstr;
3450 if (!is_long)
3451 tok = TOK_STR;
3452 else
3453 tok = TOK_LSTR;
3456 break;
3458 case '<':
3459 PEEKC(c, p);
3460 if (c == '=') {
3461 p++;
3462 tok = TOK_LE;
3463 } else if (c == '<') {
3464 PEEKC(c, p);
3465 if (c == '=') {
3466 p++;
3467 tok = TOK_A_SHL;
3468 } else {
3469 tok = TOK_SHL;
3471 } else {
3472 tok = TOK_LT;
3474 break;
3476 case '>':
3477 PEEKC(c, p);
3478 if (c == '=') {
3479 p++;
3480 tok = TOK_GE;
3481 } else if (c == '>') {
3482 PEEKC(c, p);
3483 if (c == '=') {
3484 p++;
3485 tok = TOK_A_SAR;
3486 } else {
3487 tok = TOK_SAR;
3489 } else {
3490 tok = TOK_GT;
3492 break;
3494 case '&':
3495 PEEKC(c, p);
3496 if (c == '&') {
3497 p++;
3498 tok = TOK_LAND;
3499 } else if (c == '=') {
3500 p++;
3501 tok = TOK_A_AND;
3502 } else {
3503 tok = '&';
3505 break;
3507 case '|':
3508 PEEKC(c, p);
3509 if (c == '|') {
3510 p++;
3511 tok = TOK_LOR;
3512 } else if (c == '=') {
3513 p++;
3514 tok = TOK_A_OR;
3515 } else {
3516 tok = '|';
3518 break;
3520 case '+':
3521 PEEKC(c, p);
3522 if (c == '+') {
3523 p++;
3524 tok = TOK_INC;
3525 } else if (c == '=') {
3526 p++;
3527 tok = TOK_A_ADD;
3528 } else {
3529 tok = '+';
3531 break;
3533 case '-':
3534 PEEKC(c, p);
3535 if (c == '-') {
3536 p++;
3537 tok = TOK_DEC;
3538 } else if (c == '=') {
3539 p++;
3540 tok = TOK_A_SUB;
3541 } else if (c == '>') {
3542 p++;
3543 tok = TOK_ARROW;
3544 } else {
3545 tok = '-';
3547 break;
3549 PARSE2('!', '!', '=', TOK_NE)
3550 PARSE2('=', '=', '=', TOK_EQ)
3551 PARSE2('*', '*', '=', TOK_A_MUL)
3552 PARSE2('%', '%', '=', TOK_A_MOD)
3553 PARSE2('^', '^', '=', TOK_A_XOR)
3555 /* comments or operator */
3556 case '/':
3557 PEEKC(c, p);
3558 if (c == '*') {
3559 p = parse_comment(p);
3560 goto redo_no_start;
3561 } else if (c == '/') {
3562 p = parse_line_comment(p);
3563 goto redo_no_start;
3564 } else if (c == '=') {
3565 p++;
3566 tok = TOK_A_DIV;
3567 } else {
3568 tok = '/';
3570 break;
3572 /* simple tokens */
3573 case '(':
3574 case ')':
3575 case '[':
3576 case ']':
3577 case '{':
3578 case '}':
3579 case ',':
3580 case ';':
3581 case ':':
3582 case '?':
3583 case '~':
3584 case '$': /* only used in assembler */
3585 tok = c;
3586 p++;
3587 break;
3588 default:
3589 error("unrecognized character \\x%02x", c);
3590 break;
3592 file->buf_ptr = p;
3593 tok_flags = 0;
3594 #if defined(PARSE_DEBUG)
3595 printf("token = %s\n", get_tok_str(tok, &tokc));
3596 #endif
3599 /* return next token without macro substitution. Can read input from
3600 macro_ptr buffer */
3601 static void next_nomacro(void)
3603 if (macro_ptr) {
3604 redo:
3605 tok = *macro_ptr;
3606 if (tok) {
3607 TOK_GET(tok, macro_ptr, tokc);
3608 if (tok == TOK_LINENUM) {
3609 file->line_num = tokc.i;
3610 goto redo;
3613 } else {
3614 next_nomacro1();
3618 /* substitute args in macro_str and return allocated string */
3619 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
3621 int *st, last_tok, t, notfirst;
3622 Sym *s;
3623 CValue cval;
3624 TokenString str;
3625 CString cstr;
3627 tok_str_new(&str);
3628 last_tok = 0;
3629 while(1) {
3630 TOK_GET(t, macro_str, cval);
3631 if (!t)
3632 break;
3633 if (t == '#') {
3634 /* stringize */
3635 TOK_GET(t, macro_str, cval);
3636 if (!t)
3637 break;
3638 s = sym_find2(args, t);
3639 if (s) {
3640 cstr_new(&cstr);
3641 st = (int *)s->c;
3642 notfirst = 0;
3643 while (*st) {
3644 if (notfirst)
3645 cstr_ccat(&cstr, ' ');
3646 TOK_GET(t, st, cval);
3647 cstr_cat(&cstr, get_tok_str(t, &cval));
3648 notfirst = 1;
3650 cstr_ccat(&cstr, '\0');
3651 #ifdef PP_DEBUG
3652 printf("stringize: %s\n", (char *)cstr.data);
3653 #endif
3654 /* add string */
3655 cval.cstr = &cstr;
3656 tok_str_add2(&str, TOK_STR, &cval);
3657 cstr_free(&cstr);
3658 } else {
3659 tok_str_add2(&str, t, &cval);
3661 } else if (t >= TOK_IDENT) {
3662 s = sym_find2(args, t);
3663 if (s) {
3664 st = (int *)s->c;
3665 /* if '##' is present before or after, no arg substitution */
3666 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
3667 /* special case for var arg macros : ## eats the
3668 ',' if empty VA_ARGS variable. */
3669 /* XXX: test of the ',' is not 100%
3670 reliable. should fix it to avoid security
3671 problems */
3672 if (gnu_ext && s->type.t &&
3673 last_tok == TOK_TWOSHARPS &&
3674 str.len >= 2 && str.str[str.len - 2] == ',') {
3675 if (*st == 0) {
3676 /* suppress ',' '##' */
3677 str.len -= 2;
3678 } else {
3679 /* suppress '##' and add variable */
3680 str.len--;
3681 goto add_var;
3683 } else {
3684 int t1;
3685 add_var:
3686 for(;;) {
3687 TOK_GET(t1, st, cval);
3688 if (!t1)
3689 break;
3690 tok_str_add2(&str, t1, &cval);
3693 } else {
3694 macro_subst(&str, nested_list, st);
3696 } else {
3697 tok_str_add(&str, t);
3699 } else {
3700 tok_str_add2(&str, t, &cval);
3702 last_tok = t;
3704 tok_str_add(&str, 0);
3705 return str.str;
3708 static char const ab_month_name[12][4] =
3710 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
3711 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
3714 /* do macro substitution of current token with macro 's' and add
3715 result to (tok_str,tok_len). 'nested_list' is the list of all
3716 macros we got inside to avoid recursing. Return non zero if no
3717 substitution needs to be done */
3718 static int macro_subst_tok(TokenString *tok_str,
3719 Sym **nested_list, Sym *s)
3721 Sym *args, *sa, *sa1;
3722 int mstr_allocated, parlevel, *mstr, t;
3723 TokenString str;
3724 char *cstrval;
3725 CValue cval;
3726 CString cstr;
3728 /* if symbol is a macro, prepare substitution */
3730 /* special macros */
3731 if (tok == TOK___LINE__) {
3732 cval.i = file->line_num;
3733 tok_str_add2(tok_str, TOK_CINT, &cval);
3734 } else if (tok == TOK___FILE__) {
3735 cstrval = file->filename;
3736 goto add_cstr;
3737 tok_str_add2(tok_str, TOK_STR, &cval);
3738 } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
3739 time_t ti;
3740 struct tm *tm;
3741 char buf[64];
3743 time(&ti);
3744 tm = localtime(&ti);
3745 if (tok == TOK___DATE__) {
3746 snprintf(buf, sizeof(buf), "%s %2d %d",
3747 ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
3748 } else {
3749 snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
3750 tm->tm_hour, tm->tm_min, tm->tm_sec);
3752 cstrval = buf;
3753 add_cstr:
3754 cstr_new(&cstr);
3755 cstr_cat(&cstr, cstrval);
3756 cstr_ccat(&cstr, '\0');
3757 cval.cstr = &cstr;
3758 tok_str_add2(tok_str, TOK_STR, &cval);
3759 cstr_free(&cstr);
3760 } else {
3761 mstr = (int *)s->c;
3762 mstr_allocated = 0;
3763 if (s->type.t == MACRO_FUNC) {
3764 /* NOTE: we do not use next_nomacro to avoid eating the
3765 next token. XXX: find better solution */
3766 if (macro_ptr) {
3767 t = *macro_ptr;
3768 if (t == 0) {
3769 /* end of macro stream: we must look at the token
3770 after in the file */
3771 macro_ptr = NULL;
3772 goto parse_stream;
3774 } else {
3775 parse_stream:
3776 /* XXX: incorrect with comments */
3777 ch = file->buf_ptr[0];
3778 while (is_space(ch) || ch == '\n')
3779 cinp();
3780 t = ch;
3782 if (t != '(') /* no macro subst */
3783 return -1;
3785 /* argument macro */
3786 next_nomacro();
3787 next_nomacro();
3788 args = NULL;
3789 sa = s->next;
3790 /* NOTE: empty args are allowed, except if no args */
3791 for(;;) {
3792 /* handle '()' case */
3793 if (!args && tok == ')')
3794 break;
3795 if (!sa)
3796 error("macro '%s' used with too many args",
3797 get_tok_str(s->v, 0));
3798 tok_str_new(&str);
3799 parlevel = 0;
3800 /* NOTE: non zero sa->t indicates VA_ARGS */
3801 while ((parlevel > 0 ||
3802 (tok != ')' &&
3803 (tok != ',' || sa->type.t))) &&
3804 tok != -1) {
3805 if (tok == '(')
3806 parlevel++;
3807 else if (tok == ')')
3808 parlevel--;
3809 tok_str_add2(&str, tok, &tokc);
3810 next_nomacro();
3812 tok_str_add(&str, 0);
3813 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str);
3814 sa = sa->next;
3815 if (tok == ')') {
3816 /* special case for gcc var args: add an empty
3817 var arg argument if it is omitted */
3818 if (sa && sa->type.t && gnu_ext)
3819 continue;
3820 else
3821 break;
3823 if (tok != ',')
3824 expect(",");
3825 next_nomacro();
3827 if (sa) {
3828 error("macro '%s' used with too few args",
3829 get_tok_str(s->v, 0));
3832 /* now subst each arg */
3833 mstr = macro_arg_subst(nested_list, mstr, args);
3834 /* free memory */
3835 sa = args;
3836 while (sa) {
3837 sa1 = sa->prev;
3838 tok_str_free((int *)sa->c);
3839 tcc_free(sa);
3840 sa = sa1;
3842 mstr_allocated = 1;
3844 sym_push2(nested_list, s->v, 0, 0);
3845 macro_subst(tok_str, nested_list, mstr);
3846 /* pop nested defined symbol */
3847 sa1 = *nested_list;
3848 *nested_list = sa1->prev;
3849 tcc_free(sa1);
3850 if (mstr_allocated)
3851 tok_str_free(mstr);
3853 return 0;
3856 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
3857 return the resulting string (which must be freed). */
3858 static inline int *macro_twosharps(const int *macro_str)
3860 TokenSym *ts;
3861 const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr;
3862 int t;
3863 const char *p1, *p2;
3864 CValue cval;
3865 TokenString macro_str1;
3866 CString cstr;
3868 start_macro_ptr = macro_str;
3869 /* we search the first '##' */
3870 for(;;) {
3871 macro_ptr1 = macro_str;
3872 TOK_GET(t, macro_str, cval);
3873 /* nothing more to do if end of string */
3874 if (t == 0)
3875 return NULL;
3876 if (*macro_str == TOK_TWOSHARPS)
3877 break;
3880 /* we saw '##', so we need more processing to handle it */
3881 cstr_new(&cstr);
3882 tok_str_new(&macro_str1);
3883 tok = t;
3884 tokc = cval;
3886 /* add all tokens seen so far */
3887 for(ptr = start_macro_ptr; ptr < macro_ptr1;) {
3888 TOK_GET(t, ptr, cval);
3889 tok_str_add2(&macro_str1, t, &cval);
3891 saved_macro_ptr = macro_ptr;
3892 /* XXX: get rid of the use of macro_ptr here */
3893 macro_ptr = (int *)macro_str;
3894 for(;;) {
3895 while (*macro_ptr == TOK_TWOSHARPS) {
3896 macro_ptr++;
3897 macro_ptr1 = macro_ptr;
3898 t = *macro_ptr;
3899 if (t) {
3900 TOK_GET(t, macro_ptr, cval);
3901 /* We concatenate the two tokens if we have an
3902 identifier or a preprocessing number */
3903 cstr_reset(&cstr);
3904 p1 = get_tok_str(tok, &tokc);
3905 cstr_cat(&cstr, p1);
3906 p2 = get_tok_str(t, &cval);
3907 cstr_cat(&cstr, p2);
3908 cstr_ccat(&cstr, '\0');
3910 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
3911 (t >= TOK_IDENT || t == TOK_PPNUM)) {
3912 if (tok == TOK_PPNUM) {
3913 /* if number, then create a number token */
3914 /* NOTE: no need to allocate because
3915 tok_str_add2() does it */
3916 tokc.cstr = &cstr;
3917 } else {
3918 /* if identifier, we must do a test to
3919 validate we have a correct identifier */
3920 if (t == TOK_PPNUM) {
3921 const char *p;
3922 int c;
3924 p = p2;
3925 for(;;) {
3926 c = *p;
3927 if (c == '\0')
3928 break;
3929 p++;
3930 if (!isnum(c) && !isid(c))
3931 goto error_pasting;
3934 ts = tok_alloc(cstr.data, strlen(cstr.data));
3935 tok = ts->tok; /* modify current token */
3937 } else {
3938 const char *str = cstr.data;
3939 const unsigned char *q;
3941 /* we look for a valid token */
3942 /* XXX: do more extensive checks */
3943 if (!strcmp(str, ">>=")) {
3944 tok = TOK_A_SAR;
3945 } else if (!strcmp(str, "<<=")) {
3946 tok = TOK_A_SHL;
3947 } else if (strlen(str) == 2) {
3948 /* search in two bytes table */
3949 q = tok_two_chars;
3950 for(;;) {
3951 if (!*q)
3952 goto error_pasting;
3953 if (q[0] == str[0] && q[1] == str[1])
3954 break;
3955 q += 3;
3957 tok = q[2];
3958 } else {
3959 error_pasting:
3960 /* NOTE: because get_tok_str use a static buffer,
3961 we must save it */
3962 cstr_reset(&cstr);
3963 p1 = get_tok_str(tok, &tokc);
3964 cstr_cat(&cstr, p1);
3965 cstr_ccat(&cstr, '\0');
3966 p2 = get_tok_str(t, &cval);
3967 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
3968 /* cannot merge tokens: just add them separately */
3969 tok_str_add2(&macro_str1, tok, &tokc);
3970 /* XXX: free associated memory ? */
3971 tok = t;
3972 tokc = cval;
3977 tok_str_add2(&macro_str1, tok, &tokc);
3978 next_nomacro();
3979 if (tok == 0)
3980 break;
3982 macro_ptr = (int *)saved_macro_ptr;
3983 cstr_free(&cstr);
3984 tok_str_add(&macro_str1, 0);
3985 return macro_str1.str;
3989 /* do macro substitution of macro_str and add result to
3990 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3991 inside to avoid recursing. */
3992 static void macro_subst(TokenString *tok_str,
3993 Sym **nested_list, const int *macro_str)
3995 Sym *s;
3996 int *saved_macro_ptr, *macro_str1;
3997 const int *ptr;
3998 int t, ret;
3999 CValue cval;
4001 /* first scan for '##' operator handling */
4002 ptr = macro_str;
4003 macro_str1 = macro_twosharps(ptr);
4004 if (macro_str1)
4005 ptr = macro_str1;
4006 while (1) {
4007 /* NOTE: ptr == NULL can only happen if tokens are read from
4008 file stream due to a macro function call */
4009 if (ptr == NULL)
4010 break;
4011 TOK_GET(t, ptr, cval);
4012 if (t == 0)
4013 break;
4014 s = define_find(t);
4015 if (s != NULL) {
4016 /* if nested substitution, do nothing */
4017 if (sym_find2(*nested_list, t))
4018 goto no_subst;
4019 saved_macro_ptr = macro_ptr;
4020 macro_ptr = (int *)ptr;
4021 tok = t;
4022 ret = macro_subst_tok(tok_str, nested_list, s);
4023 ptr = (int *)macro_ptr;
4024 macro_ptr = saved_macro_ptr;
4025 if (ret != 0)
4026 goto no_subst;
4027 } else {
4028 no_subst:
4029 tok_str_add2(tok_str, t, &cval);
4032 if (macro_str1)
4033 tok_str_free(macro_str1);
4036 /* return next token with macro substitution */
4037 static void next(void)
4039 Sym *nested_list, *s;
4040 TokenString str;
4042 redo:
4043 next_nomacro();
4044 if (!macro_ptr) {
4045 /* if not reading from macro substituted string, then try
4046 to substitute macros */
4047 if (tok >= TOK_IDENT &&
4048 (parse_flags & PARSE_FLAG_PREPROCESS)) {
4049 s = define_find(tok);
4050 if (s) {
4051 /* we have a macro: we try to substitute */
4052 tok_str_new(&str);
4053 nested_list = NULL;
4054 if (macro_subst_tok(&str, &nested_list, s) == 0) {
4055 /* substitution done, NOTE: maybe empty */
4056 tok_str_add(&str, 0);
4057 macro_ptr = str.str;
4058 macro_ptr_allocated = str.str;
4059 goto redo;
4063 } else {
4064 if (tok == 0) {
4065 /* end of macro or end of unget buffer */
4066 if (unget_buffer_enabled) {
4067 macro_ptr = unget_saved_macro_ptr;
4068 unget_buffer_enabled = 0;
4069 } else {
4070 /* end of macro string: free it */
4071 tok_str_free(macro_ptr_allocated);
4072 macro_ptr = NULL;
4074 goto redo;
4078 /* convert preprocessor tokens into C tokens */
4079 if (tok == TOK_PPNUM &&
4080 (parse_flags & PARSE_FLAG_TOK_NUM)) {
4081 parse_number((char *)tokc.cstr->data);
4085 /* push back current token and set current token to 'last_tok'. Only
4086 identifier case handled for labels. */
4087 static inline void unget_tok(int last_tok)
4089 int i, n;
4090 int *q;
4091 unget_saved_macro_ptr = macro_ptr;
4092 unget_buffer_enabled = 1;
4093 q = unget_saved_buffer;
4094 macro_ptr = q;
4095 *q++ = tok;
4096 n = tok_ext_size(tok) - 1;
4097 for(i=0;i<n;i++)
4098 *q++ = tokc.tab[i];
4099 *q = 0; /* end of token string */
4100 tok = last_tok;
4104 void swap(int *p, int *q)
4106 int t;
4107 t = *p;
4108 *p = *q;
4109 *q = t;
4112 void vsetc(CType *type, int r, CValue *vc)
4114 int v;
4116 if (vtop >= vstack + VSTACK_SIZE)
4117 error("memory full");
4118 /* cannot let cpu flags if other instruction are generated. Also
4119 avoid leaving VT_JMP anywhere except on the top of the stack
4120 because it would complicate the code generator. */
4121 if (vtop >= vstack) {
4122 v = vtop->r & VT_VALMASK;
4123 if (v == VT_CMP || (v & ~1) == VT_JMP)
4124 gv(RC_INT);
4126 vtop++;
4127 vtop->type = *type;
4128 vtop->r = r;
4129 vtop->r2 = VT_CONST;
4130 vtop->c = *vc;
4133 /* push integer constant */
4134 void vpushi(int v)
4136 CValue cval;
4137 cval.i = v;
4138 vsetc(&int_type, VT_CONST, &cval);
4141 /* Return a static symbol pointing to a section */
4142 static Sym *get_sym_ref(CType *type, Section *sec,
4143 unsigned long offset, unsigned long size)
4145 int v;
4146 Sym *sym;
4148 v = anon_sym++;
4149 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
4150 sym->type.ref = type->ref;
4151 sym->r = VT_CONST | VT_SYM;
4152 put_extern_sym(sym, sec, offset, size);
4153 return sym;
4156 /* push a reference to a section offset by adding a dummy symbol */
4157 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
4159 CValue cval;
4161 cval.ul = 0;
4162 vsetc(type, VT_CONST | VT_SYM, &cval);
4163 vtop->sym = get_sym_ref(type, sec, offset, size);
4166 /* define a new external reference to a symbol 'v' of type 'u' */
4167 static Sym *external_global_sym(int v, CType *type, int r)
4169 Sym *s;
4171 s = sym_find(v);
4172 if (!s) {
4173 /* push forward reference */
4174 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
4175 s->type.ref = type->ref;
4176 s->r = r | VT_CONST | VT_SYM;
4178 return s;
4181 /* define a new external reference to a symbol 'v' of type 'u' */
4182 static Sym *external_sym(int v, CType *type, int r)
4184 Sym *s;
4186 s = sym_find(v);
4187 if (!s) {
4188 /* push forward reference */
4189 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
4190 s->type.t |= VT_EXTERN;
4191 } else {
4192 if (!is_compatible_types(&s->type, type))
4193 error("incompatible types for redefinition of '%s'",
4194 get_tok_str(v, NULL));
4196 return s;
4199 /* push a reference to global symbol v */
4200 static void vpush_global_sym(CType *type, int v)
4202 Sym *sym;
4203 CValue cval;
4205 sym = external_global_sym(v, type, 0);
4206 cval.ul = 0;
4207 vsetc(type, VT_CONST | VT_SYM, &cval);
4208 vtop->sym = sym;
4211 void vset(CType *type, int r, int v)
4213 CValue cval;
4215 cval.i = v;
4216 vsetc(type, r, &cval);
4219 void vseti(int r, int v)
4221 CType type;
4222 type.t = VT_INT;
4223 vset(&type, r, v);
4226 void vswap(void)
4228 SValue tmp;
4230 tmp = vtop[0];
4231 vtop[0] = vtop[-1];
4232 vtop[-1] = tmp;
4235 void vpushv(SValue *v)
4237 if (vtop >= vstack + VSTACK_SIZE)
4238 error("memory full");
4239 vtop++;
4240 *vtop = *v;
4243 void vdup(void)
4245 vpushv(vtop);
4248 /* save r to the memory stack, and mark it as being free */
4249 void save_reg(int r)
4251 int l, saved, size, align;
4252 SValue *p, sv;
4253 CType *type;
4255 /* modify all stack values */
4256 saved = 0;
4257 l = 0;
4258 for(p=vstack;p<=vtop;p++) {
4259 if ((p->r & VT_VALMASK) == r ||
4260 (p->r2 & VT_VALMASK) == r) {
4261 /* must save value on stack if not already done */
4262 if (!saved) {
4263 /* NOTE: must reload 'r' because r might be equal to r2 */
4264 r = p->r & VT_VALMASK;
4265 /* store register in the stack */
4266 type = &p->type;
4267 if ((p->r & VT_LVAL) ||
4268 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
4269 type = &int_type;
4270 size = type_size(type, &align);
4271 loc = (loc - size) & -align;
4272 sv.type.t = type->t;
4273 sv.r = VT_LOCAL | VT_LVAL;
4274 sv.c.ul = loc;
4275 store(r, &sv);
4276 #ifdef TCC_TARGET_I386
4277 /* x86 specific: need to pop fp register ST0 if saved */
4278 if (r == TREG_ST0) {
4279 o(0xd9dd); /* fstp %st(1) */
4281 #endif
4282 /* special long long case */
4283 if ((type->t & VT_BTYPE) == VT_LLONG) {
4284 sv.c.ul += 4;
4285 store(p->r2, &sv);
4287 l = loc;
4288 saved = 1;
4290 /* mark that stack entry as being saved on the stack */
4291 if (p->r & VT_LVAL) {
4292 /* also clear the bounded flag because the
4293 relocation address of the function was stored in
4294 p->c.ul */
4295 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
4296 } else {
4297 p->r = lvalue_type(p->type.t) | VT_LOCAL;
4299 p->r2 = VT_CONST;
4300 p->c.ul = l;
4305 /* find a free register of class 'rc'. If none, save one register */
4306 int get_reg(int rc)
4308 int r;
4309 SValue *p;
4311 /* find a free register */
4312 for(r=0;r<NB_REGS;r++) {
4313 if (reg_classes[r] & rc) {
4314 for(p=vstack;p<=vtop;p++) {
4315 if ((p->r & VT_VALMASK) == r ||
4316 (p->r2 & VT_VALMASK) == r)
4317 goto notfound;
4319 return r;
4321 notfound: ;
4324 /* no register left : free the first one on the stack (VERY
4325 IMPORTANT to start from the bottom to ensure that we don't
4326 spill registers used in gen_opi()) */
4327 for(p=vstack;p<=vtop;p++) {
4328 r = p->r & VT_VALMASK;
4329 if (r < VT_CONST && (reg_classes[r] & rc))
4330 goto save_found;
4331 /* also look at second register (if long long) */
4332 r = p->r2 & VT_VALMASK;
4333 if (r < VT_CONST && (reg_classes[r] & rc)) {
4334 save_found:
4335 save_reg(r);
4336 return r;
4339 /* Should never comes here */
4340 return -1;
4343 /* save registers up to (vtop - n) stack entry */
4344 void save_regs(int n)
4346 int r;
4347 SValue *p, *p1;
4348 p1 = vtop - n;
4349 for(p = vstack;p <= p1; p++) {
4350 r = p->r & VT_VALMASK;
4351 if (r < VT_CONST) {
4352 save_reg(r);
4357 /* move register 's' to 'r', and flush previous value of r to memory
4358 if needed */
4359 void move_reg(int r, int s)
4361 SValue sv;
4363 if (r != s) {
4364 save_reg(r);
4365 sv.type.t = VT_INT;
4366 sv.r = s;
4367 sv.c.ul = 0;
4368 load(r, &sv);
4372 /* get address of vtop (vtop MUST BE an lvalue) */
4373 void gaddrof(void)
4375 vtop->r &= ~VT_LVAL;
4376 /* tricky: if saved lvalue, then we can go back to lvalue */
4377 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
4378 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
4381 #ifdef CONFIG_TCC_BCHECK
4382 /* generate lvalue bound code */
4383 void gbound(void)
4385 int lval_type;
4386 CType type1;
4388 vtop->r &= ~VT_MUSTBOUND;
4389 /* if lvalue, then use checking code before dereferencing */
4390 if (vtop->r & VT_LVAL) {
4391 /* if not VT_BOUNDED value, then make one */
4392 if (!(vtop->r & VT_BOUNDED)) {
4393 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
4394 /* must save type because we must set it to int to get pointer */
4395 type1 = vtop->type;
4396 vtop->type.t = VT_INT;
4397 gaddrof();
4398 vpushi(0);
4399 gen_bounded_ptr_add();
4400 vtop->r |= lval_type;
4401 vtop->type = type1;
4403 /* then check for dereferencing */
4404 gen_bounded_ptr_deref();
4407 #endif
4409 /* store vtop a register belonging to class 'rc'. lvalues are
4410 converted to values. Cannot be used if cannot be converted to
4411 register value (such as structures). */
4412 int gv(int rc)
4414 int r, r2, rc2, bit_pos, bit_size, size, align, i;
4415 unsigned long long ll;
4417 /* NOTE: get_reg can modify vstack[] */
4418 if (vtop->type.t & VT_BITFIELD) {
4419 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4420 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4421 /* remove bit field info to avoid loops */
4422 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4423 /* generate shifts */
4424 vpushi(32 - (bit_pos + bit_size));
4425 gen_op(TOK_SHL);
4426 vpushi(32 - bit_size);
4427 /* NOTE: transformed to SHR if unsigned */
4428 gen_op(TOK_SAR);
4429 r = gv(rc);
4430 } else {
4431 if (is_float(vtop->type.t) &&
4432 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4433 Sym *sym;
4434 int *ptr;
4435 unsigned long offset;
4437 /* XXX: unify with initializers handling ? */
4438 /* CPUs usually cannot use float constants, so we store them
4439 generically in data segment */
4440 size = type_size(&vtop->type, &align);
4441 offset = (data_section->data_offset + align - 1) & -align;
4442 data_section->data_offset = offset;
4443 /* XXX: not portable yet */
4444 ptr = section_ptr_add(data_section, size);
4445 size = size >> 2;
4446 for(i=0;i<size;i++)
4447 ptr[i] = vtop->c.tab[i];
4448 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
4449 vtop->r |= VT_LVAL | VT_SYM;
4450 vtop->sym = sym;
4451 vtop->c.ul = 0;
4453 #ifdef CONFIG_TCC_BCHECK
4454 if (vtop->r & VT_MUSTBOUND)
4455 gbound();
4456 #endif
4458 r = vtop->r & VT_VALMASK;
4459 /* need to reload if:
4460 - constant
4461 - lvalue (need to dereference pointer)
4462 - already a register, but not in the right class */
4463 if (r >= VT_CONST ||
4464 (vtop->r & VT_LVAL) ||
4465 !(reg_classes[r] & rc) ||
4466 ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
4467 !(reg_classes[vtop->r2] & rc))) {
4468 r = get_reg(rc);
4469 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
4470 /* two register type load : expand to two words
4471 temporarily */
4472 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4473 /* load constant */
4474 ll = vtop->c.ull;
4475 vtop->c.ui = ll; /* first word */
4476 load(r, vtop);
4477 vtop->r = r; /* save register value */
4478 vpushi(ll >> 32); /* second word */
4479 } else if (r >= VT_CONST ||
4480 (vtop->r & VT_LVAL)) {
4481 /* load from memory */
4482 load(r, vtop);
4483 vdup();
4484 vtop[-1].r = r; /* save register value */
4485 /* increment pointer to get second word */
4486 vtop->type.t = VT_INT;
4487 gaddrof();
4488 vpushi(4);
4489 gen_op('+');
4490 vtop->r |= VT_LVAL;
4491 } else {
4492 /* move registers */
4493 load(r, vtop);
4494 vdup();
4495 vtop[-1].r = r; /* save register value */
4496 vtop->r = vtop[-1].r2;
4498 /* allocate second register */
4499 rc2 = RC_INT;
4500 if (rc == RC_IRET)
4501 rc2 = RC_LRET;
4502 r2 = get_reg(rc2);
4503 load(r2, vtop);
4504 vpop();
4505 /* write second register */
4506 vtop->r2 = r2;
4507 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
4508 int t1, t;
4509 /* lvalue of scalar type : need to use lvalue type
4510 because of possible cast */
4511 t = vtop->type.t;
4512 t1 = t;
4513 /* compute memory access type */
4514 if (vtop->r & VT_LVAL_BYTE)
4515 t = VT_BYTE;
4516 else if (vtop->r & VT_LVAL_SHORT)
4517 t = VT_SHORT;
4518 if (vtop->r & VT_LVAL_UNSIGNED)
4519 t |= VT_UNSIGNED;
4520 vtop->type.t = t;
4521 load(r, vtop);
4522 /* restore wanted type */
4523 vtop->type.t = t1;
4524 } else {
4525 /* one register type load */
4526 load(r, vtop);
4529 vtop->r = r;
4531 return r;
4534 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4535 void gv2(int rc1, int rc2)
4537 int v;
4539 /* generate more generic register first. But VT_JMP or VT_CMP
4540 values must be generated first in all cases to avoid possible
4541 reload errors */
4542 v = vtop[0].r & VT_VALMASK;
4543 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
4544 vswap();
4545 gv(rc1);
4546 vswap();
4547 gv(rc2);
4548 /* test if reload is needed for first register */
4549 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
4550 vswap();
4551 gv(rc1);
4552 vswap();
4554 } else {
4555 gv(rc2);
4556 vswap();
4557 gv(rc1);
4558 vswap();
4559 /* test if reload is needed for first register */
4560 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
4561 gv(rc2);
4566 /* expand long long on stack in two int registers */
4567 void lexpand(void)
4569 int u;
4571 u = vtop->type.t & VT_UNSIGNED;
4572 gv(RC_INT);
4573 vdup();
4574 vtop[0].r = vtop[-1].r2;
4575 vtop[0].r2 = VT_CONST;
4576 vtop[-1].r2 = VT_CONST;
4577 vtop[0].type.t = VT_INT | u;
4578 vtop[-1].type.t = VT_INT | u;
4581 /* build a long long from two ints */
4582 void lbuild(int t)
4584 gv2(RC_INT, RC_INT);
4585 vtop[-1].r2 = vtop[0].r;
4586 vtop[-1].type.t = t;
4587 vpop();
4590 /* rotate n first stack elements to the bottom */
4591 void vrotb(int n)
4593 int i;
4594 SValue tmp;
4596 tmp = vtop[-n + 1];
4597 for(i=-n+1;i!=0;i++)
4598 vtop[i] = vtop[i+1];
4599 vtop[0] = tmp;
4602 /* pop stack value */
4603 void vpop(void)
4605 int v;
4606 v = vtop->r & VT_VALMASK;
4607 #ifdef TCC_TARGET_I386
4608 /* for x86, we need to pop the FP stack */
4609 if (v == TREG_ST0 && !nocode_wanted) {
4610 o(0xd9dd); /* fstp %st(1) */
4611 } else
4612 #endif
4613 if (v == VT_JMP || v == VT_JMPI) {
4614 /* need to put correct jump if && or || without test */
4615 gsym(vtop->c.ul);
4617 vtop--;
4620 /* convert stack entry to register and duplicate its value in another
4621 register */
4622 void gv_dup(void)
4624 int rc, t, r, r1;
4625 SValue sv;
4627 t = vtop->type.t;
4628 if ((t & VT_BTYPE) == VT_LLONG) {
4629 lexpand();
4630 gv_dup();
4631 vswap();
4632 vrotb(3);
4633 gv_dup();
4634 vrotb(4);
4635 /* stack: H L L1 H1 */
4636 lbuild(t);
4637 vrotb(3);
4638 vrotb(3);
4639 vswap();
4640 lbuild(t);
4641 vswap();
4642 } else {
4643 /* duplicate value */
4644 rc = RC_INT;
4645 sv.type.t = VT_INT;
4646 if (is_float(t)) {
4647 rc = RC_FLOAT;
4648 sv.type.t = t;
4650 r = gv(rc);
4651 r1 = get_reg(rc);
4652 sv.r = r;
4653 sv.c.ul = 0;
4654 load(r1, &sv); /* move r to r1 */
4655 vdup();
4656 /* duplicates value */
4657 vtop->r = r1;
4661 /* generate CPU independent (unsigned) long long operations */
4662 void gen_opl(int op)
4664 int t, a, b, op1, c, i;
4665 int func;
4666 GFuncContext gf;
4667 SValue tmp;
4669 switch(op) {
4670 case '/':
4671 case TOK_PDIV:
4672 func = TOK___divdi3;
4673 goto gen_func;
4674 case TOK_UDIV:
4675 func = TOK___udivdi3;
4676 goto gen_func;
4677 case '%':
4678 func = TOK___moddi3;
4679 goto gen_func;
4680 case TOK_UMOD:
4681 func = TOK___umoddi3;
4682 gen_func:
4683 /* call generic long long function */
4684 gfunc_start(&gf, FUNC_CDECL);
4685 gfunc_param(&gf);
4686 gfunc_param(&gf);
4687 vpush_global_sym(&func_old_type, func);
4688 gfunc_call(&gf);
4689 vpushi(0);
4690 vtop->r = REG_IRET;
4691 vtop->r2 = REG_LRET;
4692 break;
4693 case '^':
4694 case '&':
4695 case '|':
4696 case '*':
4697 case '+':
4698 case '-':
4699 t = vtop->type.t;
4700 vswap();
4701 lexpand();
4702 vrotb(3);
4703 lexpand();
4704 /* stack: L1 H1 L2 H2 */
4705 tmp = vtop[0];
4706 vtop[0] = vtop[-3];
4707 vtop[-3] = tmp;
4708 tmp = vtop[-2];
4709 vtop[-2] = vtop[-3];
4710 vtop[-3] = tmp;
4711 vswap();
4712 /* stack: H1 H2 L1 L2 */
4713 if (op == '*') {
4714 vpushv(vtop - 1);
4715 vpushv(vtop - 1);
4716 gen_op(TOK_UMULL);
4717 lexpand();
4718 /* stack: H1 H2 L1 L2 ML MH */
4719 for(i=0;i<4;i++)
4720 vrotb(6);
4721 /* stack: ML MH H1 H2 L1 L2 */
4722 tmp = vtop[0];
4723 vtop[0] = vtop[-2];
4724 vtop[-2] = tmp;
4725 /* stack: ML MH H1 L2 H2 L1 */
4726 gen_op('*');
4727 vrotb(3);
4728 vrotb(3);
4729 gen_op('*');
4730 /* stack: ML MH M1 M2 */
4731 gen_op('+');
4732 gen_op('+');
4733 } else if (op == '+' || op == '-') {
4734 /* XXX: add non carry method too (for MIPS or alpha) */
4735 if (op == '+')
4736 op1 = TOK_ADDC1;
4737 else
4738 op1 = TOK_SUBC1;
4739 gen_op(op1);
4740 /* stack: H1 H2 (L1 op L2) */
4741 vrotb(3);
4742 vrotb(3);
4743 gen_op(op1 + 1); /* TOK_xxxC2 */
4744 } else {
4745 gen_op(op);
4746 /* stack: H1 H2 (L1 op L2) */
4747 vrotb(3);
4748 vrotb(3);
4749 /* stack: (L1 op L2) H1 H2 */
4750 gen_op(op);
4751 /* stack: (L1 op L2) (H1 op H2) */
4753 /* stack: L H */
4754 lbuild(t);
4755 break;
4756 case TOK_SAR:
4757 case TOK_SHR:
4758 case TOK_SHL:
4759 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4760 t = vtop[-1].type.t;
4761 vswap();
4762 lexpand();
4763 vrotb(3);
4764 /* stack: L H shift */
4765 c = (int)vtop->c.i;
4766 /* constant: simpler */
4767 /* NOTE: all comments are for SHL. the other cases are
4768 done by swaping words */
4769 vpop();
4770 if (op != TOK_SHL)
4771 vswap();
4772 if (c >= 32) {
4773 /* stack: L H */
4774 vpop();
4775 if (c > 32) {
4776 vpushi(c - 32);
4777 gen_op(op);
4779 if (op != TOK_SAR) {
4780 vpushi(0);
4781 } else {
4782 gv_dup();
4783 vpushi(31);
4784 gen_op(TOK_SAR);
4786 vswap();
4787 } else {
4788 vswap();
4789 gv_dup();
4790 /* stack: H L L */
4791 vpushi(c);
4792 gen_op(op);
4793 vswap();
4794 vpushi(32 - c);
4795 if (op == TOK_SHL)
4796 gen_op(TOK_SHR);
4797 else
4798 gen_op(TOK_SHL);
4799 vrotb(3);
4800 /* stack: L L H */
4801 vpushi(c);
4802 if (op == TOK_SHL)
4803 gen_op(TOK_SHL);
4804 else
4805 gen_op(TOK_SHR);
4806 gen_op('|');
4808 if (op != TOK_SHL)
4809 vswap();
4810 lbuild(t);
4811 } else {
4812 /* XXX: should provide a faster fallback on x86 ? */
4813 switch(op) {
4814 case TOK_SAR:
4815 func = TOK___sardi3;
4816 goto gen_func;
4817 case TOK_SHR:
4818 func = TOK___shrdi3;
4819 goto gen_func;
4820 case TOK_SHL:
4821 func = TOK___shldi3;
4822 goto gen_func;
4825 break;
4826 default:
4827 /* compare operations */
4828 t = vtop->type.t;
4829 vswap();
4830 lexpand();
4831 vrotb(3);
4832 lexpand();
4833 /* stack: L1 H1 L2 H2 */
4834 tmp = vtop[-1];
4835 vtop[-1] = vtop[-2];
4836 vtop[-2] = tmp;
4837 /* stack: L1 L2 H1 H2 */
4838 /* compare high */
4839 op1 = op;
4840 /* when values are equal, we need to compare low words. since
4841 the jump is inverted, we invert the test too. */
4842 if (op1 == TOK_LT)
4843 op1 = TOK_LE;
4844 else if (op1 == TOK_GT)
4845 op1 = TOK_GE;
4846 else if (op1 == TOK_ULT)
4847 op1 = TOK_ULE;
4848 else if (op1 == TOK_UGT)
4849 op1 = TOK_UGE;
4850 a = 0;
4851 b = 0;
4852 gen_op(op1);
4853 if (op1 != TOK_NE) {
4854 a = gtst(1, 0);
4856 if (op != TOK_EQ) {
4857 /* generate non equal test */
4858 /* XXX: NOT PORTABLE yet */
4859 if (a == 0) {
4860 b = gtst(0, 0);
4861 } else {
4862 #ifdef TCC_TARGET_I386
4863 b = psym(0x850f, 0);
4864 #else
4865 error("not implemented");
4866 #endif
4869 /* compare low. Always unsigned */
4870 op1 = op;
4871 if (op1 == TOK_LT)
4872 op1 = TOK_ULT;
4873 else if (op1 == TOK_LE)
4874 op1 = TOK_ULE;
4875 else if (op1 == TOK_GT)
4876 op1 = TOK_UGT;
4877 else if (op1 == TOK_GE)
4878 op1 = TOK_UGE;
4879 gen_op(op1);
4880 a = gtst(1, a);
4881 gsym(b);
4882 vseti(VT_JMPI, a);
4883 break;
4887 /* handle integer constant optimizations and various machine
4888 independent opt */
4889 void gen_opic(int op)
4891 int fc, c1, c2, n;
4892 SValue *v1, *v2;
4894 v1 = vtop - 1;
4895 v2 = vtop;
4896 /* currently, we cannot do computations with forward symbols */
4897 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4898 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4899 if (c1 && c2) {
4900 fc = v2->c.i;
4901 switch(op) {
4902 case '+': v1->c.i += fc; break;
4903 case '-': v1->c.i -= fc; break;
4904 case '&': v1->c.i &= fc; break;
4905 case '^': v1->c.i ^= fc; break;
4906 case '|': v1->c.i |= fc; break;
4907 case '*': v1->c.i *= fc; break;
4909 case TOK_PDIV:
4910 case '/':
4911 case '%':
4912 case TOK_UDIV:
4913 case TOK_UMOD:
4914 /* if division by zero, generate explicit division */
4915 if (fc == 0) {
4916 if (const_wanted)
4917 error("division by zero in constant");
4918 goto general_case;
4920 switch(op) {
4921 default: v1->c.i /= fc; break;
4922 case '%': v1->c.i %= fc; break;
4923 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
4924 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
4926 break;
4927 case TOK_SHL: v1->c.i <<= fc; break;
4928 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
4929 case TOK_SAR: v1->c.i >>= fc; break;
4930 /* tests */
4931 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
4932 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
4933 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
4934 case TOK_NE: v1->c.i = v1->c.i != fc; break;
4935 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
4936 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
4937 case TOK_LT: v1->c.i = v1->c.i < fc; break;
4938 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
4939 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
4940 case TOK_GT: v1->c.i = v1->c.i > fc; break;
4941 /* logical */
4942 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
4943 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
4944 default:
4945 goto general_case;
4947 vtop--;
4948 } else {
4949 /* if commutative ops, put c2 as constant */
4950 if (c1 && (op == '+' || op == '&' || op == '^' ||
4951 op == '|' || op == '*')) {
4952 vswap();
4953 swap(&c1, &c2);
4955 fc = vtop->c.i;
4956 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
4957 op == TOK_PDIV) &&
4958 fc == 1) ||
4959 ((op == '+' || op == '-' || op == '|' || op == '^' ||
4960 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
4961 fc == 0) ||
4962 (op == '&' &&
4963 fc == -1))) {
4964 /* nothing to do */
4965 vtop--;
4966 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
4967 /* try to use shifts instead of muls or divs */
4968 if (fc > 0 && (fc & (fc - 1)) == 0) {
4969 n = -1;
4970 while (fc) {
4971 fc >>= 1;
4972 n++;
4974 vtop->c.i = n;
4975 if (op == '*')
4976 op = TOK_SHL;
4977 else if (op == TOK_PDIV)
4978 op = TOK_SAR;
4979 else
4980 op = TOK_SHR;
4982 goto general_case;
4983 } else if (c2 && (op == '+' || op == '-') &&
4984 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
4985 (VT_CONST | VT_SYM)) {
4986 /* symbol + constant case */
4987 if (op == '-')
4988 fc = -fc;
4989 vtop--;
4990 vtop->c.i += fc;
4991 } else {
4992 general_case:
4993 if (!nocode_wanted) {
4994 /* call low level op generator */
4995 gen_opi(op);
4996 } else {
4997 vtop--;
5003 /* generate a floating point operation with constant propagation */
5004 void gen_opif(int op)
5006 int c1, c2;
5007 SValue *v1, *v2;
5008 long double f1, f2;
5010 v1 = vtop - 1;
5011 v2 = vtop;
5012 /* currently, we cannot do computations with forward symbols */
5013 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5014 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5015 if (c1 && c2) {
5016 if (v1->type.t == VT_FLOAT) {
5017 f1 = v1->c.f;
5018 f2 = v2->c.f;
5019 } else if (v1->type.t == VT_DOUBLE) {
5020 f1 = v1->c.d;
5021 f2 = v2->c.d;
5022 } else {
5023 f1 = v1->c.ld;
5024 f2 = v2->c.ld;
5027 /* NOTE: we only do constant propagation if finite number (not
5028 NaN or infinity) (ANSI spec) */
5029 if (!ieee_finite(f1) || !ieee_finite(f2))
5030 goto general_case;
5032 switch(op) {
5033 case '+': f1 += f2; break;
5034 case '-': f1 -= f2; break;
5035 case '*': f1 *= f2; break;
5036 case '/':
5037 if (f2 == 0.0) {
5038 if (const_wanted)
5039 error("division by zero in constant");
5040 goto general_case;
5042 f1 /= f2;
5043 break;
5044 /* XXX: also handles tests ? */
5045 default:
5046 goto general_case;
5048 /* XXX: overflow test ? */
5049 if (v1->type.t == VT_FLOAT) {
5050 v1->c.f = f1;
5051 } else if (v1->type.t == VT_DOUBLE) {
5052 v1->c.d = f1;
5053 } else {
5054 v1->c.ld = f1;
5056 vtop--;
5057 } else {
5058 general_case:
5059 if (!nocode_wanted) {
5060 gen_opf(op);
5061 } else {
5062 vtop--;
5067 static int pointed_size(CType *type)
5069 int align;
5070 return type_size(pointed_type(type), &align);
5073 #if 0
5074 void check_pointer_types(SValue *p1, SValue *p2)
5076 char buf1[256], buf2[256];
5077 int t1, t2;
5078 t1 = p1->t;
5079 t2 = p2->t;
5080 if (!is_compatible_types(t1, t2)) {
5081 type_to_str(buf1, sizeof(buf1), t1, NULL);
5082 type_to_str(buf2, sizeof(buf2), t2, NULL);
5083 error("incompatible pointers '%s' and '%s'", buf1, buf2);
5086 #endif
5088 /* generic gen_op: handles types problems */
5089 void gen_op(int op)
5091 int u, t1, t2, bt1, bt2, t;
5092 CType type1;
5094 t1 = vtop[-1].type.t;
5095 t2 = vtop[0].type.t;
5096 bt1 = t1 & VT_BTYPE;
5097 bt2 = t2 & VT_BTYPE;
5099 if (bt1 == VT_PTR || bt2 == VT_PTR) {
5100 /* at least one operand is a pointer */
5101 /* relationnal op: must be both pointers */
5102 if (op >= TOK_ULT && op <= TOK_GT) {
5103 // check_pointer_types(vtop, vtop - 1);
5104 /* pointers are handled are unsigned */
5105 t = VT_INT | VT_UNSIGNED;
5106 goto std_op;
5108 /* if both pointers, then it must be the '-' op */
5109 if (bt1 == VT_PTR && bt2 == VT_PTR) {
5110 if (op != '-')
5111 error("cannot use pointers here");
5112 // check_pointer_types(vtop - 1, vtop);
5113 /* XXX: check that types are compatible */
5114 u = pointed_size(&vtop[-1].type);
5115 gen_opic(op);
5116 /* set to integer type */
5117 vtop->type.t = VT_INT;
5118 vpushi(u);
5119 gen_op(TOK_PDIV);
5120 } else {
5121 /* exactly one pointer : must be '+' or '-'. */
5122 if (op != '-' && op != '+')
5123 error("cannot use pointers here");
5124 /* Put pointer as first operand */
5125 if (bt2 == VT_PTR) {
5126 vswap();
5127 swap(&t1, &t2);
5129 type1 = vtop[-1].type;
5130 /* XXX: cast to int ? (long long case) */
5131 vpushi(pointed_size(&vtop[-1].type));
5132 gen_op('*');
5133 #ifdef CONFIG_TCC_BCHECK
5134 /* if evaluating constant expression, no code should be
5135 generated, so no bound check */
5136 if (do_bounds_check && !const_wanted) {
5137 /* if bounded pointers, we generate a special code to
5138 test bounds */
5139 if (op == '-') {
5140 vpushi(0);
5141 vswap();
5142 gen_op('-');
5144 gen_bounded_ptr_add();
5145 } else
5146 #endif
5148 gen_opic(op);
5150 /* put again type if gen_opic() swaped operands */
5151 vtop->type = type1;
5153 } else if (is_float(bt1) || is_float(bt2)) {
5154 /* compute bigger type and do implicit casts */
5155 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
5156 t = VT_LDOUBLE;
5157 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
5158 t = VT_DOUBLE;
5159 } else {
5160 t = VT_FLOAT;
5162 /* floats can only be used for a few operations */
5163 if (op != '+' && op != '-' && op != '*' && op != '/' &&
5164 (op < TOK_ULT || op > TOK_GT))
5165 error("invalid operands for binary operation");
5166 goto std_op;
5167 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
5168 /* cast to biggest op */
5169 t = VT_LLONG;
5170 /* convert to unsigned if it does not fit in a long long */
5171 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
5172 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
5173 t |= VT_UNSIGNED;
5174 goto std_op;
5175 } else {
5176 /* integer operations */
5177 t = VT_INT;
5178 /* convert to unsigned if it does not fit in an integer */
5179 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
5180 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
5181 t |= VT_UNSIGNED;
5182 std_op:
5183 /* XXX: currently, some unsigned operations are explicit, so
5184 we modify them here */
5185 if (t & VT_UNSIGNED) {
5186 if (op == TOK_SAR)
5187 op = TOK_SHR;
5188 else if (op == '/')
5189 op = TOK_UDIV;
5190 else if (op == '%')
5191 op = TOK_UMOD;
5192 else if (op == TOK_LT)
5193 op = TOK_ULT;
5194 else if (op == TOK_GT)
5195 op = TOK_UGT;
5196 else if (op == TOK_LE)
5197 op = TOK_ULE;
5198 else if (op == TOK_GE)
5199 op = TOK_UGE;
5201 vswap();
5202 type1.t = t;
5203 gen_cast(&type1);
5204 vswap();
5205 /* special case for shifts and long long: we keep the shift as
5206 an integer */
5207 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
5208 type1.t = VT_INT;
5209 gen_cast(&type1);
5210 if (is_float(t))
5211 gen_opif(op);
5212 else if ((t & VT_BTYPE) == VT_LLONG)
5213 gen_opl(op);
5214 else
5215 gen_opic(op);
5216 if (op >= TOK_ULT && op <= TOK_GT) {
5217 /* relationnal op: the result is an int */
5218 vtop->type.t = VT_INT;
5219 } else {
5220 vtop->type.t = t;
5225 /* generic itof for unsigned long long case */
5226 void gen_cvt_itof1(int t)
5228 GFuncContext gf;
5230 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
5231 (VT_LLONG | VT_UNSIGNED)) {
5233 gfunc_start(&gf, FUNC_CDECL);
5234 gfunc_param(&gf);
5235 if (t == VT_FLOAT)
5236 vpush_global_sym(&func_old_type, TOK___ulltof);
5237 else if (t == VT_DOUBLE)
5238 vpush_global_sym(&func_old_type, TOK___ulltod);
5239 else
5240 vpush_global_sym(&func_old_type, TOK___ulltold);
5241 gfunc_call(&gf);
5242 vpushi(0);
5243 vtop->r = REG_FRET;
5244 } else {
5245 gen_cvt_itof(t);
5249 /* generic ftoi for unsigned long long case */
5250 void gen_cvt_ftoi1(int t)
5252 GFuncContext gf;
5253 int st;
5255 if (t == (VT_LLONG | VT_UNSIGNED)) {
5256 /* not handled natively */
5257 gfunc_start(&gf, FUNC_CDECL);
5258 st = vtop->type.t & VT_BTYPE;
5259 gfunc_param(&gf);
5260 if (st == VT_FLOAT)
5261 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
5262 else if (st == VT_DOUBLE)
5263 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
5264 else
5265 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
5266 gfunc_call(&gf);
5267 vpushi(0);
5268 vtop->r = REG_IRET;
5269 vtop->r2 = REG_LRET;
5270 } else {
5271 gen_cvt_ftoi(t);
5275 /* force char or short cast */
5276 void force_charshort_cast(int t)
5278 int bits, dbt;
5279 dbt = t & VT_BTYPE;
5280 /* XXX: add optimization if lvalue : just change type and offset */
5281 if (dbt == VT_BYTE)
5282 bits = 8;
5283 else
5284 bits = 16;
5285 if (t & VT_UNSIGNED) {
5286 vpushi((1 << bits) - 1);
5287 gen_op('&');
5288 } else {
5289 bits = 32 - bits;
5290 vpushi(bits);
5291 gen_op(TOK_SHL);
5292 vpushi(bits);
5293 gen_op(TOK_SAR);
5297 /* cast 'vtop' to 'type' */
5298 static void gen_cast(CType *type)
5300 int sbt, dbt, sf, df, c;
5302 /* special delayed cast for char/short */
5303 /* XXX: in some cases (multiple cascaded casts), it may still
5304 be incorrect */
5305 if (vtop->r & VT_MUSTCAST) {
5306 vtop->r &= ~VT_MUSTCAST;
5307 force_charshort_cast(vtop->type.t);
5310 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
5311 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
5313 if (sbt != dbt && !nocode_wanted) {
5314 sf = is_float(sbt);
5315 df = is_float(dbt);
5316 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5317 if (sf && df) {
5318 /* convert from fp to fp */
5319 if (c) {
5320 /* constant case: we can do it now */
5321 /* XXX: in ISOC, cannot do it if error in convert */
5322 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
5323 vtop->c.f = (float)vtop->c.d;
5324 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
5325 vtop->c.f = (float)vtop->c.ld;
5326 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
5327 vtop->c.d = (double)vtop->c.f;
5328 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
5329 vtop->c.d = (double)vtop->c.ld;
5330 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
5331 vtop->c.ld = (long double)vtop->c.f;
5332 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
5333 vtop->c.ld = (long double)vtop->c.d;
5334 } else {
5335 /* non constant case: generate code */
5336 gen_cvt_ftof(dbt);
5338 } else if (df) {
5339 /* convert int to fp */
5340 if (c) {
5341 switch(sbt) {
5342 case VT_LLONG | VT_UNSIGNED:
5343 case VT_LLONG:
5344 /* XXX: add const cases for long long */
5345 goto do_itof;
5346 case VT_INT | VT_UNSIGNED:
5347 switch(dbt) {
5348 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
5349 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
5350 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
5352 break;
5353 default:
5354 switch(dbt) {
5355 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
5356 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
5357 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
5359 break;
5361 } else {
5362 do_itof:
5363 gen_cvt_itof1(dbt);
5365 } else if (sf) {
5366 /* convert fp to int */
5367 /* we handle char/short/etc... with generic code */
5368 if (dbt != (VT_INT | VT_UNSIGNED) &&
5369 dbt != (VT_LLONG | VT_UNSIGNED) &&
5370 dbt != VT_LLONG)
5371 dbt = VT_INT;
5372 if (c) {
5373 switch(dbt) {
5374 case VT_LLONG | VT_UNSIGNED:
5375 case VT_LLONG:
5376 /* XXX: add const cases for long long */
5377 goto do_ftoi;
5378 case VT_INT | VT_UNSIGNED:
5379 switch(sbt) {
5380 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
5381 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5382 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5384 break;
5385 default:
5386 /* int case */
5387 switch(sbt) {
5388 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
5389 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
5390 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
5392 break;
5394 } else {
5395 do_ftoi:
5396 gen_cvt_ftoi1(dbt);
5398 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
5399 /* additional cast for char/short/bool... */
5400 vtop->type.t = dbt;
5401 gen_cast(type);
5403 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
5404 if ((sbt & VT_BTYPE) != VT_LLONG) {
5405 /* scalar to long long */
5406 if (c) {
5407 if (sbt == (VT_INT | VT_UNSIGNED))
5408 vtop->c.ll = vtop->c.ui;
5409 else
5410 vtop->c.ll = vtop->c.i;
5411 } else {
5412 /* machine independent conversion */
5413 gv(RC_INT);
5414 /* generate high word */
5415 if (sbt == (VT_INT | VT_UNSIGNED)) {
5416 vpushi(0);
5417 gv(RC_INT);
5418 } else {
5419 gv_dup();
5420 vpushi(31);
5421 gen_op(TOK_SAR);
5423 /* patch second register */
5424 vtop[-1].r2 = vtop->r;
5425 vpop();
5428 } else if (dbt == VT_BOOL) {
5429 /* scalar to bool */
5430 vpushi(0);
5431 gen_op(TOK_NE);
5432 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
5433 (dbt & VT_BTYPE) == VT_SHORT) {
5434 force_charshort_cast(dbt);
5435 } else if ((dbt & VT_BTYPE) == VT_INT) {
5436 /* scalar to int */
5437 if (sbt == VT_LLONG) {
5438 /* from long long: just take low order word */
5439 lexpand();
5440 vpop();
5442 /* if lvalue and single word type, nothing to do because
5443 the lvalue already contains the real type size (see
5444 VT_LVAL_xxx constants) */
5447 vtop->type = *type;
5450 /* return type size. Put alignment at 'a' */
5451 static int type_size(CType *type, int *a)
5453 Sym *s;
5454 int bt;
5456 bt = type->t & VT_BTYPE;
5457 if (bt == VT_STRUCT) {
5458 /* struct/union */
5459 s = type->ref;
5460 *a = s->r;
5461 return s->c;
5462 } else if (bt == VT_PTR) {
5463 if (type->t & VT_ARRAY) {
5464 s = type->ref;
5465 return type_size(&s->type, a) * s->c;
5466 } else {
5467 *a = PTR_SIZE;
5468 return PTR_SIZE;
5470 } else if (bt == VT_LDOUBLE) {
5471 *a = LDOUBLE_ALIGN;
5472 return LDOUBLE_SIZE;
5473 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
5474 *a = 4; /* XXX: i386 specific */
5475 return 8;
5476 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
5477 *a = 4;
5478 return 4;
5479 } else if (bt == VT_SHORT) {
5480 *a = 2;
5481 return 2;
5482 } else {
5483 /* char, void, function, _Bool */
5484 *a = 1;
5485 return 1;
5489 /* return the pointed type of t */
5490 static inline CType *pointed_type(CType *type)
5492 return &type->ref->type;
5495 /* modify type so that its it is a pointer to type. */
5496 static void mk_pointer(CType *type)
5498 Sym *s;
5499 s = sym_push(SYM_FIELD, type, 0, -1);
5500 type->t = VT_PTR | (type->t & ~VT_TYPE);
5501 type->ref = s;
5504 static int is_compatible_types(CType *type1, CType *type2)
5506 Sym *s1, *s2;
5507 int bt1, bt2, t1, t2;
5509 t1 = type1->t & VT_TYPE;
5510 t2 = type2->t & VT_TYPE;
5511 bt1 = t1 & VT_BTYPE;
5512 bt2 = t2 & VT_BTYPE;
5513 if (bt1 == VT_PTR) {
5514 type1 = pointed_type(type1);
5515 /* if function, then convert implicitely to function pointer */
5516 if (bt2 != VT_FUNC) {
5517 if (bt2 != VT_PTR)
5518 return 0;
5519 type2 = pointed_type(type2);
5521 /* void matches everything */
5522 /* XXX: not fully compliant */
5523 if ((type1->t & VT_TYPE) == VT_VOID || (type2->t & VT_TYPE) == VT_VOID)
5524 return 1;
5525 return is_compatible_types(type1, type2);
5526 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5527 return (type1->ref == type2->ref);
5528 } else if (bt1 == VT_FUNC) {
5529 if (bt2 != VT_FUNC)
5530 return 0;
5531 s1 = type1->ref;
5532 s2 = type2->ref;
5533 if (!is_compatible_types(&s1->type, &s2->type))
5534 return 0;
5535 /* XXX: not complete */
5536 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
5537 return 1;
5538 if (s1->c != s2->c)
5539 return 0;
5540 while (s1 != NULL) {
5541 if (s2 == NULL)
5542 return 0;
5543 if (!is_compatible_types(&s1->type, &s2->type))
5544 return 0;
5545 s1 = s1->next;
5546 s2 = s2->next;
5548 if (s2)
5549 return 0;
5550 return 1;
5551 } else {
5552 /* XXX: not complete */
5553 return 1;
5557 /* print a type. If 'varstr' is not NULL, then the variable is also
5558 printed in the type */
5559 /* XXX: union */
5560 /* XXX: add array and function pointers */
5561 void type_to_str(char *buf, int buf_size,
5562 CType *type, const char *varstr)
5564 int bt, v, t;
5565 Sym *s, *sa;
5566 char buf1[256];
5567 const char *tstr;
5569 t = type->t & VT_TYPE;
5570 bt = t & VT_BTYPE;
5571 buf[0] = '\0';
5572 if (t & VT_UNSIGNED)
5573 pstrcat(buf, buf_size, "unsigned ");
5574 switch(bt) {
5575 case VT_VOID:
5576 tstr = "void";
5577 goto add_tstr;
5578 case VT_BOOL:
5579 tstr = "_Bool";
5580 goto add_tstr;
5581 case VT_BYTE:
5582 tstr = "char";
5583 goto add_tstr;
5584 case VT_SHORT:
5585 tstr = "short";
5586 goto add_tstr;
5587 case VT_INT:
5588 tstr = "int";
5589 goto add_tstr;
5590 case VT_LONG:
5591 tstr = "long";
5592 goto add_tstr;
5593 case VT_LLONG:
5594 tstr = "long long";
5595 goto add_tstr;
5596 case VT_FLOAT:
5597 tstr = "float";
5598 goto add_tstr;
5599 case VT_DOUBLE:
5600 tstr = "double";
5601 goto add_tstr;
5602 case VT_LDOUBLE:
5603 tstr = "long double";
5604 add_tstr:
5605 pstrcat(buf, buf_size, tstr);
5606 break;
5607 case VT_ENUM:
5608 case VT_STRUCT:
5609 if (bt == VT_STRUCT)
5610 tstr = "struct ";
5611 else
5612 tstr = "enum ";
5613 pstrcat(buf, buf_size, tstr);
5614 v = type->ref->v & ~SYM_STRUCT;
5615 if (v >= SYM_FIRST_ANOM)
5616 pstrcat(buf, buf_size, "<anonymous>");
5617 else
5618 pstrcat(buf, buf_size, get_tok_str(v, NULL));
5619 break;
5620 case VT_FUNC:
5621 s = type->ref;
5622 type_to_str(buf, buf_size, &s->type, varstr);
5623 pstrcat(buf, buf_size, "(");
5624 sa = s->next;
5625 while (sa != NULL) {
5626 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
5627 pstrcat(buf, buf_size, buf1);
5628 sa = sa->next;
5629 if (sa)
5630 pstrcat(buf, buf_size, ", ");
5632 pstrcat(buf, buf_size, ")");
5633 goto no_var;
5634 case VT_PTR:
5635 s = type->ref;
5636 pstrcpy(buf1, sizeof(buf1), "*");
5637 if (varstr)
5638 pstrcat(buf1, sizeof(buf1), varstr);
5639 type_to_str(buf, buf_size, &s->type, buf1);
5640 goto no_var;
5642 if (varstr) {
5643 pstrcat(buf, buf_size, " ");
5644 pstrcat(buf, buf_size, varstr);
5646 no_var: ;
5649 /* verify type compatibility to store vtop in 'dt' type, and generate
5650 casts if needed. */
5651 static void gen_assign_cast(CType *dt)
5653 CType *st;
5654 char buf1[256], buf2[256];
5655 int dbt, sbt;
5657 st = &vtop->type; /* source type */
5658 dbt = dt->t & VT_BTYPE;
5659 sbt = st->t & VT_BTYPE;
5660 if (dbt == VT_PTR) {
5661 /* special cases for pointers */
5662 /* a function is implicitely a function pointer */
5663 if (sbt == VT_FUNC) {
5664 if (!is_compatible_types(pointed_type(dt), st))
5665 goto error;
5666 else
5667 goto type_ok;
5669 /* '0' can also be a pointer */
5670 if (sbt == VT_INT &&
5671 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
5672 vtop->c.i == 0)
5673 goto type_ok;
5674 /* accept implicit pointer to integer cast with warning */
5675 if (sbt == VT_BYTE || sbt == VT_SHORT ||
5676 sbt == VT_INT || sbt == VT_LLONG) {
5677 warning("assignment makes pointer from integer without a cast");
5678 goto type_ok;
5680 } else if (dbt == VT_BYTE || dbt == VT_SHORT ||
5681 dbt == VT_INT || dbt == VT_LLONG) {
5682 if (sbt == VT_PTR || sbt == VT_FUNC) {
5683 warning("assignment makes integer from pointer without a cast");
5684 goto type_ok;
5687 if (!is_compatible_types(dt, st)) {
5688 error:
5689 type_to_str(buf1, sizeof(buf1), st, NULL);
5690 type_to_str(buf2, sizeof(buf2), dt, NULL);
5691 error("cannot cast '%s' to '%s'", buf1, buf2);
5693 type_ok:
5694 gen_cast(dt);
5697 /* store vtop in lvalue pushed on stack */
5698 void vstore(void)
5700 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
5701 GFuncContext gf;
5703 ft = vtop[-1].type.t;
5704 sbt = vtop->type.t & VT_BTYPE;
5705 dbt = ft & VT_BTYPE;
5706 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
5707 (sbt == VT_INT && dbt == VT_SHORT)) {
5708 /* optimize char/short casts */
5709 delayed_cast = VT_MUSTCAST;
5710 vtop->type.t = ft & VT_TYPE;
5711 } else {
5712 delayed_cast = 0;
5713 gen_assign_cast(&vtop[-1].type);
5716 if (sbt == VT_STRUCT) {
5717 /* if structure, only generate pointer */
5718 /* structure assignment : generate memcpy */
5719 /* XXX: optimize if small size */
5720 if (!nocode_wanted) {
5721 vdup();
5722 gfunc_start(&gf, FUNC_CDECL);
5723 /* type size */
5724 size = type_size(&vtop->type, &align);
5725 vpushi(size);
5726 gfunc_param(&gf);
5727 /* source */
5728 vtop->type.t = VT_INT;
5729 gaddrof();
5730 gfunc_param(&gf);
5731 /* destination */
5732 vswap();
5733 vtop->type.t = VT_INT;
5734 gaddrof();
5735 gfunc_param(&gf);
5737 save_regs(0);
5738 vpush_global_sym(&func_old_type, TOK_memcpy);
5739 gfunc_call(&gf);
5740 } else {
5741 vswap();
5742 vpop();
5744 /* leave source on stack */
5745 } else if (ft & VT_BITFIELD) {
5746 /* bitfield store handling */
5747 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
5748 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5749 /* remove bit field info to avoid loops */
5750 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
5752 /* duplicate destination */
5753 vdup();
5754 vtop[-1] = vtop[-2];
5756 /* mask and shift source */
5757 vpushi((1 << bit_size) - 1);
5758 gen_op('&');
5759 vpushi(bit_pos);
5760 gen_op(TOK_SHL);
5761 /* load destination, mask and or with source */
5762 vswap();
5763 vpushi(~(((1 << bit_size) - 1) << bit_pos));
5764 gen_op('&');
5765 gen_op('|');
5766 /* store result */
5767 vstore();
5768 } else {
5769 #ifdef CONFIG_TCC_BCHECK
5770 /* bound check case */
5771 if (vtop[-1].r & VT_MUSTBOUND) {
5772 vswap();
5773 gbound();
5774 vswap();
5776 #endif
5777 if (!nocode_wanted) {
5778 rc = RC_INT;
5779 if (is_float(ft))
5780 rc = RC_FLOAT;
5781 r = gv(rc); /* generate value */
5782 /* if lvalue was saved on stack, must read it */
5783 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
5784 SValue sv;
5785 t = get_reg(RC_INT);
5786 sv.type.t = VT_INT;
5787 sv.r = VT_LOCAL | VT_LVAL;
5788 sv.c.ul = vtop[-1].c.ul;
5789 load(t, &sv);
5790 vtop[-1].r = t | VT_LVAL;
5792 store(r, vtop - 1);
5793 /* two word case handling : store second register at word + 4 */
5794 if ((ft & VT_BTYPE) == VT_LLONG) {
5795 vswap();
5796 /* convert to int to increment easily */
5797 vtop->type.t = VT_INT;
5798 gaddrof();
5799 vpushi(4);
5800 gen_op('+');
5801 vtop->r |= VT_LVAL;
5802 vswap();
5803 /* XXX: it works because r2 is spilled last ! */
5804 store(vtop->r2, vtop - 1);
5807 vswap();
5808 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5809 vtop->r |= delayed_cast;
5813 /* post defines POST/PRE add. c is the token ++ or -- */
5814 void inc(int post, int c)
5816 test_lvalue();
5817 vdup(); /* save lvalue */
5818 if (post) {
5819 gv_dup(); /* duplicate value */
5820 vrotb(3);
5821 vrotb(3);
5823 /* add constant */
5824 vpushi(c - TOK_MID);
5825 gen_op('+');
5826 vstore(); /* store value */
5827 if (post)
5828 vpop(); /* if post op, return saved value */
5831 /* Parse GNUC __attribute__ extension. Currently, the following
5832 extensions are recognized:
5833 - aligned(n) : set data/function alignment.
5834 - section(x) : generate data/code in this section.
5835 - unused : currently ignored, but may be used someday.
5837 static void parse_attribute(AttributeDef *ad)
5839 int t, n;
5841 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
5842 next();
5843 skip('(');
5844 skip('(');
5845 while (tok != ')') {
5846 if (tok < TOK_IDENT)
5847 expect("attribute name");
5848 t = tok;
5849 next();
5850 switch(t) {
5851 case TOK_SECTION1:
5852 case TOK_SECTION2:
5853 skip('(');
5854 if (tok != TOK_STR)
5855 expect("section name");
5856 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
5857 next();
5858 skip(')');
5859 break;
5860 case TOK_ALIGNED1:
5861 case TOK_ALIGNED2:
5862 if (tok == '(') {
5863 next();
5864 n = expr_const();
5865 if (n <= 0 || (n & (n - 1)) != 0)
5866 error("alignment must be a positive power of two");
5867 skip(')');
5868 } else {
5869 n = MAX_ALIGN;
5871 ad->aligned = n;
5872 break;
5873 case TOK_UNUSED1:
5874 case TOK_UNUSED2:
5875 /* currently, no need to handle it because tcc does not
5876 track unused objects */
5877 break;
5878 case TOK_NORETURN1:
5879 case TOK_NORETURN2:
5880 /* currently, no need to handle it because tcc does not
5881 track unused objects */
5882 break;
5883 case TOK_CDECL1:
5884 case TOK_CDECL2:
5885 case TOK_CDECL3:
5886 ad->func_call = FUNC_CDECL;
5887 break;
5888 case TOK_STDCALL1:
5889 case TOK_STDCALL2:
5890 case TOK_STDCALL3:
5891 ad->func_call = FUNC_STDCALL;
5892 break;
5893 default:
5894 // warning("'%s' attribute ignored", get_tok_str(t, NULL));
5895 /* skip parameters */
5896 /* XXX: skip parenthesis too */
5897 if (tok == '(') {
5898 next();
5899 while (tok != ')' && tok != -1)
5900 next();
5901 next();
5903 break;
5905 if (tok != ',')
5906 break;
5907 next();
5909 skip(')');
5910 skip(')');
5914 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5915 static void struct_decl(CType *type, int u)
5917 int a, v, size, align, maxalign, c, offset;
5918 int bit_size, bit_pos, bsize, bt, lbit_pos;
5919 Sym *s, *ss, **ps;
5920 AttributeDef ad;
5921 CType type1, btype;
5923 a = tok; /* save decl type */
5924 next();
5925 if (tok != '{') {
5926 v = tok;
5927 next();
5928 /* struct already defined ? return it */
5929 if (v < TOK_IDENT)
5930 expect("struct/union/enum name");
5931 s = struct_find(v);
5932 if (s) {
5933 if (s->type.t != a)
5934 error("invalid type");
5935 goto do_decl;
5937 } else {
5938 v = anon_sym++;
5940 type1.t = a;
5941 s = sym_push(v | SYM_STRUCT, &type1, 0, 0);
5942 /* put struct/union/enum name in type */
5943 do_decl:
5944 type->t = u;
5945 type->ref = s;
5947 if (tok == '{') {
5948 next();
5949 if (s->c)
5950 error("struct/union/enum already defined");
5951 /* cannot be empty */
5952 c = 0;
5953 /* non empty enums are not allowed */
5954 if (a == TOK_ENUM) {
5955 for(;;) {
5956 v = tok;
5957 if (v < TOK_UIDENT)
5958 expect("identifier");
5959 next();
5960 if (tok == '=') {
5961 next();
5962 c = expr_const();
5964 /* enum symbols have static storage */
5965 ss = sym_push(v, &int_type, VT_CONST, c);
5966 ss->type.t |= VT_STATIC;
5967 if (tok != ',')
5968 break;
5969 next();
5970 c++;
5971 /* NOTE: we accept a trailing comma */
5972 if (tok == '}')
5973 break;
5975 skip('}');
5976 } else {
5977 maxalign = 1;
5978 ps = &s->next;
5979 bit_pos = 0;
5980 offset = 0;
5981 while (tok != '}') {
5982 parse_btype(&btype, &ad);
5983 while (1) {
5984 bit_size = -1;
5985 v = 0;
5986 type1 = btype;
5987 if (tok != ':') {
5988 type_decl(&type1, &ad, &v, TYPE_DIRECT);
5989 if ((type1.t & VT_BTYPE) == VT_FUNC ||
5990 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
5991 error("invalid type for '%s'",
5992 get_tok_str(v, NULL));
5994 if (tok == ':') {
5995 next();
5996 bit_size = expr_const();
5997 /* XXX: handle v = 0 case for messages */
5998 if (bit_size < 0)
5999 error("negative width in bit-field '%s'",
6000 get_tok_str(v, NULL));
6001 if (v && bit_size == 0)
6002 error("zero width for bit-field '%s'",
6003 get_tok_str(v, NULL));
6005 size = type_size(&type1, &align);
6006 lbit_pos = 0;
6007 if (bit_size >= 0) {
6008 bt = type1.t & VT_BTYPE;
6009 if (bt != VT_INT &&
6010 bt != VT_BYTE &&
6011 bt != VT_SHORT &&
6012 bt != VT_ENUM)
6013 error("bitfields must have scalar type");
6014 bsize = size * 8;
6015 if (bit_size > bsize) {
6016 error("width of '%s' exceeds its type",
6017 get_tok_str(v, NULL));
6018 } else if (bit_size == bsize) {
6019 /* no need for bit fields */
6020 bit_pos = 0;
6021 } else if (bit_size == 0) {
6022 /* XXX: what to do if only padding in a
6023 structure ? */
6024 /* zero size: means to pad */
6025 if (bit_pos > 0)
6026 bit_pos = bsize;
6027 } else {
6028 /* we do not have enough room ? */
6029 if ((bit_pos + bit_size) > bsize)
6030 bit_pos = 0;
6031 lbit_pos = bit_pos;
6032 /* XXX: handle LSB first */
6033 type1.t |= VT_BITFIELD |
6034 (bit_pos << VT_STRUCT_SHIFT) |
6035 (bit_size << (VT_STRUCT_SHIFT + 6));
6036 bit_pos += bit_size;
6038 } else {
6039 bit_pos = 0;
6041 if (v) {
6042 /* add new memory data only if starting
6043 bit field */
6044 if (lbit_pos == 0) {
6045 if (a == TOK_STRUCT) {
6046 c = (c + align - 1) & -align;
6047 offset = c;
6048 c += size;
6049 } else {
6050 offset = 0;
6051 if (size > c)
6052 c = size;
6054 if (align > maxalign)
6055 maxalign = align;
6057 #if 0
6058 printf("add field %s offset=%d",
6059 get_tok_str(v, NULL), offset);
6060 if (type1.t & VT_BITFIELD) {
6061 printf(" pos=%d size=%d",
6062 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
6063 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
6065 printf("\n");
6066 #endif
6067 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
6068 *ps = ss;
6069 ps = &ss->next;
6071 if (tok == ';' || tok == TOK_EOF)
6072 break;
6073 skip(',');
6075 skip(';');
6077 skip('}');
6078 /* store size and alignment */
6079 s->c = (c + maxalign - 1) & -maxalign;
6080 s->r = maxalign;
6085 /* return 0 if no type declaration. otherwise, return the basic type
6086 and skip it.
6088 static int parse_btype(CType *type, AttributeDef *ad)
6090 int t, u, type_found;
6091 Sym *s;
6092 CType type1;
6094 memset(ad, 0, sizeof(AttributeDef));
6095 type_found = 0;
6096 t = 0;
6097 while(1) {
6098 switch(tok) {
6099 case TOK_EXTENSION:
6100 /* currently, we really ignore extension */
6101 next();
6102 continue;
6104 /* basic types */
6105 case TOK_CHAR:
6106 u = VT_BYTE;
6107 basic_type:
6108 next();
6109 basic_type1:
6110 if ((t & VT_BTYPE) != 0)
6111 error("too many basic types");
6112 t |= u;
6113 break;
6114 case TOK_VOID:
6115 u = VT_VOID;
6116 goto basic_type;
6117 case TOK_SHORT:
6118 u = VT_SHORT;
6119 goto basic_type;
6120 case TOK_INT:
6121 next();
6122 break;
6123 case TOK_LONG:
6124 next();
6125 if ((t & VT_BTYPE) == VT_DOUBLE) {
6126 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
6127 } else if ((t & VT_BTYPE) == VT_LONG) {
6128 t = (t & ~VT_BTYPE) | VT_LLONG;
6129 } else {
6130 u = VT_LONG;
6131 goto basic_type1;
6133 break;
6134 case TOK_BOOL:
6135 u = VT_BOOL;
6136 goto basic_type;
6137 case TOK_FLOAT:
6138 u = VT_FLOAT;
6139 goto basic_type;
6140 case TOK_DOUBLE:
6141 next();
6142 if ((t & VT_BTYPE) == VT_LONG) {
6143 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
6144 } else {
6145 u = VT_DOUBLE;
6146 goto basic_type1;
6148 break;
6149 case TOK_ENUM:
6150 struct_decl(&type1, VT_ENUM);
6151 basic_type2:
6152 u = type1.t;
6153 type->ref = type1.ref;
6154 goto basic_type1;
6155 case TOK_STRUCT:
6156 case TOK_UNION:
6157 struct_decl(&type1, VT_STRUCT);
6158 goto basic_type2;
6160 /* type modifiers */
6161 case TOK_CONST1:
6162 case TOK_CONST2:
6163 case TOK_CONST3:
6164 case TOK_VOLATILE1:
6165 case TOK_VOLATILE2:
6166 case TOK_VOLATILE3:
6167 case TOK_REGISTER:
6168 case TOK_SIGNED1:
6169 case TOK_SIGNED2:
6170 case TOK_SIGNED3:
6171 case TOK_AUTO:
6172 case TOK_RESTRICT1:
6173 case TOK_RESTRICT2:
6174 case TOK_RESTRICT3:
6175 next();
6176 break;
6177 case TOK_UNSIGNED:
6178 t |= VT_UNSIGNED;
6179 next();
6180 break;
6182 /* storage */
6183 case TOK_EXTERN:
6184 t |= VT_EXTERN;
6185 next();
6186 break;
6187 case TOK_STATIC:
6188 t |= VT_STATIC;
6189 next();
6190 break;
6191 case TOK_TYPEDEF:
6192 t |= VT_TYPEDEF;
6193 next();
6194 break;
6195 case TOK_INLINE1:
6196 case TOK_INLINE2:
6197 case TOK_INLINE3:
6198 t |= VT_INLINE;
6199 next();
6200 break;
6202 /* GNUC attribute */
6203 case TOK_ATTRIBUTE1:
6204 case TOK_ATTRIBUTE2:
6205 parse_attribute(ad);
6206 break;
6207 /* GNUC typeof */
6208 case TOK_TYPEOF1:
6209 case TOK_TYPEOF2:
6210 case TOK_TYPEOF3:
6211 next();
6212 parse_expr_type(&type1);
6213 goto basic_type2;
6214 default:
6215 s = sym_find(tok);
6216 if (!s || !(s->type.t & VT_TYPEDEF))
6217 goto the_end;
6218 t |= (s->type.t & ~VT_TYPEDEF);
6219 type->ref = s->type.ref;
6220 next();
6221 break;
6223 type_found = 1;
6225 the_end:
6226 /* long is never used as type */
6227 if ((t & VT_BTYPE) == VT_LONG)
6228 t = (t & ~VT_BTYPE) | VT_INT;
6229 type->t = t;
6230 return type_found;
6233 /* convert a function parameter type (array to pointer and function to
6234 function pointer) */
6235 static inline void convert_parameter_type(CType *pt)
6237 /* array must be transformed to pointer according to ANSI C */
6238 pt->t &= ~VT_ARRAY;
6239 if ((pt->t & VT_BTYPE) == VT_FUNC) {
6240 mk_pointer(pt);
6244 static void post_type(CType *type, AttributeDef *ad)
6246 int n, l, t1;
6247 Sym **plast, *s, *first;
6248 AttributeDef ad1;
6249 CType pt;
6251 if (tok == '(') {
6252 /* function declaration */
6253 next();
6254 l = 0;
6255 first = NULL;
6256 plast = &first;
6257 while (tok != ')') {
6258 /* read param name and compute offset */
6259 if (l != FUNC_OLD) {
6260 if (!parse_btype(&pt, &ad1)) {
6261 if (l) {
6262 error("invalid type");
6263 } else {
6264 l = FUNC_OLD;
6265 goto old_proto;
6268 l = FUNC_NEW;
6269 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
6270 break;
6271 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
6272 if ((pt.t & VT_BTYPE) == VT_VOID)
6273 error("parameter declared as void");
6274 } else {
6275 old_proto:
6276 n = tok;
6277 pt.t = VT_INT;
6278 next();
6280 convert_parameter_type(&pt);
6281 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
6282 *plast = s;
6283 plast = &s->next;
6284 if (tok == ',') {
6285 next();
6286 if (l == FUNC_NEW && tok == TOK_DOTS) {
6287 l = FUNC_ELLIPSIS;
6288 next();
6289 break;
6293 /* if no parameters, then old type prototype */
6294 if (l == 0)
6295 l = FUNC_OLD;
6296 skip(')');
6297 t1 = type->t & VT_STORAGE;
6298 type->t &= ~VT_STORAGE;
6299 post_type(type, ad);
6300 /* we push a anonymous symbol which will contain the function prototype */
6301 s = sym_push(SYM_FIELD, type, ad->func_call, l);
6302 s->next = first;
6303 type->t = t1 | VT_FUNC;
6304 type->ref = s;
6305 } else if (tok == '[') {
6306 /* array definition */
6307 next();
6308 n = -1;
6309 if (tok != ']') {
6310 n = expr_const();
6311 if (n < 0)
6312 error("invalid array size");
6314 skip(']');
6315 /* parse next post type */
6316 t1 = type->t & VT_STORAGE;
6317 type->t &= ~VT_STORAGE;
6318 post_type(type, ad);
6320 /* we push a anonymous symbol which will contain the array
6321 element type */
6322 s = sym_push(SYM_FIELD, type, 0, n);
6323 type->t = t1 | VT_ARRAY | VT_PTR;
6324 type->ref = s;
6328 /* Parse a type declaration (except basic type), and return the type
6329 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6330 expected. 'type' should contain the basic type. 'ad' is the
6331 attribute definition of the basic type. It can be modified by
6332 type_decl().
6334 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
6336 Sym *s;
6337 CType type1, *type2;
6339 while (tok == '*') {
6340 next();
6341 redo:
6342 switch(tok) {
6343 case TOK_CONST1:
6344 case TOK_CONST2:
6345 case TOK_CONST3:
6346 case TOK_VOLATILE1:
6347 case TOK_VOLATILE2:
6348 case TOK_VOLATILE3:
6349 case TOK_RESTRICT1:
6350 case TOK_RESTRICT2:
6351 case TOK_RESTRICT3:
6352 next();
6353 goto redo;
6355 mk_pointer(type);
6358 /* XXX: clarify attribute handling */
6359 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6360 parse_attribute(ad);
6362 /* recursive type */
6363 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6364 type1.t = 0; /* XXX: same as int */
6365 if (tok == '(') {
6366 next();
6367 /* XXX: this is not correct to modify 'ad' at this point, but
6368 the syntax is not clear */
6369 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6370 parse_attribute(ad);
6371 type_decl(&type1, ad, v, td);
6372 skip(')');
6373 } else {
6374 /* type identifier */
6375 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
6376 *v = tok;
6377 next();
6378 } else {
6379 if (!(td & TYPE_ABSTRACT))
6380 expect("identifier");
6381 *v = 0;
6384 post_type(type, ad);
6385 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6386 parse_attribute(ad);
6387 if (!type1.t)
6388 return;
6389 /* append type at the end of type1 */
6390 type2 = &type1;
6391 for(;;) {
6392 s = type2->ref;
6393 type2 = &s->type;
6394 if (!type2->t) {
6395 *type2 = *type;
6396 break;
6399 *type = type1;
6402 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6403 static int lvalue_type(int t)
6405 int bt, r;
6406 r = VT_LVAL;
6407 bt = t & VT_BTYPE;
6408 if (bt == VT_BYTE || bt == VT_BOOL)
6409 r |= VT_LVAL_BYTE;
6410 else if (bt == VT_SHORT)
6411 r |= VT_LVAL_SHORT;
6412 else
6413 return r;
6414 if (t & VT_UNSIGNED)
6415 r |= VT_LVAL_UNSIGNED;
6416 return r;
6419 /* indirection with full error checking and bound check */
6420 static void indir(void)
6422 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6423 expect("pointer");
6424 if ((vtop->r & VT_LVAL) && !nocode_wanted)
6425 gv(RC_INT);
6426 vtop->type = *pointed_type(&vtop->type);
6427 /* an array is never an lvalue */
6428 if (!(vtop->type.t & VT_ARRAY)) {
6429 vtop->r |= lvalue_type(vtop->type.t);
6430 /* if bound checking, the referenced pointer must be checked */
6431 if (do_bounds_check)
6432 vtop->r |= VT_MUSTBOUND;
6436 /* pass a parameter to a function and do type checking and casting */
6437 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
6439 int func_type;
6440 CType type;
6442 func_type = func->c;
6443 if (func_type == FUNC_OLD ||
6444 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
6445 /* default casting : only need to convert float to double */
6446 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
6447 type.t = VT_DOUBLE;
6448 gen_cast(&type);
6450 } else if (arg == NULL) {
6451 error("too many arguments to function");
6452 } else {
6453 gen_assign_cast(&arg->type);
6455 if (!nocode_wanted) {
6456 gfunc_param(gf);
6457 } else {
6458 vpop();
6462 /* parse an expression of the form '(type)' or '(expr)' and return its
6463 type */
6464 static void parse_expr_type(CType *type)
6466 int n;
6467 AttributeDef ad;
6469 skip('(');
6470 if (parse_btype(type, &ad)) {
6471 type_decl(type, &ad, &n, TYPE_ABSTRACT);
6472 } else {
6473 expr_type(type);
6475 skip(')');
6478 static void vpush_tokc(int t)
6480 CType type;
6481 type.t = t;
6482 vsetc(&type, VT_CONST, &tokc);
6485 static void unary(void)
6487 int n, t, align, size, r;
6488 CType type;
6489 Sym *s;
6490 GFuncContext gf;
6491 AttributeDef ad;
6493 /* XXX: GCC 2.95.3 does not generate a table although it should be
6494 better here */
6495 tok_next:
6496 switch(tok) {
6497 case TOK_EXTENSION:
6498 next();
6499 goto tok_next;
6500 case TOK_CINT:
6501 case TOK_CCHAR:
6502 case TOK_LCHAR:
6503 vpushi(tokc.i);
6504 next();
6505 break;
6506 case TOK_CUINT:
6507 vpush_tokc(VT_INT | VT_UNSIGNED);
6508 next();
6509 break;
6510 case TOK_CLLONG:
6511 vpush_tokc(VT_LLONG);
6512 next();
6513 break;
6514 case TOK_CULLONG:
6515 vpush_tokc(VT_LLONG | VT_UNSIGNED);
6516 next();
6517 break;
6518 case TOK_CFLOAT:
6519 vpush_tokc(VT_FLOAT);
6520 next();
6521 break;
6522 case TOK_CDOUBLE:
6523 vpush_tokc(VT_DOUBLE);
6524 next();
6525 break;
6526 case TOK_CLDOUBLE:
6527 vpush_tokc(VT_LDOUBLE);
6528 next();
6529 break;
6530 case TOK___FUNCTION__:
6531 if (!gnu_ext)
6532 goto tok_identifier;
6533 /* fall thru */
6534 case TOK___FUNC__:
6536 void *ptr;
6537 int len;
6538 /* special function name identifier */
6539 len = strlen(funcname) + 1;
6540 /* generate char[len] type */
6541 type.t = VT_BYTE;
6542 mk_pointer(&type);
6543 type.t |= VT_ARRAY;
6544 type.ref->c = len;
6545 vpush_ref(&type, data_section, data_section->data_offset, len);
6546 ptr = section_ptr_add(data_section, len);
6547 memcpy(ptr, funcname, len);
6548 next();
6550 break;
6551 case TOK_LSTR:
6552 t = VT_INT;
6553 goto str_init;
6554 case TOK_STR:
6555 /* string parsing */
6556 t = VT_BYTE;
6557 str_init:
6558 type.t = t;
6559 mk_pointer(&type);
6560 type.t |= VT_ARRAY;
6561 memset(&ad, 0, sizeof(AttributeDef));
6562 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
6563 break;
6564 case '(':
6565 next();
6566 /* cast ? */
6567 if (parse_btype(&type, &ad)) {
6568 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
6569 skip(')');
6570 /* check ISOC99 compound literal */
6571 if (tok == '{') {
6572 /* data is allocated locally by default */
6573 if (global_expr)
6574 r = VT_CONST;
6575 else
6576 r = VT_LOCAL;
6577 /* all except arrays are lvalues */
6578 if (!(type.t & VT_ARRAY))
6579 r |= lvalue_type(type.t);
6580 memset(&ad, 0, sizeof(AttributeDef));
6581 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
6582 } else {
6583 unary();
6584 gen_cast(&type);
6586 } else if (tok == '{') {
6587 /* save all registers */
6588 save_regs(0);
6589 /* statement expression : we do not accept break/continue
6590 inside as GCC does */
6591 block(NULL, NULL, NULL, NULL, 0, 1);
6592 skip(')');
6593 } else {
6594 gexpr();
6595 skip(')');
6597 break;
6598 case '*':
6599 next();
6600 unary();
6601 indir();
6602 break;
6603 case '&':
6604 next();
6605 unary();
6606 /* functions names must be treated as function pointers,
6607 except for unary '&' and sizeof. Since we consider that
6608 functions are not lvalues, we only have to handle it
6609 there and in function calls. */
6610 /* arrays can also be used although they are not lvalues */
6611 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
6612 !(vtop->type.t & VT_ARRAY))
6613 test_lvalue();
6614 mk_pointer(&vtop->type);
6615 gaddrof();
6616 break;
6617 case '!':
6618 next();
6619 unary();
6620 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
6621 vtop->c.i = !vtop->c.i;
6622 else if ((vtop->r & VT_VALMASK) == VT_CMP)
6623 vtop->c.i = vtop->c.i ^ 1;
6624 else
6625 vseti(VT_JMP, gtst(1, 0));
6626 break;
6627 case '~':
6628 next();
6629 unary();
6630 vpushi(-1);
6631 gen_op('^');
6632 break;
6633 case '+':
6634 next();
6635 /* in order to force cast, we add zero */
6636 unary();
6637 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
6638 error("pointer not accepted for unary plus");
6639 vpushi(0);
6640 gen_op('+');
6641 break;
6642 case TOK_SIZEOF:
6643 case TOK_ALIGNOF1:
6644 case TOK_ALIGNOF2:
6645 t = tok;
6646 next();
6647 if (tok == '(') {
6648 parse_expr_type(&type);
6649 } else {
6650 unary_type(&type);
6652 size = type_size(&type, &align);
6653 if (t == TOK_SIZEOF)
6654 vpushi(size);
6655 else
6656 vpushi(align);
6657 break;
6659 case TOK_INC:
6660 case TOK_DEC:
6661 t = tok;
6662 next();
6663 unary();
6664 inc(0, t);
6665 break;
6666 case '-':
6667 next();
6668 vpushi(0);
6669 unary();
6670 gen_op('-');
6671 break;
6672 case TOK_LAND:
6673 if (!gnu_ext)
6674 goto tok_identifier;
6675 next();
6676 /* allow to take the address of a label */
6677 if (tok < TOK_UIDENT)
6678 expect("label identifier");
6679 s = label_find(tok);
6680 if (!s) {
6681 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
6682 } else {
6683 if (s->r == LABEL_DECLARED)
6684 s->r = LABEL_FORWARD;
6686 if (!s->type.t) {
6687 s->type.t = VT_VOID;
6688 mk_pointer(&s->type);
6689 s->type.t |= VT_STATIC;
6691 vset(&s->type, VT_CONST | VT_SYM, 0);
6692 vtop->sym = s;
6693 next();
6694 break;
6695 default:
6696 tok_identifier:
6697 t = tok;
6698 next();
6699 if (t < TOK_UIDENT)
6700 expect("identifier");
6701 s = sym_find(t);
6702 if (!s) {
6703 if (tok != '(')
6704 error("'%s' undeclared", get_tok_str(t, NULL));
6705 /* for simple function calls, we tolerate undeclared
6706 external reference to int() function */
6707 s = external_global_sym(t, &func_old_type, 0);
6709 vset(&s->type, s->r, s->c);
6710 /* if forward reference, we must point to s */
6711 if (vtop->r & VT_SYM) {
6712 vtop->sym = s;
6713 vtop->c.ul = 0;
6715 break;
6718 /* post operations */
6719 while (1) {
6720 if (tok == TOK_INC || tok == TOK_DEC) {
6721 inc(1, tok);
6722 next();
6723 } else if (tok == '.' || tok == TOK_ARROW) {
6724 /* field */
6725 if (tok == TOK_ARROW)
6726 indir();
6727 test_lvalue();
6728 gaddrof();
6729 next();
6730 /* expect pointer on structure */
6731 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
6732 expect("struct or union");
6733 s = vtop->type.ref;
6734 /* find field */
6735 tok |= SYM_FIELD;
6736 while ((s = s->next) != NULL) {
6737 if (s->v == tok)
6738 break;
6740 if (!s)
6741 error("field not found");
6742 /* add field offset to pointer */
6743 vtop->type = char_pointer_type; /* change type to 'char *' */
6744 vpushi(s->c);
6745 gen_op('+');
6746 /* change type to field type, and set to lvalue */
6747 vtop->type = s->type;
6748 /* an array is never an lvalue */
6749 if (!(vtop->type.t & VT_ARRAY)) {
6750 vtop->r |= lvalue_type(vtop->type.t);
6751 /* if bound checking, the referenced pointer must be checked */
6752 if (do_bounds_check)
6753 vtop->r |= VT_MUSTBOUND;
6755 next();
6756 } else if (tok == '[') {
6757 next();
6758 gexpr();
6759 gen_op('+');
6760 indir();
6761 skip(']');
6762 } else if (tok == '(') {
6763 SValue ret;
6764 Sym *sa;
6766 /* function call */
6767 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
6768 /* pointer test (no array accepted) */
6769 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
6770 vtop->type = *pointed_type(&vtop->type);
6771 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
6772 goto error_func;
6773 } else {
6774 error_func:
6775 expect("function pointer");
6777 } else {
6778 vtop->r &= ~VT_LVAL; /* no lvalue */
6780 /* get return type */
6781 s = vtop->type.ref;
6782 if (!nocode_wanted) {
6783 save_regs(0); /* save used temporary registers */
6784 gfunc_start(&gf, s->r);
6786 next();
6787 sa = s->next; /* first parameter */
6788 #ifdef INVERT_FUNC_PARAMS
6790 int parlevel;
6791 Sym *args, *s1;
6792 ParseState saved_parse_state;
6793 TokenString str;
6795 /* read each argument and store it on a stack */
6796 args = NULL;
6797 if (tok != ')') {
6798 for(;;) {
6799 tok_str_new(&str);
6800 parlevel = 0;
6801 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
6802 tok != TOK_EOF) {
6803 if (tok == '(')
6804 parlevel++;
6805 else if (tok == ')')
6806 parlevel--;
6807 tok_str_add_tok(&str);
6808 next();
6810 tok_str_add(&str, -1); /* end of file added */
6811 tok_str_add(&str, 0);
6812 s1 = sym_push2(&args, 0, 0, (int)str.str);
6813 s1->next = sa; /* add reference to argument */
6814 if (sa)
6815 sa = sa->next;
6816 if (tok == ')')
6817 break;
6818 skip(',');
6822 /* now generate code in reverse order by reading the stack */
6823 save_parse_state(&saved_parse_state);
6824 while (args) {
6825 macro_ptr = (int *)args->c;
6826 next();
6827 expr_eq();
6828 if (tok != -1)
6829 expect("',' or ')'");
6830 gfunc_param_typed(&gf, s, args->next);
6831 s1 = args->prev;
6832 tok_str_free((int *)args->c);
6833 tcc_free(args);
6834 args = s1;
6836 restore_parse_state(&saved_parse_state);
6838 #endif
6839 /* compute first implicit argument if a structure is returned */
6840 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6841 /* get some space for the returned structure */
6842 size = type_size(&s->type, &align);
6843 loc = (loc - size) & -align;
6844 ret.type = s->type;
6845 ret.r = VT_LOCAL | VT_LVAL;
6846 /* pass it as 'int' to avoid structure arg passing
6847 problems */
6848 vseti(VT_LOCAL, loc);
6849 ret.c = vtop->c;
6850 if (!nocode_wanted)
6851 gfunc_param(&gf);
6852 else
6853 vtop--;
6854 } else {
6855 ret.type = s->type;
6856 ret.r2 = VT_CONST;
6857 /* return in register */
6858 if (is_float(ret.type.t)) {
6859 ret.r = REG_FRET;
6860 } else {
6861 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
6862 ret.r2 = REG_LRET;
6863 ret.r = REG_IRET;
6865 ret.c.i = 0;
6867 #ifndef INVERT_FUNC_PARAMS
6868 if (tok != ')') {
6869 for(;;) {
6870 expr_eq();
6871 gfunc_param_typed(&gf, s, sa);
6872 if (sa)
6873 sa = sa->next;
6874 if (tok == ')')
6875 break;
6876 skip(',');
6879 #endif
6880 if (sa)
6881 error("too few arguments to function");
6882 skip(')');
6883 if (!nocode_wanted)
6884 gfunc_call(&gf);
6885 else
6886 vtop--;
6887 /* return value */
6888 vsetc(&ret.type, ret.r, &ret.c);
6889 vtop->r2 = ret.r2;
6890 } else {
6891 break;
6896 static void uneq(void)
6898 int t;
6900 unary();
6901 if (tok == '=' ||
6902 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
6903 tok == TOK_A_XOR || tok == TOK_A_OR ||
6904 tok == TOK_A_SHL || tok == TOK_A_SAR) {
6905 test_lvalue();
6906 t = tok;
6907 next();
6908 if (t == '=') {
6909 expr_eq();
6910 } else {
6911 vdup();
6912 expr_eq();
6913 gen_op(t & 0x7f);
6915 vstore();
6919 static void expr_prod(void)
6921 int t;
6923 uneq();
6924 while (tok == '*' || tok == '/' || tok == '%') {
6925 t = tok;
6926 next();
6927 uneq();
6928 gen_op(t);
6932 static void expr_sum(void)
6934 int t;
6936 expr_prod();
6937 while (tok == '+' || tok == '-') {
6938 t = tok;
6939 next();
6940 expr_prod();
6941 gen_op(t);
6945 static void expr_shift(void)
6947 int t;
6949 expr_sum();
6950 while (tok == TOK_SHL || tok == TOK_SAR) {
6951 t = tok;
6952 next();
6953 expr_sum();
6954 gen_op(t);
6958 static void expr_cmp(void)
6960 int t;
6962 expr_shift();
6963 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
6964 tok == TOK_ULT || tok == TOK_UGE) {
6965 t = tok;
6966 next();
6967 expr_shift();
6968 gen_op(t);
6972 static void expr_cmpeq(void)
6974 int t;
6976 expr_cmp();
6977 while (tok == TOK_EQ || tok == TOK_NE) {
6978 t = tok;
6979 next();
6980 expr_cmp();
6981 gen_op(t);
6985 static void expr_and(void)
6987 expr_cmpeq();
6988 while (tok == '&') {
6989 next();
6990 expr_cmpeq();
6991 gen_op('&');
6995 static void expr_xor(void)
6997 expr_and();
6998 while (tok == '^') {
6999 next();
7000 expr_and();
7001 gen_op('^');
7005 static void expr_or(void)
7007 expr_xor();
7008 while (tok == '|') {
7009 next();
7010 expr_xor();
7011 gen_op('|');
7015 /* XXX: fix this mess */
7016 static void expr_land_const(void)
7018 expr_or();
7019 while (tok == TOK_LAND) {
7020 next();
7021 expr_or();
7022 gen_op(TOK_LAND);
7026 /* XXX: fix this mess */
7027 static void expr_lor_const(void)
7029 expr_land_const();
7030 while (tok == TOK_LOR) {
7031 next();
7032 expr_land_const();
7033 gen_op(TOK_LOR);
7037 /* only used if non constant */
7038 static void expr_land(void)
7040 int t;
7042 expr_or();
7043 if (tok == TOK_LAND) {
7044 t = 0;
7045 for(;;) {
7046 t = gtst(1, t);
7047 if (tok != TOK_LAND) {
7048 vseti(VT_JMPI, t);
7049 break;
7051 next();
7052 expr_or();
7057 static void expr_lor(void)
7059 int t;
7061 expr_land();
7062 if (tok == TOK_LOR) {
7063 t = 0;
7064 for(;;) {
7065 t = gtst(0, t);
7066 if (tok != TOK_LOR) {
7067 vseti(VT_JMP, t);
7068 break;
7070 next();
7071 expr_land();
7076 /* XXX: better constant handling */
7077 static void expr_eq(void)
7079 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
7080 SValue sv;
7081 CType type, type1, type2;
7083 if (const_wanted) {
7084 int c1, c;
7085 expr_lor_const();
7086 if (tok == '?') {
7087 c = vtop->c.i;
7088 vpop();
7089 next();
7090 if (tok == ':' && gnu_ext) {
7091 c1 = c;
7092 } else {
7093 gexpr();
7094 c1 = vtop->c.i;
7095 vpop();
7097 skip(':');
7098 expr_eq();
7099 if (c)
7100 vtop->c.i = c1;
7102 } else {
7103 expr_lor();
7104 if (tok == '?') {
7105 next();
7106 if (vtop != vstack) {
7107 /* needed to avoid having different registers saved in
7108 each branch */
7109 if (is_float(vtop->type.t))
7110 rc = RC_FLOAT;
7111 else
7112 rc = RC_INT;
7113 gv(rc);
7114 save_regs(1);
7116 if (tok == ':' && gnu_ext) {
7117 gv_dup();
7118 tt = gtst(1, 0);
7119 } else {
7120 tt = gtst(1, 0);
7121 gexpr();
7123 type1 = vtop->type;
7124 sv = *vtop; /* save value to handle it later */
7125 vtop--; /* no vpop so that FP stack is not flushed */
7126 skip(':');
7127 u = gjmp(0);
7128 gsym(tt);
7129 expr_eq();
7130 type2 = vtop->type;
7132 t1 = type1.t;
7133 bt1 = t1 & VT_BTYPE;
7134 t2 = type2.t;
7135 bt2 = t2 & VT_BTYPE;
7136 /* cast operands to correct type according to ISOC rules */
7137 if (is_float(bt1) || is_float(bt2)) {
7138 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
7139 type.t = VT_LDOUBLE;
7140 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
7141 type.t = VT_DOUBLE;
7142 } else {
7143 type.t = VT_FLOAT;
7145 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
7146 /* cast to biggest op */
7147 type.t = VT_LLONG;
7148 /* convert to unsigned if it does not fit in a long long */
7149 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
7150 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
7151 type.t |= VT_UNSIGNED;
7152 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
7153 /* XXX: test pointer compatibility */
7154 type = type1;
7155 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
7156 /* XXX: test structure compatibility */
7157 type = type1;
7158 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
7159 /* NOTE: as an extension, we accept void on only one side */
7160 type.t = VT_VOID;
7161 } else {
7162 /* integer operations */
7163 type.t = VT_INT;
7164 /* convert to unsigned if it does not fit in an integer */
7165 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
7166 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
7167 type.t |= VT_UNSIGNED;
7170 /* now we convert second operand */
7171 gen_cast(&type);
7172 rc = RC_INT;
7173 if (is_float(type.t)) {
7174 rc = RC_FLOAT;
7175 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
7176 /* for long longs, we use fixed registers to avoid having
7177 to handle a complicated move */
7178 rc = RC_IRET;
7181 r2 = gv(rc);
7182 /* this is horrible, but we must also convert first
7183 operand */
7184 tt = gjmp(0);
7185 gsym(u);
7186 /* put again first value and cast it */
7187 *vtop = sv;
7188 gen_cast(&type);
7189 r1 = gv(rc);
7190 move_reg(r2, r1);
7191 vtop->r = r2;
7192 gsym(tt);
7197 static void gexpr(void)
7199 while (1) {
7200 expr_eq();
7201 if (tok != ',')
7202 break;
7203 vpop();
7204 next();
7208 /* parse an expression and return its type without any side effect. */
7209 static void expr_type(CType *type)
7211 int a;
7213 a = nocode_wanted;
7214 nocode_wanted = 1;
7215 gexpr();
7216 *type = vtop->type;
7217 vpop();
7218 nocode_wanted = a;
7221 /* parse a unary expression and return its type without any side
7222 effect. */
7223 static void unary_type(CType *type)
7225 int a;
7227 a = nocode_wanted;
7228 nocode_wanted = 1;
7229 unary();
7230 *type = vtop->type;
7231 vpop();
7232 nocode_wanted = a;
7235 /* parse a constant expression and return value in vtop. */
7236 static void expr_const1(void)
7238 int a;
7239 a = const_wanted;
7240 const_wanted = 1;
7241 expr_eq();
7242 const_wanted = a;
7245 /* parse an integer constant and return its value. */
7246 static int expr_const(void)
7248 int c;
7249 expr_const1();
7250 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
7251 expect("constant expression");
7252 c = vtop->c.i;
7253 vpop();
7254 return c;
7257 /* return the label token if current token is a label, otherwise
7258 return zero */
7259 static int is_label(void)
7261 int last_tok;
7263 /* fast test first */
7264 if (tok < TOK_UIDENT)
7265 return 0;
7266 /* no need to save tokc because tok is an identifier */
7267 last_tok = tok;
7268 next();
7269 if (tok == ':') {
7270 next();
7271 return last_tok;
7272 } else {
7273 unget_tok(last_tok);
7274 return 0;
7278 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
7279 int case_reg, int is_expr)
7281 int a, b, c, d;
7282 Sym *s;
7284 /* generate line number info */
7285 if (do_debug &&
7286 (last_line_num != file->line_num || last_ind != ind)) {
7287 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
7288 last_ind = ind;
7289 last_line_num = file->line_num;
7292 if (is_expr) {
7293 /* default return value is (void) */
7294 vpushi(0);
7295 vtop->type.t = VT_VOID;
7298 if (tok == TOK_IF) {
7299 /* if test */
7300 next();
7301 skip('(');
7302 gexpr();
7303 skip(')');
7304 a = gtst(1, 0);
7305 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7306 c = tok;
7307 if (c == TOK_ELSE) {
7308 next();
7309 d = gjmp(0);
7310 gsym(a);
7311 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7312 gsym(d); /* patch else jmp */
7313 } else
7314 gsym(a);
7315 } else if (tok == TOK_WHILE) {
7316 next();
7317 d = ind;
7318 skip('(');
7319 gexpr();
7320 skip(')');
7321 a = gtst(1, 0);
7322 b = 0;
7323 block(&a, &b, case_sym, def_sym, case_reg, 0);
7324 gjmp_addr(d);
7325 gsym(a);
7326 gsym_addr(b, d);
7327 } else if (tok == '{') {
7328 Sym *llabel;
7330 next();
7331 /* record local declaration stack position */
7332 s = local_stack;
7333 llabel = local_label_stack;
7334 /* handle local labels declarations */
7335 if (tok == TOK_LABEL) {
7336 next();
7337 for(;;) {
7338 if (tok < TOK_UIDENT)
7339 expect("label identifier");
7340 label_push(&local_label_stack, tok, LABEL_DECLARED);
7341 next();
7342 if (tok == ',') {
7343 next();
7344 } else {
7345 skip(';');
7346 break;
7350 while (tok != '}') {
7351 decl(VT_LOCAL);
7352 if (tok != '}') {
7353 if (is_expr)
7354 vpop();
7355 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
7358 /* pop locally defined labels */
7359 label_pop(&local_label_stack, llabel);
7360 /* pop locally defined symbols */
7361 sym_pop(&local_stack, s);
7362 next();
7363 } else if (tok == TOK_RETURN) {
7364 next();
7365 if (tok != ';') {
7366 gexpr();
7367 gen_assign_cast(&func_vt);
7368 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
7369 CType type;
7370 /* if returning structure, must copy it to implicit
7371 first pointer arg location */
7372 type = func_vt;
7373 mk_pointer(&type);
7374 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
7375 indir();
7376 vswap();
7377 /* copy structure value to pointer */
7378 vstore();
7379 } else if (is_float(func_vt.t)) {
7380 gv(RC_FRET);
7381 } else {
7382 gv(RC_IRET);
7384 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
7386 skip(';');
7387 rsym = gjmp(rsym); /* jmp */
7388 } else if (tok == TOK_BREAK) {
7389 /* compute jump */
7390 if (!bsym)
7391 error("cannot break");
7392 *bsym = gjmp(*bsym);
7393 next();
7394 skip(';');
7395 } else if (tok == TOK_CONTINUE) {
7396 /* compute jump */
7397 if (!csym)
7398 error("cannot continue");
7399 *csym = gjmp(*csym);
7400 next();
7401 skip(';');
7402 } else if (tok == TOK_FOR) {
7403 int e;
7404 next();
7405 skip('(');
7406 if (tok != ';') {
7407 gexpr();
7408 vpop();
7410 skip(';');
7411 d = ind;
7412 c = ind;
7413 a = 0;
7414 b = 0;
7415 if (tok != ';') {
7416 gexpr();
7417 a = gtst(1, 0);
7419 skip(';');
7420 if (tok != ')') {
7421 e = gjmp(0);
7422 c = ind;
7423 gexpr();
7424 vpop();
7425 gjmp_addr(d);
7426 gsym(e);
7428 skip(')');
7429 block(&a, &b, case_sym, def_sym, case_reg, 0);
7430 gjmp_addr(c);
7431 gsym(a);
7432 gsym_addr(b, c);
7433 } else
7434 if (tok == TOK_DO) {
7435 next();
7436 a = 0;
7437 b = 0;
7438 d = ind;
7439 block(&a, &b, case_sym, def_sym, case_reg, 0);
7440 skip(TOK_WHILE);
7441 skip('(');
7442 gsym(b);
7443 gexpr();
7444 c = gtst(0, 0);
7445 gsym_addr(c, d);
7446 skip(')');
7447 gsym(a);
7448 skip(';');
7449 } else
7450 if (tok == TOK_SWITCH) {
7451 next();
7452 skip('(');
7453 gexpr();
7454 /* XXX: other types than integer */
7455 case_reg = gv(RC_INT);
7456 vpop();
7457 skip(')');
7458 a = 0;
7459 b = gjmp(0); /* jump to first case */
7460 c = 0;
7461 block(&a, csym, &b, &c, case_reg, 0);
7462 /* if no default, jmp after switch */
7463 if (c == 0)
7464 c = ind;
7465 /* default label */
7466 gsym_addr(b, c);
7467 /* break label */
7468 gsym(a);
7469 } else
7470 if (tok == TOK_CASE) {
7471 int v1, v2;
7472 if (!case_sym)
7473 expect("switch");
7474 next();
7475 v1 = expr_const();
7476 v2 = v1;
7477 if (gnu_ext && tok == TOK_DOTS) {
7478 next();
7479 v2 = expr_const();
7480 if (v2 < v1)
7481 warning("empty case range");
7483 /* since a case is like a label, we must skip it with a jmp */
7484 b = gjmp(0);
7485 gsym(*case_sym);
7486 vseti(case_reg, 0);
7487 vpushi(v1);
7488 if (v1 == v2) {
7489 gen_op(TOK_EQ);
7490 *case_sym = gtst(1, 0);
7491 } else {
7492 gen_op(TOK_GE);
7493 *case_sym = gtst(1, 0);
7494 vseti(case_reg, 0);
7495 vpushi(v2);
7496 gen_op(TOK_LE);
7497 *case_sym = gtst(1, *case_sym);
7499 gsym(b);
7500 skip(':');
7501 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7502 } else
7503 if (tok == TOK_DEFAULT) {
7504 next();
7505 skip(':');
7506 if (!def_sym)
7507 expect("switch");
7508 if (*def_sym)
7509 error("too many 'default'");
7510 *def_sym = ind;
7511 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7512 } else
7513 if (tok == TOK_GOTO) {
7514 next();
7515 if (tok == '*' && gnu_ext) {
7516 /* computed goto */
7517 next();
7518 gexpr();
7519 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
7520 expect("pointer");
7521 ggoto();
7522 } else if (tok >= TOK_UIDENT) {
7523 s = label_find(tok);
7524 /* put forward definition if needed */
7525 if (!s) {
7526 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
7527 } else {
7528 if (s->r == LABEL_DECLARED)
7529 s->r = LABEL_FORWARD;
7531 /* label already defined */
7532 if (s->r & LABEL_FORWARD)
7533 s->next = (void *)gjmp((long)s->next);
7534 else
7535 gjmp_addr((long)s->next);
7536 next();
7537 } else {
7538 expect("label identifier");
7540 skip(';');
7541 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
7542 asm_instr();
7543 } else {
7544 b = is_label();
7545 if (b) {
7546 /* label case */
7547 s = label_find(b);
7548 if (s) {
7549 if (s->r == LABEL_DEFINED)
7550 error("duplicate label '%s'", get_tok_str(s->v, NULL));
7551 gsym((long)s->next);
7552 s->r = LABEL_DEFINED;
7553 } else {
7554 s = label_push(&global_label_stack, b, LABEL_DEFINED);
7556 s->next = (void *)ind;
7557 /* we accept this, but it is a mistake */
7558 if (tok == '}') {
7559 warning("deprecated use of label at end of compound statement");
7560 } else {
7561 if (is_expr)
7562 vpop();
7563 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
7565 } else {
7566 /* expression case */
7567 if (tok != ';') {
7568 if (is_expr) {
7569 vpop();
7570 gexpr();
7571 } else {
7572 gexpr();
7573 vpop();
7576 skip(';');
7581 /* t is the array or struct type. c is the array or struct
7582 address. cur_index/cur_field is the pointer to the current
7583 value. 'size_only' is true if only size info is needed (only used
7584 in arrays) */
7585 static void decl_designator(CType *type, Section *sec, unsigned long c,
7586 int *cur_index, Sym **cur_field,
7587 int size_only)
7589 Sym *s, *f;
7590 int notfirst, index, index_last, align, l, nb_elems, elem_size;
7591 CType type1;
7593 notfirst = 0;
7594 elem_size = 0;
7595 nb_elems = 1;
7596 if (gnu_ext && (l = is_label()) != 0)
7597 goto struct_field;
7598 while (tok == '[' || tok == '.') {
7599 if (tok == '[') {
7600 if (!(type->t & VT_ARRAY))
7601 expect("array type");
7602 s = type->ref;
7603 next();
7604 index = expr_const();
7605 if (index < 0 || (s->c >= 0 && index >= s->c))
7606 expect("invalid index");
7607 if (tok == TOK_DOTS && gnu_ext) {
7608 next();
7609 index_last = expr_const();
7610 if (index_last < 0 ||
7611 (s->c >= 0 && index_last >= s->c) ||
7612 index_last < index)
7613 expect("invalid index");
7614 } else {
7615 index_last = index;
7617 skip(']');
7618 if (!notfirst)
7619 *cur_index = index_last;
7620 type = pointed_type(type);
7621 elem_size = type_size(type, &align);
7622 c += index * elem_size;
7623 /* NOTE: we only support ranges for last designator */
7624 nb_elems = index_last - index + 1;
7625 if (nb_elems != 1) {
7626 notfirst = 1;
7627 break;
7629 } else {
7630 next();
7631 l = tok;
7632 next();
7633 struct_field:
7634 if ((type->t & VT_BTYPE) != VT_STRUCT)
7635 expect("struct/union type");
7636 s = type->ref;
7637 l |= SYM_FIELD;
7638 f = s->next;
7639 while (f) {
7640 if (f->v == l)
7641 break;
7642 f = f->next;
7644 if (!f)
7645 expect("field");
7646 if (!notfirst)
7647 *cur_field = f;
7648 /* XXX: fix this mess by using explicit storage field */
7649 type1 = f->type;
7650 type1.t |= (type->t & ~VT_TYPE);
7651 type = &type1;
7652 c += f->c;
7654 notfirst = 1;
7656 if (notfirst) {
7657 if (tok == '=') {
7658 next();
7659 } else {
7660 if (!gnu_ext)
7661 expect("=");
7663 } else {
7664 if (type->t & VT_ARRAY) {
7665 index = *cur_index;
7666 type = pointed_type(type);
7667 c += index * type_size(type, &align);
7668 } else {
7669 f = *cur_field;
7670 if (!f)
7671 error("too many field init");
7672 /* XXX: fix this mess by using explicit storage field */
7673 type1 = f->type;
7674 type1.t |= (type->t & ~VT_TYPE);
7675 type = &type1;
7676 c += f->c;
7679 decl_initializer(type, sec, c, 0, size_only);
7681 /* XXX: make it more general */
7682 if (!size_only && nb_elems > 1) {
7683 unsigned long c_end;
7684 uint8_t *src, *dst;
7685 int i;
7687 if (!sec)
7688 error("range init not supported yet for dynamic storage");
7689 c_end = c + nb_elems * elem_size;
7690 if (c_end > sec->data_allocated)
7691 section_realloc(sec, c_end);
7692 src = sec->data + c;
7693 dst = src;
7694 for(i = 1; i < nb_elems; i++) {
7695 dst += elem_size;
7696 memcpy(dst, src, elem_size);
7701 #define EXPR_VAL 0
7702 #define EXPR_CONST 1
7703 #define EXPR_ANY 2
7705 /* store a value or an expression directly in global data or in local array */
7706 static void init_putv(CType *type, Section *sec, unsigned long c,
7707 int v, int expr_type)
7709 int saved_global_expr, bt, bit_pos, bit_size;
7710 void *ptr;
7711 unsigned long long bit_mask;
7713 switch(expr_type) {
7714 case EXPR_VAL:
7715 vpushi(v);
7716 break;
7717 case EXPR_CONST:
7718 /* compound literals must be allocated globally in this case */
7719 saved_global_expr = global_expr;
7720 global_expr = 1;
7721 expr_const1();
7722 global_expr = saved_global_expr;
7723 /* NOTE: symbols are accepted */
7724 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
7725 error("initializer element is not constant");
7726 break;
7727 case EXPR_ANY:
7728 expr_eq();
7729 break;
7732 if (sec) {
7733 /* XXX: not portable */
7734 /* XXX: generate error if incorrect relocation */
7735 gen_assign_cast(type);
7736 bt = type->t & VT_BTYPE;
7737 ptr = sec->data + c;
7738 /* XXX: make code faster ? */
7739 if (!(type->t & VT_BITFIELD)) {
7740 bit_pos = 0;
7741 bit_size = 32;
7742 bit_mask = -1LL;
7743 } else {
7744 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
7745 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
7746 bit_mask = (1LL << bit_size) - 1;
7748 if ((vtop->r & VT_SYM) &&
7749 (bt == VT_BYTE ||
7750 bt == VT_SHORT ||
7751 bt == VT_DOUBLE ||
7752 bt == VT_LDOUBLE ||
7753 bt == VT_LLONG ||
7754 (bt == VT_INT && bit_size != 32)))
7755 error("initializer element is not computable at load time");
7756 switch(bt) {
7757 case VT_BYTE:
7758 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7759 break;
7760 case VT_SHORT:
7761 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7762 break;
7763 case VT_DOUBLE:
7764 *(double *)ptr = vtop->c.d;
7765 break;
7766 case VT_LDOUBLE:
7767 *(long double *)ptr = vtop->c.ld;
7768 break;
7769 case VT_LLONG:
7770 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
7771 break;
7772 default:
7773 if (vtop->r & VT_SYM) {
7774 greloc(sec, vtop->sym, c, R_DATA_32);
7776 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7777 break;
7779 vtop--;
7780 } else {
7781 vset(type, VT_LOCAL, c);
7782 vswap();
7783 vstore();
7784 vpop();
7788 /* put zeros for variable based init */
7789 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
7791 GFuncContext gf;
7793 if (sec) {
7794 /* nothing to do because globals are already set to zero */
7795 } else {
7796 gfunc_start(&gf, FUNC_CDECL);
7797 vpushi(size);
7798 gfunc_param(&gf);
7799 vpushi(0);
7800 gfunc_param(&gf);
7801 vseti(VT_LOCAL, c);
7802 gfunc_param(&gf);
7803 vpush_global_sym(&func_old_type, TOK_memset);
7804 gfunc_call(&gf);
7808 /* 't' contains the type and storage info. 'c' is the offset of the
7809 object in section 'sec'. If 'sec' is NULL, it means stack based
7810 allocation. 'first' is true if array '{' must be read (multi
7811 dimension implicit array init handling). 'size_only' is true if
7812 size only evaluation is wanted (only for arrays). */
7813 static void decl_initializer(CType *type, Section *sec, unsigned long c,
7814 int first, int size_only)
7816 int index, array_length, n, no_oblock, nb, parlevel, i;
7817 int size1, align1, expr_type;
7818 Sym *s, *f;
7819 CType *t1;
7821 if (type->t & VT_ARRAY) {
7822 s = type->ref;
7823 n = s->c;
7824 array_length = 0;
7825 t1 = pointed_type(type);
7826 size1 = type_size(t1, &align1);
7828 no_oblock = 1;
7829 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
7830 tok == '{') {
7831 skip('{');
7832 no_oblock = 0;
7835 /* only parse strings here if correct type (otherwise: handle
7836 them as ((w)char *) expressions */
7837 if ((tok == TOK_LSTR &&
7838 (t1->t & VT_BTYPE) == VT_INT) ||
7839 (tok == TOK_STR &&
7840 (t1->t & VT_BTYPE) == VT_BYTE)) {
7841 while (tok == TOK_STR || tok == TOK_LSTR) {
7842 int cstr_len, ch;
7843 CString *cstr;
7845 cstr = tokc.cstr;
7846 /* compute maximum number of chars wanted */
7847 if (tok == TOK_STR)
7848 cstr_len = cstr->size;
7849 else
7850 cstr_len = cstr->size / sizeof(int);
7851 cstr_len--;
7852 nb = cstr_len;
7853 if (n >= 0 && nb > (n - array_length))
7854 nb = n - array_length;
7855 if (!size_only) {
7856 if (cstr_len > nb)
7857 warning("initializer-string for array is too long");
7858 /* in order to go faster for common case (char
7859 string in global variable, we handle it
7860 specifically */
7861 if (sec && tok == TOK_STR && size1 == 1) {
7862 memcpy(sec->data + c + array_length, cstr->data, nb);
7863 } else {
7864 for(i=0;i<nb;i++) {
7865 if (tok == TOK_STR)
7866 ch = ((unsigned char *)cstr->data)[i];
7867 else
7868 ch = ((int *)cstr->data)[i];
7869 init_putv(t1, sec, c + (array_length + i) * size1,
7870 ch, EXPR_VAL);
7874 array_length += nb;
7875 next();
7877 /* only add trailing zero if enough storage (no
7878 warning in this case since it is standard) */
7879 if (n < 0 || array_length < n) {
7880 if (!size_only) {
7881 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
7883 array_length++;
7885 } else {
7886 index = 0;
7887 while (tok != '}') {
7888 decl_designator(type, sec, c, &index, NULL, size_only);
7889 if (n >= 0 && index >= n)
7890 error("index too large");
7891 /* must put zero in holes (note that doing it that way
7892 ensures that it even works with designators) */
7893 if (!size_only && array_length < index) {
7894 init_putz(t1, sec, c + array_length * size1,
7895 (index - array_length) * size1);
7897 index++;
7898 if (index > array_length)
7899 array_length = index;
7900 /* special test for multi dimensional arrays (may not
7901 be strictly correct if designators are used at the
7902 same time) */
7903 if (index >= n && no_oblock)
7904 break;
7905 if (tok == '}')
7906 break;
7907 skip(',');
7910 if (!no_oblock)
7911 skip('}');
7912 /* put zeros at the end */
7913 if (!size_only && n >= 0 && array_length < n) {
7914 init_putz(t1, sec, c + array_length * size1,
7915 (n - array_length) * size1);
7917 /* patch type size if needed */
7918 if (n < 0)
7919 s->c = array_length;
7920 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
7921 (sec || !first || tok == '{')) {
7922 int par_count;
7924 /* NOTE: the previous test is a specific case for automatic
7925 struct/union init */
7926 /* XXX: union needs only one init */
7928 /* XXX: this test is incorrect for local initializers
7929 beginning with ( without {. It would be much more difficult
7930 to do it correctly (ideally, the expression parser should
7931 be used in all cases) */
7932 par_count = 0;
7933 if (tok == '(') {
7934 AttributeDef ad1;
7935 CType type1;
7936 next();
7937 while (tok == '(') {
7938 par_count++;
7939 next();
7941 if (!parse_btype(&type1, &ad1))
7942 expect("cast");
7943 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
7944 if (!is_compatible_types(type, &type1))
7945 error("invalid type for cast");
7946 skip(')');
7948 no_oblock = 1;
7949 if (first || tok == '{') {
7950 skip('{');
7951 no_oblock = 0;
7953 s = type->ref;
7954 f = s->next;
7955 array_length = 0;
7956 index = 0;
7957 n = s->c;
7958 while (tok != '}') {
7959 decl_designator(type, sec, c, NULL, &f, size_only);
7960 index = f->c;
7961 if (!size_only && array_length < index) {
7962 init_putz(type, sec, c + array_length,
7963 index - array_length);
7965 index = index + type_size(&f->type, &align1);
7966 if (index > array_length)
7967 array_length = index;
7968 f = f->next;
7969 if (no_oblock && f == NULL)
7970 break;
7971 if (tok == '}')
7972 break;
7973 skip(',');
7975 /* put zeros at the end */
7976 if (!size_only && array_length < n) {
7977 init_putz(type, sec, c + array_length,
7978 n - array_length);
7980 if (!no_oblock)
7981 skip('}');
7982 while (par_count) {
7983 skip(')');
7984 par_count--;
7986 } else if (tok == '{') {
7987 next();
7988 decl_initializer(type, sec, c, first, size_only);
7989 skip('}');
7990 } else if (size_only) {
7991 /* just skip expression */
7992 parlevel = 0;
7993 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
7994 tok != -1) {
7995 if (tok == '(')
7996 parlevel++;
7997 else if (tok == ')')
7998 parlevel--;
7999 next();
8001 } else {
8002 /* currently, we always use constant expression for globals
8003 (may change for scripting case) */
8004 expr_type = EXPR_CONST;
8005 if (!sec)
8006 expr_type = EXPR_ANY;
8007 init_putv(type, sec, c, 0, expr_type);
8011 /* parse an initializer for type 't' if 'has_init' is non zero, and
8012 allocate space in local or global data space ('r' is either
8013 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8014 variable 'v' of scope 'scope' is declared before initializers are
8015 parsed. If 'v' is zero, then a reference to the new object is put
8016 in the value stack. If 'has_init' is 2, a special parsing is done
8017 to handle string constants. */
8018 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
8019 int has_init, int v, int scope)
8021 int size, align, addr, data_offset;
8022 int level;
8023 ParseState saved_parse_state;
8024 TokenString init_str;
8025 Section *sec;
8027 size = type_size(type, &align);
8028 /* If unknown size, we must evaluate it before
8029 evaluating initializers because
8030 initializers can generate global data too
8031 (e.g. string pointers or ISOC99 compound
8032 literals). It also simplifies local
8033 initializers handling */
8034 tok_str_new(&init_str);
8035 if (size < 0) {
8036 if (!has_init)
8037 error("unknown type size");
8038 /* get all init string */
8039 if (has_init == 2) {
8040 /* only get strings */
8041 while (tok == TOK_STR || tok == TOK_LSTR) {
8042 tok_str_add_tok(&init_str);
8043 next();
8045 } else {
8046 level = 0;
8047 while (level > 0 || (tok != ',' && tok != ';')) {
8048 if (tok < 0)
8049 error("unexpected end of file in initializer");
8050 tok_str_add_tok(&init_str);
8051 if (tok == '{')
8052 level++;
8053 else if (tok == '}') {
8054 if (level == 0)
8055 break;
8056 level--;
8058 next();
8061 tok_str_add(&init_str, -1);
8062 tok_str_add(&init_str, 0);
8064 /* compute size */
8065 save_parse_state(&saved_parse_state);
8067 macro_ptr = init_str.str;
8068 next();
8069 decl_initializer(type, NULL, 0, 1, 1);
8070 /* prepare second initializer parsing */
8071 macro_ptr = init_str.str;
8072 next();
8074 /* if still unknown size, error */
8075 size = type_size(type, &align);
8076 if (size < 0)
8077 error("unknown type size");
8079 /* take into account specified alignment if bigger */
8080 if (ad->aligned > align)
8081 align = ad->aligned;
8082 if ((r & VT_VALMASK) == VT_LOCAL) {
8083 sec = NULL;
8084 if (do_bounds_check && (type->t & VT_ARRAY))
8085 loc--;
8086 loc = (loc - size) & -align;
8087 addr = loc;
8088 /* handles bounds */
8089 /* XXX: currently, since we do only one pass, we cannot track
8090 '&' operators, so we add only arrays */
8091 if (do_bounds_check && (type->t & VT_ARRAY)) {
8092 unsigned long *bounds_ptr;
8093 /* add padding between regions */
8094 loc--;
8095 /* then add local bound info */
8096 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
8097 bounds_ptr[0] = addr;
8098 bounds_ptr[1] = size;
8100 if (v) {
8101 /* local variable */
8102 sym_push(v, type, r, addr);
8103 } else {
8104 /* push local reference */
8105 vset(type, r, addr);
8107 } else {
8108 Sym *sym;
8110 sym = NULL;
8111 if (v && scope == VT_CONST) {
8112 /* see if the symbol was already defined */
8113 sym = sym_find(v);
8114 if (sym) {
8115 if (!is_compatible_types(&sym->type, type))
8116 error("incompatible types for redefinition of '%s'",
8117 get_tok_str(v, NULL));
8118 if (sym->type.t & VT_EXTERN) {
8119 /* if the variable is extern, it was not allocated */
8120 sym->type.t &= ~VT_EXTERN;
8121 } else {
8122 /* we accept several definitions of the same
8123 global variable. this is tricky, because we
8124 must play with the SHN_COMMON type of the symbol */
8125 /* XXX: should check if the variable was already
8126 initialized. It is incorrect to initialized it
8127 twice */
8128 /* no init data, we won't add more to the symbol */
8129 if (!has_init)
8130 goto no_alloc;
8135 /* allocate symbol in corresponding section */
8136 sec = ad->section;
8137 if (!sec) {
8138 if (has_init)
8139 sec = data_section;
8141 if (sec) {
8142 data_offset = sec->data_offset;
8143 data_offset = (data_offset + align - 1) & -align;
8144 addr = data_offset;
8145 /* very important to increment global pointer at this time
8146 because initializers themselves can create new initializers */
8147 data_offset += size;
8148 /* add padding if bound check */
8149 if (do_bounds_check)
8150 data_offset++;
8151 sec->data_offset = data_offset;
8152 /* allocate section space to put the data */
8153 if (sec->sh_type != SHT_NOBITS &&
8154 data_offset > sec->data_allocated)
8155 section_realloc(sec, data_offset);
8156 } else {
8157 addr = 0; /* avoid warning */
8160 if (v) {
8161 if (scope == VT_CONST) {
8162 if (!sym)
8163 goto do_def;
8164 } else {
8165 do_def:
8166 sym = sym_push(v, type, r | VT_SYM, 0);
8168 /* update symbol definition */
8169 if (sec) {
8170 put_extern_sym(sym, sec, addr, size);
8171 } else {
8172 Elf32_Sym *esym;
8173 /* put a common area */
8174 put_extern_sym(sym, NULL, align, size);
8175 /* XXX: find a nicer way */
8176 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
8177 esym->st_shndx = SHN_COMMON;
8179 } else {
8180 CValue cval;
8182 /* push global reference */
8183 sym = get_sym_ref(type, sec, addr, size);
8184 cval.ul = 0;
8185 vsetc(type, VT_CONST | VT_SYM, &cval);
8186 vtop->sym = sym;
8189 /* handles bounds now because the symbol must be defined
8190 before for the relocation */
8191 if (do_bounds_check) {
8192 unsigned long *bounds_ptr;
8194 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
8195 /* then add global bound info */
8196 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
8197 bounds_ptr[0] = 0; /* relocated */
8198 bounds_ptr[1] = size;
8201 if (has_init) {
8202 decl_initializer(type, sec, addr, 1, 0);
8203 /* restore parse state if needed */
8204 if (init_str.str) {
8205 tok_str_free(init_str.str);
8206 restore_parse_state(&saved_parse_state);
8209 no_alloc: ;
8212 void put_func_debug(Sym *sym)
8214 char buf[512];
8216 /* stabs info */
8217 /* XXX: we put here a dummy type */
8218 snprintf(buf, sizeof(buf), "%s:%c1",
8219 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
8220 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
8221 cur_text_section, sym->c);
8222 last_ind = 0;
8223 last_line_num = 0;
8226 /* not finished : try to put some local vars in registers */
8227 //#define CONFIG_REG_VARS
8229 #ifdef CONFIG_REG_VARS
8230 void add_var_ref(int t)
8232 printf("%s:%d: &%s\n",
8233 file->filename, file->line_num,
8234 get_tok_str(t, NULL));
8237 /* first pass on a function with heuristic to extract variable usage
8238 and pointer references to local variables for register allocation */
8239 void analyse_function(void)
8241 int level, t;
8243 for(;;) {
8244 if (tok == -1)
8245 break;
8246 /* any symbol coming after '&' is considered as being a
8247 variable whose reference is taken. It is highly unaccurate
8248 but it is difficult to do better without a complete parse */
8249 if (tok == '&') {
8250 next();
8251 /* if '& number', then no need to examine next tokens */
8252 if (tok == TOK_CINT ||
8253 tok == TOK_CUINT ||
8254 tok == TOK_CLLONG ||
8255 tok == TOK_CULLONG) {
8256 continue;
8257 } else if (tok >= TOK_UIDENT) {
8258 /* if '& ident [' or '& ident ->', then ident address
8259 is not needed */
8260 t = tok;
8261 next();
8262 if (tok != '[' && tok != TOK_ARROW)
8263 add_var_ref(t);
8264 } else {
8265 level = 0;
8266 while (tok != '}' && tok != ';' &&
8267 !((tok == ',' || tok == ')') && level == 0)) {
8268 if (tok >= TOK_UIDENT) {
8269 add_var_ref(tok);
8270 } else if (tok == '(') {
8271 level++;
8272 } else if (tok == ')') {
8273 level--;
8275 next();
8278 } else {
8279 next();
8283 #endif
8285 /* parse an old style function declaration list */
8286 /* XXX: check multiple parameter */
8287 static void func_decl_list(Sym *func_sym)
8289 AttributeDef ad;
8290 int v;
8291 Sym *s;
8292 CType btype, type;
8294 /* parse each declaration */
8295 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
8296 if (!parse_btype(&btype, &ad))
8297 expect("declaration list");
8298 if (((btype.t & VT_BTYPE) == VT_ENUM ||
8299 (btype.t & VT_BTYPE) == VT_STRUCT) &&
8300 tok == ';') {
8301 /* we accept no variable after */
8302 } else {
8303 for(;;) {
8304 type = btype;
8305 type_decl(&type, &ad, &v, TYPE_DIRECT);
8306 /* find parameter in function parameter list */
8307 s = func_sym->next;
8308 while (s != NULL) {
8309 if ((s->v & ~SYM_FIELD) == v)
8310 goto found;
8311 s = s->next;
8313 error("declaration for parameter '%s' but no such parameter",
8314 get_tok_str(v, NULL));
8315 found:
8316 /* check that no storage specifier except 'register' was given */
8317 if (type.t & VT_STORAGE)
8318 error("storage class specified for '%s'", get_tok_str(v, NULL));
8319 convert_parameter_type(&type);
8320 /* we can add the type (NOTE: it could be local to the function) */
8321 s->type = type;
8322 /* accept other parameters */
8323 if (tok == ',')
8324 next();
8325 else
8326 break;
8329 skip(';');
8333 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
8334 static void decl(int l)
8336 int v, has_init, r;
8337 CType type, btype;
8338 Sym *sym;
8339 AttributeDef ad;
8341 while (1) {
8342 if (!parse_btype(&btype, &ad)) {
8343 /* skip redundant ';' */
8344 /* XXX: find more elegant solution */
8345 if (tok == ';') {
8346 next();
8347 continue;
8349 /* special test for old K&R protos without explicit int
8350 type. Only accepted when defining global data */
8351 if (l == VT_LOCAL || tok < TOK_DEFINE)
8352 break;
8353 btype.t = VT_INT;
8355 if (((btype.t & VT_BTYPE) == VT_ENUM ||
8356 (btype.t & VT_BTYPE) == VT_STRUCT) &&
8357 tok == ';') {
8358 /* we accept no variable after */
8359 next();
8360 continue;
8362 while (1) { /* iterate thru each declaration */
8363 type = btype;
8364 type_decl(&type, &ad, &v, TYPE_DIRECT);
8365 #if 0
8367 char buf[500];
8368 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
8369 printf("type = '%s'\n", buf);
8371 #endif
8372 if ((type.t & VT_BTYPE) == VT_FUNC) {
8373 /* if old style function prototype, we accept a
8374 declaration list */
8375 sym = type.ref;
8376 if (sym->c == FUNC_OLD)
8377 func_decl_list(sym);
8380 if (tok == '{') {
8381 #ifdef CONFIG_REG_VARS
8382 TokenString func_str;
8383 ParseState saved_parse_state;
8384 int block_level;
8385 #endif
8387 if (l == VT_LOCAL)
8388 error("cannot use local functions");
8389 if (!(type.t & VT_FUNC))
8390 expect("function definition");
8391 /* XXX: cannot do better now: convert extern line to static inline */
8392 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
8393 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
8395 #ifdef CONFIG_REG_VARS
8396 /* parse all function code and record it */
8398 tok_str_new(&func_str);
8400 block_level = 0;
8401 for(;;) {
8402 int t;
8403 if (tok == -1)
8404 error("unexpected end of file");
8405 tok_str_add_tok(&func_str);
8406 t = tok;
8407 next();
8408 if (t == '{') {
8409 block_level++;
8410 } else if (t == '}') {
8411 block_level--;
8412 if (block_level == 0)
8413 break;
8416 tok_str_add(&func_str, -1);
8417 tok_str_add(&func_str, 0);
8419 save_parse_state(&saved_parse_state);
8421 macro_ptr = func_str.str;
8422 next();
8423 analyse_function();
8424 #endif
8426 /* compute text section */
8427 cur_text_section = ad.section;
8428 if (!cur_text_section)
8429 cur_text_section = text_section;
8430 ind = cur_text_section->data_offset;
8431 funcname = get_tok_str(v, NULL);
8432 sym = sym_find(v);
8433 if (sym) {
8434 /* if symbol is already defined, then put complete type */
8435 sym->type = type;
8436 } else {
8437 /* put function symbol */
8438 sym = global_identifier_push(v, type.t, 0);
8439 sym->type.ref = type.ref;
8441 /* NOTE: we patch the symbol size later */
8442 put_extern_sym(sym, cur_text_section, ind, 0);
8443 func_ind = ind;
8444 sym->r = VT_SYM | VT_CONST;
8445 /* put debug symbol */
8446 if (do_debug)
8447 put_func_debug(sym);
8448 /* push a dummy symbol to enable local sym storage */
8449 sym_push2(&local_stack, SYM_FIELD, 0, 0);
8450 gfunc_prolog(&type);
8451 loc = 0;
8452 rsym = 0;
8453 #ifdef CONFIG_REG_VARS
8454 macro_ptr = func_str.str;
8455 next();
8456 #endif
8457 block(NULL, NULL, NULL, NULL, 0, 0);
8458 gsym(rsym);
8459 gfunc_epilog();
8460 cur_text_section->data_offset = ind;
8461 label_pop(&global_label_stack, NULL);
8462 sym_pop(&local_stack, NULL); /* reset local stack */
8463 /* end of function */
8464 /* patch symbol size */
8465 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
8466 ind - func_ind;
8467 if (do_debug) {
8468 put_stabn(N_FUN, 0, 0, ind - func_ind);
8470 funcname = ""; /* for safety */
8471 func_vt.t = VT_VOID; /* for safety */
8472 ind = 0; /* for safety */
8474 #ifdef CONFIG_REG_VARS
8475 tok_str_free(func_str.str);
8476 restore_parse_state(&saved_parse_state);
8477 #endif
8478 break;
8479 } else {
8480 if (btype.t & VT_TYPEDEF) {
8481 /* save typedefed type */
8482 /* XXX: test storage specifiers ? */
8483 sym = sym_push(v, &type, 0, 0);
8484 sym->type.t |= VT_TYPEDEF;
8485 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
8486 /* external function definition */
8487 external_sym(v, &type, 0);
8488 } else {
8489 /* not lvalue if array */
8490 r = 0;
8491 if (!(type.t & VT_ARRAY))
8492 r |= lvalue_type(type.t);
8493 has_init = (tok == '=');
8494 if ((btype.t & VT_EXTERN) ||
8495 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
8496 !has_init && l == VT_CONST && type.ref->c < 0)) {
8497 /* external variable */
8498 /* NOTE: as GCC, uninitialized global static
8499 arrays of null size are considered as
8500 extern */
8501 external_sym(v, &type, r);
8502 } else {
8503 if (type.t & VT_STATIC)
8504 r |= VT_CONST;
8505 else
8506 r |= l;
8507 if (has_init)
8508 next();
8509 decl_initializer_alloc(&type, &ad, r,
8510 has_init, v, l);
8513 if (tok != ',') {
8514 skip(';');
8515 break;
8517 next();
8523 /* better than nothing, but needs extension to handle '-E' option
8524 correctly too */
8525 static void preprocess_init(TCCState *s1)
8527 s1->include_stack_ptr = s1->include_stack;
8528 /* XXX: move that before to avoid having to initialize
8529 file->ifdef_stack_ptr ? */
8530 s1->ifdef_stack_ptr = s1->ifdef_stack;
8531 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
8533 /* XXX: not ANSI compliant: bound checking says error */
8534 vtop = vstack - 1;
8537 /* compile the C file opened in 'file'. Return non zero if errors. */
8538 static int tcc_compile(TCCState *s1)
8540 Sym *define_start;
8541 char buf[512];
8542 volatile int section_sym;
8544 #ifdef INC_DEBUG
8545 printf("%s: **** new file\n", file->filename);
8546 #endif
8547 preprocess_init(s1);
8549 funcname = "";
8550 anon_sym = SYM_FIRST_ANOM;
8552 /* file info: full path + filename */
8553 section_sym = 0; /* avoid warning */
8554 if (do_debug) {
8555 section_sym = put_elf_sym(symtab_section, 0, 0,
8556 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
8557 text_section->sh_num, NULL);
8558 getcwd(buf, sizeof(buf));
8559 pstrcat(buf, sizeof(buf), "/");
8560 put_stabs_r(buf, N_SO, 0, 0,
8561 text_section->data_offset, text_section, section_sym);
8562 put_stabs_r(file->filename, N_SO, 0, 0,
8563 text_section->data_offset, text_section, section_sym);
8565 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8566 symbols can be safely used */
8567 put_elf_sym(symtab_section, 0, 0,
8568 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
8569 SHN_ABS, file->filename);
8571 /* define some often used types */
8572 int_type.t = VT_INT;
8574 char_pointer_type.t = VT_BYTE;
8575 mk_pointer(&char_pointer_type);
8577 func_old_type.t = VT_FUNC;
8578 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
8580 #if 0
8581 /* define 'void *alloca(unsigned int)' builtin function */
8583 Sym *s1;
8585 p = anon_sym++;
8586 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
8587 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
8588 s1->next = NULL;
8589 sym->next = s1;
8590 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
8592 #endif
8594 define_start = define_stack;
8596 if (setjmp(s1->error_jmp_buf) == 0) {
8597 s1->nb_errors = 0;
8598 s1->error_set_jmp_enabled = 1;
8600 ch = file->buf_ptr[0];
8601 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
8602 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
8603 next();
8604 decl(VT_CONST);
8605 if (tok != -1)
8606 expect("declaration");
8608 /* end of translation unit info */
8609 if (do_debug) {
8610 put_stabs_r(NULL, N_SO, 0, 0,
8611 text_section->data_offset, text_section, section_sym);
8614 s1->error_set_jmp_enabled = 0;
8616 /* reset define stack, but leave -Dsymbols (may be incorrect if
8617 they are undefined) */
8618 free_defines(define_start);
8620 sym_pop(&global_stack, NULL);
8622 return s1->nb_errors != 0 ? -1 : 0;
8625 #ifdef LIBTCC
8626 int tcc_compile_string(TCCState *s, const char *str)
8628 BufferedFile bf1, *bf = &bf1;
8629 int ret, len;
8630 char *buf;
8632 /* init file structure */
8633 bf->fd = -1;
8634 /* XXX: avoid copying */
8635 len = strlen(str);
8636 buf = tcc_malloc(len + 1);
8637 if (!buf)
8638 return -1;
8639 memcpy(buf, str, len);
8640 buf[len] = CH_EOB;
8641 bf->buf_ptr = buf;
8642 bf->buf_end = buf + len;
8643 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
8644 bf->line_num = 1;
8645 file = bf;
8647 ret = tcc_compile(s);
8649 tcc_free(buf);
8651 /* currently, no need to close */
8652 return ret;
8654 #endif
8656 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8657 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
8659 BufferedFile bf1, *bf = &bf1;
8661 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
8662 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
8663 /* default value */
8664 if (!value)
8665 value = "1";
8666 pstrcat(bf->buffer, IO_BUF_SIZE, value);
8668 /* init file structure */
8669 bf->fd = -1;
8670 bf->buf_ptr = bf->buffer;
8671 bf->buf_end = bf->buffer + strlen(bf->buffer);
8672 *bf->buf_end = CH_EOB;
8673 bf->filename[0] = '\0';
8674 bf->line_num = 1;
8675 file = bf;
8677 s1->include_stack_ptr = s1->include_stack;
8679 /* parse with define parser */
8680 ch = file->buf_ptr[0];
8681 next_nomacro();
8682 parse_define();
8683 file = NULL;
8686 /* undefine a preprocessor symbol */
8687 void tcc_undefine_symbol(TCCState *s1, const char *sym)
8689 TokenSym *ts;
8690 Sym *s;
8691 ts = tok_alloc(sym, strlen(sym));
8692 s = define_find(ts->tok);
8693 /* undefine symbol by putting an invalid name */
8694 if (s)
8695 define_undef(s);
8698 #ifdef CONFIG_TCC_ASM
8700 #include "i386-asm.c"
8701 #include "tccasm.c"
8703 #else
8704 static void asm_instr(void)
8706 error("inline asm() not supported");
8708 #endif
8710 #include "tccelf.c"
8712 /* print the position in the source file of PC value 'pc' by reading
8713 the stabs debug information */
8714 static void rt_printline(unsigned long wanted_pc)
8716 Stab_Sym *sym, *sym_end;
8717 char func_name[128], last_func_name[128];
8718 unsigned long func_addr, last_pc, pc;
8719 const char *incl_files[INCLUDE_STACK_SIZE];
8720 int incl_index, len, last_line_num, i;
8721 const char *str, *p;
8723 fprintf(stderr, "0x%08lx:", wanted_pc);
8725 func_name[0] = '\0';
8726 func_addr = 0;
8727 incl_index = 0;
8728 last_func_name[0] = '\0';
8729 last_pc = 0xffffffff;
8730 last_line_num = 1;
8731 sym = (Stab_Sym *)stab_section->data + 1;
8732 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
8733 while (sym < sym_end) {
8734 switch(sym->n_type) {
8735 /* function start or end */
8736 case N_FUN:
8737 if (sym->n_strx == 0) {
8738 /* we test if between last line and end of function */
8739 pc = sym->n_value + func_addr;
8740 if (wanted_pc >= last_pc && wanted_pc < pc)
8741 goto found;
8742 func_name[0] = '\0';
8743 func_addr = 0;
8744 } else {
8745 str = stabstr_section->data + sym->n_strx;
8746 p = strchr(str, ':');
8747 if (!p) {
8748 pstrcpy(func_name, sizeof(func_name), str);
8749 } else {
8750 len = p - str;
8751 if (len > sizeof(func_name) - 1)
8752 len = sizeof(func_name) - 1;
8753 memcpy(func_name, str, len);
8754 func_name[len] = '\0';
8756 func_addr = sym->n_value;
8758 break;
8759 /* line number info */
8760 case N_SLINE:
8761 pc = sym->n_value + func_addr;
8762 if (wanted_pc >= last_pc && wanted_pc < pc)
8763 goto found;
8764 last_pc = pc;
8765 last_line_num = sym->n_desc;
8766 /* XXX: slow! */
8767 strcpy(last_func_name, func_name);
8768 break;
8769 /* include files */
8770 case N_BINCL:
8771 str = stabstr_section->data + sym->n_strx;
8772 add_incl:
8773 if (incl_index < INCLUDE_STACK_SIZE) {
8774 incl_files[incl_index++] = str;
8776 break;
8777 case N_EINCL:
8778 if (incl_index > 1)
8779 incl_index--;
8780 break;
8781 case N_SO:
8782 if (sym->n_strx == 0) {
8783 incl_index = 0; /* end of translation unit */
8784 } else {
8785 str = stabstr_section->data + sym->n_strx;
8786 /* do not add path */
8787 len = strlen(str);
8788 if (len > 0 && str[len - 1] != '/')
8789 goto add_incl;
8791 break;
8793 sym++;
8796 /* second pass: we try symtab symbols (no line number info) */
8797 incl_index = 0;
8799 Elf32_Sym *sym, *sym_end;
8800 int type;
8802 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
8803 for(sym = (Elf32_Sym *)symtab_section->data + 1;
8804 sym < sym_end;
8805 sym++) {
8806 type = ELF32_ST_TYPE(sym->st_info);
8807 if (type == STT_FUNC) {
8808 if (wanted_pc >= sym->st_value &&
8809 wanted_pc < sym->st_value + sym->st_size) {
8810 pstrcpy(last_func_name, sizeof(last_func_name),
8811 strtab_section->data + sym->st_name);
8812 goto found;
8817 /* did not find any info: */
8818 fprintf(stderr, " ???\n");
8819 return;
8820 found:
8821 if (last_func_name[0] != '\0') {
8822 fprintf(stderr, " %s()", last_func_name);
8824 if (incl_index > 0) {
8825 fprintf(stderr, " (%s:%d",
8826 incl_files[incl_index - 1], last_line_num);
8827 for(i = incl_index - 2; i >= 0; i--)
8828 fprintf(stderr, ", included from %s", incl_files[i]);
8829 fprintf(stderr, ")");
8831 fprintf(stderr, "\n");
8834 #ifndef WIN32
8836 #ifdef __i386__
8838 /* fix for glibc 2.1 */
8839 #ifndef REG_EIP
8840 #define REG_EIP EIP
8841 #define REG_EBP EBP
8842 #endif
8844 /* return the PC at frame level 'level'. Return non zero if not found */
8845 static int rt_get_caller_pc(unsigned long *paddr,
8846 ucontext_t *uc, int level)
8848 unsigned long fp;
8849 int i;
8851 if (level == 0) {
8852 #ifdef __FreeBSD__
8853 *paddr = uc->uc_mcontext.mc_eip;
8854 #else
8855 *paddr = uc->uc_mcontext.gregs[REG_EIP];
8856 #endif
8857 return 0;
8858 } else {
8859 #ifdef __FreeBSD__
8860 fp = uc->uc_mcontext.mc_ebp;
8861 #else
8862 fp = uc->uc_mcontext.gregs[REG_EBP];
8863 #endif
8864 for(i=1;i<level;i++) {
8865 /* XXX: check address validity with program info */
8866 if (fp <= 0x1000 || fp >= 0xc0000000)
8867 return -1;
8868 fp = ((unsigned long *)fp)[0];
8870 *paddr = ((unsigned long *)fp)[1];
8871 return 0;
8874 #else
8875 #error add arch specific rt_get_caller_pc()
8876 #endif
8878 /* emit a run time error at position 'pc' */
8879 void rt_error(ucontext_t *uc, const char *fmt, ...)
8881 va_list ap;
8882 unsigned long pc;
8883 int i;
8885 va_start(ap, fmt);
8886 fprintf(stderr, "Runtime error: ");
8887 vfprintf(stderr, fmt, ap);
8888 fprintf(stderr, "\n");
8889 for(i=0;i<num_callers;i++) {
8890 if (rt_get_caller_pc(&pc, uc, i) < 0)
8891 break;
8892 if (i == 0)
8893 fprintf(stderr, "at ");
8894 else
8895 fprintf(stderr, "by ");
8896 rt_printline(pc);
8898 exit(255);
8899 va_end(ap);
8902 /* signal handler for fatal errors */
8903 static void sig_error(int signum, siginfo_t *siginf, void *puc)
8905 ucontext_t *uc = puc;
8907 switch(signum) {
8908 case SIGFPE:
8909 switch(siginf->si_code) {
8910 case FPE_INTDIV:
8911 case FPE_FLTDIV:
8912 rt_error(uc, "division by zero");
8913 break;
8914 default:
8915 rt_error(uc, "floating point exception");
8916 break;
8918 break;
8919 case SIGBUS:
8920 case SIGSEGV:
8921 if (rt_bound_error_msg && *rt_bound_error_msg)
8922 rt_error(uc, *rt_bound_error_msg);
8923 else
8924 rt_error(uc, "dereferencing invalid pointer");
8925 break;
8926 case SIGILL:
8927 rt_error(uc, "illegal instruction");
8928 break;
8929 case SIGABRT:
8930 rt_error(uc, "abort() called");
8931 break;
8932 default:
8933 rt_error(uc, "caught signal %d", signum);
8934 break;
8936 exit(255);
8938 #endif
8940 /* do all relocations (needed before using tcc_get_symbol()) */
8941 int tcc_relocate(TCCState *s1)
8943 Section *s;
8944 int i;
8946 s1->nb_errors = 0;
8948 tcc_add_runtime(s1);
8950 relocate_common_syms();
8952 /* compute relocation address : section are relocated in place. We
8953 also alloc the bss space */
8954 for(i = 1; i < s1->nb_sections; i++) {
8955 s = s1->sections[i];
8956 if (s->sh_flags & SHF_ALLOC) {
8957 if (s->sh_type == SHT_NOBITS)
8958 s->data = tcc_mallocz(s->data_offset);
8959 s->sh_addr = (unsigned long)s->data;
8963 relocate_syms(s1, 1);
8965 if (s1->nb_errors != 0)
8966 return -1;
8968 /* relocate each section */
8969 for(i = 1; i < s1->nb_sections; i++) {
8970 s = s1->sections[i];
8971 if (s->reloc)
8972 relocate_section(s1, s);
8974 return 0;
8977 /* launch the compiled program with the given arguments */
8978 int tcc_run(TCCState *s1, int argc, char **argv)
8980 int (*prog_main)(int, char **);
8982 if (tcc_relocate(s1) < 0)
8983 return -1;
8985 prog_main = tcc_get_symbol(s1, "main");
8987 if (do_debug) {
8988 #ifdef WIN32
8989 error("debug mode currently not available for Windows");
8990 #else
8991 struct sigaction sigact;
8992 /* install TCC signal handlers to print debug info on fatal
8993 runtime errors */
8994 sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
8995 sigact.sa_sigaction = sig_error;
8996 sigemptyset(&sigact.sa_mask);
8997 sigaction(SIGFPE, &sigact, NULL);
8998 sigaction(SIGILL, &sigact, NULL);
8999 sigaction(SIGSEGV, &sigact, NULL);
9000 sigaction(SIGBUS, &sigact, NULL);
9001 sigaction(SIGABRT, &sigact, NULL);
9002 #endif
9005 #ifdef CONFIG_TCC_BCHECK
9006 if (do_bounds_check) {
9007 void (*bound_init)(void);
9009 /* set error function */
9010 rt_bound_error_msg = (void *)tcc_get_symbol(s1, "__bound_error_msg");
9012 /* XXX: use .init section so that it also work in binary ? */
9013 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
9014 bound_init();
9016 #endif
9017 return (*prog_main)(argc, argv);
9020 TCCState *tcc_new(void)
9022 const char *p, *r;
9023 TCCState *s;
9024 TokenSym *ts;
9025 int i, c;
9027 s = tcc_mallocz(sizeof(TCCState));
9028 if (!s)
9029 return NULL;
9030 tcc_state = s;
9031 s->output_type = TCC_OUTPUT_MEMORY;
9033 /* init isid table */
9034 for(i=0;i<256;i++)
9035 isidnum_table[i] = isid(i) || isnum(i);
9037 /* add all tokens */
9038 table_ident = NULL;
9039 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
9041 tok_ident = TOK_IDENT;
9042 p = tcc_keywords;
9043 while (*p) {
9044 r = p;
9045 for(;;) {
9046 c = *r++;
9047 if (c == '\0')
9048 break;
9050 ts = tok_alloc(p, r - p - 1);
9051 p = r;
9054 /* we add dummy defines for some special macros to speed up tests
9055 and to have working defined() */
9056 define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
9057 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
9058 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
9059 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
9061 /* standard defines */
9062 tcc_define_symbol(s, "__STDC__", NULL);
9063 #if defined(TCC_TARGET_I386)
9064 tcc_define_symbol(s, "__i386__", NULL);
9065 #endif
9066 #if defined(linux)
9067 tcc_define_symbol(s, "__linux__", NULL);
9068 tcc_define_symbol(s, "linux", NULL);
9069 #endif
9070 /* tiny C specific defines */
9071 tcc_define_symbol(s, "__TINYC__", NULL);
9073 /* tiny C & gcc defines */
9074 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
9075 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
9076 tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
9078 /* default library paths */
9079 tcc_add_library_path(s, "/usr/local/lib");
9080 tcc_add_library_path(s, "/usr/lib");
9081 tcc_add_library_path(s, "/lib");
9083 /* no section zero */
9084 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
9086 /* create standard sections */
9087 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
9088 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
9089 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
9091 /* symbols are always generated for linking stage */
9092 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
9093 ".strtab",
9094 ".hashtab", SHF_PRIVATE);
9095 strtab_section = symtab_section->link;
9097 /* private symbol table for dynamic symbols */
9098 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
9099 ".dynstrtab",
9100 ".dynhashtab", SHF_PRIVATE);
9101 return s;
9104 void tcc_delete(TCCState *s1)
9106 int i, n;
9108 /* free -D defines */
9109 free_defines(NULL);
9111 /* free tokens */
9112 n = tok_ident - TOK_IDENT;
9113 for(i = 0; i < n; i++)
9114 tcc_free(table_ident[i]);
9115 tcc_free(table_ident);
9117 /* free all sections */
9119 free_section(symtab_section->hash);
9121 free_section(s1->dynsymtab_section->hash);
9122 free_section(s1->dynsymtab_section->link);
9123 free_section(s1->dynsymtab_section);
9125 for(i = 1; i < s1->nb_sections; i++)
9126 free_section(s1->sections[i]);
9127 tcc_free(s1->sections);
9129 /* free loaded dlls array */
9130 for(i = 0; i < s1->nb_loaded_dlls; i++)
9131 tcc_free(s1->loaded_dlls[i]);
9132 tcc_free(s1->loaded_dlls);
9134 /* library paths */
9135 for(i = 0; i < s1->nb_library_paths; i++)
9136 tcc_free(s1->library_paths[i]);
9137 tcc_free(s1->library_paths);
9139 /* cached includes */
9140 for(i = 0; i < s1->nb_cached_includes; i++)
9141 tcc_free(s1->cached_includes[i]);
9142 tcc_free(s1->cached_includes);
9144 for(i = 0; i < s1->nb_include_paths; i++)
9145 tcc_free(s1->include_paths[i]);
9146 tcc_free(s1->include_paths);
9148 for(i = 0; i < s1->nb_sysinclude_paths; i++)
9149 tcc_free(s1->sysinclude_paths[i]);
9150 tcc_free(s1->sysinclude_paths);
9152 tcc_free(s1);
9155 int tcc_add_include_path(TCCState *s1, const char *pathname)
9157 char *pathname1;
9159 pathname1 = tcc_strdup(pathname);
9160 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
9161 return 0;
9164 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
9166 char *pathname1;
9168 pathname1 = tcc_strdup(pathname);
9169 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
9170 return 0;
9173 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
9175 const char *ext, *filename1;
9176 Elf32_Ehdr ehdr;
9177 int fd, ret;
9178 BufferedFile *saved_file;
9180 /* find source file type with extension */
9181 filename1 = strrchr(filename, '/');
9182 if (filename1)
9183 filename1++;
9184 else
9185 filename1 = filename;
9186 ext = strrchr(filename1, '.');
9187 if (ext)
9188 ext++;
9190 /* open the file */
9191 saved_file = file;
9192 file = tcc_open(s1, filename);
9193 if (!file) {
9194 if (flags & AFF_PRINT_ERROR) {
9195 error_noabort("file '%s' not found", filename);
9197 ret = -1;
9198 goto fail1;
9201 if (!ext || !strcmp(ext, "c")) {
9202 /* C file assumed */
9203 ret = tcc_compile(s1);
9204 } else
9205 #ifdef CONFIG_TCC_ASM
9206 if (!strcmp(ext, "S")) {
9207 /* preprocessed assembler */
9208 ret = tcc_assemble(s1, 1);
9209 } else if (!strcmp(ext, "s")) {
9210 /* non preprocessed assembler */
9211 ret = tcc_assemble(s1, 0);
9212 } else
9213 #endif
9215 fd = file->fd;
9216 /* assume executable format: auto guess file type */
9217 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
9218 error_noabort("could not read header");
9219 goto fail;
9221 lseek(fd, 0, SEEK_SET);
9223 if (ehdr.e_ident[0] == ELFMAG0 &&
9224 ehdr.e_ident[1] == ELFMAG1 &&
9225 ehdr.e_ident[2] == ELFMAG2 &&
9226 ehdr.e_ident[3] == ELFMAG3) {
9227 file->line_num = 0; /* do not display line number if error */
9228 if (ehdr.e_type == ET_REL) {
9229 ret = tcc_load_object_file(s1, fd, 0);
9230 } else if (ehdr.e_type == ET_DYN) {
9231 ret = tcc_load_dll(s1, fd, filename,
9232 (flags & AFF_REFERENCED_DLL) != 0);
9233 } else {
9234 error_noabort("unrecognized ELF file");
9235 goto fail;
9237 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
9238 file->line_num = 0; /* do not display line number if error */
9239 ret = tcc_load_archive(s1, fd);
9240 } else {
9241 /* as GNU ld, consider it is an ld script if not recognized */
9242 ret = tcc_load_ldscript(s1);
9243 if (ret < 0) {
9244 error_noabort("unrecognized file type");
9245 goto fail;
9249 the_end:
9250 tcc_close(file);
9251 fail1:
9252 file = saved_file;
9253 return ret;
9254 fail:
9255 ret = -1;
9256 goto the_end;
9259 int tcc_add_file(TCCState *s, const char *filename)
9261 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
9264 int tcc_add_library_path(TCCState *s, const char *pathname)
9266 char *pathname1;
9268 pathname1 = tcc_strdup(pathname);
9269 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
9270 return 0;
9273 /* find and load a dll. Return non zero if not found */
9274 /* XXX: add '-rpath' option support ? */
9275 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
9277 char buf[1024];
9278 int i;
9280 for(i = 0; i < s->nb_library_paths; i++) {
9281 snprintf(buf, sizeof(buf), "%s/%s",
9282 s->library_paths[i], filename);
9283 if (tcc_add_file_internal(s, buf, flags) == 0)
9284 return 0;
9286 return -1;
9289 /* the library name is the same as the argument of the '-l' option */
9290 int tcc_add_library(TCCState *s, const char *libraryname)
9292 char buf[1024];
9293 int i;
9294 void *h;
9296 /* first we look for the dynamic library if not static linking */
9297 if (!s->static_link) {
9298 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
9299 /* if we output to memory, then we simply we dlopen(). */
9300 if (s->output_type == TCC_OUTPUT_MEMORY) {
9301 /* Since the libc is already loaded, we don't need to load it again */
9302 if (!strcmp(libraryname, "c"))
9303 return 0;
9304 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
9305 if (h)
9306 return 0;
9307 } else {
9308 if (tcc_add_dll(s, buf, 0) == 0)
9309 return 0;
9313 /* then we look for the static library */
9314 for(i = 0; i < s->nb_library_paths; i++) {
9315 snprintf(buf, sizeof(buf), "%s/lib%s.a",
9316 s->library_paths[i], libraryname);
9317 if (tcc_add_file_internal(s, buf, 0) == 0)
9318 return 0;
9320 return -1;
9323 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
9325 add_elf_sym(symtab_section, val, 0,
9326 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
9327 SHN_ABS, name);
9328 return 0;
9331 int tcc_set_output_type(TCCState *s, int output_type)
9333 char buf[1024];
9335 s->output_type = output_type;
9337 if (!s->nostdinc) {
9338 /* default include paths */
9339 /* XXX: reverse order needed if -isystem support */
9340 tcc_add_sysinclude_path(s, "/usr/local/include");
9341 tcc_add_sysinclude_path(s, "/usr/include");
9342 snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path);
9343 tcc_add_sysinclude_path(s, buf);
9346 /* if bound checking, then add corresponding sections */
9347 #ifdef CONFIG_TCC_BCHECK
9348 if (do_bounds_check) {
9349 /* define symbol */
9350 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
9351 /* create bounds sections */
9352 bounds_section = new_section(s, ".bounds",
9353 SHT_PROGBITS, SHF_ALLOC);
9354 lbounds_section = new_section(s, ".lbounds",
9355 SHT_PROGBITS, SHF_ALLOC);
9357 #endif
9359 /* add debug sections */
9360 if (do_debug) {
9361 /* stab symbols */
9362 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
9363 stab_section->sh_entsize = sizeof(Stab_Sym);
9364 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
9365 put_elf_str(stabstr_section, "");
9366 stab_section->link = stabstr_section;
9367 /* put first entry */
9368 put_stabs("", 0, 0, 0, 0);
9371 /* add libc crt1/crti objects */
9372 if (output_type == TCC_OUTPUT_EXE ||
9373 output_type == TCC_OUTPUT_DLL) {
9374 if (output_type != TCC_OUTPUT_DLL)
9375 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
9376 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
9378 return 0;
9381 #if !defined(LIBTCC)
9383 static int64_t getclock_us(void)
9385 #ifdef WIN32
9386 struct _timeb tb;
9387 _ftime(&tb);
9388 return (tb.time * 1000LL + tb.millitm) * 1000LL;
9389 #else
9390 struct timeval tv;
9391 gettimeofday(&tv, NULL);
9392 return tv.tv_sec * 1000000LL + tv.tv_usec;
9393 #endif
9396 void help(void)
9398 printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
9399 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
9400 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
9401 " [infile1 infile2...] [-run infile args...]\n"
9402 "\n"
9403 "General options:\n"
9404 " -v display current version\n"
9405 " -c compile only - generate an object file\n"
9406 " -o outfile set output filename\n"
9407 " -Bdir set tcc internal library path\n"
9408 " -bench output compilation statistics\n"
9409 " -run run compiled source\n"
9410 "Preprocessor options:\n"
9411 " -Idir add include path 'dir'\n"
9412 " -Dsym[=val] define 'sym' with value 'val'\n"
9413 " -Usym undefine 'sym'\n"
9414 "Linker options:\n"
9415 " -Ldir add library path 'dir'\n"
9416 " -llib link with dynamic or static library 'lib'\n"
9417 " -shared generate a shared library\n"
9418 " -static static linking\n"
9419 " -r relocatable output\n"
9420 "Debugger options:\n"
9421 " -g generate runtime debug info\n"
9422 #ifdef CONFIG_TCC_BCHECK
9423 " -b compile with built-in memory and bounds checker (implies -g)\n"
9424 #endif
9425 " -bt N show N callers in stack traces\n"
9429 #define TCC_OPTION_HAS_ARG 0x0001
9430 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
9432 typedef struct TCCOption {
9433 const char *name;
9434 uint16_t index;
9435 uint16_t flags;
9436 } TCCOption;
9438 enum {
9439 TCC_OPTION_HELP,
9440 TCC_OPTION_I,
9441 TCC_OPTION_D,
9442 TCC_OPTION_U,
9443 TCC_OPTION_L,
9444 TCC_OPTION_B,
9445 TCC_OPTION_l,
9446 TCC_OPTION_bench,
9447 TCC_OPTION_bt,
9448 TCC_OPTION_b,
9449 TCC_OPTION_g,
9450 TCC_OPTION_c,
9451 TCC_OPTION_static,
9452 TCC_OPTION_shared,
9453 TCC_OPTION_o,
9454 TCC_OPTION_r,
9455 TCC_OPTION_W,
9456 TCC_OPTION_O,
9457 TCC_OPTION_m,
9458 TCC_OPTION_f,
9459 TCC_OPTION_nostdinc,
9460 TCC_OPTION_print_search_dirs,
9461 TCC_OPTION_rdynamic,
9462 TCC_OPTION_run,
9463 TCC_OPTION_v,
9466 static const TCCOption tcc_options[] = {
9467 { "h", TCC_OPTION_HELP, 0 },
9468 { "?", TCC_OPTION_HELP, 0 },
9469 { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
9470 { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
9471 { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
9472 { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
9473 { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
9474 { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9475 { "bench", TCC_OPTION_bench, 0 },
9476 { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
9477 #ifdef CONFIG_TCC_BCHECK
9478 { "b", TCC_OPTION_b, 0 },
9479 #endif
9480 { "g", TCC_OPTION_g, 0 },
9481 { "c", TCC_OPTION_c, 0 },
9482 { "static", TCC_OPTION_static, 0 },
9483 { "shared", TCC_OPTION_shared, 0 },
9484 { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
9485 { "run", TCC_OPTION_run, 0 },
9486 { "rdynamic", TCC_OPTION_rdynamic, 0 }, /* currently ignored */
9487 { "r", TCC_OPTION_r, 0 },
9488 { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9489 { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9490 { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
9491 { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9492 { "nostdinc", TCC_OPTION_nostdinc, 0 },
9493 { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
9494 { "v", TCC_OPTION_v, 0 },
9495 { NULL },
9498 int main(int argc, char **argv)
9500 char *r;
9501 int optind, output_type, multiple_files, i, reloc_output;
9502 TCCState *s;
9503 char **files;
9504 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
9505 char objfilename[1024];
9506 int64_t start_time = 0;
9507 const TCCOption *popt;
9508 const char *optarg, *p1, *r1, *outfile;
9509 int print_search_dirs;
9511 s = tcc_new();
9512 output_type = TCC_OUTPUT_EXE;
9514 optind = 1;
9515 outfile = NULL;
9516 multiple_files = 1;
9517 dminus = 0;
9518 files = NULL;
9519 nb_files = 0;
9520 nb_libraries = 0;
9521 reloc_output = 0;
9522 print_search_dirs = 0;
9523 while (1) {
9524 if (optind >= argc) {
9525 if (nb_files == 0 && !print_search_dirs)
9526 goto show_help;
9527 else
9528 break;
9530 r = argv[optind++];
9531 if (r[0] != '-') {
9532 /* add a new file */
9533 dynarray_add((void ***)&files, &nb_files, r);
9534 if (!multiple_files) {
9535 optind--;
9536 /* argv[0] will be this file */
9537 break;
9539 } else {
9540 /* find option in table (match only the first chars */
9541 popt = tcc_options;
9542 for(;;) {
9543 p1 = popt->name;
9544 if (p1 == NULL)
9545 error("invalid option -- '%s'", r);
9546 r1 = r + 1;
9547 for(;;) {
9548 if (*p1 == '\0')
9549 goto option_found;
9550 if (*r1 != *p1)
9551 break;
9552 p1++;
9553 r1++;
9555 popt++;
9557 option_found:
9558 if (popt->flags & TCC_OPTION_HAS_ARG) {
9559 if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) {
9560 optarg = r1;
9561 } else {
9562 if (optind >= argc)
9563 error("argument to '%s' is missing", r);
9564 optarg = argv[optind++];
9566 } else {
9567 if (*r1 != '\0')
9568 goto show_help;
9569 optarg = NULL;
9572 switch(popt->index) {
9573 case TCC_OPTION_HELP:
9574 show_help:
9575 help();
9576 return 1;
9577 case TCC_OPTION_I:
9578 if (tcc_add_include_path(s, optarg) < 0)
9579 error("too many include paths");
9580 break;
9581 case TCC_OPTION_D:
9583 char *sym, *value;
9584 sym = (char *)optarg;
9585 value = strchr(sym, '=');
9586 if (value) {
9587 *value = '\0';
9588 value++;
9590 tcc_define_symbol(s, sym, value);
9592 break;
9593 case TCC_OPTION_U:
9594 tcc_undefine_symbol(s, optarg);
9595 break;
9596 case TCC_OPTION_L:
9597 tcc_add_library_path(s, optarg);
9598 break;
9599 case TCC_OPTION_B:
9600 /* set tcc utilities path (mainly for tcc development) */
9601 tcc_lib_path = optarg;
9602 break;
9603 case TCC_OPTION_l:
9604 dynarray_add((void ***)&files, &nb_files, r);
9605 nb_libraries++;
9606 break;
9607 case TCC_OPTION_bench:
9608 do_bench = 1;
9609 break;
9610 case TCC_OPTION_bt:
9611 num_callers = atoi(optarg);
9612 break;
9613 #ifdef CONFIG_TCC_BCHECK
9614 case TCC_OPTION_b:
9615 do_bounds_check = 1;
9616 do_debug = 1;
9617 break;
9618 #endif
9619 case TCC_OPTION_g:
9620 do_debug = 1;
9621 break;
9622 case TCC_OPTION_c:
9623 multiple_files = 1;
9624 output_type = TCC_OUTPUT_OBJ;
9625 break;
9626 case TCC_OPTION_static:
9627 s->static_link = 1;
9628 break;
9629 case TCC_OPTION_shared:
9630 output_type = TCC_OUTPUT_DLL;
9631 break;
9632 case TCC_OPTION_o:
9633 multiple_files = 1;
9634 outfile = optarg;
9635 break;
9636 case TCC_OPTION_r:
9637 /* generate a .o merging several output files */
9638 reloc_output = 1;
9639 output_type = TCC_OUTPUT_OBJ;
9640 break;
9641 case TCC_OPTION_nostdinc:
9642 s->nostdinc = 1;
9643 break;
9644 case TCC_OPTION_print_search_dirs:
9645 print_search_dirs = 1;
9646 break;
9647 case TCC_OPTION_run:
9648 multiple_files = 0;
9649 output_type = TCC_OUTPUT_MEMORY;
9650 break;
9651 case TCC_OPTION_v:
9652 printf("tcc version %s\n", TCC_VERSION);
9653 return 0;
9654 default:
9655 break;
9659 if (print_search_dirs) {
9660 /* enough for Linux kernel */
9661 printf("install: %s/\n", tcc_lib_path);
9662 return 0;
9665 nb_objfiles = nb_files - nb_libraries;
9667 /* if outfile provided without other options, we output an
9668 executable */
9669 if (outfile && output_type == TCC_OUTPUT_MEMORY)
9670 output_type = TCC_OUTPUT_EXE;
9672 /* check -c consistency : only single file handled. XXX: checks file type */
9673 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9674 /* accepts only a single input file */
9675 if (nb_objfiles != 1)
9676 error("cannot specify multiple files with -c");
9677 if (nb_libraries != 0)
9678 error("cannot specify libraries with -c");
9681 /* compute default outfile name */
9682 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
9683 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9684 char *ext;
9685 /* add .o extension */
9686 pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
9687 ext = strrchr(objfilename, '.');
9688 if (!ext)
9689 goto default_outfile;
9690 strcpy(ext + 1, "o");
9691 } else {
9692 default_outfile:
9693 pstrcpy(objfilename, sizeof(objfilename), "a.out");
9695 outfile = objfilename;
9698 if (do_bench) {
9699 start_time = getclock_us();
9702 tcc_set_output_type(s, output_type);
9704 /* compile or add each files or library */
9705 for(i = 0;i < nb_files; i++) {
9706 const char *filename;
9708 filename = files[i];
9709 if (filename[0] == '-') {
9710 if (tcc_add_library(s, filename + 2) < 0)
9711 error("cannot find %s", filename);
9712 } else {
9713 if (tcc_add_file(s, filename) < 0) {
9714 ret = 1;
9715 goto the_end;
9720 /* free all files */
9721 tcc_free(files);
9723 if (do_bench) {
9724 double total_time;
9725 total_time = (double)(getclock_us() - start_time) / 1000000.0;
9726 if (total_time < 0.001)
9727 total_time = 0.001;
9728 if (total_bytes < 1)
9729 total_bytes = 1;
9730 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
9731 tok_ident - TOK_IDENT, total_lines, total_bytes,
9732 total_time, (int)(total_lines / total_time),
9733 total_bytes / total_time / 1000000.0);
9736 if (s->output_type != TCC_OUTPUT_MEMORY) {
9737 tcc_output_file(s, outfile);
9738 ret = 0;
9739 } else {
9740 ret = tcc_run(s, argc - optind, argv + optind);
9742 the_end:
9743 /* XXX: cannot do it with bound checking because of the malloc hooks */
9744 if (!do_bounds_check)
9745 tcc_delete(s);
9747 #ifdef MEM_DEBUG
9748 if (do_bench) {
9749 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
9751 #endif
9752 return ret;
9755 #endif