sanitized string and character constant parsing
[tinycc.git] / tcc.c
blobc557beaf2e8a2f8edfc00ddbbd5057cc5aa675ac
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define _GNU_SOURCE
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <math.h>
27 #include <unistd.h>
28 #include <signal.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <setjmp.h>
32 #ifdef WIN32
33 #include <sys/timeb.h>
34 #endif
35 #ifndef WIN32
36 #include <sys/time.h>
37 #include <sys/ucontext.h>
38 #endif
39 #include "elf.h"
40 #include "stab.h"
41 #ifndef CONFIG_TCC_STATIC
42 #include <dlfcn.h>
43 #endif
45 #include "libtcc.h"
47 /* parser debug */
48 //#define PARSE_DEBUG
49 /* preprocessor debug */
50 //#define PP_DEBUG
51 /* include file debug */
52 //#define INC_DEBUG
54 //#define MEM_DEBUG
56 /* assembler debug */
57 //#define ASM_DEBUG
59 /* target selection */
60 //#define TCC_TARGET_I386 /* i386 code generator */
62 /* default target is I386 */
63 #if !defined(TCC_TARGET_I386)
64 #define TCC_TARGET_I386
65 #endif
67 #if !defined(WIN32) && !defined(TCC_UCLIBC)
68 #define CONFIG_TCC_BCHECK /* enable bound checking code */
69 #endif
71 /* define it to include assembler support */
72 #define CONFIG_TCC_ASM
74 #ifndef CONFIG_TCC_PREFIX
75 #define CONFIG_TCC_PREFIX "/usr/local"
76 #endif
78 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
79 executables or dlls */
80 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
82 #define INCLUDE_STACK_SIZE 32
83 #define IFDEF_STACK_SIZE 64
84 #define VSTACK_SIZE 64
85 #define STRING_MAX_SIZE 1024
87 #define TOK_HASH_SIZE 2048 /* must be a power of two */
88 #define TOK_ALLOC_INCR 512 /* must be a power of two */
89 #define TOK_STR_ALLOC_INCR_BITS 6
90 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
91 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
93 /* token symbol management */
94 typedef struct TokenSym {
95 struct TokenSym *hash_next;
96 struct Sym *sym_define; /* direct pointer to define */
97 struct Sym *sym_label; /* direct pointer to label */
98 struct Sym *sym_struct; /* direct pointer to structure */
99 struct Sym *sym_identifier; /* direct pointer to identifier */
100 int tok; /* token number */
101 int len;
102 char str[1];
103 } TokenSym;
105 typedef struct CString {
106 int size; /* size in bytes */
107 void *data; /* either 'char *' or 'int *' */
108 int size_allocated;
109 void *data_allocated; /* if non NULL, data has been malloced */
110 } CString;
112 /* type definition */
113 typedef struct CType {
114 int t;
115 struct Sym *ref;
116 } CType;
118 /* constant value */
119 typedef union CValue {
120 long double ld;
121 double d;
122 float f;
123 int i;
124 unsigned int ui;
125 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
126 long long ll;
127 unsigned long long ull;
128 struct CString *cstr;
129 void *ptr;
130 int tab[1];
131 } CValue;
133 /* value on stack */
134 typedef struct SValue {
135 CType type; /* type */
136 unsigned short r; /* register + flags */
137 unsigned short r2; /* second register, used for 'long long'
138 type. If not used, set to VT_CONST */
139 CValue c; /* constant, if VT_CONST */
140 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
141 } SValue;
143 /* symbol management */
144 typedef struct Sym {
145 int v; /* symbol token */
146 int r; /* associated register */
147 int c; /* associated number */
148 CType type; /* associated type */
149 struct Sym *next; /* next related symbol */
150 struct Sym *prev; /* prev symbol in stack */
151 struct Sym *prev_tok; /* previous symbol for this token */
152 } Sym;
154 /* section definition */
155 /* XXX: use directly ELF structure for parameters ? */
156 /* special flag to indicate that the section should not be linked to
157 the other ones */
158 #define SHF_PRIVATE 0x80000000
160 typedef struct Section {
161 unsigned long data_offset; /* current data offset */
162 unsigned char *data; /* section data */
163 unsigned long data_allocated; /* used for realloc() handling */
164 int sh_name; /* elf section name (only used during output) */
165 int sh_num; /* elf section number */
166 int sh_type; /* elf section type */
167 int sh_flags; /* elf section flags */
168 int sh_info; /* elf section info */
169 int sh_addralign; /* elf section alignment */
170 int sh_entsize; /* elf entry size */
171 unsigned long sh_size; /* section size (only used during output) */
172 unsigned long sh_addr; /* address at which the section is relocated */
173 unsigned long sh_offset; /* address at which the section is relocated */
174 int nb_hashed_syms; /* used to resize the hash table */
175 struct Section *link; /* link to another section */
176 struct Section *reloc; /* corresponding section for relocation, if any */
177 struct Section *hash; /* hash table for symbols */
178 struct Section *next;
179 char name[64]; /* section name */
180 } Section;
182 typedef struct DLLReference {
183 int level;
184 char name[1];
185 } DLLReference;
187 /* GNUC attribute definition */
188 typedef struct AttributeDef {
189 int aligned;
190 Section *section;
191 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
192 } AttributeDef;
194 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
195 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
196 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
198 /* stored in 'Sym.c' field */
199 #define FUNC_NEW 1 /* ansi function prototype */
200 #define FUNC_OLD 2 /* old function prototype */
201 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
203 /* stored in 'Sym.r' field */
204 #define FUNC_CDECL 0 /* standard c call */
205 #define FUNC_STDCALL 1 /* pascal c call */
207 /* field 'Sym.t' for macros */
208 #define MACRO_OBJ 0 /* object like macro */
209 #define MACRO_FUNC 1 /* function like macro */
211 /* field 'Sym.r' for C labels */
212 #define LABEL_DEFINED 0 /* label is defined */
213 #define LABEL_FORWARD 1 /* label is forward defined */
214 #define LABEL_DECLARED 2 /* label is declared but never used */
216 /* type_decl() types */
217 #define TYPE_ABSTRACT 1 /* type without variable */
218 #define TYPE_DIRECT 2 /* type with variable */
220 #define IO_BUF_SIZE 8192
222 typedef struct BufferedFile {
223 uint8_t *buf_ptr;
224 uint8_t *buf_end;
225 int fd;
226 int line_num; /* current line number - here to simplify code */
227 int ifndef_macro; /* #ifndef macro / #endif search */
228 int ifndef_macro_saved; /* saved ifndef_macro */
229 int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
230 char inc_type; /* type of include */
231 char inc_filename[512]; /* filename specified by the user */
232 char filename[1024]; /* current filename - here to simplify code */
233 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
234 } BufferedFile;
236 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
237 #define CH_EOF (-1) /* end of file */
239 /* parsing state (used to save parser state to reparse part of the
240 source several times) */
241 typedef struct ParseState {
242 int *macro_ptr;
243 int line_num;
244 int tok;
245 CValue tokc;
246 } ParseState;
248 /* used to record tokens */
249 typedef struct TokenString {
250 int *str;
251 int len;
252 int allocated_len;
253 int last_line_num;
254 } TokenString;
256 /* include file cache, used to find files faster and also to eliminate
257 inclusion if the include file is protected by #ifndef ... #endif */
258 typedef struct CachedInclude {
259 int ifndef_macro;
260 char type; /* '"' or '>' to give include type */
261 char filename[1]; /* path specified in #include */
262 } CachedInclude;
264 /* parser */
265 static struct BufferedFile *file;
266 static int ch, tok;
267 static CValue tokc;
268 static CString tokcstr; /* current parsed string, if any */
269 /* additional informations about token */
270 static int tok_flags;
271 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
272 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
273 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
275 static int *macro_ptr, *macro_ptr_allocated;
276 static int *unget_saved_macro_ptr;
277 static int unget_saved_buffer[TOK_MAX_SIZE + 1];
278 static int unget_buffer_enabled;
279 static int parse_flags;
280 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
281 #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
282 #define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
283 token. line feed is also
284 returned at eof */
286 static Section *text_section, *data_section, *bss_section; /* predefined sections */
287 static Section *cur_text_section; /* current section where function code is
288 generated */
289 /* bound check related sections */
290 static Section *bounds_section; /* contains global data bound description */
291 static Section *lbounds_section; /* contains local data bound description */
292 /* symbol sections */
293 static Section *symtab_section, *strtab_section;
295 /* debug sections */
296 static Section *stab_section, *stabstr_section;
298 /* loc : local variable index
299 ind : output code index
300 rsym: return symbol
301 anon_sym: anonymous symbol index
303 static int rsym, anon_sym, ind, loc;
304 /* expression generation modifiers */
305 static int const_wanted; /* true if constant wanted */
306 static int nocode_wanted; /* true if no code generation wanted for an expression */
307 static int global_expr; /* true if compound literals must be allocated
308 globally (used during initializers parsing */
309 static CType func_vt; /* current function return type (used by return
310 instruction) */
311 static int func_vc;
312 static int last_line_num, last_ind, func_ind; /* debug last line number and pc */
313 static int tok_ident;
314 static TokenSym **table_ident;
315 static TokenSym *hash_ident[TOK_HASH_SIZE];
316 static char token_buf[STRING_MAX_SIZE + 1];
317 static char *funcname;
318 static Sym *global_stack, *local_stack;
319 static Sym *define_stack;
320 static Sym *global_label_stack, *local_label_stack;
322 static SValue vstack[VSTACK_SIZE], *vtop;
323 /* some predefined types */
324 static CType char_pointer_type, func_old_type, int_type;
325 /* true if isid(c) || isnum(c) */
326 static unsigned char isidnum_table[256];
328 /* compile with debug symbol (and use them if error during execution) */
329 static int do_debug = 0;
331 /* compile with built-in memory and bounds checker */
332 static int do_bounds_check = 0;
334 /* display benchmark infos */
335 static int do_bench = 0;
336 static int total_lines;
337 static int total_bytes;
339 /* use GNU C extensions */
340 static int gnu_ext = 1;
342 /* use Tiny C extensions */
343 static int tcc_ext = 1;
345 /* max number of callers shown if error */
346 static int num_callers = 6;
347 static const char **rt_bound_error_msg;
349 /* XXX: 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_PREFIX "/lib/tcc";
355 struct TCCState {
356 int output_type;
358 BufferedFile **include_stack_ptr;
359 int *ifdef_stack_ptr;
361 /* include file handling */
362 char **include_paths;
363 int nb_include_paths;
364 char **sysinclude_paths;
365 int nb_sysinclude_paths;
366 CachedInclude **cached_includes;
367 int nb_cached_includes;
369 char **library_paths;
370 int nb_library_paths;
372 /* array of all loaded dlls (including those referenced by loaded
373 dlls) */
374 DLLReference **loaded_dlls;
375 int nb_loaded_dlls;
377 /* sections */
378 Section **sections;
379 int nb_sections; /* number of sections, including first dummy section */
381 /* got handling */
382 Section *got;
383 Section *plt;
384 unsigned long *got_offsets;
385 int nb_got_offsets;
386 /* give the correspondance from symtab indexes to dynsym indexes */
387 int *symtab_to_dynsym;
389 /* temporary dynamic symbol sections (for dll loading) */
390 Section *dynsymtab_section;
391 /* exported dynamic symbol section */
392 Section *dynsym;
394 /* if true, no standard headers are added */
395 int nostdinc;
397 /* if true, static linking is performed */
398 int static_link;
400 /* error handling */
401 void *error_opaque;
402 void (*error_func)(void *opaque, const char *msg);
403 int error_set_jmp_enabled;
404 jmp_buf error_jmp_buf;
405 int nb_errors;
407 /* tiny assembler state */
408 Sym *asm_labels;
410 /* see include_stack_ptr */
411 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
413 /* see ifdef_stack_ptr */
414 int ifdef_stack[IFDEF_STACK_SIZE];
417 /* The current value can be: */
418 #define VT_VALMASK 0x00ff
419 #define VT_CONST 0x00f0 /* constant in vc
420 (must be first non register value) */
421 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
422 #define VT_LOCAL 0x00f2 /* offset on stack */
423 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
424 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
425 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
426 #define VT_LVAL 0x0100 /* var is an lvalue */
427 #define VT_SYM 0x0200 /* a symbol value is added */
428 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
429 char/short stored in integer registers) */
430 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
431 dereferencing value */
432 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
433 bounding function call point is in vc */
434 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
435 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
436 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
437 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
439 /* types */
440 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
442 #define VT_INT 0 /* integer type */
443 #define VT_BYTE 1 /* signed byte type */
444 #define VT_SHORT 2 /* short type */
445 #define VT_VOID 3 /* void type */
446 #define VT_PTR 4 /* pointer */
447 #define VT_ENUM 5 /* enum definition */
448 #define VT_FUNC 6 /* function type */
449 #define VT_STRUCT 7 /* struct/union definition */
450 #define VT_FLOAT 8 /* IEEE float */
451 #define VT_DOUBLE 9 /* IEEE double */
452 #define VT_LDOUBLE 10 /* IEEE long double */
453 #define VT_BOOL 11 /* ISOC99 boolean type */
454 #define VT_LLONG 12 /* 64 bit integer */
455 #define VT_LONG 13 /* long integer (NEVER USED as type, only
456 during parsing) */
457 #define VT_BTYPE 0x000f /* mask for basic type */
458 #define VT_UNSIGNED 0x0010 /* unsigned type */
459 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
460 #define VT_BITFIELD 0x0040 /* bitfield modifier */
462 /* storage */
463 #define VT_EXTERN 0x00000080 /* extern definition */
464 #define VT_STATIC 0x00000100 /* static variable */
465 #define VT_TYPEDEF 0x00000200 /* typedef definition */
466 #define VT_INLINE 0x00000400 /* inline definition */
468 /* type mask (except storage) */
469 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
470 #define VT_TYPE (~(VT_STORAGE))
472 /* token values */
474 /* warning: the following compare tokens depend on i386 asm code */
475 #define TOK_ULT 0x92
476 #define TOK_UGE 0x93
477 #define TOK_EQ 0x94
478 #define TOK_NE 0x95
479 #define TOK_ULE 0x96
480 #define TOK_UGT 0x97
481 #define TOK_LT 0x9c
482 #define TOK_GE 0x9d
483 #define TOK_LE 0x9e
484 #define TOK_GT 0x9f
486 #define TOK_LAND 0xa0
487 #define TOK_LOR 0xa1
489 #define TOK_DEC 0xa2
490 #define TOK_MID 0xa3 /* inc/dec, to void constant */
491 #define TOK_INC 0xa4
492 #define TOK_UDIV 0xb0 /* unsigned division */
493 #define TOK_UMOD 0xb1 /* unsigned modulo */
494 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
495 #define TOK_CINT 0xb3 /* number in tokc */
496 #define TOK_CCHAR 0xb4 /* char constant in tokc */
497 #define TOK_STR 0xb5 /* pointer to string in tokc */
498 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
499 #define TOK_LCHAR 0xb7
500 #define TOK_LSTR 0xb8
501 #define TOK_CFLOAT 0xb9 /* float constant */
502 #define TOK_LINENUM 0xba /* line number info */
503 #define TOK_CDOUBLE 0xc0 /* double constant */
504 #define TOK_CLDOUBLE 0xc1 /* long double constant */
505 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
506 #define TOK_ADDC1 0xc3 /* add with carry generation */
507 #define TOK_ADDC2 0xc4 /* add with carry use */
508 #define TOK_SUBC1 0xc5 /* add with carry generation */
509 #define TOK_SUBC2 0xc6 /* add with carry use */
510 #define TOK_CUINT 0xc8 /* unsigned int constant */
511 #define TOK_CLLONG 0xc9 /* long long constant */
512 #define TOK_CULLONG 0xca /* unsigned long long constant */
513 #define TOK_ARROW 0xcb
514 #define TOK_DOTS 0xcc /* three dots */
515 #define TOK_SHR 0xcd /* unsigned shift right */
516 #define TOK_PPNUM 0xce /* preprocessor number */
518 #define TOK_SHL 0x01 /* shift left */
519 #define TOK_SAR 0x02 /* signed shift right */
521 /* assignement operators : normal operator or 0x80 */
522 #define TOK_A_MOD 0xa5
523 #define TOK_A_AND 0xa6
524 #define TOK_A_MUL 0xaa
525 #define TOK_A_ADD 0xab
526 #define TOK_A_SUB 0xad
527 #define TOK_A_DIV 0xaf
528 #define TOK_A_XOR 0xde
529 #define TOK_A_OR 0xfc
530 #define TOK_A_SHL 0x81
531 #define TOK_A_SAR 0x82
533 /* WARNING: the content of this string encodes token numbers */
534 static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
536 #define TOK_EOF (-1) /* end of file */
537 #define TOK_LINEFEED 10 /* line feed */
539 /* all identificators and strings have token above that */
540 #define TOK_IDENT 256
542 /* only used for i386 asm opcodes definitions */
543 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
545 #define DEF_BWL(x) \
546 DEF(TOK_ASM_ ## x ## b, #x "b") \
547 DEF(TOK_ASM_ ## x ## w, #x "w") \
548 DEF(TOK_ASM_ ## x ## l, #x "l") \
549 DEF(TOK_ASM_ ## x, #x)
551 #define DEF_WL(x) \
552 DEF(TOK_ASM_ ## x ## w, #x "w") \
553 DEF(TOK_ASM_ ## x ## l, #x "l") \
554 DEF(TOK_ASM_ ## x, #x)
556 #define DEF_FP1(x) \
557 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
558 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
559 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
560 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
562 #define DEF_FP(x) \
563 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
564 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
565 DEF_FP1(x)
567 #define DEF_ASMTEST(x) \
568 DEF_ASM(x ## o) \
569 DEF_ASM(x ## no) \
570 DEF_ASM(x ## b) \
571 DEF_ASM(x ## c) \
572 DEF_ASM(x ## nae) \
573 DEF_ASM(x ## nb) \
574 DEF_ASM(x ## nc) \
575 DEF_ASM(x ## ae) \
576 DEF_ASM(x ## e) \
577 DEF_ASM(x ## z) \
578 DEF_ASM(x ## ne) \
579 DEF_ASM(x ## nz) \
580 DEF_ASM(x ## be) \
581 DEF_ASM(x ## na) \
582 DEF_ASM(x ## nbe) \
583 DEF_ASM(x ## a) \
584 DEF_ASM(x ## s) \
585 DEF_ASM(x ## ns) \
586 DEF_ASM(x ## p) \
587 DEF_ASM(x ## pe) \
588 DEF_ASM(x ## np) \
589 DEF_ASM(x ## po) \
590 DEF_ASM(x ## l) \
591 DEF_ASM(x ## nge) \
592 DEF_ASM(x ## nl) \
593 DEF_ASM(x ## ge) \
594 DEF_ASM(x ## le) \
595 DEF_ASM(x ## ng) \
596 DEF_ASM(x ## nle) \
597 DEF_ASM(x ## g)
599 #define TOK_ASM_int TOK_INT
601 enum {
602 TOK_LAST = TOK_IDENT - 1,
603 #define DEF(id, str) id,
604 #include "tcctok.h"
605 #undef DEF
608 static const char tcc_keywords[] =
609 #define DEF(id, str) str "\0"
610 #include "tcctok.h"
611 #undef DEF
614 #define TOK_UIDENT TOK_DEFINE
616 #ifdef WIN32
617 #define snprintf _snprintf
618 #define vsnprintf _vsnprintf
619 #endif
621 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
622 /* currently incorrect */
623 long double strtold(const char *nptr, char **endptr)
625 return (long double)strtod(nptr, endptr);
627 float strtof(const char *nptr, char **endptr)
629 return (float)strtod(nptr, endptr);
631 #else
632 /* XXX: need to define this to use them in non ISOC99 context */
633 extern float strtof (const char *__nptr, char **__endptr);
634 extern long double strtold (const char *__nptr, char **__endptr);
635 #endif
637 static char *pstrcpy(char *buf, int buf_size, const char *s);
638 static char *pstrcat(char *buf, int buf_size, const char *s);
640 static void next(void);
641 static void next_nomacro(void);
642 static void parse_expr_type(CType *type);
643 static void expr_type(CType *type);
644 static void unary_type(CType *type);
645 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
646 int case_reg, int is_expr);
647 static int expr_const(void);
648 static void expr_eq(void);
649 static void gexpr(void);
650 static void decl(int l);
651 static void decl_initializer(CType *type, Section *sec, unsigned long c,
652 int first, int size_only);
653 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
654 int has_init, int v, int scope);
655 int gv(int rc);
656 void gv2(int rc1, int rc2);
657 void move_reg(int r, int s);
658 void save_regs(int n);
659 void save_reg(int r);
660 void vpop(void);
661 void vswap(void);
662 void vdup(void);
663 int get_reg(int rc);
665 static void macro_subst(TokenString *tok_str,
666 Sym **nested_list, const int *macro_str);
667 int save_reg_forced(int r);
668 void gen_op(int op);
669 void force_charshort_cast(int t);
670 static void gen_cast(CType *type);
671 void vstore(void);
672 static Sym *sym_find(int v);
673 static Sym *sym_push(int v, CType *type, int r, int c);
675 /* type handling */
676 static int type_size(CType *type, int *a);
677 static inline CType *pointed_type(CType *type);
678 static int pointed_size(CType *type);
679 static int lvalue_type(int t);
680 static int is_compatible_types(CType *type1, CType *type2);
681 static int parse_btype(CType *type, AttributeDef *ad);
682 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
684 void error(const char *fmt, ...);
685 void vpushi(int v);
686 void vset(CType *type, int r, int v);
687 void type_to_str(char *buf, int buf_size,
688 CType *type, const char *varstr);
689 char *get_tok_str(int v, CValue *cv);
690 static Sym *get_sym_ref(CType *type, Section *sec,
691 unsigned long offset, unsigned long size);
692 static Sym *external_global_sym(int v, CType *type, int r);
694 /* section generation */
695 static void section_realloc(Section *sec, unsigned long new_size);
696 static void *section_ptr_add(Section *sec, unsigned long size);
697 static void put_extern_sym(Sym *sym, Section *section,
698 unsigned long value, unsigned long size);
699 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
700 static int put_elf_str(Section *s, const char *sym);
701 static int put_elf_sym(Section *s,
702 unsigned long value, unsigned long size,
703 int info, int other, int shndx, const char *name);
704 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
705 int info, int sh_num, const char *name);
706 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
707 int type, int symbol);
708 static void put_stabs(const char *str, int type, int other, int desc,
709 unsigned long value);
710 static void put_stabs_r(const char *str, int type, int other, int desc,
711 unsigned long value, Section *sec, int sym_index);
712 static void put_stabn(int type, int other, int desc, int value);
713 static void put_stabd(int type, int other, int desc);
714 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
716 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
717 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
718 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
720 /* tccasm.c */
722 #ifdef CONFIG_TCC_ASM
724 typedef struct ExprValue {
725 uint32_t v;
726 Sym *sym;
727 } ExprValue;
729 #define MAX_ASM_OPERANDS 30
731 typedef struct ASMOperand {
732 int id; /* GCC 3 optionnal identifier (0 if number only supported */
733 char *constraint;
734 char asm_str[16]; /* computed asm string for operand */
735 SValue *vt; /* C value of the expression */
736 int ref_index; /* if >= 0, gives reference to a output constraint */
737 int priority; /* priority, used to assign registers */
738 int reg; /* if >= 0, register number used for this operand */
739 } ASMOperand;
741 static void asm_expr(TCCState *s1, ExprValue *pe);
742 static int asm_int_expr(TCCState *s1);
743 static int find_constraint(ASMOperand *operands, int nb_operands,
744 const char *name, const char **pp);
746 static int tcc_assemble(TCCState *s1, int do_preprocess);
748 #endif
750 static void asm_instr(void);
752 /* true if float/double/long double type */
753 static inline int is_float(int t)
755 int bt;
756 bt = t & VT_BTYPE;
757 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
760 #ifdef TCC_TARGET_I386
761 #include "i386-gen.c"
762 #endif
764 #ifdef CONFIG_TCC_STATIC
766 #define RTLD_LAZY 0x001
767 #define RTLD_NOW 0x002
768 #define RTLD_GLOBAL 0x100
769 #define RTLD_DEFAULT NULL
771 /* dummy function for profiling */
772 void *dlopen(const char *filename, int flag)
774 return NULL;
777 const char *dlerror(void)
779 return "error";
782 typedef struct TCCSyms {
783 char *str;
784 void *ptr;
785 } TCCSyms;
787 #define TCCSYM(a) { #a, &a, },
789 /* add the symbol you want here if no dynamic linking is done */
790 static TCCSyms tcc_syms[] = {
791 TCCSYM(printf)
792 TCCSYM(fprintf)
793 TCCSYM(fopen)
794 TCCSYM(fclose)
795 { NULL, NULL },
798 void *dlsym(void *handle, const char *symbol)
800 TCCSyms *p;
801 p = tcc_syms;
802 while (p->str != NULL) {
803 if (!strcmp(p->str, symbol))
804 return p->ptr;
805 p++;
807 return NULL;
810 #endif
812 /********************************************************/
814 /* we use our own 'finite' function to avoid potential problems with
815 non standard math libs */
816 /* XXX: endianness 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 static void parse_line_comment(void)
1777 /* single line C++ comments */
1778 /* XXX: accept '\\\n' ? */
1779 inp();
1780 while (ch != '\n' && ch != CH_EOF)
1781 inp();
1784 static void parse_comment(void)
1786 uint8_t *p;
1787 int c;
1789 /* C comments */
1790 p = file->buf_ptr;
1791 p++;
1792 for(;;) {
1793 /* fast skip loop */
1794 for(;;) {
1795 c = *p;
1796 if (c == '\n' || c == '*' || c == '\\')
1797 break;
1798 p++;
1799 c = *p;
1800 if (c == '\n' || c == '*' || c == '\\')
1801 break;
1802 p++;
1804 /* now we can handle all the cases */
1805 if (c == '\n') {
1806 file->line_num++;
1807 p++;
1808 } else if (c == '*') {
1809 p++;
1810 for(;;) {
1811 c = *p;
1812 if (c == '*') {
1813 p++;
1814 } else if (c == '/') {
1815 goto end_of_comment;
1816 } else if (c == '\\') {
1817 file->buf_ptr = p;
1818 c = handle_eob();
1819 if (c == '\\') {
1820 /* skip '\\n', but if '\' followed but another
1821 char, behave asif a stray was parsed */
1822 ch = file->buf_ptr[0];
1823 while (ch == '\\') {
1824 inp();
1825 if (ch == '\n') {
1826 file->line_num++;
1827 inp();
1828 } else if (ch == '\r') {
1829 inp();
1830 if (ch == '\n') {
1831 file->line_num++;
1832 inp();
1834 } else {
1835 p = file->buf_ptr;
1836 break;
1840 p = file->buf_ptr;
1841 } else {
1842 break;
1845 } else {
1846 /* stray, eob or eof */
1847 file->buf_ptr = p;
1848 c = handle_eob();
1849 p = file->buf_ptr;
1850 if (c == CH_EOF) {
1851 error("unexpected end of file in comment");
1852 } else if (c == '\\') {
1853 p++;
1857 end_of_comment:
1858 p++;
1859 file->buf_ptr = p;
1860 ch = *p;
1863 #define cinp minp
1865 /* space exlcuding newline */
1866 static inline int is_space(int ch)
1868 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1871 static inline void skip_spaces(void)
1873 while (is_space(ch))
1874 cinp();
1877 /* parse a string without interpreting escapes */
1878 static uint8_t *parse_pp_string(uint8_t *p,
1879 int sep, CString *str)
1881 int c;
1882 p++;
1883 for(;;) {
1884 c = *p;
1885 if (c == sep) {
1886 break;
1887 } else if (c == '\\') {
1888 file->buf_ptr = p;
1889 c = handle_eob();
1890 p = file->buf_ptr;
1891 if (c == CH_EOF) {
1892 unterminated_string:
1893 /* XXX: indicate line number of start of string */
1894 error("missing terminating %c character", sep);
1895 } else if (c == '\\') {
1896 /* escape : just skip \[\r]\n */
1897 PEEKC_EOB(c, p);
1898 if (c == '\n') {
1899 file->line_num++;
1900 p++;
1901 } else if (c == '\r') {
1902 PEEKC_EOB(c, p);
1903 if (c != '\n')
1904 expect("'\n' after '\r'");
1905 file->line_num++;
1906 p++;
1907 } else if (c == CH_EOF) {
1908 goto unterminated_string;
1909 } else {
1910 if (str) {
1911 cstr_ccat(str, '\\');
1912 cstr_ccat(str, c);
1914 p++;
1917 } else if (c == '\n') {
1918 file->line_num++;
1919 goto add_char;
1920 } else if (c == '\r') {
1921 PEEKC_EOB(c, p);
1922 if (c != '\n') {
1923 cstr_ccat(str, '\r');
1924 } else {
1925 file->line_num++;
1926 goto add_char;
1928 } else {
1929 add_char:
1930 if (str)
1931 cstr_ccat(str, c);
1932 p++;
1935 p++;
1936 return p;
1939 /* skip block of text until #else, #elif or #endif. skip also pairs of
1940 #if/#endif */
1941 void preprocess_skip(void)
1943 int a, start_of_line, c;
1944 uint8_t *p;
1946 p = file->buf_ptr;
1947 start_of_line = 1;
1948 a = 0;
1949 for(;;) {
1950 redo_no_start:
1951 c = *p;
1952 switch(c) {
1953 case ' ':
1954 case '\t':
1955 case '\f':
1956 case '\v':
1957 case '\r':
1958 p++;
1959 goto redo_no_start;
1960 case '\n':
1961 start_of_line = 1;
1962 file->line_num++;
1963 p++;
1964 goto redo_no_start;
1965 case '\\':
1966 file->buf_ptr = p;
1967 c = handle_eob();
1968 if (c == CH_EOF) {
1969 expect("#endif");
1970 } else if (c == '\\') {
1971 /* XXX: incorrect: should not give an error */
1972 ch = file->buf_ptr[0];
1973 handle_stray();
1975 p = file->buf_ptr;
1976 goto redo_no_start;
1977 /* skip strings */
1978 case '\"':
1979 case '\'':
1980 p = parse_pp_string(p, c, NULL);
1981 break;
1982 /* skip comments */
1983 case '/':
1984 file->buf_ptr = p;
1985 ch = *p;
1986 minp();
1987 if (ch == '*') {
1988 parse_comment();
1989 } else if (ch == '/') {
1990 parse_line_comment();
1992 p = file->buf_ptr;
1993 break;
1995 case '#':
1996 p++;
1997 if (start_of_line) {
1998 file->buf_ptr = p;
1999 next_nomacro();
2000 p = file->buf_ptr;
2001 if (a == 0 &&
2002 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
2003 goto the_end;
2004 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
2005 a++;
2006 else if (tok == TOK_ENDIF)
2007 a--;
2009 break;
2010 default:
2011 p++;
2012 break;
2014 start_of_line = 0;
2016 the_end: ;
2017 file->buf_ptr = p;
2020 /* ParseState handling */
2022 /* XXX: currently, no include file info is stored. Thus, we cannot display
2023 accurate messages if the function or data definition spans multiple
2024 files */
2026 /* save current parse state in 's' */
2027 void save_parse_state(ParseState *s)
2029 s->line_num = file->line_num;
2030 s->macro_ptr = macro_ptr;
2031 s->tok = tok;
2032 s->tokc = tokc;
2035 /* restore parse state from 's' */
2036 void restore_parse_state(ParseState *s)
2038 file->line_num = s->line_num;
2039 macro_ptr = s->macro_ptr;
2040 tok = s->tok;
2041 tokc = s->tokc;
2044 /* return the number of additional 'ints' necessary to store the
2045 token */
2046 static inline int tok_ext_size(int t)
2048 switch(t) {
2049 /* 4 bytes */
2050 case TOK_CINT:
2051 case TOK_CUINT:
2052 case TOK_CCHAR:
2053 case TOK_LCHAR:
2054 case TOK_STR:
2055 case TOK_LSTR:
2056 case TOK_CFLOAT:
2057 case TOK_LINENUM:
2058 case TOK_PPNUM:
2059 return 1;
2060 case TOK_CDOUBLE:
2061 case TOK_CLLONG:
2062 case TOK_CULLONG:
2063 return 2;
2064 case TOK_CLDOUBLE:
2065 return LDOUBLE_SIZE / 4;
2066 default:
2067 return 0;
2071 /* token string handling */
2073 static inline void tok_str_new(TokenString *s)
2075 s->str = NULL;
2076 s->len = 0;
2077 s->allocated_len = 0;
2078 s->last_line_num = -1;
2081 static void tok_str_free(int *str)
2083 const int *p;
2084 CString *cstr;
2085 int t;
2087 p = str;
2088 for(;;) {
2089 t = *p;
2090 /* NOTE: we test zero separately so that GCC can generate a
2091 table for the following switch */
2092 if (t == 0)
2093 break;
2094 switch(t) {
2095 case TOK_CINT:
2096 case TOK_CUINT:
2097 case TOK_CCHAR:
2098 case TOK_LCHAR:
2099 case TOK_CFLOAT:
2100 case TOK_LINENUM:
2101 p += 2;
2102 break;
2103 case TOK_PPNUM:
2104 case TOK_STR:
2105 case TOK_LSTR:
2106 /* XXX: use a macro to be portable on 64 bit ? */
2107 cstr = (CString *)p[1];
2108 cstr_free(cstr);
2109 tcc_free(cstr);
2110 p += 2;
2111 break;
2112 case TOK_CDOUBLE:
2113 case TOK_CLLONG:
2114 case TOK_CULLONG:
2115 p += 3;
2116 break;
2117 case TOK_CLDOUBLE:
2118 p += 1 + (LDOUBLE_SIZE / 4);
2119 break;
2120 default:
2121 p++;
2122 break;
2125 tcc_free(str);
2128 static int *tok_str_realloc(TokenString *s)
2130 int *str, len;
2132 len = s->allocated_len + TOK_STR_ALLOC_INCR;
2133 str = tcc_realloc(s->str, len * sizeof(int));
2134 if (!str)
2135 error("memory full");
2136 s->allocated_len = len;
2137 s->str = str;
2138 return str;
2141 static void tok_str_add(TokenString *s, int t)
2143 int len, *str;
2145 len = s->len;
2146 str = s->str;
2147 if (len >= s->allocated_len)
2148 str = tok_str_realloc(s);
2149 str[len++] = t;
2150 s->len = len;
2153 static void tok_str_add2(TokenString *s, int t, CValue *cv)
2155 int len, *str;
2157 len = s->len;
2158 str = s->str;
2160 /* allocate space for worst case */
2161 if (len + TOK_MAX_SIZE > s->allocated_len)
2162 str = tok_str_realloc(s);
2163 str[len++] = t;
2164 switch(t) {
2165 case TOK_CINT:
2166 case TOK_CUINT:
2167 case TOK_CCHAR:
2168 case TOK_LCHAR:
2169 case TOK_CFLOAT:
2170 case TOK_LINENUM:
2171 str[len++] = cv->tab[0];
2172 break;
2173 case TOK_PPNUM:
2174 case TOK_STR:
2175 case TOK_LSTR:
2176 str[len++] = (int)cstr_dup(cv->cstr);
2177 break;
2178 case TOK_CDOUBLE:
2179 case TOK_CLLONG:
2180 case TOK_CULLONG:
2181 str[len++] = cv->tab[0];
2182 str[len++] = cv->tab[1];
2183 break;
2184 case TOK_CLDOUBLE:
2185 #if LDOUBLE_SIZE == 12
2186 str[len++] = cv->tab[0];
2187 str[len++] = cv->tab[1];
2188 str[len++] = cv->tab[2];
2189 #else
2190 #error add long double size support
2191 #endif
2192 break;
2193 default:
2194 break;
2196 s->len = len;
2199 /* add the current parse token in token string 's' */
2200 static void tok_str_add_tok(TokenString *s)
2202 CValue cval;
2204 /* save line number info */
2205 if (file->line_num != s->last_line_num) {
2206 s->last_line_num = file->line_num;
2207 cval.i = s->last_line_num;
2208 tok_str_add2(s, TOK_LINENUM, &cval);
2210 tok_str_add2(s, tok, &tokc);
2213 #if LDOUBLE_SIZE == 12
2214 #define LDOUBLE_GET(p, cv) \
2215 cv.tab[0] = p[0]; \
2216 cv.tab[1] = p[1]; \
2217 cv.tab[2] = p[2];
2218 #else
2219 #error add long double size support
2220 #endif
2223 /* get a token from an integer array and increment pointer
2224 accordingly. we code it as a macro to avoid pointer aliasing. */
2225 #define TOK_GET(t, p, cv) \
2227 t = *p++; \
2228 switch(t) { \
2229 case TOK_CINT: \
2230 case TOK_CUINT: \
2231 case TOK_CCHAR: \
2232 case TOK_LCHAR: \
2233 case TOK_CFLOAT: \
2234 case TOK_LINENUM: \
2235 case TOK_STR: \
2236 case TOK_LSTR: \
2237 case TOK_PPNUM: \
2238 cv.tab[0] = *p++; \
2239 break; \
2240 case TOK_CDOUBLE: \
2241 case TOK_CLLONG: \
2242 case TOK_CULLONG: \
2243 cv.tab[0] = p[0]; \
2244 cv.tab[1] = p[1]; \
2245 p += 2; \
2246 break; \
2247 case TOK_CLDOUBLE: \
2248 LDOUBLE_GET(p, cv); \
2249 p += LDOUBLE_SIZE / 4; \
2250 break; \
2251 default: \
2252 break; \
2256 /* defines handling */
2257 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
2259 Sym *s;
2261 s = sym_push2(&define_stack, v, macro_type, (int)str);
2262 s->next = first_arg;
2263 table_ident[v - TOK_IDENT]->sym_define = s;
2266 /* undefined a define symbol. Its name is just set to zero */
2267 static void define_undef(Sym *s)
2269 int v;
2270 v = s->v;
2271 if (v >= TOK_IDENT && v < tok_ident)
2272 table_ident[v - TOK_IDENT]->sym_define = NULL;
2273 s->v = 0;
2276 static inline Sym *define_find(int v)
2278 v -= TOK_IDENT;
2279 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2280 return NULL;
2281 return table_ident[v]->sym_define;
2284 /* free define stack until top reaches 'b' */
2285 static void free_defines(Sym *b)
2287 Sym *top, *top1;
2288 int v;
2290 top = define_stack;
2291 while (top != b) {
2292 top1 = top->prev;
2293 /* do not free args or predefined defines */
2294 if (top->c)
2295 tok_str_free((int *)top->c);
2296 v = top->v;
2297 if (v >= TOK_IDENT && v < tok_ident)
2298 table_ident[v - TOK_IDENT]->sym_define = NULL;
2299 tcc_free(top);
2300 top = top1;
2302 define_stack = b;
2305 /* label lookup */
2306 static Sym *label_find(int v)
2308 v -= TOK_IDENT;
2309 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2310 return NULL;
2311 return table_ident[v]->sym_label;
2314 static Sym *label_push(Sym **ptop, int v, int flags)
2316 Sym *s, **ps;
2317 s = sym_push2(ptop, v, 0, 0);
2318 s->r = flags;
2319 ps = &table_ident[v - TOK_IDENT]->sym_label;
2320 if (ptop == &global_label_stack) {
2321 /* modify the top most local identifier, so that
2322 sym_identifier will point to 's' when popped */
2323 while (*ps != NULL)
2324 ps = &(*ps)->prev_tok;
2326 s->prev_tok = *ps;
2327 *ps = s;
2328 return s;
2331 /* pop labels until element last is reached. Look if any labels are
2332 undefined. Define symbols if '&&label' was used. */
2333 static void label_pop(Sym **ptop, Sym *slast)
2335 Sym *s, *s1;
2336 for(s = *ptop; s != slast; s = s1) {
2337 s1 = s->prev;
2338 if (s->r == LABEL_DECLARED) {
2339 warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
2340 } else if (s->r == LABEL_FORWARD) {
2341 error("label '%s' used but not defined",
2342 get_tok_str(s->v, NULL));
2343 } else {
2344 if (s->c) {
2345 /* define corresponding symbol. A size of
2346 1 is put. */
2347 put_extern_sym(s, cur_text_section, (long)s->next, 1);
2350 /* remove label */
2351 table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
2352 tcc_free(s);
2354 *ptop = slast;
2357 /* eval an expression for #if/#elif */
2358 static int expr_preprocess(void)
2360 int c, t;
2361 TokenString str;
2363 tok_str_new(&str);
2364 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2365 next(); /* do macro subst */
2366 if (tok == TOK_DEFINED) {
2367 next_nomacro();
2368 t = tok;
2369 if (t == '(')
2370 next_nomacro();
2371 c = define_find(tok) != 0;
2372 if (t == '(')
2373 next_nomacro();
2374 tok = TOK_CINT;
2375 tokc.i = c;
2376 } else if (tok >= TOK_IDENT) {
2377 /* if undefined macro */
2378 tok = TOK_CINT;
2379 tokc.i = 0;
2381 tok_str_add_tok(&str);
2383 tok_str_add(&str, -1); /* simulate end of file */
2384 tok_str_add(&str, 0);
2385 /* now evaluate C constant expression */
2386 macro_ptr = str.str;
2387 next();
2388 c = expr_const();
2389 macro_ptr = NULL;
2390 tok_str_free(str.str);
2391 return c != 0;
2394 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2395 static void tok_print(int *str)
2397 int t;
2398 CValue cval;
2400 while (1) {
2401 TOK_GET(t, str, cval);
2402 if (!t)
2403 break;
2404 printf(" %s", get_tok_str(t, &cval));
2406 printf("\n");
2408 #endif
2410 /* parse after #define */
2411 static void parse_define(void)
2413 Sym *s, *first, **ps;
2414 int v, t, varg, is_vaargs, c;
2415 TokenString str;
2417 v = tok;
2418 if (v < TOK_IDENT)
2419 error("invalid macro name '%s'", get_tok_str(tok, &tokc));
2420 /* XXX: should check if same macro (ANSI) */
2421 first = NULL;
2422 t = MACRO_OBJ;
2423 /* '(' must be just after macro definition for MACRO_FUNC */
2424 c = file->buf_ptr[0];
2425 if (c == '\\')
2426 c = handle_stray1(file->buf_ptr);
2427 if (c == '(') {
2428 next_nomacro();
2429 next_nomacro();
2430 ps = &first;
2431 while (tok != ')') {
2432 varg = tok;
2433 next_nomacro();
2434 is_vaargs = 0;
2435 if (varg == TOK_DOTS) {
2436 varg = TOK___VA_ARGS__;
2437 is_vaargs = 1;
2438 } else if (tok == TOK_DOTS && gnu_ext) {
2439 is_vaargs = 1;
2440 next_nomacro();
2442 if (varg < TOK_IDENT)
2443 error("badly punctuated parameter list");
2444 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
2445 *ps = s;
2446 ps = &s->next;
2447 if (tok != ',')
2448 break;
2449 next_nomacro();
2451 t = MACRO_FUNC;
2453 tok_str_new(&str);
2454 next_nomacro();
2455 /* EOF testing necessary for '-D' handling */
2456 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2457 tok_str_add2(&str, tok, &tokc);
2458 next_nomacro();
2460 tok_str_add(&str, 0);
2461 #ifdef PP_DEBUG
2462 printf("define %s %d: ", get_tok_str(v, NULL), t);
2463 tok_print(str.str);
2464 #endif
2465 define_push(v, t, str.str, first);
2468 /* XXX: use a token or a hash table to accelerate matching ? */
2469 static CachedInclude *search_cached_include(TCCState *s1,
2470 int type, const char *filename)
2472 CachedInclude *e;
2473 int i;
2475 for(i = 0;i < s1->nb_cached_includes; i++) {
2476 e = s1->cached_includes[i];
2477 if (e->type == type && !strcmp(e->filename, filename))
2478 return e;
2480 return NULL;
2483 static inline void add_cached_include(TCCState *s1, int type,
2484 const char *filename, int ifndef_macro)
2486 CachedInclude *e;
2488 if (search_cached_include(s1, type, filename))
2489 return;
2490 #ifdef INC_DEBUG
2491 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
2492 #endif
2493 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
2494 if (!e)
2495 return;
2496 e->type = type;
2497 strcpy(e->filename, filename);
2498 e->ifndef_macro = ifndef_macro;
2499 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
2502 /* is_bof is true if first non space token at beginning of file */
2503 static void preprocess(int is_bof)
2505 TCCState *s1 = tcc_state;
2506 int size, i, c, n, saved_parse_flags;
2507 char buf[1024], *q, *p;
2508 char buf1[1024];
2509 BufferedFile *f;
2510 Sym *s;
2511 CachedInclude *e;
2513 saved_parse_flags = parse_flags;
2514 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
2515 PARSE_FLAG_LINEFEED;
2516 next_nomacro();
2517 redo:
2518 switch(tok) {
2519 case TOK_DEFINE:
2520 next_nomacro();
2521 parse_define();
2522 break;
2523 case TOK_UNDEF:
2524 next_nomacro();
2525 s = define_find(tok);
2526 /* undefine symbol by putting an invalid name */
2527 if (s)
2528 define_undef(s);
2529 break;
2530 case TOK_INCLUDE:
2531 ch = file->buf_ptr[0];
2532 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2533 skip_spaces();
2534 if (ch == '<') {
2535 c = '>';
2536 goto read_name;
2537 } else if (ch == '\"') {
2538 c = ch;
2539 read_name:
2540 /* XXX: better stray handling */
2541 minp();
2542 q = buf;
2543 while (ch != c && ch != '\n' && ch != CH_EOF) {
2544 if ((q - buf) < sizeof(buf) - 1)
2545 *q++ = ch;
2546 minp();
2548 *q = '\0';
2549 minp();
2550 #if 0
2551 /* eat all spaces and comments after include */
2552 /* XXX: slightly incorrect */
2553 while (ch1 != '\n' && ch1 != CH_EOF)
2554 inp();
2555 #endif
2556 } else {
2557 /* computed #include : either we have only strings or
2558 we have anything enclosed in '<>' */
2559 next();
2560 buf[0] = '\0';
2561 if (tok == TOK_STR) {
2562 while (tok != TOK_LINEFEED) {
2563 if (tok != TOK_STR) {
2564 include_syntax:
2565 error("'#include' expects \"FILENAME\" or <FILENAME>");
2567 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2568 next();
2570 c = '\"';
2571 } else {
2572 int len;
2573 while (tok != TOK_LINEFEED) {
2574 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2575 next();
2577 len = strlen(buf);
2578 /* check syntax and remove '<>' */
2579 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2580 goto include_syntax;
2581 memmove(buf, buf + 1, len - 2);
2582 buf[len - 2] = '\0';
2583 c = '>';
2587 e = search_cached_include(s1, c, buf);
2588 if (e && define_find(e->ifndef_macro)) {
2589 /* no need to parse the include because the 'ifndef macro'
2590 is defined */
2591 #ifdef INC_DEBUG
2592 printf("%s: skipping %s\n", file->filename, buf);
2593 #endif
2594 } else {
2595 if (c == '\"') {
2596 /* first search in current dir if "header.h" */
2597 size = 0;
2598 p = strrchr(file->filename, '/');
2599 if (p)
2600 size = p + 1 - file->filename;
2601 if (size > sizeof(buf1) - 1)
2602 size = sizeof(buf1) - 1;
2603 memcpy(buf1, file->filename, size);
2604 buf1[size] = '\0';
2605 pstrcat(buf1, sizeof(buf1), buf);
2606 f = tcc_open(s1, buf1);
2607 if (f)
2608 goto found;
2610 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2611 error("#include recursion too deep");
2612 /* now search in all the include paths */
2613 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2614 for(i = 0; i < n; i++) {
2615 const char *path;
2616 if (i < s1->nb_include_paths)
2617 path = s1->include_paths[i];
2618 else
2619 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2620 pstrcpy(buf1, sizeof(buf1), path);
2621 pstrcat(buf1, sizeof(buf1), "/");
2622 pstrcat(buf1, sizeof(buf1), buf);
2623 f = tcc_open(s1, buf1);
2624 if (f)
2625 goto found;
2627 error("include file '%s' not found", buf);
2628 f = NULL;
2629 found:
2630 #ifdef INC_DEBUG
2631 printf("%s: including %s\n", file->filename, buf1);
2632 #endif
2633 f->inc_type = c;
2634 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2635 /* push current file in stack */
2636 /* XXX: fix current line init */
2637 *s1->include_stack_ptr++ = file;
2638 file = f;
2639 /* add include file debug info */
2640 if (do_debug) {
2641 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2643 tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
2644 ch = file->buf_ptr[0];
2645 goto the_end;
2647 break;
2648 case TOK_IFNDEF:
2649 c = 1;
2650 goto do_ifdef;
2651 case TOK_IF:
2652 c = expr_preprocess();
2653 goto do_if;
2654 case TOK_IFDEF:
2655 c = 0;
2656 do_ifdef:
2657 next_nomacro();
2658 if (tok < TOK_IDENT)
2659 error("invalid argument for '#if%sdef'", c ? "n" : "");
2660 if (is_bof) {
2661 if (c) {
2662 #ifdef INC_DEBUG
2663 printf("#ifndef %s\n", get_tok_str(tok, NULL));
2664 #endif
2665 file->ifndef_macro = tok;
2668 c = (define_find(tok) != 0) ^ c;
2669 do_if:
2670 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2671 error("memory full");
2672 *s1->ifdef_stack_ptr++ = c;
2673 goto test_skip;
2674 case TOK_ELSE:
2675 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2676 error("#else without matching #if");
2677 if (s1->ifdef_stack_ptr[-1] & 2)
2678 error("#else after #else");
2679 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2680 goto test_skip;
2681 case TOK_ELIF:
2682 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2683 error("#elif without matching #if");
2684 c = s1->ifdef_stack_ptr[-1];
2685 if (c > 1)
2686 error("#elif after #else");
2687 /* last #if/#elif expression was true: we skip */
2688 if (c == 1)
2689 goto skip;
2690 c = expr_preprocess();
2691 s1->ifdef_stack_ptr[-1] = c;
2692 test_skip:
2693 if (!(c & 1)) {
2694 skip:
2695 preprocess_skip();
2696 is_bof = 0;
2697 goto redo;
2699 break;
2700 case TOK_ENDIF:
2701 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2702 error("#endif without matching #if");
2703 s1->ifdef_stack_ptr--;
2704 /* '#ifndef macro' was at the start of file. Now we check if
2705 an '#endif' is exactly at the end of file */
2706 if (file->ifndef_macro &&
2707 s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
2708 file->ifndef_macro_saved = file->ifndef_macro;
2709 /* need to set to zero to avoid false matches if another
2710 #ifndef at middle of file */
2711 file->ifndef_macro = 0;
2712 while (tok != TOK_LINEFEED)
2713 next_nomacro();
2714 tok_flags |= TOK_FLAG_ENDIF;
2715 goto the_end;
2717 break;
2718 case TOK_LINE:
2719 next();
2720 if (tok != TOK_CINT)
2721 error("#line");
2722 file->line_num = tokc.i - 1; /* the line number will be incremented after */
2723 next();
2724 if (tok != TOK_LINEFEED) {
2725 if (tok != TOK_STR)
2726 error("#line");
2727 pstrcpy(file->filename, sizeof(file->filename),
2728 (char *)tokc.cstr->data);
2730 break;
2731 case TOK_ERROR:
2732 case TOK_WARNING:
2733 c = tok;
2734 ch = file->buf_ptr[0];
2735 skip_spaces();
2736 q = buf;
2737 while (ch != '\n' && ch != CH_EOF) {
2738 if ((q - buf) < sizeof(buf) - 1)
2739 *q++ = ch;
2740 minp();
2742 *q = '\0';
2743 if (c == TOK_ERROR)
2744 error("#error %s", buf);
2745 else
2746 warning("#warning %s", buf);
2747 break;
2748 case TOK_PRAGMA:
2749 /* ignored */
2750 break;
2751 default:
2752 if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
2753 /* '!' is ignored to allow C scripts. numbers are ignored
2754 to emulate cpp behaviour */
2755 } else {
2756 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
2758 break;
2760 /* ignore other preprocess commands or #! for C scripts */
2761 while (tok != TOK_LINEFEED)
2762 next_nomacro();
2763 the_end:
2764 parse_flags = saved_parse_flags;
2767 /* evaluate escape codes in a string. */
2768 static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
2770 int c, n;
2771 const char *p;
2773 p = buf;
2774 for(;;) {
2775 c = *p;
2776 if (c == '\0')
2777 break;
2778 if (c == '\\') {
2779 p++;
2780 /* escape */
2781 c = *p;
2782 switch(c) {
2783 case '0': case '1': case '2': case '3':
2784 case '4': case '5': case '6': case '7':
2785 /* at most three octal digits */
2786 n = c - '0';
2787 p++;
2788 c = *p;
2789 if (isoct(c)) {
2790 n = n * 8 + c - '0';
2791 p++;
2792 c = *p;
2793 if (isoct(c)) {
2794 n = n * 8 + c - '0';
2795 p++;
2798 c = n;
2799 goto add_char_nonext;
2800 case 'x':
2801 p++;
2802 n = 0;
2803 for(;;) {
2804 c = *p;
2805 if (c >= 'a' && c <= 'f')
2806 c = c - 'a' + 10;
2807 else if (c >= 'A' && c <= 'F')
2808 c = c - 'A' + 10;
2809 else if (isnum(c))
2810 c = c - '0';
2811 else
2812 break;
2813 n = n * 16 + c;
2814 p++;
2816 c = n;
2817 goto add_char_nonext;
2818 case 'a':
2819 c = '\a';
2820 break;
2821 case 'b':
2822 c = '\b';
2823 break;
2824 case 'f':
2825 c = '\f';
2826 break;
2827 case 'n':
2828 c = '\n';
2829 break;
2830 case 'r':
2831 c = '\r';
2832 break;
2833 case 't':
2834 c = '\t';
2835 break;
2836 case 'v':
2837 c = '\v';
2838 break;
2839 case 'e':
2840 if (!gnu_ext)
2841 goto invalid_escape;
2842 c = 27;
2843 break;
2844 case '\'':
2845 case '\"':
2846 case '\\':
2847 case '?':
2848 break;
2849 default:
2850 invalid_escape:
2851 error("invalid escaped char");
2854 p++;
2855 add_char_nonext:
2856 if (!is_long)
2857 cstr_ccat(outstr, c);
2858 else
2859 cstr_wccat(outstr, c);
2861 /* add a trailing '\0' */
2862 if (!is_long)
2863 cstr_ccat(outstr, '\0');
2864 else
2865 cstr_wccat(outstr, '\0');
2868 /* we use 64 bit numbers */
2869 #define BN_SIZE 2
2871 /* bn = (bn << shift) | or_val */
2872 void bn_lshift(unsigned int *bn, int shift, int or_val)
2874 int i;
2875 unsigned int v;
2876 for(i=0;i<BN_SIZE;i++) {
2877 v = bn[i];
2878 bn[i] = (v << shift) | or_val;
2879 or_val = v >> (32 - shift);
2883 void bn_zero(unsigned int *bn)
2885 int i;
2886 for(i=0;i<BN_SIZE;i++) {
2887 bn[i] = 0;
2891 /* parse number in null terminated string 'p' and return it in the
2892 current token */
2893 void parse_number(const char *p)
2895 int b, t, shift, frac_bits, s, exp_val, ch;
2896 char *q;
2897 unsigned int bn[BN_SIZE];
2898 double d;
2900 /* number */
2901 q = token_buf;
2902 ch = *p++;
2903 t = ch;
2904 ch = *p++;
2905 *q++ = t;
2906 b = 10;
2907 if (t == '.') {
2908 goto float_frac_parse;
2909 } else if (t == '0') {
2910 if (ch == 'x' || ch == 'X') {
2911 q--;
2912 ch = *p++;
2913 b = 16;
2914 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2915 q--;
2916 ch = *p++;
2917 b = 2;
2920 /* parse all digits. cannot check octal numbers at this stage
2921 because of floating point constants */
2922 while (1) {
2923 if (ch >= 'a' && ch <= 'f')
2924 t = ch - 'a' + 10;
2925 else if (ch >= 'A' && ch <= 'F')
2926 t = ch - 'A' + 10;
2927 else if (isnum(ch))
2928 t = ch - '0';
2929 else
2930 break;
2931 if (t >= b)
2932 break;
2933 if (q >= token_buf + STRING_MAX_SIZE) {
2934 num_too_long:
2935 error("number too long");
2937 *q++ = ch;
2938 ch = *p++;
2940 if (ch == '.' ||
2941 ((ch == 'e' || ch == 'E') && b == 10) ||
2942 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2943 if (b != 10) {
2944 /* NOTE: strtox should support that for hexa numbers, but
2945 non ISOC99 libcs do not support it, so we prefer to do
2946 it by hand */
2947 /* hexadecimal or binary floats */
2948 /* XXX: handle overflows */
2949 *q = '\0';
2950 if (b == 16)
2951 shift = 4;
2952 else
2953 shift = 2;
2954 bn_zero(bn);
2955 q = token_buf;
2956 while (1) {
2957 t = *q++;
2958 if (t == '\0') {
2959 break;
2960 } else if (t >= 'a') {
2961 t = t - 'a' + 10;
2962 } else if (t >= 'A') {
2963 t = t - 'A' + 10;
2964 } else {
2965 t = t - '0';
2967 bn_lshift(bn, shift, t);
2969 frac_bits = 0;
2970 if (ch == '.') {
2971 ch = *p++;
2972 while (1) {
2973 t = ch;
2974 if (t >= 'a' && t <= 'f') {
2975 t = t - 'a' + 10;
2976 } else if (t >= 'A' && t <= 'F') {
2977 t = t - 'A' + 10;
2978 } else if (t >= '0' && t <= '9') {
2979 t = t - '0';
2980 } else {
2981 break;
2983 if (t >= b)
2984 error("invalid digit");
2985 bn_lshift(bn, shift, t);
2986 frac_bits += shift;
2987 ch = *p++;
2990 if (ch != 'p' && ch != 'P')
2991 expect("exponent");
2992 ch = *p++;
2993 s = 1;
2994 exp_val = 0;
2995 if (ch == '+') {
2996 ch = *p++;
2997 } else if (ch == '-') {
2998 s = -1;
2999 ch = *p++;
3001 if (ch < '0' || ch > '9')
3002 expect("exponent digits");
3003 while (ch >= '0' && ch <= '9') {
3004 exp_val = exp_val * 10 + ch - '0';
3005 ch = *p++;
3007 exp_val = exp_val * s;
3009 /* now we can generate the number */
3010 /* XXX: should patch directly float number */
3011 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
3012 d = ldexp(d, exp_val - frac_bits);
3013 t = toup(ch);
3014 if (t == 'F') {
3015 ch = *p++;
3016 tok = TOK_CFLOAT;
3017 /* float : should handle overflow */
3018 tokc.f = (float)d;
3019 } else if (t == 'L') {
3020 ch = *p++;
3021 tok = TOK_CLDOUBLE;
3022 /* XXX: not large enough */
3023 tokc.ld = (long double)d;
3024 } else {
3025 tok = TOK_CDOUBLE;
3026 tokc.d = d;
3028 } else {
3029 /* decimal floats */
3030 if (ch == '.') {
3031 if (q >= token_buf + STRING_MAX_SIZE)
3032 goto num_too_long;
3033 *q++ = ch;
3034 ch = *p++;
3035 float_frac_parse:
3036 while (ch >= '0' && ch <= '9') {
3037 if (q >= token_buf + STRING_MAX_SIZE)
3038 goto num_too_long;
3039 *q++ = ch;
3040 ch = *p++;
3043 if (ch == 'e' || ch == 'E') {
3044 if (q >= token_buf + STRING_MAX_SIZE)
3045 goto num_too_long;
3046 *q++ = ch;
3047 ch = *p++;
3048 if (ch == '-' || ch == '+') {
3049 if (q >= token_buf + STRING_MAX_SIZE)
3050 goto num_too_long;
3051 *q++ = ch;
3052 ch = *p++;
3054 if (ch < '0' || ch > '9')
3055 expect("exponent digits");
3056 while (ch >= '0' && ch <= '9') {
3057 if (q >= token_buf + STRING_MAX_SIZE)
3058 goto num_too_long;
3059 *q++ = ch;
3060 ch = *p++;
3063 *q = '\0';
3064 t = toup(ch);
3065 errno = 0;
3066 if (t == 'F') {
3067 ch = *p++;
3068 tok = TOK_CFLOAT;
3069 tokc.f = strtof(token_buf, NULL);
3070 } else if (t == 'L') {
3071 ch = *p++;
3072 tok = TOK_CLDOUBLE;
3073 tokc.ld = strtold(token_buf, NULL);
3074 } else {
3075 tok = TOK_CDOUBLE;
3076 tokc.d = strtod(token_buf, NULL);
3079 } else {
3080 unsigned long long n, n1;
3081 int lcount, ucount;
3083 /* integer number */
3084 *q = '\0';
3085 q = token_buf;
3086 if (b == 10 && *q == '0') {
3087 b = 8;
3088 q++;
3090 n = 0;
3091 while(1) {
3092 t = *q++;
3093 /* no need for checks except for base 10 / 8 errors */
3094 if (t == '\0') {
3095 break;
3096 } else if (t >= 'a') {
3097 t = t - 'a' + 10;
3098 } else if (t >= 'A') {
3099 t = t - 'A' + 10;
3100 } else {
3101 t = t - '0';
3102 if (t >= b)
3103 error("invalid digit");
3105 n1 = n;
3106 n = n * b + t;
3107 /* detect overflow */
3108 /* XXX: this test is not reliable */
3109 if (n < n1)
3110 error("integer constant overflow");
3113 /* XXX: not exactly ANSI compliant */
3114 if ((n & 0xffffffff00000000LL) != 0) {
3115 if ((n >> 63) != 0)
3116 tok = TOK_CULLONG;
3117 else
3118 tok = TOK_CLLONG;
3119 } else if (n > 0x7fffffff) {
3120 tok = TOK_CUINT;
3121 } else {
3122 tok = TOK_CINT;
3124 lcount = 0;
3125 ucount = 0;
3126 for(;;) {
3127 t = toup(ch);
3128 if (t == 'L') {
3129 if (lcount >= 2)
3130 error("three 'l's in integer constant");
3131 lcount++;
3132 if (lcount == 2) {
3133 if (tok == TOK_CINT)
3134 tok = TOK_CLLONG;
3135 else if (tok == TOK_CUINT)
3136 tok = TOK_CULLONG;
3138 ch = *p++;
3139 } else if (t == 'U') {
3140 if (ucount >= 1)
3141 error("two 'u's in integer constant");
3142 ucount++;
3143 if (tok == TOK_CINT)
3144 tok = TOK_CUINT;
3145 else if (tok == TOK_CLLONG)
3146 tok = TOK_CULLONG;
3147 ch = *p++;
3148 } else {
3149 break;
3152 if (tok == TOK_CINT || tok == TOK_CUINT)
3153 tokc.ui = n;
3154 else
3155 tokc.ull = n;
3160 #define PARSE2(c1, tok1, c2, tok2) \
3161 case c1: \
3162 PEEKC(c, p); \
3163 if (c == c2) { \
3164 p++; \
3165 tok = tok2; \
3166 } else { \
3167 tok = tok1; \
3169 break;
3171 /* return next token without macro substitution */
3172 static inline void next_nomacro1(void)
3174 int t, c, is_long;
3175 TokenSym *ts;
3176 uint8_t *p, *p1;
3177 unsigned int h;
3179 p = file->buf_ptr;
3180 redo_no_start:
3181 c = *p;
3182 switch(c) {
3183 case ' ':
3184 case '\t':
3185 case '\f':
3186 case '\v':
3187 case '\r':
3188 p++;
3189 goto redo_no_start;
3191 case '\\':
3192 /* first look if it is in fact an end of buffer */
3193 if (p >= file->buf_end) {
3194 file->buf_ptr = p;
3195 handle_eob();
3196 p = file->buf_ptr;
3197 if (p >= file->buf_end)
3198 goto parse_eof;
3199 else
3200 goto redo_no_start;
3201 } else {
3202 file->buf_ptr = p;
3203 ch = *p;
3204 handle_stray();
3205 p = file->buf_ptr;
3206 goto redo_no_start;
3208 parse_eof:
3210 TCCState *s1 = tcc_state;
3211 if (parse_flags & PARSE_FLAG_LINEFEED) {
3212 tok = TOK_LINEFEED;
3213 } else if (s1->include_stack_ptr == s1->include_stack ||
3214 !(parse_flags & PARSE_FLAG_PREPROCESS)) {
3215 /* no include left : end of file. */
3216 tok = TOK_EOF;
3217 } else {
3218 /* pop include file */
3220 /* test if previous '#endif' was after a #ifdef at
3221 start of file */
3222 if (tok_flags & TOK_FLAG_ENDIF) {
3223 #ifdef INC_DEBUG
3224 printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
3225 #endif
3226 add_cached_include(s1, file->inc_type, file->inc_filename,
3227 file->ifndef_macro_saved);
3230 /* add end of include file debug info */
3231 if (do_debug) {
3232 put_stabd(N_EINCL, 0, 0);
3234 /* pop include stack */
3235 tcc_close(file);
3236 s1->include_stack_ptr--;
3237 file = *s1->include_stack_ptr;
3238 p = file->buf_ptr;
3239 goto redo_no_start;
3242 break;
3244 case '\n':
3245 if (parse_flags & PARSE_FLAG_LINEFEED) {
3246 tok = TOK_LINEFEED;
3247 } else {
3248 file->line_num++;
3249 tok_flags |= TOK_FLAG_BOL;
3250 p++;
3251 goto redo_no_start;
3253 break;
3255 case '#':
3256 /* XXX: simplify */
3257 PEEKC(c, p);
3258 if ((tok_flags & TOK_FLAG_BOL) &&
3259 (parse_flags & PARSE_FLAG_PREPROCESS)) {
3260 file->buf_ptr = p;
3261 preprocess(tok_flags & TOK_FLAG_BOF);
3262 p = file->buf_ptr;
3263 goto redo_no_start;
3264 } else {
3265 if (c == '#') {
3266 p++;
3267 tok = TOK_TWOSHARPS;
3268 } else {
3269 tok = '#';
3272 break;
3274 case 'a': case 'b': case 'c': case 'd':
3275 case 'e': case 'f': case 'g': case 'h':
3276 case 'i': case 'j': case 'k': case 'l':
3277 case 'm': case 'n': case 'o': case 'p':
3278 case 'q': case 'r': case 's': case 't':
3279 case 'u': case 'v': case 'w': case 'x':
3280 case 'y': case 'z':
3281 case 'A': case 'B': case 'C': case 'D':
3282 case 'E': case 'F': case 'G': case 'H':
3283 case 'I': case 'J': case 'K':
3284 case 'M': case 'N': case 'O': case 'P':
3285 case 'Q': case 'R': case 'S': case 'T':
3286 case 'U': case 'V': case 'W': case 'X':
3287 case 'Y': case 'Z':
3288 case '_':
3289 parse_ident_fast:
3290 p1 = p;
3291 h = TOK_HASH_INIT;
3292 h = TOK_HASH_FUNC(h, c);
3293 p++;
3294 for(;;) {
3295 c = *p;
3296 if (!isidnum_table[c])
3297 break;
3298 h = TOK_HASH_FUNC(h, c);
3299 p++;
3301 if (c != '\\') {
3302 TokenSym **pts;
3303 int len;
3305 /* fast case : no stray found, so we have the full token
3306 and we have already hashed it */
3307 len = p - p1;
3308 h &= (TOK_HASH_SIZE - 1);
3309 pts = &hash_ident[h];
3310 for(;;) {
3311 ts = *pts;
3312 if (!ts)
3313 break;
3314 if (ts->len == len && !memcmp(ts->str, p1, len))
3315 goto token_found;
3316 pts = &(ts->hash_next);
3318 ts = tok_alloc_new(pts, p1, len);
3319 token_found: ;
3320 } else {
3321 /* slower case */
3322 cstr_reset(&tokcstr);
3324 while (p1 < p) {
3325 cstr_ccat(&tokcstr, *p1);
3326 p1++;
3328 p--;
3329 PEEKC(c, p);
3330 parse_ident_slow:
3331 while (isidnum_table[c]) {
3332 cstr_ccat(&tokcstr, c);
3333 PEEKC(c, p);
3335 ts = tok_alloc(tokcstr.data, tokcstr.size);
3337 tok = ts->tok;
3338 break;
3339 case 'L':
3340 t = p[1];
3341 if (t != '\\' && t != '\'' && t != '\"') {
3342 /* fast case */
3343 goto parse_ident_fast;
3344 } else {
3345 PEEKC(c, p);
3346 if (c == '\'' || c == '\"') {
3347 is_long = 1;
3348 goto str_const;
3349 } else {
3350 cstr_reset(&tokcstr);
3351 cstr_ccat(&tokcstr, 'L');
3352 goto parse_ident_slow;
3355 break;
3356 case '0': case '1': case '2': case '3':
3357 case '4': case '5': case '6': case '7':
3358 case '8': case '9':
3360 cstr_reset(&tokcstr);
3361 /* after the first digit, accept digits, alpha, '.' or sign if
3362 prefixed by 'eEpP' */
3363 parse_num:
3364 for(;;) {
3365 t = c;
3366 cstr_ccat(&tokcstr, c);
3367 PEEKC(c, p);
3368 if (!(isnum(c) || isid(c) || c == '.' ||
3369 ((c == '+' || c == '-') &&
3370 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
3371 break;
3373 /* We add a trailing '\0' to ease parsing */
3374 cstr_ccat(&tokcstr, '\0');
3375 tokc.cstr = &tokcstr;
3376 tok = TOK_PPNUM;
3377 break;
3378 case '.':
3379 /* special dot handling because it can also start a number */
3380 PEEKC(c, p);
3381 if (isnum(c)) {
3382 cstr_reset(&tokcstr);
3383 cstr_ccat(&tokcstr, '.');
3384 goto parse_num;
3385 } else if (c == '.') {
3386 PEEKC(c, p);
3387 if (c != '.')
3388 expect("'.'");
3389 PEEKC(c, p);
3390 tok = TOK_DOTS;
3391 } else {
3392 tok = '.';
3394 break;
3395 case '\'':
3396 case '\"':
3397 is_long = 0;
3398 str_const:
3400 CString str;
3401 int sep;
3403 sep = c;
3405 /* parse the string */
3406 cstr_new(&str);
3407 p = parse_pp_string(p, sep, &str);
3408 cstr_ccat(&str, '\0');
3410 /* eval the escape (should be done as TOK_PPNUM) */
3411 cstr_reset(&tokcstr);
3412 parse_escape_string(&tokcstr, str.data, is_long);
3413 cstr_free(&str);
3415 if (sep == '\'') {
3416 int char_size;
3417 /* XXX: make it portable */
3418 if (!is_long)
3419 char_size = 1;
3420 else
3421 char_size = sizeof(int);
3422 if (tokcstr.size <= char_size)
3423 error("empty character constant");
3424 if (tokcstr.size > 2 * char_size)
3425 warning("multi-character character constant");
3426 if (!is_long) {
3427 tokc.i = *(int8_t *)tokcstr.data;
3428 tok = TOK_CCHAR;
3429 } else {
3430 tokc.i = *(int *)tokcstr.data;
3431 tok = TOK_LCHAR;
3433 } else {
3434 tokc.cstr = &tokcstr;
3435 if (!is_long)
3436 tok = TOK_STR;
3437 else
3438 tok = TOK_LSTR;
3441 break;
3443 case '<':
3444 PEEKC(c, p);
3445 if (c == '=') {
3446 p++;
3447 tok = TOK_LE;
3448 } else if (c == '<') {
3449 PEEKC(c, p);
3450 if (c == '=') {
3451 p++;
3452 tok = TOK_A_SHL;
3453 } else {
3454 tok = TOK_SHL;
3456 } else {
3457 tok = TOK_LT;
3459 break;
3461 case '>':
3462 PEEKC(c, p);
3463 if (c == '=') {
3464 p++;
3465 tok = TOK_GE;
3466 } else if (c == '>') {
3467 PEEKC(c, p);
3468 if (c == '=') {
3469 p++;
3470 tok = TOK_A_SAR;
3471 } else {
3472 tok = TOK_SAR;
3474 } else {
3475 tok = TOK_GT;
3477 break;
3479 case '&':
3480 PEEKC(c, p);
3481 if (c == '&') {
3482 p++;
3483 tok = TOK_LAND;
3484 } else if (c == '=') {
3485 p++;
3486 tok = TOK_A_AND;
3487 } else {
3488 tok = '&';
3490 break;
3492 case '|':
3493 PEEKC(c, p);
3494 if (c == '|') {
3495 p++;
3496 tok = TOK_LOR;
3497 } else if (c == '=') {
3498 p++;
3499 tok = TOK_A_OR;
3500 } else {
3501 tok = '|';
3503 break;
3505 case '+':
3506 PEEKC(c, p);
3507 if (c == '+') {
3508 p++;
3509 tok = TOK_INC;
3510 } else if (c == '=') {
3511 p++;
3512 tok = TOK_A_ADD;
3513 } else {
3514 tok = '+';
3516 break;
3518 case '-':
3519 PEEKC(c, p);
3520 if (c == '-') {
3521 p++;
3522 tok = TOK_DEC;
3523 } else if (c == '=') {
3524 p++;
3525 tok = TOK_A_SUB;
3526 } else if (c == '>') {
3527 p++;
3528 tok = TOK_ARROW;
3529 } else {
3530 tok = '-';
3532 break;
3534 PARSE2('!', '!', '=', TOK_NE)
3535 PARSE2('=', '=', '=', TOK_EQ)
3536 PARSE2('*', '*', '=', TOK_A_MUL)
3537 PARSE2('%', '%', '=', TOK_A_MOD)
3538 PARSE2('^', '^', '=', TOK_A_XOR)
3540 /* comments or operator */
3541 case '/':
3542 PEEKC(c, p);
3543 if (c == '*') {
3544 file->buf_ptr = p;
3545 parse_comment();
3546 p = file->buf_ptr;
3547 goto redo_no_start;
3548 } else if (c == '/') {
3549 file->buf_ptr = p;
3550 parse_line_comment();
3551 p = file->buf_ptr;
3552 goto redo_no_start;
3553 } else if (c == '=') {
3554 p++;
3555 tok = TOK_A_DIV;
3556 } else {
3557 tok = '/';
3559 break;
3561 /* simple tokens */
3562 case '(':
3563 case ')':
3564 case '[':
3565 case ']':
3566 case '{':
3567 case '}':
3568 case ',':
3569 case ';':
3570 case ':':
3571 case '?':
3572 case '~':
3573 case '$': /* only used in assembler */
3574 tok = c;
3575 p++;
3576 break;
3577 default:
3578 error("unrecognized character \\x%02x", c);
3579 break;
3581 file->buf_ptr = p;
3582 tok_flags = 0;
3583 #if defined(PARSE_DEBUG)
3584 printf("token = %s\n", get_tok_str(tok, &tokc));
3585 #endif
3588 /* return next token without macro substitution. Can read input from
3589 macro_ptr buffer */
3590 static void next_nomacro(void)
3592 if (macro_ptr) {
3593 redo:
3594 tok = *macro_ptr;
3595 if (tok) {
3596 TOK_GET(tok, macro_ptr, tokc);
3597 if (tok == TOK_LINENUM) {
3598 file->line_num = tokc.i;
3599 goto redo;
3602 } else {
3603 next_nomacro1();
3607 /* substitute args in macro_str and return allocated string */
3608 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
3610 int *st, last_tok, t, notfirst;
3611 Sym *s;
3612 CValue cval;
3613 TokenString str;
3614 CString cstr;
3616 tok_str_new(&str);
3617 last_tok = 0;
3618 while(1) {
3619 TOK_GET(t, macro_str, cval);
3620 if (!t)
3621 break;
3622 if (t == '#') {
3623 /* stringize */
3624 TOK_GET(t, macro_str, cval);
3625 if (!t)
3626 break;
3627 s = sym_find2(args, t);
3628 if (s) {
3629 cstr_new(&cstr);
3630 st = (int *)s->c;
3631 notfirst = 0;
3632 while (*st) {
3633 if (notfirst)
3634 cstr_ccat(&cstr, ' ');
3635 TOK_GET(t, st, cval);
3636 cstr_cat(&cstr, get_tok_str(t, &cval));
3637 notfirst = 1;
3639 cstr_ccat(&cstr, '\0');
3640 #ifdef PP_DEBUG
3641 printf("stringize: %s\n", (char *)cstr.data);
3642 #endif
3643 /* add string */
3644 cval.cstr = &cstr;
3645 tok_str_add2(&str, TOK_STR, &cval);
3646 cstr_free(&cstr);
3647 } else {
3648 tok_str_add2(&str, t, &cval);
3650 } else if (t >= TOK_IDENT) {
3651 s = sym_find2(args, t);
3652 if (s) {
3653 st = (int *)s->c;
3654 /* if '##' is present before or after, no arg substitution */
3655 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
3656 /* special case for var arg macros : ## eats the
3657 ',' if empty VA_ARGS variable. */
3658 /* XXX: test of the ',' is not 100%
3659 reliable. should fix it to avoid security
3660 problems */
3661 if (gnu_ext && s->type.t &&
3662 last_tok == TOK_TWOSHARPS &&
3663 str.len >= 2 && str.str[str.len - 2] == ',') {
3664 if (*st == 0) {
3665 /* suppress ',' '##' */
3666 str.len -= 2;
3667 } else {
3668 /* suppress '##' and add variable */
3669 str.len--;
3670 goto add_var;
3672 } else {
3673 int t1;
3674 add_var:
3675 for(;;) {
3676 TOK_GET(t1, st, cval);
3677 if (!t1)
3678 break;
3679 tok_str_add2(&str, t1, &cval);
3682 } else {
3683 macro_subst(&str, nested_list, st);
3685 } else {
3686 tok_str_add(&str, t);
3688 } else {
3689 tok_str_add2(&str, t, &cval);
3691 last_tok = t;
3693 tok_str_add(&str, 0);
3694 return str.str;
3697 /* do macro substitution of current token with macro 's' and add
3698 result to (tok_str,tok_len). 'nested_list' is the list of all
3699 macros we got inside to avoid recursing. Return non zero if no
3700 substitution needs to be done */
3701 static int macro_subst_tok(TokenString *tok_str,
3702 Sym **nested_list, Sym *s)
3704 Sym *args, *sa, *sa1;
3705 int mstr_allocated, parlevel, *mstr, t;
3706 TokenString str;
3707 char *cstrval;
3708 CValue cval;
3709 CString cstr;
3711 /* if symbol is a macro, prepare substitution */
3713 /* special macros */
3714 if (tok == TOK___LINE__) {
3715 cval.i = file->line_num;
3716 tok_str_add2(tok_str, TOK_CINT, &cval);
3717 } else if (tok == TOK___FILE__) {
3718 cstrval = file->filename;
3719 goto add_cstr;
3720 tok_str_add2(tok_str, TOK_STR, &cval);
3721 } else if (tok == TOK___DATE__) {
3722 cstrval = "Jan 1 2002";
3723 goto add_cstr;
3724 } else if (tok == TOK___TIME__) {
3725 cstrval = "00:00:00";
3726 add_cstr:
3727 cstr_new(&cstr);
3728 cstr_cat(&cstr, cstrval);
3729 cstr_ccat(&cstr, '\0');
3730 cval.cstr = &cstr;
3731 tok_str_add2(tok_str, TOK_STR, &cval);
3732 cstr_free(&cstr);
3733 } else {
3734 mstr = (int *)s->c;
3735 mstr_allocated = 0;
3736 if (s->type.t == MACRO_FUNC) {
3737 /* NOTE: we do not use next_nomacro to avoid eating the
3738 next token. XXX: find better solution */
3739 if (macro_ptr) {
3740 t = *macro_ptr;
3741 } else {
3742 /* XXX: incorrect with comments */
3743 ch = file->buf_ptr[0];
3744 while (is_space(ch) || ch == '\n')
3745 cinp();
3746 t = ch;
3748 if (t != '(') /* no macro subst */
3749 return -1;
3751 /* argument macro */
3752 next_nomacro();
3753 next_nomacro();
3754 args = NULL;
3755 sa = s->next;
3756 /* NOTE: empty args are allowed, except if no args */
3757 for(;;) {
3758 /* handle '()' case */
3759 if (!args && tok == ')')
3760 break;
3761 if (!sa)
3762 error("macro '%s' used with too many args",
3763 get_tok_str(s->v, 0));
3764 tok_str_new(&str);
3765 parlevel = 0;
3766 /* NOTE: non zero sa->t indicates VA_ARGS */
3767 while ((parlevel > 0 ||
3768 (tok != ')' &&
3769 (tok != ',' || sa->type.t))) &&
3770 tok != -1) {
3771 if (tok == '(')
3772 parlevel++;
3773 else if (tok == ')')
3774 parlevel--;
3775 tok_str_add2(&str, tok, &tokc);
3776 next_nomacro();
3778 tok_str_add(&str, 0);
3779 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str);
3780 sa = sa->next;
3781 if (tok == ')') {
3782 /* special case for gcc var args: add an empty
3783 var arg argument if it is omitted */
3784 if (sa && sa->type.t && gnu_ext)
3785 continue;
3786 else
3787 break;
3789 if (tok != ',')
3790 expect(",");
3791 next_nomacro();
3793 if (sa) {
3794 error("macro '%s' used with too few args",
3795 get_tok_str(s->v, 0));
3798 /* now subst each arg */
3799 mstr = macro_arg_subst(nested_list, mstr, args);
3800 /* free memory */
3801 sa = args;
3802 while (sa) {
3803 sa1 = sa->prev;
3804 tok_str_free((int *)sa->c);
3805 tcc_free(sa);
3806 sa = sa1;
3808 mstr_allocated = 1;
3810 sym_push2(nested_list, s->v, 0, 0);
3811 macro_subst(tok_str, nested_list, mstr);
3812 /* pop nested defined symbol */
3813 sa1 = *nested_list;
3814 *nested_list = sa1->prev;
3815 tcc_free(sa1);
3816 if (mstr_allocated)
3817 tok_str_free(mstr);
3819 return 0;
3822 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
3823 return the resulting string (which must be freed). */
3824 static inline int *macro_twosharps(const int *macro_str)
3826 TokenSym *ts;
3827 const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr;
3828 int t;
3829 const char *p1, *p2;
3830 CValue cval;
3831 TokenString macro_str1;
3832 CString cstr;
3834 start_macro_ptr = macro_str;
3835 /* we search the first '##' */
3836 for(;;) {
3837 macro_ptr1 = macro_str;
3838 TOK_GET(t, macro_str, cval);
3839 /* nothing more to do if end of string */
3840 if (t == 0)
3841 return NULL;
3842 if (*macro_str == TOK_TWOSHARPS)
3843 break;
3846 /* we saw '##', so we need more processing to handle it */
3847 cstr_new(&cstr);
3848 tok_str_new(&macro_str1);
3849 tok = t;
3850 tokc = cval;
3852 /* add all tokens seen so far */
3853 for(ptr = start_macro_ptr; ptr < macro_ptr1;) {
3854 TOK_GET(t, ptr, cval);
3855 tok_str_add2(&macro_str1, t, &cval);
3857 saved_macro_ptr = macro_ptr;
3858 /* XXX: get rid of the use of macro_ptr here */
3859 macro_ptr = (int *)macro_str;
3860 for(;;) {
3861 while (*macro_ptr == TOK_TWOSHARPS) {
3862 macro_ptr++;
3863 macro_ptr1 = macro_ptr;
3864 t = *macro_ptr;
3865 if (t) {
3866 TOK_GET(t, macro_ptr, cval);
3867 /* We concatenate the two tokens if we have an
3868 identifier or a preprocessing number */
3869 cstr_reset(&cstr);
3870 p1 = get_tok_str(tok, &tokc);
3871 cstr_cat(&cstr, p1);
3872 p2 = get_tok_str(t, &cval);
3873 cstr_cat(&cstr, p2);
3874 cstr_ccat(&cstr, '\0');
3876 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
3877 (t >= TOK_IDENT || t == TOK_PPNUM)) {
3878 if (tok == TOK_PPNUM) {
3879 /* if number, then create a number token */
3880 /* NOTE: no need to allocate because
3881 tok_str_add2() does it */
3882 tokc.cstr = &cstr;
3883 } else {
3884 /* if identifier, we must do a test to
3885 validate we have a correct identifier */
3886 if (t == TOK_PPNUM) {
3887 const char *p;
3888 int c;
3890 p = p2;
3891 for(;;) {
3892 c = *p;
3893 if (c == '\0')
3894 break;
3895 p++;
3896 if (!isnum(c) && !isid(c))
3897 goto error_pasting;
3900 ts = tok_alloc(cstr.data, strlen(cstr.data));
3901 tok = ts->tok; /* modify current token */
3903 } else {
3904 const char *str = cstr.data;
3905 const unsigned char *q;
3907 /* we look for a valid token */
3908 /* XXX: do more extensive checks */
3909 if (!strcmp(str, ">>=")) {
3910 tok = TOK_A_SAR;
3911 } else if (!strcmp(str, "<<=")) {
3912 tok = TOK_A_SHL;
3913 } else if (strlen(str) == 2) {
3914 /* search in two bytes table */
3915 q = tok_two_chars;
3916 for(;;) {
3917 if (!*q)
3918 goto error_pasting;
3919 if (q[0] == str[0] && q[1] == str[1])
3920 break;
3921 q += 3;
3923 tok = q[2];
3924 } else {
3925 error_pasting:
3926 /* NOTE: because get_tok_str use a static buffer,
3927 we must save it */
3928 cstr_reset(&cstr);
3929 p1 = get_tok_str(tok, &tokc);
3930 cstr_cat(&cstr, p1);
3931 cstr_ccat(&cstr, '\0');
3932 p2 = get_tok_str(t, &cval);
3933 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
3934 /* cannot merge tokens: just add them separately */
3935 tok_str_add2(&macro_str1, tok, &tokc);
3936 /* XXX: free associated memory ? */
3937 tok = t;
3938 tokc = cval;
3943 tok_str_add2(&macro_str1, tok, &tokc);
3944 next_nomacro();
3945 if (tok == 0)
3946 break;
3948 macro_ptr = (int *)saved_macro_ptr;
3949 cstr_free(&cstr);
3950 tok_str_add(&macro_str1, 0);
3951 return macro_str1.str;
3955 /* do macro substitution of macro_str and add result to
3956 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3957 inside to avoid recursing. */
3958 static void macro_subst(TokenString *tok_str,
3959 Sym **nested_list, const int *macro_str)
3961 Sym *s;
3962 int *saved_macro_ptr, *macro_str1;
3963 const int *ptr;
3964 int t, ret;
3965 CValue cval;
3967 /* first scan for '##' operator handling */
3968 ptr = macro_str;
3969 macro_str1 = macro_twosharps(ptr);
3970 if (macro_str1)
3971 ptr = macro_str1;
3972 while (1) {
3973 TOK_GET(t, ptr, cval);
3974 if (t == 0)
3975 break;
3976 s = define_find(t);
3977 if (s != NULL) {
3978 /* if nested substitution, do nothing */
3979 if (sym_find2(*nested_list, t))
3980 goto no_subst;
3981 saved_macro_ptr = macro_ptr;
3982 macro_ptr = (int *)ptr;
3983 tok = t;
3984 ret = macro_subst_tok(tok_str, nested_list, s);
3985 ptr = (int *)macro_ptr;
3986 macro_ptr = saved_macro_ptr;
3987 if (ret != 0)
3988 goto no_subst;
3989 } else {
3990 no_subst:
3991 tok_str_add2(tok_str, t, &cval);
3994 if (macro_str1)
3995 tok_str_free(macro_str1);
3998 /* return next token with macro substitution */
3999 static void next(void)
4001 Sym *nested_list, *s;
4002 TokenString str;
4004 redo:
4005 next_nomacro();
4006 if (!macro_ptr) {
4007 /* if not reading from macro substituted string, then try
4008 to substitute macros */
4009 if (tok >= TOK_IDENT &&
4010 (parse_flags & PARSE_FLAG_PREPROCESS)) {
4011 s = define_find(tok);
4012 if (s) {
4013 /* we have a macro: we try to substitute */
4014 tok_str_new(&str);
4015 nested_list = NULL;
4016 if (macro_subst_tok(&str, &nested_list, s) == 0) {
4017 /* substitution done, NOTE: maybe empty */
4018 tok_str_add(&str, 0);
4019 macro_ptr = str.str;
4020 macro_ptr_allocated = str.str;
4021 goto redo;
4025 } else {
4026 if (tok == 0) {
4027 /* end of macro or end of unget buffer */
4028 if (unget_buffer_enabled) {
4029 macro_ptr = unget_saved_macro_ptr;
4030 unget_buffer_enabled = 0;
4031 } else {
4032 /* end of macro string: free it */
4033 tok_str_free(macro_ptr_allocated);
4034 macro_ptr = NULL;
4036 goto redo;
4040 /* convert preprocessor tokens into C tokens */
4041 if (tok == TOK_PPNUM &&
4042 (parse_flags & PARSE_FLAG_TOK_NUM)) {
4043 parse_number((char *)tokc.cstr->data);
4047 /* push back current token and set current token to 'last_tok'. Only
4048 identifier case handled for labels. */
4049 static inline void unget_tok(int last_tok)
4051 int i, n;
4052 int *q;
4053 unget_saved_macro_ptr = macro_ptr;
4054 unget_buffer_enabled = 1;
4055 q = unget_saved_buffer;
4056 macro_ptr = q;
4057 *q++ = tok;
4058 n = tok_ext_size(tok) - 1;
4059 for(i=0;i<n;i++)
4060 *q++ = tokc.tab[i];
4061 *q = 0; /* end of token string */
4062 tok = last_tok;
4066 void swap(int *p, int *q)
4068 int t;
4069 t = *p;
4070 *p = *q;
4071 *q = t;
4074 void vsetc(CType *type, int r, CValue *vc)
4076 int v;
4078 if (vtop >= vstack + VSTACK_SIZE)
4079 error("memory full");
4080 /* cannot let cpu flags if other instruction are generated. Also
4081 avoid leaving VT_JMP anywhere except on the top of the stack
4082 because it would complicate the code generator. */
4083 if (vtop >= vstack) {
4084 v = vtop->r & VT_VALMASK;
4085 if (v == VT_CMP || (v & ~1) == VT_JMP)
4086 gv(RC_INT);
4088 vtop++;
4089 vtop->type = *type;
4090 vtop->r = r;
4091 vtop->r2 = VT_CONST;
4092 vtop->c = *vc;
4095 /* push integer constant */
4096 void vpushi(int v)
4098 CValue cval;
4099 cval.i = v;
4100 vsetc(&int_type, VT_CONST, &cval);
4103 /* Return a static symbol pointing to a section */
4104 static Sym *get_sym_ref(CType *type, Section *sec,
4105 unsigned long offset, unsigned long size)
4107 int v;
4108 Sym *sym;
4110 v = anon_sym++;
4111 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
4112 sym->type.ref = type->ref;
4113 sym->r = VT_CONST | VT_SYM;
4114 put_extern_sym(sym, sec, offset, size);
4115 return sym;
4118 /* push a reference to a section offset by adding a dummy symbol */
4119 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
4121 CValue cval;
4123 cval.ul = 0;
4124 vsetc(type, VT_CONST | VT_SYM, &cval);
4125 vtop->sym = get_sym_ref(type, sec, offset, size);
4128 /* define a new external reference to a symbol 'v' of type 'u' */
4129 static Sym *external_global_sym(int v, CType *type, int r)
4131 Sym *s;
4133 s = sym_find(v);
4134 if (!s) {
4135 /* push forward reference */
4136 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
4137 s->type.ref = type->ref;
4138 s->r = r | VT_CONST | VT_SYM;
4140 return s;
4143 /* define a new external reference to a symbol 'v' of type 'u' */
4144 static Sym *external_sym(int v, CType *type, int r)
4146 Sym *s;
4148 s = sym_find(v);
4149 if (!s) {
4150 /* push forward reference */
4151 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
4152 s->type.t |= VT_EXTERN;
4153 } else {
4154 if (!is_compatible_types(&s->type, type))
4155 error("incompatible types for redefinition of '%s'",
4156 get_tok_str(v, NULL));
4158 return s;
4161 /* push a reference to global symbol v */
4162 static void vpush_global_sym(CType *type, int v)
4164 Sym *sym;
4165 CValue cval;
4167 sym = external_global_sym(v, type, 0);
4168 cval.ul = 0;
4169 vsetc(type, VT_CONST | VT_SYM, &cval);
4170 vtop->sym = sym;
4173 void vset(CType *type, int r, int v)
4175 CValue cval;
4177 cval.i = v;
4178 vsetc(type, r, &cval);
4181 void vseti(int r, int v)
4183 CType type;
4184 type.t = VT_INT;
4185 vset(&type, r, v);
4188 void vswap(void)
4190 SValue tmp;
4192 tmp = vtop[0];
4193 vtop[0] = vtop[-1];
4194 vtop[-1] = tmp;
4197 void vpushv(SValue *v)
4199 if (vtop >= vstack + VSTACK_SIZE)
4200 error("memory full");
4201 vtop++;
4202 *vtop = *v;
4205 void vdup(void)
4207 vpushv(vtop);
4210 /* save r to the memory stack, and mark it as being free */
4211 void save_reg(int r)
4213 int l, saved, size, align;
4214 SValue *p, sv;
4215 CType *type;
4217 /* modify all stack values */
4218 saved = 0;
4219 l = 0;
4220 for(p=vstack;p<=vtop;p++) {
4221 if ((p->r & VT_VALMASK) == r ||
4222 (p->r2 & VT_VALMASK) == r) {
4223 /* must save value on stack if not already done */
4224 if (!saved) {
4225 /* NOTE: must reload 'r' because r might be equal to r2 */
4226 r = p->r & VT_VALMASK;
4227 /* store register in the stack */
4228 type = &p->type;
4229 if ((p->r & VT_LVAL) ||
4230 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
4231 type = &int_type;
4232 size = type_size(type, &align);
4233 loc = (loc - size) & -align;
4234 sv.type.t = type->t;
4235 sv.r = VT_LOCAL | VT_LVAL;
4236 sv.c.ul = loc;
4237 store(r, &sv);
4238 #ifdef TCC_TARGET_I386
4239 /* x86 specific: need to pop fp register ST0 if saved */
4240 if (r == TREG_ST0) {
4241 o(0xd9dd); /* fstp %st(1) */
4243 #endif
4244 /* special long long case */
4245 if ((type->t & VT_BTYPE) == VT_LLONG) {
4246 sv.c.ul += 4;
4247 store(p->r2, &sv);
4249 l = loc;
4250 saved = 1;
4252 /* mark that stack entry as being saved on the stack */
4253 if (p->r & VT_LVAL) {
4254 /* also clear the bounded flag because the
4255 relocation address of the function was stored in
4256 p->c.ul */
4257 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
4258 } else {
4259 p->r = lvalue_type(p->type.t) | VT_LOCAL;
4261 p->r2 = VT_CONST;
4262 p->c.ul = l;
4267 /* find a free register of class 'rc'. If none, save one register */
4268 int get_reg(int rc)
4270 int r;
4271 SValue *p;
4273 /* find a free register */
4274 for(r=0;r<NB_REGS;r++) {
4275 if (reg_classes[r] & rc) {
4276 for(p=vstack;p<=vtop;p++) {
4277 if ((p->r & VT_VALMASK) == r ||
4278 (p->r2 & VT_VALMASK) == r)
4279 goto notfound;
4281 return r;
4283 notfound: ;
4286 /* no register left : free the first one on the stack (VERY
4287 IMPORTANT to start from the bottom to ensure that we don't
4288 spill registers used in gen_opi()) */
4289 for(p=vstack;p<=vtop;p++) {
4290 r = p->r & VT_VALMASK;
4291 if (r < VT_CONST && (reg_classes[r] & rc))
4292 goto save_found;
4293 /* also look at second register (if long long) */
4294 r = p->r2 & VT_VALMASK;
4295 if (r < VT_CONST && (reg_classes[r] & rc)) {
4296 save_found:
4297 save_reg(r);
4298 return r;
4301 /* Should never comes here */
4302 return -1;
4305 /* save registers up to (vtop - n) stack entry */
4306 void save_regs(int n)
4308 int r;
4309 SValue *p, *p1;
4310 p1 = vtop - n;
4311 for(p = vstack;p <= p1; p++) {
4312 r = p->r & VT_VALMASK;
4313 if (r < VT_CONST) {
4314 save_reg(r);
4319 /* move register 's' to 'r', and flush previous value of r to memory
4320 if needed */
4321 void move_reg(int r, int s)
4323 SValue sv;
4325 if (r != s) {
4326 save_reg(r);
4327 sv.type.t = VT_INT;
4328 sv.r = s;
4329 sv.c.ul = 0;
4330 load(r, &sv);
4334 /* get address of vtop (vtop MUST BE an lvalue) */
4335 void gaddrof(void)
4337 vtop->r &= ~VT_LVAL;
4338 /* tricky: if saved lvalue, then we can go back to lvalue */
4339 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
4340 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
4343 #ifdef CONFIG_TCC_BCHECK
4344 /* generate lvalue bound code */
4345 void gbound(void)
4347 int lval_type;
4348 CType type1;
4350 vtop->r &= ~VT_MUSTBOUND;
4351 /* if lvalue, then use checking code before dereferencing */
4352 if (vtop->r & VT_LVAL) {
4353 /* if not VT_BOUNDED value, then make one */
4354 if (!(vtop->r & VT_BOUNDED)) {
4355 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
4356 /* must save type because we must set it to int to get pointer */
4357 type1 = vtop->type;
4358 vtop->type.t = VT_INT;
4359 gaddrof();
4360 vpushi(0);
4361 gen_bounded_ptr_add();
4362 vtop->r |= lval_type;
4363 vtop->type = type1;
4365 /* then check for dereferencing */
4366 gen_bounded_ptr_deref();
4369 #endif
4371 /* store vtop a register belonging to class 'rc'. lvalues are
4372 converted to values. Cannot be used if cannot be converted to
4373 register value (such as structures). */
4374 int gv(int rc)
4376 int r, r2, rc2, bit_pos, bit_size, size, align, i;
4377 unsigned long long ll;
4379 /* NOTE: get_reg can modify vstack[] */
4380 if (vtop->type.t & VT_BITFIELD) {
4381 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4382 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4383 /* remove bit field info to avoid loops */
4384 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4385 /* generate shifts */
4386 vpushi(32 - (bit_pos + bit_size));
4387 gen_op(TOK_SHL);
4388 vpushi(32 - bit_size);
4389 /* NOTE: transformed to SHR if unsigned */
4390 gen_op(TOK_SAR);
4391 r = gv(rc);
4392 } else {
4393 if (is_float(vtop->type.t) &&
4394 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4395 Sym *sym;
4396 int *ptr;
4397 unsigned long offset;
4399 /* XXX: unify with initializers handling ? */
4400 /* CPUs usually cannot use float constants, so we store them
4401 generically in data segment */
4402 size = type_size(&vtop->type, &align);
4403 offset = (data_section->data_offset + align - 1) & -align;
4404 data_section->data_offset = offset;
4405 /* XXX: not portable yet */
4406 ptr = section_ptr_add(data_section, size);
4407 size = size >> 2;
4408 for(i=0;i<size;i++)
4409 ptr[i] = vtop->c.tab[i];
4410 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
4411 vtop->r |= VT_LVAL | VT_SYM;
4412 vtop->sym = sym;
4413 vtop->c.ul = 0;
4415 #ifdef CONFIG_TCC_BCHECK
4416 if (vtop->r & VT_MUSTBOUND)
4417 gbound();
4418 #endif
4420 r = vtop->r & VT_VALMASK;
4421 /* need to reload if:
4422 - constant
4423 - lvalue (need to dereference pointer)
4424 - already a register, but not in the right class */
4425 if (r >= VT_CONST ||
4426 (vtop->r & VT_LVAL) ||
4427 !(reg_classes[r] & rc) ||
4428 ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
4429 !(reg_classes[vtop->r2] & rc))) {
4430 r = get_reg(rc);
4431 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
4432 /* two register type load : expand to two words
4433 temporarily */
4434 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4435 /* load constant */
4436 ll = vtop->c.ull;
4437 vtop->c.ui = ll; /* first word */
4438 load(r, vtop);
4439 vtop->r = r; /* save register value */
4440 vpushi(ll >> 32); /* second word */
4441 } else if (r >= VT_CONST ||
4442 (vtop->r & VT_LVAL)) {
4443 /* load from memory */
4444 load(r, vtop);
4445 vdup();
4446 vtop[-1].r = r; /* save register value */
4447 /* increment pointer to get second word */
4448 vtop->type.t = VT_INT;
4449 gaddrof();
4450 vpushi(4);
4451 gen_op('+');
4452 vtop->r |= VT_LVAL;
4453 } else {
4454 /* move registers */
4455 load(r, vtop);
4456 vdup();
4457 vtop[-1].r = r; /* save register value */
4458 vtop->r = vtop[-1].r2;
4460 /* allocate second register */
4461 rc2 = RC_INT;
4462 if (rc == RC_IRET)
4463 rc2 = RC_LRET;
4464 r2 = get_reg(rc2);
4465 load(r2, vtop);
4466 vpop();
4467 /* write second register */
4468 vtop->r2 = r2;
4469 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
4470 int t1, t;
4471 /* lvalue of scalar type : need to use lvalue type
4472 because of possible cast */
4473 t = vtop->type.t;
4474 t1 = t;
4475 /* compute memory access type */
4476 if (vtop->r & VT_LVAL_BYTE)
4477 t = VT_BYTE;
4478 else if (vtop->r & VT_LVAL_SHORT)
4479 t = VT_SHORT;
4480 if (vtop->r & VT_LVAL_UNSIGNED)
4481 t |= VT_UNSIGNED;
4482 vtop->type.t = t;
4483 load(r, vtop);
4484 /* restore wanted type */
4485 vtop->type.t = t1;
4486 } else {
4487 /* one register type load */
4488 load(r, vtop);
4491 vtop->r = r;
4493 return r;
4496 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4497 void gv2(int rc1, int rc2)
4499 int v;
4501 /* generate more generic register first. But VT_JMP or VT_CMP
4502 values must be generated first in all cases to avoid possible
4503 reload errors */
4504 v = vtop[0].r & VT_VALMASK;
4505 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
4506 vswap();
4507 gv(rc1);
4508 vswap();
4509 gv(rc2);
4510 /* test if reload is needed for first register */
4511 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
4512 vswap();
4513 gv(rc1);
4514 vswap();
4516 } else {
4517 gv(rc2);
4518 vswap();
4519 gv(rc1);
4520 vswap();
4521 /* test if reload is needed for first register */
4522 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
4523 gv(rc2);
4528 /* expand long long on stack in two int registers */
4529 void lexpand(void)
4531 int u;
4533 u = vtop->type.t & VT_UNSIGNED;
4534 gv(RC_INT);
4535 vdup();
4536 vtop[0].r = vtop[-1].r2;
4537 vtop[0].r2 = VT_CONST;
4538 vtop[-1].r2 = VT_CONST;
4539 vtop[0].type.t = VT_INT | u;
4540 vtop[-1].type.t = VT_INT | u;
4543 /* build a long long from two ints */
4544 void lbuild(int t)
4546 gv2(RC_INT, RC_INT);
4547 vtop[-1].r2 = vtop[0].r;
4548 vtop[-1].type.t = t;
4549 vpop();
4552 /* rotate n first stack elements to the bottom */
4553 void vrotb(int n)
4555 int i;
4556 SValue tmp;
4558 tmp = vtop[-n + 1];
4559 for(i=-n+1;i!=0;i++)
4560 vtop[i] = vtop[i+1];
4561 vtop[0] = tmp;
4564 /* pop stack value */
4565 void vpop(void)
4567 int v;
4568 v = vtop->r & VT_VALMASK;
4569 #ifdef TCC_TARGET_I386
4570 /* for x86, we need to pop the FP stack */
4571 if (v == TREG_ST0 && !nocode_wanted) {
4572 o(0xd9dd); /* fstp %st(1) */
4573 } else
4574 #endif
4575 if (v == VT_JMP || v == VT_JMPI) {
4576 /* need to put correct jump if && or || without test */
4577 gsym(vtop->c.ul);
4579 vtop--;
4582 /* convert stack entry to register and duplicate its value in another
4583 register */
4584 void gv_dup(void)
4586 int rc, t, r, r1;
4587 SValue sv;
4589 t = vtop->type.t;
4590 if ((t & VT_BTYPE) == VT_LLONG) {
4591 lexpand();
4592 gv_dup();
4593 vswap();
4594 vrotb(3);
4595 gv_dup();
4596 vrotb(4);
4597 /* stack: H L L1 H1 */
4598 lbuild(t);
4599 vrotb(3);
4600 vrotb(3);
4601 vswap();
4602 lbuild(t);
4603 vswap();
4604 } else {
4605 /* duplicate value */
4606 rc = RC_INT;
4607 sv.type.t = VT_INT;
4608 if (is_float(t)) {
4609 rc = RC_FLOAT;
4610 sv.type.t = t;
4612 r = gv(rc);
4613 r1 = get_reg(rc);
4614 sv.r = r;
4615 sv.c.ul = 0;
4616 load(r1, &sv); /* move r to r1 */
4617 vdup();
4618 /* duplicates value */
4619 vtop->r = r1;
4623 /* generate CPU independent (unsigned) long long operations */
4624 void gen_opl(int op)
4626 int t, a, b, op1, c, i;
4627 int func;
4628 GFuncContext gf;
4629 SValue tmp;
4631 switch(op) {
4632 case '/':
4633 case TOK_PDIV:
4634 func = TOK___divdi3;
4635 goto gen_func;
4636 case TOK_UDIV:
4637 func = TOK___udivdi3;
4638 goto gen_func;
4639 case '%':
4640 func = TOK___moddi3;
4641 goto gen_func;
4642 case TOK_UMOD:
4643 func = TOK___umoddi3;
4644 gen_func:
4645 /* call generic long long function */
4646 gfunc_start(&gf, FUNC_CDECL);
4647 gfunc_param(&gf);
4648 gfunc_param(&gf);
4649 vpush_global_sym(&func_old_type, func);
4650 gfunc_call(&gf);
4651 vpushi(0);
4652 vtop->r = REG_IRET;
4653 vtop->r2 = REG_LRET;
4654 break;
4655 case '^':
4656 case '&':
4657 case '|':
4658 case '*':
4659 case '+':
4660 case '-':
4661 t = vtop->type.t;
4662 vswap();
4663 lexpand();
4664 vrotb(3);
4665 lexpand();
4666 /* stack: L1 H1 L2 H2 */
4667 tmp = vtop[0];
4668 vtop[0] = vtop[-3];
4669 vtop[-3] = tmp;
4670 tmp = vtop[-2];
4671 vtop[-2] = vtop[-3];
4672 vtop[-3] = tmp;
4673 vswap();
4674 /* stack: H1 H2 L1 L2 */
4675 if (op == '*') {
4676 vpushv(vtop - 1);
4677 vpushv(vtop - 1);
4678 gen_op(TOK_UMULL);
4679 lexpand();
4680 /* stack: H1 H2 L1 L2 ML MH */
4681 for(i=0;i<4;i++)
4682 vrotb(6);
4683 /* stack: ML MH H1 H2 L1 L2 */
4684 tmp = vtop[0];
4685 vtop[0] = vtop[-2];
4686 vtop[-2] = tmp;
4687 /* stack: ML MH H1 L2 H2 L1 */
4688 gen_op('*');
4689 vrotb(3);
4690 vrotb(3);
4691 gen_op('*');
4692 /* stack: ML MH M1 M2 */
4693 gen_op('+');
4694 gen_op('+');
4695 } else if (op == '+' || op == '-') {
4696 /* XXX: add non carry method too (for MIPS or alpha) */
4697 if (op == '+')
4698 op1 = TOK_ADDC1;
4699 else
4700 op1 = TOK_SUBC1;
4701 gen_op(op1);
4702 /* stack: H1 H2 (L1 op L2) */
4703 vrotb(3);
4704 vrotb(3);
4705 gen_op(op1 + 1); /* TOK_xxxC2 */
4706 } else {
4707 gen_op(op);
4708 /* stack: H1 H2 (L1 op L2) */
4709 vrotb(3);
4710 vrotb(3);
4711 /* stack: (L1 op L2) H1 H2 */
4712 gen_op(op);
4713 /* stack: (L1 op L2) (H1 op H2) */
4715 /* stack: L H */
4716 lbuild(t);
4717 break;
4718 case TOK_SAR:
4719 case TOK_SHR:
4720 case TOK_SHL:
4721 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4722 t = vtop[-1].type.t;
4723 vswap();
4724 lexpand();
4725 vrotb(3);
4726 /* stack: L H shift */
4727 c = (int)vtop->c.i;
4728 /* constant: simpler */
4729 /* NOTE: all comments are for SHL. the other cases are
4730 done by swaping words */
4731 vpop();
4732 if (op != TOK_SHL)
4733 vswap();
4734 if (c >= 32) {
4735 /* stack: L H */
4736 vpop();
4737 if (c > 32) {
4738 vpushi(c - 32);
4739 gen_op(op);
4741 if (op != TOK_SAR) {
4742 vpushi(0);
4743 } else {
4744 gv_dup();
4745 vpushi(31);
4746 gen_op(TOK_SAR);
4748 vswap();
4749 } else {
4750 vswap();
4751 gv_dup();
4752 /* stack: H L L */
4753 vpushi(c);
4754 gen_op(op);
4755 vswap();
4756 vpushi(32 - c);
4757 if (op == TOK_SHL)
4758 gen_op(TOK_SHR);
4759 else
4760 gen_op(TOK_SHL);
4761 vrotb(3);
4762 /* stack: L L H */
4763 vpushi(c);
4764 if (op == TOK_SHL)
4765 gen_op(TOK_SHL);
4766 else
4767 gen_op(TOK_SHR);
4768 gen_op('|');
4770 if (op != TOK_SHL)
4771 vswap();
4772 lbuild(t);
4773 } else {
4774 /* XXX: should provide a faster fallback on x86 ? */
4775 switch(op) {
4776 case TOK_SAR:
4777 func = TOK___sardi3;
4778 goto gen_func;
4779 case TOK_SHR:
4780 func = TOK___shrdi3;
4781 goto gen_func;
4782 case TOK_SHL:
4783 func = TOK___shldi3;
4784 goto gen_func;
4787 break;
4788 default:
4789 /* compare operations */
4790 t = vtop->type.t;
4791 vswap();
4792 lexpand();
4793 vrotb(3);
4794 lexpand();
4795 /* stack: L1 H1 L2 H2 */
4796 tmp = vtop[-1];
4797 vtop[-1] = vtop[-2];
4798 vtop[-2] = tmp;
4799 /* stack: L1 L2 H1 H2 */
4800 /* compare high */
4801 op1 = op;
4802 /* when values are equal, we need to compare low words. since
4803 the jump is inverted, we invert the test too. */
4804 if (op1 == TOK_LT)
4805 op1 = TOK_LE;
4806 else if (op1 == TOK_GT)
4807 op1 = TOK_GE;
4808 else if (op1 == TOK_ULT)
4809 op1 = TOK_ULE;
4810 else if (op1 == TOK_UGT)
4811 op1 = TOK_UGE;
4812 a = 0;
4813 b = 0;
4814 gen_op(op1);
4815 if (op1 != TOK_NE) {
4816 a = gtst(1, 0);
4818 if (op != TOK_EQ) {
4819 /* generate non equal test */
4820 /* XXX: NOT PORTABLE yet */
4821 if (a == 0) {
4822 b = gtst(0, 0);
4823 } else {
4824 #ifdef TCC_TARGET_I386
4825 b = psym(0x850f, 0);
4826 #else
4827 error("not implemented");
4828 #endif
4831 /* compare low. Always unsigned */
4832 op1 = op;
4833 if (op1 == TOK_LT)
4834 op1 = TOK_ULT;
4835 else if (op1 == TOK_LE)
4836 op1 = TOK_ULE;
4837 else if (op1 == TOK_GT)
4838 op1 = TOK_UGT;
4839 else if (op1 == TOK_GE)
4840 op1 = TOK_UGE;
4841 gen_op(op1);
4842 a = gtst(1, a);
4843 gsym(b);
4844 vseti(VT_JMPI, a);
4845 break;
4849 /* handle integer constant optimizations and various machine
4850 independent opt */
4851 void gen_opic(int op)
4853 int fc, c1, c2, n;
4854 SValue *v1, *v2;
4856 v1 = vtop - 1;
4857 v2 = vtop;
4858 /* currently, we cannot do computations with forward symbols */
4859 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4860 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4861 if (c1 && c2) {
4862 fc = v2->c.i;
4863 switch(op) {
4864 case '+': v1->c.i += fc; break;
4865 case '-': v1->c.i -= fc; break;
4866 case '&': v1->c.i &= fc; break;
4867 case '^': v1->c.i ^= fc; break;
4868 case '|': v1->c.i |= fc; break;
4869 case '*': v1->c.i *= fc; break;
4871 case TOK_PDIV:
4872 case '/':
4873 case '%':
4874 case TOK_UDIV:
4875 case TOK_UMOD:
4876 /* if division by zero, generate explicit division */
4877 if (fc == 0) {
4878 if (const_wanted)
4879 error("division by zero in constant");
4880 goto general_case;
4882 switch(op) {
4883 default: v1->c.i /= fc; break;
4884 case '%': v1->c.i %= fc; break;
4885 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
4886 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
4888 break;
4889 case TOK_SHL: v1->c.i <<= fc; break;
4890 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
4891 case TOK_SAR: v1->c.i >>= fc; break;
4892 /* tests */
4893 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
4894 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
4895 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
4896 case TOK_NE: v1->c.i = v1->c.i != fc; break;
4897 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
4898 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
4899 case TOK_LT: v1->c.i = v1->c.i < fc; break;
4900 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
4901 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
4902 case TOK_GT: v1->c.i = v1->c.i > fc; break;
4903 /* logical */
4904 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
4905 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
4906 default:
4907 goto general_case;
4909 vtop--;
4910 } else {
4911 /* if commutative ops, put c2 as constant */
4912 if (c1 && (op == '+' || op == '&' || op == '^' ||
4913 op == '|' || op == '*')) {
4914 vswap();
4915 swap(&c1, &c2);
4917 fc = vtop->c.i;
4918 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
4919 op == TOK_PDIV) &&
4920 fc == 1) ||
4921 ((op == '+' || op == '-' || op == '|' || op == '^' ||
4922 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
4923 fc == 0) ||
4924 (op == '&' &&
4925 fc == -1))) {
4926 /* nothing to do */
4927 vtop--;
4928 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
4929 /* try to use shifts instead of muls or divs */
4930 if (fc > 0 && (fc & (fc - 1)) == 0) {
4931 n = -1;
4932 while (fc) {
4933 fc >>= 1;
4934 n++;
4936 vtop->c.i = n;
4937 if (op == '*')
4938 op = TOK_SHL;
4939 else if (op == TOK_PDIV)
4940 op = TOK_SAR;
4941 else
4942 op = TOK_SHR;
4944 goto general_case;
4945 } else if (c2 && (op == '+' || op == '-') &&
4946 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
4947 (VT_CONST | VT_SYM)) {
4948 /* symbol + constant case */
4949 if (op == '-')
4950 fc = -fc;
4951 vtop--;
4952 vtop->c.i += fc;
4953 } else {
4954 general_case:
4955 if (!nocode_wanted) {
4956 /* call low level op generator */
4957 gen_opi(op);
4958 } else {
4959 vtop--;
4965 /* generate a floating point operation with constant propagation */
4966 void gen_opif(int op)
4968 int c1, c2;
4969 SValue *v1, *v2;
4970 long double f1, f2;
4972 v1 = vtop - 1;
4973 v2 = vtop;
4974 /* currently, we cannot do computations with forward symbols */
4975 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4976 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4977 if (c1 && c2) {
4978 if (v1->type.t == VT_FLOAT) {
4979 f1 = v1->c.f;
4980 f2 = v2->c.f;
4981 } else if (v1->type.t == VT_DOUBLE) {
4982 f1 = v1->c.d;
4983 f2 = v2->c.d;
4984 } else {
4985 f1 = v1->c.ld;
4986 f2 = v2->c.ld;
4989 /* NOTE: we only do constant propagation if finite number (not
4990 NaN or infinity) (ANSI spec) */
4991 if (!ieee_finite(f1) || !ieee_finite(f2))
4992 goto general_case;
4994 switch(op) {
4995 case '+': f1 += f2; break;
4996 case '-': f1 -= f2; break;
4997 case '*': f1 *= f2; break;
4998 case '/':
4999 if (f2 == 0.0) {
5000 if (const_wanted)
5001 error("division by zero in constant");
5002 goto general_case;
5004 f1 /= f2;
5005 break;
5006 /* XXX: also handles tests ? */
5007 default:
5008 goto general_case;
5010 /* XXX: overflow test ? */
5011 if (v1->type.t == VT_FLOAT) {
5012 v1->c.f = f1;
5013 } else if (v1->type.t == VT_DOUBLE) {
5014 v1->c.d = f1;
5015 } else {
5016 v1->c.ld = f1;
5018 vtop--;
5019 } else {
5020 general_case:
5021 if (!nocode_wanted) {
5022 gen_opf(op);
5023 } else {
5024 vtop--;
5029 static int pointed_size(CType *type)
5031 int align;
5032 return type_size(pointed_type(type), &align);
5035 #if 0
5036 void check_pointer_types(SValue *p1, SValue *p2)
5038 char buf1[256], buf2[256];
5039 int t1, t2;
5040 t1 = p1->t;
5041 t2 = p2->t;
5042 if (!is_compatible_types(t1, t2)) {
5043 type_to_str(buf1, sizeof(buf1), t1, NULL);
5044 type_to_str(buf2, sizeof(buf2), t2, NULL);
5045 error("incompatible pointers '%s' and '%s'", buf1, buf2);
5048 #endif
5050 /* generic gen_op: handles types problems */
5051 void gen_op(int op)
5053 int u, t1, t2, bt1, bt2, t;
5054 CType type1;
5056 t1 = vtop[-1].type.t;
5057 t2 = vtop[0].type.t;
5058 bt1 = t1 & VT_BTYPE;
5059 bt2 = t2 & VT_BTYPE;
5061 if (bt1 == VT_PTR || bt2 == VT_PTR) {
5062 /* at least one operand is a pointer */
5063 /* relationnal op: must be both pointers */
5064 if (op >= TOK_ULT && op <= TOK_GT) {
5065 // check_pointer_types(vtop, vtop - 1);
5066 /* pointers are handled are unsigned */
5067 t = VT_INT | VT_UNSIGNED;
5068 goto std_op;
5070 /* if both pointers, then it must be the '-' op */
5071 if (bt1 == VT_PTR && bt2 == VT_PTR) {
5072 if (op != '-')
5073 error("cannot use pointers here");
5074 // check_pointer_types(vtop - 1, vtop);
5075 /* XXX: check that types are compatible */
5076 u = pointed_size(&vtop[-1].type);
5077 gen_opic(op);
5078 /* set to integer type */
5079 vtop->type.t = VT_INT;
5080 vpushi(u);
5081 gen_op(TOK_PDIV);
5082 } else {
5083 /* exactly one pointer : must be '+' or '-'. */
5084 if (op != '-' && op != '+')
5085 error("cannot use pointers here");
5086 /* Put pointer as first operand */
5087 if (bt2 == VT_PTR) {
5088 vswap();
5089 swap(&t1, &t2);
5091 type1 = vtop[-1].type;
5092 /* XXX: cast to int ? (long long case) */
5093 vpushi(pointed_size(&vtop[-1].type));
5094 gen_op('*');
5095 #ifdef CONFIG_TCC_BCHECK
5096 /* if evaluating constant expression, no code should be
5097 generated, so no bound check */
5098 if (do_bounds_check && !const_wanted) {
5099 /* if bounded pointers, we generate a special code to
5100 test bounds */
5101 if (op == '-') {
5102 vpushi(0);
5103 vswap();
5104 gen_op('-');
5106 gen_bounded_ptr_add();
5107 } else
5108 #endif
5110 gen_opic(op);
5112 /* put again type if gen_opic() swaped operands */
5113 vtop->type = type1;
5115 } else if (is_float(bt1) || is_float(bt2)) {
5116 /* compute bigger type and do implicit casts */
5117 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
5118 t = VT_LDOUBLE;
5119 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
5120 t = VT_DOUBLE;
5121 } else {
5122 t = VT_FLOAT;
5124 /* floats can only be used for a few operations */
5125 if (op != '+' && op != '-' && op != '*' && op != '/' &&
5126 (op < TOK_ULT || op > TOK_GT))
5127 error("invalid operands for binary operation");
5128 goto std_op;
5129 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
5130 /* cast to biggest op */
5131 t = VT_LLONG;
5132 /* convert to unsigned if it does not fit in a long long */
5133 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
5134 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
5135 t |= VT_UNSIGNED;
5136 goto std_op;
5137 } else {
5138 /* integer operations */
5139 t = VT_INT;
5140 /* convert to unsigned if it does not fit in an integer */
5141 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
5142 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
5143 t |= VT_UNSIGNED;
5144 std_op:
5145 /* XXX: currently, some unsigned operations are explicit, so
5146 we modify them here */
5147 if (t & VT_UNSIGNED) {
5148 if (op == TOK_SAR)
5149 op = TOK_SHR;
5150 else if (op == '/')
5151 op = TOK_UDIV;
5152 else if (op == '%')
5153 op = TOK_UMOD;
5154 else if (op == TOK_LT)
5155 op = TOK_ULT;
5156 else if (op == TOK_GT)
5157 op = TOK_UGT;
5158 else if (op == TOK_LE)
5159 op = TOK_ULE;
5160 else if (op == TOK_GE)
5161 op = TOK_UGE;
5163 vswap();
5164 type1.t = t;
5165 gen_cast(&type1);
5166 vswap();
5167 /* special case for shifts and long long: we keep the shift as
5168 an integer */
5169 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
5170 type1.t = VT_INT;
5171 gen_cast(&type1);
5172 if (is_float(t))
5173 gen_opif(op);
5174 else if ((t & VT_BTYPE) == VT_LLONG)
5175 gen_opl(op);
5176 else
5177 gen_opic(op);
5178 if (op >= TOK_ULT && op <= TOK_GT) {
5179 /* relationnal op: the result is an int */
5180 vtop->type.t = VT_INT;
5181 } else {
5182 vtop->type.t = t;
5187 /* generic itof for unsigned long long case */
5188 void gen_cvt_itof1(int t)
5190 GFuncContext gf;
5192 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
5193 (VT_LLONG | VT_UNSIGNED)) {
5195 gfunc_start(&gf, FUNC_CDECL);
5196 gfunc_param(&gf);
5197 if (t == VT_FLOAT)
5198 vpush_global_sym(&func_old_type, TOK___ulltof);
5199 else if (t == VT_DOUBLE)
5200 vpush_global_sym(&func_old_type, TOK___ulltod);
5201 else
5202 vpush_global_sym(&func_old_type, TOK___ulltold);
5203 gfunc_call(&gf);
5204 vpushi(0);
5205 vtop->r = REG_FRET;
5206 } else {
5207 gen_cvt_itof(t);
5211 /* generic ftoi for unsigned long long case */
5212 void gen_cvt_ftoi1(int t)
5214 GFuncContext gf;
5215 int st;
5217 if (t == (VT_LLONG | VT_UNSIGNED)) {
5218 /* not handled natively */
5219 gfunc_start(&gf, FUNC_CDECL);
5220 st = vtop->type.t & VT_BTYPE;
5221 gfunc_param(&gf);
5222 if (st == VT_FLOAT)
5223 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
5224 else if (st == VT_DOUBLE)
5225 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
5226 else
5227 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
5228 gfunc_call(&gf);
5229 vpushi(0);
5230 vtop->r = REG_IRET;
5231 vtop->r2 = REG_LRET;
5232 } else {
5233 gen_cvt_ftoi(t);
5237 /* force char or short cast */
5238 void force_charshort_cast(int t)
5240 int bits, dbt;
5241 dbt = t & VT_BTYPE;
5242 /* XXX: add optimization if lvalue : just change type and offset */
5243 if (dbt == VT_BYTE)
5244 bits = 8;
5245 else
5246 bits = 16;
5247 if (t & VT_UNSIGNED) {
5248 vpushi((1 << bits) - 1);
5249 gen_op('&');
5250 } else {
5251 bits = 32 - bits;
5252 vpushi(bits);
5253 gen_op(TOK_SHL);
5254 vpushi(bits);
5255 gen_op(TOK_SAR);
5259 /* cast 'vtop' to 'type' */
5260 static void gen_cast(CType *type)
5262 int sbt, dbt, sf, df, c;
5264 /* special delayed cast for char/short */
5265 /* XXX: in some cases (multiple cascaded casts), it may still
5266 be incorrect */
5267 if (vtop->r & VT_MUSTCAST) {
5268 vtop->r &= ~VT_MUSTCAST;
5269 force_charshort_cast(vtop->type.t);
5272 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
5273 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
5275 if (sbt != dbt && !nocode_wanted) {
5276 sf = is_float(sbt);
5277 df = is_float(dbt);
5278 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5279 if (sf && df) {
5280 /* convert from fp to fp */
5281 if (c) {
5282 /* constant case: we can do it now */
5283 /* XXX: in ISOC, cannot do it if error in convert */
5284 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
5285 vtop->c.f = (float)vtop->c.d;
5286 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
5287 vtop->c.f = (float)vtop->c.ld;
5288 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
5289 vtop->c.d = (double)vtop->c.f;
5290 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
5291 vtop->c.d = (double)vtop->c.ld;
5292 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
5293 vtop->c.ld = (long double)vtop->c.f;
5294 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
5295 vtop->c.ld = (long double)vtop->c.d;
5296 } else {
5297 /* non constant case: generate code */
5298 gen_cvt_ftof(dbt);
5300 } else if (df) {
5301 /* convert int to fp */
5302 if (c) {
5303 switch(sbt) {
5304 case VT_LLONG | VT_UNSIGNED:
5305 case VT_LLONG:
5306 /* XXX: add const cases for long long */
5307 goto do_itof;
5308 case VT_INT | VT_UNSIGNED:
5309 switch(dbt) {
5310 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
5311 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
5312 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
5314 break;
5315 default:
5316 switch(dbt) {
5317 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
5318 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
5319 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
5321 break;
5323 } else {
5324 do_itof:
5325 gen_cvt_itof1(dbt);
5327 } else if (sf) {
5328 /* convert fp to int */
5329 /* we handle char/short/etc... with generic code */
5330 if (dbt != (VT_INT | VT_UNSIGNED) &&
5331 dbt != (VT_LLONG | VT_UNSIGNED) &&
5332 dbt != VT_LLONG)
5333 dbt = VT_INT;
5334 if (c) {
5335 switch(dbt) {
5336 case VT_LLONG | VT_UNSIGNED:
5337 case VT_LLONG:
5338 /* XXX: add const cases for long long */
5339 goto do_ftoi;
5340 case VT_INT | VT_UNSIGNED:
5341 switch(sbt) {
5342 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
5343 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5344 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5346 break;
5347 default:
5348 /* int case */
5349 switch(sbt) {
5350 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
5351 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
5352 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
5354 break;
5356 } else {
5357 do_ftoi:
5358 gen_cvt_ftoi1(dbt);
5360 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
5361 /* additional cast for char/short/bool... */
5362 vtop->type.t = dbt;
5363 gen_cast(type);
5365 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
5366 if ((sbt & VT_BTYPE) != VT_LLONG) {
5367 /* scalar to long long */
5368 if (c) {
5369 if (sbt == (VT_INT | VT_UNSIGNED))
5370 vtop->c.ll = vtop->c.ui;
5371 else
5372 vtop->c.ll = vtop->c.i;
5373 } else {
5374 /* machine independent conversion */
5375 gv(RC_INT);
5376 /* generate high word */
5377 if (sbt == (VT_INT | VT_UNSIGNED)) {
5378 vpushi(0);
5379 gv(RC_INT);
5380 } else {
5381 gv_dup();
5382 vpushi(31);
5383 gen_op(TOK_SAR);
5385 /* patch second register */
5386 vtop[-1].r2 = vtop->r;
5387 vpop();
5390 } else if (dbt == VT_BOOL) {
5391 /* scalar to bool */
5392 vpushi(0);
5393 gen_op(TOK_NE);
5394 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
5395 (dbt & VT_BTYPE) == VT_SHORT) {
5396 force_charshort_cast(dbt);
5397 } else if ((dbt & VT_BTYPE) == VT_INT) {
5398 /* scalar to int */
5399 if (sbt == VT_LLONG) {
5400 /* from long long: just take low order word */
5401 lexpand();
5402 vpop();
5404 /* if lvalue and single word type, nothing to do because
5405 the lvalue already contains the real type size (see
5406 VT_LVAL_xxx constants) */
5409 vtop->type = *type;
5412 /* return type size. Put alignment at 'a' */
5413 static int type_size(CType *type, int *a)
5415 Sym *s;
5416 int bt;
5418 bt = type->t & VT_BTYPE;
5419 if (bt == VT_STRUCT) {
5420 /* struct/union */
5421 s = type->ref;
5422 *a = s->r;
5423 return s->c;
5424 } else if (bt == VT_PTR) {
5425 if (type->t & VT_ARRAY) {
5426 s = type->ref;
5427 return type_size(&s->type, a) * s->c;
5428 } else {
5429 *a = PTR_SIZE;
5430 return PTR_SIZE;
5432 } else if (bt == VT_LDOUBLE) {
5433 *a = LDOUBLE_ALIGN;
5434 return LDOUBLE_SIZE;
5435 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
5436 *a = 4; /* XXX: i386 specific */
5437 return 8;
5438 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
5439 *a = 4;
5440 return 4;
5441 } else if (bt == VT_SHORT) {
5442 *a = 2;
5443 return 2;
5444 } else {
5445 /* char, void, function, _Bool */
5446 *a = 1;
5447 return 1;
5451 /* return the pointed type of t */
5452 static inline CType *pointed_type(CType *type)
5454 return &type->ref->type;
5457 /* modify type so that its it is a pointer to type. */
5458 static void mk_pointer(CType *type)
5460 Sym *s;
5461 s = sym_push(SYM_FIELD, type, 0, -1);
5462 type->t = VT_PTR | (type->t & ~VT_TYPE);
5463 type->ref = s;
5466 static int is_compatible_types(CType *type1, CType *type2)
5468 Sym *s1, *s2;
5469 int bt1, bt2, t1, t2;
5471 t1 = type1->t & VT_TYPE;
5472 t2 = type2->t & VT_TYPE;
5473 bt1 = t1 & VT_BTYPE;
5474 bt2 = t2 & VT_BTYPE;
5475 if (bt1 == VT_PTR) {
5476 type1 = pointed_type(type1);
5477 /* if function, then convert implicitely to function pointer */
5478 if (bt2 != VT_FUNC) {
5479 if (bt2 != VT_PTR)
5480 return 0;
5481 type2 = pointed_type(type2);
5483 /* void matches everything */
5484 /* XXX: not fully compliant */
5485 if ((type1->t & VT_TYPE) == VT_VOID || (type2->t & VT_TYPE) == VT_VOID)
5486 return 1;
5487 return is_compatible_types(type1, type2);
5488 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5489 return (type1->ref == type2->ref);
5490 } else if (bt1 == VT_FUNC) {
5491 if (bt2 != VT_FUNC)
5492 return 0;
5493 s1 = type1->ref;
5494 s2 = type2->ref;
5495 if (!is_compatible_types(&s1->type, &s2->type))
5496 return 0;
5497 /* XXX: not complete */
5498 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
5499 return 1;
5500 if (s1->c != s2->c)
5501 return 0;
5502 while (s1 != NULL) {
5503 if (s2 == NULL)
5504 return 0;
5505 if (!is_compatible_types(&s1->type, &s2->type))
5506 return 0;
5507 s1 = s1->next;
5508 s2 = s2->next;
5510 if (s2)
5511 return 0;
5512 return 1;
5513 } else {
5514 /* XXX: not complete */
5515 return 1;
5519 /* print a type. If 'varstr' is not NULL, then the variable is also
5520 printed in the type */
5521 /* XXX: union */
5522 /* XXX: add array and function pointers */
5523 void type_to_str(char *buf, int buf_size,
5524 CType *type, const char *varstr)
5526 int bt, v, t;
5527 Sym *s, *sa;
5528 char buf1[256];
5529 const char *tstr;
5531 t = type->t & VT_TYPE;
5532 bt = t & VT_BTYPE;
5533 buf[0] = '\0';
5534 if (t & VT_UNSIGNED)
5535 pstrcat(buf, buf_size, "unsigned ");
5536 switch(bt) {
5537 case VT_VOID:
5538 tstr = "void";
5539 goto add_tstr;
5540 case VT_BOOL:
5541 tstr = "_Bool";
5542 goto add_tstr;
5543 case VT_BYTE:
5544 tstr = "char";
5545 goto add_tstr;
5546 case VT_SHORT:
5547 tstr = "short";
5548 goto add_tstr;
5549 case VT_INT:
5550 tstr = "int";
5551 goto add_tstr;
5552 case VT_LONG:
5553 tstr = "long";
5554 goto add_tstr;
5555 case VT_LLONG:
5556 tstr = "long long";
5557 goto add_tstr;
5558 case VT_FLOAT:
5559 tstr = "float";
5560 goto add_tstr;
5561 case VT_DOUBLE:
5562 tstr = "double";
5563 goto add_tstr;
5564 case VT_LDOUBLE:
5565 tstr = "long double";
5566 add_tstr:
5567 pstrcat(buf, buf_size, tstr);
5568 break;
5569 case VT_ENUM:
5570 case VT_STRUCT:
5571 if (bt == VT_STRUCT)
5572 tstr = "struct ";
5573 else
5574 tstr = "enum ";
5575 pstrcat(buf, buf_size, tstr);
5576 v = type->ref->v & ~SYM_STRUCT;
5577 if (v >= SYM_FIRST_ANOM)
5578 pstrcat(buf, buf_size, "<anonymous>");
5579 else
5580 pstrcat(buf, buf_size, get_tok_str(v, NULL));
5581 break;
5582 case VT_FUNC:
5583 s = type->ref;
5584 type_to_str(buf, buf_size, &s->type, varstr);
5585 pstrcat(buf, buf_size, "(");
5586 sa = s->next;
5587 while (sa != NULL) {
5588 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
5589 pstrcat(buf, buf_size, buf1);
5590 sa = sa->next;
5591 if (sa)
5592 pstrcat(buf, buf_size, ", ");
5594 pstrcat(buf, buf_size, ")");
5595 goto no_var;
5596 case VT_PTR:
5597 s = type->ref;
5598 pstrcpy(buf1, sizeof(buf1), "*");
5599 if (varstr)
5600 pstrcat(buf1, sizeof(buf1), varstr);
5601 type_to_str(buf, buf_size, &s->type, buf1);
5602 goto no_var;
5604 if (varstr) {
5605 pstrcat(buf, buf_size, " ");
5606 pstrcat(buf, buf_size, varstr);
5608 no_var: ;
5611 /* verify type compatibility to store vtop in 'dt' type, and generate
5612 casts if needed. */
5613 static void gen_assign_cast(CType *dt)
5615 CType *st;
5616 char buf1[256], buf2[256];
5617 int dbt, sbt;
5619 st = &vtop->type; /* source type */
5620 dbt = dt->t & VT_BTYPE;
5621 sbt = st->t & VT_BTYPE;
5622 if (dbt == VT_PTR) {
5623 /* special cases for pointers */
5624 /* a function is implicitely a function pointer */
5625 if (sbt == VT_FUNC) {
5626 if (!is_compatible_types(pointed_type(dt), st))
5627 goto error;
5628 else
5629 goto type_ok;
5631 /* '0' can also be a pointer */
5632 if (sbt == VT_INT &&
5633 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
5634 vtop->c.i == 0)
5635 goto type_ok;
5636 /* accept implicit pointer to integer cast with warning */
5637 if (sbt == VT_BYTE || sbt == VT_SHORT ||
5638 sbt == VT_INT || sbt == VT_LLONG) {
5639 warning("assignment makes pointer from integer without a cast");
5640 goto type_ok;
5642 } else if (dbt == VT_BYTE || dbt == VT_SHORT ||
5643 dbt == VT_INT || dbt == VT_LLONG) {
5644 if (sbt == VT_PTR || sbt == VT_FUNC) {
5645 warning("assignment makes integer from pointer without a cast");
5646 goto type_ok;
5649 if (!is_compatible_types(dt, st)) {
5650 error:
5651 type_to_str(buf1, sizeof(buf1), st, NULL);
5652 type_to_str(buf2, sizeof(buf2), dt, NULL);
5653 error("cannot cast '%s' to '%s'", buf1, buf2);
5655 type_ok:
5656 gen_cast(dt);
5659 /* store vtop in lvalue pushed on stack */
5660 void vstore(void)
5662 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
5663 GFuncContext gf;
5665 ft = vtop[-1].type.t;
5666 sbt = vtop->type.t & VT_BTYPE;
5667 dbt = ft & VT_BTYPE;
5668 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
5669 (sbt == VT_INT && dbt == VT_SHORT)) {
5670 /* optimize char/short casts */
5671 delayed_cast = VT_MUSTCAST;
5672 vtop->type.t = ft & VT_TYPE;
5673 } else {
5674 delayed_cast = 0;
5675 gen_assign_cast(&vtop[-1].type);
5678 if (sbt == VT_STRUCT) {
5679 /* if structure, only generate pointer */
5680 /* structure assignment : generate memcpy */
5681 /* XXX: optimize if small size */
5682 if (!nocode_wanted) {
5683 vdup();
5684 gfunc_start(&gf, FUNC_CDECL);
5685 /* type size */
5686 size = type_size(&vtop->type, &align);
5687 vpushi(size);
5688 gfunc_param(&gf);
5689 /* source */
5690 vtop->type.t = VT_INT;
5691 gaddrof();
5692 gfunc_param(&gf);
5693 /* destination */
5694 vswap();
5695 vtop->type.t = VT_INT;
5696 gaddrof();
5697 gfunc_param(&gf);
5699 save_regs(0);
5700 vpush_global_sym(&func_old_type, TOK_memcpy);
5701 gfunc_call(&gf);
5702 } else {
5703 vswap();
5704 vpop();
5706 /* leave source on stack */
5707 } else if (ft & VT_BITFIELD) {
5708 /* bitfield store handling */
5709 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
5710 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5711 /* remove bit field info to avoid loops */
5712 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
5714 /* duplicate destination */
5715 vdup();
5716 vtop[-1] = vtop[-2];
5718 /* mask and shift source */
5719 vpushi((1 << bit_size) - 1);
5720 gen_op('&');
5721 vpushi(bit_pos);
5722 gen_op(TOK_SHL);
5723 /* load destination, mask and or with source */
5724 vswap();
5725 vpushi(~(((1 << bit_size) - 1) << bit_pos));
5726 gen_op('&');
5727 gen_op('|');
5728 /* store result */
5729 vstore();
5730 } else {
5731 #ifdef CONFIG_TCC_BCHECK
5732 /* bound check case */
5733 if (vtop[-1].r & VT_MUSTBOUND) {
5734 vswap();
5735 gbound();
5736 vswap();
5738 #endif
5739 if (!nocode_wanted) {
5740 rc = RC_INT;
5741 if (is_float(ft))
5742 rc = RC_FLOAT;
5743 r = gv(rc); /* generate value */
5744 /* if lvalue was saved on stack, must read it */
5745 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
5746 SValue sv;
5747 t = get_reg(RC_INT);
5748 sv.type.t = VT_INT;
5749 sv.r = VT_LOCAL | VT_LVAL;
5750 sv.c.ul = vtop[-1].c.ul;
5751 load(t, &sv);
5752 vtop[-1].r = t | VT_LVAL;
5754 store(r, vtop - 1);
5755 /* two word case handling : store second register at word + 4 */
5756 if ((ft & VT_BTYPE) == VT_LLONG) {
5757 vswap();
5758 /* convert to int to increment easily */
5759 vtop->type.t = VT_INT;
5760 gaddrof();
5761 vpushi(4);
5762 gen_op('+');
5763 vtop->r |= VT_LVAL;
5764 vswap();
5765 /* XXX: it works because r2 is spilled last ! */
5766 store(vtop->r2, vtop - 1);
5769 vswap();
5770 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5771 vtop->r |= delayed_cast;
5775 /* post defines POST/PRE add. c is the token ++ or -- */
5776 void inc(int post, int c)
5778 test_lvalue();
5779 vdup(); /* save lvalue */
5780 if (post) {
5781 gv_dup(); /* duplicate value */
5782 vrotb(3);
5783 vrotb(3);
5785 /* add constant */
5786 vpushi(c - TOK_MID);
5787 gen_op('+');
5788 vstore(); /* store value */
5789 if (post)
5790 vpop(); /* if post op, return saved value */
5793 /* Parse GNUC __attribute__ extension. Currently, the following
5794 extensions are recognized:
5795 - aligned(n) : set data/function alignment.
5796 - section(x) : generate data/code in this section.
5797 - unused : currently ignored, but may be used someday.
5799 static void parse_attribute(AttributeDef *ad)
5801 int t, n;
5803 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
5804 next();
5805 skip('(');
5806 skip('(');
5807 while (tok != ')') {
5808 if (tok < TOK_IDENT)
5809 expect("attribute name");
5810 t = tok;
5811 next();
5812 switch(t) {
5813 case TOK_SECTION1:
5814 case TOK_SECTION2:
5815 skip('(');
5816 if (tok != TOK_STR)
5817 expect("section name");
5818 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
5819 next();
5820 skip(')');
5821 break;
5822 case TOK_ALIGNED1:
5823 case TOK_ALIGNED2:
5824 if (tok == '(') {
5825 next();
5826 n = expr_const();
5827 if (n <= 0 || (n & (n - 1)) != 0)
5828 error("alignment must be a positive power of two");
5829 skip(')');
5830 } else {
5831 n = MAX_ALIGN;
5833 ad->aligned = n;
5834 break;
5835 case TOK_UNUSED1:
5836 case TOK_UNUSED2:
5837 /* currently, no need to handle it because tcc does not
5838 track unused objects */
5839 break;
5840 case TOK_NORETURN1:
5841 case TOK_NORETURN2:
5842 /* currently, no need to handle it because tcc does not
5843 track unused objects */
5844 break;
5845 case TOK_CDECL1:
5846 case TOK_CDECL2:
5847 case TOK_CDECL3:
5848 ad->func_call = FUNC_CDECL;
5849 break;
5850 case TOK_STDCALL1:
5851 case TOK_STDCALL2:
5852 case TOK_STDCALL3:
5853 ad->func_call = FUNC_STDCALL;
5854 break;
5855 default:
5856 // warning("'%s' attribute ignored", get_tok_str(t, NULL));
5857 /* skip parameters */
5858 /* XXX: skip parenthesis too */
5859 if (tok == '(') {
5860 next();
5861 while (tok != ')' && tok != -1)
5862 next();
5863 next();
5865 break;
5867 if (tok != ',')
5868 break;
5869 next();
5871 skip(')');
5872 skip(')');
5876 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5877 static void struct_decl(CType *type, int u)
5879 int a, v, size, align, maxalign, c, offset;
5880 int bit_size, bit_pos, bsize, bt, lbit_pos;
5881 Sym *s, *ss, **ps;
5882 AttributeDef ad;
5883 CType type1, btype;
5885 a = tok; /* save decl type */
5886 next();
5887 if (tok != '{') {
5888 v = tok;
5889 next();
5890 /* struct already defined ? return it */
5891 if (v < TOK_IDENT)
5892 expect("struct/union/enum name");
5893 s = struct_find(v);
5894 if (s) {
5895 if (s->type.t != a)
5896 error("invalid type");
5897 goto do_decl;
5899 } else {
5900 v = anon_sym++;
5902 type1.t = a;
5903 s = sym_push(v | SYM_STRUCT, &type1, 0, 0);
5904 /* put struct/union/enum name in type */
5905 do_decl:
5906 type->t = u;
5907 type->ref = s;
5909 if (tok == '{') {
5910 next();
5911 if (s->c)
5912 error("struct/union/enum already defined");
5913 /* cannot be empty */
5914 c = 0;
5915 /* non empty enums are not allowed */
5916 if (a == TOK_ENUM) {
5917 for(;;) {
5918 v = tok;
5919 if (v < TOK_UIDENT)
5920 expect("identifier");
5921 next();
5922 if (tok == '=') {
5923 next();
5924 c = expr_const();
5926 /* enum symbols have static storage */
5927 ss = sym_push(v, &int_type, VT_CONST, c);
5928 ss->type.t |= VT_STATIC;
5929 if (tok != ',')
5930 break;
5931 next();
5932 c++;
5933 /* NOTE: we accept a trailing comma */
5934 if (tok == '}')
5935 break;
5937 skip('}');
5938 } else {
5939 maxalign = 1;
5940 ps = &s->next;
5941 bit_pos = 0;
5942 offset = 0;
5943 while (tok != '}') {
5944 parse_btype(&btype, &ad);
5945 while (1) {
5946 bit_size = -1;
5947 v = 0;
5948 type1 = btype;
5949 if (tok != ':') {
5950 type_decl(&type1, &ad, &v, TYPE_DIRECT);
5951 if ((type1.t & VT_BTYPE) == VT_FUNC ||
5952 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
5953 error("invalid type for '%s'",
5954 get_tok_str(v, NULL));
5956 if (tok == ':') {
5957 next();
5958 bit_size = expr_const();
5959 /* XXX: handle v = 0 case for messages */
5960 if (bit_size < 0)
5961 error("negative width in bit-field '%s'",
5962 get_tok_str(v, NULL));
5963 if (v && bit_size == 0)
5964 error("zero width for bit-field '%s'",
5965 get_tok_str(v, NULL));
5967 size = type_size(&type1, &align);
5968 lbit_pos = 0;
5969 if (bit_size >= 0) {
5970 bt = type1.t & VT_BTYPE;
5971 if (bt != VT_INT &&
5972 bt != VT_BYTE &&
5973 bt != VT_SHORT &&
5974 bt != VT_ENUM)
5975 error("bitfields must have scalar type");
5976 bsize = size * 8;
5977 if (bit_size > bsize) {
5978 error("width of '%s' exceeds its type",
5979 get_tok_str(v, NULL));
5980 } else if (bit_size == bsize) {
5981 /* no need for bit fields */
5982 bit_pos = 0;
5983 } else if (bit_size == 0) {
5984 /* XXX: what to do if only padding in a
5985 structure ? */
5986 /* zero size: means to pad */
5987 if (bit_pos > 0)
5988 bit_pos = bsize;
5989 } else {
5990 /* we do not have enough room ? */
5991 if ((bit_pos + bit_size) > bsize)
5992 bit_pos = 0;
5993 lbit_pos = bit_pos;
5994 /* XXX: handle LSB first */
5995 type1.t |= VT_BITFIELD |
5996 (bit_pos << VT_STRUCT_SHIFT) |
5997 (bit_size << (VT_STRUCT_SHIFT + 6));
5998 bit_pos += bit_size;
6000 } else {
6001 bit_pos = 0;
6003 if (v) {
6004 /* add new memory data only if starting
6005 bit field */
6006 if (lbit_pos == 0) {
6007 if (a == TOK_STRUCT) {
6008 c = (c + align - 1) & -align;
6009 offset = c;
6010 c += size;
6011 } else {
6012 offset = 0;
6013 if (size > c)
6014 c = size;
6016 if (align > maxalign)
6017 maxalign = align;
6019 #if 0
6020 printf("add field %s offset=%d",
6021 get_tok_str(v, NULL), offset);
6022 if (type1.t & VT_BITFIELD) {
6023 printf(" pos=%d size=%d",
6024 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
6025 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
6027 printf("\n");
6028 #endif
6029 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
6030 *ps = ss;
6031 ps = &ss->next;
6033 if (tok == ';' || tok == TOK_EOF)
6034 break;
6035 skip(',');
6037 skip(';');
6039 skip('}');
6040 /* store size and alignment */
6041 s->c = (c + maxalign - 1) & -maxalign;
6042 s->r = maxalign;
6047 /* return 0 if no type declaration. otherwise, return the basic type
6048 and skip it.
6050 static int parse_btype(CType *type, AttributeDef *ad)
6052 int t, u, type_found;
6053 Sym *s;
6054 CType type1;
6056 memset(ad, 0, sizeof(AttributeDef));
6057 type_found = 0;
6058 t = 0;
6059 while(1) {
6060 switch(tok) {
6061 case TOK_EXTENSION:
6062 /* currently, we really ignore extension */
6063 next();
6064 continue;
6066 /* basic types */
6067 case TOK_CHAR:
6068 u = VT_BYTE;
6069 basic_type:
6070 next();
6071 basic_type1:
6072 if ((t & VT_BTYPE) != 0)
6073 error("too many basic types");
6074 t |= u;
6075 break;
6076 case TOK_VOID:
6077 u = VT_VOID;
6078 goto basic_type;
6079 case TOK_SHORT:
6080 u = VT_SHORT;
6081 goto basic_type;
6082 case TOK_INT:
6083 next();
6084 break;
6085 case TOK_LONG:
6086 next();
6087 if ((t & VT_BTYPE) == VT_DOUBLE) {
6088 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
6089 } else if ((t & VT_BTYPE) == VT_LONG) {
6090 t = (t & ~VT_BTYPE) | VT_LLONG;
6091 } else {
6092 u = VT_LONG;
6093 goto basic_type1;
6095 break;
6096 case TOK_BOOL:
6097 u = VT_BOOL;
6098 goto basic_type;
6099 case TOK_FLOAT:
6100 u = VT_FLOAT;
6101 goto basic_type;
6102 case TOK_DOUBLE:
6103 next();
6104 if ((t & VT_BTYPE) == VT_LONG) {
6105 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
6106 } else {
6107 u = VT_DOUBLE;
6108 goto basic_type1;
6110 break;
6111 case TOK_ENUM:
6112 struct_decl(&type1, VT_ENUM);
6113 basic_type2:
6114 u = type1.t;
6115 type->ref = type1.ref;
6116 goto basic_type1;
6117 case TOK_STRUCT:
6118 case TOK_UNION:
6119 struct_decl(&type1, VT_STRUCT);
6120 goto basic_type2;
6122 /* type modifiers */
6123 case TOK_CONST1:
6124 case TOK_CONST2:
6125 case TOK_CONST3:
6126 case TOK_VOLATILE1:
6127 case TOK_VOLATILE2:
6128 case TOK_VOLATILE3:
6129 case TOK_REGISTER:
6130 case TOK_SIGNED1:
6131 case TOK_SIGNED2:
6132 case TOK_SIGNED3:
6133 case TOK_AUTO:
6134 case TOK_RESTRICT1:
6135 case TOK_RESTRICT2:
6136 case TOK_RESTRICT3:
6137 next();
6138 break;
6139 case TOK_UNSIGNED:
6140 t |= VT_UNSIGNED;
6141 next();
6142 break;
6144 /* storage */
6145 case TOK_EXTERN:
6146 t |= VT_EXTERN;
6147 next();
6148 break;
6149 case TOK_STATIC:
6150 t |= VT_STATIC;
6151 next();
6152 break;
6153 case TOK_TYPEDEF:
6154 t |= VT_TYPEDEF;
6155 next();
6156 break;
6157 case TOK_INLINE1:
6158 case TOK_INLINE2:
6159 case TOK_INLINE3:
6160 t |= VT_INLINE;
6161 next();
6162 break;
6164 /* GNUC attribute */
6165 case TOK_ATTRIBUTE1:
6166 case TOK_ATTRIBUTE2:
6167 parse_attribute(ad);
6168 break;
6169 /* GNUC typeof */
6170 case TOK_TYPEOF1:
6171 case TOK_TYPEOF2:
6172 case TOK_TYPEOF3:
6173 next();
6174 parse_expr_type(&type1);
6175 goto basic_type2;
6176 default:
6177 s = sym_find(tok);
6178 if (!s || !(s->type.t & VT_TYPEDEF))
6179 goto the_end;
6180 t |= (s->type.t & ~VT_TYPEDEF);
6181 type->ref = s->type.ref;
6182 next();
6183 break;
6185 type_found = 1;
6187 the_end:
6188 /* long is never used as type */
6189 if ((t & VT_BTYPE) == VT_LONG)
6190 t = (t & ~VT_BTYPE) | VT_INT;
6191 type->t = t;
6192 return type_found;
6195 /* convert a function parameter type (array to pointer and function to
6196 function pointer) */
6197 static inline void convert_parameter_type(CType *pt)
6199 /* array must be transformed to pointer according to ANSI C */
6200 pt->t &= ~VT_ARRAY;
6201 if ((pt->t & VT_BTYPE) == VT_FUNC) {
6202 mk_pointer(pt);
6206 static void post_type(CType *type, AttributeDef *ad)
6208 int n, l, t1;
6209 Sym **plast, *s, *first;
6210 AttributeDef ad1;
6211 CType pt;
6213 if (tok == '(') {
6214 /* function declaration */
6215 next();
6216 l = 0;
6217 first = NULL;
6218 plast = &first;
6219 while (tok != ')') {
6220 /* read param name and compute offset */
6221 if (l != FUNC_OLD) {
6222 if (!parse_btype(&pt, &ad1)) {
6223 if (l) {
6224 error("invalid type");
6225 } else {
6226 l = FUNC_OLD;
6227 goto old_proto;
6230 l = FUNC_NEW;
6231 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
6232 break;
6233 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
6234 if ((pt.t & VT_BTYPE) == VT_VOID)
6235 error("parameter declared as void");
6236 } else {
6237 old_proto:
6238 n = tok;
6239 pt.t = VT_INT;
6240 next();
6242 convert_parameter_type(&pt);
6243 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
6244 *plast = s;
6245 plast = &s->next;
6246 if (tok == ',') {
6247 next();
6248 if (l == FUNC_NEW && tok == TOK_DOTS) {
6249 l = FUNC_ELLIPSIS;
6250 next();
6251 break;
6255 /* if no parameters, then old type prototype */
6256 if (l == 0)
6257 l = FUNC_OLD;
6258 skip(')');
6259 t1 = type->t & VT_STORAGE;
6260 type->t &= ~VT_STORAGE;
6261 post_type(type, ad);
6262 /* we push a anonymous symbol which will contain the function prototype */
6263 s = sym_push(SYM_FIELD, type, ad->func_call, l);
6264 s->next = first;
6265 type->t = t1 | VT_FUNC;
6266 type->ref = s;
6267 } else if (tok == '[') {
6268 /* array definition */
6269 next();
6270 n = -1;
6271 if (tok != ']') {
6272 n = expr_const();
6273 if (n < 0)
6274 error("invalid array size");
6276 skip(']');
6277 /* parse next post type */
6278 t1 = type->t & VT_STORAGE;
6279 type->t &= ~VT_STORAGE;
6280 post_type(type, ad);
6282 /* we push a anonymous symbol which will contain the array
6283 element type */
6284 s = sym_push(SYM_FIELD, type, 0, n);
6285 type->t = t1 | VT_ARRAY | VT_PTR;
6286 type->ref = s;
6290 /* Parse a type declaration (except basic type), and return the type
6291 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6292 expected. 'type' should contain the basic type. 'ad' is the
6293 attribute definition of the basic type. It can be modified by
6294 type_decl().
6296 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
6298 Sym *s;
6299 CType type1, *type2;
6301 while (tok == '*') {
6302 next();
6303 redo:
6304 switch(tok) {
6305 case TOK_CONST1:
6306 case TOK_CONST2:
6307 case TOK_CONST3:
6308 case TOK_VOLATILE1:
6309 case TOK_VOLATILE2:
6310 case TOK_VOLATILE3:
6311 case TOK_RESTRICT1:
6312 case TOK_RESTRICT2:
6313 case TOK_RESTRICT3:
6314 next();
6315 goto redo;
6317 mk_pointer(type);
6320 /* XXX: clarify attribute handling */
6321 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6322 parse_attribute(ad);
6324 /* recursive type */
6325 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6326 type1.t = 0; /* XXX: same as int */
6327 if (tok == '(') {
6328 next();
6329 /* XXX: this is not correct to modify 'ad' at this point, but
6330 the syntax is not clear */
6331 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6332 parse_attribute(ad);
6333 type_decl(&type1, ad, v, td);
6334 skip(')');
6335 } else {
6336 /* type identifier */
6337 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
6338 *v = tok;
6339 next();
6340 } else {
6341 if (!(td & TYPE_ABSTRACT))
6342 expect("identifier");
6343 *v = 0;
6346 post_type(type, ad);
6347 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6348 parse_attribute(ad);
6349 if (!type1.t)
6350 return;
6351 /* append type at the end of type1 */
6352 type2 = &type1;
6353 for(;;) {
6354 s = type2->ref;
6355 type2 = &s->type;
6356 if (!type2->t) {
6357 *type2 = *type;
6358 break;
6361 *type = type1;
6364 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6365 static int lvalue_type(int t)
6367 int bt, r;
6368 r = VT_LVAL;
6369 bt = t & VT_BTYPE;
6370 if (bt == VT_BYTE || bt == VT_BOOL)
6371 r |= VT_LVAL_BYTE;
6372 else if (bt == VT_SHORT)
6373 r |= VT_LVAL_SHORT;
6374 else
6375 return r;
6376 if (t & VT_UNSIGNED)
6377 r |= VT_LVAL_UNSIGNED;
6378 return r;
6381 /* indirection with full error checking and bound check */
6382 static void indir(void)
6384 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6385 expect("pointer");
6386 if ((vtop->r & VT_LVAL) && !nocode_wanted)
6387 gv(RC_INT);
6388 vtop->type = *pointed_type(&vtop->type);
6389 /* an array is never an lvalue */
6390 if (!(vtop->type.t & VT_ARRAY)) {
6391 vtop->r |= lvalue_type(vtop->type.t);
6392 /* if bound checking, the referenced pointer must be checked */
6393 if (do_bounds_check)
6394 vtop->r |= VT_MUSTBOUND;
6398 /* pass a parameter to a function and do type checking and casting */
6399 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
6401 int func_type;
6402 CType type;
6404 func_type = func->c;
6405 if (func_type == FUNC_OLD ||
6406 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
6407 /* default casting : only need to convert float to double */
6408 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
6409 type.t = VT_DOUBLE;
6410 gen_cast(&type);
6412 } else if (arg == NULL) {
6413 error("too many arguments to function");
6414 } else {
6415 gen_assign_cast(&arg->type);
6417 if (!nocode_wanted) {
6418 gfunc_param(gf);
6419 } else {
6420 vpop();
6424 /* parse an expression of the form '(type)' or '(expr)' and return its
6425 type */
6426 static void parse_expr_type(CType *type)
6428 int n;
6429 AttributeDef ad;
6431 skip('(');
6432 if (parse_btype(type, &ad)) {
6433 type_decl(type, &ad, &n, TYPE_ABSTRACT);
6434 } else {
6435 expr_type(type);
6437 skip(')');
6440 static void vpush_tokc(int t)
6442 CType type;
6443 type.t = t;
6444 vsetc(&type, VT_CONST, &tokc);
6447 static void unary(void)
6449 int n, t, align, size, r;
6450 CType type;
6451 Sym *s;
6452 GFuncContext gf;
6453 AttributeDef ad;
6455 /* XXX: GCC 2.95.3 does not generate a table although it should be
6456 better here */
6457 tok_next:
6458 switch(tok) {
6459 case TOK_EXTENSION:
6460 next();
6461 goto tok_next;
6462 case TOK_CINT:
6463 case TOK_CCHAR:
6464 case TOK_LCHAR:
6465 vpushi(tokc.i);
6466 next();
6467 break;
6468 case TOK_CUINT:
6469 vpush_tokc(VT_INT | VT_UNSIGNED);
6470 next();
6471 break;
6472 case TOK_CLLONG:
6473 vpush_tokc(VT_LLONG);
6474 next();
6475 break;
6476 case TOK_CULLONG:
6477 vpush_tokc(VT_LLONG | VT_UNSIGNED);
6478 next();
6479 break;
6480 case TOK_CFLOAT:
6481 vpush_tokc(VT_FLOAT);
6482 next();
6483 break;
6484 case TOK_CDOUBLE:
6485 vpush_tokc(VT_DOUBLE);
6486 next();
6487 break;
6488 case TOK_CLDOUBLE:
6489 vpush_tokc(VT_LDOUBLE);
6490 next();
6491 break;
6492 case TOK___FUNCTION__:
6493 if (!gnu_ext)
6494 goto tok_identifier;
6495 /* fall thru */
6496 case TOK___FUNC__:
6498 void *ptr;
6499 int len;
6500 /* special function name identifier */
6501 len = strlen(funcname) + 1;
6502 /* generate char[len] type */
6503 type.t = VT_BYTE;
6504 mk_pointer(&type);
6505 type.t |= VT_ARRAY;
6506 type.ref->c = len;
6507 vpush_ref(&type, data_section, data_section->data_offset, len);
6508 ptr = section_ptr_add(data_section, len);
6509 memcpy(ptr, funcname, len);
6510 next();
6512 break;
6513 case TOK_LSTR:
6514 t = VT_INT;
6515 goto str_init;
6516 case TOK_STR:
6517 /* string parsing */
6518 t = VT_BYTE;
6519 str_init:
6520 type.t = t;
6521 mk_pointer(&type);
6522 type.t |= VT_ARRAY;
6523 memset(&ad, 0, sizeof(AttributeDef));
6524 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
6525 break;
6526 case '(':
6527 next();
6528 /* cast ? */
6529 if (parse_btype(&type, &ad)) {
6530 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
6531 skip(')');
6532 /* check ISOC99 compound literal */
6533 if (tok == '{') {
6534 /* data is allocated locally by default */
6535 if (global_expr)
6536 r = VT_CONST;
6537 else
6538 r = VT_LOCAL;
6539 /* all except arrays are lvalues */
6540 if (!(type.t & VT_ARRAY))
6541 r |= lvalue_type(type.t);
6542 memset(&ad, 0, sizeof(AttributeDef));
6543 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
6544 } else {
6545 unary();
6546 gen_cast(&type);
6548 } else if (tok == '{') {
6549 /* save all registers */
6550 save_regs(0);
6551 /* statement expression : we do not accept break/continue
6552 inside as GCC does */
6553 block(NULL, NULL, NULL, NULL, 0, 1);
6554 skip(')');
6555 } else {
6556 gexpr();
6557 skip(')');
6559 break;
6560 case '*':
6561 next();
6562 unary();
6563 indir();
6564 break;
6565 case '&':
6566 next();
6567 unary();
6568 /* functions names must be treated as function pointers,
6569 except for unary '&' and sizeof. Since we consider that
6570 functions are not lvalues, we only have to handle it
6571 there and in function calls. */
6572 /* arrays can also be used although they are not lvalues */
6573 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
6574 !(vtop->type.t & VT_ARRAY))
6575 test_lvalue();
6576 mk_pointer(&vtop->type);
6577 gaddrof();
6578 break;
6579 case '!':
6580 next();
6581 unary();
6582 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
6583 vtop->c.i = !vtop->c.i;
6584 else if ((vtop->r & VT_VALMASK) == VT_CMP)
6585 vtop->c.i = vtop->c.i ^ 1;
6586 else
6587 vseti(VT_JMP, gtst(1, 0));
6588 break;
6589 case '~':
6590 next();
6591 unary();
6592 vpushi(-1);
6593 gen_op('^');
6594 break;
6595 case '+':
6596 next();
6597 /* in order to force cast, we add zero */
6598 unary();
6599 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
6600 error("pointer not accepted for unary plus");
6601 vpushi(0);
6602 gen_op('+');
6603 break;
6604 case TOK_SIZEOF:
6605 case TOK_ALIGNOF1:
6606 case TOK_ALIGNOF2:
6607 t = tok;
6608 next();
6609 if (tok == '(') {
6610 parse_expr_type(&type);
6611 } else {
6612 unary_type(&type);
6614 size = type_size(&type, &align);
6615 if (t == TOK_SIZEOF)
6616 vpushi(size);
6617 else
6618 vpushi(align);
6619 break;
6621 case TOK_INC:
6622 case TOK_DEC:
6623 t = tok;
6624 next();
6625 unary();
6626 inc(0, t);
6627 break;
6628 case '-':
6629 next();
6630 vpushi(0);
6631 unary();
6632 gen_op('-');
6633 break;
6634 case TOK_LAND:
6635 if (!gnu_ext)
6636 goto tok_identifier;
6637 next();
6638 /* allow to take the address of a label */
6639 if (tok < TOK_UIDENT)
6640 expect("label identifier");
6641 s = label_find(tok);
6642 if (!s) {
6643 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
6644 } else {
6645 if (s->r == LABEL_DECLARED)
6646 s->r = LABEL_FORWARD;
6648 if (!s->type.t) {
6649 s->type.t = VT_VOID;
6650 mk_pointer(&s->type);
6651 s->type.t |= VT_STATIC;
6653 vset(&s->type, VT_CONST | VT_SYM, 0);
6654 vtop->sym = s;
6655 next();
6656 break;
6657 default:
6658 tok_identifier:
6659 t = tok;
6660 next();
6661 if (t < TOK_UIDENT)
6662 expect("identifier");
6663 s = sym_find(t);
6664 if (!s) {
6665 if (tok != '(')
6666 error("'%s' undeclared", get_tok_str(t, NULL));
6667 /* for simple function calls, we tolerate undeclared
6668 external reference to int() function */
6669 s = external_global_sym(t, &func_old_type, 0);
6671 vset(&s->type, s->r, s->c);
6672 /* if forward reference, we must point to s */
6673 if (vtop->r & VT_SYM) {
6674 vtop->sym = s;
6675 vtop->c.ul = 0;
6677 break;
6680 /* post operations */
6681 while (1) {
6682 if (tok == TOK_INC || tok == TOK_DEC) {
6683 inc(1, tok);
6684 next();
6685 } else if (tok == '.' || tok == TOK_ARROW) {
6686 /* field */
6687 if (tok == TOK_ARROW)
6688 indir();
6689 test_lvalue();
6690 gaddrof();
6691 next();
6692 /* expect pointer on structure */
6693 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
6694 expect("struct or union");
6695 s = vtop->type.ref;
6696 /* find field */
6697 tok |= SYM_FIELD;
6698 while ((s = s->next) != NULL) {
6699 if (s->v == tok)
6700 break;
6702 if (!s)
6703 error("field not found");
6704 /* add field offset to pointer */
6705 vtop->type = char_pointer_type; /* change type to 'char *' */
6706 vpushi(s->c);
6707 gen_op('+');
6708 /* change type to field type, and set to lvalue */
6709 vtop->type = s->type;
6710 /* an array is never an lvalue */
6711 if (!(vtop->type.t & VT_ARRAY)) {
6712 vtop->r |= lvalue_type(vtop->type.t);
6713 /* if bound checking, the referenced pointer must be checked */
6714 if (do_bounds_check)
6715 vtop->r |= VT_MUSTBOUND;
6717 next();
6718 } else if (tok == '[') {
6719 next();
6720 gexpr();
6721 gen_op('+');
6722 indir();
6723 skip(']');
6724 } else if (tok == '(') {
6725 SValue ret;
6726 Sym *sa;
6728 /* function call */
6729 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
6730 /* pointer test (no array accepted) */
6731 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
6732 vtop->type = *pointed_type(&vtop->type);
6733 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
6734 goto error_func;
6735 } else {
6736 error_func:
6737 expect("function pointer");
6739 } else {
6740 vtop->r &= ~VT_LVAL; /* no lvalue */
6742 /* get return type */
6743 s = vtop->type.ref;
6744 if (!nocode_wanted) {
6745 save_regs(0); /* save used temporary registers */
6746 gfunc_start(&gf, s->r);
6748 next();
6749 sa = s->next; /* first parameter */
6750 #ifdef INVERT_FUNC_PARAMS
6752 int parlevel;
6753 Sym *args, *s1;
6754 ParseState saved_parse_state;
6755 TokenString str;
6757 /* read each argument and store it on a stack */
6758 args = NULL;
6759 if (tok != ')') {
6760 for(;;) {
6761 tok_str_new(&str);
6762 parlevel = 0;
6763 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
6764 tok != TOK_EOF) {
6765 if (tok == '(')
6766 parlevel++;
6767 else if (tok == ')')
6768 parlevel--;
6769 tok_str_add_tok(&str);
6770 next();
6772 tok_str_add(&str, -1); /* end of file added */
6773 tok_str_add(&str, 0);
6774 s1 = sym_push2(&args, 0, 0, (int)str.str);
6775 s1->next = sa; /* add reference to argument */
6776 if (sa)
6777 sa = sa->next;
6778 if (tok == ')')
6779 break;
6780 skip(',');
6784 /* now generate code in reverse order by reading the stack */
6785 save_parse_state(&saved_parse_state);
6786 while (args) {
6787 macro_ptr = (int *)args->c;
6788 next();
6789 expr_eq();
6790 if (tok != -1)
6791 expect("',' or ')'");
6792 gfunc_param_typed(&gf, s, args->next);
6793 s1 = args->prev;
6794 tok_str_free((int *)args->c);
6795 tcc_free(args);
6796 args = s1;
6798 restore_parse_state(&saved_parse_state);
6800 #endif
6801 /* compute first implicit argument if a structure is returned */
6802 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6803 /* get some space for the returned structure */
6804 size = type_size(&s->type, &align);
6805 loc = (loc - size) & -align;
6806 ret.type = s->type;
6807 ret.r = VT_LOCAL | VT_LVAL;
6808 /* pass it as 'int' to avoid structure arg passing
6809 problems */
6810 vseti(VT_LOCAL, loc);
6811 ret.c = vtop->c;
6812 if (!nocode_wanted)
6813 gfunc_param(&gf);
6814 else
6815 vtop--;
6816 } else {
6817 ret.type = s->type;
6818 ret.r2 = VT_CONST;
6819 /* return in register */
6820 if (is_float(ret.type.t)) {
6821 ret.r = REG_FRET;
6822 } else {
6823 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
6824 ret.r2 = REG_LRET;
6825 ret.r = REG_IRET;
6827 ret.c.i = 0;
6829 #ifndef INVERT_FUNC_PARAMS
6830 if (tok != ')') {
6831 for(;;) {
6832 expr_eq();
6833 gfunc_param_typed(&gf, s, sa);
6834 if (sa)
6835 sa = sa->next;
6836 if (tok == ')')
6837 break;
6838 skip(',');
6841 #endif
6842 if (sa)
6843 error("too few arguments to function");
6844 skip(')');
6845 if (!nocode_wanted)
6846 gfunc_call(&gf);
6847 else
6848 vtop--;
6849 /* return value */
6850 vsetc(&ret.type, ret.r, &ret.c);
6851 vtop->r2 = ret.r2;
6852 } else {
6853 break;
6858 static void uneq(void)
6860 int t;
6862 unary();
6863 if (tok == '=' ||
6864 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
6865 tok == TOK_A_XOR || tok == TOK_A_OR ||
6866 tok == TOK_A_SHL || tok == TOK_A_SAR) {
6867 test_lvalue();
6868 t = tok;
6869 next();
6870 if (t == '=') {
6871 expr_eq();
6872 } else {
6873 vdup();
6874 expr_eq();
6875 gen_op(t & 0x7f);
6877 vstore();
6881 static void expr_prod(void)
6883 int t;
6885 uneq();
6886 while (tok == '*' || tok == '/' || tok == '%') {
6887 t = tok;
6888 next();
6889 uneq();
6890 gen_op(t);
6894 static void expr_sum(void)
6896 int t;
6898 expr_prod();
6899 while (tok == '+' || tok == '-') {
6900 t = tok;
6901 next();
6902 expr_prod();
6903 gen_op(t);
6907 static void expr_shift(void)
6909 int t;
6911 expr_sum();
6912 while (tok == TOK_SHL || tok == TOK_SAR) {
6913 t = tok;
6914 next();
6915 expr_sum();
6916 gen_op(t);
6920 static void expr_cmp(void)
6922 int t;
6924 expr_shift();
6925 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
6926 tok == TOK_ULT || tok == TOK_UGE) {
6927 t = tok;
6928 next();
6929 expr_shift();
6930 gen_op(t);
6934 static void expr_cmpeq(void)
6936 int t;
6938 expr_cmp();
6939 while (tok == TOK_EQ || tok == TOK_NE) {
6940 t = tok;
6941 next();
6942 expr_cmp();
6943 gen_op(t);
6947 static void expr_and(void)
6949 expr_cmpeq();
6950 while (tok == '&') {
6951 next();
6952 expr_cmpeq();
6953 gen_op('&');
6957 static void expr_xor(void)
6959 expr_and();
6960 while (tok == '^') {
6961 next();
6962 expr_and();
6963 gen_op('^');
6967 static void expr_or(void)
6969 expr_xor();
6970 while (tok == '|') {
6971 next();
6972 expr_xor();
6973 gen_op('|');
6977 /* XXX: fix this mess */
6978 static void expr_land_const(void)
6980 expr_or();
6981 while (tok == TOK_LAND) {
6982 next();
6983 expr_or();
6984 gen_op(TOK_LAND);
6988 /* XXX: fix this mess */
6989 static void expr_lor_const(void)
6991 expr_land_const();
6992 while (tok == TOK_LOR) {
6993 next();
6994 expr_land_const();
6995 gen_op(TOK_LOR);
6999 /* only used if non constant */
7000 static void expr_land(void)
7002 int t;
7004 expr_or();
7005 if (tok == TOK_LAND) {
7006 t = 0;
7007 for(;;) {
7008 t = gtst(1, t);
7009 if (tok != TOK_LAND) {
7010 vseti(VT_JMPI, t);
7011 break;
7013 next();
7014 expr_or();
7019 static void expr_lor(void)
7021 int t;
7023 expr_land();
7024 if (tok == TOK_LOR) {
7025 t = 0;
7026 for(;;) {
7027 t = gtst(0, t);
7028 if (tok != TOK_LOR) {
7029 vseti(VT_JMP, t);
7030 break;
7032 next();
7033 expr_land();
7038 /* XXX: better constant handling */
7039 static void expr_eq(void)
7041 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
7042 SValue sv;
7043 CType type, type1, type2;
7045 if (const_wanted) {
7046 int c1, c;
7047 expr_lor_const();
7048 if (tok == '?') {
7049 c = vtop->c.i;
7050 vpop();
7051 next();
7052 if (tok == ':' && gnu_ext) {
7053 c1 = c;
7054 } else {
7055 gexpr();
7056 c1 = vtop->c.i;
7057 vpop();
7059 skip(':');
7060 expr_eq();
7061 if (c)
7062 vtop->c.i = c1;
7064 } else {
7065 expr_lor();
7066 if (tok == '?') {
7067 next();
7068 if (vtop != vstack) {
7069 /* needed to avoid having different registers saved in
7070 each branch */
7071 if (is_float(vtop->type.t))
7072 rc = RC_FLOAT;
7073 else
7074 rc = RC_INT;
7075 gv(rc);
7076 save_regs(1);
7078 if (tok == ':' && gnu_ext) {
7079 gv_dup();
7080 tt = gtst(1, 0);
7081 } else {
7082 tt = gtst(1, 0);
7083 gexpr();
7085 type1 = vtop->type;
7086 sv = *vtop; /* save value to handle it later */
7087 vtop--; /* no vpop so that FP stack is not flushed */
7088 skip(':');
7089 u = gjmp(0);
7090 gsym(tt);
7091 expr_eq();
7092 type2 = vtop->type;
7094 t1 = type1.t;
7095 bt1 = t1 & VT_BTYPE;
7096 t2 = type2.t;
7097 bt2 = t2 & VT_BTYPE;
7098 /* cast operands to correct type according to ISOC rules */
7099 if (is_float(bt1) || is_float(bt2)) {
7100 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
7101 type.t = VT_LDOUBLE;
7102 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
7103 type.t = VT_DOUBLE;
7104 } else {
7105 type.t = VT_FLOAT;
7107 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
7108 /* cast to biggest op */
7109 type.t = VT_LLONG;
7110 /* convert to unsigned if it does not fit in a long long */
7111 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
7112 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
7113 type.t |= VT_UNSIGNED;
7114 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
7115 /* XXX: test pointer compatibility */
7116 type = type1;
7117 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
7118 /* XXX: test structure compatibility */
7119 type = type1;
7120 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
7121 /* NOTE: as an extension, we accept void on only one side */
7122 type.t = VT_VOID;
7123 } else {
7124 /* integer operations */
7125 type.t = VT_INT;
7126 /* convert to unsigned if it does not fit in an integer */
7127 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
7128 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
7129 type.t |= VT_UNSIGNED;
7132 /* now we convert second operand */
7133 gen_cast(&type);
7134 rc = RC_INT;
7135 if (is_float(type.t)) {
7136 rc = RC_FLOAT;
7137 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
7138 /* for long longs, we use fixed registers to avoid having
7139 to handle a complicated move */
7140 rc = RC_IRET;
7143 r2 = gv(rc);
7144 /* this is horrible, but we must also convert first
7145 operand */
7146 tt = gjmp(0);
7147 gsym(u);
7148 /* put again first value and cast it */
7149 *vtop = sv;
7150 gen_cast(&type);
7151 r1 = gv(rc);
7152 move_reg(r2, r1);
7153 vtop->r = r2;
7154 gsym(tt);
7159 static void gexpr(void)
7161 while (1) {
7162 expr_eq();
7163 if (tok != ',')
7164 break;
7165 vpop();
7166 next();
7170 /* parse an expression and return its type without any side effect. */
7171 static void expr_type(CType *type)
7173 int a;
7175 a = nocode_wanted;
7176 nocode_wanted = 1;
7177 gexpr();
7178 *type = vtop->type;
7179 vpop();
7180 nocode_wanted = a;
7183 /* parse a unary expression and return its type without any side
7184 effect. */
7185 static void unary_type(CType *type)
7187 int a;
7189 a = nocode_wanted;
7190 nocode_wanted = 1;
7191 unary();
7192 *type = vtop->type;
7193 vpop();
7194 nocode_wanted = a;
7197 /* parse a constant expression and return value in vtop. */
7198 static void expr_const1(void)
7200 int a;
7201 a = const_wanted;
7202 const_wanted = 1;
7203 expr_eq();
7204 const_wanted = a;
7207 /* parse an integer constant and return its value. */
7208 static int expr_const(void)
7210 int c;
7211 expr_const1();
7212 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
7213 expect("constant expression");
7214 c = vtop->c.i;
7215 vpop();
7216 return c;
7219 /* return the label token if current token is a label, otherwise
7220 return zero */
7221 static int is_label(void)
7223 int last_tok;
7225 /* fast test first */
7226 if (tok < TOK_UIDENT)
7227 return 0;
7228 /* no need to save tokc because tok is an identifier */
7229 last_tok = tok;
7230 next();
7231 if (tok == ':') {
7232 next();
7233 return last_tok;
7234 } else {
7235 unget_tok(last_tok);
7236 return 0;
7240 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
7241 int case_reg, int is_expr)
7243 int a, b, c, d;
7244 Sym *s;
7246 /* generate line number info */
7247 if (do_debug &&
7248 (last_line_num != file->line_num || last_ind != ind)) {
7249 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
7250 last_ind = ind;
7251 last_line_num = file->line_num;
7254 if (is_expr) {
7255 /* default return value is (void) */
7256 vpushi(0);
7257 vtop->type.t = VT_VOID;
7260 if (tok == TOK_IF) {
7261 /* if test */
7262 next();
7263 skip('(');
7264 gexpr();
7265 skip(')');
7266 a = gtst(1, 0);
7267 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7268 c = tok;
7269 if (c == TOK_ELSE) {
7270 next();
7271 d = gjmp(0);
7272 gsym(a);
7273 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7274 gsym(d); /* patch else jmp */
7275 } else
7276 gsym(a);
7277 } else if (tok == TOK_WHILE) {
7278 next();
7279 d = ind;
7280 skip('(');
7281 gexpr();
7282 skip(')');
7283 a = gtst(1, 0);
7284 b = 0;
7285 block(&a, &b, case_sym, def_sym, case_reg, 0);
7286 gjmp_addr(d);
7287 gsym(a);
7288 gsym_addr(b, d);
7289 } else if (tok == '{') {
7290 Sym *llabel;
7292 next();
7293 /* record local declaration stack position */
7294 s = local_stack;
7295 llabel = local_label_stack;
7296 /* handle local labels declarations */
7297 if (tok == TOK_LABEL) {
7298 next();
7299 for(;;) {
7300 if (tok < TOK_UIDENT)
7301 expect("label identifier");
7302 label_push(&local_label_stack, tok, LABEL_DECLARED);
7303 next();
7304 if (tok == ',') {
7305 next();
7306 } else {
7307 skip(';');
7308 break;
7312 while (tok != '}') {
7313 decl(VT_LOCAL);
7314 if (tok != '}') {
7315 if (is_expr)
7316 vpop();
7317 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
7320 /* pop locally defined labels */
7321 label_pop(&local_label_stack, llabel);
7322 /* pop locally defined symbols */
7323 sym_pop(&local_stack, s);
7324 next();
7325 } else if (tok == TOK_RETURN) {
7326 next();
7327 if (tok != ';') {
7328 gexpr();
7329 gen_assign_cast(&func_vt);
7330 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
7331 CType type;
7332 /* if returning structure, must copy it to implicit
7333 first pointer arg location */
7334 type = func_vt;
7335 mk_pointer(&type);
7336 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
7337 indir();
7338 vswap();
7339 /* copy structure value to pointer */
7340 vstore();
7341 } else if (is_float(func_vt.t)) {
7342 gv(RC_FRET);
7343 } else {
7344 gv(RC_IRET);
7346 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
7348 skip(';');
7349 rsym = gjmp(rsym); /* jmp */
7350 } else if (tok == TOK_BREAK) {
7351 /* compute jump */
7352 if (!bsym)
7353 error("cannot break");
7354 *bsym = gjmp(*bsym);
7355 next();
7356 skip(';');
7357 } else if (tok == TOK_CONTINUE) {
7358 /* compute jump */
7359 if (!csym)
7360 error("cannot continue");
7361 *csym = gjmp(*csym);
7362 next();
7363 skip(';');
7364 } else if (tok == TOK_FOR) {
7365 int e;
7366 next();
7367 skip('(');
7368 if (tok != ';') {
7369 gexpr();
7370 vpop();
7372 skip(';');
7373 d = ind;
7374 c = ind;
7375 a = 0;
7376 b = 0;
7377 if (tok != ';') {
7378 gexpr();
7379 a = gtst(1, 0);
7381 skip(';');
7382 if (tok != ')') {
7383 e = gjmp(0);
7384 c = ind;
7385 gexpr();
7386 vpop();
7387 gjmp_addr(d);
7388 gsym(e);
7390 skip(')');
7391 block(&a, &b, case_sym, def_sym, case_reg, 0);
7392 gjmp_addr(c);
7393 gsym(a);
7394 gsym_addr(b, c);
7395 } else
7396 if (tok == TOK_DO) {
7397 next();
7398 a = 0;
7399 b = 0;
7400 d = ind;
7401 block(&a, &b, case_sym, def_sym, case_reg, 0);
7402 skip(TOK_WHILE);
7403 skip('(');
7404 gsym(b);
7405 gexpr();
7406 c = gtst(0, 0);
7407 gsym_addr(c, d);
7408 skip(')');
7409 gsym(a);
7410 skip(';');
7411 } else
7412 if (tok == TOK_SWITCH) {
7413 next();
7414 skip('(');
7415 gexpr();
7416 /* XXX: other types than integer */
7417 case_reg = gv(RC_INT);
7418 vpop();
7419 skip(')');
7420 a = 0;
7421 b = gjmp(0); /* jump to first case */
7422 c = 0;
7423 block(&a, csym, &b, &c, case_reg, 0);
7424 /* if no default, jmp after switch */
7425 if (c == 0)
7426 c = ind;
7427 /* default label */
7428 gsym_addr(b, c);
7429 /* break label */
7430 gsym(a);
7431 } else
7432 if (tok == TOK_CASE) {
7433 int v1, v2;
7434 if (!case_sym)
7435 expect("switch");
7436 next();
7437 v1 = expr_const();
7438 v2 = v1;
7439 if (gnu_ext && tok == TOK_DOTS) {
7440 next();
7441 v2 = expr_const();
7442 if (v2 < v1)
7443 warning("empty case range");
7445 /* since a case is like a label, we must skip it with a jmp */
7446 b = gjmp(0);
7447 gsym(*case_sym);
7448 vseti(case_reg, 0);
7449 vpushi(v1);
7450 if (v1 == v2) {
7451 gen_op(TOK_EQ);
7452 *case_sym = gtst(1, 0);
7453 } else {
7454 gen_op(TOK_GE);
7455 *case_sym = gtst(1, 0);
7456 vseti(case_reg, 0);
7457 vpushi(v2);
7458 gen_op(TOK_LE);
7459 *case_sym = gtst(1, *case_sym);
7461 gsym(b);
7462 skip(':');
7463 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7464 } else
7465 if (tok == TOK_DEFAULT) {
7466 next();
7467 skip(':');
7468 if (!def_sym)
7469 expect("switch");
7470 if (*def_sym)
7471 error("too many 'default'");
7472 *def_sym = ind;
7473 block(bsym, csym, case_sym, def_sym, case_reg, 0);
7474 } else
7475 if (tok == TOK_GOTO) {
7476 next();
7477 if (tok == '*' && gnu_ext) {
7478 /* computed goto */
7479 next();
7480 gexpr();
7481 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
7482 expect("pointer");
7483 ggoto();
7484 } else if (tok >= TOK_UIDENT) {
7485 s = label_find(tok);
7486 /* put forward definition if needed */
7487 if (!s) {
7488 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
7489 } else {
7490 if (s->r == LABEL_DECLARED)
7491 s->r = LABEL_FORWARD;
7493 /* label already defined */
7494 if (s->r & LABEL_FORWARD)
7495 s->next = (void *)gjmp((long)s->next);
7496 else
7497 gjmp_addr((long)s->next);
7498 next();
7499 } else {
7500 expect("label identifier");
7502 skip(';');
7503 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
7504 asm_instr();
7505 } else {
7506 b = is_label();
7507 if (b) {
7508 /* label case */
7509 s = label_find(b);
7510 if (s) {
7511 if (s->r == LABEL_DEFINED)
7512 error("duplicate label '%s'", get_tok_str(s->v, NULL));
7513 gsym((long)s->next);
7514 s->r = LABEL_DEFINED;
7515 } else {
7516 s = label_push(&global_label_stack, b, LABEL_DEFINED);
7518 s->next = (void *)ind;
7519 /* we accept this, but it is a mistake */
7520 if (tok == '}') {
7521 warning("deprecated use of label at end of compound statement");
7522 } else {
7523 if (is_expr)
7524 vpop();
7525 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
7527 } else {
7528 /* expression case */
7529 if (tok != ';') {
7530 if (is_expr) {
7531 vpop();
7532 gexpr();
7533 } else {
7534 gexpr();
7535 vpop();
7538 skip(';');
7543 /* t is the array or struct type. c is the array or struct
7544 address. cur_index/cur_field is the pointer to the current
7545 value. 'size_only' is true if only size info is needed (only used
7546 in arrays) */
7547 static void decl_designator(CType *type, Section *sec, unsigned long c,
7548 int *cur_index, Sym **cur_field,
7549 int size_only)
7551 Sym *s, *f;
7552 int notfirst, index, index_last, align, l, nb_elems, elem_size;
7553 CType type1;
7555 notfirst = 0;
7556 elem_size = 0;
7557 nb_elems = 1;
7558 if (gnu_ext && (l = is_label()) != 0)
7559 goto struct_field;
7560 while (tok == '[' || tok == '.') {
7561 if (tok == '[') {
7562 if (!(type->t & VT_ARRAY))
7563 expect("array type");
7564 s = type->ref;
7565 next();
7566 index = expr_const();
7567 if (index < 0 || (s->c >= 0 && index >= s->c))
7568 expect("invalid index");
7569 if (tok == TOK_DOTS && gnu_ext) {
7570 next();
7571 index_last = expr_const();
7572 if (index_last < 0 ||
7573 (s->c >= 0 && index_last >= s->c) ||
7574 index_last < index)
7575 expect("invalid index");
7576 } else {
7577 index_last = index;
7579 skip(']');
7580 if (!notfirst)
7581 *cur_index = index_last;
7582 type = pointed_type(type);
7583 elem_size = type_size(type, &align);
7584 c += index * elem_size;
7585 /* NOTE: we only support ranges for last designator */
7586 nb_elems = index_last - index + 1;
7587 if (nb_elems != 1) {
7588 notfirst = 1;
7589 break;
7591 } else {
7592 next();
7593 l = tok;
7594 next();
7595 struct_field:
7596 if ((type->t & VT_BTYPE) != VT_STRUCT)
7597 expect("struct/union type");
7598 s = type->ref;
7599 l |= SYM_FIELD;
7600 f = s->next;
7601 while (f) {
7602 if (f->v == l)
7603 break;
7604 f = f->next;
7606 if (!f)
7607 expect("field");
7608 if (!notfirst)
7609 *cur_field = f;
7610 /* XXX: fix this mess by using explicit storage field */
7611 type1 = f->type;
7612 type1.t |= (type->t & ~VT_TYPE);
7613 type = &type1;
7614 c += f->c;
7616 notfirst = 1;
7618 if (notfirst) {
7619 if (tok == '=') {
7620 next();
7621 } else {
7622 if (!gnu_ext)
7623 expect("=");
7625 } else {
7626 if (type->t & VT_ARRAY) {
7627 index = *cur_index;
7628 type = pointed_type(type);
7629 c += index * type_size(type, &align);
7630 } else {
7631 f = *cur_field;
7632 if (!f)
7633 error("too many field init");
7634 /* XXX: fix this mess by using explicit storage field */
7635 type1 = f->type;
7636 type1.t |= (type->t & ~VT_TYPE);
7637 type = &type1;
7638 c += f->c;
7641 decl_initializer(type, sec, c, 0, size_only);
7643 /* XXX: make it more general */
7644 if (!size_only && nb_elems > 1) {
7645 unsigned long c_end;
7646 uint8_t *src, *dst;
7647 int i;
7649 if (!sec)
7650 error("range init not supported yet for dynamic storage");
7651 c_end = c + nb_elems * elem_size;
7652 if (c_end > sec->data_allocated)
7653 section_realloc(sec, c_end);
7654 src = sec->data + c;
7655 dst = src;
7656 for(i = 1; i < nb_elems; i++) {
7657 dst += elem_size;
7658 memcpy(dst, src, elem_size);
7663 #define EXPR_VAL 0
7664 #define EXPR_CONST 1
7665 #define EXPR_ANY 2
7667 /* store a value or an expression directly in global data or in local array */
7668 static void init_putv(CType *type, Section *sec, unsigned long c,
7669 int v, int expr_type)
7671 int saved_global_expr, bt, bit_pos, bit_size;
7672 void *ptr;
7673 unsigned long long bit_mask;
7675 switch(expr_type) {
7676 case EXPR_VAL:
7677 vpushi(v);
7678 break;
7679 case EXPR_CONST:
7680 /* compound literals must be allocated globally in this case */
7681 saved_global_expr = global_expr;
7682 global_expr = 1;
7683 expr_const1();
7684 global_expr = saved_global_expr;
7685 /* NOTE: symbols are accepted */
7686 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
7687 error("initializer element is not constant");
7688 break;
7689 case EXPR_ANY:
7690 expr_eq();
7691 break;
7694 if (sec) {
7695 /* XXX: not portable */
7696 /* XXX: generate error if incorrect relocation */
7697 gen_assign_cast(type);
7698 bt = type->t & VT_BTYPE;
7699 ptr = sec->data + c;
7700 /* XXX: make code faster ? */
7701 if (!(type->t & VT_BITFIELD)) {
7702 bit_pos = 0;
7703 bit_size = 32;
7704 bit_mask = -1LL;
7705 } else {
7706 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
7707 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
7708 bit_mask = (1LL << bit_size) - 1;
7710 if ((vtop->r & VT_SYM) &&
7711 (bt == VT_BYTE ||
7712 bt == VT_SHORT ||
7713 bt == VT_DOUBLE ||
7714 bt == VT_LDOUBLE ||
7715 bt == VT_LLONG ||
7716 (bt == VT_INT && bit_size != 32)))
7717 error("initializer element is not computable at load time");
7718 switch(bt) {
7719 case VT_BYTE:
7720 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7721 break;
7722 case VT_SHORT:
7723 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7724 break;
7725 case VT_DOUBLE:
7726 *(double *)ptr = vtop->c.d;
7727 break;
7728 case VT_LDOUBLE:
7729 *(long double *)ptr = vtop->c.ld;
7730 break;
7731 case VT_LLONG:
7732 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
7733 break;
7734 default:
7735 if (vtop->r & VT_SYM) {
7736 greloc(sec, vtop->sym, c, R_DATA_32);
7738 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
7739 break;
7741 vtop--;
7742 } else {
7743 vset(type, VT_LOCAL, c);
7744 vswap();
7745 vstore();
7746 vpop();
7750 /* put zeros for variable based init */
7751 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
7753 GFuncContext gf;
7755 if (sec) {
7756 /* nothing to do because globals are already set to zero */
7757 } else {
7758 gfunc_start(&gf, FUNC_CDECL);
7759 vpushi(size);
7760 gfunc_param(&gf);
7761 vpushi(0);
7762 gfunc_param(&gf);
7763 vseti(VT_LOCAL, c);
7764 gfunc_param(&gf);
7765 vpush_global_sym(&func_old_type, TOK_memset);
7766 gfunc_call(&gf);
7770 /* 't' contains the type and storage info. 'c' is the offset of the
7771 object in section 'sec'. If 'sec' is NULL, it means stack based
7772 allocation. 'first' is true if array '{' must be read (multi
7773 dimension implicit array init handling). 'size_only' is true if
7774 size only evaluation is wanted (only for arrays). */
7775 static void decl_initializer(CType *type, Section *sec, unsigned long c,
7776 int first, int size_only)
7778 int index, array_length, n, no_oblock, nb, parlevel, i;
7779 int size1, align1, expr_type;
7780 Sym *s, *f;
7781 CType *t1;
7783 if (type->t & VT_ARRAY) {
7784 s = type->ref;
7785 n = s->c;
7786 array_length = 0;
7787 t1 = pointed_type(type);
7788 size1 = type_size(t1, &align1);
7790 no_oblock = 1;
7791 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
7792 tok == '{') {
7793 skip('{');
7794 no_oblock = 0;
7797 /* only parse strings here if correct type (otherwise: handle
7798 them as ((w)char *) expressions */
7799 if ((tok == TOK_LSTR &&
7800 (t1->t & VT_BTYPE) == VT_INT) ||
7801 (tok == TOK_STR &&
7802 (t1->t & VT_BTYPE) == VT_BYTE)) {
7803 while (tok == TOK_STR || tok == TOK_LSTR) {
7804 int cstr_len, ch;
7805 CString *cstr;
7807 cstr = tokc.cstr;
7808 /* compute maximum number of chars wanted */
7809 if (tok == TOK_STR)
7810 cstr_len = cstr->size;
7811 else
7812 cstr_len = cstr->size / sizeof(int);
7813 cstr_len--;
7814 nb = cstr_len;
7815 if (n >= 0 && nb > (n - array_length))
7816 nb = n - array_length;
7817 if (!size_only) {
7818 if (cstr_len > nb)
7819 warning("initializer-string for array is too long");
7820 /* in order to go faster for common case (char
7821 string in global variable, we handle it
7822 specifically */
7823 if (sec && tok == TOK_STR && size1 == 1) {
7824 memcpy(sec->data + c + array_length, cstr->data, nb);
7825 } else {
7826 for(i=0;i<nb;i++) {
7827 if (tok == TOK_STR)
7828 ch = ((unsigned char *)cstr->data)[i];
7829 else
7830 ch = ((int *)cstr->data)[i];
7831 init_putv(t1, sec, c + (array_length + i) * size1,
7832 ch, EXPR_VAL);
7836 array_length += nb;
7837 next();
7839 /* only add trailing zero if enough storage (no
7840 warning in this case since it is standard) */
7841 if (n < 0 || array_length < n) {
7842 if (!size_only) {
7843 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
7845 array_length++;
7847 } else {
7848 index = 0;
7849 while (tok != '}') {
7850 decl_designator(type, sec, c, &index, NULL, size_only);
7851 if (n >= 0 && index >= n)
7852 error("index too large");
7853 /* must put zero in holes (note that doing it that way
7854 ensures that it even works with designators) */
7855 if (!size_only && array_length < index) {
7856 init_putz(t1, sec, c + array_length * size1,
7857 (index - array_length) * size1);
7859 index++;
7860 if (index > array_length)
7861 array_length = index;
7862 /* special test for multi dimensional arrays (may not
7863 be strictly correct if designators are used at the
7864 same time) */
7865 if (index >= n && no_oblock)
7866 break;
7867 if (tok == '}')
7868 break;
7869 skip(',');
7872 if (!no_oblock)
7873 skip('}');
7874 /* put zeros at the end */
7875 if (!size_only && n >= 0 && array_length < n) {
7876 init_putz(t1, sec, c + array_length * size1,
7877 (n - array_length) * size1);
7879 /* patch type size if needed */
7880 if (n < 0)
7881 s->c = array_length;
7882 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
7883 (sec || !first || tok == '{')) {
7884 int par_count;
7886 /* NOTE: the previous test is a specific case for automatic
7887 struct/union init */
7888 /* XXX: union needs only one init */
7890 /* XXX: this test is incorrect for local initializers
7891 beginning with ( without {. It would be much more difficult
7892 to do it correctly (ideally, the expression parser should
7893 be used in all cases) */
7894 par_count = 0;
7895 if (tok == '(') {
7896 AttributeDef ad1;
7897 CType type1;
7898 next();
7899 while (tok == '(') {
7900 par_count++;
7901 next();
7903 if (!parse_btype(&type1, &ad1))
7904 expect("cast");
7905 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
7906 if (!is_compatible_types(type, &type1))
7907 error("invalid type for cast");
7908 skip(')');
7910 no_oblock = 1;
7911 if (first || tok == '{') {
7912 skip('{');
7913 no_oblock = 0;
7915 s = type->ref;
7916 f = s->next;
7917 array_length = 0;
7918 index = 0;
7919 n = s->c;
7920 while (tok != '}') {
7921 decl_designator(type, sec, c, NULL, &f, size_only);
7922 index = f->c;
7923 if (!size_only && array_length < index) {
7924 init_putz(type, sec, c + array_length,
7925 index - array_length);
7927 index = index + type_size(&f->type, &align1);
7928 if (index > array_length)
7929 array_length = index;
7930 f = f->next;
7931 if (no_oblock && f == NULL)
7932 break;
7933 if (tok == '}')
7934 break;
7935 skip(',');
7937 /* put zeros at the end */
7938 if (!size_only && array_length < n) {
7939 init_putz(type, sec, c + array_length,
7940 n - array_length);
7942 if (!no_oblock)
7943 skip('}');
7944 while (par_count) {
7945 skip(')');
7946 par_count--;
7948 } else if (tok == '{') {
7949 next();
7950 decl_initializer(type, sec, c, first, size_only);
7951 skip('}');
7952 } else if (size_only) {
7953 /* just skip expression */
7954 parlevel = 0;
7955 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
7956 tok != -1) {
7957 if (tok == '(')
7958 parlevel++;
7959 else if (tok == ')')
7960 parlevel--;
7961 next();
7963 } else {
7964 /* currently, we always use constant expression for globals
7965 (may change for scripting case) */
7966 expr_type = EXPR_CONST;
7967 if (!sec)
7968 expr_type = EXPR_ANY;
7969 init_putv(type, sec, c, 0, expr_type);
7973 /* parse an initializer for type 't' if 'has_init' is non zero, and
7974 allocate space in local or global data space ('r' is either
7975 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7976 variable 'v' of scope 'scope' is declared before initializers are
7977 parsed. If 'v' is zero, then a reference to the new object is put
7978 in the value stack. If 'has_init' is 2, a special parsing is done
7979 to handle string constants. */
7980 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
7981 int has_init, int v, int scope)
7983 int size, align, addr, data_offset;
7984 int level;
7985 ParseState saved_parse_state;
7986 TokenString init_str;
7987 Section *sec;
7989 size = type_size(type, &align);
7990 /* If unknown size, we must evaluate it before
7991 evaluating initializers because
7992 initializers can generate global data too
7993 (e.g. string pointers or ISOC99 compound
7994 literals). It also simplifies local
7995 initializers handling */
7996 tok_str_new(&init_str);
7997 if (size < 0) {
7998 if (!has_init)
7999 error("unknown type size");
8000 /* get all init string */
8001 if (has_init == 2) {
8002 /* only get strings */
8003 while (tok == TOK_STR || tok == TOK_LSTR) {
8004 tok_str_add_tok(&init_str);
8005 next();
8007 } else {
8008 level = 0;
8009 while (level > 0 || (tok != ',' && tok != ';')) {
8010 if (tok < 0)
8011 error("unexpected end of file in initializer");
8012 tok_str_add_tok(&init_str);
8013 if (tok == '{')
8014 level++;
8015 else if (tok == '}') {
8016 if (level == 0)
8017 break;
8018 level--;
8020 next();
8023 tok_str_add(&init_str, -1);
8024 tok_str_add(&init_str, 0);
8026 /* compute size */
8027 save_parse_state(&saved_parse_state);
8029 macro_ptr = init_str.str;
8030 next();
8031 decl_initializer(type, NULL, 0, 1, 1);
8032 /* prepare second initializer parsing */
8033 macro_ptr = init_str.str;
8034 next();
8036 /* if still unknown size, error */
8037 size = type_size(type, &align);
8038 if (size < 0)
8039 error("unknown type size");
8041 /* take into account specified alignment if bigger */
8042 if (ad->aligned > align)
8043 align = ad->aligned;
8044 if ((r & VT_VALMASK) == VT_LOCAL) {
8045 sec = NULL;
8046 if (do_bounds_check && (type->t & VT_ARRAY))
8047 loc--;
8048 loc = (loc - size) & -align;
8049 addr = loc;
8050 /* handles bounds */
8051 /* XXX: currently, since we do only one pass, we cannot track
8052 '&' operators, so we add only arrays */
8053 if (do_bounds_check && (type->t & VT_ARRAY)) {
8054 unsigned long *bounds_ptr;
8055 /* add padding between regions */
8056 loc--;
8057 /* then add local bound info */
8058 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
8059 bounds_ptr[0] = addr;
8060 bounds_ptr[1] = size;
8062 if (v) {
8063 /* local variable */
8064 sym_push(v, type, r, addr);
8065 } else {
8066 /* push local reference */
8067 vset(type, r, addr);
8069 } else {
8070 Sym *sym;
8072 sym = NULL;
8073 if (v && scope == VT_CONST) {
8074 /* see if the symbol was already defined */
8075 sym = sym_find(v);
8076 if (sym) {
8077 if (!is_compatible_types(&sym->type, type))
8078 error("incompatible types for redefinition of '%s'",
8079 get_tok_str(v, NULL));
8080 if (sym->type.t & VT_EXTERN) {
8081 /* if the variable is extern, it was not allocated */
8082 sym->type.t &= ~VT_EXTERN;
8083 } else {
8084 /* we accept several definitions of the same
8085 global variable. this is tricky, because we
8086 must play with the SHN_COMMON type of the symbol */
8087 /* XXX: should check if the variable was already
8088 initialized. It is incorrect to initialized it
8089 twice */
8090 /* no init data, we won't add more to the symbol */
8091 if (!has_init)
8092 goto no_alloc;
8097 /* allocate symbol in corresponding section */
8098 sec = ad->section;
8099 if (!sec) {
8100 if (has_init)
8101 sec = data_section;
8103 if (sec) {
8104 data_offset = sec->data_offset;
8105 data_offset = (data_offset + align - 1) & -align;
8106 addr = data_offset;
8107 /* very important to increment global pointer at this time
8108 because initializers themselves can create new initializers */
8109 data_offset += size;
8110 /* add padding if bound check */
8111 if (do_bounds_check)
8112 data_offset++;
8113 sec->data_offset = data_offset;
8114 /* allocate section space to put the data */
8115 if (sec->sh_type != SHT_NOBITS &&
8116 data_offset > sec->data_allocated)
8117 section_realloc(sec, data_offset);
8118 } else {
8119 addr = 0; /* avoid warning */
8122 if (v) {
8123 if (scope == VT_CONST) {
8124 if (!sym)
8125 goto do_def;
8126 } else {
8127 do_def:
8128 sym = sym_push(v, type, r | VT_SYM, 0);
8130 /* update symbol definition */
8131 if (sec) {
8132 put_extern_sym(sym, sec, addr, size);
8133 } else {
8134 Elf32_Sym *esym;
8135 /* put a common area */
8136 put_extern_sym(sym, NULL, align, size);
8137 /* XXX: find a nicer way */
8138 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
8139 esym->st_shndx = SHN_COMMON;
8141 } else {
8142 CValue cval;
8144 /* push global reference */
8145 sym = get_sym_ref(type, sec, addr, size);
8146 cval.ul = 0;
8147 vsetc(type, VT_CONST | VT_SYM, &cval);
8148 vtop->sym = sym;
8151 /* handles bounds now because the symbol must be defined
8152 before for the relocation */
8153 if (do_bounds_check) {
8154 unsigned long *bounds_ptr;
8156 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
8157 /* then add global bound info */
8158 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
8159 bounds_ptr[0] = 0; /* relocated */
8160 bounds_ptr[1] = size;
8163 if (has_init) {
8164 decl_initializer(type, sec, addr, 1, 0);
8165 /* restore parse state if needed */
8166 if (init_str.str) {
8167 tok_str_free(init_str.str);
8168 restore_parse_state(&saved_parse_state);
8171 no_alloc: ;
8174 void put_func_debug(Sym *sym)
8176 char buf[512];
8178 /* stabs info */
8179 /* XXX: we put here a dummy type */
8180 snprintf(buf, sizeof(buf), "%s:%c1",
8181 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
8182 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
8183 cur_text_section, sym->c);
8184 last_ind = 0;
8185 last_line_num = 0;
8188 /* not finished : try to put some local vars in registers */
8189 //#define CONFIG_REG_VARS
8191 #ifdef CONFIG_REG_VARS
8192 void add_var_ref(int t)
8194 printf("%s:%d: &%s\n",
8195 file->filename, file->line_num,
8196 get_tok_str(t, NULL));
8199 /* first pass on a function with heuristic to extract variable usage
8200 and pointer references to local variables for register allocation */
8201 void analyse_function(void)
8203 int level, t;
8205 for(;;) {
8206 if (tok == -1)
8207 break;
8208 /* any symbol coming after '&' is considered as being a
8209 variable whose reference is taken. It is highly unaccurate
8210 but it is difficult to do better without a complete parse */
8211 if (tok == '&') {
8212 next();
8213 /* if '& number', then no need to examine next tokens */
8214 if (tok == TOK_CINT ||
8215 tok == TOK_CUINT ||
8216 tok == TOK_CLLONG ||
8217 tok == TOK_CULLONG) {
8218 continue;
8219 } else if (tok >= TOK_UIDENT) {
8220 /* if '& ident [' or '& ident ->', then ident address
8221 is not needed */
8222 t = tok;
8223 next();
8224 if (tok != '[' && tok != TOK_ARROW)
8225 add_var_ref(t);
8226 } else {
8227 level = 0;
8228 while (tok != '}' && tok != ';' &&
8229 !((tok == ',' || tok == ')') && level == 0)) {
8230 if (tok >= TOK_UIDENT) {
8231 add_var_ref(tok);
8232 } else if (tok == '(') {
8233 level++;
8234 } else if (tok == ')') {
8235 level--;
8237 next();
8240 } else {
8241 next();
8245 #endif
8247 /* parse an old style function declaration list */
8248 /* XXX: check multiple parameter */
8249 static void func_decl_list(Sym *func_sym)
8251 AttributeDef ad;
8252 int v;
8253 Sym *s;
8254 CType btype, type;
8256 /* parse each declaration */
8257 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
8258 if (!parse_btype(&btype, &ad))
8259 expect("declaration list");
8260 if (((btype.t & VT_BTYPE) == VT_ENUM ||
8261 (btype.t & VT_BTYPE) == VT_STRUCT) &&
8262 tok == ';') {
8263 /* we accept no variable after */
8264 } else {
8265 for(;;) {
8266 type = btype;
8267 type_decl(&type, &ad, &v, TYPE_DIRECT);
8268 /* find parameter in function parameter list */
8269 s = func_sym->next;
8270 while (s != NULL) {
8271 if ((s->v & ~SYM_FIELD) == v)
8272 goto found;
8273 s = s->next;
8275 error("declaration for parameter '%s' but no such parameter",
8276 get_tok_str(v, NULL));
8277 found:
8278 /* check that no storage specifier except 'register' was given */
8279 if (type.t & VT_STORAGE)
8280 error("storage class specified for '%s'", get_tok_str(v, NULL));
8281 convert_parameter_type(&type);
8282 /* we can add the type (NOTE: it could be local to the function) */
8283 s->type = type;
8284 /* accept other parameters */
8285 if (tok == ',')
8286 next();
8287 else
8288 break;
8291 skip(';');
8295 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
8296 static void decl(int l)
8298 int v, has_init, r;
8299 CType type, btype;
8300 Sym *sym;
8301 AttributeDef ad;
8303 while (1) {
8304 if (!parse_btype(&btype, &ad)) {
8305 /* skip redundant ';' */
8306 /* XXX: find more elegant solution */
8307 if (tok == ';') {
8308 next();
8309 continue;
8311 /* special test for old K&R protos without explicit int
8312 type. Only accepted when defining global data */
8313 if (l == VT_LOCAL || tok < TOK_DEFINE)
8314 break;
8315 btype.t = VT_INT;
8317 if (((btype.t & VT_BTYPE) == VT_ENUM ||
8318 (btype.t & VT_BTYPE) == VT_STRUCT) &&
8319 tok == ';') {
8320 /* we accept no variable after */
8321 next();
8322 continue;
8324 while (1) { /* iterate thru each declaration */
8325 type = btype;
8326 type_decl(&type, &ad, &v, TYPE_DIRECT);
8327 #if 0
8329 char buf[500];
8330 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
8331 printf("type = '%s'\n", buf);
8333 #endif
8334 if ((type.t & VT_BTYPE) == VT_FUNC) {
8335 /* if old style function prototype, we accept a
8336 declaration list */
8337 sym = type.ref;
8338 if (sym->c == FUNC_OLD)
8339 func_decl_list(sym);
8342 if (tok == '{') {
8343 #ifdef CONFIG_REG_VARS
8344 TokenString func_str;
8345 ParseState saved_parse_state;
8346 int block_level;
8347 #endif
8349 if (l == VT_LOCAL)
8350 error("cannot use local functions");
8351 if (!(type.t & VT_FUNC))
8352 expect("function definition");
8353 /* XXX: cannot do better now: convert extern line to static inline */
8354 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
8355 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
8357 #ifdef CONFIG_REG_VARS
8358 /* parse all function code and record it */
8360 tok_str_new(&func_str);
8362 block_level = 0;
8363 for(;;) {
8364 int t;
8365 if (tok == -1)
8366 error("unexpected end of file");
8367 tok_str_add_tok(&func_str);
8368 t = tok;
8369 next();
8370 if (t == '{') {
8371 block_level++;
8372 } else if (t == '}') {
8373 block_level--;
8374 if (block_level == 0)
8375 break;
8378 tok_str_add(&func_str, -1);
8379 tok_str_add(&func_str, 0);
8381 save_parse_state(&saved_parse_state);
8383 macro_ptr = func_str.str;
8384 next();
8385 analyse_function();
8386 #endif
8388 /* compute text section */
8389 cur_text_section = ad.section;
8390 if (!cur_text_section)
8391 cur_text_section = text_section;
8392 ind = cur_text_section->data_offset;
8393 funcname = get_tok_str(v, NULL);
8394 sym = sym_find(v);
8395 if (sym) {
8396 /* if symbol is already defined, then put complete type */
8397 sym->type = type;
8398 } else {
8399 /* put function symbol */
8400 sym = global_identifier_push(v, type.t, 0);
8401 sym->type.ref = type.ref;
8403 /* NOTE: we patch the symbol size later */
8404 put_extern_sym(sym, cur_text_section, ind, 0);
8405 func_ind = ind;
8406 sym->r = VT_SYM | VT_CONST;
8407 /* put debug symbol */
8408 if (do_debug)
8409 put_func_debug(sym);
8410 /* push a dummy symbol to enable local sym storage */
8411 sym_push2(&local_stack, SYM_FIELD, 0, 0);
8412 gfunc_prolog(&type);
8413 loc = 0;
8414 rsym = 0;
8415 #ifdef CONFIG_REG_VARS
8416 macro_ptr = func_str.str;
8417 next();
8418 #endif
8419 block(NULL, NULL, NULL, NULL, 0, 0);
8420 gsym(rsym);
8421 gfunc_epilog();
8422 cur_text_section->data_offset = ind;
8423 label_pop(&global_label_stack, NULL);
8424 sym_pop(&local_stack, NULL); /* reset local stack */
8425 /* end of function */
8426 /* patch symbol size */
8427 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
8428 ind - func_ind;
8429 if (do_debug) {
8430 put_stabn(N_FUN, 0, 0, ind - func_ind);
8432 funcname = ""; /* for safety */
8433 func_vt.t = VT_VOID; /* for safety */
8434 ind = 0; /* for safety */
8436 #ifdef CONFIG_REG_VARS
8437 tok_str_free(func_str.str);
8438 restore_parse_state(&saved_parse_state);
8439 #endif
8440 break;
8441 } else {
8442 if (btype.t & VT_TYPEDEF) {
8443 /* save typedefed type */
8444 /* XXX: test storage specifiers ? */
8445 sym = sym_push(v, &type, 0, 0);
8446 sym->type.t |= VT_TYPEDEF;
8447 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
8448 /* external function definition */
8449 external_sym(v, &type, 0);
8450 } else {
8451 /* not lvalue if array */
8452 r = 0;
8453 if (!(type.t & VT_ARRAY))
8454 r |= lvalue_type(type.t);
8455 has_init = (tok == '=');
8456 if ((btype.t & VT_EXTERN) ||
8457 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
8458 !has_init && l == VT_CONST && type.ref->c < 0)) {
8459 /* external variable */
8460 /* NOTE: as GCC, uninitialized global static
8461 arrays of null size are considered as
8462 extern */
8463 external_sym(v, &type, r);
8464 } else {
8465 if (type.t & VT_STATIC)
8466 r |= VT_CONST;
8467 else
8468 r |= l;
8469 if (has_init)
8470 next();
8471 decl_initializer_alloc(&type, &ad, r,
8472 has_init, v, l);
8475 if (tok != ',') {
8476 skip(';');
8477 break;
8479 next();
8485 /* better than nothing, but needs extension to handle '-E' option
8486 correctly too */
8487 static void preprocess_init(TCCState *s1)
8489 s1->include_stack_ptr = s1->include_stack;
8490 /* XXX: move that before to avoid having to initialize
8491 file->ifdef_stack_ptr ? */
8492 s1->ifdef_stack_ptr = s1->ifdef_stack;
8493 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
8495 /* XXX: not ANSI compliant: bound checking says error */
8496 vtop = vstack - 1;
8499 /* compile the C file opened in 'file'. Return non zero if errors. */
8500 static int tcc_compile(TCCState *s1)
8502 Sym *define_start;
8503 char buf[512];
8504 volatile int section_sym;
8506 #ifdef INC_DEBUG
8507 printf("%s: **** new file\n", file->filename);
8508 #endif
8509 preprocess_init(s1);
8511 funcname = "";
8512 anon_sym = SYM_FIRST_ANOM;
8514 /* file info: full path + filename */
8515 section_sym = 0; /* avoid warning */
8516 if (do_debug) {
8517 section_sym = put_elf_sym(symtab_section, 0, 0,
8518 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
8519 text_section->sh_num, NULL);
8520 getcwd(buf, sizeof(buf));
8521 pstrcat(buf, sizeof(buf), "/");
8522 put_stabs_r(buf, N_SO, 0, 0,
8523 text_section->data_offset, text_section, section_sym);
8524 put_stabs_r(file->filename, N_SO, 0, 0,
8525 text_section->data_offset, text_section, section_sym);
8527 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8528 symbols can be safely used */
8529 put_elf_sym(symtab_section, 0, 0,
8530 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
8531 SHN_ABS, file->filename);
8533 /* define some often used types */
8534 int_type.t = VT_INT;
8536 char_pointer_type.t = VT_BYTE;
8537 mk_pointer(&char_pointer_type);
8539 func_old_type.t = VT_FUNC;
8540 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
8542 #if 0
8543 /* define 'void *alloca(unsigned int)' builtin function */
8545 Sym *s1;
8547 p = anon_sym++;
8548 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
8549 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
8550 s1->next = NULL;
8551 sym->next = s1;
8552 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
8554 #endif
8556 define_start = define_stack;
8558 if (setjmp(s1->error_jmp_buf) == 0) {
8559 s1->nb_errors = 0;
8560 s1->error_set_jmp_enabled = 1;
8562 ch = file->buf_ptr[0];
8563 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
8564 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
8565 next();
8566 decl(VT_CONST);
8567 if (tok != -1)
8568 expect("declaration");
8570 /* end of translation unit info */
8571 if (do_debug) {
8572 put_stabs_r(NULL, N_SO, 0, 0,
8573 text_section->data_offset, text_section, section_sym);
8576 s1->error_set_jmp_enabled = 0;
8578 /* reset define stack, but leave -Dsymbols (may be incorrect if
8579 they are undefined) */
8580 free_defines(define_start);
8582 sym_pop(&global_stack, NULL);
8584 return s1->nb_errors != 0 ? -1 : 0;
8587 #ifdef LIBTCC
8588 int tcc_compile_string(TCCState *s, const char *str)
8590 BufferedFile bf1, *bf = &bf1;
8591 int ret, len;
8592 char *buf;
8594 /* init file structure */
8595 bf->fd = -1;
8596 /* XXX: avoid copying */
8597 len = strlen(str);
8598 buf = tcc_malloc(len + 1);
8599 if (!buf)
8600 return -1;
8601 memcpy(buf, str, len);
8602 buf[len] = CH_EOB;
8603 bf->buf_ptr = buf;
8604 bf->buf_end = buf + len;
8605 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
8606 bf->line_num = 1;
8607 file = bf;
8609 ret = tcc_compile(s);
8611 tcc_free(buf);
8613 /* currently, no need to close */
8614 return ret;
8616 #endif
8618 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8619 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
8621 BufferedFile bf1, *bf = &bf1;
8623 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
8624 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
8625 /* default value */
8626 if (!value)
8627 value = "1";
8628 pstrcat(bf->buffer, IO_BUF_SIZE, value);
8630 /* init file structure */
8631 bf->fd = -1;
8632 bf->buf_ptr = bf->buffer;
8633 bf->buf_end = bf->buffer + strlen(bf->buffer);
8634 *bf->buf_end = CH_EOB;
8635 bf->filename[0] = '\0';
8636 bf->line_num = 1;
8637 file = bf;
8639 s1->include_stack_ptr = s1->include_stack;
8641 /* parse with define parser */
8642 ch = file->buf_ptr[0];
8643 next_nomacro();
8644 parse_define();
8645 file = NULL;
8648 /* undefine a preprocessor symbol */
8649 void tcc_undefine_symbol(TCCState *s1, const char *sym)
8651 TokenSym *ts;
8652 Sym *s;
8653 ts = tok_alloc(sym, strlen(sym));
8654 s = define_find(ts->tok);
8655 /* undefine symbol by putting an invalid name */
8656 if (s)
8657 define_undef(s);
8660 #ifdef CONFIG_TCC_ASM
8662 #include "i386-asm.c"
8663 #include "tccasm.c"
8665 #else
8666 static void asm_instr(void)
8668 error("inline asm() not supported");
8670 #endif
8672 #include "tccelf.c"
8674 /* print the position in the source file of PC value 'pc' by reading
8675 the stabs debug information */
8676 static void rt_printline(unsigned long wanted_pc)
8678 Stab_Sym *sym, *sym_end;
8679 char func_name[128], last_func_name[128];
8680 unsigned long func_addr, last_pc, pc;
8681 const char *incl_files[INCLUDE_STACK_SIZE];
8682 int incl_index, len, last_line_num, i;
8683 const char *str, *p;
8685 fprintf(stderr, "0x%08lx:", wanted_pc);
8687 func_name[0] = '\0';
8688 func_addr = 0;
8689 incl_index = 0;
8690 last_func_name[0] = '\0';
8691 last_pc = 0xffffffff;
8692 last_line_num = 1;
8693 sym = (Stab_Sym *)stab_section->data + 1;
8694 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
8695 while (sym < sym_end) {
8696 switch(sym->n_type) {
8697 /* function start or end */
8698 case N_FUN:
8699 if (sym->n_strx == 0) {
8700 /* we test if between last line and end of function */
8701 pc = sym->n_value + func_addr;
8702 if (wanted_pc >= last_pc && wanted_pc < pc)
8703 goto found;
8704 func_name[0] = '\0';
8705 func_addr = 0;
8706 } else {
8707 str = stabstr_section->data + sym->n_strx;
8708 p = strchr(str, ':');
8709 if (!p) {
8710 pstrcpy(func_name, sizeof(func_name), str);
8711 } else {
8712 len = p - str;
8713 if (len > sizeof(func_name) - 1)
8714 len = sizeof(func_name) - 1;
8715 memcpy(func_name, str, len);
8716 func_name[len] = '\0';
8718 func_addr = sym->n_value;
8720 break;
8721 /* line number info */
8722 case N_SLINE:
8723 pc = sym->n_value + func_addr;
8724 if (wanted_pc >= last_pc && wanted_pc < pc)
8725 goto found;
8726 last_pc = pc;
8727 last_line_num = sym->n_desc;
8728 /* XXX: slow! */
8729 strcpy(last_func_name, func_name);
8730 break;
8731 /* include files */
8732 case N_BINCL:
8733 str = stabstr_section->data + sym->n_strx;
8734 add_incl:
8735 if (incl_index < INCLUDE_STACK_SIZE) {
8736 incl_files[incl_index++] = str;
8738 break;
8739 case N_EINCL:
8740 if (incl_index > 1)
8741 incl_index--;
8742 break;
8743 case N_SO:
8744 if (sym->n_strx == 0) {
8745 incl_index = 0; /* end of translation unit */
8746 } else {
8747 str = stabstr_section->data + sym->n_strx;
8748 /* do not add path */
8749 len = strlen(str);
8750 if (len > 0 && str[len - 1] != '/')
8751 goto add_incl;
8753 break;
8755 sym++;
8758 /* second pass: we try symtab symbols (no line number info) */
8759 incl_index = 0;
8761 Elf32_Sym *sym, *sym_end;
8762 int type;
8764 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
8765 for(sym = (Elf32_Sym *)symtab_section->data + 1;
8766 sym < sym_end;
8767 sym++) {
8768 type = ELF32_ST_TYPE(sym->st_info);
8769 if (type == STT_FUNC) {
8770 if (wanted_pc >= sym->st_value &&
8771 wanted_pc < sym->st_value + sym->st_size) {
8772 pstrcpy(last_func_name, sizeof(last_func_name),
8773 strtab_section->data + sym->st_name);
8774 goto found;
8779 /* did not find any info: */
8780 fprintf(stderr, " ???\n");
8781 return;
8782 found:
8783 if (last_func_name[0] != '\0') {
8784 fprintf(stderr, " %s()", last_func_name);
8786 if (incl_index > 0) {
8787 fprintf(stderr, " (%s:%d",
8788 incl_files[incl_index - 1], last_line_num);
8789 for(i = incl_index - 2; i >= 0; i--)
8790 fprintf(stderr, ", included from %s", incl_files[i]);
8791 fprintf(stderr, ")");
8793 fprintf(stderr, "\n");
8796 #ifndef WIN32
8798 #ifdef __i386__
8800 /* fix for glibc 2.1 */
8801 #ifndef REG_EIP
8802 #define REG_EIP EIP
8803 #define REG_EBP EBP
8804 #endif
8806 /* return the PC at frame level 'level'. Return non zero if not found */
8807 static int rt_get_caller_pc(unsigned long *paddr,
8808 ucontext_t *uc, int level)
8810 unsigned long fp;
8811 int i;
8813 if (level == 0) {
8814 #ifdef __FreeBSD__
8815 *paddr = uc->uc_mcontext.mc_eip;
8816 #else
8817 *paddr = uc->uc_mcontext.gregs[REG_EIP];
8818 #endif
8819 return 0;
8820 } else {
8821 #ifdef __FreeBSD__
8822 fp = uc->uc_mcontext.mc_ebp;
8823 #else
8824 fp = uc->uc_mcontext.gregs[REG_EBP];
8825 #endif
8826 for(i=1;i<level;i++) {
8827 /* XXX: check address validity with program info */
8828 if (fp <= 0x1000 || fp >= 0xc0000000)
8829 return -1;
8830 fp = ((unsigned long *)fp)[0];
8832 *paddr = ((unsigned long *)fp)[1];
8833 return 0;
8836 #else
8837 #error add arch specific rt_get_caller_pc()
8838 #endif
8840 /* emit a run time error at position 'pc' */
8841 void rt_error(ucontext_t *uc, const char *fmt, ...)
8843 va_list ap;
8844 unsigned long pc;
8845 int i;
8847 va_start(ap, fmt);
8848 fprintf(stderr, "Runtime error: ");
8849 vfprintf(stderr, fmt, ap);
8850 fprintf(stderr, "\n");
8851 for(i=0;i<num_callers;i++) {
8852 if (rt_get_caller_pc(&pc, uc, i) < 0)
8853 break;
8854 if (i == 0)
8855 fprintf(stderr, "at ");
8856 else
8857 fprintf(stderr, "by ");
8858 rt_printline(pc);
8860 exit(255);
8861 va_end(ap);
8864 /* signal handler for fatal errors */
8865 static void sig_error(int signum, siginfo_t *siginf, void *puc)
8867 ucontext_t *uc = puc;
8869 switch(signum) {
8870 case SIGFPE:
8871 switch(siginf->si_code) {
8872 case FPE_INTDIV:
8873 case FPE_FLTDIV:
8874 rt_error(uc, "division by zero");
8875 break;
8876 default:
8877 rt_error(uc, "floating point exception");
8878 break;
8880 break;
8881 case SIGBUS:
8882 case SIGSEGV:
8883 if (rt_bound_error_msg && *rt_bound_error_msg)
8884 rt_error(uc, *rt_bound_error_msg);
8885 else
8886 rt_error(uc, "dereferencing invalid pointer");
8887 break;
8888 case SIGILL:
8889 rt_error(uc, "illegal instruction");
8890 break;
8891 case SIGABRT:
8892 rt_error(uc, "abort() called");
8893 break;
8894 default:
8895 rt_error(uc, "caught signal %d", signum);
8896 break;
8898 exit(255);
8900 #endif
8902 /* do all relocations (needed before using tcc_get_symbol()) */
8903 int tcc_relocate(TCCState *s1)
8905 Section *s;
8906 int i;
8908 s1->nb_errors = 0;
8910 tcc_add_runtime(s1);
8912 relocate_common_syms();
8914 /* compute relocation address : section are relocated in place. We
8915 also alloc the bss space */
8916 for(i = 1; i < s1->nb_sections; i++) {
8917 s = s1->sections[i];
8918 if (s->sh_flags & SHF_ALLOC) {
8919 if (s->sh_type == SHT_NOBITS)
8920 s->data = tcc_mallocz(s->data_offset);
8921 s->sh_addr = (unsigned long)s->data;
8925 relocate_syms(s1, 1);
8927 if (s1->nb_errors != 0)
8928 return -1;
8930 /* relocate each section */
8931 for(i = 1; i < s1->nb_sections; i++) {
8932 s = s1->sections[i];
8933 if (s->reloc)
8934 relocate_section(s1, s);
8936 return 0;
8939 /* launch the compiled program with the given arguments */
8940 int tcc_run(TCCState *s1, int argc, char **argv)
8942 int (*prog_main)(int, char **);
8944 if (tcc_relocate(s1) < 0)
8945 return -1;
8947 prog_main = tcc_get_symbol(s1, "main");
8949 if (do_debug) {
8950 #ifdef WIN32
8951 error("debug mode currently not available for Windows");
8952 #else
8953 struct sigaction sigact;
8954 /* install TCC signal handlers to print debug info on fatal
8955 runtime errors */
8956 sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
8957 sigact.sa_sigaction = sig_error;
8958 sigemptyset(&sigact.sa_mask);
8959 sigaction(SIGFPE, &sigact, NULL);
8960 sigaction(SIGILL, &sigact, NULL);
8961 sigaction(SIGSEGV, &sigact, NULL);
8962 sigaction(SIGBUS, &sigact, NULL);
8963 sigaction(SIGABRT, &sigact, NULL);
8964 #endif
8967 #ifdef CONFIG_TCC_BCHECK
8968 if (do_bounds_check) {
8969 void (*bound_init)(void);
8971 /* set error function */
8972 rt_bound_error_msg = (void *)tcc_get_symbol(s1, "__bound_error_msg");
8974 /* XXX: use .init section so that it also work in binary ? */
8975 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
8976 bound_init();
8978 #endif
8979 return (*prog_main)(argc, argv);
8982 TCCState *tcc_new(void)
8984 const char *p, *r;
8985 TCCState *s;
8986 TokenSym *ts;
8987 int i, c;
8989 s = tcc_mallocz(sizeof(TCCState));
8990 if (!s)
8991 return NULL;
8992 tcc_state = s;
8993 s->output_type = TCC_OUTPUT_MEMORY;
8995 /* init isid table */
8996 for(i=0;i<256;i++)
8997 isidnum_table[i] = isid(i) || isnum(i);
8999 /* add all tokens */
9000 table_ident = NULL;
9001 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
9003 tok_ident = TOK_IDENT;
9004 p = tcc_keywords;
9005 while (*p) {
9006 r = p;
9007 for(;;) {
9008 c = *r++;
9009 if (c == '\0')
9010 break;
9012 ts = tok_alloc(p, r - p - 1);
9013 p = r;
9016 /* we add dummy defines for some special macros to speed up tests
9017 and to have working defined() */
9018 define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
9019 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
9020 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
9021 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
9023 /* standard defines */
9024 tcc_define_symbol(s, "__STDC__", NULL);
9025 #if defined(TCC_TARGET_I386)
9026 tcc_define_symbol(s, "__i386__", NULL);
9027 #endif
9028 #if defined(linux)
9029 tcc_define_symbol(s, "__linux__", NULL);
9030 tcc_define_symbol(s, "linux", NULL);
9031 #endif
9032 /* tiny C specific defines */
9033 tcc_define_symbol(s, "__TINYC__", NULL);
9035 /* tiny C & gcc defines */
9036 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
9037 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
9038 tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
9040 /* default library paths */
9041 tcc_add_library_path(s, "/usr/local/lib");
9042 tcc_add_library_path(s, "/usr/lib");
9043 tcc_add_library_path(s, "/lib");
9045 /* no section zero */
9046 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
9048 /* create standard sections */
9049 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
9050 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
9051 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
9053 /* symbols are always generated for linking stage */
9054 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
9055 ".strtab",
9056 ".hashtab", SHF_PRIVATE);
9057 strtab_section = symtab_section->link;
9059 /* private symbol table for dynamic symbols */
9060 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
9061 ".dynstrtab",
9062 ".dynhashtab", SHF_PRIVATE);
9063 return s;
9066 void tcc_delete(TCCState *s1)
9068 int i, n;
9070 /* free -D defines */
9071 free_defines(NULL);
9073 /* free tokens */
9074 n = tok_ident - TOK_IDENT;
9075 for(i = 0; i < n; i++)
9076 tcc_free(table_ident[i]);
9077 tcc_free(table_ident);
9079 /* free all sections */
9081 free_section(symtab_section->hash);
9083 free_section(s1->dynsymtab_section->hash);
9084 free_section(s1->dynsymtab_section->link);
9085 free_section(s1->dynsymtab_section);
9087 for(i = 1; i < s1->nb_sections; i++)
9088 free_section(s1->sections[i]);
9089 tcc_free(s1->sections);
9091 /* free loaded dlls array */
9092 for(i = 0; i < s1->nb_loaded_dlls; i++)
9093 tcc_free(s1->loaded_dlls[i]);
9094 tcc_free(s1->loaded_dlls);
9096 /* library paths */
9097 for(i = 0; i < s1->nb_library_paths; i++)
9098 tcc_free(s1->library_paths[i]);
9099 tcc_free(s1->library_paths);
9101 /* cached includes */
9102 for(i = 0; i < s1->nb_cached_includes; i++)
9103 tcc_free(s1->cached_includes[i]);
9104 tcc_free(s1->cached_includes);
9106 for(i = 0; i < s1->nb_include_paths; i++)
9107 tcc_free(s1->include_paths[i]);
9108 tcc_free(s1->include_paths);
9110 for(i = 0; i < s1->nb_sysinclude_paths; i++)
9111 tcc_free(s1->sysinclude_paths[i]);
9112 tcc_free(s1->sysinclude_paths);
9114 tcc_free(s1);
9117 int tcc_add_include_path(TCCState *s1, const char *pathname)
9119 char *pathname1;
9121 pathname1 = tcc_strdup(pathname);
9122 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
9123 return 0;
9126 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
9128 char *pathname1;
9130 pathname1 = tcc_strdup(pathname);
9131 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
9132 return 0;
9135 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
9137 const char *ext, *filename1;
9138 Elf32_Ehdr ehdr;
9139 int fd, ret;
9140 BufferedFile *saved_file;
9142 /* find source file type with extension */
9143 filename1 = strrchr(filename, '/');
9144 if (filename1)
9145 filename1++;
9146 else
9147 filename1 = filename;
9148 ext = strrchr(filename1, '.');
9149 if (ext)
9150 ext++;
9152 /* open the file */
9153 saved_file = file;
9154 file = tcc_open(s1, filename);
9155 if (!file) {
9156 if (flags & AFF_PRINT_ERROR) {
9157 error_noabort("file '%s' not found", filename);
9159 ret = -1;
9160 goto fail1;
9163 if (!ext || !strcmp(ext, "c")) {
9164 /* C file assumed */
9165 ret = tcc_compile(s1);
9166 } else
9167 #ifdef CONFIG_TCC_ASM
9168 if (!strcmp(ext, "S")) {
9169 /* preprocessed assembler */
9170 ret = tcc_assemble(s1, 1);
9171 } else if (!strcmp(ext, "s")) {
9172 /* non preprocessed assembler */
9173 ret = tcc_assemble(s1, 0);
9174 } else
9175 #endif
9177 fd = file->fd;
9178 /* assume executable format: auto guess file type */
9179 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
9180 error_noabort("could not read header");
9181 goto fail;
9183 lseek(fd, 0, SEEK_SET);
9185 if (ehdr.e_ident[0] == ELFMAG0 &&
9186 ehdr.e_ident[1] == ELFMAG1 &&
9187 ehdr.e_ident[2] == ELFMAG2 &&
9188 ehdr.e_ident[3] == ELFMAG3) {
9189 file->line_num = 0; /* do not display line number if error */
9190 if (ehdr.e_type == ET_REL) {
9191 ret = tcc_load_object_file(s1, fd, 0);
9192 } else if (ehdr.e_type == ET_DYN) {
9193 ret = tcc_load_dll(s1, fd, filename,
9194 (flags & AFF_REFERENCED_DLL) != 0);
9195 } else {
9196 error_noabort("unrecognized ELF file");
9197 goto fail;
9199 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
9200 file->line_num = 0; /* do not display line number if error */
9201 ret = tcc_load_archive(s1, fd);
9202 } else {
9203 /* as GNU ld, consider it is an ld script if not recognized */
9204 ret = tcc_load_ldscript(s1);
9205 if (ret < 0) {
9206 error_noabort("unrecognized file type");
9207 goto fail;
9211 the_end:
9212 tcc_close(file);
9213 fail1:
9214 file = saved_file;
9215 return ret;
9216 fail:
9217 ret = -1;
9218 goto the_end;
9221 int tcc_add_file(TCCState *s, const char *filename)
9223 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
9226 int tcc_add_library_path(TCCState *s, const char *pathname)
9228 char *pathname1;
9230 pathname1 = tcc_strdup(pathname);
9231 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
9232 return 0;
9235 /* find and load a dll. Return non zero if not found */
9236 /* XXX: add '-rpath' option support ? */
9237 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
9239 char buf[1024];
9240 int i;
9242 for(i = 0; i < s->nb_library_paths; i++) {
9243 snprintf(buf, sizeof(buf), "%s/%s",
9244 s->library_paths[i], filename);
9245 if (tcc_add_file_internal(s, buf, flags) == 0)
9246 return 0;
9248 return -1;
9251 /* the library name is the same as the argument of the '-l' option */
9252 int tcc_add_library(TCCState *s, const char *libraryname)
9254 char buf[1024];
9255 int i;
9256 void *h;
9258 /* first we look for the dynamic library if not static linking */
9259 if (!s->static_link) {
9260 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
9261 /* if we output to memory, then we simply we dlopen(). */
9262 if (s->output_type == TCC_OUTPUT_MEMORY) {
9263 /* Since the libc is already loaded, we don't need to load it again */
9264 if (!strcmp(libraryname, "c"))
9265 return 0;
9266 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
9267 if (h)
9268 return 0;
9269 } else {
9270 if (tcc_add_dll(s, buf, 0) == 0)
9271 return 0;
9275 /* then we look for the static library */
9276 for(i = 0; i < s->nb_library_paths; i++) {
9277 snprintf(buf, sizeof(buf), "%s/lib%s.a",
9278 s->library_paths[i], libraryname);
9279 if (tcc_add_file_internal(s, buf, 0) == 0)
9280 return 0;
9282 return -1;
9285 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
9287 add_elf_sym(symtab_section, val, 0,
9288 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
9289 SHN_ABS, name);
9290 return 0;
9293 int tcc_set_output_type(TCCState *s, int output_type)
9295 char buf[1024];
9297 s->output_type = output_type;
9299 if (!s->nostdinc) {
9300 /* default include paths */
9301 /* XXX: reverse order needed if -isystem support */
9302 tcc_add_sysinclude_path(s, "/usr/local/include");
9303 tcc_add_sysinclude_path(s, "/usr/include");
9304 snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path);
9305 tcc_add_sysinclude_path(s, buf);
9308 /* if bound checking, then add corresponding sections */
9309 #ifdef CONFIG_TCC_BCHECK
9310 if (do_bounds_check) {
9311 /* define symbol */
9312 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
9313 /* create bounds sections */
9314 bounds_section = new_section(s, ".bounds",
9315 SHT_PROGBITS, SHF_ALLOC);
9316 lbounds_section = new_section(s, ".lbounds",
9317 SHT_PROGBITS, SHF_ALLOC);
9319 #endif
9321 /* add debug sections */
9322 if (do_debug) {
9323 /* stab symbols */
9324 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
9325 stab_section->sh_entsize = sizeof(Stab_Sym);
9326 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
9327 put_elf_str(stabstr_section, "");
9328 stab_section->link = stabstr_section;
9329 /* put first entry */
9330 put_stabs("", 0, 0, 0, 0);
9333 /* add libc crt1/crti objects */
9334 if (output_type == TCC_OUTPUT_EXE ||
9335 output_type == TCC_OUTPUT_DLL) {
9336 if (output_type != TCC_OUTPUT_DLL)
9337 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
9338 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
9340 return 0;
9343 #if !defined(LIBTCC)
9345 static int64_t getclock_us(void)
9347 #ifdef WIN32
9348 struct _timeb tb;
9349 _ftime(&tb);
9350 return (tb.time * 1000LL + tb.millitm) * 1000LL;
9351 #else
9352 struct timeval tv;
9353 gettimeofday(&tv, NULL);
9354 return tv.tv_sec * 1000000LL + tv.tv_usec;
9355 #endif
9358 void help(void)
9360 printf("tcc version 0.9.16 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
9361 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
9362 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
9363 " [--] infile1 [infile2... --] [infile_args...]\n"
9364 "\n"
9365 "General options:\n"
9366 " -c compile only - generate an object file\n"
9367 " -o outfile set output filename\n"
9368 " -- allows multiples input files if no -o option given. Also\n"
9369 " separate input files from runtime arguments\n"
9370 " -Bdir set tcc internal library path\n"
9371 " -bench output compilation statistics\n"
9372 "Preprocessor options:\n"
9373 " -Idir add include path 'dir'\n"
9374 " -Dsym[=val] define 'sym' with value 'val'\n"
9375 " -Usym undefine 'sym'\n"
9376 "Linker options:\n"
9377 " -Ldir add library path 'dir'\n"
9378 " -llib link with dynamic or static library 'lib'\n"
9379 " -shared generate a shared library\n"
9380 " -static static linking\n"
9381 " -r relocatable output\n"
9382 "Debugger options:\n"
9383 " -g generate runtime debug info\n"
9384 #ifdef CONFIG_TCC_BCHECK
9385 " -b compile with built-in memory and bounds checker (implies -g)\n"
9386 #endif
9387 " -bt N show N callers in stack traces\n"
9391 #define TCC_OPTION_HAS_ARG 0x0001
9392 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
9394 typedef struct TCCOption {
9395 const char *name;
9396 uint16_t index;
9397 uint16_t flags;
9398 } TCCOption;
9400 enum {
9401 TCC_OPTION_HELP,
9402 TCC_OPTION_MARKER,
9403 TCC_OPTION_I,
9404 TCC_OPTION_D,
9405 TCC_OPTION_U,
9406 TCC_OPTION_L,
9407 TCC_OPTION_B,
9408 TCC_OPTION_l,
9409 TCC_OPTION_bench,
9410 TCC_OPTION_bt,
9411 TCC_OPTION_b,
9412 TCC_OPTION_g,
9413 TCC_OPTION_c,
9414 TCC_OPTION_static,
9415 TCC_OPTION_shared,
9416 TCC_OPTION_o,
9417 TCC_OPTION_r,
9418 TCC_OPTION_W,
9419 TCC_OPTION_O,
9420 TCC_OPTION_m,
9421 TCC_OPTION_f,
9422 TCC_OPTION_nostdinc,
9423 TCC_OPTION_print_search_dirs,
9424 TCC_OPTION_rdynamic,
9427 static const TCCOption tcc_options[] = {
9428 { "h", TCC_OPTION_HELP, 0 },
9429 { "?", TCC_OPTION_HELP, 0 },
9430 { "-", TCC_OPTION_MARKER, 0 },
9431 { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
9432 { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
9433 { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
9434 { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
9435 { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
9436 { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9437 { "bench", TCC_OPTION_bench, 0 },
9438 { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
9439 #ifdef CONFIG_TCC_BCHECK
9440 { "b", TCC_OPTION_b, 0 },
9441 #endif
9442 { "g", TCC_OPTION_g, 0 },
9443 { "c", TCC_OPTION_c, 0 },
9444 { "static", TCC_OPTION_static, 0 },
9445 { "shared", TCC_OPTION_shared, 0 },
9446 { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
9447 { "rdynamic", TCC_OPTION_rdynamic, 0 }, /* currently ignored */
9448 { "r", TCC_OPTION_r, 0 },
9449 { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9450 { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9451 { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
9452 { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
9453 { "nostdinc", TCC_OPTION_nostdinc, 0 },
9454 { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
9455 { NULL },
9458 int main(int argc, char **argv)
9460 char *r;
9461 int optind, output_type, multiple_files, i, reloc_output;
9462 TCCState *s;
9463 char **files;
9464 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
9465 char objfilename[1024];
9466 int64_t start_time = 0;
9467 const TCCOption *popt;
9468 const char *optarg, *p1, *r1, *outfile;
9469 int print_search_dirs;
9471 s = tcc_new();
9472 output_type = TCC_OUTPUT_MEMORY;
9474 optind = 1;
9475 outfile = NULL;
9476 multiple_files = 0;
9477 dminus = 0;
9478 files = NULL;
9479 nb_files = 0;
9480 nb_libraries = 0;
9481 reloc_output = 0;
9482 print_search_dirs = 0;
9483 while (1) {
9484 if (optind >= argc) {
9485 if (nb_files == 0 && !print_search_dirs)
9486 goto show_help;
9487 else
9488 break;
9490 r = argv[optind++];
9491 if (r[0] != '-') {
9492 /* add a new file */
9493 dynarray_add((void ***)&files, &nb_files, r);
9494 if (!multiple_files) {
9495 optind--;
9496 /* argv[0] will be this file */
9497 break;
9499 } else {
9500 /* find option in table (match only the first chars */
9501 popt = tcc_options;
9502 for(;;) {
9503 p1 = popt->name;
9504 if (p1 == NULL)
9505 error("invalid option -- '%s'", r);
9506 r1 = r + 1;
9507 for(;;) {
9508 if (*p1 == '\0')
9509 goto option_found;
9510 if (*r1 != *p1)
9511 break;
9512 p1++;
9513 r1++;
9515 popt++;
9517 option_found:
9518 if (popt->flags & TCC_OPTION_HAS_ARG) {
9519 if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) {
9520 optarg = r1;
9521 } else {
9522 if (optind >= argc)
9523 error("argument to '%s' is missing", r);
9524 optarg = argv[optind++];
9526 } else {
9527 if (*r1 != '\0')
9528 goto show_help;
9529 optarg = NULL;
9532 switch(popt->index) {
9533 case TCC_OPTION_HELP:
9534 show_help:
9535 help();
9536 return 1;
9537 case TCC_OPTION_MARKER:
9538 /* '--' enables multiple files input and also ends several
9539 file input */
9540 if (dminus && multiple_files) {
9541 optind--; /* argv[0] will be '--' */
9542 goto end_parse;
9544 dminus = 1;
9545 multiple_files = 1;
9546 case TCC_OPTION_I:
9547 if (tcc_add_include_path(s, optarg) < 0)
9548 error("too many include paths");
9549 break;
9550 case TCC_OPTION_D:
9552 char *sym, *value;
9553 sym = (char *)optarg;
9554 value = strchr(sym, '=');
9555 if (value) {
9556 *value = '\0';
9557 value++;
9559 tcc_define_symbol(s, sym, value);
9561 break;
9562 case TCC_OPTION_U:
9563 tcc_undefine_symbol(s, optarg);
9564 break;
9565 case TCC_OPTION_L:
9566 tcc_add_library_path(s, optarg);
9567 break;
9568 case TCC_OPTION_B:
9569 /* set tcc utilities path (mainly for tcc development) */
9570 tcc_lib_path = optarg;
9571 break;
9572 case TCC_OPTION_l:
9573 dynarray_add((void ***)&files, &nb_files, r);
9574 nb_libraries++;
9575 break;
9576 case TCC_OPTION_bench:
9577 do_bench = 1;
9578 break;
9579 case TCC_OPTION_bt:
9580 num_callers = atoi(optarg);
9581 break;
9582 #ifdef CONFIG_TCC_BCHECK
9583 case TCC_OPTION_b:
9584 do_bounds_check = 1;
9585 do_debug = 1;
9586 break;
9587 #endif
9588 case TCC_OPTION_g:
9589 do_debug = 1;
9590 break;
9591 case TCC_OPTION_c:
9592 multiple_files = 1;
9593 output_type = TCC_OUTPUT_OBJ;
9594 break;
9595 case TCC_OPTION_static:
9596 s->static_link = 1;
9597 break;
9598 case TCC_OPTION_shared:
9599 output_type = TCC_OUTPUT_DLL;
9600 break;
9601 case TCC_OPTION_o:
9602 multiple_files = 1;
9603 outfile = optarg;
9604 break;
9605 case TCC_OPTION_r:
9606 /* generate a .o merging several output files */
9607 reloc_output = 1;
9608 output_type = TCC_OUTPUT_OBJ;
9609 break;
9610 case TCC_OPTION_nostdinc:
9611 s->nostdinc = 1;
9612 break;
9613 case TCC_OPTION_print_search_dirs:
9614 print_search_dirs = 1;
9615 break;
9616 default:
9617 break;
9621 end_parse:
9622 if (print_search_dirs) {
9623 /* enough for Linux kernel */
9624 printf("install: %s/\n", tcc_lib_path);
9625 return 0;
9628 nb_objfiles = nb_files - nb_libraries;
9630 /* if outfile provided without other options, we output an
9631 executable */
9632 if (outfile && output_type == TCC_OUTPUT_MEMORY)
9633 output_type = TCC_OUTPUT_EXE;
9635 /* check -c consistency : only single file handled. XXX: checks file type */
9636 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9637 /* accepts only a single input file */
9638 if (nb_objfiles != 1)
9639 error("cannot specify multiple files with -c");
9640 if (nb_libraries != 0)
9641 error("cannot specify libraries with -c");
9644 /* compute default outfile name */
9645 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
9646 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9647 char *ext;
9648 /* add .o extension */
9649 pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
9650 ext = strrchr(objfilename, '.');
9651 if (!ext)
9652 goto default_outfile;
9653 strcpy(ext + 1, "o");
9654 } else {
9655 default_outfile:
9656 pstrcpy(objfilename, sizeof(objfilename), "a.out");
9658 outfile = objfilename;
9661 if (do_bench) {
9662 start_time = getclock_us();
9665 tcc_set_output_type(s, output_type);
9667 /* compile or add each files or library */
9668 for(i = 0;i < nb_files; i++) {
9669 const char *filename;
9671 filename = files[i];
9672 if (filename[0] == '-') {
9673 if (tcc_add_library(s, filename + 2) < 0)
9674 error("cannot find %s", filename);
9675 } else {
9676 if (tcc_add_file(s, filename) < 0) {
9677 ret = 1;
9678 goto the_end;
9683 /* free all files */
9684 tcc_free(files);
9686 if (do_bench) {
9687 double total_time;
9688 total_time = (double)(getclock_us() - start_time) / 1000000.0;
9689 if (total_time < 0.001)
9690 total_time = 0.001;
9691 if (total_bytes < 1)
9692 total_bytes = 1;
9693 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
9694 tok_ident - TOK_IDENT, total_lines, total_bytes,
9695 total_time, (int)(total_lines / total_time),
9696 total_bytes / total_time / 1000000.0);
9699 if (s->output_type != TCC_OUTPUT_MEMORY) {
9700 tcc_output_file(s, outfile);
9701 ret = 0;
9702 } else {
9703 ret = tcc_run(s, argc - optind, argv + optind);
9705 the_end:
9706 /* XXX: cannot do it with bound checking because of the malloc hooks */
9707 if (!do_bounds_check)
9708 tcc_delete(s);
9710 #ifdef MEM_DEBUG
9711 if (do_bench) {
9712 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
9714 #endif
9715 return ret;
9718 #endif