sizeof/alignof/typeof tests
[tinycc/miki.git] / tcc.c
blobb690d2306a99df50c007269b67fb40fe4e89bfd1
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <math.h>
26 #include <unistd.h>
27 #include <signal.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <setjmp.h>
31 #ifndef WIN32
32 #include <sys/ucontext.h>
33 #endif
34 #include "elf.h"
35 #include "stab.h"
36 #ifndef CONFIG_TCC_STATIC
37 #include <dlfcn.h>
38 #endif
40 #include "libtcc.h"
42 //#define DEBUG
43 /* preprocessor debug */
44 //#define PP_DEBUG
45 /* include file debug */
46 //#define INC_DEBUG
48 //#define MEM_DEBUG
50 /* target selection */
51 //#define TCC_TARGET_I386 /* i386 code generator */
52 //#define TCC_TARGET_IL /* .NET CLI generator */
54 /* default target is I386 */
55 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
56 #define TCC_TARGET_I386
57 #endif
59 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
60 #define CONFIG_TCC_BCHECK /* enable bound checking code */
61 #endif
63 #ifndef CONFIG_TCC_PREFIX
64 #define CONFIG_TCC_PREFIX "/usr/local"
65 #endif
67 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
68 executables or dlls */
69 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
71 #define INCLUDE_STACK_SIZE 32
72 #define IFDEF_STACK_SIZE 64
73 #define VSTACK_SIZE 64
74 #define STRING_MAX_SIZE 1024
76 #define TOK_HASH_SIZE 2048 /* must be a power of two */
77 #define TOK_ALLOC_INCR 512 /* must be a power of two */
78 #define SYM_HASH_SIZE 1031
80 /* token symbol management */
81 typedef struct TokenSym {
82 struct TokenSym *hash_next;
83 int tok; /* token number */
84 int len;
85 char str[1];
86 } TokenSym;
88 typedef struct CString {
89 int size; /* size in bytes */
90 void *data; /* either 'char *' or 'int *' */
91 int size_allocated;
92 void *data_allocated; /* if non NULL, data has been malloced */
93 } CString;
95 /* constant value */
96 typedef union CValue {
97 long double ld;
98 double d;
99 float f;
100 int i;
101 unsigned int ui;
102 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
103 long long ll;
104 unsigned long long ull;
105 struct CString *cstr;
106 void *ptr;
107 int tab[1];
108 } CValue;
110 /* value on stack */
111 typedef struct SValue {
112 int t; /* type */
113 unsigned short r; /* register + flags */
114 unsigned short r2; /* second register, used for 'long long'
115 type. If not used, set to VT_CONST */
116 CValue c; /* constant, if VT_CONST */
117 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
118 } SValue;
120 /* symbol management */
121 typedef struct Sym {
122 int v; /* symbol token */
123 int t; /* associated type */
124 int r; /* associated register */
125 int c; /* associated number */
126 struct Sym *next; /* next related symbol */
127 struct Sym *prev; /* prev symbol in stack */
128 struct Sym *hash_next; /* next symbol in hash table */
129 } Sym;
131 typedef struct SymStack {
132 struct Sym *top;
133 struct Sym *hash[SYM_HASH_SIZE];
134 } SymStack;
136 /* section definition */
137 /* XXX: use directly ELF structure for parameters ? */
138 /* special flag to indicate that the section should not be linked to
139 the other ones */
140 #define SHF_PRIVATE 0x80000000
142 typedef struct Section {
143 unsigned long data_offset; /* current data offset */
144 unsigned char *data; /* section data */
145 unsigned long data_allocated; /* used for realloc() handling */
146 int sh_name; /* elf section name (only used during output) */
147 int sh_num; /* elf section number */
148 int sh_type; /* elf section type */
149 int sh_flags; /* elf section flags */
150 int sh_info; /* elf section info */
151 int sh_addralign; /* elf section alignment */
152 int sh_entsize; /* elf entry size */
153 unsigned long sh_size; /* section size (only used during output) */
154 unsigned long sh_addr; /* address at which the section is relocated */
155 unsigned long sh_offset; /* address at which the section is relocated */
156 int nb_hashed_syms; /* used to resize the hash table */
157 struct Section *link; /* link to another section */
158 struct Section *reloc; /* corresponding section for relocation, if any */
159 struct Section *hash; /* hash table for symbols */
160 struct Section *next;
161 char name[64]; /* section name */
162 } Section;
164 typedef struct DLLReference {
165 int level;
166 char name[1];
167 } DLLReference;
169 /* GNUC attribute definition */
170 typedef struct AttributeDef {
171 int aligned;
172 Section *section;
173 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
174 } AttributeDef;
176 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
177 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
178 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
180 /* stored in 'Sym.c' field */
181 #define FUNC_NEW 1 /* ansi function prototype */
182 #define FUNC_OLD 2 /* old function prototype */
183 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
185 /* stored in 'Sym.r' field */
186 #define FUNC_CDECL 0 /* standard c call */
187 #define FUNC_STDCALL 1 /* pascal c call */
189 /* field 'Sym.t' for macros */
190 #define MACRO_OBJ 0 /* object like macro */
191 #define MACRO_FUNC 1 /* function like macro */
193 /* field 'Sym.t' for labels */
194 #define LABEL_FORWARD 1 /* label is forward defined */
196 /* type_decl() types */
197 #define TYPE_ABSTRACT 1 /* type without variable */
198 #define TYPE_DIRECT 2 /* type with variable */
200 #define IO_BUF_SIZE 8192
202 typedef struct BufferedFile {
203 unsigned char *buf_ptr;
204 unsigned char *buf_end;
205 int fd;
206 int line_num; /* current line number - here to simply code */
207 int ifndef_macro; /*'#ifndef macro \n #define macro' search */
208 int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
209 char inc_type; /* type of include */
210 char inc_filename[512]; /* filename specified by the user */
211 char filename[1024]; /* current filename - here to simplify code */
212 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
213 } BufferedFile;
215 #define CH_EOB 0 /* end of buffer or '\0' char in file */
216 #define CH_EOF (-1) /* end of file */
218 /* parsing state (used to save parser state to reparse part of the
219 source several times) */
220 typedef struct ParseState {
221 int *macro_ptr;
222 int line_num;
223 int tok;
224 CValue tokc;
225 } ParseState;
227 /* used to record tokens */
228 typedef struct TokenString {
229 int *str;
230 int len;
231 int last_line_num;
232 } TokenString;
234 /* include file cache, used to find files faster and also to eliminate
235 inclusion if the include file is protected by #ifndef ... #endif */
236 typedef struct CachedInclude {
237 int ifndef_macro;
238 char type; /* '"' or '>' to give include type */
239 char filename[1]; /* path specified in #include */
240 } CachedInclude;
242 /* parser */
243 struct BufferedFile *file;
244 int ch, ch1, tok, tok1;
245 CValue tokc, tok1c;
246 CString tokcstr; /* current parsed string, if any */
247 /* if true, line feed is returned as a token. line feed is also
248 returned at eof */
249 int return_linefeed;
250 /* set to TRUE if eof was reached */
251 int eof_seen;
252 Section *text_section, *data_section, *bss_section; /* predefined sections */
253 Section *cur_text_section; /* current section where function code is
254 generated */
255 /* bound check related sections */
256 Section *bounds_section; /* contains global data bound description */
257 Section *lbounds_section; /* contains local data bound description */
258 /* symbol sections */
259 Section *symtab_section, *strtab_section;
261 /* debug sections */
262 Section *stab_section, *stabstr_section;
264 /* loc : local variable index
265 ind : output code index
266 rsym: return symbol
267 anon_sym: anonymous symbol index
269 int rsym, anon_sym,
270 prog, ind, loc;
271 /* expression generation modifiers */
272 int const_wanted; /* true if constant wanted */
273 int nocode_wanted; /* true if no code generation wanted for an expression */
274 int global_expr; /* true if compound literals must be allocated
275 globally (used during initializers parsing */
276 int func_vt, func_vc; /* current function return type (used by
277 return instruction) */
278 int last_line_num, last_ind, func_ind; /* debug last line number and pc */
279 int tok_ident;
280 TokenSym **table_ident;
281 TokenSym *hash_ident[TOK_HASH_SIZE];
282 char token_buf[STRING_MAX_SIZE + 1];
283 char *funcname;
284 SymStack define_stack, global_stack, local_stack, label_stack;
286 SValue vstack[VSTACK_SIZE], *vtop;
287 int *macro_ptr, *macro_ptr_allocated;
288 int char_pointer_type;
289 int func_old_type;
291 /* compile with debug symbol (and use them if error during execution) */
292 int do_debug = 0;
294 /* compile with built-in memory and bounds checker */
295 int do_bounds_check = 0;
297 /* display benchmark infos */
298 int do_bench = 0;
299 int total_lines;
300 int total_bytes;
302 /* use GNU C extensions */
303 int gnu_ext = 1;
305 /* use Tiny C extensions */
306 int tcc_ext = 1;
308 /* XXX: suppress that ASAP */
309 static struct TCCState *tcc_state;
311 /* give the path of the tcc libraries */
312 static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc";
314 struct TCCState {
315 int output_type;
317 BufferedFile **include_stack_ptr;
318 int *ifdef_stack_ptr;
320 /* include file handling */
321 char **include_paths;
322 int nb_include_paths;
323 char **sysinclude_paths;
324 int nb_sysinclude_paths;
325 CachedInclude **cached_includes;
326 int nb_cached_includes;
328 char **library_paths;
329 int nb_library_paths;
331 /* array of all loaded dlls (including those referenced by loaded
332 dlls) */
333 DLLReference **loaded_dlls;
334 int nb_loaded_dlls;
336 /* sections */
337 Section **sections;
338 int nb_sections; /* number of sections, including first dummy section */
340 /* got handling */
341 Section *got;
342 unsigned long *got_offsets;
343 int nb_got_offsets;
344 int nb_plt_entries;
345 /* give the correspondance from symtab indexes to dynsym indexes */
346 int *symtab_to_dynsym;
348 /* temporary dynamic symbol sections (for dll loading) */
349 Section *dynsymtab_section;
350 /* exported dynamic symbol section */
351 Section *dynsym;
353 /* if true, static linking is performed */
354 int static_link;
356 /* error handling */
357 void *error_opaque;
358 void (*error_func)(void *opaque, const char *msg);
359 int error_set_jmp_enabled;
360 jmp_buf error_jmp_buf;
361 int nb_errors;
363 /* see include_stack_ptr */
364 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
366 /* see ifdef_stack_ptr */
367 int ifdef_stack[IFDEF_STACK_SIZE];
370 /* The current value can be: */
371 #define VT_VALMASK 0x00ff
372 #define VT_CONST 0x00f0 /* constant in vc
373 (must be first non register value) */
374 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
375 #define VT_LOCAL 0x00f2 /* offset on stack */
376 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
377 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
378 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
379 #define VT_LVAL 0x0100 /* var is an lvalue */
380 #define VT_SYM 0x0200 /* a symbol value is added */
381 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
382 char/short stored in integer registers) */
383 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
384 dereferencing value */
385 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
386 bounding function call point is in vc */
387 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
388 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
389 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
390 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
392 /* types */
393 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
395 #define VT_INT 0 /* integer type */
396 #define VT_BYTE 1 /* signed byte type */
397 #define VT_SHORT 2 /* short type */
398 #define VT_VOID 3 /* void type */
399 #define VT_PTR 4 /* pointer */
400 #define VT_ENUM 5 /* enum definition */
401 #define VT_FUNC 6 /* function type */
402 #define VT_STRUCT 7 /* struct/union definition */
403 #define VT_FLOAT 8 /* IEEE float */
404 #define VT_DOUBLE 9 /* IEEE double */
405 #define VT_LDOUBLE 10 /* IEEE long double */
406 #define VT_BOOL 11 /* ISOC99 boolean type */
407 #define VT_LLONG 12 /* 64 bit integer */
408 #define VT_LONG 13 /* long integer (NEVER USED as type, only
409 during parsing) */
410 #define VT_BTYPE 0x000f /* mask for basic type */
411 #define VT_UNSIGNED 0x0010 /* unsigned type */
412 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
413 #define VT_BITFIELD 0x0040 /* bitfield modifier */
415 /* storage */
416 #define VT_EXTERN 0x00000080 /* extern definition */
417 #define VT_STATIC 0x00000100 /* static variable */
418 #define VT_TYPEDEF 0x00000200 /* typedef definition */
420 /* type mask (except storage) */
421 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
423 /* token values */
425 /* warning: the following compare tokens depend on i386 asm code */
426 #define TOK_ULT 0x92
427 #define TOK_UGE 0x93
428 #define TOK_EQ 0x94
429 #define TOK_NE 0x95
430 #define TOK_ULE 0x96
431 #define TOK_UGT 0x97
432 #define TOK_LT 0x9c
433 #define TOK_GE 0x9d
434 #define TOK_LE 0x9e
435 #define TOK_GT 0x9f
437 #define TOK_LAND 0xa0
438 #define TOK_LOR 0xa1
440 #define TOK_DEC 0xa2
441 #define TOK_MID 0xa3 /* inc/dec, to void constant */
442 #define TOK_INC 0xa4
443 #define TOK_UDIV 0xb0 /* unsigned division */
444 #define TOK_UMOD 0xb1 /* unsigned modulo */
445 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
446 #define TOK_CINT 0xb3 /* number in tokc */
447 #define TOK_CCHAR 0xb4 /* char constant in tokc */
448 #define TOK_STR 0xb5 /* pointer to string in tokc */
449 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
450 #define TOK_LCHAR 0xb7
451 #define TOK_LSTR 0xb8
452 #define TOK_CFLOAT 0xb9 /* float constant */
453 #define TOK_LINENUM 0xba /* line number info */
454 #define TOK_CDOUBLE 0xc0 /* double constant */
455 #define TOK_CLDOUBLE 0xc1 /* long double constant */
456 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
457 #define TOK_ADDC1 0xc3 /* add with carry generation */
458 #define TOK_ADDC2 0xc4 /* add with carry use */
459 #define TOK_SUBC1 0xc5 /* add with carry generation */
460 #define TOK_SUBC2 0xc6 /* add with carry use */
461 #define TOK_CUINT 0xc8 /* unsigned int constant */
462 #define TOK_CLLONG 0xc9 /* long long constant */
463 #define TOK_CULLONG 0xca /* unsigned long long constant */
464 #define TOK_ARROW 0xcb
465 #define TOK_DOTS 0xcc /* three dots */
466 #define TOK_SHR 0xcd /* unsigned shift right */
467 #define TOK_PPNUM 0xce /* preprocessor number */
469 #define TOK_SHL 0x01 /* shift left */
470 #define TOK_SAR 0x02 /* signed shift right */
472 /* assignement operators : normal operator or 0x80 */
473 #define TOK_A_MOD 0xa5
474 #define TOK_A_AND 0xa6
475 #define TOK_A_MUL 0xaa
476 #define TOK_A_ADD 0xab
477 #define TOK_A_SUB 0xad
478 #define TOK_A_DIV 0xaf
479 #define TOK_A_XOR 0xde
480 #define TOK_A_OR 0xfc
481 #define TOK_A_SHL 0x81
482 #define TOK_A_SAR 0x82
484 /* WARNING: the content of this string encodes token numbers */
485 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";
487 #define TOK_EOF (-1) /* end of file */
488 #define TOK_LINEFEED 10 /* line feed */
490 /* all identificators and strings have token above that */
491 #define TOK_IDENT 256
493 enum {
494 TOK_LAST = TOK_IDENT - 1,
495 #define DEF(id, str) id,
496 #include "tcctok.h"
497 #undef DEF
500 static const char *tcc_keywords =
501 #define DEF(id, str) str "\0"
502 #include "tcctok.h"
503 #undef DEF
506 #define TOK_UIDENT TOK_DEFINE
508 #ifdef WIN32
509 #define snprintf _snprintf
510 #endif
512 #if defined(WIN32) || defined(TCC_UCLIBC)
513 /* currently incorrect */
514 long double strtold(const char *nptr, char **endptr)
516 return (long double)strtod(nptr, endptr);
518 float strtof(const char *nptr, char **endptr)
520 return (float)strtod(nptr, endptr);
522 #else
523 /* XXX: need to define this to use them in non ISOC99 context */
524 extern float strtof (const char *__nptr, char **__endptr);
525 extern long double strtold (const char *__nptr, char **__endptr);
526 #endif
528 static char *pstrcpy(char *buf, int buf_size, const char *s);
529 static char *pstrcat(char *buf, int buf_size, const char *s);
531 static void sum(int l);
532 static void next(void);
533 static void next_nomacro(void);
534 static int parse_expr_type(void);
535 static int expr_type(void);
536 static int unary_type(void);
537 static int expr_const(void);
538 static void expr_eq(void);
539 static void gexpr(void);
540 static void decl(int l);
541 static void decl_initializer(int t, Section *sec, unsigned long c,
542 int first, int size_only);
543 static void decl_initializer_alloc(int t, AttributeDef *ad, int r,
544 int has_init, int v, int scope);
545 int gv(int rc);
546 void gv2(int rc1, int rc2);
547 void move_reg(int r, int s);
548 void save_regs(int n);
549 void save_reg(int r);
550 void vpop(void);
551 void vswap(void);
552 void vdup(void);
553 int get_reg(int rc);
555 static void macro_subst(TokenString *tok_str,
556 Sym **nested_list, int *macro_str);
557 int save_reg_forced(int r);
558 void gen_op(int op);
559 void force_charshort_cast(int t);
560 void gen_cast(int t);
561 void vstore(void);
562 Sym *sym_find(int v);
563 Sym *sym_push(int v, int t, int r, int c);
565 /* type handling */
566 int type_size(int t, int *a);
567 int pointed_type(int t);
568 int pointed_size(int t);
569 static int lvalue_type(int t);
570 int is_compatible_types(int t1, int t2);
571 int parse_btype(int *type_ptr, AttributeDef *ad);
572 int type_decl(AttributeDef *ad, int *v, int t, int td);
574 void error(const char *fmt, ...);
575 void rt_error(unsigned long pc, const char *fmt, ...);
576 void vpushi(int v);
577 void vset(int t, int r, int v);
578 void type_to_str(char *buf, int buf_size,
579 int t, const char *varstr);
580 char *get_tok_str(int v, CValue *cv);
581 static Sym *get_sym_ref(int t, Section *sec,
582 unsigned long offset, unsigned long size);
583 static Sym *external_global_sym(int v, int u, int r);
585 /* section generation */
586 static void section_realloc(Section *sec, unsigned long new_size);
587 static void *section_ptr_add(Section *sec, unsigned long size);
588 static void put_extern_sym(Sym *sym, Section *section,
589 unsigned long value, unsigned long size);
590 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
591 static int put_elf_str(Section *s, const char *sym);
592 static int put_elf_sym(Section *s,
593 unsigned long value, unsigned long size,
594 int info, int other, int shndx, const char *name);
595 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
596 int info, int sh_num, const char *name);
597 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
598 int type, int symbol);
599 static void put_stabs(const char *str, int type, int other, int desc,
600 unsigned long value);
601 static void put_stabs_r(const char *str, int type, int other, int desc,
602 unsigned long value, Section *sec, int sym_index);
603 static void put_stabn(int type, int other, int desc, int value);
604 static void put_stabd(int type, int other, int desc);
605 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
607 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
608 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
609 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
611 /* true if float/double/long double type */
612 static inline int is_float(int t)
614 int bt;
615 bt = t & VT_BTYPE;
616 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
619 #ifdef TCC_TARGET_I386
620 #include "i386-gen.c"
621 #endif
622 #ifdef TCC_TARGET_IL
623 #include "il-gen.c"
624 #endif
626 #ifdef CONFIG_TCC_STATIC
628 #define RTLD_LAZY 0x001
629 #define RTLD_NOW 0x002
630 #define RTLD_GLOBAL 0x100
632 /* dummy function for profiling */
633 void *dlopen(const char *filename, int flag)
635 return NULL;
638 const char *dlerror(void)
640 return "error";
643 typedef struct TCCSyms {
644 char *str;
645 void *ptr;
646 } TCCSyms;
648 #define TCCSYM(a) { #a, &a, },
650 /* add the symbol you want here if no dynamic linking is done */
651 static TCCSyms tcc_syms[] = {
652 TCCSYM(printf)
653 TCCSYM(fprintf)
654 TCCSYM(fopen)
655 TCCSYM(fclose)
656 { NULL, NULL },
659 void *dlsym(void *handle, const char *symbol)
661 TCCSyms *p;
662 p = tcc_syms;
663 while (p->str != NULL) {
664 if (!strcmp(p->str, symbol))
665 return p->ptr;
666 p++;
668 return NULL;
671 #endif
673 /********************************************************/
675 /* we use our own 'finite' function to avoid potential problems with
676 non standard math libs */
677 /* XXX: endianness dependant */
678 int ieee_finite(double d)
680 int *p = (int *)&d;
681 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
684 /* copy a string and truncate it. */
685 static char *pstrcpy(char *buf, int buf_size, const char *s)
687 char *q, *q_end;
688 int c;
690 if (buf_size > 0) {
691 q = buf;
692 q_end = buf + buf_size - 1;
693 while (q < q_end) {
694 c = *s++;
695 if (c == '\0')
696 break;
697 *q++ = c;
699 *q = '\0';
701 return buf;
704 /* strcat and truncate. */
705 static char *pstrcat(char *buf, int buf_size, const char *s)
707 int len;
708 len = strlen(buf);
709 if (len < buf_size)
710 pstrcpy(buf + len, buf_size - len, s);
711 return buf;
714 /* memory management */
715 #ifdef MEM_DEBUG
716 int mem_cur_size;
717 int mem_max_size;
718 #endif
720 static inline void tcc_free(void *ptr)
722 #ifdef MEM_DEBUG
723 mem_cur_size -= malloc_usable_size(ptr);
724 #endif
725 free(ptr);
728 static void *tcc_malloc(unsigned long size)
730 void *ptr;
731 ptr = malloc(size);
732 if (!ptr && size)
733 error("memory full");
734 #ifdef MEM_DEBUG
735 mem_cur_size += malloc_usable_size(ptr);
736 if (mem_cur_size > mem_max_size)
737 mem_max_size = mem_cur_size;
738 #endif
739 return ptr;
742 static void *tcc_mallocz(unsigned long size)
744 void *ptr;
745 ptr = tcc_malloc(size);
746 memset(ptr, 0, size);
747 return ptr;
750 static inline void *tcc_realloc(void *ptr, unsigned long size)
752 void *ptr1;
753 #ifdef MEM_DEBUG
754 mem_cur_size -= malloc_usable_size(ptr);
755 #endif
756 ptr1 = realloc(ptr, size);
757 #ifdef MEM_DEBUG
758 /* NOTE: count not correct if alloc error, but not critical */
759 mem_cur_size += malloc_usable_size(ptr1);
760 if (mem_cur_size > mem_max_size)
761 mem_max_size = mem_cur_size;
762 #endif
763 return ptr1;
766 static char *tcc_strdup(const char *str)
768 char *ptr;
769 ptr = tcc_malloc(strlen(str) + 1);
770 strcpy(ptr, str);
771 return ptr;
774 #define free(p) use_tcc_free(p)
775 #define malloc(s) use_tcc_malloc(s)
776 #define realloc(p, s) use_tcc_realloc(p, s)
778 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
780 int nb, nb_alloc;
781 void **pp;
783 nb = *nb_ptr;
784 pp = *ptab;
785 /* every power of two we double array size */
786 if ((nb & (nb - 1)) == 0) {
787 if (!nb)
788 nb_alloc = 1;
789 else
790 nb_alloc = nb * 2;
791 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
792 if (!pp)
793 error("memory full");
794 *ptab = pp;
796 pp[nb++] = data;
797 *nb_ptr = nb;
800 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
802 Section *sec;
804 sec = tcc_mallocz(sizeof(Section));
805 pstrcpy(sec->name, sizeof(sec->name), name);
806 sec->sh_type = sh_type;
807 sec->sh_flags = sh_flags;
808 switch(sh_type) {
809 case SHT_HASH:
810 case SHT_REL:
811 case SHT_DYNSYM:
812 case SHT_SYMTAB:
813 case SHT_DYNAMIC:
814 sec->sh_addralign = 4;
815 break;
816 case SHT_STRTAB:
817 sec->sh_addralign = 1;
818 break;
819 default:
820 sec->sh_addralign = 32; /* default conservative alignment */
821 break;
824 /* only add section if not private */
825 if (!(sh_flags & SHF_PRIVATE)) {
826 sec->sh_num = s1->nb_sections;
827 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
829 return sec;
832 static void free_section(Section *s)
834 tcc_free(s->data);
835 tcc_free(s);
838 /* realloc section and set its content to zero */
839 static void section_realloc(Section *sec, unsigned long new_size)
841 unsigned long size;
842 unsigned char *data;
844 size = sec->data_allocated;
845 if (size == 0)
846 size = 1;
847 while (size < new_size)
848 size = size * 2;
849 data = tcc_realloc(sec->data, size);
850 if (!data)
851 error("memory full");
852 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
853 sec->data = data;
854 sec->data_allocated = size;
857 /* reserve at least 'size' bytes in section 'sec' from
858 sec->data_offset. */
859 static void *section_ptr_add(Section *sec, unsigned long size)
861 unsigned long offset, offset1;
863 offset = sec->data_offset;
864 offset1 = offset + size;
865 if (offset1 > sec->data_allocated)
866 section_realloc(sec, offset1);
867 sec->data_offset = offset1;
868 return sec->data + offset;
871 /* return a reference to a section, and create it if it does not
872 exists */
873 Section *find_section(TCCState *s1, const char *name)
875 Section *sec;
876 int i;
877 for(i = 1; i < s1->nb_sections; i++) {
878 sec = s1->sections[i];
879 if (!strcmp(name, sec->name))
880 return sec;
882 /* sections are created as PROGBITS */
883 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
886 /* update sym->c so that it points to an external symbol in section
887 'section' with value 'value' */
888 static void put_extern_sym(Sym *sym, Section *section,
889 unsigned long value, unsigned long size)
891 int sym_type, sym_bind, sh_num, info;
892 Elf32_Sym *esym;
893 const char *name;
894 char buf[32];
896 if (section)
897 sh_num = section->sh_num;
898 else
899 sh_num = SHN_UNDEF;
900 if (!sym->c) {
901 if ((sym->t & VT_BTYPE) == VT_FUNC)
902 sym_type = STT_FUNC;
903 else
904 sym_type = STT_OBJECT;
905 if (sym->t & VT_STATIC)
906 sym_bind = STB_LOCAL;
907 else
908 sym_bind = STB_GLOBAL;
910 name = get_tok_str(sym->v, NULL);
911 #ifdef CONFIG_TCC_BCHECK
912 if (do_bounds_check) {
913 /* if bound checking is activated, we change some function
914 names by adding the "__bound" prefix */
915 switch(sym->v) {
916 #if 0
917 /* XXX: we rely only on malloc hooks */
918 case TOK_malloc:
919 case TOK_free:
920 case TOK_realloc:
921 case TOK_memalign:
922 case TOK_calloc:
923 #endif
924 case TOK_memcpy:
925 case TOK_memmove:
926 case TOK_memset:
927 case TOK_strlen:
928 case TOK_strcpy:
929 strcpy(buf, "__bound_");
930 strcat(buf, name);
931 name = buf;
932 break;
935 #endif
936 info = ELF32_ST_INFO(sym_bind, sym_type);
937 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
938 } else {
939 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
940 esym->st_value = value;
941 esym->st_size = size;
942 esym->st_shndx = sh_num;
946 /* add a new relocation entry to symbol 'sym' in section 's' */
947 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
949 if (!sym->c)
950 put_extern_sym(sym, NULL, 0, 0);
951 /* now we can add ELF relocation info */
952 put_elf_reloc(symtab_section, s, offset, type, sym->c);
955 static inline int isid(int c)
957 return (c >= 'a' && c <= 'z') ||
958 (c >= 'A' && c <= 'Z') ||
959 c == '_';
962 static inline int isnum(int c)
964 return c >= '0' && c <= '9';
967 static inline int isoct(int c)
969 return c >= '0' && c <= '7';
972 static inline int toup(int c)
974 if (c >= 'a' && c <= 'z')
975 return c - 'a' + 'A';
976 else
977 return c;
980 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
982 int len;
983 len = strlen(buf);
984 vsnprintf(buf + len, buf_size - len, fmt, ap);
987 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
989 va_list ap;
990 va_start(ap, fmt);
991 strcat_vprintf(buf, buf_size, fmt, ap);
992 va_end(ap);
995 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
997 char buf[2048];
998 BufferedFile **f;
1000 buf[0] = '\0';
1001 if (file) {
1002 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1003 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1004 (*f)->filename, (*f)->line_num);
1005 if (file->line_num > 0) {
1006 strcat_printf(buf, sizeof(buf),
1007 "%s:%d: ", file->filename, file->line_num);
1008 } else {
1009 strcat_printf(buf, sizeof(buf),
1010 "%s: ", file->filename);
1012 } else {
1013 strcat_printf(buf, sizeof(buf),
1014 "tcc: ");
1016 if (is_warning)
1017 strcat_printf(buf, sizeof(buf), "warning: ");
1018 strcat_vprintf(buf, sizeof(buf), fmt, ap);
1020 if (!s1->error_func) {
1021 /* default case: stderr */
1022 fprintf(stderr, "%s\n", buf);
1023 } else {
1024 s1->error_func(s1->error_opaque, buf);
1026 if (!is_warning)
1027 s1->nb_errors++;
1030 #ifdef LIBTCC
1031 void tcc_set_error_func(TCCState *s, void *error_opaque,
1032 void (*error_func)(void *opaque, const char *msg))
1034 s->error_opaque = error_opaque;
1035 s->error_func = error_func;
1037 #endif
1039 /* error without aborting current compilation */
1040 void error_noabort(const char *fmt, ...)
1042 TCCState *s1 = tcc_state;
1043 va_list ap;
1045 va_start(ap, fmt);
1046 error1(s1, 0, fmt, ap);
1047 va_end(ap);
1050 void error(const char *fmt, ...)
1052 TCCState *s1 = tcc_state;
1053 va_list ap;
1055 va_start(ap, fmt);
1056 error1(s1, 0, fmt, ap);
1057 va_end(ap);
1058 /* better than nothing: in some cases, we accept to handle errors */
1059 if (s1->error_set_jmp_enabled) {
1060 longjmp(s1->error_jmp_buf, 1);
1061 } else {
1062 /* XXX: suppress it someday */
1063 exit(1);
1067 void expect(const char *msg)
1069 error("%s expected", msg);
1072 void warning(const char *fmt, ...)
1074 TCCState *s1 = tcc_state;
1075 va_list ap;
1077 va_start(ap, fmt);
1078 error1(s1, 1, fmt, ap);
1079 va_end(ap);
1082 void skip(int c)
1084 if (tok != c)
1085 error("'%c' expected", c);
1086 next();
1089 void test_lvalue(void)
1091 if (!(vtop->r & VT_LVAL))
1092 expect("lvalue");
1095 TokenSym *tok_alloc(const char *str, int len)
1097 TokenSym *ts, **pts, **ptable;
1098 int h, i;
1100 h = 1;
1101 for(i=0;i<len;i++)
1102 h = (h * 263 + ((unsigned char *)str)[i]) & (TOK_HASH_SIZE - 1);
1104 pts = &hash_ident[h];
1105 while (1) {
1106 ts = *pts;
1107 if (!ts)
1108 break;
1109 if (ts->len == len && !memcmp(ts->str, str, len))
1110 return ts;
1111 pts = &(ts->hash_next);
1114 if (tok_ident >= SYM_FIRST_ANOM)
1115 error("memory full");
1117 /* expand token table if needed */
1118 i = tok_ident - TOK_IDENT;
1119 if ((i % TOK_ALLOC_INCR) == 0) {
1120 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1121 if (!ptable)
1122 error("memory full");
1123 table_ident = ptable;
1126 ts = tcc_malloc(sizeof(TokenSym) + len);
1127 table_ident[i] = ts;
1128 ts->tok = tok_ident++;
1129 ts->len = len;
1130 ts->hash_next = NULL;
1131 memcpy(ts->str, str, len + 1);
1132 *pts = ts;
1133 return ts;
1136 /* CString handling */
1138 static void cstr_realloc(CString *cstr, int new_size)
1140 int size;
1141 void *data;
1143 size = cstr->size_allocated;
1144 if (size == 0)
1145 size = 8; /* no need to allocate a too small first string */
1146 while (size < new_size)
1147 size = size * 2;
1148 data = tcc_realloc(cstr->data_allocated, size);
1149 if (!data)
1150 error("memory full");
1151 cstr->data_allocated = data;
1152 cstr->size_allocated = size;
1153 cstr->data = data;
1156 /* add a byte */
1157 static void cstr_ccat(CString *cstr, int ch)
1159 int size;
1160 size = cstr->size + 1;
1161 if (size > cstr->size_allocated)
1162 cstr_realloc(cstr, size);
1163 ((unsigned char *)cstr->data)[size - 1] = ch;
1164 cstr->size = size;
1167 static void cstr_cat(CString *cstr, const char *str)
1169 int c;
1170 for(;;) {
1171 c = *str;
1172 if (c == '\0')
1173 break;
1174 cstr_ccat(cstr, c);
1175 str++;
1179 /* add a wide char */
1180 static void cstr_wccat(CString *cstr, int ch)
1182 int size;
1183 size = cstr->size + sizeof(int);
1184 if (size > cstr->size_allocated)
1185 cstr_realloc(cstr, size);
1186 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1187 cstr->size = size;
1190 static void cstr_new(CString *cstr)
1192 memset(cstr, 0, sizeof(CString));
1195 /* free string and reset it to NULL */
1196 static void cstr_free(CString *cstr)
1198 tcc_free(cstr->data_allocated);
1199 cstr_new(cstr);
1202 #define cstr_reset(cstr) cstr_free(cstr)
1204 /* XXX: unicode ? */
1205 static void add_char(CString *cstr, int c)
1207 if (c == '\'' || c == '\"' || c == '\\') {
1208 /* XXX: could be more precise if char or string */
1209 cstr_ccat(cstr, '\\');
1211 if (c >= 32 && c <= 126) {
1212 cstr_ccat(cstr, c);
1213 } else {
1214 cstr_ccat(cstr, '\\');
1215 if (c == '\n') {
1216 cstr_ccat(cstr, 'n');
1217 } else {
1218 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1219 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1220 cstr_ccat(cstr, '0' + (c & 7));
1225 /* XXX: buffer overflow */
1226 /* XXX: float tokens */
1227 char *get_tok_str(int v, CValue *cv)
1229 static char buf[STRING_MAX_SIZE + 1];
1230 static CString cstr_buf;
1231 CString *cstr;
1232 unsigned char *q;
1233 char *p;
1234 int i, len;
1236 /* NOTE: to go faster, we give a fixed buffer for small strings */
1237 cstr_reset(&cstr_buf);
1238 cstr_buf.data = buf;
1239 cstr_buf.size_allocated = sizeof(buf);
1240 p = buf;
1242 switch(v) {
1243 case TOK_CINT:
1244 case TOK_CUINT:
1245 /* XXX: not quite exact, but only useful for testing */
1246 sprintf(p, "%u", cv->ui);
1247 break;
1248 case TOK_CLLONG:
1249 case TOK_CULLONG:
1250 /* XXX: not quite exact, but only useful for testing */
1251 sprintf(p, "%Lu", cv->ull);
1252 break;
1253 case TOK_CCHAR:
1254 case TOK_LCHAR:
1255 cstr_ccat(&cstr_buf, '\'');
1256 add_char(&cstr_buf, cv->i);
1257 cstr_ccat(&cstr_buf, '\'');
1258 cstr_ccat(&cstr_buf, '\0');
1259 break;
1260 case TOK_PPNUM:
1261 cstr = cv->cstr;
1262 len = cstr->size - 1;
1263 for(i=0;i<len;i++)
1264 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1265 cstr_ccat(&cstr_buf, '\0');
1266 break;
1267 case TOK_STR:
1268 case TOK_LSTR:
1269 cstr = cv->cstr;
1270 cstr_ccat(&cstr_buf, '\"');
1271 if (v == TOK_STR) {
1272 len = cstr->size - 1;
1273 for(i=0;i<len;i++)
1274 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1275 } else {
1276 len = (cstr->size / sizeof(int)) - 1;
1277 for(i=0;i<len;i++)
1278 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1280 cstr_ccat(&cstr_buf, '\"');
1281 cstr_ccat(&cstr_buf, '\0');
1282 break;
1283 case TOK_LT:
1284 v = '<';
1285 goto addv;
1286 case TOK_GT:
1287 v = '>';
1288 goto addv;
1289 case TOK_A_SHL:
1290 return strcpy(p, "<<=");
1291 case TOK_A_SAR:
1292 return strcpy(p, ">>=");
1293 default:
1294 if (v < TOK_IDENT) {
1295 /* search in two bytes table */
1296 q = tok_two_chars;
1297 while (*q) {
1298 if (q[2] == v) {
1299 *p++ = q[0];
1300 *p++ = q[1];
1301 *p = '\0';
1302 return buf;
1304 q += 3;
1306 addv:
1307 *p++ = v;
1308 *p = '\0';
1309 } else if (v < tok_ident) {
1310 return table_ident[v - TOK_IDENT]->str;
1311 } else if (v >= SYM_FIRST_ANOM) {
1312 /* special name for anonymous symbol */
1313 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1314 } else {
1315 /* should never happen */
1316 return NULL;
1318 break;
1320 return cstr_buf.data;
1323 /* push, without hashing */
1324 Sym *sym_push2(Sym **ps, int v, int t, int c)
1326 Sym *s;
1327 s = tcc_malloc(sizeof(Sym));
1328 s->v = v;
1329 s->t = t;
1330 s->c = c;
1331 s->next = NULL;
1332 /* add in stack */
1333 s->prev = *ps;
1334 *ps = s;
1335 return s;
1338 /* find a symbol and return its associated structure. 's' is the top
1339 of the symbol stack */
1340 Sym *sym_find2(Sym *s, int v)
1342 while (s) {
1343 if (s->v == v)
1344 return s;
1345 s = s->prev;
1347 return NULL;
1350 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1352 /* find a symbol and return its associated structure. 'st' is the
1353 symbol stack */
1354 Sym *sym_find1(SymStack *st, int v)
1356 Sym *s;
1358 s = st->hash[HASH_SYM(v)];
1359 while (s) {
1360 if (s->v == v)
1361 return s;
1362 s = s->hash_next;
1364 return NULL;
1367 Sym *sym_push1(SymStack *st, int v, int t, int c)
1369 Sym *s, **ps;
1370 s = sym_push2(&st->top, v, t, c);
1371 /* add in hash table */
1372 if (v) {
1373 ps = &st->hash[HASH_SYM(v)];
1374 s->hash_next = *ps;
1375 *ps = s;
1377 return s;
1380 /* find a symbol in the right symbol space */
1381 Sym *sym_find(int v)
1383 Sym *s;
1384 s = sym_find1(&local_stack, v);
1385 if (!s)
1386 s = sym_find1(&global_stack, v);
1387 return s;
1390 /* push a given symbol on the symbol stack */
1391 Sym *sym_push(int v, int t, int r, int c)
1393 Sym *s;
1394 if (local_stack.top)
1395 s = sym_push1(&local_stack, v, t, c);
1396 else
1397 s = sym_push1(&global_stack, v, t, c);
1398 s->r = r;
1399 return s;
1402 /* pop symbols until top reaches 'b' */
1403 void sym_pop(SymStack *st, Sym *b)
1405 Sym *s, *ss;
1407 s = st->top;
1408 while(s != b) {
1409 ss = s->prev;
1410 /* free hash table entry, except if symbol was freed (only
1411 used for #undef symbols) */
1412 if (s->v)
1413 st->hash[HASH_SYM(s->v)] = s->hash_next;
1414 tcc_free(s);
1415 s = ss;
1417 st->top = b;
1420 /* undefined a hashed symbol (used for #undef). Its name is set to
1421 zero */
1422 void sym_undef(SymStack *st, Sym *s)
1424 Sym **ss;
1425 ss = &st->hash[HASH_SYM(s->v)];
1426 while (*ss != NULL) {
1427 if (*ss == s)
1428 break;
1429 ss = &(*ss)->hash_next;
1431 *ss = s->hash_next;
1432 s->v = 0;
1435 /* I/O layer */
1437 BufferedFile *tcc_open(TCCState *s1, const char *filename)
1439 int fd;
1440 BufferedFile *bf;
1442 fd = open(filename, O_RDONLY);
1443 if (fd < 0)
1444 return NULL;
1445 bf = tcc_malloc(sizeof(BufferedFile));
1446 if (!bf) {
1447 close(fd);
1448 return NULL;
1450 bf->fd = fd;
1451 bf->buf_ptr = bf->buffer;
1452 bf->buf_end = bf->buffer;
1453 bf->buffer[0] = CH_EOB; /* put eob symbol */
1454 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1455 bf->line_num = 1;
1456 bf->ifndef_macro = 0;
1457 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1458 // printf("opening '%s'\n", filename);
1459 return bf;
1462 void tcc_close(BufferedFile *bf)
1464 total_lines += bf->line_num;
1465 close(bf->fd);
1466 tcc_free(bf);
1469 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1470 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1472 /* fill input buffer and return next char */
1473 int tcc_getc_slow(BufferedFile *bf)
1475 int len;
1476 /* only tries to read if really end of buffer */
1477 if (bf->buf_ptr >= bf->buf_end) {
1478 if (bf->fd != -1) {
1479 len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
1480 if (len < 0)
1481 len = 0;
1482 } else {
1483 len = 0;
1485 total_bytes += len;
1486 bf->buf_ptr = bf->buffer;
1487 bf->buf_end = bf->buffer + len;
1488 *bf->buf_end = CH_EOB;
1490 if (bf->buf_ptr < bf->buf_end) {
1491 return *bf->buf_ptr++;
1492 } else {
1493 bf->buf_ptr = bf->buf_end;
1494 return CH_EOF;
1498 /* no need to put that inline */
1499 void handle_eob(void)
1501 TCCState *s1 = tcc_state;
1502 for(;;) {
1503 ch1 = tcc_getc_slow(file);
1504 if (ch1 != CH_EOF)
1505 return;
1506 eof_seen = 1;
1507 if (return_linefeed) {
1508 ch1 = '\n';
1509 return;
1511 if (s1->include_stack_ptr == s1->include_stack)
1512 return;
1513 /* add end of include file debug info */
1514 if (do_debug) {
1515 put_stabd(N_EINCL, 0, 0);
1517 /* pop include stack */
1518 tcc_close(file);
1519 s1->include_stack_ptr--;
1520 file = *s1->include_stack_ptr;
1524 /* read next char from current input file */
1525 static inline void inp(void)
1527 ch1 = TCC_GETC(file);
1528 /* end of buffer/file handling */
1529 if (ch1 == CH_EOB)
1530 handle_eob();
1531 if (ch1 == '\n')
1532 file->line_num++;
1533 // printf("ch1=%c 0x%x\n", ch1, ch1);
1536 /* handle '\\n' and '\\r\n' */
1537 static void handle_stray(void)
1539 do {
1540 if (ch1 == '\n') {
1541 inp();
1542 } else if (ch1 == '\r') {
1543 inp();
1544 if (ch1 != '\n')
1545 error("invalid character after '\\'");
1546 inp();
1547 } else {
1548 break;
1550 ch = ch1;
1551 inp();
1552 } while (ch == '\\');
1555 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1556 case */
1557 static inline void minp(void)
1559 ch = ch1;
1560 inp();
1561 if (ch == '\\')
1562 handle_stray();
1566 /* same as minp, but also skip comments */
1567 static void cinp(void)
1569 int c;
1571 if (ch1 == '/') {
1572 inp();
1573 if (ch1 == '/') {
1574 /* single line C++ comments */
1575 inp();
1576 while (ch1 != '\n' && ch1 != CH_EOF)
1577 inp();
1578 ch = ' '; /* return space */
1579 } else if (ch1 == '*') {
1580 /* C comments */
1581 inp();
1582 while (ch1 != CH_EOF) {
1583 c = ch1;
1584 inp();
1585 if (c == '*' && ch1 == '/') {
1586 inp();
1587 ch = ' '; /* return space */
1588 break;
1591 } else {
1592 ch = '/';
1594 } else {
1595 minp();
1599 /* space exlcuding newline */
1600 static inline int is_space(int ch)
1602 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1605 static inline void skip_spaces(void)
1607 while (is_space(ch))
1608 cinp();
1611 /* skip block of text until #else, #elif or #endif. skip also pairs of
1612 #if/#endif */
1613 void preprocess_skip(void)
1615 int a;
1616 a = 0;
1617 while (1) {
1618 while (ch != '\n') {
1619 if (ch == CH_EOF)
1620 expect("#endif");
1621 cinp();
1623 cinp();
1624 skip_spaces();
1625 if (ch == '#') {
1626 cinp();
1627 next_nomacro();
1628 if (a == 0 &&
1629 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1630 break;
1631 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1632 a++;
1633 else if (tok == TOK_ENDIF)
1634 a--;
1639 /* ParseState handling */
1641 /* XXX: currently, no include file info is stored. Thus, we cannot display
1642 accurate messages if the function or data definition spans multiple
1643 files */
1645 /* save current parse state in 's' */
1646 void save_parse_state(ParseState *s)
1648 s->line_num = file->line_num;
1649 s->macro_ptr = macro_ptr;
1650 s->tok = tok;
1651 s->tokc = tokc;
1654 /* restore parse state from 's' */
1655 void restore_parse_state(ParseState *s)
1657 file->line_num = s->line_num;
1658 macro_ptr = s->macro_ptr;
1659 tok = s->tok;
1660 tokc = s->tokc;
1663 /* return the number of additionnal 'ints' necessary to store the
1664 token */
1665 static inline int tok_ext_size(int t)
1667 switch(t) {
1668 /* 4 bytes */
1669 case TOK_CINT:
1670 case TOK_CUINT:
1671 case TOK_CCHAR:
1672 case TOK_LCHAR:
1673 case TOK_STR:
1674 case TOK_LSTR:
1675 case TOK_CFLOAT:
1676 case TOK_LINENUM:
1677 case TOK_PPNUM:
1678 return 1;
1679 case TOK_CDOUBLE:
1680 case TOK_CLLONG:
1681 case TOK_CULLONG:
1682 return 2;
1683 case TOK_CLDOUBLE:
1684 return LDOUBLE_SIZE / 4;
1685 default:
1686 return 0;
1690 /* token string handling */
1692 static inline void tok_str_new(TokenString *s)
1694 s->str = NULL;
1695 s->len = 0;
1696 s->last_line_num = -1;
1699 static void tok_str_free(int *str)
1701 const int *p;
1702 CString *cstr;
1703 int t;
1705 p = str;
1706 for(;;) {
1707 t = *p++;
1708 if (t == 0)
1709 break;
1710 if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) {
1711 /* XXX: use a macro to be portable on 64 bit ? */
1712 cstr = (CString *)(*p++);
1713 cstr_free(cstr);
1714 tcc_free(cstr);
1715 } else {
1716 p += tok_ext_size(t);
1719 tcc_free(str);
1722 static void tok_str_add(TokenString *s, int t)
1724 int len, *str;
1726 len = s->len;
1727 str = s->str;
1728 if ((len & 63) == 0) {
1729 str = tcc_realloc(str, (len + 64) * sizeof(int));
1730 if (!str)
1731 return;
1732 s->str = str;
1734 str[len++] = t;
1735 s->len = len;
1738 static void tok_str_add2(TokenString *s, int t, CValue *cv)
1740 int n, i, size;
1741 CString *cstr, *cstr1;
1742 CValue cv1;
1744 tok_str_add(s, t);
1745 if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) {
1746 /* special case: need to duplicate string */
1747 cstr1 = cv->cstr;
1748 cstr = tcc_malloc(sizeof(CString));
1749 size = cstr1->size;
1750 cstr->size = size;
1751 cstr->size_allocated = size;
1752 cstr->data_allocated = tcc_malloc(size);
1753 cstr->data = cstr->data_allocated;
1754 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1755 cv1.cstr = cstr;
1756 tok_str_add(s, cv1.tab[0]);
1757 } else {
1758 n = tok_ext_size(t);
1759 for(i=0;i<n;i++)
1760 tok_str_add(s, cv->tab[i]);
1764 /* add the current parse token in token string 's' */
1765 static void tok_str_add_tok(TokenString *s)
1767 CValue cval;
1769 /* save line number info */
1770 if (file->line_num != s->last_line_num) {
1771 s->last_line_num = file->line_num;
1772 cval.i = s->last_line_num;
1773 tok_str_add2(s, TOK_LINENUM, &cval);
1775 tok_str_add2(s, tok, &tokc);
1778 /* get a token from an integer array and increment pointer accordingly */
1779 static int tok_get(int **tok_str, CValue *cv)
1781 int *p, t, n, i;
1783 p = *tok_str;
1784 t = *p++;
1785 n = tok_ext_size(t);
1786 for(i=0;i<n;i++)
1787 cv->tab[i] = *p++;
1788 *tok_str = p;
1789 return t;
1792 /* eval an expression for #if/#elif */
1793 int expr_preprocess(void)
1795 int c, t;
1796 TokenString str;
1798 tok_str_new(&str);
1799 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1800 next(); /* do macro subst */
1801 if (tok == TOK_DEFINED) {
1802 next_nomacro();
1803 t = tok;
1804 if (t == '(')
1805 next_nomacro();
1806 c = sym_find1(&define_stack, tok) != 0;
1807 if (t == '(')
1808 next_nomacro();
1809 tok = TOK_CINT;
1810 tokc.i = c;
1811 } else if (tok >= TOK_IDENT) {
1812 /* if undefined macro */
1813 tok = TOK_CINT;
1814 tokc.i = 0;
1816 tok_str_add_tok(&str);
1818 tok_str_add(&str, -1); /* simulate end of file */
1819 tok_str_add(&str, 0);
1820 /* now evaluate C constant expression */
1821 macro_ptr = str.str;
1822 next();
1823 c = expr_const();
1824 macro_ptr = NULL;
1825 tok_str_free(str.str);
1826 return c != 0;
1829 #if defined(DEBUG) || defined(PP_DEBUG)
1830 void tok_print(int *str)
1832 int t;
1833 CValue cval;
1835 while (1) {
1836 t = tok_get(&str, &cval);
1837 if (!t)
1838 break;
1839 printf(" %s", get_tok_str(t, &cval));
1841 printf("\n");
1843 #endif
1845 /* parse after #define */
1846 void parse_define(void)
1848 Sym *s, *first, **ps;
1849 int v, t, varg, is_vaargs;
1850 TokenString str;
1852 v = tok;
1853 /* XXX: should check if same macro (ANSI) */
1854 first = NULL;
1855 t = MACRO_OBJ;
1856 /* '(' must be just after macro definition for MACRO_FUNC */
1857 if (ch == '(') {
1858 next_nomacro();
1859 next_nomacro();
1860 ps = &first;
1861 while (tok != ')') {
1862 varg = tok;
1863 next_nomacro();
1864 is_vaargs = 0;
1865 if (varg == TOK_DOTS) {
1866 varg = TOK___VA_ARGS__;
1867 is_vaargs = 1;
1868 } else if (tok == TOK_DOTS && gnu_ext) {
1869 is_vaargs = 1;
1870 next_nomacro();
1872 if (varg < TOK_IDENT)
1873 error("badly punctuated parameter list");
1874 s = sym_push1(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
1875 *ps = s;
1876 ps = &s->next;
1877 if (tok != ',')
1878 break;
1879 next_nomacro();
1881 t = MACRO_FUNC;
1883 tok_str_new(&str);
1884 next_nomacro();
1885 /* EOF testing necessary for '-D' handling */
1886 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1887 tok_str_add2(&str, tok, &tokc);
1888 next_nomacro();
1890 tok_str_add(&str, 0);
1891 #ifdef PP_DEBUG
1892 printf("define %s %d: ", get_tok_str(v, NULL), t);
1893 tok_print(str.str);
1894 #endif
1895 s = sym_push1(&define_stack, v, t, (int)str.str);
1896 s->next = first;
1899 /* XXX: use a token or a hash table to accelerate matching ? */
1900 static CachedInclude *search_cached_include(TCCState *s1,
1901 int type, const char *filename)
1903 CachedInclude *e;
1904 int i;
1906 for(i = 0;i < s1->nb_cached_includes; i++) {
1907 e = s1->cached_includes[i];
1908 if (e->type == type && !strcmp(e->filename, filename))
1909 return e;
1911 return NULL;
1914 static inline void add_cached_include(TCCState *s1, int type,
1915 const char *filename, int ifndef_macro)
1917 CachedInclude *e;
1919 if (search_cached_include(s1, type, filename))
1920 return;
1921 #ifdef INC_DEBUG
1922 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
1923 #endif
1924 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
1925 if (!e)
1926 return;
1927 e->type = type;
1928 strcpy(e->filename, filename);
1929 e->ifndef_macro = ifndef_macro;
1930 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
1934 enum IncludeState {
1935 INCLUDE_STATE_NONE = 0,
1936 INCLUDE_STATE_SEEK_IFNDEF,
1939 void preprocess(void)
1941 TCCState *s1 = tcc_state;
1942 int size, i, c, n;
1943 enum IncludeState state;
1944 char buf[1024], *q, *p;
1945 char buf1[1024];
1946 BufferedFile *f;
1947 Sym *s;
1948 CachedInclude *e;
1950 return_linefeed = 1; /* linefeed will be returned as a
1951 token. EOF is also returned as line feed */
1952 state = INCLUDE_STATE_NONE;
1953 eof_seen = 0;
1954 redo1:
1955 cinp();
1956 next_nomacro();
1957 redo:
1958 if (tok == TOK_DEFINE) {
1959 next_nomacro();
1960 parse_define();
1961 } else if (tok == TOK_UNDEF) {
1962 next_nomacro();
1963 s = sym_find1(&define_stack, tok);
1964 /* undefine symbol by putting an invalid name */
1965 if (s)
1966 sym_undef(&define_stack, s);
1967 } else if (tok == TOK_INCLUDE) {
1968 skip_spaces();
1969 if (ch == '<') {
1970 c = '>';
1971 goto read_name;
1972 } else if (ch == '\"') {
1973 c = ch;
1974 read_name:
1975 minp();
1976 q = buf;
1977 while (ch != c && ch != '\n' && ch != CH_EOF) {
1978 if ((q - buf) < sizeof(buf) - 1)
1979 *q++ = ch;
1980 minp();
1982 *q = '\0';
1983 /* eat all spaces and comments after include */
1984 /* XXX: slightly incorrect */
1985 while (ch1 != '\n' && ch1 != CH_EOF)
1986 inp();
1987 } else {
1988 /* computed #include : either we have only strings or
1989 we have anything enclosed in '<>' */
1990 next();
1991 buf[0] = '\0';
1992 if (tok == TOK_STR) {
1993 while (tok != TOK_LINEFEED) {
1994 if (tok != TOK_STR) {
1995 include_syntax:
1996 error("'#include' expects \"FILENAME\" or <FILENAME>");
1998 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
1999 next();
2001 c = '\"';
2002 } else {
2003 int len;
2004 while (tok != TOK_LINEFEED) {
2005 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2006 next();
2008 len = strlen(buf);
2009 /* check syntax and remove '<>' */
2010 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2011 goto include_syntax;
2012 memmove(buf, buf + 1, len - 2);
2013 buf[len - 2] = '\0';
2014 c = '>';
2018 ch = '\n';
2019 e = search_cached_include(s1, c, buf);
2020 if (e && sym_find1(&define_stack, e->ifndef_macro)) {
2021 /* no need to parse the include because the 'ifndef macro'
2022 is defined */
2023 #ifdef INC_DEBUG
2024 printf("%s: skipping %s\n", file->filename, buf);
2025 #endif
2026 } else {
2027 if (c == '\"') {
2028 /* first search in current dir if "header.h" */
2029 size = 0;
2030 p = strrchr(file->filename, '/');
2031 if (p)
2032 size = p + 1 - file->filename;
2033 if (size > sizeof(buf1) - 1)
2034 size = sizeof(buf1) - 1;
2035 memcpy(buf1, file->filename, size);
2036 buf1[size] = '\0';
2037 pstrcat(buf1, sizeof(buf1), buf);
2038 f = tcc_open(s1, buf1);
2039 if (f)
2040 goto found;
2042 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2043 error("#include recursion too deep");
2044 /* now search in all the include paths */
2045 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2046 for(i = 0; i < n; i++) {
2047 const char *path;
2048 if (i < s1->nb_include_paths)
2049 path = s1->include_paths[i];
2050 else
2051 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2052 pstrcpy(buf1, sizeof(buf1), path);
2053 pstrcat(buf1, sizeof(buf1), "/");
2054 pstrcat(buf1, sizeof(buf1), buf);
2055 f = tcc_open(s1, buf1);
2056 if (f)
2057 goto found;
2059 error("include file '%s' not found", buf);
2060 f = NULL;
2061 found:
2062 #ifdef INC_DEBUG
2063 printf("%s: including %s\n", file->filename, buf1);
2064 #endif
2065 f->inc_type = c;
2066 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2067 /* push current file in stack */
2068 /* XXX: fix current line init */
2069 *s1->include_stack_ptr++ = file;
2070 file = f;
2071 /* add include file debug info */
2072 if (do_debug) {
2073 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2075 /* we check for the construct: #ifndef IDENT \n #define IDENT */
2076 inp();
2077 /* get first non space char */
2078 while (is_space(ch) || ch == '\n')
2079 cinp();
2080 if (ch != '#')
2081 goto the_end;
2082 state = INCLUDE_STATE_SEEK_IFNDEF;
2083 goto redo1;
2085 } else if (tok == TOK_IFNDEF) {
2086 c = 1;
2087 goto do_ifdef;
2088 } else if (tok == TOK_IF) {
2089 c = expr_preprocess();
2090 goto do_if;
2091 } else if (tok == TOK_IFDEF) {
2092 c = 0;
2093 do_ifdef:
2094 next_nomacro();
2095 if (tok < TOK_IDENT)
2096 error("invalid argument for '#if%sdef'", c ? "n" : "");
2097 if (state == INCLUDE_STATE_SEEK_IFNDEF) {
2098 if (c) {
2099 file->ifndef_macro = tok;
2101 state = INCLUDE_STATE_NONE;
2103 c = (sym_find1(&define_stack, tok) != 0) ^ c;
2104 do_if:
2105 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2106 error("memory full");
2107 *s1->ifdef_stack_ptr++ = c;
2108 goto test_skip;
2109 } else if (tok == TOK_ELSE) {
2110 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2111 error("#else without matching #if");
2112 if (s1->ifdef_stack_ptr[-1] & 2)
2113 error("#else after #else");
2114 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2115 goto test_skip;
2116 } else if (tok == TOK_ELIF) {
2117 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2118 error("#elif without matching #if");
2119 c = s1->ifdef_stack_ptr[-1];
2120 if (c > 1)
2121 error("#elif after #else");
2122 /* last #if/#elif expression was true: we skip */
2123 if (c == 1)
2124 goto skip;
2125 c = expr_preprocess();
2126 s1->ifdef_stack_ptr[-1] = c;
2127 test_skip:
2128 if (!(c & 1)) {
2129 skip:
2130 preprocess_skip();
2131 state = INCLUDE_STATE_NONE;
2132 goto redo;
2134 } else if (tok == TOK_ENDIF) {
2135 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2136 error("#endif without matching #if");
2137 if (file->ifndef_macro &&
2138 s1->ifdef_stack_ptr == (file->ifdef_stack_ptr + 1)) {
2139 /* '#ifndef macro \n #define macro' was at the start of
2140 file. Now we check if an '#endif' is exactly at the end
2141 of file */
2142 while (tok != TOK_LINEFEED)
2143 next_nomacro();
2144 /* XXX: should also skip comments, but it is more complicated */
2145 if (eof_seen) {
2146 add_cached_include(s1, file->inc_type, file->inc_filename,
2147 file->ifndef_macro);
2148 } else {
2149 /* if not end of file, we must desactivate the ifndef
2150 macro search */
2151 file->ifndef_macro = 0;
2154 s1->ifdef_stack_ptr--;
2155 } else if (tok == TOK_LINE) {
2156 int line_num;
2157 next();
2158 if (tok != TOK_CINT)
2159 error("#line");
2160 line_num = tokc.i;
2161 next();
2162 if (tok != TOK_LINEFEED) {
2163 if (tok != TOK_STR)
2164 error("#line");
2165 pstrcpy(file->filename, sizeof(file->filename),
2166 (char *)tokc.cstr->data);
2168 /* NOTE: we do it there to avoid problems with linefeed */
2169 file->line_num = line_num;
2170 } else if (tok == TOK_ERROR) {
2171 error("#error");
2173 /* ignore other preprocess commands or #! for C scripts */
2174 while (tok != TOK_LINEFEED && tok != TOK_EOF)
2175 next_nomacro();
2176 the_end:
2177 return_linefeed = 0;
2180 /* read a number in base b */
2181 static int getn(int b)
2183 int n, t;
2184 n = 0;
2185 while (1) {
2186 if (ch >= 'a' && ch <= 'f')
2187 t = ch - 'a' + 10;
2188 else if (ch >= 'A' && ch <= 'F')
2189 t = ch - 'A' + 10;
2190 else if (isnum(ch))
2191 t = ch - '0';
2192 else
2193 break;
2194 if (t < 0 || t >= b)
2195 break;
2196 n = n * b + t;
2197 cinp();
2199 return n;
2202 /* read a character for string or char constant and eval escape codes */
2203 static int getq(void)
2205 int c;
2207 c = ch;
2208 minp();
2209 if (c == '\\') {
2210 if (isoct(ch)) {
2211 /* at most three octal digits */
2212 c = ch - '0';
2213 minp();
2214 if (isoct(ch)) {
2215 c = c * 8 + ch - '0';
2216 minp();
2217 if (isoct(ch)) {
2218 c = c * 8 + ch - '0';
2219 minp();
2222 return c;
2223 } else if (ch == 'x') {
2224 minp();
2225 return getn(16);
2226 } else {
2227 if (ch == 'a')
2228 c = '\a';
2229 else if (ch == 'b')
2230 c = '\b';
2231 else if (ch == 'f')
2232 c = '\f';
2233 else if (ch == 'n')
2234 c = '\n';
2235 else if (ch == 'r')
2236 c = '\r';
2237 else if (ch == 't')
2238 c = '\t';
2239 else if (ch == 'v')
2240 c = '\v';
2241 else if (ch == 'e' && gnu_ext)
2242 c = 27;
2243 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
2244 c = ch;
2245 else
2246 error("invalid escaped char");
2247 minp();
2249 } else if (c == '\r' && ch == '\n') {
2250 minp();
2251 c = '\n';
2253 return c;
2256 /* we use 64 bit numbers */
2257 #define BN_SIZE 2
2259 /* bn = (bn << shift) | or_val */
2260 void bn_lshift(unsigned int *bn, int shift, int or_val)
2262 int i;
2263 unsigned int v;
2264 for(i=0;i<BN_SIZE;i++) {
2265 v = bn[i];
2266 bn[i] = (v << shift) | or_val;
2267 or_val = v >> (32 - shift);
2271 void bn_zero(unsigned int *bn)
2273 int i;
2274 for(i=0;i<BN_SIZE;i++) {
2275 bn[i] = 0;
2279 /* parse number in null terminated string 'p' and return it in the
2280 current token */
2281 void parse_number(const char *p)
2283 int b, t, shift, frac_bits, s, exp_val, ch;
2284 char *q;
2285 unsigned int bn[BN_SIZE];
2286 double d;
2288 /* number */
2289 q = token_buf;
2290 ch = *p++;
2291 t = ch;
2292 ch = *p++;
2293 *q++ = t;
2294 b = 10;
2295 if (t == '.') {
2296 goto float_frac_parse;
2297 } else if (t == '0') {
2298 if (ch == 'x' || ch == 'X') {
2299 q--;
2300 ch = *p++;
2301 b = 16;
2302 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2303 q--;
2304 ch = *p++;
2305 b = 2;
2308 /* parse all digits. cannot check octal numbers at this stage
2309 because of floating point constants */
2310 while (1) {
2311 if (ch >= 'a' && ch <= 'f')
2312 t = ch - 'a' + 10;
2313 else if (ch >= 'A' && ch <= 'F')
2314 t = ch - 'A' + 10;
2315 else if (isnum(ch))
2316 t = ch - '0';
2317 else
2318 break;
2319 if (t >= b)
2320 break;
2321 if (q >= token_buf + STRING_MAX_SIZE) {
2322 num_too_long:
2323 error("number too long");
2325 *q++ = ch;
2326 ch = *p++;
2328 if (ch == '.' ||
2329 ((ch == 'e' || ch == 'E') && b == 10) ||
2330 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2331 if (b != 10) {
2332 /* NOTE: strtox should support that for hexa numbers, but
2333 non ISOC99 libcs do not support it, so we prefer to do
2334 it by hand */
2335 /* hexadecimal or binary floats */
2336 /* XXX: handle overflows */
2337 *q = '\0';
2338 if (b == 16)
2339 shift = 4;
2340 else
2341 shift = 2;
2342 bn_zero(bn);
2343 q = token_buf;
2344 while (1) {
2345 t = *q++;
2346 if (t == '\0') {
2347 break;
2348 } else if (t >= 'a') {
2349 t = t - 'a' + 10;
2350 } else if (t >= 'A') {
2351 t = t - 'A' + 10;
2352 } else {
2353 t = t - '0';
2355 bn_lshift(bn, shift, t);
2357 frac_bits = 0;
2358 if (ch == '.') {
2359 ch = *p++;
2360 while (1) {
2361 t = ch;
2362 if (t >= 'a' && t <= 'f') {
2363 t = t - 'a' + 10;
2364 } else if (t >= 'A' && t <= 'F') {
2365 t = t - 'A' + 10;
2366 } else if (t >= '0' && t <= '9') {
2367 t = t - '0';
2368 } else {
2369 break;
2371 if (t >= b)
2372 error("invalid digit");
2373 bn_lshift(bn, shift, t);
2374 frac_bits += shift;
2375 ch = *p++;
2378 if (ch != 'p' && ch != 'P')
2379 error("exponent expected");
2380 ch = *p++;
2381 s = 1;
2382 exp_val = 0;
2383 if (ch == '+') {
2384 ch = *p++;
2385 } else if (ch == '-') {
2386 s = -1;
2387 ch = *p++;
2389 if (ch < '0' || ch > '9')
2390 error("exponent digits expected");
2391 while (ch >= '0' && ch <= '9') {
2392 exp_val = exp_val * 10 + ch - '0';
2393 ch = *p++;
2395 exp_val = exp_val * s;
2397 /* now we can generate the number */
2398 /* XXX: should patch directly float number */
2399 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
2400 d = ldexp(d, exp_val - frac_bits);
2401 t = toup(ch);
2402 if (t == 'F') {
2403 ch = *p++;
2404 tok = TOK_CFLOAT;
2405 /* float : should handle overflow */
2406 tokc.f = (float)d;
2407 } else if (t == 'L') {
2408 ch = *p++;
2409 tok = TOK_CLDOUBLE;
2410 /* XXX: not large enough */
2411 tokc.ld = (long double)d;
2412 } else {
2413 tok = TOK_CDOUBLE;
2414 tokc.d = d;
2416 } else {
2417 /* decimal floats */
2418 if (ch == '.') {
2419 if (q >= token_buf + STRING_MAX_SIZE)
2420 goto num_too_long;
2421 *q++ = ch;
2422 ch = *p++;
2423 float_frac_parse:
2424 while (ch >= '0' && ch <= '9') {
2425 if (q >= token_buf + STRING_MAX_SIZE)
2426 goto num_too_long;
2427 *q++ = ch;
2428 ch = *p++;
2431 if (ch == 'e' || ch == 'E') {
2432 if (q >= token_buf + STRING_MAX_SIZE)
2433 goto num_too_long;
2434 *q++ = ch;
2435 ch = *p++;
2436 if (ch == '-' || ch == '+') {
2437 if (q >= token_buf + STRING_MAX_SIZE)
2438 goto num_too_long;
2439 *q++ = ch;
2440 ch = *p++;
2442 if (ch < '0' || ch > '9')
2443 error("exponent digits expected");
2444 while (ch >= '0' && ch <= '9') {
2445 if (q >= token_buf + STRING_MAX_SIZE)
2446 goto num_too_long;
2447 *q++ = ch;
2448 ch = *p++;
2451 *q = '\0';
2452 t = toup(ch);
2453 errno = 0;
2454 if (t == 'F') {
2455 ch = *p++;
2456 tok = TOK_CFLOAT;
2457 tokc.f = strtof(token_buf, NULL);
2458 } else if (t == 'L') {
2459 ch = *p++;
2460 tok = TOK_CLDOUBLE;
2461 tokc.ld = strtold(token_buf, NULL);
2462 } else {
2463 tok = TOK_CDOUBLE;
2464 tokc.d = strtod(token_buf, NULL);
2467 } else {
2468 unsigned long long n, n1;
2469 int lcount, ucount;
2471 /* integer number */
2472 *q = '\0';
2473 q = token_buf;
2474 if (b == 10 && *q == '0') {
2475 b = 8;
2476 q++;
2478 n = 0;
2479 while(1) {
2480 t = *q++;
2481 /* no need for checks except for base 10 / 8 errors */
2482 if (t == '\0') {
2483 break;
2484 } else if (t >= 'a') {
2485 t = t - 'a' + 10;
2486 } else if (t >= 'A') {
2487 t = t - 'A' + 10;
2488 } else {
2489 t = t - '0';
2490 if (t >= b)
2491 error("invalid digit");
2493 n1 = n;
2494 n = n * b + t;
2495 /* detect overflow */
2496 /* XXX: this test is not reliable */
2497 if (n < n1)
2498 error("integer constant overflow");
2501 /* XXX: not exactly ANSI compliant */
2502 if ((n & 0xffffffff00000000LL) != 0) {
2503 if ((n >> 63) != 0)
2504 tok = TOK_CULLONG;
2505 else
2506 tok = TOK_CLLONG;
2507 } else if (n > 0x7fffffff) {
2508 tok = TOK_CUINT;
2509 } else {
2510 tok = TOK_CINT;
2512 lcount = 0;
2513 ucount = 0;
2514 for(;;) {
2515 t = toup(ch);
2516 if (t == 'L') {
2517 if (lcount >= 2)
2518 error("three 'l's in integer constant");
2519 lcount++;
2520 if (lcount == 2) {
2521 if (tok == TOK_CINT)
2522 tok = TOK_CLLONG;
2523 else if (tok == TOK_CUINT)
2524 tok = TOK_CULLONG;
2526 ch = *p++;
2527 } else if (t == 'U') {
2528 if (ucount >= 1)
2529 error("two 'u's in integer constant");
2530 ucount++;
2531 if (tok == TOK_CINT)
2532 tok = TOK_CUINT;
2533 else if (tok == TOK_CLLONG)
2534 tok = TOK_CULLONG;
2535 ch = *p++;
2536 } else {
2537 break;
2540 if (tok == TOK_CINT || tok == TOK_CUINT)
2541 tokc.ui = n;
2542 else
2543 tokc.ull = n;
2547 /* return next token without macro substitution */
2548 static inline void next_nomacro1(void)
2550 int b;
2551 char *q;
2552 TokenSym *ts;
2554 /* skip spaces */
2555 while(1) {
2556 while (ch == '\n') {
2557 /* during preprocessor parsing, '\n' is a token */
2558 if (return_linefeed) {
2559 tok = TOK_LINEFEED;
2560 return;
2562 cinp();
2563 skip_spaces();
2564 if (ch == '#') {
2565 /* preprocessor command if # at start of line after
2566 spaces */
2567 preprocess();
2570 if (!is_space(ch))
2571 break;
2572 cinp();
2574 if (isid(ch)) {
2575 q = token_buf;
2576 *q++ = ch;
2577 cinp();
2578 if (q[-1] == 'L') {
2579 if (ch == '\'') {
2580 tok = TOK_LCHAR;
2581 goto char_const;
2583 if (ch == '\"') {
2584 tok = TOK_LSTR;
2585 goto str_const;
2588 while (isid(ch) || isnum(ch)) {
2589 if (q >= token_buf + STRING_MAX_SIZE)
2590 error("ident too long");
2591 *q++ = ch;
2592 cinp();
2594 *q = '\0';
2595 ts = tok_alloc(token_buf, q - token_buf);
2596 tok = ts->tok;
2597 } else if (isnum(ch)) {
2598 int t;
2599 cstr_reset(&tokcstr);
2600 /* after the first digit, accept digits, alpha, '.' or sign if
2601 prefixed by 'eEpP' */
2602 parse_num:
2603 for(;;) {
2604 t = ch;
2605 cstr_ccat(&tokcstr, ch);
2606 cinp();
2607 if (!(isnum(ch) || isid(ch) || ch == '.' ||
2608 ((ch == '+' || ch == '-') &&
2609 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
2610 break;
2612 /* We add a trailing '\0' to ease parsing */
2613 cstr_ccat(&tokcstr, '\0');
2614 tokc.cstr = &tokcstr;
2615 tok = TOK_PPNUM;
2616 } else if (ch == '.') {
2617 /* special dot handling because it can also start a number */
2618 cinp();
2619 if (isnum(ch)) {
2620 cstr_reset(&tokcstr);
2621 cstr_ccat(&tokcstr, '.');
2622 goto parse_num;
2624 if (ch == '.') {
2625 cinp();
2626 if (ch != '.')
2627 expect("'.'");
2628 cinp();
2629 tok = TOK_DOTS;
2630 } else {
2631 tok = '.';
2633 } else if (ch == '\'') {
2634 tok = TOK_CCHAR;
2635 char_const:
2636 minp();
2637 b = getq();
2638 /* this cast is needed if >= 128 */
2639 if (tok == TOK_CCHAR)
2640 b = (char)b;
2641 tokc.i = b;
2642 if (ch != '\'')
2643 expect("\'");
2644 minp();
2645 } else if (ch == '\"') {
2646 tok = TOK_STR;
2647 str_const:
2648 minp();
2649 cstr_reset(&tokcstr);
2650 while (ch != '\"') {
2651 b = getq();
2652 if (ch == CH_EOF)
2653 error("unterminated string");
2654 if (tok == TOK_STR)
2655 cstr_ccat(&tokcstr, b);
2656 else
2657 cstr_wccat(&tokcstr, b);
2659 if (tok == TOK_STR)
2660 cstr_ccat(&tokcstr, '\0');
2661 else
2662 cstr_wccat(&tokcstr, '\0');
2663 tokc.cstr = &tokcstr;
2664 minp();
2665 } else {
2666 q = tok_two_chars;
2667 /* two chars */
2668 tok = ch;
2669 cinp();
2670 while (*q) {
2671 if (*q == tok && q[1] == ch) {
2672 cinp();
2673 tok = q[2] & 0xff;
2674 /* three chars tests */
2675 if (tok == TOK_SHL || tok == TOK_SAR) {
2676 if (ch == '=') {
2677 tok = tok | 0x80;
2678 cinp();
2680 } else if (tok == TOK_DOTS) {
2681 if (ch != '.')
2682 error("parse error");
2683 cinp();
2685 return;
2687 q = q + 3;
2689 /* single char substitutions */
2690 if (tok == '<')
2691 tok = TOK_LT;
2692 else if (tok == '>')
2693 tok = TOK_GT;
2697 /* return next token without macro substitution. Can read input from
2698 macro_ptr buffer */
2699 static void next_nomacro(void)
2701 if (macro_ptr) {
2702 redo:
2703 tok = *macro_ptr;
2704 if (tok) {
2705 tok = tok_get(&macro_ptr, &tokc);
2706 if (tok == TOK_LINENUM) {
2707 file->line_num = tokc.i;
2708 goto redo;
2711 } else {
2712 next_nomacro1();
2716 /* substitute args in macro_str and return allocated string */
2717 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
2719 int *st, last_tok, t, notfirst;
2720 Sym *s;
2721 CValue cval;
2722 TokenString str;
2723 CString cstr;
2725 tok_str_new(&str);
2726 last_tok = 0;
2727 while(1) {
2728 t = tok_get(&macro_str, &cval);
2729 if (!t)
2730 break;
2731 if (t == '#') {
2732 /* stringize */
2733 t = tok_get(&macro_str, &cval);
2734 if (!t)
2735 break;
2736 s = sym_find2(args, t);
2737 if (s) {
2738 cstr_new(&cstr);
2739 st = (int *)s->c;
2740 notfirst = 0;
2741 while (*st) {
2742 if (notfirst)
2743 cstr_ccat(&cstr, ' ');
2744 t = tok_get(&st, &cval);
2745 cstr_cat(&cstr, get_tok_str(t, &cval));
2746 notfirst = 1;
2748 cstr_ccat(&cstr, '\0');
2749 #ifdef PP_DEBUG
2750 printf("stringize: %s\n", (char *)cstr.data);
2751 #endif
2752 /* add string */
2753 cval.cstr = &cstr;
2754 tok_str_add2(&str, TOK_STR, &cval);
2755 cstr_free(&cstr);
2756 } else {
2757 tok_str_add2(&str, t, &cval);
2759 } else if (t >= TOK_IDENT) {
2760 s = sym_find2(args, t);
2761 if (s) {
2762 st = (int *)s->c;
2763 /* if '##' is present before or after, no arg substitution */
2764 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
2765 /* special case for var arg macros : ## eats the
2766 ',' if empty VA_ARGS variable. */
2767 /* XXX: test of the ',' is not 100%
2768 reliable. should fix it to avoid security
2769 problems */
2770 if (gnu_ext && s->t &&
2771 last_tok == TOK_TWOSHARPS &&
2772 str.len >= 2 && str.str[str.len - 2] == ',') {
2773 if (*st == 0) {
2774 /* suppress ',' '##' */
2775 str.len -= 2;
2776 } else {
2777 /* suppress '##' and add variable */
2778 str.len--;
2779 goto add_var;
2781 } else {
2782 int t1;
2783 add_var:
2784 for(;;) {
2785 t1 = tok_get(&st, &cval);
2786 if (!t1)
2787 break;
2788 tok_str_add2(&str, t1, &cval);
2791 } else {
2792 macro_subst(&str, nested_list, st);
2794 } else {
2795 tok_str_add(&str, t);
2797 } else {
2798 tok_str_add2(&str, t, &cval);
2800 last_tok = t;
2802 tok_str_add(&str, 0);
2803 return str.str;
2806 /* handle the '##' operator */
2807 static int *macro_twosharps(void)
2809 TokenSym *ts;
2810 int *macro_ptr1;
2811 int t;
2812 const char *p1, *p2;
2813 CValue cval;
2814 TokenString macro_str1;
2815 CString cstr;
2817 cstr_new(&cstr);
2818 tok_str_new(&macro_str1);
2819 tok = 0;
2820 while (1) {
2821 next_nomacro();
2822 if (tok == 0)
2823 break;
2824 while (*macro_ptr == TOK_TWOSHARPS) {
2825 macro_ptr++;
2826 macro_ptr1 = macro_ptr;
2827 t = *macro_ptr;
2828 if (t) {
2829 t = tok_get(&macro_ptr, &cval);
2831 /* We concatenate the two tokens if we have an
2832 identifier or a preprocessing number */
2833 cstr_reset(&cstr);
2834 p1 = get_tok_str(tok, &tokc);
2835 cstr_cat(&cstr, p1);
2836 p2 = get_tok_str(t, &cval);
2837 cstr_cat(&cstr, p2);
2838 cstr_ccat(&cstr, '\0');
2840 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
2841 (t >= TOK_IDENT || t == TOK_PPNUM)) {
2842 if (tok == TOK_PPNUM) {
2843 /* if number, then create a number token */
2844 /* NOTE: no need to allocate because
2845 tok_str_add2() does it */
2846 tokc.cstr = &cstr;
2847 } else {
2848 /* if identifier, we must do a test to
2849 validate we have a correct identifier */
2850 if (t == TOK_PPNUM) {
2851 const char *p;
2852 int c;
2854 p = p2;
2855 for(;;) {
2856 c = *p;
2857 if (c == '\0')
2858 break;
2859 p++;
2860 if (!isnum(c) && !isid(c))
2861 goto error_pasting;
2864 ts = tok_alloc(cstr.data, strlen(cstr.data));
2865 tok = ts->tok; /* modify current token */
2867 } else {
2868 const char *str = cstr.data;
2869 const unsigned char *q;
2871 /* we look for a valid token */
2872 /* XXX: do more extensive checks */
2873 if (!strcmp(str, ">>=")) {
2874 tok = TOK_A_SAR;
2875 } else if (!strcmp(str, "<<=")) {
2876 tok = TOK_A_SHL;
2877 } else if (strlen(str) == 2) {
2878 /* search in two bytes table */
2879 q = tok_two_chars;
2880 for(;;) {
2881 if (!*q)
2882 goto error_pasting;
2883 if (q[0] == str[0] && q[1] == str[1])
2884 break;
2885 q += 3;
2887 tok = q[2];
2888 } else {
2889 error_pasting:
2890 /* NOTE: because get_tok_str use a static buffer,
2891 we must save it */
2892 cstr_reset(&cstr);
2893 p1 = get_tok_str(tok, &tokc);
2894 cstr_cat(&cstr, p1);
2895 cstr_ccat(&cstr, '\0');
2896 p2 = get_tok_str(t, &cval);
2897 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
2898 /* cannot merge tokens: just add them separately */
2899 tok_str_add2(&macro_str1, tok, &tokc);
2900 /* XXX: free associated memory ? */
2901 tok = t;
2902 tokc = cval;
2907 tok_str_add2(&macro_str1, tok, &tokc);
2909 cstr_free(&cstr);
2910 tok_str_add(&macro_str1, 0);
2911 return macro_str1.str;
2915 /* do macro substitution of current token with macro 's' and add
2916 result to (tok_str,tok_len). 'nested_list' is the list of all
2917 macros we got inside to avoid recursing. Return non zero if no
2918 substitution needs to be done */
2919 static int macro_subst_tok(TokenString *tok_str,
2920 Sym **nested_list, Sym *s)
2922 Sym *args, *sa, *sa1;
2923 int mstr_allocated, parlevel, *mstr, t;
2924 TokenString str;
2925 char *cstrval;
2926 CValue cval;
2927 CString cstr;
2929 /* if symbol is a macro, prepare substitution */
2930 /* if nested substitution, do nothing */
2931 if (sym_find2(*nested_list, tok))
2932 return -1;
2934 /* special macros */
2935 if (tok == TOK___LINE__) {
2936 cval.i = file->line_num;
2937 tok_str_add2(tok_str, TOK_CINT, &cval);
2938 } else if (tok == TOK___FILE__) {
2939 cstrval = file->filename;
2940 goto add_cstr;
2941 tok_str_add2(tok_str, TOK_STR, &cval);
2942 } else if (tok == TOK___DATE__) {
2943 cstrval = "Jan 1 2002";
2944 goto add_cstr;
2945 } else if (tok == TOK___TIME__) {
2946 cstrval = "00:00:00";
2947 add_cstr:
2948 cstr_new(&cstr);
2949 cstr_cat(&cstr, cstrval);
2950 cstr_ccat(&cstr, '\0');
2951 cval.cstr = &cstr;
2952 tok_str_add2(tok_str, TOK_STR, &cval);
2953 cstr_free(&cstr);
2954 } else {
2955 mstr = (int *)s->c;
2956 mstr_allocated = 0;
2957 if (s->t == MACRO_FUNC) {
2958 /* NOTE: we do not use next_nomacro to avoid eating the
2959 next token. XXX: find better solution */
2960 if (macro_ptr) {
2961 t = *macro_ptr;
2962 } else {
2963 while (is_space(ch) || ch == '\n')
2964 cinp();
2965 t = ch;
2967 if (t != '(') /* no macro subst */
2968 return -1;
2970 /* argument macro */
2971 next_nomacro();
2972 next_nomacro();
2973 args = NULL;
2974 sa = s->next;
2975 /* NOTE: empty args are allowed, except if no args */
2976 for(;;) {
2977 /* handle '()' case */
2978 if (!args && tok == ')')
2979 break;
2980 if (!sa)
2981 error("macro '%s' used with too many args",
2982 get_tok_str(s->v, 0));
2983 tok_str_new(&str);
2984 parlevel = 0;
2985 /* NOTE: non zero sa->t indicates VA_ARGS */
2986 while ((parlevel > 0 ||
2987 (tok != ')' &&
2988 (tok != ',' || sa->t))) &&
2989 tok != -1) {
2990 if (tok == '(')
2991 parlevel++;
2992 else if (tok == ')')
2993 parlevel--;
2994 tok_str_add2(&str, tok, &tokc);
2995 next_nomacro();
2997 tok_str_add(&str, 0);
2998 sym_push2(&args, sa->v & ~SYM_FIELD, sa->t, (int)str.str);
2999 sa = sa->next;
3000 if (tok == ')') {
3001 /* special case for gcc var args: add an empty
3002 var arg argument if it is omitted */
3003 if (sa && sa->t && gnu_ext)
3004 continue;
3005 else
3006 break;
3008 if (tok != ',')
3009 expect(",");
3010 next_nomacro();
3012 if (sa) {
3013 error("macro '%s' used with too few args",
3014 get_tok_str(s->v, 0));
3017 /* now subst each arg */
3018 mstr = macro_arg_subst(nested_list, mstr, args);
3019 /* free memory */
3020 sa = args;
3021 while (sa) {
3022 sa1 = sa->prev;
3023 tok_str_free((int *)sa->c);
3024 tcc_free(sa);
3025 sa = sa1;
3027 mstr_allocated = 1;
3029 sym_push2(nested_list, s->v, 0, 0);
3030 macro_subst(tok_str, nested_list, mstr);
3031 /* pop nested defined symbol */
3032 sa1 = *nested_list;
3033 *nested_list = sa1->prev;
3034 tcc_free(sa1);
3035 if (mstr_allocated)
3036 tok_str_free(mstr);
3038 return 0;
3041 /* do macro substitution of macro_str and add result to
3042 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3043 inside to avoid recursing. */
3044 static void macro_subst(TokenString *tok_str,
3045 Sym **nested_list, int *macro_str)
3047 Sym *s;
3048 int *saved_macro_ptr;
3049 int *macro_str1;
3051 saved_macro_ptr = macro_ptr;
3052 macro_ptr = macro_str;
3053 /* first scan for '##' operator handling */
3054 macro_str1 = macro_twosharps();
3055 macro_ptr = macro_str1;
3057 while (1) {
3058 next_nomacro();
3059 if (tok == 0)
3060 break;
3061 s = sym_find1(&define_stack, tok);
3062 if (s != NULL) {
3063 if (macro_subst_tok(tok_str, nested_list, s) != 0)
3064 goto no_subst;
3065 } else {
3066 no_subst:
3067 tok_str_add2(tok_str, tok, &tokc);
3070 macro_ptr = saved_macro_ptr;
3071 tok_str_free(macro_str1);
3074 /* return next token with macro substitution */
3075 static void next(void)
3077 Sym *nested_list, *s;
3078 TokenString str;
3080 /* special 'ungettok' case for label parsing */
3081 if (tok1) {
3082 tok = tok1;
3083 tokc = tok1c;
3084 tok1 = 0;
3085 } else {
3086 redo:
3087 next_nomacro();
3088 if (!macro_ptr) {
3089 /* if not reading from macro substituted string, then try
3090 to substitute macros */
3091 if (tok >= TOK_IDENT) {
3092 s = sym_find1(&define_stack, tok);
3093 if (s) {
3094 /* we have a macro: we try to substitute */
3095 tok_str_new(&str);
3096 nested_list = NULL;
3097 if (macro_subst_tok(&str, &nested_list, s) == 0) {
3098 /* substitution done, NOTE: maybe empty */
3099 tok_str_add(&str, 0);
3100 macro_ptr = str.str;
3101 macro_ptr_allocated = str.str;
3102 goto redo;
3106 } else {
3107 if (tok == 0) {
3108 /* end of macro string: free it */
3109 tok_str_free(macro_ptr_allocated);
3110 macro_ptr = NULL;
3111 goto redo;
3115 /* convert preprocessor tokens into C tokens */
3116 if (tok == TOK_PPNUM) {
3117 parse_number((char *)tokc.cstr->data);
3120 #if defined(DEBUG)
3121 printf("token = %s\n", get_tok_str(tok, &tokc));
3122 #endif
3125 void swap(int *p, int *q)
3127 int t;
3128 t = *p;
3129 *p = *q;
3130 *q = t;
3133 void vsetc(int t, int r, CValue *vc)
3135 int v;
3137 if (vtop >= vstack + VSTACK_SIZE)
3138 error("memory full");
3139 /* cannot let cpu flags if other instruction are generated. Also
3140 avoid leaving VT_JMP anywhere except on the top of the stack
3141 because it would complicate the code generator. */
3142 if (vtop >= vstack) {
3143 v = vtop->r & VT_VALMASK;
3144 if (v == VT_CMP || (v & ~1) == VT_JMP)
3145 gv(RC_INT);
3147 vtop++;
3148 vtop->t = t;
3149 vtop->r = r;
3150 vtop->r2 = VT_CONST;
3151 vtop->c = *vc;
3154 /* push integer constant */
3155 void vpushi(int v)
3157 CValue cval;
3158 cval.i = v;
3159 vsetc(VT_INT, VT_CONST, &cval);
3162 /* Return a static symbol pointing to a section */
3163 static Sym *get_sym_ref(int t, Section *sec,
3164 unsigned long offset, unsigned long size)
3166 int v;
3167 Sym *sym;
3169 v = anon_sym++;
3170 sym = sym_push1(&global_stack, v, t | VT_STATIC, 0);
3171 sym->r = VT_CONST | VT_SYM;
3172 put_extern_sym(sym, sec, offset, size);
3173 return sym;
3176 /* push a reference to a section offset by adding a dummy symbol */
3177 static void vpush_ref(int t, Section *sec, unsigned long offset, unsigned long size)
3179 CValue cval;
3181 cval.ul = 0;
3182 vsetc(t, VT_CONST | VT_SYM, &cval);
3183 vtop->sym = get_sym_ref(t, sec, offset, size);
3186 /* define a new external reference to a symbol 'v' of type 'u' */
3187 static Sym *external_global_sym(int v, int u, int r)
3189 Sym *s;
3191 s = sym_find(v);
3192 if (!s) {
3193 /* push forward reference */
3194 s = sym_push1(&global_stack,
3195 v, u | VT_EXTERN, 0);
3196 s->r = r | VT_CONST | VT_SYM;
3198 return s;
3201 /* define a new external reference to a symbol 'v' of type 'u' */
3202 static Sym *external_sym(int v, int u, int r)
3204 Sym *s;
3206 s = sym_find(v);
3207 if (!s) {
3208 /* push forward reference */
3209 s = sym_push(v, u | VT_EXTERN, r | VT_CONST | VT_SYM, 0);
3211 return s;
3214 /* push a reference to global symbol v */
3215 static void vpush_global_sym(int t, int v)
3217 Sym *sym;
3218 CValue cval;
3220 sym = external_global_sym(v, t, 0);
3221 cval.ul = 0;
3222 vsetc(t, VT_CONST | VT_SYM, &cval);
3223 vtop->sym = sym;
3226 void vset(int t, int r, int v)
3228 CValue cval;
3230 cval.i = v;
3231 vsetc(t, r, &cval);
3234 void vswap(void)
3236 SValue tmp;
3238 tmp = vtop[0];
3239 vtop[0] = vtop[-1];
3240 vtop[-1] = tmp;
3243 void vpushv(SValue *v)
3245 if (vtop >= vstack + VSTACK_SIZE)
3246 error("memory full");
3247 vtop++;
3248 *vtop = *v;
3251 void vdup(void)
3253 vpushv(vtop);
3256 /* save r to the memory stack, and mark it as being free */
3257 void save_reg(int r)
3259 int l, saved, t, size, align;
3260 SValue *p, sv;
3262 /* modify all stack values */
3263 saved = 0;
3264 l = 0;
3265 for(p=vstack;p<=vtop;p++) {
3266 if ((p->r & VT_VALMASK) == r ||
3267 (p->r2 & VT_VALMASK) == r) {
3268 /* must save value on stack if not already done */
3269 if (!saved) {
3270 /* NOTE: must reload 'r' because r might be equal to r2 */
3271 r = p->r & VT_VALMASK;
3272 /* store register in the stack */
3273 t = p->t;
3274 if ((p->r & VT_LVAL) ||
3275 (!is_float(t) && (t & VT_BTYPE) != VT_LLONG))
3276 t = VT_INT;
3277 size = type_size(t, &align);
3278 loc = (loc - size) & -align;
3279 sv.t = t;
3280 sv.r = VT_LOCAL | VT_LVAL;
3281 sv.c.ul = loc;
3282 store(r, &sv);
3283 #ifdef TCC_TARGET_I386
3284 /* x86 specific: need to pop fp register ST0 if saved */
3285 if (r == REG_ST0) {
3286 o(0xd9dd); /* fstp %st(1) */
3288 #endif
3289 /* special long long case */
3290 if ((t & VT_BTYPE) == VT_LLONG) {
3291 sv.c.ul += 4;
3292 store(p->r2, &sv);
3294 l = loc;
3295 saved = 1;
3297 /* mark that stack entry as being saved on the stack */
3298 if (p->r & VT_LVAL) {
3299 /* also suppress the bounded flag because the
3300 relocation address of the function was stored in
3301 p->c.ul */
3302 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
3303 } else {
3304 p->r = lvalue_type(p->t) | VT_LOCAL;
3306 p->r2 = VT_CONST;
3307 p->c.ul = l;
3312 /* find a free register of class 'rc'. If none, save one register */
3313 int get_reg(int rc)
3315 int r;
3316 SValue *p;
3318 /* find a free register */
3319 for(r=0;r<NB_REGS;r++) {
3320 if (reg_classes[r] & rc) {
3321 for(p=vstack;p<=vtop;p++) {
3322 if ((p->r & VT_VALMASK) == r ||
3323 (p->r2 & VT_VALMASK) == r)
3324 goto notfound;
3326 return r;
3328 notfound: ;
3331 /* no register left : free the first one on the stack (VERY
3332 IMPORTANT to start from the bottom to ensure that we don't
3333 spill registers used in gen_opi()) */
3334 for(p=vstack;p<=vtop;p++) {
3335 r = p->r & VT_VALMASK;
3336 if (r < VT_CONST && (reg_classes[r] & rc))
3337 goto save_found;
3338 /* also look at second register (if long long) */
3339 r = p->r2 & VT_VALMASK;
3340 if (r < VT_CONST && (reg_classes[r] & rc)) {
3341 save_found:
3342 save_reg(r);
3343 return r;
3346 /* Should never comes here */
3347 return -1;
3350 /* save registers up to (vtop - n) stack entry */
3351 void save_regs(int n)
3353 int r;
3354 SValue *p, *p1;
3355 p1 = vtop - n;
3356 for(p = vstack;p <= p1; p++) {
3357 r = p->r & VT_VALMASK;
3358 if (r < VT_CONST) {
3359 save_reg(r);
3364 /* move register 's' to 'r', and flush previous value of r to memory
3365 if needed */
3366 void move_reg(int r, int s)
3368 SValue sv;
3370 if (r != s) {
3371 save_reg(r);
3372 sv.t = VT_INT;
3373 sv.r = s;
3374 sv.c.ul = 0;
3375 load(r, &sv);
3379 /* get address of vtop (vtop MUST BE an lvalue) */
3380 void gaddrof(void)
3382 vtop->r &= ~VT_LVAL;
3383 /* tricky: if saved lvalue, then we can go back to lvalue */
3384 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
3385 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
3388 #ifdef CONFIG_TCC_BCHECK
3389 /* generate lvalue bound code */
3390 void gbound(void)
3392 int lval_type, t1;
3394 vtop->r &= ~VT_MUSTBOUND;
3395 /* if lvalue, then use checking code before dereferencing */
3396 if (vtop->r & VT_LVAL) {
3397 /* if not VT_BOUNDED value, then make one */
3398 if (!(vtop->r & VT_BOUNDED)) {
3399 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
3400 /* must save type because we must set it to int to get pointer */
3401 t1 = vtop->t;
3402 vtop->t = VT_INT;
3403 gaddrof();
3404 vpushi(0);
3405 gen_bounded_ptr_add();
3406 vtop->r |= lval_type;
3407 vtop->t = t1;
3409 /* then check for dereferencing */
3410 gen_bounded_ptr_deref();
3413 #endif
3415 /* store vtop a register belonging to class 'rc'. lvalues are
3416 converted to values. Cannot be used if cannot be converted to
3417 register value (such as structures). */
3418 int gv(int rc)
3420 int r, r2, rc2, bit_pos, bit_size, size, align, i;
3421 unsigned long long ll;
3423 /* NOTE: get_reg can modify vstack[] */
3424 if (vtop->t & VT_BITFIELD) {
3425 bit_pos = (vtop->t >> VT_STRUCT_SHIFT) & 0x3f;
3426 bit_size = (vtop->t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
3427 /* remove bit field info to avoid loops */
3428 vtop->t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
3429 /* generate shifts */
3430 vpushi(32 - (bit_pos + bit_size));
3431 gen_op(TOK_SHL);
3432 vpushi(32 - bit_size);
3433 /* NOTE: transformed to SHR if unsigned */
3434 gen_op(TOK_SAR);
3435 r = gv(rc);
3436 } else {
3437 if (is_float(vtop->t) &&
3438 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3439 Sym *sym;
3440 int *ptr;
3441 unsigned long offset;
3443 /* XXX: unify with initializers handling ? */
3444 /* CPUs usually cannot use float constants, so we store them
3445 generically in data segment */
3446 size = type_size(vtop->t, &align);
3447 offset = (data_section->data_offset + align - 1) & -align;
3448 data_section->data_offset = offset;
3449 /* XXX: not portable yet */
3450 ptr = section_ptr_add(data_section, size);
3451 size = size >> 2;
3452 for(i=0;i<size;i++)
3453 ptr[i] = vtop->c.tab[i];
3454 sym = get_sym_ref(vtop->t, data_section, offset, size << 2);
3455 vtop->r |= VT_LVAL | VT_SYM;
3456 vtop->sym = sym;
3457 vtop->c.ul = 0;
3459 #ifdef CONFIG_TCC_BCHECK
3460 if (vtop->r & VT_MUSTBOUND)
3461 gbound();
3462 #endif
3464 r = vtop->r & VT_VALMASK;
3465 /* need to reload if:
3466 - constant
3467 - lvalue (need to dereference pointer)
3468 - already a register, but not in the right class */
3469 if (r >= VT_CONST ||
3470 (vtop->r & VT_LVAL) ||
3471 !(reg_classes[r] & rc) ||
3472 ((vtop->t & VT_BTYPE) == VT_LLONG &&
3473 !(reg_classes[vtop->r2] & rc))) {
3474 r = get_reg(rc);
3475 if ((vtop->t & VT_BTYPE) == VT_LLONG) {
3476 /* two register type load : expand to two words
3477 temporarily */
3478 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3479 /* load constant */
3480 ll = vtop->c.ull;
3481 vtop->c.ui = ll; /* first word */
3482 load(r, vtop);
3483 vtop->r = r; /* save register value */
3484 vpushi(ll >> 32); /* second word */
3485 } else if (r >= VT_CONST ||
3486 (vtop->r & VT_LVAL)) {
3487 /* load from memory */
3488 load(r, vtop);
3489 vdup();
3490 vtop[-1].r = r; /* save register value */
3491 /* increment pointer to get second word */
3492 vtop->t = VT_INT;
3493 gaddrof();
3494 vpushi(4);
3495 gen_op('+');
3496 vtop->r |= VT_LVAL;
3497 } else {
3498 /* move registers */
3499 load(r, vtop);
3500 vdup();
3501 vtop[-1].r = r; /* save register value */
3502 vtop->r = vtop[-1].r2;
3504 /* allocate second register */
3505 rc2 = RC_INT;
3506 if (rc == RC_IRET)
3507 rc2 = RC_LRET;
3508 r2 = get_reg(rc2);
3509 load(r2, vtop);
3510 vpop();
3511 /* write second register */
3512 vtop->r2 = r2;
3513 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->t)) {
3514 int t1, t;
3515 /* lvalue of scalar type : need to use lvalue type
3516 because of possible cast */
3517 t = vtop->t;
3518 t1 = t;
3519 /* compute memory access type */
3520 if (vtop->r & VT_LVAL_BYTE)
3521 t = VT_BYTE;
3522 else if (vtop->r & VT_LVAL_SHORT)
3523 t = VT_SHORT;
3524 if (vtop->r & VT_LVAL_UNSIGNED)
3525 t |= VT_UNSIGNED;
3526 vtop->t = t;
3527 load(r, vtop);
3528 /* restore wanted type */
3529 vtop->t = t1;
3530 } else {
3531 /* one register type load */
3532 load(r, vtop);
3535 vtop->r = r;
3537 return r;
3540 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3541 void gv2(int rc1, int rc2)
3543 int v;
3545 /* generate more generic register first. But VT_JMP or VT_CMP
3546 values must be generated first in all cases to avoid possible
3547 reload errors */
3548 v = vtop[0].r & VT_VALMASK;
3549 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
3550 vswap();
3551 gv(rc1);
3552 vswap();
3553 gv(rc2);
3554 /* test if reload is needed for first register */
3555 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
3556 vswap();
3557 gv(rc1);
3558 vswap();
3560 } else {
3561 gv(rc2);
3562 vswap();
3563 gv(rc1);
3564 vswap();
3565 /* test if reload is needed for first register */
3566 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
3567 gv(rc2);
3572 /* expand long long on stack in two int registers */
3573 void lexpand(void)
3575 int u;
3577 u = vtop->t & VT_UNSIGNED;
3578 gv(RC_INT);
3579 vdup();
3580 vtop[0].r = vtop[-1].r2;
3581 vtop[0].r2 = VT_CONST;
3582 vtop[-1].r2 = VT_CONST;
3583 vtop[0].t = VT_INT | u;
3584 vtop[-1].t = VT_INT | u;
3587 /* build a long long from two ints */
3588 void lbuild(int t)
3590 gv2(RC_INT, RC_INT);
3591 vtop[-1].r2 = vtop[0].r;
3592 vtop[-1].t = t;
3593 vpop();
3596 /* rotate n first stack elements to the bottom */
3597 void vrotb(int n)
3599 int i;
3600 SValue tmp;
3602 tmp = vtop[-n + 1];
3603 for(i=-n+1;i!=0;i++)
3604 vtop[i] = vtop[i+1];
3605 vtop[0] = tmp;
3608 /* pop stack value */
3609 void vpop(void)
3611 int v;
3612 v = vtop->r & VT_VALMASK;
3613 #ifdef TCC_TARGET_I386
3614 /* for x86, we need to pop the FP stack */
3615 if (v == REG_ST0 && !nocode_wanted) {
3616 o(0xd9dd); /* fstp %st(1) */
3617 } else
3618 #endif
3619 if (v == VT_JMP || v == VT_JMPI) {
3620 /* need to put correct jump if && or || without test */
3621 gsym(vtop->c.ul);
3623 vtop--;
3626 /* convert stack entry to register and duplicate its value in another
3627 register */
3628 void gv_dup(void)
3630 int rc, t, r, r1;
3631 SValue sv;
3633 t = vtop->t;
3634 if ((t & VT_BTYPE) == VT_LLONG) {
3635 lexpand();
3636 gv_dup();
3637 vswap();
3638 vrotb(3);
3639 gv_dup();
3640 vrotb(4);
3641 /* stack: H L L1 H1 */
3642 lbuild(t);
3643 vrotb(3);
3644 vrotb(3);
3645 vswap();
3646 lbuild(t);
3647 vswap();
3648 } else {
3649 /* duplicate value */
3650 rc = RC_INT;
3651 sv.t = VT_INT;
3652 if (is_float(t)) {
3653 rc = RC_FLOAT;
3654 sv.t = t;
3656 r = gv(rc);
3657 r1 = get_reg(rc);
3658 sv.r = r;
3659 sv.c.ul = 0;
3660 load(r1, &sv); /* move r to r1 */
3661 vdup();
3662 /* duplicates value */
3663 vtop->r = r1;
3667 /* generate CPU independent (unsigned) long long operations */
3668 void gen_opl(int op)
3670 int t, a, b, op1, c, i;
3671 int func;
3672 GFuncContext gf;
3673 SValue tmp;
3675 switch(op) {
3676 case '/':
3677 case TOK_PDIV:
3678 func = TOK___divdi3;
3679 goto gen_func;
3680 case TOK_UDIV:
3681 func = TOK___udivdi3;
3682 goto gen_func;
3683 case '%':
3684 func = TOK___moddi3;
3685 goto gen_func;
3686 case TOK_UMOD:
3687 func = TOK___umoddi3;
3688 gen_func:
3689 /* call generic long long function */
3690 gfunc_start(&gf, FUNC_CDECL);
3691 gfunc_param(&gf);
3692 gfunc_param(&gf);
3693 vpush_global_sym(func_old_type, func);
3694 gfunc_call(&gf);
3695 vpushi(0);
3696 vtop->r = REG_IRET;
3697 vtop->r2 = REG_LRET;
3698 break;
3699 case '^':
3700 case '&':
3701 case '|':
3702 case '*':
3703 case '+':
3704 case '-':
3705 t = vtop->t;
3706 vswap();
3707 lexpand();
3708 vrotb(3);
3709 lexpand();
3710 /* stack: L1 H1 L2 H2 */
3711 tmp = vtop[0];
3712 vtop[0] = vtop[-3];
3713 vtop[-3] = tmp;
3714 tmp = vtop[-2];
3715 vtop[-2] = vtop[-3];
3716 vtop[-3] = tmp;
3717 vswap();
3718 /* stack: H1 H2 L1 L2 */
3719 if (op == '*') {
3720 vpushv(vtop - 1);
3721 vpushv(vtop - 1);
3722 gen_op(TOK_UMULL);
3723 lexpand();
3724 /* stack: H1 H2 L1 L2 ML MH */
3725 for(i=0;i<4;i++)
3726 vrotb(6);
3727 /* stack: ML MH H1 H2 L1 L2 */
3728 tmp = vtop[0];
3729 vtop[0] = vtop[-2];
3730 vtop[-2] = tmp;
3731 /* stack: ML MH H1 L2 H2 L1 */
3732 gen_op('*');
3733 vrotb(3);
3734 vrotb(3);
3735 gen_op('*');
3736 /* stack: ML MH M1 M2 */
3737 gen_op('+');
3738 gen_op('+');
3739 } else if (op == '+' || op == '-') {
3740 /* XXX: add non carry method too (for MIPS or alpha) */
3741 if (op == '+')
3742 op1 = TOK_ADDC1;
3743 else
3744 op1 = TOK_SUBC1;
3745 gen_op(op1);
3746 /* stack: H1 H2 (L1 op L2) */
3747 vrotb(3);
3748 vrotb(3);
3749 gen_op(op1 + 1); /* TOK_xxxC2 */
3750 } else {
3751 gen_op(op);
3752 /* stack: H1 H2 (L1 op L2) */
3753 vrotb(3);
3754 vrotb(3);
3755 /* stack: (L1 op L2) H1 H2 */
3756 gen_op(op);
3757 /* stack: (L1 op L2) (H1 op H2) */
3759 /* stack: L H */
3760 lbuild(t);
3761 break;
3762 case TOK_SAR:
3763 case TOK_SHR:
3764 case TOK_SHL:
3765 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3766 t = vtop[-1].t;
3767 vswap();
3768 lexpand();
3769 vrotb(3);
3770 /* stack: L H shift */
3771 c = (int)vtop->c.i;
3772 /* constant: simpler */
3773 /* NOTE: all comments are for SHL. the other cases are
3774 done by swaping words */
3775 vpop();
3776 if (op != TOK_SHL)
3777 vswap();
3778 if (c >= 32) {
3779 /* stack: L H */
3780 vpop();
3781 if (c > 32) {
3782 vpushi(c - 32);
3783 gen_op(op);
3785 if (op != TOK_SAR) {
3786 vpushi(0);
3787 } else {
3788 gv_dup();
3789 vpushi(31);
3790 gen_op(TOK_SAR);
3792 vswap();
3793 } else {
3794 vswap();
3795 gv_dup();
3796 /* stack: H L L */
3797 vpushi(c);
3798 gen_op(op);
3799 vswap();
3800 vpushi(32 - c);
3801 if (op == TOK_SHL)
3802 gen_op(TOK_SHR);
3803 else
3804 gen_op(TOK_SHL);
3805 vrotb(3);
3806 /* stack: L L H */
3807 vpushi(c);
3808 if (op == TOK_SHL)
3809 gen_op(TOK_SHL);
3810 else
3811 gen_op(TOK_SHR);
3812 gen_op('|');
3814 if (op != TOK_SHL)
3815 vswap();
3816 lbuild(t);
3817 } else {
3818 /* XXX: should provide a faster fallback on x86 ? */
3819 switch(op) {
3820 case TOK_SAR:
3821 func = TOK___sardi3;
3822 goto gen_func;
3823 case TOK_SHR:
3824 func = TOK___shrdi3;
3825 goto gen_func;
3826 case TOK_SHL:
3827 func = TOK___shldi3;
3828 goto gen_func;
3831 break;
3832 default:
3833 /* compare operations */
3834 t = vtop->t;
3835 vswap();
3836 lexpand();
3837 vrotb(3);
3838 lexpand();
3839 /* stack: L1 H1 L2 H2 */
3840 tmp = vtop[-1];
3841 vtop[-1] = vtop[-2];
3842 vtop[-2] = tmp;
3843 /* stack: L1 L2 H1 H2 */
3844 /* compare high */
3845 op1 = op;
3846 /* when values are equal, we need to compare low words. since
3847 the jump is inverted, we invert the test too. */
3848 if (op1 == TOK_LT)
3849 op1 = TOK_LE;
3850 else if (op1 == TOK_GT)
3851 op1 = TOK_GE;
3852 else if (op1 == TOK_ULT)
3853 op1 = TOK_ULE;
3854 else if (op1 == TOK_UGT)
3855 op1 = TOK_UGE;
3856 a = 0;
3857 b = 0;
3858 gen_op(op1);
3859 if (op1 != TOK_NE) {
3860 a = gtst(1, 0);
3862 if (op != TOK_EQ) {
3863 /* generate non equal test */
3864 /* XXX: NOT PORTABLE yet */
3865 if (a == 0) {
3866 b = gtst(0, 0);
3867 } else {
3868 #ifdef TCC_TARGET_I386
3869 b = psym(0x850f, 0);
3870 #else
3871 error("not implemented");
3872 #endif
3875 /* compare low */
3876 gen_op(op);
3877 a = gtst(1, a);
3878 gsym(b);
3879 vset(VT_INT, VT_JMPI, a);
3880 break;
3884 /* handle integer constant optimizations and various machine
3885 independant opt */
3886 void gen_opic(int op)
3888 int fc, c1, c2, n;
3889 SValue *v1, *v2;
3891 v1 = vtop - 1;
3892 v2 = vtop;
3893 /* currently, we cannot do computations with forward symbols */
3894 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3895 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3896 if (c1 && c2) {
3897 fc = v2->c.i;
3898 switch(op) {
3899 case '+': v1->c.i += fc; break;
3900 case '-': v1->c.i -= fc; break;
3901 case '&': v1->c.i &= fc; break;
3902 case '^': v1->c.i ^= fc; break;
3903 case '|': v1->c.i |= fc; break;
3904 case '*': v1->c.i *= fc; break;
3906 case TOK_PDIV:
3907 case '/':
3908 case '%':
3909 case TOK_UDIV:
3910 case TOK_UMOD:
3911 /* if division by zero, generate explicit division */
3912 if (fc == 0) {
3913 if (const_wanted)
3914 error("division by zero in constant");
3915 goto general_case;
3917 switch(op) {
3918 default: v1->c.i /= fc; break;
3919 case '%': v1->c.i %= fc; break;
3920 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
3921 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
3923 break;
3924 case TOK_SHL: v1->c.i <<= fc; break;
3925 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
3926 case TOK_SAR: v1->c.i >>= fc; break;
3927 /* tests */
3928 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
3929 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
3930 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
3931 case TOK_NE: v1->c.i = v1->c.i != fc; break;
3932 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
3933 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
3934 case TOK_LT: v1->c.i = v1->c.i < fc; break;
3935 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
3936 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
3937 case TOK_GT: v1->c.i = v1->c.i > fc; break;
3938 /* logical */
3939 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
3940 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
3941 default:
3942 goto general_case;
3944 vtop--;
3945 } else {
3946 /* if commutative ops, put c2 as constant */
3947 if (c1 && (op == '+' || op == '&' || op == '^' ||
3948 op == '|' || op == '*')) {
3949 vswap();
3950 swap(&c1, &c2);
3952 fc = vtop->c.i;
3953 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
3954 op == TOK_PDIV) &&
3955 fc == 1) ||
3956 ((op == '+' || op == '-' || op == '|' || op == '^' ||
3957 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
3958 fc == 0) ||
3959 (op == '&' &&
3960 fc == -1))) {
3961 /* nothing to do */
3962 vtop--;
3963 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
3964 /* try to use shifts instead of muls or divs */
3965 if (fc > 0 && (fc & (fc - 1)) == 0) {
3966 n = -1;
3967 while (fc) {
3968 fc >>= 1;
3969 n++;
3971 vtop->c.i = n;
3972 if (op == '*')
3973 op = TOK_SHL;
3974 else if (op == TOK_PDIV)
3975 op = TOK_SAR;
3976 else
3977 op = TOK_SHR;
3979 goto general_case;
3980 } else if (c2 && (op == '+' || op == '-') &&
3981 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
3982 (VT_CONST | VT_SYM)) {
3983 /* symbol + constant case */
3984 if (op == '-')
3985 fc = -fc;
3986 vtop--;
3987 vtop->c.i += fc;
3988 } else {
3989 general_case:
3990 if (!nocode_wanted) {
3991 /* call low level op generator */
3992 gen_opi(op);
3993 } else {
3994 vtop--;
4000 /* generate a floating point operation with constant propagation */
4001 void gen_opif(int op)
4003 int c1, c2;
4004 SValue *v1, *v2;
4005 long double f1, f2;
4007 v1 = vtop - 1;
4008 v2 = vtop;
4009 /* currently, we cannot do computations with forward symbols */
4010 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4011 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4012 if (c1 && c2) {
4013 if (v1->t == VT_FLOAT) {
4014 f1 = v1->c.f;
4015 f2 = v2->c.f;
4016 } else if (v1->t == VT_DOUBLE) {
4017 f1 = v1->c.d;
4018 f2 = v2->c.d;
4019 } else {
4020 f1 = v1->c.ld;
4021 f2 = v2->c.ld;
4024 /* NOTE: we only do constant propagation if finite number (not
4025 NaN or infinity) (ANSI spec) */
4026 if (!ieee_finite(f1) || !ieee_finite(f2))
4027 goto general_case;
4029 switch(op) {
4030 case '+': f1 += f2; break;
4031 case '-': f1 -= f2; break;
4032 case '*': f1 *= f2; break;
4033 case '/':
4034 if (f2 == 0.0) {
4035 if (const_wanted)
4036 error("division by zero in constant");
4037 goto general_case;
4039 f1 /= f2;
4040 break;
4041 /* XXX: also handles tests ? */
4042 default:
4043 goto general_case;
4045 /* XXX: overflow test ? */
4046 if (v1->t == VT_FLOAT) {
4047 v1->c.f = f1;
4048 } else if (v1->t == VT_DOUBLE) {
4049 v1->c.d = f1;
4050 } else {
4051 v1->c.ld = f1;
4053 vtop--;
4054 } else {
4055 general_case:
4056 if (!nocode_wanted) {
4057 gen_opf(op);
4058 } else {
4059 vtop--;
4064 int pointed_size(int t)
4066 return type_size(pointed_type(t), &t);
4069 #if 0
4070 void check_pointer_types(SValue *p1, SValue *p2)
4072 char buf1[256], buf2[256];
4073 int t1, t2;
4074 t1 = p1->t;
4075 t2 = p2->t;
4076 if (!is_compatible_types(t1, t2)) {
4077 type_to_str(buf1, sizeof(buf1), t1, NULL);
4078 type_to_str(buf2, sizeof(buf2), t2, NULL);
4079 error("incompatible pointers '%s' and '%s'", buf1, buf2);
4082 #endif
4084 /* generic gen_op: handles types problems */
4085 void gen_op(int op)
4087 int u, t1, t2, bt1, bt2, t;
4089 t1 = vtop[-1].t;
4090 t2 = vtop[0].t;
4091 bt1 = t1 & VT_BTYPE;
4092 bt2 = t2 & VT_BTYPE;
4094 if (bt1 == VT_PTR || bt2 == VT_PTR) {
4095 /* at least one operand is a pointer */
4096 /* relationnal op: must be both pointers */
4097 if (op >= TOK_ULT && op <= TOK_GT) {
4098 // check_pointer_types(vtop, vtop - 1);
4099 /* pointers are handled are unsigned */
4100 t = VT_INT | VT_UNSIGNED;
4101 goto std_op;
4103 /* if both pointers, then it must be the '-' op */
4104 if ((t1 & VT_BTYPE) == VT_PTR &&
4105 (t2 & VT_BTYPE) == VT_PTR) {
4106 if (op != '-')
4107 error("cannot use pointers here");
4108 // check_pointer_types(vtop - 1, vtop);
4109 /* XXX: check that types are compatible */
4110 u = pointed_size(t1);
4111 gen_opic(op);
4112 /* set to integer type */
4113 vtop->t = VT_INT;
4114 vpushi(u);
4115 gen_op(TOK_PDIV);
4116 } else {
4117 /* exactly one pointer : must be '+' or '-'. */
4118 if (op != '-' && op != '+')
4119 error("cannot use pointers here");
4120 /* Put pointer as first operand */
4121 if ((t2 & VT_BTYPE) == VT_PTR) {
4122 vswap();
4123 swap(&t1, &t2);
4125 /* XXX: cast to int ? (long long case) */
4126 vpushi(pointed_size(vtop[-1].t));
4127 gen_op('*');
4128 #ifdef CONFIG_TCC_BCHECK
4129 /* if evaluating constant expression, no code should be
4130 generated, so no bound check */
4131 if (do_bounds_check && !const_wanted) {
4132 /* if bounded pointers, we generate a special code to
4133 test bounds */
4134 if (op == '-') {
4135 vpushi(0);
4136 vswap();
4137 gen_op('-');
4139 gen_bounded_ptr_add();
4140 } else
4141 #endif
4143 gen_opic(op);
4145 /* put again type if gen_opic() swaped operands */
4146 vtop->t = t1;
4148 } else if (is_float(bt1) || is_float(bt2)) {
4149 /* compute bigger type and do implicit casts */
4150 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4151 t = VT_LDOUBLE;
4152 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4153 t = VT_DOUBLE;
4154 } else {
4155 t = VT_FLOAT;
4157 /* floats can only be used for a few operations */
4158 if (op != '+' && op != '-' && op != '*' && op != '/' &&
4159 (op < TOK_ULT || op > TOK_GT))
4160 error("invalid operands for binary operation");
4161 goto std_op;
4162 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4163 /* cast to biggest op */
4164 t = VT_LLONG;
4165 /* convert to unsigned if it does not fit in a long long */
4166 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4167 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4168 t |= VT_UNSIGNED;
4169 goto std_op;
4170 } else {
4171 /* integer operations */
4172 t = VT_INT;
4173 /* convert to unsigned if it does not fit in an integer */
4174 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4175 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4176 t |= VT_UNSIGNED;
4177 std_op:
4178 /* XXX: currently, some unsigned operations are explicit, so
4179 we modify them here */
4180 if (t & VT_UNSIGNED) {
4181 if (op == TOK_SAR)
4182 op = TOK_SHR;
4183 else if (op == '/')
4184 op = TOK_UDIV;
4185 else if (op == '%')
4186 op = TOK_UMOD;
4187 else if (op == TOK_LT)
4188 op = TOK_ULT;
4189 else if (op == TOK_GT)
4190 op = TOK_UGT;
4191 else if (op == TOK_LE)
4192 op = TOK_ULE;
4193 else if (op == TOK_GE)
4194 op = TOK_UGE;
4196 vswap();
4197 gen_cast(t);
4198 vswap();
4199 /* special case for shifts and long long: we keep the shift as
4200 an integer */
4201 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
4202 gen_cast(VT_INT);
4203 else
4204 gen_cast(t);
4205 if (is_float(t))
4206 gen_opif(op);
4207 else if ((t & VT_BTYPE) == VT_LLONG)
4208 gen_opl(op);
4209 else
4210 gen_opic(op);
4211 if (op >= TOK_ULT && op <= TOK_GT) {
4212 /* relationnal op: the result is an int */
4213 vtop->t = VT_INT;
4214 } else {
4215 vtop->t = t;
4220 /* generic itof for unsigned long long case */
4221 void gen_cvt_itof1(int t)
4223 GFuncContext gf;
4225 if ((vtop->t & (VT_BTYPE | VT_UNSIGNED)) ==
4226 (VT_LLONG | VT_UNSIGNED)) {
4228 gfunc_start(&gf, FUNC_CDECL);
4229 gfunc_param(&gf);
4230 if (t == VT_FLOAT)
4231 vpush_global_sym(func_old_type, TOK___ulltof);
4232 else if (t == VT_DOUBLE)
4233 vpush_global_sym(func_old_type, TOK___ulltod);
4234 else
4235 vpush_global_sym(func_old_type, TOK___ulltold);
4236 gfunc_call(&gf);
4237 vpushi(0);
4238 vtop->r = REG_FRET;
4239 } else {
4240 gen_cvt_itof(t);
4244 /* generic ftoi for unsigned long long case */
4245 void gen_cvt_ftoi1(int t)
4247 GFuncContext gf;
4248 int st;
4250 if (t == (VT_LLONG | VT_UNSIGNED)) {
4251 /* not handled natively */
4252 gfunc_start(&gf, FUNC_CDECL);
4253 st = vtop->t & VT_BTYPE;
4254 gfunc_param(&gf);
4255 if (st == VT_FLOAT)
4256 vpush_global_sym(func_old_type, TOK___fixunssfdi);
4257 else if (st == VT_DOUBLE)
4258 vpush_global_sym(func_old_type, TOK___fixunsdfdi);
4259 else
4260 vpush_global_sym(func_old_type, TOK___fixunsxfdi);
4261 gfunc_call(&gf);
4262 vpushi(0);
4263 vtop->r = REG_IRET;
4264 vtop->r2 = REG_LRET;
4265 } else {
4266 gen_cvt_ftoi(t);
4270 /* force char or short cast */
4271 void force_charshort_cast(int t)
4273 int bits, dbt;
4274 dbt = t & VT_BTYPE;
4275 /* XXX: add optimization if lvalue : just change type and offset */
4276 if (dbt == VT_BYTE)
4277 bits = 8;
4278 else
4279 bits = 16;
4280 if (t & VT_UNSIGNED) {
4281 vpushi((1 << bits) - 1);
4282 gen_op('&');
4283 } else {
4284 bits = 32 - bits;
4285 vpushi(bits);
4286 gen_op(TOK_SHL);
4287 vpushi(bits);
4288 gen_op(TOK_SAR);
4292 /* cast 'vtop' to 't' type */
4293 void gen_cast(int t)
4295 int sbt, dbt, sf, df, c;
4297 /* special delayed cast for char/short */
4298 /* XXX: in some cases (multiple cascaded casts), it may still
4299 be incorrect */
4300 if (vtop->r & VT_MUSTCAST) {
4301 vtop->r &= ~VT_MUSTCAST;
4302 force_charshort_cast(vtop->t);
4305 dbt = t & (VT_BTYPE | VT_UNSIGNED);
4306 sbt = vtop->t & (VT_BTYPE | VT_UNSIGNED);
4308 if (sbt != dbt && !nocode_wanted) {
4309 sf = is_float(sbt);
4310 df = is_float(dbt);
4311 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4312 if (sf && df) {
4313 /* convert from fp to fp */
4314 if (c) {
4315 /* constant case: we can do it now */
4316 /* XXX: in ISOC, cannot do it if error in convert */
4317 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
4318 vtop->c.f = (float)vtop->c.d;
4319 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
4320 vtop->c.f = (float)vtop->c.ld;
4321 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
4322 vtop->c.d = (double)vtop->c.f;
4323 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
4324 vtop->c.d = (double)vtop->c.ld;
4325 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
4326 vtop->c.ld = (long double)vtop->c.f;
4327 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
4328 vtop->c.ld = (long double)vtop->c.d;
4329 } else {
4330 /* non constant case: generate code */
4331 gen_cvt_ftof(dbt);
4333 } else if (df) {
4334 /* convert int to fp */
4335 if (c) {
4336 switch(sbt) {
4337 case VT_LLONG | VT_UNSIGNED:
4338 case VT_LLONG:
4339 /* XXX: add const cases for long long */
4340 goto do_itof;
4341 case VT_INT | VT_UNSIGNED:
4342 switch(dbt) {
4343 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
4344 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
4345 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
4347 break;
4348 default:
4349 switch(dbt) {
4350 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
4351 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
4352 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
4354 break;
4356 } else {
4357 do_itof:
4358 gen_cvt_itof1(dbt);
4360 } else if (sf) {
4361 /* convert fp to int */
4362 /* we handle char/short/etc... with generic code */
4363 if (dbt != (VT_INT | VT_UNSIGNED) &&
4364 dbt != (VT_LLONG | VT_UNSIGNED) &&
4365 dbt != VT_LLONG)
4366 dbt = VT_INT;
4367 if (c) {
4368 switch(dbt) {
4369 case VT_LLONG | VT_UNSIGNED:
4370 case VT_LLONG:
4371 /* XXX: add const cases for long long */
4372 goto do_ftoi;
4373 case VT_INT | VT_UNSIGNED:
4374 switch(sbt) {
4375 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
4376 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4377 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4379 break;
4380 default:
4381 /* int case */
4382 switch(sbt) {
4383 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
4384 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
4385 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
4387 break;
4389 } else {
4390 do_ftoi:
4391 gen_cvt_ftoi1(dbt);
4393 if (dbt == VT_INT && (t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
4394 /* additionnal cast for char/short/bool... */
4395 vtop->t = dbt;
4396 gen_cast(t);
4398 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
4399 if ((sbt & VT_BTYPE) != VT_LLONG) {
4400 /* scalar to long long */
4401 if (c) {
4402 if (sbt == (VT_INT | VT_UNSIGNED))
4403 vtop->c.ll = vtop->c.ui;
4404 else
4405 vtop->c.ll = vtop->c.i;
4406 } else {
4407 /* machine independant conversion */
4408 gv(RC_INT);
4409 /* generate high word */
4410 if (sbt == (VT_INT | VT_UNSIGNED)) {
4411 vpushi(0);
4412 gv(RC_INT);
4413 } else {
4414 gv_dup();
4415 vpushi(31);
4416 gen_op(TOK_SAR);
4418 /* patch second register */
4419 vtop[-1].r2 = vtop->r;
4420 vpop();
4423 } else if (dbt == VT_BOOL) {
4424 /* scalar to bool */
4425 vpushi(0);
4426 gen_op(TOK_NE);
4427 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
4428 (dbt & VT_BTYPE) == VT_SHORT) {
4429 force_charshort_cast(t);
4430 } else if ((dbt & VT_BTYPE) == VT_INT) {
4431 /* scalar to int */
4432 if (sbt == VT_LLONG) {
4433 /* from long long: just take low order word */
4434 lexpand();
4435 vpop();
4437 /* if lvalue and single word type, nothing to do because
4438 the lvalue already contains the real type size (see
4439 VT_LVAL_xxx constants) */
4442 vtop->t = t;
4445 /* return type size. Put alignment at 'a' */
4446 int type_size(int t, int *a)
4448 Sym *s;
4449 int bt;
4451 bt = t & VT_BTYPE;
4452 if (bt == VT_STRUCT) {
4453 /* struct/union */
4454 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4455 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
4456 return s->c;
4457 } else if (bt == VT_PTR) {
4458 if (t & VT_ARRAY) {
4459 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4460 return type_size(s->t, a) * s->c;
4461 } else {
4462 *a = PTR_SIZE;
4463 return PTR_SIZE;
4465 } else if (bt == VT_LDOUBLE) {
4466 *a = LDOUBLE_ALIGN;
4467 return LDOUBLE_SIZE;
4468 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
4469 *a = 8;
4470 return 8;
4471 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
4472 *a = 4;
4473 return 4;
4474 } else if (bt == VT_SHORT) {
4475 *a = 2;
4476 return 2;
4477 } else {
4478 /* char, void, function, _Bool */
4479 *a = 1;
4480 return 1;
4484 /* return the pointed type of t */
4485 int pointed_type(int t)
4487 Sym *s;
4488 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4489 return s->t | (t & ~VT_TYPE);
4492 int mk_pointer(int t)
4494 int p;
4495 p = anon_sym++;
4496 sym_push(p, t, 0, -1);
4497 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
4500 int is_compatible_types(int t1, int t2)
4502 Sym *s1, *s2;
4503 int bt1, bt2;
4505 t1 &= VT_TYPE;
4506 t2 &= VT_TYPE;
4507 bt1 = t1 & VT_BTYPE;
4508 bt2 = t2 & VT_BTYPE;
4509 if (bt1 == VT_PTR) {
4510 t1 = pointed_type(t1);
4511 /* if function, then convert implicitely to function pointer */
4512 if (bt2 != VT_FUNC) {
4513 if (bt2 != VT_PTR)
4514 return 0;
4515 t2 = pointed_type(t2);
4517 /* void matches everything */
4518 t1 &= VT_TYPE;
4519 t2 &= VT_TYPE;
4520 if (t1 == VT_VOID || t2 == VT_VOID)
4521 return 1;
4522 return is_compatible_types(t1, t2);
4523 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4524 return (t2 == t1);
4525 } else if (bt1 == VT_FUNC) {
4526 if (bt2 != VT_FUNC)
4527 return 0;
4528 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
4529 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
4530 if (!is_compatible_types(s1->t, s2->t))
4531 return 0;
4532 /* XXX: not complete */
4533 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
4534 return 1;
4535 if (s1->c != s2->c)
4536 return 0;
4537 while (s1 != NULL) {
4538 if (s2 == NULL)
4539 return 0;
4540 if (!is_compatible_types(s1->t, s2->t))
4541 return 0;
4542 s1 = s1->next;
4543 s2 = s2->next;
4545 if (s2)
4546 return 0;
4547 return 1;
4548 } else {
4549 /* XXX: not complete */
4550 return 1;
4554 /* print a type. If 'varstr' is not NULL, then the variable is also
4555 printed in the type */
4556 /* XXX: union */
4557 /* XXX: add array and function pointers */
4558 void type_to_str(char *buf, int buf_size,
4559 int t, const char *varstr)
4561 int bt, v;
4562 Sym *s, *sa;
4563 char buf1[256];
4564 const char *tstr;
4566 t = t & VT_TYPE;
4567 bt = t & VT_BTYPE;
4568 buf[0] = '\0';
4569 if (t & VT_UNSIGNED)
4570 pstrcat(buf, buf_size, "unsigned ");
4571 switch(bt) {
4572 case VT_VOID:
4573 tstr = "void";
4574 goto add_tstr;
4575 case VT_BOOL:
4576 tstr = "_Bool";
4577 goto add_tstr;
4578 case VT_BYTE:
4579 tstr = "char";
4580 goto add_tstr;
4581 case VT_SHORT:
4582 tstr = "short";
4583 goto add_tstr;
4584 case VT_INT:
4585 tstr = "int";
4586 goto add_tstr;
4587 case VT_LONG:
4588 tstr = "long";
4589 goto add_tstr;
4590 case VT_LLONG:
4591 tstr = "long long";
4592 goto add_tstr;
4593 case VT_FLOAT:
4594 tstr = "float";
4595 goto add_tstr;
4596 case VT_DOUBLE:
4597 tstr = "double";
4598 goto add_tstr;
4599 case VT_LDOUBLE:
4600 tstr = "long double";
4601 add_tstr:
4602 pstrcat(buf, buf_size, tstr);
4603 break;
4604 case VT_ENUM:
4605 case VT_STRUCT:
4606 if (bt == VT_STRUCT)
4607 tstr = "struct ";
4608 else
4609 tstr = "enum ";
4610 pstrcat(buf, buf_size, tstr);
4611 v = (unsigned)t >> VT_STRUCT_SHIFT;
4612 if (v >= SYM_FIRST_ANOM)
4613 pstrcat(buf, buf_size, "<anonymous>");
4614 else
4615 pstrcat(buf, buf_size, get_tok_str(v, NULL));
4616 break;
4617 case VT_FUNC:
4618 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4619 type_to_str(buf, buf_size, s->t, varstr);
4620 pstrcat(buf, buf_size, "(");
4621 sa = s->next;
4622 while (sa != NULL) {
4623 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
4624 pstrcat(buf, buf_size, buf1);
4625 sa = sa->next;
4626 if (sa)
4627 pstrcat(buf, buf_size, ", ");
4629 pstrcat(buf, buf_size, ")");
4630 goto no_var;
4631 case VT_PTR:
4632 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4633 pstrcpy(buf1, sizeof(buf1), "*");
4634 if (varstr)
4635 pstrcat(buf1, sizeof(buf1), varstr);
4636 type_to_str(buf, buf_size, s->t, buf1);
4637 goto no_var;
4639 if (varstr) {
4640 pstrcat(buf, buf_size, " ");
4641 pstrcat(buf, buf_size, varstr);
4643 no_var: ;
4646 /* verify type compatibility to store vtop in 'dt' type, and generate
4647 casts if needed. */
4648 void gen_assign_cast(int dt)
4650 int st;
4651 char buf1[256], buf2[256];
4653 st = vtop->t; /* source type */
4654 if ((dt & VT_BTYPE) == VT_PTR) {
4655 /* special cases for pointers */
4656 /* a function is implicitely a function pointer */
4657 if ((st & VT_BTYPE) == VT_FUNC) {
4658 if (!is_compatible_types(pointed_type(dt), st))
4659 goto error;
4660 else
4661 goto type_ok;
4663 /* '0' can also be a pointer */
4664 if ((st & VT_BTYPE) == VT_INT &&
4665 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
4666 vtop->c.i == 0)
4667 goto type_ok;
4669 if (!is_compatible_types(dt, st)) {
4670 error:
4671 type_to_str(buf1, sizeof(buf1), st, NULL);
4672 type_to_str(buf2, sizeof(buf2), dt, NULL);
4673 error("cannot cast '%s' to '%s'", buf1, buf2);
4675 type_ok:
4676 gen_cast(dt);
4679 /* store vtop in lvalue pushed on stack */
4680 void vstore(void)
4682 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
4683 GFuncContext gf;
4685 ft = vtop[-1].t;
4686 sbt = vtop->t & VT_BTYPE;
4687 dbt = ft & VT_BTYPE;
4688 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
4689 (sbt == VT_INT && dbt == VT_SHORT)) {
4690 /* optimize char/short casts */
4691 delayed_cast = VT_MUSTCAST;
4692 vtop->t = ft & VT_TYPE;
4693 } else {
4694 delayed_cast = 0;
4695 gen_assign_cast(ft & VT_TYPE);
4698 if (sbt == VT_STRUCT) {
4699 /* if structure, only generate pointer */
4700 /* structure assignment : generate memcpy */
4701 /* XXX: optimize if small size */
4702 if (!nocode_wanted) {
4703 vdup();
4704 gfunc_start(&gf, FUNC_CDECL);
4705 /* type size */
4706 size = type_size(vtop->t, &align);
4707 vpushi(size);
4708 gfunc_param(&gf);
4709 /* source */
4710 vtop->t = VT_INT;
4711 gaddrof();
4712 gfunc_param(&gf);
4713 /* destination */
4714 vswap();
4715 vtop->t = VT_INT;
4716 gaddrof();
4717 gfunc_param(&gf);
4719 save_regs(0);
4720 vpush_global_sym(func_old_type, TOK_memcpy);
4721 gfunc_call(&gf);
4722 } else {
4723 vswap();
4724 vpop();
4726 /* leave source on stack */
4727 } else if (ft & VT_BITFIELD) {
4728 /* bitfield store handling */
4729 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
4730 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4731 /* remove bit field info to avoid loops */
4732 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4734 /* duplicate destination */
4735 vdup();
4736 vtop[-1] = vtop[-2];
4738 /* mask and shift source */
4739 vpushi((1 << bit_size) - 1);
4740 gen_op('&');
4741 vpushi(bit_pos);
4742 gen_op(TOK_SHL);
4743 /* load destination, mask and or with source */
4744 vswap();
4745 vpushi(~(((1 << bit_size) - 1) << bit_pos));
4746 gen_op('&');
4747 gen_op('|');
4748 /* store result */
4749 vstore();
4750 } else {
4751 #ifdef CONFIG_TCC_BCHECK
4752 /* bound check case */
4753 if (vtop[-1].r & VT_MUSTBOUND) {
4754 vswap();
4755 gbound();
4756 vswap();
4758 #endif
4759 if (!nocode_wanted) {
4760 rc = RC_INT;
4761 if (is_float(ft))
4762 rc = RC_FLOAT;
4763 r = gv(rc); /* generate value */
4764 /* if lvalue was saved on stack, must read it */
4765 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
4766 SValue sv;
4767 t = get_reg(RC_INT);
4768 sv.t = VT_INT;
4769 sv.r = VT_LOCAL | VT_LVAL;
4770 sv.c.ul = vtop[-1].c.ul;
4771 load(t, &sv);
4772 vtop[-1].r = t | VT_LVAL;
4774 store(r, vtop - 1);
4775 /* two word case handling : store second register at word + 4 */
4776 if ((ft & VT_BTYPE) == VT_LLONG) {
4777 vswap();
4778 /* convert to int to increment easily */
4779 vtop->t = VT_INT;
4780 gaddrof();
4781 vpushi(4);
4782 gen_op('+');
4783 vtop->r |= VT_LVAL;
4784 vswap();
4785 /* XXX: it works because r2 is spilled last ! */
4786 store(vtop->r2, vtop - 1);
4789 vswap();
4790 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4791 vtop->r |= delayed_cast;
4795 /* post defines POST/PRE add. c is the token ++ or -- */
4796 void inc(int post, int c)
4798 test_lvalue();
4799 vdup(); /* save lvalue */
4800 if (post) {
4801 gv_dup(); /* duplicate value */
4802 vrotb(3);
4803 vrotb(3);
4805 /* add constant */
4806 vpushi(c - TOK_MID);
4807 gen_op('+');
4808 vstore(); /* store value */
4809 if (post)
4810 vpop(); /* if post op, return saved value */
4813 /* Parse GNUC __attribute__ extension. Currently, the following
4814 extensions are recognized:
4815 - aligned(n) : set data/function alignment.
4816 - section(x) : generate data/code in this section.
4817 - unused : currently ignored, but may be used someday.
4819 void parse_attribute(AttributeDef *ad)
4821 int t, n;
4823 next();
4824 skip('(');
4825 skip('(');
4826 while (tok != ')') {
4827 if (tok < TOK_IDENT)
4828 expect("attribute name");
4829 t = tok;
4830 next();
4831 switch(t) {
4832 case TOK_SECTION:
4833 case TOK___SECTION__:
4834 skip('(');
4835 if (tok != TOK_STR)
4836 expect("section name");
4837 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
4838 next();
4839 skip(')');
4840 break;
4841 case TOK_ALIGNED:
4842 case TOK___ALIGNED__:
4843 skip('(');
4844 n = expr_const();
4845 if (n <= 0 || (n & (n - 1)) != 0)
4846 error("alignment must be a positive power of two");
4847 ad->aligned = n;
4848 skip(')');
4849 break;
4850 case TOK_UNUSED:
4851 case TOK___UNUSED__:
4852 /* currently, no need to handle it because tcc does not
4853 track unused objects */
4854 break;
4855 case TOK_NORETURN:
4856 case TOK___NORETURN__:
4857 /* currently, no need to handle it because tcc does not
4858 track unused objects */
4859 break;
4860 case TOK_CDECL:
4861 case TOK___CDECL:
4862 case TOK___CDECL__:
4863 ad->func_call = FUNC_CDECL;
4864 break;
4865 case TOK_STDCALL:
4866 case TOK___STDCALL:
4867 case TOK___STDCALL__:
4868 ad->func_call = FUNC_STDCALL;
4869 break;
4870 default:
4871 warning("'%s' attribute ignored", get_tok_str(t, NULL));
4872 /* skip parameters */
4873 /* XXX: skip parenthesis too */
4874 if (tok == '(') {
4875 next();
4876 while (tok != ')' && tok != -1)
4877 next();
4878 next();
4880 break;
4882 if (tok != ',')
4883 break;
4884 next();
4886 skip(')');
4887 skip(')');
4890 /* enum/struct/union declaration */
4891 int struct_decl(int u)
4893 int a, t, b, v, size, align, maxalign, c, offset;
4894 int bit_size, bit_pos, bsize, bt, lbit_pos;
4895 Sym *s, *ss, **ps;
4896 AttributeDef ad;
4898 a = tok; /* save decl type */
4899 next();
4900 if (tok != '{') {
4901 v = tok;
4902 next();
4903 /* struct already defined ? return it */
4904 /* XXX: check consistency */
4905 s = sym_find(v | SYM_STRUCT);
4906 if (s) {
4907 if (s->t != a)
4908 error("invalid type");
4909 goto do_decl;
4911 } else {
4912 v = anon_sym++;
4914 s = sym_push(v | SYM_STRUCT, a, 0, 0);
4915 /* put struct/union/enum name in type */
4916 do_decl:
4917 u = u | (v << VT_STRUCT_SHIFT);
4919 if (tok == '{') {
4920 next();
4921 if (s->c)
4922 error("struct/union/enum already defined");
4923 /* cannot be empty */
4924 c = 0;
4925 maxalign = 0;
4926 ps = &s->next;
4927 bit_pos = 0;
4928 offset = 0;
4929 while (1) {
4930 if (a == TOK_ENUM) {
4931 v = tok;
4932 next();
4933 if (tok == '=') {
4934 next();
4935 c = expr_const();
4937 /* enum symbols have static storage */
4938 sym_push(v, VT_STATIC | VT_INT, VT_CONST, c);
4939 if (tok == ',')
4940 next();
4941 c++;
4942 } else {
4943 parse_btype(&b, &ad);
4944 while (1) {
4945 bit_size = -1;
4946 v = 0;
4947 if (tok != ':') {
4948 t = type_decl(&ad, &v, b, TYPE_DIRECT);
4949 if ((t & VT_BTYPE) == VT_FUNC ||
4950 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
4951 error("invalid type for '%s'",
4952 get_tok_str(v, NULL));
4953 } else {
4954 t = b;
4956 if (tok == ':') {
4957 next();
4958 bit_size = expr_const();
4959 /* XXX: handle v = 0 case for messages */
4960 if (bit_size < 0)
4961 error("negative width in bit-field '%s'",
4962 get_tok_str(v, NULL));
4963 if (v && bit_size == 0)
4964 error("zero width for bit-field '%s'",
4965 get_tok_str(v, NULL));
4967 size = type_size(t, &align);
4968 lbit_pos = 0;
4969 if (bit_size >= 0) {
4970 bt = t & VT_BTYPE;
4971 if (bt != VT_INT &&
4972 bt != VT_BYTE &&
4973 bt != VT_SHORT)
4974 error("bitfields must have scalar type");
4975 bsize = size * 8;
4976 if (bit_size > bsize) {
4977 error("width of '%s' exceeds its type",
4978 get_tok_str(v, NULL));
4979 } else if (bit_size == bsize) {
4980 /* no need for bit fields */
4981 bit_pos = 0;
4982 } else if (bit_size == 0) {
4983 /* XXX: what to do if only padding in a
4984 structure ? */
4985 /* zero size: means to pad */
4986 if (bit_pos > 0)
4987 bit_pos = bsize;
4988 } else {
4989 /* we do not have enough room ? */
4990 if ((bit_pos + bit_size) > bsize)
4991 bit_pos = 0;
4992 lbit_pos = bit_pos;
4993 /* XXX: handle LSB first */
4994 t |= VT_BITFIELD |
4995 (bit_pos << VT_STRUCT_SHIFT) |
4996 (bit_size << (VT_STRUCT_SHIFT + 6));
4997 bit_pos += bit_size;
4999 } else {
5000 bit_pos = 0;
5002 if (v) {
5003 /* add new memory data only if starting
5004 bit field */
5005 if (lbit_pos == 0) {
5006 if (a == TOK_STRUCT) {
5007 c = (c + align - 1) & -align;
5008 offset = c;
5009 c += size;
5010 } else {
5011 offset = 0;
5012 if (size > c)
5013 c = size;
5015 if (align > maxalign)
5016 maxalign = align;
5018 #if 0
5019 printf("add field %s offset=%d",
5020 get_tok_str(v, NULL), offset);
5021 if (t & VT_BITFIELD) {
5022 printf(" pos=%d size=%d",
5023 (t >> VT_STRUCT_SHIFT) & 0x3f,
5024 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
5026 printf("\n");
5027 #endif
5028 ss = sym_push(v | SYM_FIELD, t, 0, offset);
5029 *ps = ss;
5030 ps = &ss->next;
5032 if (tok == ';' || tok == -1)
5033 break;
5034 skip(',');
5036 skip(';');
5038 if (tok == '}')
5039 break;
5041 skip('}');
5042 /* size for struct/union, dummy for enum */
5043 s->c = (c + maxalign - 1) & -maxalign;
5045 return u;
5048 /* return 0 if no type declaration. otherwise, return the basic type
5049 and skip it.
5051 int parse_btype(int *type_ptr, AttributeDef *ad)
5053 int t, u, type_found;
5054 Sym *s;
5056 memset(ad, 0, sizeof(AttributeDef));
5057 type_found = 0;
5058 t = 0;
5059 while(1) {
5060 switch(tok) {
5061 /* basic types */
5062 case TOK_CHAR:
5063 u = VT_BYTE;
5064 basic_type:
5065 next();
5066 basic_type1:
5067 if ((t & VT_BTYPE) != 0)
5068 error("too many basic types");
5069 t |= u;
5070 break;
5071 case TOK_VOID:
5072 u = VT_VOID;
5073 goto basic_type;
5074 case TOK_SHORT:
5075 u = VT_SHORT;
5076 goto basic_type;
5077 case TOK_INT:
5078 next();
5079 break;
5080 case TOK_LONG:
5081 next();
5082 if ((t & VT_BTYPE) == VT_DOUBLE) {
5083 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5084 } else if ((t & VT_BTYPE) == VT_LONG) {
5085 t = (t & ~VT_BTYPE) | VT_LLONG;
5086 } else {
5087 u = VT_LONG;
5088 goto basic_type1;
5090 break;
5091 case TOK_BOOL:
5092 u = VT_BOOL;
5093 goto basic_type;
5094 case TOK_FLOAT:
5095 u = VT_FLOAT;
5096 goto basic_type;
5097 case TOK_DOUBLE:
5098 next();
5099 if ((t & VT_BTYPE) == VT_LONG) {
5100 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5101 } else {
5102 u = VT_DOUBLE;
5103 goto basic_type1;
5105 break;
5106 case TOK_ENUM:
5107 u = struct_decl(VT_ENUM);
5108 goto basic_type1;
5109 case TOK_STRUCT:
5110 case TOK_UNION:
5111 u = struct_decl(VT_STRUCT);
5112 goto basic_type1;
5114 /* type modifiers */
5115 case TOK_CONST:
5116 case TOK_VOLATILE:
5117 case TOK_REGISTER:
5118 case TOK_SIGNED:
5119 case TOK___SIGNED__:
5120 case TOK_AUTO:
5121 case TOK_INLINE:
5122 case TOK___INLINE__:
5123 case TOK_RESTRICT:
5124 next();
5125 break;
5126 case TOK_UNSIGNED:
5127 t |= VT_UNSIGNED;
5128 next();
5129 break;
5131 /* storage */
5132 case TOK_EXTERN:
5133 t |= VT_EXTERN;
5134 next();
5135 break;
5136 case TOK_STATIC:
5137 t |= VT_STATIC;
5138 next();
5139 break;
5140 case TOK_TYPEDEF:
5141 t |= VT_TYPEDEF;
5142 next();
5143 break;
5144 /* GNUC attribute */
5145 case TOK___ATTRIBUTE__:
5146 parse_attribute(ad);
5147 break;
5148 /* GNUC typeof */
5149 case TOK_TYPEOF:
5150 next();
5151 u = parse_expr_type();
5152 goto basic_type1;
5153 default:
5154 s = sym_find(tok);
5155 if (!s || !(s->t & VT_TYPEDEF))
5156 goto the_end;
5157 t |= (s->t & ~VT_TYPEDEF);
5158 next();
5159 break;
5161 type_found = 1;
5163 the_end:
5164 /* long is never used as type */
5165 if ((t & VT_BTYPE) == VT_LONG)
5166 t = (t & ~VT_BTYPE) | VT_INT;
5167 *type_ptr = t;
5168 return type_found;
5171 int post_type(int t, AttributeDef *ad)
5173 int p, n, pt, l, t1;
5174 Sym **plast, *s, *first;
5175 AttributeDef ad1;
5177 if (tok == '(') {
5178 /* function declaration */
5179 next();
5180 l = 0;
5181 first = NULL;
5182 plast = &first;
5183 while (tok != ')') {
5184 /* read param name and compute offset */
5185 if (l != FUNC_OLD) {
5186 if (!parse_btype(&pt, &ad1)) {
5187 if (l) {
5188 error("invalid type");
5189 } else {
5190 l = FUNC_OLD;
5191 goto old_proto;
5194 l = FUNC_NEW;
5195 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
5196 break;
5197 pt = type_decl(&ad1, &n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
5198 if ((pt & VT_BTYPE) == VT_VOID)
5199 error("parameter declared as void");
5200 } else {
5201 old_proto:
5202 n = tok;
5203 pt = VT_INT;
5204 next();
5206 /* array must be transformed to pointer according to ANSI C */
5207 pt &= ~VT_ARRAY;
5208 s = sym_push(n | SYM_FIELD, pt, 0, 0);
5209 *plast = s;
5210 plast = &s->next;
5211 if (tok == ',') {
5212 next();
5213 if (l == FUNC_NEW && tok == TOK_DOTS) {
5214 l = FUNC_ELLIPSIS;
5215 next();
5216 break;
5220 /* if no parameters, then old type prototype */
5221 if (l == 0)
5222 l = FUNC_OLD;
5223 skip(')');
5224 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5225 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
5226 /* we push a anonymous symbol which will contain the function prototype */
5227 p = anon_sym++;
5228 s = sym_push(p, t, ad->func_call, l);
5229 s->next = first;
5230 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
5231 } else if (tok == '[') {
5232 /* array definition */
5233 next();
5234 n = -1;
5235 if (tok != ']') {
5236 n = expr_const();
5237 if (n < 0)
5238 error("invalid array size");
5240 skip(']');
5241 /* parse next post type */
5242 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5243 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
5245 /* we push a anonymous symbol which will contain the array
5246 element type */
5247 p = anon_sym++;
5248 sym_push(p, t, 0, n);
5249 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
5251 return t;
5254 /* Read a type declaration (except basic type), and return the
5255 type. 'td' is a bitmask indicating which kind of type decl is
5256 expected. 't' should contain the basic type. 'ad' is the attribute
5257 definition of the basic type. It can be modified by type_decl(). */
5258 int type_decl(AttributeDef *ad, int *v, int t, int td)
5260 int u, p;
5261 Sym *s;
5263 while (tok == '*') {
5264 next();
5265 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
5266 next();
5267 t = mk_pointer(t);
5270 /* recursive type */
5271 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5272 if (tok == '(') {
5273 next();
5274 /* XXX: this is not correct to modify 'ad' at this point, but
5275 the syntax is not clear */
5276 if (tok == TOK___ATTRIBUTE__)
5277 parse_attribute(ad);
5278 u = type_decl(ad, v, 0, td);
5279 skip(')');
5280 } else {
5281 u = 0;
5282 /* type identifier */
5283 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
5284 *v = tok;
5285 next();
5286 } else {
5287 if (!(td & TYPE_ABSTRACT))
5288 expect("identifier");
5289 *v = 0;
5292 /* append t at the end of u */
5293 t = post_type(t, ad);
5294 if (tok == TOK___ATTRIBUTE__)
5295 parse_attribute(ad);
5296 if (!u)
5297 return t;
5298 p = u;
5299 while(1) {
5300 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
5301 p = s->t;
5302 if (!p) {
5303 s->t = t;
5304 break;
5307 return u;
5310 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5311 static int lvalue_type(int t)
5313 int bt, r;
5314 r = VT_LVAL;
5315 bt = t & VT_BTYPE;
5316 if (bt == VT_BYTE)
5317 r |= VT_LVAL_BYTE;
5318 else if (bt == VT_SHORT)
5319 r |= VT_LVAL_SHORT;
5320 else
5321 return r;
5322 if (t & VT_UNSIGNED)
5323 r |= VT_LVAL_UNSIGNED;
5324 return r;
5327 /* indirection with full error checking and bound check */
5328 static void indir(void)
5330 if ((vtop->t & VT_BTYPE) != VT_PTR)
5331 expect("pointer");
5332 if ((vtop->r & VT_LVAL) && !nocode_wanted)
5333 gv(RC_INT);
5334 vtop->t = pointed_type(vtop->t);
5335 /* an array is never an lvalue */
5336 if (!(vtop->t & VT_ARRAY)) {
5337 vtop->r |= lvalue_type(vtop->t);
5338 /* if bound checking, the referenced pointer must be checked */
5339 if (do_bounds_check)
5340 vtop->r |= VT_MUSTBOUND;
5344 /* pass a parameter to a function and do type checking and casting */
5345 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
5347 int func_type;
5348 func_type = func->c;
5349 if (func_type == FUNC_OLD ||
5350 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
5351 /* default casting : only need to convert float to double */
5352 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
5353 gen_cast(VT_DOUBLE);
5354 } else if (arg == NULL) {
5355 error("too many arguments to function");
5356 } else {
5357 gen_assign_cast(arg->t);
5359 if (!nocode_wanted) {
5360 gfunc_param(gf);
5361 } else {
5362 vpop();
5366 /* parse an expression of the form '(type)' or '(expr)' and return its
5367 type */
5368 static int parse_expr_type(void)
5370 int ft, n;
5371 AttributeDef ad;
5373 skip('(');
5374 if (parse_btype(&ft, &ad)) {
5375 ft = type_decl(&ad, &n, ft, TYPE_ABSTRACT);
5376 } else {
5377 ft = expr_type();
5379 skip(')');
5380 return ft;
5383 static void unary(void)
5385 int n, t, ft, align, size, r;
5386 Sym *s;
5387 GFuncContext gf;
5388 AttributeDef ad;
5390 if (tok == TOK_CINT || tok == TOK_CCHAR || tok == TOK_LCHAR) {
5391 vpushi(tokc.i);
5392 next();
5393 } else if (tok == TOK_CUINT) {
5394 vsetc(VT_INT | VT_UNSIGNED, VT_CONST, &tokc);
5395 next();
5396 } else if (tok == TOK_CLLONG) {
5397 vsetc(VT_LLONG, VT_CONST, &tokc);
5398 next();
5399 } else if (tok == TOK_CULLONG) {
5400 vsetc(VT_LLONG | VT_UNSIGNED, VT_CONST, &tokc);
5401 next();
5402 } else if (tok == TOK_CFLOAT) {
5403 vsetc(VT_FLOAT, VT_CONST, &tokc);
5404 next();
5405 } else if (tok == TOK_CDOUBLE) {
5406 vsetc(VT_DOUBLE, VT_CONST, &tokc);
5407 next();
5408 } else if (tok == TOK_CLDOUBLE) {
5409 vsetc(VT_LDOUBLE, VT_CONST, &tokc);
5410 next();
5411 } else if (tok == TOK___FUNC__ || (tok == TOK___FUNCTION__ && gnu_ext)) {
5412 void *ptr;
5413 int len;
5414 /* special function name identifier */
5416 len = strlen(funcname) + 1;
5417 /* generate char[len] type */
5418 t = VT_ARRAY | mk_pointer(VT_BYTE);
5419 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5420 s->c = len;
5421 vpush_ref(t, data_section, data_section->data_offset, len);
5422 ptr = section_ptr_add(data_section, len);
5423 memcpy(ptr, funcname, len);
5424 next();
5425 } else if (tok == TOK_LSTR) {
5426 t = VT_INT;
5427 goto str_init;
5428 } else if (tok == TOK_STR) {
5429 /* string parsing */
5430 t = VT_BYTE;
5431 str_init:
5432 t = VT_ARRAY | mk_pointer(t);
5433 memset(&ad, 0, sizeof(AttributeDef));
5434 decl_initializer_alloc(t, &ad, VT_CONST, 2, 0, 0);
5435 } else {
5436 t = tok;
5437 next();
5438 if (t == '(') {
5439 /* cast ? */
5440 if (parse_btype(&t, &ad)) {
5441 ft = type_decl(&ad, &n, t, TYPE_ABSTRACT);
5442 skip(')');
5443 /* check ISOC99 compound literal */
5444 if (tok == '{') {
5445 /* data is allocated locally by default */
5446 if (global_expr)
5447 r = VT_CONST;
5448 else
5449 r = VT_LOCAL;
5450 /* all except arrays are lvalues */
5451 if (!(ft & VT_ARRAY))
5452 r |= lvalue_type(ft);
5453 memset(&ad, 0, sizeof(AttributeDef));
5454 decl_initializer_alloc(ft, &ad, r, 1, 0, 0);
5455 } else {
5456 unary();
5457 gen_cast(ft);
5459 } else {
5460 gexpr();
5461 skip(')');
5463 } else if (t == '*') {
5464 unary();
5465 indir();
5466 } else if (t == '&') {
5467 unary();
5468 /* functions names must be treated as function pointers,
5469 except for unary '&' and sizeof. Since we consider that
5470 functions are not lvalues, we only have to handle it
5471 there and in function calls. */
5472 /* arrays can also be used although they are not lvalues */
5473 if ((vtop->t & VT_BTYPE) != VT_FUNC &&
5474 !(vtop->t & VT_ARRAY))
5475 test_lvalue();
5476 vtop->t = mk_pointer(vtop->t);
5477 gaddrof();
5478 } else
5479 if (t == '!') {
5480 unary();
5481 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
5482 vtop->c.i = !vtop->c.i;
5483 else if ((vtop->r & VT_VALMASK) == VT_CMP)
5484 vtop->c.i = vtop->c.i ^ 1;
5485 else
5486 vset(VT_INT, VT_JMP, gtst(1, 0));
5487 } else
5488 if (t == '~') {
5489 unary();
5490 vpushi(-1);
5491 gen_op('^');
5492 } else
5493 if (t == '+') {
5494 /* in order to force cast, we add zero */
5495 unary();
5496 if ((vtop->t & VT_BTYPE) == VT_PTR)
5497 error("pointer not accepted for unary plus");
5498 vpushi(0);
5499 gen_op('+');
5500 } else
5501 if (t == TOK_SIZEOF || t == TOK_ALIGNOF) {
5502 if (tok == '(') {
5503 ft = parse_expr_type();
5504 } else {
5505 ft = unary_type();
5507 size = type_size(ft, &align);
5508 if (t == TOK_SIZEOF)
5509 vpushi(size);
5510 else
5511 vpushi(align);
5512 } else
5513 if (t == TOK_INC || t == TOK_DEC) {
5514 unary();
5515 inc(0, t);
5516 } else if (t == '-') {
5517 vpushi(0);
5518 unary();
5519 gen_op('-');
5520 } else
5522 if (t < TOK_UIDENT)
5523 expect("identifier");
5524 s = sym_find(t);
5525 if (!s) {
5526 if (tok != '(')
5527 error("'%s' undeclared", get_tok_str(t, NULL));
5528 /* for simple function calls, we tolerate undeclared
5529 external reference to int() function */
5530 s = external_global_sym(t, func_old_type, 0);
5532 vset(s->t, s->r, s->c);
5533 /* if forward reference, we must point to s */
5534 if (vtop->r & VT_SYM) {
5535 vtop->sym = s;
5536 vtop->c.ul = 0;
5541 /* post operations */
5542 while (1) {
5543 if (tok == TOK_INC || tok == TOK_DEC) {
5544 inc(1, tok);
5545 next();
5546 } else if (tok == '.' || tok == TOK_ARROW) {
5547 /* field */
5548 if (tok == TOK_ARROW)
5549 indir();
5550 test_lvalue();
5551 gaddrof();
5552 next();
5553 /* expect pointer on structure */
5554 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
5555 expect("struct or union");
5556 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5557 /* find field */
5558 tok |= SYM_FIELD;
5559 while ((s = s->next) != NULL) {
5560 if (s->v == tok)
5561 break;
5563 if (!s)
5564 error("field not found");
5565 /* add field offset to pointer */
5566 vtop->t = char_pointer_type; /* change type to 'char *' */
5567 vpushi(s->c);
5568 gen_op('+');
5569 /* change type to field type, and set to lvalue */
5570 vtop->t = s->t;
5571 /* an array is never an lvalue */
5572 if (!(vtop->t & VT_ARRAY)) {
5573 vtop->r |= lvalue_type(vtop->t);
5574 /* if bound checking, the referenced pointer must be checked */
5575 if (do_bounds_check)
5576 vtop->r |= VT_MUSTBOUND;
5578 next();
5579 } else if (tok == '[') {
5580 next();
5581 gexpr();
5582 gen_op('+');
5583 indir();
5584 skip(']');
5585 } else if (tok == '(') {
5586 SValue ret;
5587 Sym *sa;
5589 /* function call */
5590 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
5591 /* pointer test (no array accepted) */
5592 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
5593 vtop->t = pointed_type(vtop->t);
5594 if ((vtop->t & VT_BTYPE) != VT_FUNC)
5595 goto error_func;
5596 } else {
5597 error_func:
5598 expect("function pointer");
5600 } else {
5601 vtop->r &= ~VT_LVAL; /* no lvalue */
5603 /* get return type */
5604 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
5605 if (!nocode_wanted) {
5606 save_regs(0); /* save used temporary registers */
5607 gfunc_start(&gf, s->r);
5609 next();
5610 sa = s->next; /* first parameter */
5611 #ifdef INVERT_FUNC_PARAMS
5613 int parlevel;
5614 Sym *args, *s1;
5615 ParseState saved_parse_state;
5616 TokenString str;
5618 /* read each argument and store it on a stack */
5619 args = NULL;
5620 if (tok != ')') {
5621 for(;;) {
5622 tok_str_new(&str);
5623 parlevel = 0;
5624 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
5625 tok != TOK_EOF) {
5626 if (tok == '(')
5627 parlevel++;
5628 else if (tok == ')')
5629 parlevel--;
5630 tok_str_add_tok(&str);
5631 next();
5633 tok_str_add(&str, -1); /* end of file added */
5634 tok_str_add(&str, 0);
5635 s1 = sym_push2(&args, 0, 0, (int)str.str);
5636 s1->next = sa; /* add reference to argument */
5637 if (sa)
5638 sa = sa->next;
5639 if (tok == ')')
5640 break;
5641 skip(',');
5645 /* now generate code in reverse order by reading the stack */
5646 save_parse_state(&saved_parse_state);
5647 while (args) {
5648 macro_ptr = (int *)args->c;
5649 next();
5650 expr_eq();
5651 if (tok != -1)
5652 expect("',' or ')'");
5653 gfunc_param_typed(&gf, s, args->next);
5654 s1 = args->prev;
5655 tok_str_free((int *)args->c);
5656 tcc_free(args);
5657 args = s1;
5659 restore_parse_state(&saved_parse_state);
5661 #endif
5662 /* compute first implicit argument if a structure is returned */
5663 if ((s->t & VT_BTYPE) == VT_STRUCT) {
5664 /* get some space for the returned structure */
5665 size = type_size(s->t, &align);
5666 loc = (loc - size) & -align;
5667 ret.t = s->t;
5668 ret.r = VT_LOCAL | VT_LVAL;
5669 /* pass it as 'int' to avoid structure arg passing
5670 problems */
5671 vset(VT_INT, VT_LOCAL, loc);
5672 ret.c = vtop->c;
5673 if (!nocode_wanted)
5674 gfunc_param(&gf);
5675 else
5676 vtop--;
5677 } else {
5678 ret.t = s->t;
5679 ret.r2 = VT_CONST;
5680 /* return in register */
5681 if (is_float(ret.t)) {
5682 ret.r = REG_FRET;
5683 } else {
5684 if ((ret.t & VT_BTYPE) == VT_LLONG)
5685 ret.r2 = REG_LRET;
5686 ret.r = REG_IRET;
5688 ret.c.i = 0;
5690 #ifndef INVERT_FUNC_PARAMS
5691 if (tok != ')') {
5692 for(;;) {
5693 expr_eq();
5694 gfunc_param_typed(&gf, s, sa);
5695 if (sa)
5696 sa = sa->next;
5697 if (tok == ')')
5698 break;
5699 skip(',');
5702 #endif
5703 if (sa)
5704 error("too few arguments to function");
5705 skip(')');
5706 if (!nocode_wanted)
5707 gfunc_call(&gf);
5708 else
5709 vtop--;
5710 /* return value */
5711 vsetc(ret.t, ret.r, &ret.c);
5712 vtop->r2 = ret.r2;
5713 } else {
5714 break;
5719 static void uneq(void)
5721 int t;
5723 unary();
5724 if (tok == '=' ||
5725 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5726 tok == TOK_A_XOR || tok == TOK_A_OR ||
5727 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5728 test_lvalue();
5729 t = tok;
5730 next();
5731 if (t == '=') {
5732 expr_eq();
5733 } else {
5734 vdup();
5735 expr_eq();
5736 gen_op(t & 0x7f);
5738 vstore();
5742 static void sum(int l)
5744 int t;
5746 if (l == 0)
5747 uneq();
5748 else {
5749 sum(--l);
5750 while ((l == 0 && (tok == '*' || tok == '/' || tok == '%')) ||
5751 (l == 1 && (tok == '+' || tok == '-')) ||
5752 (l == 2 && (tok == TOK_SHL || tok == TOK_SAR)) ||
5753 (l == 3 && ((tok >= TOK_ULE && tok <= TOK_GT) ||
5754 tok == TOK_ULT || tok == TOK_UGE)) ||
5755 (l == 4 && (tok == TOK_EQ || tok == TOK_NE)) ||
5756 (l == 5 && tok == '&') ||
5757 (l == 6 && tok == '^') ||
5758 (l == 7 && tok == '|') ||
5759 (l == 8 && tok == TOK_LAND) ||
5760 (l == 9 && tok == TOK_LOR)) {
5761 t = tok;
5762 next();
5763 sum(l);
5764 gen_op(t);
5769 /* only used if non constant */
5770 static void eand(void)
5772 int t;
5774 sum(8);
5775 t = 0;
5776 while (1) {
5777 if (tok != TOK_LAND) {
5778 if (t) {
5779 t = gtst(1, t);
5780 vset(VT_INT, VT_JMPI, t);
5782 break;
5784 t = gtst(1, t);
5785 next();
5786 sum(8);
5790 static void eor(void)
5792 int t;
5794 eand();
5795 t = 0;
5796 while (1) {
5797 if (tok != TOK_LOR) {
5798 if (t) {
5799 t = gtst(0, t);
5800 vset(VT_INT, VT_JMP, t);
5802 break;
5804 t = gtst(0, t);
5805 next();
5806 eand();
5810 /* XXX: better constant handling */
5811 static void expr_eq(void)
5813 int tt, u, r1, r2, rc, t1, t2, t, bt1, bt2;
5814 SValue sv;
5816 if (const_wanted) {
5817 int c1, c;
5818 sum(10);
5819 if (tok == '?') {
5820 c = vtop->c.i;
5821 vpop();
5822 next();
5823 gexpr();
5824 c1 = vtop->c.i;
5825 vpop();
5826 skip(':');
5827 expr_eq();
5828 if (c)
5829 vtop->c.i = c1;
5831 } else {
5832 eor();
5833 if (tok == '?') {
5834 next();
5835 save_regs(1); /* we need to save all registers here except
5836 at the top because it is a branch point */
5837 tt = gtst(1, 0);
5838 gexpr();
5839 t1 = vtop->t;
5840 bt1 = t1 & VT_BTYPE;
5841 sv = *vtop; /* save value to handle it later */
5842 vtop--; /* no vpop so that FP stack is not flushed */
5843 skip(':');
5844 u = gjmp(0);
5846 gsym(tt);
5847 expr_eq();
5848 t2 = vtop->t;
5850 bt2 = t2 & VT_BTYPE;
5851 /* cast operands to correct type according to ISOC rules */
5852 if (is_float(bt1) || is_float(bt2)) {
5853 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
5854 t = VT_LDOUBLE;
5855 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
5856 t = VT_DOUBLE;
5857 } else {
5858 t = VT_FLOAT;
5860 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
5861 /* cast to biggest op */
5862 t = VT_LLONG;
5863 /* convert to unsigned if it does not fit in a long long */
5864 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
5865 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
5866 t |= VT_UNSIGNED;
5867 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
5868 /* XXX: test pointer compatibility */
5869 t = t1;
5870 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5871 /* XXX: test structure compatibility */
5872 t = t1;
5873 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
5874 /* NOTE: as an extension, we accept void on only one side */
5875 t = VT_VOID;
5876 } else {
5877 /* integer operations */
5878 t = VT_INT;
5879 /* convert to unsigned if it does not fit in an integer */
5880 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
5881 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
5882 t |= VT_UNSIGNED;
5885 /* now we convert second operand */
5886 gen_cast(t);
5887 rc = RC_INT;
5888 if (is_float(t)) {
5889 rc = RC_FLOAT;
5890 } else if ((t & VT_BTYPE) == VT_LLONG) {
5891 /* for long longs, we use fixed registers to avoid having
5892 to handle a complicated move */
5893 rc = RC_IRET;
5895 r2 = gv(rc);
5896 /* this is horrible, but we must also convert first
5897 operand */
5898 tt = gjmp(0);
5899 gsym(u);
5900 /* put again first value and cast it */
5901 *vtop = sv;
5902 gen_cast(t);
5903 r1 = gv(rc);
5904 move_reg(r2, r1);
5905 vtop->r = r2;
5906 gsym(tt);
5911 static void gexpr(void)
5913 while (1) {
5914 expr_eq();
5915 if (tok != ',')
5916 break;
5917 vpop();
5918 next();
5922 /* parse an expression and return its type without any side effect. */
5923 static int expr_type(void)
5925 int a, t;
5927 a = nocode_wanted;
5928 nocode_wanted = 1;
5929 gexpr();
5930 t = vtop->t;
5931 vpop();
5932 nocode_wanted = a;
5933 return t;
5936 /* parse a unary expression and return its type without any side
5937 effect. */
5938 static int unary_type(void)
5940 int a, t;
5942 a = nocode_wanted;
5943 nocode_wanted = 1;
5944 unary();
5945 t = vtop->t;
5946 vpop();
5947 nocode_wanted = a;
5948 return t;
5951 /* parse a constant expression and return value in vtop. */
5952 static void expr_const1(void)
5954 int a;
5955 a = const_wanted;
5956 const_wanted = 1;
5957 expr_eq();
5958 const_wanted = a;
5961 /* parse an integer constant and return its value. */
5962 static int expr_const(void)
5964 int c;
5965 expr_const1();
5966 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
5967 expect("constant expression");
5968 c = vtop->c.i;
5969 vpop();
5970 return c;
5973 /* return the label token if current token is a label, otherwise
5974 return zero */
5975 static int is_label(void)
5977 int t;
5978 CValue c;
5980 /* fast test first */
5981 if (tok < TOK_UIDENT)
5982 return 0;
5983 /* no need to save tokc since we expect an identifier */
5984 t = tok;
5985 c = tokc;
5986 next();
5987 if (tok == ':') {
5988 next();
5989 return t;
5990 } else {
5991 /* XXX: may not work in all cases (macros ?) */
5992 tok1 = tok;
5993 tok1c = tokc;
5994 tok = t;
5995 tokc = c;
5996 return 0;
6000 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
6002 int a, b, c, d;
6003 Sym *s;
6005 /* generate line number info */
6006 if (do_debug &&
6007 (last_line_num != file->line_num || last_ind != ind)) {
6008 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
6009 last_ind = ind;
6010 last_line_num = file->line_num;
6013 if (tok == TOK_IF) {
6014 /* if test */
6015 next();
6016 skip('(');
6017 gexpr();
6018 skip(')');
6019 a = gtst(1, 0);
6020 block(bsym, csym, case_sym, def_sym, case_reg);
6021 c = tok;
6022 if (c == TOK_ELSE) {
6023 next();
6024 d = gjmp(0);
6025 gsym(a);
6026 block(bsym, csym, case_sym, def_sym, case_reg);
6027 gsym(d); /* patch else jmp */
6028 } else
6029 gsym(a);
6030 } else if (tok == TOK_WHILE) {
6031 next();
6032 d = ind;
6033 skip('(');
6034 gexpr();
6035 skip(')');
6036 a = gtst(1, 0);
6037 b = 0;
6038 block(&a, &b, case_sym, def_sym, case_reg);
6039 gjmp_addr(d);
6040 gsym(a);
6041 gsym_addr(b, d);
6042 } else if (tok == '{') {
6043 next();
6044 /* declarations */
6045 s = local_stack.top;
6046 while (tok != '}') {
6047 decl(VT_LOCAL);
6048 if (tok != '}')
6049 block(bsym, csym, case_sym, def_sym, case_reg);
6051 /* pop locally defined symbols */
6052 sym_pop(&local_stack, s);
6053 next();
6054 } else if (tok == TOK_RETURN) {
6055 next();
6056 if (tok != ';') {
6057 gexpr();
6058 gen_assign_cast(func_vt);
6059 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
6060 /* if returning structure, must copy it to implicit
6061 first pointer arg location */
6062 vset(mk_pointer(func_vt), VT_LOCAL | VT_LVAL, func_vc);
6063 indir();
6064 vswap();
6065 /* copy structure value to pointer */
6066 vstore();
6067 } else if (is_float(func_vt)) {
6068 gv(RC_FRET);
6069 } else {
6070 gv(RC_IRET);
6072 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
6074 skip(';');
6075 rsym = gjmp(rsym); /* jmp */
6076 } else if (tok == TOK_BREAK) {
6077 /* compute jump */
6078 if (!bsym)
6079 error("cannot break");
6080 *bsym = gjmp(*bsym);
6081 next();
6082 skip(';');
6083 } else if (tok == TOK_CONTINUE) {
6084 /* compute jump */
6085 if (!csym)
6086 error("cannot continue");
6087 *csym = gjmp(*csym);
6088 next();
6089 skip(';');
6090 } else if (tok == TOK_FOR) {
6091 int e;
6092 next();
6093 skip('(');
6094 if (tok != ';') {
6095 gexpr();
6096 vpop();
6098 skip(';');
6099 d = ind;
6100 c = ind;
6101 a = 0;
6102 b = 0;
6103 if (tok != ';') {
6104 gexpr();
6105 a = gtst(1, 0);
6107 skip(';');
6108 if (tok != ')') {
6109 e = gjmp(0);
6110 c = ind;
6111 gexpr();
6112 vpop();
6113 gjmp_addr(d);
6114 gsym(e);
6116 skip(')');
6117 block(&a, &b, case_sym, def_sym, case_reg);
6118 gjmp_addr(c);
6119 gsym(a);
6120 gsym_addr(b, c);
6121 } else
6122 if (tok == TOK_DO) {
6123 next();
6124 a = 0;
6125 b = 0;
6126 d = ind;
6127 block(&a, &b, case_sym, def_sym, case_reg);
6128 skip(TOK_WHILE);
6129 skip('(');
6130 gsym(b);
6131 gexpr();
6132 c = gtst(0, 0);
6133 gsym_addr(c, d);
6134 skip(')');
6135 gsym(a);
6136 skip(';');
6137 } else
6138 if (tok == TOK_SWITCH) {
6139 next();
6140 skip('(');
6141 gexpr();
6142 /* XXX: other types than integer */
6143 case_reg = gv(RC_INT);
6144 vpop();
6145 skip(')');
6146 a = 0;
6147 b = gjmp(0); /* jump to first case */
6148 c = 0;
6149 block(&a, csym, &b, &c, case_reg);
6150 /* if no default, jmp after switch */
6151 if (c == 0)
6152 c = ind;
6153 /* default label */
6154 gsym_addr(b, c);
6155 /* break label */
6156 gsym(a);
6157 } else
6158 if (tok == TOK_CASE) {
6159 int v1, v2;
6160 if (!case_sym)
6161 expect("switch");
6162 next();
6163 v1 = expr_const();
6164 v2 = v1;
6165 if (gnu_ext && tok == TOK_DOTS) {
6166 next();
6167 v2 = expr_const();
6168 if (v2 < v1)
6169 warning("empty case range");
6171 /* since a case is like a label, we must skip it with a jmp */
6172 b = gjmp(0);
6173 gsym(*case_sym);
6174 vset(VT_INT, case_reg, 0);
6175 vpushi(v1);
6176 if (v1 == v2) {
6177 gen_op(TOK_EQ);
6178 *case_sym = gtst(1, 0);
6179 } else {
6180 gen_op(TOK_GE);
6181 *case_sym = gtst(1, 0);
6182 vset(VT_INT, case_reg, 0);
6183 vpushi(v2);
6184 gen_op(TOK_LE);
6185 *case_sym = gtst(1, *case_sym);
6187 gsym(b);
6188 skip(':');
6189 block(bsym, csym, case_sym, def_sym, case_reg);
6190 } else
6191 if (tok == TOK_DEFAULT) {
6192 next();
6193 skip(':');
6194 if (!def_sym)
6195 expect("switch");
6196 if (*def_sym)
6197 error("too many 'default'");
6198 *def_sym = ind;
6199 block(bsym, csym, case_sym, def_sym, case_reg);
6200 } else
6201 if (tok == TOK_GOTO) {
6202 next();
6203 s = sym_find1(&label_stack, tok);
6204 /* put forward definition if needed */
6205 if (!s)
6206 s = sym_push1(&label_stack, tok, LABEL_FORWARD, 0);
6207 /* label already defined */
6208 if (s->t & LABEL_FORWARD)
6209 s->c = gjmp(s->c);
6210 else
6211 gjmp_addr(s->c);
6212 next();
6213 skip(';');
6214 } else {
6215 b = is_label();
6216 if (b) {
6217 /* label case */
6218 s = sym_find1(&label_stack, b);
6219 if (s) {
6220 if (!(s->t & LABEL_FORWARD))
6221 error("multiple defined label");
6222 gsym(s->c);
6223 s->c = ind;
6224 s->t = 0;
6225 } else {
6226 sym_push1(&label_stack, b, 0, ind);
6228 /* we accept this, but it is a mistake */
6229 if (tok == '}')
6230 warning("deprecated use of label at end of compound statement");
6231 else
6232 block(bsym, csym, case_sym, def_sym, case_reg);
6233 } else {
6234 /* expression case */
6235 if (tok != ';') {
6236 gexpr();
6237 vpop();
6239 skip(';');
6244 /* t is the array or struct type. c is the array or struct
6245 address. cur_index/cur_field is the pointer to the current
6246 value. 'size_only' is true if only size info is needed (only used
6247 in arrays) */
6248 static void decl_designator(int t, Section *sec, unsigned long c,
6249 int *cur_index, Sym **cur_field,
6250 int size_only)
6252 Sym *s, *f;
6253 int notfirst, index, align, l;
6255 notfirst = 0;
6256 if (gnu_ext && (l = is_label()) != 0)
6257 goto struct_field;
6259 while (tok == '[' || tok == '.') {
6260 if (tok == '[') {
6261 if (!(t & VT_ARRAY))
6262 expect("array type");
6263 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
6264 next();
6265 index = expr_const();
6266 if (index < 0 || (s->c >= 0 && index >= s->c))
6267 expect("invalid index");
6268 skip(']');
6269 if (!notfirst)
6270 *cur_index = index;
6271 t = pointed_type(t);
6272 c += index * type_size(t, &align);
6273 } else {
6274 next();
6275 l = tok;
6276 next();
6277 struct_field:
6278 if ((t & VT_BTYPE) != VT_STRUCT)
6279 expect("struct/union type");
6280 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
6281 l |= SYM_FIELD;
6282 f = s->next;
6283 while (f) {
6284 if (f->v == l)
6285 break;
6286 f = f->next;
6288 if (!f)
6289 expect("field");
6290 if (!notfirst)
6291 *cur_field = f;
6292 t = f->t | (t & ~VT_TYPE);
6293 c += f->c;
6295 notfirst = 1;
6297 if (notfirst) {
6298 if (tok == '=') {
6299 next();
6300 } else {
6301 if (!gnu_ext)
6302 expect("=");
6304 } else {
6305 if (t & VT_ARRAY) {
6306 index = *cur_index;
6307 t = pointed_type(t);
6308 c += index * type_size(t, &align);
6309 } else {
6310 f = *cur_field;
6311 if (!f)
6312 error("too many field init");
6313 t = f->t | (t & ~VT_TYPE);
6314 c += f->c;
6317 decl_initializer(t, sec, c, 0, size_only);
6320 #define EXPR_VAL 0
6321 #define EXPR_CONST 1
6322 #define EXPR_ANY 2
6324 /* store a value or an expression directly in global data or in local array */
6325 static void init_putv(int t, Section *sec, unsigned long c,
6326 int v, int expr_type)
6328 int saved_global_expr, bt;
6329 void *ptr;
6331 switch(expr_type) {
6332 case EXPR_VAL:
6333 vpushi(v);
6334 break;
6335 case EXPR_CONST:
6336 /* compound literals must be allocated globally in this case */
6337 saved_global_expr = global_expr;
6338 global_expr = 1;
6339 expr_const1();
6340 global_expr = saved_global_expr;
6341 /* NOTE: symbols are accepted */
6342 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
6343 error("initializer element is not constant");
6344 break;
6345 case EXPR_ANY:
6346 expr_eq();
6347 break;
6350 if (sec) {
6351 /* XXX: not portable */
6352 /* XXX: generate error if incorrect relocation */
6353 gen_assign_cast(t);
6354 bt = t & VT_BTYPE;
6355 ptr = sec->data + c;
6356 if ((vtop->r & VT_SYM) &&
6357 (bt == VT_BYTE ||
6358 bt == VT_SHORT ||
6359 bt == VT_DOUBLE ||
6360 bt == VT_LDOUBLE ||
6361 bt == VT_LLONG))
6362 error("initializer element is not computable at load time");
6363 switch(bt) {
6364 case VT_BYTE:
6365 *(char *)ptr = vtop->c.i;
6366 break;
6367 case VT_SHORT:
6368 *(short *)ptr = vtop->c.i;
6369 break;
6370 case VT_DOUBLE:
6371 *(double *)ptr = vtop->c.d;
6372 break;
6373 case VT_LDOUBLE:
6374 *(long double *)ptr = vtop->c.ld;
6375 break;
6376 case VT_LLONG:
6377 *(long long *)ptr = vtop->c.ll;
6378 break;
6379 default:
6380 if (vtop->r & VT_SYM) {
6381 greloc(sec, vtop->sym, c, R_DATA_32);
6383 *(int *)ptr = vtop->c.i;
6384 break;
6386 vtop--;
6387 } else {
6388 vset(t, VT_LOCAL, c);
6389 vswap();
6390 vstore();
6391 vpop();
6395 /* put zeros for variable based init */
6396 static void init_putz(int t, Section *sec, unsigned long c, int size)
6398 GFuncContext gf;
6400 if (sec) {
6401 /* nothing to do because globals are already set to zero */
6402 } else {
6403 gfunc_start(&gf, FUNC_CDECL);
6404 vpushi(size);
6405 gfunc_param(&gf);
6406 vpushi(0);
6407 gfunc_param(&gf);
6408 vset(VT_INT, VT_LOCAL, c);
6409 gfunc_param(&gf);
6410 vpush_global_sym(func_old_type, TOK_memset);
6411 gfunc_call(&gf);
6415 /* 't' contains the type and storage info. 'c' is the offset of the
6416 object in section 'sec'. If 'sec' is NULL, it means stack based
6417 allocation. 'first' is true if array '{' must be read (multi
6418 dimension implicit array init handling). 'size_only' is true if
6419 size only evaluation is wanted (only for arrays). */
6420 static void decl_initializer(int t, Section *sec, unsigned long c,
6421 int first, int size_only)
6423 int index, array_length, n, no_oblock, nb, parlevel, i;
6424 int t1, size1, align1, expr_type;
6425 Sym *s, *f;
6427 if (t & VT_ARRAY) {
6428 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
6429 n = s->c;
6430 array_length = 0;
6431 t1 = pointed_type(t);
6432 size1 = type_size(t1, &align1);
6434 no_oblock = 1;
6435 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
6436 tok == '{') {
6437 skip('{');
6438 no_oblock = 0;
6441 /* only parse strings here if correct type (otherwise: handle
6442 them as ((w)char *) expressions */
6443 if ((tok == TOK_LSTR &&
6444 (t1 & VT_BTYPE) == VT_INT) ||
6445 (tok == TOK_STR &&
6446 (t1 & VT_BTYPE) == VT_BYTE)) {
6447 while (tok == TOK_STR || tok == TOK_LSTR) {
6448 int cstr_len, ch;
6449 CString *cstr;
6451 cstr = tokc.cstr;
6452 /* compute maximum number of chars wanted */
6453 if (tok == TOK_STR)
6454 cstr_len = cstr->size;
6455 else
6456 cstr_len = cstr->size / sizeof(int);
6457 cstr_len--;
6458 nb = cstr_len;
6459 if (n >= 0 && nb > (n - array_length))
6460 nb = n - array_length;
6461 if (!size_only) {
6462 if (cstr_len > nb)
6463 warning("initializer-string for array is too long");
6464 /* in order to go faster for common case (char
6465 string in global variable, we handle it
6466 specifically */
6467 if (sec && tok == TOK_STR && size1 == 1) {
6468 memcpy(sec->data + c + array_length, cstr->data, nb);
6469 } else {
6470 for(i=0;i<nb;i++) {
6471 if (tok == TOK_STR)
6472 ch = ((unsigned char *)cstr->data)[i];
6473 else
6474 ch = ((int *)cstr->data)[i];
6475 init_putv(t1, sec, c + (array_length + i) * size1,
6476 ch, EXPR_VAL);
6480 array_length += nb;
6481 next();
6483 /* only add trailing zero if enough storage (no
6484 warning in this case since it is standard) */
6485 if (n < 0 || array_length < n) {
6486 if (!size_only) {
6487 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
6489 array_length++;
6491 } else {
6492 index = 0;
6493 while (tok != '}') {
6494 decl_designator(t, sec, c, &index, NULL, size_only);
6495 if (n >= 0 && index >= n)
6496 error("index too large");
6497 /* must put zero in holes (note that doing it that way
6498 ensures that it even works with designators) */
6499 if (!size_only && array_length < index) {
6500 init_putz(t1, sec, c + array_length * size1,
6501 (index - array_length) * size1);
6503 index++;
6504 if (index > array_length)
6505 array_length = index;
6506 /* special test for multi dimensional arrays (may not
6507 be strictly correct if designators are used at the
6508 same time) */
6509 if (index >= n && no_oblock)
6510 break;
6511 if (tok == '}')
6512 break;
6513 skip(',');
6516 if (!no_oblock)
6517 skip('}');
6518 /* put zeros at the end */
6519 if (!size_only && n >= 0 && array_length < n) {
6520 init_putz(t1, sec, c + array_length * size1,
6521 (n - array_length) * size1);
6523 /* patch type size if needed */
6524 if (n < 0)
6525 s->c = array_length;
6526 } else if ((t & VT_BTYPE) == VT_STRUCT && tok == '{') {
6527 /* XXX: union needs only one init */
6528 next();
6529 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
6530 f = s->next;
6531 array_length = 0;
6532 index = 0;
6533 n = s->c;
6534 while (tok != '}') {
6535 decl_designator(t, sec, c, NULL, &f, size_only);
6536 /* fill with zero between fields */
6537 index = f->c;
6538 if (!size_only && array_length < index) {
6539 init_putz(t, sec, c + array_length,
6540 index - array_length);
6542 index = index + type_size(f->t, &align1);
6543 if (index > array_length)
6544 array_length = index;
6545 if (tok == '}')
6546 break;
6547 skip(',');
6548 f = f->next;
6550 /* put zeros at the end */
6551 if (!size_only && array_length < n) {
6552 init_putz(t, sec, c + array_length,
6553 n - array_length);
6555 skip('}');
6556 } else if (tok == '{') {
6557 next();
6558 decl_initializer(t, sec, c, first, size_only);
6559 skip('}');
6560 } else if (size_only) {
6561 /* just skip expression */
6562 parlevel = 0;
6563 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
6564 tok != -1) {
6565 if (tok == '(')
6566 parlevel++;
6567 else if (tok == ')')
6568 parlevel--;
6569 next();
6571 } else {
6572 /* currently, we always use constant expression for globals
6573 (may change for scripting case) */
6574 expr_type = EXPR_CONST;
6575 if (!sec)
6576 expr_type = EXPR_ANY;
6577 init_putv(t, sec, c, 0, expr_type);
6581 /* parse an initializer for type 't' if 'has_init' is non zero, and
6582 allocate space in local or global data space ('r' is either
6583 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6584 variable 'v' of scope 'scope' is declared before initializers are
6585 parsed. If 'v' is zero, then a reference to the new object is put
6586 in the value stack. If 'has_init' is 2, a special parsing is done
6587 to handle string constants. */
6588 static void decl_initializer_alloc(int t, AttributeDef *ad, int r,
6589 int has_init, int v, int scope)
6591 int size, align, addr, data_offset;
6592 int level;
6593 ParseState saved_parse_state;
6594 TokenString init_str;
6595 Section *sec;
6597 size = type_size(t, &align);
6598 /* If unknown size, we must evaluate it before
6599 evaluating initializers because
6600 initializers can generate global data too
6601 (e.g. string pointers or ISOC99 compound
6602 literals). It also simplifies local
6603 initializers handling */
6604 tok_str_new(&init_str);
6605 if (size < 0) {
6606 if (!has_init)
6607 error("unknown type size");
6608 /* get all init string */
6609 if (has_init == 2) {
6610 /* only get strings */
6611 while (tok == TOK_STR || tok == TOK_LSTR) {
6612 tok_str_add_tok(&init_str);
6613 next();
6615 } else {
6616 level = 0;
6617 while (level > 0 || (tok != ',' && tok != ';')) {
6618 if (tok < 0)
6619 error("unexpected end of file in initializer");
6620 tok_str_add_tok(&init_str);
6621 if (tok == '{')
6622 level++;
6623 else if (tok == '}') {
6624 if (level == 0)
6625 break;
6626 level--;
6628 next();
6631 tok_str_add(&init_str, -1);
6632 tok_str_add(&init_str, 0);
6634 /* compute size */
6635 save_parse_state(&saved_parse_state);
6637 macro_ptr = init_str.str;
6638 next();
6639 decl_initializer(t, NULL, 0, 1, 1);
6640 /* prepare second initializer parsing */
6641 macro_ptr = init_str.str;
6642 next();
6644 /* if still unknown size, error */
6645 size = type_size(t, &align);
6646 if (size < 0)
6647 error("unknown type size");
6649 /* take into account specified alignment if bigger */
6650 if (ad->aligned > align)
6651 align = ad->aligned;
6652 if ((r & VT_VALMASK) == VT_LOCAL) {
6653 sec = NULL;
6654 if (do_bounds_check && (t & VT_ARRAY))
6655 loc--;
6656 #ifdef TCC_TARGET_IL
6657 /* XXX: ugly patch to allocate local variables for IL, just
6658 for testing */
6659 addr = loc;
6660 loc++;
6661 #else
6662 loc = (loc - size) & -align;
6663 addr = loc;
6664 #endif
6665 /* handles bounds */
6666 /* XXX: currently, since we do only one pass, we cannot track
6667 '&' operators, so we add only arrays */
6668 if (do_bounds_check && (t & VT_ARRAY)) {
6669 unsigned long *bounds_ptr;
6670 /* add padding between regions */
6671 loc--;
6672 /* then add local bound info */
6673 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
6674 bounds_ptr[0] = addr;
6675 bounds_ptr[1] = size;
6677 } else {
6678 /* compute section */
6679 sec = ad->section;
6680 if (!sec) {
6681 if (has_init)
6682 sec = data_section;
6683 else
6684 sec = bss_section;
6686 data_offset = sec->data_offset;
6687 data_offset = (data_offset + align - 1) & -align;
6688 addr = data_offset;
6689 /* very important to increment global pointer at this time
6690 because initializers themselves can create new initializers */
6691 data_offset += size;
6692 /* add padding if bound check */
6693 if (do_bounds_check)
6694 data_offset++;
6695 sec->data_offset = data_offset;
6696 /* allocate section space to put the data */
6697 if (sec->sh_type != SHT_NOBITS &&
6698 data_offset > sec->data_allocated)
6699 section_realloc(sec, data_offset);
6701 if (!sec) {
6702 if (v) {
6703 /* local variable */
6704 sym_push(v, t, r, addr);
6705 } else {
6706 /* push local reference */
6707 vset(t, r, addr);
6709 } else {
6710 Sym *sym;
6712 if (v) {
6713 if (scope == VT_CONST) {
6714 /* global scope: see if already defined */
6715 sym = sym_find(v);
6716 if (!sym)
6717 goto do_def;
6718 if (!is_compatible_types(sym->t, t))
6719 error("incompatible types for redefinition of '%s'",
6720 get_tok_str(v, NULL));
6721 if (!(sym->t & VT_EXTERN))
6722 error("redefinition of '%s'", get_tok_str(v, NULL));
6723 sym->t &= ~VT_EXTERN;
6724 } else {
6725 do_def:
6726 sym = sym_push(v, t, r | VT_SYM, 0);
6728 put_extern_sym(sym, sec, addr, size);
6729 } else {
6730 CValue cval;
6732 /* push global reference */
6733 sym = get_sym_ref(t, sec, addr, size);
6734 cval.ul = 0;
6735 vsetc(t, VT_CONST | VT_SYM, &cval);
6736 vtop->sym = sym;
6739 /* handles bounds now because the symbol must be defined
6740 before for the relocation */
6741 if (do_bounds_check) {
6742 unsigned long *bounds_ptr;
6744 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
6745 /* then add global bound info */
6746 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
6747 bounds_ptr[0] = 0; /* relocated */
6748 bounds_ptr[1] = size;
6751 if (has_init) {
6752 decl_initializer(t, sec, addr, 1, 0);
6753 /* restore parse state if needed */
6754 if (init_str.str) {
6755 tok_str_free(init_str.str);
6756 restore_parse_state(&saved_parse_state);
6761 void put_func_debug(Sym *sym)
6763 char buf[512];
6765 /* stabs info */
6766 /* XXX: we put here a dummy type */
6767 snprintf(buf, sizeof(buf), "%s:%c1",
6768 funcname, sym->t & VT_STATIC ? 'f' : 'F');
6769 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
6770 cur_text_section, sym->c);
6771 last_ind = 0;
6772 last_line_num = 0;
6775 /* not finished : try to put some local vars in registers */
6776 //#define CONFIG_REG_VARS
6778 #ifdef CONFIG_REG_VARS
6779 void add_var_ref(int t)
6781 printf("%s:%d: &%s\n",
6782 file->filename, file->line_num,
6783 get_tok_str(t, NULL));
6786 /* first pass on a function with heuristic to extract variable usage
6787 and pointer references to local variables for register allocation */
6788 void analyse_function(void)
6790 int level, t;
6792 for(;;) {
6793 if (tok == -1)
6794 break;
6795 /* any symbol coming after '&' is considered as being a
6796 variable whose reference is taken. It is highly unaccurate
6797 but it is difficult to do better without a complete parse */
6798 if (tok == '&') {
6799 next();
6800 /* if '& number', then no need to examine next tokens */
6801 if (tok == TOK_CINT ||
6802 tok == TOK_CUINT ||
6803 tok == TOK_CLLONG ||
6804 tok == TOK_CULLONG) {
6805 continue;
6806 } else if (tok >= TOK_UIDENT) {
6807 /* if '& ident [' or '& ident ->', then ident address
6808 is not needed */
6809 t = tok;
6810 next();
6811 if (tok != '[' && tok != TOK_ARROW)
6812 add_var_ref(t);
6813 } else {
6814 level = 0;
6815 while (tok != '}' && tok != ';' &&
6816 !((tok == ',' || tok == ')') && level == 0)) {
6817 if (tok >= TOK_UIDENT) {
6818 add_var_ref(tok);
6819 } else if (tok == '(') {
6820 level++;
6821 } else if (tok == ')') {
6822 level--;
6824 next();
6827 } else {
6828 next();
6832 #endif
6834 /* parse an old style function declaration list */
6835 /* XXX: check multiple parameter */
6836 static void func_decl_list(Sym *func_sym)
6838 AttributeDef ad;
6839 int b, v, t;
6840 Sym *s;
6841 /* parse each declaration */
6842 while (tok != '{' && tok != ';' && tok != TOK_EOF) {
6843 if (!parse_btype(&b, &ad))
6844 expect("declaration list");
6845 if (((b & VT_BTYPE) == VT_ENUM ||
6846 (b & VT_BTYPE) == VT_STRUCT) &&
6847 tok == ';') {
6848 /* we accept no variable after */
6849 } else {
6850 for(;;) {
6851 t = type_decl(&ad, &v, b, TYPE_DIRECT);
6852 /* find parameter in function parameter list */
6853 s = func_sym->next;
6854 while (s != NULL) {
6855 if ((s->v & ~SYM_FIELD) == v)
6856 goto found;
6857 s = s->next;
6859 error("declaration for parameter '%s' but no such parameter",
6860 get_tok_str(v, NULL));
6861 found:
6862 /* check that no storage specifier except 'register' was given */
6863 if (t & (VT_EXTERN | VT_STATIC | VT_TYPEDEF))
6864 error("storage class specified for '%s'", get_tok_str(v, NULL));
6865 /* we can add the type (NOTE: it could be local to the function) */
6866 s->t = t;
6867 /* accept other parameters */
6868 if (tok == ',')
6869 next();
6870 else
6871 break;
6874 skip(';');
6878 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6879 static void decl(int l)
6881 int t, b, v, has_init, r;
6882 Sym *sym;
6883 AttributeDef ad;
6885 while (1) {
6886 if (!parse_btype(&b, &ad)) {
6887 /* skip redundant ';' */
6888 /* XXX: find more elegant solution */
6889 if (tok == ';') {
6890 next();
6891 continue;
6893 /* special test for old K&R protos without explicit int
6894 type. Only accepted when defining global data */
6895 if (l == VT_LOCAL || tok < TOK_DEFINE)
6896 break;
6897 b = VT_INT;
6899 if (((b & VT_BTYPE) == VT_ENUM ||
6900 (b & VT_BTYPE) == VT_STRUCT) &&
6901 tok == ';') {
6902 /* we accept no variable after */
6903 next();
6904 continue;
6906 while (1) { /* iterate thru each declaration */
6907 t = type_decl(&ad, &v, b, TYPE_DIRECT);
6908 #if 0
6910 char buf[500];
6911 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6912 printf("type = '%s'\n", buf);
6914 #endif
6915 if ((t & VT_BTYPE) == VT_FUNC) {
6916 /* if old style function prototype, we accept a
6917 declaration list */
6918 sym = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
6919 if (sym->c == FUNC_OLD)
6920 func_decl_list(sym);
6923 if (tok == '{') {
6924 #ifdef CONFIG_REG_VARS
6925 TokenString func_str;
6926 ParseState saved_parse_state;
6927 int block_level;
6928 #endif
6930 if (l == VT_LOCAL)
6931 error("cannot use local functions");
6932 if (!(t & VT_FUNC))
6933 expect("function definition");
6935 #ifdef CONFIG_REG_VARS
6936 /* parse all function code and record it */
6938 tok_str_new(&func_str);
6940 block_level = 0;
6941 for(;;) {
6942 int t;
6943 if (tok == -1)
6944 error("unexpected end of file");
6945 tok_str_add_tok(&func_str);
6946 t = tok;
6947 next();
6948 if (t == '{') {
6949 block_level++;
6950 } else if (t == '}') {
6951 block_level--;
6952 if (block_level == 0)
6953 break;
6956 tok_str_add(&func_str, -1);
6957 tok_str_add(&func_str, 0);
6959 save_parse_state(&saved_parse_state);
6961 macro_ptr = func_str.str;
6962 next();
6963 analyse_function();
6964 #endif
6966 /* compute text section */
6967 cur_text_section = ad.section;
6968 if (!cur_text_section)
6969 cur_text_section = text_section;
6970 ind = cur_text_section->data_offset;
6971 funcname = get_tok_str(v, NULL);
6972 sym = sym_find(v);
6973 if (sym) {
6974 /* if symbol is already defined, then put complete type */
6975 sym->t = t;
6976 } else {
6977 /* put function symbol */
6978 sym = sym_push1(&global_stack, v, t, 0);
6980 /* NOTE: we patch the symbol size later */
6981 put_extern_sym(sym, cur_text_section, ind, 0);
6982 func_ind = ind;
6983 sym->r = VT_SYM | VT_CONST;
6984 /* put debug symbol */
6985 if (do_debug)
6986 put_func_debug(sym);
6987 /* push a dummy symbol to enable local sym storage */
6988 sym_push1(&local_stack, 0, 0, 0);
6989 gfunc_prolog(t);
6990 loc = 0;
6991 rsym = 0;
6992 #ifdef CONFIG_REG_VARS
6993 macro_ptr = func_str.str;
6994 next();
6995 #endif
6996 block(NULL, NULL, NULL, NULL, 0);
6997 gsym(rsym);
6998 gfunc_epilog();
6999 cur_text_section->data_offset = ind;
7000 sym_pop(&label_stack, NULL); /* reset label stack */
7001 sym_pop(&local_stack, NULL); /* reset local stack */
7002 /* end of function */
7003 /* patch symbol size */
7004 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
7005 ind - func_ind;
7006 if (do_debug) {
7007 put_stabn(N_FUN, 0, 0, ind - func_ind);
7009 funcname = ""; /* for safety */
7010 func_vt = VT_VOID; /* for safety */
7011 ind = 0; /* for safety */
7013 #ifdef CONFIG_REG_VARS
7014 tok_str_free(func_str.str);
7015 restore_parse_state(&saved_parse_state);
7016 #endif
7017 break;
7018 } else {
7019 if (b & VT_TYPEDEF) {
7020 /* save typedefed type */
7021 /* XXX: test storage specifiers ? */
7022 sym_push(v, t | VT_TYPEDEF, 0, 0);
7023 } else if ((t & VT_BTYPE) == VT_FUNC) {
7024 /* external function definition */
7025 external_sym(v, t, 0);
7026 } else {
7027 /* not lvalue if array */
7028 r = 0;
7029 if (!(t & VT_ARRAY))
7030 r |= lvalue_type(t);
7031 if (b & VT_EXTERN) {
7032 /* external variable */
7033 external_sym(v, t, r);
7034 } else {
7035 if (t & VT_STATIC)
7036 r |= VT_CONST;
7037 else
7038 r |= l;
7039 has_init = (tok == '=');
7040 if (has_init)
7041 next();
7042 decl_initializer_alloc(t, &ad, r,
7043 has_init, v, l);
7046 if (tok != ',') {
7047 skip(';');
7048 break;
7050 next();
7056 /* free define stack until top reaches 'b' */
7057 static void free_defines(Sym *b)
7059 Sym *top, *top1;
7061 top = define_stack.top;
7062 while (top != b) {
7063 top1 = top->prev;
7064 /* do not free args or predefined defines */
7065 if (top->c)
7066 tok_str_free((int *)top->c);
7067 sym_pop(&define_stack, top1);
7068 top = top1;
7072 /* compile the C file opened in 'file'. Return non zero if errors. */
7073 static int tcc_compile(TCCState *s1)
7075 Sym *define_start, *sym;
7076 char buf[512];
7077 volatile int section_sym;
7078 int p;
7080 #ifdef INC_DEBUG
7081 printf("%s: **** new file\n", file->filename);
7082 #endif
7083 funcname = "";
7084 s1->include_stack_ptr = s1->include_stack;
7085 /* XXX: move that before to avoid having to initialize
7086 file->ifdef_stack_ptr ? */
7087 s1->ifdef_stack_ptr = s1->ifdef_stack;
7088 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
7090 /* XXX: not ANSI compliant: bound checking says error */
7091 vtop = vstack - 1;
7092 anon_sym = SYM_FIRST_ANOM;
7094 /* file info: full path + filename */
7095 section_sym = 0; /* avoid warning */
7096 if (do_debug) {
7097 section_sym = put_elf_sym(symtab_section, 0, 0,
7098 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
7099 text_section->sh_num, NULL);
7100 getcwd(buf, sizeof(buf));
7101 pstrcat(buf, sizeof(buf), "/");
7102 put_stabs_r(buf, N_SO, 0, 0,
7103 text_section->data_offset, text_section, section_sym);
7104 put_stabs_r(file->filename, N_SO, 0, 0,
7105 text_section->data_offset, text_section, section_sym);
7107 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
7108 symbols can be safely used */
7109 put_elf_sym(symtab_section, 0, 0,
7110 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
7111 SHN_ABS, file->filename);
7113 /* define common 'char *' type because it is often used internally
7114 for arrays and struct dereference */
7115 char_pointer_type = mk_pointer(VT_BYTE);
7116 /* define an old type function 'int func()' */
7117 p = anon_sym++;
7118 sym = sym_push(p, 0, FUNC_CDECL, FUNC_OLD);
7119 func_old_type = VT_FUNC | (p << VT_STRUCT_SHIFT);
7120 #if 0
7121 /* define 'void *alloca(unsigned int)' builtin function */
7123 Sym *s1;
7125 p = anon_sym++;
7126 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
7127 s1 = sym_push(0, VT_UNSIGNED | VT_INT, 0, 0);
7128 s1->next = NULL;
7129 sym->next = s1;
7130 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
7132 #endif
7134 define_start = define_stack.top;
7136 if (setjmp(s1->error_jmp_buf) == 0) {
7137 s1->nb_errors = 0;
7138 s1->error_set_jmp_enabled = 1;
7140 inp();
7141 ch = '\n'; /* needed to parse correctly first preprocessor command */
7142 next();
7143 decl(VT_CONST);
7144 if (tok != -1)
7145 expect("declaration");
7147 /* end of translation unit info */
7148 if (do_debug) {
7149 put_stabs_r(NULL, N_SO, 0, 0,
7150 text_section->data_offset, text_section, section_sym);
7153 s1->error_set_jmp_enabled = 0;
7155 /* reset define stack, but leave -Dsymbols (may be incorrect if
7156 they are undefined) */
7157 free_defines(define_start);
7159 sym_pop(&global_stack, NULL);
7161 return s1->nb_errors != 0 ? -1 : 0;
7164 int tcc_compile_string(TCCState *s, const char *str)
7166 BufferedFile bf1, *bf = &bf1;
7167 int ret;
7169 /* init file structure */
7170 bf->fd = -1;
7171 bf->buf_ptr = (char *)str;
7172 bf->buf_end = (char *)str + strlen(bf->buffer);
7173 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
7174 bf->line_num = 1;
7175 file = bf;
7177 ret = tcc_compile(s);
7179 /* currently, no need to close */
7180 return ret;
7183 /* define a symbol. A value can also be provided with the '=' operator */
7184 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
7186 BufferedFile bf1, *bf = &bf1;
7188 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
7189 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
7190 /* default value */
7191 if (!value)
7192 value = "1";
7193 pstrcat(bf->buffer, IO_BUF_SIZE, value);
7195 /* init file structure */
7196 bf->fd = -1;
7197 bf->buf_ptr = bf->buffer;
7198 bf->buf_end = bf->buffer + strlen(bf->buffer);
7199 bf->filename[0] = '\0';
7200 bf->line_num = 1;
7201 file = bf;
7203 s1->include_stack_ptr = s1->include_stack;
7205 /* parse with define parser */
7206 inp();
7207 ch = '\n'; /* needed to parse correctly first preprocessor command */
7208 next_nomacro();
7209 parse_define();
7210 file = NULL;
7213 void tcc_undefine_symbol(TCCState *s1, const char *sym)
7215 TokenSym *ts;
7216 Sym *s;
7217 ts = tok_alloc(sym, strlen(sym));
7218 s = sym_find1(&define_stack, tok);
7219 /* undefine symbol by putting an invalid name */
7220 if (s)
7221 sym_undef(&define_stack, s);
7224 #include "tccelf.c"
7226 /* print the position in the source file of PC value 'pc' by reading
7227 the stabs debug information */
7228 static void rt_printline(unsigned long wanted_pc)
7230 Stab_Sym *sym, *sym_end;
7231 char func_name[128], last_func_name[128];
7232 unsigned long func_addr, last_pc, pc;
7233 const char *incl_files[INCLUDE_STACK_SIZE];
7234 int incl_index, len, last_line_num, i;
7235 const char *str, *p;
7237 func_name[0] = '\0';
7238 func_addr = 0;
7239 incl_index = 0;
7240 last_func_name[0] = '\0';
7241 last_pc = 0xffffffff;
7242 last_line_num = 1;
7243 sym = (Stab_Sym *)stab_section->data + 1;
7244 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
7245 while (sym < sym_end) {
7246 switch(sym->n_type) {
7247 /* function start or end */
7248 case N_FUN:
7249 if (sym->n_strx == 0) {
7250 func_name[0] = '\0';
7251 func_addr = 0;
7252 } else {
7253 str = stabstr_section->data + sym->n_strx;
7254 p = strchr(str, ':');
7255 if (!p) {
7256 pstrcpy(func_name, sizeof(func_name), str);
7257 } else {
7258 len = p - str;
7259 if (len > sizeof(func_name) - 1)
7260 len = sizeof(func_name) - 1;
7261 memcpy(func_name, str, len);
7262 func_name[len] = '\0';
7264 func_addr = sym->n_value;
7266 break;
7267 /* line number info */
7268 case N_SLINE:
7269 pc = sym->n_value + func_addr;
7270 if (wanted_pc >= last_pc && wanted_pc < pc)
7271 goto found;
7272 last_pc = pc;
7273 last_line_num = sym->n_desc;
7274 /* XXX: slow! */
7275 strcpy(last_func_name, func_name);
7276 break;
7277 /* include files */
7278 case N_BINCL:
7279 str = stabstr_section->data + sym->n_strx;
7280 add_incl:
7281 if (incl_index < INCLUDE_STACK_SIZE) {
7282 incl_files[incl_index++] = str;
7284 break;
7285 case N_EINCL:
7286 if (incl_index > 1)
7287 incl_index--;
7288 break;
7289 case N_SO:
7290 if (sym->n_strx == 0) {
7291 incl_index = 0; /* end of translation unit */
7292 } else {
7293 str = stabstr_section->data + sym->n_strx;
7294 /* do not add path */
7295 len = strlen(str);
7296 if (len > 0 && str[len - 1] != '/')
7297 goto add_incl;
7299 break;
7301 sym++;
7303 /* did not find line number info: */
7304 fprintf(stderr, "(no debug info, pc=0x%08lx): ", wanted_pc);
7305 return;
7306 found:
7307 for(i = 0; i < incl_index - 1; i++)
7308 fprintf(stderr, "In file included from %s\n",
7309 incl_files[i]);
7310 if (incl_index > 0) {
7311 fprintf(stderr, "%s:%d: ",
7312 incl_files[incl_index - 1], last_line_num);
7314 if (last_func_name[0] != '\0') {
7315 fprintf(stderr, "in function '%s()': ", last_func_name);
7319 /* emit a run time error at position 'pc' */
7320 void rt_error(unsigned long pc, const char *fmt, ...)
7322 va_list ap;
7323 va_start(ap, fmt);
7325 rt_printline(pc);
7326 vfprintf(stderr, fmt, ap);
7327 fprintf(stderr, "\n");
7328 exit(255);
7329 va_end(ap);
7332 #ifndef WIN32
7333 /* signal handler for fatal errors */
7334 static void sig_error(int signum, siginfo_t *siginf, void *puc)
7336 struct ucontext *uc = puc;
7337 unsigned long pc;
7339 #ifdef __i386__
7340 pc = uc->uc_mcontext.gregs[14];
7341 #else
7342 #error please put the right sigcontext field
7343 #endif
7345 switch(signum) {
7346 case SIGFPE:
7347 switch(siginf->si_code) {
7348 case FPE_INTDIV:
7349 case FPE_FLTDIV:
7350 rt_error(pc, "division by zero");
7351 break;
7352 default:
7353 rt_error(pc, "floating point exception");
7354 break;
7356 break;
7357 case SIGBUS:
7358 case SIGSEGV:
7359 rt_error(pc, "dereferencing invalid pointer");
7360 break;
7361 case SIGILL:
7362 rt_error(pc, "illegal instruction");
7363 break;
7364 case SIGABRT:
7365 rt_error(pc, "abort() called");
7366 break;
7367 default:
7368 rt_error(pc, "caught signal %d", signum);
7369 break;
7371 exit(255);
7373 #endif
7375 /* do all relocations (needed before using tcc_get_symbol()) */
7376 int tcc_relocate(TCCState *s1)
7378 Section *s;
7379 int i;
7381 s1->nb_errors = 0;
7383 tcc_add_runtime(s1);
7385 relocate_common_syms();
7387 /* compute relocation address : section are relocated in place. We
7388 also alloc the bss space */
7389 for(i = 1; i < s1->nb_sections; i++) {
7390 s = s1->sections[i];
7391 if (s->sh_flags & SHF_ALLOC) {
7392 if (s->sh_type == SHT_NOBITS)
7393 s->data = tcc_mallocz(s->data_offset);
7394 s->sh_addr = (unsigned long)s->data;
7398 relocate_syms(s1, 1);
7400 if (s1->nb_errors != 0)
7401 return -1;
7403 /* relocate each section */
7404 for(i = 1; i < s1->nb_sections; i++) {
7405 s = s1->sections[i];
7406 if (s->reloc)
7407 relocate_section(s1, s);
7409 return 0;
7412 /* launch the compiled program with the given arguments */
7413 int tcc_run(TCCState *s1, int argc, char **argv)
7415 int (*prog_main)(int, char **);
7417 if (tcc_relocate(s1) < 0)
7418 return -1;
7420 prog_main = tcc_get_symbol(s1, "main");
7422 if (do_debug) {
7423 #ifdef WIN32
7424 error("debug mode currently not available for Windows");
7425 #else
7426 struct sigaction sigact;
7427 /* install TCC signal handlers to print debug info on fatal
7428 runtime errors */
7429 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
7430 sigact.sa_sigaction = sig_error;
7431 sigemptyset(&sigact.sa_mask);
7432 sigaction(SIGFPE, &sigact, NULL);
7433 sigaction(SIGILL, &sigact, NULL);
7434 sigaction(SIGSEGV, &sigact, NULL);
7435 sigaction(SIGBUS, &sigact, NULL);
7436 sigaction(SIGABRT, &sigact, NULL);
7437 #endif
7440 #ifdef CONFIG_TCC_BCHECK
7441 if (do_bounds_check) {
7442 void (*bound_init)(void);
7443 void **bound_error_func;
7445 /* set error function */
7446 bound_error_func = (void **)tcc_get_symbol(s1, "__bound_error_func");
7447 *bound_error_func = rt_error;
7449 /* XXX: use .init section so that it also work in binary ? */
7450 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
7451 bound_init();
7453 #endif
7454 return (*prog_main)(argc, argv);
7457 TCCState *tcc_new(void)
7459 const char *p, *r;
7460 TCCState *s;
7462 s = tcc_mallocz(sizeof(TCCState));
7463 if (!s)
7464 return NULL;
7465 tcc_state = s;
7466 s->output_type = TCC_OUTPUT_MEMORY;
7468 /* default include paths */
7469 tcc_add_sysinclude_path(s, "/usr/local/include");
7470 tcc_add_sysinclude_path(s, "/usr/include");
7471 tcc_add_sysinclude_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
7473 /* add all tokens */
7474 table_ident = NULL;
7475 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
7477 tok_ident = TOK_IDENT;
7478 p = tcc_keywords;
7479 while (*p) {
7480 r = p;
7481 while (*r++);
7482 tok_alloc(p, r - p - 1);
7483 p = r;
7486 /* we add dummy defines for some special macros to speed up tests
7487 and to have working defined() */
7488 sym_push1(&define_stack, TOK___LINE__, MACRO_OBJ, 0);
7489 sym_push1(&define_stack, TOK___FILE__, MACRO_OBJ, 0);
7490 sym_push1(&define_stack, TOK___DATE__, MACRO_OBJ, 0);
7491 sym_push1(&define_stack, TOK___TIME__, MACRO_OBJ, 0);
7493 /* standard defines */
7494 tcc_define_symbol(s, "__STDC__", NULL);
7495 #if defined(TCC_TARGET_I386)
7496 tcc_define_symbol(s, "__i386__", NULL);
7497 #endif
7498 #if defined(linux)
7499 tcc_define_symbol(s, "linux", NULL);
7500 #endif
7501 /* tiny C specific defines */
7502 tcc_define_symbol(s, "__TINYC__", NULL);
7504 /* default library paths */
7505 tcc_add_library_path(s, "/usr/local/lib");
7506 tcc_add_library_path(s, "/usr/lib");
7507 tcc_add_library_path(s, "/lib");
7509 /* no section zero */
7510 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
7512 /* create standard sections */
7513 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
7514 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
7515 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
7517 /* symbols are always generated for linking stage */
7518 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
7519 ".strtab",
7520 ".hashtab", SHF_PRIVATE);
7521 strtab_section = symtab_section->link;
7523 /* private symbol table for dynamic symbols */
7524 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
7525 ".dynstrtab",
7526 ".dynhashtab", SHF_PRIVATE);
7527 return s;
7530 void tcc_delete(TCCState *s1)
7532 int i, n;
7534 /* free -D defines */
7535 free_defines(NULL);
7537 /* free tokens */
7538 n = tok_ident - TOK_IDENT;
7539 for(i = 0; i < n; i++)
7540 tcc_free(table_ident[i]);
7541 tcc_free(table_ident);
7543 /* free all sections */
7545 free_section(symtab_section->hash);
7547 free_section(s1->dynsymtab_section->hash);
7548 free_section(s1->dynsymtab_section->link);
7549 free_section(s1->dynsymtab_section);
7551 for(i = 1; i < s1->nb_sections; i++)
7552 free_section(s1->sections[i]);
7553 tcc_free(s1->sections);
7555 /* free loaded dlls array */
7556 for(i = 0; i < s1->nb_loaded_dlls; i++)
7557 tcc_free(s1->loaded_dlls[i]);
7558 tcc_free(s1->loaded_dlls);
7560 /* library paths */
7561 for(i = 0; i < s1->nb_library_paths; i++)
7562 tcc_free(s1->library_paths[i]);
7563 tcc_free(s1->library_paths);
7565 /* cached includes */
7566 for(i = 0; i < s1->nb_cached_includes; i++)
7567 tcc_free(s1->cached_includes[i]);
7568 tcc_free(s1->cached_includes);
7570 for(i = 0; i < s1->nb_include_paths; i++)
7571 tcc_free(s1->include_paths[i]);
7572 tcc_free(s1->include_paths);
7574 for(i = 0; i < s1->nb_sysinclude_paths; i++)
7575 tcc_free(s1->sysinclude_paths[i]);
7576 tcc_free(s1->sysinclude_paths);
7578 tcc_free(s1);
7581 int tcc_add_include_path(TCCState *s1, const char *pathname)
7583 char *pathname1;
7585 pathname1 = tcc_strdup(pathname);
7586 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
7587 return 0;
7590 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
7592 char *pathname1;
7594 pathname1 = tcc_strdup(pathname);
7595 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
7596 return 0;
7599 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
7601 const char *ext;
7602 Elf32_Ehdr ehdr;
7603 int fd, ret;
7604 BufferedFile *saved_file;
7606 /* find source file type with extension */
7607 ext = strrchr(filename, '.');
7608 if (ext)
7609 ext++;
7611 /* open the file */
7612 saved_file = file;
7613 file = tcc_open(s1, filename);
7614 if (!file) {
7615 if (flags & AFF_PRINT_ERROR) {
7616 error_noabort("file '%s' not found", filename);
7618 ret = -1;
7619 goto fail1;
7622 if (!ext || !strcmp(ext, "c")) {
7623 /* C file assumed */
7624 ret = tcc_compile(s1);
7625 } else {
7626 fd = file->fd;
7627 /* assume executable format: auto guess file type */
7628 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
7629 error_noabort("could not read header");
7630 goto fail;
7632 lseek(fd, 0, SEEK_SET);
7634 if (ehdr.e_ident[0] == ELFMAG0 &&
7635 ehdr.e_ident[1] == ELFMAG1 &&
7636 ehdr.e_ident[2] == ELFMAG2 &&
7637 ehdr.e_ident[3] == ELFMAG3) {
7638 file->line_num = 0; /* do not display line number if error */
7639 if (ehdr.e_type == ET_REL) {
7640 ret = tcc_load_object_file(s1, fd, 0);
7641 } else if (ehdr.e_type == ET_DYN) {
7642 ret = tcc_load_dll(s1, fd, filename,
7643 (flags & AFF_REFERENCED_DLL) != 0);
7644 } else {
7645 error_noabort("unrecognized ELF file");
7646 goto fail;
7648 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
7649 file->line_num = 0; /* do not display line number if error */
7650 ret = tcc_load_archive(s1, fd);
7651 } else {
7652 /* as GNU ld, consider it is an ld script if not recognized */
7653 ret = tcc_load_ldscript(s1);
7654 if (ret < 0) {
7655 error_noabort("unrecognized file type");
7656 goto fail;
7660 the_end:
7661 tcc_close(file);
7662 fail1:
7663 file = saved_file;
7664 return ret;
7665 fail:
7666 ret = -1;
7667 goto the_end;
7670 int tcc_add_file(TCCState *s, const char *filename)
7672 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
7675 int tcc_add_library_path(TCCState *s, const char *pathname)
7677 char *pathname1;
7679 pathname1 = tcc_strdup(pathname);
7680 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
7681 return 0;
7684 /* find and load a dll. Return non zero if not found */
7685 /* XXX: add '-rpath' option support ? */
7686 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
7688 char buf[1024];
7689 int i;
7691 for(i = 0; i < s->nb_library_paths; i++) {
7692 snprintf(buf, sizeof(buf), "%s/%s",
7693 s->library_paths[i], filename);
7694 if (tcc_add_file_internal(s, buf, flags) == 0)
7695 return 0;
7697 return -1;
7700 /* the library name is the same as the argument of the '-l' option */
7701 int tcc_add_library(TCCState *s, const char *libraryname)
7703 char buf[1024];
7704 int i;
7705 void *h;
7707 /* first we look for the dynamic library if not static linking */
7708 if (!s->static_link) {
7709 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
7710 /* if we output to memory, then we simply we dlopen(). */
7711 if (s->output_type == TCC_OUTPUT_MEMORY) {
7712 /* Since the libc is already loaded, we don't need to load it again */
7713 if (!strcmp(libraryname, "c"))
7714 return 0;
7715 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
7716 if (h)
7717 return 0;
7718 } else {
7719 if (tcc_add_dll(s, buf, 0) == 0)
7720 return 0;
7724 /* then we look for the static library */
7725 for(i = 0; i < s->nb_library_paths; i++) {
7726 snprintf(buf, sizeof(buf), "%s/lib%s.a",
7727 s->library_paths[i], libraryname);
7728 if (tcc_add_file_internal(s, buf, 0) == 0)
7729 return 0;
7731 return -1;
7734 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
7736 add_elf_sym(symtab_section, val, 0,
7737 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7738 SHN_ABS, name);
7739 return 0;
7742 int tcc_set_output_type(TCCState *s, int output_type)
7744 s->output_type = output_type;
7746 /* if bound checking, then add corresponding sections */
7747 #ifdef CONFIG_TCC_BCHECK
7748 if (do_bounds_check) {
7749 /* define symbol */
7750 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
7751 /* create bounds sections */
7752 bounds_section = new_section(s, ".bounds",
7753 SHT_PROGBITS, SHF_ALLOC);
7754 lbounds_section = new_section(s, ".lbounds",
7755 SHT_PROGBITS, SHF_ALLOC);
7757 #endif
7759 /* add debug sections */
7760 if (do_debug) {
7761 /* stab symbols */
7762 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
7763 stab_section->sh_entsize = sizeof(Stab_Sym);
7764 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
7765 put_elf_str(stabstr_section, "");
7766 stab_section->link = stabstr_section;
7767 /* put first entry */
7768 put_stabs("", 0, 0, 0, 0);
7771 /* add libc crt1/crti objects */
7772 if (output_type == TCC_OUTPUT_EXE ||
7773 output_type == TCC_OUTPUT_DLL) {
7774 if (output_type != TCC_OUTPUT_DLL)
7775 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
7776 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
7778 return 0;
7781 #if !defined(LIBTCC)
7783 void help(void)
7785 printf("tcc version 0.9.12 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7786 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7787 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
7788 " [--] infile1 [infile2... --] [infile_args...]\n"
7789 "\n"
7790 "General options:\n"
7791 " -c compile only - generate an object file\n"
7792 " -o outfile set output filename\n"
7793 " -- allows multiples input files if no -o option given. Also\n"
7794 " separate input files from runtime arguments\n"
7795 " -Bdir set tcc internal library path\n"
7796 " -bench output compilation statistics\n"
7797 "Preprocessor options:\n"
7798 " -Idir add include path 'dir'\n"
7799 " -Dsym[=val] define 'sym' with value 'val'\n"
7800 " -Usym undefine 'sym'\n"
7801 "C compiler options:\n"
7802 " -g generate runtime debug info\n"
7803 #ifdef CONFIG_TCC_BCHECK
7804 " -b compile with built-in memory and bounds checker (implies -g)\n"
7805 #endif
7806 "Linker options:\n"
7807 " -Ldir add library path 'dir'\n"
7808 " -llib link with dynamic or static library 'lib'\n"
7809 " -shared generate a shared library\n"
7810 " -static static linking\n"
7811 " -r relocatable output\n"
7815 int main(int argc, char **argv)
7817 char *r, *outfile;
7818 int optind, output_type, multiple_files, i, reloc_output;
7819 TCCState *s;
7820 char **files;
7821 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
7822 char objfilename[1024];
7824 s = tcc_new();
7825 output_type = TCC_OUTPUT_MEMORY;
7827 optind = 1;
7828 outfile = NULL;
7829 multiple_files = 0;
7830 dminus = 0;
7831 files = NULL;
7832 nb_files = 0;
7833 nb_libraries = 0;
7834 reloc_output = 0;
7835 while (1) {
7836 if (optind >= argc) {
7837 if (nb_files == 0)
7838 goto show_help;
7839 else
7840 break;
7842 r = argv[optind++];
7843 if (r[0] != '-') {
7844 /* add a new file */
7845 dynarray_add((void ***)&files, &nb_files, r);
7846 if (!multiple_files) {
7847 optind--;
7848 /* argv[0] will be this file */
7849 break;
7851 } else if (r[1] == '-') {
7852 /* '--' enables multiple files input and also ends several file input */
7853 if (dminus && multiple_files) {
7854 optind--; /* argv[0] will be '--' */
7855 break;
7857 dminus = 1;
7858 multiple_files = 1;
7859 } else if (r[1] == 'h' || r[1] == '?') {
7860 show_help:
7861 help();
7862 return 1;
7863 } else if (r[1] == 'I') {
7864 if (tcc_add_include_path(s, r + 2) < 0)
7865 error("too many include paths");
7866 } else if (r[1] == 'D') {
7867 char *sym, *value;
7868 sym = r + 2;
7869 value = strchr(sym, '=');
7870 if (value) {
7871 *value = '\0';
7872 value++;
7874 tcc_define_symbol(s, sym, value);
7875 } else if (r[1] == 'U') {
7876 tcc_undefine_symbol(s, r + 2);
7877 } else if (r[1] == 'L') {
7878 tcc_add_library_path(s, r + 2);
7879 } else if (r[1] == 'B') {
7880 /* set tcc utilities path (mainly for tcc development) */
7881 tcc_lib_path = r + 2;
7882 } else if (r[1] == 'l') {
7883 dynarray_add((void ***)&files, &nb_files, r);
7884 nb_libraries++;
7885 } else if (!strcmp(r + 1, "bench")) {
7886 do_bench = 1;
7887 } else
7888 #ifdef CONFIG_TCC_BCHECK
7889 if (r[1] == 'b') {
7890 do_bounds_check = 1;
7891 do_debug = 1;
7892 } else
7893 #endif
7894 if (r[1] == 'g') {
7895 do_debug = 1;
7896 } else if (r[1] == 'c') {
7897 multiple_files = 1;
7898 output_type = TCC_OUTPUT_OBJ;
7899 } else if (!strcmp(r + 1, "static")) {
7900 s->static_link = 1;
7901 } else if (!strcmp(r + 1, "shared")) {
7902 output_type = TCC_OUTPUT_DLL;
7903 } else if (r[1] == 'o') {
7904 if (optind >= argc)
7905 goto show_help;
7906 multiple_files = 1;
7907 outfile = argv[optind++];
7908 } else if (r[1] == 'r') {
7909 /* generate a .o merging several output files */
7910 reloc_output = 1;
7911 output_type = TCC_OUTPUT_OBJ;
7912 } else if (r[1] == 'W' || r[1] == 'O' || r[1] == 'm' || r[1] == 'f') {
7913 /* ignore those options to be a drop-in replacement for gcc */
7914 } else {
7915 error("invalid option -- '%s'", r);
7919 nb_objfiles = nb_files - nb_libraries;
7921 /* if outfile provided without other options, we output an
7922 executable */
7923 if (outfile && output_type == TCC_OUTPUT_MEMORY)
7924 output_type = TCC_OUTPUT_EXE;
7926 /* check -c consistency : only single file handled. XXX: checks file type */
7927 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
7928 /* accepts only a single input file */
7929 if (nb_objfiles != 1)
7930 error("cannot specify multiple files with -c");
7931 if (nb_libraries != 0)
7932 error("cannot specify libraries with -c");
7935 /* compute default outfile name */
7936 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
7937 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
7938 char *ext;
7939 /* add .o extension */
7940 pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
7941 ext = strrchr(objfilename, '.');
7942 if (!ext)
7943 goto default_outfile;
7944 strcpy(ext + 1, "o");
7945 } else {
7946 default_outfile:
7947 pstrcpy(objfilename, sizeof(objfilename), "a.out");
7949 outfile = objfilename;
7952 tcc_set_output_type(s, output_type);
7954 /* compile or add each files or library */
7955 for(i = 0;i < nb_files; i++) {
7956 const char *filename;
7958 filename = files[i];
7959 if (filename[0] == '-') {
7960 if (tcc_add_library(s, filename + 2) < 0)
7961 error("cannot find %s", filename);
7962 } else {
7963 if (tcc_add_file(s, filename) < 0) {
7964 ret = 1;
7965 goto the_end;
7970 /* free all files */
7971 tcc_free(files);
7973 if (do_bench) {
7974 printf("total: %d idents, %d lines, %d bytes\n",
7975 tok_ident - TOK_IDENT, total_lines, total_bytes);
7978 if (s->output_type != TCC_OUTPUT_MEMORY) {
7979 tcc_output_file(s, outfile);
7980 ret = 0;
7981 } else {
7982 ret = tcc_run(s, argc - optind, argv + optind);
7984 the_end:
7985 tcc_delete(s);
7987 #ifdef MEM_DEBUG
7988 if (do_bench) {
7989 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
7991 #endif
7992 return ret;
7995 #endif