update
[tinycc.git] / tcc.c
blob4f982ae63d0afc8f8815a4266c25c5007b26712b
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 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <math.h>
26 #include <unistd.h>
27 #include <signal.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <setjmp.h>
31 #ifdef WIN32
32 #include <sys/timeb.h>
33 #endif
34 #ifndef WIN32
35 #include <sys/time.h>
36 #include <sys/ucontext.h>
37 #endif
38 #include "elf.h"
39 #include "stab.h"
40 #ifndef CONFIG_TCC_STATIC
41 #include <dlfcn.h>
42 #endif
44 #include "libtcc.h"
46 /* parser debug */
47 //#define PARSE_DEBUG
48 /* preprocessor debug */
49 //#define PP_DEBUG
50 /* include file debug */
51 //#define INC_DEBUG
53 //#define MEM_DEBUG
55 /* target selection */
56 //#define TCC_TARGET_I386 /* i386 code generator */
57 //#define TCC_TARGET_IL /* .NET CLI generator */
59 /* default target is I386 */
60 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
61 #define TCC_TARGET_I386
62 #endif
64 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
65 #define CONFIG_TCC_BCHECK /* enable bound checking code */
66 #endif
68 #ifndef CONFIG_TCC_PREFIX
69 #define CONFIG_TCC_PREFIX "/usr/local"
70 #endif
72 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
73 executables or dlls */
74 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
76 #define INCLUDE_STACK_SIZE 32
77 #define IFDEF_STACK_SIZE 64
78 #define VSTACK_SIZE 64
79 #define STRING_MAX_SIZE 1024
81 #define TOK_HASH_SIZE 2048 /* must be a power of two */
82 #define TOK_ALLOC_INCR 512 /* must be a power of two */
83 #define TOK_STR_ALLOC_INCR_BITS 6
84 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
85 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
87 /* token symbol management */
88 typedef struct TokenSym {
89 struct TokenSym *hash_next;
90 struct Sym *sym_define; /* direct pointer to define */
91 struct Sym *sym_label; /* direct pointer to label */
92 struct Sym *sym_struct; /* direct pointer to structure */
93 struct Sym *sym_identifier; /* direct pointer to identifier */
94 int tok; /* token number */
95 int len;
96 char str[1];
97 } TokenSym;
99 typedef struct CString {
100 int size; /* size in bytes */
101 void *data; /* either 'char *' or 'int *' */
102 int size_allocated;
103 void *data_allocated; /* if non NULL, data has been malloced */
104 } CString;
106 /* type definition */
107 typedef struct CType {
108 int t;
109 struct Sym *ref;
110 } CType;
112 /* constant value */
113 typedef union CValue {
114 long double ld;
115 double d;
116 float f;
117 int i;
118 unsigned int ui;
119 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
120 long long ll;
121 unsigned long long ull;
122 struct CString *cstr;
123 void *ptr;
124 int tab[1];
125 } CValue;
127 /* value on stack */
128 typedef struct SValue {
129 CType type; /* type */
130 unsigned short r; /* register + flags */
131 unsigned short r2; /* second register, used for 'long long'
132 type. If not used, set to VT_CONST */
133 CValue c; /* constant, if VT_CONST */
134 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
135 } SValue;
137 /* symbol management */
138 typedef struct Sym {
139 int v; /* symbol token */
140 int r; /* associated register */
141 int c; /* associated number */
142 CType type; /* associated type */
143 struct Sym *next; /* next related symbol */
144 struct Sym *prev; /* prev symbol in stack */
145 struct Sym *prev_tok; /* previous symbol for this token */
146 } Sym;
148 /* section definition */
149 /* XXX: use directly ELF structure for parameters ? */
150 /* special flag to indicate that the section should not be linked to
151 the other ones */
152 #define SHF_PRIVATE 0x80000000
154 typedef struct Section {
155 unsigned long data_offset; /* current data offset */
156 unsigned char *data; /* section data */
157 unsigned long data_allocated; /* used for realloc() handling */
158 int sh_name; /* elf section name (only used during output) */
159 int sh_num; /* elf section number */
160 int sh_type; /* elf section type */
161 int sh_flags; /* elf section flags */
162 int sh_info; /* elf section info */
163 int sh_addralign; /* elf section alignment */
164 int sh_entsize; /* elf entry size */
165 unsigned long sh_size; /* section size (only used during output) */
166 unsigned long sh_addr; /* address at which the section is relocated */
167 unsigned long sh_offset; /* address at which the section is relocated */
168 int nb_hashed_syms; /* used to resize the hash table */
169 struct Section *link; /* link to another section */
170 struct Section *reloc; /* corresponding section for relocation, if any */
171 struct Section *hash; /* hash table for symbols */
172 struct Section *next;
173 char name[64]; /* section name */
174 } Section;
176 typedef struct DLLReference {
177 int level;
178 char name[1];
179 } DLLReference;
181 /* GNUC attribute definition */
182 typedef struct AttributeDef {
183 int aligned;
184 Section *section;
185 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
186 } AttributeDef;
188 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
189 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
190 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
192 /* stored in 'Sym.c' field */
193 #define FUNC_NEW 1 /* ansi function prototype */
194 #define FUNC_OLD 2 /* old function prototype */
195 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
197 /* stored in 'Sym.r' field */
198 #define FUNC_CDECL 0 /* standard c call */
199 #define FUNC_STDCALL 1 /* pascal c call */
201 /* field 'Sym.t' for macros */
202 #define MACRO_OBJ 0 /* object like macro */
203 #define MACRO_FUNC 1 /* function like macro */
205 /* field 'Sym.r' for labels */
206 #define LABEL_FORWARD 1 /* label is forward defined */
208 /* type_decl() types */
209 #define TYPE_ABSTRACT 1 /* type without variable */
210 #define TYPE_DIRECT 2 /* type with variable */
212 #define IO_BUF_SIZE 8192
214 typedef struct BufferedFile {
215 uint8_t *buf_ptr;
216 uint8_t *buf_end;
217 int fd;
218 int line_num; /* current line number - here to simply code */
219 int ifndef_macro; /* #ifndef macro / #endif search */
220 int ifndef_macro_saved; /* saved ifndef_macro */
221 int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
222 char inc_type; /* type of include */
223 char inc_filename[512]; /* filename specified by the user */
224 char filename[1024]; /* current filename - here to simplify code */
225 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
226 } BufferedFile;
228 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
229 #define CH_EOF (-1) /* end of file */
231 /* parsing state (used to save parser state to reparse part of the
232 source several times) */
233 typedef struct ParseState {
234 int *macro_ptr;
235 int line_num;
236 int tok;
237 CValue tokc;
238 } ParseState;
240 /* used to record tokens */
241 typedef struct TokenString {
242 int *str;
243 int len;
244 int allocated_len;
245 int last_line_num;
246 } TokenString;
248 /* include file cache, used to find files faster and also to eliminate
249 inclusion if the include file is protected by #ifndef ... #endif */
250 typedef struct CachedInclude {
251 int ifndef_macro;
252 char type; /* '"' or '>' to give include type */
253 char filename[1]; /* path specified in #include */
254 } CachedInclude;
256 /* parser */
257 static struct BufferedFile *file;
258 static int ch, tok, tok1;
259 static CValue tokc, tok1c;
260 static CString tokcstr; /* current parsed string, if any */
261 /* additionnal informations about token */
262 static int tok_flags;
263 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
264 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
265 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
267 /* if true, line feed is returned as a token. line feed is also
268 returned at eof */
269 static int return_linefeed;
270 static Section *text_section, *data_section, *bss_section; /* predefined sections */
271 static Section *cur_text_section; /* current section where function code is
272 generated */
273 /* bound check related sections */
274 static Section *bounds_section; /* contains global data bound description */
275 static Section *lbounds_section; /* contains local data bound description */
276 /* symbol sections */
277 static Section *symtab_section, *strtab_section;
279 /* debug sections */
280 static Section *stab_section, *stabstr_section;
282 /* loc : local variable index
283 ind : output code index
284 rsym: return symbol
285 anon_sym: anonymous symbol index
287 static int rsym, anon_sym, ind, loc;
288 /* expression generation modifiers */
289 static int const_wanted; /* true if constant wanted */
290 static int nocode_wanted; /* true if no code generation wanted for an expression */
291 static int global_expr; /* true if compound literals must be allocated
292 globally (used during initializers parsing */
293 static CType func_vt; /* current function return type (used by return
294 instruction) */
295 static int func_vc;
296 static int last_line_num, last_ind, func_ind; /* debug last line number and pc */
297 static int tok_ident;
298 static TokenSym **table_ident;
299 static TokenSym *hash_ident[TOK_HASH_SIZE];
300 static char token_buf[STRING_MAX_SIZE + 1];
301 static char *funcname;
302 static Sym *global_stack, *local_stack;
303 static Sym *define_stack;
304 static Sym *label_stack;
306 static SValue vstack[VSTACK_SIZE], *vtop;
307 static int *macro_ptr, *macro_ptr_allocated;
308 /* some predefined types */
309 static CType char_pointer_type, func_old_type, int_type;
311 /* compile with debug symbol (and use them if error during execution) */
312 static int do_debug = 0;
314 /* compile with built-in memory and bounds checker */
315 static int do_bounds_check = 0;
317 /* display benchmark infos */
318 static int do_bench = 0;
319 static int total_lines;
320 static int total_bytes;
322 /* use GNU C extensions */
323 static int gnu_ext = 1;
325 /* use Tiny C extensions */
326 static int tcc_ext = 1;
328 /* max number of callers shown if error */
329 static int num_callers = 6;
330 static const char **rt_bound_error_msg;
332 /* XXX: suppress that ASAP */
333 static struct TCCState *tcc_state;
335 /* give the path of the tcc libraries */
336 static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc";
338 struct TCCState {
339 int output_type;
341 BufferedFile **include_stack_ptr;
342 int *ifdef_stack_ptr;
344 /* include file handling */
345 char **include_paths;
346 int nb_include_paths;
347 char **sysinclude_paths;
348 int nb_sysinclude_paths;
349 CachedInclude **cached_includes;
350 int nb_cached_includes;
352 char **library_paths;
353 int nb_library_paths;
355 /* array of all loaded dlls (including those referenced by loaded
356 dlls) */
357 DLLReference **loaded_dlls;
358 int nb_loaded_dlls;
360 /* sections */
361 Section **sections;
362 int nb_sections; /* number of sections, including first dummy section */
364 /* got handling */
365 Section *got;
366 unsigned long *got_offsets;
367 int nb_got_offsets;
368 int nb_plt_entries;
369 /* give the correspondance from symtab indexes to dynsym indexes */
370 int *symtab_to_dynsym;
372 /* temporary dynamic symbol sections (for dll loading) */
373 Section *dynsymtab_section;
374 /* exported dynamic symbol section */
375 Section *dynsym;
377 /* if true, static linking is performed */
378 int static_link;
380 /* error handling */
381 void *error_opaque;
382 void (*error_func)(void *opaque, const char *msg);
383 int error_set_jmp_enabled;
384 jmp_buf error_jmp_buf;
385 int nb_errors;
387 /* see include_stack_ptr */
388 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
390 /* see ifdef_stack_ptr */
391 int ifdef_stack[IFDEF_STACK_SIZE];
394 /* The current value can be: */
395 #define VT_VALMASK 0x00ff
396 #define VT_CONST 0x00f0 /* constant in vc
397 (must be first non register value) */
398 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
399 #define VT_LOCAL 0x00f2 /* offset on stack */
400 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
401 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
402 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
403 #define VT_LVAL 0x0100 /* var is an lvalue */
404 #define VT_SYM 0x0200 /* a symbol value is added */
405 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
406 char/short stored in integer registers) */
407 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
408 dereferencing value */
409 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
410 bounding function call point is in vc */
411 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
412 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
413 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
414 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
416 /* types */
417 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
419 #define VT_INT 0 /* integer type */
420 #define VT_BYTE 1 /* signed byte type */
421 #define VT_SHORT 2 /* short type */
422 #define VT_VOID 3 /* void type */
423 #define VT_PTR 4 /* pointer */
424 #define VT_ENUM 5 /* enum definition */
425 #define VT_FUNC 6 /* function type */
426 #define VT_STRUCT 7 /* struct/union definition */
427 #define VT_FLOAT 8 /* IEEE float */
428 #define VT_DOUBLE 9 /* IEEE double */
429 #define VT_LDOUBLE 10 /* IEEE long double */
430 #define VT_BOOL 11 /* ISOC99 boolean type */
431 #define VT_LLONG 12 /* 64 bit integer */
432 #define VT_LONG 13 /* long integer (NEVER USED as type, only
433 during parsing) */
434 #define VT_BTYPE 0x000f /* mask for basic type */
435 #define VT_UNSIGNED 0x0010 /* unsigned type */
436 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
437 #define VT_BITFIELD 0x0040 /* bitfield modifier */
439 /* storage */
440 #define VT_EXTERN 0x00000080 /* extern definition */
441 #define VT_STATIC 0x00000100 /* static variable */
442 #define VT_TYPEDEF 0x00000200 /* typedef definition */
444 /* type mask (except storage) */
445 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
447 /* token values */
449 /* warning: the following compare tokens depend on i386 asm code */
450 #define TOK_ULT 0x92
451 #define TOK_UGE 0x93
452 #define TOK_EQ 0x94
453 #define TOK_NE 0x95
454 #define TOK_ULE 0x96
455 #define TOK_UGT 0x97
456 #define TOK_LT 0x9c
457 #define TOK_GE 0x9d
458 #define TOK_LE 0x9e
459 #define TOK_GT 0x9f
461 #define TOK_LAND 0xa0
462 #define TOK_LOR 0xa1
464 #define TOK_DEC 0xa2
465 #define TOK_MID 0xa3 /* inc/dec, to void constant */
466 #define TOK_INC 0xa4
467 #define TOK_UDIV 0xb0 /* unsigned division */
468 #define TOK_UMOD 0xb1 /* unsigned modulo */
469 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
470 #define TOK_CINT 0xb3 /* number in tokc */
471 #define TOK_CCHAR 0xb4 /* char constant in tokc */
472 #define TOK_STR 0xb5 /* pointer to string in tokc */
473 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
474 #define TOK_LCHAR 0xb7
475 #define TOK_LSTR 0xb8
476 #define TOK_CFLOAT 0xb9 /* float constant */
477 #define TOK_LINENUM 0xba /* line number info */
478 #define TOK_CDOUBLE 0xc0 /* double constant */
479 #define TOK_CLDOUBLE 0xc1 /* long double constant */
480 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
481 #define TOK_ADDC1 0xc3 /* add with carry generation */
482 #define TOK_ADDC2 0xc4 /* add with carry use */
483 #define TOK_SUBC1 0xc5 /* add with carry generation */
484 #define TOK_SUBC2 0xc6 /* add with carry use */
485 #define TOK_CUINT 0xc8 /* unsigned int constant */
486 #define TOK_CLLONG 0xc9 /* long long constant */
487 #define TOK_CULLONG 0xca /* unsigned long long constant */
488 #define TOK_ARROW 0xcb
489 #define TOK_DOTS 0xcc /* three dots */
490 #define TOK_SHR 0xcd /* unsigned shift right */
491 #define TOK_PPNUM 0xce /* preprocessor number */
493 #define TOK_SHL 0x01 /* shift left */
494 #define TOK_SAR 0x02 /* signed shift right */
496 /* assignement operators : normal operator or 0x80 */
497 #define TOK_A_MOD 0xa5
498 #define TOK_A_AND 0xa6
499 #define TOK_A_MUL 0xaa
500 #define TOK_A_ADD 0xab
501 #define TOK_A_SUB 0xad
502 #define TOK_A_DIV 0xaf
503 #define TOK_A_XOR 0xde
504 #define TOK_A_OR 0xfc
505 #define TOK_A_SHL 0x81
506 #define TOK_A_SAR 0x82
508 /* WARNING: the content of this string encodes token numbers */
509 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";
511 #define TOK_EOF (-1) /* end of file */
512 #define TOK_LINEFEED 10 /* line feed */
514 /* all identificators and strings have token above that */
515 #define TOK_IDENT 256
517 enum {
518 TOK_LAST = TOK_IDENT - 1,
519 #define DEF(id, str) id,
520 #include "tcctok.h"
521 #undef DEF
524 static const char *tcc_keywords =
525 #define DEF(id, str) str "\0"
526 #include "tcctok.h"
527 #undef DEF
530 #define TOK_UIDENT TOK_DEFINE
532 #ifdef WIN32
533 #define snprintf _snprintf
534 #define vsnprintf _vsnprintf
535 #endif
537 #if defined(WIN32) || defined(TCC_UCLIBC)
538 /* currently incorrect */
539 long double strtold(const char *nptr, char **endptr)
541 return (long double)strtod(nptr, endptr);
543 float strtof(const char *nptr, char **endptr)
545 return (float)strtod(nptr, endptr);
547 #else
548 /* XXX: need to define this to use them in non ISOC99 context */
549 extern float strtof (const char *__nptr, char **__endptr);
550 extern long double strtold (const char *__nptr, char **__endptr);
551 #endif
553 static char *pstrcpy(char *buf, int buf_size, const char *s);
554 static char *pstrcat(char *buf, int buf_size, const char *s);
556 static void next(void);
557 static void next_nomacro(void);
558 static void parse_expr_type(CType *type);
559 static void expr_type(CType *type);
560 static void unary_type(CType *type);
561 static int expr_const(void);
562 static void expr_eq(void);
563 static void gexpr(void);
564 static void decl(int l);
565 static void decl_initializer(CType *type, Section *sec, unsigned long c,
566 int first, int size_only);
567 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
568 int has_init, int v, int scope);
569 int gv(int rc);
570 void gv2(int rc1, int rc2);
571 void move_reg(int r, int s);
572 void save_regs(int n);
573 void save_reg(int r);
574 void vpop(void);
575 void vswap(void);
576 void vdup(void);
577 int get_reg(int rc);
579 static void macro_subst(TokenString *tok_str,
580 Sym **nested_list, int *macro_str);
581 int save_reg_forced(int r);
582 void gen_op(int op);
583 void force_charshort_cast(int t);
584 static void gen_cast(CType *type);
585 void vstore(void);
586 static Sym *sym_find(int v);
587 static Sym *sym_push(int v, CType *type, int r, int c);
589 /* type handling */
590 static int type_size(CType *type, int *a);
591 static inline CType *pointed_type(CType *type);
592 static int pointed_size(CType *type);
593 static int lvalue_type(int t);
594 static int is_compatible_types(CType *type1, CType *type2);
595 static int parse_btype(CType *type, AttributeDef *ad);
596 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
598 void error(const char *fmt, ...);
599 void vpushi(int v);
600 void vset(CType *type, int r, int v);
601 void type_to_str(char *buf, int buf_size,
602 CType *type, const char *varstr);
603 char *get_tok_str(int v, CValue *cv);
604 static Sym *get_sym_ref(CType *type, Section *sec,
605 unsigned long offset, unsigned long size);
606 static Sym *external_global_sym(int v, CType *type, int r);
608 /* section generation */
609 static void section_realloc(Section *sec, unsigned long new_size);
610 static void *section_ptr_add(Section *sec, unsigned long size);
611 static void put_extern_sym(Sym *sym, Section *section,
612 unsigned long value, unsigned long size);
613 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
614 static int put_elf_str(Section *s, const char *sym);
615 static int put_elf_sym(Section *s,
616 unsigned long value, unsigned long size,
617 int info, int other, int shndx, const char *name);
618 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
619 int info, int sh_num, const char *name);
620 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
621 int type, int symbol);
622 static void put_stabs(const char *str, int type, int other, int desc,
623 unsigned long value);
624 static void put_stabs_r(const char *str, int type, int other, int desc,
625 unsigned long value, Section *sec, int sym_index);
626 static void put_stabn(int type, int other, int desc, int value);
627 static void put_stabd(int type, int other, int desc);
628 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
630 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
631 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
632 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
634 /* true if float/double/long double type */
635 static inline int is_float(int t)
637 int bt;
638 bt = t & VT_BTYPE;
639 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
642 #ifdef TCC_TARGET_I386
643 #include "i386-gen.c"
644 #endif
645 #ifdef TCC_TARGET_IL
646 #include "il-gen.c"
647 #endif
649 #ifdef CONFIG_TCC_STATIC
651 #define RTLD_LAZY 0x001
652 #define RTLD_NOW 0x002
653 #define RTLD_GLOBAL 0x100
654 #define RTLD_DEFAULT NULL
656 /* dummy function for profiling */
657 void *dlopen(const char *filename, int flag)
659 return NULL;
662 const char *dlerror(void)
664 return "error";
667 typedef struct TCCSyms {
668 char *str;
669 void *ptr;
670 } TCCSyms;
672 #define TCCSYM(a) { #a, &a, },
674 /* add the symbol you want here if no dynamic linking is done */
675 static TCCSyms tcc_syms[] = {
676 TCCSYM(printf)
677 TCCSYM(fprintf)
678 TCCSYM(fopen)
679 TCCSYM(fclose)
680 { NULL, NULL },
683 void *dlsym(void *handle, const char *symbol)
685 TCCSyms *p;
686 p = tcc_syms;
687 while (p->str != NULL) {
688 if (!strcmp(p->str, symbol))
689 return p->ptr;
690 p++;
692 return NULL;
695 #endif
697 /********************************************************/
699 /* we use our own 'finite' function to avoid potential problems with
700 non standard math libs */
701 /* XXX: endianness dependant */
702 int ieee_finite(double d)
704 int *p = (int *)&d;
705 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
708 /* copy a string and truncate it. */
709 static char *pstrcpy(char *buf, int buf_size, const char *s)
711 char *q, *q_end;
712 int c;
714 if (buf_size > 0) {
715 q = buf;
716 q_end = buf + buf_size - 1;
717 while (q < q_end) {
718 c = *s++;
719 if (c == '\0')
720 break;
721 *q++ = c;
723 *q = '\0';
725 return buf;
728 /* strcat and truncate. */
729 static char *pstrcat(char *buf, int buf_size, const char *s)
731 int len;
732 len = strlen(buf);
733 if (len < buf_size)
734 pstrcpy(buf + len, buf_size - len, s);
735 return buf;
738 /* memory management */
739 #ifdef MEM_DEBUG
740 int mem_cur_size;
741 int mem_max_size;
742 #endif
744 static inline void tcc_free(void *ptr)
746 #ifdef MEM_DEBUG
747 mem_cur_size -= malloc_usable_size(ptr);
748 #endif
749 free(ptr);
752 static void *tcc_malloc(unsigned long size)
754 void *ptr;
755 ptr = malloc(size);
756 if (!ptr && size)
757 error("memory full");
758 #ifdef MEM_DEBUG
759 mem_cur_size += malloc_usable_size(ptr);
760 if (mem_cur_size > mem_max_size)
761 mem_max_size = mem_cur_size;
762 #endif
763 return ptr;
766 static void *tcc_mallocz(unsigned long size)
768 void *ptr;
769 ptr = tcc_malloc(size);
770 memset(ptr, 0, size);
771 return ptr;
774 static inline void *tcc_realloc(void *ptr, unsigned long size)
776 void *ptr1;
777 #ifdef MEM_DEBUG
778 mem_cur_size -= malloc_usable_size(ptr);
779 #endif
780 ptr1 = realloc(ptr, size);
781 #ifdef MEM_DEBUG
782 /* NOTE: count not correct if alloc error, but not critical */
783 mem_cur_size += malloc_usable_size(ptr1);
784 if (mem_cur_size > mem_max_size)
785 mem_max_size = mem_cur_size;
786 #endif
787 return ptr1;
790 static char *tcc_strdup(const char *str)
792 char *ptr;
793 ptr = tcc_malloc(strlen(str) + 1);
794 strcpy(ptr, str);
795 return ptr;
798 #define free(p) use_tcc_free(p)
799 #define malloc(s) use_tcc_malloc(s)
800 #define realloc(p, s) use_tcc_realloc(p, s)
802 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
804 int nb, nb_alloc;
805 void **pp;
807 nb = *nb_ptr;
808 pp = *ptab;
809 /* every power of two we double array size */
810 if ((nb & (nb - 1)) == 0) {
811 if (!nb)
812 nb_alloc = 1;
813 else
814 nb_alloc = nb * 2;
815 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
816 if (!pp)
817 error("memory full");
818 *ptab = pp;
820 pp[nb++] = data;
821 *nb_ptr = nb;
824 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
826 Section *sec;
828 sec = tcc_mallocz(sizeof(Section));
829 pstrcpy(sec->name, sizeof(sec->name), name);
830 sec->sh_type = sh_type;
831 sec->sh_flags = sh_flags;
832 switch(sh_type) {
833 case SHT_HASH:
834 case SHT_REL:
835 case SHT_DYNSYM:
836 case SHT_SYMTAB:
837 case SHT_DYNAMIC:
838 sec->sh_addralign = 4;
839 break;
840 case SHT_STRTAB:
841 sec->sh_addralign = 1;
842 break;
843 default:
844 sec->sh_addralign = 32; /* default conservative alignment */
845 break;
848 /* only add section if not private */
849 if (!(sh_flags & SHF_PRIVATE)) {
850 sec->sh_num = s1->nb_sections;
851 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
853 return sec;
856 static void free_section(Section *s)
858 tcc_free(s->data);
859 tcc_free(s);
862 /* realloc section and set its content to zero */
863 static void section_realloc(Section *sec, unsigned long new_size)
865 unsigned long size;
866 unsigned char *data;
868 size = sec->data_allocated;
869 if (size == 0)
870 size = 1;
871 while (size < new_size)
872 size = size * 2;
873 data = tcc_realloc(sec->data, size);
874 if (!data)
875 error("memory full");
876 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
877 sec->data = data;
878 sec->data_allocated = size;
881 /* reserve at least 'size' bytes in section 'sec' from
882 sec->data_offset. */
883 static void *section_ptr_add(Section *sec, unsigned long size)
885 unsigned long offset, offset1;
887 offset = sec->data_offset;
888 offset1 = offset + size;
889 if (offset1 > sec->data_allocated)
890 section_realloc(sec, offset1);
891 sec->data_offset = offset1;
892 return sec->data + offset;
895 /* return a reference to a section, and create it if it does not
896 exists */
897 Section *find_section(TCCState *s1, const char *name)
899 Section *sec;
900 int i;
901 for(i = 1; i < s1->nb_sections; i++) {
902 sec = s1->sections[i];
903 if (!strcmp(name, sec->name))
904 return sec;
906 /* sections are created as PROGBITS */
907 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
910 /* update sym->c so that it points to an external symbol in section
911 'section' with value 'value' */
912 static void put_extern_sym(Sym *sym, Section *section,
913 unsigned long value, unsigned long size)
915 int sym_type, sym_bind, sh_num, info;
916 Elf32_Sym *esym;
917 const char *name;
919 if (section)
920 sh_num = section->sh_num;
921 else
922 sh_num = SHN_UNDEF;
923 if (!sym->c) {
924 if ((sym->type.t & VT_BTYPE) == VT_FUNC)
925 sym_type = STT_FUNC;
926 else
927 sym_type = STT_OBJECT;
928 if (sym->type.t & VT_STATIC)
929 sym_bind = STB_LOCAL;
930 else
931 sym_bind = STB_GLOBAL;
933 name = get_tok_str(sym->v, NULL);
934 #ifdef CONFIG_TCC_BCHECK
935 if (do_bounds_check) {
936 char buf[32];
938 /* XXX: avoid doing that for statics ? */
939 /* if bound checking is activated, we change some function
940 names by adding the "__bound" prefix */
941 switch(sym->v) {
942 #if 0
943 /* XXX: we rely only on malloc hooks */
944 case TOK_malloc:
945 case TOK_free:
946 case TOK_realloc:
947 case TOK_memalign:
948 case TOK_calloc:
949 #endif
950 case TOK_memcpy:
951 case TOK_memmove:
952 case TOK_memset:
953 case TOK_strlen:
954 case TOK_strcpy:
955 strcpy(buf, "__bound_");
956 strcat(buf, name);
957 name = buf;
958 break;
961 #endif
962 info = ELF32_ST_INFO(sym_bind, sym_type);
963 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
964 } else {
965 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
966 esym->st_value = value;
967 esym->st_size = size;
968 esym->st_shndx = sh_num;
972 /* add a new relocation entry to symbol 'sym' in section 's' */
973 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
975 if (!sym->c)
976 put_extern_sym(sym, NULL, 0, 0);
977 /* now we can add ELF relocation info */
978 put_elf_reloc(symtab_section, s, offset, type, sym->c);
981 static inline int isid(int c)
983 return (c >= 'a' && c <= 'z') ||
984 (c >= 'A' && c <= 'Z') ||
985 c == '_';
988 static inline int isnum(int c)
990 return c >= '0' && c <= '9';
993 static inline int isoct(int c)
995 return c >= '0' && c <= '7';
998 static inline int toup(int c)
1000 if (c >= 'a' && c <= 'z')
1001 return c - 'a' + 'A';
1002 else
1003 return c;
1006 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
1008 int len;
1009 len = strlen(buf);
1010 vsnprintf(buf + len, buf_size - len, fmt, ap);
1013 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
1015 va_list ap;
1016 va_start(ap, fmt);
1017 strcat_vprintf(buf, buf_size, fmt, ap);
1018 va_end(ap);
1021 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
1023 char buf[2048];
1024 BufferedFile **f;
1026 buf[0] = '\0';
1027 if (file) {
1028 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1029 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1030 (*f)->filename, (*f)->line_num);
1031 if (file->line_num > 0) {
1032 strcat_printf(buf, sizeof(buf),
1033 "%s:%d: ", file->filename, file->line_num);
1034 } else {
1035 strcat_printf(buf, sizeof(buf),
1036 "%s: ", file->filename);
1038 } else {
1039 strcat_printf(buf, sizeof(buf),
1040 "tcc: ");
1042 if (is_warning)
1043 strcat_printf(buf, sizeof(buf), "warning: ");
1044 strcat_vprintf(buf, sizeof(buf), fmt, ap);
1046 if (!s1->error_func) {
1047 /* default case: stderr */
1048 fprintf(stderr, "%s\n", buf);
1049 } else {
1050 s1->error_func(s1->error_opaque, buf);
1052 if (!is_warning)
1053 s1->nb_errors++;
1056 #ifdef LIBTCC
1057 void tcc_set_error_func(TCCState *s, void *error_opaque,
1058 void (*error_func)(void *opaque, const char *msg))
1060 s->error_opaque = error_opaque;
1061 s->error_func = error_func;
1063 #endif
1065 /* error without aborting current compilation */
1066 void error_noabort(const char *fmt, ...)
1068 TCCState *s1 = tcc_state;
1069 va_list ap;
1071 va_start(ap, fmt);
1072 error1(s1, 0, fmt, ap);
1073 va_end(ap);
1076 void error(const char *fmt, ...)
1078 TCCState *s1 = tcc_state;
1079 va_list ap;
1081 va_start(ap, fmt);
1082 error1(s1, 0, fmt, ap);
1083 va_end(ap);
1084 /* better than nothing: in some cases, we accept to handle errors */
1085 if (s1->error_set_jmp_enabled) {
1086 longjmp(s1->error_jmp_buf, 1);
1087 } else {
1088 /* XXX: suppress it someday */
1089 exit(1);
1093 void expect(const char *msg)
1095 error("%s expected", msg);
1098 void warning(const char *fmt, ...)
1100 TCCState *s1 = tcc_state;
1101 va_list ap;
1103 va_start(ap, fmt);
1104 error1(s1, 1, fmt, ap);
1105 va_end(ap);
1108 void skip(int c)
1110 if (tok != c)
1111 error("'%c' expected", c);
1112 next();
1115 void test_lvalue(void)
1117 if (!(vtop->r & VT_LVAL))
1118 expect("lvalue");
1121 /* allocate a new token */
1122 static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
1124 TokenSym *ts, **ptable;
1125 int i;
1127 if (tok_ident >= SYM_FIRST_ANOM)
1128 error("memory full");
1130 /* expand token table if needed */
1131 i = tok_ident - TOK_IDENT;
1132 if ((i % TOK_ALLOC_INCR) == 0) {
1133 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1134 if (!ptable)
1135 error("memory full");
1136 table_ident = ptable;
1139 ts = tcc_malloc(sizeof(TokenSym) + len);
1140 table_ident[i] = ts;
1141 ts->tok = tok_ident++;
1142 ts->sym_define = NULL;
1143 ts->sym_label = NULL;
1144 ts->sym_struct = NULL;
1145 ts->sym_identifier = NULL;
1146 ts->len = len;
1147 ts->hash_next = NULL;
1148 memcpy(ts->str, str, len);
1149 ts->str[len] = '\0';
1150 *pts = ts;
1151 return ts;
1154 #define TOK_HASH_INIT 1
1155 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1157 /* find a token and add it if not found */
1158 static TokenSym *tok_alloc(const char *str, int len)
1160 TokenSym *ts, **pts;
1161 int i;
1162 unsigned int h;
1164 h = TOK_HASH_INIT;
1165 for(i=0;i<len;i++)
1166 h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
1167 h &= (TOK_HASH_SIZE - 1);
1169 pts = &hash_ident[h];
1170 for(;;) {
1171 ts = *pts;
1172 if (!ts)
1173 break;
1174 if (ts->len == len && !memcmp(ts->str, str, len))
1175 return ts;
1176 pts = &(ts->hash_next);
1178 return tok_alloc_new(pts, str, len);
1181 /* CString handling */
1183 static void cstr_realloc(CString *cstr, int new_size)
1185 int size;
1186 void *data;
1188 size = cstr->size_allocated;
1189 if (size == 0)
1190 size = 8; /* no need to allocate a too small first string */
1191 while (size < new_size)
1192 size = size * 2;
1193 data = tcc_realloc(cstr->data_allocated, size);
1194 if (!data)
1195 error("memory full");
1196 cstr->data_allocated = data;
1197 cstr->size_allocated = size;
1198 cstr->data = data;
1201 /* add a byte */
1202 static void cstr_ccat(CString *cstr, int ch)
1204 int size;
1205 size = cstr->size + 1;
1206 if (size > cstr->size_allocated)
1207 cstr_realloc(cstr, size);
1208 ((unsigned char *)cstr->data)[size - 1] = ch;
1209 cstr->size = size;
1212 static void cstr_cat(CString *cstr, const char *str)
1214 int c;
1215 for(;;) {
1216 c = *str;
1217 if (c == '\0')
1218 break;
1219 cstr_ccat(cstr, c);
1220 str++;
1224 /* add a wide char */
1225 static void cstr_wccat(CString *cstr, int ch)
1227 int size;
1228 size = cstr->size + sizeof(int);
1229 if (size > cstr->size_allocated)
1230 cstr_realloc(cstr, size);
1231 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1232 cstr->size = size;
1235 static void cstr_new(CString *cstr)
1237 memset(cstr, 0, sizeof(CString));
1240 /* free string and reset it to NULL */
1241 static void cstr_free(CString *cstr)
1243 tcc_free(cstr->data_allocated);
1244 cstr_new(cstr);
1247 #define cstr_reset(cstr) cstr_free(cstr)
1249 static CString *cstr_dup(CString *cstr1)
1251 CString *cstr;
1252 int size;
1254 cstr = tcc_malloc(sizeof(CString));
1255 size = cstr1->size;
1256 cstr->size = size;
1257 cstr->size_allocated = size;
1258 cstr->data_allocated = tcc_malloc(size);
1259 cstr->data = cstr->data_allocated;
1260 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1261 return cstr;
1264 /* XXX: unicode ? */
1265 static void add_char(CString *cstr, int c)
1267 if (c == '\'' || c == '\"' || c == '\\') {
1268 /* XXX: could be more precise if char or string */
1269 cstr_ccat(cstr, '\\');
1271 if (c >= 32 && c <= 126) {
1272 cstr_ccat(cstr, c);
1273 } else {
1274 cstr_ccat(cstr, '\\');
1275 if (c == '\n') {
1276 cstr_ccat(cstr, 'n');
1277 } else {
1278 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1279 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1280 cstr_ccat(cstr, '0' + (c & 7));
1285 /* XXX: buffer overflow */
1286 /* XXX: float tokens */
1287 char *get_tok_str(int v, CValue *cv)
1289 static char buf[STRING_MAX_SIZE + 1];
1290 static CString cstr_buf;
1291 CString *cstr;
1292 unsigned char *q;
1293 char *p;
1294 int i, len;
1296 /* NOTE: to go faster, we give a fixed buffer for small strings */
1297 cstr_reset(&cstr_buf);
1298 cstr_buf.data = buf;
1299 cstr_buf.size_allocated = sizeof(buf);
1300 p = buf;
1302 switch(v) {
1303 case TOK_CINT:
1304 case TOK_CUINT:
1305 /* XXX: not quite exact, but only useful for testing */
1306 sprintf(p, "%u", cv->ui);
1307 break;
1308 case TOK_CLLONG:
1309 case TOK_CULLONG:
1310 /* XXX: not quite exact, but only useful for testing */
1311 sprintf(p, "%Lu", cv->ull);
1312 break;
1313 case TOK_CCHAR:
1314 case TOK_LCHAR:
1315 cstr_ccat(&cstr_buf, '\'');
1316 add_char(&cstr_buf, cv->i);
1317 cstr_ccat(&cstr_buf, '\'');
1318 cstr_ccat(&cstr_buf, '\0');
1319 break;
1320 case TOK_PPNUM:
1321 cstr = cv->cstr;
1322 len = cstr->size - 1;
1323 for(i=0;i<len;i++)
1324 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1325 cstr_ccat(&cstr_buf, '\0');
1326 break;
1327 case TOK_STR:
1328 case TOK_LSTR:
1329 cstr = cv->cstr;
1330 cstr_ccat(&cstr_buf, '\"');
1331 if (v == TOK_STR) {
1332 len = cstr->size - 1;
1333 for(i=0;i<len;i++)
1334 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1335 } else {
1336 len = (cstr->size / sizeof(int)) - 1;
1337 for(i=0;i<len;i++)
1338 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1340 cstr_ccat(&cstr_buf, '\"');
1341 cstr_ccat(&cstr_buf, '\0');
1342 break;
1343 case TOK_LT:
1344 v = '<';
1345 goto addv;
1346 case TOK_GT:
1347 v = '>';
1348 goto addv;
1349 case TOK_A_SHL:
1350 return strcpy(p, "<<=");
1351 case TOK_A_SAR:
1352 return strcpy(p, ">>=");
1353 default:
1354 if (v < TOK_IDENT) {
1355 /* search in two bytes table */
1356 q = tok_two_chars;
1357 while (*q) {
1358 if (q[2] == v) {
1359 *p++ = q[0];
1360 *p++ = q[1];
1361 *p = '\0';
1362 return buf;
1364 q += 3;
1366 addv:
1367 *p++ = v;
1368 *p = '\0';
1369 } else if (v < tok_ident) {
1370 return table_ident[v - TOK_IDENT]->str;
1371 } else if (v >= SYM_FIRST_ANOM) {
1372 /* special name for anonymous symbol */
1373 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1374 } else {
1375 /* should never happen */
1376 return NULL;
1378 break;
1380 return cstr_buf.data;
1383 /* push, without hashing */
1384 static Sym *sym_push2(Sym **ps, int v, int t, int c)
1386 Sym *s;
1387 s = tcc_malloc(sizeof(Sym));
1388 s->v = v;
1389 s->type.t = t;
1390 s->c = c;
1391 s->next = NULL;
1392 /* add in stack */
1393 s->prev = *ps;
1394 *ps = s;
1395 return s;
1398 /* find a symbol and return its associated structure. 's' is the top
1399 of the symbol stack */
1400 static Sym *sym_find2(Sym *s, int v)
1402 while (s) {
1403 if (s->v == v)
1404 return s;
1405 s = s->prev;
1407 return NULL;
1410 /* structure lookup */
1411 static Sym *struct_find(int v)
1413 v -= TOK_IDENT;
1414 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1415 return NULL;
1416 return table_ident[v]->sym_struct;
1419 /* find an identifier */
1420 static inline Sym *sym_find(int v)
1422 v -= TOK_IDENT;
1423 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1424 return NULL;
1425 return table_ident[v]->sym_identifier;
1428 /* push a given symbol on the symbol stack */
1429 static Sym *sym_push(int v, CType *type, int r, int c)
1431 Sym *s, **ps;
1432 TokenSym *ts;
1434 if (local_stack)
1435 ps = &local_stack;
1436 else
1437 ps = &global_stack;
1438 s = sym_push2(ps, v, type->t, c);
1439 s->type.ref = type->ref;
1440 s->r = r;
1441 /* don't record fields or anonymous symbols */
1442 /* XXX: simplify */
1443 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1444 /* record symbol in token array */
1445 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1446 if (v & SYM_STRUCT)
1447 ps = &ts->sym_struct;
1448 else
1449 ps = &ts->sym_identifier;
1450 s->prev_tok = *ps;
1451 *ps = s;
1453 return s;
1456 /* push a global identifier */
1457 static Sym *global_identifier_push(int v, int t, int c)
1459 Sym *s, **ps;
1460 s = sym_push2(&global_stack, v, t, c);
1461 /* don't record anonymous symbol */
1462 if (v < SYM_FIRST_ANOM) {
1463 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1464 /* modify the top most local identifier, so that
1465 sym_identifier will point to 's' when popped */
1466 while (*ps != NULL)
1467 ps = &(*ps)->prev_tok;
1468 s->prev_tok = NULL;
1469 *ps = s;
1471 return s;
1474 /* pop symbols until top reaches 'b' */
1475 static void sym_pop(Sym **ptop, Sym *b)
1477 Sym *s, *ss, **ps;
1478 TokenSym *ts;
1479 int v;
1481 s = *ptop;
1482 while(s != b) {
1483 ss = s->prev;
1484 v = s->v;
1485 /* remove symbol in token array */
1486 /* XXX: simplify */
1487 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1488 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1489 if (v & SYM_STRUCT)
1490 ps = &ts->sym_struct;
1491 else
1492 ps = &ts->sym_identifier;
1493 *ps = s->prev_tok;
1495 tcc_free(s);
1496 s = ss;
1498 *ptop = b;
1501 /* I/O layer */
1503 BufferedFile *tcc_open(TCCState *s1, const char *filename)
1505 int fd;
1506 BufferedFile *bf;
1508 fd = open(filename, O_RDONLY);
1509 if (fd < 0)
1510 return NULL;
1511 bf = tcc_malloc(sizeof(BufferedFile));
1512 if (!bf) {
1513 close(fd);
1514 return NULL;
1516 bf->fd = fd;
1517 bf->buf_ptr = bf->buffer;
1518 bf->buf_end = bf->buffer;
1519 bf->buffer[0] = CH_EOB; /* put eob symbol */
1520 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1521 bf->line_num = 1;
1522 bf->ifndef_macro = 0;
1523 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1524 // printf("opening '%s'\n", filename);
1525 return bf;
1528 void tcc_close(BufferedFile *bf)
1530 total_lines += bf->line_num;
1531 close(bf->fd);
1532 tcc_free(bf);
1535 /* fill input buffer and peek next char */
1536 static int tcc_peekc_slow(BufferedFile *bf)
1538 int len;
1539 /* only tries to read if really end of buffer */
1540 if (bf->buf_ptr >= bf->buf_end) {
1541 if (bf->fd != -1) {
1542 #if defined(PARSE_DEBUG)
1543 len = 8;
1544 #else
1545 len = IO_BUF_SIZE;
1546 #endif
1547 len = read(bf->fd, bf->buffer, len);
1548 if (len < 0)
1549 len = 0;
1550 } else {
1551 len = 0;
1553 total_bytes += len;
1554 bf->buf_ptr = bf->buffer;
1555 bf->buf_end = bf->buffer + len;
1556 *bf->buf_end = CH_EOB;
1558 if (bf->buf_ptr < bf->buf_end) {
1559 return bf->buf_ptr[0];
1560 } else {
1561 bf->buf_ptr = bf->buf_end;
1562 return CH_EOF;
1566 /* return the current character, handling end of block if necessary
1567 (but not stray) */
1568 static int handle_eob(void)
1570 return tcc_peekc_slow(file);
1573 /* read next char from current input file and handle end of input buffer */
1574 static inline void inp(void)
1576 ch = *(++(file->buf_ptr));
1577 /* end of buffer/file handling */
1578 if (ch == CH_EOB)
1579 ch = handle_eob();
1582 /* handle '\[\r]\n' */
1583 static void handle_stray(void)
1585 while (ch == '\\') {
1586 inp();
1587 if (ch == '\n') {
1588 file->line_num++;
1589 inp();
1590 } else if (ch == '\r') {
1591 inp();
1592 if (ch != '\n')
1593 goto fail;
1594 file->line_num++;
1595 inp();
1596 } else {
1597 fail:
1598 error("stray '\\' in program");
1603 /* skip the stray and handle the \\n case. Output an error if
1604 incorrect char after the stray */
1605 static int handle_stray1(uint8_t *p)
1607 int c;
1609 if (p >= file->buf_end) {
1610 file->buf_ptr = p;
1611 c = handle_eob();
1612 p = file->buf_ptr;
1613 if (c == '\\')
1614 goto parse_stray;
1615 } else {
1616 parse_stray:
1617 file->buf_ptr = p;
1618 ch = *p;
1619 handle_stray();
1620 p = file->buf_ptr;
1621 c = *p;
1623 return c;
1626 /* handle the complicated stray case */
1627 #define PEEKC(c, p)\
1629 p++;\
1630 c = *p;\
1631 if (c == '\\') {\
1632 c = handle_stray1(p);\
1633 p = file->buf_ptr;\
1637 /* input with '\[\r]\n' handling. Note that this function cannot
1638 handle other characters after '\', so you cannot call it inside
1639 strings or comments */
1640 static void minp(void)
1642 inp();
1643 if (ch == '\\')
1644 handle_stray();
1648 static void parse_line_comment(void)
1650 /* single line C++ comments */
1651 /* XXX: accept '\\\n' ? */
1652 inp();
1653 while (ch != '\n' && ch != CH_EOF)
1654 inp();
1657 static void parse_comment(void)
1659 uint8_t *p;
1660 int c;
1662 /* C comments */
1663 p = file->buf_ptr;
1664 p++;
1665 for(;;) {
1666 /* fast skip loop */
1667 for(;;) {
1668 c = *p;
1669 if (c == '\n' || c == '*' || c == '\\')
1670 break;
1671 p++;
1672 c = *p;
1673 if (c == '\n' || c == '*' || c == '\\')
1674 break;
1675 p++;
1677 /* now we can handle all the cases */
1678 if (c == '\n') {
1679 file->line_num++;
1680 p++;
1681 } else if (c == '*') {
1682 p++;
1683 for(;;) {
1684 c = *p;
1685 if (c == '*') {
1686 p++;
1687 } else if (c == '/') {
1688 goto end_of_comment;
1689 } else if (c == '\\') {
1690 file->buf_ptr = p;
1691 c = handle_eob();
1692 if (c == '\\') {
1693 /* skip '\\n', but if '\' followed but another
1694 char, behave asif a stray was parsed */
1695 ch = file->buf_ptr[0];
1696 while (ch == '\\') {
1697 inp();
1698 if (ch == '\n') {
1699 file->line_num++;
1700 inp();
1701 } else if (ch == '\r') {
1702 inp();
1703 if (ch == '\n') {
1704 file->line_num++;
1705 inp();
1707 } else {
1708 p = file->buf_ptr;
1709 break;
1713 p = file->buf_ptr;
1714 } else {
1715 break;
1718 } else {
1719 /* stray, eob or eof */
1720 file->buf_ptr = p;
1721 c = handle_eob();
1722 p = file->buf_ptr;
1723 if (c == CH_EOF) {
1724 error("unexpected end of file in comment");
1725 } else if (c == '\\') {
1726 p++;
1730 end_of_comment:
1731 p++;
1732 file->buf_ptr = p;
1733 ch = *p;
1736 #define cinp minp
1738 /* space exlcuding newline */
1739 static inline int is_space(int ch)
1741 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1744 static inline void skip_spaces(void)
1746 while (is_space(ch))
1747 cinp();
1750 /* skip block of text until #else, #elif or #endif. skip also pairs of
1751 #if/#endif */
1752 void preprocess_skip(void)
1754 int a, start_of_line, sep, c;
1755 uint8_t *p;
1757 p = file->buf_ptr;
1758 start_of_line = 1;
1759 a = 0;
1760 for(;;) {
1761 redo_no_start:
1762 c = *p;
1763 switch(c) {
1764 case ' ':
1765 case '\t':
1766 case '\f':
1767 case '\v':
1768 case '\r':
1769 p++;
1770 goto redo_no_start;
1771 case '\n':
1772 start_of_line = 1;
1773 file->line_num++;
1774 p++;
1775 goto redo_no_start;
1776 case '\\':
1777 file->buf_ptr = p;
1778 c = handle_eob();
1779 if (c == CH_EOF) {
1780 expect("#endif");
1781 } else if (c == '\\') {
1782 /* XXX: incorrect: should not give an error */
1783 ch = file->buf_ptr[0];
1784 handle_stray();
1786 p = file->buf_ptr;
1787 goto redo_no_start;
1788 /* skip strings */
1789 case '\"':
1790 case '\'':
1791 sep = c;
1792 p++;
1793 for(;;) {
1794 c = *p;
1795 if (c == sep) {
1796 break;
1797 } else if (c == '\\') {
1798 file->buf_ptr = p;
1799 c = handle_eob();
1800 p = file->buf_ptr;
1801 if (c == CH_EOF) {
1802 /* XXX: better error message */
1803 error("unterminated string");
1804 } else if (c == '\\') {
1805 /* ignore next char */
1806 p++;
1807 c = *p;
1808 if (c == '\\') {
1809 file->buf_ptr = p;
1810 c = handle_eob();
1811 p = file->buf_ptr;
1813 if (c == '\n')
1814 file->line_num++;
1815 else if (c != CH_EOF)
1816 p++;
1818 } else if (c == '\n') {
1819 file->line_num++;
1820 p++;
1821 } else {
1822 p++;
1825 p++;
1826 break;
1827 /* skip comments */
1828 case '/':
1829 file->buf_ptr = p;
1830 ch = *p;
1831 minp();
1832 if (ch == '*') {
1833 parse_comment();
1834 } else if (ch == '/') {
1835 parse_line_comment();
1837 p = file->buf_ptr;
1838 break;
1840 case '#':
1841 p++;
1842 if (start_of_line) {
1843 file->buf_ptr = p;
1844 next_nomacro();
1845 p = file->buf_ptr;
1846 if (a == 0 &&
1847 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1848 goto the_end;
1849 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1850 a++;
1851 else if (tok == TOK_ENDIF)
1852 a--;
1854 break;
1855 default:
1856 p++;
1857 break;
1859 start_of_line = 0;
1861 the_end: ;
1862 file->buf_ptr = p;
1865 /* ParseState handling */
1867 /* XXX: currently, no include file info is stored. Thus, we cannot display
1868 accurate messages if the function or data definition spans multiple
1869 files */
1871 /* save current parse state in 's' */
1872 void save_parse_state(ParseState *s)
1874 s->line_num = file->line_num;
1875 s->macro_ptr = macro_ptr;
1876 s->tok = tok;
1877 s->tokc = tokc;
1880 /* restore parse state from 's' */
1881 void restore_parse_state(ParseState *s)
1883 file->line_num = s->line_num;
1884 macro_ptr = s->macro_ptr;
1885 tok = s->tok;
1886 tokc = s->tokc;
1889 /* return the number of additionnal 'ints' necessary to store the
1890 token */
1891 static inline int tok_ext_size(int t)
1893 switch(t) {
1894 /* 4 bytes */
1895 case TOK_CINT:
1896 case TOK_CUINT:
1897 case TOK_CCHAR:
1898 case TOK_LCHAR:
1899 case TOK_STR:
1900 case TOK_LSTR:
1901 case TOK_CFLOAT:
1902 case TOK_LINENUM:
1903 case TOK_PPNUM:
1904 return 1;
1905 case TOK_CDOUBLE:
1906 case TOK_CLLONG:
1907 case TOK_CULLONG:
1908 return 2;
1909 case TOK_CLDOUBLE:
1910 return LDOUBLE_SIZE / 4;
1911 default:
1912 return 0;
1916 /* token string handling */
1918 static inline void tok_str_new(TokenString *s)
1920 s->str = NULL;
1921 s->len = 0;
1922 s->allocated_len = 0;
1923 s->last_line_num = -1;
1926 static void tok_str_free(int *str)
1928 const int *p;
1929 CString *cstr;
1930 int t;
1932 p = str;
1933 for(;;) {
1934 t = *p;
1935 /* NOTE: we test zero separately so that GCC can generate a
1936 table for the following switch */
1937 if (t == 0)
1938 break;
1939 switch(t) {
1940 case TOK_CINT:
1941 case TOK_CUINT:
1942 case TOK_CCHAR:
1943 case TOK_LCHAR:
1944 case TOK_CFLOAT:
1945 case TOK_LINENUM:
1946 p += 2;
1947 break;
1948 case TOK_PPNUM:
1949 case TOK_STR:
1950 case TOK_LSTR:
1951 /* XXX: use a macro to be portable on 64 bit ? */
1952 cstr = (CString *)p[1];
1953 cstr_free(cstr);
1954 tcc_free(cstr);
1955 p += 2;
1956 break;
1957 case TOK_CDOUBLE:
1958 case TOK_CLLONG:
1959 case TOK_CULLONG:
1960 p += 3;
1961 break;
1962 case TOK_CLDOUBLE:
1963 p += 1 + (LDOUBLE_SIZE / 4);
1964 break;
1965 default:
1966 p++;
1967 break;
1970 tcc_free(str);
1973 static int *tok_str_realloc(TokenString *s)
1975 int *str, len;
1977 len = s->allocated_len + TOK_STR_ALLOC_INCR;
1978 str = tcc_realloc(s->str, len * sizeof(int));
1979 if (!str)
1980 error("memory full");
1981 s->allocated_len = len;
1982 s->str = str;
1983 return str;
1986 static void tok_str_add(TokenString *s, int t)
1988 int len, *str;
1990 len = s->len;
1991 str = s->str;
1992 if (len >= s->allocated_len)
1993 str = tok_str_realloc(s);
1994 str[len++] = t;
1995 s->len = len;
1998 static void tok_str_add2(TokenString *s, int t, CValue *cv)
2000 int len, *str;
2002 len = s->len;
2003 str = s->str;
2005 /* allocate space for worst case */
2006 if (len + TOK_MAX_SIZE > s->allocated_len)
2007 str = tok_str_realloc(s);
2008 str[len++] = t;
2009 switch(t) {
2010 case TOK_CINT:
2011 case TOK_CUINT:
2012 case TOK_CCHAR:
2013 case TOK_LCHAR:
2014 case TOK_CFLOAT:
2015 case TOK_LINENUM:
2016 str[len++] = cv->tab[0];
2017 break;
2018 case TOK_PPNUM:
2019 case TOK_STR:
2020 case TOK_LSTR:
2021 str[len++] = (int)cstr_dup(cv->cstr);
2022 break;
2023 case TOK_CDOUBLE:
2024 case TOK_CLLONG:
2025 case TOK_CULLONG:
2026 str[len++] = cv->tab[0];
2027 str[len++] = cv->tab[1];
2028 break;
2029 case TOK_CLDOUBLE:
2030 #if LDOUBLE_SIZE == 12
2031 str[len++] = cv->tab[0];
2032 str[len++] = cv->tab[1];
2033 str[len++] = cv->tab[2];
2034 #else
2035 #error add long double size support
2036 #endif
2037 break;
2038 default:
2039 break;
2041 s->len = len;
2044 /* add the current parse token in token string 's' */
2045 static void tok_str_add_tok(TokenString *s)
2047 CValue cval;
2049 /* save line number info */
2050 if (file->line_num != s->last_line_num) {
2051 s->last_line_num = file->line_num;
2052 cval.i = s->last_line_num;
2053 tok_str_add2(s, TOK_LINENUM, &cval);
2055 tok_str_add2(s, tok, &tokc);
2058 #if LDOUBLE_SIZE == 12
2059 #define LDOUBLE_GET(p, cv) \
2060 cv.tab[0] = p[0]; \
2061 cv.tab[1] = p[1]; \
2062 cv.tab[2] = p[2];
2063 #else
2064 #error add long double size support
2065 #endif
2068 /* get a token from an integer array and increment pointer
2069 accordingly. we code it as a macro to avoid pointer aliasing. */
2070 #define TOK_GET(t, p, cv) \
2072 t = *p++; \
2073 switch(t) { \
2074 case TOK_CINT: \
2075 case TOK_CUINT: \
2076 case TOK_CCHAR: \
2077 case TOK_LCHAR: \
2078 case TOK_CFLOAT: \
2079 case TOK_LINENUM: \
2080 case TOK_STR: \
2081 case TOK_LSTR: \
2082 case TOK_PPNUM: \
2083 cv.tab[0] = *p++; \
2084 break; \
2085 case TOK_CDOUBLE: \
2086 case TOK_CLLONG: \
2087 case TOK_CULLONG: \
2088 cv.tab[0] = p[0]; \
2089 cv.tab[1] = p[1]; \
2090 p += 2; \
2091 break; \
2092 case TOK_CLDOUBLE: \
2093 LDOUBLE_GET(p, cv); \
2094 p += LDOUBLE_SIZE / 4; \
2095 break; \
2096 default: \
2097 break; \
2101 /* defines handling */
2102 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
2104 Sym *s;
2106 s = sym_push2(&define_stack, v, macro_type, (int)str);
2107 s->next = first_arg;
2108 table_ident[v - TOK_IDENT]->sym_define = s;
2111 /* undefined a define symbol. Its name is just set to zero */
2112 static void define_undef(Sym *s)
2114 int v;
2115 v = s->v;
2116 if (v >= TOK_IDENT && v < tok_ident)
2117 table_ident[v - TOK_IDENT]->sym_define = NULL;
2118 s->v = 0;
2121 static inline Sym *define_find(int v)
2123 v -= TOK_IDENT;
2124 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2125 return NULL;
2126 return table_ident[v]->sym_define;
2129 /* free define stack until top reaches 'b' */
2130 static void free_defines(Sym *b)
2132 Sym *top, *top1;
2133 int v;
2135 top = define_stack;
2136 while (top != b) {
2137 top1 = top->prev;
2138 /* do not free args or predefined defines */
2139 if (top->c)
2140 tok_str_free((int *)top->c);
2141 v = top->v;
2142 if (v >= TOK_IDENT && v < tok_ident)
2143 table_ident[v - TOK_IDENT]->sym_define = NULL;
2144 tcc_free(top);
2145 top = top1;
2147 define_stack = b;
2150 /* label lookup */
2151 static Sym *label_find(int v)
2153 v -= TOK_IDENT;
2154 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2155 return NULL;
2156 return table_ident[v]->sym_label;
2159 static Sym *label_push(int v, int flags)
2161 Sym *s;
2162 s = sym_push2(&label_stack, v, 0, 0);
2163 s->r = flags;
2164 table_ident[v - TOK_IDENT]->sym_label = s;
2165 return s;
2168 /* eval an expression for #if/#elif */
2169 static int expr_preprocess(void)
2171 int c, t;
2172 TokenString str;
2174 tok_str_new(&str);
2175 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2176 next(); /* do macro subst */
2177 if (tok == TOK_DEFINED) {
2178 next_nomacro();
2179 t = tok;
2180 if (t == '(')
2181 next_nomacro();
2182 c = define_find(tok) != 0;
2183 if (t == '(')
2184 next_nomacro();
2185 tok = TOK_CINT;
2186 tokc.i = c;
2187 } else if (tok >= TOK_IDENT) {
2188 /* if undefined macro */
2189 tok = TOK_CINT;
2190 tokc.i = 0;
2192 tok_str_add_tok(&str);
2194 tok_str_add(&str, -1); /* simulate end of file */
2195 tok_str_add(&str, 0);
2196 /* now evaluate C constant expression */
2197 macro_ptr = str.str;
2198 next();
2199 c = expr_const();
2200 macro_ptr = NULL;
2201 tok_str_free(str.str);
2202 return c != 0;
2205 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2206 static void tok_print(int *str)
2208 int t;
2209 CValue cval;
2211 while (1) {
2212 TOK_GET(t, str, cval);
2213 if (!t)
2214 break;
2215 printf(" %s", get_tok_str(t, &cval));
2217 printf("\n");
2219 #endif
2221 /* parse after #define */
2222 static void parse_define(void)
2224 Sym *s, *first, **ps;
2225 int v, t, varg, is_vaargs, c;
2226 TokenString str;
2228 v = tok;
2229 if (v < TOK_IDENT)
2230 error("invalid macro name '%s'", get_tok_str(tok, &tokc));
2231 /* XXX: should check if same macro (ANSI) */
2232 first = NULL;
2233 t = MACRO_OBJ;
2234 /* '(' must be just after macro definition for MACRO_FUNC */
2235 c = file->buf_ptr[0];
2236 if (c == '\\')
2237 c = handle_stray1(file->buf_ptr);
2238 if (c == '(') {
2239 next_nomacro();
2240 next_nomacro();
2241 ps = &first;
2242 while (tok != ')') {
2243 varg = tok;
2244 next_nomacro();
2245 is_vaargs = 0;
2246 if (varg == TOK_DOTS) {
2247 varg = TOK___VA_ARGS__;
2248 is_vaargs = 1;
2249 } else if (tok == TOK_DOTS && gnu_ext) {
2250 is_vaargs = 1;
2251 next_nomacro();
2253 if (varg < TOK_IDENT)
2254 error("badly punctuated parameter list");
2255 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
2256 *ps = s;
2257 ps = &s->next;
2258 if (tok != ',')
2259 break;
2260 next_nomacro();
2262 t = MACRO_FUNC;
2264 tok_str_new(&str);
2265 next_nomacro();
2266 /* EOF testing necessary for '-D' handling */
2267 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2268 tok_str_add2(&str, tok, &tokc);
2269 next_nomacro();
2271 tok_str_add(&str, 0);
2272 #ifdef PP_DEBUG
2273 printf("define %s %d: ", get_tok_str(v, NULL), t);
2274 tok_print(str.str);
2275 #endif
2276 define_push(v, t, str.str, first);
2279 /* XXX: use a token or a hash table to accelerate matching ? */
2280 static CachedInclude *search_cached_include(TCCState *s1,
2281 int type, const char *filename)
2283 CachedInclude *e;
2284 int i;
2286 for(i = 0;i < s1->nb_cached_includes; i++) {
2287 e = s1->cached_includes[i];
2288 if (e->type == type && !strcmp(e->filename, filename))
2289 return e;
2291 return NULL;
2294 static inline void add_cached_include(TCCState *s1, int type,
2295 const char *filename, int ifndef_macro)
2297 CachedInclude *e;
2299 if (search_cached_include(s1, type, filename))
2300 return;
2301 #ifdef INC_DEBUG
2302 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
2303 #endif
2304 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
2305 if (!e)
2306 return;
2307 e->type = type;
2308 strcpy(e->filename, filename);
2309 e->ifndef_macro = ifndef_macro;
2310 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
2313 /* is_bof is true if first non space token at beginning of file */
2314 static void preprocess(int is_bof)
2316 TCCState *s1 = tcc_state;
2317 int size, i, c, n;
2318 char buf[1024], *q, *p;
2319 char buf1[1024];
2320 BufferedFile *f;
2321 Sym *s;
2322 CachedInclude *e;
2324 return_linefeed = 1; /* linefeed will be returned as a
2325 token. EOF is also returned as line feed */
2326 next_nomacro();
2327 redo:
2328 switch(tok) {
2329 case TOK_DEFINE:
2330 next_nomacro();
2331 parse_define();
2332 break;
2333 case TOK_UNDEF:
2334 next_nomacro();
2335 s = define_find(tok);
2336 /* undefine symbol by putting an invalid name */
2337 if (s)
2338 define_undef(s);
2339 break;
2340 case TOK_INCLUDE:
2341 ch = file->buf_ptr[0];
2342 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2343 skip_spaces();
2344 if (ch == '<') {
2345 c = '>';
2346 goto read_name;
2347 } else if (ch == '\"') {
2348 c = ch;
2349 read_name:
2350 /* XXX: better stray handling */
2351 minp();
2352 q = buf;
2353 while (ch != c && ch != '\n' && ch != CH_EOF) {
2354 if ((q - buf) < sizeof(buf) - 1)
2355 *q++ = ch;
2356 minp();
2358 *q = '\0';
2359 minp();
2360 #if 0
2361 /* eat all spaces and comments after include */
2362 /* XXX: slightly incorrect */
2363 while (ch1 != '\n' && ch1 != CH_EOF)
2364 inp();
2365 #endif
2366 } else {
2367 /* computed #include : either we have only strings or
2368 we have anything enclosed in '<>' */
2369 next();
2370 buf[0] = '\0';
2371 if (tok == TOK_STR) {
2372 while (tok != TOK_LINEFEED) {
2373 if (tok != TOK_STR) {
2374 include_syntax:
2375 error("'#include' expects \"FILENAME\" or <FILENAME>");
2377 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2378 next();
2380 c = '\"';
2381 } else {
2382 int len;
2383 while (tok != TOK_LINEFEED) {
2384 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2385 next();
2387 len = strlen(buf);
2388 /* check syntax and remove '<>' */
2389 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2390 goto include_syntax;
2391 memmove(buf, buf + 1, len - 2);
2392 buf[len - 2] = '\0';
2393 c = '>';
2397 e = search_cached_include(s1, c, buf);
2398 if (e && define_find(e->ifndef_macro)) {
2399 /* no need to parse the include because the 'ifndef macro'
2400 is defined */
2401 #ifdef INC_DEBUG
2402 printf("%s: skipping %s\n", file->filename, buf);
2403 #endif
2404 } else {
2405 if (c == '\"') {
2406 /* first search in current dir if "header.h" */
2407 size = 0;
2408 p = strrchr(file->filename, '/');
2409 if (p)
2410 size = p + 1 - file->filename;
2411 if (size > sizeof(buf1) - 1)
2412 size = sizeof(buf1) - 1;
2413 memcpy(buf1, file->filename, size);
2414 buf1[size] = '\0';
2415 pstrcat(buf1, sizeof(buf1), buf);
2416 f = tcc_open(s1, buf1);
2417 if (f)
2418 goto found;
2420 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2421 error("#include recursion too deep");
2422 /* now search in all the include paths */
2423 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2424 for(i = 0; i < n; i++) {
2425 const char *path;
2426 if (i < s1->nb_include_paths)
2427 path = s1->include_paths[i];
2428 else
2429 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2430 pstrcpy(buf1, sizeof(buf1), path);
2431 pstrcat(buf1, sizeof(buf1), "/");
2432 pstrcat(buf1, sizeof(buf1), buf);
2433 f = tcc_open(s1, buf1);
2434 if (f)
2435 goto found;
2437 error("include file '%s' not found", buf);
2438 f = NULL;
2439 found:
2440 #ifdef INC_DEBUG
2441 printf("%s: including %s\n", file->filename, buf1);
2442 #endif
2443 f->inc_type = c;
2444 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2445 /* push current file in stack */
2446 /* XXX: fix current line init */
2447 *s1->include_stack_ptr++ = file;
2448 file = f;
2449 /* add include file debug info */
2450 if (do_debug) {
2451 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2453 tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
2454 ch = file->buf_ptr[0];
2455 goto the_end;
2457 break;
2458 case TOK_IFNDEF:
2459 c = 1;
2460 goto do_ifdef;
2461 case TOK_IF:
2462 c = expr_preprocess();
2463 goto do_if;
2464 case TOK_IFDEF:
2465 c = 0;
2466 do_ifdef:
2467 next_nomacro();
2468 if (tok < TOK_IDENT)
2469 error("invalid argument for '#if%sdef'", c ? "n" : "");
2470 if (is_bof) {
2471 if (c) {
2472 #ifdef INC_DEBUG
2473 printf("#ifndef %s\n", get_tok_str(tok, NULL));
2474 #endif
2475 file->ifndef_macro = tok;
2478 c = (define_find(tok) != 0) ^ c;
2479 do_if:
2480 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2481 error("memory full");
2482 *s1->ifdef_stack_ptr++ = c;
2483 goto test_skip;
2484 case TOK_ELSE:
2485 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2486 error("#else without matching #if");
2487 if (s1->ifdef_stack_ptr[-1] & 2)
2488 error("#else after #else");
2489 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2490 goto test_skip;
2491 case TOK_ELIF:
2492 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2493 error("#elif without matching #if");
2494 c = s1->ifdef_stack_ptr[-1];
2495 if (c > 1)
2496 error("#elif after #else");
2497 /* last #if/#elif expression was true: we skip */
2498 if (c == 1)
2499 goto skip;
2500 c = expr_preprocess();
2501 s1->ifdef_stack_ptr[-1] = c;
2502 test_skip:
2503 if (!(c & 1)) {
2504 skip:
2505 preprocess_skip();
2506 is_bof = 0;
2507 goto redo;
2509 break;
2510 case TOK_ENDIF:
2511 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2512 error("#endif without matching #if");
2513 s1->ifdef_stack_ptr--;
2514 /* '#ifndef macro' was at the start of file. Now we check if
2515 an '#endif' is exactly at the end of file */
2516 if (file->ifndef_macro &&
2517 s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
2518 file->ifndef_macro_saved = file->ifndef_macro;
2519 /* need to set to zero to avoid false matches if another
2520 #ifndef at middle of file */
2521 file->ifndef_macro = 0;
2522 while (tok != TOK_LINEFEED)
2523 next_nomacro();
2524 tok_flags |= TOK_FLAG_ENDIF;
2525 goto the_end;
2527 break;
2528 case TOK_LINE:
2529 next();
2530 if (tok != TOK_CINT)
2531 error("#line");
2532 file->line_num = tokc.i - 1; /* the line number will be incremented after */
2533 next();
2534 if (tok != TOK_LINEFEED) {
2535 if (tok != TOK_STR)
2536 error("#line");
2537 pstrcpy(file->filename, sizeof(file->filename),
2538 (char *)tokc.cstr->data);
2540 break;
2541 case TOK_ERROR:
2542 case TOK_WARNING:
2543 c = tok;
2544 skip_spaces();
2545 q = buf;
2546 while (ch != '\n' && ch != CH_EOF) {
2547 if ((q - buf) < sizeof(buf) - 1)
2548 *q++ = ch;
2549 minp();
2551 *q = '\0';
2552 if (c == TOK_ERROR)
2553 error("#error %s", buf);
2554 else
2555 warning("#warning %s", buf);
2556 break;
2557 case TOK_PRAGMA:
2558 /* ignored */
2559 break;
2560 default:
2561 if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
2562 /* '!' is ignored to allow C scripts. numbers are ignored
2563 to emulate cpp behaviour */
2564 } else {
2565 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
2567 break;
2569 /* ignore other preprocess commands or #! for C scripts */
2570 while (tok != TOK_LINEFEED)
2571 next_nomacro();
2572 the_end:
2573 return_linefeed = 0;
2576 /* read a number in base b */
2577 static int getn(int b)
2579 int n, t;
2580 n = 0;
2581 while (1) {
2582 if (ch >= 'a' && ch <= 'f')
2583 t = ch - 'a' + 10;
2584 else if (ch >= 'A' && ch <= 'F')
2585 t = ch - 'A' + 10;
2586 else if (isnum(ch))
2587 t = ch - '0';
2588 else
2589 break;
2590 if (t < 0 || t >= b)
2591 break;
2592 n = n * b + t;
2593 inp();
2595 return n;
2598 /* read a character for string or char constant and eval escape codes */
2599 static int getq(void)
2601 int c;
2603 redo:
2604 c = ch;
2605 inp();
2606 if (c == '\\') {
2607 switch(ch) {
2608 case '0': case '1': case '2': case '3':
2609 case '4': case '5': case '6': case '7':
2610 /* at most three octal digits */
2611 c = ch - '0';
2612 inp();
2613 if (isoct(ch)) {
2614 c = c * 8 + ch - '0';
2615 inp();
2616 if (isoct(ch)) {
2617 c = c * 8 + ch - '0';
2618 inp();
2621 return c;
2622 case 'x':
2623 inp();
2624 return getn(16);
2625 case 'a':
2626 c = '\a';
2627 break;
2628 case 'b':
2629 c = '\b';
2630 break;
2631 case 'f':
2632 c = '\f';
2633 break;
2634 case 'n':
2635 c = '\n';
2636 break;
2637 case 'r':
2638 c = '\r';
2639 break;
2640 case 't':
2641 c = '\t';
2642 break;
2643 case 'v':
2644 c = '\v';
2645 break;
2646 case 'e':
2647 if (!gnu_ext)
2648 goto invalid_escape;
2649 c = 27;
2650 break;
2651 case '\'':
2652 case '\"':
2653 case '\\':
2654 case '?':
2655 c = ch;
2656 break;
2657 case '\n':
2658 inp();
2659 goto redo;
2660 case '\r':
2661 inp();
2662 if (ch != '\n')
2663 goto invalid_escape;
2664 inp();
2665 goto redo;
2666 default:
2667 invalid_escape:
2668 error("invalid escaped char");
2670 inp();
2671 } else if (c == '\r' && ch == '\n') {
2672 inp();
2673 c = '\n';
2675 return c;
2678 /* we use 64 bit numbers */
2679 #define BN_SIZE 2
2681 /* bn = (bn << shift) | or_val */
2682 void bn_lshift(unsigned int *bn, int shift, int or_val)
2684 int i;
2685 unsigned int v;
2686 for(i=0;i<BN_SIZE;i++) {
2687 v = bn[i];
2688 bn[i] = (v << shift) | or_val;
2689 or_val = v >> (32 - shift);
2693 void bn_zero(unsigned int *bn)
2695 int i;
2696 for(i=0;i<BN_SIZE;i++) {
2697 bn[i] = 0;
2701 /* parse number in null terminated string 'p' and return it in the
2702 current token */
2703 void parse_number(const char *p)
2705 int b, t, shift, frac_bits, s, exp_val, ch;
2706 char *q;
2707 unsigned int bn[BN_SIZE];
2708 double d;
2710 /* number */
2711 q = token_buf;
2712 ch = *p++;
2713 t = ch;
2714 ch = *p++;
2715 *q++ = t;
2716 b = 10;
2717 if (t == '.') {
2718 goto float_frac_parse;
2719 } else if (t == '0') {
2720 if (ch == 'x' || ch == 'X') {
2721 q--;
2722 ch = *p++;
2723 b = 16;
2724 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2725 q--;
2726 ch = *p++;
2727 b = 2;
2730 /* parse all digits. cannot check octal numbers at this stage
2731 because of floating point constants */
2732 while (1) {
2733 if (ch >= 'a' && ch <= 'f')
2734 t = ch - 'a' + 10;
2735 else if (ch >= 'A' && ch <= 'F')
2736 t = ch - 'A' + 10;
2737 else if (isnum(ch))
2738 t = ch - '0';
2739 else
2740 break;
2741 if (t >= b)
2742 break;
2743 if (q >= token_buf + STRING_MAX_SIZE) {
2744 num_too_long:
2745 error("number too long");
2747 *q++ = ch;
2748 ch = *p++;
2750 if (ch == '.' ||
2751 ((ch == 'e' || ch == 'E') && b == 10) ||
2752 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2753 if (b != 10) {
2754 /* NOTE: strtox should support that for hexa numbers, but
2755 non ISOC99 libcs do not support it, so we prefer to do
2756 it by hand */
2757 /* hexadecimal or binary floats */
2758 /* XXX: handle overflows */
2759 *q = '\0';
2760 if (b == 16)
2761 shift = 4;
2762 else
2763 shift = 2;
2764 bn_zero(bn);
2765 q = token_buf;
2766 while (1) {
2767 t = *q++;
2768 if (t == '\0') {
2769 break;
2770 } else if (t >= 'a') {
2771 t = t - 'a' + 10;
2772 } else if (t >= 'A') {
2773 t = t - 'A' + 10;
2774 } else {
2775 t = t - '0';
2777 bn_lshift(bn, shift, t);
2779 frac_bits = 0;
2780 if (ch == '.') {
2781 ch = *p++;
2782 while (1) {
2783 t = ch;
2784 if (t >= 'a' && t <= 'f') {
2785 t = t - 'a' + 10;
2786 } else if (t >= 'A' && t <= 'F') {
2787 t = t - 'A' + 10;
2788 } else if (t >= '0' && t <= '9') {
2789 t = t - '0';
2790 } else {
2791 break;
2793 if (t >= b)
2794 error("invalid digit");
2795 bn_lshift(bn, shift, t);
2796 frac_bits += shift;
2797 ch = *p++;
2800 if (ch != 'p' && ch != 'P')
2801 expect("exponent");
2802 ch = *p++;
2803 s = 1;
2804 exp_val = 0;
2805 if (ch == '+') {
2806 ch = *p++;
2807 } else if (ch == '-') {
2808 s = -1;
2809 ch = *p++;
2811 if (ch < '0' || ch > '9')
2812 expect("exponent digits");
2813 while (ch >= '0' && ch <= '9') {
2814 exp_val = exp_val * 10 + ch - '0';
2815 ch = *p++;
2817 exp_val = exp_val * s;
2819 /* now we can generate the number */
2820 /* XXX: should patch directly float number */
2821 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
2822 d = ldexp(d, exp_val - frac_bits);
2823 t = toup(ch);
2824 if (t == 'F') {
2825 ch = *p++;
2826 tok = TOK_CFLOAT;
2827 /* float : should handle overflow */
2828 tokc.f = (float)d;
2829 } else if (t == 'L') {
2830 ch = *p++;
2831 tok = TOK_CLDOUBLE;
2832 /* XXX: not large enough */
2833 tokc.ld = (long double)d;
2834 } else {
2835 tok = TOK_CDOUBLE;
2836 tokc.d = d;
2838 } else {
2839 /* decimal floats */
2840 if (ch == '.') {
2841 if (q >= token_buf + STRING_MAX_SIZE)
2842 goto num_too_long;
2843 *q++ = ch;
2844 ch = *p++;
2845 float_frac_parse:
2846 while (ch >= '0' && ch <= '9') {
2847 if (q >= token_buf + STRING_MAX_SIZE)
2848 goto num_too_long;
2849 *q++ = ch;
2850 ch = *p++;
2853 if (ch == 'e' || ch == 'E') {
2854 if (q >= token_buf + STRING_MAX_SIZE)
2855 goto num_too_long;
2856 *q++ = ch;
2857 ch = *p++;
2858 if (ch == '-' || ch == '+') {
2859 if (q >= token_buf + STRING_MAX_SIZE)
2860 goto num_too_long;
2861 *q++ = ch;
2862 ch = *p++;
2864 if (ch < '0' || ch > '9')
2865 expect("exponent digits");
2866 while (ch >= '0' && ch <= '9') {
2867 if (q >= token_buf + STRING_MAX_SIZE)
2868 goto num_too_long;
2869 *q++ = ch;
2870 ch = *p++;
2873 *q = '\0';
2874 t = toup(ch);
2875 errno = 0;
2876 if (t == 'F') {
2877 ch = *p++;
2878 tok = TOK_CFLOAT;
2879 tokc.f = strtof(token_buf, NULL);
2880 } else if (t == 'L') {
2881 ch = *p++;
2882 tok = TOK_CLDOUBLE;
2883 tokc.ld = strtold(token_buf, NULL);
2884 } else {
2885 tok = TOK_CDOUBLE;
2886 tokc.d = strtod(token_buf, NULL);
2889 } else {
2890 unsigned long long n, n1;
2891 int lcount, ucount;
2893 /* integer number */
2894 *q = '\0';
2895 q = token_buf;
2896 if (b == 10 && *q == '0') {
2897 b = 8;
2898 q++;
2900 n = 0;
2901 while(1) {
2902 t = *q++;
2903 /* no need for checks except for base 10 / 8 errors */
2904 if (t == '\0') {
2905 break;
2906 } else if (t >= 'a') {
2907 t = t - 'a' + 10;
2908 } else if (t >= 'A') {
2909 t = t - 'A' + 10;
2910 } else {
2911 t = t - '0';
2912 if (t >= b)
2913 error("invalid digit");
2915 n1 = n;
2916 n = n * b + t;
2917 /* detect overflow */
2918 /* XXX: this test is not reliable */
2919 if (n < n1)
2920 error("integer constant overflow");
2923 /* XXX: not exactly ANSI compliant */
2924 if ((n & 0xffffffff00000000LL) != 0) {
2925 if ((n >> 63) != 0)
2926 tok = TOK_CULLONG;
2927 else
2928 tok = TOK_CLLONG;
2929 } else if (n > 0x7fffffff) {
2930 tok = TOK_CUINT;
2931 } else {
2932 tok = TOK_CINT;
2934 lcount = 0;
2935 ucount = 0;
2936 for(;;) {
2937 t = toup(ch);
2938 if (t == 'L') {
2939 if (lcount >= 2)
2940 error("three 'l's in integer constant");
2941 lcount++;
2942 if (lcount == 2) {
2943 if (tok == TOK_CINT)
2944 tok = TOK_CLLONG;
2945 else if (tok == TOK_CUINT)
2946 tok = TOK_CULLONG;
2948 ch = *p++;
2949 } else if (t == 'U') {
2950 if (ucount >= 1)
2951 error("two 'u's in integer constant");
2952 ucount++;
2953 if (tok == TOK_CINT)
2954 tok = TOK_CUINT;
2955 else if (tok == TOK_CLLONG)
2956 tok = TOK_CULLONG;
2957 ch = *p++;
2958 } else {
2959 break;
2962 if (tok == TOK_CINT || tok == TOK_CUINT)
2963 tokc.ui = n;
2964 else
2965 tokc.ull = n;
2970 #define PARSE2(c1, tok1, c2, tok2) \
2971 case c1: \
2972 PEEKC(c, p); \
2973 if (c == c2) { \
2974 p++; \
2975 tok = tok2; \
2976 } else { \
2977 tok = tok1; \
2979 break;
2981 /* return next token without macro substitution */
2982 static inline void next_nomacro1(void)
2984 int b, t, c;
2985 TokenSym *ts;
2986 uint8_t *p, *p1;
2987 unsigned int h;
2989 p = file->buf_ptr;
2990 redo_no_start:
2991 c = *p;
2992 switch(c) {
2993 case ' ':
2994 case '\t':
2995 case '\f':
2996 case '\v':
2997 case '\r':
2998 p++;
2999 goto redo_no_start;
3001 case '\\':
3002 /* first look if it is in fact an end of buffer */
3003 if (p >= file->buf_end) {
3004 file->buf_ptr = p;
3005 handle_eob();
3006 p = file->buf_ptr;
3007 if (p >= file->buf_end)
3008 goto parse_eof;
3009 else
3010 goto redo_no_start;
3011 } else {
3012 file->buf_ptr = p;
3013 ch = *p;
3014 handle_stray();
3015 p = file->buf_ptr;
3016 goto redo_no_start;
3018 parse_eof:
3020 TCCState *s1 = tcc_state;
3022 if (return_linefeed) {
3023 tok = TOK_LINEFEED;
3024 } else if (s1->include_stack_ptr == s1->include_stack) {
3025 /* no include left : end of file */
3026 tok = TOK_EOF;
3027 } else {
3028 /* pop include file */
3030 /* test if previous '#endif' was after a #ifdef at
3031 start of file */
3032 if (tok_flags & TOK_FLAG_ENDIF) {
3033 #ifdef INC_DEBUG
3034 printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
3035 #endif
3036 add_cached_include(s1, file->inc_type, file->inc_filename,
3037 file->ifndef_macro_saved);
3040 /* add end of include file debug info */
3041 if (do_debug) {
3042 put_stabd(N_EINCL, 0, 0);
3044 /* pop include stack */
3045 tcc_close(file);
3046 s1->include_stack_ptr--;
3047 file = *s1->include_stack_ptr;
3048 p = file->buf_ptr;
3049 goto redo_no_start;
3052 break;
3054 case '\n':
3055 if (return_linefeed) {
3056 tok = TOK_LINEFEED;
3057 } else {
3058 file->line_num++;
3059 tok_flags |= TOK_FLAG_BOL;
3060 p++;
3061 goto redo_no_start;
3063 break;
3065 case '#':
3066 /* XXX: simplify */
3067 PEEKC(c, p);
3068 if (tok_flags & TOK_FLAG_BOL) {
3069 file->buf_ptr = p;
3070 preprocess(tok_flags & TOK_FLAG_BOF);
3071 p = file->buf_ptr;
3072 goto redo_no_start;
3073 } else {
3074 if (c == '#') {
3075 p++;
3076 tok = TOK_TWOSHARPS;
3077 } else {
3078 tok = '#';
3081 break;
3083 case 'a': case 'b': case 'c': case 'd':
3084 case 'e': case 'f': case 'g': case 'h':
3085 case 'i': case 'j': case 'k': case 'l':
3086 case 'm': case 'n': case 'o': case 'p':
3087 case 'q': case 'r': case 's': case 't':
3088 case 'u': case 'v': case 'w': case 'x':
3089 case 'y': case 'z':
3090 case 'A': case 'B': case 'C': case 'D':
3091 case 'E': case 'F': case 'G': case 'H':
3092 case 'I': case 'J': case 'K':
3093 case 'M': case 'N': case 'O': case 'P':
3094 case 'Q': case 'R': case 'S': case 'T':
3095 case 'U': case 'V': case 'W': case 'X':
3096 case 'Y': case 'Z':
3097 case '_':
3098 parse_ident_fast:
3099 p1 = p;
3100 h = TOK_HASH_INIT;
3101 h = TOK_HASH_FUNC(h, c);
3102 p++;
3103 for(;;) {
3104 c = *p;
3105 if (!isid(c) && !isnum(c))
3106 break;
3107 h = TOK_HASH_FUNC(h, c);
3108 p++;
3110 if (c != '\\') {
3111 TokenSym **pts;
3112 int len;
3114 /* fast case : no stray found, so we have the full token
3115 and we have already hashed it */
3116 len = p - p1;
3117 h &= (TOK_HASH_SIZE - 1);
3118 pts = &hash_ident[h];
3119 for(;;) {
3120 ts = *pts;
3121 if (!ts)
3122 break;
3123 if (ts->len == len && !memcmp(ts->str, p1, len))
3124 goto token_found;
3125 pts = &(ts->hash_next);
3127 ts = tok_alloc_new(pts, p1, len);
3128 token_found: ;
3129 } else {
3130 /* slower case */
3131 cstr_reset(&tokcstr);
3133 while (p1 < p) {
3134 cstr_ccat(&tokcstr, *p1);
3135 p1++;
3137 p--;
3138 PEEKC(c, p);
3139 parse_ident_slow:
3140 while (isid(c) || isnum(c)) {
3141 cstr_ccat(&tokcstr, c);
3142 PEEKC(c, p);
3144 ts = tok_alloc(tokcstr.data, tokcstr.size);
3146 tok = ts->tok;
3147 break;
3148 case 'L':
3149 t = p[1];
3150 if (t != '\\' && t != '\'' && t != '\"') {
3151 /* fast case */
3152 goto parse_ident_fast;
3153 } else {
3154 PEEKC(c, p);
3155 if (c == '\'') {
3156 tok = TOK_LCHAR;
3157 goto char_const;
3158 } else if (c == '\"') {
3159 tok = TOK_LSTR;
3160 goto str_const;
3161 } else {
3162 cstr_reset(&tokcstr);
3163 cstr_ccat(&tokcstr, 'L');
3164 goto parse_ident_slow;
3167 break;
3168 case '0': case '1': case '2': case '3':
3169 case '4': case '5': case '6': case '7':
3170 case '8': case '9':
3172 cstr_reset(&tokcstr);
3173 /* after the first digit, accept digits, alpha, '.' or sign if
3174 prefixed by 'eEpP' */
3175 parse_num:
3176 for(;;) {
3177 t = c;
3178 cstr_ccat(&tokcstr, c);
3179 PEEKC(c, p);
3180 if (!(isnum(c) || isid(c) || c == '.' ||
3181 ((c == '+' || c == '-') &&
3182 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
3183 break;
3185 /* We add a trailing '\0' to ease parsing */
3186 cstr_ccat(&tokcstr, '\0');
3187 tokc.cstr = &tokcstr;
3188 tok = TOK_PPNUM;
3189 break;
3190 case '.':
3191 /* special dot handling because it can also start a number */
3192 PEEKC(c, p);
3193 if (isnum(c)) {
3194 cstr_reset(&tokcstr);
3195 cstr_ccat(&tokcstr, '.');
3196 goto parse_num;
3197 } else if (c == '.') {
3198 PEEKC(c, p);
3199 if (c != '.')
3200 expect("'.'");
3201 PEEKC(c, p);
3202 tok = TOK_DOTS;
3203 } else {
3204 tok = '.';
3206 break;
3207 case '\'':
3208 tok = TOK_CCHAR;
3209 char_const:
3210 file->buf_ptr = p;
3211 inp();
3212 b = getq();
3213 /* this cast is needed if >= 128 */
3214 if (tok == TOK_CCHAR)
3215 b = (char)b;
3216 tokc.i = b;
3217 if (ch != '\'')
3218 error("unterminated character constant");
3219 p = file->buf_ptr;
3220 p++;
3221 break;
3222 case '\"':
3223 tok = TOK_STR;
3224 str_const:
3225 file->buf_ptr = p;
3226 inp();
3227 cstr_reset(&tokcstr);
3228 while (ch != '\"') {
3229 b = getq();
3230 if (ch == CH_EOF)
3231 error("unterminated string");
3232 if (tok == TOK_STR)
3233 cstr_ccat(&tokcstr, b);
3234 else
3235 cstr_wccat(&tokcstr, b);
3237 if (tok == TOK_STR)
3238 cstr_ccat(&tokcstr, '\0');
3239 else
3240 cstr_wccat(&tokcstr, '\0');
3241 tokc.cstr = &tokcstr;
3242 p = file->buf_ptr;
3243 p++;
3244 break;
3246 case '<':
3247 PEEKC(c, p);
3248 if (c == '=') {
3249 p++;
3250 tok = TOK_LE;
3251 } else if (c == '<') {
3252 PEEKC(c, p);
3253 if (c == '=') {
3254 p++;
3255 tok = TOK_A_SHL;
3256 } else {
3257 tok = TOK_SHL;
3259 } else {
3260 tok = TOK_LT;
3262 break;
3264 case '>':
3265 PEEKC(c, p);
3266 if (c == '=') {
3267 p++;
3268 tok = TOK_GE;
3269 } else if (c == '>') {
3270 PEEKC(c, p);
3271 if (c == '=') {
3272 p++;
3273 tok = TOK_A_SAR;
3274 } else {
3275 tok = TOK_SAR;
3277 } else {
3278 tok = TOK_GT;
3280 break;
3282 case '&':
3283 PEEKC(c, p);
3284 if (c == '&') {
3285 p++;
3286 tok = TOK_LAND;
3287 } else if (c == '=') {
3288 p++;
3289 tok = TOK_A_AND;
3290 } else {
3291 tok = '&';
3293 break;
3295 case '|':
3296 PEEKC(c, p);
3297 if (c == '|') {
3298 p++;
3299 tok = TOK_LOR;
3300 } else if (c == '=') {
3301 p++;
3302 tok = TOK_A_OR;
3303 } else {
3304 tok = '|';
3306 break;
3308 case '+':
3309 PEEKC(c, p);
3310 if (c == '+') {
3311 p++;
3312 tok = TOK_INC;
3313 } else if (c == '=') {
3314 p++;
3315 tok = TOK_A_ADD;
3316 } else {
3317 tok = '+';
3319 break;
3321 case '-':
3322 PEEKC(c, p);
3323 if (c == '-') {
3324 p++;
3325 tok = TOK_DEC;
3326 } else if (c == '=') {
3327 p++;
3328 tok = TOK_A_SUB;
3329 } else if (c == '>') {
3330 p++;
3331 tok = TOK_ARROW;
3332 } else {
3333 tok = '-';
3335 break;
3337 PARSE2('!', '!', '=', TOK_NE)
3338 PARSE2('=', '=', '=', TOK_EQ)
3339 PARSE2('*', '*', '=', TOK_A_MUL)
3340 PARSE2('%', '%', '=', TOK_A_MOD)
3341 PARSE2('^', '^', '=', TOK_A_XOR)
3343 /* comments or operator */
3344 case '/':
3345 PEEKC(c, p);
3346 if (c == '*') {
3347 file->buf_ptr = p;
3348 parse_comment();
3349 p = file->buf_ptr;
3350 goto redo_no_start;
3351 } else if (c == '/') {
3352 file->buf_ptr = p;
3353 parse_line_comment();
3354 p = file->buf_ptr;
3355 goto redo_no_start;
3356 } else if (c == '=') {
3357 p++;
3358 tok = TOK_A_DIV;
3359 } else {
3360 tok = '/';
3362 break;
3364 /* simple tokens */
3365 case '(':
3366 case ')':
3367 case '[':
3368 case ']':
3369 case '{':
3370 case '}':
3371 case ',':
3372 case ';':
3373 case ':':
3374 case '?':
3375 case '~':
3376 tok = c;
3377 p++;
3378 break;
3379 default:
3380 error("unrecognized character \\x%02x", c);
3381 break;
3383 file->buf_ptr = p;
3384 tok_flags = 0;
3385 #if defined(PARSE_DEBUG)
3386 printf("token = %s\n", get_tok_str(tok, &tokc));
3387 #endif
3390 /* return next token without macro substitution. Can read input from
3391 macro_ptr buffer */
3392 static void next_nomacro(void)
3394 if (macro_ptr) {
3395 redo:
3396 tok = *macro_ptr;
3397 if (tok) {
3398 TOK_GET(tok, macro_ptr, tokc);
3399 if (tok == TOK_LINENUM) {
3400 file->line_num = tokc.i;
3401 goto redo;
3404 } else {
3405 next_nomacro1();
3409 /* substitute args in macro_str and return allocated string */
3410 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
3412 int *st, last_tok, t, notfirst;
3413 Sym *s;
3414 CValue cval;
3415 TokenString str;
3416 CString cstr;
3418 tok_str_new(&str);
3419 last_tok = 0;
3420 while(1) {
3421 TOK_GET(t, macro_str, cval);
3422 if (!t)
3423 break;
3424 if (t == '#') {
3425 /* stringize */
3426 TOK_GET(t, macro_str, cval);
3427 if (!t)
3428 break;
3429 s = sym_find2(args, t);
3430 if (s) {
3431 cstr_new(&cstr);
3432 st = (int *)s->c;
3433 notfirst = 0;
3434 while (*st) {
3435 if (notfirst)
3436 cstr_ccat(&cstr, ' ');
3437 TOK_GET(t, st, cval);
3438 cstr_cat(&cstr, get_tok_str(t, &cval));
3439 notfirst = 1;
3441 cstr_ccat(&cstr, '\0');
3442 #ifdef PP_DEBUG
3443 printf("stringize: %s\n", (char *)cstr.data);
3444 #endif
3445 /* add string */
3446 cval.cstr = &cstr;
3447 tok_str_add2(&str, TOK_STR, &cval);
3448 cstr_free(&cstr);
3449 } else {
3450 tok_str_add2(&str, t, &cval);
3452 } else if (t >= TOK_IDENT) {
3453 s = sym_find2(args, t);
3454 if (s) {
3455 st = (int *)s->c;
3456 /* if '##' is present before or after, no arg substitution */
3457 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
3458 /* special case for var arg macros : ## eats the
3459 ',' if empty VA_ARGS variable. */
3460 /* XXX: test of the ',' is not 100%
3461 reliable. should fix it to avoid security
3462 problems */
3463 if (gnu_ext && s->type.t &&
3464 last_tok == TOK_TWOSHARPS &&
3465 str.len >= 2 && str.str[str.len - 2] == ',') {
3466 if (*st == 0) {
3467 /* suppress ',' '##' */
3468 str.len -= 2;
3469 } else {
3470 /* suppress '##' and add variable */
3471 str.len--;
3472 goto add_var;
3474 } else {
3475 int t1;
3476 add_var:
3477 for(;;) {
3478 TOK_GET(t1, st, cval);
3479 if (!t1)
3480 break;
3481 tok_str_add2(&str, t1, &cval);
3484 } else {
3485 macro_subst(&str, nested_list, st);
3487 } else {
3488 tok_str_add(&str, t);
3490 } else {
3491 tok_str_add2(&str, t, &cval);
3493 last_tok = t;
3495 tok_str_add(&str, 0);
3496 return str.str;
3499 /* handle the '##' operator */
3500 static int *macro_twosharps(void)
3502 TokenSym *ts;
3503 int *macro_ptr1;
3504 int t;
3505 const char *p1, *p2;
3506 CValue cval;
3507 TokenString macro_str1;
3508 CString cstr;
3510 cstr_new(&cstr);
3511 tok_str_new(&macro_str1);
3512 tok = 0;
3513 while (1) {
3514 next_nomacro();
3515 if (tok == 0)
3516 break;
3517 while (*macro_ptr == TOK_TWOSHARPS) {
3518 macro_ptr++;
3519 macro_ptr1 = macro_ptr;
3520 t = *macro_ptr;
3521 if (t) {
3522 TOK_GET(t, macro_ptr, cval);
3524 /* We concatenate the two tokens if we have an
3525 identifier or a preprocessing number */
3526 cstr_reset(&cstr);
3527 p1 = get_tok_str(tok, &tokc);
3528 cstr_cat(&cstr, p1);
3529 p2 = get_tok_str(t, &cval);
3530 cstr_cat(&cstr, p2);
3531 cstr_ccat(&cstr, '\0');
3533 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
3534 (t >= TOK_IDENT || t == TOK_PPNUM)) {
3535 if (tok == TOK_PPNUM) {
3536 /* if number, then create a number token */
3537 /* NOTE: no need to allocate because
3538 tok_str_add2() does it */
3539 tokc.cstr = &cstr;
3540 } else {
3541 /* if identifier, we must do a test to
3542 validate we have a correct identifier */
3543 if (t == TOK_PPNUM) {
3544 const char *p;
3545 int c;
3547 p = p2;
3548 for(;;) {
3549 c = *p;
3550 if (c == '\0')
3551 break;
3552 p++;
3553 if (!isnum(c) && !isid(c))
3554 goto error_pasting;
3557 ts = tok_alloc(cstr.data, strlen(cstr.data));
3558 tok = ts->tok; /* modify current token */
3560 } else {
3561 const char *str = cstr.data;
3562 const unsigned char *q;
3564 /* we look for a valid token */
3565 /* XXX: do more extensive checks */
3566 if (!strcmp(str, ">>=")) {
3567 tok = TOK_A_SAR;
3568 } else if (!strcmp(str, "<<=")) {
3569 tok = TOK_A_SHL;
3570 } else if (strlen(str) == 2) {
3571 /* search in two bytes table */
3572 q = tok_two_chars;
3573 for(;;) {
3574 if (!*q)
3575 goto error_pasting;
3576 if (q[0] == str[0] && q[1] == str[1])
3577 break;
3578 q += 3;
3580 tok = q[2];
3581 } else {
3582 error_pasting:
3583 /* NOTE: because get_tok_str use a static buffer,
3584 we must save it */
3585 cstr_reset(&cstr);
3586 p1 = get_tok_str(tok, &tokc);
3587 cstr_cat(&cstr, p1);
3588 cstr_ccat(&cstr, '\0');
3589 p2 = get_tok_str(t, &cval);
3590 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
3591 /* cannot merge tokens: just add them separately */
3592 tok_str_add2(&macro_str1, tok, &tokc);
3593 /* XXX: free associated memory ? */
3594 tok = t;
3595 tokc = cval;
3600 tok_str_add2(&macro_str1, tok, &tokc);
3602 cstr_free(&cstr);
3603 tok_str_add(&macro_str1, 0);
3604 return macro_str1.str;
3608 /* do macro substitution of current token with macro 's' and add
3609 result to (tok_str,tok_len). 'nested_list' is the list of all
3610 macros we got inside to avoid recursing. Return non zero if no
3611 substitution needs to be done */
3612 static int macro_subst_tok(TokenString *tok_str,
3613 Sym **nested_list, Sym *s)
3615 Sym *args, *sa, *sa1;
3616 int mstr_allocated, parlevel, *mstr, t;
3617 TokenString str;
3618 char *cstrval;
3619 CValue cval;
3620 CString cstr;
3622 /* if symbol is a macro, prepare substitution */
3623 /* if nested substitution, do nothing */
3624 if (sym_find2(*nested_list, tok))
3625 return -1;
3627 /* special macros */
3628 if (tok == TOK___LINE__) {
3629 cval.i = file->line_num;
3630 tok_str_add2(tok_str, TOK_CINT, &cval);
3631 } else if (tok == TOK___FILE__) {
3632 cstrval = file->filename;
3633 goto add_cstr;
3634 tok_str_add2(tok_str, TOK_STR, &cval);
3635 } else if (tok == TOK___DATE__) {
3636 cstrval = "Jan 1 2002";
3637 goto add_cstr;
3638 } else if (tok == TOK___TIME__) {
3639 cstrval = "00:00:00";
3640 add_cstr:
3641 cstr_new(&cstr);
3642 cstr_cat(&cstr, cstrval);
3643 cstr_ccat(&cstr, '\0');
3644 cval.cstr = &cstr;
3645 tok_str_add2(tok_str, TOK_STR, &cval);
3646 cstr_free(&cstr);
3647 } else {
3648 mstr = (int *)s->c;
3649 mstr_allocated = 0;
3650 if (s->type.t == MACRO_FUNC) {
3651 /* NOTE: we do not use next_nomacro to avoid eating the
3652 next token. XXX: find better solution */
3653 if (macro_ptr) {
3654 t = *macro_ptr;
3655 } else {
3656 /* XXX: incorrect with comments */
3657 ch = file->buf_ptr[0];
3658 while (is_space(ch) || ch == '\n')
3659 cinp();
3660 t = ch;
3662 if (t != '(') /* no macro subst */
3663 return -1;
3665 /* argument macro */
3666 next_nomacro();
3667 next_nomacro();
3668 args = NULL;
3669 sa = s->next;
3670 /* NOTE: empty args are allowed, except if no args */
3671 for(;;) {
3672 /* handle '()' case */
3673 if (!args && tok == ')')
3674 break;
3675 if (!sa)
3676 error("macro '%s' used with too many args",
3677 get_tok_str(s->v, 0));
3678 tok_str_new(&str);
3679 parlevel = 0;
3680 /* NOTE: non zero sa->t indicates VA_ARGS */
3681 while ((parlevel > 0 ||
3682 (tok != ')' &&
3683 (tok != ',' || sa->type.t))) &&
3684 tok != -1) {
3685 if (tok == '(')
3686 parlevel++;
3687 else if (tok == ')')
3688 parlevel--;
3689 tok_str_add2(&str, tok, &tokc);
3690 next_nomacro();
3692 tok_str_add(&str, 0);
3693 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str);
3694 sa = sa->next;
3695 if (tok == ')') {
3696 /* special case for gcc var args: add an empty
3697 var arg argument if it is omitted */
3698 if (sa && sa->type.t && gnu_ext)
3699 continue;
3700 else
3701 break;
3703 if (tok != ',')
3704 expect(",");
3705 next_nomacro();
3707 if (sa) {
3708 error("macro '%s' used with too few args",
3709 get_tok_str(s->v, 0));
3712 /* now subst each arg */
3713 mstr = macro_arg_subst(nested_list, mstr, args);
3714 /* free memory */
3715 sa = args;
3716 while (sa) {
3717 sa1 = sa->prev;
3718 tok_str_free((int *)sa->c);
3719 tcc_free(sa);
3720 sa = sa1;
3722 mstr_allocated = 1;
3724 sym_push2(nested_list, s->v, 0, 0);
3725 macro_subst(tok_str, nested_list, mstr);
3726 /* pop nested defined symbol */
3727 sa1 = *nested_list;
3728 *nested_list = sa1->prev;
3729 tcc_free(sa1);
3730 if (mstr_allocated)
3731 tok_str_free(mstr);
3733 return 0;
3736 /* do macro substitution of macro_str and add result to
3737 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3738 inside to avoid recursing. */
3739 static void macro_subst(TokenString *tok_str,
3740 Sym **nested_list, int *macro_str)
3742 Sym *s;
3743 int *saved_macro_ptr;
3744 int *macro_str1;
3746 saved_macro_ptr = macro_ptr;
3747 macro_ptr = macro_str;
3748 /* first scan for '##' operator handling */
3749 macro_str1 = macro_twosharps();
3750 macro_ptr = macro_str1;
3752 while (1) {
3753 next_nomacro();
3754 if (tok == 0)
3755 break;
3756 s = define_find(tok);
3757 if (s != NULL) {
3758 if (macro_subst_tok(tok_str, nested_list, s) != 0)
3759 goto no_subst;
3760 } else {
3761 no_subst:
3762 tok_str_add2(tok_str, tok, &tokc);
3765 macro_ptr = saved_macro_ptr;
3766 tok_str_free(macro_str1);
3769 /* return next token with macro substitution */
3770 static void next(void)
3772 Sym *nested_list, *s;
3773 TokenString str;
3775 /* special 'ungettok' case for label parsing */
3776 if (tok1) {
3777 tok = tok1;
3778 tokc = tok1c;
3779 tok1 = 0;
3780 } else {
3781 redo:
3782 next_nomacro();
3783 if (!macro_ptr) {
3784 /* if not reading from macro substituted string, then try
3785 to substitute macros */
3786 if (tok >= TOK_IDENT) {
3787 s = define_find(tok);
3788 if (s) {
3789 /* we have a macro: we try to substitute */
3790 tok_str_new(&str);
3791 nested_list = NULL;
3792 if (macro_subst_tok(&str, &nested_list, s) == 0) {
3793 /* substitution done, NOTE: maybe empty */
3794 tok_str_add(&str, 0);
3795 macro_ptr = str.str;
3796 macro_ptr_allocated = str.str;
3797 goto redo;
3801 } else {
3802 if (tok == 0) {
3803 /* end of macro string: free it */
3804 tok_str_free(macro_ptr_allocated);
3805 macro_ptr = NULL;
3806 goto redo;
3810 /* convert preprocessor tokens into C tokens */
3811 if (tok == TOK_PPNUM) {
3812 parse_number((char *)tokc.cstr->data);
3817 void swap(int *p, int *q)
3819 int t;
3820 t = *p;
3821 *p = *q;
3822 *q = t;
3825 void vsetc(CType *type, int r, CValue *vc)
3827 int v;
3829 if (vtop >= vstack + VSTACK_SIZE)
3830 error("memory full");
3831 /* cannot let cpu flags if other instruction are generated. Also
3832 avoid leaving VT_JMP anywhere except on the top of the stack
3833 because it would complicate the code generator. */
3834 if (vtop >= vstack) {
3835 v = vtop->r & VT_VALMASK;
3836 if (v == VT_CMP || (v & ~1) == VT_JMP)
3837 gv(RC_INT);
3839 vtop++;
3840 vtop->type = *type;
3841 vtop->r = r;
3842 vtop->r2 = VT_CONST;
3843 vtop->c = *vc;
3846 /* push integer constant */
3847 void vpushi(int v)
3849 CValue cval;
3850 cval.i = v;
3851 vsetc(&int_type, VT_CONST, &cval);
3854 /* Return a static symbol pointing to a section */
3855 static Sym *get_sym_ref(CType *type, Section *sec,
3856 unsigned long offset, unsigned long size)
3858 int v;
3859 Sym *sym;
3861 v = anon_sym++;
3862 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
3863 sym->type.ref = type->ref;
3864 sym->r = VT_CONST | VT_SYM;
3865 put_extern_sym(sym, sec, offset, size);
3866 return sym;
3869 /* push a reference to a section offset by adding a dummy symbol */
3870 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
3872 CValue cval;
3874 cval.ul = 0;
3875 vsetc(type, VT_CONST | VT_SYM, &cval);
3876 vtop->sym = get_sym_ref(type, sec, offset, size);
3879 /* define a new external reference to a symbol 'v' of type 'u' */
3880 static Sym *external_global_sym(int v, CType *type, int r)
3882 Sym *s;
3884 s = sym_find(v);
3885 if (!s) {
3886 /* push forward reference */
3887 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
3888 s->type.ref = type->ref;
3889 s->r = r | VT_CONST | VT_SYM;
3891 return s;
3894 /* define a new external reference to a symbol 'v' of type 'u' */
3895 static Sym *external_sym(int v, CType *type, int r)
3897 Sym *s;
3899 s = sym_find(v);
3900 if (!s) {
3901 /* push forward reference */
3902 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
3903 s->type.t |= VT_EXTERN;
3905 return s;
3908 /* push a reference to global symbol v */
3909 static void vpush_global_sym(CType *type, int v)
3911 Sym *sym;
3912 CValue cval;
3914 sym = external_global_sym(v, type, 0);
3915 cval.ul = 0;
3916 vsetc(type, VT_CONST | VT_SYM, &cval);
3917 vtop->sym = sym;
3920 void vset(CType *type, int r, int v)
3922 CValue cval;
3924 cval.i = v;
3925 vsetc(type, r, &cval);
3928 void vseti(int r, int v)
3930 CType type;
3931 type.t = VT_INT;
3932 vset(&type, r, v);
3935 void vswap(void)
3937 SValue tmp;
3939 tmp = vtop[0];
3940 vtop[0] = vtop[-1];
3941 vtop[-1] = tmp;
3944 void vpushv(SValue *v)
3946 if (vtop >= vstack + VSTACK_SIZE)
3947 error("memory full");
3948 vtop++;
3949 *vtop = *v;
3952 void vdup(void)
3954 vpushv(vtop);
3957 /* save r to the memory stack, and mark it as being free */
3958 void save_reg(int r)
3960 int l, saved, size, align;
3961 SValue *p, sv;
3962 CType *type;
3964 /* modify all stack values */
3965 saved = 0;
3966 l = 0;
3967 for(p=vstack;p<=vtop;p++) {
3968 if ((p->r & VT_VALMASK) == r ||
3969 (p->r2 & VT_VALMASK) == r) {
3970 /* must save value on stack if not already done */
3971 if (!saved) {
3972 /* NOTE: must reload 'r' because r might be equal to r2 */
3973 r = p->r & VT_VALMASK;
3974 /* store register in the stack */
3975 type = &p->type;
3976 if ((p->r & VT_LVAL) ||
3977 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
3978 type = &int_type;
3979 size = type_size(type, &align);
3980 loc = (loc - size) & -align;
3981 sv.type.t = type->t;
3982 sv.r = VT_LOCAL | VT_LVAL;
3983 sv.c.ul = loc;
3984 store(r, &sv);
3985 #ifdef TCC_TARGET_I386
3986 /* x86 specific: need to pop fp register ST0 if saved */
3987 if (r == REG_ST0) {
3988 o(0xd9dd); /* fstp %st(1) */
3990 #endif
3991 /* special long long case */
3992 if ((type->t & VT_BTYPE) == VT_LLONG) {
3993 sv.c.ul += 4;
3994 store(p->r2, &sv);
3996 l = loc;
3997 saved = 1;
3999 /* mark that stack entry as being saved on the stack */
4000 if (p->r & VT_LVAL) {
4001 /* also suppress the bounded flag because the
4002 relocation address of the function was stored in
4003 p->c.ul */
4004 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
4005 } else {
4006 p->r = lvalue_type(p->type.t) | VT_LOCAL;
4008 p->r2 = VT_CONST;
4009 p->c.ul = l;
4014 /* find a free register of class 'rc'. If none, save one register */
4015 int get_reg(int rc)
4017 int r;
4018 SValue *p;
4020 /* find a free register */
4021 for(r=0;r<NB_REGS;r++) {
4022 if (reg_classes[r] & rc) {
4023 for(p=vstack;p<=vtop;p++) {
4024 if ((p->r & VT_VALMASK) == r ||
4025 (p->r2 & VT_VALMASK) == r)
4026 goto notfound;
4028 return r;
4030 notfound: ;
4033 /* no register left : free the first one on the stack (VERY
4034 IMPORTANT to start from the bottom to ensure that we don't
4035 spill registers used in gen_opi()) */
4036 for(p=vstack;p<=vtop;p++) {
4037 r = p->r & VT_VALMASK;
4038 if (r < VT_CONST && (reg_classes[r] & rc))
4039 goto save_found;
4040 /* also look at second register (if long long) */
4041 r = p->r2 & VT_VALMASK;
4042 if (r < VT_CONST && (reg_classes[r] & rc)) {
4043 save_found:
4044 save_reg(r);
4045 return r;
4048 /* Should never comes here */
4049 return -1;
4052 /* save registers up to (vtop - n) stack entry */
4053 void save_regs(int n)
4055 int r;
4056 SValue *p, *p1;
4057 p1 = vtop - n;
4058 for(p = vstack;p <= p1; p++) {
4059 r = p->r & VT_VALMASK;
4060 if (r < VT_CONST) {
4061 save_reg(r);
4066 /* move register 's' to 'r', and flush previous value of r to memory
4067 if needed */
4068 void move_reg(int r, int s)
4070 SValue sv;
4072 if (r != s) {
4073 save_reg(r);
4074 sv.type.t = VT_INT;
4075 sv.r = s;
4076 sv.c.ul = 0;
4077 load(r, &sv);
4081 /* get address of vtop (vtop MUST BE an lvalue) */
4082 void gaddrof(void)
4084 vtop->r &= ~VT_LVAL;
4085 /* tricky: if saved lvalue, then we can go back to lvalue */
4086 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
4087 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
4090 #ifdef CONFIG_TCC_BCHECK
4091 /* generate lvalue bound code */
4092 void gbound(void)
4094 int lval_type;
4095 CType type1;
4097 vtop->r &= ~VT_MUSTBOUND;
4098 /* if lvalue, then use checking code before dereferencing */
4099 if (vtop->r & VT_LVAL) {
4100 /* if not VT_BOUNDED value, then make one */
4101 if (!(vtop->r & VT_BOUNDED)) {
4102 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
4103 /* must save type because we must set it to int to get pointer */
4104 type1 = vtop->type;
4105 vtop->type.t = VT_INT;
4106 gaddrof();
4107 vpushi(0);
4108 gen_bounded_ptr_add();
4109 vtop->r |= lval_type;
4110 vtop->type = type1;
4112 /* then check for dereferencing */
4113 gen_bounded_ptr_deref();
4116 #endif
4118 /* store vtop a register belonging to class 'rc'. lvalues are
4119 converted to values. Cannot be used if cannot be converted to
4120 register value (such as structures). */
4121 int gv(int rc)
4123 int r, r2, rc2, bit_pos, bit_size, size, align, i;
4124 unsigned long long ll;
4126 /* NOTE: get_reg can modify vstack[] */
4127 if (vtop->type.t & VT_BITFIELD) {
4128 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4129 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4130 /* remove bit field info to avoid loops */
4131 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4132 /* generate shifts */
4133 vpushi(32 - (bit_pos + bit_size));
4134 gen_op(TOK_SHL);
4135 vpushi(32 - bit_size);
4136 /* NOTE: transformed to SHR if unsigned */
4137 gen_op(TOK_SAR);
4138 r = gv(rc);
4139 } else {
4140 if (is_float(vtop->type.t) &&
4141 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4142 Sym *sym;
4143 int *ptr;
4144 unsigned long offset;
4146 /* XXX: unify with initializers handling ? */
4147 /* CPUs usually cannot use float constants, so we store them
4148 generically in data segment */
4149 size = type_size(&vtop->type, &align);
4150 offset = (data_section->data_offset + align - 1) & -align;
4151 data_section->data_offset = offset;
4152 /* XXX: not portable yet */
4153 ptr = section_ptr_add(data_section, size);
4154 size = size >> 2;
4155 for(i=0;i<size;i++)
4156 ptr[i] = vtop->c.tab[i];
4157 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
4158 vtop->r |= VT_LVAL | VT_SYM;
4159 vtop->sym = sym;
4160 vtop->c.ul = 0;
4162 #ifdef CONFIG_TCC_BCHECK
4163 if (vtop->r & VT_MUSTBOUND)
4164 gbound();
4165 #endif
4167 r = vtop->r & VT_VALMASK;
4168 /* need to reload if:
4169 - constant
4170 - lvalue (need to dereference pointer)
4171 - already a register, but not in the right class */
4172 if (r >= VT_CONST ||
4173 (vtop->r & VT_LVAL) ||
4174 !(reg_classes[r] & rc) ||
4175 ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
4176 !(reg_classes[vtop->r2] & rc))) {
4177 r = get_reg(rc);
4178 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
4179 /* two register type load : expand to two words
4180 temporarily */
4181 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4182 /* load constant */
4183 ll = vtop->c.ull;
4184 vtop->c.ui = ll; /* first word */
4185 load(r, vtop);
4186 vtop->r = r; /* save register value */
4187 vpushi(ll >> 32); /* second word */
4188 } else if (r >= VT_CONST ||
4189 (vtop->r & VT_LVAL)) {
4190 /* load from memory */
4191 load(r, vtop);
4192 vdup();
4193 vtop[-1].r = r; /* save register value */
4194 /* increment pointer to get second word */
4195 vtop->type.t = VT_INT;
4196 gaddrof();
4197 vpushi(4);
4198 gen_op('+');
4199 vtop->r |= VT_LVAL;
4200 } else {
4201 /* move registers */
4202 load(r, vtop);
4203 vdup();
4204 vtop[-1].r = r; /* save register value */
4205 vtop->r = vtop[-1].r2;
4207 /* allocate second register */
4208 rc2 = RC_INT;
4209 if (rc == RC_IRET)
4210 rc2 = RC_LRET;
4211 r2 = get_reg(rc2);
4212 load(r2, vtop);
4213 vpop();
4214 /* write second register */
4215 vtop->r2 = r2;
4216 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
4217 int t1, t;
4218 /* lvalue of scalar type : need to use lvalue type
4219 because of possible cast */
4220 t = vtop->type.t;
4221 t1 = t;
4222 /* compute memory access type */
4223 if (vtop->r & VT_LVAL_BYTE)
4224 t = VT_BYTE;
4225 else if (vtop->r & VT_LVAL_SHORT)
4226 t = VT_SHORT;
4227 if (vtop->r & VT_LVAL_UNSIGNED)
4228 t |= VT_UNSIGNED;
4229 vtop->type.t = t;
4230 load(r, vtop);
4231 /* restore wanted type */
4232 vtop->type.t = t1;
4233 } else {
4234 /* one register type load */
4235 load(r, vtop);
4238 vtop->r = r;
4240 return r;
4243 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4244 void gv2(int rc1, int rc2)
4246 int v;
4248 /* generate more generic register first. But VT_JMP or VT_CMP
4249 values must be generated first in all cases to avoid possible
4250 reload errors */
4251 v = vtop[0].r & VT_VALMASK;
4252 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
4253 vswap();
4254 gv(rc1);
4255 vswap();
4256 gv(rc2);
4257 /* test if reload is needed for first register */
4258 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
4259 vswap();
4260 gv(rc1);
4261 vswap();
4263 } else {
4264 gv(rc2);
4265 vswap();
4266 gv(rc1);
4267 vswap();
4268 /* test if reload is needed for first register */
4269 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
4270 gv(rc2);
4275 /* expand long long on stack in two int registers */
4276 void lexpand(void)
4278 int u;
4280 u = vtop->type.t & VT_UNSIGNED;
4281 gv(RC_INT);
4282 vdup();
4283 vtop[0].r = vtop[-1].r2;
4284 vtop[0].r2 = VT_CONST;
4285 vtop[-1].r2 = VT_CONST;
4286 vtop[0].type.t = VT_INT | u;
4287 vtop[-1].type.t = VT_INT | u;
4290 /* build a long long from two ints */
4291 void lbuild(int t)
4293 gv2(RC_INT, RC_INT);
4294 vtop[-1].r2 = vtop[0].r;
4295 vtop[-1].type.t = t;
4296 vpop();
4299 /* rotate n first stack elements to the bottom */
4300 void vrotb(int n)
4302 int i;
4303 SValue tmp;
4305 tmp = vtop[-n + 1];
4306 for(i=-n+1;i!=0;i++)
4307 vtop[i] = vtop[i+1];
4308 vtop[0] = tmp;
4311 /* pop stack value */
4312 void vpop(void)
4314 int v;
4315 v = vtop->r & VT_VALMASK;
4316 #ifdef TCC_TARGET_I386
4317 /* for x86, we need to pop the FP stack */
4318 if (v == REG_ST0 && !nocode_wanted) {
4319 o(0xd9dd); /* fstp %st(1) */
4320 } else
4321 #endif
4322 if (v == VT_JMP || v == VT_JMPI) {
4323 /* need to put correct jump if && or || without test */
4324 gsym(vtop->c.ul);
4326 vtop--;
4329 /* convert stack entry to register and duplicate its value in another
4330 register */
4331 void gv_dup(void)
4333 int rc, t, r, r1;
4334 SValue sv;
4336 t = vtop->type.t;
4337 if ((t & VT_BTYPE) == VT_LLONG) {
4338 lexpand();
4339 gv_dup();
4340 vswap();
4341 vrotb(3);
4342 gv_dup();
4343 vrotb(4);
4344 /* stack: H L L1 H1 */
4345 lbuild(t);
4346 vrotb(3);
4347 vrotb(3);
4348 vswap();
4349 lbuild(t);
4350 vswap();
4351 } else {
4352 /* duplicate value */
4353 rc = RC_INT;
4354 sv.type.t = VT_INT;
4355 if (is_float(t)) {
4356 rc = RC_FLOAT;
4357 sv.type.t = t;
4359 r = gv(rc);
4360 r1 = get_reg(rc);
4361 sv.r = r;
4362 sv.c.ul = 0;
4363 load(r1, &sv); /* move r to r1 */
4364 vdup();
4365 /* duplicates value */
4366 vtop->r = r1;
4370 /* generate CPU independent (unsigned) long long operations */
4371 void gen_opl(int op)
4373 int t, a, b, op1, c, i;
4374 int func;
4375 GFuncContext gf;
4376 SValue tmp;
4378 switch(op) {
4379 case '/':
4380 case TOK_PDIV:
4381 func = TOK___divdi3;
4382 goto gen_func;
4383 case TOK_UDIV:
4384 func = TOK___udivdi3;
4385 goto gen_func;
4386 case '%':
4387 func = TOK___moddi3;
4388 goto gen_func;
4389 case TOK_UMOD:
4390 func = TOK___umoddi3;
4391 gen_func:
4392 /* call generic long long function */
4393 gfunc_start(&gf, FUNC_CDECL);
4394 gfunc_param(&gf);
4395 gfunc_param(&gf);
4396 vpush_global_sym(&func_old_type, func);
4397 gfunc_call(&gf);
4398 vpushi(0);
4399 vtop->r = REG_IRET;
4400 vtop->r2 = REG_LRET;
4401 break;
4402 case '^':
4403 case '&':
4404 case '|':
4405 case '*':
4406 case '+':
4407 case '-':
4408 t = vtop->type.t;
4409 vswap();
4410 lexpand();
4411 vrotb(3);
4412 lexpand();
4413 /* stack: L1 H1 L2 H2 */
4414 tmp = vtop[0];
4415 vtop[0] = vtop[-3];
4416 vtop[-3] = tmp;
4417 tmp = vtop[-2];
4418 vtop[-2] = vtop[-3];
4419 vtop[-3] = tmp;
4420 vswap();
4421 /* stack: H1 H2 L1 L2 */
4422 if (op == '*') {
4423 vpushv(vtop - 1);
4424 vpushv(vtop - 1);
4425 gen_op(TOK_UMULL);
4426 lexpand();
4427 /* stack: H1 H2 L1 L2 ML MH */
4428 for(i=0;i<4;i++)
4429 vrotb(6);
4430 /* stack: ML MH H1 H2 L1 L2 */
4431 tmp = vtop[0];
4432 vtop[0] = vtop[-2];
4433 vtop[-2] = tmp;
4434 /* stack: ML MH H1 L2 H2 L1 */
4435 gen_op('*');
4436 vrotb(3);
4437 vrotb(3);
4438 gen_op('*');
4439 /* stack: ML MH M1 M2 */
4440 gen_op('+');
4441 gen_op('+');
4442 } else if (op == '+' || op == '-') {
4443 /* XXX: add non carry method too (for MIPS or alpha) */
4444 if (op == '+')
4445 op1 = TOK_ADDC1;
4446 else
4447 op1 = TOK_SUBC1;
4448 gen_op(op1);
4449 /* stack: H1 H2 (L1 op L2) */
4450 vrotb(3);
4451 vrotb(3);
4452 gen_op(op1 + 1); /* TOK_xxxC2 */
4453 } else {
4454 gen_op(op);
4455 /* stack: H1 H2 (L1 op L2) */
4456 vrotb(3);
4457 vrotb(3);
4458 /* stack: (L1 op L2) H1 H2 */
4459 gen_op(op);
4460 /* stack: (L1 op L2) (H1 op H2) */
4462 /* stack: L H */
4463 lbuild(t);
4464 break;
4465 case TOK_SAR:
4466 case TOK_SHR:
4467 case TOK_SHL:
4468 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4469 t = vtop[-1].type.t;
4470 vswap();
4471 lexpand();
4472 vrotb(3);
4473 /* stack: L H shift */
4474 c = (int)vtop->c.i;
4475 /* constant: simpler */
4476 /* NOTE: all comments are for SHL. the other cases are
4477 done by swaping words */
4478 vpop();
4479 if (op != TOK_SHL)
4480 vswap();
4481 if (c >= 32) {
4482 /* stack: L H */
4483 vpop();
4484 if (c > 32) {
4485 vpushi(c - 32);
4486 gen_op(op);
4488 if (op != TOK_SAR) {
4489 vpushi(0);
4490 } else {
4491 gv_dup();
4492 vpushi(31);
4493 gen_op(TOK_SAR);
4495 vswap();
4496 } else {
4497 vswap();
4498 gv_dup();
4499 /* stack: H L L */
4500 vpushi(c);
4501 gen_op(op);
4502 vswap();
4503 vpushi(32 - c);
4504 if (op == TOK_SHL)
4505 gen_op(TOK_SHR);
4506 else
4507 gen_op(TOK_SHL);
4508 vrotb(3);
4509 /* stack: L L H */
4510 vpushi(c);
4511 if (op == TOK_SHL)
4512 gen_op(TOK_SHL);
4513 else
4514 gen_op(TOK_SHR);
4515 gen_op('|');
4517 if (op != TOK_SHL)
4518 vswap();
4519 lbuild(t);
4520 } else {
4521 /* XXX: should provide a faster fallback on x86 ? */
4522 switch(op) {
4523 case TOK_SAR:
4524 func = TOK___sardi3;
4525 goto gen_func;
4526 case TOK_SHR:
4527 func = TOK___shrdi3;
4528 goto gen_func;
4529 case TOK_SHL:
4530 func = TOK___shldi3;
4531 goto gen_func;
4534 break;
4535 default:
4536 /* compare operations */
4537 t = vtop->type.t;
4538 vswap();
4539 lexpand();
4540 vrotb(3);
4541 lexpand();
4542 /* stack: L1 H1 L2 H2 */
4543 tmp = vtop[-1];
4544 vtop[-1] = vtop[-2];
4545 vtop[-2] = tmp;
4546 /* stack: L1 L2 H1 H2 */
4547 /* compare high */
4548 op1 = op;
4549 /* when values are equal, we need to compare low words. since
4550 the jump is inverted, we invert the test too. */
4551 if (op1 == TOK_LT)
4552 op1 = TOK_LE;
4553 else if (op1 == TOK_GT)
4554 op1 = TOK_GE;
4555 else if (op1 == TOK_ULT)
4556 op1 = TOK_ULE;
4557 else if (op1 == TOK_UGT)
4558 op1 = TOK_UGE;
4559 a = 0;
4560 b = 0;
4561 gen_op(op1);
4562 if (op1 != TOK_NE) {
4563 a = gtst(1, 0);
4565 if (op != TOK_EQ) {
4566 /* generate non equal test */
4567 /* XXX: NOT PORTABLE yet */
4568 if (a == 0) {
4569 b = gtst(0, 0);
4570 } else {
4571 #ifdef TCC_TARGET_I386
4572 b = psym(0x850f, 0);
4573 #else
4574 error("not implemented");
4575 #endif
4578 /* compare low. Always unsigned */
4579 op1 = op;
4580 if (op1 == TOK_LT)
4581 op1 = TOK_ULT;
4582 else if (op1 == TOK_LE)
4583 op1 = TOK_ULE;
4584 else if (op1 == TOK_GT)
4585 op1 = TOK_UGT;
4586 else if (op1 == TOK_GE)
4587 op1 = TOK_UGE;
4588 gen_op(op1);
4589 a = gtst(1, a);
4590 gsym(b);
4591 vseti(VT_JMPI, a);
4592 break;
4596 /* handle integer constant optimizations and various machine
4597 independant opt */
4598 void gen_opic(int op)
4600 int fc, c1, c2, n;
4601 SValue *v1, *v2;
4603 v1 = vtop - 1;
4604 v2 = vtop;
4605 /* currently, we cannot do computations with forward symbols */
4606 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4607 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4608 if (c1 && c2) {
4609 fc = v2->c.i;
4610 switch(op) {
4611 case '+': v1->c.i += fc; break;
4612 case '-': v1->c.i -= fc; break;
4613 case '&': v1->c.i &= fc; break;
4614 case '^': v1->c.i ^= fc; break;
4615 case '|': v1->c.i |= fc; break;
4616 case '*': v1->c.i *= fc; break;
4618 case TOK_PDIV:
4619 case '/':
4620 case '%':
4621 case TOK_UDIV:
4622 case TOK_UMOD:
4623 /* if division by zero, generate explicit division */
4624 if (fc == 0) {
4625 if (const_wanted)
4626 error("division by zero in constant");
4627 goto general_case;
4629 switch(op) {
4630 default: v1->c.i /= fc; break;
4631 case '%': v1->c.i %= fc; break;
4632 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
4633 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
4635 break;
4636 case TOK_SHL: v1->c.i <<= fc; break;
4637 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
4638 case TOK_SAR: v1->c.i >>= fc; break;
4639 /* tests */
4640 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
4641 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
4642 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
4643 case TOK_NE: v1->c.i = v1->c.i != fc; break;
4644 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
4645 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
4646 case TOK_LT: v1->c.i = v1->c.i < fc; break;
4647 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
4648 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
4649 case TOK_GT: v1->c.i = v1->c.i > fc; break;
4650 /* logical */
4651 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
4652 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
4653 default:
4654 goto general_case;
4656 vtop--;
4657 } else {
4658 /* if commutative ops, put c2 as constant */
4659 if (c1 && (op == '+' || op == '&' || op == '^' ||
4660 op == '|' || op == '*')) {
4661 vswap();
4662 swap(&c1, &c2);
4664 fc = vtop->c.i;
4665 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
4666 op == TOK_PDIV) &&
4667 fc == 1) ||
4668 ((op == '+' || op == '-' || op == '|' || op == '^' ||
4669 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
4670 fc == 0) ||
4671 (op == '&' &&
4672 fc == -1))) {
4673 /* nothing to do */
4674 vtop--;
4675 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
4676 /* try to use shifts instead of muls or divs */
4677 if (fc > 0 && (fc & (fc - 1)) == 0) {
4678 n = -1;
4679 while (fc) {
4680 fc >>= 1;
4681 n++;
4683 vtop->c.i = n;
4684 if (op == '*')
4685 op = TOK_SHL;
4686 else if (op == TOK_PDIV)
4687 op = TOK_SAR;
4688 else
4689 op = TOK_SHR;
4691 goto general_case;
4692 } else if (c2 && (op == '+' || op == '-') &&
4693 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
4694 (VT_CONST | VT_SYM)) {
4695 /* symbol + constant case */
4696 if (op == '-')
4697 fc = -fc;
4698 vtop--;
4699 vtop->c.i += fc;
4700 } else {
4701 general_case:
4702 if (!nocode_wanted) {
4703 /* call low level op generator */
4704 gen_opi(op);
4705 } else {
4706 vtop--;
4712 /* generate a floating point operation with constant propagation */
4713 void gen_opif(int op)
4715 int c1, c2;
4716 SValue *v1, *v2;
4717 long double f1, f2;
4719 v1 = vtop - 1;
4720 v2 = vtop;
4721 /* currently, we cannot do computations with forward symbols */
4722 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4723 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4724 if (c1 && c2) {
4725 if (v1->type.t == VT_FLOAT) {
4726 f1 = v1->c.f;
4727 f2 = v2->c.f;
4728 } else if (v1->type.t == VT_DOUBLE) {
4729 f1 = v1->c.d;
4730 f2 = v2->c.d;
4731 } else {
4732 f1 = v1->c.ld;
4733 f2 = v2->c.ld;
4736 /* NOTE: we only do constant propagation if finite number (not
4737 NaN or infinity) (ANSI spec) */
4738 if (!ieee_finite(f1) || !ieee_finite(f2))
4739 goto general_case;
4741 switch(op) {
4742 case '+': f1 += f2; break;
4743 case '-': f1 -= f2; break;
4744 case '*': f1 *= f2; break;
4745 case '/':
4746 if (f2 == 0.0) {
4747 if (const_wanted)
4748 error("division by zero in constant");
4749 goto general_case;
4751 f1 /= f2;
4752 break;
4753 /* XXX: also handles tests ? */
4754 default:
4755 goto general_case;
4757 /* XXX: overflow test ? */
4758 if (v1->type.t == VT_FLOAT) {
4759 v1->c.f = f1;
4760 } else if (v1->type.t == VT_DOUBLE) {
4761 v1->c.d = f1;
4762 } else {
4763 v1->c.ld = f1;
4765 vtop--;
4766 } else {
4767 general_case:
4768 if (!nocode_wanted) {
4769 gen_opf(op);
4770 } else {
4771 vtop--;
4776 static int pointed_size(CType *type)
4778 int align;
4779 return type_size(pointed_type(type), &align);
4782 #if 0
4783 void check_pointer_types(SValue *p1, SValue *p2)
4785 char buf1[256], buf2[256];
4786 int t1, t2;
4787 t1 = p1->t;
4788 t2 = p2->t;
4789 if (!is_compatible_types(t1, t2)) {
4790 type_to_str(buf1, sizeof(buf1), t1, NULL);
4791 type_to_str(buf2, sizeof(buf2), t2, NULL);
4792 error("incompatible pointers '%s' and '%s'", buf1, buf2);
4795 #endif
4797 /* generic gen_op: handles types problems */
4798 void gen_op(int op)
4800 int u, t1, t2, bt1, bt2, t;
4801 CType type1;
4803 t1 = vtop[-1].type.t;
4804 t2 = vtop[0].type.t;
4805 bt1 = t1 & VT_BTYPE;
4806 bt2 = t2 & VT_BTYPE;
4808 if (bt1 == VT_PTR || bt2 == VT_PTR) {
4809 /* at least one operand is a pointer */
4810 /* relationnal op: must be both pointers */
4811 if (op >= TOK_ULT && op <= TOK_GT) {
4812 // check_pointer_types(vtop, vtop - 1);
4813 /* pointers are handled are unsigned */
4814 t = VT_INT | VT_UNSIGNED;
4815 goto std_op;
4817 /* if both pointers, then it must be the '-' op */
4818 if (bt1 == VT_PTR && bt2 == VT_PTR) {
4819 if (op != '-')
4820 error("cannot use pointers here");
4821 // check_pointer_types(vtop - 1, vtop);
4822 /* XXX: check that types are compatible */
4823 u = pointed_size(&vtop[-1].type);
4824 gen_opic(op);
4825 /* set to integer type */
4826 vtop->type.t = VT_INT;
4827 vpushi(u);
4828 gen_op(TOK_PDIV);
4829 } else {
4830 /* exactly one pointer : must be '+' or '-'. */
4831 if (op != '-' && op != '+')
4832 error("cannot use pointers here");
4833 /* Put pointer as first operand */
4834 if (bt2 == VT_PTR) {
4835 vswap();
4836 swap(&t1, &t2);
4838 type1 = vtop[-1].type;
4839 /* XXX: cast to int ? (long long case) */
4840 vpushi(pointed_size(&vtop[-1].type));
4841 gen_op('*');
4842 #ifdef CONFIG_TCC_BCHECK
4843 /* if evaluating constant expression, no code should be
4844 generated, so no bound check */
4845 if (do_bounds_check && !const_wanted) {
4846 /* if bounded pointers, we generate a special code to
4847 test bounds */
4848 if (op == '-') {
4849 vpushi(0);
4850 vswap();
4851 gen_op('-');
4853 gen_bounded_ptr_add();
4854 } else
4855 #endif
4857 gen_opic(op);
4859 /* put again type if gen_opic() swaped operands */
4860 vtop->type = type1;
4862 } else if (is_float(bt1) || is_float(bt2)) {
4863 /* compute bigger type and do implicit casts */
4864 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4865 t = VT_LDOUBLE;
4866 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4867 t = VT_DOUBLE;
4868 } else {
4869 t = VT_FLOAT;
4871 /* floats can only be used for a few operations */
4872 if (op != '+' && op != '-' && op != '*' && op != '/' &&
4873 (op < TOK_ULT || op > TOK_GT))
4874 error("invalid operands for binary operation");
4875 goto std_op;
4876 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4877 /* cast to biggest op */
4878 t = VT_LLONG;
4879 /* convert to unsigned if it does not fit in a long long */
4880 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4881 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4882 t |= VT_UNSIGNED;
4883 goto std_op;
4884 } else {
4885 /* integer operations */
4886 t = VT_INT;
4887 /* convert to unsigned if it does not fit in an integer */
4888 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4889 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4890 t |= VT_UNSIGNED;
4891 std_op:
4892 /* XXX: currently, some unsigned operations are explicit, so
4893 we modify them here */
4894 if (t & VT_UNSIGNED) {
4895 if (op == TOK_SAR)
4896 op = TOK_SHR;
4897 else if (op == '/')
4898 op = TOK_UDIV;
4899 else if (op == '%')
4900 op = TOK_UMOD;
4901 else if (op == TOK_LT)
4902 op = TOK_ULT;
4903 else if (op == TOK_GT)
4904 op = TOK_UGT;
4905 else if (op == TOK_LE)
4906 op = TOK_ULE;
4907 else if (op == TOK_GE)
4908 op = TOK_UGE;
4910 vswap();
4911 type1.t = t;
4912 gen_cast(&type1);
4913 vswap();
4914 /* special case for shifts and long long: we keep the shift as
4915 an integer */
4916 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
4917 type1.t = VT_INT;
4918 gen_cast(&type1);
4919 if (is_float(t))
4920 gen_opif(op);
4921 else if ((t & VT_BTYPE) == VT_LLONG)
4922 gen_opl(op);
4923 else
4924 gen_opic(op);
4925 if (op >= TOK_ULT && op <= TOK_GT) {
4926 /* relationnal op: the result is an int */
4927 vtop->type.t = VT_INT;
4928 } else {
4929 vtop->type.t = t;
4934 /* generic itof for unsigned long long case */
4935 void gen_cvt_itof1(int t)
4937 GFuncContext gf;
4939 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
4940 (VT_LLONG | VT_UNSIGNED)) {
4942 gfunc_start(&gf, FUNC_CDECL);
4943 gfunc_param(&gf);
4944 if (t == VT_FLOAT)
4945 vpush_global_sym(&func_old_type, TOK___ulltof);
4946 else if (t == VT_DOUBLE)
4947 vpush_global_sym(&func_old_type, TOK___ulltod);
4948 else
4949 vpush_global_sym(&func_old_type, TOK___ulltold);
4950 gfunc_call(&gf);
4951 vpushi(0);
4952 vtop->r = REG_FRET;
4953 } else {
4954 gen_cvt_itof(t);
4958 /* generic ftoi for unsigned long long case */
4959 void gen_cvt_ftoi1(int t)
4961 GFuncContext gf;
4962 int st;
4964 if (t == (VT_LLONG | VT_UNSIGNED)) {
4965 /* not handled natively */
4966 gfunc_start(&gf, FUNC_CDECL);
4967 st = vtop->type.t & VT_BTYPE;
4968 gfunc_param(&gf);
4969 if (st == VT_FLOAT)
4970 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
4971 else if (st == VT_DOUBLE)
4972 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
4973 else
4974 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
4975 gfunc_call(&gf);
4976 vpushi(0);
4977 vtop->r = REG_IRET;
4978 vtop->r2 = REG_LRET;
4979 } else {
4980 gen_cvt_ftoi(t);
4984 /* force char or short cast */
4985 void force_charshort_cast(int t)
4987 int bits, dbt;
4988 dbt = t & VT_BTYPE;
4989 /* XXX: add optimization if lvalue : just change type and offset */
4990 if (dbt == VT_BYTE)
4991 bits = 8;
4992 else
4993 bits = 16;
4994 if (t & VT_UNSIGNED) {
4995 vpushi((1 << bits) - 1);
4996 gen_op('&');
4997 } else {
4998 bits = 32 - bits;
4999 vpushi(bits);
5000 gen_op(TOK_SHL);
5001 vpushi(bits);
5002 gen_op(TOK_SAR);
5006 /* cast 'vtop' to 'type' */
5007 static void gen_cast(CType *type)
5009 int sbt, dbt, sf, df, c;
5011 /* special delayed cast for char/short */
5012 /* XXX: in some cases (multiple cascaded casts), it may still
5013 be incorrect */
5014 if (vtop->r & VT_MUSTCAST) {
5015 vtop->r &= ~VT_MUSTCAST;
5016 force_charshort_cast(vtop->type.t);
5019 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
5020 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
5022 if (sbt != dbt && !nocode_wanted) {
5023 sf = is_float(sbt);
5024 df = is_float(dbt);
5025 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5026 if (sf && df) {
5027 /* convert from fp to fp */
5028 if (c) {
5029 /* constant case: we can do it now */
5030 /* XXX: in ISOC, cannot do it if error in convert */
5031 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
5032 vtop->c.f = (float)vtop->c.d;
5033 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
5034 vtop->c.f = (float)vtop->c.ld;
5035 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
5036 vtop->c.d = (double)vtop->c.f;
5037 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
5038 vtop->c.d = (double)vtop->c.ld;
5039 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
5040 vtop->c.ld = (long double)vtop->c.f;
5041 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
5042 vtop->c.ld = (long double)vtop->c.d;
5043 } else {
5044 /* non constant case: generate code */
5045 gen_cvt_ftof(dbt);
5047 } else if (df) {
5048 /* convert int to fp */
5049 if (c) {
5050 switch(sbt) {
5051 case VT_LLONG | VT_UNSIGNED:
5052 case VT_LLONG:
5053 /* XXX: add const cases for long long */
5054 goto do_itof;
5055 case VT_INT | VT_UNSIGNED:
5056 switch(dbt) {
5057 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
5058 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
5059 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
5061 break;
5062 default:
5063 switch(dbt) {
5064 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
5065 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
5066 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
5068 break;
5070 } else {
5071 do_itof:
5072 gen_cvt_itof1(dbt);
5074 } else if (sf) {
5075 /* convert fp to int */
5076 /* we handle char/short/etc... with generic code */
5077 if (dbt != (VT_INT | VT_UNSIGNED) &&
5078 dbt != (VT_LLONG | VT_UNSIGNED) &&
5079 dbt != VT_LLONG)
5080 dbt = VT_INT;
5081 if (c) {
5082 switch(dbt) {
5083 case VT_LLONG | VT_UNSIGNED:
5084 case VT_LLONG:
5085 /* XXX: add const cases for long long */
5086 goto do_ftoi;
5087 case VT_INT | VT_UNSIGNED:
5088 switch(sbt) {
5089 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
5090 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5091 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5093 break;
5094 default:
5095 /* int case */
5096 switch(sbt) {
5097 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
5098 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
5099 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
5101 break;
5103 } else {
5104 do_ftoi:
5105 gen_cvt_ftoi1(dbt);
5107 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
5108 /* additionnal cast for char/short/bool... */
5109 vtop->type.t = dbt;
5110 gen_cast(type);
5112 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
5113 if ((sbt & VT_BTYPE) != VT_LLONG) {
5114 /* scalar to long long */
5115 if (c) {
5116 if (sbt == (VT_INT | VT_UNSIGNED))
5117 vtop->c.ll = vtop->c.ui;
5118 else
5119 vtop->c.ll = vtop->c.i;
5120 } else {
5121 /* machine independant conversion */
5122 gv(RC_INT);
5123 /* generate high word */
5124 if (sbt == (VT_INT | VT_UNSIGNED)) {
5125 vpushi(0);
5126 gv(RC_INT);
5127 } else {
5128 gv_dup();
5129 vpushi(31);
5130 gen_op(TOK_SAR);
5132 /* patch second register */
5133 vtop[-1].r2 = vtop->r;
5134 vpop();
5137 } else if (dbt == VT_BOOL) {
5138 /* scalar to bool */
5139 vpushi(0);
5140 gen_op(TOK_NE);
5141 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
5142 (dbt & VT_BTYPE) == VT_SHORT) {
5143 force_charshort_cast(dbt);
5144 } else if ((dbt & VT_BTYPE) == VT_INT) {
5145 /* scalar to int */
5146 if (sbt == VT_LLONG) {
5147 /* from long long: just take low order word */
5148 lexpand();
5149 vpop();
5151 /* if lvalue and single word type, nothing to do because
5152 the lvalue already contains the real type size (see
5153 VT_LVAL_xxx constants) */
5156 vtop->type = *type;
5159 /* return type size. Put alignment at 'a' */
5160 static int type_size(CType *type, int *a)
5162 Sym *s;
5163 int bt;
5165 bt = type->t & VT_BTYPE;
5166 if (bt == VT_STRUCT) {
5167 /* struct/union */
5168 s = type->ref;
5169 *a = s->r;
5170 return s->c;
5171 } else if (bt == VT_PTR) {
5172 if (type->t & VT_ARRAY) {
5173 s = type->ref;
5174 return type_size(&s->type, a) * s->c;
5175 } else {
5176 *a = PTR_SIZE;
5177 return PTR_SIZE;
5179 } else if (bt == VT_LDOUBLE) {
5180 *a = LDOUBLE_ALIGN;
5181 return LDOUBLE_SIZE;
5182 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
5183 *a = 4; /* XXX: i386 specific */
5184 return 8;
5185 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
5186 *a = 4;
5187 return 4;
5188 } else if (bt == VT_SHORT) {
5189 *a = 2;
5190 return 2;
5191 } else {
5192 /* char, void, function, _Bool */
5193 *a = 1;
5194 return 1;
5198 /* return the pointed type of t */
5199 static inline CType *pointed_type(CType *type)
5201 return &type->ref->type;
5204 /* modify type so that its it is a pointer to type. */
5205 static void mk_pointer(CType *type)
5207 Sym *s;
5208 s = sym_push(SYM_FIELD, type, 0, -1);
5209 type->t = VT_PTR | (type->t & ~VT_TYPE);
5210 type->ref = s;
5213 static int is_compatible_types(CType *type1, CType *type2)
5215 Sym *s1, *s2;
5216 int bt1, bt2, t1, t2;
5218 t1 = type1->t & VT_TYPE;
5219 t2 = type2->t & VT_TYPE;
5220 bt1 = t1 & VT_BTYPE;
5221 bt2 = t2 & VT_BTYPE;
5222 if (bt1 == VT_PTR) {
5223 type1 = pointed_type(type1);
5224 /* if function, then convert implicitely to function pointer */
5225 if (bt2 != VT_FUNC) {
5226 if (bt2 != VT_PTR)
5227 return 0;
5228 type2 = pointed_type(type2);
5230 /* void matches everything */
5231 /* XXX: not fully compliant */
5232 if ((type1->t & VT_TYPE) == VT_VOID || (type2->t & VT_TYPE) == VT_VOID)
5233 return 1;
5234 return is_compatible_types(type1, type2);
5235 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5236 return (type1->ref == type2->ref);
5237 } else if (bt1 == VT_FUNC) {
5238 if (bt2 != VT_FUNC)
5239 return 0;
5240 s1 = type1->ref;
5241 s2 = type2->ref;
5242 if (!is_compatible_types(&s1->type, &s2->type))
5243 return 0;
5244 /* XXX: not complete */
5245 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
5246 return 1;
5247 if (s1->c != s2->c)
5248 return 0;
5249 while (s1 != NULL) {
5250 if (s2 == NULL)
5251 return 0;
5252 if (!is_compatible_types(&s1->type, &s2->type))
5253 return 0;
5254 s1 = s1->next;
5255 s2 = s2->next;
5257 if (s2)
5258 return 0;
5259 return 1;
5260 } else {
5261 /* XXX: not complete */
5262 return 1;
5266 /* print a type. If 'varstr' is not NULL, then the variable is also
5267 printed in the type */
5268 /* XXX: union */
5269 /* XXX: add array and function pointers */
5270 void type_to_str(char *buf, int buf_size,
5271 CType *type, const char *varstr)
5273 int bt, v, t;
5274 Sym *s, *sa;
5275 char buf1[256];
5276 const char *tstr;
5278 t = type->t & VT_TYPE;
5279 bt = t & VT_BTYPE;
5280 buf[0] = '\0';
5281 if (t & VT_UNSIGNED)
5282 pstrcat(buf, buf_size, "unsigned ");
5283 switch(bt) {
5284 case VT_VOID:
5285 tstr = "void";
5286 goto add_tstr;
5287 case VT_BOOL:
5288 tstr = "_Bool";
5289 goto add_tstr;
5290 case VT_BYTE:
5291 tstr = "char";
5292 goto add_tstr;
5293 case VT_SHORT:
5294 tstr = "short";
5295 goto add_tstr;
5296 case VT_INT:
5297 tstr = "int";
5298 goto add_tstr;
5299 case VT_LONG:
5300 tstr = "long";
5301 goto add_tstr;
5302 case VT_LLONG:
5303 tstr = "long long";
5304 goto add_tstr;
5305 case VT_FLOAT:
5306 tstr = "float";
5307 goto add_tstr;
5308 case VT_DOUBLE:
5309 tstr = "double";
5310 goto add_tstr;
5311 case VT_LDOUBLE:
5312 tstr = "long double";
5313 add_tstr:
5314 pstrcat(buf, buf_size, tstr);
5315 break;
5316 case VT_ENUM:
5317 case VT_STRUCT:
5318 if (bt == VT_STRUCT)
5319 tstr = "struct ";
5320 else
5321 tstr = "enum ";
5322 pstrcat(buf, buf_size, tstr);
5323 v = type->ref->v & ~SYM_STRUCT;
5324 if (v >= SYM_FIRST_ANOM)
5325 pstrcat(buf, buf_size, "<anonymous>");
5326 else
5327 pstrcat(buf, buf_size, get_tok_str(v, NULL));
5328 break;
5329 case VT_FUNC:
5330 s = type->ref;
5331 type_to_str(buf, buf_size, &s->type, varstr);
5332 pstrcat(buf, buf_size, "(");
5333 sa = s->next;
5334 while (sa != NULL) {
5335 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
5336 pstrcat(buf, buf_size, buf1);
5337 sa = sa->next;
5338 if (sa)
5339 pstrcat(buf, buf_size, ", ");
5341 pstrcat(buf, buf_size, ")");
5342 goto no_var;
5343 case VT_PTR:
5344 s = type->ref;
5345 pstrcpy(buf1, sizeof(buf1), "*");
5346 if (varstr)
5347 pstrcat(buf1, sizeof(buf1), varstr);
5348 type_to_str(buf, buf_size, &s->type, buf1);
5349 goto no_var;
5351 if (varstr) {
5352 pstrcat(buf, buf_size, " ");
5353 pstrcat(buf, buf_size, varstr);
5355 no_var: ;
5358 /* verify type compatibility to store vtop in 'dt' type, and generate
5359 casts if needed. */
5360 static void gen_assign_cast(CType *dt)
5362 CType *st;
5363 char buf1[256], buf2[256];
5364 int dbt, sbt;
5366 st = &vtop->type; /* source type */
5367 dbt = dt->t & VT_BTYPE;
5368 sbt = st->t & VT_BTYPE;
5369 if (dbt == VT_PTR) {
5370 /* special cases for pointers */
5371 /* a function is implicitely a function pointer */
5372 if (sbt == VT_FUNC) {
5373 if (!is_compatible_types(pointed_type(dt), st))
5374 goto error;
5375 else
5376 goto type_ok;
5378 /* '0' can also be a pointer */
5379 if (sbt == VT_INT &&
5380 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
5381 vtop->c.i == 0)
5382 goto type_ok;
5383 /* accept implicit pointer to integer cast with warning */
5384 if (sbt == VT_BYTE || sbt == VT_SHORT ||
5385 sbt == VT_INT || sbt == VT_LLONG) {
5386 warning("assignment makes pointer from integer without a cast");
5387 goto type_ok;
5389 } else if (dbt == VT_BYTE || dbt == VT_SHORT ||
5390 dbt == VT_INT || dbt == VT_LLONG) {
5391 if (sbt == VT_PTR || sbt == VT_FUNC) {
5392 warning("assignment makes integer from pointer without a cast");
5393 goto type_ok;
5396 if (!is_compatible_types(dt, st)) {
5397 error:
5398 type_to_str(buf1, sizeof(buf1), st, NULL);
5399 type_to_str(buf2, sizeof(buf2), dt, NULL);
5400 error("cannot cast '%s' to '%s'", buf1, buf2);
5402 type_ok:
5403 gen_cast(dt);
5406 /* store vtop in lvalue pushed on stack */
5407 void vstore(void)
5409 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
5410 GFuncContext gf;
5412 ft = vtop[-1].type.t;
5413 sbt = vtop->type.t & VT_BTYPE;
5414 dbt = ft & VT_BTYPE;
5415 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
5416 (sbt == VT_INT && dbt == VT_SHORT)) {
5417 /* optimize char/short casts */
5418 delayed_cast = VT_MUSTCAST;
5419 vtop->type.t = ft & VT_TYPE;
5420 } else {
5421 delayed_cast = 0;
5422 gen_assign_cast(&vtop[-1].type);
5425 if (sbt == VT_STRUCT) {
5426 /* if structure, only generate pointer */
5427 /* structure assignment : generate memcpy */
5428 /* XXX: optimize if small size */
5429 if (!nocode_wanted) {
5430 vdup();
5431 gfunc_start(&gf, FUNC_CDECL);
5432 /* type size */
5433 size = type_size(&vtop->type, &align);
5434 vpushi(size);
5435 gfunc_param(&gf);
5436 /* source */
5437 vtop->type.t = VT_INT;
5438 gaddrof();
5439 gfunc_param(&gf);
5440 /* destination */
5441 vswap();
5442 vtop->type.t = VT_INT;
5443 gaddrof();
5444 gfunc_param(&gf);
5446 save_regs(0);
5447 vpush_global_sym(&func_old_type, TOK_memcpy);
5448 gfunc_call(&gf);
5449 } else {
5450 vswap();
5451 vpop();
5453 /* leave source on stack */
5454 } else if (ft & VT_BITFIELD) {
5455 /* bitfield store handling */
5456 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
5457 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5458 /* remove bit field info to avoid loops */
5459 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
5461 /* duplicate destination */
5462 vdup();
5463 vtop[-1] = vtop[-2];
5465 /* mask and shift source */
5466 vpushi((1 << bit_size) - 1);
5467 gen_op('&');
5468 vpushi(bit_pos);
5469 gen_op(TOK_SHL);
5470 /* load destination, mask and or with source */
5471 vswap();
5472 vpushi(~(((1 << bit_size) - 1) << bit_pos));
5473 gen_op('&');
5474 gen_op('|');
5475 /* store result */
5476 vstore();
5477 } else {
5478 #ifdef CONFIG_TCC_BCHECK
5479 /* bound check case */
5480 if (vtop[-1].r & VT_MUSTBOUND) {
5481 vswap();
5482 gbound();
5483 vswap();
5485 #endif
5486 if (!nocode_wanted) {
5487 rc = RC_INT;
5488 if (is_float(ft))
5489 rc = RC_FLOAT;
5490 r = gv(rc); /* generate value */
5491 /* if lvalue was saved on stack, must read it */
5492 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
5493 SValue sv;
5494 t = get_reg(RC_INT);
5495 sv.type.t = VT_INT;
5496 sv.r = VT_LOCAL | VT_LVAL;
5497 sv.c.ul = vtop[-1].c.ul;
5498 load(t, &sv);
5499 vtop[-1].r = t | VT_LVAL;
5501 store(r, vtop - 1);
5502 /* two word case handling : store second register at word + 4 */
5503 if ((ft & VT_BTYPE) == VT_LLONG) {
5504 vswap();
5505 /* convert to int to increment easily */
5506 vtop->type.t = VT_INT;
5507 gaddrof();
5508 vpushi(4);
5509 gen_op('+');
5510 vtop->r |= VT_LVAL;
5511 vswap();
5512 /* XXX: it works because r2 is spilled last ! */
5513 store(vtop->r2, vtop - 1);
5516 vswap();
5517 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5518 vtop->r |= delayed_cast;
5522 /* post defines POST/PRE add. c is the token ++ or -- */
5523 void inc(int post, int c)
5525 test_lvalue();
5526 vdup(); /* save lvalue */
5527 if (post) {
5528 gv_dup(); /* duplicate value */
5529 vrotb(3);
5530 vrotb(3);
5532 /* add constant */
5533 vpushi(c - TOK_MID);
5534 gen_op('+');
5535 vstore(); /* store value */
5536 if (post)
5537 vpop(); /* if post op, return saved value */
5540 /* Parse GNUC __attribute__ extension. Currently, the following
5541 extensions are recognized:
5542 - aligned(n) : set data/function alignment.
5543 - section(x) : generate data/code in this section.
5544 - unused : currently ignored, but may be used someday.
5546 void parse_attribute(AttributeDef *ad)
5548 int t, n;
5550 next();
5551 skip('(');
5552 skip('(');
5553 while (tok != ')') {
5554 if (tok < TOK_IDENT)
5555 expect("attribute name");
5556 t = tok;
5557 next();
5558 switch(t) {
5559 case TOK_SECTION:
5560 case TOK___SECTION__:
5561 skip('(');
5562 if (tok != TOK_STR)
5563 expect("section name");
5564 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
5565 next();
5566 skip(')');
5567 break;
5568 case TOK_ALIGNED:
5569 case TOK___ALIGNED__:
5570 skip('(');
5571 n = expr_const();
5572 if (n <= 0 || (n & (n - 1)) != 0)
5573 error("alignment must be a positive power of two");
5574 ad->aligned = n;
5575 skip(')');
5576 break;
5577 case TOK_UNUSED:
5578 case TOK___UNUSED__:
5579 /* currently, no need to handle it because tcc does not
5580 track unused objects */
5581 break;
5582 case TOK_NORETURN:
5583 case TOK___NORETURN__:
5584 /* currently, no need to handle it because tcc does not
5585 track unused objects */
5586 break;
5587 case TOK_CDECL:
5588 case TOK___CDECL:
5589 case TOK___CDECL__:
5590 ad->func_call = FUNC_CDECL;
5591 break;
5592 case TOK_STDCALL:
5593 case TOK___STDCALL:
5594 case TOK___STDCALL__:
5595 ad->func_call = FUNC_STDCALL;
5596 break;
5597 default:
5598 warning("'%s' attribute ignored", get_tok_str(t, NULL));
5599 /* skip parameters */
5600 /* XXX: skip parenthesis too */
5601 if (tok == '(') {
5602 next();
5603 while (tok != ')' && tok != -1)
5604 next();
5605 next();
5607 break;
5609 if (tok != ',')
5610 break;
5611 next();
5613 skip(')');
5614 skip(')');
5617 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5618 static void struct_decl(CType *type, int u)
5620 int a, v, size, align, maxalign, c, offset;
5621 int bit_size, bit_pos, bsize, bt, lbit_pos;
5622 Sym *s, *ss, **ps;
5623 AttributeDef ad;
5624 CType type1, btype;
5626 a = tok; /* save decl type */
5627 next();
5628 if (tok != '{') {
5629 v = tok;
5630 next();
5631 /* struct already defined ? return it */
5632 /* XXX: check consistency */
5633 s = struct_find(v);
5634 if (s) {
5635 if (s->type.t != a)
5636 error("invalid type");
5637 goto do_decl;
5639 } else {
5640 v = anon_sym++;
5642 type1.t = a;
5643 s = sym_push(v | SYM_STRUCT, &type1, 0, 0);
5644 /* put struct/union/enum name in type */
5645 do_decl:
5646 type->t = u;
5647 type->ref = s;
5649 if (tok == '{') {
5650 next();
5651 if (s->c)
5652 error("struct/union/enum already defined");
5653 /* cannot be empty */
5654 c = 0;
5655 /* non empty enums are not allowed */
5656 if (a == TOK_ENUM) {
5657 for(;;) {
5658 v = tok;
5659 if (v < TOK_UIDENT)
5660 expect("identifier");
5661 next();
5662 if (tok == '=') {
5663 next();
5664 c = expr_const();
5666 /* enum symbols have static storage */
5667 ss = sym_push(v, &int_type, VT_CONST, c);
5668 ss->type.t |= VT_STATIC;
5669 if (tok != ',')
5670 break;
5671 next();
5672 c++;
5673 /* NOTE: we accept a trailing comma */
5674 if (tok == '}')
5675 break;
5677 skip('}');
5678 } else {
5679 maxalign = 1;
5680 ps = &s->next;
5681 bit_pos = 0;
5682 offset = 0;
5683 while (tok != '}') {
5684 parse_btype(&btype, &ad);
5685 while (1) {
5686 bit_size = -1;
5687 v = 0;
5688 type1 = btype;
5689 if (tok != ':') {
5690 type_decl(&type1, &ad, &v, TYPE_DIRECT);
5691 if ((type1.t & VT_BTYPE) == VT_FUNC ||
5692 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
5693 error("invalid type for '%s'",
5694 get_tok_str(v, NULL));
5696 if (tok == ':') {
5697 next();
5698 bit_size = expr_const();
5699 /* XXX: handle v = 0 case for messages */
5700 if (bit_size < 0)
5701 error("negative width in bit-field '%s'",
5702 get_tok_str(v, NULL));
5703 if (v && bit_size == 0)
5704 error("zero width for bit-field '%s'",
5705 get_tok_str(v, NULL));
5707 size = type_size(&type1, &align);
5708 lbit_pos = 0;
5709 if (bit_size >= 0) {
5710 bt = type1.t & VT_BTYPE;
5711 if (bt != VT_INT &&
5712 bt != VT_BYTE &&
5713 bt != VT_SHORT &&
5714 bt != VT_ENUM)
5715 error("bitfields must have scalar type");
5716 bsize = size * 8;
5717 if (bit_size > bsize) {
5718 error("width of '%s' exceeds its type",
5719 get_tok_str(v, NULL));
5720 } else if (bit_size == bsize) {
5721 /* no need for bit fields */
5722 bit_pos = 0;
5723 } else if (bit_size == 0) {
5724 /* XXX: what to do if only padding in a
5725 structure ? */
5726 /* zero size: means to pad */
5727 if (bit_pos > 0)
5728 bit_pos = bsize;
5729 } else {
5730 /* we do not have enough room ? */
5731 if ((bit_pos + bit_size) > bsize)
5732 bit_pos = 0;
5733 lbit_pos = bit_pos;
5734 /* XXX: handle LSB first */
5735 type1.t |= VT_BITFIELD |
5736 (bit_pos << VT_STRUCT_SHIFT) |
5737 (bit_size << (VT_STRUCT_SHIFT + 6));
5738 bit_pos += bit_size;
5740 } else {
5741 bit_pos = 0;
5743 if (v) {
5744 /* add new memory data only if starting
5745 bit field */
5746 if (lbit_pos == 0) {
5747 if (a == TOK_STRUCT) {
5748 c = (c + align - 1) & -align;
5749 offset = c;
5750 c += size;
5751 } else {
5752 offset = 0;
5753 if (size > c)
5754 c = size;
5756 if (align > maxalign)
5757 maxalign = align;
5759 #if 0
5760 printf("add field %s offset=%d",
5761 get_tok_str(v, NULL), offset);
5762 if (type1.t & VT_BITFIELD) {
5763 printf(" pos=%d size=%d",
5764 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
5765 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
5767 printf("\n");
5768 #endif
5769 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
5770 *ps = ss;
5771 ps = &ss->next;
5773 if (tok == ';' || tok == TOK_EOF)
5774 break;
5775 skip(',');
5777 skip(';');
5779 skip('}');
5780 /* store size and alignment */
5781 s->c = (c + maxalign - 1) & -maxalign;
5782 s->r = maxalign;
5787 /* return 0 if no type declaration. otherwise, return the basic type
5788 and skip it.
5790 static int parse_btype(CType *type, AttributeDef *ad)
5792 int t, u, type_found;
5793 Sym *s;
5794 CType type1;
5796 memset(ad, 0, sizeof(AttributeDef));
5797 type_found = 0;
5798 t = 0;
5799 while(1) {
5800 switch(tok) {
5801 /* basic types */
5802 case TOK_CHAR:
5803 u = VT_BYTE;
5804 basic_type:
5805 next();
5806 basic_type1:
5807 if ((t & VT_BTYPE) != 0)
5808 error("too many basic types");
5809 t |= u;
5810 break;
5811 case TOK_VOID:
5812 u = VT_VOID;
5813 goto basic_type;
5814 case TOK_SHORT:
5815 u = VT_SHORT;
5816 goto basic_type;
5817 case TOK_INT:
5818 next();
5819 break;
5820 case TOK_LONG:
5821 next();
5822 if ((t & VT_BTYPE) == VT_DOUBLE) {
5823 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5824 } else if ((t & VT_BTYPE) == VT_LONG) {
5825 t = (t & ~VT_BTYPE) | VT_LLONG;
5826 } else {
5827 u = VT_LONG;
5828 goto basic_type1;
5830 break;
5831 case TOK_BOOL:
5832 u = VT_BOOL;
5833 goto basic_type;
5834 case TOK_FLOAT:
5835 u = VT_FLOAT;
5836 goto basic_type;
5837 case TOK_DOUBLE:
5838 next();
5839 if ((t & VT_BTYPE) == VT_LONG) {
5840 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5841 } else {
5842 u = VT_DOUBLE;
5843 goto basic_type1;
5845 break;
5846 case TOK_ENUM:
5847 struct_decl(&type1, VT_ENUM);
5848 basic_type2:
5849 u = type1.t;
5850 type->ref = type1.ref;
5851 goto basic_type1;
5852 case TOK_STRUCT:
5853 case TOK_UNION:
5854 struct_decl(&type1, VT_STRUCT);
5855 goto basic_type2;
5857 /* type modifiers */
5858 case TOK_CONST:
5859 case TOK_VOLATILE:
5860 case TOK_REGISTER:
5861 case TOK_SIGNED:
5862 case TOK___SIGNED__:
5863 case TOK_AUTO:
5864 case TOK_INLINE:
5865 case TOK___INLINE__:
5866 case TOK_RESTRICT:
5867 next();
5868 break;
5869 case TOK_UNSIGNED:
5870 t |= VT_UNSIGNED;
5871 next();
5872 break;
5874 /* storage */
5875 case TOK_EXTERN:
5876 t |= VT_EXTERN;
5877 next();
5878 break;
5879 case TOK_STATIC:
5880 t |= VT_STATIC;
5881 next();
5882 break;
5883 case TOK_TYPEDEF:
5884 t |= VT_TYPEDEF;
5885 next();
5886 break;
5887 /* GNUC attribute */
5888 case TOK___ATTRIBUTE__:
5889 parse_attribute(ad);
5890 break;
5891 /* GNUC typeof */
5892 case TOK_TYPEOF:
5893 next();
5894 parse_expr_type(&type1);
5895 goto basic_type2;
5896 default:
5897 s = sym_find(tok);
5898 if (!s || !(s->type.t & VT_TYPEDEF))
5899 goto the_end;
5900 t |= (s->type.t & ~VT_TYPEDEF);
5901 type->ref = s->type.ref;
5902 next();
5903 break;
5905 type_found = 1;
5907 the_end:
5908 /* long is never used as type */
5909 if ((t & VT_BTYPE) == VT_LONG)
5910 t = (t & ~VT_BTYPE) | VT_INT;
5911 type->t = t;
5912 return type_found;
5915 static void post_type(CType *type, AttributeDef *ad)
5917 int n, l, t1;
5918 Sym **plast, *s, *first;
5919 AttributeDef ad1;
5920 CType pt;
5922 if (tok == '(') {
5923 /* function declaration */
5924 next();
5925 l = 0;
5926 first = NULL;
5927 plast = &first;
5928 while (tok != ')') {
5929 /* read param name and compute offset */
5930 if (l != FUNC_OLD) {
5931 if (!parse_btype(&pt, &ad1)) {
5932 if (l) {
5933 error("invalid type");
5934 } else {
5935 l = FUNC_OLD;
5936 goto old_proto;
5939 l = FUNC_NEW;
5940 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
5941 break;
5942 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
5943 if ((pt.t & VT_BTYPE) == VT_VOID)
5944 error("parameter declared as void");
5945 } else {
5946 old_proto:
5947 n = tok;
5948 pt.t = VT_INT;
5949 next();
5951 /* array must be transformed to pointer according to ANSI C */
5952 pt.t &= ~VT_ARRAY;
5953 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
5954 *plast = s;
5955 plast = &s->next;
5956 if (tok == ',') {
5957 next();
5958 if (l == FUNC_NEW && tok == TOK_DOTS) {
5959 l = FUNC_ELLIPSIS;
5960 next();
5961 break;
5965 /* if no parameters, then old type prototype */
5966 if (l == 0)
5967 l = FUNC_OLD;
5968 skip(')');
5969 t1 = type->t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5970 type->t &= ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5971 post_type(type, ad);
5972 /* we push a anonymous symbol which will contain the function prototype */
5973 s = sym_push(SYM_FIELD, type, ad->func_call, l);
5974 s->next = first;
5975 type->t = t1 | VT_FUNC;
5976 type->ref = s;
5977 } else if (tok == '[') {
5978 /* array definition */
5979 next();
5980 n = -1;
5981 if (tok != ']') {
5982 n = expr_const();
5983 if (n < 0)
5984 error("invalid array size");
5986 skip(']');
5987 /* parse next post type */
5988 t1 = type->t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5989 type->t &= ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5990 post_type(type, ad);
5992 /* we push a anonymous symbol which will contain the array
5993 element type */
5994 s = sym_push(SYM_FIELD, type, 0, n);
5995 type->t = t1 | VT_ARRAY | VT_PTR;
5996 type->ref = s;
6000 /* Parse a type declaration (except basic type), and return the type
6001 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6002 expected. 'type' should contain the basic type. 'ad' is the
6003 attribute definition of the basic type. It can be modified by
6004 type_decl().
6006 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
6008 Sym *s;
6009 CType type1, *type2;
6011 while (tok == '*') {
6012 next();
6013 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
6014 next();
6015 mk_pointer(type);
6018 /* recursive type */
6019 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6020 type1.t = 0; /* XXX: same as int */
6021 if (tok == '(') {
6022 next();
6023 /* XXX: this is not correct to modify 'ad' at this point, but
6024 the syntax is not clear */
6025 if (tok == TOK___ATTRIBUTE__)
6026 parse_attribute(ad);
6027 type_decl(&type1, ad, v, td);
6028 skip(')');
6029 } else {
6030 /* type identifier */
6031 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
6032 *v = tok;
6033 next();
6034 } else {
6035 if (!(td & TYPE_ABSTRACT))
6036 expect("identifier");
6037 *v = 0;
6040 post_type(type, ad);
6041 if (tok == TOK___ATTRIBUTE__)
6042 parse_attribute(ad);
6043 if (!type1.t)
6044 return;
6045 /* append type at the end of type1 */
6046 type2 = &type1;
6047 for(;;) {
6048 s = type2->ref;
6049 type2 = &s->type;
6050 if (!type2->t) {
6051 *type2 = *type;
6052 break;
6055 *type = type1;
6058 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6059 static int lvalue_type(int t)
6061 int bt, r;
6062 r = VT_LVAL;
6063 bt = t & VT_BTYPE;
6064 if (bt == VT_BYTE)
6065 r |= VT_LVAL_BYTE;
6066 else if (bt == VT_SHORT)
6067 r |= VT_LVAL_SHORT;
6068 else
6069 return r;
6070 if (t & VT_UNSIGNED)
6071 r |= VT_LVAL_UNSIGNED;
6072 return r;
6075 /* indirection with full error checking and bound check */
6076 static void indir(void)
6078 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6079 expect("pointer");
6080 if ((vtop->r & VT_LVAL) && !nocode_wanted)
6081 gv(RC_INT);
6082 vtop->type = *pointed_type(&vtop->type);
6083 /* an array is never an lvalue */
6084 if (!(vtop->type.t & VT_ARRAY)) {
6085 vtop->r |= lvalue_type(vtop->type.t);
6086 /* if bound checking, the referenced pointer must be checked */
6087 if (do_bounds_check)
6088 vtop->r |= VT_MUSTBOUND;
6092 /* pass a parameter to a function and do type checking and casting */
6093 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
6095 int func_type;
6096 CType type;
6098 func_type = func->c;
6099 if (func_type == FUNC_OLD ||
6100 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
6101 /* default casting : only need to convert float to double */
6102 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
6103 type.t = VT_DOUBLE;
6104 gen_cast(&type);
6106 } else if (arg == NULL) {
6107 error("too many arguments to function");
6108 } else {
6109 gen_assign_cast(&arg->type);
6111 if (!nocode_wanted) {
6112 gfunc_param(gf);
6113 } else {
6114 vpop();
6118 /* parse an expression of the form '(type)' or '(expr)' and return its
6119 type */
6120 static void parse_expr_type(CType *type)
6122 int n;
6123 AttributeDef ad;
6125 skip('(');
6126 if (parse_btype(type, &ad)) {
6127 type_decl(type, &ad, &n, TYPE_ABSTRACT);
6128 } else {
6129 expr_type(type);
6131 skip(')');
6134 static void vpush_tokc(int t)
6136 CType type;
6137 type.t = t;
6138 vsetc(&type, VT_CONST, &tokc);
6141 static void unary(void)
6143 int n, t, align, size, r;
6144 CType type;
6145 Sym *s;
6146 GFuncContext gf;
6147 AttributeDef ad;
6149 /* XXX: GCC 2.95.3 does not generate a table although it should be
6150 better here */
6151 switch(tok) {
6152 case TOK_CINT:
6153 case TOK_CCHAR:
6154 case TOK_LCHAR:
6155 vpushi(tokc.i);
6156 next();
6157 break;
6158 case TOK_CUINT:
6159 vpush_tokc(VT_INT | VT_UNSIGNED);
6160 next();
6161 break;
6162 case TOK_CLLONG:
6163 vpush_tokc(VT_LLONG);
6164 next();
6165 break;
6166 case TOK_CULLONG:
6167 vpush_tokc(VT_LLONG | VT_UNSIGNED);
6168 next();
6169 break;
6170 case TOK_CFLOAT:
6171 vpush_tokc(VT_FLOAT);
6172 next();
6173 break;
6174 case TOK_CDOUBLE:
6175 vpush_tokc(VT_DOUBLE);
6176 next();
6177 break;
6178 case TOK_CLDOUBLE:
6179 vpush_tokc(VT_LDOUBLE);
6180 next();
6181 break;
6182 case TOK___FUNCTION__:
6183 if (!gnu_ext)
6184 goto tok_identifier;
6185 /* fall thru */
6186 case TOK___FUNC__:
6188 void *ptr;
6189 int len;
6190 /* special function name identifier */
6191 len = strlen(funcname) + 1;
6192 /* generate char[len] type */
6193 type.t = VT_BYTE;
6194 mk_pointer(&type);
6195 type.t |= VT_ARRAY;
6196 type.ref->c = len;
6197 vpush_ref(&type, data_section, data_section->data_offset, len);
6198 ptr = section_ptr_add(data_section, len);
6199 memcpy(ptr, funcname, len);
6200 next();
6202 break;
6203 case TOK_LSTR:
6204 t = VT_INT;
6205 goto str_init;
6206 case TOK_STR:
6207 /* string parsing */
6208 t = VT_BYTE;
6209 str_init:
6210 type.t = t;
6211 mk_pointer(&type);
6212 type.t |= VT_ARRAY;
6213 memset(&ad, 0, sizeof(AttributeDef));
6214 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
6215 break;
6216 case '(':
6217 next();
6218 /* cast ? */
6219 if (parse_btype(&type, &ad)) {
6220 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
6221 skip(')');
6222 /* check ISOC99 compound literal */
6223 if (tok == '{') {
6224 /* data is allocated locally by default */
6225 if (global_expr)
6226 r = VT_CONST;
6227 else
6228 r = VT_LOCAL;
6229 /* all except arrays are lvalues */
6230 if (!(type.t & VT_ARRAY))
6231 r |= lvalue_type(type.t);
6232 memset(&ad, 0, sizeof(AttributeDef));
6233 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
6234 } else {
6235 unary();
6236 gen_cast(&type);
6238 } else {
6239 gexpr();
6240 skip(')');
6242 break;
6243 case '*':
6244 next();
6245 unary();
6246 indir();
6247 break;
6248 case '&':
6249 next();
6250 unary();
6251 /* functions names must be treated as function pointers,
6252 except for unary '&' and sizeof. Since we consider that
6253 functions are not lvalues, we only have to handle it
6254 there and in function calls. */
6255 /* arrays can also be used although they are not lvalues */
6256 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
6257 !(vtop->type.t & VT_ARRAY))
6258 test_lvalue();
6259 mk_pointer(&vtop->type);
6260 gaddrof();
6261 break;
6262 case '!':
6263 next();
6264 unary();
6265 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
6266 vtop->c.i = !vtop->c.i;
6267 else if ((vtop->r & VT_VALMASK) == VT_CMP)
6268 vtop->c.i = vtop->c.i ^ 1;
6269 else
6270 vseti(VT_JMP, gtst(1, 0));
6271 break;
6272 case '~':
6273 next();
6274 unary();
6275 vpushi(-1);
6276 gen_op('^');
6277 break;
6278 case '+':
6279 next();
6280 /* in order to force cast, we add zero */
6281 unary();
6282 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
6283 error("pointer not accepted for unary plus");
6284 vpushi(0);
6285 gen_op('+');
6286 break;
6287 case TOK_SIZEOF:
6288 case TOK_ALIGNOF:
6289 t = tok;
6290 next();
6291 if (tok == '(') {
6292 parse_expr_type(&type);
6293 } else {
6294 unary_type(&type);
6296 size = type_size(&type, &align);
6297 if (t == TOK_SIZEOF)
6298 vpushi(size);
6299 else
6300 vpushi(align);
6301 break;
6303 case TOK_INC:
6304 case TOK_DEC:
6305 t = tok;
6306 next();
6307 unary();
6308 inc(0, t);
6309 break;
6310 case '-':
6311 next();
6312 vpushi(0);
6313 unary();
6314 gen_op('-');
6315 break;
6316 case TOK_LAND:
6317 if (!gnu_ext)
6318 goto tok_identifier;
6319 next();
6320 /* allow to take the address of a label */
6321 if (tok < TOK_UIDENT)
6322 expect("label identifier");
6323 s = label_find(tok);
6324 if (!s) {
6325 s = label_push(tok, LABEL_FORWARD);
6327 if (!s->type.t) {
6328 s->type.t = VT_VOID;
6329 mk_pointer(&s->type);
6330 s->type.t |= VT_STATIC;
6332 vset(&s->type, VT_CONST | VT_SYM, 0);
6333 vtop->sym = s;
6334 next();
6335 break;
6336 default:
6337 tok_identifier:
6338 t = tok;
6339 next();
6340 if (t < TOK_UIDENT)
6341 expect("identifier");
6342 s = sym_find(t);
6343 if (!s) {
6344 if (tok != '(')
6345 error("'%s' undeclared", get_tok_str(t, NULL));
6346 /* for simple function calls, we tolerate undeclared
6347 external reference to int() function */
6348 s = external_global_sym(t, &func_old_type, 0);
6350 vset(&s->type, s->r, s->c);
6351 /* if forward reference, we must point to s */
6352 if (vtop->r & VT_SYM) {
6353 vtop->sym = s;
6354 vtop->c.ul = 0;
6356 break;
6359 /* post operations */
6360 while (1) {
6361 if (tok == TOK_INC || tok == TOK_DEC) {
6362 inc(1, tok);
6363 next();
6364 } else if (tok == '.' || tok == TOK_ARROW) {
6365 /* field */
6366 if (tok == TOK_ARROW)
6367 indir();
6368 test_lvalue();
6369 gaddrof();
6370 next();
6371 /* expect pointer on structure */
6372 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
6373 expect("struct or union");
6374 s = vtop->type.ref;
6375 /* find field */
6376 tok |= SYM_FIELD;
6377 while ((s = s->next) != NULL) {
6378 if (s->v == tok)
6379 break;
6381 if (!s)
6382 error("field not found");
6383 /* add field offset to pointer */
6384 vtop->type = char_pointer_type; /* change type to 'char *' */
6385 vpushi(s->c);
6386 gen_op('+');
6387 /* change type to field type, and set to lvalue */
6388 vtop->type = s->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;
6396 next();
6397 } else if (tok == '[') {
6398 next();
6399 gexpr();
6400 gen_op('+');
6401 indir();
6402 skip(']');
6403 } else if (tok == '(') {
6404 SValue ret;
6405 Sym *sa;
6407 /* function call */
6408 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
6409 /* pointer test (no array accepted) */
6410 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
6411 vtop->type = *pointed_type(&vtop->type);
6412 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
6413 goto error_func;
6414 } else {
6415 error_func:
6416 expect("function pointer");
6418 } else {
6419 vtop->r &= ~VT_LVAL; /* no lvalue */
6421 /* get return type */
6422 s = vtop->type.ref;
6423 if (!nocode_wanted) {
6424 save_regs(0); /* save used temporary registers */
6425 gfunc_start(&gf, s->r);
6427 next();
6428 sa = s->next; /* first parameter */
6429 #ifdef INVERT_FUNC_PARAMS
6431 int parlevel;
6432 Sym *args, *s1;
6433 ParseState saved_parse_state;
6434 TokenString str;
6436 /* read each argument and store it on a stack */
6437 args = NULL;
6438 if (tok != ')') {
6439 for(;;) {
6440 tok_str_new(&str);
6441 parlevel = 0;
6442 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
6443 tok != TOK_EOF) {
6444 if (tok == '(')
6445 parlevel++;
6446 else if (tok == ')')
6447 parlevel--;
6448 tok_str_add_tok(&str);
6449 next();
6451 tok_str_add(&str, -1); /* end of file added */
6452 tok_str_add(&str, 0);
6453 s1 = sym_push2(&args, 0, 0, (int)str.str);
6454 s1->next = sa; /* add reference to argument */
6455 if (sa)
6456 sa = sa->next;
6457 if (tok == ')')
6458 break;
6459 skip(',');
6463 /* now generate code in reverse order by reading the stack */
6464 save_parse_state(&saved_parse_state);
6465 while (args) {
6466 macro_ptr = (int *)args->c;
6467 next();
6468 expr_eq();
6469 if (tok != -1)
6470 expect("',' or ')'");
6471 gfunc_param_typed(&gf, s, args->next);
6472 s1 = args->prev;
6473 tok_str_free((int *)args->c);
6474 tcc_free(args);
6475 args = s1;
6477 restore_parse_state(&saved_parse_state);
6479 #endif
6480 /* compute first implicit argument if a structure is returned */
6481 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6482 /* get some space for the returned structure */
6483 size = type_size(&s->type, &align);
6484 loc = (loc - size) & -align;
6485 ret.type = s->type;
6486 ret.r = VT_LOCAL | VT_LVAL;
6487 /* pass it as 'int' to avoid structure arg passing
6488 problems */
6489 vseti(VT_LOCAL, loc);
6490 ret.c = vtop->c;
6491 if (!nocode_wanted)
6492 gfunc_param(&gf);
6493 else
6494 vtop--;
6495 } else {
6496 ret.type = s->type;
6497 ret.r2 = VT_CONST;
6498 /* return in register */
6499 if (is_float(ret.type.t)) {
6500 ret.r = REG_FRET;
6501 } else {
6502 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
6503 ret.r2 = REG_LRET;
6504 ret.r = REG_IRET;
6506 ret.c.i = 0;
6508 #ifndef INVERT_FUNC_PARAMS
6509 if (tok != ')') {
6510 for(;;) {
6511 expr_eq();
6512 gfunc_param_typed(&gf, s, sa);
6513 if (sa)
6514 sa = sa->next;
6515 if (tok == ')')
6516 break;
6517 skip(',');
6520 #endif
6521 if (sa)
6522 error("too few arguments to function");
6523 skip(')');
6524 if (!nocode_wanted)
6525 gfunc_call(&gf);
6526 else
6527 vtop--;
6528 /* return value */
6529 vsetc(&ret.type, ret.r, &ret.c);
6530 vtop->r2 = ret.r2;
6531 } else {
6532 break;
6537 static void uneq(void)
6539 int t;
6541 unary();
6542 if (tok == '=' ||
6543 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
6544 tok == TOK_A_XOR || tok == TOK_A_OR ||
6545 tok == TOK_A_SHL || tok == TOK_A_SAR) {
6546 test_lvalue();
6547 t = tok;
6548 next();
6549 if (t == '=') {
6550 expr_eq();
6551 } else {
6552 vdup();
6553 expr_eq();
6554 gen_op(t & 0x7f);
6556 vstore();
6560 static void expr_prod(void)
6562 int t;
6564 uneq();
6565 while (tok == '*' || tok == '/' || tok == '%') {
6566 t = tok;
6567 next();
6568 uneq();
6569 gen_op(t);
6573 static void expr_sum(void)
6575 int t;
6577 expr_prod();
6578 while (tok == '+' || tok == '-') {
6579 t = tok;
6580 next();
6581 expr_prod();
6582 gen_op(t);
6586 static void expr_shift(void)
6588 int t;
6590 expr_sum();
6591 while (tok == TOK_SHL || tok == TOK_SAR) {
6592 t = tok;
6593 next();
6594 expr_sum();
6595 gen_op(t);
6599 static void expr_cmp(void)
6601 int t;
6603 expr_shift();
6604 while ((tok >= TOK_ULE && tok <= TOK_GT) ||
6605 tok == TOK_ULT || tok == TOK_UGE) {
6606 t = tok;
6607 next();
6608 expr_shift();
6609 gen_op(t);
6613 static void expr_cmpeq(void)
6615 int t;
6617 expr_cmp();
6618 while (tok == TOK_EQ || tok == TOK_NE) {
6619 t = tok;
6620 next();
6621 expr_cmp();
6622 gen_op(t);
6626 static void expr_and(void)
6628 expr_cmpeq();
6629 while (tok == '&') {
6630 next();
6631 expr_cmpeq();
6632 gen_op('&');
6636 static void expr_xor(void)
6638 expr_and();
6639 while (tok == '^') {
6640 next();
6641 expr_and();
6642 gen_op('^');
6646 static void expr_or(void)
6648 expr_xor();
6649 while (tok == '|') {
6650 next();
6651 expr_xor();
6652 gen_op('|');
6656 /* XXX: suppress this mess */
6657 static void expr_land_const(void)
6659 expr_or();
6660 while (tok == TOK_LAND) {
6661 next();
6662 expr_or();
6663 gen_op(TOK_LAND);
6667 /* XXX: suppress this mess */
6668 static void expr_lor_const(void)
6670 expr_land_const();
6671 while (tok == TOK_LOR) {
6672 next();
6673 expr_land_const();
6674 gen_op(TOK_LOR);
6678 /* only used if non constant */
6679 static void expr_land(void)
6681 int t;
6683 expr_or();
6684 if (tok == TOK_LAND) {
6685 t = 0;
6686 for(;;) {
6687 t = gtst(1, t);
6688 if (tok != TOK_LAND) {
6689 vseti(VT_JMPI, t);
6690 break;
6692 next();
6693 expr_or();
6698 static void expr_lor(void)
6700 int t;
6702 expr_land();
6703 if (tok == TOK_LOR) {
6704 t = 0;
6705 for(;;) {
6706 t = gtst(0, t);
6707 if (tok != TOK_LOR) {
6708 vseti(VT_JMP, t);
6709 break;
6711 next();
6712 expr_land();
6717 /* XXX: better constant handling */
6718 static void expr_eq(void)
6720 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
6721 SValue sv;
6722 CType type, type1, type2;
6724 if (const_wanted) {
6725 int c1, c;
6726 expr_lor_const();
6727 if (tok == '?') {
6728 c = vtop->c.i;
6729 vpop();
6730 next();
6731 gexpr();
6732 c1 = vtop->c.i;
6733 vpop();
6734 skip(':');
6735 expr_eq();
6736 if (c)
6737 vtop->c.i = c1;
6739 } else {
6740 expr_lor();
6741 if (tok == '?') {
6742 next();
6743 if (vtop != vstack) {
6744 /* needed to avoid having different registers saved in
6745 each branch */
6746 if (is_float(vtop->type.t))
6747 rc = RC_FLOAT;
6748 else
6749 rc = RC_INT;
6750 gv(rc);
6751 save_regs(1);
6753 tt = gtst(1, 0);
6754 gexpr();
6755 type1 = vtop->type;
6756 sv = *vtop; /* save value to handle it later */
6757 vtop--; /* no vpop so that FP stack is not flushed */
6758 skip(':');
6759 u = gjmp(0);
6760 gsym(tt);
6761 expr_eq();
6762 type2 = vtop->type;
6764 t1 = type1.t;
6765 bt1 = t1 & VT_BTYPE;
6766 t2 = type2.t;
6767 bt2 = t2 & VT_BTYPE;
6768 /* cast operands to correct type according to ISOC rules */
6769 if (is_float(bt1) || is_float(bt2)) {
6770 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
6771 type.t = VT_LDOUBLE;
6772 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
6773 type.t = VT_DOUBLE;
6774 } else {
6775 type.t = VT_FLOAT;
6777 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
6778 /* cast to biggest op */
6779 type.t = VT_LLONG;
6780 /* convert to unsigned if it does not fit in a long long */
6781 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
6782 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
6783 type.t |= VT_UNSIGNED;
6784 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
6785 /* XXX: test pointer compatibility */
6786 type = type1;
6787 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
6788 /* XXX: test structure compatibility */
6789 type = type1;
6790 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
6791 /* NOTE: as an extension, we accept void on only one side */
6792 type.t = VT_VOID;
6793 } else {
6794 /* integer operations */
6795 type.t = VT_INT;
6796 /* convert to unsigned if it does not fit in an integer */
6797 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
6798 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
6799 type.t |= VT_UNSIGNED;
6802 /* now we convert second operand */
6803 gen_cast(&type);
6804 rc = RC_INT;
6805 if (is_float(type.t)) {
6806 rc = RC_FLOAT;
6807 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
6808 /* for long longs, we use fixed registers to avoid having
6809 to handle a complicated move */
6810 rc = RC_IRET;
6813 r2 = gv(rc);
6814 /* this is horrible, but we must also convert first
6815 operand */
6816 tt = gjmp(0);
6817 gsym(u);
6818 /* put again first value and cast it */
6819 *vtop = sv;
6820 gen_cast(&type);
6821 r1 = gv(rc);
6822 move_reg(r2, r1);
6823 vtop->r = r2;
6824 gsym(tt);
6829 static void gexpr(void)
6831 while (1) {
6832 expr_eq();
6833 if (tok != ',')
6834 break;
6835 vpop();
6836 next();
6840 /* parse an expression and return its type without any side effect. */
6841 static void expr_type(CType *type)
6843 int a;
6845 a = nocode_wanted;
6846 nocode_wanted = 1;
6847 gexpr();
6848 *type = vtop->type;
6849 vpop();
6850 nocode_wanted = a;
6853 /* parse a unary expression and return its type without any side
6854 effect. */
6855 static void unary_type(CType *type)
6857 int a;
6859 a = nocode_wanted;
6860 nocode_wanted = 1;
6861 unary();
6862 *type = vtop->type;
6863 vpop();
6864 nocode_wanted = a;
6867 /* parse a constant expression and return value in vtop. */
6868 static void expr_const1(void)
6870 int a;
6871 a = const_wanted;
6872 const_wanted = 1;
6873 expr_eq();
6874 const_wanted = a;
6877 /* parse an integer constant and return its value. */
6878 static int expr_const(void)
6880 int c;
6881 expr_const1();
6882 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
6883 expect("constant expression");
6884 c = vtop->c.i;
6885 vpop();
6886 return c;
6889 /* return the label token if current token is a label, otherwise
6890 return zero */
6891 static int is_label(void)
6893 int t;
6894 CValue c;
6896 /* fast test first */
6897 if (tok < TOK_UIDENT)
6898 return 0;
6899 /* no need to save tokc since we expect an identifier */
6900 t = tok;
6901 c = tokc;
6902 next();
6903 if (tok == ':') {
6904 next();
6905 return t;
6906 } else {
6907 /* XXX: may not work in all cases (macros ?) */
6908 tok1 = tok;
6909 tok1c = tokc;
6910 tok = t;
6911 tokc = c;
6912 return 0;
6916 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
6918 int a, b, c, d;
6919 Sym *s;
6921 /* generate line number info */
6922 if (do_debug &&
6923 (last_line_num != file->line_num || last_ind != ind)) {
6924 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
6925 last_ind = ind;
6926 last_line_num = file->line_num;
6929 if (tok == TOK_IF) {
6930 /* if test */
6931 next();
6932 skip('(');
6933 gexpr();
6934 skip(')');
6935 a = gtst(1, 0);
6936 block(bsym, csym, case_sym, def_sym, case_reg);
6937 c = tok;
6938 if (c == TOK_ELSE) {
6939 next();
6940 d = gjmp(0);
6941 gsym(a);
6942 block(bsym, csym, case_sym, def_sym, case_reg);
6943 gsym(d); /* patch else jmp */
6944 } else
6945 gsym(a);
6946 } else if (tok == TOK_WHILE) {
6947 next();
6948 d = ind;
6949 skip('(');
6950 gexpr();
6951 skip(')');
6952 a = gtst(1, 0);
6953 b = 0;
6954 block(&a, &b, case_sym, def_sym, case_reg);
6955 gjmp_addr(d);
6956 gsym(a);
6957 gsym_addr(b, d);
6958 } else if (tok == '{') {
6959 next();
6960 /* declarations */
6961 s = local_stack;
6962 while (tok != '}') {
6963 decl(VT_LOCAL);
6964 if (tok != '}')
6965 block(bsym, csym, case_sym, def_sym, case_reg);
6967 /* pop locally defined symbols */
6968 sym_pop(&local_stack, s);
6969 next();
6970 } else if (tok == TOK_RETURN) {
6971 next();
6972 if (tok != ';') {
6973 gexpr();
6974 gen_assign_cast(&func_vt);
6975 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
6976 CType type;
6977 /* if returning structure, must copy it to implicit
6978 first pointer arg location */
6979 type = func_vt;
6980 mk_pointer(&type);
6981 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
6982 indir();
6983 vswap();
6984 /* copy structure value to pointer */
6985 vstore();
6986 } else if (is_float(func_vt.t)) {
6987 gv(RC_FRET);
6988 } else {
6989 gv(RC_IRET);
6991 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
6993 skip(';');
6994 rsym = gjmp(rsym); /* jmp */
6995 } else if (tok == TOK_BREAK) {
6996 /* compute jump */
6997 if (!bsym)
6998 error("cannot break");
6999 *bsym = gjmp(*bsym);
7000 next();
7001 skip(';');
7002 } else if (tok == TOK_CONTINUE) {
7003 /* compute jump */
7004 if (!csym)
7005 error("cannot continue");
7006 *csym = gjmp(*csym);
7007 next();
7008 skip(';');
7009 } else if (tok == TOK_FOR) {
7010 int e;
7011 next();
7012 skip('(');
7013 if (tok != ';') {
7014 gexpr();
7015 vpop();
7017 skip(';');
7018 d = ind;
7019 c = ind;
7020 a = 0;
7021 b = 0;
7022 if (tok != ';') {
7023 gexpr();
7024 a = gtst(1, 0);
7026 skip(';');
7027 if (tok != ')') {
7028 e = gjmp(0);
7029 c = ind;
7030 gexpr();
7031 vpop();
7032 gjmp_addr(d);
7033 gsym(e);
7035 skip(')');
7036 block(&a, &b, case_sym, def_sym, case_reg);
7037 gjmp_addr(c);
7038 gsym(a);
7039 gsym_addr(b, c);
7040 } else
7041 if (tok == TOK_DO) {
7042 next();
7043 a = 0;
7044 b = 0;
7045 d = ind;
7046 block(&a, &b, case_sym, def_sym, case_reg);
7047 skip(TOK_WHILE);
7048 skip('(');
7049 gsym(b);
7050 gexpr();
7051 c = gtst(0, 0);
7052 gsym_addr(c, d);
7053 skip(')');
7054 gsym(a);
7055 skip(';');
7056 } else
7057 if (tok == TOK_SWITCH) {
7058 next();
7059 skip('(');
7060 gexpr();
7061 /* XXX: other types than integer */
7062 case_reg = gv(RC_INT);
7063 vpop();
7064 skip(')');
7065 a = 0;
7066 b = gjmp(0); /* jump to first case */
7067 c = 0;
7068 block(&a, csym, &b, &c, case_reg);
7069 /* if no default, jmp after switch */
7070 if (c == 0)
7071 c = ind;
7072 /* default label */
7073 gsym_addr(b, c);
7074 /* break label */
7075 gsym(a);
7076 } else
7077 if (tok == TOK_CASE) {
7078 int v1, v2;
7079 if (!case_sym)
7080 expect("switch");
7081 next();
7082 v1 = expr_const();
7083 v2 = v1;
7084 if (gnu_ext && tok == TOK_DOTS) {
7085 next();
7086 v2 = expr_const();
7087 if (v2 < v1)
7088 warning("empty case range");
7090 /* since a case is like a label, we must skip it with a jmp */
7091 b = gjmp(0);
7092 gsym(*case_sym);
7093 vseti(case_reg, 0);
7094 vpushi(v1);
7095 if (v1 == v2) {
7096 gen_op(TOK_EQ);
7097 *case_sym = gtst(1, 0);
7098 } else {
7099 gen_op(TOK_GE);
7100 *case_sym = gtst(1, 0);
7101 vseti(case_reg, 0);
7102 vpushi(v2);
7103 gen_op(TOK_LE);
7104 *case_sym = gtst(1, *case_sym);
7106 gsym(b);
7107 skip(':');
7108 block(bsym, csym, case_sym, def_sym, case_reg);
7109 } else
7110 if (tok == TOK_DEFAULT) {
7111 next();
7112 skip(':');
7113 if (!def_sym)
7114 expect("switch");
7115 if (*def_sym)
7116 error("too many 'default'");
7117 *def_sym = ind;
7118 block(bsym, csym, case_sym, def_sym, case_reg);
7119 } else
7120 if (tok == TOK_GOTO) {
7121 next();
7122 if (tok == '*' && gnu_ext) {
7123 /* computed goto */
7124 next();
7125 gexpr();
7126 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
7127 expect("pointer");
7128 ggoto();
7129 } else if (tok >= TOK_UIDENT) {
7130 s = label_find(tok);
7131 /* put forward definition if needed */
7132 if (!s) {
7133 s = label_push(tok, LABEL_FORWARD);
7135 /* label already defined */
7136 if (s->r & LABEL_FORWARD)
7137 s->next = (void *)gjmp((long)s->next);
7138 else
7139 gjmp_addr((long)s->next);
7140 next();
7141 } else {
7142 expect("label identifier");
7144 skip(';');
7145 } else {
7146 b = is_label();
7147 if (b) {
7148 /* label case */
7149 s = label_find(b);
7150 if (s) {
7151 if (!(s->r & LABEL_FORWARD))
7152 error("multiple defined label");
7153 gsym((long)s->next);
7154 } else {
7155 s = label_push(b, 0);
7157 s->next = (void *)ind;
7158 s->r = 0;
7159 /* we accept this, but it is a mistake */
7160 if (tok == '}')
7161 warning("deprecated use of label at end of compound statement");
7162 else
7163 block(bsym, csym, case_sym, def_sym, case_reg);
7164 } else {
7165 /* expression case */
7166 if (tok != ';') {
7167 gexpr();
7168 vpop();
7170 skip(';');
7175 /* t is the array or struct type. c is the array or struct
7176 address. cur_index/cur_field is the pointer to the current
7177 value. 'size_only' is true if only size info is needed (only used
7178 in arrays) */
7179 static void decl_designator(CType *type, Section *sec, unsigned long c,
7180 int *cur_index, Sym **cur_field,
7181 int size_only)
7183 Sym *s, *f;
7184 int notfirst, index, align, l;
7185 CType type1;
7187 notfirst = 0;
7188 if (gnu_ext && (l = is_label()) != 0)
7189 goto struct_field;
7191 while (tok == '[' || tok == '.') {
7192 if (tok == '[') {
7193 if (!(type->t & VT_ARRAY))
7194 expect("array type");
7195 s = type->ref;
7196 next();
7197 index = expr_const();
7198 if (index < 0 || (s->c >= 0 && index >= s->c))
7199 expect("invalid index");
7200 skip(']');
7201 if (!notfirst)
7202 *cur_index = index;
7203 type = pointed_type(type);
7204 c += index * type_size(type, &align);
7205 } else {
7206 next();
7207 l = tok;
7208 next();
7209 struct_field:
7210 if ((type->t & VT_BTYPE) != VT_STRUCT)
7211 expect("struct/union type");
7212 s = type->ref;
7213 l |= SYM_FIELD;
7214 f = s->next;
7215 while (f) {
7216 if (f->v == l)
7217 break;
7218 f = f->next;
7220 if (!f)
7221 expect("field");
7222 if (!notfirst)
7223 *cur_field = f;
7224 /* XXX: suppress this mess by using explicit storage field */
7225 type1 = f->type;
7226 type1.t |= (type->t & ~VT_TYPE);
7227 type = &type1;
7228 c += f->c;
7230 notfirst = 1;
7232 if (notfirst) {
7233 if (tok == '=') {
7234 next();
7235 } else {
7236 if (!gnu_ext)
7237 expect("=");
7239 } else {
7240 if (type->t & VT_ARRAY) {
7241 index = *cur_index;
7242 type = pointed_type(type);
7243 c += index * type_size(type, &align);
7244 } else {
7245 f = *cur_field;
7246 if (!f)
7247 error("too many field init");
7248 /* XXX: suppress this mess by using explicit storage field */
7249 type1 = f->type;
7250 type1.t |= (type->t & ~VT_TYPE);
7251 type = &type1;
7252 c += f->c;
7255 decl_initializer(type, sec, c, 0, size_only);
7258 #define EXPR_VAL 0
7259 #define EXPR_CONST 1
7260 #define EXPR_ANY 2
7262 /* store a value or an expression directly in global data or in local array */
7263 static void init_putv(CType *type, Section *sec, unsigned long c,
7264 int v, int expr_type)
7266 int saved_global_expr, bt;
7267 void *ptr;
7269 switch(expr_type) {
7270 case EXPR_VAL:
7271 vpushi(v);
7272 break;
7273 case EXPR_CONST:
7274 /* compound literals must be allocated globally in this case */
7275 saved_global_expr = global_expr;
7276 global_expr = 1;
7277 expr_const1();
7278 global_expr = saved_global_expr;
7279 /* NOTE: symbols are accepted */
7280 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
7281 error("initializer element is not constant");
7282 break;
7283 case EXPR_ANY:
7284 expr_eq();
7285 break;
7288 if (sec) {
7289 /* XXX: not portable */
7290 /* XXX: generate error if incorrect relocation */
7291 gen_assign_cast(type);
7292 bt = type->t & VT_BTYPE;
7293 ptr = sec->data + c;
7294 if ((vtop->r & VT_SYM) &&
7295 (bt == VT_BYTE ||
7296 bt == VT_SHORT ||
7297 bt == VT_DOUBLE ||
7298 bt == VT_LDOUBLE ||
7299 bt == VT_LLONG))
7300 error("initializer element is not computable at load time");
7301 switch(bt) {
7302 case VT_BYTE:
7303 *(char *)ptr = vtop->c.i;
7304 break;
7305 case VT_SHORT:
7306 *(short *)ptr = vtop->c.i;
7307 break;
7308 case VT_DOUBLE:
7309 *(double *)ptr = vtop->c.d;
7310 break;
7311 case VT_LDOUBLE:
7312 *(long double *)ptr = vtop->c.ld;
7313 break;
7314 case VT_LLONG:
7315 *(long long *)ptr = vtop->c.ll;
7316 break;
7317 default:
7318 if (vtop->r & VT_SYM) {
7319 greloc(sec, vtop->sym, c, R_DATA_32);
7321 *(int *)ptr = vtop->c.i;
7322 break;
7324 vtop--;
7325 } else {
7326 vset(type, VT_LOCAL, c);
7327 vswap();
7328 vstore();
7329 vpop();
7333 /* put zeros for variable based init */
7334 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
7336 GFuncContext gf;
7338 if (sec) {
7339 /* nothing to do because globals are already set to zero */
7340 } else {
7341 gfunc_start(&gf, FUNC_CDECL);
7342 vpushi(size);
7343 gfunc_param(&gf);
7344 vpushi(0);
7345 gfunc_param(&gf);
7346 vseti(VT_LOCAL, c);
7347 gfunc_param(&gf);
7348 vpush_global_sym(&func_old_type, TOK_memset);
7349 gfunc_call(&gf);
7353 /* 't' contains the type and storage info. 'c' is the offset of the
7354 object in section 'sec'. If 'sec' is NULL, it means stack based
7355 allocation. 'first' is true if array '{' must be read (multi
7356 dimension implicit array init handling). 'size_only' is true if
7357 size only evaluation is wanted (only for arrays). */
7358 static void decl_initializer(CType *type, Section *sec, unsigned long c,
7359 int first, int size_only)
7361 int index, array_length, n, no_oblock, nb, parlevel, i;
7362 int size1, align1, expr_type;
7363 Sym *s, *f;
7364 CType *t1;
7366 if (type->t & VT_ARRAY) {
7367 s = type->ref;
7368 n = s->c;
7369 array_length = 0;
7370 t1 = pointed_type(type);
7371 size1 = type_size(t1, &align1);
7373 no_oblock = 1;
7374 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
7375 tok == '{') {
7376 skip('{');
7377 no_oblock = 0;
7380 /* only parse strings here if correct type (otherwise: handle
7381 them as ((w)char *) expressions */
7382 if ((tok == TOK_LSTR &&
7383 (t1->t & VT_BTYPE) == VT_INT) ||
7384 (tok == TOK_STR &&
7385 (t1->t & VT_BTYPE) == VT_BYTE)) {
7386 while (tok == TOK_STR || tok == TOK_LSTR) {
7387 int cstr_len, ch;
7388 CString *cstr;
7390 cstr = tokc.cstr;
7391 /* compute maximum number of chars wanted */
7392 if (tok == TOK_STR)
7393 cstr_len = cstr->size;
7394 else
7395 cstr_len = cstr->size / sizeof(int);
7396 cstr_len--;
7397 nb = cstr_len;
7398 if (n >= 0 && nb > (n - array_length))
7399 nb = n - array_length;
7400 if (!size_only) {
7401 if (cstr_len > nb)
7402 warning("initializer-string for array is too long");
7403 /* in order to go faster for common case (char
7404 string in global variable, we handle it
7405 specifically */
7406 if (sec && tok == TOK_STR && size1 == 1) {
7407 memcpy(sec->data + c + array_length, cstr->data, nb);
7408 } else {
7409 for(i=0;i<nb;i++) {
7410 if (tok == TOK_STR)
7411 ch = ((unsigned char *)cstr->data)[i];
7412 else
7413 ch = ((int *)cstr->data)[i];
7414 init_putv(t1, sec, c + (array_length + i) * size1,
7415 ch, EXPR_VAL);
7419 array_length += nb;
7420 next();
7422 /* only add trailing zero if enough storage (no
7423 warning in this case since it is standard) */
7424 if (n < 0 || array_length < n) {
7425 if (!size_only) {
7426 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
7428 array_length++;
7430 } else {
7431 index = 0;
7432 while (tok != '}') {
7433 decl_designator(type, sec, c, &index, NULL, size_only);
7434 if (n >= 0 && index >= n)
7435 error("index too large");
7436 /* must put zero in holes (note that doing it that way
7437 ensures that it even works with designators) */
7438 if (!size_only && array_length < index) {
7439 init_putz(t1, sec, c + array_length * size1,
7440 (index - array_length) * size1);
7442 index++;
7443 if (index > array_length)
7444 array_length = index;
7445 /* special test for multi dimensional arrays (may not
7446 be strictly correct if designators are used at the
7447 same time) */
7448 if (index >= n && no_oblock)
7449 break;
7450 if (tok == '}')
7451 break;
7452 skip(',');
7455 if (!no_oblock)
7456 skip('}');
7457 /* put zeros at the end */
7458 if (!size_only && n >= 0 && array_length < n) {
7459 init_putz(t1, sec, c + array_length * size1,
7460 (n - array_length) * size1);
7462 /* patch type size if needed */
7463 if (n < 0)
7464 s->c = array_length;
7465 } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
7466 (sec || !first || tok == '{')) {
7467 /* NOTE: the previous test is a specific case for automatic
7468 struct/union init */
7469 /* XXX: union needs only one init */
7470 /* XXX: handle bit fields */
7471 no_oblock = 1;
7472 if (first || tok == '{') {
7473 skip('{');
7474 no_oblock = 0;
7476 s = type->ref;
7477 f = s->next;
7478 array_length = 0;
7479 index = 0;
7480 n = s->c;
7481 while (tok != '}') {
7482 decl_designator(type, sec, c, NULL, &f, size_only);
7483 /* XXX: bitfields ? */
7484 /* fill with zero between fields */
7485 index = f->c;
7486 if (!size_only && array_length < index) {
7487 init_putz(type, sec, c + array_length,
7488 index - array_length);
7490 index = index + type_size(&f->type, &align1);
7491 if (index > array_length)
7492 array_length = index;
7493 if (no_oblock && f->next == NULL)
7494 break;
7495 if (tok == '}')
7496 break;
7497 skip(',');
7498 f = f->next;
7500 /* put zeros at the end */
7501 if (!size_only && array_length < n) {
7502 init_putz(type, sec, c + array_length,
7503 n - array_length);
7505 if (!no_oblock)
7506 skip('}');
7507 } else if (tok == '{') {
7508 next();
7509 decl_initializer(type, sec, c, first, size_only);
7510 skip('}');
7511 } else if (size_only) {
7512 /* just skip expression */
7513 parlevel = 0;
7514 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
7515 tok != -1) {
7516 if (tok == '(')
7517 parlevel++;
7518 else if (tok == ')')
7519 parlevel--;
7520 next();
7522 } else {
7523 /* currently, we always use constant expression for globals
7524 (may change for scripting case) */
7525 expr_type = EXPR_CONST;
7526 if (!sec)
7527 expr_type = EXPR_ANY;
7528 init_putv(type, sec, c, 0, expr_type);
7532 /* parse an initializer for type 't' if 'has_init' is non zero, and
7533 allocate space in local or global data space ('r' is either
7534 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7535 variable 'v' of scope 'scope' is declared before initializers are
7536 parsed. If 'v' is zero, then a reference to the new object is put
7537 in the value stack. If 'has_init' is 2, a special parsing is done
7538 to handle string constants. */
7539 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
7540 int has_init, int v, int scope)
7542 int size, align, addr, data_offset;
7543 int level;
7544 ParseState saved_parse_state;
7545 TokenString init_str;
7546 Section *sec;
7548 size = type_size(type, &align);
7549 /* If unknown size, we must evaluate it before
7550 evaluating initializers because
7551 initializers can generate global data too
7552 (e.g. string pointers or ISOC99 compound
7553 literals). It also simplifies local
7554 initializers handling */
7555 tok_str_new(&init_str);
7556 if (size < 0) {
7557 if (!has_init)
7558 error("unknown type size");
7559 /* get all init string */
7560 if (has_init == 2) {
7561 /* only get strings */
7562 while (tok == TOK_STR || tok == TOK_LSTR) {
7563 tok_str_add_tok(&init_str);
7564 next();
7566 } else {
7567 level = 0;
7568 while (level > 0 || (tok != ',' && tok != ';')) {
7569 if (tok < 0)
7570 error("unexpected end of file in initializer");
7571 tok_str_add_tok(&init_str);
7572 if (tok == '{')
7573 level++;
7574 else if (tok == '}') {
7575 if (level == 0)
7576 break;
7577 level--;
7579 next();
7582 tok_str_add(&init_str, -1);
7583 tok_str_add(&init_str, 0);
7585 /* compute size */
7586 save_parse_state(&saved_parse_state);
7588 macro_ptr = init_str.str;
7589 next();
7590 decl_initializer(type, NULL, 0, 1, 1);
7591 /* prepare second initializer parsing */
7592 macro_ptr = init_str.str;
7593 next();
7595 /* if still unknown size, error */
7596 size = type_size(type, &align);
7597 if (size < 0)
7598 error("unknown type size");
7600 /* take into account specified alignment if bigger */
7601 if (ad->aligned > align)
7602 align = ad->aligned;
7603 if ((r & VT_VALMASK) == VT_LOCAL) {
7604 sec = NULL;
7605 if (do_bounds_check && (type->t & VT_ARRAY))
7606 loc--;
7607 #ifdef TCC_TARGET_IL
7608 /* XXX: ugly patch to allocate local variables for IL, just
7609 for testing */
7610 addr = loc;
7611 loc++;
7612 #else
7613 loc = (loc - size) & -align;
7614 addr = loc;
7615 #endif
7616 /* handles bounds */
7617 /* XXX: currently, since we do only one pass, we cannot track
7618 '&' operators, so we add only arrays */
7619 if (do_bounds_check && (type->t & VT_ARRAY)) {
7620 unsigned long *bounds_ptr;
7621 /* add padding between regions */
7622 loc--;
7623 /* then add local bound info */
7624 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
7625 bounds_ptr[0] = addr;
7626 bounds_ptr[1] = size;
7628 } else {
7629 /* compute section */
7630 sec = ad->section;
7631 if (!sec) {
7632 if (has_init)
7633 sec = data_section;
7634 else
7635 sec = bss_section;
7637 data_offset = sec->data_offset;
7638 data_offset = (data_offset + align - 1) & -align;
7639 addr = data_offset;
7640 /* very important to increment global pointer at this time
7641 because initializers themselves can create new initializers */
7642 data_offset += size;
7643 /* add padding if bound check */
7644 if (do_bounds_check)
7645 data_offset++;
7646 sec->data_offset = data_offset;
7647 /* allocate section space to put the data */
7648 if (sec->sh_type != SHT_NOBITS &&
7649 data_offset > sec->data_allocated)
7650 section_realloc(sec, data_offset);
7652 if (!sec) {
7653 if (v) {
7654 /* local variable */
7655 sym_push(v, type, r, addr);
7656 } else {
7657 /* push local reference */
7658 vset(type, r, addr);
7660 } else {
7661 Sym *sym;
7663 if (v) {
7664 if (scope == VT_CONST) {
7665 /* global scope: see if already defined */
7666 sym = sym_find(v);
7667 if (!sym)
7668 goto do_def;
7669 if (!is_compatible_types(&sym->type, type))
7670 error("incompatible types for redefinition of '%s'",
7671 get_tok_str(v, NULL));
7672 if (!(sym->type.t & VT_EXTERN))
7673 error("redefinition of '%s'", get_tok_str(v, NULL));
7674 sym->type.t &= ~VT_EXTERN;
7675 } else {
7676 do_def:
7677 sym = sym_push(v, type, r | VT_SYM, 0);
7679 put_extern_sym(sym, sec, addr, size);
7680 } else {
7681 CValue cval;
7683 /* push global reference */
7684 sym = get_sym_ref(type, sec, addr, size);
7685 cval.ul = 0;
7686 vsetc(type, VT_CONST | VT_SYM, &cval);
7687 vtop->sym = sym;
7690 /* handles bounds now because the symbol must be defined
7691 before for the relocation */
7692 if (do_bounds_check) {
7693 unsigned long *bounds_ptr;
7695 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
7696 /* then add global bound info */
7697 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
7698 bounds_ptr[0] = 0; /* relocated */
7699 bounds_ptr[1] = size;
7702 if (has_init) {
7703 decl_initializer(type, sec, addr, 1, 0);
7704 /* restore parse state if needed */
7705 if (init_str.str) {
7706 tok_str_free(init_str.str);
7707 restore_parse_state(&saved_parse_state);
7712 void put_func_debug(Sym *sym)
7714 char buf[512];
7716 /* stabs info */
7717 /* XXX: we put here a dummy type */
7718 snprintf(buf, sizeof(buf), "%s:%c1",
7719 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
7720 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
7721 cur_text_section, sym->c);
7722 last_ind = 0;
7723 last_line_num = 0;
7726 /* not finished : try to put some local vars in registers */
7727 //#define CONFIG_REG_VARS
7729 #ifdef CONFIG_REG_VARS
7730 void add_var_ref(int t)
7732 printf("%s:%d: &%s\n",
7733 file->filename, file->line_num,
7734 get_tok_str(t, NULL));
7737 /* first pass on a function with heuristic to extract variable usage
7738 and pointer references to local variables for register allocation */
7739 void analyse_function(void)
7741 int level, t;
7743 for(;;) {
7744 if (tok == -1)
7745 break;
7746 /* any symbol coming after '&' is considered as being a
7747 variable whose reference is taken. It is highly unaccurate
7748 but it is difficult to do better without a complete parse */
7749 if (tok == '&') {
7750 next();
7751 /* if '& number', then no need to examine next tokens */
7752 if (tok == TOK_CINT ||
7753 tok == TOK_CUINT ||
7754 tok == TOK_CLLONG ||
7755 tok == TOK_CULLONG) {
7756 continue;
7757 } else if (tok >= TOK_UIDENT) {
7758 /* if '& ident [' or '& ident ->', then ident address
7759 is not needed */
7760 t = tok;
7761 next();
7762 if (tok != '[' && tok != TOK_ARROW)
7763 add_var_ref(t);
7764 } else {
7765 level = 0;
7766 while (tok != '}' && tok != ';' &&
7767 !((tok == ',' || tok == ')') && level == 0)) {
7768 if (tok >= TOK_UIDENT) {
7769 add_var_ref(tok);
7770 } else if (tok == '(') {
7771 level++;
7772 } else if (tok == ')') {
7773 level--;
7775 next();
7778 } else {
7779 next();
7783 #endif
7785 /* parse an old style function declaration list */
7786 /* XXX: check multiple parameter */
7787 static void func_decl_list(Sym *func_sym)
7789 AttributeDef ad;
7790 int v;
7791 Sym *s;
7792 CType btype, type;
7794 /* parse each declaration */
7795 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
7796 if (!parse_btype(&btype, &ad))
7797 expect("declaration list");
7798 if (((btype.t & VT_BTYPE) == VT_ENUM ||
7799 (btype.t & VT_BTYPE) == VT_STRUCT) &&
7800 tok == ';') {
7801 /* we accept no variable after */
7802 } else {
7803 for(;;) {
7804 type = btype;
7805 type_decl(&type, &ad, &v, TYPE_DIRECT);
7806 /* find parameter in function parameter list */
7807 s = func_sym->next;
7808 while (s != NULL) {
7809 if ((s->v & ~SYM_FIELD) == v)
7810 goto found;
7811 s = s->next;
7813 error("declaration for parameter '%s' but no such parameter",
7814 get_tok_str(v, NULL));
7815 found:
7816 /* check that no storage specifier except 'register' was given */
7817 if (type.t & (VT_EXTERN | VT_STATIC | VT_TYPEDEF))
7818 error("storage class specified for '%s'", get_tok_str(v, NULL));
7819 /* we can add the type (NOTE: it could be local to the function) */
7820 s->type = type;
7821 /* accept other parameters */
7822 if (tok == ',')
7823 next();
7824 else
7825 break;
7828 skip(';');
7832 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
7833 static void decl(int l)
7835 int v, has_init, r;
7836 CType type, btype;
7837 Sym *sym;
7838 AttributeDef ad;
7840 while (1) {
7841 if (!parse_btype(&btype, &ad)) {
7842 /* skip redundant ';' */
7843 /* XXX: find more elegant solution */
7844 if (tok == ';') {
7845 next();
7846 continue;
7848 /* special test for old K&R protos without explicit int
7849 type. Only accepted when defining global data */
7850 if (l == VT_LOCAL || tok < TOK_DEFINE)
7851 break;
7852 btype.t = VT_INT;
7854 if (((btype.t & VT_BTYPE) == VT_ENUM ||
7855 (btype.t & VT_BTYPE) == VT_STRUCT) &&
7856 tok == ';') {
7857 /* we accept no variable after */
7858 next();
7859 continue;
7861 while (1) { /* iterate thru each declaration */
7862 type = btype;
7863 type_decl(&type, &ad, &v, TYPE_DIRECT);
7864 #if 0
7866 char buf[500];
7867 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
7868 printf("type = '%s'\n", buf);
7870 #endif
7871 if ((type.t & VT_BTYPE) == VT_FUNC) {
7872 /* if old style function prototype, we accept a
7873 declaration list */
7874 sym = type.ref;
7875 if (sym->c == FUNC_OLD)
7876 func_decl_list(sym);
7879 if (tok == '{') {
7880 #ifdef CONFIG_REG_VARS
7881 TokenString func_str;
7882 ParseState saved_parse_state;
7883 int block_level;
7884 #endif
7886 if (l == VT_LOCAL)
7887 error("cannot use local functions");
7888 if (!(type.t & VT_FUNC))
7889 expect("function definition");
7891 #ifdef CONFIG_REG_VARS
7892 /* parse all function code and record it */
7894 tok_str_new(&func_str);
7896 block_level = 0;
7897 for(;;) {
7898 int t;
7899 if (tok == -1)
7900 error("unexpected end of file");
7901 tok_str_add_tok(&func_str);
7902 t = tok;
7903 next();
7904 if (t == '{') {
7905 block_level++;
7906 } else if (t == '}') {
7907 block_level--;
7908 if (block_level == 0)
7909 break;
7912 tok_str_add(&func_str, -1);
7913 tok_str_add(&func_str, 0);
7915 save_parse_state(&saved_parse_state);
7917 macro_ptr = func_str.str;
7918 next();
7919 analyse_function();
7920 #endif
7922 /* compute text section */
7923 cur_text_section = ad.section;
7924 if (!cur_text_section)
7925 cur_text_section = text_section;
7926 ind = cur_text_section->data_offset;
7927 funcname = get_tok_str(v, NULL);
7928 sym = sym_find(v);
7929 if (sym) {
7930 /* if symbol is already defined, then put complete type */
7931 sym->type = type;
7932 } else {
7933 /* put function symbol */
7934 sym = global_identifier_push(v, type.t, 0);
7935 sym->type.ref = type.ref;
7937 /* NOTE: we patch the symbol size later */
7938 put_extern_sym(sym, cur_text_section, ind, 0);
7939 func_ind = ind;
7940 sym->r = VT_SYM | VT_CONST;
7941 /* put debug symbol */
7942 if (do_debug)
7943 put_func_debug(sym);
7944 /* push a dummy symbol to enable local sym storage */
7945 sym_push2(&local_stack, SYM_FIELD, 0, 0);
7946 gfunc_prolog(&type);
7947 loc = 0;
7948 rsym = 0;
7949 #ifdef CONFIG_REG_VARS
7950 macro_ptr = func_str.str;
7951 next();
7952 #endif
7953 block(NULL, NULL, NULL, NULL, 0);
7954 gsym(rsym);
7955 gfunc_epilog();
7956 cur_text_section->data_offset = ind;
7957 /* look if any labels are undefined. Define symbols if
7958 '&&label' was used. */
7960 Sym *s, *s1;
7961 for(s = label_stack; s != NULL; s = s1) {
7962 s1 = s->prev;
7963 if (s->r & LABEL_FORWARD) {
7964 error("label '%s' used but not defined",
7965 get_tok_str(s->v, NULL));
7967 if (s->c) {
7968 /* define corresponding symbol. A size of
7969 1 is put. */
7970 put_extern_sym(s, cur_text_section, (long)s->next, 1);
7972 /* remove label */
7973 table_ident[s->v - TOK_IDENT]->sym_label = NULL;
7974 tcc_free(s);
7976 label_stack = NULL;
7978 sym_pop(&local_stack, NULL); /* reset local stack */
7979 /* end of function */
7980 /* patch symbol size */
7981 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
7982 ind - func_ind;
7983 if (do_debug) {
7984 put_stabn(N_FUN, 0, 0, ind - func_ind);
7986 funcname = ""; /* for safety */
7987 func_vt.t = VT_VOID; /* for safety */
7988 ind = 0; /* for safety */
7990 #ifdef CONFIG_REG_VARS
7991 tok_str_free(func_str.str);
7992 restore_parse_state(&saved_parse_state);
7993 #endif
7994 break;
7995 } else {
7996 if (btype.t & VT_TYPEDEF) {
7997 /* save typedefed type */
7998 /* XXX: test storage specifiers ? */
7999 sym = sym_push(v, &type, 0, 0);
8000 sym->type.t |= VT_TYPEDEF;
8001 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
8002 /* external function definition */
8003 external_sym(v, &type, 0);
8004 } else {
8005 /* not lvalue if array */
8006 r = 0;
8007 if (!(type.t & VT_ARRAY))
8008 r |= lvalue_type(type.t);
8009 if (btype.t & VT_EXTERN) {
8010 /* external variable */
8011 external_sym(v, &type, r);
8012 } else {
8013 if (type.t & VT_STATIC)
8014 r |= VT_CONST;
8015 else
8016 r |= l;
8017 has_init = (tok == '=');
8018 if (has_init)
8019 next();
8020 decl_initializer_alloc(&type, &ad, r,
8021 has_init, v, l);
8024 if (tok != ',') {
8025 skip(';');
8026 break;
8028 next();
8034 /* compile the C file opened in 'file'. Return non zero if errors. */
8035 static int tcc_compile(TCCState *s1)
8037 Sym *define_start;
8038 char buf[512];
8039 volatile int section_sym;
8041 #ifdef INC_DEBUG
8042 printf("%s: **** new file\n", file->filename);
8043 #endif
8044 funcname = "";
8045 s1->include_stack_ptr = s1->include_stack;
8046 /* XXX: move that before to avoid having to initialize
8047 file->ifdef_stack_ptr ? */
8048 s1->ifdef_stack_ptr = s1->ifdef_stack;
8049 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
8051 /* XXX: not ANSI compliant: bound checking says error */
8052 vtop = vstack - 1;
8053 anon_sym = SYM_FIRST_ANOM;
8055 /* file info: full path + filename */
8056 section_sym = 0; /* avoid warning */
8057 if (do_debug) {
8058 section_sym = put_elf_sym(symtab_section, 0, 0,
8059 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
8060 text_section->sh_num, NULL);
8061 getcwd(buf, sizeof(buf));
8062 pstrcat(buf, sizeof(buf), "/");
8063 put_stabs_r(buf, N_SO, 0, 0,
8064 text_section->data_offset, text_section, section_sym);
8065 put_stabs_r(file->filename, N_SO, 0, 0,
8066 text_section->data_offset, text_section, section_sym);
8068 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8069 symbols can be safely used */
8070 put_elf_sym(symtab_section, 0, 0,
8071 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
8072 SHN_ABS, file->filename);
8074 /* define some often used types */
8075 int_type.t = VT_INT;
8077 char_pointer_type.t = VT_BYTE;
8078 mk_pointer(&char_pointer_type);
8080 func_old_type.t = VT_FUNC;
8081 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
8083 #if 0
8084 /* define 'void *alloca(unsigned int)' builtin function */
8086 Sym *s1;
8088 p = anon_sym++;
8089 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
8090 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
8091 s1->next = NULL;
8092 sym->next = s1;
8093 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
8095 #endif
8097 define_start = define_stack;
8099 if (setjmp(s1->error_jmp_buf) == 0) {
8100 s1->nb_errors = 0;
8101 s1->error_set_jmp_enabled = 1;
8103 ch = file->buf_ptr[0];
8104 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
8105 next();
8106 decl(VT_CONST);
8107 if (tok != -1)
8108 expect("declaration");
8110 /* end of translation unit info */
8111 if (do_debug) {
8112 put_stabs_r(NULL, N_SO, 0, 0,
8113 text_section->data_offset, text_section, section_sym);
8116 s1->error_set_jmp_enabled = 0;
8118 /* reset define stack, but leave -Dsymbols (may be incorrect if
8119 they are undefined) */
8120 free_defines(define_start);
8122 sym_pop(&global_stack, NULL);
8124 return s1->nb_errors != 0 ? -1 : 0;
8127 #ifdef LIBTCC
8128 int tcc_compile_string(TCCState *s, const char *str)
8130 BufferedFile bf1, *bf = &bf1;
8131 int ret, len;
8132 char *buf;
8134 /* init file structure */
8135 bf->fd = -1;
8136 /* XXX: avoid copying */
8137 len = strlen(str);
8138 buf = tcc_malloc(len + 1);
8139 if (!buf)
8140 return -1;
8141 buf[len] = CH_EOB;
8142 bf->buf_ptr = buf;
8143 bf->buf_end = buf + len;
8144 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
8145 bf->line_num = 1;
8146 file = bf;
8148 ret = tcc_compile(s);
8150 tcc_free(buf);
8152 /* currently, no need to close */
8153 return ret;
8155 #endif
8157 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8158 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
8160 BufferedFile bf1, *bf = &bf1;
8162 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
8163 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
8164 /* default value */
8165 if (!value)
8166 value = "1";
8167 pstrcat(bf->buffer, IO_BUF_SIZE, value);
8169 /* init file structure */
8170 bf->fd = -1;
8171 bf->buf_ptr = bf->buffer;
8172 bf->buf_end = bf->buffer + strlen(bf->buffer);
8173 *bf->buf_end = CH_EOB;
8174 bf->filename[0] = '\0';
8175 bf->line_num = 1;
8176 file = bf;
8178 s1->include_stack_ptr = s1->include_stack;
8180 /* parse with define parser */
8181 ch = file->buf_ptr[0];
8182 next_nomacro();
8183 parse_define();
8184 file = NULL;
8187 /* undefine a preprocessor symbol */
8188 void tcc_undefine_symbol(TCCState *s1, const char *sym)
8190 TokenSym *ts;
8191 Sym *s;
8192 ts = tok_alloc(sym, strlen(sym));
8193 s = define_find(ts->tok);
8194 /* undefine symbol by putting an invalid name */
8195 if (s)
8196 define_undef(s);
8199 #include "tccelf.c"
8201 /* print the position in the source file of PC value 'pc' by reading
8202 the stabs debug information */
8203 static void rt_printline(unsigned long wanted_pc)
8205 Stab_Sym *sym, *sym_end;
8206 char func_name[128], last_func_name[128];
8207 unsigned long func_addr, last_pc, pc;
8208 const char *incl_files[INCLUDE_STACK_SIZE];
8209 int incl_index, len, last_line_num, i;
8210 const char *str, *p;
8212 fprintf(stderr, "0x%08lx:", wanted_pc);
8214 func_name[0] = '\0';
8215 func_addr = 0;
8216 incl_index = 0;
8217 last_func_name[0] = '\0';
8218 last_pc = 0xffffffff;
8219 last_line_num = 1;
8220 sym = (Stab_Sym *)stab_section->data + 1;
8221 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
8222 while (sym < sym_end) {
8223 switch(sym->n_type) {
8224 /* function start or end */
8225 case N_FUN:
8226 if (sym->n_strx == 0) {
8227 /* we test if between last line and end of function */
8228 pc = sym->n_value + func_addr;
8229 if (wanted_pc >= last_pc && wanted_pc < pc)
8230 goto found;
8231 func_name[0] = '\0';
8232 func_addr = 0;
8233 } else {
8234 str = stabstr_section->data + sym->n_strx;
8235 p = strchr(str, ':');
8236 if (!p) {
8237 pstrcpy(func_name, sizeof(func_name), str);
8238 } else {
8239 len = p - str;
8240 if (len > sizeof(func_name) - 1)
8241 len = sizeof(func_name) - 1;
8242 memcpy(func_name, str, len);
8243 func_name[len] = '\0';
8245 func_addr = sym->n_value;
8247 break;
8248 /* line number info */
8249 case N_SLINE:
8250 pc = sym->n_value + func_addr;
8251 if (wanted_pc >= last_pc && wanted_pc < pc)
8252 goto found;
8253 last_pc = pc;
8254 last_line_num = sym->n_desc;
8255 /* XXX: slow! */
8256 strcpy(last_func_name, func_name);
8257 break;
8258 /* include files */
8259 case N_BINCL:
8260 str = stabstr_section->data + sym->n_strx;
8261 add_incl:
8262 if (incl_index < INCLUDE_STACK_SIZE) {
8263 incl_files[incl_index++] = str;
8265 break;
8266 case N_EINCL:
8267 if (incl_index > 1)
8268 incl_index--;
8269 break;
8270 case N_SO:
8271 if (sym->n_strx == 0) {
8272 incl_index = 0; /* end of translation unit */
8273 } else {
8274 str = stabstr_section->data + sym->n_strx;
8275 /* do not add path */
8276 len = strlen(str);
8277 if (len > 0 && str[len - 1] != '/')
8278 goto add_incl;
8280 break;
8282 sym++;
8285 /* second pass: we try symtab symbols (no line number info) */
8286 incl_index = 0;
8288 Elf32_Sym *sym, *sym_end;
8289 int type;
8291 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
8292 for(sym = (Elf32_Sym *)symtab_section->data + 1;
8293 sym < sym_end;
8294 sym++) {
8295 type = ELF32_ST_TYPE(sym->st_info);
8296 if (type == STT_FUNC) {
8297 if (wanted_pc >= sym->st_value &&
8298 wanted_pc < sym->st_value + sym->st_size) {
8299 pstrcpy(last_func_name, sizeof(last_func_name),
8300 strtab_section->data + sym->st_name);
8301 goto found;
8306 /* did not find any info: */
8307 fprintf(stderr, " ???\n");
8308 return;
8309 found:
8310 if (last_func_name[0] != '\0') {
8311 fprintf(stderr, " %s()", last_func_name);
8313 if (incl_index > 0) {
8314 fprintf(stderr, " (%s:%d",
8315 incl_files[incl_index - 1], last_line_num);
8316 for(i = incl_index - 2; i >= 0; i--)
8317 fprintf(stderr, ", included from %s", incl_files[i]);
8318 fprintf(stderr, ")");
8320 fprintf(stderr, "\n");
8323 #ifndef WIN32
8325 #ifdef __i386__
8327 #ifndef EIP
8328 #define EIP 14
8329 #define EBP 6
8330 #endif
8332 /* return the PC at frame level 'level'. Return non zero if not found */
8333 static int rt_get_caller_pc(unsigned long *paddr,
8334 struct ucontext *uc, int level)
8336 unsigned long fp;
8337 int i;
8339 if (level == 0) {
8340 *paddr = uc->uc_mcontext.gregs[EIP];
8341 return 0;
8342 } else {
8343 fp = uc->uc_mcontext.gregs[EBP];
8344 for(i=1;i<level;i++) {
8345 /* XXX: check address validity with program info */
8346 if (fp <= 0x1000 || fp >= 0xc0000000)
8347 return -1;
8348 fp = ((unsigned long *)fp)[0];
8350 *paddr = ((unsigned long *)fp)[1];
8351 return 0;
8354 #else
8355 #error add arch specific rt_get_caller_pc()
8356 #endif
8358 /* emit a run time error at position 'pc' */
8359 void rt_error(struct ucontext *uc, const char *fmt, ...)
8361 va_list ap;
8362 unsigned long pc;
8363 int i;
8365 va_start(ap, fmt);
8366 fprintf(stderr, "Runtime error: ");
8367 vfprintf(stderr, fmt, ap);
8368 fprintf(stderr, "\n");
8369 for(i=0;i<num_callers;i++) {
8370 if (rt_get_caller_pc(&pc, uc, i) < 0)
8371 break;
8372 if (i == 0)
8373 fprintf(stderr, "at ");
8374 else
8375 fprintf(stderr, "by ");
8376 rt_printline(pc);
8378 exit(255);
8379 va_end(ap);
8382 /* signal handler for fatal errors */
8383 static void sig_error(int signum, siginfo_t *siginf, void *puc)
8385 struct ucontext *uc = puc;
8387 switch(signum) {
8388 case SIGFPE:
8389 switch(siginf->si_code) {
8390 case FPE_INTDIV:
8391 case FPE_FLTDIV:
8392 rt_error(uc, "division by zero");
8393 break;
8394 default:
8395 rt_error(uc, "floating point exception");
8396 break;
8398 break;
8399 case SIGBUS:
8400 case SIGSEGV:
8401 if (rt_bound_error_msg && *rt_bound_error_msg)
8402 rt_error(uc, *rt_bound_error_msg);
8403 else
8404 rt_error(uc, "dereferencing invalid pointer");
8405 break;
8406 case SIGILL:
8407 rt_error(uc, "illegal instruction");
8408 break;
8409 case SIGABRT:
8410 rt_error(uc, "abort() called");
8411 break;
8412 default:
8413 rt_error(uc, "caught signal %d", signum);
8414 break;
8416 exit(255);
8418 #endif
8420 /* do all relocations (needed before using tcc_get_symbol()) */
8421 int tcc_relocate(TCCState *s1)
8423 Section *s;
8424 int i;
8426 s1->nb_errors = 0;
8428 tcc_add_runtime(s1);
8430 relocate_common_syms();
8432 /* compute relocation address : section are relocated in place. We
8433 also alloc the bss space */
8434 for(i = 1; i < s1->nb_sections; i++) {
8435 s = s1->sections[i];
8436 if (s->sh_flags & SHF_ALLOC) {
8437 if (s->sh_type == SHT_NOBITS)
8438 s->data = tcc_mallocz(s->data_offset);
8439 s->sh_addr = (unsigned long)s->data;
8443 relocate_syms(s1, 1);
8445 if (s1->nb_errors != 0)
8446 return -1;
8448 /* relocate each section */
8449 for(i = 1; i < s1->nb_sections; i++) {
8450 s = s1->sections[i];
8451 if (s->reloc)
8452 relocate_section(s1, s);
8454 return 0;
8457 /* launch the compiled program with the given arguments */
8458 int tcc_run(TCCState *s1, int argc, char **argv)
8460 int (*prog_main)(int, char **);
8462 if (tcc_relocate(s1) < 0)
8463 return -1;
8465 prog_main = tcc_get_symbol(s1, "main");
8467 if (do_debug) {
8468 #ifdef WIN32
8469 error("debug mode currently not available for Windows");
8470 #else
8471 struct sigaction sigact;
8472 /* install TCC signal handlers to print debug info on fatal
8473 runtime errors */
8474 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
8475 sigact.sa_sigaction = sig_error;
8476 sigemptyset(&sigact.sa_mask);
8477 sigaction(SIGFPE, &sigact, NULL);
8478 sigaction(SIGILL, &sigact, NULL);
8479 sigaction(SIGSEGV, &sigact, NULL);
8480 sigaction(SIGBUS, &sigact, NULL);
8481 sigaction(SIGABRT, &sigact, NULL);
8482 #endif
8485 #ifdef CONFIG_TCC_BCHECK
8486 if (do_bounds_check) {
8487 void (*bound_init)(void);
8489 /* set error function */
8490 rt_bound_error_msg = (void *)tcc_get_symbol(s1, "__bound_error_msg");
8492 /* XXX: use .init section so that it also work in binary ? */
8493 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
8494 bound_init();
8496 #endif
8497 return (*prog_main)(argc, argv);
8500 TCCState *tcc_new(void)
8502 const char *p, *r;
8503 TCCState *s;
8505 s = tcc_mallocz(sizeof(TCCState));
8506 if (!s)
8507 return NULL;
8508 tcc_state = s;
8509 s->output_type = TCC_OUTPUT_MEMORY;
8511 /* default include paths */
8512 tcc_add_sysinclude_path(s, "/usr/local/include");
8513 tcc_add_sysinclude_path(s, "/usr/include");
8514 tcc_add_sysinclude_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
8516 /* add all tokens */
8517 table_ident = NULL;
8518 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
8520 tok_ident = TOK_IDENT;
8521 p = tcc_keywords;
8522 while (*p) {
8523 r = p;
8524 while (*r++);
8525 tok_alloc(p, r - p - 1);
8526 p = r;
8529 /* we add dummy defines for some special macros to speed up tests
8530 and to have working defined() */
8531 define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
8532 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
8533 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
8534 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
8536 /* standard defines */
8537 tcc_define_symbol(s, "__STDC__", NULL);
8538 #if defined(TCC_TARGET_I386)
8539 tcc_define_symbol(s, "__i386__", NULL);
8540 #endif
8541 #if defined(linux)
8542 tcc_define_symbol(s, "linux", NULL);
8543 #endif
8544 /* tiny C specific defines */
8545 tcc_define_symbol(s, "__TINYC__", NULL);
8547 /* tiny C & gcc defines */
8548 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
8549 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
8550 tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
8552 /* default library paths */
8553 tcc_add_library_path(s, "/usr/local/lib");
8554 tcc_add_library_path(s, "/usr/lib");
8555 tcc_add_library_path(s, "/lib");
8557 /* no section zero */
8558 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
8560 /* create standard sections */
8561 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
8562 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
8563 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
8565 /* symbols are always generated for linking stage */
8566 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
8567 ".strtab",
8568 ".hashtab", SHF_PRIVATE);
8569 strtab_section = symtab_section->link;
8571 /* private symbol table for dynamic symbols */
8572 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
8573 ".dynstrtab",
8574 ".dynhashtab", SHF_PRIVATE);
8575 return s;
8578 void tcc_delete(TCCState *s1)
8580 int i, n;
8582 /* free -D defines */
8583 free_defines(NULL);
8585 /* free tokens */
8586 n = tok_ident - TOK_IDENT;
8587 for(i = 0; i < n; i++)
8588 tcc_free(table_ident[i]);
8589 tcc_free(table_ident);
8591 /* free all sections */
8593 free_section(symtab_section->hash);
8595 free_section(s1->dynsymtab_section->hash);
8596 free_section(s1->dynsymtab_section->link);
8597 free_section(s1->dynsymtab_section);
8599 for(i = 1; i < s1->nb_sections; i++)
8600 free_section(s1->sections[i]);
8601 tcc_free(s1->sections);
8603 /* free loaded dlls array */
8604 for(i = 0; i < s1->nb_loaded_dlls; i++)
8605 tcc_free(s1->loaded_dlls[i]);
8606 tcc_free(s1->loaded_dlls);
8608 /* library paths */
8609 for(i = 0; i < s1->nb_library_paths; i++)
8610 tcc_free(s1->library_paths[i]);
8611 tcc_free(s1->library_paths);
8613 /* cached includes */
8614 for(i = 0; i < s1->nb_cached_includes; i++)
8615 tcc_free(s1->cached_includes[i]);
8616 tcc_free(s1->cached_includes);
8618 for(i = 0; i < s1->nb_include_paths; i++)
8619 tcc_free(s1->include_paths[i]);
8620 tcc_free(s1->include_paths);
8622 for(i = 0; i < s1->nb_sysinclude_paths; i++)
8623 tcc_free(s1->sysinclude_paths[i]);
8624 tcc_free(s1->sysinclude_paths);
8626 tcc_free(s1);
8629 int tcc_add_include_path(TCCState *s1, const char *pathname)
8631 char *pathname1;
8633 pathname1 = tcc_strdup(pathname);
8634 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
8635 return 0;
8638 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
8640 char *pathname1;
8642 pathname1 = tcc_strdup(pathname);
8643 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
8644 return 0;
8647 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
8649 const char *ext;
8650 Elf32_Ehdr ehdr;
8651 int fd, ret;
8652 BufferedFile *saved_file;
8654 /* find source file type with extension */
8655 ext = strrchr(filename, '.');
8656 if (ext)
8657 ext++;
8659 /* open the file */
8660 saved_file = file;
8661 file = tcc_open(s1, filename);
8662 if (!file) {
8663 if (flags & AFF_PRINT_ERROR) {
8664 error_noabort("file '%s' not found", filename);
8666 ret = -1;
8667 goto fail1;
8670 if (!ext || !strcmp(ext, "c")) {
8671 /* C file assumed */
8672 ret = tcc_compile(s1);
8673 } else {
8674 fd = file->fd;
8675 /* assume executable format: auto guess file type */
8676 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
8677 error_noabort("could not read header");
8678 goto fail;
8680 lseek(fd, 0, SEEK_SET);
8682 if (ehdr.e_ident[0] == ELFMAG0 &&
8683 ehdr.e_ident[1] == ELFMAG1 &&
8684 ehdr.e_ident[2] == ELFMAG2 &&
8685 ehdr.e_ident[3] == ELFMAG3) {
8686 file->line_num = 0; /* do not display line number if error */
8687 if (ehdr.e_type == ET_REL) {
8688 ret = tcc_load_object_file(s1, fd, 0);
8689 } else if (ehdr.e_type == ET_DYN) {
8690 ret = tcc_load_dll(s1, fd, filename,
8691 (flags & AFF_REFERENCED_DLL) != 0);
8692 } else {
8693 error_noabort("unrecognized ELF file");
8694 goto fail;
8696 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
8697 file->line_num = 0; /* do not display line number if error */
8698 ret = tcc_load_archive(s1, fd);
8699 } else {
8700 /* as GNU ld, consider it is an ld script if not recognized */
8701 ret = tcc_load_ldscript(s1);
8702 if (ret < 0) {
8703 error_noabort("unrecognized file type");
8704 goto fail;
8708 the_end:
8709 tcc_close(file);
8710 fail1:
8711 file = saved_file;
8712 return ret;
8713 fail:
8714 ret = -1;
8715 goto the_end;
8718 int tcc_add_file(TCCState *s, const char *filename)
8720 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
8723 int tcc_add_library_path(TCCState *s, const char *pathname)
8725 char *pathname1;
8727 pathname1 = tcc_strdup(pathname);
8728 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
8729 return 0;
8732 /* find and load a dll. Return non zero if not found */
8733 /* XXX: add '-rpath' option support ? */
8734 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
8736 char buf[1024];
8737 int i;
8739 for(i = 0; i < s->nb_library_paths; i++) {
8740 snprintf(buf, sizeof(buf), "%s/%s",
8741 s->library_paths[i], filename);
8742 if (tcc_add_file_internal(s, buf, flags) == 0)
8743 return 0;
8745 return -1;
8748 /* the library name is the same as the argument of the '-l' option */
8749 int tcc_add_library(TCCState *s, const char *libraryname)
8751 char buf[1024];
8752 int i;
8753 void *h;
8755 /* first we look for the dynamic library if not static linking */
8756 if (!s->static_link) {
8757 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
8758 /* if we output to memory, then we simply we dlopen(). */
8759 if (s->output_type == TCC_OUTPUT_MEMORY) {
8760 /* Since the libc is already loaded, we don't need to load it again */
8761 if (!strcmp(libraryname, "c"))
8762 return 0;
8763 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
8764 if (h)
8765 return 0;
8766 } else {
8767 if (tcc_add_dll(s, buf, 0) == 0)
8768 return 0;
8772 /* then we look for the static library */
8773 for(i = 0; i < s->nb_library_paths; i++) {
8774 snprintf(buf, sizeof(buf), "%s/lib%s.a",
8775 s->library_paths[i], libraryname);
8776 if (tcc_add_file_internal(s, buf, 0) == 0)
8777 return 0;
8779 return -1;
8782 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
8784 add_elf_sym(symtab_section, val, 0,
8785 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
8786 SHN_ABS, name);
8787 return 0;
8790 int tcc_set_output_type(TCCState *s, int output_type)
8792 s->output_type = output_type;
8794 /* if bound checking, then add corresponding sections */
8795 #ifdef CONFIG_TCC_BCHECK
8796 if (do_bounds_check) {
8797 /* define symbol */
8798 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
8799 /* create bounds sections */
8800 bounds_section = new_section(s, ".bounds",
8801 SHT_PROGBITS, SHF_ALLOC);
8802 lbounds_section = new_section(s, ".lbounds",
8803 SHT_PROGBITS, SHF_ALLOC);
8805 #endif
8807 /* add debug sections */
8808 if (do_debug) {
8809 /* stab symbols */
8810 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
8811 stab_section->sh_entsize = sizeof(Stab_Sym);
8812 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
8813 put_elf_str(stabstr_section, "");
8814 stab_section->link = stabstr_section;
8815 /* put first entry */
8816 put_stabs("", 0, 0, 0, 0);
8819 /* add libc crt1/crti objects */
8820 if (output_type == TCC_OUTPUT_EXE ||
8821 output_type == TCC_OUTPUT_DLL) {
8822 if (output_type != TCC_OUTPUT_DLL)
8823 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
8824 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
8826 return 0;
8829 #if !defined(LIBTCC)
8831 static int64_t getclock_us(void)
8833 #ifdef WIN32
8834 struct _timeb tb;
8835 _ftime(&tb);
8836 return (tb.time * 1000LL + tb.millitm) * 1000LL;
8837 #else
8838 struct timeval tv;
8839 gettimeofday(&tv, NULL);
8840 return tv.tv_sec * 1000000LL + tv.tv_usec;
8841 #endif
8844 void help(void)
8846 printf("tcc version 0.9.13 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8847 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8848 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
8849 " [--] infile1 [infile2... --] [infile_args...]\n"
8850 "\n"
8851 "General options:\n"
8852 " -c compile only - generate an object file\n"
8853 " -o outfile set output filename\n"
8854 " -- allows multiples input files if no -o option given. Also\n"
8855 " separate input files from runtime arguments\n"
8856 " -Bdir set tcc internal library path\n"
8857 " -bench output compilation statistics\n"
8858 "Preprocessor options:\n"
8859 " -Idir add include path 'dir'\n"
8860 " -Dsym[=val] define 'sym' with value 'val'\n"
8861 " -Usym undefine 'sym'\n"
8862 "Linker options:\n"
8863 " -Ldir add library path 'dir'\n"
8864 " -llib link with dynamic or static library 'lib'\n"
8865 " -shared generate a shared library\n"
8866 " -static static linking\n"
8867 " -r relocatable output\n"
8868 "Debugger options:\n"
8869 " -g generate runtime debug info\n"
8870 #ifdef CONFIG_TCC_BCHECK
8871 " -b compile with built-in memory and bounds checker (implies -g)\n"
8872 #endif
8873 " -bt N show N callers in stack traces\n"
8877 int main(int argc, char **argv)
8879 char *r, *outfile;
8880 int optind, output_type, multiple_files, i, reloc_output;
8881 TCCState *s;
8882 char **files;
8883 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
8884 char objfilename[1024];
8885 int64_t start_time = 0;
8887 s = tcc_new();
8888 output_type = TCC_OUTPUT_MEMORY;
8890 optind = 1;
8891 outfile = NULL;
8892 multiple_files = 0;
8893 dminus = 0;
8894 files = NULL;
8895 nb_files = 0;
8896 nb_libraries = 0;
8897 reloc_output = 0;
8898 while (1) {
8899 if (optind >= argc) {
8900 if (nb_files == 0)
8901 goto show_help;
8902 else
8903 break;
8905 r = argv[optind++];
8906 if (r[0] != '-') {
8907 /* add a new file */
8908 dynarray_add((void ***)&files, &nb_files, r);
8909 if (!multiple_files) {
8910 optind--;
8911 /* argv[0] will be this file */
8912 break;
8914 } else if (r[1] == '-') {
8915 /* '--' enables multiple files input and also ends several file input */
8916 if (dminus && multiple_files) {
8917 optind--; /* argv[0] will be '--' */
8918 break;
8920 dminus = 1;
8921 multiple_files = 1;
8922 } else if (r[1] == 'h' || r[1] == '?') {
8923 show_help:
8924 help();
8925 return 1;
8926 } else if (r[1] == 'I') {
8927 if (tcc_add_include_path(s, r + 2) < 0)
8928 error("too many include paths");
8929 } else if (r[1] == 'D') {
8930 char *sym, *value;
8931 sym = r + 2;
8932 value = strchr(sym, '=');
8933 if (value) {
8934 *value = '\0';
8935 value++;
8937 tcc_define_symbol(s, sym, value);
8938 } else if (r[1] == 'U') {
8939 tcc_undefine_symbol(s, r + 2);
8940 } else if (r[1] == 'L') {
8941 tcc_add_library_path(s, r + 2);
8942 } else if (r[1] == 'B') {
8943 /* set tcc utilities path (mainly for tcc development) */
8944 tcc_lib_path = r + 2;
8945 } else if (r[1] == 'l') {
8946 dynarray_add((void ***)&files, &nb_files, r);
8947 nb_libraries++;
8948 } else if (!strcmp(r + 1, "bench")) {
8949 do_bench = 1;
8950 } else if (!strcmp(r + 1, "bt")) {
8951 num_callers = atoi(argv[optind++]);
8952 } else
8953 #ifdef CONFIG_TCC_BCHECK
8954 if (r[1] == 'b') {
8955 do_bounds_check = 1;
8956 do_debug = 1;
8957 } else
8958 #endif
8959 if (r[1] == 'g') {
8960 do_debug = 1;
8961 } else if (r[1] == 'c') {
8962 multiple_files = 1;
8963 output_type = TCC_OUTPUT_OBJ;
8964 } else if (!strcmp(r + 1, "static")) {
8965 s->static_link = 1;
8966 } else if (!strcmp(r + 1, "shared")) {
8967 output_type = TCC_OUTPUT_DLL;
8968 } else if (r[1] == 'o') {
8969 if (optind >= argc)
8970 goto show_help;
8971 multiple_files = 1;
8972 outfile = argv[optind++];
8973 } else if (r[1] == 'r') {
8974 /* generate a .o merging several output files */
8975 reloc_output = 1;
8976 output_type = TCC_OUTPUT_OBJ;
8977 } else if (r[1] == 'W' || r[1] == 'O' || r[1] == 'm' || r[1] == 'f') {
8978 /* ignore those options to be a drop-in replacement for gcc */
8979 } else {
8980 error("invalid option -- '%s'", r);
8984 nb_objfiles = nb_files - nb_libraries;
8986 /* if outfile provided without other options, we output an
8987 executable */
8988 if (outfile && output_type == TCC_OUTPUT_MEMORY)
8989 output_type = TCC_OUTPUT_EXE;
8991 /* check -c consistency : only single file handled. XXX: checks file type */
8992 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
8993 /* accepts only a single input file */
8994 if (nb_objfiles != 1)
8995 error("cannot specify multiple files with -c");
8996 if (nb_libraries != 0)
8997 error("cannot specify libraries with -c");
9000 /* compute default outfile name */
9001 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
9002 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
9003 char *ext;
9004 /* add .o extension */
9005 pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
9006 ext = strrchr(objfilename, '.');
9007 if (!ext)
9008 goto default_outfile;
9009 strcpy(ext + 1, "o");
9010 } else {
9011 default_outfile:
9012 pstrcpy(objfilename, sizeof(objfilename), "a.out");
9014 outfile = objfilename;
9017 if (do_bench) {
9018 start_time = getclock_us();
9021 tcc_set_output_type(s, output_type);
9023 /* compile or add each files or library */
9024 for(i = 0;i < nb_files; i++) {
9025 const char *filename;
9027 filename = files[i];
9028 if (filename[0] == '-') {
9029 if (tcc_add_library(s, filename + 2) < 0)
9030 error("cannot find %s", filename);
9031 } else {
9032 if (tcc_add_file(s, filename) < 0) {
9033 ret = 1;
9034 goto the_end;
9039 /* free all files */
9040 tcc_free(files);
9042 if (do_bench) {
9043 double total_time;
9044 total_time = (double)(getclock_us() - start_time) / 1000000.0;
9045 if (total_time < 0.001)
9046 total_time = 0.001;
9047 if (total_bytes < 1)
9048 total_bytes = 1;
9049 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
9050 tok_ident - TOK_IDENT, total_lines, total_bytes,
9051 total_time, (int)(total_lines / total_time),
9052 total_bytes / total_time / 1000000.0);
9055 if (s->output_type != TCC_OUTPUT_MEMORY) {
9056 tcc_output_file(s, outfile);
9057 ret = 0;
9058 } else {
9059 ret = tcc_run(s, argc - optind, argv + optind);
9061 the_end:
9062 /* XXX: cannot do it with bound checking because of the malloc hooks */
9063 if (!do_bounds_check)
9064 tcc_delete(s);
9066 #ifdef MEM_DEBUG
9067 if (do_bench) {
9068 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
9070 #endif
9071 return ret;
9074 #endif