double fix
[tinycc.git] / tcc.c
blob35bc618f4a0476bb17a5612e902dd0428368900e
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 #ifndef WIN32
31 #include <sys/ucontext.h>
32 #endif
33 #include "elf.h"
34 #include "stab.h"
35 #ifndef CONFIG_TCC_STATIC
36 #include <dlfcn.h>
37 #endif
39 #include "libtcc.h"
41 //#define DEBUG
42 /* preprocessor debug */
43 //#define PP_DEBUG
45 //#define MEM_DEBUG
47 /* target selection */
48 //#define TCC_TARGET_I386 /* i386 code generator */
49 //#define TCC_TARGET_IL /* .NET CLI generator */
51 /* default target is I386 */
52 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
53 #define TCC_TARGET_I386
54 #endif
56 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
57 #define CONFIG_TCC_BCHECK /* enable bound checking code */
58 #endif
60 #ifndef CONFIG_TCC_PREFIX
61 #define CONFIG_TCC_PREFIX "/usr/local"
62 #endif
64 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
65 executables or dlls */
66 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
68 #define INCLUDE_STACK_SIZE 32
69 #define IFDEF_STACK_SIZE 64
70 #define VSTACK_SIZE 64
71 #define STRING_MAX_SIZE 1024
73 #define TOK_HASH_SIZE 2048 /* must be a power of two */
74 #define TOK_ALLOC_INCR 512 /* must be a power of two */
75 #define SYM_HASH_SIZE 1031
77 /* token symbol management */
78 typedef struct TokenSym {
79 struct TokenSym *hash_next;
80 int tok; /* token number */
81 int len;
82 char str[1];
83 } TokenSym;
85 typedef struct CString {
86 int size; /* size in bytes */
87 void *data; /* either 'char *' or 'int *' */
88 int size_allocated;
89 void *data_allocated; /* if non NULL, data has been malloced */
90 } CString;
92 /* constant value */
93 typedef union CValue {
94 long double ld;
95 double d;
96 float f;
97 int i;
98 unsigned int ui;
99 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
100 long long ll;
101 unsigned long long ull;
102 struct CString *cstr;
103 void *ptr;
104 int tab[1];
105 } CValue;
107 /* value on stack */
108 typedef struct SValue {
109 int t; /* type */
110 unsigned short r; /* register + flags */
111 unsigned short r2; /* second register, used for 'long long'
112 type. If not used, set to VT_CONST */
113 CValue c; /* constant, if VT_CONST */
114 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
115 } SValue;
117 /* symbol management */
118 typedef struct Sym {
119 int v; /* symbol token */
120 int t; /* associated type */
121 int r; /* associated register */
122 int c; /* associated number */
123 struct Sym *next; /* next related symbol */
124 struct Sym *prev; /* prev symbol in stack */
125 struct Sym *hash_next; /* next symbol in hash table */
126 } Sym;
128 typedef struct SymStack {
129 struct Sym *top;
130 struct Sym *hash[SYM_HASH_SIZE];
131 } SymStack;
133 /* section definition */
134 /* XXX: use directly ELF structure for parameters ? */
135 /* special flag to indicate that the section should not be linked to
136 the other ones */
137 #define SHF_PRIVATE 0x80000000
139 typedef struct Section {
140 unsigned long data_offset; /* current data offset */
141 unsigned char *data; /* section data */
142 unsigned long data_allocated; /* used for realloc() handling */
143 int sh_name; /* elf section name (only used during output) */
144 int sh_num; /* elf section number */
145 int sh_type; /* elf section type */
146 int sh_flags; /* elf section flags */
147 int sh_info; /* elf section info */
148 int sh_addralign; /* elf section alignment */
149 int sh_entsize; /* elf entry size */
150 unsigned long sh_size; /* section size (only used during output) */
151 unsigned long sh_addr; /* address at which the section is relocated */
152 unsigned long sh_offset; /* address at which the section is relocated */
153 int nb_hashed_syms; /* used to resize the hash table */
154 struct Section *link; /* link to another section */
155 struct Section *reloc; /* corresponding section for relocation, if any */
156 struct Section *hash; /* hash table for symbols */
157 struct Section *next;
158 char name[64]; /* section name */
159 } Section;
161 typedef struct DLLReference {
162 int level;
163 char name[1];
164 } DLLReference;
166 /* GNUC attribute definition */
167 typedef struct AttributeDef {
168 int aligned;
169 Section *section;
170 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
171 } AttributeDef;
173 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
174 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
175 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
177 /* stored in 'Sym.c' field */
178 #define FUNC_NEW 1 /* ansi function prototype */
179 #define FUNC_OLD 2 /* old function prototype */
180 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
182 /* stored in 'Sym.r' field */
183 #define FUNC_CDECL 0 /* standard c call */
184 #define FUNC_STDCALL 1 /* pascal c call */
186 /* field 'Sym.t' for macros */
187 #define MACRO_OBJ 0 /* object like macro */
188 #define MACRO_FUNC 1 /* function like macro */
190 /* field 'Sym.t' for labels */
191 #define LABEL_FORWARD 1 /* label is forward defined */
193 /* type_decl() types */
194 #define TYPE_ABSTRACT 1 /* type without variable */
195 #define TYPE_DIRECT 2 /* type with variable */
197 #define IO_BUF_SIZE 8192
199 typedef struct BufferedFile {
200 unsigned char *buf_ptr;
201 unsigned char *buf_end;
202 int fd;
203 int line_num; /* current line number - here to simply code */
204 char filename[1024]; /* current filename - here to simplify code */
205 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
206 } BufferedFile;
208 #define CH_EOB 0 /* end of buffer or '\0' char in file */
209 #define CH_EOF (-1) /* end of file */
211 /* parsing state (used to save parser state to reparse part of the
212 source several times) */
213 typedef struct ParseState {
214 int *macro_ptr;
215 int line_num;
216 int tok;
217 CValue tokc;
218 } ParseState;
220 /* used to record tokens */
221 typedef struct TokenString {
222 int *str;
223 int len;
224 int last_line_num;
225 } TokenString;
227 /* parser */
228 struct BufferedFile *file;
229 int ch, ch1, tok, tok1;
230 CValue tokc, tok1c;
231 CString tokcstr; /* current parsed string, if any */
232 int return_linefeed; /* if true, line feed is returned as a token */
234 /* sections */
235 Section **sections;
236 int nb_sections; /* number of sections, including first dummy section */
237 Section *text_section, *data_section, *bss_section; /* predefined sections */
238 Section *cur_text_section; /* current section where function code is
239 generated */
240 /* bound check related sections */
241 Section *bounds_section; /* contains global data bound description */
242 Section *lbounds_section; /* contains local data bound description */
243 /* symbol sections */
244 Section *symtab_section, *strtab_section;
245 /* temporary dynamic symbol sections (for dll loading) */
246 Section *dynsymtab_section;
247 /* exported dynamic symbol section */
248 Section *dynsym;
249 /* got handling */
250 Section *got;
251 unsigned long *got_offsets;
252 int nb_got_offsets;
253 int nb_plt_entries;
254 /* give the correspondance from symtab indexes to dynsym indexes */
255 int *symtab_to_dynsym;
257 /* array of all loaded dlls (including those referenced by loaded
258 dlls) */
259 DLLReference **loaded_dlls;
260 int nb_loaded_dlls;
262 /* debug sections */
263 Section *stab_section, *stabstr_section;
265 char **library_paths;
266 int nb_library_paths;
268 /* loc : local variable index
269 ind : output code index
270 rsym: return symbol
271 anon_sym: anonymous symbol index
273 int rsym, anon_sym,
274 prog, ind, loc, const_wanted;
275 int global_expr; /* true if compound literals must be allocated
276 globally (used during initializers parsing */
277 int func_vt, func_vc; /* current function return type (used by
278 return instruction) */
279 int last_line_num, last_ind, func_ind; /* debug last line number and pc */
280 int tok_ident;
281 TokenSym **table_ident;
282 TokenSym *hash_ident[TOK_HASH_SIZE];
283 char token_buf[STRING_MAX_SIZE + 1];
284 char *funcname;
285 SymStack define_stack, global_stack, local_stack, label_stack;
287 SValue vstack[VSTACK_SIZE], *vtop;
288 int *macro_ptr, *macro_ptr_allocated;
289 BufferedFile *include_stack[INCLUDE_STACK_SIZE], **include_stack_ptr;
290 int ifdef_stack[IFDEF_STACK_SIZE], *ifdef_stack_ptr;
291 char **include_paths;
292 int nb_include_paths;
293 char **sysinclude_paths;
294 int nb_sysinclude_paths;
295 int char_pointer_type;
296 int func_old_type;
298 /* compile with debug symbol (and use them if error during execution) */
299 int do_debug = 0;
301 /* compile with built-in memory and bounds checker */
302 int do_bounds_check = 0;
304 /* display benchmark infos */
305 int do_bench = 0;
306 int total_lines;
307 int total_bytes;
309 /* use GNU C extensions */
310 int gnu_ext = 1;
312 /* use Tiny C extensions */
313 int tcc_ext = 1;
315 /* if true, static linking is performed */
316 int static_link = 0;
318 /* give the path of the tcc libraries */
319 static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc";
321 struct TCCState {
322 int output_type;
325 /* The current value can be: */
326 #define VT_VALMASK 0x00ff
327 #define VT_CONST 0x00f0 /* constant in vc
328 (must be first non register value) */
329 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
330 #define VT_LOCAL 0x00f2 /* offset on stack */
331 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
332 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
333 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
334 #define VT_LVAL 0x0100 /* var is an lvalue */
335 #define VT_SYM 0x0200 /* a symbol value is added */
336 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
337 char/short stored in integer registers) */
338 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
339 dereferencing value */
340 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
341 bounding function call point is in vc */
342 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
343 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
344 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
345 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
347 /* types */
348 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
350 #define VT_INT 0 /* integer type */
351 #define VT_BYTE 1 /* signed byte type */
352 #define VT_SHORT 2 /* short type */
353 #define VT_VOID 3 /* void type */
354 #define VT_PTR 4 /* pointer */
355 #define VT_ENUM 5 /* enum definition */
356 #define VT_FUNC 6 /* function type */
357 #define VT_STRUCT 7 /* struct/union definition */
358 #define VT_FLOAT 8 /* IEEE float */
359 #define VT_DOUBLE 9 /* IEEE double */
360 #define VT_LDOUBLE 10 /* IEEE long double */
361 #define VT_BOOL 11 /* ISOC99 boolean type */
362 #define VT_LLONG 12 /* 64 bit integer */
363 #define VT_LONG 13 /* long integer (NEVER USED as type, only
364 during parsing) */
365 #define VT_BTYPE 0x000f /* mask for basic type */
366 #define VT_UNSIGNED 0x0010 /* unsigned type */
367 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
368 #define VT_BITFIELD 0x0040 /* bitfield modifier */
370 /* storage */
371 #define VT_EXTERN 0x00000080 /* extern definition */
372 #define VT_STATIC 0x00000100 /* static variable */
373 #define VT_TYPEDEF 0x00000200 /* typedef definition */
375 /* type mask (except storage) */
376 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
378 /* token values */
380 /* warning: the following compare tokens depend on i386 asm code */
381 #define TOK_ULT 0x92
382 #define TOK_UGE 0x93
383 #define TOK_EQ 0x94
384 #define TOK_NE 0x95
385 #define TOK_ULE 0x96
386 #define TOK_UGT 0x97
387 #define TOK_LT 0x9c
388 #define TOK_GE 0x9d
389 #define TOK_LE 0x9e
390 #define TOK_GT 0x9f
392 #define TOK_LAND 0xa0
393 #define TOK_LOR 0xa1
395 #define TOK_DEC 0xa2
396 #define TOK_MID 0xa3 /* inc/dec, to void constant */
397 #define TOK_INC 0xa4
398 #define TOK_UDIV 0xb0 /* unsigned division */
399 #define TOK_UMOD 0xb1 /* unsigned modulo */
400 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
401 #define TOK_CINT 0xb3 /* number in tokc */
402 #define TOK_CCHAR 0xb4 /* char constant in tokc */
403 #define TOK_STR 0xb5 /* pointer to string in tokc */
404 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
405 #define TOK_LCHAR 0xb7
406 #define TOK_LSTR 0xb8
407 #define TOK_CFLOAT 0xb9 /* float constant */
408 #define TOK_LINENUM 0xba /* line number info */
409 #define TOK_CDOUBLE 0xc0 /* double constant */
410 #define TOK_CLDOUBLE 0xc1 /* long double constant */
411 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
412 #define TOK_ADDC1 0xc3 /* add with carry generation */
413 #define TOK_ADDC2 0xc4 /* add with carry use */
414 #define TOK_SUBC1 0xc5 /* add with carry generation */
415 #define TOK_SUBC2 0xc6 /* add with carry use */
416 #define TOK_CUINT 0xc8 /* unsigned int constant */
417 #define TOK_CLLONG 0xc9 /* long long constant */
418 #define TOK_CULLONG 0xca /* unsigned long long constant */
419 #define TOK_ARROW 0xcb
420 #define TOK_DOTS 0xcc /* three dots */
421 #define TOK_SHR 0xcd /* unsigned shift right */
423 #define TOK_SHL 0x01 /* shift left */
424 #define TOK_SAR 0x02 /* signed shift right */
426 /* assignement operators : normal operator or 0x80 */
427 #define TOK_A_MOD 0xa5
428 #define TOK_A_AND 0xa6
429 #define TOK_A_MUL 0xaa
430 #define TOK_A_ADD 0xab
431 #define TOK_A_SUB 0xad
432 #define TOK_A_DIV 0xaf
433 #define TOK_A_XOR 0xde
434 #define TOK_A_OR 0xfc
435 #define TOK_A_SHL 0x81
436 #define TOK_A_SAR 0x82
438 /* WARNING: the content of this string encodes token numbers */
439 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";
441 #define TOK_EOF (-1) /* end of file */
442 #define TOK_LINEFEED 10 /* line feed */
444 /* all identificators and strings have token above that */
445 #define TOK_IDENT 256
447 enum {
448 TOK_INT = TOK_IDENT,
449 TOK_VOID,
450 TOK_CHAR,
451 TOK_IF,
452 TOK_ELSE,
453 TOK_WHILE,
454 TOK_BREAK,
455 TOK_RETURN,
456 TOK_FOR,
457 TOK_EXTERN,
458 TOK_STATIC,
459 TOK_UNSIGNED,
460 TOK_GOTO,
461 TOK_DO,
462 TOK_CONTINUE,
463 TOK_SWITCH,
464 TOK_CASE,
466 /* ignored types Must have contiguous values */
467 TOK_CONST,
468 TOK_VOLATILE,
469 TOK_LONG,
470 TOK_REGISTER,
471 TOK_SIGNED,
472 TOK___SIGNED__, /* gcc keyword */
473 TOK_AUTO,
474 TOK_INLINE,
475 TOK___INLINE__, /* gcc keyword */
476 TOK_RESTRICT,
478 /* unsupported type */
479 TOK_FLOAT,
480 TOK_DOUBLE,
481 TOK_BOOL,
483 TOK_SHORT,
484 TOK_STRUCT,
485 TOK_UNION,
486 TOK_TYPEDEF,
487 TOK_DEFAULT,
488 TOK_ENUM,
489 TOK_SIZEOF,
490 TOK___ATTRIBUTE__,
492 /* preprocessor only */
493 TOK_UIDENT, /* first "user" ident (not keyword) */
494 TOK_DEFINE = TOK_UIDENT,
495 TOK_INCLUDE,
496 TOK_IFDEF,
497 TOK_IFNDEF,
498 TOK_ELIF,
499 TOK_ENDIF,
500 TOK_DEFINED,
501 TOK_UNDEF,
502 TOK_ERROR,
503 TOK_LINE,
505 #define DEF(id, str) id,
506 #include "tcctok.h"
507 #undef DEF
510 char *tcc_keywords =
511 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
512 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
513 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
514 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
515 "sizeof\0__attribute__\0"
516 /* the following are not keywords. They are included to ease parsing */
517 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
518 "defined\0undef\0error\0line\0"
519 /* builtin functions */
520 #define DEF(id, str) str "\0"
521 #include "tcctok.h"
522 #undef DEF
525 #ifdef WIN32
526 #define snprintf _snprintf
527 #endif
529 #if defined(WIN32) || defined(TCC_UCLIBC)
530 /* currently incorrect */
531 long double strtold(const char *nptr, char **endptr)
533 return (long double)strtod(nptr, endptr);
535 float strtof(const char *nptr, char **endptr)
537 return (float)strtod(nptr, endptr);
539 #else
540 /* XXX: need to define this to use them in non ISOC99 context */
541 extern float strtof (const char *__nptr, char **__endptr);
542 extern long double strtold (const char *__nptr, char **__endptr);
543 #endif
545 static char *pstrcpy(char *buf, int buf_size, const char *s);
546 static char *pstrcat(char *buf, int buf_size, const char *s);
548 void sum(int l);
549 void next(void);
550 void next_nomacro(void);
551 static int expr_const(void);
552 void expr_eq(void);
553 void gexpr(void);
554 void decl(int l);
555 static void decl_initializer(int t, Section *sec, unsigned long c,
556 int first, int size_only);
557 static void decl_initializer_alloc(int t, AttributeDef *ad, int r,
558 int has_init, int v, int scope);
559 int gv(int rc);
560 void gv2(int rc1, int rc2);
561 void move_reg(int r, int s);
562 void save_regs(int n);
563 void save_reg(int r);
564 void vpop(void);
565 void vswap(void);
566 void vdup(void);
567 int get_reg(int rc);
569 void macro_subst(TokenString *tok_str,
570 Sym **nested_list, int *macro_str);
571 int save_reg_forced(int r);
572 void gen_op(int op);
573 void force_charshort_cast(int t);
574 void gen_cast(int t);
575 void vstore(void);
576 Sym *sym_find(int v);
577 Sym *sym_push(int v, int t, int r, int c);
579 /* type handling */
580 int type_size(int t, int *a);
581 int pointed_type(int t);
582 int pointed_size(int t);
583 static int lvalue_type(int t);
584 int is_compatible_types(int t1, int t2);
585 int parse_btype(int *type_ptr, AttributeDef *ad);
586 int type_decl(AttributeDef *ad, int *v, int t, int td);
588 void error(const char *fmt, ...);
589 void rt_error(unsigned long pc, const char *fmt, ...);
590 void vpushi(int v);
591 void vset(int t, int r, int v);
592 void type_to_str(char *buf, int buf_size,
593 int t, const char *varstr);
594 char *get_tok_str(int v, CValue *cv);
595 static Sym *get_sym_ref(int t, Section *sec,
596 unsigned long offset, unsigned long size);
597 static Sym *external_global_sym(int v, int u, int r);
599 /* section generation */
600 static void section_realloc(Section *sec, unsigned long new_size);
601 static void *section_ptr_add(Section *sec, unsigned long size);
602 static void put_extern_sym(Sym *sym, Section *section,
603 unsigned long value, unsigned long size);
604 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
605 static int put_elf_str(Section *s, const char *sym);
606 static int put_elf_sym(Section *s,
607 unsigned long value, unsigned long size,
608 int info, int other, int shndx, const char *name);
609 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
610 int info, int sh_num, const char *name);
611 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
612 int type, int symbol);
613 static void put_stabs(const char *str, int type, int other, int desc,
614 unsigned long value);
615 static void put_stabs_r(const char *str, int type, int other, int desc,
616 unsigned long value, Section *sec, int sym_index);
617 static void put_stabn(int type, int other, int desc, int value);
618 static void put_stabd(int type, int other, int desc);
619 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
621 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
622 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
623 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
625 /* true if float/double/long double type */
626 static inline int is_float(int t)
628 int bt;
629 bt = t & VT_BTYPE;
630 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
633 #ifdef TCC_TARGET_I386
634 #include "i386-gen.c"
635 #endif
636 #ifdef TCC_TARGET_IL
637 #include "il-gen.c"
638 #endif
640 #ifdef CONFIG_TCC_STATIC
642 #define RTLD_LAZY 0x001
643 #define RTLD_NOW 0x002
644 #define RTLD_GLOBAL 0x100
646 /* dummy function for profiling */
647 void *dlopen(const char *filename, int flag)
649 return NULL;
652 const char *dlerror(void)
654 return "error";
657 typedef struct TCCSyms {
658 char *str;
659 void *ptr;
660 } TCCSyms;
662 #define TCCSYM(a) { #a, &a, },
664 /* add the symbol you want here if no dynamic linking is done */
665 static TCCSyms tcc_syms[] = {
666 TCCSYM(printf)
667 TCCSYM(fprintf)
668 TCCSYM(fopen)
669 TCCSYM(fclose)
670 { NULL, NULL },
673 void *dlsym(void *handle, const char *symbol)
675 TCCSyms *p;
676 p = tcc_syms;
677 while (p->str != NULL) {
678 if (!strcmp(p->str, symbol))
679 return p->ptr;
680 p++;
682 return NULL;
685 #endif
687 /********************************************************/
689 /* we use our own 'finite' function to avoid potential problems with
690 non standard math libs */
691 /* XXX: endianness dependant */
692 int ieee_finite(double d)
694 int *p = (int *)&d;
695 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
698 /* copy a string and truncate it. */
699 static char *pstrcpy(char *buf, int buf_size, const char *s)
701 char *q, *q_end;
702 int c;
704 if (buf_size > 0) {
705 q = buf;
706 q_end = buf + buf_size - 1;
707 while (q < q_end) {
708 c = *s++;
709 if (c == '\0')
710 break;
711 *q++ = c;
713 *q = '\0';
715 return buf;
718 /* strcat and truncate. */
719 static char *pstrcat(char *buf, int buf_size, const char *s)
721 int len;
722 len = strlen(buf);
723 if (len < buf_size)
724 pstrcpy(buf + len, buf_size - len, s);
725 return buf;
728 /* memory management */
729 #ifdef MEM_DEBUG
730 int mem_cur_size;
731 int mem_max_size;
732 #endif
734 static inline void tcc_free(void *ptr)
736 #ifdef MEM_DEBUG
737 mem_cur_size -= malloc_usable_size(ptr);
738 #endif
739 free(ptr);
742 static void *tcc_malloc(unsigned long size)
744 void *ptr;
745 ptr = malloc(size);
746 if (!ptr)
747 error("memory full");
748 #ifdef MEM_DEBUG
749 mem_cur_size += malloc_usable_size(ptr);
750 if (mem_cur_size > mem_max_size)
751 mem_max_size = mem_cur_size;
752 #endif
753 return ptr;
756 static void *tcc_mallocz(unsigned long size)
758 void *ptr;
759 ptr = tcc_malloc(size);
760 memset(ptr, 0, size);
761 return ptr;
764 static inline void *tcc_realloc(void *ptr, unsigned long size)
766 void *ptr1;
767 #ifdef MEM_DEBUG
768 mem_cur_size -= malloc_usable_size(ptr);
769 #endif
770 ptr1 = realloc(ptr, size);
771 #ifdef MEM_DEBUG
772 /* NOTE: count not correct if alloc error, but not critical */
773 mem_cur_size += malloc_usable_size(ptr1);
774 if (mem_cur_size > mem_max_size)
775 mem_max_size = mem_cur_size;
776 #endif
777 return ptr1;
780 static char *tcc_strdup(const char *str)
782 char *ptr;
783 ptr = tcc_malloc(strlen(str) + 1);
784 strcpy(ptr, str);
785 return ptr;
788 #define free(p) use_tcc_free(p)
789 #define malloc(s) use_tcc_malloc(s)
790 #define realloc(p, s) use_tcc_realloc(p, s)
792 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
794 int nb, nb_alloc;
795 void **pp;
797 nb = *nb_ptr;
798 pp = *ptab;
799 /* every power of two we double array size */
800 if ((nb & (nb - 1)) == 0) {
801 if (!nb)
802 nb_alloc = 1;
803 else
804 nb_alloc = nb * 2;
805 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
806 if (!pp)
807 error("memory full");
808 *ptab = pp;
810 pp[nb++] = data;
811 *nb_ptr = nb;
814 Section *new_section(const char *name, int sh_type, int sh_flags)
816 Section *sec;
818 sec = tcc_mallocz(sizeof(Section));
819 pstrcpy(sec->name, sizeof(sec->name), name);
820 sec->sh_type = sh_type;
821 sec->sh_flags = sh_flags;
822 switch(sh_type) {
823 case SHT_HASH:
824 case SHT_REL:
825 case SHT_DYNSYM:
826 case SHT_SYMTAB:
827 case SHT_DYNAMIC:
828 sec->sh_addralign = 4;
829 break;
830 case SHT_STRTAB:
831 sec->sh_addralign = 1;
832 break;
833 default:
834 sec->sh_addralign = 32; /* default conservative alignment */
835 break;
838 /* only add section if not private */
839 if (!(sh_flags & SHF_PRIVATE)) {
840 sec->sh_num = nb_sections;
841 dynarray_add((void ***)&sections, &nb_sections, sec);
843 return sec;
846 /* realloc section and set its content to zero */
847 static void section_realloc(Section *sec, unsigned long new_size)
849 unsigned long size;
850 unsigned char *data;
852 size = sec->data_allocated;
853 if (size == 0)
854 size = 1;
855 while (size < new_size)
856 size = size * 2;
857 data = tcc_realloc(sec->data, size);
858 if (!data)
859 error("memory full");
860 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
861 sec->data = data;
862 sec->data_allocated = size;
865 /* reserve at least 'size' bytes in section 'sec' from
866 sec->data_offset. */
867 static void *section_ptr_add(Section *sec, unsigned long size)
869 unsigned long offset, offset1;
871 offset = sec->data_offset;
872 offset1 = offset + size;
873 if (offset1 > sec->data_allocated)
874 section_realloc(sec, offset1);
875 sec->data_offset = offset1;
876 return sec->data + offset;
879 /* return a reference to a section, and create it if it does not
880 exists */
881 Section *find_section(const char *name)
883 Section *sec;
884 int i;
885 for(i = 1; i < nb_sections; i++) {
886 sec = sections[i];
887 if (!strcmp(name, sec->name))
888 return sec;
890 /* sections are created as PROGBITS */
891 return new_section(name, SHT_PROGBITS, SHF_ALLOC);
894 /* update sym->c so that it points to an external symbol in section
895 'section' with value 'value' */
896 static void put_extern_sym(Sym *sym, Section *section,
897 unsigned long value, unsigned long size)
899 int sym_type, sym_bind, sh_num, info;
900 Elf32_Sym *esym;
901 const char *name;
902 char buf[32];
904 if (section)
905 sh_num = section->sh_num;
906 else
907 sh_num = SHN_UNDEF;
908 if (!sym->c) {
909 if ((sym->t & VT_BTYPE) == VT_FUNC)
910 sym_type = STT_FUNC;
911 else
912 sym_type = STT_OBJECT;
913 if (sym->t & VT_STATIC)
914 sym_bind = STB_LOCAL;
915 else
916 sym_bind = STB_GLOBAL;
918 name = get_tok_str(sym->v, NULL);
919 #ifdef CONFIG_TCC_BCHECK
920 if (do_bounds_check) {
921 /* if bound checking is activated, we change some function
922 names by adding the "__bound" prefix */
923 switch(sym->v) {
924 case TOK_malloc:
925 case TOK_free:
926 case TOK_realloc:
927 case TOK_memalign:
928 case TOK_calloc:
929 case TOK_memcpy:
930 case TOK_memmove:
931 case TOK_memset:
932 case TOK_strlen:
933 case TOK_strcpy:
934 strcpy(buf, "__bound_");
935 strcat(buf, name);
936 name = buf;
937 break;
940 #endif
941 info = ELF32_ST_INFO(sym_bind, sym_type);
942 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
943 } else {
944 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
945 esym->st_value = value;
946 esym->st_size = size;
947 esym->st_shndx = sh_num;
951 /* add a new relocation entry to symbol 'sym' in section 's' */
952 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
954 if (!sym->c)
955 put_extern_sym(sym, NULL, 0, 0);
956 /* now we can add ELF relocation info */
957 put_elf_reloc(symtab_section, s, offset, type, sym->c);
960 static inline int isid(int c)
962 return (c >= 'a' && c <= 'z') ||
963 (c >= 'A' && c <= 'Z') ||
964 c == '_';
967 static inline int isnum(int c)
969 return c >= '0' && c <= '9';
972 static inline int isoct(int c)
974 return c >= '0' && c <= '7';
977 static inline int toup(int c)
979 if (ch >= 'a' && ch <= 'z')
980 return ch - 'a' + 'A';
981 else
982 return ch;
985 void printline(void)
987 BufferedFile **f;
989 if (file) {
990 for(f = include_stack; f < include_stack_ptr; f++)
991 fprintf(stderr, "In file included from %s:%d:\n",
992 (*f)->filename, (*f)->line_num);
993 if (file->line_num > 0) {
994 fprintf(stderr, "%s:%d: ", file->filename, file->line_num);
995 } else {
996 fprintf(stderr, "%s: ", file->filename);
998 } else {
999 fprintf(stderr, "tcc: ");
1003 void error(const char *fmt, ...)
1005 va_list ap;
1006 va_start(ap, fmt);
1007 printline();
1008 vfprintf(stderr, fmt, ap);
1009 fprintf(stderr, "\n");
1010 exit(1);
1011 va_end(ap);
1014 void expect(const char *msg)
1016 error("%s expected", msg);
1019 void warning(const char *fmt, ...)
1021 va_list ap;
1023 va_start(ap, fmt);
1024 printline();
1025 fprintf(stderr, "warning: ");
1026 vfprintf(stderr, fmt, ap);
1027 fprintf(stderr, "\n");
1028 va_end(ap);
1031 void skip(int c)
1033 if (tok != c)
1034 error("'%c' expected", c);
1035 next();
1038 void test_lvalue(void)
1040 if (!(vtop->r & VT_LVAL))
1041 expect("lvalue");
1044 TokenSym *tok_alloc(const char *str, int len)
1046 TokenSym *ts, **pts, **ptable;
1047 int h, i;
1049 if (len <= 0)
1050 len = strlen(str);
1051 h = 1;
1052 for(i=0;i<len;i++)
1053 h = (h * 263 + ((unsigned char *)str)[i]) & (TOK_HASH_SIZE - 1);
1055 pts = &hash_ident[h];
1056 while (1) {
1057 ts = *pts;
1058 if (!ts)
1059 break;
1060 if (ts->len == len && !memcmp(ts->str, str, len))
1061 return ts;
1062 pts = &(ts->hash_next);
1065 if (tok_ident >= SYM_FIRST_ANOM)
1066 error("memory full");
1068 /* expand token table if needed */
1069 i = tok_ident - TOK_IDENT;
1070 if ((i % TOK_ALLOC_INCR) == 0) {
1071 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1072 if (!ptable)
1073 error("memory full");
1074 table_ident = ptable;
1077 ts = tcc_malloc(sizeof(TokenSym) + len);
1078 table_ident[i] = ts;
1079 ts->tok = tok_ident++;
1080 ts->len = len;
1081 ts->hash_next = NULL;
1082 memcpy(ts->str, str, len + 1);
1083 *pts = ts;
1084 return ts;
1087 /* CString handling */
1089 static void cstr_realloc(CString *cstr, int new_size)
1091 int size;
1092 void *data;
1094 size = cstr->size_allocated;
1095 if (size == 0)
1096 size = 8; /* no need to allocate a too small first string */
1097 while (size < new_size)
1098 size = size * 2;
1099 data = tcc_realloc(cstr->data_allocated, size);
1100 if (!data)
1101 error("memory full");
1102 cstr->data_allocated = data;
1103 cstr->size_allocated = size;
1104 cstr->data = data;
1107 /* add a byte */
1108 static void cstr_ccat(CString *cstr, int ch)
1110 int size;
1111 size = cstr->size + 1;
1112 if (size > cstr->size_allocated)
1113 cstr_realloc(cstr, size);
1114 ((unsigned char *)cstr->data)[size - 1] = ch;
1115 cstr->size = size;
1118 static void cstr_cat(CString *cstr, const char *str)
1120 int c;
1121 for(;;) {
1122 c = *str;
1123 if (c == '\0')
1124 break;
1125 cstr_ccat(cstr, c);
1126 str++;
1130 /* add a wide char */
1131 static void cstr_wccat(CString *cstr, int ch)
1133 int size;
1134 size = cstr->size + sizeof(int);
1135 if (size > cstr->size_allocated)
1136 cstr_realloc(cstr, size);
1137 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1138 cstr->size = size;
1141 static void cstr_new(CString *cstr)
1143 memset(cstr, 0, sizeof(CString));
1146 /* free string and reset it to NULL */
1147 static void cstr_free(CString *cstr)
1149 tcc_free(cstr->data_allocated);
1150 cstr_new(cstr);
1153 #define cstr_reset(cstr) cstr_free(cstr)
1155 /* XXX: unicode ? */
1156 static void add_char(CString *cstr, int c)
1158 if (c == '\'' || c == '\"' || c == '\\') {
1159 /* XXX: could be more precise if char or string */
1160 cstr_ccat(cstr, '\\');
1162 if (c >= 32 && c <= 126) {
1163 cstr_ccat(cstr, c);
1164 } else {
1165 cstr_ccat(cstr, '\\');
1166 if (c == '\n') {
1167 cstr_ccat(cstr, 'n');
1168 } else {
1169 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1170 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1171 cstr_ccat(cstr, '0' + (c & 7));
1176 /* XXX: buffer overflow */
1177 /* XXX: float tokens */
1178 char *get_tok_str(int v, CValue *cv)
1180 static char buf[STRING_MAX_SIZE + 1];
1181 static CString cstr_buf;
1182 CString *cstr;
1183 unsigned char *q;
1184 char *p;
1185 int i, len;
1187 /* NOTE: to go faster, we give a fixed buffer for small strings */
1188 cstr_reset(&cstr_buf);
1189 cstr_buf.data = buf;
1190 cstr_buf.size_allocated = sizeof(buf);
1191 p = buf;
1193 switch(v) {
1194 case TOK_CINT:
1195 case TOK_CUINT:
1196 /* XXX: not exact */
1197 sprintf(p, "%u", cv->ui);
1198 break;
1199 case TOK_CCHAR:
1200 case TOK_LCHAR:
1201 cstr_ccat(&cstr_buf, '\'');
1202 add_char(&cstr_buf, cv->i);
1203 cstr_ccat(&cstr_buf, '\'');
1204 cstr_ccat(&cstr_buf, '\0');
1205 break;
1206 case TOK_STR:
1207 case TOK_LSTR:
1208 cstr = cv->cstr;
1209 cstr_ccat(&cstr_buf, '\"');
1210 if (v == TOK_STR) {
1211 len = cstr->size - 1;
1212 for(i=0;i<len;i++)
1213 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1214 } else {
1215 len = (cstr->size / sizeof(int)) - 1;
1216 for(i=0;i<len;i++)
1217 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1219 cstr_ccat(&cstr_buf, '\"');
1220 cstr_ccat(&cstr_buf, '\0');
1221 break;
1222 case TOK_LT:
1223 v = '<';
1224 goto addv;
1225 case TOK_GT:
1226 v = '>';
1227 goto addv;
1228 case TOK_A_SHL:
1229 return strcpy(p, "<<=");
1230 case TOK_A_SAR:
1231 return strcpy(p, ">>=");
1232 default:
1233 if (v < TOK_IDENT) {
1234 /* search in two bytes table */
1235 q = tok_two_chars;
1236 while (*q) {
1237 if (q[2] == v) {
1238 *p++ = q[0];
1239 *p++ = q[1];
1240 *p = '\0';
1241 return buf;
1243 q += 3;
1245 addv:
1246 *p++ = v;
1247 *p = '\0';
1248 } else if (v < tok_ident) {
1249 return table_ident[v - TOK_IDENT]->str;
1250 } else if (v >= SYM_FIRST_ANOM) {
1251 /* special name for anonymous symbol */
1252 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1253 } else {
1254 /* should never happen */
1255 return NULL;
1257 break;
1259 return cstr_buf.data;
1262 /* push, without hashing */
1263 Sym *sym_push2(Sym **ps, int v, int t, int c)
1265 Sym *s;
1266 s = tcc_malloc(sizeof(Sym));
1267 s->v = v;
1268 s->t = t;
1269 s->c = c;
1270 s->next = NULL;
1271 /* add in stack */
1272 s->prev = *ps;
1273 *ps = s;
1274 return s;
1277 /* find a symbol and return its associated structure. 's' is the top
1278 of the symbol stack */
1279 Sym *sym_find2(Sym *s, int v)
1281 while (s) {
1282 if (s->v == v)
1283 return s;
1284 s = s->prev;
1286 return NULL;
1289 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1291 /* find a symbol and return its associated structure. 'st' is the
1292 symbol stack */
1293 Sym *sym_find1(SymStack *st, int v)
1295 Sym *s;
1297 s = st->hash[HASH_SYM(v)];
1298 while (s) {
1299 if (s->v == v)
1300 return s;
1301 s = s->hash_next;
1303 return NULL;
1306 Sym *sym_push1(SymStack *st, int v, int t, int c)
1308 Sym *s, **ps;
1309 s = sym_push2(&st->top, v, t, c);
1310 /* add in hash table */
1311 if (v) {
1312 ps = &st->hash[HASH_SYM(v)];
1313 s->hash_next = *ps;
1314 *ps = s;
1316 return s;
1319 /* find a symbol in the right symbol space */
1320 Sym *sym_find(int v)
1322 Sym *s;
1323 s = sym_find1(&local_stack, v);
1324 if (!s)
1325 s = sym_find1(&global_stack, v);
1326 return s;
1329 /* push a given symbol on the symbol stack */
1330 Sym *sym_push(int v, int t, int r, int c)
1332 Sym *s;
1333 if (local_stack.top)
1334 s = sym_push1(&local_stack, v, t, c);
1335 else
1336 s = sym_push1(&global_stack, v, t, c);
1337 s->r = r;
1338 return s;
1341 /* pop symbols until top reaches 'b' */
1342 void sym_pop(SymStack *st, Sym *b)
1344 Sym *s, *ss;
1346 s = st->top;
1347 while(s != b) {
1348 ss = s->prev;
1349 /* free hash table entry, except if symbol was freed (only
1350 used for #undef symbols) */
1351 if (s->v)
1352 st->hash[HASH_SYM(s->v)] = s->hash_next;
1353 tcc_free(s);
1354 s = ss;
1356 st->top = b;
1359 /* undefined a hashed symbol (used for #undef). Its name is set to
1360 zero */
1361 void sym_undef(SymStack *st, Sym *s)
1363 Sym **ss;
1364 ss = &st->hash[HASH_SYM(s->v)];
1365 while (*ss != NULL) {
1366 if (*ss == s)
1367 break;
1368 ss = &(*ss)->hash_next;
1370 *ss = s->hash_next;
1371 s->v = 0;
1374 /* I/O layer */
1376 BufferedFile *tcc_open(const char *filename)
1378 int fd;
1379 BufferedFile *bf;
1381 fd = open(filename, O_RDONLY);
1382 if (fd < 0)
1383 return NULL;
1384 bf = tcc_malloc(sizeof(BufferedFile));
1385 if (!bf) {
1386 close(fd);
1387 return NULL;
1389 bf->fd = fd;
1390 bf->buf_ptr = bf->buffer;
1391 bf->buf_end = bf->buffer;
1392 bf->buffer[0] = CH_EOB; /* put eob symbol */
1393 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1394 bf->line_num = 1;
1395 // printf("opening '%s'\n", filename);
1396 return bf;
1399 void tcc_close(BufferedFile *bf)
1401 total_lines += bf->line_num;
1402 close(bf->fd);
1403 tcc_free(bf);
1406 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1407 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1409 /* fill input buffer and return next char */
1410 int tcc_getc_slow(BufferedFile *bf)
1412 int len;
1413 /* only tries to read if really end of buffer */
1414 if (bf->buf_ptr >= bf->buf_end) {
1415 if (bf->fd != -1) {
1416 len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
1417 if (len < 0)
1418 len = 0;
1419 } else {
1420 len = 0;
1422 total_bytes += len;
1423 bf->buf_ptr = bf->buffer;
1424 bf->buf_end = bf->buffer + len;
1425 *bf->buf_end = CH_EOB;
1427 if (bf->buf_ptr < bf->buf_end) {
1428 return *bf->buf_ptr++;
1429 } else {
1430 bf->buf_ptr = bf->buf_end;
1431 return CH_EOF;
1435 /* no need to put that inline */
1436 void handle_eob(void)
1438 for(;;) {
1439 ch1 = tcc_getc_slow(file);
1440 if (ch1 != CH_EOF)
1441 return;
1443 if (include_stack_ptr == include_stack)
1444 return;
1445 /* add end of include file debug info */
1446 if (do_debug) {
1447 put_stabd(N_EINCL, 0, 0);
1449 /* pop include stack */
1450 tcc_close(file);
1451 include_stack_ptr--;
1452 file = *include_stack_ptr;
1456 /* read next char from current input file */
1457 static inline void inp(void)
1459 ch1 = TCC_GETC(file);
1460 /* end of buffer/file handling */
1461 if (ch1 == CH_EOB)
1462 handle_eob();
1463 if (ch1 == '\n')
1464 file->line_num++;
1465 // printf("ch1=%c 0x%x\n", ch1, ch1);
1468 /* handle '\\n' and '\\r\n' */
1469 static void handle_stray(void)
1471 do {
1472 if (ch1 == '\n') {
1473 inp();
1474 } else if (ch1 == '\r') {
1475 inp();
1476 if (ch1 != '\n')
1477 error("invalid character after '\\'");
1478 inp();
1479 } else {
1480 break;
1482 ch = ch1;
1483 inp();
1484 } while (ch == '\\');
1487 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1488 case */
1489 static inline void minp(void)
1491 ch = ch1;
1492 inp();
1493 if (ch == '\\')
1494 handle_stray();
1498 /* same as minp, but also skip comments */
1499 static void cinp(void)
1501 int c;
1503 if (ch1 == '/') {
1504 inp();
1505 if (ch1 == '/') {
1506 /* single line C++ comments */
1507 inp();
1508 while (ch1 != '\n' && ch1 != CH_EOF)
1509 inp();
1510 ch = ' '; /* return space */
1511 } else if (ch1 == '*') {
1512 /* C comments */
1513 inp();
1514 while (ch1 != CH_EOF) {
1515 c = ch1;
1516 inp();
1517 if (c == '*' && ch1 == '/') {
1518 inp();
1519 ch = ' '; /* return space */
1520 break;
1523 } else {
1524 ch = '/';
1526 } else {
1527 minp();
1531 /* space exlcuding newline */
1532 static inline int is_space(int ch)
1534 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1537 static inline void skip_spaces(void)
1539 while (is_space(ch))
1540 cinp();
1543 /* skip block of text until #else, #elif or #endif. skip also pairs of
1544 #if/#endif */
1545 void preprocess_skip(void)
1547 int a;
1548 a = 0;
1549 while (1) {
1550 while (ch != '\n') {
1551 if (ch == CH_EOF)
1552 expect("#endif");
1553 cinp();
1555 cinp();
1556 skip_spaces();
1557 if (ch == '#') {
1558 cinp();
1559 next_nomacro();
1560 if (a == 0 &&
1561 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1562 break;
1563 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1564 a++;
1565 else if (tok == TOK_ENDIF)
1566 a--;
1571 /* ParseState handling */
1573 /* XXX: currently, no include file info is stored. Thus, we cannot display
1574 accurate messages if the function or data definition spans multiple
1575 files */
1577 /* save current parse state in 's' */
1578 void save_parse_state(ParseState *s)
1580 s->line_num = file->line_num;
1581 s->macro_ptr = macro_ptr;
1582 s->tok = tok;
1583 s->tokc = tokc;
1586 /* restore parse state from 's' */
1587 void restore_parse_state(ParseState *s)
1589 file->line_num = s->line_num;
1590 macro_ptr = s->macro_ptr;
1591 tok = s->tok;
1592 tokc = s->tokc;
1595 /* return the number of additionnal 'ints' necessary to store the
1596 token */
1597 static inline int tok_ext_size(int t)
1599 switch(t) {
1600 /* 4 bytes */
1601 case TOK_CINT:
1602 case TOK_CUINT:
1603 case TOK_CCHAR:
1604 case TOK_LCHAR:
1605 case TOK_STR:
1606 case TOK_LSTR:
1607 case TOK_CFLOAT:
1608 case TOK_LINENUM:
1609 return 1;
1610 case TOK_CDOUBLE:
1611 case TOK_CLLONG:
1612 case TOK_CULLONG:
1613 return 2;
1614 case TOK_CLDOUBLE:
1615 return LDOUBLE_SIZE / 4;
1616 default:
1617 return 0;
1621 /* token string handling */
1623 static inline void tok_str_new(TokenString *s)
1625 s->str = NULL;
1626 s->len = 0;
1627 s->last_line_num = -1;
1630 static void tok_str_free(int *str)
1632 const int *p;
1633 CString *cstr;
1634 int t;
1636 p = str;
1637 for(;;) {
1638 t = *p++;
1639 if (t == 0)
1640 break;
1641 if (t == TOK_STR || t == TOK_LSTR) {
1642 /* XXX: use a macro to be portable on 64 bit ? */
1643 cstr = (CString *)(*p++);
1644 cstr_free(cstr);
1645 tcc_free(cstr);
1646 } else {
1647 p += tok_ext_size(t);
1650 tcc_free(str);
1653 static void tok_str_add(TokenString *s, int t)
1655 int len, *str;
1657 len = s->len;
1658 str = s->str;
1659 if ((len & 63) == 0) {
1660 str = tcc_realloc(str, (len + 64) * sizeof(int));
1661 if (!str)
1662 return;
1663 s->str = str;
1665 str[len++] = t;
1666 s->len = len;
1669 static void tok_str_add2(TokenString *s, int t, CValue *cv)
1671 int n, i, size;
1672 CString *cstr, *cstr1;
1673 CValue cv1;
1675 tok_str_add(s, t);
1676 if (t == TOK_STR || t == TOK_LSTR) {
1677 /* special case: need to duplicate string */
1678 cstr1 = cv->cstr;
1679 cstr = tcc_malloc(sizeof(CString));
1680 size = cstr1->size;
1681 cstr->size = size;
1682 cstr->size_allocated = size;
1683 cstr->data_allocated = tcc_malloc(size);
1684 cstr->data = cstr->data_allocated;
1685 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1686 cv1.cstr = cstr;
1687 tok_str_add(s, cv1.tab[0]);
1688 } else {
1689 n = tok_ext_size(t);
1690 for(i=0;i<n;i++)
1691 tok_str_add(s, cv->tab[i]);
1695 /* add the current parse token in token string 's' */
1696 static void tok_str_add_tok(TokenString *s)
1698 CValue cval;
1700 /* save line number info */
1701 if (file->line_num != s->last_line_num) {
1702 s->last_line_num = file->line_num;
1703 cval.i = s->last_line_num;
1704 tok_str_add2(s, TOK_LINENUM, &cval);
1706 tok_str_add2(s, tok, &tokc);
1709 /* get a token from an integer array and increment pointer accordingly */
1710 static int tok_get(int **tok_str, CValue *cv)
1712 int *p, t, n, i;
1714 p = *tok_str;
1715 t = *p++;
1716 n = tok_ext_size(t);
1717 for(i=0;i<n;i++)
1718 cv->tab[i] = *p++;
1719 *tok_str = p;
1720 return t;
1723 /* eval an expression for #if/#elif */
1724 int expr_preprocess(void)
1726 int c, t;
1727 TokenString str;
1729 tok_str_new(&str);
1730 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1731 next(); /* do macro subst */
1732 if (tok == TOK_DEFINED) {
1733 next_nomacro();
1734 t = tok;
1735 if (t == '(')
1736 next_nomacro();
1737 c = sym_find1(&define_stack, tok) != 0;
1738 if (t == '(')
1739 next_nomacro();
1740 tok = TOK_CINT;
1741 tokc.i = c;
1742 } else if (tok >= TOK_IDENT) {
1743 /* if undefined macro */
1744 tok = TOK_CINT;
1745 tokc.i = 0;
1747 tok_str_add_tok(&str);
1749 tok_str_add(&str, -1); /* simulate end of file */
1750 tok_str_add(&str, 0);
1751 /* now evaluate C constant expression */
1752 macro_ptr = str.str;
1753 next();
1754 c = expr_const();
1755 macro_ptr = NULL;
1756 tok_str_free(str.str);
1757 return c != 0;
1760 #if defined(DEBUG) || defined(PP_DEBUG)
1761 void tok_print(int *str)
1763 int t;
1764 CValue cval;
1766 while (1) {
1767 t = tok_get(&str, &cval);
1768 if (!t)
1769 break;
1770 printf(" %s", get_tok_str(t, &cval));
1772 printf("\n");
1774 #endif
1776 /* parse after #define */
1777 void parse_define(void)
1779 Sym *s, *first, **ps;
1780 int v, t, varg, is_vaargs;
1781 TokenString str;
1783 v = tok;
1784 /* XXX: should check if same macro (ANSI) */
1785 first = NULL;
1786 t = MACRO_OBJ;
1787 /* '(' must be just after macro definition for MACRO_FUNC */
1788 if (ch == '(') {
1789 next_nomacro();
1790 next_nomacro();
1791 ps = &first;
1792 while (tok != ')') {
1793 varg = tok;
1794 next_nomacro();
1795 is_vaargs = 0;
1796 if (varg == TOK_DOTS) {
1797 varg = TOK___VA_ARGS__;
1798 is_vaargs = 1;
1799 } else if (tok == TOK_DOTS && gnu_ext) {
1800 is_vaargs = 1;
1801 next_nomacro();
1803 if (varg < TOK_IDENT)
1804 error("badly punctuated parameter list");
1805 s = sym_push1(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
1806 *ps = s;
1807 ps = &s->next;
1808 if (tok != ',')
1809 break;
1810 next_nomacro();
1812 t = MACRO_FUNC;
1814 tok_str_new(&str);
1815 while (1) {
1816 skip_spaces();
1817 if (ch == '\n' || ch == CH_EOF)
1818 break;
1819 next_nomacro();
1820 tok_str_add2(&str, tok, &tokc);
1822 tok_str_add(&str, 0);
1823 #ifdef PP_DEBUG
1824 printf("define %s %d: ", get_tok_str(v, NULL), t);
1825 tok_print(str.str);
1826 #endif
1827 s = sym_push1(&define_stack, v, t, (int)str.str);
1828 s->next = first;
1831 void preprocess(void)
1833 int size, i, c, n;
1834 char buf[1024], *q, *p;
1835 char buf1[1024];
1836 BufferedFile *f;
1837 Sym *s;
1839 return_linefeed = 1; /* linefeed will be returned as a token */
1840 cinp();
1841 next_nomacro();
1842 redo:
1843 if (tok == TOK_DEFINE) {
1844 next_nomacro();
1845 parse_define();
1846 } else if (tok == TOK_UNDEF) {
1847 next_nomacro();
1848 s = sym_find1(&define_stack, tok);
1849 /* undefine symbol by putting an invalid name */
1850 if (s)
1851 sym_undef(&define_stack, s);
1852 } else if (tok == TOK_INCLUDE) {
1853 skip_spaces();
1854 if (ch == '<') {
1855 c = '>';
1856 goto read_name;
1857 } else if (ch == '\"') {
1858 c = ch;
1859 read_name:
1860 minp();
1861 q = buf;
1862 while (ch != c && ch != '\n' && ch != CH_EOF) {
1863 if ((q - buf) < sizeof(buf) - 1)
1864 *q++ = ch;
1865 minp();
1867 *q = '\0';
1868 /* eat all spaces and comments after include */
1869 /* XXX: slightly incorrect */
1870 while (ch1 != '\n' && ch1 != CH_EOF)
1871 inp();
1872 } else {
1873 /* computed #include : either we have only strings or
1874 we have anything enclosed in '<>' */
1875 next();
1876 buf[0] = '\0';
1877 if (tok == TOK_STR) {
1878 while (tok != TOK_LINEFEED) {
1879 if (tok != TOK_STR) {
1880 include_syntax:
1881 error("'#include' expects \"FILENAME\" or <FILENAME>");
1883 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
1884 next();
1886 c = '\"';
1887 } else {
1888 int len;
1889 while (tok != TOK_LINEFEED) {
1890 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
1891 next();
1893 len = strlen(buf);
1894 /* check syntax and remove '<>' */
1895 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
1896 goto include_syntax;
1897 memmove(buf, buf + 1, len - 2);
1898 buf[len - 2] = '\0';
1899 c = '>';
1903 if (include_stack_ptr >= include_stack + INCLUDE_STACK_SIZE)
1904 error("memory full");
1905 if (c == '\"') {
1906 /* first search in current dir if "header.h" */
1907 size = 0;
1908 p = strrchr(file->filename, '/');
1909 if (p)
1910 size = p + 1 - file->filename;
1911 if (size > sizeof(buf1) - 1)
1912 size = sizeof(buf1) - 1;
1913 memcpy(buf1, file->filename, size);
1914 buf1[size] = '\0';
1915 pstrcat(buf1, sizeof(buf1), buf);
1916 f = tcc_open(buf1);
1917 if (f)
1918 goto found;
1920 /* now search in all the include paths */
1921 n = nb_include_paths + nb_sysinclude_paths;
1922 for(i = 0; i < n; i++) {
1923 const char *path;
1924 if (i < nb_include_paths)
1925 path = include_paths[i];
1926 else
1927 path = sysinclude_paths[i - nb_include_paths];
1928 pstrcpy(buf1, sizeof(buf1), path);
1929 pstrcat(buf1, sizeof(buf1), "/");
1930 pstrcat(buf1, sizeof(buf1), buf);
1931 f = tcc_open(buf1);
1932 if (f)
1933 goto found;
1935 error("include file '%s' not found", buf);
1936 f = NULL;
1937 found:
1938 /* push current file in stack */
1939 /* XXX: fix current line init */
1940 *include_stack_ptr++ = file;
1941 file = f;
1942 /* add include file debug info */
1943 if (do_debug) {
1944 put_stabs(file->filename, N_BINCL, 0, 0, 0);
1946 ch = '\n';
1947 goto the_end;
1948 } else if (tok == TOK_IFNDEF) {
1949 c = 1;
1950 goto do_ifdef;
1951 } else if (tok == TOK_IF) {
1952 c = expr_preprocess();
1953 goto do_if;
1954 } else if (tok == TOK_IFDEF) {
1955 c = 0;
1956 do_ifdef:
1957 next_nomacro();
1958 c = (sym_find1(&define_stack, tok) != 0) ^ c;
1959 do_if:
1960 if (ifdef_stack_ptr >= ifdef_stack + IFDEF_STACK_SIZE)
1961 error("memory full");
1962 *ifdef_stack_ptr++ = c;
1963 goto test_skip;
1964 } else if (tok == TOK_ELSE) {
1965 if (ifdef_stack_ptr == ifdef_stack)
1966 error("#else without matching #if");
1967 if (ifdef_stack_ptr[-1] & 2)
1968 error("#else after #else");
1969 c = (ifdef_stack_ptr[-1] ^= 3);
1970 goto test_skip;
1971 } else if (tok == TOK_ELIF) {
1972 if (ifdef_stack_ptr == ifdef_stack)
1973 error("#elif without matching #if");
1974 c = ifdef_stack_ptr[-1];
1975 if (c > 1)
1976 error("#elif after #else");
1977 /* last #if/#elif expression was true: we skip */
1978 if (c == 1)
1979 goto skip;
1980 c = expr_preprocess();
1981 ifdef_stack_ptr[-1] = c;
1982 test_skip:
1983 if (!(c & 1)) {
1984 skip:
1985 preprocess_skip();
1986 goto redo;
1988 } else if (tok == TOK_ENDIF) {
1989 if (ifdef_stack_ptr == ifdef_stack)
1990 error("#endif without matching #if");
1991 ifdef_stack_ptr--;
1992 } else if (tok == TOK_LINE) {
1993 int line_num;
1994 next();
1995 if (tok != TOK_CINT)
1996 error("#line");
1997 line_num = tokc.i;
1998 next();
1999 if (tok != TOK_LINEFEED) {
2000 if (tok != TOK_STR)
2001 error("#line");
2002 pstrcpy(file->filename, sizeof(file->filename),
2003 (char *)tokc.cstr->data);
2005 /* NOTE: we do it there to avoid problems with linefeed */
2006 file->line_num = line_num;
2007 } else if (tok == TOK_ERROR) {
2008 error("#error");
2010 /* ignore other preprocess commands or #! for C scripts */
2011 while (tok != TOK_LINEFEED && tok != TOK_EOF)
2012 next_nomacro();
2013 the_end:
2014 return_linefeed = 0;
2017 /* read a number in base b */
2018 static int getn(int b)
2020 int n, t;
2021 n = 0;
2022 while (1) {
2023 if (ch >= 'a' && ch <= 'f')
2024 t = ch - 'a' + 10;
2025 else if (ch >= 'A' && ch <= 'F')
2026 t = ch - 'A' + 10;
2027 else if (isnum(ch))
2028 t = ch - '0';
2029 else
2030 break;
2031 if (t < 0 || t >= b)
2032 break;
2033 n = n * b + t;
2034 cinp();
2036 return n;
2039 /* read a character for string or char constant and eval escape codes */
2040 static int getq(void)
2042 int c;
2044 c = ch;
2045 minp();
2046 if (c == '\\') {
2047 if (isoct(ch)) {
2048 /* at most three octal digits */
2049 c = ch - '0';
2050 minp();
2051 if (isoct(ch)) {
2052 c = c * 8 + ch - '0';
2053 minp();
2054 if (isoct(ch)) {
2055 c = c * 8 + ch - '0';
2056 minp();
2059 return c;
2060 } else if (ch == 'x') {
2061 minp();
2062 return getn(16);
2063 } else {
2064 if (ch == 'a')
2065 c = '\a';
2066 else if (ch == 'b')
2067 c = '\b';
2068 else if (ch == 'f')
2069 c = '\f';
2070 else if (ch == 'n')
2071 c = '\n';
2072 else if (ch == 'r')
2073 c = '\r';
2074 else if (ch == 't')
2075 c = '\t';
2076 else if (ch == 'v')
2077 c = '\v';
2078 else if (ch == 'e' && gnu_ext)
2079 c = 27;
2080 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
2081 c = ch;
2082 else
2083 error("invalid escaped char");
2084 minp();
2086 } else if (c == '\r' && ch == '\n') {
2087 minp();
2088 c = '\n';
2090 return c;
2093 /* we use 64 bit numbers */
2094 #define BN_SIZE 2
2096 /* bn = (bn << shift) | or_val */
2097 void bn_lshift(unsigned int *bn, int shift, int or_val)
2099 int i;
2100 unsigned int v;
2101 for(i=0;i<BN_SIZE;i++) {
2102 v = bn[i];
2103 bn[i] = (v << shift) | or_val;
2104 or_val = v >> (32 - shift);
2108 void bn_zero(unsigned int *bn)
2110 int i;
2111 for(i=0;i<BN_SIZE;i++) {
2112 bn[i] = 0;
2116 void parse_number(void)
2118 int b, t, shift, frac_bits, s, exp_val;
2119 char *q;
2120 unsigned int bn[BN_SIZE];
2121 double d;
2123 /* number */
2124 q = token_buf;
2125 t = ch;
2126 cinp();
2127 *q++ = t;
2128 b = 10;
2129 if (t == '.') {
2130 /* special dot handling */
2131 if (ch >= '0' && ch <= '9') {
2132 goto float_frac_parse;
2133 } else if (ch == '.') {
2134 cinp();
2135 if (ch != '.')
2136 expect("'.'");
2137 cinp();
2138 tok = TOK_DOTS;
2139 } else {
2140 /* dots */
2141 tok = t;
2143 return;
2144 } else if (t == '0') {
2145 if (ch == 'x' || ch == 'X') {
2146 q--;
2147 cinp();
2148 b = 16;
2149 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2150 q--;
2151 cinp();
2152 b = 2;
2155 /* parse all digits. cannot check octal numbers at this stage
2156 because of floating point constants */
2157 while (1) {
2158 if (ch >= 'a' && ch <= 'f')
2159 t = ch - 'a' + 10;
2160 else if (ch >= 'A' && ch <= 'F')
2161 t = ch - 'A' + 10;
2162 else if (isnum(ch))
2163 t = ch - '0';
2164 else
2165 break;
2166 if (t >= b)
2167 break;
2168 if (q >= token_buf + STRING_MAX_SIZE) {
2169 num_too_long:
2170 error("number too long");
2172 *q++ = ch;
2173 cinp();
2175 if (ch == '.' ||
2176 ((ch == 'e' || ch == 'E') && b == 10) ||
2177 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2178 if (b != 10) {
2179 /* NOTE: strtox should support that for hexa numbers, but
2180 non ISOC99 libcs do not support it, so we prefer to do
2181 it by hand */
2182 /* hexadecimal or binary floats */
2183 /* XXX: handle overflows */
2184 *q = '\0';
2185 if (b == 16)
2186 shift = 4;
2187 else
2188 shift = 2;
2189 bn_zero(bn);
2190 q = token_buf;
2191 while (1) {
2192 t = *q++;
2193 if (t == '\0') {
2194 break;
2195 } else if (t >= 'a') {
2196 t = t - 'a' + 10;
2197 } else if (t >= 'A') {
2198 t = t - 'A' + 10;
2199 } else {
2200 t = t - '0';
2202 bn_lshift(bn, shift, t);
2204 frac_bits = 0;
2205 if (ch == '.') {
2206 cinp();
2207 while (1) {
2208 t = ch;
2209 if (t >= 'a' && t <= 'f') {
2210 t = t - 'a' + 10;
2211 } else if (t >= 'A' && t <= 'F') {
2212 t = t - 'A' + 10;
2213 } else if (t >= '0' && t <= '9') {
2214 t = t - '0';
2215 } else {
2216 break;
2218 if (t >= b)
2219 error("invalid digit");
2220 bn_lshift(bn, shift, t);
2221 frac_bits += shift;
2222 cinp();
2225 if (ch != 'p' && ch != 'P')
2226 error("exponent expected");
2227 cinp();
2228 s = 1;
2229 exp_val = 0;
2230 if (ch == '+') {
2231 cinp();
2232 } else if (ch == '-') {
2233 s = -1;
2234 cinp();
2236 if (ch < '0' || ch > '9')
2237 error("exponent digits expected");
2238 while (ch >= '0' && ch <= '9') {
2239 exp_val = exp_val * 10 + ch - '0';
2240 cinp();
2242 exp_val = exp_val * s;
2244 /* now we can generate the number */
2245 /* XXX: should patch directly float number */
2246 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
2247 d = ldexp(d, exp_val - frac_bits);
2248 t = toup(ch);
2249 if (t == 'F') {
2250 cinp();
2251 tok = TOK_CFLOAT;
2252 /* float : should handle overflow */
2253 tokc.f = (float)d;
2254 } else if (t == 'L') {
2255 cinp();
2256 tok = TOK_CLDOUBLE;
2257 /* XXX: not large enough */
2258 tokc.ld = (long double)d;
2259 } else {
2260 tok = TOK_CDOUBLE;
2261 tokc.d = d;
2263 } else {
2264 /* decimal floats */
2265 if (ch == '.') {
2266 if (q >= token_buf + STRING_MAX_SIZE)
2267 goto num_too_long;
2268 *q++ = ch;
2269 cinp();
2270 float_frac_parse:
2271 while (ch >= '0' && ch <= '9') {
2272 if (q >= token_buf + STRING_MAX_SIZE)
2273 goto num_too_long;
2274 *q++ = ch;
2275 cinp();
2278 if (ch == 'e' || ch == 'E') {
2279 if (q >= token_buf + STRING_MAX_SIZE)
2280 goto num_too_long;
2281 *q++ = ch;
2282 cinp();
2283 if (ch == '-' || ch == '+') {
2284 if (q >= token_buf + STRING_MAX_SIZE)
2285 goto num_too_long;
2286 *q++ = ch;
2287 cinp();
2289 if (ch < '0' || ch > '9')
2290 error("exponent digits expected");
2291 while (ch >= '0' && ch <= '9') {
2292 if (q >= token_buf + STRING_MAX_SIZE)
2293 goto num_too_long;
2294 *q++ = ch;
2295 cinp();
2298 *q = '\0';
2299 t = toup(ch);
2300 errno = 0;
2301 if (t == 'F') {
2302 cinp();
2303 tok = TOK_CFLOAT;
2304 tokc.f = strtof(token_buf, NULL);
2305 } else if (t == 'L') {
2306 cinp();
2307 tok = TOK_CLDOUBLE;
2308 tokc.ld = strtold(token_buf, NULL);
2309 } else {
2310 tok = TOK_CDOUBLE;
2311 tokc.d = strtod(token_buf, NULL);
2314 } else {
2315 unsigned long long n, n1;
2316 int lcount;
2318 /* integer number */
2319 *q = '\0';
2320 q = token_buf;
2321 if (b == 10 && *q == '0') {
2322 b = 8;
2323 q++;
2325 n = 0;
2326 while(1) {
2327 t = *q++;
2328 /* no need for checks except for base 10 / 8 errors */
2329 if (t == '\0') {
2330 break;
2331 } else if (t >= 'a') {
2332 t = t - 'a' + 10;
2333 } else if (t >= 'A') {
2334 t = t - 'A' + 10;
2335 } else {
2336 t = t - '0';
2337 if (t >= b)
2338 error("invalid digit");
2340 n1 = n;
2341 n = n * b + t;
2342 /* detect overflow */
2343 if (n < n1)
2344 error("integer constant overflow");
2347 /* XXX: not exactly ANSI compliant */
2348 if ((n & 0xffffffff00000000LL) != 0) {
2349 if ((n >> 63) != 0)
2350 tok = TOK_CULLONG;
2351 else
2352 tok = TOK_CLLONG;
2353 } else if (n > 0x7fffffff) {
2354 tok = TOK_CUINT;
2355 } else {
2356 tok = TOK_CINT;
2358 lcount = 0;
2359 for(;;) {
2360 t = toup(ch);
2361 if (t == 'L') {
2362 if (lcount >= 2)
2363 error("three 'l' in integer constant");
2364 lcount++;
2365 if (lcount == 2) {
2366 if (tok == TOK_CINT)
2367 tok = TOK_CLLONG;
2368 else if (tok == TOK_CUINT)
2369 tok = TOK_CULLONG;
2371 cinp();
2372 } else if (t == 'U') {
2373 if (tok == TOK_CINT)
2374 tok = TOK_CUINT;
2375 else if (tok == TOK_CLLONG)
2376 tok = TOK_CULLONG;
2377 cinp();
2378 } else {
2379 break;
2382 if (tok == TOK_CINT || tok == TOK_CUINT)
2383 tokc.ui = n;
2384 else
2385 tokc.ull = n;
2390 /* return next token without macro substitution */
2391 void next_nomacro1(void)
2393 int b;
2394 char *q;
2395 TokenSym *ts;
2397 /* skip spaces */
2398 while(1) {
2399 while (ch == '\n') {
2400 /* during preprocessor parsing, '\n' is a token */
2401 if (return_linefeed) {
2402 tok = TOK_LINEFEED;
2403 return;
2405 cinp();
2406 skip_spaces();
2407 if (ch == '#') {
2408 /* preprocessor command if # at start of line after
2409 spaces */
2410 preprocess();
2413 if (!is_space(ch))
2414 break;
2415 cinp();
2417 if (isid(ch)) {
2418 q = token_buf;
2419 *q++ = ch;
2420 cinp();
2421 if (q[-1] == 'L') {
2422 if (ch == '\'') {
2423 tok = TOK_LCHAR;
2424 goto char_const;
2426 if (ch == '\"') {
2427 tok = TOK_LSTR;
2428 goto str_const;
2431 while (isid(ch) || isnum(ch)) {
2432 if (q >= token_buf + STRING_MAX_SIZE)
2433 error("ident too long");
2434 *q++ = ch;
2435 cinp();
2437 *q = '\0';
2438 ts = tok_alloc(token_buf, q - token_buf);
2439 tok = ts->tok;
2440 } else if (isnum(ch) || ch == '.') {
2441 parse_number();
2442 } else if (ch == '\'') {
2443 tok = TOK_CCHAR;
2444 char_const:
2445 minp();
2446 b = getq();
2447 /* this cast is needed if >= 128 */
2448 if (tok == TOK_CCHAR)
2449 b = (char)b;
2450 tokc.i = b;
2451 if (ch != '\'')
2452 expect("\'");
2453 minp();
2454 } else if (ch == '\"') {
2455 tok = TOK_STR;
2456 str_const:
2457 minp();
2458 cstr_reset(&tokcstr);
2459 while (ch != '\"') {
2460 b = getq();
2461 if (ch == CH_EOF)
2462 error("unterminated string");
2463 if (tok == TOK_STR)
2464 cstr_ccat(&tokcstr, b);
2465 else
2466 cstr_wccat(&tokcstr, b);
2468 if (tok == TOK_STR)
2469 cstr_ccat(&tokcstr, '\0');
2470 else
2471 cstr_wccat(&tokcstr, '\0');
2472 tokc.cstr = &tokcstr;
2473 minp();
2474 } else {
2475 q = tok_two_chars;
2476 /* two chars */
2477 tok = ch;
2478 cinp();
2479 while (*q) {
2480 if (*q == tok && q[1] == ch) {
2481 cinp();
2482 tok = q[2] & 0xff;
2483 /* three chars tests */
2484 if (tok == TOK_SHL || tok == TOK_SAR) {
2485 if (ch == '=') {
2486 tok = tok | 0x80;
2487 cinp();
2489 } else if (tok == TOK_DOTS) {
2490 if (ch != '.')
2491 error("parse error");
2492 cinp();
2494 return;
2496 q = q + 3;
2498 /* single char substitutions */
2499 if (tok == '<')
2500 tok = TOK_LT;
2501 else if (tok == '>')
2502 tok = TOK_GT;
2506 /* return next token without macro substitution. Can read input from
2507 macro_ptr buffer */
2508 void next_nomacro()
2510 if (macro_ptr) {
2511 redo:
2512 tok = *macro_ptr;
2513 if (tok) {
2514 tok = tok_get(&macro_ptr, &tokc);
2515 if (tok == TOK_LINENUM) {
2516 file->line_num = tokc.i;
2517 goto redo;
2520 } else {
2521 next_nomacro1();
2525 /* substitute args in macro_str and return allocated string */
2526 int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
2528 int *st, last_tok, t, notfirst;
2529 Sym *s;
2530 CValue cval;
2531 TokenString str;
2532 CString cstr;
2534 tok_str_new(&str);
2535 last_tok = 0;
2536 while(1) {
2537 t = tok_get(&macro_str, &cval);
2538 if (!t)
2539 break;
2540 if (t == '#') {
2541 /* stringize */
2542 t = tok_get(&macro_str, &cval);
2543 if (!t)
2544 break;
2545 s = sym_find2(args, t);
2546 if (s) {
2547 cstr_new(&cstr);
2548 st = (int *)s->c;
2549 notfirst = 0;
2550 while (*st) {
2551 if (notfirst)
2552 cstr_ccat(&cstr, ' ');
2553 t = tok_get(&st, &cval);
2554 cstr_cat(&cstr, get_tok_str(t, &cval));
2555 notfirst = 1;
2557 cstr_ccat(&cstr, '\0');
2558 #ifdef PP_DEBUG
2559 printf("stringize: %s\n", (char *)cstr.data);
2560 #endif
2561 /* add string */
2562 cval.cstr = &cstr;
2563 tok_str_add2(&str, TOK_STR, &cval);
2564 cstr_free(&cstr);
2565 } else {
2566 tok_str_add2(&str, t, &cval);
2568 } else if (t >= TOK_IDENT) {
2569 s = sym_find2(args, t);
2570 if (s) {
2571 st = (int *)s->c;
2572 /* if '##' is present before or after, no arg substitution */
2573 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
2574 /* special case for var arg macros : ## eats the
2575 ',' if empty VA_ARGS riable. */
2576 /* XXX: test of the ',' is not 100%
2577 reliable. should fix it to avoid security
2578 problems */
2579 if (gnu_ext && s->t && *st == 0 &&
2580 last_tok == TOK_TWOSHARPS &&
2581 str.len >= 2 && str.str[str.len - 2] == ',') {
2582 /* suppress ',' '##' */
2583 str.len -= 2;
2584 } else {
2585 int t1;
2586 for(;;) {
2587 t1 = tok_get(&st, &cval);
2588 if (!t1)
2589 break;
2590 tok_str_add2(&str, t1, &cval);
2593 } else {
2594 macro_subst(&str, nested_list, st);
2596 } else {
2597 tok_str_add(&str, t);
2599 } else {
2600 tok_str_add2(&str, t, &cval);
2602 last_tok = t;
2604 tok_str_add(&str, 0);
2605 return str.str;
2608 /* handle the '##' operator */
2609 int *macro_twosharps(int *macro_str)
2611 TokenSym *ts;
2612 int *macro_ptr1;
2613 int t;
2614 char *p;
2615 CValue cval;
2616 TokenString macro_str1;
2618 tok_str_new(&macro_str1);
2619 tok = 0;
2620 while (1) {
2621 next_nomacro();
2622 if (tok == 0)
2623 break;
2624 while (*macro_ptr == TOK_TWOSHARPS) {
2625 macro_ptr++;
2626 macro_ptr1 = macro_ptr;
2627 t = *macro_ptr;
2628 if (t) {
2629 t = tok_get(&macro_ptr, &cval);
2630 /* XXX: we handle only most common cases:
2631 ident + ident or ident + number */
2632 if (tok >= TOK_IDENT &&
2633 (t >= TOK_IDENT || t == TOK_CINT)) {
2634 p = get_tok_str(tok, &tokc);
2635 pstrcpy(token_buf, sizeof(token_buf), p);
2636 p = get_tok_str(t, &cval);
2637 pstrcat(token_buf, sizeof(token_buf), p);
2638 ts = tok_alloc(token_buf, 0);
2639 tok = ts->tok; /* modify current token */
2640 } else {
2641 /* cannot merge tokens: skip '##' */
2642 macro_ptr = macro_ptr1;
2643 break;
2647 tok_str_add2(&macro_str1, tok, &tokc);
2649 tok_str_add(&macro_str1, 0);
2650 return macro_str1.str;
2653 /* do macro substitution of macro_str and add result to
2654 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2655 substituted. 'nested_list' is the list of all macros we got inside
2656 to avoid recursing. */
2657 void macro_subst(TokenString *tok_str,
2658 Sym **nested_list, int *macro_str)
2660 Sym *s, *args, *sa, *sa1;
2661 int parlevel, *mstr, t, *saved_macro_ptr;
2662 int mstr_allocated, *macro_str1;
2663 CString cstr;
2664 CValue cval;
2665 TokenString str;
2666 char *cstrval;
2668 saved_macro_ptr = macro_ptr;
2669 macro_ptr = macro_str;
2670 macro_str1 = NULL;
2671 if (macro_str) {
2672 /* first scan for '##' operator handling */
2673 macro_str1 = macro_twosharps(macro_str);
2674 macro_ptr = macro_str1;
2677 while (1) {
2678 next_nomacro();
2679 if (tok == 0)
2680 break;
2681 if ((s = sym_find1(&define_stack, tok)) != NULL) {
2682 /* if symbol is a macro, prepare substitution */
2683 /* if nested substitution, do nothing */
2684 if (sym_find2(*nested_list, tok))
2685 goto no_subst;
2687 /* special macros */
2688 if (tok == TOK___LINE__) {
2689 cval.i = file->line_num;
2690 tok_str_add2(tok_str, TOK_CINT, &cval);
2691 } else if (tok == TOK___FILE__) {
2692 cstrval = file->filename;
2693 goto add_cstr;
2694 tok_str_add2(tok_str, TOK_STR, &cval);
2695 } else if (tok == TOK___DATE__) {
2696 cstrval = "Jan 1 2002";
2697 goto add_cstr;
2698 } else if (tok == TOK___TIME__) {
2699 cstrval = "00:00:00";
2700 add_cstr:
2701 cstr_new(&cstr);
2702 cstr_cat(&cstr, cstrval);
2703 cstr_ccat(&cstr, '\0');
2704 cval.cstr = &cstr;
2705 tok_str_add2(tok_str, TOK_STR, &cval);
2706 cstr_free(&cstr);
2707 } else {
2708 mstr = (int *)s->c;
2709 mstr_allocated = 0;
2710 if (s->t == MACRO_FUNC) {
2711 /* NOTE: we do not use next_nomacro to avoid eating the
2712 next token. XXX: find better solution */
2713 if (macro_ptr) {
2714 t = *macro_ptr;
2715 } else {
2716 while (is_space(ch) || ch == '\n')
2717 cinp();
2718 t = ch;
2720 if (t != '(') /* no macro subst */
2721 goto no_subst;
2723 /* argument macro */
2724 next_nomacro();
2725 next_nomacro();
2726 args = NULL;
2727 sa = s->next;
2728 /* NOTE: empty args are allowed, except if no args */
2729 for(;;) {
2730 /* handle '()' case */
2731 if (!args && tok == ')')
2732 break;
2733 if (!sa)
2734 error("macro '%s' used with too many args",
2735 get_tok_str(s->v, 0));
2736 tok_str_new(&str);
2737 parlevel = 0;
2738 /* NOTE: non zero sa->t indicates VA_ARGS */
2739 while ((parlevel > 0 ||
2740 (tok != ')' &&
2741 (tok != ',' || sa->t))) &&
2742 tok != -1) {
2743 if (tok == '(')
2744 parlevel++;
2745 else if (tok == ')')
2746 parlevel--;
2747 tok_str_add2(&str, tok, &tokc);
2748 next_nomacro();
2750 tok_str_add(&str, 0);
2751 sym_push2(&args, sa->v & ~SYM_FIELD, sa->t, (int)str.str);
2752 sa = sa->next;
2753 if (tok == ')') {
2754 /* special case for gcc var args: add an empty
2755 var arg argument if it is omitted */
2756 if (sa && sa->t && gnu_ext)
2757 continue;
2758 else
2759 break;
2761 if (tok != ',')
2762 expect(",");
2763 next_nomacro();
2765 if (sa) {
2766 error("macro '%s' used with too few args",
2767 get_tok_str(s->v, 0));
2770 /* now subst each arg */
2771 mstr = macro_arg_subst(nested_list, mstr, args);
2772 /* free memory */
2773 sa = args;
2774 while (sa) {
2775 sa1 = sa->prev;
2776 tok_str_free((int *)sa->c);
2777 tcc_free(sa);
2778 sa = sa1;
2780 mstr_allocated = 1;
2782 sym_push2(nested_list, s->v, 0, 0);
2783 macro_subst(tok_str, nested_list, mstr);
2784 /* pop nested defined symbol */
2785 sa1 = *nested_list;
2786 *nested_list = sa1->prev;
2787 tcc_free(sa1);
2788 if (mstr_allocated)
2789 tok_str_free(mstr);
2791 } else {
2792 no_subst:
2793 /* no need to add if reading input stream */
2794 if (!macro_str)
2795 return;
2796 tok_str_add2(tok_str, tok, &tokc);
2798 /* only replace one macro while parsing input stream */
2799 if (!macro_str)
2800 return;
2802 macro_ptr = saved_macro_ptr;
2803 if (macro_str1)
2804 tok_str_free(macro_str1);
2807 /* return next token with macro substitution */
2808 void next(void)
2810 Sym *nested_list;
2811 TokenString str;
2813 /* special 'ungettok' case for label parsing */
2814 if (tok1) {
2815 tok = tok1;
2816 tokc = tok1c;
2817 tok1 = 0;
2818 } else {
2819 redo:
2820 if (!macro_ptr) {
2821 /* if not reading from macro substituted string, then try
2822 to substitute */
2823 /* XXX: optimize non macro case */
2824 tok_str_new(&str);
2825 nested_list = NULL;
2826 macro_subst(&str, &nested_list, NULL);
2827 if (str.str) {
2828 tok_str_add(&str, 0);
2829 macro_ptr = str.str;
2830 macro_ptr_allocated = str.str;
2831 goto redo;
2833 if (tok == 0)
2834 goto redo;
2835 } else {
2836 next_nomacro();
2837 if (tok == 0) {
2838 /* end of macro string: free it */
2839 tok_str_free(macro_ptr_allocated);
2840 macro_ptr = NULL;
2841 goto redo;
2845 #if defined(DEBUG)
2846 printf("token = %s\n", get_tok_str(tok, &tokc));
2847 #endif
2850 void swap(int *p, int *q)
2852 int t;
2853 t = *p;
2854 *p = *q;
2855 *q = t;
2858 void vsetc(int t, int r, CValue *vc)
2860 if (vtop >= vstack + VSTACK_SIZE)
2861 error("memory full");
2862 /* cannot let cpu flags if other instruction are generated */
2863 /* XXX: VT_JMP test too ? */
2864 if ((vtop->r & VT_VALMASK) == VT_CMP)
2865 gv(RC_INT);
2866 vtop++;
2867 vtop->t = t;
2868 vtop->r = r;
2869 vtop->r2 = VT_CONST;
2870 vtop->c = *vc;
2873 /* push integer constant */
2874 void vpushi(int v)
2876 CValue cval;
2877 cval.i = v;
2878 vsetc(VT_INT, VT_CONST, &cval);
2881 /* Return a static symbol pointing to a section */
2882 static Sym *get_sym_ref(int t, Section *sec,
2883 unsigned long offset, unsigned long size)
2885 int v;
2886 Sym *sym;
2888 v = anon_sym++;
2889 sym = sym_push1(&global_stack, v, t | VT_STATIC, 0);
2890 sym->r = VT_CONST | VT_SYM;
2891 put_extern_sym(sym, sec, offset, size);
2892 return sym;
2895 /* push a reference to a section offset by adding a dummy symbol */
2896 static void vpush_ref(int t, Section *sec, unsigned long offset, unsigned long size)
2898 CValue cval;
2900 cval.ul = 0;
2901 vsetc(t, VT_CONST | VT_SYM, &cval);
2902 vtop->sym = get_sym_ref(t, sec, offset, size);
2905 /* define a new external reference to a symbol 'v' of type 'u' */
2906 static Sym *external_global_sym(int v, int u, int r)
2908 Sym *s;
2910 s = sym_find(v);
2911 if (!s) {
2912 /* push forward reference */
2913 s = sym_push1(&global_stack,
2914 v, u | VT_EXTERN, 0);
2915 s->r = r | VT_CONST | VT_SYM;
2917 return s;
2920 /* define a new external reference to a symbol 'v' of type 'u' */
2921 static Sym *external_sym(int v, int u, int r)
2923 Sym *s;
2925 s = sym_find(v);
2926 if (!s) {
2927 /* push forward reference */
2928 s = sym_push(v, u | VT_EXTERN, r | VT_CONST | VT_SYM, 0);
2930 return s;
2933 /* push a reference to global symbol v */
2934 static void vpush_global_sym(int t, int v)
2936 Sym *sym;
2937 CValue cval;
2939 sym = external_global_sym(v, t, 0);
2940 cval.ul = 0;
2941 vsetc(t, VT_CONST | VT_SYM, &cval);
2942 vtop->sym = sym;
2945 void vset(int t, int r, int v)
2947 CValue cval;
2949 cval.i = v;
2950 vsetc(t, r, &cval);
2953 void vswap(void)
2955 SValue tmp;
2957 tmp = vtop[0];
2958 vtop[0] = vtop[-1];
2959 vtop[-1] = tmp;
2962 void vpushv(SValue *v)
2964 if (vtop >= vstack + VSTACK_SIZE)
2965 error("memory full");
2966 vtop++;
2967 *vtop = *v;
2970 void vdup(void)
2972 vpushv(vtop);
2975 /* save r to the memory stack, and mark it as being free */
2976 void save_reg(int r)
2978 int l, saved, t, size, align;
2979 SValue *p, sv;
2981 /* modify all stack values */
2982 saved = 0;
2983 l = 0;
2984 for(p=vstack;p<=vtop;p++) {
2985 if ((p->r & VT_VALMASK) == r ||
2986 (p->r2 & VT_VALMASK) == r) {
2987 /* must save value on stack if not already done */
2988 if (!saved) {
2989 /* store register in the stack */
2990 t = p->t;
2991 if ((p->r & VT_LVAL) ||
2992 (!is_float(t) && (t & VT_BTYPE) != VT_LLONG))
2993 t = VT_INT;
2994 size = type_size(t, &align);
2995 loc = (loc - size) & -align;
2996 sv.t = t;
2997 sv.r = VT_LOCAL | VT_LVAL;
2998 sv.c.ul = loc;
2999 store(r, &sv);
3000 #ifdef TCC_TARGET_I386
3001 /* x86 specific: need to pop fp register ST0 if saved */
3002 if (r == REG_ST0) {
3003 o(0xd9dd); /* fstp %st(1) */
3005 #endif
3006 /* special long long case */
3007 if ((t & VT_BTYPE) == VT_LLONG) {
3008 sv.c.ul += 4;
3009 store(p->r2, &sv);
3011 l = loc;
3012 saved = 1;
3014 /* mark that stack entry as being saved on the stack */
3015 if (p->r & VT_LVAL) {
3016 /* also suppress the bounded flag because the
3017 relocation address of the function was stored in
3018 p->c.ul */
3019 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
3020 } else {
3021 p->r = lvalue_type(p->t) | VT_LOCAL;
3023 p->r2 = VT_CONST;
3024 p->c.ul = l;
3029 /* find a free register of class 'rc'. If none, save one register */
3030 int get_reg(int rc)
3032 int r;
3033 SValue *p;
3035 /* find a free register */
3036 for(r=0;r<NB_REGS;r++) {
3037 if (reg_classes[r] & rc) {
3038 for(p=vstack;p<=vtop;p++) {
3039 if ((p->r & VT_VALMASK) == r ||
3040 (p->r2 & VT_VALMASK) == r)
3041 goto notfound;
3043 return r;
3045 notfound: ;
3048 /* no register left : free the first one on the stack (VERY
3049 IMPORTANT to start from the bottom to ensure that we don't
3050 spill registers used in gen_opi()) */
3051 for(p=vstack;p<=vtop;p++) {
3052 r = p->r & VT_VALMASK;
3053 if (r < VT_CONST && (reg_classes[r] & rc)) {
3054 save_reg(r);
3055 break;
3058 return r;
3061 /* save registers up to (vtop - n) stack entry */
3062 void save_regs(int n)
3064 int r;
3065 SValue *p, *p1;
3066 p1 = vtop - n;
3067 for(p = vstack;p <= p1; p++) {
3068 r = p->r & VT_VALMASK;
3069 if (r < VT_CONST) {
3070 save_reg(r);
3075 /* move register 's' to 'r', and flush previous value of r to memory
3076 if needed */
3077 void move_reg(int r, int s)
3079 SValue sv;
3081 if (r != s) {
3082 save_reg(r);
3083 sv.t = VT_INT;
3084 sv.r = s;
3085 sv.c.ul = 0;
3086 load(r, &sv);
3090 /* get address of vtop (vtop MUST BE an lvalue) */
3091 void gaddrof(void)
3093 vtop->r &= ~VT_LVAL;
3094 /* tricky: if saved lvalue, then we can go back to lvalue */
3095 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
3096 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
3099 #ifdef CONFIG_TCC_BCHECK
3100 /* generate lvalue bound code */
3101 void gbound(void)
3103 int lval_type, t1;
3105 vtop->r &= ~VT_MUSTBOUND;
3106 /* if lvalue, then use checking code before dereferencing */
3107 if (vtop->r & VT_LVAL) {
3108 /* if not VT_BOUNDED value, then make one */
3109 if (!(vtop->r & VT_BOUNDED)) {
3110 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
3111 /* must save type because we must set it to int to get pointer */
3112 t1 = vtop->t;
3113 vtop->t = VT_INT;
3114 gaddrof();
3115 vpushi(0);
3116 gen_bounded_ptr_add();
3117 vtop->r |= lval_type;
3118 vtop->t = t1;
3120 /* then check for dereferencing */
3121 gen_bounded_ptr_deref();
3124 #endif
3126 /* store vtop a register belonging to class 'rc'. lvalues are
3127 converted to values. Cannot be used if cannot be converted to
3128 register value (such as structures). */
3129 int gv(int rc)
3131 int r, r2, rc2, bit_pos, bit_size, size, align, i;
3132 unsigned long long ll;
3134 /* NOTE: get_reg can modify vstack[] */
3135 if (vtop->t & VT_BITFIELD) {
3136 bit_pos = (vtop->t >> VT_STRUCT_SHIFT) & 0x3f;
3137 bit_size = (vtop->t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
3138 /* remove bit field info to avoid loops */
3139 vtop->t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
3140 /* generate shifts */
3141 vpushi(32 - (bit_pos + bit_size));
3142 gen_op(TOK_SHL);
3143 vpushi(32 - bit_size);
3144 /* NOTE: transformed to SHR if unsigned */
3145 gen_op(TOK_SAR);
3146 r = gv(rc);
3147 } else {
3148 if (is_float(vtop->t) &&
3149 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3150 Sym *sym;
3151 int *ptr;
3152 unsigned long offset;
3154 /* XXX: unify with initializers handling ? */
3155 /* CPUs usually cannot use float constants, so we store them
3156 generically in data segment */
3157 size = type_size(vtop->t, &align);
3158 offset = (data_section->data_offset + align - 1) & -align;
3159 data_section->data_offset = offset;
3160 /* XXX: not portable yet */
3161 ptr = section_ptr_add(data_section, size);
3162 size = size >> 2;
3163 for(i=0;i<size;i++)
3164 ptr[i] = vtop->c.tab[i];
3165 sym = get_sym_ref(vtop->t, data_section, offset, size << 2);
3166 vtop->r |= VT_LVAL | VT_SYM;
3167 vtop->sym = sym;
3168 vtop->c.ul = 0;
3170 #ifdef CONFIG_TCC_BCHECK
3171 if (vtop->r & VT_MUSTBOUND)
3172 gbound();
3173 #endif
3175 r = vtop->r & VT_VALMASK;
3176 /* need to reload if:
3177 - constant
3178 - lvalue (need to dereference pointer)
3179 - already a register, but not in the right class */
3180 if (r >= VT_CONST ||
3181 (vtop->r & VT_LVAL) ||
3182 !(reg_classes[r] & rc) ||
3183 ((vtop->t & VT_BTYPE) == VT_LLONG &&
3184 !(reg_classes[vtop->r2] & rc))) {
3185 r = get_reg(rc);
3186 if ((vtop->t & VT_BTYPE) == VT_LLONG) {
3187 /* two register type load : expand to two words
3188 temporarily */
3189 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3190 /* load constant */
3191 ll = vtop->c.ull;
3192 vtop->c.ui = ll; /* first word */
3193 load(r, vtop);
3194 vtop->r = r; /* save register value */
3195 vpushi(ll >> 32); /* second word */
3196 } else if (r >= VT_CONST ||
3197 (vtop->r & VT_LVAL)) {
3198 /* load from memory */
3199 load(r, vtop);
3200 vdup();
3201 vtop[-1].r = r; /* save register value */
3202 /* increment pointer to get second word */
3203 vtop->t = VT_INT;
3204 gaddrof();
3205 vpushi(4);
3206 gen_op('+');
3207 vtop->r |= VT_LVAL;
3208 } else {
3209 /* move registers */
3210 load(r, vtop);
3211 vdup();
3212 vtop[-1].r = r; /* save register value */
3213 vtop->r = vtop[-1].r2;
3215 /* allocate second register */
3216 rc2 = RC_INT;
3217 if (rc == RC_IRET)
3218 rc2 = RC_LRET;
3219 r2 = get_reg(rc2);
3220 load(r2, vtop);
3221 vpop();
3222 /* write second register */
3223 vtop->r2 = r2;
3224 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->t)) {
3225 int t1, t;
3226 /* lvalue of scalar type : need to use lvalue type
3227 because of possible cast */
3228 t = vtop->t;
3229 t1 = t;
3230 /* compute memory access type */
3231 if (vtop->r & VT_LVAL_BYTE)
3232 t = VT_BYTE;
3233 else if (vtop->r & VT_LVAL_SHORT)
3234 t = VT_SHORT;
3235 if (vtop->r & VT_LVAL_UNSIGNED)
3236 t |= VT_UNSIGNED;
3237 vtop->t = t;
3238 load(r, vtop);
3239 /* restore wanted type */
3240 vtop->t = t1;
3241 } else {
3242 /* one register type load */
3243 load(r, vtop);
3246 vtop->r = r;
3248 return r;
3251 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3252 void gv2(int rc1, int rc2)
3254 /* generate more generic register first */
3255 if (rc1 <= rc2) {
3256 vswap();
3257 gv(rc1);
3258 vswap();
3259 gv(rc2);
3260 /* test if reload is needed for first register */
3261 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
3262 vswap();
3263 gv(rc1);
3264 vswap();
3266 } else {
3267 gv(rc2);
3268 vswap();
3269 gv(rc1);
3270 vswap();
3271 /* test if reload is needed for first register */
3272 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
3273 gv(rc2);
3278 /* expand long long on stack in two int registers */
3279 void lexpand(void)
3281 int u;
3283 u = vtop->t & VT_UNSIGNED;
3284 gv(RC_INT);
3285 vdup();
3286 vtop[0].r = vtop[-1].r2;
3287 vtop[0].r2 = VT_CONST;
3288 vtop[-1].r2 = VT_CONST;
3289 vtop[0].t = VT_INT | u;
3290 vtop[-1].t = VT_INT | u;
3293 /* build a long long from two ints */
3294 void lbuild(int t)
3296 gv2(RC_INT, RC_INT);
3297 vtop[-1].r2 = vtop[0].r;
3298 vtop[-1].t = t;
3299 vpop();
3302 /* rotate n first stack elements to the bottom */
3303 void vrotb(int n)
3305 int i;
3306 SValue tmp;
3308 tmp = vtop[-n + 1];
3309 for(i=-n+1;i!=0;i++)
3310 vtop[i] = vtop[i+1];
3311 vtop[0] = tmp;
3314 /* pop stack value */
3315 void vpop(void)
3317 int v;
3318 v = vtop->r & VT_VALMASK;
3319 #ifdef TCC_TARGET_I386
3320 /* for x86, we need to pop the FP stack */
3321 if (v == REG_ST0) {
3322 o(0xd9dd); /* fstp %st(1) */
3323 } else
3324 #endif
3325 if (v == VT_JMP || v == VT_JMPI) {
3326 /* need to put correct jump if && or || without test */
3327 gsym(vtop->c.ul);
3329 vtop--;
3332 /* convert stack entry to register and duplicate its value in another
3333 register */
3334 void gv_dup(void)
3336 int rc, t, r, r1;
3337 SValue sv;
3339 t = vtop->t;
3340 if ((t & VT_BTYPE) == VT_LLONG) {
3341 lexpand();
3342 gv_dup();
3343 vswap();
3344 vrotb(3);
3345 gv_dup();
3346 vrotb(4);
3347 /* stack: H L L1 H1 */
3348 lbuild(t);
3349 vrotb(3);
3350 vrotb(3);
3351 vswap();
3352 lbuild(t);
3353 vswap();
3354 } else {
3355 /* duplicate value */
3356 rc = RC_INT;
3357 sv.t = VT_INT;
3358 if (is_float(t)) {
3359 rc = RC_FLOAT;
3360 sv.t = t;
3362 r = gv(rc);
3363 r1 = get_reg(rc);
3364 sv.r = r;
3365 sv.c.ul = 0;
3366 load(r1, &sv); /* move r to r1 */
3367 vdup();
3368 /* duplicates value */
3369 vtop->r = r1;
3373 /* generate CPU independent (unsigned) long long operations */
3374 void gen_opl(int op)
3376 int t, a, b, op1, c, i;
3377 int func;
3378 GFuncContext gf;
3379 SValue tmp;
3381 switch(op) {
3382 case '/':
3383 case TOK_PDIV:
3384 func = TOK___divdi3;
3385 goto gen_func;
3386 case TOK_UDIV:
3387 func = TOK___udivdi3;
3388 goto gen_func;
3389 case '%':
3390 func = TOK___moddi3;
3391 goto gen_func;
3392 case TOK_UMOD:
3393 func = TOK___umoddi3;
3394 gen_func:
3395 /* call generic long long function */
3396 gfunc_start(&gf, FUNC_CDECL);
3397 gfunc_param(&gf);
3398 gfunc_param(&gf);
3399 vpush_global_sym(func_old_type, func);
3400 gfunc_call(&gf);
3401 vpushi(0);
3402 vtop->r = REG_IRET;
3403 vtop->r2 = REG_LRET;
3404 break;
3405 case '^':
3406 case '&':
3407 case '|':
3408 case '*':
3409 case '+':
3410 case '-':
3411 t = vtop->t;
3412 vswap();
3413 lexpand();
3414 vrotb(3);
3415 lexpand();
3416 /* stack: L1 H1 L2 H2 */
3417 tmp = vtop[0];
3418 vtop[0] = vtop[-3];
3419 vtop[-3] = tmp;
3420 tmp = vtop[-2];
3421 vtop[-2] = vtop[-3];
3422 vtop[-3] = tmp;
3423 vswap();
3424 /* stack: H1 H2 L1 L2 */
3425 if (op == '*') {
3426 vpushv(vtop - 1);
3427 vpushv(vtop - 1);
3428 gen_op(TOK_UMULL);
3429 lexpand();
3430 /* stack: H1 H2 L1 L2 ML MH */
3431 for(i=0;i<4;i++)
3432 vrotb(6);
3433 /* stack: ML MH H1 H2 L1 L2 */
3434 tmp = vtop[0];
3435 vtop[0] = vtop[-2];
3436 vtop[-2] = tmp;
3437 /* stack: ML MH H1 L2 H2 L1 */
3438 gen_op('*');
3439 vrotb(3);
3440 vrotb(3);
3441 gen_op('*');
3442 /* stack: ML MH M1 M2 */
3443 gen_op('+');
3444 gen_op('+');
3445 } else if (op == '+' || op == '-') {
3446 /* XXX: add non carry method too (for MIPS or alpha) */
3447 if (op == '+')
3448 op1 = TOK_ADDC1;
3449 else
3450 op1 = TOK_SUBC1;
3451 gen_op(op1);
3452 /* stack: H1 H2 (L1 op L2) */
3453 vrotb(3);
3454 vrotb(3);
3455 gen_op(op1 + 1); /* TOK_xxxC2 */
3456 } else {
3457 gen_op(op);
3458 /* stack: H1 H2 (L1 op L2) */
3459 vrotb(3);
3460 vrotb(3);
3461 /* stack: (L1 op L2) H1 H2 */
3462 gen_op(op);
3463 /* stack: (L1 op L2) (H1 op H2) */
3465 /* stack: L H */
3466 lbuild(t);
3467 break;
3468 case TOK_SAR:
3469 case TOK_SHR:
3470 case TOK_SHL:
3471 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3472 t = vtop[-1].t;
3473 vswap();
3474 lexpand();
3475 vrotb(3);
3476 /* stack: L H shift */
3477 c = (int)vtop->c.i;
3478 /* constant: simpler */
3479 /* NOTE: all comments are for SHL. the other cases are
3480 done by swaping words */
3481 vpop();
3482 if (op != TOK_SHL)
3483 vswap();
3484 if (c >= 32) {
3485 /* stack: L H */
3486 vpop();
3487 if (c > 32) {
3488 vpushi(c - 32);
3489 gen_op(op);
3491 if (op != TOK_SAR) {
3492 vpushi(0);
3493 } else {
3494 gv_dup();
3495 vpushi(31);
3496 gen_op(TOK_SAR);
3498 vswap();
3499 } else {
3500 vswap();
3501 gv_dup();
3502 /* stack: H L L */
3503 vpushi(c);
3504 gen_op(op);
3505 vswap();
3506 vpushi(32 - c);
3507 if (op == TOK_SHL)
3508 gen_op(TOK_SHR);
3509 else
3510 gen_op(TOK_SHL);
3511 vrotb(3);
3512 /* stack: L L H */
3513 vpushi(c);
3514 gen_op(op);
3515 gen_op('|');
3517 if (op != TOK_SHL)
3518 vswap();
3519 lbuild(t);
3520 } else {
3521 /* XXX: should provide a faster fallback on x86 ? */
3522 switch(op) {
3523 case TOK_SAR:
3524 func = TOK___sardi3;
3525 goto gen_func;
3526 case TOK_SHR:
3527 func = TOK___shrdi3;
3528 goto gen_func;
3529 case TOK_SHL:
3530 func = TOK___shldi3;
3531 goto gen_func;
3534 break;
3535 default:
3536 /* compare operations */
3537 t = vtop->t;
3538 vswap();
3539 lexpand();
3540 vrotb(3);
3541 lexpand();
3542 /* stack: L1 H1 L2 H2 */
3543 tmp = vtop[-1];
3544 vtop[-1] = vtop[-2];
3545 vtop[-2] = tmp;
3546 /* stack: L1 L2 H1 H2 */
3547 /* compare high */
3548 op1 = op;
3549 /* when values are equal, we need to compare low words. since
3550 the jump is inverted, we invert the test too. */
3551 if (op1 == TOK_LT)
3552 op1 = TOK_LE;
3553 else if (op1 == TOK_GT)
3554 op1 = TOK_GE;
3555 else if (op1 == TOK_ULT)
3556 op1 = TOK_ULE;
3557 else if (op1 == TOK_UGT)
3558 op1 = TOK_UGE;
3559 a = 0;
3560 b = 0;
3561 gen_op(op1);
3562 if (op1 != TOK_NE) {
3563 a = gtst(1, 0);
3565 if (op != TOK_EQ) {
3566 /* generate non equal test */
3567 /* XXX: NOT PORTABLE yet */
3568 if (a == 0) {
3569 b = gtst(0, 0);
3570 } else {
3571 #ifdef TCC_TARGET_I386
3572 b = psym(0x850f, 0);
3573 #else
3574 error("not implemented");
3575 #endif
3578 /* compare low */
3579 gen_op(op);
3580 a = gtst(1, a);
3581 gsym(b);
3582 vset(VT_INT, VT_JMPI, a);
3583 break;
3587 /* handle integer constant optimizations and various machine
3588 independant opt */
3589 void gen_opic(int op)
3591 int fc, c1, c2, n;
3592 SValue *v1, *v2;
3594 v1 = vtop - 1;
3595 v2 = vtop;
3596 /* currently, we cannot do computations with forward symbols */
3597 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3598 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3599 if (c1 && c2) {
3600 fc = v2->c.i;
3601 switch(op) {
3602 case '+': v1->c.i += fc; break;
3603 case '-': v1->c.i -= fc; break;
3604 case '&': v1->c.i &= fc; break;
3605 case '^': v1->c.i ^= fc; break;
3606 case '|': v1->c.i |= fc; break;
3607 case '*': v1->c.i *= fc; break;
3609 case TOK_PDIV:
3610 case '/':
3611 case '%':
3612 case TOK_UDIV:
3613 case TOK_UMOD:
3614 /* if division by zero, generate explicit division */
3615 if (fc == 0) {
3616 if (const_wanted)
3617 error("division by zero in constant");
3618 goto general_case;
3620 switch(op) {
3621 default: v1->c.i /= fc; break;
3622 case '%': v1->c.i %= fc; break;
3623 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
3624 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
3626 break;
3627 case TOK_SHL: v1->c.i <<= fc; break;
3628 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
3629 case TOK_SAR: v1->c.i >>= fc; break;
3630 /* tests */
3631 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
3632 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
3633 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
3634 case TOK_NE: v1->c.i = v1->c.i != fc; break;
3635 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
3636 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
3637 case TOK_LT: v1->c.i = v1->c.i < fc; break;
3638 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
3639 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
3640 case TOK_GT: v1->c.i = v1->c.i > fc; break;
3641 /* logical */
3642 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
3643 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
3644 default:
3645 goto general_case;
3647 vtop--;
3648 } else {
3649 /* if commutative ops, put c2 as constant */
3650 if (c1 && (op == '+' || op == '&' || op == '^' ||
3651 op == '|' || op == '*')) {
3652 vswap();
3653 swap(&c1, &c2);
3655 fc = vtop->c.i;
3656 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
3657 op == TOK_PDIV) &&
3658 fc == 1) ||
3659 ((op == '+' || op == '-' || op == '|' || op == '^' ||
3660 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
3661 fc == 0) ||
3662 (op == '&' &&
3663 fc == -1))) {
3664 /* nothing to do */
3665 vtop--;
3666 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
3667 /* try to use shifts instead of muls or divs */
3668 if (fc > 0 && (fc & (fc - 1)) == 0) {
3669 n = -1;
3670 while (fc) {
3671 fc >>= 1;
3672 n++;
3674 vtop->c.i = n;
3675 if (op == '*')
3676 op = TOK_SHL;
3677 else if (op == TOK_PDIV)
3678 op = TOK_SAR;
3679 else
3680 op = TOK_SHR;
3682 goto general_case;
3683 } else if (c2 && (op == '+' || op == '-') &&
3684 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
3685 (VT_CONST | VT_SYM)) {
3686 /* symbol + constant case */
3687 if (op == '-')
3688 fc = -fc;
3689 vtop--;
3690 vtop->c.i += fc;
3691 } else {
3692 general_case:
3693 /* call low level op generator */
3694 gen_opi(op);
3699 /* generate a floating point operation with constant propagation */
3700 void gen_opif(int op)
3702 int c1, c2;
3703 SValue *v1, *v2;
3704 long double f1, f2;
3706 v1 = vtop - 1;
3707 v2 = vtop;
3708 /* currently, we cannot do computations with forward symbols */
3709 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3710 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3711 if (c1 && c2) {
3712 if (v1->t == VT_FLOAT) {
3713 f1 = v1->c.f;
3714 f2 = v2->c.f;
3715 } else if (v1->t == VT_DOUBLE) {
3716 f1 = v1->c.d;
3717 f2 = v2->c.d;
3718 } else {
3719 f1 = v1->c.ld;
3720 f2 = v2->c.ld;
3723 /* NOTE: we only do constant propagation if finite number (not
3724 NaN or infinity) (ANSI spec) */
3725 if (!ieee_finite(f1) || !ieee_finite(f2))
3726 goto general_case;
3728 switch(op) {
3729 case '+': f1 += f2; break;
3730 case '-': f1 -= f2; break;
3731 case '*': f1 *= f2; break;
3732 case '/':
3733 if (f2 == 0.0) {
3734 if (const_wanted)
3735 error("division by zero in constant");
3736 goto general_case;
3738 f1 /= f2;
3739 break;
3740 /* XXX: also handles tests ? */
3741 default:
3742 goto general_case;
3744 /* XXX: overflow test ? */
3745 if (v1->t == VT_FLOAT) {
3746 v1->c.f = f1;
3747 } else if (v1->t == VT_DOUBLE) {
3748 v1->c.d = f1;
3749 } else {
3750 v1->c.ld = f1;
3752 vtop--;
3753 } else {
3754 general_case:
3755 gen_opf(op);
3759 int pointed_size(int t)
3761 return type_size(pointed_type(t), &t);
3764 #if 0
3765 void check_pointer_types(SValue *p1, SValue *p2)
3767 char buf1[256], buf2[256];
3768 int t1, t2;
3769 t1 = p1->t;
3770 t2 = p2->t;
3771 if (!is_compatible_types(t1, t2)) {
3772 type_to_str(buf1, sizeof(buf1), t1, NULL);
3773 type_to_str(buf2, sizeof(buf2), t2, NULL);
3774 error("incompatible pointers '%s' and '%s'", buf1, buf2);
3777 #endif
3779 /* generic gen_op: handles types problems */
3780 void gen_op(int op)
3782 int u, t1, t2, bt1, bt2, t;
3784 t1 = vtop[-1].t;
3785 t2 = vtop[0].t;
3786 bt1 = t1 & VT_BTYPE;
3787 bt2 = t2 & VT_BTYPE;
3789 if (bt1 == VT_PTR || bt2 == VT_PTR) {
3790 /* at least one operand is a pointer */
3791 /* relationnal op: must be both pointers */
3792 if (op >= TOK_ULT && op <= TOK_GT) {
3793 // check_pointer_types(vtop, vtop - 1);
3794 /* pointers are handled are unsigned */
3795 t = VT_INT | VT_UNSIGNED;
3796 goto std_op;
3798 /* if both pointers, then it must be the '-' op */
3799 if ((t1 & VT_BTYPE) == VT_PTR &&
3800 (t2 & VT_BTYPE) == VT_PTR) {
3801 if (op != '-')
3802 error("cannot use pointers here");
3803 // check_pointer_types(vtop - 1, vtop);
3804 /* XXX: check that types are compatible */
3805 u = pointed_size(t1);
3806 gen_opic(op);
3807 /* set to integer type */
3808 vtop->t = VT_INT;
3809 vpushi(u);
3810 gen_op(TOK_PDIV);
3811 } else {
3812 /* exactly one pointer : must be '+' or '-'. */
3813 if (op != '-' && op != '+')
3814 error("cannot use pointers here");
3815 /* Put pointer as first operand */
3816 if ((t2 & VT_BTYPE) == VT_PTR) {
3817 vswap();
3818 swap(&t1, &t2);
3820 /* XXX: cast to int ? (long long case) */
3821 vpushi(pointed_size(vtop[-1].t));
3822 gen_op('*');
3823 #ifdef CONFIG_TCC_BCHECK
3824 /* if evaluating constant expression, no code should be
3825 generated, so no bound check */
3826 if (do_bounds_check && !const_wanted) {
3827 /* if bounded pointers, we generate a special code to
3828 test bounds */
3829 if (op == '-') {
3830 vpushi(0);
3831 vswap();
3832 gen_op('-');
3834 gen_bounded_ptr_add();
3835 } else
3836 #endif
3838 gen_opic(op);
3840 /* put again type if gen_opic() swaped operands */
3841 vtop->t = t1;
3843 } else if (is_float(bt1) || is_float(bt2)) {
3844 /* compute bigger type and do implicit casts */
3845 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3846 t = VT_LDOUBLE;
3847 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3848 t = VT_DOUBLE;
3849 } else {
3850 t = VT_FLOAT;
3852 /* floats can only be used for a few operations */
3853 if (op != '+' && op != '-' && op != '*' && op != '/' &&
3854 (op < TOK_ULT || op > TOK_GT))
3855 error("invalid operands for binary operation");
3856 goto std_op;
3857 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3858 /* cast to biggest op */
3859 t = VT_LLONG;
3860 /* convert to unsigned if it does not fit in a long long */
3861 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
3862 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
3863 t |= VT_UNSIGNED;
3864 goto std_op;
3865 } else {
3866 /* integer operations */
3867 t = VT_INT;
3868 /* convert to unsigned if it does not fit in an integer */
3869 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
3870 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
3871 t |= VT_UNSIGNED;
3872 std_op:
3873 /* XXX: currently, some unsigned operations are explicit, so
3874 we modify them here */
3875 if (t & VT_UNSIGNED) {
3876 if (op == TOK_SAR)
3877 op = TOK_SHR;
3878 else if (op == '/')
3879 op = TOK_UDIV;
3880 else if (op == '%')
3881 op = TOK_UMOD;
3882 else if (op == TOK_LT)
3883 op = TOK_ULT;
3884 else if (op == TOK_GT)
3885 op = TOK_UGT;
3886 else if (op == TOK_LE)
3887 op = TOK_ULE;
3888 else if (op == TOK_GE)
3889 op = TOK_UGE;
3891 vswap();
3892 gen_cast(t);
3893 vswap();
3894 /* special case for shifts and long long: we keep the shift as
3895 an integer */
3896 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
3897 gen_cast(VT_INT);
3898 else
3899 gen_cast(t);
3900 if (is_float(t))
3901 gen_opif(op);
3902 else if ((t & VT_BTYPE) == VT_LLONG)
3903 gen_opl(op);
3904 else
3905 gen_opic(op);
3906 if (op >= TOK_ULT && op <= TOK_GT) {
3907 /* relationnal op: the result is an int */
3908 vtop->t = VT_INT;
3909 } else {
3910 vtop->t = t;
3915 /* generic itof for unsigned long long case */
3916 void gen_cvt_itof1(int t)
3918 GFuncContext gf;
3920 if ((vtop->t & (VT_BTYPE | VT_UNSIGNED)) ==
3921 (VT_LLONG | VT_UNSIGNED)) {
3923 gfunc_start(&gf, FUNC_CDECL);
3924 gfunc_param(&gf);
3925 if (t == VT_FLOAT)
3926 vpush_global_sym(func_old_type, TOK___ulltof);
3927 else if (t == VT_DOUBLE)
3928 vpush_global_sym(func_old_type, TOK___ulltod);
3929 else
3930 vpush_global_sym(func_old_type, TOK___ulltold);
3931 gfunc_call(&gf);
3932 vpushi(0);
3933 vtop->r = REG_FRET;
3934 } else {
3935 gen_cvt_itof(t);
3939 /* generic ftoi for unsigned long long case */
3940 void gen_cvt_ftoi1(int t)
3942 GFuncContext gf;
3943 int st;
3945 if (t == (VT_LLONG | VT_UNSIGNED)) {
3946 /* not handled natively */
3947 gfunc_start(&gf, FUNC_CDECL);
3948 st = vtop->t & VT_BTYPE;
3949 gfunc_param(&gf);
3950 if (st == VT_FLOAT)
3951 vpush_global_sym(func_old_type, TOK___fixunssfdi);
3952 else if (st == VT_DOUBLE)
3953 vpush_global_sym(func_old_type, TOK___fixunsdfdi);
3954 else
3955 vpush_global_sym(func_old_type, TOK___fixunsxfdi);
3956 gfunc_call(&gf);
3957 vpushi(0);
3958 vtop->r = REG_IRET;
3959 vtop->r2 = REG_LRET;
3960 } else {
3961 gen_cvt_ftoi(t);
3965 /* force char or short cast */
3966 void force_charshort_cast(int t)
3968 int bits, dbt;
3969 dbt = t & VT_BTYPE;
3970 /* XXX: add optimization if lvalue : just change type and offset */
3971 if (dbt == VT_BYTE)
3972 bits = 8;
3973 else
3974 bits = 16;
3975 if (t & VT_UNSIGNED) {
3976 vpushi((1 << bits) - 1);
3977 gen_op('&');
3978 } else {
3979 bits = 32 - bits;
3980 vpushi(bits);
3981 gen_op(TOK_SHL);
3982 vpushi(bits);
3983 gen_op(TOK_SAR);
3987 /* cast 'vtop' to 't' type */
3988 void gen_cast(int t)
3990 int sbt, dbt, sf, df, c;
3992 /* special delayed cast for char/short */
3993 /* XXX: in some cases (multiple cascaded casts), it may still
3994 be incorrect */
3995 if (vtop->r & VT_MUSTCAST) {
3996 vtop->r &= ~VT_MUSTCAST;
3997 force_charshort_cast(vtop->t);
4000 dbt = t & (VT_BTYPE | VT_UNSIGNED);
4001 sbt = vtop->t & (VT_BTYPE | VT_UNSIGNED);
4003 if (sbt != dbt) {
4004 sf = is_float(sbt);
4005 df = is_float(dbt);
4006 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4007 if (sf && df) {
4008 /* convert from fp to fp */
4009 if (c) {
4010 /* constant case: we can do it now */
4011 /* XXX: in ISOC, cannot do it if error in convert */
4012 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
4013 vtop->c.f = (float)vtop->c.d;
4014 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
4015 vtop->c.f = (float)vtop->c.ld;
4016 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
4017 vtop->c.d = (double)vtop->c.f;
4018 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
4019 vtop->c.d = (double)vtop->c.ld;
4020 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
4021 vtop->c.ld = (long double)vtop->c.f;
4022 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
4023 vtop->c.ld = (long double)vtop->c.d;
4024 } else {
4025 /* non constant case: generate code */
4026 gen_cvt_ftof(dbt);
4028 } else if (df) {
4029 /* convert int to fp */
4030 if (c) {
4031 switch(sbt) {
4032 case VT_LLONG | VT_UNSIGNED:
4033 case VT_LLONG:
4034 /* XXX: add const cases for long long */
4035 goto do_itof;
4036 case VT_INT | VT_UNSIGNED:
4037 switch(dbt) {
4038 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
4039 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
4040 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
4042 break;
4043 default:
4044 switch(dbt) {
4045 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
4046 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
4047 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
4049 break;
4051 } else {
4052 do_itof:
4053 gen_cvt_itof1(dbt);
4055 } else if (sf) {
4056 /* convert fp to int */
4057 /* we handle char/short/etc... with generic code */
4058 if (dbt != (VT_INT | VT_UNSIGNED) &&
4059 dbt != (VT_LLONG | VT_UNSIGNED) &&
4060 dbt != VT_LLONG)
4061 dbt = VT_INT;
4062 if (c) {
4063 switch(dbt) {
4064 case VT_LLONG | VT_UNSIGNED:
4065 case VT_LLONG:
4066 /* XXX: add const cases for long long */
4067 goto do_ftoi;
4068 case VT_INT | VT_UNSIGNED:
4069 switch(sbt) {
4070 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
4071 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4072 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4074 break;
4075 default:
4076 /* int case */
4077 switch(sbt) {
4078 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
4079 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
4080 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
4082 break;
4084 } else {
4085 do_ftoi:
4086 gen_cvt_ftoi1(dbt);
4088 if (dbt == VT_INT && (t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
4089 /* additionnal cast for char/short/bool... */
4090 vtop->t = dbt;
4091 gen_cast(t);
4093 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
4094 if ((sbt & VT_BTYPE) != VT_LLONG) {
4095 /* scalar to long long */
4096 if (c) {
4097 if (sbt == (VT_INT | VT_UNSIGNED))
4098 vtop->c.ll = vtop->c.ui;
4099 else
4100 vtop->c.ll = vtop->c.i;
4101 } else {
4102 /* machine independant conversion */
4103 gv(RC_INT);
4104 /* generate high word */
4105 if (sbt == (VT_INT | VT_UNSIGNED)) {
4106 vpushi(0);
4107 gv(RC_INT);
4108 } else {
4109 gv_dup();
4110 vpushi(31);
4111 gen_op(TOK_SAR);
4113 /* patch second register */
4114 vtop[-1].r2 = vtop->r;
4115 vpop();
4118 } else if (dbt == VT_BOOL) {
4119 /* scalar to bool */
4120 vpushi(0);
4121 gen_op(TOK_NE);
4122 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
4123 (dbt & VT_BTYPE) == VT_SHORT) {
4124 force_charshort_cast(t);
4125 } else if ((dbt & VT_BTYPE) == VT_INT) {
4126 /* scalar to int */
4127 if (sbt == VT_LLONG) {
4128 /* from long long: just take low order word */
4129 lexpand();
4130 vpop();
4132 /* if lvalue and single word type, nothing to do because
4133 the lvalue already contains the real type size (see
4134 VT_LVAL_xxx constants) */
4137 vtop->t = t;
4140 /* return type size. Put alignment at 'a' */
4141 int type_size(int t, int *a)
4143 Sym *s;
4144 int bt;
4146 bt = t & VT_BTYPE;
4147 if (bt == VT_STRUCT) {
4148 /* struct/union */
4149 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4150 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
4151 return s->c;
4152 } else if (bt == VT_PTR) {
4153 if (t & VT_ARRAY) {
4154 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4155 return type_size(s->t, a) * s->c;
4156 } else {
4157 *a = PTR_SIZE;
4158 return PTR_SIZE;
4160 } else if (bt == VT_LDOUBLE) {
4161 *a = LDOUBLE_ALIGN;
4162 return LDOUBLE_SIZE;
4163 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
4164 *a = 8;
4165 return 8;
4166 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
4167 *a = 4;
4168 return 4;
4169 } else if (bt == VT_SHORT) {
4170 *a = 2;
4171 return 2;
4172 } else {
4173 /* char, void, function, _Bool */
4174 *a = 1;
4175 return 1;
4179 /* return the pointed type of t */
4180 int pointed_type(int t)
4182 Sym *s;
4183 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4184 return s->t | (t & ~VT_TYPE);
4187 int mk_pointer(int t)
4189 int p;
4190 p = anon_sym++;
4191 sym_push(p, t, 0, -1);
4192 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
4195 int is_compatible_types(int t1, int t2)
4197 Sym *s1, *s2;
4198 int bt1, bt2;
4200 t1 &= VT_TYPE;
4201 t2 &= VT_TYPE;
4202 bt1 = t1 & VT_BTYPE;
4203 bt2 = t2 & VT_BTYPE;
4204 if (bt1 == VT_PTR) {
4205 t1 = pointed_type(t1);
4206 /* if function, then convert implicitely to function pointer */
4207 if (bt2 != VT_FUNC) {
4208 if (bt2 != VT_PTR)
4209 return 0;
4210 t2 = pointed_type(t2);
4212 /* void matches everything */
4213 t1 &= VT_TYPE;
4214 t2 &= VT_TYPE;
4215 if (t1 == VT_VOID || t2 == VT_VOID)
4216 return 1;
4217 return is_compatible_types(t1, t2);
4218 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4219 return (t2 == t1);
4220 } else if (bt1 == VT_FUNC) {
4221 if (bt2 != VT_FUNC)
4222 return 0;
4223 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
4224 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
4225 if (!is_compatible_types(s1->t, s2->t))
4226 return 0;
4227 /* XXX: not complete */
4228 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
4229 return 1;
4230 if (s1->c != s2->c)
4231 return 0;
4232 while (s1 != NULL) {
4233 if (s2 == NULL)
4234 return 0;
4235 if (!is_compatible_types(s1->t, s2->t))
4236 return 0;
4237 s1 = s1->next;
4238 s2 = s2->next;
4240 if (s2)
4241 return 0;
4242 return 1;
4243 } else {
4244 /* XXX: not complete */
4245 return 1;
4249 /* print a type. If 'varstr' is not NULL, then the variable is also
4250 printed in the type */
4251 /* XXX: union */
4252 /* XXX: add array and function pointers */
4253 void type_to_str(char *buf, int buf_size,
4254 int t, const char *varstr)
4256 int bt, v;
4257 Sym *s, *sa;
4258 char buf1[256];
4259 const char *tstr;
4261 t = t & VT_TYPE;
4262 bt = t & VT_BTYPE;
4263 buf[0] = '\0';
4264 if (t & VT_UNSIGNED)
4265 pstrcat(buf, buf_size, "unsigned ");
4266 switch(bt) {
4267 case VT_VOID:
4268 tstr = "void";
4269 goto add_tstr;
4270 case VT_BOOL:
4271 tstr = "_Bool";
4272 goto add_tstr;
4273 case VT_BYTE:
4274 tstr = "char";
4275 goto add_tstr;
4276 case VT_SHORT:
4277 tstr = "short";
4278 goto add_tstr;
4279 case VT_INT:
4280 tstr = "int";
4281 goto add_tstr;
4282 case VT_LONG:
4283 tstr = "long";
4284 goto add_tstr;
4285 case VT_LLONG:
4286 tstr = "long long";
4287 goto add_tstr;
4288 case VT_FLOAT:
4289 tstr = "float";
4290 goto add_tstr;
4291 case VT_DOUBLE:
4292 tstr = "double";
4293 goto add_tstr;
4294 case VT_LDOUBLE:
4295 tstr = "long double";
4296 add_tstr:
4297 pstrcat(buf, buf_size, tstr);
4298 break;
4299 case VT_ENUM:
4300 case VT_STRUCT:
4301 if (bt == VT_STRUCT)
4302 tstr = "struct ";
4303 else
4304 tstr = "enum ";
4305 pstrcat(buf, buf_size, tstr);
4306 v = (unsigned)t >> VT_STRUCT_SHIFT;
4307 if (v >= SYM_FIRST_ANOM)
4308 pstrcat(buf, buf_size, "<anonymous>");
4309 else
4310 pstrcat(buf, buf_size, get_tok_str(v, NULL));
4311 break;
4312 case VT_FUNC:
4313 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4314 type_to_str(buf, buf_size, s->t, varstr);
4315 pstrcat(buf, buf_size, "(");
4316 sa = s->next;
4317 while (sa != NULL) {
4318 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
4319 pstrcat(buf, buf_size, buf1);
4320 sa = sa->next;
4321 if (sa)
4322 pstrcat(buf, buf_size, ", ");
4324 pstrcat(buf, buf_size, ")");
4325 goto no_var;
4326 case VT_PTR:
4327 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4328 pstrcpy(buf1, sizeof(buf1), "*");
4329 if (varstr)
4330 pstrcat(buf1, sizeof(buf1), varstr);
4331 type_to_str(buf, buf_size, s->t, buf1);
4332 goto no_var;
4334 if (varstr) {
4335 pstrcat(buf, buf_size, " ");
4336 pstrcat(buf, buf_size, varstr);
4338 no_var: ;
4341 /* verify type compatibility to store vtop in 'dt' type, and generate
4342 casts if needed. */
4343 void gen_assign_cast(int dt)
4345 int st;
4346 char buf1[256], buf2[256];
4348 st = vtop->t; /* source type */
4349 if ((dt & VT_BTYPE) == VT_PTR) {
4350 /* special cases for pointers */
4351 /* a function is implicitely a function pointer */
4352 if ((st & VT_BTYPE) == VT_FUNC) {
4353 if (!is_compatible_types(pointed_type(dt), st))
4354 goto error;
4355 else
4356 goto type_ok;
4358 /* '0' can also be a pointer */
4359 if ((st & VT_BTYPE) == VT_INT &&
4360 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
4361 vtop->c.i == 0)
4362 goto type_ok;
4364 if (!is_compatible_types(dt, st)) {
4365 error:
4366 type_to_str(buf1, sizeof(buf1), st, NULL);
4367 type_to_str(buf2, sizeof(buf2), dt, NULL);
4368 error("cannot cast '%s' to '%s'", buf1, buf2);
4370 type_ok:
4371 gen_cast(dt);
4374 /* store vtop in lvalue pushed on stack */
4375 void vstore(void)
4377 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
4378 GFuncContext gf;
4380 ft = vtop[-1].t;
4381 sbt = vtop->t & VT_BTYPE;
4382 dbt = ft & VT_BTYPE;
4383 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
4384 (sbt == VT_INT && dbt == VT_SHORT)) {
4385 /* optimize char/short casts */
4386 delayed_cast = VT_MUSTCAST;
4387 vtop->t = ft & VT_TYPE;
4388 } else {
4389 delayed_cast = 0;
4390 gen_assign_cast(ft & VT_TYPE);
4393 if (sbt == VT_STRUCT) {
4394 /* if structure, only generate pointer */
4395 /* structure assignment : generate memcpy */
4396 /* XXX: optimize if small size */
4397 vdup();
4398 gfunc_start(&gf, FUNC_CDECL);
4399 /* type size */
4400 size = type_size(vtop->t, &align);
4401 vpushi(size);
4402 gfunc_param(&gf);
4403 /* source */
4404 vtop->t = VT_INT;
4405 gaddrof();
4406 gfunc_param(&gf);
4407 /* destination */
4408 vswap();
4409 vtop->t = VT_INT;
4410 gaddrof();
4411 gfunc_param(&gf);
4413 save_regs(0);
4414 vpush_global_sym(func_old_type, TOK_memcpy);
4415 gfunc_call(&gf);
4416 /* leave source on stack */
4417 } else if (ft & VT_BITFIELD) {
4418 /* bitfield store handling */
4419 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
4420 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4421 /* remove bit field info to avoid loops */
4422 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4424 /* duplicate destination */
4425 vdup();
4426 vtop[-1] = vtop[-2];
4428 /* mask and shift source */
4429 vpushi((1 << bit_size) - 1);
4430 gen_op('&');
4431 vpushi(bit_pos);
4432 gen_op(TOK_SHL);
4433 /* load destination, mask and or with source */
4434 vswap();
4435 vpushi(~(((1 << bit_size) - 1) << bit_pos));
4436 gen_op('&');
4437 gen_op('|');
4438 /* store result */
4439 vstore();
4440 } else {
4441 #ifdef CONFIG_TCC_BCHECK
4442 /* bound check case */
4443 if (vtop[-1].r & VT_MUSTBOUND) {
4444 vswap();
4445 gbound();
4446 vswap();
4448 #endif
4449 rc = RC_INT;
4450 if (is_float(ft))
4451 rc = RC_FLOAT;
4452 r = gv(rc); /* generate value */
4453 /* if lvalue was saved on stack, must read it */
4454 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
4455 SValue sv;
4456 t = get_reg(RC_INT);
4457 sv.t = VT_INT;
4458 sv.r = VT_LOCAL | VT_LVAL;
4459 sv.c.ul = vtop[-1].c.ul;
4460 load(t, &sv);
4461 vtop[-1].r = t | VT_LVAL;
4463 store(r, vtop - 1);
4464 /* two word case handling : store second register at word + 4 */
4465 if ((ft & VT_BTYPE) == VT_LLONG) {
4466 vswap();
4467 /* convert to int to increment easily */
4468 vtop->t = VT_INT;
4469 gaddrof();
4470 vpushi(4);
4471 gen_op('+');
4472 vtop->r |= VT_LVAL;
4473 vswap();
4474 /* XXX: it works because r2 is spilled last ! */
4475 store(vtop->r2, vtop - 1);
4477 vswap();
4478 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4479 vtop->r |= delayed_cast;
4483 /* post defines POST/PRE add. c is the token ++ or -- */
4484 void inc(int post, int c)
4486 test_lvalue();
4487 vdup(); /* save lvalue */
4488 if (post) {
4489 gv_dup(); /* duplicate value */
4490 vrotb(3);
4491 vrotb(3);
4493 /* add constant */
4494 vpushi(c - TOK_MID);
4495 gen_op('+');
4496 vstore(); /* store value */
4497 if (post)
4498 vpop(); /* if post op, return saved value */
4501 /* Parse GNUC __attribute__ extension. Currently, the following
4502 extensions are recognized:
4503 - aligned(n) : set data/function alignment.
4504 - section(x) : generate data/code in this section.
4505 - unused : currently ignored, but may be used someday.
4507 void parse_attribute(AttributeDef *ad)
4509 int t, n;
4511 next();
4512 skip('(');
4513 skip('(');
4514 while (tok != ')') {
4515 if (tok < TOK_IDENT)
4516 expect("attribute name");
4517 t = tok;
4518 next();
4519 switch(t) {
4520 case TOK_SECTION:
4521 case TOK___SECTION__:
4522 skip('(');
4523 if (tok != TOK_STR)
4524 expect("section name");
4525 ad->section = find_section((char *)tokc.cstr->data);
4526 next();
4527 skip(')');
4528 break;
4529 case TOK_ALIGNED:
4530 case TOK___ALIGNED__:
4531 skip('(');
4532 n = expr_const();
4533 if (n <= 0 || (n & (n - 1)) != 0)
4534 error("alignment must be a positive power of two");
4535 ad->aligned = n;
4536 skip(')');
4537 break;
4538 case TOK_UNUSED:
4539 case TOK___UNUSED__:
4540 /* currently, no need to handle it because tcc does not
4541 track unused objects */
4542 break;
4543 case TOK_NORETURN:
4544 case TOK___NORETURN__:
4545 /* currently, no need to handle it because tcc does not
4546 track unused objects */
4547 break;
4548 case TOK_CDECL:
4549 case TOK___CDECL:
4550 case TOK___CDECL__:
4551 ad->func_call = FUNC_CDECL;
4552 break;
4553 case TOK_STDCALL:
4554 case TOK___STDCALL:
4555 case TOK___STDCALL__:
4556 ad->func_call = FUNC_STDCALL;
4557 break;
4558 default:
4559 warning("'%s' attribute ignored", get_tok_str(t, NULL));
4560 /* skip parameters */
4561 /* XXX: skip parenthesis too */
4562 if (tok == '(') {
4563 next();
4564 while (tok != ')' && tok != -1)
4565 next();
4566 next();
4568 break;
4570 if (tok != ',')
4571 break;
4572 next();
4574 skip(')');
4575 skip(')');
4578 /* enum/struct/union declaration */
4579 int struct_decl(int u)
4581 int a, t, b, v, size, align, maxalign, c, offset;
4582 int bit_size, bit_pos, bsize, bt, lbit_pos;
4583 Sym *s, *ss, **ps;
4584 AttributeDef ad;
4586 a = tok; /* save decl type */
4587 next();
4588 if (tok != '{') {
4589 v = tok;
4590 next();
4591 /* struct already defined ? return it */
4592 /* XXX: check consistency */
4593 s = sym_find(v | SYM_STRUCT);
4594 if (s) {
4595 if (s->t != a)
4596 error("invalid type");
4597 goto do_decl;
4599 } else {
4600 v = anon_sym++;
4602 s = sym_push(v | SYM_STRUCT, a, 0, 0);
4603 /* put struct/union/enum name in type */
4604 do_decl:
4605 u = u | (v << VT_STRUCT_SHIFT);
4607 if (tok == '{') {
4608 next();
4609 if (s->c)
4610 error("struct/union/enum already defined");
4611 /* cannot be empty */
4612 c = 0;
4613 maxalign = 0;
4614 ps = &s->next;
4615 bit_pos = 0;
4616 offset = 0;
4617 while (1) {
4618 if (a == TOK_ENUM) {
4619 v = tok;
4620 next();
4621 if (tok == '=') {
4622 next();
4623 c = expr_const();
4625 /* enum symbols have static storage */
4626 sym_push(v, VT_STATIC | VT_INT, VT_CONST, c);
4627 if (tok == ',')
4628 next();
4629 c++;
4630 } else {
4631 parse_btype(&b, &ad);
4632 while (1) {
4633 bit_size = -1;
4634 v = 0;
4635 if (tok != ':') {
4636 t = type_decl(&ad, &v, b, TYPE_DIRECT);
4637 if ((t & VT_BTYPE) == VT_FUNC ||
4638 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
4639 error("invalid type for '%s'",
4640 get_tok_str(v, NULL));
4641 } else {
4642 t = b;
4644 if (tok == ':') {
4645 next();
4646 bit_size = expr_const();
4647 /* XXX: handle v = 0 case for messages */
4648 if (bit_size < 0)
4649 error("negative width in bit-field '%s'",
4650 get_tok_str(v, NULL));
4651 if (v && bit_size == 0)
4652 error("zero width for bit-field '%s'",
4653 get_tok_str(v, NULL));
4655 size = type_size(t, &align);
4656 lbit_pos = 0;
4657 if (bit_size >= 0) {
4658 bt = t & VT_BTYPE;
4659 if (bt != VT_INT &&
4660 bt != VT_BYTE &&
4661 bt != VT_SHORT)
4662 error("bitfields must have scalar type");
4663 bsize = size * 8;
4664 if (bit_size > bsize) {
4665 error("width of '%s' exceeds its type",
4666 get_tok_str(v, NULL));
4667 } else if (bit_size == bsize) {
4668 /* no need for bit fields */
4669 bit_pos = 0;
4670 } else if (bit_size == 0) {
4671 /* XXX: what to do if only padding in a
4672 structure ? */
4673 /* zero size: means to pad */
4674 if (bit_pos > 0)
4675 bit_pos = bsize;
4676 } else {
4677 /* we do not have enough room ? */
4678 if ((bit_pos + bit_size) > bsize)
4679 bit_pos = 0;
4680 lbit_pos = bit_pos;
4681 /* XXX: handle LSB first */
4682 t |= VT_BITFIELD |
4683 (bit_pos << VT_STRUCT_SHIFT) |
4684 (bit_size << (VT_STRUCT_SHIFT + 6));
4685 bit_pos += bit_size;
4687 } else {
4688 bit_pos = 0;
4690 if (v) {
4691 /* add new memory data only if starting
4692 bit field */
4693 if (lbit_pos == 0) {
4694 if (a == TOK_STRUCT) {
4695 c = (c + align - 1) & -align;
4696 offset = c;
4697 c += size;
4698 } else {
4699 offset = 0;
4700 if (size > c)
4701 c = size;
4703 if (align > maxalign)
4704 maxalign = align;
4706 #if 0
4707 printf("add field %s offset=%d",
4708 get_tok_str(v, NULL), offset);
4709 if (t & VT_BITFIELD) {
4710 printf(" pos=%d size=%d",
4711 (t >> VT_STRUCT_SHIFT) & 0x3f,
4712 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
4714 printf("\n");
4715 #endif
4716 ss = sym_push(v | SYM_FIELD, t, 0, offset);
4717 *ps = ss;
4718 ps = &ss->next;
4720 if (tok == ';' || tok == -1)
4721 break;
4722 skip(',');
4724 skip(';');
4726 if (tok == '}')
4727 break;
4729 skip('}');
4730 /* size for struct/union, dummy for enum */
4731 s->c = (c + maxalign - 1) & -maxalign;
4733 return u;
4736 /* return 0 if no type declaration. otherwise, return the basic type
4737 and skip it.
4739 int parse_btype(int *type_ptr, AttributeDef *ad)
4741 int t, u, type_found;
4742 Sym *s;
4744 memset(ad, 0, sizeof(AttributeDef));
4745 type_found = 0;
4746 t = 0;
4747 while(1) {
4748 switch(tok) {
4749 /* basic types */
4750 case TOK_CHAR:
4751 u = VT_BYTE;
4752 basic_type:
4753 next();
4754 basic_type1:
4755 if ((t & VT_BTYPE) != 0)
4756 error("too many basic types");
4757 t |= u;
4758 break;
4759 case TOK_VOID:
4760 u = VT_VOID;
4761 goto basic_type;
4762 case TOK_SHORT:
4763 u = VT_SHORT;
4764 goto basic_type;
4765 case TOK_INT:
4766 next();
4767 break;
4768 case TOK_LONG:
4769 next();
4770 if ((t & VT_BTYPE) == VT_DOUBLE) {
4771 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4772 } else if ((t & VT_BTYPE) == VT_LONG) {
4773 t = (t & ~VT_BTYPE) | VT_LLONG;
4774 } else {
4775 u = VT_LONG;
4776 goto basic_type1;
4778 break;
4779 case TOK_BOOL:
4780 u = VT_BOOL;
4781 goto basic_type;
4782 case TOK_FLOAT:
4783 u = VT_FLOAT;
4784 goto basic_type;
4785 case TOK_DOUBLE:
4786 next();
4787 if ((t & VT_BTYPE) == VT_LONG) {
4788 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4789 } else {
4790 u = VT_DOUBLE;
4791 goto basic_type1;
4793 break;
4794 case TOK_ENUM:
4795 u = struct_decl(VT_ENUM);
4796 goto basic_type1;
4797 case TOK_STRUCT:
4798 case TOK_UNION:
4799 u = struct_decl(VT_STRUCT);
4800 goto basic_type1;
4802 /* type modifiers */
4803 case TOK_CONST:
4804 case TOK_VOLATILE:
4805 case TOK_REGISTER:
4806 case TOK_SIGNED:
4807 case TOK___SIGNED__:
4808 case TOK_AUTO:
4809 case TOK_INLINE:
4810 case TOK___INLINE__:
4811 case TOK_RESTRICT:
4812 next();
4813 break;
4814 case TOK_UNSIGNED:
4815 t |= VT_UNSIGNED;
4816 next();
4817 break;
4819 /* storage */
4820 case TOK_EXTERN:
4821 t |= VT_EXTERN;
4822 next();
4823 break;
4824 case TOK_STATIC:
4825 t |= VT_STATIC;
4826 next();
4827 break;
4828 case TOK_TYPEDEF:
4829 t |= VT_TYPEDEF;
4830 next();
4831 break;
4832 /* GNUC attribute */
4833 case TOK___ATTRIBUTE__:
4834 parse_attribute(ad);
4835 break;
4836 default:
4837 s = sym_find(tok);
4838 if (!s || !(s->t & VT_TYPEDEF))
4839 goto the_end;
4840 t |= (s->t & ~VT_TYPEDEF);
4841 next();
4842 break;
4844 type_found = 1;
4846 the_end:
4847 /* long is never used as type */
4848 if ((t & VT_BTYPE) == VT_LONG)
4849 t = (t & ~VT_BTYPE) | VT_INT;
4850 *type_ptr = t;
4851 return type_found;
4854 int post_type(int t, AttributeDef *ad)
4856 int p, n, pt, l, t1;
4857 Sym **plast, *s, *first;
4858 AttributeDef ad1;
4860 if (tok == '(') {
4861 /* function declaration */
4862 next();
4863 l = 0;
4864 first = NULL;
4865 plast = &first;
4866 while (tok != ')') {
4867 /* read param name and compute offset */
4868 if (l != FUNC_OLD) {
4869 if (!parse_btype(&pt, &ad1)) {
4870 if (l) {
4871 error("invalid type");
4872 } else {
4873 l = FUNC_OLD;
4874 goto old_proto;
4877 l = FUNC_NEW;
4878 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
4879 break;
4880 pt = type_decl(&ad1, &n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
4881 if ((pt & VT_BTYPE) == VT_VOID)
4882 error("parameter declared as void");
4883 } else {
4884 old_proto:
4885 n = tok;
4886 pt = VT_INT;
4887 next();
4889 /* array must be transformed to pointer according to ANSI C */
4890 pt &= ~VT_ARRAY;
4891 s = sym_push(n | SYM_FIELD, pt, 0, 0);
4892 *plast = s;
4893 plast = &s->next;
4894 if (tok == ',') {
4895 next();
4896 if (l == FUNC_NEW && tok == TOK_DOTS) {
4897 l = FUNC_ELLIPSIS;
4898 next();
4899 break;
4903 /* if no parameters, then old type prototype */
4904 if (l == 0)
4905 l = FUNC_OLD;
4906 skip(')');
4907 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4908 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4909 /* we push a anonymous symbol which will contain the function prototype */
4910 p = anon_sym++;
4911 s = sym_push(p, t, ad->func_call, l);
4912 s->next = first;
4913 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
4914 } else if (tok == '[') {
4915 /* array definition */
4916 next();
4917 n = -1;
4918 if (tok != ']') {
4919 n = expr_const();
4920 if (n < 0)
4921 error("invalid array size");
4923 skip(']');
4924 /* parse next post type */
4925 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4926 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4928 /* we push a anonymous symbol which will contain the array
4929 element type */
4930 p = anon_sym++;
4931 sym_push(p, t, 0, n);
4932 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
4934 return t;
4937 /* Read a type declaration (except basic type), and return the
4938 type. 'td' is a bitmask indicating which kind of type decl is
4939 expected. 't' should contain the basic type. 'ad' is the attribute
4940 definition of the basic type. It can be modified by type_decl(). */
4941 int type_decl(AttributeDef *ad, int *v, int t, int td)
4943 int u, p;
4944 Sym *s;
4946 while (tok == '*') {
4947 next();
4948 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
4949 next();
4950 t = mk_pointer(t);
4953 /* recursive type */
4954 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4955 if (tok == '(') {
4956 next();
4957 /* XXX: this is not correct to modify 'ad' at this point, but
4958 the syntax is not clear */
4959 if (tok == TOK___ATTRIBUTE__)
4960 parse_attribute(ad);
4961 u = type_decl(ad, v, 0, td);
4962 skip(')');
4963 } else {
4964 u = 0;
4965 /* type identifier */
4966 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
4967 *v = tok;
4968 next();
4969 } else {
4970 if (!(td & TYPE_ABSTRACT))
4971 expect("identifier");
4972 *v = 0;
4975 /* append t at the end of u */
4976 t = post_type(t, ad);
4977 if (tok == TOK___ATTRIBUTE__)
4978 parse_attribute(ad);
4979 if (!u)
4980 return t;
4981 p = u;
4982 while(1) {
4983 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
4984 p = s->t;
4985 if (!p) {
4986 s->t = t;
4987 break;
4990 return u;
4993 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4994 static int lvalue_type(int t)
4996 int bt, r;
4997 r = VT_LVAL;
4998 bt = t & VT_BTYPE;
4999 if (bt == VT_BYTE)
5000 r |= VT_LVAL_BYTE;
5001 else if (bt == VT_SHORT)
5002 r |= VT_LVAL_SHORT;
5003 else
5004 return r;
5005 if (t & VT_UNSIGNED)
5006 r |= VT_LVAL_UNSIGNED;
5007 return r;
5010 /* indirection with full error checking and bound check */
5011 static void indir(void)
5013 if ((vtop->t & VT_BTYPE) != VT_PTR)
5014 expect("pointer");
5015 if (vtop->r & VT_LVAL)
5016 gv(RC_INT);
5017 vtop->t = pointed_type(vtop->t);
5018 /* an array is never an lvalue */
5019 if (!(vtop->t & VT_ARRAY)) {
5020 vtop->r |= lvalue_type(vtop->t);
5021 /* if bound checking, the referenced pointer must be checked */
5022 if (do_bounds_check)
5023 vtop->r |= VT_MUSTBOUND;
5027 /* pass a parameter to a function and do type checking and casting */
5028 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
5030 int func_type;
5031 func_type = func->c;
5032 if (func_type == FUNC_OLD ||
5033 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
5034 /* default casting : only need to convert float to double */
5035 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
5036 gen_cast(VT_DOUBLE);
5037 } else if (arg == NULL) {
5038 error("too many arguments to function");
5039 } else {
5040 gen_assign_cast(arg->t);
5042 gfunc_param(gf);
5045 void unary(void)
5047 int n, t, ft, align, size, r;
5048 Sym *s;
5049 GFuncContext gf;
5050 AttributeDef ad;
5052 if (tok == TOK_CINT || tok == TOK_CCHAR || tok == TOK_LCHAR) {
5053 vpushi(tokc.i);
5054 next();
5055 } else if (tok == TOK_CUINT) {
5056 vsetc(VT_INT | VT_UNSIGNED, VT_CONST, &tokc);
5057 next();
5058 } else if (tok == TOK_CLLONG) {
5059 vsetc(VT_LLONG, VT_CONST, &tokc);
5060 next();
5061 } else if (tok == TOK_CULLONG) {
5062 vsetc(VT_LLONG | VT_UNSIGNED, VT_CONST, &tokc);
5063 next();
5064 } else if (tok == TOK_CFLOAT) {
5065 vsetc(VT_FLOAT, VT_CONST, &tokc);
5066 next();
5067 } else if (tok == TOK_CDOUBLE) {
5068 vsetc(VT_DOUBLE, VT_CONST, &tokc);
5069 next();
5070 } else if (tok == TOK_CLDOUBLE) {
5071 vsetc(VT_LDOUBLE, VT_CONST, &tokc);
5072 next();
5073 } else if (tok == TOK___FUNC__ || (tok == TOK___FUNCTION__ && gnu_ext)) {
5074 void *ptr;
5075 int len;
5076 /* special function name identifier */
5078 len = strlen(funcname) + 1;
5079 /* generate char[len] type */
5080 t = VT_ARRAY | mk_pointer(VT_BYTE);
5081 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5082 s->c = len;
5083 vpush_ref(t, data_section, data_section->data_offset, len);
5084 ptr = section_ptr_add(data_section, len);
5085 memcpy(ptr, funcname, len);
5086 next();
5087 } else if (tok == TOK_LSTR) {
5088 t = VT_INT;
5089 goto str_init;
5090 } else if (tok == TOK_STR) {
5091 /* string parsing */
5092 t = VT_BYTE;
5093 str_init:
5094 t = VT_ARRAY | mk_pointer(t);
5095 memset(&ad, 0, sizeof(AttributeDef));
5096 decl_initializer_alloc(t, &ad, VT_CONST, 2, 0, 0);
5097 } else {
5098 t = tok;
5099 next();
5100 if (t == '(') {
5101 /* cast ? */
5102 if (parse_btype(&t, &ad)) {
5103 ft = type_decl(&ad, &n, t, TYPE_ABSTRACT);
5104 skip(')');
5105 /* check ISOC99 compound literal */
5106 if (tok == '{') {
5107 /* data is allocated locally by default */
5108 if (global_expr)
5109 r = VT_CONST;
5110 else
5111 r = VT_LOCAL;
5112 /* all except arrays are lvalues */
5113 if (!(ft & VT_ARRAY))
5114 r |= lvalue_type(ft);
5115 memset(&ad, 0, sizeof(AttributeDef));
5116 decl_initializer_alloc(ft, &ad, r, 1, 0, 0);
5117 } else {
5118 unary();
5119 gen_cast(ft);
5121 } else {
5122 gexpr();
5123 skip(')');
5125 } else if (t == '*') {
5126 unary();
5127 indir();
5128 } else if (t == '&') {
5129 unary();
5130 /* functions names must be treated as function pointers,
5131 except for unary '&' and sizeof. Since we consider that
5132 functions are not lvalues, we only have to handle it
5133 there and in function calls. */
5134 /* arrays can also be used although they are not lvalues */
5135 if ((vtop->t & VT_BTYPE) != VT_FUNC &&
5136 !(vtop->t & VT_ARRAY))
5137 test_lvalue();
5138 vtop->t = mk_pointer(vtop->t);
5139 gaddrof();
5140 } else
5141 if (t == '!') {
5142 unary();
5143 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
5144 vtop->c.i = !vtop->c.i;
5145 else if ((vtop->r & VT_VALMASK) == VT_CMP)
5146 vtop->c.i = vtop->c.i ^ 1;
5147 else
5148 vset(VT_INT, VT_JMP, gtst(1, 0));
5149 } else
5150 if (t == '~') {
5151 unary();
5152 vpushi(-1);
5153 gen_op('^');
5154 } else
5155 if (t == '+') {
5156 /* in order to force cast, we add zero */
5157 unary();
5158 if ((vtop->t & VT_BTYPE) == VT_PTR)
5159 error("pointer not accepted for unary plus");
5160 vpushi(0);
5161 gen_op('+');
5162 } else
5163 if (t == TOK_SIZEOF) {
5164 if (tok == '(') {
5165 next();
5166 if (parse_btype(&t, &ad)) {
5167 t = type_decl(&ad, &n, t, TYPE_ABSTRACT);
5168 } else {
5169 /* XXX: some code could be generated: add eval
5170 flag */
5171 gexpr();
5172 t = vtop->t;
5173 vpop();
5175 skip(')');
5176 } else {
5177 unary();
5178 t = vtop->t;
5179 vpop();
5181 vpushi(type_size(t, &t));
5182 } else
5183 if (t == TOK_INC || t == TOK_DEC) {
5184 unary();
5185 inc(0, t);
5186 } else if (t == '-') {
5187 vpushi(0);
5188 unary();
5189 gen_op('-');
5190 } else
5192 if (t < TOK_UIDENT)
5193 expect("identifier");
5194 s = sym_find(t);
5195 if (!s) {
5196 if (tok != '(')
5197 error("'%s' undeclared", get_tok_str(t, NULL));
5198 /* for simple function calls, we tolerate undeclared
5199 external reference to int() function */
5200 s = external_global_sym(t, func_old_type, 0);
5202 vset(s->t, s->r, s->c);
5203 /* if forward reference, we must point to s */
5204 if (vtop->r & VT_SYM) {
5205 vtop->sym = s;
5206 vtop->c.ul = 0;
5211 /* post operations */
5212 while (1) {
5213 if (tok == TOK_INC || tok == TOK_DEC) {
5214 inc(1, tok);
5215 next();
5216 } else if (tok == '.' || tok == TOK_ARROW) {
5217 /* field */
5218 if (tok == TOK_ARROW)
5219 indir();
5220 test_lvalue();
5221 gaddrof();
5222 next();
5223 /* expect pointer on structure */
5224 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
5225 expect("struct or union");
5226 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5227 /* find field */
5228 tok |= SYM_FIELD;
5229 while ((s = s->next) != NULL) {
5230 if (s->v == tok)
5231 break;
5233 if (!s)
5234 error("field not found");
5235 /* add field offset to pointer */
5236 vtop->t = char_pointer_type; /* change type to 'char *' */
5237 vpushi(s->c);
5238 gen_op('+');
5239 /* change type to field type, and set to lvalue */
5240 vtop->t = s->t;
5241 /* an array is never an lvalue */
5242 if (!(vtop->t & VT_ARRAY))
5243 vtop->r |= lvalue_type(vtop->t);
5244 next();
5245 } else if (tok == '[') {
5246 next();
5247 gexpr();
5248 gen_op('+');
5249 indir();
5250 skip(']');
5251 } else if (tok == '(') {
5252 SValue ret;
5253 Sym *sa;
5255 /* function call */
5256 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
5257 /* pointer test (no array accepted) */
5258 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
5259 vtop->t = pointed_type(vtop->t);
5260 if ((vtop->t & VT_BTYPE) != VT_FUNC)
5261 goto error_func;
5262 } else {
5263 error_func:
5264 expect("function pointer");
5266 } else {
5267 vtop->r &= ~VT_LVAL; /* no lvalue */
5269 /* get return type */
5270 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
5271 save_regs(0); /* save used temporary registers */
5272 gfunc_start(&gf, s->r);
5273 next();
5274 sa = s->next; /* first parameter */
5275 #ifdef INVERT_FUNC_PARAMS
5277 int parlevel;
5278 Sym *args, *s1;
5279 ParseState saved_parse_state;
5280 TokenString str;
5282 /* read each argument and store it on a stack */
5283 args = NULL;
5284 if (tok != ')') {
5285 for(;;) {
5286 tok_str_new(&str);
5287 parlevel = 0;
5288 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
5289 tok != TOK_EOF) {
5290 if (tok == '(')
5291 parlevel++;
5292 else if (tok == ')')
5293 parlevel--;
5294 tok_str_add_tok(&str);
5295 next();
5297 tok_str_add(&str, -1); /* end of file added */
5298 tok_str_add(&str, 0);
5299 s1 = sym_push2(&args, 0, 0, (int)str.str);
5300 s1->next = sa; /* add reference to argument */
5301 if (sa)
5302 sa = sa->next;
5303 if (tok == ')')
5304 break;
5305 skip(',');
5309 /* now generate code in reverse order by reading the stack */
5310 save_parse_state(&saved_parse_state);
5311 while (args) {
5312 macro_ptr = (int *)args->c;
5313 next();
5314 expr_eq();
5315 if (tok != -1)
5316 expect("',' or ')'");
5317 gfunc_param_typed(&gf, s, args->next);
5318 s1 = args->prev;
5319 tok_str_free((int *)args->c);
5320 tcc_free(args);
5321 args = s1;
5323 restore_parse_state(&saved_parse_state);
5325 #endif
5326 /* compute first implicit argument if a structure is returned */
5327 if ((s->t & VT_BTYPE) == VT_STRUCT) {
5328 /* get some space for the returned structure */
5329 size = type_size(s->t, &align);
5330 loc = (loc - size) & -align;
5331 ret.t = s->t;
5332 ret.r = VT_LOCAL | VT_LVAL;
5333 /* pass it as 'int' to avoid structure arg passing
5334 problems */
5335 vset(VT_INT, VT_LOCAL, loc);
5336 ret.c = vtop->c;
5337 gfunc_param(&gf);
5338 } else {
5339 ret.t = s->t;
5340 ret.r2 = VT_CONST;
5341 /* return in register */
5342 if (is_float(ret.t)) {
5343 ret.r = REG_FRET;
5344 } else {
5345 if ((ret.t & VT_BTYPE) == VT_LLONG)
5346 ret.r2 = REG_LRET;
5347 ret.r = REG_IRET;
5349 ret.c.i = 0;
5351 #ifndef INVERT_FUNC_PARAMS
5352 if (tok != ')') {
5353 for(;;) {
5354 expr_eq();
5355 gfunc_param_typed(&gf, s, sa);
5356 if (sa)
5357 sa = sa->next;
5358 if (tok == ')')
5359 break;
5360 skip(',');
5363 #endif
5364 if (sa)
5365 error("too few arguments to function");
5366 skip(')');
5367 gfunc_call(&gf);
5368 /* return value */
5369 vsetc(ret.t, ret.r, &ret.c);
5370 vtop->r2 = ret.r2;
5371 } else {
5372 break;
5377 void uneq(void)
5379 int t;
5381 unary();
5382 if (tok == '=' ||
5383 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5384 tok == TOK_A_XOR || tok == TOK_A_OR ||
5385 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5386 test_lvalue();
5387 t = tok;
5388 next();
5389 if (t == '=') {
5390 expr_eq();
5391 } else {
5392 vdup();
5393 expr_eq();
5394 gen_op(t & 0x7f);
5396 vstore();
5400 void sum(int l)
5402 int t;
5404 if (l == 0)
5405 uneq();
5406 else {
5407 sum(--l);
5408 while ((l == 0 && (tok == '*' || tok == '/' || tok == '%')) ||
5409 (l == 1 && (tok == '+' || tok == '-')) ||
5410 (l == 2 && (tok == TOK_SHL || tok == TOK_SAR)) ||
5411 (l == 3 && ((tok >= TOK_ULE && tok <= TOK_GT) ||
5412 tok == TOK_ULT || tok == TOK_UGE)) ||
5413 (l == 4 && (tok == TOK_EQ || tok == TOK_NE)) ||
5414 (l == 5 && tok == '&') ||
5415 (l == 6 && tok == '^') ||
5416 (l == 7 && tok == '|') ||
5417 (l == 8 && tok == TOK_LAND) ||
5418 (l == 9 && tok == TOK_LOR)) {
5419 t = tok;
5420 next();
5421 sum(l);
5422 gen_op(t);
5427 /* only used if non constant */
5428 void eand(void)
5430 int t;
5432 sum(8);
5433 t = 0;
5434 while (1) {
5435 if (tok != TOK_LAND) {
5436 if (t) {
5437 t = gtst(1, t);
5438 vset(VT_INT, VT_JMPI, t);
5440 break;
5442 t = gtst(1, t);
5443 next();
5444 sum(8);
5448 void eor(void)
5450 int t;
5452 eand();
5453 t = 0;
5454 while (1) {
5455 if (tok != TOK_LOR) {
5456 if (t) {
5457 t = gtst(0, t);
5458 vset(VT_INT, VT_JMP, t);
5460 break;
5462 t = gtst(0, t);
5463 next();
5464 eand();
5468 /* XXX: better constant handling */
5469 void expr_eq(void)
5471 int t, u, c, r1, r2, rc;
5473 if (const_wanted) {
5474 sum(10);
5475 if (tok == '?') {
5476 c = vtop->c.i;
5477 vpop();
5478 next();
5479 gexpr();
5480 t = vtop->c.i;
5481 vpop();
5482 skip(':');
5483 expr_eq();
5484 if (c)
5485 vtop->c.i = t;
5487 } else {
5488 eor();
5489 if (tok == '?') {
5490 next();
5491 save_regs(1); /* we need to save all registers here except
5492 at the top because it is a branch point */
5493 t = gtst(1, 0);
5494 gexpr();
5495 /* XXX: long long handling ? */
5496 rc = RC_INT;
5497 if (is_float(vtop->t))
5498 rc = RC_FLOAT;
5499 r1 = gv(rc);
5500 vtop--; /* no vpop so that FP stack is not flushed */
5501 skip(':');
5502 u = gjmp(0);
5504 gsym(t);
5505 expr_eq();
5506 r2 = gv(rc);
5507 move_reg(r1, r2);
5508 vtop->r = r1;
5509 gsym(u);
5514 void gexpr(void)
5516 while (1) {
5517 expr_eq();
5518 if (tok != ',')
5519 break;
5520 vpop();
5521 next();
5525 /* parse a constant expression and return value in vtop. */
5526 static void expr_const1(void)
5528 int a;
5529 a = const_wanted;
5530 const_wanted = 1;
5531 expr_eq();
5532 const_wanted = a;
5535 /* parse an integer constant and return its value. */
5536 static int expr_const(void)
5538 int c;
5539 expr_const1();
5540 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
5541 expect("constant expression");
5542 c = vtop->c.i;
5543 vpop();
5544 return c;
5547 /* return the label token if current token is a label, otherwise
5548 return zero */
5549 int is_label(void)
5551 int t;
5552 CValue c;
5554 /* fast test first */
5555 if (tok < TOK_UIDENT)
5556 return 0;
5557 /* no need to save tokc since we expect an identifier */
5558 t = tok;
5559 c = tokc;
5560 next();
5561 if (tok == ':') {
5562 next();
5563 return t;
5564 } else {
5565 /* XXX: may not work in all cases (macros ?) */
5566 tok1 = tok;
5567 tok1c = tokc;
5568 tok = t;
5569 tokc = c;
5570 return 0;
5574 void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
5576 int a, b, c, d;
5577 Sym *s;
5579 /* generate line number info */
5580 if (do_debug &&
5581 (last_line_num != file->line_num || last_ind != ind)) {
5582 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
5583 last_ind = ind;
5584 last_line_num = file->line_num;
5587 if (tok == TOK_IF) {
5588 /* if test */
5589 next();
5590 skip('(');
5591 gexpr();
5592 skip(')');
5593 a = gtst(1, 0);
5594 block(bsym, csym, case_sym, def_sym, case_reg);
5595 c = tok;
5596 if (c == TOK_ELSE) {
5597 next();
5598 d = gjmp(0);
5599 gsym(a);
5600 block(bsym, csym, case_sym, def_sym, case_reg);
5601 gsym(d); /* patch else jmp */
5602 } else
5603 gsym(a);
5604 } else if (tok == TOK_WHILE) {
5605 next();
5606 d = ind;
5607 skip('(');
5608 gexpr();
5609 skip(')');
5610 a = gtst(1, 0);
5611 b = 0;
5612 block(&a, &b, case_sym, def_sym, case_reg);
5613 gjmp_addr(d);
5614 gsym(a);
5615 gsym_addr(b, d);
5616 } else if (tok == '{') {
5617 next();
5618 /* declarations */
5619 s = local_stack.top;
5620 while (tok != '}') {
5621 decl(VT_LOCAL);
5622 if (tok != '}')
5623 block(bsym, csym, case_sym, def_sym, case_reg);
5625 /* pop locally defined symbols */
5626 sym_pop(&local_stack, s);
5627 next();
5628 } else if (tok == TOK_RETURN) {
5629 next();
5630 if (tok != ';') {
5631 gexpr();
5632 gen_assign_cast(func_vt);
5633 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
5634 /* if returning structure, must copy it to implicit
5635 first pointer arg location */
5636 vset(mk_pointer(func_vt), VT_LOCAL | VT_LVAL, func_vc);
5637 indir();
5638 vswap();
5639 /* copy structure value to pointer */
5640 vstore();
5641 } else if (is_float(func_vt)) {
5642 gv(RC_FRET);
5643 } else {
5644 gv(RC_IRET);
5646 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5648 skip(';');
5649 rsym = gjmp(rsym); /* jmp */
5650 } else if (tok == TOK_BREAK) {
5651 /* compute jump */
5652 if (!bsym)
5653 error("cannot break");
5654 *bsym = gjmp(*bsym);
5655 next();
5656 skip(';');
5657 } else if (tok == TOK_CONTINUE) {
5658 /* compute jump */
5659 if (!csym)
5660 error("cannot continue");
5661 *csym = gjmp(*csym);
5662 next();
5663 skip(';');
5664 } else if (tok == TOK_FOR) {
5665 int e;
5666 next();
5667 skip('(');
5668 if (tok != ';') {
5669 gexpr();
5670 vpop();
5672 skip(';');
5673 d = ind;
5674 c = ind;
5675 a = 0;
5676 b = 0;
5677 if (tok != ';') {
5678 gexpr();
5679 a = gtst(1, 0);
5681 skip(';');
5682 if (tok != ')') {
5683 e = gjmp(0);
5684 c = ind;
5685 gexpr();
5686 vpop();
5687 gjmp_addr(d);
5688 gsym(e);
5690 skip(')');
5691 block(&a, &b, case_sym, def_sym, case_reg);
5692 gjmp_addr(c);
5693 gsym(a);
5694 gsym_addr(b, c);
5695 } else
5696 if (tok == TOK_DO) {
5697 next();
5698 a = 0;
5699 b = 0;
5700 d = ind;
5701 block(&a, &b, case_sym, def_sym, case_reg);
5702 skip(TOK_WHILE);
5703 skip('(');
5704 gsym(b);
5705 gexpr();
5706 c = gtst(0, 0);
5707 gsym_addr(c, d);
5708 skip(')');
5709 gsym(a);
5710 skip(';');
5711 } else
5712 if (tok == TOK_SWITCH) {
5713 next();
5714 skip('(');
5715 gexpr();
5716 /* XXX: other types than integer */
5717 case_reg = gv(RC_INT);
5718 vpop();
5719 skip(')');
5720 a = 0;
5721 b = gjmp(0); /* jump to first case */
5722 c = 0;
5723 block(&a, csym, &b, &c, case_reg);
5724 /* if no default, jmp after switch */
5725 if (c == 0)
5726 c = ind;
5727 /* default label */
5728 gsym_addr(b, c);
5729 /* break label */
5730 gsym(a);
5731 } else
5732 if (tok == TOK_CASE) {
5733 int v1, v2;
5734 if (!case_sym)
5735 expect("switch");
5736 next();
5737 v1 = expr_const();
5738 v2 = v1;
5739 if (gnu_ext && tok == TOK_DOTS) {
5740 next();
5741 v2 = expr_const();
5742 if (v2 < v1)
5743 warning("empty case range");
5745 /* since a case is like a label, we must skip it with a jmp */
5746 b = gjmp(0);
5747 gsym(*case_sym);
5748 vset(VT_INT, case_reg, 0);
5749 vpushi(v1);
5750 if (v1 == v2) {
5751 gen_op(TOK_EQ);
5752 *case_sym = gtst(1, 0);
5753 } else {
5754 gen_op(TOK_GE);
5755 *case_sym = gtst(1, 0);
5756 vset(VT_INT, case_reg, 0);
5757 vpushi(v2);
5758 gen_op(TOK_LE);
5759 *case_sym = gtst(1, *case_sym);
5761 gsym(b);
5762 skip(':');
5763 block(bsym, csym, case_sym, def_sym, case_reg);
5764 } else
5765 if (tok == TOK_DEFAULT) {
5766 next();
5767 skip(':');
5768 if (!def_sym)
5769 expect("switch");
5770 if (*def_sym)
5771 error("too many 'default'");
5772 *def_sym = ind;
5773 block(bsym, csym, case_sym, def_sym, case_reg);
5774 } else
5775 if (tok == TOK_GOTO) {
5776 next();
5777 s = sym_find1(&label_stack, tok);
5778 /* put forward definition if needed */
5779 if (!s)
5780 s = sym_push1(&label_stack, tok, LABEL_FORWARD, 0);
5781 /* label already defined */
5782 if (s->t & LABEL_FORWARD)
5783 s->c = gjmp(s->c);
5784 else
5785 gjmp_addr(s->c);
5786 next();
5787 skip(';');
5788 } else {
5789 b = is_label();
5790 if (b) {
5791 /* label case */
5792 s = sym_find1(&label_stack, b);
5793 if (s) {
5794 if (!(s->t & LABEL_FORWARD))
5795 error("multiple defined label");
5796 gsym(s->c);
5797 s->c = ind;
5798 s->t = 0;
5799 } else {
5800 sym_push1(&label_stack, b, 0, ind);
5802 /* we accept this, but it is a mistake */
5803 if (tok == '}')
5804 warning("deprecated use of label at end of compound statement");
5805 else
5806 block(bsym, csym, case_sym, def_sym, case_reg);
5807 } else {
5808 /* expression case */
5809 if (tok != ';') {
5810 gexpr();
5811 vpop();
5813 skip(';');
5818 /* t is the array or struct type. c is the array or struct
5819 address. cur_index/cur_field is the pointer to the current
5820 value. 'size_only' is true if only size info is needed (only used
5821 in arrays) */
5822 static void decl_designator(int t, Section *sec, unsigned long c,
5823 int *cur_index, Sym **cur_field,
5824 int size_only)
5826 Sym *s, *f;
5827 int notfirst, index, align, l;
5829 notfirst = 0;
5830 if (gnu_ext && (l = is_label()) != 0)
5831 goto struct_field;
5833 while (tok == '[' || tok == '.') {
5834 if (tok == '[') {
5835 if (!(t & VT_ARRAY))
5836 expect("array type");
5837 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5838 next();
5839 index = expr_const();
5840 if (index < 0 || (s->c >= 0 && index >= s->c))
5841 expect("invalid index");
5842 skip(']');
5843 if (!notfirst)
5844 *cur_index = index;
5845 t = pointed_type(t);
5846 c += index * type_size(t, &align);
5847 } else {
5848 next();
5849 l = tok;
5850 next();
5851 struct_field:
5852 if ((t & VT_BTYPE) != VT_STRUCT)
5853 expect("struct/union type");
5854 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5855 l |= SYM_FIELD;
5856 f = s->next;
5857 while (f) {
5858 if (f->v == l)
5859 break;
5860 f = f->next;
5862 if (!f)
5863 expect("field");
5864 if (!notfirst)
5865 *cur_field = f;
5866 t = f->t | (t & ~VT_TYPE);
5867 c += f->c;
5869 notfirst = 1;
5871 if (notfirst) {
5872 if (tok == '=') {
5873 next();
5874 } else {
5875 if (!gnu_ext)
5876 expect("=");
5878 } else {
5879 if (t & VT_ARRAY) {
5880 index = *cur_index;
5881 t = pointed_type(t);
5882 c += index * type_size(t, &align);
5883 } else {
5884 f = *cur_field;
5885 if (!f)
5886 error("too many field init");
5887 t = f->t | (t & ~VT_TYPE);
5888 c += f->c;
5891 decl_initializer(t, sec, c, 0, size_only);
5894 #define EXPR_VAL 0
5895 #define EXPR_CONST 1
5896 #define EXPR_ANY 2
5898 /* store a value or an expression directly in global data or in local array */
5899 static void init_putv(int t, Section *sec, unsigned long c,
5900 int v, int expr_type)
5902 int saved_global_expr, bt;
5903 void *ptr;
5905 switch(expr_type) {
5906 case EXPR_VAL:
5907 vpushi(v);
5908 break;
5909 case EXPR_CONST:
5910 /* compound literals must be allocated globally in this case */
5911 saved_global_expr = global_expr;
5912 global_expr = 1;
5913 expr_const1();
5914 global_expr = saved_global_expr;
5915 /* NOTE: symbols are accepted */
5916 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5917 error("initializer element is not constant");
5918 break;
5919 case EXPR_ANY:
5920 expr_eq();
5921 break;
5924 if (sec) {
5925 /* XXX: not portable */
5926 /* XXX: generate error if incorrect relocation */
5927 gen_assign_cast(t);
5928 bt = t & VT_BTYPE;
5929 ptr = sec->data + c;
5930 if ((vtop->r & VT_SYM) &&
5931 (bt == VT_BYTE ||
5932 bt == VT_SHORT ||
5933 bt == VT_DOUBLE ||
5934 bt == VT_LDOUBLE ||
5935 bt == VT_LLONG))
5936 error("initializer element is not computable at load time");
5937 switch(bt) {
5938 case VT_BYTE:
5939 *(char *)ptr = vtop->c.i;
5940 break;
5941 case VT_SHORT:
5942 *(short *)ptr = vtop->c.i;
5943 break;
5944 case VT_DOUBLE:
5945 *(double *)ptr = vtop->c.d;
5946 break;
5947 case VT_LDOUBLE:
5948 *(long double *)ptr = vtop->c.ld;
5949 break;
5950 case VT_LLONG:
5951 *(long long *)ptr = vtop->c.ll;
5952 break;
5953 default:
5954 if (vtop->r & VT_SYM) {
5955 greloc(sec, vtop->sym, c, R_DATA_32);
5957 *(int *)ptr = vtop->c.i;
5958 break;
5960 vtop--;
5961 } else {
5962 vset(t, VT_LOCAL, c);
5963 vswap();
5964 vstore();
5965 vpop();
5969 /* put zeros for variable based init */
5970 static void init_putz(int t, Section *sec, unsigned long c, int size)
5972 GFuncContext gf;
5974 if (sec) {
5975 /* nothing to do because globals are already set to zero */
5976 } else {
5977 gfunc_start(&gf, FUNC_CDECL);
5978 vpushi(size);
5979 gfunc_param(&gf);
5980 vpushi(0);
5981 gfunc_param(&gf);
5982 vset(VT_INT, VT_LOCAL, c);
5983 gfunc_param(&gf);
5984 vpush_global_sym(func_old_type, TOK_memset);
5985 gfunc_call(&gf);
5989 /* 't' contains the type and storage info. 'c' is the offset of the
5990 object in section 'sec'. If 'sec' is NULL, it means stack based
5991 allocation. 'first' is true if array '{' must be read (multi
5992 dimension implicit array init handling). 'size_only' is true if
5993 size only evaluation is wanted (only for arrays). */
5994 static void decl_initializer(int t, Section *sec, unsigned long c,
5995 int first, int size_only)
5997 int index, array_length, n, no_oblock, nb, parlevel, i;
5998 int t1, size1, align1, expr_type;
5999 Sym *s, *f;
6001 if (t & VT_ARRAY) {
6002 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
6003 n = s->c;
6004 array_length = 0;
6005 t1 = pointed_type(t);
6006 size1 = type_size(t1, &align1);
6008 no_oblock = 1;
6009 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
6010 tok == '{') {
6011 skip('{');
6012 no_oblock = 0;
6015 /* only parse strings here if correct type (otherwise: handle
6016 them as ((w)char *) expressions */
6017 if ((tok == TOK_LSTR &&
6018 (t1 & VT_BTYPE) == VT_INT) ||
6019 (tok == TOK_STR &&
6020 (t1 & VT_BTYPE) == VT_BYTE)) {
6021 while (tok == TOK_STR || tok == TOK_LSTR) {
6022 int cstr_len, ch;
6023 CString *cstr;
6025 cstr = tokc.cstr;
6026 /* compute maximum number of chars wanted */
6027 if (tok == TOK_STR)
6028 cstr_len = cstr->size;
6029 else
6030 cstr_len = cstr->size / sizeof(int);
6031 cstr_len--;
6032 nb = cstr_len;
6033 if (n >= 0 && nb > (n - array_length))
6034 nb = n - array_length;
6035 if (!size_only) {
6036 if (cstr_len > nb)
6037 warning("initializer-string for array is too long");
6038 for(i=0;i<nb;i++) {
6039 if (tok == TOK_STR)
6040 ch = ((unsigned char *)cstr->data)[i];
6041 else
6042 ch = ((int *)cstr->data)[i];
6043 init_putv(t1, sec, c + (array_length + i) * size1,
6044 ch, EXPR_VAL);
6047 array_length += nb;
6048 next();
6050 /* only add trailing zero if enough storage (no
6051 warning in this case since it is standard) */
6052 if (n < 0 || array_length < n) {
6053 if (!size_only) {
6054 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
6056 array_length++;
6058 } else {
6059 index = 0;
6060 while (tok != '}') {
6061 decl_designator(t, sec, c, &index, NULL, size_only);
6062 if (n >= 0 && index >= n)
6063 error("index too large");
6064 /* must put zero in holes (note that doing it that way
6065 ensures that it even works with designators) */
6066 if (!size_only && array_length < index) {
6067 init_putz(t1, sec, c + array_length * size1,
6068 (index - array_length) * size1);
6070 index++;
6071 if (index > array_length)
6072 array_length = index;
6073 /* special test for multi dimensional arrays (may not
6074 be strictly correct if designators are used at the
6075 same time) */
6076 if (index >= n && no_oblock)
6077 break;
6078 if (tok == '}')
6079 break;
6080 skip(',');
6083 if (!no_oblock)
6084 skip('}');
6085 /* put zeros at the end */
6086 if (!size_only && n >= 0 && array_length < n) {
6087 init_putz(t1, sec, c + array_length * size1,
6088 (n - array_length) * size1);
6090 /* patch type size if needed */
6091 if (n < 0)
6092 s->c = array_length;
6093 } else if ((t & VT_BTYPE) == VT_STRUCT && tok == '{') {
6094 /* XXX: union needs only one init */
6095 next();
6096 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
6097 f = s->next;
6098 array_length = 0;
6099 index = 0;
6100 n = s->c;
6101 while (tok != '}') {
6102 decl_designator(t, sec, c, NULL, &f, size_only);
6103 /* fill with zero between fields */
6104 index = f->c;
6105 if (!size_only && array_length < index) {
6106 init_putz(t, sec, c + array_length,
6107 index - array_length);
6109 index = index + type_size(f->t, &align1);
6110 if (index > array_length)
6111 array_length = index;
6112 if (tok == '}')
6113 break;
6114 skip(',');
6115 f = f->next;
6117 /* put zeros at the end */
6118 if (!size_only && array_length < n) {
6119 init_putz(t, sec, c + array_length,
6120 n - array_length);
6122 skip('}');
6123 } else if (tok == '{') {
6124 next();
6125 decl_initializer(t, sec, c, first, size_only);
6126 skip('}');
6127 } else if (size_only) {
6128 /* just skip expression */
6129 parlevel = 0;
6130 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
6131 tok != -1) {
6132 if (tok == '(')
6133 parlevel++;
6134 else if (tok == ')')
6135 parlevel--;
6136 next();
6138 } else {
6139 /* currently, we always use constant expression for globals
6140 (may change for scripting case) */
6141 expr_type = EXPR_CONST;
6142 if (!sec)
6143 expr_type = EXPR_ANY;
6144 init_putv(t, sec, c, 0, expr_type);
6148 /* parse an initializer for type 't' if 'has_init' is non zero, and
6149 allocate space in local or global data space ('r' is either
6150 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6151 variable 'v' of scope 'scope' is declared before initializers are
6152 parsed. If 'v' is zero, then a reference to the new object is put
6153 in the value stack. If 'has_init' is 2, a special parsing is done
6154 to handle string constants. */
6155 static void decl_initializer_alloc(int t, AttributeDef *ad, int r,
6156 int has_init, int v, int scope)
6158 int size, align, addr, data_offset;
6159 int level;
6160 ParseState saved_parse_state;
6161 TokenString init_str;
6162 Section *sec;
6164 size = type_size(t, &align);
6165 /* If unknown size, we must evaluate it before
6166 evaluating initializers because
6167 initializers can generate global data too
6168 (e.g. string pointers or ISOC99 compound
6169 literals). It also simplifies local
6170 initializers handling */
6171 tok_str_new(&init_str);
6172 if (size < 0) {
6173 if (!has_init)
6174 error("unknown type size");
6175 /* get all init string */
6176 if (has_init == 2) {
6177 /* only get strings */
6178 while (tok == TOK_STR || tok == TOK_LSTR) {
6179 tok_str_add_tok(&init_str);
6180 next();
6182 } else {
6183 level = 0;
6184 while (level > 0 || (tok != ',' && tok != ';')) {
6185 if (tok < 0)
6186 error("unexpected end of file in initializer");
6187 tok_str_add_tok(&init_str);
6188 if (tok == '{')
6189 level++;
6190 else if (tok == '}') {
6191 if (level == 0)
6192 break;
6193 level--;
6195 next();
6198 tok_str_add(&init_str, -1);
6199 tok_str_add(&init_str, 0);
6201 /* compute size */
6202 save_parse_state(&saved_parse_state);
6204 macro_ptr = init_str.str;
6205 next();
6206 decl_initializer(t, NULL, 0, 1, 1);
6207 /* prepare second initializer parsing */
6208 macro_ptr = init_str.str;
6209 next();
6211 /* if still unknown size, error */
6212 size = type_size(t, &align);
6213 if (size < 0)
6214 error("unknown type size");
6216 /* take into account specified alignment if bigger */
6217 if (ad->aligned > align)
6218 align = ad->aligned;
6219 if ((r & VT_VALMASK) == VT_LOCAL) {
6220 sec = NULL;
6221 if (do_bounds_check && (t & VT_ARRAY))
6222 loc--;
6223 #ifdef TCC_TARGET_IL
6224 /* XXX: ugly patch to allocate local variables for IL, just
6225 for testing */
6226 addr = loc;
6227 loc++;
6228 #else
6229 loc = (loc - size) & -align;
6230 addr = loc;
6231 #endif
6232 /* handles bounds */
6233 /* XXX: currently, since we do only one pass, we cannot track
6234 '&' operators, so we add only arrays */
6235 if (do_bounds_check && (t & VT_ARRAY)) {
6236 unsigned long *bounds_ptr;
6237 /* add padding between regions */
6238 loc--;
6239 /* then add local bound info */
6240 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
6241 bounds_ptr[0] = addr;
6242 bounds_ptr[1] = size;
6244 } else {
6245 /* compute section */
6246 sec = ad->section;
6247 if (!sec) {
6248 if (has_init)
6249 sec = data_section;
6250 else
6251 sec = bss_section;
6253 data_offset = sec->data_offset;
6254 data_offset = (data_offset + align - 1) & -align;
6255 addr = data_offset;
6256 /* very important to increment global pointer at this time
6257 because initializers themselves can create new initializers */
6258 data_offset += size;
6259 /* add padding if bound check */
6260 if (do_bounds_check)
6261 data_offset++;
6262 sec->data_offset = data_offset;
6263 /* allocate section space to put the data */
6264 if (sec->sh_type != SHT_NOBITS &&
6265 data_offset > sec->data_allocated)
6266 section_realloc(sec, data_offset);
6268 if (!sec) {
6269 if (v) {
6270 /* local variable */
6271 sym_push(v, t, r, addr);
6272 } else {
6273 /* push local reference */
6274 vset(t, r, addr);
6276 } else {
6277 Sym *sym;
6279 if (v) {
6280 if (scope == VT_CONST) {
6281 /* global scope: see if already defined */
6282 sym = sym_find(v);
6283 if (!sym)
6284 goto do_def;
6285 if (!is_compatible_types(sym->t, t))
6286 error("incompatible types for redefinition of '%s'",
6287 get_tok_str(v, NULL));
6288 if (!(sym->t & VT_EXTERN))
6289 error("redefinition of '%s'", get_tok_str(v, NULL));
6290 sym->t &= ~VT_EXTERN;
6291 } else {
6292 do_def:
6293 sym = sym_push(v, t, r | VT_SYM, 0);
6295 put_extern_sym(sym, sec, addr, size);
6296 } else {
6297 CValue cval;
6299 /* push global reference */
6300 sym = get_sym_ref(t, sec, addr, size);
6301 cval.ul = 0;
6302 vsetc(t, VT_CONST | VT_SYM, &cval);
6303 vtop->sym = sym;
6306 /* handles bounds now because the symbol must be defined
6307 before for the relocation */
6308 if (do_bounds_check) {
6309 unsigned long *bounds_ptr;
6311 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
6312 /* then add global bound info */
6313 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
6314 bounds_ptr[0] = 0; /* relocated */
6315 bounds_ptr[1] = size;
6318 if (has_init) {
6319 decl_initializer(t, sec, addr, 1, 0);
6320 /* restore parse state if needed */
6321 if (init_str.str) {
6322 tok_str_free(init_str.str);
6323 restore_parse_state(&saved_parse_state);
6328 void put_func_debug(Sym *sym)
6330 char buf[512];
6332 /* stabs info */
6333 /* XXX: we put here a dummy type */
6334 snprintf(buf, sizeof(buf), "%s:%c1",
6335 funcname, sym->t & VT_STATIC ? 'f' : 'F');
6336 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
6337 cur_text_section, sym->c);
6338 last_ind = 0;
6339 last_line_num = 0;
6342 /* not finished : try to put some local vars in registers */
6343 //#define CONFIG_REG_VARS
6345 #ifdef CONFIG_REG_VARS
6346 void add_var_ref(int t)
6348 printf("%s:%d: &%s\n",
6349 file->filename, file->line_num,
6350 get_tok_str(t, NULL));
6353 /* first pass on a function with heuristic to extract variable usage
6354 and pointer references to local variables for register allocation */
6355 void analyse_function(void)
6357 int level, t;
6359 for(;;) {
6360 if (tok == -1)
6361 break;
6362 /* any symbol coming after '&' is considered as being a
6363 variable whose reference is taken. It is highly unaccurate
6364 but it is difficult to do better without a complete parse */
6365 if (tok == '&') {
6366 next();
6367 /* if '& number', then no need to examine next tokens */
6368 if (tok == TOK_CINT ||
6369 tok == TOK_CUINT ||
6370 tok == TOK_CLLONG ||
6371 tok == TOK_CULLONG) {
6372 continue;
6373 } else if (tok >= TOK_UIDENT) {
6374 /* if '& ident [' or '& ident ->', then ident address
6375 is not needed */
6376 t = tok;
6377 next();
6378 if (tok != '[' && tok != TOK_ARROW)
6379 add_var_ref(t);
6380 } else {
6381 level = 0;
6382 while (tok != '}' && tok != ';' &&
6383 !((tok == ',' || tok == ')') && level == 0)) {
6384 if (tok >= TOK_UIDENT) {
6385 add_var_ref(tok);
6386 } else if (tok == '(') {
6387 level++;
6388 } else if (tok == ')') {
6389 level--;
6391 next();
6394 } else {
6395 next();
6399 #endif
6401 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6402 void decl(int l)
6404 int t, b, v, has_init, r;
6405 Sym *sym;
6406 AttributeDef ad;
6408 while (1) {
6409 if (!parse_btype(&b, &ad)) {
6410 /* skip redundant ';' */
6411 /* XXX: find more elegant solution */
6412 if (tok == ';') {
6413 next();
6414 continue;
6416 /* special test for old K&R protos without explicit int
6417 type. Only accepted when defining global data */
6418 if (l == VT_LOCAL || tok < TOK_DEFINE)
6419 break;
6420 b = VT_INT;
6422 if (((b & VT_BTYPE) == VT_ENUM ||
6423 (b & VT_BTYPE) == VT_STRUCT) &&
6424 tok == ';') {
6425 /* we accept no variable after */
6426 next();
6427 continue;
6429 while (1) { /* iterate thru each declaration */
6430 t = type_decl(&ad, &v, b, TYPE_DIRECT);
6431 #if 0
6433 char buf[500];
6434 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6435 printf("type = '%s'\n", buf);
6437 #endif
6438 if (tok == '{') {
6439 #ifdef CONFIG_REG_VARS
6440 TokenString func_str;
6441 ParseState saved_parse_state;
6442 int block_level;
6443 #endif
6445 if (l == VT_LOCAL)
6446 error("cannot use local functions");
6447 if (!(t & VT_FUNC))
6448 expect("function definition");
6450 #ifdef CONFIG_REG_VARS
6451 /* parse all function code and record it */
6453 tok_str_new(&func_str);
6455 block_level = 0;
6456 for(;;) {
6457 int t;
6458 if (tok == -1)
6459 error("unexpected end of file");
6460 tok_str_add_tok(&func_str);
6461 t = tok;
6462 next();
6463 if (t == '{') {
6464 block_level++;
6465 } else if (t == '}') {
6466 block_level--;
6467 if (block_level == 0)
6468 break;
6471 tok_str_add(&func_str, -1);
6472 tok_str_add(&func_str, 0);
6474 save_parse_state(&saved_parse_state);
6476 macro_ptr = func_str.str;
6477 next();
6478 analyse_function();
6479 #endif
6481 /* compute text section */
6482 cur_text_section = ad.section;
6483 if (!cur_text_section)
6484 cur_text_section = text_section;
6485 ind = cur_text_section->data_offset;
6486 funcname = get_tok_str(v, NULL);
6487 sym = sym_find(v);
6488 if (sym) {
6489 /* if symbol is already defined, then put complete type */
6490 sym->t = t;
6491 } else {
6492 /* put function symbol */
6493 sym = sym_push1(&global_stack, v, t, 0);
6495 /* NOTE: we patch the symbol size later */
6496 put_extern_sym(sym, cur_text_section, ind, 0);
6497 func_ind = ind;
6498 sym->r = VT_SYM | VT_CONST;
6499 /* put debug symbol */
6500 if (do_debug)
6501 put_func_debug(sym);
6502 /* push a dummy symbol to enable local sym storage */
6503 sym_push1(&local_stack, 0, 0, 0);
6504 gfunc_prolog(t);
6505 loc = 0;
6506 rsym = 0;
6507 #ifdef CONFIG_REG_VARS
6508 macro_ptr = func_str.str;
6509 next();
6510 #endif
6511 block(NULL, NULL, NULL, NULL, 0);
6512 gsym(rsym);
6513 gfunc_epilog();
6514 cur_text_section->data_offset = ind;
6515 sym_pop(&label_stack, NULL); /* reset label stack */
6516 sym_pop(&local_stack, NULL); /* reset local stack */
6517 /* end of function */
6518 /* patch symbol size */
6519 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
6520 ind - func_ind;
6521 if (do_debug) {
6522 put_stabn(N_FUN, 0, 0, ind - func_ind);
6524 funcname = ""; /* for safety */
6525 func_vt = VT_VOID; /* for safety */
6526 ind = 0; /* for safety */
6528 #ifdef CONFIG_REG_VARS
6529 tok_str_free(func_str.str);
6530 restore_parse_state(&saved_parse_state);
6531 #endif
6532 break;
6533 } else {
6534 if (b & VT_TYPEDEF) {
6535 /* save typedefed type */
6536 /* XXX: test storage specifiers ? */
6537 sym_push(v, t | VT_TYPEDEF, 0, 0);
6538 } else if ((t & VT_BTYPE) == VT_FUNC) {
6539 /* external function definition */
6540 external_sym(v, t, 0);
6541 } else {
6542 /* not lvalue if array */
6543 r = 0;
6544 if (!(t & VT_ARRAY))
6545 r |= lvalue_type(t);
6546 if (b & VT_EXTERN) {
6547 /* external variable */
6548 external_sym(v, t, r);
6549 } else {
6550 if (t & VT_STATIC)
6551 r |= VT_CONST;
6552 else
6553 r |= l;
6554 has_init = (tok == '=');
6555 if (has_init)
6556 next();
6557 decl_initializer_alloc(t, &ad, r,
6558 has_init, v, l);
6561 if (tok != ',') {
6562 skip(';');
6563 break;
6565 next();
6571 /* compile the C file opened in 'file'. Return non zero if errors. */
6572 static int tcc_compile(TCCState *s)
6574 Sym *define_start, *sym;
6575 char buf[512];
6576 int p, section_sym;
6578 funcname = "";
6579 include_stack_ptr = include_stack;
6580 ifdef_stack_ptr = ifdef_stack;
6582 /* XXX: not ANSI compliant: bound checking says error */
6583 vtop = vstack - 1;
6584 anon_sym = SYM_FIRST_ANOM;
6586 /* file info: full path + filename */
6587 section_sym = 0; /* avoid warning */
6588 if (do_debug) {
6589 section_sym = put_elf_sym(symtab_section, 0, 0,
6590 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
6591 text_section->sh_num, NULL);
6592 getcwd(buf, sizeof(buf));
6593 pstrcat(buf, sizeof(buf), "/");
6594 put_stabs_r(buf, N_SO, 0, 0,
6595 text_section->data_offset, text_section, section_sym);
6596 put_stabs_r(file->filename, N_SO, 0, 0,
6597 text_section->data_offset, text_section, section_sym);
6599 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6600 symbols can be safely used */
6601 put_elf_sym(symtab_section, 0, 0,
6602 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
6603 SHN_ABS, file->filename);
6605 /* define common 'char *' type because it is often used internally
6606 for arrays and struct dereference */
6607 char_pointer_type = mk_pointer(VT_BYTE);
6608 /* define an old type function 'int func()' */
6609 p = anon_sym++;
6610 sym = sym_push(p, 0, FUNC_CDECL, FUNC_OLD);
6611 func_old_type = VT_FUNC | (p << VT_STRUCT_SHIFT);
6612 #if 0
6613 /* define 'void *alloca(unsigned int)' builtin function */
6615 Sym *s1;
6617 p = anon_sym++;
6618 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
6619 s1 = sym_push(0, VT_UNSIGNED | VT_INT, 0, 0);
6620 s1->next = NULL;
6621 sym->next = s1;
6622 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
6624 #endif
6626 define_start = define_stack.top;
6627 inp();
6628 ch = '\n'; /* needed to parse correctly first preprocessor command */
6629 next();
6630 decl(VT_CONST);
6631 if (tok != -1)
6632 expect("declaration");
6634 /* end of translation unit info */
6635 if (do_debug) {
6636 put_stabs_r(NULL, N_SO, 0, 0,
6637 text_section->data_offset, text_section, section_sym);
6640 /* reset define stack, but leave -Dsymbols (may be incorrect if
6641 they are undefined) */
6642 sym_pop(&define_stack, define_start);
6644 sym_pop(&global_stack, NULL);
6646 return 0;
6649 int tcc_compile_string(TCCState *s, const char *str)
6651 BufferedFile bf1, *bf = &bf1;
6652 int ret;
6654 /* init file structure */
6655 bf->fd = -1;
6656 bf->buf_ptr = (char *)str;
6657 bf->buf_end = (char *)str + strlen(bf->buffer);
6658 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
6659 bf->line_num = 1;
6660 file = bf;
6662 ret = tcc_compile(s);
6664 /* currently, no need to close */
6665 return ret;
6668 /* define a symbol. A value can also be provided with the '=' operator */
6669 void tcc_define_symbol(TCCState *s, const char *sym, const char *value)
6671 BufferedFile bf1, *bf = &bf1;
6673 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
6674 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
6675 /* default value */
6676 if (!value)
6677 value = "1";
6678 pstrcat(bf->buffer, IO_BUF_SIZE, value);
6680 /* init file structure */
6681 bf->fd = -1;
6682 bf->buf_ptr = bf->buffer;
6683 bf->buf_end = bf->buffer + strlen(bf->buffer);
6684 bf->filename[0] = '\0';
6685 bf->line_num = 1;
6686 file = bf;
6688 include_stack_ptr = include_stack;
6690 /* parse with define parser */
6691 inp();
6692 ch = '\n'; /* needed to parse correctly first preprocessor command */
6693 next_nomacro();
6694 parse_define();
6695 file = NULL;
6698 void tcc_undefine_symbol(TCCState *s1, const char *sym)
6700 TokenSym *ts;
6701 Sym *s;
6702 ts = tok_alloc(sym, 0);
6703 s = sym_find1(&define_stack, tok);
6704 /* undefine symbol by putting an invalid name */
6705 if (s)
6706 sym_undef(&define_stack, s);
6709 #include "tccelf.c"
6711 /* print the position in the source file of PC value 'pc' by reading
6712 the stabs debug information */
6713 static void rt_printline(unsigned long wanted_pc)
6715 Stab_Sym *sym, *sym_end;
6716 char func_name[128], last_func_name[128];
6717 unsigned long func_addr, last_pc, pc;
6718 const char *incl_files[INCLUDE_STACK_SIZE];
6719 int incl_index, len, last_line_num, i;
6720 const char *str, *p;
6722 func_name[0] = '\0';
6723 func_addr = 0;
6724 incl_index = 0;
6725 last_func_name[0] = '\0';
6726 last_pc = 0xffffffff;
6727 last_line_num = 1;
6728 sym = (Stab_Sym *)stab_section->data + 1;
6729 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
6730 while (sym < sym_end) {
6731 switch(sym->n_type) {
6732 /* function start or end */
6733 case N_FUN:
6734 if (sym->n_strx == 0) {
6735 func_name[0] = '\0';
6736 func_addr = 0;
6737 } else {
6738 str = stabstr_section->data + sym->n_strx;
6739 p = strchr(str, ':');
6740 if (!p) {
6741 pstrcpy(func_name, sizeof(func_name), str);
6742 } else {
6743 len = p - str;
6744 if (len > sizeof(func_name) - 1)
6745 len = sizeof(func_name) - 1;
6746 memcpy(func_name, str, len);
6747 func_name[len] = '\0';
6749 func_addr = sym->n_value;
6751 break;
6752 /* line number info */
6753 case N_SLINE:
6754 pc = sym->n_value + func_addr;
6755 if (wanted_pc >= last_pc && wanted_pc < pc)
6756 goto found;
6757 last_pc = pc;
6758 last_line_num = sym->n_desc;
6759 /* XXX: slow! */
6760 strcpy(last_func_name, func_name);
6761 break;
6762 /* include files */
6763 case N_BINCL:
6764 str = stabstr_section->data + sym->n_strx;
6765 add_incl:
6766 if (incl_index < INCLUDE_STACK_SIZE) {
6767 incl_files[incl_index++] = str;
6769 break;
6770 case N_EINCL:
6771 if (incl_index > 1)
6772 incl_index--;
6773 break;
6774 case N_SO:
6775 if (sym->n_strx == 0) {
6776 incl_index = 0; /* end of translation unit */
6777 } else {
6778 str = stabstr_section->data + sym->n_strx;
6779 /* do not add path */
6780 len = strlen(str);
6781 if (len > 0 && str[len - 1] != '/')
6782 goto add_incl;
6784 break;
6786 sym++;
6788 /* did not find line number info: */
6789 fprintf(stderr, "(no debug info, pc=0x%08lx): ", wanted_pc);
6790 return;
6791 found:
6792 for(i = 0; i < incl_index - 1; i++)
6793 fprintf(stderr, "In file included from %s\n",
6794 incl_files[i]);
6795 if (incl_index > 0) {
6796 fprintf(stderr, "%s:%d: ",
6797 incl_files[incl_index - 1], last_line_num);
6799 if (last_func_name[0] != '\0') {
6800 fprintf(stderr, "in function '%s()': ", last_func_name);
6804 /* emit a run time error at position 'pc' */
6805 void rt_error(unsigned long pc, const char *fmt, ...)
6807 va_list ap;
6808 va_start(ap, fmt);
6810 rt_printline(pc);
6811 vfprintf(stderr, fmt, ap);
6812 fprintf(stderr, "\n");
6813 exit(255);
6814 va_end(ap);
6817 #ifndef WIN32
6818 /* signal handler for fatal errors */
6819 static void sig_error(int signum, siginfo_t *siginf, void *puc)
6821 struct ucontext *uc = puc;
6822 unsigned long pc;
6824 #ifdef __i386__
6825 pc = uc->uc_mcontext.gregs[14];
6826 #else
6827 #error please put the right sigcontext field
6828 #endif
6830 switch(signum) {
6831 case SIGFPE:
6832 switch(siginf->si_code) {
6833 case FPE_INTDIV:
6834 case FPE_FLTDIV:
6835 rt_error(pc, "division by zero");
6836 break;
6837 default:
6838 rt_error(pc, "floating point exception");
6839 break;
6841 break;
6842 case SIGBUS:
6843 case SIGSEGV:
6844 rt_error(pc, "dereferencing invalid pointer");
6845 break;
6846 case SIGILL:
6847 rt_error(pc, "illegal instruction");
6848 break;
6849 case SIGABRT:
6850 rt_error(pc, "abort() called");
6851 break;
6852 default:
6853 rt_error(pc, "caught signal %d", signum);
6854 break;
6856 exit(255);
6858 #endif
6860 /* launch the compiled program with the given arguments */
6861 int tcc_run(TCCState *s1, int argc, char **argv)
6863 Section *s;
6864 int (*prog_main)(int, char **);
6865 int i;
6867 tcc_add_runtime(s1);
6869 relocate_common_syms();
6871 /* compute relocation address : section are relocated in place. We
6872 also alloc the bss space */
6873 for(i = 1; i < nb_sections; i++) {
6874 s = sections[i];
6875 if (s->sh_flags & SHF_ALLOC) {
6876 void *data;
6877 if (s->sh_type == SHT_NOBITS) {
6878 data = tcc_mallocz(s->data_offset);
6879 } else {
6880 data = s->data;
6882 s->sh_addr = (unsigned long)data;
6886 relocate_syms(1);
6888 /* relocate each section */
6889 for(i = 1; i < nb_sections; i++) {
6890 s = sections[i];
6891 if (s->reloc)
6892 relocate_section(s1, s);
6895 prog_main = (void *)get_elf_sym_val("main");
6897 if (do_debug) {
6898 #ifdef WIN32
6899 error("debug mode currently not available for Windows");
6900 #else
6901 struct sigaction sigact;
6902 /* install TCC signal handlers to print debug info on fatal
6903 runtime errors */
6904 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
6905 sigact.sa_sigaction = sig_error;
6906 sigemptyset(&sigact.sa_mask);
6907 sigaction(SIGFPE, &sigact, NULL);
6908 sigaction(SIGILL, &sigact, NULL);
6909 sigaction(SIGSEGV, &sigact, NULL);
6910 sigaction(SIGBUS, &sigact, NULL);
6911 sigaction(SIGABRT, &sigact, NULL);
6912 #endif
6915 #ifdef CONFIG_TCC_BCHECK
6916 if (do_bounds_check) {
6917 void (*bound_init)(void);
6918 void **bound_error_func;
6920 /* set error function */
6921 bound_error_func = (void **)get_elf_sym_val("__bound_error_func");
6922 *bound_error_func = rt_error;
6924 /* XXX: use .init section so that it also work in binary ? */
6925 bound_init = (void *)get_elf_sym_val("__bound_init");
6926 bound_init();
6928 #endif
6929 return (*prog_main)(argc, argv);
6932 TCCState *tcc_new(void)
6934 char *p, *r;
6935 TCCState *s;
6937 s = tcc_malloc(sizeof(TCCState));
6938 if (!s)
6939 return NULL;
6940 s->output_type = TCC_OUTPUT_MEMORY;
6942 /* default include paths */
6943 tcc_add_sysinclude_path(s, "/usr/local/include");
6944 tcc_add_sysinclude_path(s, "/usr/include");
6945 tcc_add_sysinclude_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
6947 /* add all tokens */
6948 tok_ident = TOK_IDENT;
6949 p = tcc_keywords;
6950 while (*p) {
6951 r = p;
6952 while (*r++);
6953 tok_alloc(p, r - p - 1);
6954 p = r;
6957 /* we add dummy defines for some special macros to speed up tests
6958 and to have working defined() */
6959 sym_push1(&define_stack, TOK___LINE__, MACRO_OBJ, 0);
6960 sym_push1(&define_stack, TOK___FILE__, MACRO_OBJ, 0);
6961 sym_push1(&define_stack, TOK___DATE__, MACRO_OBJ, 0);
6962 sym_push1(&define_stack, TOK___TIME__, MACRO_OBJ, 0);
6964 /* standard defines */
6965 tcc_define_symbol(s, "__STDC__", NULL);
6966 #if defined(TCC_TARGET_I386)
6967 tcc_define_symbol(s, "__i386__", NULL);
6968 #endif
6969 #if defined(linux)
6970 tcc_define_symbol(s, "linux", NULL);
6971 #endif
6972 /* tiny C specific defines */
6973 tcc_define_symbol(s, "__TINYC__", NULL);
6975 /* default library paths */
6976 tcc_add_library_path(s, "/usr/local/lib");
6977 tcc_add_library_path(s, "/usr/lib");
6978 tcc_add_library_path(s, "/lib");
6980 /* no section zero */
6981 dynarray_add((void ***)&sections, &nb_sections, NULL);
6983 /* create standard sections */
6984 text_section = new_section(".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
6985 data_section = new_section(".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
6986 bss_section = new_section(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
6988 /* symbols are always generated for linking stage */
6989 symtab_section = new_symtab(".symtab", SHT_SYMTAB, 0,
6990 ".strtab",
6991 ".hashtab", SHF_PRIVATE);
6992 strtab_section = symtab_section->link;
6994 /* private symbol table for dynamic symbols */
6995 dynsymtab_section = new_symtab(".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
6996 ".dynstrtab",
6997 ".dynhashtab", SHF_PRIVATE);
6998 return s;
7001 void tcc_delete(TCCState *s)
7003 tcc_free(s);
7006 int tcc_add_include_path(TCCState *s, const char *pathname)
7008 char *pathname1;
7010 pathname1 = tcc_strdup(pathname);
7011 dynarray_add((void ***)&include_paths, &nb_include_paths, pathname1);
7012 return 0;
7015 int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
7017 char *pathname1;
7019 pathname1 = tcc_strdup(pathname);
7020 dynarray_add((void ***)&sysinclude_paths, &nb_sysinclude_paths, pathname1);
7021 return 0;
7024 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags)
7026 const char *ext;
7027 Elf32_Ehdr ehdr;
7028 int fd;
7029 BufferedFile *saved_file;
7031 /* find source file type with extension */
7032 ext = strrchr(filename, '.');
7033 if (ext)
7034 ext++;
7036 /* open the file */
7037 saved_file = file;
7038 file = tcc_open(filename);
7039 if (!file) {
7040 if (flags & AFF_PRINT_ERROR) {
7041 error("file '%s' not found", filename);
7042 } else {
7043 file = saved_file;
7044 return -1;
7048 if (!ext || !strcmp(ext, "c")) {
7049 /* C file assumed */
7050 tcc_compile(s);
7051 } else {
7052 fd = file->fd;
7053 /* assume executable format: auto guess file type */
7054 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
7055 error("could not read header");
7056 lseek(fd, 0, SEEK_SET);
7058 if (ehdr.e_ident[0] == ELFMAG0 &&
7059 ehdr.e_ident[1] == ELFMAG1 &&
7060 ehdr.e_ident[2] == ELFMAG2 &&
7061 ehdr.e_ident[3] == ELFMAG3) {
7062 file->line_num = 0; /* do not display line number if error */
7063 if (ehdr.e_type == ET_REL) {
7064 tcc_load_object_file(s, fd, 0);
7065 } else if (ehdr.e_type == ET_DYN) {
7066 tcc_load_dll(s, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
7067 } else {
7068 error("unrecognized ELF file");
7070 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
7071 file->line_num = 0; /* do not display line number if error */
7072 tcc_load_archive(s, fd);
7073 } else {
7074 /* as GNU ld, consider it is an ld script if not recognized */
7075 if (tcc_load_ldscript(s) < 0)
7076 error("unrecognized file type");
7079 tcc_close(file);
7080 file = saved_file;
7081 return 0;
7084 void tcc_add_file(TCCState *s, const char *filename)
7086 tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
7089 int tcc_add_library_path(TCCState *s, const char *pathname)
7091 char *pathname1;
7093 pathname1 = tcc_strdup(pathname);
7094 dynarray_add((void ***)&library_paths, &nb_library_paths, pathname1);
7095 return 0;
7098 /* find and load a dll. Return non zero if not found */
7099 /* XXX: add '-rpath' option support ? */
7100 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
7102 char buf[1024];
7103 int i;
7105 for(i = 0; i < nb_library_paths; i++) {
7106 snprintf(buf, sizeof(buf), "%s/%s",
7107 library_paths[i], filename);
7108 if (tcc_add_file_internal(s, buf, flags) == 0)
7109 return 0;
7111 return -1;
7114 /* the library name is the same as the argument of the '-l' option */
7115 int tcc_add_library(TCCState *s, const char *libraryname)
7117 char buf[1024];
7118 int i;
7119 void *h;
7121 /* first we look for the dynamic library if not static linking */
7122 if (!static_link) {
7123 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
7124 /* if we output to memory, then we simply we dlopen(). */
7125 if (s->output_type == TCC_OUTPUT_MEMORY) {
7126 /* Since the libc is already loaded, we don't need to load it again */
7127 if (!strcmp(libraryname, "c"))
7128 return 0;
7129 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
7130 if (h)
7131 return 0;
7132 } else {
7133 if (tcc_add_dll(s, buf, 0) == 0)
7134 return 0;
7138 /* then we look for the static library */
7139 for(i = 0; i < nb_library_paths; i++) {
7140 snprintf(buf, sizeof(buf), "%s/lib%s.a",
7141 library_paths[i], libraryname);
7142 if (tcc_add_file_internal(s, buf, 0) == 0)
7143 return 0;
7145 return -1;
7148 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
7150 add_elf_sym(symtab_section, val, 0,
7151 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7152 SHN_ABS, name);
7153 return 0;
7156 int tcc_set_output_type(TCCState *s, int output_type)
7158 s->output_type = output_type;
7160 /* if bound checking, then add corresponding sections */
7161 #ifdef CONFIG_TCC_BCHECK
7162 if (do_bounds_check) {
7163 /* define symbol */
7164 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
7165 /* create bounds sections */
7166 bounds_section = new_section(".bounds",
7167 SHT_PROGBITS, SHF_ALLOC);
7168 lbounds_section = new_section(".lbounds",
7169 SHT_PROGBITS, SHF_ALLOC);
7171 #endif
7173 /* add debug sections */
7174 if (do_debug) {
7175 /* stab symbols */
7176 stab_section = new_section(".stab", SHT_PROGBITS, 0);
7177 stab_section->sh_entsize = sizeof(Stab_Sym);
7178 stabstr_section = new_section(".stabstr", SHT_STRTAB, 0);
7179 put_elf_str(stabstr_section, "");
7180 stab_section->link = stabstr_section;
7181 /* put first entry */
7182 put_stabs("", 0, 0, 0, 0);
7185 /* add libc crt1/crti objects */
7186 if (output_type == TCC_OUTPUT_EXE ||
7187 output_type == TCC_OUTPUT_DLL) {
7188 if (output_type != TCC_OUTPUT_DLL)
7189 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
7190 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
7192 return 0;
7195 #if !defined(LIBTCC)
7197 void help(void)
7199 printf("tcc version 0.9.11 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7200 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7201 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
7202 " [--] infile1 [infile2... --] [infile_args...]\n"
7203 "\n"
7204 "General options:\n"
7205 " -c compile only - generate an object file\n"
7206 " -o outfile set output filename\n"
7207 " -- allows multiples input files if no -o option given. Also\n"
7208 " separate input files from runtime arguments\n"
7209 " -Bdir set tcc internal library path\n"
7210 " -bench output compilation statistics\n"
7211 "Preprocessor options:\n"
7212 " -Idir add include path 'dir'\n"
7213 " -Dsym[=val] define 'sym' with value 'val'\n"
7214 " -Usym undefine 'sym'\n"
7215 "C compiler options:\n"
7216 " -g generate runtime debug info\n"
7217 #ifdef CONFIG_TCC_BCHECK
7218 " -b compile with built-in memory and bounds checker (implies -g)\n"
7219 #endif
7220 "Linker options:\n"
7221 " -Ldir add library path 'dir'\n"
7222 " -llib link with dynamic or static library 'lib'\n"
7223 " -shared generate a shared library\n"
7224 " -static static linking\n"
7225 " -r relocatable output\n"
7229 int main(int argc, char **argv)
7231 char *r, *outfile;
7232 int optind, output_type, multiple_files, i, reloc_output;
7233 TCCState *s;
7234 char **files;
7235 int nb_files, nb_libraries, nb_objfiles;
7236 char objfilename[1024];
7238 s = tcc_new();
7239 output_type = TCC_OUTPUT_MEMORY;
7241 optind = 1;
7242 outfile = NULL;
7243 multiple_files = 0;
7244 files = NULL;
7245 nb_files = 0;
7246 nb_libraries = 0;
7247 reloc_output = 0;
7248 while (1) {
7249 if (optind >= argc) {
7250 if (nb_files == 0)
7251 goto show_help;
7252 else
7253 break;
7255 r = argv[optind++];
7256 if (r[0] != '-') {
7257 /* add a new file */
7258 dynarray_add((void ***)&files, &nb_files, r);
7259 if (!multiple_files) {
7260 optind--;
7261 /* argv[0] will be this file */
7262 break;
7264 } else if (r[1] == '-') {
7265 /* '--' enables multiple files input and also ends several file input */
7266 if (multiple_files) {
7267 optind--; /* argv[0] will be '--' */
7268 break;
7270 multiple_files = 1;
7271 } else if (r[1] == 'h' || r[1] == '?') {
7272 show_help:
7273 help();
7274 return 1;
7275 } else if (r[1] == 'I') {
7276 if (tcc_add_include_path(s, r + 2) < 0)
7277 error("too many include paths");
7278 } else if (r[1] == 'D') {
7279 char *sym, *value;
7280 sym = r + 2;
7281 value = strchr(sym, '=');
7282 if (value) {
7283 *value = '\0';
7284 value++;
7286 tcc_define_symbol(s, sym, value);
7287 } else if (r[1] == 'U') {
7288 tcc_undefine_symbol(s, r + 2);
7289 } else if (r[1] == 'L') {
7290 tcc_add_library_path(s, r + 2);
7291 } else if (r[1] == 'B') {
7292 /* set tcc utilities path (mainly for tcc development) */
7293 tcc_lib_path = r + 2;
7294 } else if (r[1] == 'l') {
7295 dynarray_add((void ***)&files, &nb_files, r);
7296 nb_libraries++;
7297 } else if (!strcmp(r + 1, "bench")) {
7298 do_bench = 1;
7299 } else
7300 #ifdef CONFIG_TCC_BCHECK
7301 if (r[1] == 'b') {
7302 do_bounds_check = 1;
7303 do_debug = 1;
7304 } else
7305 #endif
7306 if (r[1] == 'g') {
7307 do_debug = 1;
7308 } else if (r[1] == 'c') {
7309 multiple_files = 1;
7310 output_type = TCC_OUTPUT_OBJ;
7311 } else if (!strcmp(r + 1, "static")) {
7312 static_link = 1;
7313 } else if (!strcmp(r + 1, "shared")) {
7314 output_type = TCC_OUTPUT_DLL;
7315 } else if (r[1] == 'o') {
7316 if (optind >= argc)
7317 goto show_help;
7318 multiple_files = 1;
7319 outfile = argv[optind++];
7320 } else if (r[1] == 'r') {
7321 /* generate a .o merging several output files */
7322 reloc_output = 1;
7323 output_type = TCC_OUTPUT_OBJ;
7324 } else {
7325 error("invalid option -- '%s'", r);
7329 nb_objfiles = nb_files - nb_libraries;
7331 /* if outfile provided without other options, we output an
7332 executable */
7333 if (outfile && output_type == TCC_OUTPUT_MEMORY)
7334 output_type = TCC_OUTPUT_EXE;
7336 /* check -c consistency : only single file handled. XXX: checks file type */
7337 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
7338 /* accepts only a single input file */
7339 if (nb_objfiles != 1)
7340 error("cannot specify multiple files with -c");
7341 if (nb_libraries != 0)
7342 error("cannot specify libraries with -c");
7345 /* compute default outfile name */
7346 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
7347 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
7348 char *ext;
7349 /* add .o extension */
7350 pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
7351 ext = strrchr(objfilename, '.');
7352 if (!ext)
7353 goto default_outfile;
7354 strcpy(ext + 1, "o");
7355 } else {
7356 default_outfile:
7357 pstrcpy(objfilename, sizeof(objfilename), "a.out");
7359 outfile = objfilename;
7362 tcc_set_output_type(s, output_type);
7364 /* compile or add each files or library */
7365 for(i = 0;i < nb_files; i++) {
7366 const char *filename;
7368 filename = files[i];
7369 if (filename[0] == '-') {
7370 if (tcc_add_library(s, filename + 2) < 0)
7371 error("cannot find %s", filename);
7372 } else {
7373 tcc_add_file(s, filename);
7377 if (do_bench) {
7378 printf("total: %d idents, %d lines, %d bytes\n",
7379 tok_ident - TOK_IDENT, total_lines, total_bytes);
7380 #ifdef MEM_DEBUG
7381 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
7382 #endif
7385 if (s->output_type != TCC_OUTPUT_MEMORY) {
7386 tcc_output_file(s, outfile);
7387 return 0;
7388 } else {
7389 return tcc_run(s, argc - optind, argv + optind);
7393 #endif