added computed gotos - better runtime error handling
[tinycc.git] / tcc.c
blobd76c471f6f8c15d544d8edfcdb9b5aeb726a022f
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.r' 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 /* max number of callers shown if error */
309 static int num_callers = 6;
310 static const char **rt_bound_error_msg;
312 /* XXX: suppress that ASAP */
313 static struct TCCState *tcc_state;
315 /* give the path of the tcc libraries */
316 static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc";
318 struct TCCState {
319 int output_type;
321 BufferedFile **include_stack_ptr;
322 int *ifdef_stack_ptr;
324 /* include file handling */
325 char **include_paths;
326 int nb_include_paths;
327 char **sysinclude_paths;
328 int nb_sysinclude_paths;
329 CachedInclude **cached_includes;
330 int nb_cached_includes;
332 char **library_paths;
333 int nb_library_paths;
335 /* array of all loaded dlls (including those referenced by loaded
336 dlls) */
337 DLLReference **loaded_dlls;
338 int nb_loaded_dlls;
340 /* sections */
341 Section **sections;
342 int nb_sections; /* number of sections, including first dummy section */
344 /* got handling */
345 Section *got;
346 unsigned long *got_offsets;
347 int nb_got_offsets;
348 int nb_plt_entries;
349 /* give the correspondance from symtab indexes to dynsym indexes */
350 int *symtab_to_dynsym;
352 /* temporary dynamic symbol sections (for dll loading) */
353 Section *dynsymtab_section;
354 /* exported dynamic symbol section */
355 Section *dynsym;
357 /* if true, static linking is performed */
358 int static_link;
360 /* error handling */
361 void *error_opaque;
362 void (*error_func)(void *opaque, const char *msg);
363 int error_set_jmp_enabled;
364 jmp_buf error_jmp_buf;
365 int nb_errors;
367 /* see include_stack_ptr */
368 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
370 /* see ifdef_stack_ptr */
371 int ifdef_stack[IFDEF_STACK_SIZE];
374 /* The current value can be: */
375 #define VT_VALMASK 0x00ff
376 #define VT_CONST 0x00f0 /* constant in vc
377 (must be first non register value) */
378 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
379 #define VT_LOCAL 0x00f2 /* offset on stack */
380 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
381 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
382 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
383 #define VT_LVAL 0x0100 /* var is an lvalue */
384 #define VT_SYM 0x0200 /* a symbol value is added */
385 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
386 char/short stored in integer registers) */
387 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
388 dereferencing value */
389 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
390 bounding function call point is in vc */
391 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
392 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
393 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
394 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
396 /* types */
397 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
399 #define VT_INT 0 /* integer type */
400 #define VT_BYTE 1 /* signed byte type */
401 #define VT_SHORT 2 /* short type */
402 #define VT_VOID 3 /* void type */
403 #define VT_PTR 4 /* pointer */
404 #define VT_ENUM 5 /* enum definition */
405 #define VT_FUNC 6 /* function type */
406 #define VT_STRUCT 7 /* struct/union definition */
407 #define VT_FLOAT 8 /* IEEE float */
408 #define VT_DOUBLE 9 /* IEEE double */
409 #define VT_LDOUBLE 10 /* IEEE long double */
410 #define VT_BOOL 11 /* ISOC99 boolean type */
411 #define VT_LLONG 12 /* 64 bit integer */
412 #define VT_LONG 13 /* long integer (NEVER USED as type, only
413 during parsing) */
414 #define VT_BTYPE 0x000f /* mask for basic type */
415 #define VT_UNSIGNED 0x0010 /* unsigned type */
416 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
417 #define VT_BITFIELD 0x0040 /* bitfield modifier */
419 /* storage */
420 #define VT_EXTERN 0x00000080 /* extern definition */
421 #define VT_STATIC 0x00000100 /* static variable */
422 #define VT_TYPEDEF 0x00000200 /* typedef definition */
424 /* type mask (except storage) */
425 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
427 /* token values */
429 /* warning: the following compare tokens depend on i386 asm code */
430 #define TOK_ULT 0x92
431 #define TOK_UGE 0x93
432 #define TOK_EQ 0x94
433 #define TOK_NE 0x95
434 #define TOK_ULE 0x96
435 #define TOK_UGT 0x97
436 #define TOK_LT 0x9c
437 #define TOK_GE 0x9d
438 #define TOK_LE 0x9e
439 #define TOK_GT 0x9f
441 #define TOK_LAND 0xa0
442 #define TOK_LOR 0xa1
444 #define TOK_DEC 0xa2
445 #define TOK_MID 0xa3 /* inc/dec, to void constant */
446 #define TOK_INC 0xa4
447 #define TOK_UDIV 0xb0 /* unsigned division */
448 #define TOK_UMOD 0xb1 /* unsigned modulo */
449 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
450 #define TOK_CINT 0xb3 /* number in tokc */
451 #define TOK_CCHAR 0xb4 /* char constant in tokc */
452 #define TOK_STR 0xb5 /* pointer to string in tokc */
453 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
454 #define TOK_LCHAR 0xb7
455 #define TOK_LSTR 0xb8
456 #define TOK_CFLOAT 0xb9 /* float constant */
457 #define TOK_LINENUM 0xba /* line number info */
458 #define TOK_CDOUBLE 0xc0 /* double constant */
459 #define TOK_CLDOUBLE 0xc1 /* long double constant */
460 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
461 #define TOK_ADDC1 0xc3 /* add with carry generation */
462 #define TOK_ADDC2 0xc4 /* add with carry use */
463 #define TOK_SUBC1 0xc5 /* add with carry generation */
464 #define TOK_SUBC2 0xc6 /* add with carry use */
465 #define TOK_CUINT 0xc8 /* unsigned int constant */
466 #define TOK_CLLONG 0xc9 /* long long constant */
467 #define TOK_CULLONG 0xca /* unsigned long long constant */
468 #define TOK_ARROW 0xcb
469 #define TOK_DOTS 0xcc /* three dots */
470 #define TOK_SHR 0xcd /* unsigned shift right */
471 #define TOK_PPNUM 0xce /* preprocessor number */
473 #define TOK_SHL 0x01 /* shift left */
474 #define TOK_SAR 0x02 /* signed shift right */
476 /* assignement operators : normal operator or 0x80 */
477 #define TOK_A_MOD 0xa5
478 #define TOK_A_AND 0xa6
479 #define TOK_A_MUL 0xaa
480 #define TOK_A_ADD 0xab
481 #define TOK_A_SUB 0xad
482 #define TOK_A_DIV 0xaf
483 #define TOK_A_XOR 0xde
484 #define TOK_A_OR 0xfc
485 #define TOK_A_SHL 0x81
486 #define TOK_A_SAR 0x82
488 /* WARNING: the content of this string encodes token numbers */
489 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";
491 #define TOK_EOF (-1) /* end of file */
492 #define TOK_LINEFEED 10 /* line feed */
494 /* all identificators and strings have token above that */
495 #define TOK_IDENT 256
497 enum {
498 TOK_LAST = TOK_IDENT - 1,
499 #define DEF(id, str) id,
500 #include "tcctok.h"
501 #undef DEF
504 static const char *tcc_keywords =
505 #define DEF(id, str) str "\0"
506 #include "tcctok.h"
507 #undef DEF
510 #define TOK_UIDENT TOK_DEFINE
512 #ifdef WIN32
513 #define snprintf _snprintf
514 #endif
516 #if defined(WIN32) || defined(TCC_UCLIBC)
517 /* currently incorrect */
518 long double strtold(const char *nptr, char **endptr)
520 return (long double)strtod(nptr, endptr);
522 float strtof(const char *nptr, char **endptr)
524 return (float)strtod(nptr, endptr);
526 #else
527 /* XXX: need to define this to use them in non ISOC99 context */
528 extern float strtof (const char *__nptr, char **__endptr);
529 extern long double strtold (const char *__nptr, char **__endptr);
530 #endif
532 static char *pstrcpy(char *buf, int buf_size, const char *s);
533 static char *pstrcat(char *buf, int buf_size, const char *s);
535 static void sum(int l);
536 static void next(void);
537 static void next_nomacro(void);
538 static int parse_expr_type(void);
539 static int expr_type(void);
540 static int unary_type(void);
541 static int expr_const(void);
542 static void expr_eq(void);
543 static void gexpr(void);
544 static void decl(int l);
545 static void decl_initializer(int t, Section *sec, unsigned long c,
546 int first, int size_only);
547 static void decl_initializer_alloc(int t, AttributeDef *ad, int r,
548 int has_init, int v, int scope);
549 int gv(int rc);
550 void gv2(int rc1, int rc2);
551 void move_reg(int r, int s);
552 void save_regs(int n);
553 void save_reg(int r);
554 void vpop(void);
555 void vswap(void);
556 void vdup(void);
557 int get_reg(int rc);
559 static void macro_subst(TokenString *tok_str,
560 Sym **nested_list, int *macro_str);
561 int save_reg_forced(int r);
562 void gen_op(int op);
563 void force_charshort_cast(int t);
564 void gen_cast(int t);
565 void vstore(void);
566 Sym *sym_find(int v);
567 Sym *sym_push(int v, int t, int r, int c);
569 /* type handling */
570 int type_size(int t, int *a);
571 int pointed_type(int t);
572 int pointed_size(int t);
573 static int lvalue_type(int t);
574 int is_compatible_types(int t1, int t2);
575 int parse_btype(int *type_ptr, AttributeDef *ad);
576 int type_decl(AttributeDef *ad, int *v, int t, int td);
578 void error(const char *fmt, ...);
579 void rt_error(struct ucontext *uc, const char *fmt, ...);
580 void vpushi(int v);
581 void vset(int t, int r, int v);
582 void type_to_str(char *buf, int buf_size,
583 int t, const char *varstr);
584 char *get_tok_str(int v, CValue *cv);
585 static Sym *get_sym_ref(int t, Section *sec,
586 unsigned long offset, unsigned long size);
587 static Sym *external_global_sym(int v, int u, int r);
589 /* section generation */
590 static void section_realloc(Section *sec, unsigned long new_size);
591 static void *section_ptr_add(Section *sec, unsigned long size);
592 static void put_extern_sym(Sym *sym, Section *section,
593 unsigned long value, unsigned long size);
594 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
595 static int put_elf_str(Section *s, const char *sym);
596 static int put_elf_sym(Section *s,
597 unsigned long value, unsigned long size,
598 int info, int other, int shndx, const char *name);
599 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
600 int info, int sh_num, const char *name);
601 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
602 int type, int symbol);
603 static void put_stabs(const char *str, int type, int other, int desc,
604 unsigned long value);
605 static void put_stabs_r(const char *str, int type, int other, int desc,
606 unsigned long value, Section *sec, int sym_index);
607 static void put_stabn(int type, int other, int desc, int value);
608 static void put_stabd(int type, int other, int desc);
609 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
611 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
612 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
613 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
615 /* true if float/double/long double type */
616 static inline int is_float(int t)
618 int bt;
619 bt = t & VT_BTYPE;
620 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
623 #ifdef TCC_TARGET_I386
624 #include "i386-gen.c"
625 #endif
626 #ifdef TCC_TARGET_IL
627 #include "il-gen.c"
628 #endif
630 #ifdef CONFIG_TCC_STATIC
632 #define RTLD_LAZY 0x001
633 #define RTLD_NOW 0x002
634 #define RTLD_GLOBAL 0x100
636 /* dummy function for profiling */
637 void *dlopen(const char *filename, int flag)
639 return NULL;
642 const char *dlerror(void)
644 return "error";
647 typedef struct TCCSyms {
648 char *str;
649 void *ptr;
650 } TCCSyms;
652 #define TCCSYM(a) { #a, &a, },
654 /* add the symbol you want here if no dynamic linking is done */
655 static TCCSyms tcc_syms[] = {
656 TCCSYM(printf)
657 TCCSYM(fprintf)
658 TCCSYM(fopen)
659 TCCSYM(fclose)
660 { NULL, NULL },
663 void *dlsym(void *handle, const char *symbol)
665 TCCSyms *p;
666 p = tcc_syms;
667 while (p->str != NULL) {
668 if (!strcmp(p->str, symbol))
669 return p->ptr;
670 p++;
672 return NULL;
675 #endif
677 /********************************************************/
679 /* we use our own 'finite' function to avoid potential problems with
680 non standard math libs */
681 /* XXX: endianness dependant */
682 int ieee_finite(double d)
684 int *p = (int *)&d;
685 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
688 /* copy a string and truncate it. */
689 static char *pstrcpy(char *buf, int buf_size, const char *s)
691 char *q, *q_end;
692 int c;
694 if (buf_size > 0) {
695 q = buf;
696 q_end = buf + buf_size - 1;
697 while (q < q_end) {
698 c = *s++;
699 if (c == '\0')
700 break;
701 *q++ = c;
703 *q = '\0';
705 return buf;
708 /* strcat and truncate. */
709 static char *pstrcat(char *buf, int buf_size, const char *s)
711 int len;
712 len = strlen(buf);
713 if (len < buf_size)
714 pstrcpy(buf + len, buf_size - len, s);
715 return buf;
718 /* memory management */
719 #ifdef MEM_DEBUG
720 int mem_cur_size;
721 int mem_max_size;
722 #endif
724 static inline void tcc_free(void *ptr)
726 #ifdef MEM_DEBUG
727 mem_cur_size -= malloc_usable_size(ptr);
728 #endif
729 free(ptr);
732 static void *tcc_malloc(unsigned long size)
734 void *ptr;
735 ptr = malloc(size);
736 if (!ptr && size)
737 error("memory full");
738 #ifdef MEM_DEBUG
739 mem_cur_size += malloc_usable_size(ptr);
740 if (mem_cur_size > mem_max_size)
741 mem_max_size = mem_cur_size;
742 #endif
743 return ptr;
746 static void *tcc_mallocz(unsigned long size)
748 void *ptr;
749 ptr = tcc_malloc(size);
750 memset(ptr, 0, size);
751 return ptr;
754 static inline void *tcc_realloc(void *ptr, unsigned long size)
756 void *ptr1;
757 #ifdef MEM_DEBUG
758 mem_cur_size -= malloc_usable_size(ptr);
759 #endif
760 ptr1 = realloc(ptr, size);
761 #ifdef MEM_DEBUG
762 /* NOTE: count not correct if alloc error, but not critical */
763 mem_cur_size += malloc_usable_size(ptr1);
764 if (mem_cur_size > mem_max_size)
765 mem_max_size = mem_cur_size;
766 #endif
767 return ptr1;
770 static char *tcc_strdup(const char *str)
772 char *ptr;
773 ptr = tcc_malloc(strlen(str) + 1);
774 strcpy(ptr, str);
775 return ptr;
778 #define free(p) use_tcc_free(p)
779 #define malloc(s) use_tcc_malloc(s)
780 #define realloc(p, s) use_tcc_realloc(p, s)
782 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
784 int nb, nb_alloc;
785 void **pp;
787 nb = *nb_ptr;
788 pp = *ptab;
789 /* every power of two we double array size */
790 if ((nb & (nb - 1)) == 0) {
791 if (!nb)
792 nb_alloc = 1;
793 else
794 nb_alloc = nb * 2;
795 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
796 if (!pp)
797 error("memory full");
798 *ptab = pp;
800 pp[nb++] = data;
801 *nb_ptr = nb;
804 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
806 Section *sec;
808 sec = tcc_mallocz(sizeof(Section));
809 pstrcpy(sec->name, sizeof(sec->name), name);
810 sec->sh_type = sh_type;
811 sec->sh_flags = sh_flags;
812 switch(sh_type) {
813 case SHT_HASH:
814 case SHT_REL:
815 case SHT_DYNSYM:
816 case SHT_SYMTAB:
817 case SHT_DYNAMIC:
818 sec->sh_addralign = 4;
819 break;
820 case SHT_STRTAB:
821 sec->sh_addralign = 1;
822 break;
823 default:
824 sec->sh_addralign = 32; /* default conservative alignment */
825 break;
828 /* only add section if not private */
829 if (!(sh_flags & SHF_PRIVATE)) {
830 sec->sh_num = s1->nb_sections;
831 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
833 return sec;
836 static void free_section(Section *s)
838 tcc_free(s->data);
839 tcc_free(s);
842 /* realloc section and set its content to zero */
843 static void section_realloc(Section *sec, unsigned long new_size)
845 unsigned long size;
846 unsigned char *data;
848 size = sec->data_allocated;
849 if (size == 0)
850 size = 1;
851 while (size < new_size)
852 size = size * 2;
853 data = tcc_realloc(sec->data, size);
854 if (!data)
855 error("memory full");
856 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
857 sec->data = data;
858 sec->data_allocated = size;
861 /* reserve at least 'size' bytes in section 'sec' from
862 sec->data_offset. */
863 static void *section_ptr_add(Section *sec, unsigned long size)
865 unsigned long offset, offset1;
867 offset = sec->data_offset;
868 offset1 = offset + size;
869 if (offset1 > sec->data_allocated)
870 section_realloc(sec, offset1);
871 sec->data_offset = offset1;
872 return sec->data + offset;
875 /* return a reference to a section, and create it if it does not
876 exists */
877 Section *find_section(TCCState *s1, const char *name)
879 Section *sec;
880 int i;
881 for(i = 1; i < s1->nb_sections; i++) {
882 sec = s1->sections[i];
883 if (!strcmp(name, sec->name))
884 return sec;
886 /* sections are created as PROGBITS */
887 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
890 /* update sym->c so that it points to an external symbol in section
891 'section' with value 'value' */
892 static void put_extern_sym(Sym *sym, Section *section,
893 unsigned long value, unsigned long size)
895 int sym_type, sym_bind, sh_num, info;
896 Elf32_Sym *esym;
897 const char *name;
898 char buf[32];
900 if (section)
901 sh_num = section->sh_num;
902 else
903 sh_num = SHN_UNDEF;
904 if (!sym->c) {
905 if ((sym->t & VT_BTYPE) == VT_FUNC)
906 sym_type = STT_FUNC;
907 else
908 sym_type = STT_OBJECT;
909 if (sym->t & VT_STATIC)
910 sym_bind = STB_LOCAL;
911 else
912 sym_bind = STB_GLOBAL;
914 name = get_tok_str(sym->v, NULL);
915 #ifdef CONFIG_TCC_BCHECK
916 if (do_bounds_check) {
917 /* XXX: avoid doing that for statics ? */
918 /* if bound checking is activated, we change some function
919 names by adding the "__bound" prefix */
920 switch(sym->v) {
921 #if 0
922 /* XXX: we rely only on malloc hooks */
923 case TOK_malloc:
924 case TOK_free:
925 case TOK_realloc:
926 case TOK_memalign:
927 case TOK_calloc:
928 #endif
929 case TOK_memcpy:
930 case TOK_memmove:
931 case TOK_memset:
932 case TOK_strlen:
933 case TOK_strcpy:
934 strcpy(buf, "__bound_");
935 strcat(buf, name);
936 name = buf;
937 break;
940 #endif
941 info = ELF32_ST_INFO(sym_bind, sym_type);
942 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
943 } else {
944 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
945 esym->st_value = value;
946 esym->st_size = size;
947 esym->st_shndx = sh_num;
951 /* add a new relocation entry to symbol 'sym' in section 's' */
952 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
954 if (!sym->c)
955 put_extern_sym(sym, NULL, 0, 0);
956 /* now we can add ELF relocation info */
957 put_elf_reloc(symtab_section, s, offset, type, sym->c);
960 static inline int isid(int c)
962 return (c >= 'a' && c <= 'z') ||
963 (c >= 'A' && c <= 'Z') ||
964 c == '_';
967 static inline int isnum(int c)
969 return c >= '0' && c <= '9';
972 static inline int isoct(int c)
974 return c >= '0' && c <= '7';
977 static inline int toup(int c)
979 if (c >= 'a' && c <= 'z')
980 return c - 'a' + 'A';
981 else
982 return c;
985 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
987 int len;
988 len = strlen(buf);
989 vsnprintf(buf + len, buf_size - len, fmt, ap);
992 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
994 va_list ap;
995 va_start(ap, fmt);
996 strcat_vprintf(buf, buf_size, fmt, ap);
997 va_end(ap);
1000 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
1002 char buf[2048];
1003 BufferedFile **f;
1005 buf[0] = '\0';
1006 if (file) {
1007 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1008 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1009 (*f)->filename, (*f)->line_num);
1010 if (file->line_num > 0) {
1011 strcat_printf(buf, sizeof(buf),
1012 "%s:%d: ", file->filename, file->line_num);
1013 } else {
1014 strcat_printf(buf, sizeof(buf),
1015 "%s: ", file->filename);
1017 } else {
1018 strcat_printf(buf, sizeof(buf),
1019 "tcc: ");
1021 if (is_warning)
1022 strcat_printf(buf, sizeof(buf), "warning: ");
1023 strcat_vprintf(buf, sizeof(buf), fmt, ap);
1025 if (!s1->error_func) {
1026 /* default case: stderr */
1027 fprintf(stderr, "%s\n", buf);
1028 } else {
1029 s1->error_func(s1->error_opaque, buf);
1031 if (!is_warning)
1032 s1->nb_errors++;
1035 #ifdef LIBTCC
1036 void tcc_set_error_func(TCCState *s, void *error_opaque,
1037 void (*error_func)(void *opaque, const char *msg))
1039 s->error_opaque = error_opaque;
1040 s->error_func = error_func;
1042 #endif
1044 /* error without aborting current compilation */
1045 void error_noabort(const char *fmt, ...)
1047 TCCState *s1 = tcc_state;
1048 va_list ap;
1050 va_start(ap, fmt);
1051 error1(s1, 0, fmt, ap);
1052 va_end(ap);
1055 void error(const char *fmt, ...)
1057 TCCState *s1 = tcc_state;
1058 va_list ap;
1060 va_start(ap, fmt);
1061 error1(s1, 0, fmt, ap);
1062 va_end(ap);
1063 /* better than nothing: in some cases, we accept to handle errors */
1064 if (s1->error_set_jmp_enabled) {
1065 longjmp(s1->error_jmp_buf, 1);
1066 } else {
1067 /* XXX: suppress it someday */
1068 exit(1);
1072 void expect(const char *msg)
1074 error("%s expected", msg);
1077 void warning(const char *fmt, ...)
1079 TCCState *s1 = tcc_state;
1080 va_list ap;
1082 va_start(ap, fmt);
1083 error1(s1, 1, fmt, ap);
1084 va_end(ap);
1087 void skip(int c)
1089 if (tok != c)
1090 error("'%c' expected", c);
1091 next();
1094 void test_lvalue(void)
1096 if (!(vtop->r & VT_LVAL))
1097 expect("lvalue");
1100 TokenSym *tok_alloc(const char *str, int len)
1102 TokenSym *ts, **pts, **ptable;
1103 int h, i;
1105 h = 1;
1106 for(i=0;i<len;i++)
1107 h = (h * 263 + ((unsigned char *)str)[i]) & (TOK_HASH_SIZE - 1);
1109 pts = &hash_ident[h];
1110 while (1) {
1111 ts = *pts;
1112 if (!ts)
1113 break;
1114 if (ts->len == len && !memcmp(ts->str, str, len))
1115 return ts;
1116 pts = &(ts->hash_next);
1119 if (tok_ident >= SYM_FIRST_ANOM)
1120 error("memory full");
1122 /* expand token table if needed */
1123 i = tok_ident - TOK_IDENT;
1124 if ((i % TOK_ALLOC_INCR) == 0) {
1125 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1126 if (!ptable)
1127 error("memory full");
1128 table_ident = ptable;
1131 ts = tcc_malloc(sizeof(TokenSym) + len);
1132 table_ident[i] = ts;
1133 ts->tok = tok_ident++;
1134 ts->len = len;
1135 ts->hash_next = NULL;
1136 memcpy(ts->str, str, len + 1);
1137 *pts = ts;
1138 return ts;
1141 /* CString handling */
1143 static void cstr_realloc(CString *cstr, int new_size)
1145 int size;
1146 void *data;
1148 size = cstr->size_allocated;
1149 if (size == 0)
1150 size = 8; /* no need to allocate a too small first string */
1151 while (size < new_size)
1152 size = size * 2;
1153 data = tcc_realloc(cstr->data_allocated, size);
1154 if (!data)
1155 error("memory full");
1156 cstr->data_allocated = data;
1157 cstr->size_allocated = size;
1158 cstr->data = data;
1161 /* add a byte */
1162 static void cstr_ccat(CString *cstr, int ch)
1164 int size;
1165 size = cstr->size + 1;
1166 if (size > cstr->size_allocated)
1167 cstr_realloc(cstr, size);
1168 ((unsigned char *)cstr->data)[size - 1] = ch;
1169 cstr->size = size;
1172 static void cstr_cat(CString *cstr, const char *str)
1174 int c;
1175 for(;;) {
1176 c = *str;
1177 if (c == '\0')
1178 break;
1179 cstr_ccat(cstr, c);
1180 str++;
1184 /* add a wide char */
1185 static void cstr_wccat(CString *cstr, int ch)
1187 int size;
1188 size = cstr->size + sizeof(int);
1189 if (size > cstr->size_allocated)
1190 cstr_realloc(cstr, size);
1191 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1192 cstr->size = size;
1195 static void cstr_new(CString *cstr)
1197 memset(cstr, 0, sizeof(CString));
1200 /* free string and reset it to NULL */
1201 static void cstr_free(CString *cstr)
1203 tcc_free(cstr->data_allocated);
1204 cstr_new(cstr);
1207 #define cstr_reset(cstr) cstr_free(cstr)
1209 /* XXX: unicode ? */
1210 static void add_char(CString *cstr, int c)
1212 if (c == '\'' || c == '\"' || c == '\\') {
1213 /* XXX: could be more precise if char or string */
1214 cstr_ccat(cstr, '\\');
1216 if (c >= 32 && c <= 126) {
1217 cstr_ccat(cstr, c);
1218 } else {
1219 cstr_ccat(cstr, '\\');
1220 if (c == '\n') {
1221 cstr_ccat(cstr, 'n');
1222 } else {
1223 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1224 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1225 cstr_ccat(cstr, '0' + (c & 7));
1230 /* XXX: buffer overflow */
1231 /* XXX: float tokens */
1232 char *get_tok_str(int v, CValue *cv)
1234 static char buf[STRING_MAX_SIZE + 1];
1235 static CString cstr_buf;
1236 CString *cstr;
1237 unsigned char *q;
1238 char *p;
1239 int i, len;
1241 /* NOTE: to go faster, we give a fixed buffer for small strings */
1242 cstr_reset(&cstr_buf);
1243 cstr_buf.data = buf;
1244 cstr_buf.size_allocated = sizeof(buf);
1245 p = buf;
1247 switch(v) {
1248 case TOK_CINT:
1249 case TOK_CUINT:
1250 /* XXX: not quite exact, but only useful for testing */
1251 sprintf(p, "%u", cv->ui);
1252 break;
1253 case TOK_CLLONG:
1254 case TOK_CULLONG:
1255 /* XXX: not quite exact, but only useful for testing */
1256 sprintf(p, "%Lu", cv->ull);
1257 break;
1258 case TOK_CCHAR:
1259 case TOK_LCHAR:
1260 cstr_ccat(&cstr_buf, '\'');
1261 add_char(&cstr_buf, cv->i);
1262 cstr_ccat(&cstr_buf, '\'');
1263 cstr_ccat(&cstr_buf, '\0');
1264 break;
1265 case TOK_PPNUM:
1266 cstr = cv->cstr;
1267 len = cstr->size - 1;
1268 for(i=0;i<len;i++)
1269 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1270 cstr_ccat(&cstr_buf, '\0');
1271 break;
1272 case TOK_STR:
1273 case TOK_LSTR:
1274 cstr = cv->cstr;
1275 cstr_ccat(&cstr_buf, '\"');
1276 if (v == TOK_STR) {
1277 len = cstr->size - 1;
1278 for(i=0;i<len;i++)
1279 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1280 } else {
1281 len = (cstr->size / sizeof(int)) - 1;
1282 for(i=0;i<len;i++)
1283 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1285 cstr_ccat(&cstr_buf, '\"');
1286 cstr_ccat(&cstr_buf, '\0');
1287 break;
1288 case TOK_LT:
1289 v = '<';
1290 goto addv;
1291 case TOK_GT:
1292 v = '>';
1293 goto addv;
1294 case TOK_A_SHL:
1295 return strcpy(p, "<<=");
1296 case TOK_A_SAR:
1297 return strcpy(p, ">>=");
1298 default:
1299 if (v < TOK_IDENT) {
1300 /* search in two bytes table */
1301 q = tok_two_chars;
1302 while (*q) {
1303 if (q[2] == v) {
1304 *p++ = q[0];
1305 *p++ = q[1];
1306 *p = '\0';
1307 return buf;
1309 q += 3;
1311 addv:
1312 *p++ = v;
1313 *p = '\0';
1314 } else if (v < tok_ident) {
1315 return table_ident[v - TOK_IDENT]->str;
1316 } else if (v >= SYM_FIRST_ANOM) {
1317 /* special name for anonymous symbol */
1318 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1319 } else {
1320 /* should never happen */
1321 return NULL;
1323 break;
1325 return cstr_buf.data;
1328 /* push, without hashing */
1329 Sym *sym_push2(Sym **ps, int v, int t, int c)
1331 Sym *s;
1332 s = tcc_malloc(sizeof(Sym));
1333 s->v = v;
1334 s->t = t;
1335 s->c = c;
1336 s->next = NULL;
1337 /* add in stack */
1338 s->prev = *ps;
1339 *ps = s;
1340 return s;
1343 /* find a symbol and return its associated structure. 's' is the top
1344 of the symbol stack */
1345 Sym *sym_find2(Sym *s, int v)
1347 while (s) {
1348 if (s->v == v)
1349 return s;
1350 s = s->prev;
1352 return NULL;
1355 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1357 /* find a symbol and return its associated structure. 'st' is the
1358 symbol stack */
1359 Sym *sym_find1(SymStack *st, int v)
1361 Sym *s;
1363 s = st->hash[HASH_SYM(v)];
1364 while (s) {
1365 if (s->v == v)
1366 return s;
1367 s = s->hash_next;
1369 return NULL;
1372 Sym *sym_push1(SymStack *st, int v, int t, int c)
1374 Sym *s, **ps;
1375 s = sym_push2(&st->top, v, t, c);
1376 /* add in hash table */
1377 if (v) {
1378 ps = &st->hash[HASH_SYM(v)];
1379 s->hash_next = *ps;
1380 *ps = s;
1382 return s;
1385 /* find a symbol in the right symbol space */
1386 Sym *sym_find(int v)
1388 Sym *s;
1389 s = sym_find1(&local_stack, v);
1390 if (!s)
1391 s = sym_find1(&global_stack, v);
1392 return s;
1395 /* push a given symbol on the symbol stack */
1396 Sym *sym_push(int v, int t, int r, int c)
1398 Sym *s;
1399 if (local_stack.top)
1400 s = sym_push1(&local_stack, v, t, c);
1401 else
1402 s = sym_push1(&global_stack, v, t, c);
1403 s->r = r;
1404 return s;
1407 /* pop symbols until top reaches 'b' */
1408 void sym_pop(SymStack *st, Sym *b)
1410 Sym *s, *ss;
1412 s = st->top;
1413 while(s != b) {
1414 ss = s->prev;
1415 /* free hash table entry, except if symbol was freed (only
1416 used for #undef symbols) */
1417 if (s->v)
1418 st->hash[HASH_SYM(s->v)] = s->hash_next;
1419 tcc_free(s);
1420 s = ss;
1422 st->top = b;
1425 /* undefined a hashed symbol (used for #undef). Its name is set to
1426 zero */
1427 void sym_undef(SymStack *st, Sym *s)
1429 Sym **ss;
1430 ss = &st->hash[HASH_SYM(s->v)];
1431 while (*ss != NULL) {
1432 if (*ss == s)
1433 break;
1434 ss = &(*ss)->hash_next;
1436 *ss = s->hash_next;
1437 s->v = 0;
1440 /* I/O layer */
1442 BufferedFile *tcc_open(TCCState *s1, const char *filename)
1444 int fd;
1445 BufferedFile *bf;
1447 fd = open(filename, O_RDONLY);
1448 if (fd < 0)
1449 return NULL;
1450 bf = tcc_malloc(sizeof(BufferedFile));
1451 if (!bf) {
1452 close(fd);
1453 return NULL;
1455 bf->fd = fd;
1456 bf->buf_ptr = bf->buffer;
1457 bf->buf_end = bf->buffer;
1458 bf->buffer[0] = CH_EOB; /* put eob symbol */
1459 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1460 bf->line_num = 1;
1461 bf->ifndef_macro = 0;
1462 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1463 // printf("opening '%s'\n", filename);
1464 return bf;
1467 void tcc_close(BufferedFile *bf)
1469 total_lines += bf->line_num;
1470 close(bf->fd);
1471 tcc_free(bf);
1474 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1475 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1477 /* fill input buffer and return next char */
1478 int tcc_getc_slow(BufferedFile *bf)
1480 int len;
1481 /* only tries to read if really end of buffer */
1482 if (bf->buf_ptr >= bf->buf_end) {
1483 if (bf->fd != -1) {
1484 len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
1485 if (len < 0)
1486 len = 0;
1487 } else {
1488 len = 0;
1490 total_bytes += len;
1491 bf->buf_ptr = bf->buffer;
1492 bf->buf_end = bf->buffer + len;
1493 *bf->buf_end = CH_EOB;
1495 if (bf->buf_ptr < bf->buf_end) {
1496 return *bf->buf_ptr++;
1497 } else {
1498 bf->buf_ptr = bf->buf_end;
1499 return CH_EOF;
1503 /* no need to put that inline */
1504 void handle_eob(void)
1506 TCCState *s1 = tcc_state;
1507 for(;;) {
1508 ch1 = tcc_getc_slow(file);
1509 if (ch1 != CH_EOF)
1510 return;
1511 eof_seen = 1;
1512 if (return_linefeed) {
1513 ch1 = '\n';
1514 return;
1516 if (s1->include_stack_ptr == s1->include_stack)
1517 return;
1518 /* add end of include file debug info */
1519 if (do_debug) {
1520 put_stabd(N_EINCL, 0, 0);
1522 /* pop include stack */
1523 tcc_close(file);
1524 s1->include_stack_ptr--;
1525 file = *s1->include_stack_ptr;
1529 /* read next char from current input file */
1530 static inline void inp(void)
1532 ch1 = TCC_GETC(file);
1533 /* end of buffer/file handling */
1534 if (ch1 == CH_EOB)
1535 handle_eob();
1536 if (ch1 == '\n')
1537 file->line_num++;
1538 // printf("ch1=%c 0x%x\n", ch1, ch1);
1541 /* handle '\\n' and '\\r\n' */
1542 static void handle_stray(void)
1544 do {
1545 if (ch1 == '\n') {
1546 inp();
1547 } else if (ch1 == '\r') {
1548 inp();
1549 if (ch1 != '\n')
1550 error("invalid character after '\\'");
1551 inp();
1552 } else {
1553 break;
1555 ch = ch1;
1556 inp();
1557 } while (ch == '\\');
1560 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1561 case */
1562 static inline void minp(void)
1564 ch = ch1;
1565 inp();
1566 if (ch == '\\')
1567 handle_stray();
1571 /* same as minp, but also skip comments */
1572 static void cinp(void)
1574 int c;
1576 if (ch1 == '/') {
1577 inp();
1578 if (ch1 == '/') {
1579 /* single line C++ comments */
1580 inp();
1581 while (ch1 != '\n' && ch1 != CH_EOF)
1582 inp();
1583 ch = ' '; /* return space */
1584 } else if (ch1 == '*') {
1585 /* C comments */
1586 inp();
1587 while (ch1 != CH_EOF) {
1588 c = ch1;
1589 inp();
1590 if (c == '*' && ch1 == '/') {
1591 inp();
1592 ch = ' '; /* return space */
1593 break;
1596 } else {
1597 ch = '/';
1599 } else {
1600 minp();
1604 /* space exlcuding newline */
1605 static inline int is_space(int ch)
1607 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1610 static inline void skip_spaces(void)
1612 while (is_space(ch))
1613 cinp();
1616 /* skip block of text until #else, #elif or #endif. skip also pairs of
1617 #if/#endif */
1618 void preprocess_skip(void)
1620 int a;
1621 a = 0;
1622 while (1) {
1623 while (ch != '\n') {
1624 if (ch == CH_EOF)
1625 expect("#endif");
1626 cinp();
1628 cinp();
1629 skip_spaces();
1630 if (ch == '#') {
1631 cinp();
1632 next_nomacro();
1633 if (a == 0 &&
1634 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1635 break;
1636 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1637 a++;
1638 else if (tok == TOK_ENDIF)
1639 a--;
1644 /* ParseState handling */
1646 /* XXX: currently, no include file info is stored. Thus, we cannot display
1647 accurate messages if the function or data definition spans multiple
1648 files */
1650 /* save current parse state in 's' */
1651 void save_parse_state(ParseState *s)
1653 s->line_num = file->line_num;
1654 s->macro_ptr = macro_ptr;
1655 s->tok = tok;
1656 s->tokc = tokc;
1659 /* restore parse state from 's' */
1660 void restore_parse_state(ParseState *s)
1662 file->line_num = s->line_num;
1663 macro_ptr = s->macro_ptr;
1664 tok = s->tok;
1665 tokc = s->tokc;
1668 /* return the number of additionnal 'ints' necessary to store the
1669 token */
1670 static inline int tok_ext_size(int t)
1672 switch(t) {
1673 /* 4 bytes */
1674 case TOK_CINT:
1675 case TOK_CUINT:
1676 case TOK_CCHAR:
1677 case TOK_LCHAR:
1678 case TOK_STR:
1679 case TOK_LSTR:
1680 case TOK_CFLOAT:
1681 case TOK_LINENUM:
1682 case TOK_PPNUM:
1683 return 1;
1684 case TOK_CDOUBLE:
1685 case TOK_CLLONG:
1686 case TOK_CULLONG:
1687 return 2;
1688 case TOK_CLDOUBLE:
1689 return LDOUBLE_SIZE / 4;
1690 default:
1691 return 0;
1695 /* token string handling */
1697 static inline void tok_str_new(TokenString *s)
1699 s->str = NULL;
1700 s->len = 0;
1701 s->last_line_num = -1;
1704 static void tok_str_free(int *str)
1706 const int *p;
1707 CString *cstr;
1708 int t;
1710 p = str;
1711 for(;;) {
1712 t = *p++;
1713 if (t == 0)
1714 break;
1715 if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) {
1716 /* XXX: use a macro to be portable on 64 bit ? */
1717 cstr = (CString *)(*p++);
1718 cstr_free(cstr);
1719 tcc_free(cstr);
1720 } else {
1721 p += tok_ext_size(t);
1724 tcc_free(str);
1727 static void tok_str_add(TokenString *s, int t)
1729 int len, *str;
1731 len = s->len;
1732 str = s->str;
1733 if ((len & 63) == 0) {
1734 str = tcc_realloc(str, (len + 64) * sizeof(int));
1735 if (!str)
1736 return;
1737 s->str = str;
1739 str[len++] = t;
1740 s->len = len;
1743 static void tok_str_add2(TokenString *s, int t, CValue *cv)
1745 int n, i, size;
1746 CString *cstr, *cstr1;
1747 CValue cv1;
1749 tok_str_add(s, t);
1750 if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) {
1751 /* special case: need to duplicate string */
1752 cstr1 = cv->cstr;
1753 cstr = tcc_malloc(sizeof(CString));
1754 size = cstr1->size;
1755 cstr->size = size;
1756 cstr->size_allocated = size;
1757 cstr->data_allocated = tcc_malloc(size);
1758 cstr->data = cstr->data_allocated;
1759 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1760 cv1.cstr = cstr;
1761 tok_str_add(s, cv1.tab[0]);
1762 } else {
1763 n = tok_ext_size(t);
1764 for(i=0;i<n;i++)
1765 tok_str_add(s, cv->tab[i]);
1769 /* add the current parse token in token string 's' */
1770 static void tok_str_add_tok(TokenString *s)
1772 CValue cval;
1774 /* save line number info */
1775 if (file->line_num != s->last_line_num) {
1776 s->last_line_num = file->line_num;
1777 cval.i = s->last_line_num;
1778 tok_str_add2(s, TOK_LINENUM, &cval);
1780 tok_str_add2(s, tok, &tokc);
1783 /* get a token from an integer array and increment pointer accordingly */
1784 static int tok_get(int **tok_str, CValue *cv)
1786 int *p, t, n, i;
1788 p = *tok_str;
1789 t = *p++;
1790 n = tok_ext_size(t);
1791 for(i=0;i<n;i++)
1792 cv->tab[i] = *p++;
1793 *tok_str = p;
1794 return t;
1797 /* eval an expression for #if/#elif */
1798 int expr_preprocess(void)
1800 int c, t;
1801 TokenString str;
1803 tok_str_new(&str);
1804 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1805 next(); /* do macro subst */
1806 if (tok == TOK_DEFINED) {
1807 next_nomacro();
1808 t = tok;
1809 if (t == '(')
1810 next_nomacro();
1811 c = sym_find1(&define_stack, tok) != 0;
1812 if (t == '(')
1813 next_nomacro();
1814 tok = TOK_CINT;
1815 tokc.i = c;
1816 } else if (tok >= TOK_IDENT) {
1817 /* if undefined macro */
1818 tok = TOK_CINT;
1819 tokc.i = 0;
1821 tok_str_add_tok(&str);
1823 tok_str_add(&str, -1); /* simulate end of file */
1824 tok_str_add(&str, 0);
1825 /* now evaluate C constant expression */
1826 macro_ptr = str.str;
1827 next();
1828 c = expr_const();
1829 macro_ptr = NULL;
1830 tok_str_free(str.str);
1831 return c != 0;
1834 #if defined(DEBUG) || defined(PP_DEBUG)
1835 void tok_print(int *str)
1837 int t;
1838 CValue cval;
1840 while (1) {
1841 t = tok_get(&str, &cval);
1842 if (!t)
1843 break;
1844 printf(" %s", get_tok_str(t, &cval));
1846 printf("\n");
1848 #endif
1850 /* parse after #define */
1851 void parse_define(void)
1853 Sym *s, *first, **ps;
1854 int v, t, varg, is_vaargs;
1855 TokenString str;
1857 v = tok;
1858 /* XXX: should check if same macro (ANSI) */
1859 first = NULL;
1860 t = MACRO_OBJ;
1861 /* '(' must be just after macro definition for MACRO_FUNC */
1862 if (ch == '(') {
1863 next_nomacro();
1864 next_nomacro();
1865 ps = &first;
1866 while (tok != ')') {
1867 varg = tok;
1868 next_nomacro();
1869 is_vaargs = 0;
1870 if (varg == TOK_DOTS) {
1871 varg = TOK___VA_ARGS__;
1872 is_vaargs = 1;
1873 } else if (tok == TOK_DOTS && gnu_ext) {
1874 is_vaargs = 1;
1875 next_nomacro();
1877 if (varg < TOK_IDENT)
1878 error("badly punctuated parameter list");
1879 s = sym_push1(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
1880 *ps = s;
1881 ps = &s->next;
1882 if (tok != ',')
1883 break;
1884 next_nomacro();
1886 t = MACRO_FUNC;
1888 tok_str_new(&str);
1889 next_nomacro();
1890 /* EOF testing necessary for '-D' handling */
1891 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1892 tok_str_add2(&str, tok, &tokc);
1893 next_nomacro();
1895 tok_str_add(&str, 0);
1896 #ifdef PP_DEBUG
1897 printf("define %s %d: ", get_tok_str(v, NULL), t);
1898 tok_print(str.str);
1899 #endif
1900 s = sym_push1(&define_stack, v, t, (int)str.str);
1901 s->next = first;
1904 /* XXX: use a token or a hash table to accelerate matching ? */
1905 static CachedInclude *search_cached_include(TCCState *s1,
1906 int type, const char *filename)
1908 CachedInclude *e;
1909 int i;
1911 for(i = 0;i < s1->nb_cached_includes; i++) {
1912 e = s1->cached_includes[i];
1913 if (e->type == type && !strcmp(e->filename, filename))
1914 return e;
1916 return NULL;
1919 static inline void add_cached_include(TCCState *s1, int type,
1920 const char *filename, int ifndef_macro)
1922 CachedInclude *e;
1924 if (search_cached_include(s1, type, filename))
1925 return;
1926 #ifdef INC_DEBUG
1927 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
1928 #endif
1929 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
1930 if (!e)
1931 return;
1932 e->type = type;
1933 strcpy(e->filename, filename);
1934 e->ifndef_macro = ifndef_macro;
1935 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
1939 enum IncludeState {
1940 INCLUDE_STATE_NONE = 0,
1941 INCLUDE_STATE_SEEK_IFNDEF,
1944 void preprocess(void)
1946 TCCState *s1 = tcc_state;
1947 int size, i, c, n;
1948 enum IncludeState state;
1949 char buf[1024], *q, *p;
1950 char buf1[1024];
1951 BufferedFile *f;
1952 Sym *s;
1953 CachedInclude *e;
1955 return_linefeed = 1; /* linefeed will be returned as a
1956 token. EOF is also returned as line feed */
1957 state = INCLUDE_STATE_NONE;
1958 eof_seen = 0;
1959 redo1:
1960 cinp();
1961 next_nomacro();
1962 redo:
1963 if (tok == TOK_DEFINE) {
1964 next_nomacro();
1965 parse_define();
1966 } else if (tok == TOK_UNDEF) {
1967 next_nomacro();
1968 s = sym_find1(&define_stack, tok);
1969 /* undefine symbol by putting an invalid name */
1970 if (s)
1971 sym_undef(&define_stack, s);
1972 } else if (tok == TOK_INCLUDE) {
1973 skip_spaces();
1974 if (ch == '<') {
1975 c = '>';
1976 goto read_name;
1977 } else if (ch == '\"') {
1978 c = ch;
1979 read_name:
1980 minp();
1981 q = buf;
1982 while (ch != c && ch != '\n' && ch != CH_EOF) {
1983 if ((q - buf) < sizeof(buf) - 1)
1984 *q++ = ch;
1985 minp();
1987 *q = '\0';
1988 /* eat all spaces and comments after include */
1989 /* XXX: slightly incorrect */
1990 while (ch1 != '\n' && ch1 != CH_EOF)
1991 inp();
1992 } else {
1993 /* computed #include : either we have only strings or
1994 we have anything enclosed in '<>' */
1995 next();
1996 buf[0] = '\0';
1997 if (tok == TOK_STR) {
1998 while (tok != TOK_LINEFEED) {
1999 if (tok != TOK_STR) {
2000 include_syntax:
2001 error("'#include' expects \"FILENAME\" or <FILENAME>");
2003 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2004 next();
2006 c = '\"';
2007 } else {
2008 int len;
2009 while (tok != TOK_LINEFEED) {
2010 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2011 next();
2013 len = strlen(buf);
2014 /* check syntax and remove '<>' */
2015 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2016 goto include_syntax;
2017 memmove(buf, buf + 1, len - 2);
2018 buf[len - 2] = '\0';
2019 c = '>';
2023 ch = '\n';
2024 e = search_cached_include(s1, c, buf);
2025 if (e && sym_find1(&define_stack, e->ifndef_macro)) {
2026 /* no need to parse the include because the 'ifndef macro'
2027 is defined */
2028 #ifdef INC_DEBUG
2029 printf("%s: skipping %s\n", file->filename, buf);
2030 #endif
2031 } else {
2032 if (c == '\"') {
2033 /* first search in current dir if "header.h" */
2034 size = 0;
2035 p = strrchr(file->filename, '/');
2036 if (p)
2037 size = p + 1 - file->filename;
2038 if (size > sizeof(buf1) - 1)
2039 size = sizeof(buf1) - 1;
2040 memcpy(buf1, file->filename, size);
2041 buf1[size] = '\0';
2042 pstrcat(buf1, sizeof(buf1), buf);
2043 f = tcc_open(s1, buf1);
2044 if (f)
2045 goto found;
2047 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2048 error("#include recursion too deep");
2049 /* now search in all the include paths */
2050 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2051 for(i = 0; i < n; i++) {
2052 const char *path;
2053 if (i < s1->nb_include_paths)
2054 path = s1->include_paths[i];
2055 else
2056 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2057 pstrcpy(buf1, sizeof(buf1), path);
2058 pstrcat(buf1, sizeof(buf1), "/");
2059 pstrcat(buf1, sizeof(buf1), buf);
2060 f = tcc_open(s1, buf1);
2061 if (f)
2062 goto found;
2064 error("include file '%s' not found", buf);
2065 f = NULL;
2066 found:
2067 #ifdef INC_DEBUG
2068 printf("%s: including %s\n", file->filename, buf1);
2069 #endif
2070 f->inc_type = c;
2071 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2072 /* push current file in stack */
2073 /* XXX: fix current line init */
2074 *s1->include_stack_ptr++ = file;
2075 file = f;
2076 /* add include file debug info */
2077 if (do_debug) {
2078 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2080 /* we check for the construct: #ifndef IDENT \n #define IDENT */
2081 inp();
2082 /* get first non space char */
2083 while (is_space(ch) || ch == '\n')
2084 cinp();
2085 if (ch != '#')
2086 goto the_end;
2087 state = INCLUDE_STATE_SEEK_IFNDEF;
2088 goto redo1;
2090 } else if (tok == TOK_IFNDEF) {
2091 c = 1;
2092 goto do_ifdef;
2093 } else if (tok == TOK_IF) {
2094 c = expr_preprocess();
2095 goto do_if;
2096 } else if (tok == TOK_IFDEF) {
2097 c = 0;
2098 do_ifdef:
2099 next_nomacro();
2100 if (tok < TOK_IDENT)
2101 error("invalid argument for '#if%sdef'", c ? "n" : "");
2102 if (state == INCLUDE_STATE_SEEK_IFNDEF) {
2103 if (c) {
2104 file->ifndef_macro = tok;
2106 state = INCLUDE_STATE_NONE;
2108 c = (sym_find1(&define_stack, tok) != 0) ^ c;
2109 do_if:
2110 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2111 error("memory full");
2112 *s1->ifdef_stack_ptr++ = c;
2113 goto test_skip;
2114 } else if (tok == TOK_ELSE) {
2115 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2116 error("#else without matching #if");
2117 if (s1->ifdef_stack_ptr[-1] & 2)
2118 error("#else after #else");
2119 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2120 goto test_skip;
2121 } else if (tok == TOK_ELIF) {
2122 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2123 error("#elif without matching #if");
2124 c = s1->ifdef_stack_ptr[-1];
2125 if (c > 1)
2126 error("#elif after #else");
2127 /* last #if/#elif expression was true: we skip */
2128 if (c == 1)
2129 goto skip;
2130 c = expr_preprocess();
2131 s1->ifdef_stack_ptr[-1] = c;
2132 test_skip:
2133 if (!(c & 1)) {
2134 skip:
2135 preprocess_skip();
2136 state = INCLUDE_STATE_NONE;
2137 goto redo;
2139 } else if (tok == TOK_ENDIF) {
2140 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2141 error("#endif without matching #if");
2142 if (file->ifndef_macro &&
2143 s1->ifdef_stack_ptr == (file->ifdef_stack_ptr + 1)) {
2144 /* '#ifndef macro \n #define macro' was at the start of
2145 file. Now we check if an '#endif' is exactly at the end
2146 of file */
2147 while (tok != TOK_LINEFEED)
2148 next_nomacro();
2149 /* XXX: should also skip comments, but it is more complicated */
2150 if (eof_seen) {
2151 add_cached_include(s1, file->inc_type, file->inc_filename,
2152 file->ifndef_macro);
2153 } else {
2154 /* if not end of file, we must desactivate the ifndef
2155 macro search */
2156 file->ifndef_macro = 0;
2159 s1->ifdef_stack_ptr--;
2160 } else if (tok == TOK_LINE) {
2161 int line_num;
2162 next();
2163 if (tok != TOK_CINT)
2164 error("#line");
2165 line_num = tokc.i;
2166 next();
2167 if (tok != TOK_LINEFEED) {
2168 if (tok != TOK_STR)
2169 error("#line");
2170 pstrcpy(file->filename, sizeof(file->filename),
2171 (char *)tokc.cstr->data);
2173 /* NOTE: we do it there to avoid problems with linefeed */
2174 file->line_num = line_num;
2175 } else if (tok == TOK_ERROR) {
2176 error("#error");
2178 /* ignore other preprocess commands or #! for C scripts */
2179 while (tok != TOK_LINEFEED && tok != TOK_EOF)
2180 next_nomacro();
2181 the_end:
2182 return_linefeed = 0;
2185 /* read a number in base b */
2186 static int getn(int b)
2188 int n, t;
2189 n = 0;
2190 while (1) {
2191 if (ch >= 'a' && ch <= 'f')
2192 t = ch - 'a' + 10;
2193 else if (ch >= 'A' && ch <= 'F')
2194 t = ch - 'A' + 10;
2195 else if (isnum(ch))
2196 t = ch - '0';
2197 else
2198 break;
2199 if (t < 0 || t >= b)
2200 break;
2201 n = n * b + t;
2202 cinp();
2204 return n;
2207 /* read a character for string or char constant and eval escape codes */
2208 static int getq(void)
2210 int c;
2212 c = ch;
2213 minp();
2214 if (c == '\\') {
2215 if (isoct(ch)) {
2216 /* at most three octal digits */
2217 c = ch - '0';
2218 minp();
2219 if (isoct(ch)) {
2220 c = c * 8 + ch - '0';
2221 minp();
2222 if (isoct(ch)) {
2223 c = c * 8 + ch - '0';
2224 minp();
2227 return c;
2228 } else if (ch == 'x') {
2229 minp();
2230 return getn(16);
2231 } else {
2232 if (ch == 'a')
2233 c = '\a';
2234 else if (ch == 'b')
2235 c = '\b';
2236 else if (ch == 'f')
2237 c = '\f';
2238 else if (ch == 'n')
2239 c = '\n';
2240 else if (ch == 'r')
2241 c = '\r';
2242 else if (ch == 't')
2243 c = '\t';
2244 else if (ch == 'v')
2245 c = '\v';
2246 else if (ch == 'e' && gnu_ext)
2247 c = 27;
2248 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
2249 c = ch;
2250 else
2251 error("invalid escaped char");
2252 minp();
2254 } else if (c == '\r' && ch == '\n') {
2255 minp();
2256 c = '\n';
2258 return c;
2261 /* we use 64 bit numbers */
2262 #define BN_SIZE 2
2264 /* bn = (bn << shift) | or_val */
2265 void bn_lshift(unsigned int *bn, int shift, int or_val)
2267 int i;
2268 unsigned int v;
2269 for(i=0;i<BN_SIZE;i++) {
2270 v = bn[i];
2271 bn[i] = (v << shift) | or_val;
2272 or_val = v >> (32 - shift);
2276 void bn_zero(unsigned int *bn)
2278 int i;
2279 for(i=0;i<BN_SIZE;i++) {
2280 bn[i] = 0;
2284 /* parse number in null terminated string 'p' and return it in the
2285 current token */
2286 void parse_number(const char *p)
2288 int b, t, shift, frac_bits, s, exp_val, ch;
2289 char *q;
2290 unsigned int bn[BN_SIZE];
2291 double d;
2293 /* number */
2294 q = token_buf;
2295 ch = *p++;
2296 t = ch;
2297 ch = *p++;
2298 *q++ = t;
2299 b = 10;
2300 if (t == '.') {
2301 goto float_frac_parse;
2302 } else if (t == '0') {
2303 if (ch == 'x' || ch == 'X') {
2304 q--;
2305 ch = *p++;
2306 b = 16;
2307 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2308 q--;
2309 ch = *p++;
2310 b = 2;
2313 /* parse all digits. cannot check octal numbers at this stage
2314 because of floating point constants */
2315 while (1) {
2316 if (ch >= 'a' && ch <= 'f')
2317 t = ch - 'a' + 10;
2318 else if (ch >= 'A' && ch <= 'F')
2319 t = ch - 'A' + 10;
2320 else if (isnum(ch))
2321 t = ch - '0';
2322 else
2323 break;
2324 if (t >= b)
2325 break;
2326 if (q >= token_buf + STRING_MAX_SIZE) {
2327 num_too_long:
2328 error("number too long");
2330 *q++ = ch;
2331 ch = *p++;
2333 if (ch == '.' ||
2334 ((ch == 'e' || ch == 'E') && b == 10) ||
2335 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2336 if (b != 10) {
2337 /* NOTE: strtox should support that for hexa numbers, but
2338 non ISOC99 libcs do not support it, so we prefer to do
2339 it by hand */
2340 /* hexadecimal or binary floats */
2341 /* XXX: handle overflows */
2342 *q = '\0';
2343 if (b == 16)
2344 shift = 4;
2345 else
2346 shift = 2;
2347 bn_zero(bn);
2348 q = token_buf;
2349 while (1) {
2350 t = *q++;
2351 if (t == '\0') {
2352 break;
2353 } else if (t >= 'a') {
2354 t = t - 'a' + 10;
2355 } else if (t >= 'A') {
2356 t = t - 'A' + 10;
2357 } else {
2358 t = t - '0';
2360 bn_lshift(bn, shift, t);
2362 frac_bits = 0;
2363 if (ch == '.') {
2364 ch = *p++;
2365 while (1) {
2366 t = ch;
2367 if (t >= 'a' && t <= 'f') {
2368 t = t - 'a' + 10;
2369 } else if (t >= 'A' && t <= 'F') {
2370 t = t - 'A' + 10;
2371 } else if (t >= '0' && t <= '9') {
2372 t = t - '0';
2373 } else {
2374 break;
2376 if (t >= b)
2377 error("invalid digit");
2378 bn_lshift(bn, shift, t);
2379 frac_bits += shift;
2380 ch = *p++;
2383 if (ch != 'p' && ch != 'P')
2384 error("exponent expected");
2385 ch = *p++;
2386 s = 1;
2387 exp_val = 0;
2388 if (ch == '+') {
2389 ch = *p++;
2390 } else if (ch == '-') {
2391 s = -1;
2392 ch = *p++;
2394 if (ch < '0' || ch > '9')
2395 error("exponent digits expected");
2396 while (ch >= '0' && ch <= '9') {
2397 exp_val = exp_val * 10 + ch - '0';
2398 ch = *p++;
2400 exp_val = exp_val * s;
2402 /* now we can generate the number */
2403 /* XXX: should patch directly float number */
2404 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
2405 d = ldexp(d, exp_val - frac_bits);
2406 t = toup(ch);
2407 if (t == 'F') {
2408 ch = *p++;
2409 tok = TOK_CFLOAT;
2410 /* float : should handle overflow */
2411 tokc.f = (float)d;
2412 } else if (t == 'L') {
2413 ch = *p++;
2414 tok = TOK_CLDOUBLE;
2415 /* XXX: not large enough */
2416 tokc.ld = (long double)d;
2417 } else {
2418 tok = TOK_CDOUBLE;
2419 tokc.d = d;
2421 } else {
2422 /* decimal floats */
2423 if (ch == '.') {
2424 if (q >= token_buf + STRING_MAX_SIZE)
2425 goto num_too_long;
2426 *q++ = ch;
2427 ch = *p++;
2428 float_frac_parse:
2429 while (ch >= '0' && ch <= '9') {
2430 if (q >= token_buf + STRING_MAX_SIZE)
2431 goto num_too_long;
2432 *q++ = ch;
2433 ch = *p++;
2436 if (ch == 'e' || ch == 'E') {
2437 if (q >= token_buf + STRING_MAX_SIZE)
2438 goto num_too_long;
2439 *q++ = ch;
2440 ch = *p++;
2441 if (ch == '-' || ch == '+') {
2442 if (q >= token_buf + STRING_MAX_SIZE)
2443 goto num_too_long;
2444 *q++ = ch;
2445 ch = *p++;
2447 if (ch < '0' || ch > '9')
2448 error("exponent digits expected");
2449 while (ch >= '0' && ch <= '9') {
2450 if (q >= token_buf + STRING_MAX_SIZE)
2451 goto num_too_long;
2452 *q++ = ch;
2453 ch = *p++;
2456 *q = '\0';
2457 t = toup(ch);
2458 errno = 0;
2459 if (t == 'F') {
2460 ch = *p++;
2461 tok = TOK_CFLOAT;
2462 tokc.f = strtof(token_buf, NULL);
2463 } else if (t == 'L') {
2464 ch = *p++;
2465 tok = TOK_CLDOUBLE;
2466 tokc.ld = strtold(token_buf, NULL);
2467 } else {
2468 tok = TOK_CDOUBLE;
2469 tokc.d = strtod(token_buf, NULL);
2472 } else {
2473 unsigned long long n, n1;
2474 int lcount, ucount;
2476 /* integer number */
2477 *q = '\0';
2478 q = token_buf;
2479 if (b == 10 && *q == '0') {
2480 b = 8;
2481 q++;
2483 n = 0;
2484 while(1) {
2485 t = *q++;
2486 /* no need for checks except for base 10 / 8 errors */
2487 if (t == '\0') {
2488 break;
2489 } else if (t >= 'a') {
2490 t = t - 'a' + 10;
2491 } else if (t >= 'A') {
2492 t = t - 'A' + 10;
2493 } else {
2494 t = t - '0';
2495 if (t >= b)
2496 error("invalid digit");
2498 n1 = n;
2499 n = n * b + t;
2500 /* detect overflow */
2501 /* XXX: this test is not reliable */
2502 if (n < n1)
2503 error("integer constant overflow");
2506 /* XXX: not exactly ANSI compliant */
2507 if ((n & 0xffffffff00000000LL) != 0) {
2508 if ((n >> 63) != 0)
2509 tok = TOK_CULLONG;
2510 else
2511 tok = TOK_CLLONG;
2512 } else if (n > 0x7fffffff) {
2513 tok = TOK_CUINT;
2514 } else {
2515 tok = TOK_CINT;
2517 lcount = 0;
2518 ucount = 0;
2519 for(;;) {
2520 t = toup(ch);
2521 if (t == 'L') {
2522 if (lcount >= 2)
2523 error("three 'l's in integer constant");
2524 lcount++;
2525 if (lcount == 2) {
2526 if (tok == TOK_CINT)
2527 tok = TOK_CLLONG;
2528 else if (tok == TOK_CUINT)
2529 tok = TOK_CULLONG;
2531 ch = *p++;
2532 } else if (t == 'U') {
2533 if (ucount >= 1)
2534 error("two 'u's in integer constant");
2535 ucount++;
2536 if (tok == TOK_CINT)
2537 tok = TOK_CUINT;
2538 else if (tok == TOK_CLLONG)
2539 tok = TOK_CULLONG;
2540 ch = *p++;
2541 } else {
2542 break;
2545 if (tok == TOK_CINT || tok == TOK_CUINT)
2546 tokc.ui = n;
2547 else
2548 tokc.ull = n;
2552 /* return next token without macro substitution */
2553 static inline void next_nomacro1(void)
2555 int b;
2556 char *q;
2557 TokenSym *ts;
2559 /* skip spaces */
2560 while(1) {
2561 while (ch == '\n') {
2562 /* during preprocessor parsing, '\n' is a token */
2563 if (return_linefeed) {
2564 tok = TOK_LINEFEED;
2565 return;
2567 cinp();
2568 skip_spaces();
2569 if (ch == '#') {
2570 /* preprocessor command if # at start of line after
2571 spaces */
2572 preprocess();
2575 if (!is_space(ch))
2576 break;
2577 cinp();
2579 if (isid(ch)) {
2580 q = token_buf;
2581 *q++ = ch;
2582 cinp();
2583 if (q[-1] == 'L') {
2584 if (ch == '\'') {
2585 tok = TOK_LCHAR;
2586 goto char_const;
2588 if (ch == '\"') {
2589 tok = TOK_LSTR;
2590 goto str_const;
2593 while (isid(ch) || isnum(ch)) {
2594 if (q >= token_buf + STRING_MAX_SIZE)
2595 error("ident too long");
2596 *q++ = ch;
2597 cinp();
2599 *q = '\0';
2600 ts = tok_alloc(token_buf, q - token_buf);
2601 tok = ts->tok;
2602 } else if (isnum(ch)) {
2603 int t;
2604 cstr_reset(&tokcstr);
2605 /* after the first digit, accept digits, alpha, '.' or sign if
2606 prefixed by 'eEpP' */
2607 parse_num:
2608 for(;;) {
2609 t = ch;
2610 cstr_ccat(&tokcstr, ch);
2611 cinp();
2612 if (!(isnum(ch) || isid(ch) || ch == '.' ||
2613 ((ch == '+' || ch == '-') &&
2614 (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
2615 break;
2617 /* We add a trailing '\0' to ease parsing */
2618 cstr_ccat(&tokcstr, '\0');
2619 tokc.cstr = &tokcstr;
2620 tok = TOK_PPNUM;
2621 } else if (ch == '.') {
2622 /* special dot handling because it can also start a number */
2623 cinp();
2624 if (isnum(ch)) {
2625 cstr_reset(&tokcstr);
2626 cstr_ccat(&tokcstr, '.');
2627 goto parse_num;
2629 if (ch == '.') {
2630 cinp();
2631 if (ch != '.')
2632 expect("'.'");
2633 cinp();
2634 tok = TOK_DOTS;
2635 } else {
2636 tok = '.';
2638 } else if (ch == '\'') {
2639 tok = TOK_CCHAR;
2640 char_const:
2641 minp();
2642 b = getq();
2643 /* this cast is needed if >= 128 */
2644 if (tok == TOK_CCHAR)
2645 b = (char)b;
2646 tokc.i = b;
2647 if (ch != '\'')
2648 expect("\'");
2649 minp();
2650 } else if (ch == '\"') {
2651 tok = TOK_STR;
2652 str_const:
2653 minp();
2654 cstr_reset(&tokcstr);
2655 while (ch != '\"') {
2656 b = getq();
2657 if (ch == CH_EOF)
2658 error("unterminated string");
2659 if (tok == TOK_STR)
2660 cstr_ccat(&tokcstr, b);
2661 else
2662 cstr_wccat(&tokcstr, b);
2664 if (tok == TOK_STR)
2665 cstr_ccat(&tokcstr, '\0');
2666 else
2667 cstr_wccat(&tokcstr, '\0');
2668 tokc.cstr = &tokcstr;
2669 minp();
2670 } else {
2671 q = tok_two_chars;
2672 /* two chars */
2673 tok = ch;
2674 cinp();
2675 while (*q) {
2676 if (*q == tok && q[1] == ch) {
2677 cinp();
2678 tok = q[2] & 0xff;
2679 /* three chars tests */
2680 if (tok == TOK_SHL || tok == TOK_SAR) {
2681 if (ch == '=') {
2682 tok = tok | 0x80;
2683 cinp();
2685 } else if (tok == TOK_DOTS) {
2686 if (ch != '.')
2687 error("parse error");
2688 cinp();
2690 return;
2692 q = q + 3;
2694 /* single char substitutions */
2695 if (tok == '<')
2696 tok = TOK_LT;
2697 else if (tok == '>')
2698 tok = TOK_GT;
2702 /* return next token without macro substitution. Can read input from
2703 macro_ptr buffer */
2704 static void next_nomacro(void)
2706 if (macro_ptr) {
2707 redo:
2708 tok = *macro_ptr;
2709 if (tok) {
2710 tok = tok_get(&macro_ptr, &tokc);
2711 if (tok == TOK_LINENUM) {
2712 file->line_num = tokc.i;
2713 goto redo;
2716 } else {
2717 next_nomacro1();
2721 /* substitute args in macro_str and return allocated string */
2722 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
2724 int *st, last_tok, t, notfirst;
2725 Sym *s;
2726 CValue cval;
2727 TokenString str;
2728 CString cstr;
2730 tok_str_new(&str);
2731 last_tok = 0;
2732 while(1) {
2733 t = tok_get(&macro_str, &cval);
2734 if (!t)
2735 break;
2736 if (t == '#') {
2737 /* stringize */
2738 t = tok_get(&macro_str, &cval);
2739 if (!t)
2740 break;
2741 s = sym_find2(args, t);
2742 if (s) {
2743 cstr_new(&cstr);
2744 st = (int *)s->c;
2745 notfirst = 0;
2746 while (*st) {
2747 if (notfirst)
2748 cstr_ccat(&cstr, ' ');
2749 t = tok_get(&st, &cval);
2750 cstr_cat(&cstr, get_tok_str(t, &cval));
2751 notfirst = 1;
2753 cstr_ccat(&cstr, '\0');
2754 #ifdef PP_DEBUG
2755 printf("stringize: %s\n", (char *)cstr.data);
2756 #endif
2757 /* add string */
2758 cval.cstr = &cstr;
2759 tok_str_add2(&str, TOK_STR, &cval);
2760 cstr_free(&cstr);
2761 } else {
2762 tok_str_add2(&str, t, &cval);
2764 } else if (t >= TOK_IDENT) {
2765 s = sym_find2(args, t);
2766 if (s) {
2767 st = (int *)s->c;
2768 /* if '##' is present before or after, no arg substitution */
2769 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
2770 /* special case for var arg macros : ## eats the
2771 ',' if empty VA_ARGS variable. */
2772 /* XXX: test of the ',' is not 100%
2773 reliable. should fix it to avoid security
2774 problems */
2775 if (gnu_ext && s->t &&
2776 last_tok == TOK_TWOSHARPS &&
2777 str.len >= 2 && str.str[str.len - 2] == ',') {
2778 if (*st == 0) {
2779 /* suppress ',' '##' */
2780 str.len -= 2;
2781 } else {
2782 /* suppress '##' and add variable */
2783 str.len--;
2784 goto add_var;
2786 } else {
2787 int t1;
2788 add_var:
2789 for(;;) {
2790 t1 = tok_get(&st, &cval);
2791 if (!t1)
2792 break;
2793 tok_str_add2(&str, t1, &cval);
2796 } else {
2797 macro_subst(&str, nested_list, st);
2799 } else {
2800 tok_str_add(&str, t);
2802 } else {
2803 tok_str_add2(&str, t, &cval);
2805 last_tok = t;
2807 tok_str_add(&str, 0);
2808 return str.str;
2811 /* handle the '##' operator */
2812 static int *macro_twosharps(void)
2814 TokenSym *ts;
2815 int *macro_ptr1;
2816 int t;
2817 const char *p1, *p2;
2818 CValue cval;
2819 TokenString macro_str1;
2820 CString cstr;
2822 cstr_new(&cstr);
2823 tok_str_new(&macro_str1);
2824 tok = 0;
2825 while (1) {
2826 next_nomacro();
2827 if (tok == 0)
2828 break;
2829 while (*macro_ptr == TOK_TWOSHARPS) {
2830 macro_ptr++;
2831 macro_ptr1 = macro_ptr;
2832 t = *macro_ptr;
2833 if (t) {
2834 t = tok_get(&macro_ptr, &cval);
2836 /* We concatenate the two tokens if we have an
2837 identifier or a preprocessing number */
2838 cstr_reset(&cstr);
2839 p1 = get_tok_str(tok, &tokc);
2840 cstr_cat(&cstr, p1);
2841 p2 = get_tok_str(t, &cval);
2842 cstr_cat(&cstr, p2);
2843 cstr_ccat(&cstr, '\0');
2845 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
2846 (t >= TOK_IDENT || t == TOK_PPNUM)) {
2847 if (tok == TOK_PPNUM) {
2848 /* if number, then create a number token */
2849 /* NOTE: no need to allocate because
2850 tok_str_add2() does it */
2851 tokc.cstr = &cstr;
2852 } else {
2853 /* if identifier, we must do a test to
2854 validate we have a correct identifier */
2855 if (t == TOK_PPNUM) {
2856 const char *p;
2857 int c;
2859 p = p2;
2860 for(;;) {
2861 c = *p;
2862 if (c == '\0')
2863 break;
2864 p++;
2865 if (!isnum(c) && !isid(c))
2866 goto error_pasting;
2869 ts = tok_alloc(cstr.data, strlen(cstr.data));
2870 tok = ts->tok; /* modify current token */
2872 } else {
2873 const char *str = cstr.data;
2874 const unsigned char *q;
2876 /* we look for a valid token */
2877 /* XXX: do more extensive checks */
2878 if (!strcmp(str, ">>=")) {
2879 tok = TOK_A_SAR;
2880 } else if (!strcmp(str, "<<=")) {
2881 tok = TOK_A_SHL;
2882 } else if (strlen(str) == 2) {
2883 /* search in two bytes table */
2884 q = tok_two_chars;
2885 for(;;) {
2886 if (!*q)
2887 goto error_pasting;
2888 if (q[0] == str[0] && q[1] == str[1])
2889 break;
2890 q += 3;
2892 tok = q[2];
2893 } else {
2894 error_pasting:
2895 /* NOTE: because get_tok_str use a static buffer,
2896 we must save it */
2897 cstr_reset(&cstr);
2898 p1 = get_tok_str(tok, &tokc);
2899 cstr_cat(&cstr, p1);
2900 cstr_ccat(&cstr, '\0');
2901 p2 = get_tok_str(t, &cval);
2902 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
2903 /* cannot merge tokens: just add them separately */
2904 tok_str_add2(&macro_str1, tok, &tokc);
2905 /* XXX: free associated memory ? */
2906 tok = t;
2907 tokc = cval;
2912 tok_str_add2(&macro_str1, tok, &tokc);
2914 cstr_free(&cstr);
2915 tok_str_add(&macro_str1, 0);
2916 return macro_str1.str;
2920 /* do macro substitution of current token with macro 's' and add
2921 result to (tok_str,tok_len). 'nested_list' is the list of all
2922 macros we got inside to avoid recursing. Return non zero if no
2923 substitution needs to be done */
2924 static int macro_subst_tok(TokenString *tok_str,
2925 Sym **nested_list, Sym *s)
2927 Sym *args, *sa, *sa1;
2928 int mstr_allocated, parlevel, *mstr, t;
2929 TokenString str;
2930 char *cstrval;
2931 CValue cval;
2932 CString cstr;
2934 /* if symbol is a macro, prepare substitution */
2935 /* if nested substitution, do nothing */
2936 if (sym_find2(*nested_list, tok))
2937 return -1;
2939 /* special macros */
2940 if (tok == TOK___LINE__) {
2941 cval.i = file->line_num;
2942 tok_str_add2(tok_str, TOK_CINT, &cval);
2943 } else if (tok == TOK___FILE__) {
2944 cstrval = file->filename;
2945 goto add_cstr;
2946 tok_str_add2(tok_str, TOK_STR, &cval);
2947 } else if (tok == TOK___DATE__) {
2948 cstrval = "Jan 1 2002";
2949 goto add_cstr;
2950 } else if (tok == TOK___TIME__) {
2951 cstrval = "00:00:00";
2952 add_cstr:
2953 cstr_new(&cstr);
2954 cstr_cat(&cstr, cstrval);
2955 cstr_ccat(&cstr, '\0');
2956 cval.cstr = &cstr;
2957 tok_str_add2(tok_str, TOK_STR, &cval);
2958 cstr_free(&cstr);
2959 } else {
2960 mstr = (int *)s->c;
2961 mstr_allocated = 0;
2962 if (s->t == MACRO_FUNC) {
2963 /* NOTE: we do not use next_nomacro to avoid eating the
2964 next token. XXX: find better solution */
2965 if (macro_ptr) {
2966 t = *macro_ptr;
2967 } else {
2968 while (is_space(ch) || ch == '\n')
2969 cinp();
2970 t = ch;
2972 if (t != '(') /* no macro subst */
2973 return -1;
2975 /* argument macro */
2976 next_nomacro();
2977 next_nomacro();
2978 args = NULL;
2979 sa = s->next;
2980 /* NOTE: empty args are allowed, except if no args */
2981 for(;;) {
2982 /* handle '()' case */
2983 if (!args && tok == ')')
2984 break;
2985 if (!sa)
2986 error("macro '%s' used with too many args",
2987 get_tok_str(s->v, 0));
2988 tok_str_new(&str);
2989 parlevel = 0;
2990 /* NOTE: non zero sa->t indicates VA_ARGS */
2991 while ((parlevel > 0 ||
2992 (tok != ')' &&
2993 (tok != ',' || sa->t))) &&
2994 tok != -1) {
2995 if (tok == '(')
2996 parlevel++;
2997 else if (tok == ')')
2998 parlevel--;
2999 tok_str_add2(&str, tok, &tokc);
3000 next_nomacro();
3002 tok_str_add(&str, 0);
3003 sym_push2(&args, sa->v & ~SYM_FIELD, sa->t, (int)str.str);
3004 sa = sa->next;
3005 if (tok == ')') {
3006 /* special case for gcc var args: add an empty
3007 var arg argument if it is omitted */
3008 if (sa && sa->t && gnu_ext)
3009 continue;
3010 else
3011 break;
3013 if (tok != ',')
3014 expect(",");
3015 next_nomacro();
3017 if (sa) {
3018 error("macro '%s' used with too few args",
3019 get_tok_str(s->v, 0));
3022 /* now subst each arg */
3023 mstr = macro_arg_subst(nested_list, mstr, args);
3024 /* free memory */
3025 sa = args;
3026 while (sa) {
3027 sa1 = sa->prev;
3028 tok_str_free((int *)sa->c);
3029 tcc_free(sa);
3030 sa = sa1;
3032 mstr_allocated = 1;
3034 sym_push2(nested_list, s->v, 0, 0);
3035 macro_subst(tok_str, nested_list, mstr);
3036 /* pop nested defined symbol */
3037 sa1 = *nested_list;
3038 *nested_list = sa1->prev;
3039 tcc_free(sa1);
3040 if (mstr_allocated)
3041 tok_str_free(mstr);
3043 return 0;
3046 /* do macro substitution of macro_str and add result to
3047 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3048 inside to avoid recursing. */
3049 static void macro_subst(TokenString *tok_str,
3050 Sym **nested_list, int *macro_str)
3052 Sym *s;
3053 int *saved_macro_ptr;
3054 int *macro_str1;
3056 saved_macro_ptr = macro_ptr;
3057 macro_ptr = macro_str;
3058 /* first scan for '##' operator handling */
3059 macro_str1 = macro_twosharps();
3060 macro_ptr = macro_str1;
3062 while (1) {
3063 next_nomacro();
3064 if (tok == 0)
3065 break;
3066 s = sym_find1(&define_stack, tok);
3067 if (s != NULL) {
3068 if (macro_subst_tok(tok_str, nested_list, s) != 0)
3069 goto no_subst;
3070 } else {
3071 no_subst:
3072 tok_str_add2(tok_str, tok, &tokc);
3075 macro_ptr = saved_macro_ptr;
3076 tok_str_free(macro_str1);
3079 /* return next token with macro substitution */
3080 static void next(void)
3082 Sym *nested_list, *s;
3083 TokenString str;
3085 /* special 'ungettok' case for label parsing */
3086 if (tok1) {
3087 tok = tok1;
3088 tokc = tok1c;
3089 tok1 = 0;
3090 } else {
3091 redo:
3092 next_nomacro();
3093 if (!macro_ptr) {
3094 /* if not reading from macro substituted string, then try
3095 to substitute macros */
3096 if (tok >= TOK_IDENT) {
3097 s = sym_find1(&define_stack, tok);
3098 if (s) {
3099 /* we have a macro: we try to substitute */
3100 tok_str_new(&str);
3101 nested_list = NULL;
3102 if (macro_subst_tok(&str, &nested_list, s) == 0) {
3103 /* substitution done, NOTE: maybe empty */
3104 tok_str_add(&str, 0);
3105 macro_ptr = str.str;
3106 macro_ptr_allocated = str.str;
3107 goto redo;
3111 } else {
3112 if (tok == 0) {
3113 /* end of macro string: free it */
3114 tok_str_free(macro_ptr_allocated);
3115 macro_ptr = NULL;
3116 goto redo;
3120 /* convert preprocessor tokens into C tokens */
3121 if (tok == TOK_PPNUM) {
3122 parse_number((char *)tokc.cstr->data);
3125 #if defined(DEBUG)
3126 printf("token = %s\n", get_tok_str(tok, &tokc));
3127 #endif
3130 void swap(int *p, int *q)
3132 int t;
3133 t = *p;
3134 *p = *q;
3135 *q = t;
3138 void vsetc(int t, int r, CValue *vc)
3140 int v;
3142 if (vtop >= vstack + VSTACK_SIZE)
3143 error("memory full");
3144 /* cannot let cpu flags if other instruction are generated. Also
3145 avoid leaving VT_JMP anywhere except on the top of the stack
3146 because it would complicate the code generator. */
3147 if (vtop >= vstack) {
3148 v = vtop->r & VT_VALMASK;
3149 if (v == VT_CMP || (v & ~1) == VT_JMP)
3150 gv(RC_INT);
3152 vtop++;
3153 vtop->t = t;
3154 vtop->r = r;
3155 vtop->r2 = VT_CONST;
3156 vtop->c = *vc;
3159 /* push integer constant */
3160 void vpushi(int v)
3162 CValue cval;
3163 cval.i = v;
3164 vsetc(VT_INT, VT_CONST, &cval);
3167 /* Return a static symbol pointing to a section */
3168 static Sym *get_sym_ref(int t, Section *sec,
3169 unsigned long offset, unsigned long size)
3171 int v;
3172 Sym *sym;
3174 v = anon_sym++;
3175 sym = sym_push1(&global_stack, v, t | VT_STATIC, 0);
3176 sym->r = VT_CONST | VT_SYM;
3177 put_extern_sym(sym, sec, offset, size);
3178 return sym;
3181 /* push a reference to a section offset by adding a dummy symbol */
3182 static void vpush_ref(int t, Section *sec, unsigned long offset, unsigned long size)
3184 CValue cval;
3186 cval.ul = 0;
3187 vsetc(t, VT_CONST | VT_SYM, &cval);
3188 vtop->sym = get_sym_ref(t, sec, offset, size);
3191 /* define a new external reference to a symbol 'v' of type 'u' */
3192 static Sym *external_global_sym(int v, int u, int r)
3194 Sym *s;
3196 s = sym_find(v);
3197 if (!s) {
3198 /* push forward reference */
3199 s = sym_push1(&global_stack,
3200 v, u | VT_EXTERN, 0);
3201 s->r = r | VT_CONST | VT_SYM;
3203 return s;
3206 /* define a new external reference to a symbol 'v' of type 'u' */
3207 static Sym *external_sym(int v, int u, int r)
3209 Sym *s;
3211 s = sym_find(v);
3212 if (!s) {
3213 /* push forward reference */
3214 s = sym_push(v, u | VT_EXTERN, r | VT_CONST | VT_SYM, 0);
3216 return s;
3219 /* push a reference to global symbol v */
3220 static void vpush_global_sym(int t, int v)
3222 Sym *sym;
3223 CValue cval;
3225 sym = external_global_sym(v, t, 0);
3226 cval.ul = 0;
3227 vsetc(t, VT_CONST | VT_SYM, &cval);
3228 vtop->sym = sym;
3231 void vset(int t, int r, int v)
3233 CValue cval;
3235 cval.i = v;
3236 vsetc(t, r, &cval);
3239 void vswap(void)
3241 SValue tmp;
3243 tmp = vtop[0];
3244 vtop[0] = vtop[-1];
3245 vtop[-1] = tmp;
3248 void vpushv(SValue *v)
3250 if (vtop >= vstack + VSTACK_SIZE)
3251 error("memory full");
3252 vtop++;
3253 *vtop = *v;
3256 void vdup(void)
3258 vpushv(vtop);
3261 /* save r to the memory stack, and mark it as being free */
3262 void save_reg(int r)
3264 int l, saved, t, size, align;
3265 SValue *p, sv;
3267 /* modify all stack values */
3268 saved = 0;
3269 l = 0;
3270 for(p=vstack;p<=vtop;p++) {
3271 if ((p->r & VT_VALMASK) == r ||
3272 (p->r2 & VT_VALMASK) == r) {
3273 /* must save value on stack if not already done */
3274 if (!saved) {
3275 /* NOTE: must reload 'r' because r might be equal to r2 */
3276 r = p->r & VT_VALMASK;
3277 /* store register in the stack */
3278 t = p->t;
3279 if ((p->r & VT_LVAL) ||
3280 (!is_float(t) && (t & VT_BTYPE) != VT_LLONG))
3281 t = VT_INT;
3282 size = type_size(t, &align);
3283 loc = (loc - size) & -align;
3284 sv.t = t;
3285 sv.r = VT_LOCAL | VT_LVAL;
3286 sv.c.ul = loc;
3287 store(r, &sv);
3288 #ifdef TCC_TARGET_I386
3289 /* x86 specific: need to pop fp register ST0 if saved */
3290 if (r == REG_ST0) {
3291 o(0xd9dd); /* fstp %st(1) */
3293 #endif
3294 /* special long long case */
3295 if ((t & VT_BTYPE) == VT_LLONG) {
3296 sv.c.ul += 4;
3297 store(p->r2, &sv);
3299 l = loc;
3300 saved = 1;
3302 /* mark that stack entry as being saved on the stack */
3303 if (p->r & VT_LVAL) {
3304 /* also suppress the bounded flag because the
3305 relocation address of the function was stored in
3306 p->c.ul */
3307 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
3308 } else {
3309 p->r = lvalue_type(p->t) | VT_LOCAL;
3311 p->r2 = VT_CONST;
3312 p->c.ul = l;
3317 /* find a free register of class 'rc'. If none, save one register */
3318 int get_reg(int rc)
3320 int r;
3321 SValue *p;
3323 /* find a free register */
3324 for(r=0;r<NB_REGS;r++) {
3325 if (reg_classes[r] & rc) {
3326 for(p=vstack;p<=vtop;p++) {
3327 if ((p->r & VT_VALMASK) == r ||
3328 (p->r2 & VT_VALMASK) == r)
3329 goto notfound;
3331 return r;
3333 notfound: ;
3336 /* no register left : free the first one on the stack (VERY
3337 IMPORTANT to start from the bottom to ensure that we don't
3338 spill registers used in gen_opi()) */
3339 for(p=vstack;p<=vtop;p++) {
3340 r = p->r & VT_VALMASK;
3341 if (r < VT_CONST && (reg_classes[r] & rc))
3342 goto save_found;
3343 /* also look at second register (if long long) */
3344 r = p->r2 & VT_VALMASK;
3345 if (r < VT_CONST && (reg_classes[r] & rc)) {
3346 save_found:
3347 save_reg(r);
3348 return r;
3351 /* Should never comes here */
3352 return -1;
3355 /* save registers up to (vtop - n) stack entry */
3356 void save_regs(int n)
3358 int r;
3359 SValue *p, *p1;
3360 p1 = vtop - n;
3361 for(p = vstack;p <= p1; p++) {
3362 r = p->r & VT_VALMASK;
3363 if (r < VT_CONST) {
3364 save_reg(r);
3369 /* move register 's' to 'r', and flush previous value of r to memory
3370 if needed */
3371 void move_reg(int r, int s)
3373 SValue sv;
3375 if (r != s) {
3376 save_reg(r);
3377 sv.t = VT_INT;
3378 sv.r = s;
3379 sv.c.ul = 0;
3380 load(r, &sv);
3384 /* get address of vtop (vtop MUST BE an lvalue) */
3385 void gaddrof(void)
3387 vtop->r &= ~VT_LVAL;
3388 /* tricky: if saved lvalue, then we can go back to lvalue */
3389 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
3390 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
3393 #ifdef CONFIG_TCC_BCHECK
3394 /* generate lvalue bound code */
3395 void gbound(void)
3397 int lval_type, t1;
3399 vtop->r &= ~VT_MUSTBOUND;
3400 /* if lvalue, then use checking code before dereferencing */
3401 if (vtop->r & VT_LVAL) {
3402 /* if not VT_BOUNDED value, then make one */
3403 if (!(vtop->r & VT_BOUNDED)) {
3404 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
3405 /* must save type because we must set it to int to get pointer */
3406 t1 = vtop->t;
3407 vtop->t = VT_INT;
3408 gaddrof();
3409 vpushi(0);
3410 gen_bounded_ptr_add();
3411 vtop->r |= lval_type;
3412 vtop->t = t1;
3414 /* then check for dereferencing */
3415 gen_bounded_ptr_deref();
3418 #endif
3420 /* store vtop a register belonging to class 'rc'. lvalues are
3421 converted to values. Cannot be used if cannot be converted to
3422 register value (such as structures). */
3423 int gv(int rc)
3425 int r, r2, rc2, bit_pos, bit_size, size, align, i;
3426 unsigned long long ll;
3428 /* NOTE: get_reg can modify vstack[] */
3429 if (vtop->t & VT_BITFIELD) {
3430 bit_pos = (vtop->t >> VT_STRUCT_SHIFT) & 0x3f;
3431 bit_size = (vtop->t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
3432 /* remove bit field info to avoid loops */
3433 vtop->t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
3434 /* generate shifts */
3435 vpushi(32 - (bit_pos + bit_size));
3436 gen_op(TOK_SHL);
3437 vpushi(32 - bit_size);
3438 /* NOTE: transformed to SHR if unsigned */
3439 gen_op(TOK_SAR);
3440 r = gv(rc);
3441 } else {
3442 if (is_float(vtop->t) &&
3443 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3444 Sym *sym;
3445 int *ptr;
3446 unsigned long offset;
3448 /* XXX: unify with initializers handling ? */
3449 /* CPUs usually cannot use float constants, so we store them
3450 generically in data segment */
3451 size = type_size(vtop->t, &align);
3452 offset = (data_section->data_offset + align - 1) & -align;
3453 data_section->data_offset = offset;
3454 /* XXX: not portable yet */
3455 ptr = section_ptr_add(data_section, size);
3456 size = size >> 2;
3457 for(i=0;i<size;i++)
3458 ptr[i] = vtop->c.tab[i];
3459 sym = get_sym_ref(vtop->t, data_section, offset, size << 2);
3460 vtop->r |= VT_LVAL | VT_SYM;
3461 vtop->sym = sym;
3462 vtop->c.ul = 0;
3464 #ifdef CONFIG_TCC_BCHECK
3465 if (vtop->r & VT_MUSTBOUND)
3466 gbound();
3467 #endif
3469 r = vtop->r & VT_VALMASK;
3470 /* need to reload if:
3471 - constant
3472 - lvalue (need to dereference pointer)
3473 - already a register, but not in the right class */
3474 if (r >= VT_CONST ||
3475 (vtop->r & VT_LVAL) ||
3476 !(reg_classes[r] & rc) ||
3477 ((vtop->t & VT_BTYPE) == VT_LLONG &&
3478 !(reg_classes[vtop->r2] & rc))) {
3479 r = get_reg(rc);
3480 if ((vtop->t & VT_BTYPE) == VT_LLONG) {
3481 /* two register type load : expand to two words
3482 temporarily */
3483 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3484 /* load constant */
3485 ll = vtop->c.ull;
3486 vtop->c.ui = ll; /* first word */
3487 load(r, vtop);
3488 vtop->r = r; /* save register value */
3489 vpushi(ll >> 32); /* second word */
3490 } else if (r >= VT_CONST ||
3491 (vtop->r & VT_LVAL)) {
3492 /* load from memory */
3493 load(r, vtop);
3494 vdup();
3495 vtop[-1].r = r; /* save register value */
3496 /* increment pointer to get second word */
3497 vtop->t = VT_INT;
3498 gaddrof();
3499 vpushi(4);
3500 gen_op('+');
3501 vtop->r |= VT_LVAL;
3502 } else {
3503 /* move registers */
3504 load(r, vtop);
3505 vdup();
3506 vtop[-1].r = r; /* save register value */
3507 vtop->r = vtop[-1].r2;
3509 /* allocate second register */
3510 rc2 = RC_INT;
3511 if (rc == RC_IRET)
3512 rc2 = RC_LRET;
3513 r2 = get_reg(rc2);
3514 load(r2, vtop);
3515 vpop();
3516 /* write second register */
3517 vtop->r2 = r2;
3518 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->t)) {
3519 int t1, t;
3520 /* lvalue of scalar type : need to use lvalue type
3521 because of possible cast */
3522 t = vtop->t;
3523 t1 = t;
3524 /* compute memory access type */
3525 if (vtop->r & VT_LVAL_BYTE)
3526 t = VT_BYTE;
3527 else if (vtop->r & VT_LVAL_SHORT)
3528 t = VT_SHORT;
3529 if (vtop->r & VT_LVAL_UNSIGNED)
3530 t |= VT_UNSIGNED;
3531 vtop->t = t;
3532 load(r, vtop);
3533 /* restore wanted type */
3534 vtop->t = t1;
3535 } else {
3536 /* one register type load */
3537 load(r, vtop);
3540 vtop->r = r;
3542 return r;
3545 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3546 void gv2(int rc1, int rc2)
3548 int v;
3550 /* generate more generic register first. But VT_JMP or VT_CMP
3551 values must be generated first in all cases to avoid possible
3552 reload errors */
3553 v = vtop[0].r & VT_VALMASK;
3554 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
3555 vswap();
3556 gv(rc1);
3557 vswap();
3558 gv(rc2);
3559 /* test if reload is needed for first register */
3560 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
3561 vswap();
3562 gv(rc1);
3563 vswap();
3565 } else {
3566 gv(rc2);
3567 vswap();
3568 gv(rc1);
3569 vswap();
3570 /* test if reload is needed for first register */
3571 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
3572 gv(rc2);
3577 /* expand long long on stack in two int registers */
3578 void lexpand(void)
3580 int u;
3582 u = vtop->t & VT_UNSIGNED;
3583 gv(RC_INT);
3584 vdup();
3585 vtop[0].r = vtop[-1].r2;
3586 vtop[0].r2 = VT_CONST;
3587 vtop[-1].r2 = VT_CONST;
3588 vtop[0].t = VT_INT | u;
3589 vtop[-1].t = VT_INT | u;
3592 /* build a long long from two ints */
3593 void lbuild(int t)
3595 gv2(RC_INT, RC_INT);
3596 vtop[-1].r2 = vtop[0].r;
3597 vtop[-1].t = t;
3598 vpop();
3601 /* rotate n first stack elements to the bottom */
3602 void vrotb(int n)
3604 int i;
3605 SValue tmp;
3607 tmp = vtop[-n + 1];
3608 for(i=-n+1;i!=0;i++)
3609 vtop[i] = vtop[i+1];
3610 vtop[0] = tmp;
3613 /* pop stack value */
3614 void vpop(void)
3616 int v;
3617 v = vtop->r & VT_VALMASK;
3618 #ifdef TCC_TARGET_I386
3619 /* for x86, we need to pop the FP stack */
3620 if (v == REG_ST0 && !nocode_wanted) {
3621 o(0xd9dd); /* fstp %st(1) */
3622 } else
3623 #endif
3624 if (v == VT_JMP || v == VT_JMPI) {
3625 /* need to put correct jump if && or || without test */
3626 gsym(vtop->c.ul);
3628 vtop--;
3631 /* convert stack entry to register and duplicate its value in another
3632 register */
3633 void gv_dup(void)
3635 int rc, t, r, r1;
3636 SValue sv;
3638 t = vtop->t;
3639 if ((t & VT_BTYPE) == VT_LLONG) {
3640 lexpand();
3641 gv_dup();
3642 vswap();
3643 vrotb(3);
3644 gv_dup();
3645 vrotb(4);
3646 /* stack: H L L1 H1 */
3647 lbuild(t);
3648 vrotb(3);
3649 vrotb(3);
3650 vswap();
3651 lbuild(t);
3652 vswap();
3653 } else {
3654 /* duplicate value */
3655 rc = RC_INT;
3656 sv.t = VT_INT;
3657 if (is_float(t)) {
3658 rc = RC_FLOAT;
3659 sv.t = t;
3661 r = gv(rc);
3662 r1 = get_reg(rc);
3663 sv.r = r;
3664 sv.c.ul = 0;
3665 load(r1, &sv); /* move r to r1 */
3666 vdup();
3667 /* duplicates value */
3668 vtop->r = r1;
3672 /* generate CPU independent (unsigned) long long operations */
3673 void gen_opl(int op)
3675 int t, a, b, op1, c, i;
3676 int func;
3677 GFuncContext gf;
3678 SValue tmp;
3680 switch(op) {
3681 case '/':
3682 case TOK_PDIV:
3683 func = TOK___divdi3;
3684 goto gen_func;
3685 case TOK_UDIV:
3686 func = TOK___udivdi3;
3687 goto gen_func;
3688 case '%':
3689 func = TOK___moddi3;
3690 goto gen_func;
3691 case TOK_UMOD:
3692 func = TOK___umoddi3;
3693 gen_func:
3694 /* call generic long long function */
3695 gfunc_start(&gf, FUNC_CDECL);
3696 gfunc_param(&gf);
3697 gfunc_param(&gf);
3698 vpush_global_sym(func_old_type, func);
3699 gfunc_call(&gf);
3700 vpushi(0);
3701 vtop->r = REG_IRET;
3702 vtop->r2 = REG_LRET;
3703 break;
3704 case '^':
3705 case '&':
3706 case '|':
3707 case '*':
3708 case '+':
3709 case '-':
3710 t = vtop->t;
3711 vswap();
3712 lexpand();
3713 vrotb(3);
3714 lexpand();
3715 /* stack: L1 H1 L2 H2 */
3716 tmp = vtop[0];
3717 vtop[0] = vtop[-3];
3718 vtop[-3] = tmp;
3719 tmp = vtop[-2];
3720 vtop[-2] = vtop[-3];
3721 vtop[-3] = tmp;
3722 vswap();
3723 /* stack: H1 H2 L1 L2 */
3724 if (op == '*') {
3725 vpushv(vtop - 1);
3726 vpushv(vtop - 1);
3727 gen_op(TOK_UMULL);
3728 lexpand();
3729 /* stack: H1 H2 L1 L2 ML MH */
3730 for(i=0;i<4;i++)
3731 vrotb(6);
3732 /* stack: ML MH H1 H2 L1 L2 */
3733 tmp = vtop[0];
3734 vtop[0] = vtop[-2];
3735 vtop[-2] = tmp;
3736 /* stack: ML MH H1 L2 H2 L1 */
3737 gen_op('*');
3738 vrotb(3);
3739 vrotb(3);
3740 gen_op('*');
3741 /* stack: ML MH M1 M2 */
3742 gen_op('+');
3743 gen_op('+');
3744 } else if (op == '+' || op == '-') {
3745 /* XXX: add non carry method too (for MIPS or alpha) */
3746 if (op == '+')
3747 op1 = TOK_ADDC1;
3748 else
3749 op1 = TOK_SUBC1;
3750 gen_op(op1);
3751 /* stack: H1 H2 (L1 op L2) */
3752 vrotb(3);
3753 vrotb(3);
3754 gen_op(op1 + 1); /* TOK_xxxC2 */
3755 } else {
3756 gen_op(op);
3757 /* stack: H1 H2 (L1 op L2) */
3758 vrotb(3);
3759 vrotb(3);
3760 /* stack: (L1 op L2) H1 H2 */
3761 gen_op(op);
3762 /* stack: (L1 op L2) (H1 op H2) */
3764 /* stack: L H */
3765 lbuild(t);
3766 break;
3767 case TOK_SAR:
3768 case TOK_SHR:
3769 case TOK_SHL:
3770 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3771 t = vtop[-1].t;
3772 vswap();
3773 lexpand();
3774 vrotb(3);
3775 /* stack: L H shift */
3776 c = (int)vtop->c.i;
3777 /* constant: simpler */
3778 /* NOTE: all comments are for SHL. the other cases are
3779 done by swaping words */
3780 vpop();
3781 if (op != TOK_SHL)
3782 vswap();
3783 if (c >= 32) {
3784 /* stack: L H */
3785 vpop();
3786 if (c > 32) {
3787 vpushi(c - 32);
3788 gen_op(op);
3790 if (op != TOK_SAR) {
3791 vpushi(0);
3792 } else {
3793 gv_dup();
3794 vpushi(31);
3795 gen_op(TOK_SAR);
3797 vswap();
3798 } else {
3799 vswap();
3800 gv_dup();
3801 /* stack: H L L */
3802 vpushi(c);
3803 gen_op(op);
3804 vswap();
3805 vpushi(32 - c);
3806 if (op == TOK_SHL)
3807 gen_op(TOK_SHR);
3808 else
3809 gen_op(TOK_SHL);
3810 vrotb(3);
3811 /* stack: L L H */
3812 vpushi(c);
3813 if (op == TOK_SHL)
3814 gen_op(TOK_SHL);
3815 else
3816 gen_op(TOK_SHR);
3817 gen_op('|');
3819 if (op != TOK_SHL)
3820 vswap();
3821 lbuild(t);
3822 } else {
3823 /* XXX: should provide a faster fallback on x86 ? */
3824 switch(op) {
3825 case TOK_SAR:
3826 func = TOK___sardi3;
3827 goto gen_func;
3828 case TOK_SHR:
3829 func = TOK___shrdi3;
3830 goto gen_func;
3831 case TOK_SHL:
3832 func = TOK___shldi3;
3833 goto gen_func;
3836 break;
3837 default:
3838 /* compare operations */
3839 t = vtop->t;
3840 vswap();
3841 lexpand();
3842 vrotb(3);
3843 lexpand();
3844 /* stack: L1 H1 L2 H2 */
3845 tmp = vtop[-1];
3846 vtop[-1] = vtop[-2];
3847 vtop[-2] = tmp;
3848 /* stack: L1 L2 H1 H2 */
3849 /* compare high */
3850 op1 = op;
3851 /* when values are equal, we need to compare low words. since
3852 the jump is inverted, we invert the test too. */
3853 if (op1 == TOK_LT)
3854 op1 = TOK_LE;
3855 else if (op1 == TOK_GT)
3856 op1 = TOK_GE;
3857 else if (op1 == TOK_ULT)
3858 op1 = TOK_ULE;
3859 else if (op1 == TOK_UGT)
3860 op1 = TOK_UGE;
3861 a = 0;
3862 b = 0;
3863 gen_op(op1);
3864 if (op1 != TOK_NE) {
3865 a = gtst(1, 0);
3867 if (op != TOK_EQ) {
3868 /* generate non equal test */
3869 /* XXX: NOT PORTABLE yet */
3870 if (a == 0) {
3871 b = gtst(0, 0);
3872 } else {
3873 #ifdef TCC_TARGET_I386
3874 b = psym(0x850f, 0);
3875 #else
3876 error("not implemented");
3877 #endif
3880 /* compare low */
3881 gen_op(op);
3882 a = gtst(1, a);
3883 gsym(b);
3884 vset(VT_INT, VT_JMPI, a);
3885 break;
3889 /* handle integer constant optimizations and various machine
3890 independant opt */
3891 void gen_opic(int op)
3893 int fc, c1, c2, n;
3894 SValue *v1, *v2;
3896 v1 = vtop - 1;
3897 v2 = vtop;
3898 /* currently, we cannot do computations with forward symbols */
3899 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3900 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3901 if (c1 && c2) {
3902 fc = v2->c.i;
3903 switch(op) {
3904 case '+': v1->c.i += fc; break;
3905 case '-': v1->c.i -= fc; break;
3906 case '&': v1->c.i &= fc; break;
3907 case '^': v1->c.i ^= fc; break;
3908 case '|': v1->c.i |= fc; break;
3909 case '*': v1->c.i *= fc; break;
3911 case TOK_PDIV:
3912 case '/':
3913 case '%':
3914 case TOK_UDIV:
3915 case TOK_UMOD:
3916 /* if division by zero, generate explicit division */
3917 if (fc == 0) {
3918 if (const_wanted)
3919 error("division by zero in constant");
3920 goto general_case;
3922 switch(op) {
3923 default: v1->c.i /= fc; break;
3924 case '%': v1->c.i %= fc; break;
3925 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
3926 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
3928 break;
3929 case TOK_SHL: v1->c.i <<= fc; break;
3930 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
3931 case TOK_SAR: v1->c.i >>= fc; break;
3932 /* tests */
3933 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
3934 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
3935 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
3936 case TOK_NE: v1->c.i = v1->c.i != fc; break;
3937 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
3938 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
3939 case TOK_LT: v1->c.i = v1->c.i < fc; break;
3940 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
3941 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
3942 case TOK_GT: v1->c.i = v1->c.i > fc; break;
3943 /* logical */
3944 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
3945 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
3946 default:
3947 goto general_case;
3949 vtop--;
3950 } else {
3951 /* if commutative ops, put c2 as constant */
3952 if (c1 && (op == '+' || op == '&' || op == '^' ||
3953 op == '|' || op == '*')) {
3954 vswap();
3955 swap(&c1, &c2);
3957 fc = vtop->c.i;
3958 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
3959 op == TOK_PDIV) &&
3960 fc == 1) ||
3961 ((op == '+' || op == '-' || op == '|' || op == '^' ||
3962 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
3963 fc == 0) ||
3964 (op == '&' &&
3965 fc == -1))) {
3966 /* nothing to do */
3967 vtop--;
3968 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
3969 /* try to use shifts instead of muls or divs */
3970 if (fc > 0 && (fc & (fc - 1)) == 0) {
3971 n = -1;
3972 while (fc) {
3973 fc >>= 1;
3974 n++;
3976 vtop->c.i = n;
3977 if (op == '*')
3978 op = TOK_SHL;
3979 else if (op == TOK_PDIV)
3980 op = TOK_SAR;
3981 else
3982 op = TOK_SHR;
3984 goto general_case;
3985 } else if (c2 && (op == '+' || op == '-') &&
3986 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
3987 (VT_CONST | VT_SYM)) {
3988 /* symbol + constant case */
3989 if (op == '-')
3990 fc = -fc;
3991 vtop--;
3992 vtop->c.i += fc;
3993 } else {
3994 general_case:
3995 if (!nocode_wanted) {
3996 /* call low level op generator */
3997 gen_opi(op);
3998 } else {
3999 vtop--;
4005 /* generate a floating point operation with constant propagation */
4006 void gen_opif(int op)
4008 int c1, c2;
4009 SValue *v1, *v2;
4010 long double f1, f2;
4012 v1 = vtop - 1;
4013 v2 = vtop;
4014 /* currently, we cannot do computations with forward symbols */
4015 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4016 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4017 if (c1 && c2) {
4018 if (v1->t == VT_FLOAT) {
4019 f1 = v1->c.f;
4020 f2 = v2->c.f;
4021 } else if (v1->t == VT_DOUBLE) {
4022 f1 = v1->c.d;
4023 f2 = v2->c.d;
4024 } else {
4025 f1 = v1->c.ld;
4026 f2 = v2->c.ld;
4029 /* NOTE: we only do constant propagation if finite number (not
4030 NaN or infinity) (ANSI spec) */
4031 if (!ieee_finite(f1) || !ieee_finite(f2))
4032 goto general_case;
4034 switch(op) {
4035 case '+': f1 += f2; break;
4036 case '-': f1 -= f2; break;
4037 case '*': f1 *= f2; break;
4038 case '/':
4039 if (f2 == 0.0) {
4040 if (const_wanted)
4041 error("division by zero in constant");
4042 goto general_case;
4044 f1 /= f2;
4045 break;
4046 /* XXX: also handles tests ? */
4047 default:
4048 goto general_case;
4050 /* XXX: overflow test ? */
4051 if (v1->t == VT_FLOAT) {
4052 v1->c.f = f1;
4053 } else if (v1->t == VT_DOUBLE) {
4054 v1->c.d = f1;
4055 } else {
4056 v1->c.ld = f1;
4058 vtop--;
4059 } else {
4060 general_case:
4061 if (!nocode_wanted) {
4062 gen_opf(op);
4063 } else {
4064 vtop--;
4069 int pointed_size(int t)
4071 return type_size(pointed_type(t), &t);
4074 #if 0
4075 void check_pointer_types(SValue *p1, SValue *p2)
4077 char buf1[256], buf2[256];
4078 int t1, t2;
4079 t1 = p1->t;
4080 t2 = p2->t;
4081 if (!is_compatible_types(t1, t2)) {
4082 type_to_str(buf1, sizeof(buf1), t1, NULL);
4083 type_to_str(buf2, sizeof(buf2), t2, NULL);
4084 error("incompatible pointers '%s' and '%s'", buf1, buf2);
4087 #endif
4089 /* generic gen_op: handles types problems */
4090 void gen_op(int op)
4092 int u, t1, t2, bt1, bt2, t;
4094 t1 = vtop[-1].t;
4095 t2 = vtop[0].t;
4096 bt1 = t1 & VT_BTYPE;
4097 bt2 = t2 & VT_BTYPE;
4099 if (bt1 == VT_PTR || bt2 == VT_PTR) {
4100 /* at least one operand is a pointer */
4101 /* relationnal op: must be both pointers */
4102 if (op >= TOK_ULT && op <= TOK_GT) {
4103 // check_pointer_types(vtop, vtop - 1);
4104 /* pointers are handled are unsigned */
4105 t = VT_INT | VT_UNSIGNED;
4106 goto std_op;
4108 /* if both pointers, then it must be the '-' op */
4109 if ((t1 & VT_BTYPE) == VT_PTR &&
4110 (t2 & VT_BTYPE) == VT_PTR) {
4111 if (op != '-')
4112 error("cannot use pointers here");
4113 // check_pointer_types(vtop - 1, vtop);
4114 /* XXX: check that types are compatible */
4115 u = pointed_size(t1);
4116 gen_opic(op);
4117 /* set to integer type */
4118 vtop->t = VT_INT;
4119 vpushi(u);
4120 gen_op(TOK_PDIV);
4121 } else {
4122 /* exactly one pointer : must be '+' or '-'. */
4123 if (op != '-' && op != '+')
4124 error("cannot use pointers here");
4125 /* Put pointer as first operand */
4126 if ((t2 & VT_BTYPE) == VT_PTR) {
4127 vswap();
4128 swap(&t1, &t2);
4130 /* XXX: cast to int ? (long long case) */
4131 vpushi(pointed_size(vtop[-1].t));
4132 gen_op('*');
4133 #ifdef CONFIG_TCC_BCHECK
4134 /* if evaluating constant expression, no code should be
4135 generated, so no bound check */
4136 if (do_bounds_check && !const_wanted) {
4137 /* if bounded pointers, we generate a special code to
4138 test bounds */
4139 if (op == '-') {
4140 vpushi(0);
4141 vswap();
4142 gen_op('-');
4144 gen_bounded_ptr_add();
4145 } else
4146 #endif
4148 gen_opic(op);
4150 /* put again type if gen_opic() swaped operands */
4151 vtop->t = t1;
4153 } else if (is_float(bt1) || is_float(bt2)) {
4154 /* compute bigger type and do implicit casts */
4155 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4156 t = VT_LDOUBLE;
4157 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4158 t = VT_DOUBLE;
4159 } else {
4160 t = VT_FLOAT;
4162 /* floats can only be used for a few operations */
4163 if (op != '+' && op != '-' && op != '*' && op != '/' &&
4164 (op < TOK_ULT || op > TOK_GT))
4165 error("invalid operands for binary operation");
4166 goto std_op;
4167 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4168 /* cast to biggest op */
4169 t = VT_LLONG;
4170 /* convert to unsigned if it does not fit in a long long */
4171 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4172 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4173 t |= VT_UNSIGNED;
4174 goto std_op;
4175 } else {
4176 /* integer operations */
4177 t = VT_INT;
4178 /* convert to unsigned if it does not fit in an integer */
4179 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4180 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4181 t |= VT_UNSIGNED;
4182 std_op:
4183 /* XXX: currently, some unsigned operations are explicit, so
4184 we modify them here */
4185 if (t & VT_UNSIGNED) {
4186 if (op == TOK_SAR)
4187 op = TOK_SHR;
4188 else if (op == '/')
4189 op = TOK_UDIV;
4190 else if (op == '%')
4191 op = TOK_UMOD;
4192 else if (op == TOK_LT)
4193 op = TOK_ULT;
4194 else if (op == TOK_GT)
4195 op = TOK_UGT;
4196 else if (op == TOK_LE)
4197 op = TOK_ULE;
4198 else if (op == TOK_GE)
4199 op = TOK_UGE;
4201 vswap();
4202 gen_cast(t);
4203 vswap();
4204 /* special case for shifts and long long: we keep the shift as
4205 an integer */
4206 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
4207 gen_cast(VT_INT);
4208 else
4209 gen_cast(t);
4210 if (is_float(t))
4211 gen_opif(op);
4212 else if ((t & VT_BTYPE) == VT_LLONG)
4213 gen_opl(op);
4214 else
4215 gen_opic(op);
4216 if (op >= TOK_ULT && op <= TOK_GT) {
4217 /* relationnal op: the result is an int */
4218 vtop->t = VT_INT;
4219 } else {
4220 vtop->t = t;
4225 /* generic itof for unsigned long long case */
4226 void gen_cvt_itof1(int t)
4228 GFuncContext gf;
4230 if ((vtop->t & (VT_BTYPE | VT_UNSIGNED)) ==
4231 (VT_LLONG | VT_UNSIGNED)) {
4233 gfunc_start(&gf, FUNC_CDECL);
4234 gfunc_param(&gf);
4235 if (t == VT_FLOAT)
4236 vpush_global_sym(func_old_type, TOK___ulltof);
4237 else if (t == VT_DOUBLE)
4238 vpush_global_sym(func_old_type, TOK___ulltod);
4239 else
4240 vpush_global_sym(func_old_type, TOK___ulltold);
4241 gfunc_call(&gf);
4242 vpushi(0);
4243 vtop->r = REG_FRET;
4244 } else {
4245 gen_cvt_itof(t);
4249 /* generic ftoi for unsigned long long case */
4250 void gen_cvt_ftoi1(int t)
4252 GFuncContext gf;
4253 int st;
4255 if (t == (VT_LLONG | VT_UNSIGNED)) {
4256 /* not handled natively */
4257 gfunc_start(&gf, FUNC_CDECL);
4258 st = vtop->t & VT_BTYPE;
4259 gfunc_param(&gf);
4260 if (st == VT_FLOAT)
4261 vpush_global_sym(func_old_type, TOK___fixunssfdi);
4262 else if (st == VT_DOUBLE)
4263 vpush_global_sym(func_old_type, TOK___fixunsdfdi);
4264 else
4265 vpush_global_sym(func_old_type, TOK___fixunsxfdi);
4266 gfunc_call(&gf);
4267 vpushi(0);
4268 vtop->r = REG_IRET;
4269 vtop->r2 = REG_LRET;
4270 } else {
4271 gen_cvt_ftoi(t);
4275 /* force char or short cast */
4276 void force_charshort_cast(int t)
4278 int bits, dbt;
4279 dbt = t & VT_BTYPE;
4280 /* XXX: add optimization if lvalue : just change type and offset */
4281 if (dbt == VT_BYTE)
4282 bits = 8;
4283 else
4284 bits = 16;
4285 if (t & VT_UNSIGNED) {
4286 vpushi((1 << bits) - 1);
4287 gen_op('&');
4288 } else {
4289 bits = 32 - bits;
4290 vpushi(bits);
4291 gen_op(TOK_SHL);
4292 vpushi(bits);
4293 gen_op(TOK_SAR);
4297 /* cast 'vtop' to 't' type */
4298 void gen_cast(int t)
4300 int sbt, dbt, sf, df, c;
4302 /* special delayed cast for char/short */
4303 /* XXX: in some cases (multiple cascaded casts), it may still
4304 be incorrect */
4305 if (vtop->r & VT_MUSTCAST) {
4306 vtop->r &= ~VT_MUSTCAST;
4307 force_charshort_cast(vtop->t);
4310 dbt = t & (VT_BTYPE | VT_UNSIGNED);
4311 sbt = vtop->t & (VT_BTYPE | VT_UNSIGNED);
4313 if (sbt != dbt && !nocode_wanted) {
4314 sf = is_float(sbt);
4315 df = is_float(dbt);
4316 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4317 if (sf && df) {
4318 /* convert from fp to fp */
4319 if (c) {
4320 /* constant case: we can do it now */
4321 /* XXX: in ISOC, cannot do it if error in convert */
4322 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
4323 vtop->c.f = (float)vtop->c.d;
4324 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
4325 vtop->c.f = (float)vtop->c.ld;
4326 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
4327 vtop->c.d = (double)vtop->c.f;
4328 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
4329 vtop->c.d = (double)vtop->c.ld;
4330 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
4331 vtop->c.ld = (long double)vtop->c.f;
4332 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
4333 vtop->c.ld = (long double)vtop->c.d;
4334 } else {
4335 /* non constant case: generate code */
4336 gen_cvt_ftof(dbt);
4338 } else if (df) {
4339 /* convert int to fp */
4340 if (c) {
4341 switch(sbt) {
4342 case VT_LLONG | VT_UNSIGNED:
4343 case VT_LLONG:
4344 /* XXX: add const cases for long long */
4345 goto do_itof;
4346 case VT_INT | VT_UNSIGNED:
4347 switch(dbt) {
4348 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
4349 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
4350 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
4352 break;
4353 default:
4354 switch(dbt) {
4355 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
4356 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
4357 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
4359 break;
4361 } else {
4362 do_itof:
4363 gen_cvt_itof1(dbt);
4365 } else if (sf) {
4366 /* convert fp to int */
4367 /* we handle char/short/etc... with generic code */
4368 if (dbt != (VT_INT | VT_UNSIGNED) &&
4369 dbt != (VT_LLONG | VT_UNSIGNED) &&
4370 dbt != VT_LLONG)
4371 dbt = VT_INT;
4372 if (c) {
4373 switch(dbt) {
4374 case VT_LLONG | VT_UNSIGNED:
4375 case VT_LLONG:
4376 /* XXX: add const cases for long long */
4377 goto do_ftoi;
4378 case VT_INT | VT_UNSIGNED:
4379 switch(sbt) {
4380 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
4381 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4382 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4384 break;
4385 default:
4386 /* int case */
4387 switch(sbt) {
4388 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
4389 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
4390 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
4392 break;
4394 } else {
4395 do_ftoi:
4396 gen_cvt_ftoi1(dbt);
4398 if (dbt == VT_INT && (t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
4399 /* additionnal cast for char/short/bool... */
4400 vtop->t = dbt;
4401 gen_cast(t);
4403 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
4404 if ((sbt & VT_BTYPE) != VT_LLONG) {
4405 /* scalar to long long */
4406 if (c) {
4407 if (sbt == (VT_INT | VT_UNSIGNED))
4408 vtop->c.ll = vtop->c.ui;
4409 else
4410 vtop->c.ll = vtop->c.i;
4411 } else {
4412 /* machine independant conversion */
4413 gv(RC_INT);
4414 /* generate high word */
4415 if (sbt == (VT_INT | VT_UNSIGNED)) {
4416 vpushi(0);
4417 gv(RC_INT);
4418 } else {
4419 gv_dup();
4420 vpushi(31);
4421 gen_op(TOK_SAR);
4423 /* patch second register */
4424 vtop[-1].r2 = vtop->r;
4425 vpop();
4428 } else if (dbt == VT_BOOL) {
4429 /* scalar to bool */
4430 vpushi(0);
4431 gen_op(TOK_NE);
4432 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
4433 (dbt & VT_BTYPE) == VT_SHORT) {
4434 force_charshort_cast(t);
4435 } else if ((dbt & VT_BTYPE) == VT_INT) {
4436 /* scalar to int */
4437 if (sbt == VT_LLONG) {
4438 /* from long long: just take low order word */
4439 lexpand();
4440 vpop();
4442 /* if lvalue and single word type, nothing to do because
4443 the lvalue already contains the real type size (see
4444 VT_LVAL_xxx constants) */
4447 vtop->t = t;
4450 /* return type size. Put alignment at 'a' */
4451 int type_size(int t, int *a)
4453 Sym *s;
4454 int bt;
4456 bt = t & VT_BTYPE;
4457 if (bt == VT_STRUCT) {
4458 /* struct/union */
4459 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4460 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
4461 return s->c;
4462 } else if (bt == VT_PTR) {
4463 if (t & VT_ARRAY) {
4464 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4465 return type_size(s->t, a) * s->c;
4466 } else {
4467 *a = PTR_SIZE;
4468 return PTR_SIZE;
4470 } else if (bt == VT_LDOUBLE) {
4471 *a = LDOUBLE_ALIGN;
4472 return LDOUBLE_SIZE;
4473 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
4474 *a = 8;
4475 return 8;
4476 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
4477 *a = 4;
4478 return 4;
4479 } else if (bt == VT_SHORT) {
4480 *a = 2;
4481 return 2;
4482 } else {
4483 /* char, void, function, _Bool */
4484 *a = 1;
4485 return 1;
4489 /* return the pointed type of t */
4490 int pointed_type(int t)
4492 Sym *s;
4493 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4494 return s->t | (t & ~VT_TYPE);
4497 int mk_pointer(int t)
4499 int p;
4500 p = anon_sym++;
4501 sym_push(p, t, 0, -1);
4502 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
4505 int is_compatible_types(int t1, int t2)
4507 Sym *s1, *s2;
4508 int bt1, bt2;
4510 t1 &= VT_TYPE;
4511 t2 &= VT_TYPE;
4512 bt1 = t1 & VT_BTYPE;
4513 bt2 = t2 & VT_BTYPE;
4514 if (bt1 == VT_PTR) {
4515 t1 = pointed_type(t1);
4516 /* if function, then convert implicitely to function pointer */
4517 if (bt2 != VT_FUNC) {
4518 if (bt2 != VT_PTR)
4519 return 0;
4520 t2 = pointed_type(t2);
4522 /* void matches everything */
4523 t1 &= VT_TYPE;
4524 t2 &= VT_TYPE;
4525 if (t1 == VT_VOID || t2 == VT_VOID)
4526 return 1;
4527 return is_compatible_types(t1, t2);
4528 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4529 return (t2 == t1);
4530 } else if (bt1 == VT_FUNC) {
4531 if (bt2 != VT_FUNC)
4532 return 0;
4533 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
4534 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
4535 if (!is_compatible_types(s1->t, s2->t))
4536 return 0;
4537 /* XXX: not complete */
4538 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
4539 return 1;
4540 if (s1->c != s2->c)
4541 return 0;
4542 while (s1 != NULL) {
4543 if (s2 == NULL)
4544 return 0;
4545 if (!is_compatible_types(s1->t, s2->t))
4546 return 0;
4547 s1 = s1->next;
4548 s2 = s2->next;
4550 if (s2)
4551 return 0;
4552 return 1;
4553 } else {
4554 /* XXX: not complete */
4555 return 1;
4559 /* print a type. If 'varstr' is not NULL, then the variable is also
4560 printed in the type */
4561 /* XXX: union */
4562 /* XXX: add array and function pointers */
4563 void type_to_str(char *buf, int buf_size,
4564 int t, const char *varstr)
4566 int bt, v;
4567 Sym *s, *sa;
4568 char buf1[256];
4569 const char *tstr;
4571 t = t & VT_TYPE;
4572 bt = t & VT_BTYPE;
4573 buf[0] = '\0';
4574 if (t & VT_UNSIGNED)
4575 pstrcat(buf, buf_size, "unsigned ");
4576 switch(bt) {
4577 case VT_VOID:
4578 tstr = "void";
4579 goto add_tstr;
4580 case VT_BOOL:
4581 tstr = "_Bool";
4582 goto add_tstr;
4583 case VT_BYTE:
4584 tstr = "char";
4585 goto add_tstr;
4586 case VT_SHORT:
4587 tstr = "short";
4588 goto add_tstr;
4589 case VT_INT:
4590 tstr = "int";
4591 goto add_tstr;
4592 case VT_LONG:
4593 tstr = "long";
4594 goto add_tstr;
4595 case VT_LLONG:
4596 tstr = "long long";
4597 goto add_tstr;
4598 case VT_FLOAT:
4599 tstr = "float";
4600 goto add_tstr;
4601 case VT_DOUBLE:
4602 tstr = "double";
4603 goto add_tstr;
4604 case VT_LDOUBLE:
4605 tstr = "long double";
4606 add_tstr:
4607 pstrcat(buf, buf_size, tstr);
4608 break;
4609 case VT_ENUM:
4610 case VT_STRUCT:
4611 if (bt == VT_STRUCT)
4612 tstr = "struct ";
4613 else
4614 tstr = "enum ";
4615 pstrcat(buf, buf_size, tstr);
4616 v = (unsigned)t >> VT_STRUCT_SHIFT;
4617 if (v >= SYM_FIRST_ANOM)
4618 pstrcat(buf, buf_size, "<anonymous>");
4619 else
4620 pstrcat(buf, buf_size, get_tok_str(v, NULL));
4621 break;
4622 case VT_FUNC:
4623 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4624 type_to_str(buf, buf_size, s->t, varstr);
4625 pstrcat(buf, buf_size, "(");
4626 sa = s->next;
4627 while (sa != NULL) {
4628 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
4629 pstrcat(buf, buf_size, buf1);
4630 sa = sa->next;
4631 if (sa)
4632 pstrcat(buf, buf_size, ", ");
4634 pstrcat(buf, buf_size, ")");
4635 goto no_var;
4636 case VT_PTR:
4637 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4638 pstrcpy(buf1, sizeof(buf1), "*");
4639 if (varstr)
4640 pstrcat(buf1, sizeof(buf1), varstr);
4641 type_to_str(buf, buf_size, s->t, buf1);
4642 goto no_var;
4644 if (varstr) {
4645 pstrcat(buf, buf_size, " ");
4646 pstrcat(buf, buf_size, varstr);
4648 no_var: ;
4651 /* verify type compatibility to store vtop in 'dt' type, and generate
4652 casts if needed. */
4653 void gen_assign_cast(int dt)
4655 int st;
4656 char buf1[256], buf2[256];
4658 st = vtop->t; /* source type */
4659 if ((dt & VT_BTYPE) == VT_PTR) {
4660 /* special cases for pointers */
4661 /* a function is implicitely a function pointer */
4662 if ((st & VT_BTYPE) == VT_FUNC) {
4663 if (!is_compatible_types(pointed_type(dt), st))
4664 goto error;
4665 else
4666 goto type_ok;
4668 /* '0' can also be a pointer */
4669 if ((st & VT_BTYPE) == VT_INT &&
4670 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
4671 vtop->c.i == 0)
4672 goto type_ok;
4674 if (!is_compatible_types(dt, st)) {
4675 error:
4676 type_to_str(buf1, sizeof(buf1), st, NULL);
4677 type_to_str(buf2, sizeof(buf2), dt, NULL);
4678 error("cannot cast '%s' to '%s'", buf1, buf2);
4680 type_ok:
4681 gen_cast(dt);
4684 /* store vtop in lvalue pushed on stack */
4685 void vstore(void)
4687 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
4688 GFuncContext gf;
4690 ft = vtop[-1].t;
4691 sbt = vtop->t & VT_BTYPE;
4692 dbt = ft & VT_BTYPE;
4693 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
4694 (sbt == VT_INT && dbt == VT_SHORT)) {
4695 /* optimize char/short casts */
4696 delayed_cast = VT_MUSTCAST;
4697 vtop->t = ft & VT_TYPE;
4698 } else {
4699 delayed_cast = 0;
4700 gen_assign_cast(ft & VT_TYPE);
4703 if (sbt == VT_STRUCT) {
4704 /* if structure, only generate pointer */
4705 /* structure assignment : generate memcpy */
4706 /* XXX: optimize if small size */
4707 if (!nocode_wanted) {
4708 vdup();
4709 gfunc_start(&gf, FUNC_CDECL);
4710 /* type size */
4711 size = type_size(vtop->t, &align);
4712 vpushi(size);
4713 gfunc_param(&gf);
4714 /* source */
4715 vtop->t = VT_INT;
4716 gaddrof();
4717 gfunc_param(&gf);
4718 /* destination */
4719 vswap();
4720 vtop->t = VT_INT;
4721 gaddrof();
4722 gfunc_param(&gf);
4724 save_regs(0);
4725 vpush_global_sym(func_old_type, TOK_memcpy);
4726 gfunc_call(&gf);
4727 } else {
4728 vswap();
4729 vpop();
4731 /* leave source on stack */
4732 } else if (ft & VT_BITFIELD) {
4733 /* bitfield store handling */
4734 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
4735 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4736 /* remove bit field info to avoid loops */
4737 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4739 /* duplicate destination */
4740 vdup();
4741 vtop[-1] = vtop[-2];
4743 /* mask and shift source */
4744 vpushi((1 << bit_size) - 1);
4745 gen_op('&');
4746 vpushi(bit_pos);
4747 gen_op(TOK_SHL);
4748 /* load destination, mask and or with source */
4749 vswap();
4750 vpushi(~(((1 << bit_size) - 1) << bit_pos));
4751 gen_op('&');
4752 gen_op('|');
4753 /* store result */
4754 vstore();
4755 } else {
4756 #ifdef CONFIG_TCC_BCHECK
4757 /* bound check case */
4758 if (vtop[-1].r & VT_MUSTBOUND) {
4759 vswap();
4760 gbound();
4761 vswap();
4763 #endif
4764 if (!nocode_wanted) {
4765 rc = RC_INT;
4766 if (is_float(ft))
4767 rc = RC_FLOAT;
4768 r = gv(rc); /* generate value */
4769 /* if lvalue was saved on stack, must read it */
4770 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
4771 SValue sv;
4772 t = get_reg(RC_INT);
4773 sv.t = VT_INT;
4774 sv.r = VT_LOCAL | VT_LVAL;
4775 sv.c.ul = vtop[-1].c.ul;
4776 load(t, &sv);
4777 vtop[-1].r = t | VT_LVAL;
4779 store(r, vtop - 1);
4780 /* two word case handling : store second register at word + 4 */
4781 if ((ft & VT_BTYPE) == VT_LLONG) {
4782 vswap();
4783 /* convert to int to increment easily */
4784 vtop->t = VT_INT;
4785 gaddrof();
4786 vpushi(4);
4787 gen_op('+');
4788 vtop->r |= VT_LVAL;
4789 vswap();
4790 /* XXX: it works because r2 is spilled last ! */
4791 store(vtop->r2, vtop - 1);
4794 vswap();
4795 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4796 vtop->r |= delayed_cast;
4800 /* post defines POST/PRE add. c is the token ++ or -- */
4801 void inc(int post, int c)
4803 test_lvalue();
4804 vdup(); /* save lvalue */
4805 if (post) {
4806 gv_dup(); /* duplicate value */
4807 vrotb(3);
4808 vrotb(3);
4810 /* add constant */
4811 vpushi(c - TOK_MID);
4812 gen_op('+');
4813 vstore(); /* store value */
4814 if (post)
4815 vpop(); /* if post op, return saved value */
4818 /* Parse GNUC __attribute__ extension. Currently, the following
4819 extensions are recognized:
4820 - aligned(n) : set data/function alignment.
4821 - section(x) : generate data/code in this section.
4822 - unused : currently ignored, but may be used someday.
4824 void parse_attribute(AttributeDef *ad)
4826 int t, n;
4828 next();
4829 skip('(');
4830 skip('(');
4831 while (tok != ')') {
4832 if (tok < TOK_IDENT)
4833 expect("attribute name");
4834 t = tok;
4835 next();
4836 switch(t) {
4837 case TOK_SECTION:
4838 case TOK___SECTION__:
4839 skip('(');
4840 if (tok != TOK_STR)
4841 expect("section name");
4842 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
4843 next();
4844 skip(')');
4845 break;
4846 case TOK_ALIGNED:
4847 case TOK___ALIGNED__:
4848 skip('(');
4849 n = expr_const();
4850 if (n <= 0 || (n & (n - 1)) != 0)
4851 error("alignment must be a positive power of two");
4852 ad->aligned = n;
4853 skip(')');
4854 break;
4855 case TOK_UNUSED:
4856 case TOK___UNUSED__:
4857 /* currently, no need to handle it because tcc does not
4858 track unused objects */
4859 break;
4860 case TOK_NORETURN:
4861 case TOK___NORETURN__:
4862 /* currently, no need to handle it because tcc does not
4863 track unused objects */
4864 break;
4865 case TOK_CDECL:
4866 case TOK___CDECL:
4867 case TOK___CDECL__:
4868 ad->func_call = FUNC_CDECL;
4869 break;
4870 case TOK_STDCALL:
4871 case TOK___STDCALL:
4872 case TOK___STDCALL__:
4873 ad->func_call = FUNC_STDCALL;
4874 break;
4875 default:
4876 warning("'%s' attribute ignored", get_tok_str(t, NULL));
4877 /* skip parameters */
4878 /* XXX: skip parenthesis too */
4879 if (tok == '(') {
4880 next();
4881 while (tok != ')' && tok != -1)
4882 next();
4883 next();
4885 break;
4887 if (tok != ',')
4888 break;
4889 next();
4891 skip(')');
4892 skip(')');
4895 /* enum/struct/union declaration */
4896 int struct_decl(int u)
4898 int a, t, b, v, size, align, maxalign, c, offset;
4899 int bit_size, bit_pos, bsize, bt, lbit_pos;
4900 Sym *s, *ss, **ps;
4901 AttributeDef ad;
4903 a = tok; /* save decl type */
4904 next();
4905 if (tok != '{') {
4906 v = tok;
4907 next();
4908 /* struct already defined ? return it */
4909 /* XXX: check consistency */
4910 s = sym_find(v | SYM_STRUCT);
4911 if (s) {
4912 if (s->t != a)
4913 error("invalid type");
4914 goto do_decl;
4916 } else {
4917 v = anon_sym++;
4919 s = sym_push(v | SYM_STRUCT, a, 0, 0);
4920 /* put struct/union/enum name in type */
4921 do_decl:
4922 u = u | (v << VT_STRUCT_SHIFT);
4924 if (tok == '{') {
4925 next();
4926 if (s->c)
4927 error("struct/union/enum already defined");
4928 /* cannot be empty */
4929 c = 0;
4930 maxalign = 0;
4931 ps = &s->next;
4932 bit_pos = 0;
4933 offset = 0;
4934 while (1) {
4935 if (a == TOK_ENUM) {
4936 v = tok;
4937 next();
4938 if (tok == '=') {
4939 next();
4940 c = expr_const();
4942 /* enum symbols have static storage */
4943 sym_push(v, VT_STATIC | VT_INT, VT_CONST, c);
4944 if (tok == ',')
4945 next();
4946 c++;
4947 } else {
4948 parse_btype(&b, &ad);
4949 while (1) {
4950 bit_size = -1;
4951 v = 0;
4952 if (tok != ':') {
4953 t = type_decl(&ad, &v, b, TYPE_DIRECT);
4954 if ((t & VT_BTYPE) == VT_FUNC ||
4955 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
4956 error("invalid type for '%s'",
4957 get_tok_str(v, NULL));
4958 } else {
4959 t = b;
4961 if (tok == ':') {
4962 next();
4963 bit_size = expr_const();
4964 /* XXX: handle v = 0 case for messages */
4965 if (bit_size < 0)
4966 error("negative width in bit-field '%s'",
4967 get_tok_str(v, NULL));
4968 if (v && bit_size == 0)
4969 error("zero width for bit-field '%s'",
4970 get_tok_str(v, NULL));
4972 size = type_size(t, &align);
4973 lbit_pos = 0;
4974 if (bit_size >= 0) {
4975 bt = t & VT_BTYPE;
4976 if (bt != VT_INT &&
4977 bt != VT_BYTE &&
4978 bt != VT_SHORT)
4979 error("bitfields must have scalar type");
4980 bsize = size * 8;
4981 if (bit_size > bsize) {
4982 error("width of '%s' exceeds its type",
4983 get_tok_str(v, NULL));
4984 } else if (bit_size == bsize) {
4985 /* no need for bit fields */
4986 bit_pos = 0;
4987 } else if (bit_size == 0) {
4988 /* XXX: what to do if only padding in a
4989 structure ? */
4990 /* zero size: means to pad */
4991 if (bit_pos > 0)
4992 bit_pos = bsize;
4993 } else {
4994 /* we do not have enough room ? */
4995 if ((bit_pos + bit_size) > bsize)
4996 bit_pos = 0;
4997 lbit_pos = bit_pos;
4998 /* XXX: handle LSB first */
4999 t |= VT_BITFIELD |
5000 (bit_pos << VT_STRUCT_SHIFT) |
5001 (bit_size << (VT_STRUCT_SHIFT + 6));
5002 bit_pos += bit_size;
5004 } else {
5005 bit_pos = 0;
5007 if (v) {
5008 /* add new memory data only if starting
5009 bit field */
5010 if (lbit_pos == 0) {
5011 if (a == TOK_STRUCT) {
5012 c = (c + align - 1) & -align;
5013 offset = c;
5014 c += size;
5015 } else {
5016 offset = 0;
5017 if (size > c)
5018 c = size;
5020 if (align > maxalign)
5021 maxalign = align;
5023 #if 0
5024 printf("add field %s offset=%d",
5025 get_tok_str(v, NULL), offset);
5026 if (t & VT_BITFIELD) {
5027 printf(" pos=%d size=%d",
5028 (t >> VT_STRUCT_SHIFT) & 0x3f,
5029 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
5031 printf("\n");
5032 #endif
5033 ss = sym_push(v | SYM_FIELD, t, 0, offset);
5034 *ps = ss;
5035 ps = &ss->next;
5037 if (tok == ';' || tok == -1)
5038 break;
5039 skip(',');
5041 skip(';');
5043 if (tok == '}')
5044 break;
5046 skip('}');
5047 /* size for struct/union, dummy for enum */
5048 s->c = (c + maxalign - 1) & -maxalign;
5050 return u;
5053 /* return 0 if no type declaration. otherwise, return the basic type
5054 and skip it.
5056 int parse_btype(int *type_ptr, AttributeDef *ad)
5058 int t, u, type_found;
5059 Sym *s;
5061 memset(ad, 0, sizeof(AttributeDef));
5062 type_found = 0;
5063 t = 0;
5064 while(1) {
5065 switch(tok) {
5066 /* basic types */
5067 case TOK_CHAR:
5068 u = VT_BYTE;
5069 basic_type:
5070 next();
5071 basic_type1:
5072 if ((t & VT_BTYPE) != 0)
5073 error("too many basic types");
5074 t |= u;
5075 break;
5076 case TOK_VOID:
5077 u = VT_VOID;
5078 goto basic_type;
5079 case TOK_SHORT:
5080 u = VT_SHORT;
5081 goto basic_type;
5082 case TOK_INT:
5083 next();
5084 break;
5085 case TOK_LONG:
5086 next();
5087 if ((t & VT_BTYPE) == VT_DOUBLE) {
5088 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5089 } else if ((t & VT_BTYPE) == VT_LONG) {
5090 t = (t & ~VT_BTYPE) | VT_LLONG;
5091 } else {
5092 u = VT_LONG;
5093 goto basic_type1;
5095 break;
5096 case TOK_BOOL:
5097 u = VT_BOOL;
5098 goto basic_type;
5099 case TOK_FLOAT:
5100 u = VT_FLOAT;
5101 goto basic_type;
5102 case TOK_DOUBLE:
5103 next();
5104 if ((t & VT_BTYPE) == VT_LONG) {
5105 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5106 } else {
5107 u = VT_DOUBLE;
5108 goto basic_type1;
5110 break;
5111 case TOK_ENUM:
5112 u = struct_decl(VT_ENUM);
5113 goto basic_type1;
5114 case TOK_STRUCT:
5115 case TOK_UNION:
5116 u = struct_decl(VT_STRUCT);
5117 goto basic_type1;
5119 /* type modifiers */
5120 case TOK_CONST:
5121 case TOK_VOLATILE:
5122 case TOK_REGISTER:
5123 case TOK_SIGNED:
5124 case TOK___SIGNED__:
5125 case TOK_AUTO:
5126 case TOK_INLINE:
5127 case TOK___INLINE__:
5128 case TOK_RESTRICT:
5129 next();
5130 break;
5131 case TOK_UNSIGNED:
5132 t |= VT_UNSIGNED;
5133 next();
5134 break;
5136 /* storage */
5137 case TOK_EXTERN:
5138 t |= VT_EXTERN;
5139 next();
5140 break;
5141 case TOK_STATIC:
5142 t |= VT_STATIC;
5143 next();
5144 break;
5145 case TOK_TYPEDEF:
5146 t |= VT_TYPEDEF;
5147 next();
5148 break;
5149 /* GNUC attribute */
5150 case TOK___ATTRIBUTE__:
5151 parse_attribute(ad);
5152 break;
5153 /* GNUC typeof */
5154 case TOK_TYPEOF:
5155 next();
5156 u = parse_expr_type();
5157 goto basic_type1;
5158 default:
5159 s = sym_find(tok);
5160 if (!s || !(s->t & VT_TYPEDEF))
5161 goto the_end;
5162 t |= (s->t & ~VT_TYPEDEF);
5163 next();
5164 break;
5166 type_found = 1;
5168 the_end:
5169 /* long is never used as type */
5170 if ((t & VT_BTYPE) == VT_LONG)
5171 t = (t & ~VT_BTYPE) | VT_INT;
5172 *type_ptr = t;
5173 return type_found;
5176 int post_type(int t, AttributeDef *ad)
5178 int p, n, pt, l, t1;
5179 Sym **plast, *s, *first;
5180 AttributeDef ad1;
5182 if (tok == '(') {
5183 /* function declaration */
5184 next();
5185 l = 0;
5186 first = NULL;
5187 plast = &first;
5188 while (tok != ')') {
5189 /* read param name and compute offset */
5190 if (l != FUNC_OLD) {
5191 if (!parse_btype(&pt, &ad1)) {
5192 if (l) {
5193 error("invalid type");
5194 } else {
5195 l = FUNC_OLD;
5196 goto old_proto;
5199 l = FUNC_NEW;
5200 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
5201 break;
5202 pt = type_decl(&ad1, &n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
5203 if ((pt & VT_BTYPE) == VT_VOID)
5204 error("parameter declared as void");
5205 } else {
5206 old_proto:
5207 n = tok;
5208 pt = VT_INT;
5209 next();
5211 /* array must be transformed to pointer according to ANSI C */
5212 pt &= ~VT_ARRAY;
5213 s = sym_push(n | SYM_FIELD, pt, 0, 0);
5214 *plast = s;
5215 plast = &s->next;
5216 if (tok == ',') {
5217 next();
5218 if (l == FUNC_NEW && tok == TOK_DOTS) {
5219 l = FUNC_ELLIPSIS;
5220 next();
5221 break;
5225 /* if no parameters, then old type prototype */
5226 if (l == 0)
5227 l = FUNC_OLD;
5228 skip(')');
5229 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5230 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
5231 /* we push a anonymous symbol which will contain the function prototype */
5232 p = anon_sym++;
5233 s = sym_push(p, t, ad->func_call, l);
5234 s->next = first;
5235 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
5236 } else if (tok == '[') {
5237 /* array definition */
5238 next();
5239 n = -1;
5240 if (tok != ']') {
5241 n = expr_const();
5242 if (n < 0)
5243 error("invalid array size");
5245 skip(']');
5246 /* parse next post type */
5247 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5248 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
5250 /* we push a anonymous symbol which will contain the array
5251 element type */
5252 p = anon_sym++;
5253 sym_push(p, t, 0, n);
5254 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
5256 return t;
5259 /* Read a type declaration (except basic type), and return the
5260 type. 'td' is a bitmask indicating which kind of type decl is
5261 expected. 't' should contain the basic type. 'ad' is the attribute
5262 definition of the basic type. It can be modified by type_decl(). */
5263 int type_decl(AttributeDef *ad, int *v, int t, int td)
5265 int u, p;
5266 Sym *s;
5268 while (tok == '*') {
5269 next();
5270 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
5271 next();
5272 t = mk_pointer(t);
5275 /* recursive type */
5276 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5277 if (tok == '(') {
5278 next();
5279 /* XXX: this is not correct to modify 'ad' at this point, but
5280 the syntax is not clear */
5281 if (tok == TOK___ATTRIBUTE__)
5282 parse_attribute(ad);
5283 u = type_decl(ad, v, 0, td);
5284 skip(')');
5285 } else {
5286 u = 0;
5287 /* type identifier */
5288 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
5289 *v = tok;
5290 next();
5291 } else {
5292 if (!(td & TYPE_ABSTRACT))
5293 expect("identifier");
5294 *v = 0;
5297 /* append t at the end of u */
5298 t = post_type(t, ad);
5299 if (tok == TOK___ATTRIBUTE__)
5300 parse_attribute(ad);
5301 if (!u)
5302 return t;
5303 p = u;
5304 while(1) {
5305 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
5306 p = s->t;
5307 if (!p) {
5308 s->t = t;
5309 break;
5312 return u;
5315 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5316 static int lvalue_type(int t)
5318 int bt, r;
5319 r = VT_LVAL;
5320 bt = t & VT_BTYPE;
5321 if (bt == VT_BYTE)
5322 r |= VT_LVAL_BYTE;
5323 else if (bt == VT_SHORT)
5324 r |= VT_LVAL_SHORT;
5325 else
5326 return r;
5327 if (t & VT_UNSIGNED)
5328 r |= VT_LVAL_UNSIGNED;
5329 return r;
5332 /* indirection with full error checking and bound check */
5333 static void indir(void)
5335 if ((vtop->t & VT_BTYPE) != VT_PTR)
5336 expect("pointer");
5337 if ((vtop->r & VT_LVAL) && !nocode_wanted)
5338 gv(RC_INT);
5339 vtop->t = pointed_type(vtop->t);
5340 /* an array is never an lvalue */
5341 if (!(vtop->t & VT_ARRAY)) {
5342 vtop->r |= lvalue_type(vtop->t);
5343 /* if bound checking, the referenced pointer must be checked */
5344 if (do_bounds_check)
5345 vtop->r |= VT_MUSTBOUND;
5349 /* pass a parameter to a function and do type checking and casting */
5350 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
5352 int func_type;
5353 func_type = func->c;
5354 if (func_type == FUNC_OLD ||
5355 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
5356 /* default casting : only need to convert float to double */
5357 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
5358 gen_cast(VT_DOUBLE);
5359 } else if (arg == NULL) {
5360 error("too many arguments to function");
5361 } else {
5362 gen_assign_cast(arg->t);
5364 if (!nocode_wanted) {
5365 gfunc_param(gf);
5366 } else {
5367 vpop();
5371 /* parse an expression of the form '(type)' or '(expr)' and return its
5372 type */
5373 static int parse_expr_type(void)
5375 int ft, n;
5376 AttributeDef ad;
5378 skip('(');
5379 if (parse_btype(&ft, &ad)) {
5380 ft = type_decl(&ad, &n, ft, TYPE_ABSTRACT);
5381 } else {
5382 ft = expr_type();
5384 skip(')');
5385 return ft;
5388 static void unary(void)
5390 int n, t, ft, align, size, r;
5391 Sym *s;
5392 GFuncContext gf;
5393 AttributeDef ad;
5395 if (tok == TOK_CINT || tok == TOK_CCHAR || tok == TOK_LCHAR) {
5396 vpushi(tokc.i);
5397 next();
5398 } else if (tok == TOK_CUINT) {
5399 vsetc(VT_INT | VT_UNSIGNED, VT_CONST, &tokc);
5400 next();
5401 } else if (tok == TOK_CLLONG) {
5402 vsetc(VT_LLONG, VT_CONST, &tokc);
5403 next();
5404 } else if (tok == TOK_CULLONG) {
5405 vsetc(VT_LLONG | VT_UNSIGNED, VT_CONST, &tokc);
5406 next();
5407 } else if (tok == TOK_CFLOAT) {
5408 vsetc(VT_FLOAT, VT_CONST, &tokc);
5409 next();
5410 } else if (tok == TOK_CDOUBLE) {
5411 vsetc(VT_DOUBLE, VT_CONST, &tokc);
5412 next();
5413 } else if (tok == TOK_CLDOUBLE) {
5414 vsetc(VT_LDOUBLE, VT_CONST, &tokc);
5415 next();
5416 } else if (tok == TOK___FUNC__ || (tok == TOK___FUNCTION__ && gnu_ext)) {
5417 void *ptr;
5418 int len;
5419 /* special function name identifier */
5421 len = strlen(funcname) + 1;
5422 /* generate char[len] type */
5423 t = VT_ARRAY | mk_pointer(VT_BYTE);
5424 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5425 s->c = len;
5426 vpush_ref(t, data_section, data_section->data_offset, len);
5427 ptr = section_ptr_add(data_section, len);
5428 memcpy(ptr, funcname, len);
5429 next();
5430 } else if (tok == TOK_LSTR) {
5431 t = VT_INT;
5432 goto str_init;
5433 } else if (tok == TOK_STR) {
5434 /* string parsing */
5435 t = VT_BYTE;
5436 str_init:
5437 t = VT_ARRAY | mk_pointer(t);
5438 memset(&ad, 0, sizeof(AttributeDef));
5439 decl_initializer_alloc(t, &ad, VT_CONST, 2, 0, 0);
5440 } else {
5441 t = tok;
5442 next();
5443 if (t == '(') {
5444 /* cast ? */
5445 if (parse_btype(&t, &ad)) {
5446 ft = type_decl(&ad, &n, t, TYPE_ABSTRACT);
5447 skip(')');
5448 /* check ISOC99 compound literal */
5449 if (tok == '{') {
5450 /* data is allocated locally by default */
5451 if (global_expr)
5452 r = VT_CONST;
5453 else
5454 r = VT_LOCAL;
5455 /* all except arrays are lvalues */
5456 if (!(ft & VT_ARRAY))
5457 r |= lvalue_type(ft);
5458 memset(&ad, 0, sizeof(AttributeDef));
5459 decl_initializer_alloc(ft, &ad, r, 1, 0, 0);
5460 } else {
5461 unary();
5462 gen_cast(ft);
5464 } else {
5465 gexpr();
5466 skip(')');
5468 } else if (t == '*') {
5469 unary();
5470 indir();
5471 } else if (t == '&') {
5472 unary();
5473 /* functions names must be treated as function pointers,
5474 except for unary '&' and sizeof. Since we consider that
5475 functions are not lvalues, we only have to handle it
5476 there and in function calls. */
5477 /* arrays can also be used although they are not lvalues */
5478 if ((vtop->t & VT_BTYPE) != VT_FUNC &&
5479 !(vtop->t & VT_ARRAY))
5480 test_lvalue();
5481 vtop->t = mk_pointer(vtop->t);
5482 gaddrof();
5483 } else if (t == '!') {
5484 unary();
5485 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
5486 vtop->c.i = !vtop->c.i;
5487 else if ((vtop->r & VT_VALMASK) == VT_CMP)
5488 vtop->c.i = vtop->c.i ^ 1;
5489 else
5490 vset(VT_INT, VT_JMP, gtst(1, 0));
5491 } else if (t == '~') {
5492 unary();
5493 vpushi(-1);
5494 gen_op('^');
5495 } else if (t == '+') {
5496 /* in order to force cast, we add zero */
5497 unary();
5498 if ((vtop->t & VT_BTYPE) == VT_PTR)
5499 error("pointer not accepted for unary plus");
5500 vpushi(0);
5501 gen_op('+');
5502 } else if (t == TOK_SIZEOF || t == TOK_ALIGNOF) {
5503 if (tok == '(') {
5504 ft = parse_expr_type();
5505 } else {
5506 ft = unary_type();
5508 size = type_size(ft, &align);
5509 if (t == TOK_SIZEOF)
5510 vpushi(size);
5511 else
5512 vpushi(align);
5513 } else 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 if (t == TOK_LAND && gnu_ext) {
5521 /* allow to take the address of a label */
5522 if (tok < TOK_UIDENT)
5523 expect("label identifier");
5524 s = sym_find1(&label_stack, tok);
5525 if (!s) {
5526 s = sym_push1(&label_stack, tok, 0, 0);
5527 s->r = LABEL_FORWARD;
5529 if (!s->t)
5530 s->t = mk_pointer(VT_VOID) | VT_STATIC;
5531 vset(s->t, VT_CONST | VT_SYM, 0);
5532 vtop->sym = s;
5533 next();
5534 } else {
5535 if (t < TOK_UIDENT)
5536 expect("identifier");
5537 s = sym_find(t);
5538 if (!s) {
5539 if (tok != '(')
5540 error("'%s' undeclared", get_tok_str(t, NULL));
5541 /* for simple function calls, we tolerate undeclared
5542 external reference to int() function */
5543 s = external_global_sym(t, func_old_type, 0);
5545 vset(s->t, s->r, s->c);
5546 /* if forward reference, we must point to s */
5547 if (vtop->r & VT_SYM) {
5548 vtop->sym = s;
5549 vtop->c.ul = 0;
5554 /* post operations */
5555 while (1) {
5556 if (tok == TOK_INC || tok == TOK_DEC) {
5557 inc(1, tok);
5558 next();
5559 } else if (tok == '.' || tok == TOK_ARROW) {
5560 /* field */
5561 if (tok == TOK_ARROW)
5562 indir();
5563 test_lvalue();
5564 gaddrof();
5565 next();
5566 /* expect pointer on structure */
5567 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
5568 expect("struct or union");
5569 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5570 /* find field */
5571 tok |= SYM_FIELD;
5572 while ((s = s->next) != NULL) {
5573 if (s->v == tok)
5574 break;
5576 if (!s)
5577 error("field not found");
5578 /* add field offset to pointer */
5579 vtop->t = char_pointer_type; /* change type to 'char *' */
5580 vpushi(s->c);
5581 gen_op('+');
5582 /* change type to field type, and set to lvalue */
5583 vtop->t = s->t;
5584 /* an array is never an lvalue */
5585 if (!(vtop->t & VT_ARRAY)) {
5586 vtop->r |= lvalue_type(vtop->t);
5587 /* if bound checking, the referenced pointer must be checked */
5588 if (do_bounds_check)
5589 vtop->r |= VT_MUSTBOUND;
5591 next();
5592 } else if (tok == '[') {
5593 next();
5594 gexpr();
5595 gen_op('+');
5596 indir();
5597 skip(']');
5598 } else if (tok == '(') {
5599 SValue ret;
5600 Sym *sa;
5602 /* function call */
5603 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
5604 /* pointer test (no array accepted) */
5605 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
5606 vtop->t = pointed_type(vtop->t);
5607 if ((vtop->t & VT_BTYPE) != VT_FUNC)
5608 goto error_func;
5609 } else {
5610 error_func:
5611 expect("function pointer");
5613 } else {
5614 vtop->r &= ~VT_LVAL; /* no lvalue */
5616 /* get return type */
5617 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
5618 if (!nocode_wanted) {
5619 save_regs(0); /* save used temporary registers */
5620 gfunc_start(&gf, s->r);
5622 next();
5623 sa = s->next; /* first parameter */
5624 #ifdef INVERT_FUNC_PARAMS
5626 int parlevel;
5627 Sym *args, *s1;
5628 ParseState saved_parse_state;
5629 TokenString str;
5631 /* read each argument and store it on a stack */
5632 args = NULL;
5633 if (tok != ')') {
5634 for(;;) {
5635 tok_str_new(&str);
5636 parlevel = 0;
5637 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
5638 tok != TOK_EOF) {
5639 if (tok == '(')
5640 parlevel++;
5641 else if (tok == ')')
5642 parlevel--;
5643 tok_str_add_tok(&str);
5644 next();
5646 tok_str_add(&str, -1); /* end of file added */
5647 tok_str_add(&str, 0);
5648 s1 = sym_push2(&args, 0, 0, (int)str.str);
5649 s1->next = sa; /* add reference to argument */
5650 if (sa)
5651 sa = sa->next;
5652 if (tok == ')')
5653 break;
5654 skip(',');
5658 /* now generate code in reverse order by reading the stack */
5659 save_parse_state(&saved_parse_state);
5660 while (args) {
5661 macro_ptr = (int *)args->c;
5662 next();
5663 expr_eq();
5664 if (tok != -1)
5665 expect("',' or ')'");
5666 gfunc_param_typed(&gf, s, args->next);
5667 s1 = args->prev;
5668 tok_str_free((int *)args->c);
5669 tcc_free(args);
5670 args = s1;
5672 restore_parse_state(&saved_parse_state);
5674 #endif
5675 /* compute first implicit argument if a structure is returned */
5676 if ((s->t & VT_BTYPE) == VT_STRUCT) {
5677 /* get some space for the returned structure */
5678 size = type_size(s->t, &align);
5679 loc = (loc - size) & -align;
5680 ret.t = s->t;
5681 ret.r = VT_LOCAL | VT_LVAL;
5682 /* pass it as 'int' to avoid structure arg passing
5683 problems */
5684 vset(VT_INT, VT_LOCAL, loc);
5685 ret.c = vtop->c;
5686 if (!nocode_wanted)
5687 gfunc_param(&gf);
5688 else
5689 vtop--;
5690 } else {
5691 ret.t = s->t;
5692 ret.r2 = VT_CONST;
5693 /* return in register */
5694 if (is_float(ret.t)) {
5695 ret.r = REG_FRET;
5696 } else {
5697 if ((ret.t & VT_BTYPE) == VT_LLONG)
5698 ret.r2 = REG_LRET;
5699 ret.r = REG_IRET;
5701 ret.c.i = 0;
5703 #ifndef INVERT_FUNC_PARAMS
5704 if (tok != ')') {
5705 for(;;) {
5706 expr_eq();
5707 gfunc_param_typed(&gf, s, sa);
5708 if (sa)
5709 sa = sa->next;
5710 if (tok == ')')
5711 break;
5712 skip(',');
5715 #endif
5716 if (sa)
5717 error("too few arguments to function");
5718 skip(')');
5719 if (!nocode_wanted)
5720 gfunc_call(&gf);
5721 else
5722 vtop--;
5723 /* return value */
5724 vsetc(ret.t, ret.r, &ret.c);
5725 vtop->r2 = ret.r2;
5726 } else {
5727 break;
5732 static void uneq(void)
5734 int t;
5736 unary();
5737 if (tok == '=' ||
5738 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5739 tok == TOK_A_XOR || tok == TOK_A_OR ||
5740 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5741 test_lvalue();
5742 t = tok;
5743 next();
5744 if (t == '=') {
5745 expr_eq();
5746 } else {
5747 vdup();
5748 expr_eq();
5749 gen_op(t & 0x7f);
5751 vstore();
5755 static void sum(int l)
5757 int t;
5759 if (l == 0)
5760 uneq();
5761 else {
5762 sum(--l);
5763 while ((l == 0 && (tok == '*' || tok == '/' || tok == '%')) ||
5764 (l == 1 && (tok == '+' || tok == '-')) ||
5765 (l == 2 && (tok == TOK_SHL || tok == TOK_SAR)) ||
5766 (l == 3 && ((tok >= TOK_ULE && tok <= TOK_GT) ||
5767 tok == TOK_ULT || tok == TOK_UGE)) ||
5768 (l == 4 && (tok == TOK_EQ || tok == TOK_NE)) ||
5769 (l == 5 && tok == '&') ||
5770 (l == 6 && tok == '^') ||
5771 (l == 7 && tok == '|') ||
5772 (l == 8 && tok == TOK_LAND) ||
5773 (l == 9 && tok == TOK_LOR)) {
5774 t = tok;
5775 next();
5776 sum(l);
5777 gen_op(t);
5782 /* only used if non constant */
5783 static void eand(void)
5785 int t;
5787 sum(8);
5788 t = 0;
5789 while (1) {
5790 if (tok != TOK_LAND) {
5791 if (t) {
5792 t = gtst(1, t);
5793 vset(VT_INT, VT_JMPI, t);
5795 break;
5797 t = gtst(1, t);
5798 next();
5799 sum(8);
5803 static void eor(void)
5805 int t;
5807 eand();
5808 t = 0;
5809 while (1) {
5810 if (tok != TOK_LOR) {
5811 if (t) {
5812 t = gtst(0, t);
5813 vset(VT_INT, VT_JMP, t);
5815 break;
5817 t = gtst(0, t);
5818 next();
5819 eand();
5823 /* XXX: better constant handling */
5824 static void expr_eq(void)
5826 int tt, u, r1, r2, rc, t1, t2, t, bt1, bt2;
5827 SValue sv;
5829 if (const_wanted) {
5830 int c1, c;
5831 sum(10);
5832 if (tok == '?') {
5833 c = vtop->c.i;
5834 vpop();
5835 next();
5836 gexpr();
5837 c1 = vtop->c.i;
5838 vpop();
5839 skip(':');
5840 expr_eq();
5841 if (c)
5842 vtop->c.i = c1;
5844 } else {
5845 eor();
5846 if (tok == '?') {
5847 next();
5848 save_regs(1); /* we need to save all registers here except
5849 at the top because it is a branch point */
5850 tt = gtst(1, 0);
5851 gexpr();
5852 t1 = vtop->t;
5853 bt1 = t1 & VT_BTYPE;
5854 sv = *vtop; /* save value to handle it later */
5855 vtop--; /* no vpop so that FP stack is not flushed */
5856 skip(':');
5857 u = gjmp(0);
5859 gsym(tt);
5860 expr_eq();
5861 t2 = vtop->t;
5863 bt2 = t2 & VT_BTYPE;
5864 /* cast operands to correct type according to ISOC rules */
5865 if (is_float(bt1) || is_float(bt2)) {
5866 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
5867 t = VT_LDOUBLE;
5868 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
5869 t = VT_DOUBLE;
5870 } else {
5871 t = VT_FLOAT;
5873 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
5874 /* cast to biggest op */
5875 t = VT_LLONG;
5876 /* convert to unsigned if it does not fit in a long long */
5877 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
5878 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
5879 t |= VT_UNSIGNED;
5880 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
5881 /* XXX: test pointer compatibility */
5882 t = t1;
5883 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5884 /* XXX: test structure compatibility */
5885 t = t1;
5886 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
5887 /* NOTE: as an extension, we accept void on only one side */
5888 t = VT_VOID;
5889 } else {
5890 /* integer operations */
5891 t = VT_INT;
5892 /* convert to unsigned if it does not fit in an integer */
5893 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
5894 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
5895 t |= VT_UNSIGNED;
5898 /* now we convert second operand */
5899 gen_cast(t);
5900 rc = RC_INT;
5901 if (is_float(t)) {
5902 rc = RC_FLOAT;
5903 } else if ((t & VT_BTYPE) == VT_LLONG) {
5904 /* for long longs, we use fixed registers to avoid having
5905 to handle a complicated move */
5906 rc = RC_IRET;
5908 r2 = gv(rc);
5909 /* this is horrible, but we must also convert first
5910 operand */
5911 tt = gjmp(0);
5912 gsym(u);
5913 /* put again first value and cast it */
5914 *vtop = sv;
5915 gen_cast(t);
5916 r1 = gv(rc);
5917 move_reg(r2, r1);
5918 vtop->r = r2;
5919 gsym(tt);
5924 static void gexpr(void)
5926 while (1) {
5927 expr_eq();
5928 if (tok != ',')
5929 break;
5930 vpop();
5931 next();
5935 /* parse an expression and return its type without any side effect. */
5936 static int expr_type(void)
5938 int a, t;
5940 a = nocode_wanted;
5941 nocode_wanted = 1;
5942 gexpr();
5943 t = vtop->t;
5944 vpop();
5945 nocode_wanted = a;
5946 return t;
5949 /* parse a unary expression and return its type without any side
5950 effect. */
5951 static int unary_type(void)
5953 int a, t;
5955 a = nocode_wanted;
5956 nocode_wanted = 1;
5957 unary();
5958 t = vtop->t;
5959 vpop();
5960 nocode_wanted = a;
5961 return t;
5964 /* parse a constant expression and return value in vtop. */
5965 static void expr_const1(void)
5967 int a;
5968 a = const_wanted;
5969 const_wanted = 1;
5970 expr_eq();
5971 const_wanted = a;
5974 /* parse an integer constant and return its value. */
5975 static int expr_const(void)
5977 int c;
5978 expr_const1();
5979 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
5980 expect("constant expression");
5981 c = vtop->c.i;
5982 vpop();
5983 return c;
5986 /* return the label token if current token is a label, otherwise
5987 return zero */
5988 static int is_label(void)
5990 int t;
5991 CValue c;
5993 /* fast test first */
5994 if (tok < TOK_UIDENT)
5995 return 0;
5996 /* no need to save tokc since we expect an identifier */
5997 t = tok;
5998 c = tokc;
5999 next();
6000 if (tok == ':') {
6001 next();
6002 return t;
6003 } else {
6004 /* XXX: may not work in all cases (macros ?) */
6005 tok1 = tok;
6006 tok1c = tokc;
6007 tok = t;
6008 tokc = c;
6009 return 0;
6013 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
6015 int a, b, c, d;
6016 Sym *s;
6018 /* generate line number info */
6019 if (do_debug &&
6020 (last_line_num != file->line_num || last_ind != ind)) {
6021 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
6022 last_ind = ind;
6023 last_line_num = file->line_num;
6026 if (tok == TOK_IF) {
6027 /* if test */
6028 next();
6029 skip('(');
6030 gexpr();
6031 skip(')');
6032 a = gtst(1, 0);
6033 block(bsym, csym, case_sym, def_sym, case_reg);
6034 c = tok;
6035 if (c == TOK_ELSE) {
6036 next();
6037 d = gjmp(0);
6038 gsym(a);
6039 block(bsym, csym, case_sym, def_sym, case_reg);
6040 gsym(d); /* patch else jmp */
6041 } else
6042 gsym(a);
6043 } else if (tok == TOK_WHILE) {
6044 next();
6045 d = ind;
6046 skip('(');
6047 gexpr();
6048 skip(')');
6049 a = gtst(1, 0);
6050 b = 0;
6051 block(&a, &b, case_sym, def_sym, case_reg);
6052 gjmp_addr(d);
6053 gsym(a);
6054 gsym_addr(b, d);
6055 } else if (tok == '{') {
6056 next();
6057 /* declarations */
6058 s = local_stack.top;
6059 while (tok != '}') {
6060 decl(VT_LOCAL);
6061 if (tok != '}')
6062 block(bsym, csym, case_sym, def_sym, case_reg);
6064 /* pop locally defined symbols */
6065 sym_pop(&local_stack, s);
6066 next();
6067 } else if (tok == TOK_RETURN) {
6068 next();
6069 if (tok != ';') {
6070 gexpr();
6071 gen_assign_cast(func_vt);
6072 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
6073 /* if returning structure, must copy it to implicit
6074 first pointer arg location */
6075 vset(mk_pointer(func_vt), VT_LOCAL | VT_LVAL, func_vc);
6076 indir();
6077 vswap();
6078 /* copy structure value to pointer */
6079 vstore();
6080 } else if (is_float(func_vt)) {
6081 gv(RC_FRET);
6082 } else {
6083 gv(RC_IRET);
6085 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
6087 skip(';');
6088 rsym = gjmp(rsym); /* jmp */
6089 } else if (tok == TOK_BREAK) {
6090 /* compute jump */
6091 if (!bsym)
6092 error("cannot break");
6093 *bsym = gjmp(*bsym);
6094 next();
6095 skip(';');
6096 } else if (tok == TOK_CONTINUE) {
6097 /* compute jump */
6098 if (!csym)
6099 error("cannot continue");
6100 *csym = gjmp(*csym);
6101 next();
6102 skip(';');
6103 } else if (tok == TOK_FOR) {
6104 int e;
6105 next();
6106 skip('(');
6107 if (tok != ';') {
6108 gexpr();
6109 vpop();
6111 skip(';');
6112 d = ind;
6113 c = ind;
6114 a = 0;
6115 b = 0;
6116 if (tok != ';') {
6117 gexpr();
6118 a = gtst(1, 0);
6120 skip(';');
6121 if (tok != ')') {
6122 e = gjmp(0);
6123 c = ind;
6124 gexpr();
6125 vpop();
6126 gjmp_addr(d);
6127 gsym(e);
6129 skip(')');
6130 block(&a, &b, case_sym, def_sym, case_reg);
6131 gjmp_addr(c);
6132 gsym(a);
6133 gsym_addr(b, c);
6134 } else
6135 if (tok == TOK_DO) {
6136 next();
6137 a = 0;
6138 b = 0;
6139 d = ind;
6140 block(&a, &b, case_sym, def_sym, case_reg);
6141 skip(TOK_WHILE);
6142 skip('(');
6143 gsym(b);
6144 gexpr();
6145 c = gtst(0, 0);
6146 gsym_addr(c, d);
6147 skip(')');
6148 gsym(a);
6149 skip(';');
6150 } else
6151 if (tok == TOK_SWITCH) {
6152 next();
6153 skip('(');
6154 gexpr();
6155 /* XXX: other types than integer */
6156 case_reg = gv(RC_INT);
6157 vpop();
6158 skip(')');
6159 a = 0;
6160 b = gjmp(0); /* jump to first case */
6161 c = 0;
6162 block(&a, csym, &b, &c, case_reg);
6163 /* if no default, jmp after switch */
6164 if (c == 0)
6165 c = ind;
6166 /* default label */
6167 gsym_addr(b, c);
6168 /* break label */
6169 gsym(a);
6170 } else
6171 if (tok == TOK_CASE) {
6172 int v1, v2;
6173 if (!case_sym)
6174 expect("switch");
6175 next();
6176 v1 = expr_const();
6177 v2 = v1;
6178 if (gnu_ext && tok == TOK_DOTS) {
6179 next();
6180 v2 = expr_const();
6181 if (v2 < v1)
6182 warning("empty case range");
6184 /* since a case is like a label, we must skip it with a jmp */
6185 b = gjmp(0);
6186 gsym(*case_sym);
6187 vset(VT_INT, case_reg, 0);
6188 vpushi(v1);
6189 if (v1 == v2) {
6190 gen_op(TOK_EQ);
6191 *case_sym = gtst(1, 0);
6192 } else {
6193 gen_op(TOK_GE);
6194 *case_sym = gtst(1, 0);
6195 vset(VT_INT, case_reg, 0);
6196 vpushi(v2);
6197 gen_op(TOK_LE);
6198 *case_sym = gtst(1, *case_sym);
6200 gsym(b);
6201 skip(':');
6202 block(bsym, csym, case_sym, def_sym, case_reg);
6203 } else
6204 if (tok == TOK_DEFAULT) {
6205 next();
6206 skip(':');
6207 if (!def_sym)
6208 expect("switch");
6209 if (*def_sym)
6210 error("too many 'default'");
6211 *def_sym = ind;
6212 block(bsym, csym, case_sym, def_sym, case_reg);
6213 } else
6214 if (tok == TOK_GOTO) {
6215 next();
6216 if (tok == '*' && gnu_ext) {
6217 /* computed goto */
6218 next();
6219 gexpr();
6220 if ((vtop->t & VT_BTYPE) != VT_PTR)
6221 expect("pointer");
6222 ggoto();
6223 } else if (tok >= TOK_UIDENT) {
6224 s = sym_find1(&label_stack, tok);
6225 /* put forward definition if needed */
6226 if (!s) {
6227 s = sym_push1(&label_stack, tok, 0, 0);
6228 s->r = LABEL_FORWARD;
6230 /* label already defined */
6231 if (s->r & LABEL_FORWARD)
6232 s->next = (void *)gjmp((long)s->next);
6233 else
6234 gjmp_addr((long)s->next);
6235 next();
6236 } else {
6237 expect("label identifier");
6239 skip(';');
6240 } else {
6241 b = is_label();
6242 if (b) {
6243 /* label case */
6244 s = sym_find1(&label_stack, b);
6245 if (s) {
6246 if (!(s->r & LABEL_FORWARD))
6247 error("multiple defined label");
6248 gsym((long)s->next);
6249 } else {
6250 s = sym_push1(&label_stack, b, 0, 0);
6252 s->next = (void *)ind;
6253 s->r = 0;
6254 /* we accept this, but it is a mistake */
6255 if (tok == '}')
6256 warning("deprecated use of label at end of compound statement");
6257 else
6258 block(bsym, csym, case_sym, def_sym, case_reg);
6259 } else {
6260 /* expression case */
6261 if (tok != ';') {
6262 gexpr();
6263 vpop();
6265 skip(';');
6270 /* t is the array or struct type. c is the array or struct
6271 address. cur_index/cur_field is the pointer to the current
6272 value. 'size_only' is true if only size info is needed (only used
6273 in arrays) */
6274 static void decl_designator(int t, Section *sec, unsigned long c,
6275 int *cur_index, Sym **cur_field,
6276 int size_only)
6278 Sym *s, *f;
6279 int notfirst, index, align, l;
6281 notfirst = 0;
6282 if (gnu_ext && (l = is_label()) != 0)
6283 goto struct_field;
6285 while (tok == '[' || tok == '.') {
6286 if (tok == '[') {
6287 if (!(t & VT_ARRAY))
6288 expect("array type");
6289 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
6290 next();
6291 index = expr_const();
6292 if (index < 0 || (s->c >= 0 && index >= s->c))
6293 expect("invalid index");
6294 skip(']');
6295 if (!notfirst)
6296 *cur_index = index;
6297 t = pointed_type(t);
6298 c += index * type_size(t, &align);
6299 } else {
6300 next();
6301 l = tok;
6302 next();
6303 struct_field:
6304 if ((t & VT_BTYPE) != VT_STRUCT)
6305 expect("struct/union type");
6306 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
6307 l |= SYM_FIELD;
6308 f = s->next;
6309 while (f) {
6310 if (f->v == l)
6311 break;
6312 f = f->next;
6314 if (!f)
6315 expect("field");
6316 if (!notfirst)
6317 *cur_field = f;
6318 t = f->t | (t & ~VT_TYPE);
6319 c += f->c;
6321 notfirst = 1;
6323 if (notfirst) {
6324 if (tok == '=') {
6325 next();
6326 } else {
6327 if (!gnu_ext)
6328 expect("=");
6330 } else {
6331 if (t & VT_ARRAY) {
6332 index = *cur_index;
6333 t = pointed_type(t);
6334 c += index * type_size(t, &align);
6335 } else {
6336 f = *cur_field;
6337 if (!f)
6338 error("too many field init");
6339 t = f->t | (t & ~VT_TYPE);
6340 c += f->c;
6343 decl_initializer(t, sec, c, 0, size_only);
6346 #define EXPR_VAL 0
6347 #define EXPR_CONST 1
6348 #define EXPR_ANY 2
6350 /* store a value or an expression directly in global data or in local array */
6351 static void init_putv(int t, Section *sec, unsigned long c,
6352 int v, int expr_type)
6354 int saved_global_expr, bt;
6355 void *ptr;
6357 switch(expr_type) {
6358 case EXPR_VAL:
6359 vpushi(v);
6360 break;
6361 case EXPR_CONST:
6362 /* compound literals must be allocated globally in this case */
6363 saved_global_expr = global_expr;
6364 global_expr = 1;
6365 expr_const1();
6366 global_expr = saved_global_expr;
6367 /* NOTE: symbols are accepted */
6368 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
6369 error("initializer element is not constant");
6370 break;
6371 case EXPR_ANY:
6372 expr_eq();
6373 break;
6376 if (sec) {
6377 /* XXX: not portable */
6378 /* XXX: generate error if incorrect relocation */
6379 gen_assign_cast(t);
6380 bt = t & VT_BTYPE;
6381 ptr = sec->data + c;
6382 if ((vtop->r & VT_SYM) &&
6383 (bt == VT_BYTE ||
6384 bt == VT_SHORT ||
6385 bt == VT_DOUBLE ||
6386 bt == VT_LDOUBLE ||
6387 bt == VT_LLONG))
6388 error("initializer element is not computable at load time");
6389 switch(bt) {
6390 case VT_BYTE:
6391 *(char *)ptr = vtop->c.i;
6392 break;
6393 case VT_SHORT:
6394 *(short *)ptr = vtop->c.i;
6395 break;
6396 case VT_DOUBLE:
6397 *(double *)ptr = vtop->c.d;
6398 break;
6399 case VT_LDOUBLE:
6400 *(long double *)ptr = vtop->c.ld;
6401 break;
6402 case VT_LLONG:
6403 *(long long *)ptr = vtop->c.ll;
6404 break;
6405 default:
6406 if (vtop->r & VT_SYM) {
6407 greloc(sec, vtop->sym, c, R_DATA_32);
6409 *(int *)ptr = vtop->c.i;
6410 break;
6412 vtop--;
6413 } else {
6414 vset(t, VT_LOCAL, c);
6415 vswap();
6416 vstore();
6417 vpop();
6421 /* put zeros for variable based init */
6422 static void init_putz(int t, Section *sec, unsigned long c, int size)
6424 GFuncContext gf;
6426 if (sec) {
6427 /* nothing to do because globals are already set to zero */
6428 } else {
6429 gfunc_start(&gf, FUNC_CDECL);
6430 vpushi(size);
6431 gfunc_param(&gf);
6432 vpushi(0);
6433 gfunc_param(&gf);
6434 vset(VT_INT, VT_LOCAL, c);
6435 gfunc_param(&gf);
6436 vpush_global_sym(func_old_type, TOK_memset);
6437 gfunc_call(&gf);
6441 /* 't' contains the type and storage info. 'c' is the offset of the
6442 object in section 'sec'. If 'sec' is NULL, it means stack based
6443 allocation. 'first' is true if array '{' must be read (multi
6444 dimension implicit array init handling). 'size_only' is true if
6445 size only evaluation is wanted (only for arrays). */
6446 static void decl_initializer(int t, Section *sec, unsigned long c,
6447 int first, int size_only)
6449 int index, array_length, n, no_oblock, nb, parlevel, i;
6450 int t1, size1, align1, expr_type;
6451 Sym *s, *f;
6453 if (t & VT_ARRAY) {
6454 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
6455 n = s->c;
6456 array_length = 0;
6457 t1 = pointed_type(t);
6458 size1 = type_size(t1, &align1);
6460 no_oblock = 1;
6461 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
6462 tok == '{') {
6463 skip('{');
6464 no_oblock = 0;
6467 /* only parse strings here if correct type (otherwise: handle
6468 them as ((w)char *) expressions */
6469 if ((tok == TOK_LSTR &&
6470 (t1 & VT_BTYPE) == VT_INT) ||
6471 (tok == TOK_STR &&
6472 (t1 & VT_BTYPE) == VT_BYTE)) {
6473 while (tok == TOK_STR || tok == TOK_LSTR) {
6474 int cstr_len, ch;
6475 CString *cstr;
6477 cstr = tokc.cstr;
6478 /* compute maximum number of chars wanted */
6479 if (tok == TOK_STR)
6480 cstr_len = cstr->size;
6481 else
6482 cstr_len = cstr->size / sizeof(int);
6483 cstr_len--;
6484 nb = cstr_len;
6485 if (n >= 0 && nb > (n - array_length))
6486 nb = n - array_length;
6487 if (!size_only) {
6488 if (cstr_len > nb)
6489 warning("initializer-string for array is too long");
6490 /* in order to go faster for common case (char
6491 string in global variable, we handle it
6492 specifically */
6493 if (sec && tok == TOK_STR && size1 == 1) {
6494 memcpy(sec->data + c + array_length, cstr->data, nb);
6495 } else {
6496 for(i=0;i<nb;i++) {
6497 if (tok == TOK_STR)
6498 ch = ((unsigned char *)cstr->data)[i];
6499 else
6500 ch = ((int *)cstr->data)[i];
6501 init_putv(t1, sec, c + (array_length + i) * size1,
6502 ch, EXPR_VAL);
6506 array_length += nb;
6507 next();
6509 /* only add trailing zero if enough storage (no
6510 warning in this case since it is standard) */
6511 if (n < 0 || array_length < n) {
6512 if (!size_only) {
6513 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
6515 array_length++;
6517 } else {
6518 index = 0;
6519 while (tok != '}') {
6520 decl_designator(t, sec, c, &index, NULL, size_only);
6521 if (n >= 0 && index >= n)
6522 error("index too large");
6523 /* must put zero in holes (note that doing it that way
6524 ensures that it even works with designators) */
6525 if (!size_only && array_length < index) {
6526 init_putz(t1, sec, c + array_length * size1,
6527 (index - array_length) * size1);
6529 index++;
6530 if (index > array_length)
6531 array_length = index;
6532 /* special test for multi dimensional arrays (may not
6533 be strictly correct if designators are used at the
6534 same time) */
6535 if (index >= n && no_oblock)
6536 break;
6537 if (tok == '}')
6538 break;
6539 skip(',');
6542 if (!no_oblock)
6543 skip('}');
6544 /* put zeros at the end */
6545 if (!size_only && n >= 0 && array_length < n) {
6546 init_putz(t1, sec, c + array_length * size1,
6547 (n - array_length) * size1);
6549 /* patch type size if needed */
6550 if (n < 0)
6551 s->c = array_length;
6552 } else if ((t & VT_BTYPE) == VT_STRUCT && tok == '{') {
6553 /* XXX: union needs only one init */
6554 next();
6555 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
6556 f = s->next;
6557 array_length = 0;
6558 index = 0;
6559 n = s->c;
6560 while (tok != '}') {
6561 decl_designator(t, sec, c, NULL, &f, size_only);
6562 /* fill with zero between fields */
6563 index = f->c;
6564 if (!size_only && array_length < index) {
6565 init_putz(t, sec, c + array_length,
6566 index - array_length);
6568 index = index + type_size(f->t, &align1);
6569 if (index > array_length)
6570 array_length = index;
6571 if (tok == '}')
6572 break;
6573 skip(',');
6574 f = f->next;
6576 /* put zeros at the end */
6577 if (!size_only && array_length < n) {
6578 init_putz(t, sec, c + array_length,
6579 n - array_length);
6581 skip('}');
6582 } else if (tok == '{') {
6583 next();
6584 decl_initializer(t, sec, c, first, size_only);
6585 skip('}');
6586 } else if (size_only) {
6587 /* just skip expression */
6588 parlevel = 0;
6589 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
6590 tok != -1) {
6591 if (tok == '(')
6592 parlevel++;
6593 else if (tok == ')')
6594 parlevel--;
6595 next();
6597 } else {
6598 /* currently, we always use constant expression for globals
6599 (may change for scripting case) */
6600 expr_type = EXPR_CONST;
6601 if (!sec)
6602 expr_type = EXPR_ANY;
6603 init_putv(t, sec, c, 0, expr_type);
6607 /* parse an initializer for type 't' if 'has_init' is non zero, and
6608 allocate space in local or global data space ('r' is either
6609 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6610 variable 'v' of scope 'scope' is declared before initializers are
6611 parsed. If 'v' is zero, then a reference to the new object is put
6612 in the value stack. If 'has_init' is 2, a special parsing is done
6613 to handle string constants. */
6614 static void decl_initializer_alloc(int t, AttributeDef *ad, int r,
6615 int has_init, int v, int scope)
6617 int size, align, addr, data_offset;
6618 int level;
6619 ParseState saved_parse_state;
6620 TokenString init_str;
6621 Section *sec;
6623 size = type_size(t, &align);
6624 /* If unknown size, we must evaluate it before
6625 evaluating initializers because
6626 initializers can generate global data too
6627 (e.g. string pointers or ISOC99 compound
6628 literals). It also simplifies local
6629 initializers handling */
6630 tok_str_new(&init_str);
6631 if (size < 0) {
6632 if (!has_init)
6633 error("unknown type size");
6634 /* get all init string */
6635 if (has_init == 2) {
6636 /* only get strings */
6637 while (tok == TOK_STR || tok == TOK_LSTR) {
6638 tok_str_add_tok(&init_str);
6639 next();
6641 } else {
6642 level = 0;
6643 while (level > 0 || (tok != ',' && tok != ';')) {
6644 if (tok < 0)
6645 error("unexpected end of file in initializer");
6646 tok_str_add_tok(&init_str);
6647 if (tok == '{')
6648 level++;
6649 else if (tok == '}') {
6650 if (level == 0)
6651 break;
6652 level--;
6654 next();
6657 tok_str_add(&init_str, -1);
6658 tok_str_add(&init_str, 0);
6660 /* compute size */
6661 save_parse_state(&saved_parse_state);
6663 macro_ptr = init_str.str;
6664 next();
6665 decl_initializer(t, NULL, 0, 1, 1);
6666 /* prepare second initializer parsing */
6667 macro_ptr = init_str.str;
6668 next();
6670 /* if still unknown size, error */
6671 size = type_size(t, &align);
6672 if (size < 0)
6673 error("unknown type size");
6675 /* take into account specified alignment if bigger */
6676 if (ad->aligned > align)
6677 align = ad->aligned;
6678 if ((r & VT_VALMASK) == VT_LOCAL) {
6679 sec = NULL;
6680 if (do_bounds_check && (t & VT_ARRAY))
6681 loc--;
6682 #ifdef TCC_TARGET_IL
6683 /* XXX: ugly patch to allocate local variables for IL, just
6684 for testing */
6685 addr = loc;
6686 loc++;
6687 #else
6688 loc = (loc - size) & -align;
6689 addr = loc;
6690 #endif
6691 /* handles bounds */
6692 /* XXX: currently, since we do only one pass, we cannot track
6693 '&' operators, so we add only arrays */
6694 if (do_bounds_check && (t & VT_ARRAY)) {
6695 unsigned long *bounds_ptr;
6696 /* add padding between regions */
6697 loc--;
6698 /* then add local bound info */
6699 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
6700 bounds_ptr[0] = addr;
6701 bounds_ptr[1] = size;
6703 } else {
6704 /* compute section */
6705 sec = ad->section;
6706 if (!sec) {
6707 if (has_init)
6708 sec = data_section;
6709 else
6710 sec = bss_section;
6712 data_offset = sec->data_offset;
6713 data_offset = (data_offset + align - 1) & -align;
6714 addr = data_offset;
6715 /* very important to increment global pointer at this time
6716 because initializers themselves can create new initializers */
6717 data_offset += size;
6718 /* add padding if bound check */
6719 if (do_bounds_check)
6720 data_offset++;
6721 sec->data_offset = data_offset;
6722 /* allocate section space to put the data */
6723 if (sec->sh_type != SHT_NOBITS &&
6724 data_offset > sec->data_allocated)
6725 section_realloc(sec, data_offset);
6727 if (!sec) {
6728 if (v) {
6729 /* local variable */
6730 sym_push(v, t, r, addr);
6731 } else {
6732 /* push local reference */
6733 vset(t, r, addr);
6735 } else {
6736 Sym *sym;
6738 if (v) {
6739 if (scope == VT_CONST) {
6740 /* global scope: see if already defined */
6741 sym = sym_find(v);
6742 if (!sym)
6743 goto do_def;
6744 if (!is_compatible_types(sym->t, t))
6745 error("incompatible types for redefinition of '%s'",
6746 get_tok_str(v, NULL));
6747 if (!(sym->t & VT_EXTERN))
6748 error("redefinition of '%s'", get_tok_str(v, NULL));
6749 sym->t &= ~VT_EXTERN;
6750 } else {
6751 do_def:
6752 sym = sym_push(v, t, r | VT_SYM, 0);
6754 put_extern_sym(sym, sec, addr, size);
6755 } else {
6756 CValue cval;
6758 /* push global reference */
6759 sym = get_sym_ref(t, sec, addr, size);
6760 cval.ul = 0;
6761 vsetc(t, VT_CONST | VT_SYM, &cval);
6762 vtop->sym = sym;
6765 /* handles bounds now because the symbol must be defined
6766 before for the relocation */
6767 if (do_bounds_check) {
6768 unsigned long *bounds_ptr;
6770 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
6771 /* then add global bound info */
6772 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
6773 bounds_ptr[0] = 0; /* relocated */
6774 bounds_ptr[1] = size;
6777 if (has_init) {
6778 decl_initializer(t, sec, addr, 1, 0);
6779 /* restore parse state if needed */
6780 if (init_str.str) {
6781 tok_str_free(init_str.str);
6782 restore_parse_state(&saved_parse_state);
6787 void put_func_debug(Sym *sym)
6789 char buf[512];
6791 /* stabs info */
6792 /* XXX: we put here a dummy type */
6793 snprintf(buf, sizeof(buf), "%s:%c1",
6794 funcname, sym->t & VT_STATIC ? 'f' : 'F');
6795 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
6796 cur_text_section, sym->c);
6797 last_ind = 0;
6798 last_line_num = 0;
6801 /* not finished : try to put some local vars in registers */
6802 //#define CONFIG_REG_VARS
6804 #ifdef CONFIG_REG_VARS
6805 void add_var_ref(int t)
6807 printf("%s:%d: &%s\n",
6808 file->filename, file->line_num,
6809 get_tok_str(t, NULL));
6812 /* first pass on a function with heuristic to extract variable usage
6813 and pointer references to local variables for register allocation */
6814 void analyse_function(void)
6816 int level, t;
6818 for(;;) {
6819 if (tok == -1)
6820 break;
6821 /* any symbol coming after '&' is considered as being a
6822 variable whose reference is taken. It is highly unaccurate
6823 but it is difficult to do better without a complete parse */
6824 if (tok == '&') {
6825 next();
6826 /* if '& number', then no need to examine next tokens */
6827 if (tok == TOK_CINT ||
6828 tok == TOK_CUINT ||
6829 tok == TOK_CLLONG ||
6830 tok == TOK_CULLONG) {
6831 continue;
6832 } else if (tok >= TOK_UIDENT) {
6833 /* if '& ident [' or '& ident ->', then ident address
6834 is not needed */
6835 t = tok;
6836 next();
6837 if (tok != '[' && tok != TOK_ARROW)
6838 add_var_ref(t);
6839 } else {
6840 level = 0;
6841 while (tok != '}' && tok != ';' &&
6842 !((tok == ',' || tok == ')') && level == 0)) {
6843 if (tok >= TOK_UIDENT) {
6844 add_var_ref(tok);
6845 } else if (tok == '(') {
6846 level++;
6847 } else if (tok == ')') {
6848 level--;
6850 next();
6853 } else {
6854 next();
6858 #endif
6860 /* parse an old style function declaration list */
6861 /* XXX: check multiple parameter */
6862 static void func_decl_list(Sym *func_sym)
6864 AttributeDef ad;
6865 int b, v, t;
6866 Sym *s;
6867 /* parse each declaration */
6868 while (tok != '{' && tok != ';' && tok != TOK_EOF) {
6869 if (!parse_btype(&b, &ad))
6870 expect("declaration list");
6871 if (((b & VT_BTYPE) == VT_ENUM ||
6872 (b & VT_BTYPE) == VT_STRUCT) &&
6873 tok == ';') {
6874 /* we accept no variable after */
6875 } else {
6876 for(;;) {
6877 t = type_decl(&ad, &v, b, TYPE_DIRECT);
6878 /* find parameter in function parameter list */
6879 s = func_sym->next;
6880 while (s != NULL) {
6881 if ((s->v & ~SYM_FIELD) == v)
6882 goto found;
6883 s = s->next;
6885 error("declaration for parameter '%s' but no such parameter",
6886 get_tok_str(v, NULL));
6887 found:
6888 /* check that no storage specifier except 'register' was given */
6889 if (t & (VT_EXTERN | VT_STATIC | VT_TYPEDEF))
6890 error("storage class specified for '%s'", get_tok_str(v, NULL));
6891 /* we can add the type (NOTE: it could be local to the function) */
6892 s->t = t;
6893 /* accept other parameters */
6894 if (tok == ',')
6895 next();
6896 else
6897 break;
6900 skip(';');
6904 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6905 static void decl(int l)
6907 int t, b, v, has_init, r;
6908 Sym *sym;
6909 AttributeDef ad;
6911 while (1) {
6912 if (!parse_btype(&b, &ad)) {
6913 /* skip redundant ';' */
6914 /* XXX: find more elegant solution */
6915 if (tok == ';') {
6916 next();
6917 continue;
6919 /* special test for old K&R protos without explicit int
6920 type. Only accepted when defining global data */
6921 if (l == VT_LOCAL || tok < TOK_DEFINE)
6922 break;
6923 b = VT_INT;
6925 if (((b & VT_BTYPE) == VT_ENUM ||
6926 (b & VT_BTYPE) == VT_STRUCT) &&
6927 tok == ';') {
6928 /* we accept no variable after */
6929 next();
6930 continue;
6932 while (1) { /* iterate thru each declaration */
6933 t = type_decl(&ad, &v, b, TYPE_DIRECT);
6934 #if 0
6936 char buf[500];
6937 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6938 printf("type = '%s'\n", buf);
6940 #endif
6941 if ((t & VT_BTYPE) == VT_FUNC) {
6942 /* if old style function prototype, we accept a
6943 declaration list */
6944 sym = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
6945 if (sym->c == FUNC_OLD)
6946 func_decl_list(sym);
6949 if (tok == '{') {
6950 #ifdef CONFIG_REG_VARS
6951 TokenString func_str;
6952 ParseState saved_parse_state;
6953 int block_level;
6954 #endif
6956 if (l == VT_LOCAL)
6957 error("cannot use local functions");
6958 if (!(t & VT_FUNC))
6959 expect("function definition");
6961 #ifdef CONFIG_REG_VARS
6962 /* parse all function code and record it */
6964 tok_str_new(&func_str);
6966 block_level = 0;
6967 for(;;) {
6968 int t;
6969 if (tok == -1)
6970 error("unexpected end of file");
6971 tok_str_add_tok(&func_str);
6972 t = tok;
6973 next();
6974 if (t == '{') {
6975 block_level++;
6976 } else if (t == '}') {
6977 block_level--;
6978 if (block_level == 0)
6979 break;
6982 tok_str_add(&func_str, -1);
6983 tok_str_add(&func_str, 0);
6985 save_parse_state(&saved_parse_state);
6987 macro_ptr = func_str.str;
6988 next();
6989 analyse_function();
6990 #endif
6992 /* compute text section */
6993 cur_text_section = ad.section;
6994 if (!cur_text_section)
6995 cur_text_section = text_section;
6996 ind = cur_text_section->data_offset;
6997 funcname = get_tok_str(v, NULL);
6998 sym = sym_find(v);
6999 if (sym) {
7000 /* if symbol is already defined, then put complete type */
7001 sym->t = t;
7002 } else {
7003 /* put function symbol */
7004 sym = sym_push1(&global_stack, v, t, 0);
7006 /* NOTE: we patch the symbol size later */
7007 put_extern_sym(sym, cur_text_section, ind, 0);
7008 func_ind = ind;
7009 sym->r = VT_SYM | VT_CONST;
7010 /* put debug symbol */
7011 if (do_debug)
7012 put_func_debug(sym);
7013 /* push a dummy symbol to enable local sym storage */
7014 sym_push1(&local_stack, 0, 0, 0);
7015 gfunc_prolog(t);
7016 loc = 0;
7017 rsym = 0;
7018 #ifdef CONFIG_REG_VARS
7019 macro_ptr = func_str.str;
7020 next();
7021 #endif
7022 block(NULL, NULL, NULL, NULL, 0);
7023 gsym(rsym);
7024 gfunc_epilog();
7025 cur_text_section->data_offset = ind;
7026 /* look if any labels are undefined. Define symbols if
7027 '&&label' was used. */
7029 Sym *s;
7030 for(s = label_stack.top; s != NULL; s = s->prev) {
7031 if (s->r & LABEL_FORWARD) {
7032 error("label '%s' used but not defined",
7033 get_tok_str(s->v, NULL));
7035 if (s->c) {
7036 /* define corresponding symbol. A size of
7037 1 is put. */
7038 put_extern_sym(s, cur_text_section, (long)s->next, 1);
7042 sym_pop(&label_stack, NULL); /* reset label stack */
7043 sym_pop(&local_stack, NULL); /* reset local stack */
7044 /* end of function */
7045 /* patch symbol size */
7046 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
7047 ind - func_ind;
7048 if (do_debug) {
7049 put_stabn(N_FUN, 0, 0, ind - func_ind);
7051 funcname = ""; /* for safety */
7052 func_vt = VT_VOID; /* for safety */
7053 ind = 0; /* for safety */
7055 #ifdef CONFIG_REG_VARS
7056 tok_str_free(func_str.str);
7057 restore_parse_state(&saved_parse_state);
7058 #endif
7059 break;
7060 } else {
7061 if (b & VT_TYPEDEF) {
7062 /* save typedefed type */
7063 /* XXX: test storage specifiers ? */
7064 sym_push(v, t | VT_TYPEDEF, 0, 0);
7065 } else if ((t & VT_BTYPE) == VT_FUNC) {
7066 /* external function definition */
7067 external_sym(v, t, 0);
7068 } else {
7069 /* not lvalue if array */
7070 r = 0;
7071 if (!(t & VT_ARRAY))
7072 r |= lvalue_type(t);
7073 if (b & VT_EXTERN) {
7074 /* external variable */
7075 external_sym(v, t, r);
7076 } else {
7077 if (t & VT_STATIC)
7078 r |= VT_CONST;
7079 else
7080 r |= l;
7081 has_init = (tok == '=');
7082 if (has_init)
7083 next();
7084 decl_initializer_alloc(t, &ad, r,
7085 has_init, v, l);
7088 if (tok != ',') {
7089 skip(';');
7090 break;
7092 next();
7098 /* free define stack until top reaches 'b' */
7099 static void free_defines(Sym *b)
7101 Sym *top, *top1;
7103 top = define_stack.top;
7104 while (top != b) {
7105 top1 = top->prev;
7106 /* do not free args or predefined defines */
7107 if (top->c)
7108 tok_str_free((int *)top->c);
7109 sym_pop(&define_stack, top1);
7110 top = top1;
7114 /* compile the C file opened in 'file'. Return non zero if errors. */
7115 static int tcc_compile(TCCState *s1)
7117 Sym *define_start, *sym;
7118 char buf[512];
7119 volatile int section_sym;
7120 int p;
7122 #ifdef INC_DEBUG
7123 printf("%s: **** new file\n", file->filename);
7124 #endif
7125 funcname = "";
7126 s1->include_stack_ptr = s1->include_stack;
7127 /* XXX: move that before to avoid having to initialize
7128 file->ifdef_stack_ptr ? */
7129 s1->ifdef_stack_ptr = s1->ifdef_stack;
7130 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
7132 /* XXX: not ANSI compliant: bound checking says error */
7133 vtop = vstack - 1;
7134 anon_sym = SYM_FIRST_ANOM;
7136 /* file info: full path + filename */
7137 section_sym = 0; /* avoid warning */
7138 if (do_debug) {
7139 section_sym = put_elf_sym(symtab_section, 0, 0,
7140 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
7141 text_section->sh_num, NULL);
7142 getcwd(buf, sizeof(buf));
7143 pstrcat(buf, sizeof(buf), "/");
7144 put_stabs_r(buf, N_SO, 0, 0,
7145 text_section->data_offset, text_section, section_sym);
7146 put_stabs_r(file->filename, N_SO, 0, 0,
7147 text_section->data_offset, text_section, section_sym);
7149 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
7150 symbols can be safely used */
7151 put_elf_sym(symtab_section, 0, 0,
7152 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
7153 SHN_ABS, file->filename);
7155 /* define common 'char *' type because it is often used internally
7156 for arrays and struct dereference */
7157 char_pointer_type = mk_pointer(VT_BYTE);
7158 /* define an old type function 'int func()' */
7159 p = anon_sym++;
7160 sym = sym_push(p, 0, FUNC_CDECL, FUNC_OLD);
7161 func_old_type = VT_FUNC | (p << VT_STRUCT_SHIFT);
7162 #if 0
7163 /* define 'void *alloca(unsigned int)' builtin function */
7165 Sym *s1;
7167 p = anon_sym++;
7168 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
7169 s1 = sym_push(0, VT_UNSIGNED | VT_INT, 0, 0);
7170 s1->next = NULL;
7171 sym->next = s1;
7172 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
7174 #endif
7176 define_start = define_stack.top;
7178 if (setjmp(s1->error_jmp_buf) == 0) {
7179 s1->nb_errors = 0;
7180 s1->error_set_jmp_enabled = 1;
7182 inp();
7183 ch = '\n'; /* needed to parse correctly first preprocessor command */
7184 next();
7185 decl(VT_CONST);
7186 if (tok != -1)
7187 expect("declaration");
7189 /* end of translation unit info */
7190 if (do_debug) {
7191 put_stabs_r(NULL, N_SO, 0, 0,
7192 text_section->data_offset, text_section, section_sym);
7195 s1->error_set_jmp_enabled = 0;
7197 /* reset define stack, but leave -Dsymbols (may be incorrect if
7198 they are undefined) */
7199 free_defines(define_start);
7201 sym_pop(&global_stack, NULL);
7203 return s1->nb_errors != 0 ? -1 : 0;
7206 int tcc_compile_string(TCCState *s, const char *str)
7208 BufferedFile bf1, *bf = &bf1;
7209 int ret;
7211 /* init file structure */
7212 bf->fd = -1;
7213 bf->buf_ptr = (char *)str;
7214 bf->buf_end = (char *)str + strlen(bf->buffer);
7215 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
7216 bf->line_num = 1;
7217 file = bf;
7219 ret = tcc_compile(s);
7221 /* currently, no need to close */
7222 return ret;
7225 /* define a symbol. A value can also be provided with the '=' operator */
7226 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
7228 BufferedFile bf1, *bf = &bf1;
7230 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
7231 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
7232 /* default value */
7233 if (!value)
7234 value = "1";
7235 pstrcat(bf->buffer, IO_BUF_SIZE, value);
7237 /* init file structure */
7238 bf->fd = -1;
7239 bf->buf_ptr = bf->buffer;
7240 bf->buf_end = bf->buffer + strlen(bf->buffer);
7241 bf->filename[0] = '\0';
7242 bf->line_num = 1;
7243 file = bf;
7245 s1->include_stack_ptr = s1->include_stack;
7247 /* parse with define parser */
7248 inp();
7249 ch = '\n'; /* needed to parse correctly first preprocessor command */
7250 next_nomacro();
7251 parse_define();
7252 file = NULL;
7255 void tcc_undefine_symbol(TCCState *s1, const char *sym)
7257 TokenSym *ts;
7258 Sym *s;
7259 ts = tok_alloc(sym, strlen(sym));
7260 s = sym_find1(&define_stack, tok);
7261 /* undefine symbol by putting an invalid name */
7262 if (s)
7263 sym_undef(&define_stack, s);
7266 #include "tccelf.c"
7268 /* print the position in the source file of PC value 'pc' by reading
7269 the stabs debug information */
7270 static void rt_printline(unsigned long wanted_pc)
7272 Stab_Sym *sym, *sym_end;
7273 char func_name[128], last_func_name[128];
7274 unsigned long func_addr, last_pc, pc;
7275 const char *incl_files[INCLUDE_STACK_SIZE];
7276 int incl_index, len, last_line_num, i;
7277 const char *str, *p;
7279 fprintf(stderr, "0x%08lx:", wanted_pc);
7281 func_name[0] = '\0';
7282 func_addr = 0;
7283 incl_index = 0;
7284 last_func_name[0] = '\0';
7285 last_pc = 0xffffffff;
7286 last_line_num = 1;
7287 sym = (Stab_Sym *)stab_section->data + 1;
7288 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
7289 while (sym < sym_end) {
7290 switch(sym->n_type) {
7291 /* function start or end */
7292 case N_FUN:
7293 if (sym->n_strx == 0) {
7294 /* we test if between last line and end of function */
7295 pc = sym->n_value + func_addr;
7296 if (wanted_pc >= last_pc && wanted_pc < pc)
7297 goto found;
7298 func_name[0] = '\0';
7299 func_addr = 0;
7300 } else {
7301 str = stabstr_section->data + sym->n_strx;
7302 p = strchr(str, ':');
7303 if (!p) {
7304 pstrcpy(func_name, sizeof(func_name), str);
7305 } else {
7306 len = p - str;
7307 if (len > sizeof(func_name) - 1)
7308 len = sizeof(func_name) - 1;
7309 memcpy(func_name, str, len);
7310 func_name[len] = '\0';
7312 func_addr = sym->n_value;
7314 break;
7315 /* line number info */
7316 case N_SLINE:
7317 pc = sym->n_value + func_addr;
7318 if (wanted_pc >= last_pc && wanted_pc < pc)
7319 goto found;
7320 last_pc = pc;
7321 last_line_num = sym->n_desc;
7322 /* XXX: slow! */
7323 strcpy(last_func_name, func_name);
7324 break;
7325 /* include files */
7326 case N_BINCL:
7327 str = stabstr_section->data + sym->n_strx;
7328 add_incl:
7329 if (incl_index < INCLUDE_STACK_SIZE) {
7330 incl_files[incl_index++] = str;
7332 break;
7333 case N_EINCL:
7334 if (incl_index > 1)
7335 incl_index--;
7336 break;
7337 case N_SO:
7338 if (sym->n_strx == 0) {
7339 incl_index = 0; /* end of translation unit */
7340 } else {
7341 str = stabstr_section->data + sym->n_strx;
7342 /* do not add path */
7343 len = strlen(str);
7344 if (len > 0 && str[len - 1] != '/')
7345 goto add_incl;
7347 break;
7349 sym++;
7352 /* second pass: we try symtab symbols (no line number info) */
7353 incl_index = 0;
7355 Elf32_Sym *sym, *sym_end;
7356 int type;
7358 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
7359 for(sym = (Elf32_Sym *)symtab_section->data + 1;
7360 sym < sym_end;
7361 sym++) {
7362 type = ELF32_ST_TYPE(sym->st_info);
7363 if (type == STT_FUNC) {
7364 if (wanted_pc >= sym->st_value &&
7365 wanted_pc < sym->st_value + sym->st_size) {
7366 pstrcpy(last_func_name, sizeof(last_func_name),
7367 strtab_section->data + sym->st_name);
7368 goto found;
7373 /* did not find any info: */
7374 fprintf(stderr, " ???\n");
7375 return;
7376 found:
7377 if (last_func_name[0] != '\0') {
7378 fprintf(stderr, " %s()", last_func_name);
7380 if (incl_index > 0) {
7381 fprintf(stderr, " (%s:%d",
7382 incl_files[incl_index - 1], last_line_num);
7383 for(i = incl_index - 2; i >= 0; i--)
7384 fprintf(stderr, ", included from %s", incl_files[i]);
7385 fprintf(stderr, ")");
7387 fprintf(stderr, "\n");
7390 #ifdef __i386__
7392 #ifndef EIP
7393 #define EIP 14
7394 #define EBP 6
7395 #endif
7397 /* return the PC at frame level 'level'. Return non zero if not found */
7398 static int rt_get_caller_pc(unsigned long *paddr,
7399 struct ucontext *uc, int level)
7401 unsigned long fp;
7402 int i;
7404 if (level == 0) {
7405 *paddr = uc->uc_mcontext.gregs[EIP];
7406 return 0;
7407 } else {
7408 fp = uc->uc_mcontext.gregs[EBP];
7409 for(i=1;i<level;i++) {
7410 /* XXX: check address validity with program info */
7411 if (fp <= 0x1000 || fp >= 0xc0000000)
7412 return -1;
7413 fp = ((unsigned long *)fp)[0];
7415 *paddr = ((unsigned long *)fp)[1];
7416 return 0;
7419 #else
7420 #error add corresponding function
7421 #endif
7423 /* emit a run time error at position 'pc' */
7424 void rt_error(struct ucontext *uc, const char *fmt, ...)
7426 va_list ap;
7427 unsigned long pc;
7428 int i;
7430 va_start(ap, fmt);
7431 fprintf(stderr, "Runtime error: ");
7432 vfprintf(stderr, fmt, ap);
7433 fprintf(stderr, "\n");
7434 for(i=0;i<num_callers;i++) {
7435 if (rt_get_caller_pc(&pc, uc, i) < 0)
7436 break;
7437 if (i == 0)
7438 fprintf(stderr, "at ");
7439 else
7440 fprintf(stderr, "by ");
7441 rt_printline(pc);
7443 exit(255);
7444 va_end(ap);
7447 #ifndef WIN32
7448 /* signal handler for fatal errors */
7449 static void sig_error(int signum, siginfo_t *siginf, void *puc)
7451 struct ucontext *uc = puc;
7453 switch(signum) {
7454 case SIGFPE:
7455 switch(siginf->si_code) {
7456 case FPE_INTDIV:
7457 case FPE_FLTDIV:
7458 rt_error(uc, "division by zero");
7459 break;
7460 default:
7461 rt_error(uc, "floating point exception");
7462 break;
7464 break;
7465 case SIGBUS:
7466 case SIGSEGV:
7467 if (rt_bound_error_msg && *rt_bound_error_msg)
7468 rt_error(uc, *rt_bound_error_msg);
7469 else
7470 rt_error(uc, "dereferencing invalid pointer");
7471 break;
7472 case SIGILL:
7473 rt_error(uc, "illegal instruction");
7474 break;
7475 case SIGABRT:
7476 rt_error(uc, "abort() called");
7477 break;
7478 default:
7479 rt_error(uc, "caught signal %d", signum);
7480 break;
7482 exit(255);
7484 #endif
7486 /* do all relocations (needed before using tcc_get_symbol()) */
7487 int tcc_relocate(TCCState *s1)
7489 Section *s;
7490 int i;
7492 s1->nb_errors = 0;
7494 tcc_add_runtime(s1);
7496 relocate_common_syms();
7498 /* compute relocation address : section are relocated in place. We
7499 also alloc the bss space */
7500 for(i = 1; i < s1->nb_sections; i++) {
7501 s = s1->sections[i];
7502 if (s->sh_flags & SHF_ALLOC) {
7503 if (s->sh_type == SHT_NOBITS)
7504 s->data = tcc_mallocz(s->data_offset);
7505 s->sh_addr = (unsigned long)s->data;
7509 relocate_syms(s1, 1);
7511 if (s1->nb_errors != 0)
7512 return -1;
7514 /* relocate each section */
7515 for(i = 1; i < s1->nb_sections; i++) {
7516 s = s1->sections[i];
7517 if (s->reloc)
7518 relocate_section(s1, s);
7520 return 0;
7523 /* launch the compiled program with the given arguments */
7524 int tcc_run(TCCState *s1, int argc, char **argv)
7526 int (*prog_main)(int, char **);
7528 if (tcc_relocate(s1) < 0)
7529 return -1;
7531 prog_main = tcc_get_symbol(s1, "main");
7533 if (do_debug) {
7534 #ifdef WIN32
7535 error("debug mode currently not available for Windows");
7536 #else
7537 struct sigaction sigact;
7538 /* install TCC signal handlers to print debug info on fatal
7539 runtime errors */
7540 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
7541 sigact.sa_sigaction = sig_error;
7542 sigemptyset(&sigact.sa_mask);
7543 sigaction(SIGFPE, &sigact, NULL);
7544 sigaction(SIGILL, &sigact, NULL);
7545 sigaction(SIGSEGV, &sigact, NULL);
7546 sigaction(SIGBUS, &sigact, NULL);
7547 sigaction(SIGABRT, &sigact, NULL);
7548 #endif
7551 #ifdef CONFIG_TCC_BCHECK
7552 if (do_bounds_check) {
7553 void (*bound_init)(void);
7555 /* set error function */
7556 rt_bound_error_msg = (void *)tcc_get_symbol(s1, "__bound_error_msg");
7558 /* XXX: use .init section so that it also work in binary ? */
7559 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
7560 bound_init();
7562 #endif
7563 return (*prog_main)(argc, argv);
7566 TCCState *tcc_new(void)
7568 const char *p, *r;
7569 TCCState *s;
7571 s = tcc_mallocz(sizeof(TCCState));
7572 if (!s)
7573 return NULL;
7574 tcc_state = s;
7575 s->output_type = TCC_OUTPUT_MEMORY;
7577 /* default include paths */
7578 tcc_add_sysinclude_path(s, "/usr/local/include");
7579 tcc_add_sysinclude_path(s, "/usr/include");
7580 tcc_add_sysinclude_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
7582 /* add all tokens */
7583 table_ident = NULL;
7584 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
7586 tok_ident = TOK_IDENT;
7587 p = tcc_keywords;
7588 while (*p) {
7589 r = p;
7590 while (*r++);
7591 tok_alloc(p, r - p - 1);
7592 p = r;
7595 /* we add dummy defines for some special macros to speed up tests
7596 and to have working defined() */
7597 sym_push1(&define_stack, TOK___LINE__, MACRO_OBJ, 0);
7598 sym_push1(&define_stack, TOK___FILE__, MACRO_OBJ, 0);
7599 sym_push1(&define_stack, TOK___DATE__, MACRO_OBJ, 0);
7600 sym_push1(&define_stack, TOK___TIME__, MACRO_OBJ, 0);
7602 /* standard defines */
7603 tcc_define_symbol(s, "__STDC__", NULL);
7604 #if defined(TCC_TARGET_I386)
7605 tcc_define_symbol(s, "__i386__", NULL);
7606 #endif
7607 #if defined(linux)
7608 tcc_define_symbol(s, "linux", NULL);
7609 #endif
7610 /* tiny C specific defines */
7611 tcc_define_symbol(s, "__TINYC__", NULL);
7613 /* default library paths */
7614 tcc_add_library_path(s, "/usr/local/lib");
7615 tcc_add_library_path(s, "/usr/lib");
7616 tcc_add_library_path(s, "/lib");
7618 /* no section zero */
7619 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
7621 /* create standard sections */
7622 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
7623 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
7624 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
7626 /* symbols are always generated for linking stage */
7627 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
7628 ".strtab",
7629 ".hashtab", SHF_PRIVATE);
7630 strtab_section = symtab_section->link;
7632 /* private symbol table for dynamic symbols */
7633 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
7634 ".dynstrtab",
7635 ".dynhashtab", SHF_PRIVATE);
7636 return s;
7639 void tcc_delete(TCCState *s1)
7641 int i, n;
7643 /* free -D defines */
7644 free_defines(NULL);
7646 /* free tokens */
7647 n = tok_ident - TOK_IDENT;
7648 for(i = 0; i < n; i++)
7649 tcc_free(table_ident[i]);
7650 tcc_free(table_ident);
7652 /* free all sections */
7654 free_section(symtab_section->hash);
7656 free_section(s1->dynsymtab_section->hash);
7657 free_section(s1->dynsymtab_section->link);
7658 free_section(s1->dynsymtab_section);
7660 for(i = 1; i < s1->nb_sections; i++)
7661 free_section(s1->sections[i]);
7662 tcc_free(s1->sections);
7664 /* free loaded dlls array */
7665 for(i = 0; i < s1->nb_loaded_dlls; i++)
7666 tcc_free(s1->loaded_dlls[i]);
7667 tcc_free(s1->loaded_dlls);
7669 /* library paths */
7670 for(i = 0; i < s1->nb_library_paths; i++)
7671 tcc_free(s1->library_paths[i]);
7672 tcc_free(s1->library_paths);
7674 /* cached includes */
7675 for(i = 0; i < s1->nb_cached_includes; i++)
7676 tcc_free(s1->cached_includes[i]);
7677 tcc_free(s1->cached_includes);
7679 for(i = 0; i < s1->nb_include_paths; i++)
7680 tcc_free(s1->include_paths[i]);
7681 tcc_free(s1->include_paths);
7683 for(i = 0; i < s1->nb_sysinclude_paths; i++)
7684 tcc_free(s1->sysinclude_paths[i]);
7685 tcc_free(s1->sysinclude_paths);
7687 tcc_free(s1);
7690 int tcc_add_include_path(TCCState *s1, const char *pathname)
7692 char *pathname1;
7694 pathname1 = tcc_strdup(pathname);
7695 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
7696 return 0;
7699 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
7701 char *pathname1;
7703 pathname1 = tcc_strdup(pathname);
7704 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
7705 return 0;
7708 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
7710 const char *ext;
7711 Elf32_Ehdr ehdr;
7712 int fd, ret;
7713 BufferedFile *saved_file;
7715 /* find source file type with extension */
7716 ext = strrchr(filename, '.');
7717 if (ext)
7718 ext++;
7720 /* open the file */
7721 saved_file = file;
7722 file = tcc_open(s1, filename);
7723 if (!file) {
7724 if (flags & AFF_PRINT_ERROR) {
7725 error_noabort("file '%s' not found", filename);
7727 ret = -1;
7728 goto fail1;
7731 if (!ext || !strcmp(ext, "c")) {
7732 /* C file assumed */
7733 ret = tcc_compile(s1);
7734 } else {
7735 fd = file->fd;
7736 /* assume executable format: auto guess file type */
7737 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
7738 error_noabort("could not read header");
7739 goto fail;
7741 lseek(fd, 0, SEEK_SET);
7743 if (ehdr.e_ident[0] == ELFMAG0 &&
7744 ehdr.e_ident[1] == ELFMAG1 &&
7745 ehdr.e_ident[2] == ELFMAG2 &&
7746 ehdr.e_ident[3] == ELFMAG3) {
7747 file->line_num = 0; /* do not display line number if error */
7748 if (ehdr.e_type == ET_REL) {
7749 ret = tcc_load_object_file(s1, fd, 0);
7750 } else if (ehdr.e_type == ET_DYN) {
7751 ret = tcc_load_dll(s1, fd, filename,
7752 (flags & AFF_REFERENCED_DLL) != 0);
7753 } else {
7754 error_noabort("unrecognized ELF file");
7755 goto fail;
7757 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
7758 file->line_num = 0; /* do not display line number if error */
7759 ret = tcc_load_archive(s1, fd);
7760 } else {
7761 /* as GNU ld, consider it is an ld script if not recognized */
7762 ret = tcc_load_ldscript(s1);
7763 if (ret < 0) {
7764 error_noabort("unrecognized file type");
7765 goto fail;
7769 the_end:
7770 tcc_close(file);
7771 fail1:
7772 file = saved_file;
7773 return ret;
7774 fail:
7775 ret = -1;
7776 goto the_end;
7779 int tcc_add_file(TCCState *s, const char *filename)
7781 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
7784 int tcc_add_library_path(TCCState *s, const char *pathname)
7786 char *pathname1;
7788 pathname1 = tcc_strdup(pathname);
7789 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
7790 return 0;
7793 /* find and load a dll. Return non zero if not found */
7794 /* XXX: add '-rpath' option support ? */
7795 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
7797 char buf[1024];
7798 int i;
7800 for(i = 0; i < s->nb_library_paths; i++) {
7801 snprintf(buf, sizeof(buf), "%s/%s",
7802 s->library_paths[i], filename);
7803 if (tcc_add_file_internal(s, buf, flags) == 0)
7804 return 0;
7806 return -1;
7809 /* the library name is the same as the argument of the '-l' option */
7810 int tcc_add_library(TCCState *s, const char *libraryname)
7812 char buf[1024];
7813 int i;
7814 void *h;
7816 /* first we look for the dynamic library if not static linking */
7817 if (!s->static_link) {
7818 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
7819 /* if we output to memory, then we simply we dlopen(). */
7820 if (s->output_type == TCC_OUTPUT_MEMORY) {
7821 /* Since the libc is already loaded, we don't need to load it again */
7822 if (!strcmp(libraryname, "c"))
7823 return 0;
7824 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
7825 if (h)
7826 return 0;
7827 } else {
7828 if (tcc_add_dll(s, buf, 0) == 0)
7829 return 0;
7833 /* then we look for the static library */
7834 for(i = 0; i < s->nb_library_paths; i++) {
7835 snprintf(buf, sizeof(buf), "%s/lib%s.a",
7836 s->library_paths[i], libraryname);
7837 if (tcc_add_file_internal(s, buf, 0) == 0)
7838 return 0;
7840 return -1;
7843 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
7845 add_elf_sym(symtab_section, val, 0,
7846 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7847 SHN_ABS, name);
7848 return 0;
7851 int tcc_set_output_type(TCCState *s, int output_type)
7853 s->output_type = output_type;
7855 /* if bound checking, then add corresponding sections */
7856 #ifdef CONFIG_TCC_BCHECK
7857 if (do_bounds_check) {
7858 /* define symbol */
7859 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
7860 /* create bounds sections */
7861 bounds_section = new_section(s, ".bounds",
7862 SHT_PROGBITS, SHF_ALLOC);
7863 lbounds_section = new_section(s, ".lbounds",
7864 SHT_PROGBITS, SHF_ALLOC);
7866 #endif
7868 /* add debug sections */
7869 if (do_debug) {
7870 /* stab symbols */
7871 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
7872 stab_section->sh_entsize = sizeof(Stab_Sym);
7873 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
7874 put_elf_str(stabstr_section, "");
7875 stab_section->link = stabstr_section;
7876 /* put first entry */
7877 put_stabs("", 0, 0, 0, 0);
7880 /* add libc crt1/crti objects */
7881 if (output_type == TCC_OUTPUT_EXE ||
7882 output_type == TCC_OUTPUT_DLL) {
7883 if (output_type != TCC_OUTPUT_DLL)
7884 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
7885 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
7887 return 0;
7890 #if !defined(LIBTCC)
7892 void help(void)
7894 printf("tcc version 0.9.13 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7895 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7896 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
7897 " [--] infile1 [infile2... --] [infile_args...]\n"
7898 "\n"
7899 "General options:\n"
7900 " -c compile only - generate an object file\n"
7901 " -o outfile set output filename\n"
7902 " -- allows multiples input files if no -o option given. Also\n"
7903 " separate input files from runtime arguments\n"
7904 " -Bdir set tcc internal library path\n"
7905 " -bench output compilation statistics\n"
7906 "Preprocessor options:\n"
7907 " -Idir add include path 'dir'\n"
7908 " -Dsym[=val] define 'sym' with value 'val'\n"
7909 " -Usym undefine 'sym'\n"
7910 "Linker options:\n"
7911 " -Ldir add library path 'dir'\n"
7912 " -llib link with dynamic or static library 'lib'\n"
7913 " -shared generate a shared library\n"
7914 " -static static linking\n"
7915 " -r relocatable output\n"
7916 "Debugger options:\n"
7917 " -g generate runtime debug info\n"
7918 #ifdef CONFIG_TCC_BCHECK
7919 " -b compile with built-in memory and bounds checker (implies -g)\n"
7920 #endif
7921 " -bt N show N callers in stack traces\n"
7925 int main(int argc, char **argv)
7927 char *r, *outfile;
7928 int optind, output_type, multiple_files, i, reloc_output;
7929 TCCState *s;
7930 char **files;
7931 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
7932 char objfilename[1024];
7934 s = tcc_new();
7935 output_type = TCC_OUTPUT_MEMORY;
7937 optind = 1;
7938 outfile = NULL;
7939 multiple_files = 0;
7940 dminus = 0;
7941 files = NULL;
7942 nb_files = 0;
7943 nb_libraries = 0;
7944 reloc_output = 0;
7945 while (1) {
7946 if (optind >= argc) {
7947 if (nb_files == 0)
7948 goto show_help;
7949 else
7950 break;
7952 r = argv[optind++];
7953 if (r[0] != '-') {
7954 /* add a new file */
7955 dynarray_add((void ***)&files, &nb_files, r);
7956 if (!multiple_files) {
7957 optind--;
7958 /* argv[0] will be this file */
7959 break;
7961 } else if (r[1] == '-') {
7962 /* '--' enables multiple files input and also ends several file input */
7963 if (dminus && multiple_files) {
7964 optind--; /* argv[0] will be '--' */
7965 break;
7967 dminus = 1;
7968 multiple_files = 1;
7969 } else if (r[1] == 'h' || r[1] == '?') {
7970 show_help:
7971 help();
7972 return 1;
7973 } else if (r[1] == 'I') {
7974 if (tcc_add_include_path(s, r + 2) < 0)
7975 error("too many include paths");
7976 } else if (r[1] == 'D') {
7977 char *sym, *value;
7978 sym = r + 2;
7979 value = strchr(sym, '=');
7980 if (value) {
7981 *value = '\0';
7982 value++;
7984 tcc_define_symbol(s, sym, value);
7985 } else if (r[1] == 'U') {
7986 tcc_undefine_symbol(s, r + 2);
7987 } else if (r[1] == 'L') {
7988 tcc_add_library_path(s, r + 2);
7989 } else if (r[1] == 'B') {
7990 /* set tcc utilities path (mainly for tcc development) */
7991 tcc_lib_path = r + 2;
7992 } else if (r[1] == 'l') {
7993 dynarray_add((void ***)&files, &nb_files, r);
7994 nb_libraries++;
7995 } else if (!strcmp(r + 1, "bench")) {
7996 do_bench = 1;
7997 } else if (!strcmp(r + 1, "bt")) {
7998 num_callers = atoi(argv[optind++]);
7999 } else
8000 #ifdef CONFIG_TCC_BCHECK
8001 if (r[1] == 'b') {
8002 do_bounds_check = 1;
8003 do_debug = 1;
8004 } else
8005 #endif
8006 if (r[1] == 'g') {
8007 do_debug = 1;
8008 } else if (r[1] == 'c') {
8009 multiple_files = 1;
8010 output_type = TCC_OUTPUT_OBJ;
8011 } else if (!strcmp(r + 1, "static")) {
8012 s->static_link = 1;
8013 } else if (!strcmp(r + 1, "shared")) {
8014 output_type = TCC_OUTPUT_DLL;
8015 } else if (r[1] == 'o') {
8016 if (optind >= argc)
8017 goto show_help;
8018 multiple_files = 1;
8019 outfile = argv[optind++];
8020 } else if (r[1] == 'r') {
8021 /* generate a .o merging several output files */
8022 reloc_output = 1;
8023 output_type = TCC_OUTPUT_OBJ;
8024 } else if (r[1] == 'W' || r[1] == 'O' || r[1] == 'm' || r[1] == 'f') {
8025 /* ignore those options to be a drop-in replacement for gcc */
8026 } else {
8027 error("invalid option -- '%s'", r);
8031 nb_objfiles = nb_files - nb_libraries;
8033 /* if outfile provided without other options, we output an
8034 executable */
8035 if (outfile && output_type == TCC_OUTPUT_MEMORY)
8036 output_type = TCC_OUTPUT_EXE;
8038 /* check -c consistency : only single file handled. XXX: checks file type */
8039 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
8040 /* accepts only a single input file */
8041 if (nb_objfiles != 1)
8042 error("cannot specify multiple files with -c");
8043 if (nb_libraries != 0)
8044 error("cannot specify libraries with -c");
8047 /* compute default outfile name */
8048 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
8049 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
8050 char *ext;
8051 /* add .o extension */
8052 pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
8053 ext = strrchr(objfilename, '.');
8054 if (!ext)
8055 goto default_outfile;
8056 strcpy(ext + 1, "o");
8057 } else {
8058 default_outfile:
8059 pstrcpy(objfilename, sizeof(objfilename), "a.out");
8061 outfile = objfilename;
8064 tcc_set_output_type(s, output_type);
8066 /* compile or add each files or library */
8067 for(i = 0;i < nb_files; i++) {
8068 const char *filename;
8070 filename = files[i];
8071 if (filename[0] == '-') {
8072 if (tcc_add_library(s, filename + 2) < 0)
8073 error("cannot find %s", filename);
8074 } else {
8075 if (tcc_add_file(s, filename) < 0) {
8076 ret = 1;
8077 goto the_end;
8082 /* free all files */
8083 tcc_free(files);
8085 if (do_bench) {
8086 printf("total: %d idents, %d lines, %d bytes\n",
8087 tok_ident - TOK_IDENT, total_lines, total_bytes);
8090 if (s->output_type != TCC_OUTPUT_MEMORY) {
8091 tcc_output_file(s, outfile);
8092 ret = 0;
8093 } else {
8094 ret = tcc_run(s, argc - optind, argv + optind);
8096 the_end:
8097 /* XXX: cannot do it with bound checking because of the malloc hooks */
8098 if (!do_bounds_check)
8099 tcc_delete(s);
8101 #ifdef MEM_DEBUG
8102 if (do_bench) {
8103 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
8105 #endif
8106 return ret;
8109 #endif