error message fixes - CH_EOB is now '\'
[tinycc.git] / tcc.c
blobda642c45675af3007baea22fec7142655a3ba6d2
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 //#define DEBUG
47 /* preprocessor debug */
48 //#define PP_DEBUG
49 /* include file debug */
50 //#define INC_DEBUG
52 //#define MEM_DEBUG
54 /* target selection */
55 //#define TCC_TARGET_I386 /* i386 code generator */
56 //#define TCC_TARGET_IL /* .NET CLI generator */
58 /* default target is I386 */
59 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
60 #define TCC_TARGET_I386
61 #endif
63 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
64 #define CONFIG_TCC_BCHECK /* enable bound checking code */
65 #endif
67 #ifndef CONFIG_TCC_PREFIX
68 #define CONFIG_TCC_PREFIX "/usr/local"
69 #endif
71 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
72 executables or dlls */
73 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
75 #define INCLUDE_STACK_SIZE 32
76 #define IFDEF_STACK_SIZE 64
77 #define VSTACK_SIZE 64
78 #define STRING_MAX_SIZE 1024
80 #define TOK_HASH_SIZE 2048 /* must be a power of two */
81 #define TOK_ALLOC_INCR 512 /* must be a power of two */
83 /* token symbol management */
84 typedef struct TokenSym {
85 struct TokenSym *hash_next;
86 struct Sym *sym_define; /* direct pointer to define */
87 struct Sym *sym_label; /* direct pointer to label */
88 struct Sym *sym_struct; /* direct pointer to structure */
89 struct Sym *sym_identifier; /* direct pointer to identifier */
90 int tok; /* token number */
91 int len;
92 char str[1];
93 } TokenSym;
95 typedef struct CString {
96 int size; /* size in bytes */
97 void *data; /* either 'char *' or 'int *' */
98 int size_allocated;
99 void *data_allocated; /* if non NULL, data has been malloced */
100 } CString;
102 /* type definition */
103 typedef struct CType {
104 int t;
105 struct Sym *ref;
106 } CType;
108 /* constant value */
109 typedef union CValue {
110 long double ld;
111 double d;
112 float f;
113 int i;
114 unsigned int ui;
115 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
116 long long ll;
117 unsigned long long ull;
118 struct CString *cstr;
119 void *ptr;
120 int tab[1];
121 } CValue;
123 /* value on stack */
124 typedef struct SValue {
125 CType type; /* type */
126 unsigned short r; /* register + flags */
127 unsigned short r2; /* second register, used for 'long long'
128 type. If not used, set to VT_CONST */
129 CValue c; /* constant, if VT_CONST */
130 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
131 } SValue;
133 /* symbol management */
134 typedef struct Sym {
135 int v; /* symbol token */
136 int r; /* associated register */
137 int c; /* associated number */
138 CType type; /* associated type */
139 struct Sym *next; /* next related symbol */
140 struct Sym *prev; /* prev symbol in stack */
141 struct Sym *prev_tok; /* previous symbol for this token */
142 } Sym;
144 /* section definition */
145 /* XXX: use directly ELF structure for parameters ? */
146 /* special flag to indicate that the section should not be linked to
147 the other ones */
148 #define SHF_PRIVATE 0x80000000
150 typedef struct Section {
151 unsigned long data_offset; /* current data offset */
152 unsigned char *data; /* section data */
153 unsigned long data_allocated; /* used for realloc() handling */
154 int sh_name; /* elf section name (only used during output) */
155 int sh_num; /* elf section number */
156 int sh_type; /* elf section type */
157 int sh_flags; /* elf section flags */
158 int sh_info; /* elf section info */
159 int sh_addralign; /* elf section alignment */
160 int sh_entsize; /* elf entry size */
161 unsigned long sh_size; /* section size (only used during output) */
162 unsigned long sh_addr; /* address at which the section is relocated */
163 unsigned long sh_offset; /* address at which the section is relocated */
164 int nb_hashed_syms; /* used to resize the hash table */
165 struct Section *link; /* link to another section */
166 struct Section *reloc; /* corresponding section for relocation, if any */
167 struct Section *hash; /* hash table for symbols */
168 struct Section *next;
169 char name[64]; /* section name */
170 } Section;
172 typedef struct DLLReference {
173 int level;
174 char name[1];
175 } DLLReference;
177 /* GNUC attribute definition */
178 typedef struct AttributeDef {
179 int aligned;
180 Section *section;
181 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
182 } AttributeDef;
184 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
185 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
186 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
188 /* stored in 'Sym.c' field */
189 #define FUNC_NEW 1 /* ansi function prototype */
190 #define FUNC_OLD 2 /* old function prototype */
191 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
193 /* stored in 'Sym.r' field */
194 #define FUNC_CDECL 0 /* standard c call */
195 #define FUNC_STDCALL 1 /* pascal c call */
197 /* field 'Sym.t' for macros */
198 #define MACRO_OBJ 0 /* object like macro */
199 #define MACRO_FUNC 1 /* function like macro */
201 /* field 'Sym.r' for labels */
202 #define LABEL_FORWARD 1 /* label is forward defined */
204 /* type_decl() types */
205 #define TYPE_ABSTRACT 1 /* type without variable */
206 #define TYPE_DIRECT 2 /* type with variable */
208 #define IO_BUF_SIZE 8192
210 typedef struct BufferedFile {
211 unsigned char *buf_ptr;
212 unsigned char *buf_end;
213 int fd;
214 int line_num; /* current line number - here to simply code */
215 int ifndef_macro; /*'#ifndef macro \n #define macro' search */
216 int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
217 char inc_type; /* type of include */
218 char inc_filename[512]; /* filename specified by the user */
219 char filename[1024]; /* current filename - here to simplify code */
220 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
221 } BufferedFile;
223 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
224 #define CH_EOF (-1) /* end of file */
226 /* parsing state (used to save parser state to reparse part of the
227 source several times) */
228 typedef struct ParseState {
229 int *macro_ptr;
230 int line_num;
231 int tok;
232 CValue tokc;
233 } ParseState;
235 /* used to record tokens */
236 typedef struct TokenString {
237 int *str;
238 int len;
239 int last_line_num;
240 } TokenString;
242 /* include file cache, used to find files faster and also to eliminate
243 inclusion if the include file is protected by #ifndef ... #endif */
244 typedef struct CachedInclude {
245 int ifndef_macro;
246 char type; /* '"' or '>' to give include type */
247 char filename[1]; /* path specified in #include */
248 } CachedInclude;
250 /* parser */
251 struct BufferedFile *file;
252 int ch, ch1, tok, tok1;
253 CValue tokc, tok1c;
254 CString tokcstr; /* current parsed string, if any */
255 /* if true, line feed is returned as a token. line feed is also
256 returned at eof */
257 int return_linefeed;
258 /* set to TRUE if eof was reached */
259 int eof_seen;
260 Section *text_section, *data_section, *bss_section; /* predefined sections */
261 Section *cur_text_section; /* current section where function code is
262 generated */
263 /* bound check related sections */
264 Section *bounds_section; /* contains global data bound description */
265 Section *lbounds_section; /* contains local data bound description */
266 /* symbol sections */
267 Section *symtab_section, *strtab_section;
269 /* debug sections */
270 Section *stab_section, *stabstr_section;
272 /* loc : local variable index
273 ind : output code index
274 rsym: return symbol
275 anon_sym: anonymous symbol index
277 int rsym, anon_sym,
278 prog, ind, loc;
279 /* expression generation modifiers */
280 int const_wanted; /* true if constant wanted */
281 int nocode_wanted; /* true if no code generation wanted for an expression */
282 int global_expr; /* true if compound literals must be allocated
283 globally (used during initializers parsing */
284 CType func_vt; /* current function return type (used by return
285 instruction) */
286 int func_vc;
287 int last_line_num, last_ind, func_ind; /* debug last line number and pc */
288 int tok_ident;
289 TokenSym **table_ident;
290 TokenSym *hash_ident[TOK_HASH_SIZE];
291 char token_buf[STRING_MAX_SIZE + 1];
292 char *funcname;
293 Sym *global_stack, *local_stack;
294 Sym *define_stack;
295 Sym *label_stack;
297 SValue vstack[VSTACK_SIZE], *vtop;
298 int *macro_ptr, *macro_ptr_allocated;
299 /* some predefined types */
300 CType char_pointer_type, func_old_type, int_type;
302 /* compile with debug symbol (and use them if error during execution) */
303 int do_debug = 0;
305 /* compile with built-in memory and bounds checker */
306 int do_bounds_check = 0;
308 /* display benchmark infos */
309 int do_bench = 0;
310 int total_lines;
311 int total_bytes;
313 /* use GNU C extensions */
314 int gnu_ext = 1;
316 /* use Tiny C extensions */
317 int tcc_ext = 1;
319 /* max number of callers shown if error */
320 static int num_callers = 6;
321 static const char **rt_bound_error_msg;
323 /* XXX: suppress that ASAP */
324 static struct TCCState *tcc_state;
326 /* give the path of the tcc libraries */
327 static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc";
329 struct TCCState {
330 int output_type;
332 BufferedFile **include_stack_ptr;
333 int *ifdef_stack_ptr;
335 /* include file handling */
336 char **include_paths;
337 int nb_include_paths;
338 char **sysinclude_paths;
339 int nb_sysinclude_paths;
340 CachedInclude **cached_includes;
341 int nb_cached_includes;
343 char **library_paths;
344 int nb_library_paths;
346 /* array of all loaded dlls (including those referenced by loaded
347 dlls) */
348 DLLReference **loaded_dlls;
349 int nb_loaded_dlls;
351 /* sections */
352 Section **sections;
353 int nb_sections; /* number of sections, including first dummy section */
355 /* got handling */
356 Section *got;
357 unsigned long *got_offsets;
358 int nb_got_offsets;
359 int nb_plt_entries;
360 /* give the correspondance from symtab indexes to dynsym indexes */
361 int *symtab_to_dynsym;
363 /* temporary dynamic symbol sections (for dll loading) */
364 Section *dynsymtab_section;
365 /* exported dynamic symbol section */
366 Section *dynsym;
368 /* if true, static linking is performed */
369 int static_link;
371 /* error handling */
372 void *error_opaque;
373 void (*error_func)(void *opaque, const char *msg);
374 int error_set_jmp_enabled;
375 jmp_buf error_jmp_buf;
376 int nb_errors;
378 /* see include_stack_ptr */
379 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
381 /* see ifdef_stack_ptr */
382 int ifdef_stack[IFDEF_STACK_SIZE];
385 /* The current value can be: */
386 #define VT_VALMASK 0x00ff
387 #define VT_CONST 0x00f0 /* constant in vc
388 (must be first non register value) */
389 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
390 #define VT_LOCAL 0x00f2 /* offset on stack */
391 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
392 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
393 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
394 #define VT_LVAL 0x0100 /* var is an lvalue */
395 #define VT_SYM 0x0200 /* a symbol value is added */
396 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
397 char/short stored in integer registers) */
398 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
399 dereferencing value */
400 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
401 bounding function call point is in vc */
402 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
403 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
404 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
405 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
407 /* types */
408 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
410 #define VT_INT 0 /* integer type */
411 #define VT_BYTE 1 /* signed byte type */
412 #define VT_SHORT 2 /* short type */
413 #define VT_VOID 3 /* void type */
414 #define VT_PTR 4 /* pointer */
415 #define VT_ENUM 5 /* enum definition */
416 #define VT_FUNC 6 /* function type */
417 #define VT_STRUCT 7 /* struct/union definition */
418 #define VT_FLOAT 8 /* IEEE float */
419 #define VT_DOUBLE 9 /* IEEE double */
420 #define VT_LDOUBLE 10 /* IEEE long double */
421 #define VT_BOOL 11 /* ISOC99 boolean type */
422 #define VT_LLONG 12 /* 64 bit integer */
423 #define VT_LONG 13 /* long integer (NEVER USED as type, only
424 during parsing) */
425 #define VT_BTYPE 0x000f /* mask for basic type */
426 #define VT_UNSIGNED 0x0010 /* unsigned type */
427 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
428 #define VT_BITFIELD 0x0040 /* bitfield modifier */
430 /* storage */
431 #define VT_EXTERN 0x00000080 /* extern definition */
432 #define VT_STATIC 0x00000100 /* static variable */
433 #define VT_TYPEDEF 0x00000200 /* typedef definition */
435 /* type mask (except storage) */
436 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
438 /* token values */
440 /* warning: the following compare tokens depend on i386 asm code */
441 #define TOK_ULT 0x92
442 #define TOK_UGE 0x93
443 #define TOK_EQ 0x94
444 #define TOK_NE 0x95
445 #define TOK_ULE 0x96
446 #define TOK_UGT 0x97
447 #define TOK_LT 0x9c
448 #define TOK_GE 0x9d
449 #define TOK_LE 0x9e
450 #define TOK_GT 0x9f
452 #define TOK_LAND 0xa0
453 #define TOK_LOR 0xa1
455 #define TOK_DEC 0xa2
456 #define TOK_MID 0xa3 /* inc/dec, to void constant */
457 #define TOK_INC 0xa4
458 #define TOK_UDIV 0xb0 /* unsigned division */
459 #define TOK_UMOD 0xb1 /* unsigned modulo */
460 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
461 #define TOK_CINT 0xb3 /* number in tokc */
462 #define TOK_CCHAR 0xb4 /* char constant in tokc */
463 #define TOK_STR 0xb5 /* pointer to string in tokc */
464 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
465 #define TOK_LCHAR 0xb7
466 #define TOK_LSTR 0xb8
467 #define TOK_CFLOAT 0xb9 /* float constant */
468 #define TOK_LINENUM 0xba /* line number info */
469 #define TOK_CDOUBLE 0xc0 /* double constant */
470 #define TOK_CLDOUBLE 0xc1 /* long double constant */
471 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
472 #define TOK_ADDC1 0xc3 /* add with carry generation */
473 #define TOK_ADDC2 0xc4 /* add with carry use */
474 #define TOK_SUBC1 0xc5 /* add with carry generation */
475 #define TOK_SUBC2 0xc6 /* add with carry use */
476 #define TOK_CUINT 0xc8 /* unsigned int constant */
477 #define TOK_CLLONG 0xc9 /* long long constant */
478 #define TOK_CULLONG 0xca /* unsigned long long constant */
479 #define TOK_ARROW 0xcb
480 #define TOK_DOTS 0xcc /* three dots */
481 #define TOK_SHR 0xcd /* unsigned shift right */
482 #define TOK_PPNUM 0xce /* preprocessor number */
484 #define TOK_SHL 0x01 /* shift left */
485 #define TOK_SAR 0x02 /* signed shift right */
487 /* assignement operators : normal operator or 0x80 */
488 #define TOK_A_MOD 0xa5
489 #define TOK_A_AND 0xa6
490 #define TOK_A_MUL 0xaa
491 #define TOK_A_ADD 0xab
492 #define TOK_A_SUB 0xad
493 #define TOK_A_DIV 0xaf
494 #define TOK_A_XOR 0xde
495 #define TOK_A_OR 0xfc
496 #define TOK_A_SHL 0x81
497 #define TOK_A_SAR 0x82
499 /* WARNING: the content of this string encodes token numbers */
500 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";
502 #define TOK_EOF (-1) /* end of file */
503 #define TOK_LINEFEED 10 /* line feed */
505 /* all identificators and strings have token above that */
506 #define TOK_IDENT 256
508 enum {
509 TOK_LAST = TOK_IDENT - 1,
510 #define DEF(id, str) id,
511 #include "tcctok.h"
512 #undef DEF
515 static const char *tcc_keywords =
516 #define DEF(id, str) str "\0"
517 #include "tcctok.h"
518 #undef DEF
521 #define TOK_UIDENT TOK_DEFINE
523 #ifdef WIN32
524 #define snprintf _snprintf
525 #define vsnprintf _vsnprintf
526 #endif
528 #if defined(WIN32) || defined(TCC_UCLIBC)
529 /* currently incorrect */
530 long double strtold(const char *nptr, char **endptr)
532 return (long double)strtod(nptr, endptr);
534 float strtof(const char *nptr, char **endptr)
536 return (float)strtod(nptr, endptr);
538 #else
539 /* XXX: need to define this to use them in non ISOC99 context */
540 extern float strtof (const char *__nptr, char **__endptr);
541 extern long double strtold (const char *__nptr, char **__endptr);
542 #endif
544 static char *pstrcpy(char *buf, int buf_size, const char *s);
545 static char *pstrcat(char *buf, int buf_size, const char *s);
547 static void sum(int l);
548 static void next(void);
549 static void next_nomacro(void);
550 static void parse_expr_type(CType *type);
551 static void expr_type(CType *type);
552 static void unary_type(CType *type);
553 static int expr_const(void);
554 static void expr_eq(void);
555 static void gexpr(void);
556 static void decl(int l);
557 static void decl_initializer(CType *type, Section *sec, unsigned long c,
558 int first, int size_only);
559 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
560 int has_init, int v, int scope);
561 int gv(int rc);
562 void gv2(int rc1, int rc2);
563 void move_reg(int r, int s);
564 void save_regs(int n);
565 void save_reg(int r);
566 void vpop(void);
567 void vswap(void);
568 void vdup(void);
569 int get_reg(int rc);
571 static void macro_subst(TokenString *tok_str,
572 Sym **nested_list, int *macro_str);
573 int save_reg_forced(int r);
574 void gen_op(int op);
575 void force_charshort_cast(int t);
576 static void gen_cast(CType *type);
577 void vstore(void);
578 static Sym *sym_find(int v);
579 static Sym *sym_push(int v, CType *type, int r, int c);
581 /* type handling */
582 int type_size(CType *type, int *a);
583 static inline CType *pointed_type(CType *type);
584 static int pointed_size(CType *type);
585 static int lvalue_type(int t);
586 static int is_compatible_types(CType *type1, CType *type2);
587 static int parse_btype(CType *type, AttributeDef *ad);
588 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
590 void error(const char *fmt, ...);
591 void vpushi(int v);
592 void vset(CType *type, int r, int v);
593 void type_to_str(char *buf, int buf_size,
594 CType *type, const char *varstr);
595 char *get_tok_str(int v, CValue *cv);
596 static Sym *get_sym_ref(CType *type, Section *sec,
597 unsigned long offset, unsigned long size);
598 static Sym *external_global_sym(int v, CType *type, int r);
600 /* section generation */
601 static void section_realloc(Section *sec, unsigned long new_size);
602 static void *section_ptr_add(Section *sec, unsigned long size);
603 static void put_extern_sym(Sym *sym, Section *section,
604 unsigned long value, unsigned long size);
605 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
606 static int put_elf_str(Section *s, const char *sym);
607 static int put_elf_sym(Section *s,
608 unsigned long value, unsigned long size,
609 int info, int other, int shndx, const char *name);
610 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
611 int info, int sh_num, const char *name);
612 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
613 int type, int symbol);
614 static void put_stabs(const char *str, int type, int other, int desc,
615 unsigned long value);
616 static void put_stabs_r(const char *str, int type, int other, int desc,
617 unsigned long value, Section *sec, int sym_index);
618 static void put_stabn(int type, int other, int desc, int value);
619 static void put_stabd(int type, int other, int desc);
620 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
622 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
623 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
624 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
626 /* true if float/double/long double type */
627 static inline int is_float(int t)
629 int bt;
630 bt = t & VT_BTYPE;
631 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
634 #ifdef TCC_TARGET_I386
635 #include "i386-gen.c"
636 #endif
637 #ifdef TCC_TARGET_IL
638 #include "il-gen.c"
639 #endif
641 #ifdef CONFIG_TCC_STATIC
643 #define RTLD_LAZY 0x001
644 #define RTLD_NOW 0x002
645 #define RTLD_GLOBAL 0x100
646 #define RTLD_DEFAULT NULL
648 /* dummy function for profiling */
649 void *dlopen(const char *filename, int flag)
651 return NULL;
654 const char *dlerror(void)
656 return "error";
659 typedef struct TCCSyms {
660 char *str;
661 void *ptr;
662 } TCCSyms;
664 #define TCCSYM(a) { #a, &a, },
666 /* add the symbol you want here if no dynamic linking is done */
667 static TCCSyms tcc_syms[] = {
668 TCCSYM(printf)
669 TCCSYM(fprintf)
670 TCCSYM(fopen)
671 TCCSYM(fclose)
672 { NULL, NULL },
675 void *dlsym(void *handle, const char *symbol)
677 TCCSyms *p;
678 p = tcc_syms;
679 while (p->str != NULL) {
680 if (!strcmp(p->str, symbol))
681 return p->ptr;
682 p++;
684 return NULL;
687 #endif
689 /********************************************************/
691 /* we use our own 'finite' function to avoid potential problems with
692 non standard math libs */
693 /* XXX: endianness dependant */
694 int ieee_finite(double d)
696 int *p = (int *)&d;
697 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
700 /* copy a string and truncate it. */
701 static char *pstrcpy(char *buf, int buf_size, const char *s)
703 char *q, *q_end;
704 int c;
706 if (buf_size > 0) {
707 q = buf;
708 q_end = buf + buf_size - 1;
709 while (q < q_end) {
710 c = *s++;
711 if (c == '\0')
712 break;
713 *q++ = c;
715 *q = '\0';
717 return buf;
720 /* strcat and truncate. */
721 static char *pstrcat(char *buf, int buf_size, const char *s)
723 int len;
724 len = strlen(buf);
725 if (len < buf_size)
726 pstrcpy(buf + len, buf_size - len, s);
727 return buf;
730 /* memory management */
731 #ifdef MEM_DEBUG
732 int mem_cur_size;
733 int mem_max_size;
734 #endif
736 static inline void tcc_free(void *ptr)
738 #ifdef MEM_DEBUG
739 mem_cur_size -= malloc_usable_size(ptr);
740 #endif
741 free(ptr);
744 static void *tcc_malloc(unsigned long size)
746 void *ptr;
747 ptr = malloc(size);
748 if (!ptr && size)
749 error("memory full");
750 #ifdef MEM_DEBUG
751 mem_cur_size += malloc_usable_size(ptr);
752 if (mem_cur_size > mem_max_size)
753 mem_max_size = mem_cur_size;
754 #endif
755 return ptr;
758 static void *tcc_mallocz(unsigned long size)
760 void *ptr;
761 ptr = tcc_malloc(size);
762 memset(ptr, 0, size);
763 return ptr;
766 static inline void *tcc_realloc(void *ptr, unsigned long size)
768 void *ptr1;
769 #ifdef MEM_DEBUG
770 mem_cur_size -= malloc_usable_size(ptr);
771 #endif
772 ptr1 = realloc(ptr, size);
773 #ifdef MEM_DEBUG
774 /* NOTE: count not correct if alloc error, but not critical */
775 mem_cur_size += malloc_usable_size(ptr1);
776 if (mem_cur_size > mem_max_size)
777 mem_max_size = mem_cur_size;
778 #endif
779 return ptr1;
782 static char *tcc_strdup(const char *str)
784 char *ptr;
785 ptr = tcc_malloc(strlen(str) + 1);
786 strcpy(ptr, str);
787 return ptr;
790 #define free(p) use_tcc_free(p)
791 #define malloc(s) use_tcc_malloc(s)
792 #define realloc(p, s) use_tcc_realloc(p, s)
794 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
796 int nb, nb_alloc;
797 void **pp;
799 nb = *nb_ptr;
800 pp = *ptab;
801 /* every power of two we double array size */
802 if ((nb & (nb - 1)) == 0) {
803 if (!nb)
804 nb_alloc = 1;
805 else
806 nb_alloc = nb * 2;
807 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
808 if (!pp)
809 error("memory full");
810 *ptab = pp;
812 pp[nb++] = data;
813 *nb_ptr = nb;
816 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
818 Section *sec;
820 sec = tcc_mallocz(sizeof(Section));
821 pstrcpy(sec->name, sizeof(sec->name), name);
822 sec->sh_type = sh_type;
823 sec->sh_flags = sh_flags;
824 switch(sh_type) {
825 case SHT_HASH:
826 case SHT_REL:
827 case SHT_DYNSYM:
828 case SHT_SYMTAB:
829 case SHT_DYNAMIC:
830 sec->sh_addralign = 4;
831 break;
832 case SHT_STRTAB:
833 sec->sh_addralign = 1;
834 break;
835 default:
836 sec->sh_addralign = 32; /* default conservative alignment */
837 break;
840 /* only add section if not private */
841 if (!(sh_flags & SHF_PRIVATE)) {
842 sec->sh_num = s1->nb_sections;
843 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
845 return sec;
848 static void free_section(Section *s)
850 tcc_free(s->data);
851 tcc_free(s);
854 /* realloc section and set its content to zero */
855 static void section_realloc(Section *sec, unsigned long new_size)
857 unsigned long size;
858 unsigned char *data;
860 size = sec->data_allocated;
861 if (size == 0)
862 size = 1;
863 while (size < new_size)
864 size = size * 2;
865 data = tcc_realloc(sec->data, size);
866 if (!data)
867 error("memory full");
868 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
869 sec->data = data;
870 sec->data_allocated = size;
873 /* reserve at least 'size' bytes in section 'sec' from
874 sec->data_offset. */
875 static void *section_ptr_add(Section *sec, unsigned long size)
877 unsigned long offset, offset1;
879 offset = sec->data_offset;
880 offset1 = offset + size;
881 if (offset1 > sec->data_allocated)
882 section_realloc(sec, offset1);
883 sec->data_offset = offset1;
884 return sec->data + offset;
887 /* return a reference to a section, and create it if it does not
888 exists */
889 Section *find_section(TCCState *s1, const char *name)
891 Section *sec;
892 int i;
893 for(i = 1; i < s1->nb_sections; i++) {
894 sec = s1->sections[i];
895 if (!strcmp(name, sec->name))
896 return sec;
898 /* sections are created as PROGBITS */
899 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
902 /* update sym->c so that it points to an external symbol in section
903 'section' with value 'value' */
904 static void put_extern_sym(Sym *sym, Section *section,
905 unsigned long value, unsigned long size)
907 int sym_type, sym_bind, sh_num, info;
908 Elf32_Sym *esym;
909 const char *name;
911 if (section)
912 sh_num = section->sh_num;
913 else
914 sh_num = SHN_UNDEF;
915 if (!sym->c) {
916 if ((sym->type.t & VT_BTYPE) == VT_FUNC)
917 sym_type = STT_FUNC;
918 else
919 sym_type = STT_OBJECT;
920 if (sym->type.t & VT_STATIC)
921 sym_bind = STB_LOCAL;
922 else
923 sym_bind = STB_GLOBAL;
925 name = get_tok_str(sym->v, NULL);
926 #ifdef CONFIG_TCC_BCHECK
927 if (do_bounds_check) {
928 char buf[32];
930 /* XXX: avoid doing that for statics ? */
931 /* if bound checking is activated, we change some function
932 names by adding the "__bound" prefix */
933 switch(sym->v) {
934 #if 0
935 /* XXX: we rely only on malloc hooks */
936 case TOK_malloc:
937 case TOK_free:
938 case TOK_realloc:
939 case TOK_memalign:
940 case TOK_calloc:
941 #endif
942 case TOK_memcpy:
943 case TOK_memmove:
944 case TOK_memset:
945 case TOK_strlen:
946 case TOK_strcpy:
947 strcpy(buf, "__bound_");
948 strcat(buf, name);
949 name = buf;
950 break;
953 #endif
954 info = ELF32_ST_INFO(sym_bind, sym_type);
955 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
956 } else {
957 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
958 esym->st_value = value;
959 esym->st_size = size;
960 esym->st_shndx = sh_num;
964 /* add a new relocation entry to symbol 'sym' in section 's' */
965 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
967 if (!sym->c)
968 put_extern_sym(sym, NULL, 0, 0);
969 /* now we can add ELF relocation info */
970 put_elf_reloc(symtab_section, s, offset, type, sym->c);
973 static inline int isid(int c)
975 return (c >= 'a' && c <= 'z') ||
976 (c >= 'A' && c <= 'Z') ||
977 c == '_';
980 static inline int isnum(int c)
982 return c >= '0' && c <= '9';
985 static inline int isoct(int c)
987 return c >= '0' && c <= '7';
990 static inline int toup(int c)
992 if (c >= 'a' && c <= 'z')
993 return c - 'a' + 'A';
994 else
995 return c;
998 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
1000 int len;
1001 len = strlen(buf);
1002 vsnprintf(buf + len, buf_size - len, fmt, ap);
1005 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
1007 va_list ap;
1008 va_start(ap, fmt);
1009 strcat_vprintf(buf, buf_size, fmt, ap);
1010 va_end(ap);
1013 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
1015 char buf[2048];
1016 BufferedFile **f;
1018 buf[0] = '\0';
1019 if (file) {
1020 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1021 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1022 (*f)->filename, (*f)->line_num);
1023 if (file->line_num > 0) {
1024 strcat_printf(buf, sizeof(buf),
1025 "%s:%d: ", file->filename, file->line_num);
1026 } else {
1027 strcat_printf(buf, sizeof(buf),
1028 "%s: ", file->filename);
1030 } else {
1031 strcat_printf(buf, sizeof(buf),
1032 "tcc: ");
1034 if (is_warning)
1035 strcat_printf(buf, sizeof(buf), "warning: ");
1036 strcat_vprintf(buf, sizeof(buf), fmt, ap);
1038 if (!s1->error_func) {
1039 /* default case: stderr */
1040 fprintf(stderr, "%s\n", buf);
1041 } else {
1042 s1->error_func(s1->error_opaque, buf);
1044 if (!is_warning)
1045 s1->nb_errors++;
1048 #ifdef LIBTCC
1049 void tcc_set_error_func(TCCState *s, void *error_opaque,
1050 void (*error_func)(void *opaque, const char *msg))
1052 s->error_opaque = error_opaque;
1053 s->error_func = error_func;
1055 #endif
1057 /* error without aborting current compilation */
1058 void error_noabort(const char *fmt, ...)
1060 TCCState *s1 = tcc_state;
1061 va_list ap;
1063 va_start(ap, fmt);
1064 error1(s1, 0, fmt, ap);
1065 va_end(ap);
1068 void error(const char *fmt, ...)
1070 TCCState *s1 = tcc_state;
1071 va_list ap;
1073 va_start(ap, fmt);
1074 error1(s1, 0, fmt, ap);
1075 va_end(ap);
1076 /* better than nothing: in some cases, we accept to handle errors */
1077 if (s1->error_set_jmp_enabled) {
1078 longjmp(s1->error_jmp_buf, 1);
1079 } else {
1080 /* XXX: suppress it someday */
1081 exit(1);
1085 void expect(const char *msg)
1087 error("%s expected", msg);
1090 void warning(const char *fmt, ...)
1092 TCCState *s1 = tcc_state;
1093 va_list ap;
1095 va_start(ap, fmt);
1096 error1(s1, 1, fmt, ap);
1097 va_end(ap);
1100 void skip(int c)
1102 if (tok != c)
1103 error("'%c' expected", c);
1104 next();
1107 void test_lvalue(void)
1109 if (!(vtop->r & VT_LVAL))
1110 expect("lvalue");
1113 TokenSym *tok_alloc(const char *str, int len)
1115 TokenSym *ts, **pts, **ptable;
1116 int h, i;
1118 h = 1;
1119 for(i=0;i<len;i++)
1120 h = (h * 263 + ((unsigned char *)str)[i]) & (TOK_HASH_SIZE - 1);
1122 pts = &hash_ident[h];
1123 while (1) {
1124 ts = *pts;
1125 if (!ts)
1126 break;
1127 if (ts->len == len && !memcmp(ts->str, str, len))
1128 return ts;
1129 pts = &(ts->hash_next);
1132 if (tok_ident >= SYM_FIRST_ANOM)
1133 error("memory full");
1135 /* expand token table if needed */
1136 i = tok_ident - TOK_IDENT;
1137 if ((i % TOK_ALLOC_INCR) == 0) {
1138 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1139 if (!ptable)
1140 error("memory full");
1141 table_ident = ptable;
1144 ts = tcc_malloc(sizeof(TokenSym) + len);
1145 table_ident[i] = ts;
1146 ts->tok = tok_ident++;
1147 ts->sym_define = NULL;
1148 ts->sym_label = NULL;
1149 ts->sym_struct = NULL;
1150 ts->sym_identifier = NULL;
1151 ts->len = len;
1152 ts->hash_next = NULL;
1153 memcpy(ts->str, str, len);
1154 ts->str[len] = '\0';
1155 *pts = ts;
1156 return ts;
1159 /* CString handling */
1161 static void cstr_realloc(CString *cstr, int new_size)
1163 int size;
1164 void *data;
1166 size = cstr->size_allocated;
1167 if (size == 0)
1168 size = 8; /* no need to allocate a too small first string */
1169 while (size < new_size)
1170 size = size * 2;
1171 data = tcc_realloc(cstr->data_allocated, size);
1172 if (!data)
1173 error("memory full");
1174 cstr->data_allocated = data;
1175 cstr->size_allocated = size;
1176 cstr->data = data;
1179 /* add a byte */
1180 static void cstr_ccat(CString *cstr, int ch)
1182 int size;
1183 size = cstr->size + 1;
1184 if (size > cstr->size_allocated)
1185 cstr_realloc(cstr, size);
1186 ((unsigned char *)cstr->data)[size - 1] = ch;
1187 cstr->size = size;
1190 static void cstr_cat(CString *cstr, const char *str)
1192 int c;
1193 for(;;) {
1194 c = *str;
1195 if (c == '\0')
1196 break;
1197 cstr_ccat(cstr, c);
1198 str++;
1202 /* add a wide char */
1203 static void cstr_wccat(CString *cstr, int ch)
1205 int size;
1206 size = cstr->size + sizeof(int);
1207 if (size > cstr->size_allocated)
1208 cstr_realloc(cstr, size);
1209 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1210 cstr->size = size;
1213 static void cstr_new(CString *cstr)
1215 memset(cstr, 0, sizeof(CString));
1218 /* free string and reset it to NULL */
1219 static void cstr_free(CString *cstr)
1221 tcc_free(cstr->data_allocated);
1222 cstr_new(cstr);
1225 #define cstr_reset(cstr) cstr_free(cstr)
1227 /* XXX: unicode ? */
1228 static void add_char(CString *cstr, int c)
1230 if (c == '\'' || c == '\"' || c == '\\') {
1231 /* XXX: could be more precise if char or string */
1232 cstr_ccat(cstr, '\\');
1234 if (c >= 32 && c <= 126) {
1235 cstr_ccat(cstr, c);
1236 } else {
1237 cstr_ccat(cstr, '\\');
1238 if (c == '\n') {
1239 cstr_ccat(cstr, 'n');
1240 } else {
1241 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1242 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1243 cstr_ccat(cstr, '0' + (c & 7));
1248 /* XXX: buffer overflow */
1249 /* XXX: float tokens */
1250 char *get_tok_str(int v, CValue *cv)
1252 static char buf[STRING_MAX_SIZE + 1];
1253 static CString cstr_buf;
1254 CString *cstr;
1255 unsigned char *q;
1256 char *p;
1257 int i, len;
1259 /* NOTE: to go faster, we give a fixed buffer for small strings */
1260 cstr_reset(&cstr_buf);
1261 cstr_buf.data = buf;
1262 cstr_buf.size_allocated = sizeof(buf);
1263 p = buf;
1265 switch(v) {
1266 case TOK_CINT:
1267 case TOK_CUINT:
1268 /* XXX: not quite exact, but only useful for testing */
1269 sprintf(p, "%u", cv->ui);
1270 break;
1271 case TOK_CLLONG:
1272 case TOK_CULLONG:
1273 /* XXX: not quite exact, but only useful for testing */
1274 sprintf(p, "%Lu", cv->ull);
1275 break;
1276 case TOK_CCHAR:
1277 case TOK_LCHAR:
1278 cstr_ccat(&cstr_buf, '\'');
1279 add_char(&cstr_buf, cv->i);
1280 cstr_ccat(&cstr_buf, '\'');
1281 cstr_ccat(&cstr_buf, '\0');
1282 break;
1283 case TOK_PPNUM:
1284 cstr = cv->cstr;
1285 len = cstr->size - 1;
1286 for(i=0;i<len;i++)
1287 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1288 cstr_ccat(&cstr_buf, '\0');
1289 break;
1290 case TOK_STR:
1291 case TOK_LSTR:
1292 cstr = cv->cstr;
1293 cstr_ccat(&cstr_buf, '\"');
1294 if (v == TOK_STR) {
1295 len = cstr->size - 1;
1296 for(i=0;i<len;i++)
1297 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1298 } else {
1299 len = (cstr->size / sizeof(int)) - 1;
1300 for(i=0;i<len;i++)
1301 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1303 cstr_ccat(&cstr_buf, '\"');
1304 cstr_ccat(&cstr_buf, '\0');
1305 break;
1306 case TOK_LT:
1307 v = '<';
1308 goto addv;
1309 case TOK_GT:
1310 v = '>';
1311 goto addv;
1312 case TOK_A_SHL:
1313 return strcpy(p, "<<=");
1314 case TOK_A_SAR:
1315 return strcpy(p, ">>=");
1316 default:
1317 if (v < TOK_IDENT) {
1318 /* search in two bytes table */
1319 q = tok_two_chars;
1320 while (*q) {
1321 if (q[2] == v) {
1322 *p++ = q[0];
1323 *p++ = q[1];
1324 *p = '\0';
1325 return buf;
1327 q += 3;
1329 addv:
1330 *p++ = v;
1331 *p = '\0';
1332 } else if (v < tok_ident) {
1333 return table_ident[v - TOK_IDENT]->str;
1334 } else if (v >= SYM_FIRST_ANOM) {
1335 /* special name for anonymous symbol */
1336 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1337 } else {
1338 /* should never happen */
1339 return NULL;
1341 break;
1343 return cstr_buf.data;
1346 /* push, without hashing */
1347 static Sym *sym_push2(Sym **ps, int v, int t, int c)
1349 Sym *s;
1350 s = tcc_malloc(sizeof(Sym));
1351 s->v = v;
1352 s->type.t = t;
1353 s->c = c;
1354 s->next = NULL;
1355 /* add in stack */
1356 s->prev = *ps;
1357 *ps = s;
1358 return s;
1361 /* find a symbol and return its associated structure. 's' is the top
1362 of the symbol stack */
1363 static Sym *sym_find2(Sym *s, int v)
1365 while (s) {
1366 if (s->v == v)
1367 return s;
1368 s = s->prev;
1370 return NULL;
1373 /* structure lookup */
1374 static Sym *struct_find(int v)
1376 v -= TOK_IDENT;
1377 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1378 return NULL;
1379 return table_ident[v]->sym_struct;
1382 /* find an identifier */
1383 static inline Sym *sym_find(int v)
1385 v -= TOK_IDENT;
1386 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1387 return NULL;
1388 return table_ident[v]->sym_identifier;
1391 /* push a given symbol on the symbol stack */
1392 static Sym *sym_push(int v, CType *type, int r, int c)
1394 Sym *s, **ps;
1395 TokenSym *ts;
1397 if (local_stack)
1398 ps = &local_stack;
1399 else
1400 ps = &global_stack;
1401 s = sym_push2(ps, v, type->t, c);
1402 s->type.ref = type->ref;
1403 s->r = r;
1404 /* don't record fields or anonymous symbols */
1405 /* XXX: simplify */
1406 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1407 /* record symbol in token array */
1408 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1409 if (v & SYM_STRUCT)
1410 ps = &ts->sym_struct;
1411 else
1412 ps = &ts->sym_identifier;
1413 s->prev_tok = *ps;
1414 *ps = s;
1416 return s;
1419 /* push a global identifier */
1420 static Sym *global_identifier_push(int v, int t, int c)
1422 Sym *s, **ps;
1423 s = sym_push2(&global_stack, v, t, c);
1424 /* don't record anonymous symbol */
1425 if (v < SYM_FIRST_ANOM) {
1426 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1427 /* modify the top most local identifier, so that
1428 sym_identifier will point to 's' when popped */
1429 while (*ps != NULL)
1430 ps = &(*ps)->prev_tok;
1431 s->prev_tok = NULL;
1432 *ps = s;
1434 return s;
1437 /* pop symbols until top reaches 'b' */
1438 static void sym_pop(Sym **ptop, Sym *b)
1440 Sym *s, *ss, **ps;
1441 TokenSym *ts;
1442 int v;
1444 s = *ptop;
1445 while(s != b) {
1446 ss = s->prev;
1447 v = s->v;
1448 /* remove symbol in token array */
1449 /* XXX: simplify */
1450 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1451 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1452 if (v & SYM_STRUCT)
1453 ps = &ts->sym_struct;
1454 else
1455 ps = &ts->sym_identifier;
1456 *ps = s->prev_tok;
1458 tcc_free(s);
1459 s = ss;
1461 *ptop = b;
1464 /* I/O layer */
1466 BufferedFile *tcc_open(TCCState *s1, const char *filename)
1468 int fd;
1469 BufferedFile *bf;
1471 fd = open(filename, O_RDONLY);
1472 if (fd < 0)
1473 return NULL;
1474 bf = tcc_malloc(sizeof(BufferedFile));
1475 if (!bf) {
1476 close(fd);
1477 return NULL;
1479 bf->fd = fd;
1480 bf->buf_ptr = bf->buffer;
1481 bf->buf_end = bf->buffer;
1482 bf->buffer[0] = CH_EOB; /* put eob symbol */
1483 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1484 bf->line_num = 1;
1485 bf->ifndef_macro = 0;
1486 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1487 // printf("opening '%s'\n", filename);
1488 return bf;
1491 void tcc_close(BufferedFile *bf)
1493 total_lines += bf->line_num;
1494 close(bf->fd);
1495 tcc_free(bf);
1498 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1499 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1501 /* fill input buffer and return next char */
1502 int tcc_getc_slow(BufferedFile *bf)
1504 int len;
1505 /* only tries to read if really end of buffer */
1506 if (bf->buf_ptr >= bf->buf_end) {
1507 if (bf->fd != -1) {
1508 len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
1509 if (len < 0)
1510 len = 0;
1511 } else {
1512 len = 0;
1514 total_bytes += len;
1515 bf->buf_ptr = bf->buffer;
1516 bf->buf_end = bf->buffer + len;
1517 *bf->buf_end = CH_EOB;
1519 if (bf->buf_ptr < bf->buf_end) {
1520 return *bf->buf_ptr++;
1521 } else {
1522 bf->buf_ptr = bf->buf_end;
1523 return CH_EOF;
1527 /* no need to put that inline */
1528 void handle_eob(void)
1530 TCCState *s1 = tcc_state;
1532 /* no need to do anything if not at EOB */
1533 if (file->buf_ptr <= file->buf_end)
1534 return;
1536 for(;;) {
1537 ch1 = tcc_getc_slow(file);
1538 if (ch1 != CH_EOF)
1539 return;
1540 eof_seen = 1;
1541 if (return_linefeed) {
1542 ch1 = '\n';
1543 return;
1545 if (s1->include_stack_ptr == s1->include_stack)
1546 return;
1547 /* add end of include file debug info */
1548 if (do_debug) {
1549 put_stabd(N_EINCL, 0, 0);
1551 /* pop include stack */
1552 tcc_close(file);
1553 s1->include_stack_ptr--;
1554 file = *s1->include_stack_ptr;
1558 /* read next char from current input file */
1559 static inline void inp(void)
1561 ch1 = TCC_GETC(file);
1562 /* end of buffer/file handling */
1563 if (ch1 == CH_EOB)
1564 handle_eob();
1565 if (ch1 == '\n')
1566 file->line_num++;
1567 // printf("ch1=%c 0x%x\n", ch1, ch1);
1570 /* handle '\\n' and '\\r\n' */
1571 static void handle_stray(void)
1573 do {
1574 if (ch1 == '\n') {
1575 inp();
1576 } else if (ch1 == '\r') {
1577 inp();
1578 if (ch1 != '\n')
1579 error("invalid character after '\\'");
1580 inp();
1581 } else {
1582 break;
1584 ch = ch1;
1585 inp();
1586 } while (ch == '\\');
1589 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1590 case */
1591 static inline void minp(void)
1593 ch = ch1;
1594 inp();
1595 if (ch == '\\')
1596 handle_stray();
1600 /* same as minp, but also skip comments */
1601 static void cinp(void)
1603 int c;
1605 if (ch1 == '/') {
1606 inp();
1607 if (ch1 == '/') {
1608 /* single line C++ comments */
1609 inp();
1610 while (ch1 != '\n' && ch1 != CH_EOF)
1611 inp();
1612 ch = ' '; /* return space */
1613 } else if (ch1 == '*') {
1614 /* C comments */
1615 inp();
1616 while (ch1 != CH_EOF) {
1617 c = ch1;
1618 inp();
1619 if (c == '*' && ch1 == '/') {
1620 inp();
1621 ch = ' '; /* return space */
1622 break;
1625 } else {
1626 ch = '/';
1628 } else {
1629 minp();
1633 /* space exlcuding newline */
1634 static inline int is_space(int ch)
1636 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1639 static inline void skip_spaces(void)
1641 while (is_space(ch))
1642 cinp();
1645 /* skip block of text until #else, #elif or #endif. skip also pairs of
1646 #if/#endif */
1647 void preprocess_skip(void)
1649 int a;
1650 a = 0;
1651 while (1) {
1652 while (ch != '\n') {
1653 if (ch == CH_EOF)
1654 expect("#endif");
1655 cinp();
1657 cinp();
1658 skip_spaces();
1659 if (ch == '#') {
1660 cinp();
1661 next_nomacro();
1662 if (a == 0 &&
1663 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1664 break;
1665 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1666 a++;
1667 else if (tok == TOK_ENDIF)
1668 a--;
1673 /* ParseState handling */
1675 /* XXX: currently, no include file info is stored. Thus, we cannot display
1676 accurate messages if the function or data definition spans multiple
1677 files */
1679 /* save current parse state in 's' */
1680 void save_parse_state(ParseState *s)
1682 s->line_num = file->line_num;
1683 s->macro_ptr = macro_ptr;
1684 s->tok = tok;
1685 s->tokc = tokc;
1688 /* restore parse state from 's' */
1689 void restore_parse_state(ParseState *s)
1691 file->line_num = s->line_num;
1692 macro_ptr = s->macro_ptr;
1693 tok = s->tok;
1694 tokc = s->tokc;
1697 /* return the number of additionnal 'ints' necessary to store the
1698 token */
1699 static inline int tok_ext_size(int t)
1701 switch(t) {
1702 /* 4 bytes */
1703 case TOK_CINT:
1704 case TOK_CUINT:
1705 case TOK_CCHAR:
1706 case TOK_LCHAR:
1707 case TOK_STR:
1708 case TOK_LSTR:
1709 case TOK_CFLOAT:
1710 case TOK_LINENUM:
1711 case TOK_PPNUM:
1712 return 1;
1713 case TOK_CDOUBLE:
1714 case TOK_CLLONG:
1715 case TOK_CULLONG:
1716 return 2;
1717 case TOK_CLDOUBLE:
1718 return LDOUBLE_SIZE / 4;
1719 default:
1720 return 0;
1724 /* token string handling */
1726 static inline void tok_str_new(TokenString *s)
1728 s->str = NULL;
1729 s->len = 0;
1730 s->last_line_num = -1;
1733 static void tok_str_free(int *str)
1735 const int *p;
1736 CString *cstr;
1737 int t;
1739 p = str;
1740 for(;;) {
1741 t = *p++;
1742 if (t == 0)
1743 break;
1744 if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) {
1745 /* XXX: use a macro to be portable on 64 bit ? */
1746 cstr = (CString *)(*p++);
1747 cstr_free(cstr);
1748 tcc_free(cstr);
1749 } else {
1750 p += tok_ext_size(t);
1753 tcc_free(str);
1756 static void tok_str_add(TokenString *s, int t)
1758 int len, *str;
1760 len = s->len;
1761 str = s->str;
1762 if ((len & 63) == 0) {
1763 str = tcc_realloc(str, (len + 64) * sizeof(int));
1764 if (!str)
1765 return;
1766 s->str = str;
1768 str[len++] = t;
1769 s->len = len;
1772 static void tok_str_add2(TokenString *s, int t, CValue *cv)
1774 int n, i, size;
1775 CString *cstr, *cstr1;
1776 CValue cv1;
1778 tok_str_add(s, t);
1779 if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) {
1780 /* special case: need to duplicate string */
1781 cstr1 = cv->cstr;
1782 cstr = tcc_malloc(sizeof(CString));
1783 size = cstr1->size;
1784 cstr->size = size;
1785 cstr->size_allocated = size;
1786 cstr->data_allocated = tcc_malloc(size);
1787 cstr->data = cstr->data_allocated;
1788 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1789 cv1.cstr = cstr;
1790 tok_str_add(s, cv1.tab[0]);
1791 } else {
1792 n = tok_ext_size(t);
1793 for(i=0;i<n;i++)
1794 tok_str_add(s, cv->tab[i]);
1798 /* add the current parse token in token string 's' */
1799 static void tok_str_add_tok(TokenString *s)
1801 CValue cval;
1803 /* save line number info */
1804 if (file->line_num != s->last_line_num) {
1805 s->last_line_num = file->line_num;
1806 cval.i = s->last_line_num;
1807 tok_str_add2(s, TOK_LINENUM, &cval);
1809 tok_str_add2(s, tok, &tokc);
1812 /* get a token from an integer array and increment pointer accordingly */
1813 static int tok_get(int **tok_str, CValue *cv)
1815 int *p, t, n, i;
1817 p = *tok_str;
1818 t = *p++;
1819 n = tok_ext_size(t);
1820 for(i=0;i<n;i++)
1821 cv->tab[i] = *p++;
1822 *tok_str = p;
1823 return t;
1826 /* defines handling */
1827 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
1829 Sym *s;
1831 s = sym_push2(&define_stack, v, macro_type, (int)str);
1832 s->next = first_arg;
1833 table_ident[v - TOK_IDENT]->sym_define = s;
1836 /* undefined a define symbol. Its name is just set to zero */
1837 static void define_undef(Sym *s)
1839 int v;
1840 v = s->v;
1841 if (v >= TOK_IDENT && v < tok_ident)
1842 table_ident[v - TOK_IDENT]->sym_define = NULL;
1843 s->v = 0;
1846 static inline Sym *define_find(int v)
1848 v -= TOK_IDENT;
1849 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1850 return NULL;
1851 return table_ident[v]->sym_define;
1854 /* free define stack until top reaches 'b' */
1855 static void free_defines(Sym *b)
1857 Sym *top, *top1;
1858 int v;
1860 top = define_stack;
1861 while (top != b) {
1862 top1 = top->prev;
1863 /* do not free args or predefined defines */
1864 if (top->c)
1865 tok_str_free((int *)top->c);
1866 v = top->v;
1867 if (v >= TOK_IDENT && v < tok_ident)
1868 table_ident[v - TOK_IDENT]->sym_define = NULL;
1869 tcc_free(top);
1870 top = top1;
1872 define_stack = b;
1875 /* label lookup */
1876 static Sym *label_find(int v)
1878 v -= TOK_IDENT;
1879 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1880 return NULL;
1881 return table_ident[v]->sym_label;
1884 static Sym *label_push(int v, int flags)
1886 Sym *s;
1887 s = sym_push2(&label_stack, v, 0, 0);
1888 s->r = flags;
1889 table_ident[v - TOK_IDENT]->sym_label = s;
1890 return s;
1893 /* eval an expression for #if/#elif */
1894 int expr_preprocess(void)
1896 int c, t;
1897 TokenString str;
1899 tok_str_new(&str);
1900 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1901 next(); /* do macro subst */
1902 if (tok == TOK_DEFINED) {
1903 next_nomacro();
1904 t = tok;
1905 if (t == '(')
1906 next_nomacro();
1907 c = define_find(tok) != 0;
1908 if (t == '(')
1909 next_nomacro();
1910 tok = TOK_CINT;
1911 tokc.i = c;
1912 } else if (tok >= TOK_IDENT) {
1913 /* if undefined macro */
1914 tok = TOK_CINT;
1915 tokc.i = 0;
1917 tok_str_add_tok(&str);
1919 tok_str_add(&str, -1); /* simulate end of file */
1920 tok_str_add(&str, 0);
1921 /* now evaluate C constant expression */
1922 macro_ptr = str.str;
1923 next();
1924 c = expr_const();
1925 macro_ptr = NULL;
1926 tok_str_free(str.str);
1927 return c != 0;
1930 #if defined(DEBUG) || defined(PP_DEBUG)
1931 void tok_print(int *str)
1933 int t;
1934 CValue cval;
1936 while (1) {
1937 t = tok_get(&str, &cval);
1938 if (!t)
1939 break;
1940 printf(" %s", get_tok_str(t, &cval));
1942 printf("\n");
1944 #endif
1946 /* parse after #define */
1947 void parse_define(void)
1949 Sym *s, *first, **ps;
1950 int v, t, varg, is_vaargs;
1951 TokenString str;
1953 v = tok;
1954 if (v < TOK_IDENT)
1955 error("invalid macro name '%s'", get_tok_str(tok, &tokc));
1956 /* XXX: should check if same macro (ANSI) */
1957 first = NULL;
1958 t = MACRO_OBJ;
1959 /* '(' must be just after macro definition for MACRO_FUNC */
1960 if (ch == '(') {
1961 next_nomacro();
1962 next_nomacro();
1963 ps = &first;
1964 while (tok != ')') {
1965 varg = tok;
1966 next_nomacro();
1967 is_vaargs = 0;
1968 if (varg == TOK_DOTS) {
1969 varg = TOK___VA_ARGS__;
1970 is_vaargs = 1;
1971 } else if (tok == TOK_DOTS && gnu_ext) {
1972 is_vaargs = 1;
1973 next_nomacro();
1975 if (varg < TOK_IDENT)
1976 error("badly punctuated parameter list");
1977 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
1978 *ps = s;
1979 ps = &s->next;
1980 if (tok != ',')
1981 break;
1982 next_nomacro();
1984 t = MACRO_FUNC;
1986 tok_str_new(&str);
1987 next_nomacro();
1988 /* EOF testing necessary for '-D' handling */
1989 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1990 tok_str_add2(&str, tok, &tokc);
1991 next_nomacro();
1993 tok_str_add(&str, 0);
1994 #ifdef PP_DEBUG
1995 printf("define %s %d: ", get_tok_str(v, NULL), t);
1996 tok_print(str.str);
1997 #endif
1998 define_push(v, t, str.str, first);
2001 /* XXX: use a token or a hash table to accelerate matching ? */
2002 static CachedInclude *search_cached_include(TCCState *s1,
2003 int type, const char *filename)
2005 CachedInclude *e;
2006 int i;
2008 for(i = 0;i < s1->nb_cached_includes; i++) {
2009 e = s1->cached_includes[i];
2010 if (e->type == type && !strcmp(e->filename, filename))
2011 return e;
2013 return NULL;
2016 static inline void add_cached_include(TCCState *s1, int type,
2017 const char *filename, int ifndef_macro)
2019 CachedInclude *e;
2021 if (search_cached_include(s1, type, filename))
2022 return;
2023 #ifdef INC_DEBUG
2024 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
2025 #endif
2026 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
2027 if (!e)
2028 return;
2029 e->type = type;
2030 strcpy(e->filename, filename);
2031 e->ifndef_macro = ifndef_macro;
2032 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
2036 enum IncludeState {
2037 INCLUDE_STATE_NONE = 0,
2038 INCLUDE_STATE_SEEK_IFNDEF,
2041 void preprocess(void)
2043 TCCState *s1 = tcc_state;
2044 int size, i, c, n, line_num;
2045 enum IncludeState state;
2046 char buf[1024], *q, *p;
2047 char buf1[1024];
2048 BufferedFile *f;
2049 Sym *s;
2050 CachedInclude *e;
2052 return_linefeed = 1; /* linefeed will be returned as a
2053 token. EOF is also returned as line feed */
2054 state = INCLUDE_STATE_NONE;
2055 eof_seen = 0;
2056 redo1:
2057 cinp();
2058 next_nomacro();
2059 redo:
2060 switch(tok) {
2061 case TOK_DEFINE:
2062 next_nomacro();
2063 parse_define();
2064 break;
2065 case TOK_UNDEF:
2066 next_nomacro();
2067 s = define_find(tok);
2068 /* undefine symbol by putting an invalid name */
2069 if (s)
2070 define_undef(s);
2071 break;
2072 case TOK_INCLUDE:
2073 skip_spaces();
2074 if (ch == '<') {
2075 c = '>';
2076 goto read_name;
2077 } else if (ch == '\"') {
2078 c = ch;
2079 read_name:
2080 minp();
2081 q = buf;
2082 while (ch != c && ch != '\n' && ch != CH_EOF) {
2083 if ((q - buf) < sizeof(buf) - 1)
2084 *q++ = ch;
2085 minp();
2087 *q = '\0';
2088 /* eat all spaces and comments after include */
2089 /* XXX: slightly incorrect */
2090 while (ch1 != '\n' && ch1 != CH_EOF)
2091 inp();
2092 } else {
2093 /* computed #include : either we have only strings or
2094 we have anything enclosed in '<>' */
2095 next();
2096 buf[0] = '\0';
2097 if (tok == TOK_STR) {
2098 while (tok != TOK_LINEFEED) {
2099 if (tok != TOK_STR) {
2100 include_syntax:
2101 error("'#include' expects \"FILENAME\" or <FILENAME>");
2103 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2104 next();
2106 c = '\"';
2107 } else {
2108 int len;
2109 while (tok != TOK_LINEFEED) {
2110 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2111 next();
2113 len = strlen(buf);
2114 /* check syntax and remove '<>' */
2115 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2116 goto include_syntax;
2117 memmove(buf, buf + 1, len - 2);
2118 buf[len - 2] = '\0';
2119 c = '>';
2123 ch = '\n';
2124 e = search_cached_include(s1, c, buf);
2125 if (e && define_find(e->ifndef_macro)) {
2126 /* no need to parse the include because the 'ifndef macro'
2127 is defined */
2128 #ifdef INC_DEBUG
2129 printf("%s: skipping %s\n", file->filename, buf);
2130 #endif
2131 } else {
2132 if (c == '\"') {
2133 /* first search in current dir if "header.h" */
2134 size = 0;
2135 p = strrchr(file->filename, '/');
2136 if (p)
2137 size = p + 1 - file->filename;
2138 if (size > sizeof(buf1) - 1)
2139 size = sizeof(buf1) - 1;
2140 memcpy(buf1, file->filename, size);
2141 buf1[size] = '\0';
2142 pstrcat(buf1, sizeof(buf1), buf);
2143 f = tcc_open(s1, buf1);
2144 if (f)
2145 goto found;
2147 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2148 error("#include recursion too deep");
2149 /* now search in all the include paths */
2150 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2151 for(i = 0; i < n; i++) {
2152 const char *path;
2153 if (i < s1->nb_include_paths)
2154 path = s1->include_paths[i];
2155 else
2156 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2157 pstrcpy(buf1, sizeof(buf1), path);
2158 pstrcat(buf1, sizeof(buf1), "/");
2159 pstrcat(buf1, sizeof(buf1), buf);
2160 f = tcc_open(s1, buf1);
2161 if (f)
2162 goto found;
2164 error("include file '%s' not found", buf);
2165 f = NULL;
2166 found:
2167 #ifdef INC_DEBUG
2168 printf("%s: including %s\n", file->filename, buf1);
2169 #endif
2170 f->inc_type = c;
2171 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2172 /* push current file in stack */
2173 /* XXX: fix current line init */
2174 *s1->include_stack_ptr++ = file;
2175 file = f;
2176 /* add include file debug info */
2177 if (do_debug) {
2178 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2180 /* we check for the construct: #ifndef IDENT \n #define IDENT */
2181 inp();
2182 /* get first non space char */
2183 while (is_space(ch) || ch == '\n')
2184 cinp();
2185 if (ch != '#')
2186 goto the_end;
2187 state = INCLUDE_STATE_SEEK_IFNDEF;
2188 goto redo1;
2190 break;
2191 case TOK_IFNDEF:
2192 c = 1;
2193 goto do_ifdef;
2194 case TOK_IF:
2195 c = expr_preprocess();
2196 goto do_if;
2197 case TOK_IFDEF:
2198 c = 0;
2199 do_ifdef:
2200 next_nomacro();
2201 if (tok < TOK_IDENT)
2202 error("invalid argument for '#if%sdef'", c ? "n" : "");
2203 if (state == INCLUDE_STATE_SEEK_IFNDEF) {
2204 if (c) {
2205 file->ifndef_macro = tok;
2207 state = INCLUDE_STATE_NONE;
2209 c = (define_find(tok) != 0) ^ c;
2210 do_if:
2211 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2212 error("memory full");
2213 *s1->ifdef_stack_ptr++ = c;
2214 goto test_skip;
2215 case TOK_ELSE:
2216 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2217 error("#else without matching #if");
2218 if (s1->ifdef_stack_ptr[-1] & 2)
2219 error("#else after #else");
2220 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2221 goto test_skip;
2222 case TOK_ELIF:
2223 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2224 error("#elif without matching #if");
2225 c = s1->ifdef_stack_ptr[-1];
2226 if (c > 1)
2227 error("#elif after #else");
2228 /* last #if/#elif expression was true: we skip */
2229 if (c == 1)
2230 goto skip;
2231 c = expr_preprocess();
2232 s1->ifdef_stack_ptr[-1] = c;
2233 test_skip:
2234 if (!(c & 1)) {
2235 skip:
2236 preprocess_skip();
2237 state = INCLUDE_STATE_NONE;
2238 goto redo;
2240 break;
2241 case TOK_ENDIF:
2242 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2243 error("#endif without matching #if");
2244 if (file->ifndef_macro &&
2245 s1->ifdef_stack_ptr == (file->ifdef_stack_ptr + 1)) {
2246 /* '#ifndef macro \n #define macro' was at the start of
2247 file. Now we check if an '#endif' is exactly at the end
2248 of file */
2249 while (tok != TOK_LINEFEED)
2250 next_nomacro();
2251 /* XXX: should also skip comments, but it is more complicated */
2252 if (eof_seen) {
2253 add_cached_include(s1, file->inc_type, file->inc_filename,
2254 file->ifndef_macro);
2255 } else {
2256 /* if not end of file, we must desactivate the ifndef
2257 macro search */
2258 file->ifndef_macro = 0;
2261 s1->ifdef_stack_ptr--;
2262 break;
2263 case TOK_LINE:
2264 next();
2265 if (tok != TOK_CINT)
2266 error("#line");
2267 line_num = tokc.i;
2268 next();
2269 if (tok != TOK_LINEFEED) {
2270 if (tok != TOK_STR)
2271 error("#line");
2272 pstrcpy(file->filename, sizeof(file->filename),
2273 (char *)tokc.cstr->data);
2275 /* NOTE: we do it there to avoid problems with linefeed */
2276 file->line_num = line_num;
2277 break;
2278 case TOK_ERROR:
2279 case TOK_WARNING:
2280 c = tok;
2281 skip_spaces();
2282 q = buf;
2283 while (ch != '\n' && ch != CH_EOF) {
2284 if ((q - buf) < sizeof(buf) - 1)
2285 *q++ = ch;
2286 minp();
2288 *q = '\0';
2289 if (c == TOK_ERROR)
2290 error("#error %s", buf);
2291 else
2292 warning("#warning %s", buf);
2293 break;
2294 default:
2295 if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
2296 /* '!' is ignored to allow C scripts. numbers are ignored
2297 to emulate cpp behaviour */
2298 } else {
2299 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
2301 break;
2303 /* ignore other preprocess commands or #! for C scripts */
2304 while (tok != TOK_LINEFEED && tok != TOK_EOF)
2305 next_nomacro();
2306 the_end:
2307 return_linefeed = 0;
2310 /* read a number in base b */
2311 static int getn(int b)
2313 int n, t;
2314 n = 0;
2315 while (1) {
2316 if (ch >= 'a' && ch <= 'f')
2317 t = ch - 'a' + 10;
2318 else if (ch >= 'A' && ch <= 'F')
2319 t = ch - 'A' + 10;
2320 else if (isnum(ch))
2321 t = ch - '0';
2322 else
2323 break;
2324 if (t < 0 || t >= b)
2325 break;
2326 n = n * b + t;
2327 cinp();
2329 return n;
2332 /* read a character for string or char constant and eval escape codes */
2333 static int getq(void)
2335 int c;
2337 c = ch;
2338 minp();
2339 if (c == '\\') {
2340 if (isoct(ch)) {
2341 /* at most three octal digits */
2342 c = ch - '0';
2343 minp();
2344 if (isoct(ch)) {
2345 c = c * 8 + ch - '0';
2346 minp();
2347 if (isoct(ch)) {
2348 c = c * 8 + ch - '0';
2349 minp();
2352 return c;
2353 } else if (ch == 'x') {
2354 minp();
2355 return getn(16);
2356 } else {
2357 if (ch == 'a')
2358 c = '\a';
2359 else if (ch == 'b')
2360 c = '\b';
2361 else if (ch == 'f')
2362 c = '\f';
2363 else if (ch == 'n')
2364 c = '\n';
2365 else if (ch == 'r')
2366 c = '\r';
2367 else if (ch == 't')
2368 c = '\t';
2369 else if (ch == 'v')
2370 c = '\v';
2371 else if (ch == 'e' && gnu_ext)
2372 c = 27;
2373 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
2374 c = ch;
2375 else
2376 error("invalid escaped char");
2377 minp();
2379 } else if (c == '\r' && ch == '\n') {
2380 minp();
2381 c = '\n';
2383 return c;
2386 /* we use 64 bit numbers */
2387 #define BN_SIZE 2
2389 /* bn = (bn << shift) | or_val */
2390 void bn_lshift(unsigned int *bn, int shift, int or_val)
2392 int i;
2393 unsigned int v;
2394 for(i=0;i<BN_SIZE;i++) {
2395 v = bn[i];
2396 bn[i] = (v << shift) | or_val;
2397 or_val = v >> (32 - shift);
2401 void bn_zero(unsigned int *bn)
2403 int i;
2404 for(i=0;i<BN_SIZE;i++) {
2405 bn[i] = 0;
2409 /* parse number in null terminated string 'p' and return it in the
2410 current token */
2411 void parse_number(const char *p)
2413 int b, t, shift, frac_bits, s, exp_val, ch;
2414 char *q;
2415 unsigned int bn[BN_SIZE];
2416 double d;
2418 /* number */
2419 q = token_buf;
2420 ch = *p++;
2421 t = ch;
2422 ch = *p++;
2423 *q++ = t;
2424 b = 10;
2425 if (t == '.') {
2426 goto float_frac_parse;
2427 } else if (t == '0') {
2428 if (ch == 'x' || ch == 'X') {
2429 q--;
2430 ch = *p++;
2431 b = 16;
2432 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2433 q--;
2434 ch = *p++;
2435 b = 2;
2438 /* parse all digits. cannot check octal numbers at this stage
2439 because of floating point constants */
2440 while (1) {
2441 if (ch >= 'a' && ch <= 'f')
2442 t = ch - 'a' + 10;
2443 else if (ch >= 'A' && ch <= 'F')
2444 t = ch - 'A' + 10;
2445 else if (isnum(ch))
2446 t = ch - '0';
2447 else
2448 break;
2449 if (t >= b)
2450 break;
2451 if (q >= token_buf + STRING_MAX_SIZE) {
2452 num_too_long:
2453 error("number too long");
2455 *q++ = ch;
2456 ch = *p++;
2458 if (ch == '.' ||
2459 ((ch == 'e' || ch == 'E') && b == 10) ||
2460 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2461 if (b != 10) {
2462 /* NOTE: strtox should support that for hexa numbers, but
2463 non ISOC99 libcs do not support it, so we prefer to do
2464 it by hand */
2465 /* hexadecimal or binary floats */
2466 /* XXX: handle overflows */
2467 *q = '\0';
2468 if (b == 16)
2469 shift = 4;
2470 else
2471 shift = 2;
2472 bn_zero(bn);
2473 q = token_buf;
2474 while (1) {
2475 t = *q++;
2476 if (t == '\0') {
2477 break;
2478 } else if (t >= 'a') {
2479 t = t - 'a' + 10;
2480 } else if (t >= 'A') {
2481 t = t - 'A' + 10;
2482 } else {
2483 t = t - '0';
2485 bn_lshift(bn, shift, t);
2487 frac_bits = 0;
2488 if (ch == '.') {
2489 ch = *p++;
2490 while (1) {
2491 t = ch;
2492 if (t >= 'a' && t <= 'f') {
2493 t = t - 'a' + 10;
2494 } else if (t >= 'A' && t <= 'F') {
2495 t = t - 'A' + 10;
2496 } else if (t >= '0' && t <= '9') {
2497 t = t - '0';
2498 } else {
2499 break;
2501 if (t >= b)
2502 error("invalid digit");
2503 bn_lshift(bn, shift, t);
2504 frac_bits += shift;
2505 ch = *p++;
2508 if (ch != 'p' && ch != 'P')
2509 expect("exponent");
2510 ch = *p++;
2511 s = 1;
2512 exp_val = 0;
2513 if (ch == '+') {
2514 ch = *p++;
2515 } else if (ch == '-') {
2516 s = -1;
2517 ch = *p++;
2519 if (ch < '0' || ch > '9')
2520 expect("exponent digits");
2521 while (ch >= '0' && ch <= '9') {
2522 exp_val = exp_val * 10 + ch - '0';
2523 ch = *p++;
2525 exp_val = exp_val * s;
2527 /* now we can generate the number */
2528 /* XXX: should patch directly float number */
2529 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
2530 d = ldexp(d, exp_val - frac_bits);
2531 t = toup(ch);
2532 if (t == 'F') {
2533 ch = *p++;
2534 tok = TOK_CFLOAT;
2535 /* float : should handle overflow */
2536 tokc.f = (float)d;
2537 } else if (t == 'L') {
2538 ch = *p++;
2539 tok = TOK_CLDOUBLE;
2540 /* XXX: not large enough */
2541 tokc.ld = (long double)d;
2542 } else {
2543 tok = TOK_CDOUBLE;
2544 tokc.d = d;
2546 } else {
2547 /* decimal floats */
2548 if (ch == '.') {
2549 if (q >= token_buf + STRING_MAX_SIZE)
2550 goto num_too_long;
2551 *q++ = ch;
2552 ch = *p++;
2553 float_frac_parse:
2554 while (ch >= '0' && ch <= '9') {
2555 if (q >= token_buf + STRING_MAX_SIZE)
2556 goto num_too_long;
2557 *q++ = ch;
2558 ch = *p++;
2561 if (ch == 'e' || ch == 'E') {
2562 if (q >= token_buf + STRING_MAX_SIZE)
2563 goto num_too_long;
2564 *q++ = ch;
2565 ch = *p++;
2566 if (ch == '-' || ch == '+') {
2567 if (q >= token_buf + STRING_MAX_SIZE)
2568 goto num_too_long;
2569 *q++ = ch;
2570 ch = *p++;
2572 if (ch < '0' || ch > '9')
2573 expect("exponent digits");
2574 while (ch >= '0' && ch <= '9') {
2575 if (q >= token_buf + STRING_MAX_SIZE)
2576 goto num_too_long;
2577 *q++ = ch;
2578 ch = *p++;
2581 *q = '\0';
2582 t = toup(ch);
2583 errno = 0;
2584 if (t == 'F') {
2585 ch = *p++;
2586 tok = TOK_CFLOAT;
2587 tokc.f = strtof(token_buf, NULL);
2588 } else if (t == 'L') {
2589 ch = *p++;
2590 tok = TOK_CLDOUBLE;
2591 tokc.ld = strtold(token_buf, NULL);
2592 } else {
2593 tok = TOK_CDOUBLE;
2594 tokc.d = strtod(token_buf, NULL);
2597 } else {
2598 unsigned long long n, n1;
2599 int lcount, ucount;
2601 /* integer number */
2602 *q = '\0';
2603 q = token_buf;
2604 if (b == 10 && *q == '0') {
2605 b = 8;
2606 q++;
2608 n = 0;
2609 while(1) {
2610 t = *q++;
2611 /* no need for checks except for base 10 / 8 errors */
2612 if (t == '\0') {
2613 break;
2614 } else if (t >= 'a') {
2615 t = t - 'a' + 10;
2616 } else if (t >= 'A') {
2617 t = t - 'A' + 10;
2618 } else {
2619 t = t - '0';
2620 if (t >= b)
2621 error("invalid digit");
2623 n1 = n;
2624 n = n * b + t;
2625 /* detect overflow */
2626 /* XXX: this test is not reliable */
2627 if (n < n1)
2628 error("integer constant overflow");
2631 /* XXX: not exactly ANSI compliant */
2632 if ((n & 0xffffffff00000000LL) != 0) {
2633 if ((n >> 63) != 0)
2634 tok = TOK_CULLONG;
2635 else
2636 tok = TOK_CLLONG;
2637 } else if (n > 0x7fffffff) {
2638 tok = TOK_CUINT;
2639 } else {
2640 tok = TOK_CINT;
2642 lcount = 0;
2643 ucount = 0;
2644 for(;;) {
2645 t = toup(ch);
2646 if (t == 'L') {
2647 if (lcount >= 2)
2648 error("three 'l's in integer constant");
2649 lcount++;
2650 if (lcount == 2) {
2651 if (tok == TOK_CINT)
2652 tok = TOK_CLLONG;
2653 else if (tok == TOK_CUINT)
2654 tok = TOK_CULLONG;
2656 ch = *p++;
2657 } else if (t == 'U') {
2658 if (ucount >= 1)
2659 error("two 'u's in integer constant");
2660 ucount++;
2661 if (tok == TOK_CINT)
2662 tok = TOK_CUINT;
2663 else if (tok == TOK_CLLONG)
2664 tok = TOK_CULLONG;
2665 ch = *p++;
2666 } else {
2667 break;
2670 if (tok == TOK_CINT || tok == TOK_CUINT)
2671 tokc.ui = n;
2672 else
2673 tokc.ull = n;
2677 /* return next token without macro substitution */
2678 static inline void next_nomacro1(void)
2680 int b, t;
2681 char *q;
2682 TokenSym *ts;
2684 redo_no_start:
2685 switch(ch) {
2686 case ' ':
2687 case '\t':
2688 case '\f':
2689 case '\v':
2690 case '\r':
2691 cinp();
2692 goto redo_no_start;
2694 case '\n':
2695 if (return_linefeed) {
2696 /* XXX: should eat token ? */
2697 tok = TOK_LINEFEED;
2698 } else {
2699 cinp();
2700 skip_spaces();
2701 if (ch == '#') {
2702 /* preprocessor command if # at start of line after
2703 spaces */
2704 preprocess();
2706 goto redo_no_start;
2708 break;
2710 case '#':
2711 tok = ch;
2712 cinp();
2713 #if 0
2714 if (start_of_line) {
2715 preprocess();
2716 goto redo_no_start;
2717 } else
2718 #endif
2720 if (ch == '#') {
2721 cinp();
2722 tok = TOK_TWOSHARPS;
2725 break;
2727 case 'a': case 'b': case 'c': case 'd':
2728 case 'e': case 'f': case 'g': case 'h':
2729 case 'i': case 'j': case 'k': case 'l':
2730 case 'm': case 'n': case 'o': case 'p':
2731 case 'q': case 'r': case 's': case 't':
2732 case 'u': case 'v': case 'w': case 'x':
2733 case 'y': case 'z':
2734 case 'A': case 'B': case 'C': case 'D':
2735 case 'E': case 'F': case 'G': case 'H':
2736 case 'I': case 'J': case 'K':
2737 case 'M': case 'N': case 'O': case 'P':
2738 case 'Q': case 'R': case 'S': case 'T':
2739 case 'U': case 'V': case 'W': case 'X':
2740 case 'Y': case 'Z':
2741 case '_':
2742 q = token_buf;
2743 *q++ = ch;
2744 cinp();
2745 parse_ident:
2746 while (isid(ch) || isnum(ch)) {
2747 if (q >= token_buf + STRING_MAX_SIZE)
2748 error("ident too long");
2749 *q++ = ch;
2750 cinp();
2752 *q = '\0';
2753 ts = tok_alloc(token_buf, q - token_buf);
2754 tok = ts->tok;
2755 break;
2756 case 'L':
2757 cinp();
2758 if (ch == '\'') {
2759 tok = TOK_LCHAR;
2760 goto char_const;
2762 if (ch == '\"') {
2763 tok = TOK_LSTR;
2764 goto str_const;
2766 q = token_buf;
2767 *q++ = 'L';
2768 goto parse_ident;
2770 case '0': case '1': case '2': case '3':
2771 case '4': case '5': case '6': case '7':
2772 case '8': case '9':
2774 cstr_reset(&tokcstr);
2775 /* after the first digit, accept digits, alpha, '.' or sign if
2776 prefixed by 'eEpP' */
2777 parse_num:
2778 for(;;) {
2779 t = ch;
2780 cstr_ccat(&tokcstr, ch);
2781 cinp();
2782 if (!(isnum(ch) || isid(ch) || ch == '.' ||
2783 ((ch == '+' || ch == '-') &&
2784 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
2785 break;
2787 /* We add a trailing '\0' to ease parsing */
2788 cstr_ccat(&tokcstr, '\0');
2789 tokc.cstr = &tokcstr;
2790 tok = TOK_PPNUM;
2791 break;
2792 case '.':
2793 /* special dot handling because it can also start a number */
2794 cinp();
2795 if (isnum(ch)) {
2796 cstr_reset(&tokcstr);
2797 cstr_ccat(&tokcstr, '.');
2798 goto parse_num;
2800 if (ch == '.') {
2801 cinp();
2802 if (ch != '.')
2803 expect("'.'");
2804 cinp();
2805 tok = TOK_DOTS;
2806 } else {
2807 tok = '.';
2809 break;
2810 case '\'':
2811 tok = TOK_CCHAR;
2812 char_const:
2813 minp();
2814 b = getq();
2815 /* this cast is needed if >= 128 */
2816 if (tok == TOK_CCHAR)
2817 b = (char)b;
2818 tokc.i = b;
2819 if (ch != '\'')
2820 error("unterminated character constant");
2821 minp();
2822 break;
2823 case '\"':
2824 tok = TOK_STR;
2825 str_const:
2826 minp();
2827 cstr_reset(&tokcstr);
2828 while (ch != '\"') {
2829 b = getq();
2830 if (ch == CH_EOF)
2831 error("unterminated string");
2832 if (tok == TOK_STR)
2833 cstr_ccat(&tokcstr, b);
2834 else
2835 cstr_wccat(&tokcstr, b);
2837 if (tok == TOK_STR)
2838 cstr_ccat(&tokcstr, '\0');
2839 else
2840 cstr_wccat(&tokcstr, '\0');
2841 tokc.cstr = &tokcstr;
2842 minp();
2843 break;
2845 case '<':
2846 cinp();
2847 if (ch == '=') {
2848 cinp();
2849 tok = TOK_LE;
2850 } else if (ch == '<') {
2851 cinp();
2852 if (ch == '=') {
2853 cinp();
2854 tok = TOK_A_SHL;
2855 } else {
2856 tok = TOK_SHL;
2858 } else {
2859 tok = TOK_LT;
2861 break;
2863 case '>':
2864 cinp();
2865 if (ch == '=') {
2866 cinp();
2867 tok = TOK_GE;
2868 } else if (ch == '>') {
2869 cinp();
2870 if (ch == '=') {
2871 cinp();
2872 tok = TOK_A_SAR;
2873 } else {
2874 tok = TOK_SAR;
2876 } else {
2877 tok = TOK_GT;
2879 break;
2881 case '!':
2882 tok = ch;
2883 cinp();
2884 if (ch == '=') {
2885 cinp();
2886 tok = TOK_NE;
2888 break;
2890 case '=':
2891 tok = ch;
2892 cinp();
2893 if (ch == '=') {
2894 cinp();
2895 tok = TOK_EQ;
2897 break;
2899 case '&':
2900 tok = ch;
2901 cinp();
2902 if (ch == '&') {
2903 cinp();
2904 tok = TOK_LAND;
2905 } else if (ch == '=') {
2906 cinp();
2907 tok = TOK_A_AND;
2909 break;
2911 case '|':
2912 tok = ch;
2913 cinp();
2914 if (ch == '|') {
2915 cinp();
2916 tok = TOK_LOR;
2917 } else if (ch == '=') {
2918 cinp();
2919 tok = TOK_A_OR;
2921 break;
2923 case '+':
2924 tok = ch;
2925 cinp();
2926 if (ch == '+') {
2927 cinp();
2928 tok = TOK_INC;
2929 } else if (ch == '=') {
2930 cinp();
2931 tok = TOK_A_ADD;
2933 break;
2935 case '-':
2936 tok = ch;
2937 cinp();
2938 if (ch == '-') {
2939 cinp();
2940 tok = TOK_DEC;
2941 } else if (ch == '=') {
2942 cinp();
2943 tok = TOK_A_SUB;
2944 } else if (ch == '>') {
2945 cinp();
2946 tok = TOK_ARROW;
2948 break;
2950 case '*':
2951 tok = ch;
2952 cinp();
2953 if (ch == '=') {
2954 cinp();
2955 tok = TOK_A_MUL;
2957 break;
2959 case '%':
2960 tok = ch;
2961 cinp();
2962 if (ch == '=') {
2963 cinp();
2964 tok = TOK_A_MOD;
2966 break;
2968 case '^':
2969 tok = ch;
2970 cinp();
2971 if (ch == '=') {
2972 cinp();
2973 tok = TOK_A_XOR;
2975 break;
2977 /* comments or operator */
2978 case '/':
2979 tok = ch;
2980 cinp();
2981 if (ch == '=') {
2982 cinp();
2983 tok = TOK_A_DIV;
2985 #if 0
2986 else if (ch == '/' || ch == '*') {
2987 parse_comments();
2988 goto redo_no_start;
2990 #endif
2991 break;
2993 /* simple tokens */
2994 case '(':
2995 case ')':
2996 case '[':
2997 case ']':
2998 case '{':
2999 case '}':
3000 case ',':
3001 case ';':
3002 case ':':
3003 case '?':
3004 case '~':
3005 tok = ch;
3006 cinp();
3007 break;
3008 case CH_EOF:
3009 tok = TOK_EOF;
3010 break;
3011 default:
3012 error("unrecognized character \\x%02x", ch);
3013 break;
3017 /* return next token without macro substitution. Can read input from
3018 macro_ptr buffer */
3019 static void next_nomacro(void)
3021 if (macro_ptr) {
3022 redo:
3023 tok = *macro_ptr;
3024 if (tok) {
3025 tok = tok_get(&macro_ptr, &tokc);
3026 if (tok == TOK_LINENUM) {
3027 file->line_num = tokc.i;
3028 goto redo;
3031 } else {
3032 next_nomacro1();
3036 /* substitute args in macro_str and return allocated string */
3037 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
3039 int *st, last_tok, t, notfirst;
3040 Sym *s;
3041 CValue cval;
3042 TokenString str;
3043 CString cstr;
3045 tok_str_new(&str);
3046 last_tok = 0;
3047 while(1) {
3048 t = tok_get(&macro_str, &cval);
3049 if (!t)
3050 break;
3051 if (t == '#') {
3052 /* stringize */
3053 t = tok_get(&macro_str, &cval);
3054 if (!t)
3055 break;
3056 s = sym_find2(args, t);
3057 if (s) {
3058 cstr_new(&cstr);
3059 st = (int *)s->c;
3060 notfirst = 0;
3061 while (*st) {
3062 if (notfirst)
3063 cstr_ccat(&cstr, ' ');
3064 t = tok_get(&st, &cval);
3065 cstr_cat(&cstr, get_tok_str(t, &cval));
3066 notfirst = 1;
3068 cstr_ccat(&cstr, '\0');
3069 #ifdef PP_DEBUG
3070 printf("stringize: %s\n", (char *)cstr.data);
3071 #endif
3072 /* add string */
3073 cval.cstr = &cstr;
3074 tok_str_add2(&str, TOK_STR, &cval);
3075 cstr_free(&cstr);
3076 } else {
3077 tok_str_add2(&str, t, &cval);
3079 } else if (t >= TOK_IDENT) {
3080 s = sym_find2(args, t);
3081 if (s) {
3082 st = (int *)s->c;
3083 /* if '##' is present before or after, no arg substitution */
3084 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
3085 /* special case for var arg macros : ## eats the
3086 ',' if empty VA_ARGS variable. */
3087 /* XXX: test of the ',' is not 100%
3088 reliable. should fix it to avoid security
3089 problems */
3090 if (gnu_ext && s->type.t &&
3091 last_tok == TOK_TWOSHARPS &&
3092 str.len >= 2 && str.str[str.len - 2] == ',') {
3093 if (*st == 0) {
3094 /* suppress ',' '##' */
3095 str.len -= 2;
3096 } else {
3097 /* suppress '##' and add variable */
3098 str.len--;
3099 goto add_var;
3101 } else {
3102 int t1;
3103 add_var:
3104 for(;;) {
3105 t1 = tok_get(&st, &cval);
3106 if (!t1)
3107 break;
3108 tok_str_add2(&str, t1, &cval);
3111 } else {
3112 macro_subst(&str, nested_list, st);
3114 } else {
3115 tok_str_add(&str, t);
3117 } else {
3118 tok_str_add2(&str, t, &cval);
3120 last_tok = t;
3122 tok_str_add(&str, 0);
3123 return str.str;
3126 /* handle the '##' operator */
3127 static int *macro_twosharps(void)
3129 TokenSym *ts;
3130 int *macro_ptr1;
3131 int t;
3132 const char *p1, *p2;
3133 CValue cval;
3134 TokenString macro_str1;
3135 CString cstr;
3137 cstr_new(&cstr);
3138 tok_str_new(&macro_str1);
3139 tok = 0;
3140 while (1) {
3141 next_nomacro();
3142 if (tok == 0)
3143 break;
3144 while (*macro_ptr == TOK_TWOSHARPS) {
3145 macro_ptr++;
3146 macro_ptr1 = macro_ptr;
3147 t = *macro_ptr;
3148 if (t) {
3149 t = tok_get(&macro_ptr, &cval);
3151 /* We concatenate the two tokens if we have an
3152 identifier or a preprocessing number */
3153 cstr_reset(&cstr);
3154 p1 = get_tok_str(tok, &tokc);
3155 cstr_cat(&cstr, p1);
3156 p2 = get_tok_str(t, &cval);
3157 cstr_cat(&cstr, p2);
3158 cstr_ccat(&cstr, '\0');
3160 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
3161 (t >= TOK_IDENT || t == TOK_PPNUM)) {
3162 if (tok == TOK_PPNUM) {
3163 /* if number, then create a number token */
3164 /* NOTE: no need to allocate because
3165 tok_str_add2() does it */
3166 tokc.cstr = &cstr;
3167 } else {
3168 /* if identifier, we must do a test to
3169 validate we have a correct identifier */
3170 if (t == TOK_PPNUM) {
3171 const char *p;
3172 int c;
3174 p = p2;
3175 for(;;) {
3176 c = *p;
3177 if (c == '\0')
3178 break;
3179 p++;
3180 if (!isnum(c) && !isid(c))
3181 goto error_pasting;
3184 ts = tok_alloc(cstr.data, strlen(cstr.data));
3185 tok = ts->tok; /* modify current token */
3187 } else {
3188 const char *str = cstr.data;
3189 const unsigned char *q;
3191 /* we look for a valid token */
3192 /* XXX: do more extensive checks */
3193 if (!strcmp(str, ">>=")) {
3194 tok = TOK_A_SAR;
3195 } else if (!strcmp(str, "<<=")) {
3196 tok = TOK_A_SHL;
3197 } else if (strlen(str) == 2) {
3198 /* search in two bytes table */
3199 q = tok_two_chars;
3200 for(;;) {
3201 if (!*q)
3202 goto error_pasting;
3203 if (q[0] == str[0] && q[1] == str[1])
3204 break;
3205 q += 3;
3207 tok = q[2];
3208 } else {
3209 error_pasting:
3210 /* NOTE: because get_tok_str use a static buffer,
3211 we must save it */
3212 cstr_reset(&cstr);
3213 p1 = get_tok_str(tok, &tokc);
3214 cstr_cat(&cstr, p1);
3215 cstr_ccat(&cstr, '\0');
3216 p2 = get_tok_str(t, &cval);
3217 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
3218 /* cannot merge tokens: just add them separately */
3219 tok_str_add2(&macro_str1, tok, &tokc);
3220 /* XXX: free associated memory ? */
3221 tok = t;
3222 tokc = cval;
3227 tok_str_add2(&macro_str1, tok, &tokc);
3229 cstr_free(&cstr);
3230 tok_str_add(&macro_str1, 0);
3231 return macro_str1.str;
3235 /* do macro substitution of current token with macro 's' and add
3236 result to (tok_str,tok_len). 'nested_list' is the list of all
3237 macros we got inside to avoid recursing. Return non zero if no
3238 substitution needs to be done */
3239 static int macro_subst_tok(TokenString *tok_str,
3240 Sym **nested_list, Sym *s)
3242 Sym *args, *sa, *sa1;
3243 int mstr_allocated, parlevel, *mstr, t;
3244 TokenString str;
3245 char *cstrval;
3246 CValue cval;
3247 CString cstr;
3249 /* if symbol is a macro, prepare substitution */
3250 /* if nested substitution, do nothing */
3251 if (sym_find2(*nested_list, tok))
3252 return -1;
3254 /* special macros */
3255 if (tok == TOK___LINE__) {
3256 cval.i = file->line_num;
3257 tok_str_add2(tok_str, TOK_CINT, &cval);
3258 } else if (tok == TOK___FILE__) {
3259 cstrval = file->filename;
3260 goto add_cstr;
3261 tok_str_add2(tok_str, TOK_STR, &cval);
3262 } else if (tok == TOK___DATE__) {
3263 cstrval = "Jan 1 2002";
3264 goto add_cstr;
3265 } else if (tok == TOK___TIME__) {
3266 cstrval = "00:00:00";
3267 add_cstr:
3268 cstr_new(&cstr);
3269 cstr_cat(&cstr, cstrval);
3270 cstr_ccat(&cstr, '\0');
3271 cval.cstr = &cstr;
3272 tok_str_add2(tok_str, TOK_STR, &cval);
3273 cstr_free(&cstr);
3274 } else {
3275 mstr = (int *)s->c;
3276 mstr_allocated = 0;
3277 if (s->type.t == MACRO_FUNC) {
3278 /* NOTE: we do not use next_nomacro to avoid eating the
3279 next token. XXX: find better solution */
3280 if (macro_ptr) {
3281 t = *macro_ptr;
3282 } else {
3283 while (is_space(ch) || ch == '\n')
3284 cinp();
3285 t = ch;
3287 if (t != '(') /* no macro subst */
3288 return -1;
3290 /* argument macro */
3291 next_nomacro();
3292 next_nomacro();
3293 args = NULL;
3294 sa = s->next;
3295 /* NOTE: empty args are allowed, except if no args */
3296 for(;;) {
3297 /* handle '()' case */
3298 if (!args && tok == ')')
3299 break;
3300 if (!sa)
3301 error("macro '%s' used with too many args",
3302 get_tok_str(s->v, 0));
3303 tok_str_new(&str);
3304 parlevel = 0;
3305 /* NOTE: non zero sa->t indicates VA_ARGS */
3306 while ((parlevel > 0 ||
3307 (tok != ')' &&
3308 (tok != ',' || sa->type.t))) &&
3309 tok != -1) {
3310 if (tok == '(')
3311 parlevel++;
3312 else if (tok == ')')
3313 parlevel--;
3314 tok_str_add2(&str, tok, &tokc);
3315 next_nomacro();
3317 tok_str_add(&str, 0);
3318 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str);
3319 sa = sa->next;
3320 if (tok == ')') {
3321 /* special case for gcc var args: add an empty
3322 var arg argument if it is omitted */
3323 if (sa && sa->type.t && gnu_ext)
3324 continue;
3325 else
3326 break;
3328 if (tok != ',')
3329 expect(",");
3330 next_nomacro();
3332 if (sa) {
3333 error("macro '%s' used with too few args",
3334 get_tok_str(s->v, 0));
3337 /* now subst each arg */
3338 mstr = macro_arg_subst(nested_list, mstr, args);
3339 /* free memory */
3340 sa = args;
3341 while (sa) {
3342 sa1 = sa->prev;
3343 tok_str_free((int *)sa->c);
3344 tcc_free(sa);
3345 sa = sa1;
3347 mstr_allocated = 1;
3349 sym_push2(nested_list, s->v, 0, 0);
3350 macro_subst(tok_str, nested_list, mstr);
3351 /* pop nested defined symbol */
3352 sa1 = *nested_list;
3353 *nested_list = sa1->prev;
3354 tcc_free(sa1);
3355 if (mstr_allocated)
3356 tok_str_free(mstr);
3358 return 0;
3361 /* do macro substitution of macro_str and add result to
3362 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3363 inside to avoid recursing. */
3364 static void macro_subst(TokenString *tok_str,
3365 Sym **nested_list, int *macro_str)
3367 Sym *s;
3368 int *saved_macro_ptr;
3369 int *macro_str1;
3371 saved_macro_ptr = macro_ptr;
3372 macro_ptr = macro_str;
3373 /* first scan for '##' operator handling */
3374 macro_str1 = macro_twosharps();
3375 macro_ptr = macro_str1;
3377 while (1) {
3378 next_nomacro();
3379 if (tok == 0)
3380 break;
3381 s = define_find(tok);
3382 if (s != NULL) {
3383 if (macro_subst_tok(tok_str, nested_list, s) != 0)
3384 goto no_subst;
3385 } else {
3386 no_subst:
3387 tok_str_add2(tok_str, tok, &tokc);
3390 macro_ptr = saved_macro_ptr;
3391 tok_str_free(macro_str1);
3394 /* return next token with macro substitution */
3395 static void next(void)
3397 Sym *nested_list, *s;
3398 TokenString str;
3400 /* special 'ungettok' case for label parsing */
3401 if (tok1) {
3402 tok = tok1;
3403 tokc = tok1c;
3404 tok1 = 0;
3405 } else {
3406 redo:
3407 next_nomacro();
3408 if (!macro_ptr) {
3409 /* if not reading from macro substituted string, then try
3410 to substitute macros */
3411 if (tok >= TOK_IDENT) {
3412 s = define_find(tok);
3413 if (s) {
3414 /* we have a macro: we try to substitute */
3415 tok_str_new(&str);
3416 nested_list = NULL;
3417 if (macro_subst_tok(&str, &nested_list, s) == 0) {
3418 /* substitution done, NOTE: maybe empty */
3419 tok_str_add(&str, 0);
3420 macro_ptr = str.str;
3421 macro_ptr_allocated = str.str;
3422 goto redo;
3426 } else {
3427 if (tok == 0) {
3428 /* end of macro string: free it */
3429 tok_str_free(macro_ptr_allocated);
3430 macro_ptr = NULL;
3431 goto redo;
3435 /* convert preprocessor tokens into C tokens */
3436 if (tok == TOK_PPNUM) {
3437 parse_number((char *)tokc.cstr->data);
3440 #if defined(DEBUG)
3441 printf("token = %s\n", get_tok_str(tok, &tokc));
3442 #endif
3445 void swap(int *p, int *q)
3447 int t;
3448 t = *p;
3449 *p = *q;
3450 *q = t;
3453 void vsetc(CType *type, int r, CValue *vc)
3455 int v;
3457 if (vtop >= vstack + VSTACK_SIZE)
3458 error("memory full");
3459 /* cannot let cpu flags if other instruction are generated. Also
3460 avoid leaving VT_JMP anywhere except on the top of the stack
3461 because it would complicate the code generator. */
3462 if (vtop >= vstack) {
3463 v = vtop->r & VT_VALMASK;
3464 if (v == VT_CMP || (v & ~1) == VT_JMP)
3465 gv(RC_INT);
3467 vtop++;
3468 vtop->type = *type;
3469 vtop->r = r;
3470 vtop->r2 = VT_CONST;
3471 vtop->c = *vc;
3474 /* push integer constant */
3475 void vpushi(int v)
3477 CValue cval;
3478 cval.i = v;
3479 vsetc(&int_type, VT_CONST, &cval);
3482 /* Return a static symbol pointing to a section */
3483 static Sym *get_sym_ref(CType *type, Section *sec,
3484 unsigned long offset, unsigned long size)
3486 int v;
3487 Sym *sym;
3489 v = anon_sym++;
3490 sym = global_identifier_push(v, type->t | VT_STATIC, 0);
3491 sym->type.ref = type->ref;
3492 sym->r = VT_CONST | VT_SYM;
3493 put_extern_sym(sym, sec, offset, size);
3494 return sym;
3497 /* push a reference to a section offset by adding a dummy symbol */
3498 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
3500 CValue cval;
3502 cval.ul = 0;
3503 vsetc(type, VT_CONST | VT_SYM, &cval);
3504 vtop->sym = get_sym_ref(type, sec, offset, size);
3507 /* define a new external reference to a symbol 'v' of type 'u' */
3508 static Sym *external_global_sym(int v, CType *type, int r)
3510 Sym *s;
3512 s = sym_find(v);
3513 if (!s) {
3514 /* push forward reference */
3515 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
3516 s->type.ref = type->ref;
3517 s->r = r | VT_CONST | VT_SYM;
3519 return s;
3522 /* define a new external reference to a symbol 'v' of type 'u' */
3523 static Sym *external_sym(int v, CType *type, int r)
3525 Sym *s;
3527 s = sym_find(v);
3528 if (!s) {
3529 /* push forward reference */
3530 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
3531 s->type.t |= VT_EXTERN;
3533 return s;
3536 /* push a reference to global symbol v */
3537 static void vpush_global_sym(CType *type, int v)
3539 Sym *sym;
3540 CValue cval;
3542 sym = external_global_sym(v, type, 0);
3543 cval.ul = 0;
3544 vsetc(type, VT_CONST | VT_SYM, &cval);
3545 vtop->sym = sym;
3548 void vset(CType *type, int r, int v)
3550 CValue cval;
3552 cval.i = v;
3553 vsetc(type, r, &cval);
3556 void vseti(int r, int v)
3558 CType type;
3559 type.t = VT_INT;
3560 vset(&type, r, v);
3563 void vswap(void)
3565 SValue tmp;
3567 tmp = vtop[0];
3568 vtop[0] = vtop[-1];
3569 vtop[-1] = tmp;
3572 void vpushv(SValue *v)
3574 if (vtop >= vstack + VSTACK_SIZE)
3575 error("memory full");
3576 vtop++;
3577 *vtop = *v;
3580 void vdup(void)
3582 vpushv(vtop);
3585 /* save r to the memory stack, and mark it as being free */
3586 void save_reg(int r)
3588 int l, saved, size, align;
3589 SValue *p, sv;
3590 CType *type;
3592 /* modify all stack values */
3593 saved = 0;
3594 l = 0;
3595 for(p=vstack;p<=vtop;p++) {
3596 if ((p->r & VT_VALMASK) == r ||
3597 (p->r2 & VT_VALMASK) == r) {
3598 /* must save value on stack if not already done */
3599 if (!saved) {
3600 /* NOTE: must reload 'r' because r might be equal to r2 */
3601 r = p->r & VT_VALMASK;
3602 /* store register in the stack */
3603 type = &p->type;
3604 if ((p->r & VT_LVAL) ||
3605 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
3606 type = &int_type;
3607 size = type_size(type, &align);
3608 loc = (loc - size) & -align;
3609 sv.type.t = type->t;
3610 sv.r = VT_LOCAL | VT_LVAL;
3611 sv.c.ul = loc;
3612 store(r, &sv);
3613 #ifdef TCC_TARGET_I386
3614 /* x86 specific: need to pop fp register ST0 if saved */
3615 if (r == REG_ST0) {
3616 o(0xd9dd); /* fstp %st(1) */
3618 #endif
3619 /* special long long case */
3620 if ((type->t & VT_BTYPE) == VT_LLONG) {
3621 sv.c.ul += 4;
3622 store(p->r2, &sv);
3624 l = loc;
3625 saved = 1;
3627 /* mark that stack entry as being saved on the stack */
3628 if (p->r & VT_LVAL) {
3629 /* also suppress the bounded flag because the
3630 relocation address of the function was stored in
3631 p->c.ul */
3632 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
3633 } else {
3634 p->r = lvalue_type(p->type.t) | VT_LOCAL;
3636 p->r2 = VT_CONST;
3637 p->c.ul = l;
3642 /* find a free register of class 'rc'. If none, save one register */
3643 int get_reg(int rc)
3645 int r;
3646 SValue *p;
3648 /* find a free register */
3649 for(r=0;r<NB_REGS;r++) {
3650 if (reg_classes[r] & rc) {
3651 for(p=vstack;p<=vtop;p++) {
3652 if ((p->r & VT_VALMASK) == r ||
3653 (p->r2 & VT_VALMASK) == r)
3654 goto notfound;
3656 return r;
3658 notfound: ;
3661 /* no register left : free the first one on the stack (VERY
3662 IMPORTANT to start from the bottom to ensure that we don't
3663 spill registers used in gen_opi()) */
3664 for(p=vstack;p<=vtop;p++) {
3665 r = p->r & VT_VALMASK;
3666 if (r < VT_CONST && (reg_classes[r] & rc))
3667 goto save_found;
3668 /* also look at second register (if long long) */
3669 r = p->r2 & VT_VALMASK;
3670 if (r < VT_CONST && (reg_classes[r] & rc)) {
3671 save_found:
3672 save_reg(r);
3673 return r;
3676 /* Should never comes here */
3677 return -1;
3680 /* save registers up to (vtop - n) stack entry */
3681 void save_regs(int n)
3683 int r;
3684 SValue *p, *p1;
3685 p1 = vtop - n;
3686 for(p = vstack;p <= p1; p++) {
3687 r = p->r & VT_VALMASK;
3688 if (r < VT_CONST) {
3689 save_reg(r);
3694 /* move register 's' to 'r', and flush previous value of r to memory
3695 if needed */
3696 void move_reg(int r, int s)
3698 SValue sv;
3700 if (r != s) {
3701 save_reg(r);
3702 sv.type.t = VT_INT;
3703 sv.r = s;
3704 sv.c.ul = 0;
3705 load(r, &sv);
3709 /* get address of vtop (vtop MUST BE an lvalue) */
3710 void gaddrof(void)
3712 vtop->r &= ~VT_LVAL;
3713 /* tricky: if saved lvalue, then we can go back to lvalue */
3714 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
3715 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
3718 #ifdef CONFIG_TCC_BCHECK
3719 /* generate lvalue bound code */
3720 void gbound(void)
3722 int lval_type;
3723 CType type1;
3725 vtop->r &= ~VT_MUSTBOUND;
3726 /* if lvalue, then use checking code before dereferencing */
3727 if (vtop->r & VT_LVAL) {
3728 /* if not VT_BOUNDED value, then make one */
3729 if (!(vtop->r & VT_BOUNDED)) {
3730 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
3731 /* must save type because we must set it to int to get pointer */
3732 type1 = vtop->type;
3733 vtop->type.t = VT_INT;
3734 gaddrof();
3735 vpushi(0);
3736 gen_bounded_ptr_add();
3737 vtop->r |= lval_type;
3738 vtop->type = type1;
3740 /* then check for dereferencing */
3741 gen_bounded_ptr_deref();
3744 #endif
3746 /* store vtop a register belonging to class 'rc'. lvalues are
3747 converted to values. Cannot be used if cannot be converted to
3748 register value (such as structures). */
3749 int gv(int rc)
3751 int r, r2, rc2, bit_pos, bit_size, size, align, i;
3752 unsigned long long ll;
3754 /* NOTE: get_reg can modify vstack[] */
3755 if (vtop->type.t & VT_BITFIELD) {
3756 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
3757 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
3758 /* remove bit field info to avoid loops */
3759 vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
3760 /* generate shifts */
3761 vpushi(32 - (bit_pos + bit_size));
3762 gen_op(TOK_SHL);
3763 vpushi(32 - bit_size);
3764 /* NOTE: transformed to SHR if unsigned */
3765 gen_op(TOK_SAR);
3766 r = gv(rc);
3767 } else {
3768 if (is_float(vtop->type.t) &&
3769 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3770 Sym *sym;
3771 int *ptr;
3772 unsigned long offset;
3774 /* XXX: unify with initializers handling ? */
3775 /* CPUs usually cannot use float constants, so we store them
3776 generically in data segment */
3777 size = type_size(&vtop->type, &align);
3778 offset = (data_section->data_offset + align - 1) & -align;
3779 data_section->data_offset = offset;
3780 /* XXX: not portable yet */
3781 ptr = section_ptr_add(data_section, size);
3782 size = size >> 2;
3783 for(i=0;i<size;i++)
3784 ptr[i] = vtop->c.tab[i];
3785 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
3786 vtop->r |= VT_LVAL | VT_SYM;
3787 vtop->sym = sym;
3788 vtop->c.ul = 0;
3790 #ifdef CONFIG_TCC_BCHECK
3791 if (vtop->r & VT_MUSTBOUND)
3792 gbound();
3793 #endif
3795 r = vtop->r & VT_VALMASK;
3796 /* need to reload if:
3797 - constant
3798 - lvalue (need to dereference pointer)
3799 - already a register, but not in the right class */
3800 if (r >= VT_CONST ||
3801 (vtop->r & VT_LVAL) ||
3802 !(reg_classes[r] & rc) ||
3803 ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
3804 !(reg_classes[vtop->r2] & rc))) {
3805 r = get_reg(rc);
3806 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
3807 /* two register type load : expand to two words
3808 temporarily */
3809 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3810 /* load constant */
3811 ll = vtop->c.ull;
3812 vtop->c.ui = ll; /* first word */
3813 load(r, vtop);
3814 vtop->r = r; /* save register value */
3815 vpushi(ll >> 32); /* second word */
3816 } else if (r >= VT_CONST ||
3817 (vtop->r & VT_LVAL)) {
3818 /* load from memory */
3819 load(r, vtop);
3820 vdup();
3821 vtop[-1].r = r; /* save register value */
3822 /* increment pointer to get second word */
3823 vtop->type.t = VT_INT;
3824 gaddrof();
3825 vpushi(4);
3826 gen_op('+');
3827 vtop->r |= VT_LVAL;
3828 } else {
3829 /* move registers */
3830 load(r, vtop);
3831 vdup();
3832 vtop[-1].r = r; /* save register value */
3833 vtop->r = vtop[-1].r2;
3835 /* allocate second register */
3836 rc2 = RC_INT;
3837 if (rc == RC_IRET)
3838 rc2 = RC_LRET;
3839 r2 = get_reg(rc2);
3840 load(r2, vtop);
3841 vpop();
3842 /* write second register */
3843 vtop->r2 = r2;
3844 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
3845 int t1, t;
3846 /* lvalue of scalar type : need to use lvalue type
3847 because of possible cast */
3848 t = vtop->type.t;
3849 t1 = t;
3850 /* compute memory access type */
3851 if (vtop->r & VT_LVAL_BYTE)
3852 t = VT_BYTE;
3853 else if (vtop->r & VT_LVAL_SHORT)
3854 t = VT_SHORT;
3855 if (vtop->r & VT_LVAL_UNSIGNED)
3856 t |= VT_UNSIGNED;
3857 vtop->type.t = t;
3858 load(r, vtop);
3859 /* restore wanted type */
3860 vtop->type.t = t1;
3861 } else {
3862 /* one register type load */
3863 load(r, vtop);
3866 vtop->r = r;
3868 return r;
3871 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3872 void gv2(int rc1, int rc2)
3874 int v;
3876 /* generate more generic register first. But VT_JMP or VT_CMP
3877 values must be generated first in all cases to avoid possible
3878 reload errors */
3879 v = vtop[0].r & VT_VALMASK;
3880 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
3881 vswap();
3882 gv(rc1);
3883 vswap();
3884 gv(rc2);
3885 /* test if reload is needed for first register */
3886 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
3887 vswap();
3888 gv(rc1);
3889 vswap();
3891 } else {
3892 gv(rc2);
3893 vswap();
3894 gv(rc1);
3895 vswap();
3896 /* test if reload is needed for first register */
3897 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
3898 gv(rc2);
3903 /* expand long long on stack in two int registers */
3904 void lexpand(void)
3906 int u;
3908 u = vtop->type.t & VT_UNSIGNED;
3909 gv(RC_INT);
3910 vdup();
3911 vtop[0].r = vtop[-1].r2;
3912 vtop[0].r2 = VT_CONST;
3913 vtop[-1].r2 = VT_CONST;
3914 vtop[0].type.t = VT_INT | u;
3915 vtop[-1].type.t = VT_INT | u;
3918 /* build a long long from two ints */
3919 void lbuild(int t)
3921 gv2(RC_INT, RC_INT);
3922 vtop[-1].r2 = vtop[0].r;
3923 vtop[-1].type.t = t;
3924 vpop();
3927 /* rotate n first stack elements to the bottom */
3928 void vrotb(int n)
3930 int i;
3931 SValue tmp;
3933 tmp = vtop[-n + 1];
3934 for(i=-n+1;i!=0;i++)
3935 vtop[i] = vtop[i+1];
3936 vtop[0] = tmp;
3939 /* pop stack value */
3940 void vpop(void)
3942 int v;
3943 v = vtop->r & VT_VALMASK;
3944 #ifdef TCC_TARGET_I386
3945 /* for x86, we need to pop the FP stack */
3946 if (v == REG_ST0 && !nocode_wanted) {
3947 o(0xd9dd); /* fstp %st(1) */
3948 } else
3949 #endif
3950 if (v == VT_JMP || v == VT_JMPI) {
3951 /* need to put correct jump if && or || without test */
3952 gsym(vtop->c.ul);
3954 vtop--;
3957 /* convert stack entry to register and duplicate its value in another
3958 register */
3959 void gv_dup(void)
3961 int rc, t, r, r1;
3962 SValue sv;
3964 t = vtop->type.t;
3965 if ((t & VT_BTYPE) == VT_LLONG) {
3966 lexpand();
3967 gv_dup();
3968 vswap();
3969 vrotb(3);
3970 gv_dup();
3971 vrotb(4);
3972 /* stack: H L L1 H1 */
3973 lbuild(t);
3974 vrotb(3);
3975 vrotb(3);
3976 vswap();
3977 lbuild(t);
3978 vswap();
3979 } else {
3980 /* duplicate value */
3981 rc = RC_INT;
3982 sv.type.t = VT_INT;
3983 if (is_float(t)) {
3984 rc = RC_FLOAT;
3985 sv.type.t = t;
3987 r = gv(rc);
3988 r1 = get_reg(rc);
3989 sv.r = r;
3990 sv.c.ul = 0;
3991 load(r1, &sv); /* move r to r1 */
3992 vdup();
3993 /* duplicates value */
3994 vtop->r = r1;
3998 /* generate CPU independent (unsigned) long long operations */
3999 void gen_opl(int op)
4001 int t, a, b, op1, c, i;
4002 int func;
4003 GFuncContext gf;
4004 SValue tmp;
4006 switch(op) {
4007 case '/':
4008 case TOK_PDIV:
4009 func = TOK___divdi3;
4010 goto gen_func;
4011 case TOK_UDIV:
4012 func = TOK___udivdi3;
4013 goto gen_func;
4014 case '%':
4015 func = TOK___moddi3;
4016 goto gen_func;
4017 case TOK_UMOD:
4018 func = TOK___umoddi3;
4019 gen_func:
4020 /* call generic long long function */
4021 gfunc_start(&gf, FUNC_CDECL);
4022 gfunc_param(&gf);
4023 gfunc_param(&gf);
4024 vpush_global_sym(&func_old_type, func);
4025 gfunc_call(&gf);
4026 vpushi(0);
4027 vtop->r = REG_IRET;
4028 vtop->r2 = REG_LRET;
4029 break;
4030 case '^':
4031 case '&':
4032 case '|':
4033 case '*':
4034 case '+':
4035 case '-':
4036 t = vtop->type.t;
4037 vswap();
4038 lexpand();
4039 vrotb(3);
4040 lexpand();
4041 /* stack: L1 H1 L2 H2 */
4042 tmp = vtop[0];
4043 vtop[0] = vtop[-3];
4044 vtop[-3] = tmp;
4045 tmp = vtop[-2];
4046 vtop[-2] = vtop[-3];
4047 vtop[-3] = tmp;
4048 vswap();
4049 /* stack: H1 H2 L1 L2 */
4050 if (op == '*') {
4051 vpushv(vtop - 1);
4052 vpushv(vtop - 1);
4053 gen_op(TOK_UMULL);
4054 lexpand();
4055 /* stack: H1 H2 L1 L2 ML MH */
4056 for(i=0;i<4;i++)
4057 vrotb(6);
4058 /* stack: ML MH H1 H2 L1 L2 */
4059 tmp = vtop[0];
4060 vtop[0] = vtop[-2];
4061 vtop[-2] = tmp;
4062 /* stack: ML MH H1 L2 H2 L1 */
4063 gen_op('*');
4064 vrotb(3);
4065 vrotb(3);
4066 gen_op('*');
4067 /* stack: ML MH M1 M2 */
4068 gen_op('+');
4069 gen_op('+');
4070 } else if (op == '+' || op == '-') {
4071 /* XXX: add non carry method too (for MIPS or alpha) */
4072 if (op == '+')
4073 op1 = TOK_ADDC1;
4074 else
4075 op1 = TOK_SUBC1;
4076 gen_op(op1);
4077 /* stack: H1 H2 (L1 op L2) */
4078 vrotb(3);
4079 vrotb(3);
4080 gen_op(op1 + 1); /* TOK_xxxC2 */
4081 } else {
4082 gen_op(op);
4083 /* stack: H1 H2 (L1 op L2) */
4084 vrotb(3);
4085 vrotb(3);
4086 /* stack: (L1 op L2) H1 H2 */
4087 gen_op(op);
4088 /* stack: (L1 op L2) (H1 op H2) */
4090 /* stack: L H */
4091 lbuild(t);
4092 break;
4093 case TOK_SAR:
4094 case TOK_SHR:
4095 case TOK_SHL:
4096 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
4097 t = vtop[-1].type.t;
4098 vswap();
4099 lexpand();
4100 vrotb(3);
4101 /* stack: L H shift */
4102 c = (int)vtop->c.i;
4103 /* constant: simpler */
4104 /* NOTE: all comments are for SHL. the other cases are
4105 done by swaping words */
4106 vpop();
4107 if (op != TOK_SHL)
4108 vswap();
4109 if (c >= 32) {
4110 /* stack: L H */
4111 vpop();
4112 if (c > 32) {
4113 vpushi(c - 32);
4114 gen_op(op);
4116 if (op != TOK_SAR) {
4117 vpushi(0);
4118 } else {
4119 gv_dup();
4120 vpushi(31);
4121 gen_op(TOK_SAR);
4123 vswap();
4124 } else {
4125 vswap();
4126 gv_dup();
4127 /* stack: H L L */
4128 vpushi(c);
4129 gen_op(op);
4130 vswap();
4131 vpushi(32 - c);
4132 if (op == TOK_SHL)
4133 gen_op(TOK_SHR);
4134 else
4135 gen_op(TOK_SHL);
4136 vrotb(3);
4137 /* stack: L L H */
4138 vpushi(c);
4139 if (op == TOK_SHL)
4140 gen_op(TOK_SHL);
4141 else
4142 gen_op(TOK_SHR);
4143 gen_op('|');
4145 if (op != TOK_SHL)
4146 vswap();
4147 lbuild(t);
4148 } else {
4149 /* XXX: should provide a faster fallback on x86 ? */
4150 switch(op) {
4151 case TOK_SAR:
4152 func = TOK___sardi3;
4153 goto gen_func;
4154 case TOK_SHR:
4155 func = TOK___shrdi3;
4156 goto gen_func;
4157 case TOK_SHL:
4158 func = TOK___shldi3;
4159 goto gen_func;
4162 break;
4163 default:
4164 /* compare operations */
4165 t = vtop->type.t;
4166 vswap();
4167 lexpand();
4168 vrotb(3);
4169 lexpand();
4170 /* stack: L1 H1 L2 H2 */
4171 tmp = vtop[-1];
4172 vtop[-1] = vtop[-2];
4173 vtop[-2] = tmp;
4174 /* stack: L1 L2 H1 H2 */
4175 /* compare high */
4176 op1 = op;
4177 /* when values are equal, we need to compare low words. since
4178 the jump is inverted, we invert the test too. */
4179 if (op1 == TOK_LT)
4180 op1 = TOK_LE;
4181 else if (op1 == TOK_GT)
4182 op1 = TOK_GE;
4183 else if (op1 == TOK_ULT)
4184 op1 = TOK_ULE;
4185 else if (op1 == TOK_UGT)
4186 op1 = TOK_UGE;
4187 a = 0;
4188 b = 0;
4189 gen_op(op1);
4190 if (op1 != TOK_NE) {
4191 a = gtst(1, 0);
4193 if (op != TOK_EQ) {
4194 /* generate non equal test */
4195 /* XXX: NOT PORTABLE yet */
4196 if (a == 0) {
4197 b = gtst(0, 0);
4198 } else {
4199 #ifdef TCC_TARGET_I386
4200 b = psym(0x850f, 0);
4201 #else
4202 error("not implemented");
4203 #endif
4206 /* compare low */
4207 gen_op(op);
4208 a = gtst(1, a);
4209 gsym(b);
4210 vseti(VT_JMPI, a);
4211 break;
4215 /* handle integer constant optimizations and various machine
4216 independant opt */
4217 void gen_opic(int op)
4219 int fc, c1, c2, n;
4220 SValue *v1, *v2;
4222 v1 = vtop - 1;
4223 v2 = vtop;
4224 /* currently, we cannot do computations with forward symbols */
4225 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4226 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4227 if (c1 && c2) {
4228 fc = v2->c.i;
4229 switch(op) {
4230 case '+': v1->c.i += fc; break;
4231 case '-': v1->c.i -= fc; break;
4232 case '&': v1->c.i &= fc; break;
4233 case '^': v1->c.i ^= fc; break;
4234 case '|': v1->c.i |= fc; break;
4235 case '*': v1->c.i *= fc; break;
4237 case TOK_PDIV:
4238 case '/':
4239 case '%':
4240 case TOK_UDIV:
4241 case TOK_UMOD:
4242 /* if division by zero, generate explicit division */
4243 if (fc == 0) {
4244 if (const_wanted)
4245 error("division by zero in constant");
4246 goto general_case;
4248 switch(op) {
4249 default: v1->c.i /= fc; break;
4250 case '%': v1->c.i %= fc; break;
4251 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
4252 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
4254 break;
4255 case TOK_SHL: v1->c.i <<= fc; break;
4256 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
4257 case TOK_SAR: v1->c.i >>= fc; break;
4258 /* tests */
4259 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
4260 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
4261 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
4262 case TOK_NE: v1->c.i = v1->c.i != fc; break;
4263 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
4264 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
4265 case TOK_LT: v1->c.i = v1->c.i < fc; break;
4266 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
4267 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
4268 case TOK_GT: v1->c.i = v1->c.i > fc; break;
4269 /* logical */
4270 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
4271 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
4272 default:
4273 goto general_case;
4275 vtop--;
4276 } else {
4277 /* if commutative ops, put c2 as constant */
4278 if (c1 && (op == '+' || op == '&' || op == '^' ||
4279 op == '|' || op == '*')) {
4280 vswap();
4281 swap(&c1, &c2);
4283 fc = vtop->c.i;
4284 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
4285 op == TOK_PDIV) &&
4286 fc == 1) ||
4287 ((op == '+' || op == '-' || op == '|' || op == '^' ||
4288 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
4289 fc == 0) ||
4290 (op == '&' &&
4291 fc == -1))) {
4292 /* nothing to do */
4293 vtop--;
4294 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
4295 /* try to use shifts instead of muls or divs */
4296 if (fc > 0 && (fc & (fc - 1)) == 0) {
4297 n = -1;
4298 while (fc) {
4299 fc >>= 1;
4300 n++;
4302 vtop->c.i = n;
4303 if (op == '*')
4304 op = TOK_SHL;
4305 else if (op == TOK_PDIV)
4306 op = TOK_SAR;
4307 else
4308 op = TOK_SHR;
4310 goto general_case;
4311 } else if (c2 && (op == '+' || op == '-') &&
4312 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
4313 (VT_CONST | VT_SYM)) {
4314 /* symbol + constant case */
4315 if (op == '-')
4316 fc = -fc;
4317 vtop--;
4318 vtop->c.i += fc;
4319 } else {
4320 general_case:
4321 if (!nocode_wanted) {
4322 /* call low level op generator */
4323 gen_opi(op);
4324 } else {
4325 vtop--;
4331 /* generate a floating point operation with constant propagation */
4332 void gen_opif(int op)
4334 int c1, c2;
4335 SValue *v1, *v2;
4336 long double f1, f2;
4338 v1 = vtop - 1;
4339 v2 = vtop;
4340 /* currently, we cannot do computations with forward symbols */
4341 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4342 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4343 if (c1 && c2) {
4344 if (v1->type.t == VT_FLOAT) {
4345 f1 = v1->c.f;
4346 f2 = v2->c.f;
4347 } else if (v1->type.t == VT_DOUBLE) {
4348 f1 = v1->c.d;
4349 f2 = v2->c.d;
4350 } else {
4351 f1 = v1->c.ld;
4352 f2 = v2->c.ld;
4355 /* NOTE: we only do constant propagation if finite number (not
4356 NaN or infinity) (ANSI spec) */
4357 if (!ieee_finite(f1) || !ieee_finite(f2))
4358 goto general_case;
4360 switch(op) {
4361 case '+': f1 += f2; break;
4362 case '-': f1 -= f2; break;
4363 case '*': f1 *= f2; break;
4364 case '/':
4365 if (f2 == 0.0) {
4366 if (const_wanted)
4367 error("division by zero in constant");
4368 goto general_case;
4370 f1 /= f2;
4371 break;
4372 /* XXX: also handles tests ? */
4373 default:
4374 goto general_case;
4376 /* XXX: overflow test ? */
4377 if (v1->type.t == VT_FLOAT) {
4378 v1->c.f = f1;
4379 } else if (v1->type.t == VT_DOUBLE) {
4380 v1->c.d = f1;
4381 } else {
4382 v1->c.ld = f1;
4384 vtop--;
4385 } else {
4386 general_case:
4387 if (!nocode_wanted) {
4388 gen_opf(op);
4389 } else {
4390 vtop--;
4395 static int pointed_size(CType *type)
4397 int align;
4398 return type_size(pointed_type(type), &align);
4401 #if 0
4402 void check_pointer_types(SValue *p1, SValue *p2)
4404 char buf1[256], buf2[256];
4405 int t1, t2;
4406 t1 = p1->t;
4407 t2 = p2->t;
4408 if (!is_compatible_types(t1, t2)) {
4409 type_to_str(buf1, sizeof(buf1), t1, NULL);
4410 type_to_str(buf2, sizeof(buf2), t2, NULL);
4411 error("incompatible pointers '%s' and '%s'", buf1, buf2);
4414 #endif
4416 /* generic gen_op: handles types problems */
4417 void gen_op(int op)
4419 int u, t1, t2, bt1, bt2, t;
4420 CType type1;
4422 t1 = vtop[-1].type.t;
4423 t2 = vtop[0].type.t;
4424 bt1 = t1 & VT_BTYPE;
4425 bt2 = t2 & VT_BTYPE;
4427 if (bt1 == VT_PTR || bt2 == VT_PTR) {
4428 /* at least one operand is a pointer */
4429 /* relationnal op: must be both pointers */
4430 if (op >= TOK_ULT && op <= TOK_GT) {
4431 // check_pointer_types(vtop, vtop - 1);
4432 /* pointers are handled are unsigned */
4433 t = VT_INT | VT_UNSIGNED;
4434 goto std_op;
4436 /* if both pointers, then it must be the '-' op */
4437 if (bt1 == VT_PTR && bt2 == VT_PTR) {
4438 if (op != '-')
4439 error("cannot use pointers here");
4440 // check_pointer_types(vtop - 1, vtop);
4441 /* XXX: check that types are compatible */
4442 u = pointed_size(&vtop[-1].type);
4443 gen_opic(op);
4444 /* set to integer type */
4445 vtop->type.t = VT_INT;
4446 vpushi(u);
4447 gen_op(TOK_PDIV);
4448 } else {
4449 /* exactly one pointer : must be '+' or '-'. */
4450 if (op != '-' && op != '+')
4451 error("cannot use pointers here");
4452 /* Put pointer as first operand */
4453 if (bt2 == VT_PTR) {
4454 vswap();
4455 swap(&t1, &t2);
4457 type1 = vtop[-1].type;
4458 /* XXX: cast to int ? (long long case) */
4459 vpushi(pointed_size(&vtop[-1].type));
4460 gen_op('*');
4461 #ifdef CONFIG_TCC_BCHECK
4462 /* if evaluating constant expression, no code should be
4463 generated, so no bound check */
4464 if (do_bounds_check && !const_wanted) {
4465 /* if bounded pointers, we generate a special code to
4466 test bounds */
4467 if (op == '-') {
4468 vpushi(0);
4469 vswap();
4470 gen_op('-');
4472 gen_bounded_ptr_add();
4473 } else
4474 #endif
4476 gen_opic(op);
4478 /* put again type if gen_opic() swaped operands */
4479 vtop->type = type1;
4481 } else if (is_float(bt1) || is_float(bt2)) {
4482 /* compute bigger type and do implicit casts */
4483 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4484 t = VT_LDOUBLE;
4485 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4486 t = VT_DOUBLE;
4487 } else {
4488 t = VT_FLOAT;
4490 /* floats can only be used for a few operations */
4491 if (op != '+' && op != '-' && op != '*' && op != '/' &&
4492 (op < TOK_ULT || op > TOK_GT))
4493 error("invalid operands for binary operation");
4494 goto std_op;
4495 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4496 /* cast to biggest op */
4497 t = VT_LLONG;
4498 /* convert to unsigned if it does not fit in a long long */
4499 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4500 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4501 t |= VT_UNSIGNED;
4502 goto std_op;
4503 } else {
4504 /* integer operations */
4505 t = VT_INT;
4506 /* convert to unsigned if it does not fit in an integer */
4507 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4508 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4509 t |= VT_UNSIGNED;
4510 std_op:
4511 /* XXX: currently, some unsigned operations are explicit, so
4512 we modify them here */
4513 if (t & VT_UNSIGNED) {
4514 if (op == TOK_SAR)
4515 op = TOK_SHR;
4516 else if (op == '/')
4517 op = TOK_UDIV;
4518 else if (op == '%')
4519 op = TOK_UMOD;
4520 else if (op == TOK_LT)
4521 op = TOK_ULT;
4522 else if (op == TOK_GT)
4523 op = TOK_UGT;
4524 else if (op == TOK_LE)
4525 op = TOK_ULE;
4526 else if (op == TOK_GE)
4527 op = TOK_UGE;
4529 vswap();
4530 type1.t = t;
4531 gen_cast(&type1);
4532 vswap();
4533 /* special case for shifts and long long: we keep the shift as
4534 an integer */
4535 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
4536 type1.t = VT_INT;
4537 gen_cast(&type1);
4538 if (is_float(t))
4539 gen_opif(op);
4540 else if ((t & VT_BTYPE) == VT_LLONG)
4541 gen_opl(op);
4542 else
4543 gen_opic(op);
4544 if (op >= TOK_ULT && op <= TOK_GT) {
4545 /* relationnal op: the result is an int */
4546 vtop->type.t = VT_INT;
4547 } else {
4548 vtop->type.t = t;
4553 /* generic itof for unsigned long long case */
4554 void gen_cvt_itof1(int t)
4556 GFuncContext gf;
4558 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
4559 (VT_LLONG | VT_UNSIGNED)) {
4561 gfunc_start(&gf, FUNC_CDECL);
4562 gfunc_param(&gf);
4563 if (t == VT_FLOAT)
4564 vpush_global_sym(&func_old_type, TOK___ulltof);
4565 else if (t == VT_DOUBLE)
4566 vpush_global_sym(&func_old_type, TOK___ulltod);
4567 else
4568 vpush_global_sym(&func_old_type, TOK___ulltold);
4569 gfunc_call(&gf);
4570 vpushi(0);
4571 vtop->r = REG_FRET;
4572 } else {
4573 gen_cvt_itof(t);
4577 /* generic ftoi for unsigned long long case */
4578 void gen_cvt_ftoi1(int t)
4580 GFuncContext gf;
4581 int st;
4583 if (t == (VT_LLONG | VT_UNSIGNED)) {
4584 /* not handled natively */
4585 gfunc_start(&gf, FUNC_CDECL);
4586 st = vtop->type.t & VT_BTYPE;
4587 gfunc_param(&gf);
4588 if (st == VT_FLOAT)
4589 vpush_global_sym(&func_old_type, TOK___fixunssfdi);
4590 else if (st == VT_DOUBLE)
4591 vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
4592 else
4593 vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
4594 gfunc_call(&gf);
4595 vpushi(0);
4596 vtop->r = REG_IRET;
4597 vtop->r2 = REG_LRET;
4598 } else {
4599 gen_cvt_ftoi(t);
4603 /* force char or short cast */
4604 void force_charshort_cast(int t)
4606 int bits, dbt;
4607 dbt = t & VT_BTYPE;
4608 /* XXX: add optimization if lvalue : just change type and offset */
4609 if (dbt == VT_BYTE)
4610 bits = 8;
4611 else
4612 bits = 16;
4613 if (t & VT_UNSIGNED) {
4614 vpushi((1 << bits) - 1);
4615 gen_op('&');
4616 } else {
4617 bits = 32 - bits;
4618 vpushi(bits);
4619 gen_op(TOK_SHL);
4620 vpushi(bits);
4621 gen_op(TOK_SAR);
4625 /* cast 'vtop' to 'type' */
4626 static void gen_cast(CType *type)
4628 int sbt, dbt, sf, df, c;
4630 /* special delayed cast for char/short */
4631 /* XXX: in some cases (multiple cascaded casts), it may still
4632 be incorrect */
4633 if (vtop->r & VT_MUSTCAST) {
4634 vtop->r &= ~VT_MUSTCAST;
4635 force_charshort_cast(vtop->type.t);
4638 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
4639 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
4641 if (sbt != dbt && !nocode_wanted) {
4642 sf = is_float(sbt);
4643 df = is_float(dbt);
4644 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4645 if (sf && df) {
4646 /* convert from fp to fp */
4647 if (c) {
4648 /* constant case: we can do it now */
4649 /* XXX: in ISOC, cannot do it if error in convert */
4650 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
4651 vtop->c.f = (float)vtop->c.d;
4652 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
4653 vtop->c.f = (float)vtop->c.ld;
4654 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
4655 vtop->c.d = (double)vtop->c.f;
4656 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
4657 vtop->c.d = (double)vtop->c.ld;
4658 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
4659 vtop->c.ld = (long double)vtop->c.f;
4660 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
4661 vtop->c.ld = (long double)vtop->c.d;
4662 } else {
4663 /* non constant case: generate code */
4664 gen_cvt_ftof(dbt);
4666 } else if (df) {
4667 /* convert int to fp */
4668 if (c) {
4669 switch(sbt) {
4670 case VT_LLONG | VT_UNSIGNED:
4671 case VT_LLONG:
4672 /* XXX: add const cases for long long */
4673 goto do_itof;
4674 case VT_INT | VT_UNSIGNED:
4675 switch(dbt) {
4676 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
4677 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
4678 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
4680 break;
4681 default:
4682 switch(dbt) {
4683 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
4684 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
4685 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
4687 break;
4689 } else {
4690 do_itof:
4691 gen_cvt_itof1(dbt);
4693 } else if (sf) {
4694 /* convert fp to int */
4695 /* we handle char/short/etc... with generic code */
4696 if (dbt != (VT_INT | VT_UNSIGNED) &&
4697 dbt != (VT_LLONG | VT_UNSIGNED) &&
4698 dbt != VT_LLONG)
4699 dbt = VT_INT;
4700 if (c) {
4701 switch(dbt) {
4702 case VT_LLONG | VT_UNSIGNED:
4703 case VT_LLONG:
4704 /* XXX: add const cases for long long */
4705 goto do_ftoi;
4706 case VT_INT | VT_UNSIGNED:
4707 switch(sbt) {
4708 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
4709 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4710 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4712 break;
4713 default:
4714 /* int case */
4715 switch(sbt) {
4716 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
4717 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
4718 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
4720 break;
4722 } else {
4723 do_ftoi:
4724 gen_cvt_ftoi1(dbt);
4726 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
4727 /* additionnal cast for char/short/bool... */
4728 vtop->type.t = dbt;
4729 gen_cast(type);
4731 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
4732 if ((sbt & VT_BTYPE) != VT_LLONG) {
4733 /* scalar to long long */
4734 if (c) {
4735 if (sbt == (VT_INT | VT_UNSIGNED))
4736 vtop->c.ll = vtop->c.ui;
4737 else
4738 vtop->c.ll = vtop->c.i;
4739 } else {
4740 /* machine independant conversion */
4741 gv(RC_INT);
4742 /* generate high word */
4743 if (sbt == (VT_INT | VT_UNSIGNED)) {
4744 vpushi(0);
4745 gv(RC_INT);
4746 } else {
4747 gv_dup();
4748 vpushi(31);
4749 gen_op(TOK_SAR);
4751 /* patch second register */
4752 vtop[-1].r2 = vtop->r;
4753 vpop();
4756 } else if (dbt == VT_BOOL) {
4757 /* scalar to bool */
4758 vpushi(0);
4759 gen_op(TOK_NE);
4760 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
4761 (dbt & VT_BTYPE) == VT_SHORT) {
4762 force_charshort_cast(dbt);
4763 } else if ((dbt & VT_BTYPE) == VT_INT) {
4764 /* scalar to int */
4765 if (sbt == VT_LLONG) {
4766 /* from long long: just take low order word */
4767 lexpand();
4768 vpop();
4770 /* if lvalue and single word type, nothing to do because
4771 the lvalue already contains the real type size (see
4772 VT_LVAL_xxx constants) */
4775 vtop->type = *type;
4778 /* return type size. Put alignment at 'a' */
4779 int type_size(CType *type, int *a)
4781 Sym *s;
4782 int bt;
4784 bt = type->t & VT_BTYPE;
4785 if (bt == VT_STRUCT) {
4786 /* struct/union */
4787 s = type->ref;
4788 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
4789 return s->c;
4790 } else if (bt == VT_PTR) {
4791 if (type->t & VT_ARRAY) {
4792 s = type->ref;
4793 return type_size(&s->type, a) * s->c;
4794 } else {
4795 *a = PTR_SIZE;
4796 return PTR_SIZE;
4798 } else if (bt == VT_LDOUBLE) {
4799 *a = LDOUBLE_ALIGN;
4800 return LDOUBLE_SIZE;
4801 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
4802 *a = 8;
4803 return 8;
4804 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
4805 *a = 4;
4806 return 4;
4807 } else if (bt == VT_SHORT) {
4808 *a = 2;
4809 return 2;
4810 } else {
4811 /* char, void, function, _Bool */
4812 *a = 1;
4813 return 1;
4817 /* return the pointed type of t */
4818 static inline CType *pointed_type(CType *type)
4820 return &type->ref->type;
4823 /* modify type so that its it is a pointer to type. */
4824 static void mk_pointer(CType *type)
4826 Sym *s;
4827 s = sym_push(SYM_FIELD, type, 0, -1);
4828 type->t = VT_PTR | (type->t & ~VT_TYPE);
4829 type->ref = s;
4832 static int is_compatible_types(CType *type1, CType *type2)
4834 Sym *s1, *s2;
4835 int bt1, bt2, t1, t2;
4837 t1 = type1->t & VT_TYPE;
4838 t2 = type2->t & VT_TYPE;
4839 bt1 = t1 & VT_BTYPE;
4840 bt2 = t2 & VT_BTYPE;
4841 if (bt1 == VT_PTR) {
4842 type1 = pointed_type(type1);
4843 /* if function, then convert implicitely to function pointer */
4844 if (bt2 != VT_FUNC) {
4845 if (bt2 != VT_PTR)
4846 return 0;
4847 type2 = pointed_type(type2);
4849 /* void matches everything */
4850 /* XXX: not fully compliant */
4851 if ((type1->t & VT_TYPE) == VT_VOID || (type2->t & VT_TYPE) == VT_VOID)
4852 return 1;
4853 return is_compatible_types(type1, type2);
4854 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4855 return (t2 == t1);
4856 } else if (bt1 == VT_FUNC) {
4857 if (bt2 != VT_FUNC)
4858 return 0;
4859 s1 = type1->ref;
4860 s2 = type2->ref;
4861 if (!is_compatible_types(&s1->type, &s2->type))
4862 return 0;
4863 /* XXX: not complete */
4864 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
4865 return 1;
4866 if (s1->c != s2->c)
4867 return 0;
4868 while (s1 != NULL) {
4869 if (s2 == NULL)
4870 return 0;
4871 if (!is_compatible_types(&s1->type, &s2->type))
4872 return 0;
4873 s1 = s1->next;
4874 s2 = s2->next;
4876 if (s2)
4877 return 0;
4878 return 1;
4879 } else {
4880 /* XXX: not complete */
4881 return 1;
4885 /* print a type. If 'varstr' is not NULL, then the variable is also
4886 printed in the type */
4887 /* XXX: union */
4888 /* XXX: add array and function pointers */
4889 void type_to_str(char *buf, int buf_size,
4890 CType *type, const char *varstr)
4892 int bt, v, t;
4893 Sym *s, *sa;
4894 char buf1[256];
4895 const char *tstr;
4897 t = type->t & VT_TYPE;
4898 bt = t & VT_BTYPE;
4899 buf[0] = '\0';
4900 if (t & VT_UNSIGNED)
4901 pstrcat(buf, buf_size, "unsigned ");
4902 switch(bt) {
4903 case VT_VOID:
4904 tstr = "void";
4905 goto add_tstr;
4906 case VT_BOOL:
4907 tstr = "_Bool";
4908 goto add_tstr;
4909 case VT_BYTE:
4910 tstr = "char";
4911 goto add_tstr;
4912 case VT_SHORT:
4913 tstr = "short";
4914 goto add_tstr;
4915 case VT_INT:
4916 tstr = "int";
4917 goto add_tstr;
4918 case VT_LONG:
4919 tstr = "long";
4920 goto add_tstr;
4921 case VT_LLONG:
4922 tstr = "long long";
4923 goto add_tstr;
4924 case VT_FLOAT:
4925 tstr = "float";
4926 goto add_tstr;
4927 case VT_DOUBLE:
4928 tstr = "double";
4929 goto add_tstr;
4930 case VT_LDOUBLE:
4931 tstr = "long double";
4932 add_tstr:
4933 pstrcat(buf, buf_size, tstr);
4934 break;
4935 case VT_ENUM:
4936 case VT_STRUCT:
4937 if (bt == VT_STRUCT)
4938 tstr = "struct ";
4939 else
4940 tstr = "enum ";
4941 pstrcat(buf, buf_size, tstr);
4942 v = type->ref->v;
4943 if (v >= SYM_FIRST_ANOM)
4944 pstrcat(buf, buf_size, "<anonymous>");
4945 else
4946 pstrcat(buf, buf_size, get_tok_str(v, NULL));
4947 break;
4948 case VT_FUNC:
4949 s = type->ref;
4950 type_to_str(buf, buf_size, &s->type, varstr);
4951 pstrcat(buf, buf_size, "(");
4952 sa = s->next;
4953 while (sa != NULL) {
4954 type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
4955 pstrcat(buf, buf_size, buf1);
4956 sa = sa->next;
4957 if (sa)
4958 pstrcat(buf, buf_size, ", ");
4960 pstrcat(buf, buf_size, ")");
4961 goto no_var;
4962 case VT_PTR:
4963 s = type->ref;
4964 pstrcpy(buf1, sizeof(buf1), "*");
4965 if (varstr)
4966 pstrcat(buf1, sizeof(buf1), varstr);
4967 type_to_str(buf, buf_size, &s->type, buf1);
4968 goto no_var;
4970 if (varstr) {
4971 pstrcat(buf, buf_size, " ");
4972 pstrcat(buf, buf_size, varstr);
4974 no_var: ;
4977 /* verify type compatibility to store vtop in 'dt' type, and generate
4978 casts if needed. */
4979 void gen_assign_cast(CType *dt)
4981 CType *st;
4982 char buf1[256], buf2[256];
4984 st = &vtop->type; /* source type */
4985 if ((dt->t & VT_BTYPE) == VT_PTR) {
4986 /* special cases for pointers */
4987 /* a function is implicitely a function pointer */
4988 if ((st->t & VT_BTYPE) == VT_FUNC) {
4989 if (!is_compatible_types(pointed_type(dt), st))
4990 goto error;
4991 else
4992 goto type_ok;
4994 /* '0' can also be a pointer */
4995 if ((st->t & VT_BTYPE) == VT_INT &&
4996 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
4997 vtop->c.i == 0)
4998 goto type_ok;
5000 if (!is_compatible_types(dt, st)) {
5001 error:
5002 type_to_str(buf1, sizeof(buf1), st, NULL);
5003 type_to_str(buf2, sizeof(buf2), dt, NULL);
5004 error("cannot cast '%s' to '%s'", buf1, buf2);
5006 type_ok:
5007 gen_cast(dt);
5010 /* store vtop in lvalue pushed on stack */
5011 void vstore(void)
5013 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
5014 GFuncContext gf;
5016 ft = vtop[-1].type.t;
5017 sbt = vtop->type.t & VT_BTYPE;
5018 dbt = ft & VT_BTYPE;
5019 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
5020 (sbt == VT_INT && dbt == VT_SHORT)) {
5021 /* optimize char/short casts */
5022 delayed_cast = VT_MUSTCAST;
5023 vtop->type.t = ft & VT_TYPE;
5024 } else {
5025 delayed_cast = 0;
5026 gen_assign_cast(&vtop[-1].type);
5029 if (sbt == VT_STRUCT) {
5030 /* if structure, only generate pointer */
5031 /* structure assignment : generate memcpy */
5032 /* XXX: optimize if small size */
5033 if (!nocode_wanted) {
5034 vdup();
5035 gfunc_start(&gf, FUNC_CDECL);
5036 /* type size */
5037 size = type_size(&vtop->type, &align);
5038 vpushi(size);
5039 gfunc_param(&gf);
5040 /* source */
5041 vtop->type.t = VT_INT;
5042 gaddrof();
5043 gfunc_param(&gf);
5044 /* destination */
5045 vswap();
5046 vtop->type.t = VT_INT;
5047 gaddrof();
5048 gfunc_param(&gf);
5050 save_regs(0);
5051 vpush_global_sym(&func_old_type, TOK_memcpy);
5052 gfunc_call(&gf);
5053 } else {
5054 vswap();
5055 vpop();
5057 /* leave source on stack */
5058 } else if (ft & VT_BITFIELD) {
5059 /* bitfield store handling */
5060 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
5061 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
5062 /* remove bit field info to avoid loops */
5063 vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
5065 /* duplicate destination */
5066 vdup();
5067 vtop[-1] = vtop[-2];
5069 /* mask and shift source */
5070 vpushi((1 << bit_size) - 1);
5071 gen_op('&');
5072 vpushi(bit_pos);
5073 gen_op(TOK_SHL);
5074 /* load destination, mask and or with source */
5075 vswap();
5076 vpushi(~(((1 << bit_size) - 1) << bit_pos));
5077 gen_op('&');
5078 gen_op('|');
5079 /* store result */
5080 vstore();
5081 } else {
5082 #ifdef CONFIG_TCC_BCHECK
5083 /* bound check case */
5084 if (vtop[-1].r & VT_MUSTBOUND) {
5085 vswap();
5086 gbound();
5087 vswap();
5089 #endif
5090 if (!nocode_wanted) {
5091 rc = RC_INT;
5092 if (is_float(ft))
5093 rc = RC_FLOAT;
5094 r = gv(rc); /* generate value */
5095 /* if lvalue was saved on stack, must read it */
5096 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
5097 SValue sv;
5098 t = get_reg(RC_INT);
5099 sv.type.t = VT_INT;
5100 sv.r = VT_LOCAL | VT_LVAL;
5101 sv.c.ul = vtop[-1].c.ul;
5102 load(t, &sv);
5103 vtop[-1].r = t | VT_LVAL;
5105 store(r, vtop - 1);
5106 /* two word case handling : store second register at word + 4 */
5107 if ((ft & VT_BTYPE) == VT_LLONG) {
5108 vswap();
5109 /* convert to int to increment easily */
5110 vtop->type.t = VT_INT;
5111 gaddrof();
5112 vpushi(4);
5113 gen_op('+');
5114 vtop->r |= VT_LVAL;
5115 vswap();
5116 /* XXX: it works because r2 is spilled last ! */
5117 store(vtop->r2, vtop - 1);
5120 vswap();
5121 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5122 vtop->r |= delayed_cast;
5126 /* post defines POST/PRE add. c is the token ++ or -- */
5127 void inc(int post, int c)
5129 test_lvalue();
5130 vdup(); /* save lvalue */
5131 if (post) {
5132 gv_dup(); /* duplicate value */
5133 vrotb(3);
5134 vrotb(3);
5136 /* add constant */
5137 vpushi(c - TOK_MID);
5138 gen_op('+');
5139 vstore(); /* store value */
5140 if (post)
5141 vpop(); /* if post op, return saved value */
5144 /* Parse GNUC __attribute__ extension. Currently, the following
5145 extensions are recognized:
5146 - aligned(n) : set data/function alignment.
5147 - section(x) : generate data/code in this section.
5148 - unused : currently ignored, but may be used someday.
5150 void parse_attribute(AttributeDef *ad)
5152 int t, n;
5154 next();
5155 skip('(');
5156 skip('(');
5157 while (tok != ')') {
5158 if (tok < TOK_IDENT)
5159 expect("attribute name");
5160 t = tok;
5161 next();
5162 switch(t) {
5163 case TOK_SECTION:
5164 case TOK___SECTION__:
5165 skip('(');
5166 if (tok != TOK_STR)
5167 expect("section name");
5168 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
5169 next();
5170 skip(')');
5171 break;
5172 case TOK_ALIGNED:
5173 case TOK___ALIGNED__:
5174 skip('(');
5175 n = expr_const();
5176 if (n <= 0 || (n & (n - 1)) != 0)
5177 error("alignment must be a positive power of two");
5178 ad->aligned = n;
5179 skip(')');
5180 break;
5181 case TOK_UNUSED:
5182 case TOK___UNUSED__:
5183 /* currently, no need to handle it because tcc does not
5184 track unused objects */
5185 break;
5186 case TOK_NORETURN:
5187 case TOK___NORETURN__:
5188 /* currently, no need to handle it because tcc does not
5189 track unused objects */
5190 break;
5191 case TOK_CDECL:
5192 case TOK___CDECL:
5193 case TOK___CDECL__:
5194 ad->func_call = FUNC_CDECL;
5195 break;
5196 case TOK_STDCALL:
5197 case TOK___STDCALL:
5198 case TOK___STDCALL__:
5199 ad->func_call = FUNC_STDCALL;
5200 break;
5201 default:
5202 warning("'%s' attribute ignored", get_tok_str(t, NULL));
5203 /* skip parameters */
5204 /* XXX: skip parenthesis too */
5205 if (tok == '(') {
5206 next();
5207 while (tok != ')' && tok != -1)
5208 next();
5209 next();
5211 break;
5213 if (tok != ',')
5214 break;
5215 next();
5217 skip(')');
5218 skip(')');
5221 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5222 static void struct_decl(CType *type, int u)
5224 int a, v, size, align, maxalign, c, offset;
5225 int bit_size, bit_pos, bsize, bt, lbit_pos;
5226 Sym *s, *ss, **ps;
5227 AttributeDef ad;
5228 CType type1, btype;
5230 a = tok; /* save decl type */
5231 next();
5232 if (tok != '{') {
5233 v = tok;
5234 next();
5235 /* struct already defined ? return it */
5236 /* XXX: check consistency */
5237 s = struct_find(v);
5238 if (s) {
5239 if (s->type.t != a)
5240 error("invalid type");
5241 goto do_decl;
5243 } else {
5244 v = anon_sym++;
5246 type1.t = a;
5247 s = sym_push(v | SYM_STRUCT, &type1, 0, 0);
5248 /* put struct/union/enum name in type */
5249 do_decl:
5250 type->t = u;
5251 type->ref = s;
5253 if (tok == '{') {
5254 next();
5255 if (s->c)
5256 error("struct/union/enum already defined");
5257 /* cannot be empty */
5258 c = 0;
5259 maxalign = 0;
5260 ps = &s->next;
5261 bit_pos = 0;
5262 offset = 0;
5263 while (1) {
5264 if (a == TOK_ENUM) {
5265 v = tok;
5266 next();
5267 if (tok == '=') {
5268 next();
5269 c = expr_const();
5271 /* enum symbols have static storage */
5272 ss = sym_push(v, &int_type, VT_CONST, c);
5273 ss->type.t |= VT_STATIC;
5274 if (tok == ',')
5275 next();
5276 c++;
5277 } else {
5278 parse_btype(&btype, &ad);
5279 while (1) {
5280 bit_size = -1;
5281 v = 0;
5282 type1 = btype;
5283 if (tok != ':') {
5284 type_decl(&type1, &ad, &v, TYPE_DIRECT);
5285 if ((type1.t & VT_BTYPE) == VT_FUNC ||
5286 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
5287 error("invalid type for '%s'",
5288 get_tok_str(v, NULL));
5290 if (tok == ':') {
5291 next();
5292 bit_size = expr_const();
5293 /* XXX: handle v = 0 case for messages */
5294 if (bit_size < 0)
5295 error("negative width in bit-field '%s'",
5296 get_tok_str(v, NULL));
5297 if (v && bit_size == 0)
5298 error("zero width for bit-field '%s'",
5299 get_tok_str(v, NULL));
5301 size = type_size(&type1, &align);
5302 lbit_pos = 0;
5303 if (bit_size >= 0) {
5304 bt = type1.t & VT_BTYPE;
5305 if (bt != VT_INT &&
5306 bt != VT_BYTE &&
5307 bt != VT_SHORT)
5308 error("bitfields must have scalar type");
5309 bsize = size * 8;
5310 if (bit_size > bsize) {
5311 error("width of '%s' exceeds its type",
5312 get_tok_str(v, NULL));
5313 } else if (bit_size == bsize) {
5314 /* no need for bit fields */
5315 bit_pos = 0;
5316 } else if (bit_size == 0) {
5317 /* XXX: what to do if only padding in a
5318 structure ? */
5319 /* zero size: means to pad */
5320 if (bit_pos > 0)
5321 bit_pos = bsize;
5322 } else {
5323 /* we do not have enough room ? */
5324 if ((bit_pos + bit_size) > bsize)
5325 bit_pos = 0;
5326 lbit_pos = bit_pos;
5327 /* XXX: handle LSB first */
5328 type1.t |= VT_BITFIELD |
5329 (bit_pos << VT_STRUCT_SHIFT) |
5330 (bit_size << (VT_STRUCT_SHIFT + 6));
5331 bit_pos += bit_size;
5333 } else {
5334 bit_pos = 0;
5336 if (v) {
5337 /* add new memory data only if starting
5338 bit field */
5339 if (lbit_pos == 0) {
5340 if (a == TOK_STRUCT) {
5341 c = (c + align - 1) & -align;
5342 offset = c;
5343 c += size;
5344 } else {
5345 offset = 0;
5346 if (size > c)
5347 c = size;
5349 if (align > maxalign)
5350 maxalign = align;
5352 #if 0
5353 printf("add field %s offset=%d",
5354 get_tok_str(v, NULL), offset);
5355 if (type1.t & VT_BITFIELD) {
5356 printf(" pos=%d size=%d",
5357 (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
5358 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
5360 printf("\n");
5361 #endif
5362 ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
5363 *ps = ss;
5364 ps = &ss->next;
5366 if (tok == ';' || tok == -1)
5367 break;
5368 skip(',');
5370 skip(';');
5372 if (tok == '}')
5373 break;
5375 skip('}');
5376 /* size for struct/union, dummy for enum */
5377 s->c = (c + maxalign - 1) & -maxalign;
5381 /* return 0 if no type declaration. otherwise, return the basic type
5382 and skip it.
5384 static int parse_btype(CType *type, AttributeDef *ad)
5386 int t, u, type_found;
5387 Sym *s;
5388 CType type1;
5390 memset(ad, 0, sizeof(AttributeDef));
5391 type_found = 0;
5392 t = 0;
5393 while(1) {
5394 switch(tok) {
5395 /* basic types */
5396 case TOK_CHAR:
5397 u = VT_BYTE;
5398 basic_type:
5399 next();
5400 basic_type1:
5401 if ((t & VT_BTYPE) != 0)
5402 error("too many basic types");
5403 t |= u;
5404 break;
5405 case TOK_VOID:
5406 u = VT_VOID;
5407 goto basic_type;
5408 case TOK_SHORT:
5409 u = VT_SHORT;
5410 goto basic_type;
5411 case TOK_INT:
5412 next();
5413 break;
5414 case TOK_LONG:
5415 next();
5416 if ((t & VT_BTYPE) == VT_DOUBLE) {
5417 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5418 } else if ((t & VT_BTYPE) == VT_LONG) {
5419 t = (t & ~VT_BTYPE) | VT_LLONG;
5420 } else {
5421 u = VT_LONG;
5422 goto basic_type1;
5424 break;
5425 case TOK_BOOL:
5426 u = VT_BOOL;
5427 goto basic_type;
5428 case TOK_FLOAT:
5429 u = VT_FLOAT;
5430 goto basic_type;
5431 case TOK_DOUBLE:
5432 next();
5433 if ((t & VT_BTYPE) == VT_LONG) {
5434 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5435 } else {
5436 u = VT_DOUBLE;
5437 goto basic_type1;
5439 break;
5440 case TOK_ENUM:
5441 struct_decl(&type1, VT_ENUM);
5442 basic_type2:
5443 u = type1.t;
5444 type->ref = type1.ref;
5445 goto basic_type1;
5446 case TOK_STRUCT:
5447 case TOK_UNION:
5448 struct_decl(&type1, VT_STRUCT);
5449 goto basic_type2;
5451 /* type modifiers */
5452 case TOK_CONST:
5453 case TOK_VOLATILE:
5454 case TOK_REGISTER:
5455 case TOK_SIGNED:
5456 case TOK___SIGNED__:
5457 case TOK_AUTO:
5458 case TOK_INLINE:
5459 case TOK___INLINE__:
5460 case TOK_RESTRICT:
5461 next();
5462 break;
5463 case TOK_UNSIGNED:
5464 t |= VT_UNSIGNED;
5465 next();
5466 break;
5468 /* storage */
5469 case TOK_EXTERN:
5470 t |= VT_EXTERN;
5471 next();
5472 break;
5473 case TOK_STATIC:
5474 t |= VT_STATIC;
5475 next();
5476 break;
5477 case TOK_TYPEDEF:
5478 t |= VT_TYPEDEF;
5479 next();
5480 break;
5481 /* GNUC attribute */
5482 case TOK___ATTRIBUTE__:
5483 parse_attribute(ad);
5484 break;
5485 /* GNUC typeof */
5486 case TOK_TYPEOF:
5487 next();
5488 parse_expr_type(&type1);
5489 goto basic_type2;
5490 default:
5491 s = sym_find(tok);
5492 if (!s || !(s->type.t & VT_TYPEDEF))
5493 goto the_end;
5494 t |= (s->type.t & ~VT_TYPEDEF);
5495 type->ref = s->type.ref;
5496 next();
5497 break;
5499 type_found = 1;
5501 the_end:
5502 /* long is never used as type */
5503 if ((t & VT_BTYPE) == VT_LONG)
5504 t = (t & ~VT_BTYPE) | VT_INT;
5505 type->t = t;
5506 return type_found;
5509 static void post_type(CType *type, AttributeDef *ad)
5511 int n, l, t1;
5512 Sym **plast, *s, *first;
5513 AttributeDef ad1;
5514 CType pt;
5516 if (tok == '(') {
5517 /* function declaration */
5518 next();
5519 l = 0;
5520 first = NULL;
5521 plast = &first;
5522 while (tok != ')') {
5523 /* read param name and compute offset */
5524 if (l != FUNC_OLD) {
5525 if (!parse_btype(&pt, &ad1)) {
5526 if (l) {
5527 error("invalid type");
5528 } else {
5529 l = FUNC_OLD;
5530 goto old_proto;
5533 l = FUNC_NEW;
5534 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
5535 break;
5536 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
5537 if ((pt.t & VT_BTYPE) == VT_VOID)
5538 error("parameter declared as void");
5539 } else {
5540 old_proto:
5541 n = tok;
5542 pt.t = VT_INT;
5543 next();
5545 /* array must be transformed to pointer according to ANSI C */
5546 pt.t &= ~VT_ARRAY;
5547 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
5548 *plast = s;
5549 plast = &s->next;
5550 if (tok == ',') {
5551 next();
5552 if (l == FUNC_NEW && tok == TOK_DOTS) {
5553 l = FUNC_ELLIPSIS;
5554 next();
5555 break;
5559 /* if no parameters, then old type prototype */
5560 if (l == 0)
5561 l = FUNC_OLD;
5562 skip(')');
5563 t1 = type->t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5564 type->t &= ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5565 post_type(type, ad);
5566 /* we push a anonymous symbol which will contain the function prototype */
5567 s = sym_push(SYM_FIELD, type, ad->func_call, l);
5568 s->next = first;
5569 type->t = t1 | VT_FUNC;
5570 type->ref = s;
5571 } else if (tok == '[') {
5572 /* array definition */
5573 next();
5574 n = -1;
5575 if (tok != ']') {
5576 n = expr_const();
5577 if (n < 0)
5578 error("invalid array size");
5580 skip(']');
5581 /* parse next post type */
5582 t1 = type->t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5583 type->t &= ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5584 post_type(type, ad);
5586 /* we push a anonymous symbol which will contain the array
5587 element type */
5588 s = sym_push(SYM_FIELD, type, 0, n);
5589 type->t = t1 | VT_ARRAY | VT_PTR;
5590 type->ref = s;
5594 /* Parse a type declaration (except basic type), and return the type
5595 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5596 expected. 'type' should contain the basic type. 'ad' is the
5597 attribute definition of the basic type. It can be modified by
5598 type_decl().
5600 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
5602 Sym *s;
5603 CType type1, *type2;
5605 while (tok == '*') {
5606 next();
5607 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
5608 next();
5609 mk_pointer(type);
5612 /* recursive type */
5613 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5614 type1.t = 0; /* XXX: same as int */
5615 if (tok == '(') {
5616 next();
5617 /* XXX: this is not correct to modify 'ad' at this point, but
5618 the syntax is not clear */
5619 if (tok == TOK___ATTRIBUTE__)
5620 parse_attribute(ad);
5621 type_decl(&type1, ad, v, td);
5622 skip(')');
5623 } else {
5624 /* type identifier */
5625 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
5626 *v = tok;
5627 next();
5628 } else {
5629 if (!(td & TYPE_ABSTRACT))
5630 expect("identifier");
5631 *v = 0;
5634 post_type(type, ad);
5635 if (tok == TOK___ATTRIBUTE__)
5636 parse_attribute(ad);
5637 if (!type1.t)
5638 return;
5639 /* append type at the end of type1 */
5640 type2 = &type1;
5641 for(;;) {
5642 s = type2->ref;
5643 type2 = &s->type;
5644 if (!type2->t) {
5645 *type2 = *type;
5646 break;
5649 *type = type1;
5652 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5653 static int lvalue_type(int t)
5655 int bt, r;
5656 r = VT_LVAL;
5657 bt = t & VT_BTYPE;
5658 if (bt == VT_BYTE)
5659 r |= VT_LVAL_BYTE;
5660 else if (bt == VT_SHORT)
5661 r |= VT_LVAL_SHORT;
5662 else
5663 return r;
5664 if (t & VT_UNSIGNED)
5665 r |= VT_LVAL_UNSIGNED;
5666 return r;
5669 /* indirection with full error checking and bound check */
5670 static void indir(void)
5672 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
5673 expect("pointer");
5674 if ((vtop->r & VT_LVAL) && !nocode_wanted)
5675 gv(RC_INT);
5676 vtop->type = *pointed_type(&vtop->type);
5677 /* an array is never an lvalue */
5678 if (!(vtop->type.t & VT_ARRAY)) {
5679 vtop->r |= lvalue_type(vtop->type.t);
5680 /* if bound checking, the referenced pointer must be checked */
5681 if (do_bounds_check)
5682 vtop->r |= VT_MUSTBOUND;
5686 /* pass a parameter to a function and do type checking and casting */
5687 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
5689 int func_type;
5690 CType type;
5692 func_type = func->c;
5693 if (func_type == FUNC_OLD ||
5694 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
5695 /* default casting : only need to convert float to double */
5696 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
5697 type.t = VT_DOUBLE;
5698 gen_cast(&type);
5700 } else if (arg == NULL) {
5701 error("too many arguments to function");
5702 } else {
5703 gen_assign_cast(&arg->type);
5705 if (!nocode_wanted) {
5706 gfunc_param(gf);
5707 } else {
5708 vpop();
5712 /* parse an expression of the form '(type)' or '(expr)' and return its
5713 type */
5714 static void parse_expr_type(CType *type)
5716 int n;
5717 AttributeDef ad;
5719 skip('(');
5720 if (parse_btype(type, &ad)) {
5721 type_decl(type, &ad, &n, TYPE_ABSTRACT);
5722 } else {
5723 expr_type(type);
5725 skip(')');
5728 static void vpush_tokc(int t)
5730 CType type;
5731 type.t = t;
5732 vsetc(&type, VT_CONST, &tokc);
5735 static void unary(void)
5737 int n, t, align, size, r;
5738 CType type;
5739 Sym *s;
5740 GFuncContext gf;
5741 AttributeDef ad;
5743 if (tok == TOK_CINT || tok == TOK_CCHAR || tok == TOK_LCHAR) {
5744 vpushi(tokc.i);
5745 next();
5746 } else if (tok == TOK_CUINT) {
5747 vpush_tokc(VT_INT | VT_UNSIGNED);
5748 next();
5749 } else if (tok == TOK_CLLONG) {
5750 vpush_tokc(VT_LLONG);
5751 next();
5752 } else if (tok == TOK_CULLONG) {
5753 vpush_tokc(VT_LLONG | VT_UNSIGNED);
5754 next();
5755 } else if (tok == TOK_CFLOAT) {
5756 vpush_tokc(VT_FLOAT);
5757 next();
5758 } else if (tok == TOK_CDOUBLE) {
5759 vpush_tokc(VT_DOUBLE);
5760 next();
5761 } else if (tok == TOK_CLDOUBLE) {
5762 vpush_tokc(VT_LDOUBLE);
5763 next();
5764 } else if (tok == TOK___FUNC__ || (tok == TOK___FUNCTION__ && gnu_ext)) {
5765 void *ptr;
5766 int len;
5767 /* special function name identifier */
5769 len = strlen(funcname) + 1;
5770 /* generate char[len] type */
5771 type.t = VT_BYTE;
5772 mk_pointer(&type);
5773 type.t |= VT_ARRAY;
5774 type.ref->c = len;
5775 vpush_ref(&type, data_section, data_section->data_offset, len);
5776 ptr = section_ptr_add(data_section, len);
5777 memcpy(ptr, funcname, len);
5778 next();
5779 } else if (tok == TOK_LSTR) {
5780 t = VT_INT;
5781 goto str_init;
5782 } else if (tok == TOK_STR) {
5783 /* string parsing */
5784 t = VT_BYTE;
5785 str_init:
5786 type.t = t;
5787 mk_pointer(&type);
5788 type.t |= VT_ARRAY;
5789 memset(&ad, 0, sizeof(AttributeDef));
5790 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
5791 } else {
5792 t = tok;
5793 next();
5794 if (t == '(') {
5795 /* cast ? */
5796 if (parse_btype(&type, &ad)) {
5797 type_decl(&type, &ad, &n, TYPE_ABSTRACT);
5798 skip(')');
5799 /* check ISOC99 compound literal */
5800 if (tok == '{') {
5801 /* data is allocated locally by default */
5802 if (global_expr)
5803 r = VT_CONST;
5804 else
5805 r = VT_LOCAL;
5806 /* all except arrays are lvalues */
5807 if (!(type.t & VT_ARRAY))
5808 r |= lvalue_type(type.t);
5809 memset(&ad, 0, sizeof(AttributeDef));
5810 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
5811 } else {
5812 unary();
5813 gen_cast(&type);
5815 } else {
5816 gexpr();
5817 skip(')');
5819 } else if (t == '*') {
5820 unary();
5821 indir();
5822 } else if (t == '&') {
5823 unary();
5824 /* functions names must be treated as function pointers,
5825 except for unary '&' and sizeof. Since we consider that
5826 functions are not lvalues, we only have to handle it
5827 there and in function calls. */
5828 /* arrays can also be used although they are not lvalues */
5829 if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
5830 !(vtop->type.t & VT_ARRAY))
5831 test_lvalue();
5832 mk_pointer(&vtop->type);
5833 gaddrof();
5834 } else if (t == '!') {
5835 unary();
5836 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
5837 vtop->c.i = !vtop->c.i;
5838 else if ((vtop->r & VT_VALMASK) == VT_CMP)
5839 vtop->c.i = vtop->c.i ^ 1;
5840 else
5841 vseti(VT_JMP, gtst(1, 0));
5842 } else if (t == '~') {
5843 unary();
5844 vpushi(-1);
5845 gen_op('^');
5846 } else if (t == '+') {
5847 /* in order to force cast, we add zero */
5848 unary();
5849 if ((vtop->type.t & VT_BTYPE) == VT_PTR)
5850 error("pointer not accepted for unary plus");
5851 vpushi(0);
5852 gen_op('+');
5853 } else if (t == TOK_SIZEOF || t == TOK_ALIGNOF) {
5854 if (tok == '(') {
5855 parse_expr_type(&type);
5856 } else {
5857 unary_type(&type);
5859 size = type_size(&type, &align);
5860 if (t == TOK_SIZEOF)
5861 vpushi(size);
5862 else
5863 vpushi(align);
5864 } else if (t == TOK_INC || t == TOK_DEC) {
5865 unary();
5866 inc(0, t);
5867 } else if (t == '-') {
5868 vpushi(0);
5869 unary();
5870 gen_op('-');
5871 } else if (t == TOK_LAND && gnu_ext) {
5872 /* allow to take the address of a label */
5873 if (tok < TOK_UIDENT)
5874 expect("label identifier");
5875 s = label_find(tok);
5876 if (!s) {
5877 s = label_push(tok, LABEL_FORWARD);
5879 if (!s->type.t) {
5880 s->type.t = VT_VOID;
5881 mk_pointer(&s->type);
5882 s->type.t |= VT_STATIC;
5884 vset(&s->type, VT_CONST | VT_SYM, 0);
5885 vtop->sym = s;
5886 next();
5887 } else {
5888 if (t < TOK_UIDENT)
5889 expect("identifier");
5890 s = sym_find(t);
5891 if (!s) {
5892 if (tok != '(')
5893 error("'%s' undeclared", get_tok_str(t, NULL));
5894 /* for simple function calls, we tolerate undeclared
5895 external reference to int() function */
5896 s = external_global_sym(t, &func_old_type, 0);
5898 vset(&s->type, s->r, s->c);
5899 /* if forward reference, we must point to s */
5900 if (vtop->r & VT_SYM) {
5901 vtop->sym = s;
5902 vtop->c.ul = 0;
5907 /* post operations */
5908 while (1) {
5909 if (tok == TOK_INC || tok == TOK_DEC) {
5910 inc(1, tok);
5911 next();
5912 } else if (tok == '.' || tok == TOK_ARROW) {
5913 /* field */
5914 if (tok == TOK_ARROW)
5915 indir();
5916 test_lvalue();
5917 gaddrof();
5918 next();
5919 /* expect pointer on structure */
5920 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
5921 expect("struct or union");
5922 s = vtop->type.ref;
5923 /* find field */
5924 tok |= SYM_FIELD;
5925 while ((s = s->next) != NULL) {
5926 if (s->v == tok)
5927 break;
5929 if (!s)
5930 error("field not found");
5931 /* add field offset to pointer */
5932 vtop->type = char_pointer_type; /* change type to 'char *' */
5933 vpushi(s->c);
5934 gen_op('+');
5935 /* change type to field type, and set to lvalue */
5936 vtop->type = s->type;
5937 /* an array is never an lvalue */
5938 if (!(vtop->type.t & VT_ARRAY)) {
5939 vtop->r |= lvalue_type(vtop->type.t);
5940 /* if bound checking, the referenced pointer must be checked */
5941 if (do_bounds_check)
5942 vtop->r |= VT_MUSTBOUND;
5944 next();
5945 } else if (tok == '[') {
5946 next();
5947 gexpr();
5948 gen_op('+');
5949 indir();
5950 skip(']');
5951 } else if (tok == '(') {
5952 SValue ret;
5953 Sym *sa;
5955 /* function call */
5956 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
5957 /* pointer test (no array accepted) */
5958 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
5959 vtop->type = *pointed_type(&vtop->type);
5960 if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
5961 goto error_func;
5962 } else {
5963 error_func:
5964 expect("function pointer");
5966 } else {
5967 vtop->r &= ~VT_LVAL; /* no lvalue */
5969 /* get return type */
5970 s = vtop->type.ref;
5971 if (!nocode_wanted) {
5972 save_regs(0); /* save used temporary registers */
5973 gfunc_start(&gf, s->r);
5975 next();
5976 sa = s->next; /* first parameter */
5977 #ifdef INVERT_FUNC_PARAMS
5979 int parlevel;
5980 Sym *args, *s1;
5981 ParseState saved_parse_state;
5982 TokenString str;
5984 /* read each argument and store it on a stack */
5985 args = NULL;
5986 if (tok != ')') {
5987 for(;;) {
5988 tok_str_new(&str);
5989 parlevel = 0;
5990 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
5991 tok != TOK_EOF) {
5992 if (tok == '(')
5993 parlevel++;
5994 else if (tok == ')')
5995 parlevel--;
5996 tok_str_add_tok(&str);
5997 next();
5999 tok_str_add(&str, -1); /* end of file added */
6000 tok_str_add(&str, 0);
6001 s1 = sym_push2(&args, 0, 0, (int)str.str);
6002 s1->next = sa; /* add reference to argument */
6003 if (sa)
6004 sa = sa->next;
6005 if (tok == ')')
6006 break;
6007 skip(',');
6011 /* now generate code in reverse order by reading the stack */
6012 save_parse_state(&saved_parse_state);
6013 while (args) {
6014 macro_ptr = (int *)args->c;
6015 next();
6016 expr_eq();
6017 if (tok != -1)
6018 expect("',' or ')'");
6019 gfunc_param_typed(&gf, s, args->next);
6020 s1 = args->prev;
6021 tok_str_free((int *)args->c);
6022 tcc_free(args);
6023 args = s1;
6025 restore_parse_state(&saved_parse_state);
6027 #endif
6028 /* compute first implicit argument if a structure is returned */
6029 if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
6030 /* get some space for the returned structure */
6031 size = type_size(&s->type, &align);
6032 loc = (loc - size) & -align;
6033 ret.type = s->type;
6034 ret.r = VT_LOCAL | VT_LVAL;
6035 /* pass it as 'int' to avoid structure arg passing
6036 problems */
6037 vseti(VT_LOCAL, loc);
6038 ret.c = vtop->c;
6039 if (!nocode_wanted)
6040 gfunc_param(&gf);
6041 else
6042 vtop--;
6043 } else {
6044 ret.type = s->type;
6045 ret.r2 = VT_CONST;
6046 /* return in register */
6047 if (is_float(ret.type.t)) {
6048 ret.r = REG_FRET;
6049 } else {
6050 if ((ret.type.t & VT_BTYPE) == VT_LLONG)
6051 ret.r2 = REG_LRET;
6052 ret.r = REG_IRET;
6054 ret.c.i = 0;
6056 #ifndef INVERT_FUNC_PARAMS
6057 if (tok != ')') {
6058 for(;;) {
6059 expr_eq();
6060 gfunc_param_typed(&gf, s, sa);
6061 if (sa)
6062 sa = sa->next;
6063 if (tok == ')')
6064 break;
6065 skip(',');
6068 #endif
6069 if (sa)
6070 error("too few arguments to function");
6071 skip(')');
6072 if (!nocode_wanted)
6073 gfunc_call(&gf);
6074 else
6075 vtop--;
6076 /* return value */
6077 vsetc(&ret.type, ret.r, &ret.c);
6078 vtop->r2 = ret.r2;
6079 } else {
6080 break;
6085 static void uneq(void)
6087 int t;
6089 unary();
6090 if (tok == '=' ||
6091 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
6092 tok == TOK_A_XOR || tok == TOK_A_OR ||
6093 tok == TOK_A_SHL || tok == TOK_A_SAR) {
6094 test_lvalue();
6095 t = tok;
6096 next();
6097 if (t == '=') {
6098 expr_eq();
6099 } else {
6100 vdup();
6101 expr_eq();
6102 gen_op(t & 0x7f);
6104 vstore();
6108 static void sum(int l)
6110 int t;
6112 if (l == 0)
6113 uneq();
6114 else {
6115 sum(--l);
6116 while ((l == 0 && (tok == '*' || tok == '/' || tok == '%')) ||
6117 (l == 1 && (tok == '+' || tok == '-')) ||
6118 (l == 2 && (tok == TOK_SHL || tok == TOK_SAR)) ||
6119 (l == 3 && ((tok >= TOK_ULE && tok <= TOK_GT) ||
6120 tok == TOK_ULT || tok == TOK_UGE)) ||
6121 (l == 4 && (tok == TOK_EQ || tok == TOK_NE)) ||
6122 (l == 5 && tok == '&') ||
6123 (l == 6 && tok == '^') ||
6124 (l == 7 && tok == '|') ||
6125 (l == 8 && tok == TOK_LAND) ||
6126 (l == 9 && tok == TOK_LOR)) {
6127 t = tok;
6128 next();
6129 sum(l);
6130 gen_op(t);
6135 /* only used if non constant */
6136 static void eand(void)
6138 int t;
6140 sum(8);
6141 t = 0;
6142 while (1) {
6143 if (tok != TOK_LAND) {
6144 if (t) {
6145 t = gtst(1, t);
6146 vseti(VT_JMPI, t);
6148 break;
6150 t = gtst(1, t);
6151 next();
6152 sum(8);
6156 static void eor(void)
6158 int t;
6160 eand();
6161 t = 0;
6162 while (1) {
6163 if (tok != TOK_LOR) {
6164 if (t) {
6165 t = gtst(0, t);
6166 vseti(VT_JMP, t);
6168 break;
6170 t = gtst(0, t);
6171 next();
6172 eand();
6176 /* XXX: better constant handling */
6177 static void expr_eq(void)
6179 int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
6180 SValue sv;
6181 CType type, type1, type2;
6183 if (const_wanted) {
6184 int c1, c;
6185 sum(10);
6186 if (tok == '?') {
6187 c = vtop->c.i;
6188 vpop();
6189 next();
6190 gexpr();
6191 c1 = vtop->c.i;
6192 vpop();
6193 skip(':');
6194 expr_eq();
6195 if (c)
6196 vtop->c.i = c1;
6198 } else {
6199 eor();
6200 if (tok == '?') {
6201 next();
6202 save_regs(1); /* we need to save all registers here except
6203 at the top because it is a branch point */
6204 tt = gtst(1, 0);
6205 gexpr();
6206 type1 = vtop->type;
6207 sv = *vtop; /* save value to handle it later */
6208 vtop--; /* no vpop so that FP stack is not flushed */
6209 skip(':');
6210 u = gjmp(0);
6212 gsym(tt);
6213 expr_eq();
6214 type2 = vtop->type;
6216 t1 = type1.t;
6217 bt1 = t1 & VT_BTYPE;
6218 t2 = type2.t;
6219 bt2 = t2 & VT_BTYPE;
6220 /* cast operands to correct type according to ISOC rules */
6221 if (is_float(bt1) || is_float(bt2)) {
6222 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
6223 type.t = VT_LDOUBLE;
6224 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
6225 type.t = VT_DOUBLE;
6226 } else {
6227 type.t = VT_FLOAT;
6229 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
6230 /* cast to biggest op */
6231 type.t = VT_LLONG;
6232 /* convert to unsigned if it does not fit in a long long */
6233 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
6234 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
6235 type.t |= VT_UNSIGNED;
6236 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
6237 /* XXX: test pointer compatibility */
6238 type = type1;
6239 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
6240 /* XXX: test structure compatibility */
6241 type = type1;
6242 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
6243 /* NOTE: as an extension, we accept void on only one side */
6244 type.t = VT_VOID;
6245 } else {
6246 /* integer operations */
6247 type.t = VT_INT;
6248 /* convert to unsigned if it does not fit in an integer */
6249 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
6250 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
6251 type.t |= VT_UNSIGNED;
6254 /* now we convert second operand */
6255 gen_cast(&type);
6256 rc = RC_INT;
6257 if (is_float(type.t)) {
6258 rc = RC_FLOAT;
6259 } else if ((type.t & VT_BTYPE) == VT_LLONG) {
6260 /* for long longs, we use fixed registers to avoid having
6261 to handle a complicated move */
6262 rc = RC_IRET;
6264 r2 = gv(rc);
6265 /* this is horrible, but we must also convert first
6266 operand */
6267 tt = gjmp(0);
6268 gsym(u);
6269 /* put again first value and cast it */
6270 *vtop = sv;
6271 gen_cast(&type);
6272 r1 = gv(rc);
6273 move_reg(r2, r1);
6274 vtop->r = r2;
6275 gsym(tt);
6280 static void gexpr(void)
6282 while (1) {
6283 expr_eq();
6284 if (tok != ',')
6285 break;
6286 vpop();
6287 next();
6291 /* parse an expression and return its type without any side effect. */
6292 static void expr_type(CType *type)
6294 int a;
6296 a = nocode_wanted;
6297 nocode_wanted = 1;
6298 gexpr();
6299 *type = vtop->type;
6300 vpop();
6301 nocode_wanted = a;
6304 /* parse a unary expression and return its type without any side
6305 effect. */
6306 static void unary_type(CType *type)
6308 int a;
6310 a = nocode_wanted;
6311 nocode_wanted = 1;
6312 unary();
6313 *type = vtop->type;
6314 vpop();
6315 nocode_wanted = a;
6318 /* parse a constant expression and return value in vtop. */
6319 static void expr_const1(void)
6321 int a;
6322 a = const_wanted;
6323 const_wanted = 1;
6324 expr_eq();
6325 const_wanted = a;
6328 /* parse an integer constant and return its value. */
6329 static int expr_const(void)
6331 int c;
6332 expr_const1();
6333 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
6334 expect("constant expression");
6335 c = vtop->c.i;
6336 vpop();
6337 return c;
6340 /* return the label token if current token is a label, otherwise
6341 return zero */
6342 static int is_label(void)
6344 int t;
6345 CValue c;
6347 /* fast test first */
6348 if (tok < TOK_UIDENT)
6349 return 0;
6350 /* no need to save tokc since we expect an identifier */
6351 t = tok;
6352 c = tokc;
6353 next();
6354 if (tok == ':') {
6355 next();
6356 return t;
6357 } else {
6358 /* XXX: may not work in all cases (macros ?) */
6359 tok1 = tok;
6360 tok1c = tokc;
6361 tok = t;
6362 tokc = c;
6363 return 0;
6367 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
6369 int a, b, c, d;
6370 Sym *s;
6372 /* generate line number info */
6373 if (do_debug &&
6374 (last_line_num != file->line_num || last_ind != ind)) {
6375 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
6376 last_ind = ind;
6377 last_line_num = file->line_num;
6380 if (tok == TOK_IF) {
6381 /* if test */
6382 next();
6383 skip('(');
6384 gexpr();
6385 skip(')');
6386 a = gtst(1, 0);
6387 block(bsym, csym, case_sym, def_sym, case_reg);
6388 c = tok;
6389 if (c == TOK_ELSE) {
6390 next();
6391 d = gjmp(0);
6392 gsym(a);
6393 block(bsym, csym, case_sym, def_sym, case_reg);
6394 gsym(d); /* patch else jmp */
6395 } else
6396 gsym(a);
6397 } else if (tok == TOK_WHILE) {
6398 next();
6399 d = ind;
6400 skip('(');
6401 gexpr();
6402 skip(')');
6403 a = gtst(1, 0);
6404 b = 0;
6405 block(&a, &b, case_sym, def_sym, case_reg);
6406 gjmp_addr(d);
6407 gsym(a);
6408 gsym_addr(b, d);
6409 } else if (tok == '{') {
6410 next();
6411 /* declarations */
6412 s = local_stack;
6413 while (tok != '}') {
6414 decl(VT_LOCAL);
6415 if (tok != '}')
6416 block(bsym, csym, case_sym, def_sym, case_reg);
6418 /* pop locally defined symbols */
6419 sym_pop(&local_stack, s);
6420 next();
6421 } else if (tok == TOK_RETURN) {
6422 next();
6423 if (tok != ';') {
6424 gexpr();
6425 gen_assign_cast(&func_vt);
6426 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
6427 CType type;
6428 /* if returning structure, must copy it to implicit
6429 first pointer arg location */
6430 type = func_vt;
6431 mk_pointer(&type);
6432 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
6433 indir();
6434 vswap();
6435 /* copy structure value to pointer */
6436 vstore();
6437 } else if (is_float(func_vt.t)) {
6438 gv(RC_FRET);
6439 } else {
6440 gv(RC_IRET);
6442 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
6444 skip(';');
6445 rsym = gjmp(rsym); /* jmp */
6446 } else if (tok == TOK_BREAK) {
6447 /* compute jump */
6448 if (!bsym)
6449 error("cannot break");
6450 *bsym = gjmp(*bsym);
6451 next();
6452 skip(';');
6453 } else if (tok == TOK_CONTINUE) {
6454 /* compute jump */
6455 if (!csym)
6456 error("cannot continue");
6457 *csym = gjmp(*csym);
6458 next();
6459 skip(';');
6460 } else if (tok == TOK_FOR) {
6461 int e;
6462 next();
6463 skip('(');
6464 if (tok != ';') {
6465 gexpr();
6466 vpop();
6468 skip(';');
6469 d = ind;
6470 c = ind;
6471 a = 0;
6472 b = 0;
6473 if (tok != ';') {
6474 gexpr();
6475 a = gtst(1, 0);
6477 skip(';');
6478 if (tok != ')') {
6479 e = gjmp(0);
6480 c = ind;
6481 gexpr();
6482 vpop();
6483 gjmp_addr(d);
6484 gsym(e);
6486 skip(')');
6487 block(&a, &b, case_sym, def_sym, case_reg);
6488 gjmp_addr(c);
6489 gsym(a);
6490 gsym_addr(b, c);
6491 } else
6492 if (tok == TOK_DO) {
6493 next();
6494 a = 0;
6495 b = 0;
6496 d = ind;
6497 block(&a, &b, case_sym, def_sym, case_reg);
6498 skip(TOK_WHILE);
6499 skip('(');
6500 gsym(b);
6501 gexpr();
6502 c = gtst(0, 0);
6503 gsym_addr(c, d);
6504 skip(')');
6505 gsym(a);
6506 skip(';');
6507 } else
6508 if (tok == TOK_SWITCH) {
6509 next();
6510 skip('(');
6511 gexpr();
6512 /* XXX: other types than integer */
6513 case_reg = gv(RC_INT);
6514 vpop();
6515 skip(')');
6516 a = 0;
6517 b = gjmp(0); /* jump to first case */
6518 c = 0;
6519 block(&a, csym, &b, &c, case_reg);
6520 /* if no default, jmp after switch */
6521 if (c == 0)
6522 c = ind;
6523 /* default label */
6524 gsym_addr(b, c);
6525 /* break label */
6526 gsym(a);
6527 } else
6528 if (tok == TOK_CASE) {
6529 int v1, v2;
6530 if (!case_sym)
6531 expect("switch");
6532 next();
6533 v1 = expr_const();
6534 v2 = v1;
6535 if (gnu_ext && tok == TOK_DOTS) {
6536 next();
6537 v2 = expr_const();
6538 if (v2 < v1)
6539 warning("empty case range");
6541 /* since a case is like a label, we must skip it with a jmp */
6542 b = gjmp(0);
6543 gsym(*case_sym);
6544 vseti(case_reg, 0);
6545 vpushi(v1);
6546 if (v1 == v2) {
6547 gen_op(TOK_EQ);
6548 *case_sym = gtst(1, 0);
6549 } else {
6550 gen_op(TOK_GE);
6551 *case_sym = gtst(1, 0);
6552 vseti(case_reg, 0);
6553 vpushi(v2);
6554 gen_op(TOK_LE);
6555 *case_sym = gtst(1, *case_sym);
6557 gsym(b);
6558 skip(':');
6559 block(bsym, csym, case_sym, def_sym, case_reg);
6560 } else
6561 if (tok == TOK_DEFAULT) {
6562 next();
6563 skip(':');
6564 if (!def_sym)
6565 expect("switch");
6566 if (*def_sym)
6567 error("too many 'default'");
6568 *def_sym = ind;
6569 block(bsym, csym, case_sym, def_sym, case_reg);
6570 } else
6571 if (tok == TOK_GOTO) {
6572 next();
6573 if (tok == '*' && gnu_ext) {
6574 /* computed goto */
6575 next();
6576 gexpr();
6577 if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6578 expect("pointer");
6579 ggoto();
6580 } else if (tok >= TOK_UIDENT) {
6581 s = label_find(tok);
6582 /* put forward definition if needed */
6583 if (!s) {
6584 s = label_push(tok, LABEL_FORWARD);
6586 /* label already defined */
6587 if (s->r & LABEL_FORWARD)
6588 s->next = (void *)gjmp((long)s->next);
6589 else
6590 gjmp_addr((long)s->next);
6591 next();
6592 } else {
6593 expect("label identifier");
6595 skip(';');
6596 } else {
6597 b = is_label();
6598 if (b) {
6599 /* label case */
6600 s = label_find(b);
6601 if (s) {
6602 if (!(s->r & LABEL_FORWARD))
6603 error("multiple defined label");
6604 gsym((long)s->next);
6605 } else {
6606 s = label_push(b, 0);
6608 s->next = (void *)ind;
6609 s->r = 0;
6610 /* we accept this, but it is a mistake */
6611 if (tok == '}')
6612 warning("deprecated use of label at end of compound statement");
6613 else
6614 block(bsym, csym, case_sym, def_sym, case_reg);
6615 } else {
6616 /* expression case */
6617 if (tok != ';') {
6618 gexpr();
6619 vpop();
6621 skip(';');
6626 /* t is the array or struct type. c is the array or struct
6627 address. cur_index/cur_field is the pointer to the current
6628 value. 'size_only' is true if only size info is needed (only used
6629 in arrays) */
6630 static void decl_designator(CType *type, Section *sec, unsigned long c,
6631 int *cur_index, Sym **cur_field,
6632 int size_only)
6634 Sym *s, *f;
6635 int notfirst, index, align, l;
6636 CType type1;
6638 notfirst = 0;
6639 if (gnu_ext && (l = is_label()) != 0)
6640 goto struct_field;
6642 while (tok == '[' || tok == '.') {
6643 if (tok == '[') {
6644 if (!(type->t & VT_ARRAY))
6645 expect("array type");
6646 s = type->ref;
6647 next();
6648 index = expr_const();
6649 if (index < 0 || (s->c >= 0 && index >= s->c))
6650 expect("invalid index");
6651 skip(']');
6652 if (!notfirst)
6653 *cur_index = index;
6654 type = pointed_type(type);
6655 c += index * type_size(type, &align);
6656 } else {
6657 next();
6658 l = tok;
6659 next();
6660 struct_field:
6661 if ((type->t & VT_BTYPE) != VT_STRUCT)
6662 expect("struct/union type");
6663 s = type->ref;
6664 l |= SYM_FIELD;
6665 f = s->next;
6666 while (f) {
6667 if (f->v == l)
6668 break;
6669 f = f->next;
6671 if (!f)
6672 expect("field");
6673 if (!notfirst)
6674 *cur_field = f;
6675 /* XXX: suppress this mess by using explicit storage field */
6676 type1 = f->type;
6677 type1.t |= (type->t & ~VT_TYPE);
6678 type = &type1;
6679 c += f->c;
6681 notfirst = 1;
6683 if (notfirst) {
6684 if (tok == '=') {
6685 next();
6686 } else {
6687 if (!gnu_ext)
6688 expect("=");
6690 } else {
6691 if (type->t & VT_ARRAY) {
6692 index = *cur_index;
6693 type = pointed_type(type);
6694 c += index * type_size(type, &align);
6695 } else {
6696 f = *cur_field;
6697 if (!f)
6698 error("too many field init");
6699 /* XXX: suppress this mess by using explicit storage field */
6700 type1 = f->type;
6701 type1.t |= (type->t & ~VT_TYPE);
6702 type = &type1;
6703 c += f->c;
6706 decl_initializer(type, sec, c, 0, size_only);
6709 #define EXPR_VAL 0
6710 #define EXPR_CONST 1
6711 #define EXPR_ANY 2
6713 /* store a value or an expression directly in global data or in local array */
6714 static void init_putv(CType *type, Section *sec, unsigned long c,
6715 int v, int expr_type)
6717 int saved_global_expr, bt;
6718 void *ptr;
6720 switch(expr_type) {
6721 case EXPR_VAL:
6722 vpushi(v);
6723 break;
6724 case EXPR_CONST:
6725 /* compound literals must be allocated globally in this case */
6726 saved_global_expr = global_expr;
6727 global_expr = 1;
6728 expr_const1();
6729 global_expr = saved_global_expr;
6730 /* NOTE: symbols are accepted */
6731 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
6732 error("initializer element is not constant");
6733 break;
6734 case EXPR_ANY:
6735 expr_eq();
6736 break;
6739 if (sec) {
6740 /* XXX: not portable */
6741 /* XXX: generate error if incorrect relocation */
6742 gen_assign_cast(type);
6743 bt = type->t & VT_BTYPE;
6744 ptr = sec->data + c;
6745 if ((vtop->r & VT_SYM) &&
6746 (bt == VT_BYTE ||
6747 bt == VT_SHORT ||
6748 bt == VT_DOUBLE ||
6749 bt == VT_LDOUBLE ||
6750 bt == VT_LLONG))
6751 error("initializer element is not computable at load time");
6752 switch(bt) {
6753 case VT_BYTE:
6754 *(char *)ptr = vtop->c.i;
6755 break;
6756 case VT_SHORT:
6757 *(short *)ptr = vtop->c.i;
6758 break;
6759 case VT_DOUBLE:
6760 *(double *)ptr = vtop->c.d;
6761 break;
6762 case VT_LDOUBLE:
6763 *(long double *)ptr = vtop->c.ld;
6764 break;
6765 case VT_LLONG:
6766 *(long long *)ptr = vtop->c.ll;
6767 break;
6768 default:
6769 if (vtop->r & VT_SYM) {
6770 greloc(sec, vtop->sym, c, R_DATA_32);
6772 *(int *)ptr = vtop->c.i;
6773 break;
6775 vtop--;
6776 } else {
6777 vset(type, VT_LOCAL, c);
6778 vswap();
6779 vstore();
6780 vpop();
6784 /* put zeros for variable based init */
6785 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
6787 GFuncContext gf;
6789 if (sec) {
6790 /* nothing to do because globals are already set to zero */
6791 } else {
6792 gfunc_start(&gf, FUNC_CDECL);
6793 vpushi(size);
6794 gfunc_param(&gf);
6795 vpushi(0);
6796 gfunc_param(&gf);
6797 vseti(VT_LOCAL, c);
6798 gfunc_param(&gf);
6799 vpush_global_sym(&func_old_type, TOK_memset);
6800 gfunc_call(&gf);
6804 /* 't' contains the type and storage info. 'c' is the offset of the
6805 object in section 'sec'. If 'sec' is NULL, it means stack based
6806 allocation. 'first' is true if array '{' must be read (multi
6807 dimension implicit array init handling). 'size_only' is true if
6808 size only evaluation is wanted (only for arrays). */
6809 static void decl_initializer(CType *type, Section *sec, unsigned long c,
6810 int first, int size_only)
6812 int index, array_length, n, no_oblock, nb, parlevel, i;
6813 int size1, align1, expr_type;
6814 Sym *s, *f;
6815 CType *t1;
6817 if (type->t & VT_ARRAY) {
6818 s = type->ref;
6819 n = s->c;
6820 array_length = 0;
6821 t1 = pointed_type(type);
6822 size1 = type_size(t1, &align1);
6824 no_oblock = 1;
6825 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
6826 tok == '{') {
6827 skip('{');
6828 no_oblock = 0;
6831 /* only parse strings here if correct type (otherwise: handle
6832 them as ((w)char *) expressions */
6833 if ((tok == TOK_LSTR &&
6834 (t1->t & VT_BTYPE) == VT_INT) ||
6835 (tok == TOK_STR &&
6836 (t1->t & VT_BTYPE) == VT_BYTE)) {
6837 while (tok == TOK_STR || tok == TOK_LSTR) {
6838 int cstr_len, ch;
6839 CString *cstr;
6841 cstr = tokc.cstr;
6842 /* compute maximum number of chars wanted */
6843 if (tok == TOK_STR)
6844 cstr_len = cstr->size;
6845 else
6846 cstr_len = cstr->size / sizeof(int);
6847 cstr_len--;
6848 nb = cstr_len;
6849 if (n >= 0 && nb > (n - array_length))
6850 nb = n - array_length;
6851 if (!size_only) {
6852 if (cstr_len > nb)
6853 warning("initializer-string for array is too long");
6854 /* in order to go faster for common case (char
6855 string in global variable, we handle it
6856 specifically */
6857 if (sec && tok == TOK_STR && size1 == 1) {
6858 memcpy(sec->data + c + array_length, cstr->data, nb);
6859 } else {
6860 for(i=0;i<nb;i++) {
6861 if (tok == TOK_STR)
6862 ch = ((unsigned char *)cstr->data)[i];
6863 else
6864 ch = ((int *)cstr->data)[i];
6865 init_putv(t1, sec, c + (array_length + i) * size1,
6866 ch, EXPR_VAL);
6870 array_length += nb;
6871 next();
6873 /* only add trailing zero if enough storage (no
6874 warning in this case since it is standard) */
6875 if (n < 0 || array_length < n) {
6876 if (!size_only) {
6877 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
6879 array_length++;
6881 } else {
6882 index = 0;
6883 while (tok != '}') {
6884 decl_designator(type, sec, c, &index, NULL, size_only);
6885 if (n >= 0 && index >= n)
6886 error("index too large");
6887 /* must put zero in holes (note that doing it that way
6888 ensures that it even works with designators) */
6889 if (!size_only && array_length < index) {
6890 init_putz(t1, sec, c + array_length * size1,
6891 (index - array_length) * size1);
6893 index++;
6894 if (index > array_length)
6895 array_length = index;
6896 /* special test for multi dimensional arrays (may not
6897 be strictly correct if designators are used at the
6898 same time) */
6899 if (index >= n && no_oblock)
6900 break;
6901 if (tok == '}')
6902 break;
6903 skip(',');
6906 if (!no_oblock)
6907 skip('}');
6908 /* put zeros at the end */
6909 if (!size_only && n >= 0 && array_length < n) {
6910 init_putz(t1, sec, c + array_length * size1,
6911 (n - array_length) * size1);
6913 /* patch type size if needed */
6914 if (n < 0)
6915 s->c = array_length;
6916 } else if ((type->t & VT_BTYPE) == VT_STRUCT && tok == '{') {
6917 /* XXX: union needs only one init */
6918 next();
6919 s = type->ref;
6920 f = s->next;
6921 array_length = 0;
6922 index = 0;
6923 n = s->c;
6924 while (tok != '}') {
6925 decl_designator(type, sec, c, NULL, &f, size_only);
6926 /* fill with zero between fields */
6927 index = f->c;
6928 if (!size_only && array_length < index) {
6929 init_putz(type, sec, c + array_length,
6930 index - array_length);
6932 index = index + type_size(&f->type, &align1);
6933 if (index > array_length)
6934 array_length = index;
6935 if (tok == '}')
6936 break;
6937 skip(',');
6938 f = f->next;
6940 /* put zeros at the end */
6941 if (!size_only && array_length < n) {
6942 init_putz(type, sec, c + array_length,
6943 n - array_length);
6945 skip('}');
6946 } else if (tok == '{') {
6947 next();
6948 decl_initializer(type, sec, c, first, size_only);
6949 skip('}');
6950 } else if (size_only) {
6951 /* just skip expression */
6952 parlevel = 0;
6953 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
6954 tok != -1) {
6955 if (tok == '(')
6956 parlevel++;
6957 else if (tok == ')')
6958 parlevel--;
6959 next();
6961 } else {
6962 /* currently, we always use constant expression for globals
6963 (may change for scripting case) */
6964 expr_type = EXPR_CONST;
6965 if (!sec)
6966 expr_type = EXPR_ANY;
6967 init_putv(type, sec, c, 0, expr_type);
6971 /* parse an initializer for type 't' if 'has_init' is non zero, and
6972 allocate space in local or global data space ('r' is either
6973 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6974 variable 'v' of scope 'scope' is declared before initializers are
6975 parsed. If 'v' is zero, then a reference to the new object is put
6976 in the value stack. If 'has_init' is 2, a special parsing is done
6977 to handle string constants. */
6978 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
6979 int has_init, int v, int scope)
6981 int size, align, addr, data_offset;
6982 int level;
6983 ParseState saved_parse_state;
6984 TokenString init_str;
6985 Section *sec;
6987 size = type_size(type, &align);
6988 /* If unknown size, we must evaluate it before
6989 evaluating initializers because
6990 initializers can generate global data too
6991 (e.g. string pointers or ISOC99 compound
6992 literals). It also simplifies local
6993 initializers handling */
6994 tok_str_new(&init_str);
6995 if (size < 0) {
6996 if (!has_init)
6997 error("unknown type size");
6998 /* get all init string */
6999 if (has_init == 2) {
7000 /* only get strings */
7001 while (tok == TOK_STR || tok == TOK_LSTR) {
7002 tok_str_add_tok(&init_str);
7003 next();
7005 } else {
7006 level = 0;
7007 while (level > 0 || (tok != ',' && tok != ';')) {
7008 if (tok < 0)
7009 error("unexpected end of file in initializer");
7010 tok_str_add_tok(&init_str);
7011 if (tok == '{')
7012 level++;
7013 else if (tok == '}') {
7014 if (level == 0)
7015 break;
7016 level--;
7018 next();
7021 tok_str_add(&init_str, -1);
7022 tok_str_add(&init_str, 0);
7024 /* compute size */
7025 save_parse_state(&saved_parse_state);
7027 macro_ptr = init_str.str;
7028 next();
7029 decl_initializer(type, NULL, 0, 1, 1);
7030 /* prepare second initializer parsing */
7031 macro_ptr = init_str.str;
7032 next();
7034 /* if still unknown size, error */
7035 size = type_size(type, &align);
7036 if (size < 0)
7037 error("unknown type size");
7039 /* take into account specified alignment if bigger */
7040 if (ad->aligned > align)
7041 align = ad->aligned;
7042 if ((r & VT_VALMASK) == VT_LOCAL) {
7043 sec = NULL;
7044 if (do_bounds_check && (type->t & VT_ARRAY))
7045 loc--;
7046 #ifdef TCC_TARGET_IL
7047 /* XXX: ugly patch to allocate local variables for IL, just
7048 for testing */
7049 addr = loc;
7050 loc++;
7051 #else
7052 loc = (loc - size) & -align;
7053 addr = loc;
7054 #endif
7055 /* handles bounds */
7056 /* XXX: currently, since we do only one pass, we cannot track
7057 '&' operators, so we add only arrays */
7058 if (do_bounds_check && (type->t & VT_ARRAY)) {
7059 unsigned long *bounds_ptr;
7060 /* add padding between regions */
7061 loc--;
7062 /* then add local bound info */
7063 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
7064 bounds_ptr[0] = addr;
7065 bounds_ptr[1] = size;
7067 } else {
7068 /* compute section */
7069 sec = ad->section;
7070 if (!sec) {
7071 if (has_init)
7072 sec = data_section;
7073 else
7074 sec = bss_section;
7076 data_offset = sec->data_offset;
7077 data_offset = (data_offset + align - 1) & -align;
7078 addr = data_offset;
7079 /* very important to increment global pointer at this time
7080 because initializers themselves can create new initializers */
7081 data_offset += size;
7082 /* add padding if bound check */
7083 if (do_bounds_check)
7084 data_offset++;
7085 sec->data_offset = data_offset;
7086 /* allocate section space to put the data */
7087 if (sec->sh_type != SHT_NOBITS &&
7088 data_offset > sec->data_allocated)
7089 section_realloc(sec, data_offset);
7091 if (!sec) {
7092 if (v) {
7093 /* local variable */
7094 sym_push(v, type, r, addr);
7095 } else {
7096 /* push local reference */
7097 vset(type, r, addr);
7099 } else {
7100 Sym *sym;
7102 if (v) {
7103 if (scope == VT_CONST) {
7104 /* global scope: see if already defined */
7105 sym = sym_find(v);
7106 if (!sym)
7107 goto do_def;
7108 if (!is_compatible_types(&sym->type, type))
7109 error("incompatible types for redefinition of '%s'",
7110 get_tok_str(v, NULL));
7111 if (!(sym->type.t & VT_EXTERN))
7112 error("redefinition of '%s'", get_tok_str(v, NULL));
7113 sym->type.t &= ~VT_EXTERN;
7114 } else {
7115 do_def:
7116 sym = sym_push(v, type, r | VT_SYM, 0);
7118 put_extern_sym(sym, sec, addr, size);
7119 } else {
7120 CValue cval;
7122 /* push global reference */
7123 sym = get_sym_ref(type, sec, addr, size);
7124 cval.ul = 0;
7125 vsetc(type, VT_CONST | VT_SYM, &cval);
7126 vtop->sym = sym;
7129 /* handles bounds now because the symbol must be defined
7130 before for the relocation */
7131 if (do_bounds_check) {
7132 unsigned long *bounds_ptr;
7134 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
7135 /* then add global bound info */
7136 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
7137 bounds_ptr[0] = 0; /* relocated */
7138 bounds_ptr[1] = size;
7141 if (has_init) {
7142 decl_initializer(type, sec, addr, 1, 0);
7143 /* restore parse state if needed */
7144 if (init_str.str) {
7145 tok_str_free(init_str.str);
7146 restore_parse_state(&saved_parse_state);
7151 void put_func_debug(Sym *sym)
7153 char buf[512];
7155 /* stabs info */
7156 /* XXX: we put here a dummy type */
7157 snprintf(buf, sizeof(buf), "%s:%c1",
7158 funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
7159 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
7160 cur_text_section, sym->c);
7161 last_ind = 0;
7162 last_line_num = 0;
7165 /* not finished : try to put some local vars in registers */
7166 //#define CONFIG_REG_VARS
7168 #ifdef CONFIG_REG_VARS
7169 void add_var_ref(int t)
7171 printf("%s:%d: &%s\n",
7172 file->filename, file->line_num,
7173 get_tok_str(t, NULL));
7176 /* first pass on a function with heuristic to extract variable usage
7177 and pointer references to local variables for register allocation */
7178 void analyse_function(void)
7180 int level, t;
7182 for(;;) {
7183 if (tok == -1)
7184 break;
7185 /* any symbol coming after '&' is considered as being a
7186 variable whose reference is taken. It is highly unaccurate
7187 but it is difficult to do better without a complete parse */
7188 if (tok == '&') {
7189 next();
7190 /* if '& number', then no need to examine next tokens */
7191 if (tok == TOK_CINT ||
7192 tok == TOK_CUINT ||
7193 tok == TOK_CLLONG ||
7194 tok == TOK_CULLONG) {
7195 continue;
7196 } else if (tok >= TOK_UIDENT) {
7197 /* if '& ident [' or '& ident ->', then ident address
7198 is not needed */
7199 t = tok;
7200 next();
7201 if (tok != '[' && tok != TOK_ARROW)
7202 add_var_ref(t);
7203 } else {
7204 level = 0;
7205 while (tok != '}' && tok != ';' &&
7206 !((tok == ',' || tok == ')') && level == 0)) {
7207 if (tok >= TOK_UIDENT) {
7208 add_var_ref(tok);
7209 } else if (tok == '(') {
7210 level++;
7211 } else if (tok == ')') {
7212 level--;
7214 next();
7217 } else {
7218 next();
7222 #endif
7224 /* parse an old style function declaration list */
7225 /* XXX: check multiple parameter */
7226 static void func_decl_list(Sym *func_sym)
7228 AttributeDef ad;
7229 int v;
7230 Sym *s;
7231 CType btype, type;
7233 /* parse each declaration */
7234 while (tok != '{' && tok != ';' && tok != TOK_EOF) {
7235 if (!parse_btype(&btype, &ad))
7236 expect("declaration list");
7237 if (((btype.t & VT_BTYPE) == VT_ENUM ||
7238 (btype.t & VT_BTYPE) == VT_STRUCT) &&
7239 tok == ';') {
7240 /* we accept no variable after */
7241 } else {
7242 for(;;) {
7243 type = btype;
7244 type_decl(&type, &ad, &v, TYPE_DIRECT);
7245 /* find parameter in function parameter list */
7246 s = func_sym->next;
7247 while (s != NULL) {
7248 if ((s->v & ~SYM_FIELD) == v)
7249 goto found;
7250 s = s->next;
7252 error("declaration for parameter '%s' but no such parameter",
7253 get_tok_str(v, NULL));
7254 found:
7255 /* check that no storage specifier except 'register' was given */
7256 if (type.t & (VT_EXTERN | VT_STATIC | VT_TYPEDEF))
7257 error("storage class specified for '%s'", get_tok_str(v, NULL));
7258 /* we can add the type (NOTE: it could be local to the function) */
7259 s->type = type;
7260 /* accept other parameters */
7261 if (tok == ',')
7262 next();
7263 else
7264 break;
7267 skip(';');
7271 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
7272 static void decl(int l)
7274 int v, has_init, r;
7275 CType type, btype;
7276 Sym *sym;
7277 AttributeDef ad;
7279 while (1) {
7280 if (!parse_btype(&btype, &ad)) {
7281 /* skip redundant ';' */
7282 /* XXX: find more elegant solution */
7283 if (tok == ';') {
7284 next();
7285 continue;
7287 /* special test for old K&R protos without explicit int
7288 type. Only accepted when defining global data */
7289 if (l == VT_LOCAL || tok < TOK_DEFINE)
7290 break;
7291 btype.t = VT_INT;
7293 if (((btype.t & VT_BTYPE) == VT_ENUM ||
7294 (btype.t & VT_BTYPE) == VT_STRUCT) &&
7295 tok == ';') {
7296 /* we accept no variable after */
7297 next();
7298 continue;
7300 while (1) { /* iterate thru each declaration */
7301 type = btype;
7302 type_decl(&type, &ad, &v, TYPE_DIRECT);
7303 #if 0
7305 char buf[500];
7306 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
7307 printf("type = '%s'\n", buf);
7309 #endif
7310 if ((type.t & VT_BTYPE) == VT_FUNC) {
7311 /* if old style function prototype, we accept a
7312 declaration list */
7313 sym = type.ref;
7314 if (sym->c == FUNC_OLD)
7315 func_decl_list(sym);
7318 if (tok == '{') {
7319 #ifdef CONFIG_REG_VARS
7320 TokenString func_str;
7321 ParseState saved_parse_state;
7322 int block_level;
7323 #endif
7325 if (l == VT_LOCAL)
7326 error("cannot use local functions");
7327 if (!(type.t & VT_FUNC))
7328 expect("function definition");
7330 #ifdef CONFIG_REG_VARS
7331 /* parse all function code and record it */
7333 tok_str_new(&func_str);
7335 block_level = 0;
7336 for(;;) {
7337 int t;
7338 if (tok == -1)
7339 error("unexpected end of file");
7340 tok_str_add_tok(&func_str);
7341 t = tok;
7342 next();
7343 if (t == '{') {
7344 block_level++;
7345 } else if (t == '}') {
7346 block_level--;
7347 if (block_level == 0)
7348 break;
7351 tok_str_add(&func_str, -1);
7352 tok_str_add(&func_str, 0);
7354 save_parse_state(&saved_parse_state);
7356 macro_ptr = func_str.str;
7357 next();
7358 analyse_function();
7359 #endif
7361 /* compute text section */
7362 cur_text_section = ad.section;
7363 if (!cur_text_section)
7364 cur_text_section = text_section;
7365 ind = cur_text_section->data_offset;
7366 funcname = get_tok_str(v, NULL);
7367 sym = sym_find(v);
7368 if (sym) {
7369 /* if symbol is already defined, then put complete type */
7370 sym->type = type;
7371 } else {
7372 /* put function symbol */
7373 sym = global_identifier_push(v, type.t, 0);
7374 sym->type.ref = type.ref;
7376 /* NOTE: we patch the symbol size later */
7377 put_extern_sym(sym, cur_text_section, ind, 0);
7378 func_ind = ind;
7379 sym->r = VT_SYM | VT_CONST;
7380 /* put debug symbol */
7381 if (do_debug)
7382 put_func_debug(sym);
7383 /* push a dummy symbol to enable local sym storage */
7384 sym_push2(&local_stack, SYM_FIELD, 0, 0);
7385 gfunc_prolog(&type);
7386 loc = 0;
7387 rsym = 0;
7388 #ifdef CONFIG_REG_VARS
7389 macro_ptr = func_str.str;
7390 next();
7391 #endif
7392 block(NULL, NULL, NULL, NULL, 0);
7393 gsym(rsym);
7394 gfunc_epilog();
7395 cur_text_section->data_offset = ind;
7396 /* look if any labels are undefined. Define symbols if
7397 '&&label' was used. */
7399 Sym *s, *s1;
7400 for(s = label_stack; s != NULL; s = s1) {
7401 s1 = s->prev;
7402 if (s->r & LABEL_FORWARD) {
7403 error("label '%s' used but not defined",
7404 get_tok_str(s->v, NULL));
7406 if (s->c) {
7407 /* define corresponding symbol. A size of
7408 1 is put. */
7409 put_extern_sym(s, cur_text_section, (long)s->next, 1);
7411 /* remove label */
7412 table_ident[s->v - TOK_IDENT]->sym_label = NULL;
7413 tcc_free(s);
7415 label_stack = NULL;
7417 sym_pop(&local_stack, NULL); /* reset local stack */
7418 /* end of function */
7419 /* patch symbol size */
7420 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
7421 ind - func_ind;
7422 if (do_debug) {
7423 put_stabn(N_FUN, 0, 0, ind - func_ind);
7425 funcname = ""; /* for safety */
7426 func_vt.t = VT_VOID; /* for safety */
7427 ind = 0; /* for safety */
7429 #ifdef CONFIG_REG_VARS
7430 tok_str_free(func_str.str);
7431 restore_parse_state(&saved_parse_state);
7432 #endif
7433 break;
7434 } else {
7435 if (btype.t & VT_TYPEDEF) {
7436 /* save typedefed type */
7437 /* XXX: test storage specifiers ? */
7438 sym = sym_push(v, &type, 0, 0);
7439 sym->type.t |= VT_TYPEDEF;
7440 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
7441 /* external function definition */
7442 external_sym(v, &type, 0);
7443 } else {
7444 /* not lvalue if array */
7445 r = 0;
7446 if (!(type.t & VT_ARRAY))
7447 r |= lvalue_type(type.t);
7448 if (btype.t & VT_EXTERN) {
7449 /* external variable */
7450 external_sym(v, &type, r);
7451 } else {
7452 if (type.t & VT_STATIC)
7453 r |= VT_CONST;
7454 else
7455 r |= l;
7456 has_init = (tok == '=');
7457 if (has_init)
7458 next();
7459 decl_initializer_alloc(&type, &ad, r,
7460 has_init, v, l);
7463 if (tok != ',') {
7464 skip(';');
7465 break;
7467 next();
7473 /* compile the C file opened in 'file'. Return non zero if errors. */
7474 static int tcc_compile(TCCState *s1)
7476 Sym *define_start;
7477 char buf[512];
7478 volatile int section_sym;
7480 #ifdef INC_DEBUG
7481 printf("%s: **** new file\n", file->filename);
7482 #endif
7483 funcname = "";
7484 s1->include_stack_ptr = s1->include_stack;
7485 /* XXX: move that before to avoid having to initialize
7486 file->ifdef_stack_ptr ? */
7487 s1->ifdef_stack_ptr = s1->ifdef_stack;
7488 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
7490 /* XXX: not ANSI compliant: bound checking says error */
7491 vtop = vstack - 1;
7492 anon_sym = SYM_FIRST_ANOM;
7494 /* file info: full path + filename */
7495 section_sym = 0; /* avoid warning */
7496 if (do_debug) {
7497 section_sym = put_elf_sym(symtab_section, 0, 0,
7498 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
7499 text_section->sh_num, NULL);
7500 getcwd(buf, sizeof(buf));
7501 pstrcat(buf, sizeof(buf), "/");
7502 put_stabs_r(buf, N_SO, 0, 0,
7503 text_section->data_offset, text_section, section_sym);
7504 put_stabs_r(file->filename, N_SO, 0, 0,
7505 text_section->data_offset, text_section, section_sym);
7507 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
7508 symbols can be safely used */
7509 put_elf_sym(symtab_section, 0, 0,
7510 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
7511 SHN_ABS, file->filename);
7513 /* define some often used types */
7514 int_type.t = VT_INT;
7516 char_pointer_type.t = VT_BYTE;
7517 mk_pointer(&char_pointer_type);
7519 func_old_type.t = VT_FUNC;
7520 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
7522 #if 0
7523 /* define 'void *alloca(unsigned int)' builtin function */
7525 Sym *s1;
7527 p = anon_sym++;
7528 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
7529 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
7530 s1->next = NULL;
7531 sym->next = s1;
7532 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
7534 #endif
7536 define_start = define_stack;
7538 if (setjmp(s1->error_jmp_buf) == 0) {
7539 s1->nb_errors = 0;
7540 s1->error_set_jmp_enabled = 1;
7542 inp();
7543 ch = '\n'; /* needed to parse correctly first preprocessor command */
7544 next();
7545 decl(VT_CONST);
7546 if (tok != -1)
7547 expect("declaration");
7549 /* end of translation unit info */
7550 if (do_debug) {
7551 put_stabs_r(NULL, N_SO, 0, 0,
7552 text_section->data_offset, text_section, section_sym);
7555 s1->error_set_jmp_enabled = 0;
7557 /* reset define stack, but leave -Dsymbols (may be incorrect if
7558 they are undefined) */
7559 free_defines(define_start);
7561 sym_pop(&global_stack, NULL);
7563 return s1->nb_errors != 0 ? -1 : 0;
7566 #ifdef LIBTCC
7567 int tcc_compile_string(TCCState *s, const char *str)
7569 BufferedFile bf1, *bf = &bf1;
7570 int ret, len;
7571 char *buf;
7573 /* init file structure */
7574 bf->fd = -1;
7575 /* XXX: avoid copying */
7576 len = strlen(str);
7577 buf = tcc_malloc(len + 1);
7578 if (!buf)
7579 return -1;
7580 buf[len] = CH_EOB;
7581 bf->buf_ptr = buf;
7582 bf->buf_end = buf + len;
7583 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
7584 bf->line_num = 1;
7585 file = bf;
7587 ret = tcc_compile(s);
7589 tcc_free(buf);
7591 /* currently, no need to close */
7592 return ret;
7594 #endif
7596 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
7597 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
7599 BufferedFile bf1, *bf = &bf1;
7601 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
7602 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
7603 /* default value */
7604 if (!value)
7605 value = "1";
7606 pstrcat(bf->buffer, IO_BUF_SIZE, value);
7608 /* init file structure */
7609 bf->fd = -1;
7610 bf->buf_ptr = bf->buffer;
7611 bf->buf_end = bf->buffer + strlen(bf->buffer);
7612 *bf->buf_end = CH_EOB;
7613 bf->filename[0] = '\0';
7614 bf->line_num = 1;
7615 file = bf;
7617 s1->include_stack_ptr = s1->include_stack;
7619 /* parse with define parser */
7620 inp();
7621 ch = '\n'; /* needed to parse correctly first preprocessor command */
7622 next_nomacro();
7623 parse_define();
7624 file = NULL;
7627 /* undefine a preprocessor symbol */
7628 void tcc_undefine_symbol(TCCState *s1, const char *sym)
7630 TokenSym *ts;
7631 Sym *s;
7632 ts = tok_alloc(sym, strlen(sym));
7633 s = define_find(ts->tok);
7634 /* undefine symbol by putting an invalid name */
7635 if (s)
7636 define_undef(s);
7639 #include "tccelf.c"
7641 /* print the position in the source file of PC value 'pc' by reading
7642 the stabs debug information */
7643 static void rt_printline(unsigned long wanted_pc)
7645 Stab_Sym *sym, *sym_end;
7646 char func_name[128], last_func_name[128];
7647 unsigned long func_addr, last_pc, pc;
7648 const char *incl_files[INCLUDE_STACK_SIZE];
7649 int incl_index, len, last_line_num, i;
7650 const char *str, *p;
7652 fprintf(stderr, "0x%08lx:", wanted_pc);
7654 func_name[0] = '\0';
7655 func_addr = 0;
7656 incl_index = 0;
7657 last_func_name[0] = '\0';
7658 last_pc = 0xffffffff;
7659 last_line_num = 1;
7660 sym = (Stab_Sym *)stab_section->data + 1;
7661 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
7662 while (sym < sym_end) {
7663 switch(sym->n_type) {
7664 /* function start or end */
7665 case N_FUN:
7666 if (sym->n_strx == 0) {
7667 /* we test if between last line and end of function */
7668 pc = sym->n_value + func_addr;
7669 if (wanted_pc >= last_pc && wanted_pc < pc)
7670 goto found;
7671 func_name[0] = '\0';
7672 func_addr = 0;
7673 } else {
7674 str = stabstr_section->data + sym->n_strx;
7675 p = strchr(str, ':');
7676 if (!p) {
7677 pstrcpy(func_name, sizeof(func_name), str);
7678 } else {
7679 len = p - str;
7680 if (len > sizeof(func_name) - 1)
7681 len = sizeof(func_name) - 1;
7682 memcpy(func_name, str, len);
7683 func_name[len] = '\0';
7685 func_addr = sym->n_value;
7687 break;
7688 /* line number info */
7689 case N_SLINE:
7690 pc = sym->n_value + func_addr;
7691 if (wanted_pc >= last_pc && wanted_pc < pc)
7692 goto found;
7693 last_pc = pc;
7694 last_line_num = sym->n_desc;
7695 /* XXX: slow! */
7696 strcpy(last_func_name, func_name);
7697 break;
7698 /* include files */
7699 case N_BINCL:
7700 str = stabstr_section->data + sym->n_strx;
7701 add_incl:
7702 if (incl_index < INCLUDE_STACK_SIZE) {
7703 incl_files[incl_index++] = str;
7705 break;
7706 case N_EINCL:
7707 if (incl_index > 1)
7708 incl_index--;
7709 break;
7710 case N_SO:
7711 if (sym->n_strx == 0) {
7712 incl_index = 0; /* end of translation unit */
7713 } else {
7714 str = stabstr_section->data + sym->n_strx;
7715 /* do not add path */
7716 len = strlen(str);
7717 if (len > 0 && str[len - 1] != '/')
7718 goto add_incl;
7720 break;
7722 sym++;
7725 /* second pass: we try symtab symbols (no line number info) */
7726 incl_index = 0;
7728 Elf32_Sym *sym, *sym_end;
7729 int type;
7731 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
7732 for(sym = (Elf32_Sym *)symtab_section->data + 1;
7733 sym < sym_end;
7734 sym++) {
7735 type = ELF32_ST_TYPE(sym->st_info);
7736 if (type == STT_FUNC) {
7737 if (wanted_pc >= sym->st_value &&
7738 wanted_pc < sym->st_value + sym->st_size) {
7739 pstrcpy(last_func_name, sizeof(last_func_name),
7740 strtab_section->data + sym->st_name);
7741 goto found;
7746 /* did not find any info: */
7747 fprintf(stderr, " ???\n");
7748 return;
7749 found:
7750 if (last_func_name[0] != '\0') {
7751 fprintf(stderr, " %s()", last_func_name);
7753 if (incl_index > 0) {
7754 fprintf(stderr, " (%s:%d",
7755 incl_files[incl_index - 1], last_line_num);
7756 for(i = incl_index - 2; i >= 0; i--)
7757 fprintf(stderr, ", included from %s", incl_files[i]);
7758 fprintf(stderr, ")");
7760 fprintf(stderr, "\n");
7763 #ifndef WIN32
7765 #ifdef __i386__
7767 #ifndef EIP
7768 #define EIP 14
7769 #define EBP 6
7770 #endif
7772 /* return the PC at frame level 'level'. Return non zero if not found */
7773 static int rt_get_caller_pc(unsigned long *paddr,
7774 struct ucontext *uc, int level)
7776 unsigned long fp;
7777 int i;
7779 if (level == 0) {
7780 *paddr = uc->uc_mcontext.gregs[EIP];
7781 return 0;
7782 } else {
7783 fp = uc->uc_mcontext.gregs[EBP];
7784 for(i=1;i<level;i++) {
7785 /* XXX: check address validity with program info */
7786 if (fp <= 0x1000 || fp >= 0xc0000000)
7787 return -1;
7788 fp = ((unsigned long *)fp)[0];
7790 *paddr = ((unsigned long *)fp)[1];
7791 return 0;
7794 #else
7795 #error add arch specific rt_get_caller_pc()
7796 #endif
7798 /* emit a run time error at position 'pc' */
7799 void rt_error(struct ucontext *uc, const char *fmt, ...)
7801 va_list ap;
7802 unsigned long pc;
7803 int i;
7805 va_start(ap, fmt);
7806 fprintf(stderr, "Runtime error: ");
7807 vfprintf(stderr, fmt, ap);
7808 fprintf(stderr, "\n");
7809 for(i=0;i<num_callers;i++) {
7810 if (rt_get_caller_pc(&pc, uc, i) < 0)
7811 break;
7812 if (i == 0)
7813 fprintf(stderr, "at ");
7814 else
7815 fprintf(stderr, "by ");
7816 rt_printline(pc);
7818 exit(255);
7819 va_end(ap);
7822 /* signal handler for fatal errors */
7823 static void sig_error(int signum, siginfo_t *siginf, void *puc)
7825 struct ucontext *uc = puc;
7827 switch(signum) {
7828 case SIGFPE:
7829 switch(siginf->si_code) {
7830 case FPE_INTDIV:
7831 case FPE_FLTDIV:
7832 rt_error(uc, "division by zero");
7833 break;
7834 default:
7835 rt_error(uc, "floating point exception");
7836 break;
7838 break;
7839 case SIGBUS:
7840 case SIGSEGV:
7841 if (rt_bound_error_msg && *rt_bound_error_msg)
7842 rt_error(uc, *rt_bound_error_msg);
7843 else
7844 rt_error(uc, "dereferencing invalid pointer");
7845 break;
7846 case SIGILL:
7847 rt_error(uc, "illegal instruction");
7848 break;
7849 case SIGABRT:
7850 rt_error(uc, "abort() called");
7851 break;
7852 default:
7853 rt_error(uc, "caught signal %d", signum);
7854 break;
7856 exit(255);
7858 #endif
7860 /* do all relocations (needed before using tcc_get_symbol()) */
7861 int tcc_relocate(TCCState *s1)
7863 Section *s;
7864 int i;
7866 s1->nb_errors = 0;
7868 tcc_add_runtime(s1);
7870 relocate_common_syms();
7872 /* compute relocation address : section are relocated in place. We
7873 also alloc the bss space */
7874 for(i = 1; i < s1->nb_sections; i++) {
7875 s = s1->sections[i];
7876 if (s->sh_flags & SHF_ALLOC) {
7877 if (s->sh_type == SHT_NOBITS)
7878 s->data = tcc_mallocz(s->data_offset);
7879 s->sh_addr = (unsigned long)s->data;
7883 relocate_syms(s1, 1);
7885 if (s1->nb_errors != 0)
7886 return -1;
7888 /* relocate each section */
7889 for(i = 1; i < s1->nb_sections; i++) {
7890 s = s1->sections[i];
7891 if (s->reloc)
7892 relocate_section(s1, s);
7894 return 0;
7897 /* launch the compiled program with the given arguments */
7898 int tcc_run(TCCState *s1, int argc, char **argv)
7900 int (*prog_main)(int, char **);
7902 if (tcc_relocate(s1) < 0)
7903 return -1;
7905 prog_main = tcc_get_symbol(s1, "main");
7907 if (do_debug) {
7908 #ifdef WIN32
7909 error("debug mode currently not available for Windows");
7910 #else
7911 struct sigaction sigact;
7912 /* install TCC signal handlers to print debug info on fatal
7913 runtime errors */
7914 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
7915 sigact.sa_sigaction = sig_error;
7916 sigemptyset(&sigact.sa_mask);
7917 sigaction(SIGFPE, &sigact, NULL);
7918 sigaction(SIGILL, &sigact, NULL);
7919 sigaction(SIGSEGV, &sigact, NULL);
7920 sigaction(SIGBUS, &sigact, NULL);
7921 sigaction(SIGABRT, &sigact, NULL);
7922 #endif
7925 #ifdef CONFIG_TCC_BCHECK
7926 if (do_bounds_check) {
7927 void (*bound_init)(void);
7929 /* set error function */
7930 rt_bound_error_msg = (void *)tcc_get_symbol(s1, "__bound_error_msg");
7932 /* XXX: use .init section so that it also work in binary ? */
7933 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
7934 bound_init();
7936 #endif
7937 return (*prog_main)(argc, argv);
7940 TCCState *tcc_new(void)
7942 const char *p, *r;
7943 TCCState *s;
7945 s = tcc_mallocz(sizeof(TCCState));
7946 if (!s)
7947 return NULL;
7948 tcc_state = s;
7949 s->output_type = TCC_OUTPUT_MEMORY;
7951 /* default include paths */
7952 tcc_add_sysinclude_path(s, "/usr/local/include");
7953 tcc_add_sysinclude_path(s, "/usr/include");
7954 tcc_add_sysinclude_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
7956 /* add all tokens */
7957 table_ident = NULL;
7958 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
7960 tok_ident = TOK_IDENT;
7961 p = tcc_keywords;
7962 while (*p) {
7963 r = p;
7964 while (*r++);
7965 tok_alloc(p, r - p - 1);
7966 p = r;
7969 /* we add dummy defines for some special macros to speed up tests
7970 and to have working defined() */
7971 define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
7972 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
7973 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
7974 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
7976 /* standard defines */
7977 tcc_define_symbol(s, "__STDC__", NULL);
7978 #if defined(TCC_TARGET_I386)
7979 tcc_define_symbol(s, "__i386__", NULL);
7980 #endif
7981 #if defined(linux)
7982 tcc_define_symbol(s, "linux", NULL);
7983 #endif
7984 /* tiny C specific defines */
7985 tcc_define_symbol(s, "__TINYC__", NULL);
7987 /* default library paths */
7988 tcc_add_library_path(s, "/usr/local/lib");
7989 tcc_add_library_path(s, "/usr/lib");
7990 tcc_add_library_path(s, "/lib");
7992 /* no section zero */
7993 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
7995 /* create standard sections */
7996 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
7997 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
7998 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
8000 /* symbols are always generated for linking stage */
8001 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
8002 ".strtab",
8003 ".hashtab", SHF_PRIVATE);
8004 strtab_section = symtab_section->link;
8006 /* private symbol table for dynamic symbols */
8007 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
8008 ".dynstrtab",
8009 ".dynhashtab", SHF_PRIVATE);
8010 return s;
8013 void tcc_delete(TCCState *s1)
8015 int i, n;
8017 /* free -D defines */
8018 free_defines(NULL);
8020 /* free tokens */
8021 n = tok_ident - TOK_IDENT;
8022 for(i = 0; i < n; i++)
8023 tcc_free(table_ident[i]);
8024 tcc_free(table_ident);
8026 /* free all sections */
8028 free_section(symtab_section->hash);
8030 free_section(s1->dynsymtab_section->hash);
8031 free_section(s1->dynsymtab_section->link);
8032 free_section(s1->dynsymtab_section);
8034 for(i = 1; i < s1->nb_sections; i++)
8035 free_section(s1->sections[i]);
8036 tcc_free(s1->sections);
8038 /* free loaded dlls array */
8039 for(i = 0; i < s1->nb_loaded_dlls; i++)
8040 tcc_free(s1->loaded_dlls[i]);
8041 tcc_free(s1->loaded_dlls);
8043 /* library paths */
8044 for(i = 0; i < s1->nb_library_paths; i++)
8045 tcc_free(s1->library_paths[i]);
8046 tcc_free(s1->library_paths);
8048 /* cached includes */
8049 for(i = 0; i < s1->nb_cached_includes; i++)
8050 tcc_free(s1->cached_includes[i]);
8051 tcc_free(s1->cached_includes);
8053 for(i = 0; i < s1->nb_include_paths; i++)
8054 tcc_free(s1->include_paths[i]);
8055 tcc_free(s1->include_paths);
8057 for(i = 0; i < s1->nb_sysinclude_paths; i++)
8058 tcc_free(s1->sysinclude_paths[i]);
8059 tcc_free(s1->sysinclude_paths);
8061 tcc_free(s1);
8064 int tcc_add_include_path(TCCState *s1, const char *pathname)
8066 char *pathname1;
8068 pathname1 = tcc_strdup(pathname);
8069 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
8070 return 0;
8073 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
8075 char *pathname1;
8077 pathname1 = tcc_strdup(pathname);
8078 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
8079 return 0;
8082 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
8084 const char *ext;
8085 Elf32_Ehdr ehdr;
8086 int fd, ret;
8087 BufferedFile *saved_file;
8089 /* find source file type with extension */
8090 ext = strrchr(filename, '.');
8091 if (ext)
8092 ext++;
8094 /* open the file */
8095 saved_file = file;
8096 file = tcc_open(s1, filename);
8097 if (!file) {
8098 if (flags & AFF_PRINT_ERROR) {
8099 error_noabort("file '%s' not found", filename);
8101 ret = -1;
8102 goto fail1;
8105 if (!ext || !strcmp(ext, "c")) {
8106 /* C file assumed */
8107 ret = tcc_compile(s1);
8108 } else {
8109 fd = file->fd;
8110 /* assume executable format: auto guess file type */
8111 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
8112 error_noabort("could not read header");
8113 goto fail;
8115 lseek(fd, 0, SEEK_SET);
8117 if (ehdr.e_ident[0] == ELFMAG0 &&
8118 ehdr.e_ident[1] == ELFMAG1 &&
8119 ehdr.e_ident[2] == ELFMAG2 &&
8120 ehdr.e_ident[3] == ELFMAG3) {
8121 file->line_num = 0; /* do not display line number if error */
8122 if (ehdr.e_type == ET_REL) {
8123 ret = tcc_load_object_file(s1, fd, 0);
8124 } else if (ehdr.e_type == ET_DYN) {
8125 ret = tcc_load_dll(s1, fd, filename,
8126 (flags & AFF_REFERENCED_DLL) != 0);
8127 } else {
8128 error_noabort("unrecognized ELF file");
8129 goto fail;
8131 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
8132 file->line_num = 0; /* do not display line number if error */
8133 ret = tcc_load_archive(s1, fd);
8134 } else {
8135 /* as GNU ld, consider it is an ld script if not recognized */
8136 ret = tcc_load_ldscript(s1);
8137 if (ret < 0) {
8138 error_noabort("unrecognized file type");
8139 goto fail;
8143 the_end:
8144 tcc_close(file);
8145 fail1:
8146 file = saved_file;
8147 return ret;
8148 fail:
8149 ret = -1;
8150 goto the_end;
8153 int tcc_add_file(TCCState *s, const char *filename)
8155 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
8158 int tcc_add_library_path(TCCState *s, const char *pathname)
8160 char *pathname1;
8162 pathname1 = tcc_strdup(pathname);
8163 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
8164 return 0;
8167 /* find and load a dll. Return non zero if not found */
8168 /* XXX: add '-rpath' option support ? */
8169 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
8171 char buf[1024];
8172 int i;
8174 for(i = 0; i < s->nb_library_paths; i++) {
8175 snprintf(buf, sizeof(buf), "%s/%s",
8176 s->library_paths[i], filename);
8177 if (tcc_add_file_internal(s, buf, flags) == 0)
8178 return 0;
8180 return -1;
8183 /* the library name is the same as the argument of the '-l' option */
8184 int tcc_add_library(TCCState *s, const char *libraryname)
8186 char buf[1024];
8187 int i;
8188 void *h;
8190 /* first we look for the dynamic library if not static linking */
8191 if (!s->static_link) {
8192 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
8193 /* if we output to memory, then we simply we dlopen(). */
8194 if (s->output_type == TCC_OUTPUT_MEMORY) {
8195 /* Since the libc is already loaded, we don't need to load it again */
8196 if (!strcmp(libraryname, "c"))
8197 return 0;
8198 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
8199 if (h)
8200 return 0;
8201 } else {
8202 if (tcc_add_dll(s, buf, 0) == 0)
8203 return 0;
8207 /* then we look for the static library */
8208 for(i = 0; i < s->nb_library_paths; i++) {
8209 snprintf(buf, sizeof(buf), "%s/lib%s.a",
8210 s->library_paths[i], libraryname);
8211 if (tcc_add_file_internal(s, buf, 0) == 0)
8212 return 0;
8214 return -1;
8217 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
8219 add_elf_sym(symtab_section, val, 0,
8220 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
8221 SHN_ABS, name);
8222 return 0;
8225 int tcc_set_output_type(TCCState *s, int output_type)
8227 s->output_type = output_type;
8229 /* if bound checking, then add corresponding sections */
8230 #ifdef CONFIG_TCC_BCHECK
8231 if (do_bounds_check) {
8232 /* define symbol */
8233 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
8234 /* create bounds sections */
8235 bounds_section = new_section(s, ".bounds",
8236 SHT_PROGBITS, SHF_ALLOC);
8237 lbounds_section = new_section(s, ".lbounds",
8238 SHT_PROGBITS, SHF_ALLOC);
8240 #endif
8242 /* add debug sections */
8243 if (do_debug) {
8244 /* stab symbols */
8245 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
8246 stab_section->sh_entsize = sizeof(Stab_Sym);
8247 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
8248 put_elf_str(stabstr_section, "");
8249 stab_section->link = stabstr_section;
8250 /* put first entry */
8251 put_stabs("", 0, 0, 0, 0);
8254 /* add libc crt1/crti objects */
8255 if (output_type == TCC_OUTPUT_EXE ||
8256 output_type == TCC_OUTPUT_DLL) {
8257 if (output_type != TCC_OUTPUT_DLL)
8258 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
8259 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
8261 return 0;
8264 #if !defined(LIBTCC)
8266 static int64_t getclock_us(void)
8268 #ifdef WIN32
8269 struct _timeb tb;
8270 _ftime(&tb);
8271 return (tb.time * 1000LL + tb.millitm) * 1000LL;
8272 #else
8273 struct timeval tv;
8274 gettimeofday(&tv, NULL);
8275 return tv.tv_sec * 1000000LL + tv.tv_usec;
8276 #endif
8279 void help(void)
8281 printf("tcc version 0.9.13 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8282 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8283 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
8284 " [--] infile1 [infile2... --] [infile_args...]\n"
8285 "\n"
8286 "General options:\n"
8287 " -c compile only - generate an object file\n"
8288 " -o outfile set output filename\n"
8289 " -- allows multiples input files if no -o option given. Also\n"
8290 " separate input files from runtime arguments\n"
8291 " -Bdir set tcc internal library path\n"
8292 " -bench output compilation statistics\n"
8293 "Preprocessor options:\n"
8294 " -Idir add include path 'dir'\n"
8295 " -Dsym[=val] define 'sym' with value 'val'\n"
8296 " -Usym undefine 'sym'\n"
8297 "Linker options:\n"
8298 " -Ldir add library path 'dir'\n"
8299 " -llib link with dynamic or static library 'lib'\n"
8300 " -shared generate a shared library\n"
8301 " -static static linking\n"
8302 " -r relocatable output\n"
8303 "Debugger options:\n"
8304 " -g generate runtime debug info\n"
8305 #ifdef CONFIG_TCC_BCHECK
8306 " -b compile with built-in memory and bounds checker (implies -g)\n"
8307 #endif
8308 " -bt N show N callers in stack traces\n"
8312 int main(int argc, char **argv)
8314 char *r, *outfile;
8315 int optind, output_type, multiple_files, i, reloc_output;
8316 TCCState *s;
8317 char **files;
8318 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
8319 char objfilename[1024];
8320 int64_t start_time = 0;
8322 s = tcc_new();
8323 output_type = TCC_OUTPUT_MEMORY;
8325 optind = 1;
8326 outfile = NULL;
8327 multiple_files = 0;
8328 dminus = 0;
8329 files = NULL;
8330 nb_files = 0;
8331 nb_libraries = 0;
8332 reloc_output = 0;
8333 while (1) {
8334 if (optind >= argc) {
8335 if (nb_files == 0)
8336 goto show_help;
8337 else
8338 break;
8340 r = argv[optind++];
8341 if (r[0] != '-') {
8342 /* add a new file */
8343 dynarray_add((void ***)&files, &nb_files, r);
8344 if (!multiple_files) {
8345 optind--;
8346 /* argv[0] will be this file */
8347 break;
8349 } else if (r[1] == '-') {
8350 /* '--' enables multiple files input and also ends several file input */
8351 if (dminus && multiple_files) {
8352 optind--; /* argv[0] will be '--' */
8353 break;
8355 dminus = 1;
8356 multiple_files = 1;
8357 } else if (r[1] == 'h' || r[1] == '?') {
8358 show_help:
8359 help();
8360 return 1;
8361 } else if (r[1] == 'I') {
8362 if (tcc_add_include_path(s, r + 2) < 0)
8363 error("too many include paths");
8364 } else if (r[1] == 'D') {
8365 char *sym, *value;
8366 sym = r + 2;
8367 value = strchr(sym, '=');
8368 if (value) {
8369 *value = '\0';
8370 value++;
8372 tcc_define_symbol(s, sym, value);
8373 } else if (r[1] == 'U') {
8374 tcc_undefine_symbol(s, r + 2);
8375 } else if (r[1] == 'L') {
8376 tcc_add_library_path(s, r + 2);
8377 } else if (r[1] == 'B') {
8378 /* set tcc utilities path (mainly for tcc development) */
8379 tcc_lib_path = r + 2;
8380 } else if (r[1] == 'l') {
8381 dynarray_add((void ***)&files, &nb_files, r);
8382 nb_libraries++;
8383 } else if (!strcmp(r + 1, "bench")) {
8384 do_bench = 1;
8385 } else if (!strcmp(r + 1, "bt")) {
8386 num_callers = atoi(argv[optind++]);
8387 } else
8388 #ifdef CONFIG_TCC_BCHECK
8389 if (r[1] == 'b') {
8390 do_bounds_check = 1;
8391 do_debug = 1;
8392 } else
8393 #endif
8394 if (r[1] == 'g') {
8395 do_debug = 1;
8396 } else if (r[1] == 'c') {
8397 multiple_files = 1;
8398 output_type = TCC_OUTPUT_OBJ;
8399 } else if (!strcmp(r + 1, "static")) {
8400 s->static_link = 1;
8401 } else if (!strcmp(r + 1, "shared")) {
8402 output_type = TCC_OUTPUT_DLL;
8403 } else if (r[1] == 'o') {
8404 if (optind >= argc)
8405 goto show_help;
8406 multiple_files = 1;
8407 outfile = argv[optind++];
8408 } else if (r[1] == 'r') {
8409 /* generate a .o merging several output files */
8410 reloc_output = 1;
8411 output_type = TCC_OUTPUT_OBJ;
8412 } else if (r[1] == 'W' || r[1] == 'O' || r[1] == 'm' || r[1] == 'f') {
8413 /* ignore those options to be a drop-in replacement for gcc */
8414 } else {
8415 error("invalid option -- '%s'", r);
8419 nb_objfiles = nb_files - nb_libraries;
8421 /* if outfile provided without other options, we output an
8422 executable */
8423 if (outfile && output_type == TCC_OUTPUT_MEMORY)
8424 output_type = TCC_OUTPUT_EXE;
8426 /* check -c consistency : only single file handled. XXX: checks file type */
8427 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
8428 /* accepts only a single input file */
8429 if (nb_objfiles != 1)
8430 error("cannot specify multiple files with -c");
8431 if (nb_libraries != 0)
8432 error("cannot specify libraries with -c");
8435 /* compute default outfile name */
8436 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
8437 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
8438 char *ext;
8439 /* add .o extension */
8440 pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
8441 ext = strrchr(objfilename, '.');
8442 if (!ext)
8443 goto default_outfile;
8444 strcpy(ext + 1, "o");
8445 } else {
8446 default_outfile:
8447 pstrcpy(objfilename, sizeof(objfilename), "a.out");
8449 outfile = objfilename;
8452 if (do_bench) {
8453 start_time = getclock_us();
8456 tcc_set_output_type(s, output_type);
8458 /* compile or add each files or library */
8459 for(i = 0;i < nb_files; i++) {
8460 const char *filename;
8462 filename = files[i];
8463 if (filename[0] == '-') {
8464 if (tcc_add_library(s, filename + 2) < 0)
8465 error("cannot find %s", filename);
8466 } else {
8467 if (tcc_add_file(s, filename) < 0) {
8468 ret = 1;
8469 goto the_end;
8474 /* free all files */
8475 tcc_free(files);
8477 if (do_bench) {
8478 double total_time;
8479 total_time = (double)(getclock_us() - start_time) / 1000000.0;
8480 if (total_time < 0.001)
8481 total_time = 0.001;
8482 if (total_bytes < 1)
8483 total_bytes = 1;
8484 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
8485 tok_ident - TOK_IDENT, total_lines, total_bytes,
8486 total_time, (int)(total_lines / total_time),
8487 total_bytes / total_time / 1000000.0);
8490 if (s->output_type != TCC_OUTPUT_MEMORY) {
8491 tcc_output_file(s, outfile);
8492 ret = 0;
8493 } else {
8494 ret = tcc_run(s, argc - optind, argv + optind);
8496 the_end:
8497 /* XXX: cannot do it with bound checking because of the malloc hooks */
8498 if (!do_bounds_check)
8499 tcc_delete(s);
8501 #ifdef MEM_DEBUG
8502 if (do_bench) {
8503 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
8505 #endif
8506 return ret;
8509 #endif