added linux define - added __FUNCTION - fixed spaces parsing - defined special macros
[tinycc/miki.git] / tcc.c
blobddd18822f055e7af4b87875f67a07a50c6c83200
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <math.h>
26 #include <unistd.h>
27 #include <signal.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #ifndef WIN32
31 #include <sys/ucontext.h>
32 #endif
33 #include "elf.h"
34 #include "stab.h"
35 #ifndef CONFIG_TCC_STATIC
36 #include <dlfcn.h>
37 #endif
39 #include "libtcc.h"
41 //#define DEBUG
42 /* preprocessor debug */
43 //#define PP_DEBUG
45 //#define MEM_DEBUG
47 /* target selection */
48 //#define TCC_TARGET_I386 /* i386 code generator */
49 //#define TCC_TARGET_IL /* .NET CLI generator */
51 /* default target is I386 */
52 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
53 #define TCC_TARGET_I386
54 #endif
56 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
57 #define CONFIG_TCC_BCHECK /* enable bound checking code */
58 #endif
60 #ifndef CONFIG_TCC_PREFIX
61 #define CONFIG_TCC_PREFIX "/usr/local"
62 #endif
64 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
65 executables or dlls */
66 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
68 #define INCLUDE_STACK_SIZE 32
69 #define IFDEF_STACK_SIZE 64
70 #define VSTACK_SIZE 64
71 #define STRING_MAX_SIZE 1024
73 #define TOK_HASH_SIZE 2048 /* must be a power of two */
74 #define TOK_ALLOC_INCR 512 /* must be a power of two */
75 #define SYM_HASH_SIZE 1031
77 /* token symbol management */
78 typedef struct TokenSym {
79 struct TokenSym *hash_next;
80 int tok; /* token number */
81 int len;
82 char str[1];
83 } TokenSym;
85 typedef struct CString {
86 int size; /* size in bytes */
87 void *data; /* either 'char *' or 'int *' */
88 int size_allocated;
89 void *data_allocated; /* if non NULL, data has been malloced */
90 } CString;
92 /* constant value */
93 typedef union CValue {
94 long double ld;
95 double d;
96 float f;
97 int i;
98 unsigned int ui;
99 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
100 long long ll;
101 unsigned long long ull;
102 struct CString *cstr;
103 struct Sym *sym;
104 void *ptr;
105 int tab[1];
106 } CValue;
108 /* value on stack */
109 typedef struct SValue {
110 int t; /* type */
111 unsigned short r; /* register + flags */
112 unsigned short r2; /* second register, used for 'long long'
113 type. If not used, set to VT_CONST */
114 CValue c; /* constant, if VT_CONST */
115 } SValue;
117 /* symbol management */
118 typedef struct Sym {
119 int v; /* symbol token */
120 int t; /* associated type */
121 int r; /* associated register */
122 int c; /* associated number */
123 struct Sym *next; /* next related symbol */
124 struct Sym *prev; /* prev symbol in stack */
125 struct Sym *hash_next; /* next symbol in hash table */
126 } Sym;
128 typedef struct SymStack {
129 struct Sym *top;
130 struct Sym *hash[SYM_HASH_SIZE];
131 } SymStack;
133 /* section definition */
134 /* XXX: use directly ELF structure for parameters ? */
135 /* special flag to indicate that the section should not be linked to
136 the other ones */
137 #define SHF_PRIVATE 0x80000000
139 typedef struct Section {
140 unsigned long data_offset; /* current data offset */
141 unsigned char *data; /* section data */
142 unsigned long data_allocated; /* used for realloc() handling */
143 int sh_name; /* elf section name (only used during output) */
144 int sh_num; /* elf section number */
145 int sh_type; /* elf section type */
146 int sh_flags; /* elf section flags */
147 int sh_info; /* elf section info */
148 int sh_addralign; /* elf section alignment */
149 int sh_entsize; /* elf entry size */
150 unsigned long sh_size; /* section size (only used during output) */
151 unsigned long sh_addr; /* address at which the section is relocated */
152 unsigned long sh_offset; /* address at which the section is relocated */
153 int nb_hashed_syms; /* used to resize the hash table */
154 struct Section *link; /* link to another section */
155 struct Section *reloc; /* corresponding section for relocation, if any */
156 struct Section *hash; /* hash table for symbols */
157 struct Section *next;
158 char name[64]; /* section name */
159 } Section;
161 typedef struct DLLReference {
162 int level;
163 char name[1];
164 } DLLReference;
166 /* GNUC attribute definition */
167 typedef struct AttributeDef {
168 int aligned;
169 Section *section;
170 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
171 } AttributeDef;
173 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
174 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
175 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
177 /* stored in 'Sym.c' field */
178 #define FUNC_NEW 1 /* ansi function prototype */
179 #define FUNC_OLD 2 /* old function prototype */
180 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
182 /* stored in 'Sym.r' field */
183 #define FUNC_CDECL 0 /* standard c call */
184 #define FUNC_STDCALL 1 /* pascal c call */
186 /* field 'Sym.t' for macros */
187 #define MACRO_OBJ 0 /* object like macro */
188 #define MACRO_FUNC 1 /* function like macro */
190 /* field 'Sym.t' for labels */
191 #define LABEL_FORWARD 1 /* label is forward defined */
193 /* type_decl() types */
194 #define TYPE_ABSTRACT 1 /* type without variable */
195 #define TYPE_DIRECT 2 /* type with variable */
197 #define IO_BUF_SIZE 8192
199 typedef struct BufferedFile {
200 unsigned char *buf_ptr;
201 unsigned char *buf_end;
202 int fd;
203 int line_num; /* current line number - here to simply code */
204 char filename[1024]; /* current filename - here to simplify code */
205 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
206 } BufferedFile;
208 #define CH_EOB 0 /* end of buffer or '\0' char in file */
209 #define CH_EOF (-1) /* end of file */
211 /* parsing state (used to save parser state to reparse part of the
212 source several times) */
213 typedef struct ParseState {
214 int *macro_ptr;
215 int line_num;
216 int tok;
217 CValue tokc;
218 } ParseState;
220 /* used to record tokens */
221 typedef struct TokenString {
222 int *str;
223 int len;
224 int last_line_num;
225 } TokenString;
227 /* parser */
228 struct BufferedFile *file;
229 int ch, ch1, tok, tok1;
230 CValue tokc, tok1c;
231 CString tokcstr; /* current parsed string, if any */
232 int return_linefeed; /* if true, line feed is returned as a token */
234 /* sections */
235 Section **sections;
236 int nb_sections; /* number of sections, including first dummy section */
237 Section *text_section, *data_section, *bss_section; /* predefined sections */
238 Section *cur_text_section; /* current section where function code is
239 generated */
240 /* bound check related sections */
241 Section *bounds_section; /* contains global data bound description */
242 Section *lbounds_section; /* contains local data bound description */
243 /* symbol sections */
244 Section *symtab_section, *strtab_section;
245 /* temporary dynamic symbol sections (for dll loading) */
246 Section *dynsymtab_section;
247 /* exported dynamic symbol section */
248 Section *dynsym;
249 /* got handling */
250 Section *got;
251 unsigned long *got_offsets;
252 int nb_got_offsets;
253 int nb_plt_entries;
254 /* give the correspondance from symtab indexes to dynsym indexes */
255 int *symtab_to_dynsym;
257 /* array of all loaded dlls (including those referenced by loaded
258 dlls) */
259 DLLReference **loaded_dlls;
260 int nb_loaded_dlls;
262 /* debug sections */
263 Section *stab_section, *stabstr_section;
265 char **library_paths;
266 int nb_library_paths;
268 /* loc : local variable index
269 ind : output code index
270 rsym: return symbol
271 anon_sym: anonymous symbol index
273 int rsym, anon_sym,
274 prog, ind, loc, const_wanted;
275 int global_expr; /* true if compound literals must be allocated
276 globally (used during initializers parsing */
277 int func_vt, func_vc; /* current function return type (used by
278 return instruction) */
279 int last_line_num, last_ind, func_ind; /* debug last line number and pc */
280 int tok_ident;
281 TokenSym **table_ident;
282 TokenSym *hash_ident[TOK_HASH_SIZE];
283 char token_buf[STRING_MAX_SIZE + 1];
284 char *funcname;
285 SymStack define_stack, global_stack, local_stack, label_stack;
287 SValue vstack[VSTACK_SIZE], *vtop;
288 int *macro_ptr, *macro_ptr_allocated;
289 BufferedFile *include_stack[INCLUDE_STACK_SIZE], **include_stack_ptr;
290 int ifdef_stack[IFDEF_STACK_SIZE], *ifdef_stack_ptr;
291 char **include_paths;
292 int nb_include_paths;
293 char **sysinclude_paths;
294 int nb_sysinclude_paths;
295 int char_pointer_type;
296 int func_old_type;
298 /* compile with debug symbol (and use them if error during execution) */
299 int do_debug = 0;
301 /* compile with built-in memory and bounds checker */
302 int do_bounds_check = 0;
304 /* display benchmark infos */
305 int do_bench = 0;
306 int total_lines;
307 int total_bytes;
309 /* use GNU C extensions */
310 int gnu_ext = 1;
312 /* use Tiny C extensions */
313 int tcc_ext = 1;
315 /* if true, static linking is performed */
316 int static_link = 0;
318 /* give the path of the tcc libraries */
319 static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc";
321 struct TCCState {
322 int output_type;
325 /* The current value can be: */
326 #define VT_VALMASK 0x00ff
327 #define VT_CONST 0x00f0 /* constant in vc
328 (must be first non register value) */
329 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
330 #define VT_LOCAL 0x00f2 /* offset on stack */
331 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
332 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
333 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
334 #define VT_LVAL 0x0100 /* var is an lvalue */
335 #define VT_SYM 0x0200 /* a symbol value is added */
336 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
337 char/short stored in integer registers) */
338 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
339 dereferencing value */
340 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
341 bounding function call point is in vc */
342 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
343 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
344 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
345 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
347 /* types */
348 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
350 #define VT_INT 0 /* integer type */
351 #define VT_BYTE 1 /* signed byte type */
352 #define VT_SHORT 2 /* short type */
353 #define VT_VOID 3 /* void type */
354 #define VT_PTR 4 /* pointer */
355 #define VT_ENUM 5 /* enum definition */
356 #define VT_FUNC 6 /* function type */
357 #define VT_STRUCT 7 /* struct/union definition */
358 #define VT_FLOAT 8 /* IEEE float */
359 #define VT_DOUBLE 9 /* IEEE double */
360 #define VT_LDOUBLE 10 /* IEEE long double */
361 #define VT_BOOL 11 /* ISOC99 boolean type */
362 #define VT_LLONG 12 /* 64 bit integer */
363 #define VT_LONG 13 /* long integer (NEVER USED as type, only
364 during parsing) */
365 #define VT_BTYPE 0x000f /* mask for basic type */
366 #define VT_UNSIGNED 0x0010 /* unsigned type */
367 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
368 #define VT_BITFIELD 0x0040 /* bitfield modifier */
370 /* storage */
371 #define VT_EXTERN 0x00000080 /* extern definition */
372 #define VT_STATIC 0x00000100 /* static variable */
373 #define VT_TYPEDEF 0x00000200 /* typedef definition */
375 /* type mask (except storage) */
376 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
378 /* token values */
380 /* warning: the following compare tokens depend on i386 asm code */
381 #define TOK_ULT 0x92
382 #define TOK_UGE 0x93
383 #define TOK_EQ 0x94
384 #define TOK_NE 0x95
385 #define TOK_ULE 0x96
386 #define TOK_UGT 0x97
387 #define TOK_LT 0x9c
388 #define TOK_GE 0x9d
389 #define TOK_LE 0x9e
390 #define TOK_GT 0x9f
392 #define TOK_LAND 0xa0
393 #define TOK_LOR 0xa1
395 #define TOK_DEC 0xa2
396 #define TOK_MID 0xa3 /* inc/dec, to void constant */
397 #define TOK_INC 0xa4
398 #define TOK_UDIV 0xb0 /* unsigned division */
399 #define TOK_UMOD 0xb1 /* unsigned modulo */
400 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
401 #define TOK_CINT 0xb3 /* number in tokc */
402 #define TOK_CCHAR 0xb4 /* char constant in tokc */
403 #define TOK_STR 0xb5 /* pointer to string in tokc */
404 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
405 #define TOK_LCHAR 0xb7
406 #define TOK_LSTR 0xb8
407 #define TOK_CFLOAT 0xb9 /* float constant */
408 #define TOK_LINENUM 0xba /* line number info */
409 #define TOK_CDOUBLE 0xc0 /* double constant */
410 #define TOK_CLDOUBLE 0xc1 /* long double constant */
411 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
412 #define TOK_ADDC1 0xc3 /* add with carry generation */
413 #define TOK_ADDC2 0xc4 /* add with carry use */
414 #define TOK_SUBC1 0xc5 /* add with carry generation */
415 #define TOK_SUBC2 0xc6 /* add with carry use */
416 #define TOK_CUINT 0xc8 /* unsigned int constant */
417 #define TOK_CLLONG 0xc9 /* long long constant */
418 #define TOK_CULLONG 0xca /* unsigned long long constant */
419 #define TOK_ARROW 0xcb
420 #define TOK_DOTS 0xcc /* three dots */
421 #define TOK_SHR 0xcd /* unsigned shift right */
423 #define TOK_SHL 0x01 /* shift left */
424 #define TOK_SAR 0x02 /* signed shift right */
426 /* assignement operators : normal operator or 0x80 */
427 #define TOK_A_MOD 0xa5
428 #define TOK_A_AND 0xa6
429 #define TOK_A_MUL 0xaa
430 #define TOK_A_ADD 0xab
431 #define TOK_A_SUB 0xad
432 #define TOK_A_DIV 0xaf
433 #define TOK_A_XOR 0xde
434 #define TOK_A_OR 0xfc
435 #define TOK_A_SHL 0x81
436 #define TOK_A_SAR 0x82
438 /* WARNING: the content of this string encodes token numbers */
439 static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
441 #define TOK_EOF (-1) /* end of file */
442 #define TOK_LINEFEED 10 /* line feed */
444 /* all identificators and strings have token above that */
445 #define TOK_IDENT 256
447 enum {
448 TOK_INT = TOK_IDENT,
449 TOK_VOID,
450 TOK_CHAR,
451 TOK_IF,
452 TOK_ELSE,
453 TOK_WHILE,
454 TOK_BREAK,
455 TOK_RETURN,
456 TOK_FOR,
457 TOK_EXTERN,
458 TOK_STATIC,
459 TOK_UNSIGNED,
460 TOK_GOTO,
461 TOK_DO,
462 TOK_CONTINUE,
463 TOK_SWITCH,
464 TOK_CASE,
466 /* ignored types Must have contiguous values */
467 TOK_CONST,
468 TOK_VOLATILE,
469 TOK_LONG,
470 TOK_REGISTER,
471 TOK_SIGNED,
472 TOK___SIGNED__, /* gcc keyword */
473 TOK_AUTO,
474 TOK_INLINE,
475 TOK___INLINE__, /* gcc keyword */
476 TOK_RESTRICT,
478 /* unsupported type */
479 TOK_FLOAT,
480 TOK_DOUBLE,
481 TOK_BOOL,
483 TOK_SHORT,
484 TOK_STRUCT,
485 TOK_UNION,
486 TOK_TYPEDEF,
487 TOK_DEFAULT,
488 TOK_ENUM,
489 TOK_SIZEOF,
490 TOK___ATTRIBUTE__,
492 /* preprocessor only */
493 TOK_UIDENT, /* first "user" ident (not keyword) */
494 TOK_DEFINE = TOK_UIDENT,
495 TOK_INCLUDE,
496 TOK_IFDEF,
497 TOK_IFNDEF,
498 TOK_ELIF,
499 TOK_ENDIF,
500 TOK_DEFINED,
501 TOK_UNDEF,
502 TOK_ERROR,
503 TOK_LINE,
505 #define DEF(id, str) id,
506 #include "tcctok.h"
507 #undef DEF
510 char *tcc_keywords =
511 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
512 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
513 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
514 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
515 "sizeof\0__attribute__\0"
516 /* the following are not keywords. They are included to ease parsing */
517 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
518 "defined\0undef\0error\0line\0"
519 /* builtin functions */
520 #define DEF(id, str) str "\0"
521 #include "tcctok.h"
522 #undef DEF
525 #ifdef WIN32
526 #define snprintf _snprintf
527 #endif
529 #if defined(WIN32) || defined(TCC_UCLIBC)
530 /* currently incorrect */
531 long double strtold(const char *nptr, char **endptr)
533 return (long double)strtod(nptr, endptr);
535 float strtof(const char *nptr, char **endptr)
537 return (float)strtod(nptr, endptr);
539 #else
540 /* XXX: need to define this to use them in non ISOC99 context */
541 extern float strtof (const char *__nptr, char **__endptr);
542 extern long double strtold (const char *__nptr, char **__endptr);
543 #endif
545 static char *pstrcpy(char *buf, int buf_size, const char *s);
546 static char *pstrcat(char *buf, int buf_size, const char *s);
548 void sum(int l);
549 void next(void);
550 void next_nomacro(void);
551 int expr_const(void);
552 void expr_eq(void);
553 void gexpr(void);
554 void decl(int l);
555 static void decl_initializer(int t, Section *sec, unsigned long c,
556 int first, int size_only);
557 static void decl_initializer_alloc(int t, AttributeDef *ad, int r,
558 int has_init, int v, int scope);
559 int gv(int rc);
560 void gv2(int rc1, int rc2);
561 void move_reg(int r, int s);
562 void save_regs(int n);
563 void save_reg(int r);
564 void vpop(void);
565 void vswap(void);
566 void vdup(void);
567 int get_reg(int rc);
569 void macro_subst(TokenString *tok_str,
570 Sym **nested_list, int *macro_str);
571 int save_reg_forced(int r);
572 void gen_op(int op);
573 void force_charshort_cast(int t);
574 void gen_cast(int t);
575 void vstore(void);
576 Sym *sym_find(int v);
577 Sym *sym_push(int v, int t, int r, int c);
579 /* type handling */
580 int type_size(int t, int *a);
581 int pointed_type(int t);
582 int pointed_size(int t);
583 static int lvalue_type(int t);
584 int is_compatible_types(int t1, int t2);
585 int parse_btype(int *type_ptr, AttributeDef *ad);
586 int type_decl(AttributeDef *ad, int *v, int t, int td);
588 void error(const char *fmt, ...);
589 void rt_error(unsigned long pc, const char *fmt, ...);
590 void vpushi(int v);
591 void vset(int t, int r, int v);
592 void type_to_str(char *buf, int buf_size,
593 int t, const char *varstr);
594 char *get_tok_str(int v, CValue *cv);
595 Sym *external_sym(int v, int u, int r);
596 static Sym *get_sym_ref(int t, Section *sec,
597 unsigned long offset, unsigned long size);
599 /* section generation */
600 static void section_realloc(Section *sec, unsigned long new_size);
601 static void *section_ptr_add(Section *sec, unsigned long size);
602 static void put_extern_sym(Sym *sym, Section *section,
603 unsigned long value, unsigned long size);
604 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
605 static int put_elf_str(Section *s, const char *sym);
606 static int put_elf_sym(Section *s,
607 unsigned long value, unsigned long size,
608 int info, int other, int shndx, const char *name);
609 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
610 int info, int sh_num, const char *name);
611 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
612 int type, int symbol);
613 static void put_stabs(const char *str, int type, int other, int desc,
614 unsigned long value);
615 static void put_stabs_r(const char *str, int type, int other, int desc,
616 unsigned long value, Section *sec, int sym_index);
617 static void put_stabn(int type, int other, int desc, int value);
618 static void put_stabd(int type, int other, int desc);
619 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
621 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
622 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
623 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
625 /* true if float/double/long double type */
626 static inline int is_float(int t)
628 int bt;
629 bt = t & VT_BTYPE;
630 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
633 #ifdef TCC_TARGET_I386
634 #include "i386-gen.c"
635 #endif
636 #ifdef TCC_TARGET_IL
637 #include "il-gen.c"
638 #endif
640 #ifdef CONFIG_TCC_STATIC
642 #define RTLD_LAZY 0x001
643 #define RTLD_NOW 0x002
644 #define RTLD_GLOBAL 0x100
646 /* dummy function for profiling */
647 void *dlopen(const char *filename, int flag)
649 return NULL;
652 const char *dlerror(void)
654 return "error";
657 typedef struct TCCSyms {
658 char *str;
659 void *ptr;
660 } TCCSyms;
662 #define TCCSYM(a) { #a, &a, },
664 /* add the symbol you want here if no dynamic linking is done */
665 static TCCSyms tcc_syms[] = {
666 TCCSYM(printf)
667 TCCSYM(fprintf)
668 TCCSYM(fopen)
669 TCCSYM(fclose)
670 { NULL, NULL },
673 void *dlsym(void *handle, const char *symbol)
675 TCCSyms *p;
676 p = tcc_syms;
677 while (p->str != NULL) {
678 if (!strcmp(p->str, symbol))
679 return p->ptr;
680 p++;
682 return NULL;
685 #endif
687 /********************************************************/
689 /* we use our own 'finite' function to avoid potential problems with
690 non standard math libs */
691 /* XXX: endianness dependant */
692 int ieee_finite(double d)
694 int *p = (int *)&d;
695 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
698 /* copy a string and truncate it. */
699 static char *pstrcpy(char *buf, int buf_size, const char *s)
701 char *q, *q_end;
702 int c;
704 if (buf_size > 0) {
705 q = buf;
706 q_end = buf + buf_size - 1;
707 while (q < q_end) {
708 c = *s++;
709 if (c == '\0')
710 break;
711 *q++ = c;
713 *q = '\0';
715 return buf;
718 /* strcat and truncate. */
719 static char *pstrcat(char *buf, int buf_size, const char *s)
721 int len;
722 len = strlen(buf);
723 if (len < buf_size)
724 pstrcpy(buf + len, buf_size - len, s);
725 return buf;
728 /* memory management */
729 #ifdef MEM_DEBUG
730 int mem_cur_size;
731 int mem_max_size;
732 #endif
734 static inline void tcc_free(void *ptr)
736 #ifdef MEM_DEBUG
737 mem_cur_size -= malloc_usable_size(ptr);
738 #endif
739 free(ptr);
742 static void *tcc_malloc(unsigned long size)
744 void *ptr;
745 ptr = malloc(size);
746 if (!ptr)
747 error("memory full");
748 #ifdef MEM_DEBUG
749 mem_cur_size += malloc_usable_size(ptr);
750 if (mem_cur_size > mem_max_size)
751 mem_max_size = mem_cur_size;
752 #endif
753 return ptr;
756 static void *tcc_mallocz(unsigned long size)
758 void *ptr;
759 ptr = tcc_malloc(size);
760 memset(ptr, 0, size);
761 return ptr;
764 static inline void *tcc_realloc(void *ptr, unsigned long size)
766 void *ptr1;
767 #ifdef MEM_DEBUG
768 mem_cur_size -= malloc_usable_size(ptr);
769 #endif
770 ptr1 = realloc(ptr, size);
771 #ifdef MEM_DEBUG
772 /* NOTE: count not correct if alloc error, but not critical */
773 mem_cur_size += malloc_usable_size(ptr1);
774 if (mem_cur_size > mem_max_size)
775 mem_max_size = mem_cur_size;
776 #endif
777 return ptr1;
780 static char *tcc_strdup(const char *str)
782 char *ptr;
783 ptr = tcc_malloc(strlen(str) + 1);
784 strcpy(ptr, str);
785 return ptr;
788 #define free(p) use_tcc_free(p)
789 #define malloc(s) use_tcc_malloc(s)
790 #define realloc(p, s) use_tcc_realloc(p, s)
792 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
794 int nb, nb_alloc;
795 void **pp;
797 nb = *nb_ptr;
798 pp = *ptab;
799 /* every power of two we double array size */
800 if ((nb & (nb - 1)) == 0) {
801 if (!nb)
802 nb_alloc = 1;
803 else
804 nb_alloc = nb * 2;
805 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
806 if (!pp)
807 error("memory full");
808 *ptab = pp;
810 pp[nb++] = data;
811 *nb_ptr = nb;
814 Section *new_section(const char *name, int sh_type, int sh_flags)
816 Section *sec;
818 sec = tcc_mallocz(sizeof(Section));
819 pstrcpy(sec->name, sizeof(sec->name), name);
820 sec->sh_type = sh_type;
821 sec->sh_flags = sh_flags;
822 switch(sh_type) {
823 case SHT_HASH:
824 case SHT_REL:
825 case SHT_DYNSYM:
826 case SHT_SYMTAB:
827 case SHT_DYNAMIC:
828 sec->sh_addralign = 4;
829 break;
830 case SHT_STRTAB:
831 sec->sh_addralign = 1;
832 break;
833 default:
834 sec->sh_addralign = 32; /* default conservative alignment */
835 break;
838 /* only add section if not private */
839 if (!(sh_flags & SHF_PRIVATE)) {
840 sec->sh_num = nb_sections;
841 dynarray_add((void ***)&sections, &nb_sections, sec);
843 return sec;
846 /* realloc section and set its content to zero */
847 static void section_realloc(Section *sec, unsigned long new_size)
849 unsigned long size;
850 unsigned char *data;
852 size = sec->data_allocated;
853 if (size == 0)
854 size = 1;
855 while (size < new_size)
856 size = size * 2;
857 data = tcc_realloc(sec->data, size);
858 if (!data)
859 error("memory full");
860 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
861 sec->data = data;
862 sec->data_allocated = size;
865 /* reserve at least 'size' bytes in section 'sec' from
866 sec->data_offset. */
867 static void *section_ptr_add(Section *sec, unsigned long size)
869 unsigned long offset, offset1;
871 offset = sec->data_offset;
872 offset1 = offset + size;
873 if (offset1 > sec->data_allocated)
874 section_realloc(sec, offset1);
875 sec->data_offset = offset1;
876 return sec->data + offset;
879 /* return a reference to a section, and create it if it does not
880 exists */
881 Section *find_section(const char *name)
883 Section *sec;
884 int i;
885 for(i = 1; i < nb_sections; i++) {
886 sec = sections[i];
887 if (!strcmp(name, sec->name))
888 return sec;
890 /* sections are created as PROGBITS */
891 return new_section(name, SHT_PROGBITS, SHF_ALLOC);
894 /* update sym->c so that it points to an external symbol in section
895 'section' with value 'value' */
896 static void put_extern_sym(Sym *sym, Section *section,
897 unsigned long value, unsigned long size)
899 int sym_type, sym_bind, sh_num, info;
900 Elf32_Sym *esym;
901 const char *name;
902 char buf[32];
904 if (section)
905 sh_num = section->sh_num;
906 else
907 sh_num = SHN_UNDEF;
908 if (!sym->c) {
909 if ((sym->t & VT_BTYPE) == VT_FUNC)
910 sym_type = STT_FUNC;
911 else
912 sym_type = STT_OBJECT;
913 if (sym->t & VT_STATIC)
914 sym_bind = STB_LOCAL;
915 else
916 sym_bind = STB_GLOBAL;
918 name = get_tok_str(sym->v, NULL);
919 #ifdef CONFIG_TCC_BCHECK
920 if (do_bounds_check) {
921 /* if bound checking is activated, we change some function
922 names by adding the "__bound" prefix */
923 switch(sym->v) {
924 case TOK_malloc:
925 case TOK_free:
926 case TOK_realloc:
927 case TOK_memalign:
928 case TOK_calloc:
929 case TOK_memcpy:
930 case TOK_memmove:
931 case TOK_memset:
932 case TOK_strlen:
933 case TOK_strcpy:
934 strcpy(buf, "__bound_");
935 strcat(buf, name);
936 name = buf;
937 break;
940 #endif
941 info = ELF32_ST_INFO(sym_bind, sym_type);
942 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
943 } else {
944 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
945 esym->st_value = value;
946 esym->st_size = size;
947 esym->st_shndx = sh_num;
951 /* add a new relocation entry to symbol 'sym' in section 's' */
952 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
954 if (!sym->c)
955 put_extern_sym(sym, NULL, 0, 0);
956 /* now we can add ELF relocation info */
957 put_elf_reloc(symtab_section, s, offset, type, sym->c);
960 static inline int isid(int c)
962 return (c >= 'a' && c <= 'z') ||
963 (c >= 'A' && c <= 'Z') ||
964 c == '_';
967 static inline int isnum(int c)
969 return c >= '0' && c <= '9';
972 static inline int toup(int c)
974 if (ch >= 'a' && ch <= 'z')
975 return ch - 'a' + 'A';
976 else
977 return ch;
980 void printline(void)
982 BufferedFile **f;
984 if (file) {
985 for(f = include_stack; f < include_stack_ptr; f++)
986 fprintf(stderr, "In file included from %s:%d:\n",
987 (*f)->filename, (*f)->line_num);
988 if (file->line_num > 0) {
989 fprintf(stderr, "%s:%d: ", file->filename, file->line_num);
990 } else {
991 fprintf(stderr, "%s: ", file->filename);
993 } else {
994 fprintf(stderr, "tcc: ");
998 void error(const char *fmt, ...)
1000 va_list ap;
1001 va_start(ap, fmt);
1002 printline();
1003 vfprintf(stderr, fmt, ap);
1004 fprintf(stderr, "\n");
1005 exit(1);
1006 va_end(ap);
1009 void expect(const char *msg)
1011 error("%s expected", msg);
1014 void warning(const char *fmt, ...)
1016 va_list ap;
1018 va_start(ap, fmt);
1019 printline();
1020 fprintf(stderr, "warning: ");
1021 vfprintf(stderr, fmt, ap);
1022 fprintf(stderr, "\n");
1023 va_end(ap);
1026 void skip(int c)
1028 if (tok != c)
1029 error("'%c' expected", c);
1030 next();
1033 void test_lvalue(void)
1035 if (!(vtop->r & VT_LVAL))
1036 expect("lvalue");
1039 TokenSym *tok_alloc(const char *str, int len)
1041 TokenSym *ts, **pts, **ptable;
1042 int h, i;
1044 if (len <= 0)
1045 len = strlen(str);
1046 h = 1;
1047 for(i=0;i<len;i++)
1048 h = (h * 263 + ((unsigned char *)str)[i]) & (TOK_HASH_SIZE - 1);
1050 pts = &hash_ident[h];
1051 while (1) {
1052 ts = *pts;
1053 if (!ts)
1054 break;
1055 if (ts->len == len && !memcmp(ts->str, str, len))
1056 return ts;
1057 pts = &(ts->hash_next);
1060 if (tok_ident >= SYM_FIRST_ANOM)
1061 error("memory full");
1063 /* expand token table if needed */
1064 i = tok_ident - TOK_IDENT;
1065 if ((i % TOK_ALLOC_INCR) == 0) {
1066 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1067 if (!ptable)
1068 error("memory full");
1069 table_ident = ptable;
1072 ts = tcc_malloc(sizeof(TokenSym) + len);
1073 table_ident[i] = ts;
1074 ts->tok = tok_ident++;
1075 ts->len = len;
1076 ts->hash_next = NULL;
1077 memcpy(ts->str, str, len + 1);
1078 *pts = ts;
1079 return ts;
1082 /* CString handling */
1084 static void cstr_realloc(CString *cstr, int new_size)
1086 int size;
1087 void *data;
1089 size = cstr->size_allocated;
1090 if (size == 0)
1091 size = 8; /* no need to allocate a too small first string */
1092 while (size < new_size)
1093 size = size * 2;
1094 data = tcc_realloc(cstr->data_allocated, size);
1095 if (!data)
1096 error("memory full");
1097 cstr->data_allocated = data;
1098 cstr->size_allocated = size;
1099 cstr->data = data;
1102 /* add a byte */
1103 static void cstr_ccat(CString *cstr, int ch)
1105 int size;
1106 size = cstr->size + 1;
1107 if (size > cstr->size_allocated)
1108 cstr_realloc(cstr, size);
1109 ((unsigned char *)cstr->data)[size - 1] = ch;
1110 cstr->size = size;
1113 static void cstr_cat(CString *cstr, const char *str)
1115 int c;
1116 for(;;) {
1117 c = *str;
1118 if (c == '\0')
1119 break;
1120 cstr_ccat(cstr, c);
1121 str++;
1125 /* add a wide char */
1126 static void cstr_wccat(CString *cstr, int ch)
1128 int size;
1129 size = cstr->size + sizeof(int);
1130 if (size > cstr->size_allocated)
1131 cstr_realloc(cstr, size);
1132 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1133 cstr->size = size;
1136 static void cstr_new(CString *cstr)
1138 memset(cstr, 0, sizeof(CString));
1141 /* free string and reset it to NULL */
1142 static void cstr_free(CString *cstr)
1144 tcc_free(cstr->data_allocated);
1145 cstr_new(cstr);
1148 #define cstr_reset(cstr) cstr_free(cstr)
1150 /* XXX: unicode ? */
1151 static void add_char(CString *cstr, int c)
1153 if (c == '\'' || c == '\"' || c == '\\') {
1154 /* XXX: could be more precise if char or string */
1155 cstr_ccat(cstr, '\\');
1157 if (c >= 32 && c <= 126) {
1158 cstr_ccat(cstr, c);
1159 } else {
1160 cstr_ccat(cstr, '\\');
1161 if (c == '\n') {
1162 cstr_ccat(cstr, 'n');
1163 } else {
1164 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1165 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1166 cstr_ccat(cstr, '0' + (c & 7));
1171 /* XXX: buffer overflow */
1172 /* XXX: float tokens */
1173 char *get_tok_str(int v, CValue *cv)
1175 static char buf[STRING_MAX_SIZE + 1];
1176 static CString cstr_buf;
1177 CString *cstr;
1178 unsigned char *q;
1179 char *p;
1180 int i, len;
1182 /* NOTE: to go faster, we give a fixed buffer for small strings */
1183 cstr_reset(&cstr_buf);
1184 cstr_buf.data = buf;
1185 cstr_buf.size_allocated = sizeof(buf);
1186 p = buf;
1188 switch(v) {
1189 case TOK_CINT:
1190 case TOK_CUINT:
1191 /* XXX: not exact */
1192 sprintf(p, "%u", cv->ui);
1193 break;
1194 case TOK_CCHAR:
1195 case TOK_LCHAR:
1196 cstr_ccat(&cstr_buf, '\'');
1197 add_char(&cstr_buf, cv->i);
1198 cstr_ccat(&cstr_buf, '\'');
1199 cstr_ccat(&cstr_buf, '\0');
1200 break;
1201 case TOK_STR:
1202 case TOK_LSTR:
1203 cstr = cv->cstr;
1204 cstr_ccat(&cstr_buf, '\"');
1205 if (v == TOK_STR) {
1206 len = cstr->size - 1;
1207 for(i=0;i<len;i++)
1208 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1209 } else {
1210 len = (cstr->size / sizeof(int)) - 1;
1211 for(i=0;i<len;i++)
1212 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1214 cstr_ccat(&cstr_buf, '\"');
1215 cstr_ccat(&cstr_buf, '\0');
1216 break;
1217 case TOK_LT:
1218 v = '<';
1219 goto addv;
1220 case TOK_GT:
1221 v = '>';
1222 goto addv;
1223 case TOK_A_SHL:
1224 return strcpy(p, "<<=");
1225 case TOK_A_SAR:
1226 return strcpy(p, ">>=");
1227 default:
1228 if (v < TOK_IDENT) {
1229 /* search in two bytes table */
1230 q = tok_two_chars;
1231 while (*q) {
1232 if (q[2] == v) {
1233 *p++ = q[0];
1234 *p++ = q[1];
1235 *p = '\0';
1236 return buf;
1238 q += 3;
1240 addv:
1241 *p++ = v;
1242 *p = '\0';
1243 } else if (v < tok_ident) {
1244 return table_ident[v - TOK_IDENT]->str;
1245 } else if (v >= SYM_FIRST_ANOM) {
1246 /* special name for anonymous symbol */
1247 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1248 } else {
1249 /* should never happen */
1250 return NULL;
1252 break;
1254 return cstr_buf.data;
1257 /* push, without hashing */
1258 Sym *sym_push2(Sym **ps, int v, int t, int c)
1260 Sym *s;
1261 s = tcc_malloc(sizeof(Sym));
1262 s->v = v;
1263 s->t = t;
1264 s->c = c;
1265 s->next = NULL;
1266 /* add in stack */
1267 s->prev = *ps;
1268 *ps = s;
1269 return s;
1272 /* find a symbol and return its associated structure. 's' is the top
1273 of the symbol stack */
1274 Sym *sym_find2(Sym *s, int v)
1276 while (s) {
1277 if (s->v == v)
1278 return s;
1279 s = s->prev;
1281 return NULL;
1284 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1286 /* find a symbol and return its associated structure. 'st' is the
1287 symbol stack */
1288 Sym *sym_find1(SymStack *st, int v)
1290 Sym *s;
1292 s = st->hash[HASH_SYM(v)];
1293 while (s) {
1294 if (s->v == v)
1295 return s;
1296 s = s->hash_next;
1298 return NULL;
1301 Sym *sym_push1(SymStack *st, int v, int t, int c)
1303 Sym *s, **ps;
1304 s = sym_push2(&st->top, v, t, c);
1305 /* add in hash table */
1306 if (v) {
1307 ps = &st->hash[HASH_SYM(v)];
1308 s->hash_next = *ps;
1309 *ps = s;
1311 return s;
1314 /* find a symbol in the right symbol space */
1315 Sym *sym_find(int v)
1317 Sym *s;
1318 s = sym_find1(&local_stack, v);
1319 if (!s)
1320 s = sym_find1(&global_stack, v);
1321 return s;
1324 /* push a given symbol on the symbol stack */
1325 Sym *sym_push(int v, int t, int r, int c)
1327 Sym *s;
1328 if (local_stack.top)
1329 s = sym_push1(&local_stack, v, t, c);
1330 else
1331 s = sym_push1(&global_stack, v, t, c);
1332 s->r = r;
1333 return s;
1336 /* pop symbols until top reaches 'b' */
1337 void sym_pop(SymStack *st, Sym *b)
1339 Sym *s, *ss;
1341 s = st->top;
1342 while(s != b) {
1343 ss = s->prev;
1344 /* free hash table entry, except if symbol was freed (only
1345 used for #undef symbols) */
1346 if (s->v)
1347 st->hash[HASH_SYM(s->v)] = s->hash_next;
1348 tcc_free(s);
1349 s = ss;
1351 st->top = b;
1354 /* undefined a hashed symbol (used for #undef). Its name is set to
1355 zero */
1356 void sym_undef(SymStack *st, Sym *s)
1358 Sym **ss;
1359 ss = &st->hash[HASH_SYM(s->v)];
1360 while (*ss != NULL) {
1361 if (*ss == s)
1362 break;
1363 ss = &(*ss)->hash_next;
1365 *ss = s->hash_next;
1366 s->v = 0;
1369 /* I/O layer */
1371 BufferedFile *tcc_open(const char *filename)
1373 int fd;
1374 BufferedFile *bf;
1376 fd = open(filename, O_RDONLY);
1377 if (fd < 0)
1378 return NULL;
1379 bf = tcc_malloc(sizeof(BufferedFile));
1380 if (!bf) {
1381 close(fd);
1382 return NULL;
1384 bf->fd = fd;
1385 bf->buf_ptr = bf->buffer;
1386 bf->buf_end = bf->buffer;
1387 bf->buffer[0] = CH_EOB; /* put eob symbol */
1388 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1389 bf->line_num = 1;
1390 // printf("opening '%s'\n", filename);
1391 return bf;
1394 void tcc_close(BufferedFile *bf)
1396 total_lines += bf->line_num;
1397 close(bf->fd);
1398 tcc_free(bf);
1401 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1402 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1404 /* fill input buffer and return next char */
1405 int tcc_getc_slow(BufferedFile *bf)
1407 int len;
1408 /* only tries to read if really end of buffer */
1409 if (bf->buf_ptr >= bf->buf_end) {
1410 if (bf->fd != -1) {
1411 len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
1412 if (len < 0)
1413 len = 0;
1414 } else {
1415 len = 0;
1417 total_bytes += len;
1418 bf->buf_ptr = bf->buffer;
1419 bf->buf_end = bf->buffer + len;
1420 *bf->buf_end = CH_EOB;
1422 if (bf->buf_ptr < bf->buf_end) {
1423 return *bf->buf_ptr++;
1424 } else {
1425 bf->buf_ptr = bf->buf_end;
1426 return CH_EOF;
1430 /* no need to put that inline */
1431 void handle_eob(void)
1433 for(;;) {
1434 ch1 = tcc_getc_slow(file);
1435 if (ch1 != CH_EOF)
1436 return;
1438 if (include_stack_ptr == include_stack)
1439 return;
1440 /* add end of include file debug info */
1441 if (do_debug) {
1442 put_stabd(N_EINCL, 0, 0);
1444 /* pop include stack */
1445 tcc_close(file);
1446 include_stack_ptr--;
1447 file = *include_stack_ptr;
1451 /* read next char from current input file */
1452 static inline void inp(void)
1454 ch1 = TCC_GETC(file);
1455 /* end of buffer/file handling */
1456 if (ch1 == CH_EOB)
1457 handle_eob();
1458 if (ch1 == '\n')
1459 file->line_num++;
1460 // printf("ch1=%c 0x%x\n", ch1, ch1);
1463 /* handle '\\n' and '\\r\n' */
1464 static void handle_stray(void)
1466 do {
1467 if (ch1 == '\n') {
1468 inp();
1469 } else if (ch1 == '\r') {
1470 inp();
1471 if (ch1 != '\n')
1472 error("invalid character after '\\'");
1473 inp();
1474 } else {
1475 break;
1477 ch = ch1;
1478 inp();
1479 } while (ch == '\\');
1482 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1483 case */
1484 static inline void minp(void)
1486 ch = ch1;
1487 inp();
1488 if (ch == '\\')
1489 handle_stray();
1493 /* same as minp, but also skip comments */
1494 static void cinp(void)
1496 int c;
1498 if (ch1 == '/') {
1499 inp();
1500 if (ch1 == '/') {
1501 /* single line C++ comments */
1502 inp();
1503 while (ch1 != '\n' && ch1 != CH_EOF)
1504 inp();
1505 ch = ' '; /* return space */
1506 } else if (ch1 == '*') {
1507 /* C comments */
1508 inp();
1509 while (ch1 != CH_EOF) {
1510 c = ch1;
1511 inp();
1512 if (c == '*' && ch1 == '/') {
1513 inp();
1514 ch = ' '; /* return space */
1515 break;
1518 } else {
1519 ch = '/';
1521 } else {
1522 minp();
1526 /* space exlcuding newline */
1527 static inline int is_space(int ch)
1529 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1532 static inline void skip_spaces(void)
1534 while (is_space(ch))
1535 cinp();
1538 /* skip block of text until #else, #elif or #endif. skip also pairs of
1539 #if/#endif */
1540 void preprocess_skip(void)
1542 int a;
1543 a = 0;
1544 while (1) {
1545 while (ch != '\n') {
1546 if (ch == CH_EOF)
1547 expect("#endif");
1548 cinp();
1550 cinp();
1551 skip_spaces();
1552 if (ch == '#') {
1553 cinp();
1554 next_nomacro();
1555 if (a == 0 &&
1556 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1557 break;
1558 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1559 a++;
1560 else if (tok == TOK_ENDIF)
1561 a--;
1566 /* ParseState handling */
1568 /* XXX: currently, no include file info is stored. Thus, we cannot display
1569 accurate messages if the function or data definition spans multiple
1570 files */
1572 /* save current parse state in 's' */
1573 void save_parse_state(ParseState *s)
1575 s->line_num = file->line_num;
1576 s->macro_ptr = macro_ptr;
1577 s->tok = tok;
1578 s->tokc = tokc;
1581 /* restore parse state from 's' */
1582 void restore_parse_state(ParseState *s)
1584 file->line_num = s->line_num;
1585 macro_ptr = s->macro_ptr;
1586 tok = s->tok;
1587 tokc = s->tokc;
1590 /* return the number of additionnal 'ints' necessary to store the
1591 token */
1592 static inline int tok_ext_size(int t)
1594 switch(t) {
1595 /* 4 bytes */
1596 case TOK_CINT:
1597 case TOK_CUINT:
1598 case TOK_CCHAR:
1599 case TOK_LCHAR:
1600 case TOK_STR:
1601 case TOK_LSTR:
1602 case TOK_CFLOAT:
1603 case TOK_LINENUM:
1604 return 1;
1605 case TOK_CDOUBLE:
1606 case TOK_CLLONG:
1607 case TOK_CULLONG:
1608 return 2;
1609 case TOK_CLDOUBLE:
1610 return LDOUBLE_SIZE / 4;
1611 default:
1612 return 0;
1616 /* token string handling */
1618 static inline void tok_str_new(TokenString *s)
1620 s->str = NULL;
1621 s->len = 0;
1622 s->last_line_num = -1;
1625 static void tok_str_free(int *str)
1627 const int *p;
1628 CString *cstr;
1629 int t;
1631 p = str;
1632 for(;;) {
1633 t = *p++;
1634 if (t == 0)
1635 break;
1636 if (t == TOK_STR || t == TOK_LSTR) {
1637 /* XXX: use a macro to be portable on 64 bit ? */
1638 cstr = (CString *)(*p++);
1639 cstr_free(cstr);
1640 tcc_free(cstr);
1641 } else {
1642 p += tok_ext_size(t);
1645 tcc_free(str);
1648 static void tok_str_add(TokenString *s, int t)
1650 int len, *str;
1652 len = s->len;
1653 str = s->str;
1654 if ((len & 63) == 0) {
1655 str = tcc_realloc(str, (len + 64) * sizeof(int));
1656 if (!str)
1657 return;
1658 s->str = str;
1660 str[len++] = t;
1661 s->len = len;
1664 static void tok_str_add2(TokenString *s, int t, CValue *cv)
1666 int n, i, size;
1667 CString *cstr, *cstr1;
1668 CValue cv1;
1670 tok_str_add(s, t);
1671 if (t == TOK_STR || t == TOK_LSTR) {
1672 /* special case: need to duplicate string */
1673 cstr1 = cv->cstr;
1674 cstr = tcc_malloc(sizeof(CString));
1675 size = cstr1->size;
1676 cstr->size = size;
1677 cstr->size_allocated = size;
1678 cstr->data_allocated = tcc_malloc(size);
1679 cstr->data = cstr->data_allocated;
1680 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1681 cv1.cstr = cstr;
1682 tok_str_add(s, cv1.tab[0]);
1683 } else {
1684 n = tok_ext_size(t);
1685 for(i=0;i<n;i++)
1686 tok_str_add(s, cv->tab[i]);
1690 /* add the current parse token in token string 's' */
1691 static void tok_str_add_tok(TokenString *s)
1693 CValue cval;
1695 /* save line number info */
1696 if (file->line_num != s->last_line_num) {
1697 s->last_line_num = file->line_num;
1698 cval.i = s->last_line_num;
1699 tok_str_add2(s, TOK_LINENUM, &cval);
1701 tok_str_add2(s, tok, &tokc);
1704 /* get a token from an integer array and increment pointer accordingly */
1705 static int tok_get(int **tok_str, CValue *cv)
1707 int *p, t, n, i;
1709 p = *tok_str;
1710 t = *p++;
1711 n = tok_ext_size(t);
1712 for(i=0;i<n;i++)
1713 cv->tab[i] = *p++;
1714 *tok_str = p;
1715 return t;
1718 /* eval an expression for #if/#elif */
1719 int expr_preprocess(void)
1721 int c, t;
1722 TokenString str;
1724 tok_str_new(&str);
1725 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1726 next(); /* do macro subst */
1727 if (tok == TOK_DEFINED) {
1728 next_nomacro();
1729 t = tok;
1730 if (t == '(')
1731 next_nomacro();
1732 c = sym_find1(&define_stack, tok) != 0;
1733 if (t == '(')
1734 next_nomacro();
1735 tok = TOK_CINT;
1736 tokc.i = c;
1737 } else if (tok >= TOK_IDENT) {
1738 /* if undefined macro */
1739 tok = TOK_CINT;
1740 tokc.i = 0;
1742 tok_str_add_tok(&str);
1744 tok_str_add(&str, -1); /* simulate end of file */
1745 tok_str_add(&str, 0);
1746 /* now evaluate C constant expression */
1747 macro_ptr = str.str;
1748 next();
1749 c = expr_const();
1750 macro_ptr = NULL;
1751 tok_str_free(str.str);
1752 return c != 0;
1755 #if defined(DEBUG) || defined(PP_DEBUG)
1756 void tok_print(int *str)
1758 int t;
1759 CValue cval;
1761 while (1) {
1762 t = tok_get(&str, &cval);
1763 if (!t)
1764 break;
1765 printf(" %s", get_tok_str(t, &cval));
1767 printf("\n");
1769 #endif
1771 /* parse after #define */
1772 void parse_define(void)
1774 Sym *s, *first, **ps;
1775 int v, t, varg, is_vaargs;
1776 TokenString str;
1778 v = tok;
1779 /* XXX: should check if same macro (ANSI) */
1780 first = NULL;
1781 t = MACRO_OBJ;
1782 /* '(' must be just after macro definition for MACRO_FUNC */
1783 if (ch == '(') {
1784 next_nomacro();
1785 next_nomacro();
1786 ps = &first;
1787 while (tok != ')') {
1788 varg = tok;
1789 next_nomacro();
1790 is_vaargs = 0;
1791 if (varg == TOK_DOTS) {
1792 varg = TOK___VA_ARGS__;
1793 is_vaargs = 1;
1794 } else if (tok == TOK_DOTS && gnu_ext) {
1795 is_vaargs = 1;
1796 next_nomacro();
1798 if (varg < TOK_IDENT)
1799 error("badly punctuated parameter list");
1800 s = sym_push1(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
1801 *ps = s;
1802 ps = &s->next;
1803 if (tok != ',')
1804 break;
1805 next_nomacro();
1807 t = MACRO_FUNC;
1809 tok_str_new(&str);
1810 while (1) {
1811 skip_spaces();
1812 if (ch == '\n' || ch == CH_EOF)
1813 break;
1814 next_nomacro();
1815 tok_str_add2(&str, tok, &tokc);
1817 tok_str_add(&str, 0);
1818 #ifdef PP_DEBUG
1819 printf("define %s %d: ", get_tok_str(v, NULL), t);
1820 tok_print(str.str);
1821 #endif
1822 s = sym_push1(&define_stack, v, t, (int)str.str);
1823 s->next = first;
1826 void preprocess(void)
1828 int size, i, c, n;
1829 char buf[1024], *q, *p;
1830 char buf1[1024];
1831 BufferedFile *f;
1832 Sym *s;
1834 return_linefeed = 1; /* linefeed will be returned as a token */
1835 cinp();
1836 next_nomacro();
1837 redo:
1838 if (tok == TOK_DEFINE) {
1839 next_nomacro();
1840 parse_define();
1841 } else if (tok == TOK_UNDEF) {
1842 next_nomacro();
1843 s = sym_find1(&define_stack, tok);
1844 /* undefine symbol by putting an invalid name */
1845 if (s)
1846 sym_undef(&define_stack, s);
1847 } else if (tok == TOK_INCLUDE) {
1848 skip_spaces();
1849 if (ch == '<') {
1850 c = '>';
1851 goto read_name;
1852 } else if (ch == '\"') {
1853 c = ch;
1854 read_name:
1855 minp();
1856 q = buf;
1857 while (ch != c && ch != '\n' && ch != CH_EOF) {
1858 if ((q - buf) < sizeof(buf) - 1)
1859 *q++ = ch;
1860 minp();
1862 *q = '\0';
1863 /* eat all spaces and comments after include */
1864 /* XXX: slightly incorrect */
1865 while (ch1 != '\n' && ch1 != CH_EOF)
1866 inp();
1867 } else {
1868 /* computed #include : either we have only strings or
1869 we have anything enclosed in '<>' */
1870 next();
1871 buf[0] = '\0';
1872 if (tok == TOK_STR) {
1873 while (tok != TOK_LINEFEED) {
1874 if (tok != TOK_STR) {
1875 include_syntax:
1876 error("'#include' expects \"FILENAME\" or <FILENAME>");
1878 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
1879 next();
1881 c = '\"';
1882 } else {
1883 int len;
1884 while (tok != TOK_LINEFEED) {
1885 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
1886 next();
1888 len = strlen(buf);
1889 /* check syntax and remove '<>' */
1890 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
1891 goto include_syntax;
1892 memmove(buf, buf + 1, len - 2);
1893 buf[len - 2] = '\0';
1894 c = '>';
1898 if (include_stack_ptr >= include_stack + INCLUDE_STACK_SIZE)
1899 error("memory full");
1900 if (c == '\"') {
1901 /* first search in current dir if "header.h" */
1902 size = 0;
1903 p = strrchr(file->filename, '/');
1904 if (p)
1905 size = p + 1 - file->filename;
1906 if (size > sizeof(buf1) - 1)
1907 size = sizeof(buf1) - 1;
1908 memcpy(buf1, file->filename, size);
1909 buf1[size] = '\0';
1910 pstrcat(buf1, sizeof(buf1), buf);
1911 f = tcc_open(buf1);
1912 if (f)
1913 goto found;
1915 /* now search in all the include paths */
1916 n = nb_include_paths + nb_sysinclude_paths;
1917 for(i = 0; i < n; i++) {
1918 const char *path;
1919 if (i < nb_include_paths)
1920 path = include_paths[i];
1921 else
1922 path = sysinclude_paths[i - nb_include_paths];
1923 pstrcpy(buf1, sizeof(buf1), path);
1924 pstrcat(buf1, sizeof(buf1), "/");
1925 pstrcat(buf1, sizeof(buf1), buf);
1926 f = tcc_open(buf1);
1927 if (f)
1928 goto found;
1930 error("include file '%s' not found", buf);
1931 f = NULL;
1932 found:
1933 /* push current file in stack */
1934 /* XXX: fix current line init */
1935 *include_stack_ptr++ = file;
1936 file = f;
1937 /* add include file debug info */
1938 if (do_debug) {
1939 put_stabs(file->filename, N_BINCL, 0, 0, 0);
1941 ch = '\n';
1942 goto the_end;
1943 } else if (tok == TOK_IFNDEF) {
1944 c = 1;
1945 goto do_ifdef;
1946 } else if (tok == TOK_IF) {
1947 c = expr_preprocess();
1948 goto do_if;
1949 } else if (tok == TOK_IFDEF) {
1950 c = 0;
1951 do_ifdef:
1952 next_nomacro();
1953 c = (sym_find1(&define_stack, tok) != 0) ^ c;
1954 do_if:
1955 if (ifdef_stack_ptr >= ifdef_stack + IFDEF_STACK_SIZE)
1956 error("memory full");
1957 *ifdef_stack_ptr++ = c;
1958 goto test_skip;
1959 } else if (tok == TOK_ELSE) {
1960 if (ifdef_stack_ptr == ifdef_stack)
1961 error("#else without matching #if");
1962 if (ifdef_stack_ptr[-1] & 2)
1963 error("#else after #else");
1964 c = (ifdef_stack_ptr[-1] ^= 3);
1965 goto test_skip;
1966 } else if (tok == TOK_ELIF) {
1967 if (ifdef_stack_ptr == ifdef_stack)
1968 error("#elif without matching #if");
1969 c = ifdef_stack_ptr[-1];
1970 if (c > 1)
1971 error("#elif after #else");
1972 /* last #if/#elif expression was true: we skip */
1973 if (c == 1)
1974 goto skip;
1975 c = expr_preprocess();
1976 ifdef_stack_ptr[-1] = c;
1977 test_skip:
1978 if (!(c & 1)) {
1979 skip:
1980 preprocess_skip();
1981 goto redo;
1983 } else if (tok == TOK_ENDIF) {
1984 if (ifdef_stack_ptr == ifdef_stack)
1985 error("#endif without matching #if");
1986 ifdef_stack_ptr--;
1987 } else if (tok == TOK_LINE) {
1988 int line_num;
1989 next();
1990 if (tok != TOK_CINT)
1991 error("#line");
1992 line_num = tokc.i;
1993 next();
1994 if (tok != TOK_LINEFEED) {
1995 if (tok != TOK_STR)
1996 error("#line");
1997 pstrcpy(file->filename, sizeof(file->filename),
1998 (char *)tokc.cstr->data);
2000 /* NOTE: we do it there to avoid problems with linefeed */
2001 file->line_num = line_num;
2002 } else if (tok == TOK_ERROR) {
2003 error("#error");
2005 /* ignore other preprocess commands or #! for C scripts */
2006 while (tok != TOK_LINEFEED && tok != TOK_EOF)
2007 next_nomacro();
2008 the_end:
2009 return_linefeed = 0;
2012 /* read a number in base b */
2013 static int getn(int b)
2015 int n, t;
2016 n = 0;
2017 while (1) {
2018 if (ch >= 'a' && ch <= 'f')
2019 t = ch - 'a' + 10;
2020 else if (ch >= 'A' && ch <= 'F')
2021 t = ch - 'A' + 10;
2022 else if (isnum(ch))
2023 t = ch - '0';
2024 else
2025 break;
2026 if (t < 0 || t >= b)
2027 break;
2028 n = n * b + t;
2029 cinp();
2031 return n;
2034 /* read a character for string or char constant and eval escape codes */
2035 static int getq(void)
2037 int c;
2039 c = ch;
2040 minp();
2041 if (c == '\\') {
2042 if (isnum(ch)) {
2043 /* at most three octal digits */
2044 c = ch - '0';
2045 minp();
2046 if (isnum(ch)) {
2047 c = c * 8 + ch - '0';
2048 minp();
2049 if (isnum(ch)) {
2050 c = c * 8 + ch - '0';
2051 minp();
2054 return c;
2055 } else if (ch == 'x') {
2056 minp();
2057 return getn(16);
2058 } else {
2059 if (ch == 'a')
2060 c = '\a';
2061 else if (ch == 'b')
2062 c = '\b';
2063 else if (ch == 'f')
2064 c = '\f';
2065 else if (ch == 'n')
2066 c = '\n';
2067 else if (ch == 'r')
2068 c = '\r';
2069 else if (ch == 't')
2070 c = '\t';
2071 else if (ch == 'v')
2072 c = '\v';
2073 else if (ch == 'e' && gnu_ext)
2074 c = 27;
2075 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
2076 c = ch;
2077 else
2078 error("invalid escaped char");
2079 minp();
2081 } else if (c == '\r' && ch == '\n') {
2082 minp();
2083 c = '\n';
2085 return c;
2088 /* we use 64 bit numbers */
2089 #define BN_SIZE 2
2091 /* bn = (bn << shift) | or_val */
2092 void bn_lshift(unsigned int *bn, int shift, int or_val)
2094 int i;
2095 unsigned int v;
2096 for(i=0;i<BN_SIZE;i++) {
2097 v = bn[i];
2098 bn[i] = (v << shift) | or_val;
2099 or_val = v >> (32 - shift);
2103 void bn_zero(unsigned int *bn)
2105 int i;
2106 for(i=0;i<BN_SIZE;i++) {
2107 bn[i] = 0;
2111 void parse_number(void)
2113 int b, t, shift, frac_bits, s, exp_val;
2114 char *q;
2115 unsigned int bn[BN_SIZE];
2116 double d;
2118 /* number */
2119 q = token_buf;
2120 t = ch;
2121 cinp();
2122 *q++ = t;
2123 b = 10;
2124 if (t == '.') {
2125 /* special dot handling */
2126 if (ch >= '0' && ch <= '9') {
2127 goto float_frac_parse;
2128 } else if (ch == '.') {
2129 cinp();
2130 if (ch != '.')
2131 expect("'.'");
2132 cinp();
2133 tok = TOK_DOTS;
2134 } else {
2135 /* dots */
2136 tok = t;
2138 return;
2139 } else if (t == '0') {
2140 if (ch == 'x' || ch == 'X') {
2141 q--;
2142 cinp();
2143 b = 16;
2144 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2145 q--;
2146 cinp();
2147 b = 2;
2150 /* parse all digits. cannot check octal numbers at this stage
2151 because of floating point constants */
2152 while (1) {
2153 if (ch >= 'a' && ch <= 'f')
2154 t = ch - 'a' + 10;
2155 else if (ch >= 'A' && ch <= 'F')
2156 t = ch - 'A' + 10;
2157 else if (isnum(ch))
2158 t = ch - '0';
2159 else
2160 break;
2161 if (t >= b)
2162 break;
2163 if (q >= token_buf + STRING_MAX_SIZE) {
2164 num_too_long:
2165 error("number too long");
2167 *q++ = ch;
2168 cinp();
2170 if (ch == '.' ||
2171 ((ch == 'e' || ch == 'E') && b == 10) ||
2172 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2173 if (b != 10) {
2174 /* NOTE: strtox should support that for hexa numbers, but
2175 non ISOC99 libcs do not support it, so we prefer to do
2176 it by hand */
2177 /* hexadecimal or binary floats */
2178 /* XXX: handle overflows */
2179 *q = '\0';
2180 if (b == 16)
2181 shift = 4;
2182 else
2183 shift = 2;
2184 bn_zero(bn);
2185 q = token_buf;
2186 while (1) {
2187 t = *q++;
2188 if (t == '\0') {
2189 break;
2190 } else if (t >= 'a') {
2191 t = t - 'a' + 10;
2192 } else if (t >= 'A') {
2193 t = t - 'A' + 10;
2194 } else {
2195 t = t - '0';
2197 bn_lshift(bn, shift, t);
2199 frac_bits = 0;
2200 if (ch == '.') {
2201 cinp();
2202 while (1) {
2203 t = ch;
2204 if (t >= 'a' && t <= 'f') {
2205 t = t - 'a' + 10;
2206 } else if (t >= 'A' && t <= 'F') {
2207 t = t - 'A' + 10;
2208 } else if (t >= '0' && t <= '9') {
2209 t = t - '0';
2210 } else {
2211 break;
2213 if (t >= b)
2214 error("invalid digit");
2215 bn_lshift(bn, shift, t);
2216 frac_bits += shift;
2217 cinp();
2220 if (ch != 'p' && ch != 'P')
2221 error("exponent expected");
2222 cinp();
2223 s = 1;
2224 exp_val = 0;
2225 if (ch == '+') {
2226 cinp();
2227 } else if (ch == '-') {
2228 s = -1;
2229 cinp();
2231 if (ch < '0' || ch > '9')
2232 error("exponent digits expected");
2233 while (ch >= '0' && ch <= '9') {
2234 exp_val = exp_val * 10 + ch - '0';
2235 cinp();
2237 exp_val = exp_val * s;
2239 /* now we can generate the number */
2240 /* XXX: should patch directly float number */
2241 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
2242 d = ldexp(d, exp_val - frac_bits);
2243 t = toup(ch);
2244 if (t == 'F') {
2245 cinp();
2246 tok = TOK_CFLOAT;
2247 /* float : should handle overflow */
2248 tokc.f = (float)d;
2249 } else if (t == 'L') {
2250 cinp();
2251 tok = TOK_CLDOUBLE;
2252 /* XXX: not large enough */
2253 tokc.ld = (long double)d;
2254 } else {
2255 tok = TOK_CDOUBLE;
2256 tokc.d = d;
2258 } else {
2259 /* decimal floats */
2260 if (ch == '.') {
2261 if (q >= token_buf + STRING_MAX_SIZE)
2262 goto num_too_long;
2263 *q++ = ch;
2264 cinp();
2265 float_frac_parse:
2266 while (ch >= '0' && ch <= '9') {
2267 if (q >= token_buf + STRING_MAX_SIZE)
2268 goto num_too_long;
2269 *q++ = ch;
2270 cinp();
2273 if (ch == 'e' || ch == 'E') {
2274 if (q >= token_buf + STRING_MAX_SIZE)
2275 goto num_too_long;
2276 *q++ = ch;
2277 cinp();
2278 if (ch == '-' || ch == '+') {
2279 if (q >= token_buf + STRING_MAX_SIZE)
2280 goto num_too_long;
2281 *q++ = ch;
2282 cinp();
2284 if (ch < '0' || ch > '9')
2285 error("exponent digits expected");
2286 while (ch >= '0' && ch <= '9') {
2287 if (q >= token_buf + STRING_MAX_SIZE)
2288 goto num_too_long;
2289 *q++ = ch;
2290 cinp();
2293 *q = '\0';
2294 t = toup(ch);
2295 errno = 0;
2296 if (t == 'F') {
2297 cinp();
2298 tok = TOK_CFLOAT;
2299 tokc.f = strtof(token_buf, NULL);
2300 } else if (t == 'L') {
2301 cinp();
2302 tok = TOK_CLDOUBLE;
2303 tokc.ld = strtold(token_buf, NULL);
2304 } else {
2305 tok = TOK_CDOUBLE;
2306 tokc.d = strtod(token_buf, NULL);
2309 } else {
2310 unsigned long long n, n1;
2311 int lcount;
2313 /* integer number */
2314 *q = '\0';
2315 q = token_buf;
2316 if (b == 10 && *q == '0') {
2317 b = 8;
2318 q++;
2320 n = 0;
2321 while(1) {
2322 t = *q++;
2323 /* no need for checks except for base 10 / 8 errors */
2324 if (t == '\0') {
2325 break;
2326 } else if (t >= 'a') {
2327 t = t - 'a' + 10;
2328 } else if (t >= 'A') {
2329 t = t - 'A' + 10;
2330 } else {
2331 t = t - '0';
2332 if (t >= b)
2333 error("invalid digit");
2335 n1 = n;
2336 n = n * b + t;
2337 /* detect overflow */
2338 if (n < n1)
2339 error("integer constant overflow");
2342 /* XXX: not exactly ANSI compliant */
2343 if ((n & 0xffffffff00000000LL) != 0) {
2344 if ((n >> 63) != 0)
2345 tok = TOK_CULLONG;
2346 else
2347 tok = TOK_CLLONG;
2348 } else if (n > 0x7fffffff) {
2349 tok = TOK_CUINT;
2350 } else {
2351 tok = TOK_CINT;
2353 lcount = 0;
2354 for(;;) {
2355 t = toup(ch);
2356 if (t == 'L') {
2357 if (lcount >= 2)
2358 error("three 'l' in integer constant");
2359 lcount++;
2360 if (lcount == 2) {
2361 if (tok == TOK_CINT)
2362 tok = TOK_CLLONG;
2363 else if (tok == TOK_CUINT)
2364 tok = TOK_CULLONG;
2366 cinp();
2367 } else if (t == 'U') {
2368 if (tok == TOK_CINT)
2369 tok = TOK_CUINT;
2370 else if (tok == TOK_CLLONG)
2371 tok = TOK_CULLONG;
2372 cinp();
2373 } else {
2374 break;
2377 if (tok == TOK_CINT || tok == TOK_CUINT)
2378 tokc.ui = n;
2379 else
2380 tokc.ull = n;
2385 /* return next token without macro substitution */
2386 void next_nomacro1(void)
2388 int b;
2389 char *q;
2390 TokenSym *ts;
2392 /* skip spaces */
2393 while(1) {
2394 while (ch == '\n') {
2395 /* during preprocessor parsing, '\n' is a token */
2396 if (return_linefeed) {
2397 tok = TOK_LINEFEED;
2398 return;
2400 cinp();
2401 skip_spaces();
2402 if (ch == '#') {
2403 /* preprocessor command if # at start of line after
2404 spaces */
2405 preprocess();
2408 if (!is_space(ch))
2409 break;
2410 cinp();
2412 if (isid(ch)) {
2413 q = token_buf;
2414 *q++ = ch;
2415 cinp();
2416 if (q[-1] == 'L') {
2417 if (ch == '\'') {
2418 tok = TOK_LCHAR;
2419 goto char_const;
2421 if (ch == '\"') {
2422 tok = TOK_LSTR;
2423 goto str_const;
2426 while (isid(ch) || isnum(ch)) {
2427 if (q >= token_buf + STRING_MAX_SIZE)
2428 error("ident too long");
2429 *q++ = ch;
2430 cinp();
2432 *q = '\0';
2433 ts = tok_alloc(token_buf, q - token_buf);
2434 tok = ts->tok;
2435 } else if (isnum(ch) || ch == '.') {
2436 parse_number();
2437 } else if (ch == '\'') {
2438 tok = TOK_CCHAR;
2439 char_const:
2440 minp();
2441 b = getq();
2442 /* this cast is needed if >= 128 */
2443 if (tok == TOK_CCHAR)
2444 b = (char)b;
2445 tokc.i = b;
2446 if (ch != '\'')
2447 expect("\'");
2448 minp();
2449 } else if (ch == '\"') {
2450 tok = TOK_STR;
2451 str_const:
2452 minp();
2453 cstr_reset(&tokcstr);
2454 while (ch != '\"') {
2455 b = getq();
2456 if (ch == CH_EOF)
2457 error("unterminated string");
2458 if (tok == TOK_STR)
2459 cstr_ccat(&tokcstr, b);
2460 else
2461 cstr_wccat(&tokcstr, b);
2463 if (tok == TOK_STR)
2464 cstr_ccat(&tokcstr, '\0');
2465 else
2466 cstr_wccat(&tokcstr, '\0');
2467 tokc.cstr = &tokcstr;
2468 minp();
2469 } else {
2470 q = tok_two_chars;
2471 /* two chars */
2472 tok = ch;
2473 cinp();
2474 while (*q) {
2475 if (*q == tok && q[1] == ch) {
2476 cinp();
2477 tok = q[2] & 0xff;
2478 /* three chars tests */
2479 if (tok == TOK_SHL || tok == TOK_SAR) {
2480 if (ch == '=') {
2481 tok = tok | 0x80;
2482 cinp();
2484 } else if (tok == TOK_DOTS) {
2485 if (ch != '.')
2486 error("parse error");
2487 cinp();
2489 return;
2491 q = q + 3;
2493 /* single char substitutions */
2494 if (tok == '<')
2495 tok = TOK_LT;
2496 else if (tok == '>')
2497 tok = TOK_GT;
2501 /* return next token without macro substitution. Can read input from
2502 macro_ptr buffer */
2503 void next_nomacro()
2505 if (macro_ptr) {
2506 redo:
2507 tok = *macro_ptr;
2508 if (tok) {
2509 tok = tok_get(&macro_ptr, &tokc);
2510 if (tok == TOK_LINENUM) {
2511 file->line_num = tokc.i;
2512 goto redo;
2515 } else {
2516 next_nomacro1();
2520 /* substitute args in macro_str and return allocated string */
2521 int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
2523 int *st, last_tok, t, notfirst;
2524 Sym *s;
2525 CValue cval;
2526 TokenString str;
2527 CString cstr;
2529 tok_str_new(&str);
2530 last_tok = 0;
2531 while(1) {
2532 t = tok_get(&macro_str, &cval);
2533 if (!t)
2534 break;
2535 if (t == '#') {
2536 /* stringize */
2537 t = tok_get(&macro_str, &cval);
2538 if (!t)
2539 break;
2540 s = sym_find2(args, t);
2541 if (s) {
2542 cstr_new(&cstr);
2543 st = (int *)s->c;
2544 notfirst = 0;
2545 while (*st) {
2546 if (notfirst)
2547 cstr_ccat(&cstr, ' ');
2548 t = tok_get(&st, &cval);
2549 cstr_cat(&cstr, get_tok_str(t, &cval));
2550 notfirst = 1;
2552 cstr_ccat(&cstr, '\0');
2553 #ifdef PP_DEBUG
2554 printf("stringize: %s\n", (char *)cstr.data);
2555 #endif
2556 /* add string */
2557 cval.cstr = &cstr;
2558 tok_str_add2(&str, TOK_STR, &cval);
2559 cstr_free(&cstr);
2560 } else {
2561 tok_str_add2(&str, t, &cval);
2563 } else if (t >= TOK_IDENT) {
2564 s = sym_find2(args, t);
2565 if (s) {
2566 st = (int *)s->c;
2567 /* if '##' is present before or after, no arg substitution */
2568 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
2569 /* special case for var arg macros : ## eats the
2570 ',' if empty VA_ARGS riable. */
2571 /* XXX: test of the ',' is not 100%
2572 reliable. should fix it to avoid security
2573 problems */
2574 if (gnu_ext && s->t && *st == 0 &&
2575 last_tok == TOK_TWOSHARPS &&
2576 str.len >= 2 && str.str[str.len - 2] == ',') {
2577 /* suppress ',' '##' */
2578 str.len -= 2;
2579 } else {
2580 int t1;
2581 for(;;) {
2582 t1 = tok_get(&st, &cval);
2583 if (!t1)
2584 break;
2585 tok_str_add2(&str, t1, &cval);
2588 } else {
2589 macro_subst(&str, nested_list, st);
2591 } else {
2592 tok_str_add(&str, t);
2594 } else {
2595 tok_str_add2(&str, t, &cval);
2597 last_tok = t;
2599 tok_str_add(&str, 0);
2600 return str.str;
2603 /* handle the '##' operator */
2604 int *macro_twosharps(int *macro_str)
2606 TokenSym *ts;
2607 int *macro_ptr1;
2608 int t;
2609 char *p;
2610 CValue cval;
2611 TokenString macro_str1;
2613 tok_str_new(&macro_str1);
2614 tok = 0;
2615 while (1) {
2616 next_nomacro();
2617 if (tok == 0)
2618 break;
2619 while (*macro_ptr == TOK_TWOSHARPS) {
2620 macro_ptr++;
2621 macro_ptr1 = macro_ptr;
2622 t = *macro_ptr;
2623 if (t) {
2624 t = tok_get(&macro_ptr, &cval);
2625 /* XXX: we handle only most common cases:
2626 ident + ident or ident + number */
2627 if (tok >= TOK_IDENT &&
2628 (t >= TOK_IDENT || t == TOK_CINT)) {
2629 p = get_tok_str(tok, &tokc);
2630 pstrcpy(token_buf, sizeof(token_buf), p);
2631 p = get_tok_str(t, &cval);
2632 pstrcat(token_buf, sizeof(token_buf), p);
2633 ts = tok_alloc(token_buf, 0);
2634 tok = ts->tok; /* modify current token */
2635 } else {
2636 /* cannot merge tokens: skip '##' */
2637 macro_ptr = macro_ptr1;
2638 break;
2642 tok_str_add2(&macro_str1, tok, &tokc);
2644 tok_str_add(&macro_str1, 0);
2645 return macro_str1.str;
2648 /* do macro substitution of macro_str and add result to
2649 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2650 substituted. 'nested_list' is the list of all macros we got inside
2651 to avoid recursing. */
2652 void macro_subst(TokenString *tok_str,
2653 Sym **nested_list, int *macro_str)
2655 Sym *s, *args, *sa, *sa1;
2656 int parlevel, *mstr, t, *saved_macro_ptr;
2657 int mstr_allocated, *macro_str1;
2658 CString cstr;
2659 CValue cval;
2660 TokenString str;
2661 char *cstrval;
2663 saved_macro_ptr = macro_ptr;
2664 macro_ptr = macro_str;
2665 macro_str1 = NULL;
2666 if (macro_str) {
2667 /* first scan for '##' operator handling */
2668 macro_str1 = macro_twosharps(macro_str);
2669 macro_ptr = macro_str1;
2672 while (1) {
2673 next_nomacro();
2674 if (tok == 0)
2675 break;
2676 if ((s = sym_find1(&define_stack, tok)) != NULL) {
2677 /* if symbol is a macro, prepare substitution */
2678 /* if nested substitution, do nothing */
2679 if (sym_find2(*nested_list, tok))
2680 goto no_subst;
2682 /* special macros */
2683 if (tok == TOK___LINE__) {
2684 cval.i = file->line_num;
2685 tok_str_add2(tok_str, TOK_CINT, &cval);
2686 } else if (tok == TOK___FILE__) {
2687 cstrval = file->filename;
2688 goto add_cstr;
2689 tok_str_add2(tok_str, TOK_STR, &cval);
2690 } else if (tok == TOK___DATE__) {
2691 cstrval = "Jan 1 2002";
2692 goto add_cstr;
2693 } else if (tok == TOK___TIME__) {
2694 cstrval = "00:00:00";
2695 goto add_cstr;
2696 } else if (tok == TOK___FUNCTION__) {
2697 cstrval = funcname;
2698 add_cstr:
2699 cstr_new(&cstr);
2700 cstr_cat(&cstr, cstrval);
2701 cstr_ccat(&cstr, '\0');
2702 cval.cstr = &cstr;
2703 tok_str_add2(tok_str, TOK_STR, &cval);
2704 cstr_free(&cstr);
2705 } else {
2706 mstr = (int *)s->c;
2707 mstr_allocated = 0;
2708 if (s->t == MACRO_FUNC) {
2709 /* NOTE: we do not use next_nomacro to avoid eating the
2710 next token. XXX: find better solution */
2711 if (macro_ptr) {
2712 t = *macro_ptr;
2713 } else {
2714 while (is_space(ch) || ch == '\n')
2715 cinp();
2716 t = ch;
2718 if (t != '(') /* no macro subst */
2719 goto no_subst;
2721 /* argument macro */
2722 next_nomacro();
2723 next_nomacro();
2724 args = NULL;
2725 sa = s->next;
2726 /* NOTE: empty args are allowed, except if no args */
2727 for(;;) {
2728 /* handle '()' case */
2729 if (!args && tok == ')')
2730 break;
2731 if (!sa)
2732 error("macro '%s' used with too many args",
2733 get_tok_str(s->v, 0));
2734 tok_str_new(&str);
2735 parlevel = 0;
2736 /* NOTE: non zero sa->t indicates VA_ARGS */
2737 while ((parlevel > 0 ||
2738 (tok != ')' &&
2739 (tok != ',' || sa->t))) &&
2740 tok != -1) {
2741 if (tok == '(')
2742 parlevel++;
2743 else if (tok == ')')
2744 parlevel--;
2745 tok_str_add2(&str, tok, &tokc);
2746 next_nomacro();
2748 tok_str_add(&str, 0);
2749 sym_push2(&args, sa->v & ~SYM_FIELD, sa->t, (int)str.str);
2750 sa = sa->next;
2751 if (tok == ')') {
2752 /* special case for gcc var args: add an empty
2753 var arg argument if it is omitted */
2754 if (sa && sa->t && gnu_ext)
2755 continue;
2756 else
2757 break;
2759 if (tok != ',')
2760 expect(",");
2761 next_nomacro();
2763 if (sa) {
2764 error("macro '%s' used with too few args",
2765 get_tok_str(s->v, 0));
2768 /* now subst each arg */
2769 mstr = macro_arg_subst(nested_list, mstr, args);
2770 /* free memory */
2771 sa = args;
2772 while (sa) {
2773 sa1 = sa->prev;
2774 tok_str_free((int *)sa->c);
2775 tcc_free(sa);
2776 sa = sa1;
2778 mstr_allocated = 1;
2780 sym_push2(nested_list, s->v, 0, 0);
2781 macro_subst(tok_str, nested_list, mstr);
2782 /* pop nested defined symbol */
2783 sa1 = *nested_list;
2784 *nested_list = sa1->prev;
2785 tcc_free(sa1);
2786 if (mstr_allocated)
2787 tok_str_free(mstr);
2789 } else {
2790 no_subst:
2791 /* no need to add if reading input stream */
2792 if (!macro_str)
2793 return;
2794 tok_str_add2(tok_str, tok, &tokc);
2796 /* only replace one macro while parsing input stream */
2797 if (!macro_str)
2798 return;
2800 macro_ptr = saved_macro_ptr;
2801 if (macro_str1)
2802 tok_str_free(macro_str1);
2805 /* return next token with macro substitution */
2806 void next(void)
2808 Sym *nested_list;
2809 TokenString str;
2811 /* special 'ungettok' case for label parsing */
2812 if (tok1) {
2813 tok = tok1;
2814 tokc = tok1c;
2815 tok1 = 0;
2816 } else {
2817 redo:
2818 if (!macro_ptr) {
2819 /* if not reading from macro substituted string, then try
2820 to substitute */
2821 /* XXX: optimize non macro case */
2822 tok_str_new(&str);
2823 nested_list = NULL;
2824 macro_subst(&str, &nested_list, NULL);
2825 if (str.str) {
2826 tok_str_add(&str, 0);
2827 macro_ptr = str.str;
2828 macro_ptr_allocated = str.str;
2829 goto redo;
2831 if (tok == 0)
2832 goto redo;
2833 } else {
2834 next_nomacro();
2835 if (tok == 0) {
2836 /* end of macro string: free it */
2837 tok_str_free(macro_ptr_allocated);
2838 macro_ptr = NULL;
2839 goto redo;
2843 #if defined(DEBUG)
2844 printf("token = %s\n", get_tok_str(tok, &tokc));
2845 #endif
2848 void swap(int *p, int *q)
2850 int t;
2851 t = *p;
2852 *p = *q;
2853 *q = t;
2856 void vsetc(int t, int r, CValue *vc)
2858 if (vtop >= vstack + VSTACK_SIZE)
2859 error("memory full");
2860 /* cannot let cpu flags if other instruction are generated */
2861 /* XXX: VT_JMP test too ? */
2862 if ((vtop->r & VT_VALMASK) == VT_CMP)
2863 gv(RC_INT);
2864 vtop++;
2865 vtop->t = t;
2866 vtop->r = r;
2867 vtop->r2 = VT_CONST;
2868 vtop->c = *vc;
2871 /* push integer constant */
2872 void vpushi(int v)
2874 CValue cval;
2875 cval.i = v;
2876 vsetc(VT_INT, VT_CONST, &cval);
2879 /* Return a static symbol pointing to a section */
2880 static Sym *get_sym_ref(int t, Section *sec,
2881 unsigned long offset, unsigned long size)
2883 int v;
2884 Sym *sym;
2886 v = anon_sym++;
2887 sym = sym_push1(&global_stack, v, t | VT_STATIC, 0);
2888 sym->r = VT_CONST | VT_SYM;
2889 put_extern_sym(sym, sec, offset, size);
2890 return sym;
2893 /* push a reference to a section offset by adding a dummy symbol */
2894 void vpush_ref(int t, Section *sec, unsigned long offset, unsigned long size)
2896 CValue cval;
2898 cval.sym = get_sym_ref(t, sec, offset, size);
2899 vsetc(t, VT_CONST | VT_SYM, &cval);
2902 /* push a reference to global symbol v */
2903 void vpush_sym(int t, int v)
2905 Sym *sym;
2906 CValue cval;
2908 sym = external_sym(v, t, 0);
2909 cval.sym = sym;
2910 vsetc(t, VT_CONST | VT_SYM, &cval);
2913 void vset(int t, int r, int v)
2915 CValue cval;
2917 cval.i = v;
2918 vsetc(t, r, &cval);
2921 void vswap(void)
2923 SValue tmp;
2925 tmp = vtop[0];
2926 vtop[0] = vtop[-1];
2927 vtop[-1] = tmp;
2930 void vpushv(SValue *v)
2932 if (vtop >= vstack + VSTACK_SIZE)
2933 error("memory full");
2934 vtop++;
2935 *vtop = *v;
2938 void vdup(void)
2940 vpushv(vtop);
2943 /* save r to the memory stack, and mark it as being free */
2944 void save_reg(int r)
2946 int l, saved, t, size, align;
2947 SValue *p, sv;
2949 /* modify all stack values */
2950 saved = 0;
2951 l = 0;
2952 for(p=vstack;p<=vtop;p++) {
2953 if ((p->r & VT_VALMASK) == r ||
2954 (p->r2 & VT_VALMASK) == r) {
2955 /* must save value on stack if not already done */
2956 if (!saved) {
2957 /* store register in the stack */
2958 t = p->t;
2959 if ((p->r & VT_LVAL) ||
2960 (!is_float(t) && (t & VT_BTYPE) != VT_LLONG))
2961 t = VT_INT;
2962 size = type_size(t, &align);
2963 loc = (loc - size) & -align;
2964 sv.t = t;
2965 sv.r = VT_LOCAL | VT_LVAL;
2966 sv.c.ul = loc;
2967 store(r, &sv);
2968 #ifdef TCC_TARGET_I386
2969 /* x86 specific: need to pop fp register ST0 if saved */
2970 if (r == REG_ST0) {
2971 o(0xd9dd); /* fstp %st(1) */
2973 #endif
2974 /* special long long case */
2975 if ((t & VT_BTYPE) == VT_LLONG) {
2976 sv.c.ul += 4;
2977 store(p->r2, &sv);
2979 l = loc;
2980 saved = 1;
2982 /* mark that stack entry as being saved on the stack */
2983 if (p->r & VT_LVAL) {
2984 /* also suppress the bounded flag because the
2985 relocation address of the function was stored in
2986 p->c.ul */
2987 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
2988 } else {
2989 p->r = lvalue_type(p->t) | VT_LOCAL;
2991 p->r2 = VT_CONST;
2992 p->c.ul = l;
2997 /* find a free register of class 'rc'. If none, save one register */
2998 int get_reg(int rc)
3000 int r;
3001 SValue *p;
3003 /* find a free register */
3004 for(r=0;r<NB_REGS;r++) {
3005 if (reg_classes[r] & rc) {
3006 for(p=vstack;p<=vtop;p++) {
3007 if ((p->r & VT_VALMASK) == r ||
3008 (p->r2 & VT_VALMASK) == r)
3009 goto notfound;
3011 return r;
3013 notfound: ;
3016 /* no register left : free the first one on the stack (VERY
3017 IMPORTANT to start from the bottom to ensure that we don't
3018 spill registers used in gen_opi()) */
3019 for(p=vstack;p<=vtop;p++) {
3020 r = p->r & VT_VALMASK;
3021 if (r < VT_CONST && (reg_classes[r] & rc)) {
3022 save_reg(r);
3023 break;
3026 return r;
3029 /* save registers up to (vtop - n) stack entry */
3030 void save_regs(int n)
3032 int r;
3033 SValue *p, *p1;
3034 p1 = vtop - n;
3035 for(p = vstack;p <= p1; p++) {
3036 r = p->r & VT_VALMASK;
3037 if (r < VT_CONST) {
3038 save_reg(r);
3043 /* move register 's' to 'r', and flush previous value of r to memory
3044 if needed */
3045 void move_reg(int r, int s)
3047 SValue sv;
3049 if (r != s) {
3050 save_reg(r);
3051 sv.t = VT_INT;
3052 sv.r = s;
3053 sv.c.ul = 0;
3054 load(r, &sv);
3058 /* get address of vtop (vtop MUST BE an lvalue) */
3059 void gaddrof(void)
3061 vtop->r &= ~VT_LVAL;
3062 /* tricky: if saved lvalue, then we can go back to lvalue */
3063 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
3064 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
3067 #ifdef CONFIG_TCC_BCHECK
3068 /* generate lvalue bound code */
3069 void gbound(void)
3071 int lval_type, t1;
3073 vtop->r &= ~VT_MUSTBOUND;
3074 /* if lvalue, then use checking code before dereferencing */
3075 if (vtop->r & VT_LVAL) {
3076 /* if not VT_BOUNDED value, then make one */
3077 if (!(vtop->r & VT_BOUNDED)) {
3078 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
3079 /* must save type because we must set it to int to get pointer */
3080 t1 = vtop->t;
3081 vtop->t = VT_INT;
3082 gaddrof();
3083 vpushi(0);
3084 gen_bounded_ptr_add();
3085 vtop->r |= lval_type;
3086 vtop->t = t1;
3088 /* then check for dereferencing */
3089 gen_bounded_ptr_deref();
3092 #endif
3094 /* store vtop a register belonging to class 'rc'. lvalues are
3095 converted to values. Cannot be used if cannot be converted to
3096 register value (such as structures). */
3097 int gv(int rc)
3099 int r, r2, rc2, bit_pos, bit_size, size, align, i;
3100 unsigned long long ll;
3102 /* NOTE: get_reg can modify vstack[] */
3103 if (vtop->t & VT_BITFIELD) {
3104 bit_pos = (vtop->t >> VT_STRUCT_SHIFT) & 0x3f;
3105 bit_size = (vtop->t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
3106 /* remove bit field info to avoid loops */
3107 vtop->t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
3108 /* generate shifts */
3109 vpushi(32 - (bit_pos + bit_size));
3110 gen_op(TOK_SHL);
3111 vpushi(32 - bit_size);
3112 /* NOTE: transformed to SHR if unsigned */
3113 gen_op(TOK_SAR);
3114 r = gv(rc);
3115 } else {
3116 if (is_float(vtop->t) &&
3117 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3118 Sym *sym;
3119 int *ptr;
3120 unsigned long offset;
3122 /* XXX: unify with initializers handling ? */
3123 /* CPUs usually cannot use float constants, so we store them
3124 generically in data segment */
3125 size = type_size(vtop->t, &align);
3126 offset = (data_section->data_offset + align - 1) & -align;
3127 data_section->data_offset = offset;
3128 /* XXX: not portable yet */
3129 ptr = section_ptr_add(data_section, size);
3130 size = size >> 2;
3131 for(i=0;i<size;i++)
3132 ptr[i] = vtop->c.tab[i];
3133 sym = get_sym_ref(vtop->t, data_section, offset, size << 2);
3134 vtop->r |= VT_LVAL | VT_SYM;
3135 vtop->c.sym = sym;
3137 #ifdef CONFIG_TCC_BCHECK
3138 if (vtop->r & VT_MUSTBOUND)
3139 gbound();
3140 #endif
3142 r = vtop->r & VT_VALMASK;
3143 /* need to reload if:
3144 - constant
3145 - lvalue (need to dereference pointer)
3146 - already a register, but not in the right class */
3147 if (r >= VT_CONST ||
3148 (vtop->r & VT_LVAL) ||
3149 !(reg_classes[r] & rc) ||
3150 ((vtop->t & VT_BTYPE) == VT_LLONG &&
3151 !(reg_classes[vtop->r2] & rc))) {
3152 r = get_reg(rc);
3153 if ((vtop->t & VT_BTYPE) == VT_LLONG) {
3154 /* two register type load : expand to two words
3155 temporarily */
3156 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3157 /* load constant */
3158 ll = vtop->c.ull;
3159 vtop->c.ui = ll; /* first word */
3160 load(r, vtop);
3161 vtop->r = r; /* save register value */
3162 vpushi(ll >> 32); /* second word */
3163 } else if (r >= VT_CONST ||
3164 (vtop->r & VT_LVAL)) {
3165 /* load from memory */
3166 load(r, vtop);
3167 vdup();
3168 vtop[-1].r = r; /* save register value */
3169 /* increment pointer to get second word */
3170 vtop->t = VT_INT;
3171 gaddrof();
3172 vpushi(4);
3173 gen_op('+');
3174 vtop->r |= VT_LVAL;
3175 } else {
3176 /* move registers */
3177 load(r, vtop);
3178 vdup();
3179 vtop[-1].r = r; /* save register value */
3180 vtop->r = vtop[-1].r2;
3182 /* allocate second register */
3183 rc2 = RC_INT;
3184 if (rc == RC_IRET)
3185 rc2 = RC_LRET;
3186 r2 = get_reg(rc2);
3187 load(r2, vtop);
3188 vpop();
3189 /* write second register */
3190 vtop->r2 = r2;
3191 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->t)) {
3192 int t1, t;
3193 /* lvalue of scalar type : need to use lvalue type
3194 because of possible cast */
3195 t = vtop->t;
3196 t1 = t;
3197 /* compute memory access type */
3198 if (vtop->r & VT_LVAL_BYTE)
3199 t = VT_BYTE;
3200 else if (vtop->r & VT_LVAL_SHORT)
3201 t = VT_SHORT;
3202 if (vtop->r & VT_LVAL_UNSIGNED)
3203 t |= VT_UNSIGNED;
3204 vtop->t = t;
3205 load(r, vtop);
3206 /* restore wanted type */
3207 vtop->t = t1;
3208 } else {
3209 /* one register type load */
3210 load(r, vtop);
3213 vtop->r = r;
3215 return r;
3218 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3219 void gv2(int rc1, int rc2)
3221 /* generate more generic register first */
3222 if (rc1 <= rc2) {
3223 vswap();
3224 gv(rc1);
3225 vswap();
3226 gv(rc2);
3227 /* test if reload is needed for first register */
3228 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
3229 vswap();
3230 gv(rc1);
3231 vswap();
3233 } else {
3234 gv(rc2);
3235 vswap();
3236 gv(rc1);
3237 vswap();
3238 /* test if reload is needed for first register */
3239 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
3240 gv(rc2);
3245 /* expand long long on stack in two int registers */
3246 void lexpand(void)
3248 int u;
3250 u = vtop->t & VT_UNSIGNED;
3251 gv(RC_INT);
3252 vdup();
3253 vtop[0].r = vtop[-1].r2;
3254 vtop[0].r2 = VT_CONST;
3255 vtop[-1].r2 = VT_CONST;
3256 vtop[0].t = VT_INT | u;
3257 vtop[-1].t = VT_INT | u;
3260 /* build a long long from two ints */
3261 void lbuild(int t)
3263 gv2(RC_INT, RC_INT);
3264 vtop[-1].r2 = vtop[0].r;
3265 vtop[-1].t = t;
3266 vpop();
3269 /* rotate n first stack elements to the bottom */
3270 void vrotb(int n)
3272 int i;
3273 SValue tmp;
3275 tmp = vtop[-n + 1];
3276 for(i=-n+1;i!=0;i++)
3277 vtop[i] = vtop[i+1];
3278 vtop[0] = tmp;
3281 /* pop stack value */
3282 void vpop(void)
3284 int v;
3285 v = vtop->r & VT_VALMASK;
3286 #ifdef TCC_TARGET_I386
3287 /* for x86, we need to pop the FP stack */
3288 if (v == REG_ST0) {
3289 o(0xd9dd); /* fstp %st(1) */
3290 } else
3291 #endif
3292 if (v == VT_JMP || v == VT_JMPI) {
3293 /* need to put correct jump if && or || without test */
3294 gsym(vtop->c.ul);
3296 vtop--;
3299 /* convert stack entry to register and duplicate its value in another
3300 register */
3301 void gv_dup(void)
3303 int rc, t, r, r1;
3304 SValue sv;
3306 t = vtop->t;
3307 if ((t & VT_BTYPE) == VT_LLONG) {
3308 lexpand();
3309 gv_dup();
3310 vswap();
3311 vrotb(3);
3312 gv_dup();
3313 vrotb(4);
3314 /* stack: H L L1 H1 */
3315 lbuild(t);
3316 vrotb(3);
3317 vrotb(3);
3318 vswap();
3319 lbuild(t);
3320 vswap();
3321 } else {
3322 /* duplicate value */
3323 rc = RC_INT;
3324 sv.t = VT_INT;
3325 if (is_float(t)) {
3326 rc = RC_FLOAT;
3327 sv.t = t;
3329 r = gv(rc);
3330 r1 = get_reg(rc);
3331 sv.r = r;
3332 sv.c.ul = 0;
3333 load(r1, &sv); /* move r to r1 */
3334 vdup();
3335 /* duplicates value */
3336 vtop->r = r1;
3340 /* generate CPU independent (unsigned) long long operations */
3341 void gen_opl(int op)
3343 int t, a, b, op1, c, i;
3344 int func;
3345 GFuncContext gf;
3346 SValue tmp;
3348 switch(op) {
3349 case '/':
3350 case TOK_PDIV:
3351 func = TOK___divdi3;
3352 goto gen_func;
3353 case TOK_UDIV:
3354 func = TOK___udivdi3;
3355 goto gen_func;
3356 case '%':
3357 func = TOK___moddi3;
3358 goto gen_func;
3359 case TOK_UMOD:
3360 func = TOK___umoddi3;
3361 gen_func:
3362 /* call generic long long function */
3363 gfunc_start(&gf, FUNC_CDECL);
3364 gfunc_param(&gf);
3365 gfunc_param(&gf);
3366 vpush_sym(func_old_type, func);
3367 gfunc_call(&gf);
3368 vpushi(0);
3369 vtop->r = REG_IRET;
3370 vtop->r2 = REG_LRET;
3371 break;
3372 case '^':
3373 case '&':
3374 case '|':
3375 case '*':
3376 case '+':
3377 case '-':
3378 t = vtop->t;
3379 vswap();
3380 lexpand();
3381 vrotb(3);
3382 lexpand();
3383 /* stack: L1 H1 L2 H2 */
3384 tmp = vtop[0];
3385 vtop[0] = vtop[-3];
3386 vtop[-3] = tmp;
3387 tmp = vtop[-2];
3388 vtop[-2] = vtop[-3];
3389 vtop[-3] = tmp;
3390 vswap();
3391 /* stack: H1 H2 L1 L2 */
3392 if (op == '*') {
3393 vpushv(vtop - 1);
3394 vpushv(vtop - 1);
3395 gen_op(TOK_UMULL);
3396 lexpand();
3397 /* stack: H1 H2 L1 L2 ML MH */
3398 for(i=0;i<4;i++)
3399 vrotb(6);
3400 /* stack: ML MH H1 H2 L1 L2 */
3401 tmp = vtop[0];
3402 vtop[0] = vtop[-2];
3403 vtop[-2] = tmp;
3404 /* stack: ML MH H1 L2 H2 L1 */
3405 gen_op('*');
3406 vrotb(3);
3407 vrotb(3);
3408 gen_op('*');
3409 /* stack: ML MH M1 M2 */
3410 gen_op('+');
3411 gen_op('+');
3412 } else if (op == '+' || op == '-') {
3413 /* XXX: add non carry method too (for MIPS or alpha) */
3414 if (op == '+')
3415 op1 = TOK_ADDC1;
3416 else
3417 op1 = TOK_SUBC1;
3418 gen_op(op1);
3419 /* stack: H1 H2 (L1 op L2) */
3420 vrotb(3);
3421 vrotb(3);
3422 gen_op(op1 + 1); /* TOK_xxxC2 */
3423 } else {
3424 gen_op(op);
3425 /* stack: H1 H2 (L1 op L2) */
3426 vrotb(3);
3427 vrotb(3);
3428 /* stack: (L1 op L2) H1 H2 */
3429 gen_op(op);
3430 /* stack: (L1 op L2) (H1 op H2) */
3432 /* stack: L H */
3433 lbuild(t);
3434 break;
3435 case TOK_SAR:
3436 case TOK_SHR:
3437 case TOK_SHL:
3438 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3439 t = vtop[-1].t;
3440 vswap();
3441 lexpand();
3442 vrotb(3);
3443 /* stack: L H shift */
3444 c = (int)vtop->c.i;
3445 /* constant: simpler */
3446 /* NOTE: all comments are for SHL. the other cases are
3447 done by swaping words */
3448 vpop();
3449 if (op != TOK_SHL)
3450 vswap();
3451 if (c >= 32) {
3452 /* stack: L H */
3453 vpop();
3454 if (c > 32) {
3455 vpushi(c - 32);
3456 gen_op(op);
3458 if (op != TOK_SAR) {
3459 vpushi(0);
3460 } else {
3461 gv_dup();
3462 vpushi(31);
3463 gen_op(TOK_SAR);
3465 vswap();
3466 } else {
3467 vswap();
3468 gv_dup();
3469 /* stack: H L L */
3470 vpushi(c);
3471 gen_op(op);
3472 vswap();
3473 vpushi(32 - c);
3474 if (op == TOK_SHL)
3475 gen_op(TOK_SHR);
3476 else
3477 gen_op(TOK_SHL);
3478 vrotb(3);
3479 /* stack: L L H */
3480 vpushi(c);
3481 gen_op(op);
3482 gen_op('|');
3484 if (op != TOK_SHL)
3485 vswap();
3486 lbuild(t);
3487 } else {
3488 /* XXX: should provide a faster fallback on x86 ? */
3489 switch(op) {
3490 case TOK_SAR:
3491 func = TOK___sardi3;
3492 goto gen_func;
3493 case TOK_SHR:
3494 func = TOK___shrdi3;
3495 goto gen_func;
3496 case TOK_SHL:
3497 func = TOK___shldi3;
3498 goto gen_func;
3501 break;
3502 default:
3503 /* compare operations */
3504 t = vtop->t;
3505 vswap();
3506 lexpand();
3507 vrotb(3);
3508 lexpand();
3509 /* stack: L1 H1 L2 H2 */
3510 tmp = vtop[-1];
3511 vtop[-1] = vtop[-2];
3512 vtop[-2] = tmp;
3513 /* stack: L1 L2 H1 H2 */
3514 /* compare high */
3515 op1 = op;
3516 /* when values are equal, we need to compare low words. since
3517 the jump is inverted, we invert the test too. */
3518 if (op1 == TOK_LT)
3519 op1 = TOK_LE;
3520 else if (op1 == TOK_GT)
3521 op1 = TOK_GE;
3522 else if (op1 == TOK_ULT)
3523 op1 = TOK_ULE;
3524 else if (op1 == TOK_UGT)
3525 op1 = TOK_UGE;
3526 a = 0;
3527 b = 0;
3528 gen_op(op1);
3529 if (op1 != TOK_NE) {
3530 a = gtst(1, 0);
3532 if (op != TOK_EQ) {
3533 /* generate non equal test */
3534 /* XXX: NOT PORTABLE yet */
3535 if (a == 0) {
3536 b = gtst(0, 0);
3537 } else {
3538 #ifdef TCC_TARGET_I386
3539 b = psym(0x850f, 0);
3540 #else
3541 error("not implemented");
3542 #endif
3545 /* compare low */
3546 gen_op(op);
3547 a = gtst(1, a);
3548 gsym(b);
3549 vset(VT_INT, VT_JMPI, a);
3550 break;
3554 /* handle integer constant optimizations and various machine
3555 independant opt */
3556 void gen_opic(int op)
3558 int fc, c1, c2, n;
3559 SValue *v1, *v2;
3561 v1 = vtop - 1;
3562 v2 = vtop;
3563 /* currently, we cannot do computations with forward symbols */
3564 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3565 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3566 if (c1 && c2) {
3567 fc = v2->c.i;
3568 switch(op) {
3569 case '+': v1->c.i += fc; break;
3570 case '-': v1->c.i -= fc; break;
3571 case '&': v1->c.i &= fc; break;
3572 case '^': v1->c.i ^= fc; break;
3573 case '|': v1->c.i |= fc; break;
3574 case '*': v1->c.i *= fc; break;
3576 case TOK_PDIV:
3577 case '/':
3578 case '%':
3579 case TOK_UDIV:
3580 case TOK_UMOD:
3581 /* if division by zero, generate explicit division */
3582 if (fc == 0) {
3583 if (const_wanted)
3584 error("division by zero in constant");
3585 goto general_case;
3587 switch(op) {
3588 default: v1->c.i /= fc; break;
3589 case '%': v1->c.i %= fc; break;
3590 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
3591 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
3593 break;
3594 case TOK_SHL: v1->c.i <<= fc; break;
3595 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
3596 case TOK_SAR: v1->c.i >>= fc; break;
3597 /* tests */
3598 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
3599 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
3600 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
3601 case TOK_NE: v1->c.i = v1->c.i != fc; break;
3602 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
3603 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
3604 case TOK_LT: v1->c.i = v1->c.i < fc; break;
3605 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
3606 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
3607 case TOK_GT: v1->c.i = v1->c.i > fc; break;
3608 /* logical */
3609 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
3610 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
3611 default:
3612 goto general_case;
3614 vtop--;
3615 } else {
3616 /* if commutative ops, put c2 as constant */
3617 if (c1 && (op == '+' || op == '&' || op == '^' ||
3618 op == '|' || op == '*')) {
3619 vswap();
3620 swap(&c1, &c2);
3622 fc = vtop->c.i;
3623 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
3624 op == TOK_PDIV) &&
3625 fc == 1) ||
3626 ((op == '+' || op == '-' || op == '|' || op == '^' ||
3627 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
3628 fc == 0) ||
3629 (op == '&' &&
3630 fc == -1))) {
3631 /* nothing to do */
3632 vtop--;
3633 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
3634 /* try to use shifts instead of muls or divs */
3635 if (fc > 0 && (fc & (fc - 1)) == 0) {
3636 n = -1;
3637 while (fc) {
3638 fc >>= 1;
3639 n++;
3641 vtop->c.i = n;
3642 if (op == '*')
3643 op = TOK_SHL;
3644 else if (op == TOK_PDIV)
3645 op = TOK_SAR;
3646 else
3647 op = TOK_SHR;
3649 goto general_case;
3650 } else {
3651 general_case:
3652 /* call low level op generator */
3653 gen_opi(op);
3658 /* generate a floating point operation with constant propagation */
3659 void gen_opif(int op)
3661 int c1, c2;
3662 SValue *v1, *v2;
3663 long double f1, f2;
3665 v1 = vtop - 1;
3666 v2 = vtop;
3667 /* currently, we cannot do computations with forward symbols */
3668 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3669 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3670 if (c1 && c2) {
3671 if (v1->t == VT_FLOAT) {
3672 f1 = v1->c.f;
3673 f2 = v2->c.f;
3674 } else if (v1->t == VT_DOUBLE) {
3675 f1 = v1->c.d;
3676 f2 = v2->c.d;
3677 } else {
3678 f1 = v1->c.ld;
3679 f2 = v2->c.ld;
3682 /* NOTE: we only do constant propagation if finite number (not
3683 NaN or infinity) (ANSI spec) */
3684 if (!ieee_finite(f1) || !ieee_finite(f2))
3685 goto general_case;
3687 switch(op) {
3688 case '+': f1 += f2; break;
3689 case '-': f1 -= f2; break;
3690 case '*': f1 *= f2; break;
3691 case '/':
3692 if (f2 == 0.0) {
3693 if (const_wanted)
3694 error("division by zero in constant");
3695 goto general_case;
3697 f1 /= f2;
3698 break;
3699 /* XXX: also handles tests ? */
3700 default:
3701 goto general_case;
3703 /* XXX: overflow test ? */
3704 if (v1->t == VT_FLOAT) {
3705 v1->c.f = f1;
3706 } else if (v1->t == VT_DOUBLE) {
3707 v1->c.d = f1;
3708 } else {
3709 v1->c.ld = f1;
3711 vtop--;
3712 } else {
3713 general_case:
3714 gen_opf(op);
3719 int pointed_size(int t)
3721 return type_size(pointed_type(t), &t);
3724 #if 0
3725 void check_pointer_types(SValue *p1, SValue *p2)
3727 char buf1[256], buf2[256];
3728 int t1, t2;
3729 t1 = p1->t;
3730 t2 = p2->t;
3731 if (!is_compatible_types(t1, t2)) {
3732 type_to_str(buf1, sizeof(buf1), t1, NULL);
3733 type_to_str(buf2, sizeof(buf2), t2, NULL);
3734 error("incompatible pointers '%s' and '%s'", buf1, buf2);
3737 #endif
3739 /* generic gen_op: handles types problems */
3740 void gen_op(int op)
3742 int u, t1, t2, bt1, bt2, t;
3744 t1 = vtop[-1].t;
3745 t2 = vtop[0].t;
3746 bt1 = t1 & VT_BTYPE;
3747 bt2 = t2 & VT_BTYPE;
3749 if (bt1 == VT_PTR || bt2 == VT_PTR) {
3750 /* at least one operand is a pointer */
3751 /* relationnal op: must be both pointers */
3752 if (op >= TOK_ULT && op <= TOK_GT) {
3753 // check_pointer_types(vtop, vtop - 1);
3754 /* pointers are handled are unsigned */
3755 t = VT_INT | VT_UNSIGNED;
3756 goto std_op;
3758 /* if both pointers, then it must be the '-' op */
3759 if ((t1 & VT_BTYPE) == VT_PTR &&
3760 (t2 & VT_BTYPE) == VT_PTR) {
3761 if (op != '-')
3762 error("cannot use pointers here");
3763 // check_pointer_types(vtop - 1, vtop);
3764 /* XXX: check that types are compatible */
3765 u = pointed_size(t1);
3766 gen_opic(op);
3767 /* set to integer type */
3768 vtop->t = VT_INT;
3769 vpushi(u);
3770 gen_op(TOK_PDIV);
3771 } else {
3772 /* exactly one pointer : must be '+' or '-'. */
3773 if (op != '-' && op != '+')
3774 error("cannot use pointers here");
3775 /* Put pointer as first operand */
3776 if ((t2 & VT_BTYPE) == VT_PTR) {
3777 vswap();
3778 swap(&t1, &t2);
3780 /* XXX: cast to int ? (long long case) */
3781 vpushi(pointed_size(vtop[-1].t));
3782 gen_op('*');
3783 #ifdef CONFIG_TCC_BCHECK
3784 /* if evaluating constant expression, no code should be
3785 generated, so no bound check */
3786 if (do_bounds_check && !const_wanted) {
3787 /* if bounded pointers, we generate a special code to
3788 test bounds */
3789 if (op == '-') {
3790 vpushi(0);
3791 vswap();
3792 gen_op('-');
3794 gen_bounded_ptr_add();
3795 } else
3796 #endif
3798 gen_opic(op);
3800 /* put again type if gen_opic() swaped operands */
3801 vtop->t = t1;
3803 } else if (is_float(bt1) || is_float(bt2)) {
3804 /* compute bigger type and do implicit casts */
3805 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3806 t = VT_LDOUBLE;
3807 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3808 t = VT_DOUBLE;
3809 } else {
3810 t = VT_FLOAT;
3812 /* floats can only be used for a few operations */
3813 if (op != '+' && op != '-' && op != '*' && op != '/' &&
3814 (op < TOK_ULT || op > TOK_GT))
3815 error("invalid operands for binary operation");
3816 goto std_op;
3817 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3818 /* cast to biggest op */
3819 t = VT_LLONG;
3820 /* convert to unsigned if it does not fit in a long long */
3821 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
3822 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
3823 t |= VT_UNSIGNED;
3824 goto std_op;
3825 } else {
3826 /* integer operations */
3827 t = VT_INT;
3828 /* convert to unsigned if it does not fit in an integer */
3829 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
3830 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
3831 t |= VT_UNSIGNED;
3832 std_op:
3833 /* XXX: currently, some unsigned operations are explicit, so
3834 we modify them here */
3835 if (t & VT_UNSIGNED) {
3836 if (op == TOK_SAR)
3837 op = TOK_SHR;
3838 else if (op == '/')
3839 op = TOK_UDIV;
3840 else if (op == '%')
3841 op = TOK_UMOD;
3842 else if (op == TOK_LT)
3843 op = TOK_ULT;
3844 else if (op == TOK_GT)
3845 op = TOK_UGT;
3846 else if (op == TOK_LE)
3847 op = TOK_ULE;
3848 else if (op == TOK_GE)
3849 op = TOK_UGE;
3851 vswap();
3852 gen_cast(t);
3853 vswap();
3854 /* special case for shifts and long long: we keep the shift as
3855 an integer */
3856 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
3857 gen_cast(VT_INT);
3858 else
3859 gen_cast(t);
3860 if (is_float(t))
3861 gen_opif(op);
3862 else if ((t & VT_BTYPE) == VT_LLONG)
3863 gen_opl(op);
3864 else
3865 gen_opic(op);
3866 if (op >= TOK_ULT && op <= TOK_GT) {
3867 /* relationnal op: the result is an int */
3868 vtop->t = VT_INT;
3869 } else {
3870 vtop->t = t;
3875 /* generic itof for unsigned long long case */
3876 void gen_cvt_itof1(int t)
3878 GFuncContext gf;
3880 if ((vtop->t & (VT_BTYPE | VT_UNSIGNED)) ==
3881 (VT_LLONG | VT_UNSIGNED)) {
3883 gfunc_start(&gf, FUNC_CDECL);
3884 gfunc_param(&gf);
3885 if (t == VT_FLOAT)
3886 vpush_sym(func_old_type, TOK___ulltof);
3887 else if (t == VT_DOUBLE)
3888 vpush_sym(func_old_type, TOK___ulltod);
3889 else
3890 vpush_sym(func_old_type, TOK___ulltold);
3891 gfunc_call(&gf);
3892 vpushi(0);
3893 vtop->r = REG_FRET;
3894 } else {
3895 gen_cvt_itof(t);
3899 /* generic ftoi for unsigned long long case */
3900 void gen_cvt_ftoi1(int t)
3902 GFuncContext gf;
3903 int st;
3905 if (t == (VT_LLONG | VT_UNSIGNED)) {
3906 /* not handled natively */
3907 gfunc_start(&gf, FUNC_CDECL);
3908 st = vtop->t & VT_BTYPE;
3909 gfunc_param(&gf);
3910 if (st == VT_FLOAT)
3911 vpush_sym(func_old_type, TOK___fixunssfdi);
3912 else if (st == VT_DOUBLE)
3913 vpush_sym(func_old_type, TOK___fixunsdfdi);
3914 else
3915 vpush_sym(func_old_type, TOK___fixunsxfdi);
3916 gfunc_call(&gf);
3917 vpushi(0);
3918 vtop->r = REG_IRET;
3919 vtop->r2 = REG_LRET;
3920 } else {
3921 gen_cvt_ftoi(t);
3925 /* force char or short cast */
3926 void force_charshort_cast(int t)
3928 int bits, dbt;
3929 dbt = t & VT_BTYPE;
3930 /* XXX: add optimization if lvalue : just change type and offset */
3931 if (dbt == VT_BYTE)
3932 bits = 8;
3933 else
3934 bits = 16;
3935 if (t & VT_UNSIGNED) {
3936 vpushi((1 << bits) - 1);
3937 gen_op('&');
3938 } else {
3939 bits = 32 - bits;
3940 vpushi(bits);
3941 gen_op(TOK_SHL);
3942 vpushi(bits);
3943 gen_op(TOK_SAR);
3947 /* cast 'vtop' to 't' type */
3948 void gen_cast(int t)
3950 int sbt, dbt, sf, df, c;
3952 /* special delayed cast for char/short */
3953 /* XXX: in some cases (multiple cascaded casts), it may still
3954 be incorrect */
3955 if (vtop->r & VT_MUSTCAST) {
3956 vtop->r &= ~VT_MUSTCAST;
3957 force_charshort_cast(vtop->t);
3960 dbt = t & (VT_BTYPE | VT_UNSIGNED);
3961 sbt = vtop->t & (VT_BTYPE | VT_UNSIGNED);
3963 if (sbt != dbt) {
3964 sf = is_float(sbt);
3965 df = is_float(dbt);
3966 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3967 if (sf && df) {
3968 /* convert from fp to fp */
3969 if (c) {
3970 /* constant case: we can do it now */
3971 /* XXX: in ISOC, cannot do it if error in convert */
3972 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
3973 vtop->c.f = (float)vtop->c.d;
3974 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
3975 vtop->c.f = (float)vtop->c.ld;
3976 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
3977 vtop->c.d = (double)vtop->c.f;
3978 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
3979 vtop->c.d = (double)vtop->c.ld;
3980 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
3981 vtop->c.ld = (long double)vtop->c.f;
3982 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
3983 vtop->c.ld = (long double)vtop->c.d;
3984 } else {
3985 /* non constant case: generate code */
3986 gen_cvt_ftof(dbt);
3988 } else if (df) {
3989 /* convert int to fp */
3990 if (c) {
3991 switch(sbt) {
3992 case VT_LLONG | VT_UNSIGNED:
3993 case VT_LLONG:
3994 /* XXX: add const cases for long long */
3995 goto do_itof;
3996 case VT_INT | VT_UNSIGNED:
3997 switch(dbt) {
3998 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
3999 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
4000 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
4002 break;
4003 default:
4004 switch(dbt) {
4005 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
4006 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
4007 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
4009 break;
4011 } else {
4012 do_itof:
4013 gen_cvt_itof1(dbt);
4015 } else if (sf) {
4016 /* convert fp to int */
4017 /* we handle char/short/etc... with generic code */
4018 if (dbt != (VT_INT | VT_UNSIGNED) &&
4019 dbt != (VT_LLONG | VT_UNSIGNED) &&
4020 dbt != VT_LLONG)
4021 dbt = VT_INT;
4022 if (c) {
4023 switch(dbt) {
4024 case VT_LLONG | VT_UNSIGNED:
4025 case VT_LLONG:
4026 /* XXX: add const cases for long long */
4027 goto do_ftoi;
4028 case VT_INT | VT_UNSIGNED:
4029 switch(sbt) {
4030 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
4031 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4032 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4034 break;
4035 default:
4036 /* int case */
4037 switch(sbt) {
4038 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
4039 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
4040 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
4042 break;
4044 } else {
4045 do_ftoi:
4046 gen_cvt_ftoi1(dbt);
4048 if (dbt == VT_INT && (t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
4049 /* additionnal cast for char/short/bool... */
4050 vtop->t = dbt;
4051 gen_cast(t);
4053 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
4054 if ((sbt & VT_BTYPE) != VT_LLONG) {
4055 /* scalar to long long */
4056 if (c) {
4057 if (sbt == (VT_INT | VT_UNSIGNED))
4058 vtop->c.ll = vtop->c.ui;
4059 else
4060 vtop->c.ll = vtop->c.i;
4061 } else {
4062 /* machine independant conversion */
4063 gv(RC_INT);
4064 /* generate high word */
4065 if (sbt == (VT_INT | VT_UNSIGNED)) {
4066 vpushi(0);
4067 gv(RC_INT);
4068 } else {
4069 gv_dup();
4070 vpushi(31);
4071 gen_op(TOK_SAR);
4073 /* patch second register */
4074 vtop[-1].r2 = vtop->r;
4075 vpop();
4078 } else if (dbt == VT_BOOL) {
4079 /* scalar to bool */
4080 vpushi(0);
4081 gen_op(TOK_NE);
4082 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
4083 (dbt & VT_BTYPE) == VT_SHORT) {
4084 force_charshort_cast(t);
4085 } else if ((dbt & VT_BTYPE) == VT_INT) {
4086 /* scalar to int */
4087 if (sbt == VT_LLONG) {
4088 /* from long long: just take low order word */
4089 lexpand();
4090 vpop();
4092 /* if lvalue and single word type, nothing to do because
4093 the lvalue already contains the real type size (see
4094 VT_LVAL_xxx constants) */
4097 vtop->t = t;
4100 /* return type size. Put alignment at 'a' */
4101 int type_size(int t, int *a)
4103 Sym *s;
4104 int bt;
4106 bt = t & VT_BTYPE;
4107 if (bt == VT_STRUCT) {
4108 /* struct/union */
4109 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4110 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
4111 return s->c;
4112 } else if (bt == VT_PTR) {
4113 if (t & VT_ARRAY) {
4114 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4115 return type_size(s->t, a) * s->c;
4116 } else {
4117 *a = PTR_SIZE;
4118 return PTR_SIZE;
4120 } else if (bt == VT_LDOUBLE) {
4121 *a = LDOUBLE_ALIGN;
4122 return LDOUBLE_SIZE;
4123 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
4124 *a = 8;
4125 return 8;
4126 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
4127 *a = 4;
4128 return 4;
4129 } else if (bt == VT_SHORT) {
4130 *a = 2;
4131 return 2;
4132 } else {
4133 /* char, void, function, _Bool */
4134 *a = 1;
4135 return 1;
4139 /* return the pointed type of t */
4140 int pointed_type(int t)
4142 Sym *s;
4143 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4144 return s->t | (t & ~VT_TYPE);
4147 int mk_pointer(int t)
4149 int p;
4150 p = anon_sym++;
4151 sym_push(p, t, 0, -1);
4152 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
4155 int is_compatible_types(int t1, int t2)
4157 Sym *s1, *s2;
4158 int bt1, bt2;
4160 t1 &= VT_TYPE;
4161 t2 &= VT_TYPE;
4162 bt1 = t1 & VT_BTYPE;
4163 bt2 = t2 & VT_BTYPE;
4164 if (bt1 == VT_PTR) {
4165 t1 = pointed_type(t1);
4166 /* if function, then convert implicitely to function pointer */
4167 if (bt2 != VT_FUNC) {
4168 if (bt2 != VT_PTR)
4169 return 0;
4170 t2 = pointed_type(t2);
4172 /* void matches everything */
4173 t1 &= VT_TYPE;
4174 t2 &= VT_TYPE;
4175 if (t1 == VT_VOID || t2 == VT_VOID)
4176 return 1;
4177 return is_compatible_types(t1, t2);
4178 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4179 return (t2 == t1);
4180 } else if (bt1 == VT_FUNC) {
4181 if (bt2 != VT_FUNC)
4182 return 0;
4183 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
4184 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
4185 if (!is_compatible_types(s1->t, s2->t))
4186 return 0;
4187 /* XXX: not complete */
4188 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
4189 return 1;
4190 if (s1->c != s2->c)
4191 return 0;
4192 while (s1 != NULL) {
4193 if (s2 == NULL)
4194 return 0;
4195 if (!is_compatible_types(s1->t, s2->t))
4196 return 0;
4197 s1 = s1->next;
4198 s2 = s2->next;
4200 if (s2)
4201 return 0;
4202 return 1;
4203 } else {
4204 /* XXX: not complete */
4205 return 1;
4209 /* print a type. If 'varstr' is not NULL, then the variable is also
4210 printed in the type */
4211 /* XXX: union */
4212 /* XXX: add array and function pointers */
4213 void type_to_str(char *buf, int buf_size,
4214 int t, const char *varstr)
4216 int bt, v;
4217 Sym *s, *sa;
4218 char buf1[256];
4219 const char *tstr;
4221 t = t & VT_TYPE;
4222 bt = t & VT_BTYPE;
4223 buf[0] = '\0';
4224 if (t & VT_UNSIGNED)
4225 pstrcat(buf, buf_size, "unsigned ");
4226 switch(bt) {
4227 case VT_VOID:
4228 tstr = "void";
4229 goto add_tstr;
4230 case VT_BOOL:
4231 tstr = "_Bool";
4232 goto add_tstr;
4233 case VT_BYTE:
4234 tstr = "char";
4235 goto add_tstr;
4236 case VT_SHORT:
4237 tstr = "short";
4238 goto add_tstr;
4239 case VT_INT:
4240 tstr = "int";
4241 goto add_tstr;
4242 case VT_LONG:
4243 tstr = "long";
4244 goto add_tstr;
4245 case VT_LLONG:
4246 tstr = "long long";
4247 goto add_tstr;
4248 case VT_FLOAT:
4249 tstr = "float";
4250 goto add_tstr;
4251 case VT_DOUBLE:
4252 tstr = "double";
4253 goto add_tstr;
4254 case VT_LDOUBLE:
4255 tstr = "long double";
4256 add_tstr:
4257 pstrcat(buf, buf_size, tstr);
4258 break;
4259 case VT_ENUM:
4260 case VT_STRUCT:
4261 if (bt == VT_STRUCT)
4262 tstr = "struct ";
4263 else
4264 tstr = "enum ";
4265 pstrcat(buf, buf_size, tstr);
4266 v = (unsigned)t >> VT_STRUCT_SHIFT;
4267 if (v >= SYM_FIRST_ANOM)
4268 pstrcat(buf, buf_size, "<anonymous>");
4269 else
4270 pstrcat(buf, buf_size, get_tok_str(v, NULL));
4271 break;
4272 case VT_FUNC:
4273 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4274 type_to_str(buf, buf_size, s->t, varstr);
4275 pstrcat(buf, buf_size, "(");
4276 sa = s->next;
4277 while (sa != NULL) {
4278 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
4279 pstrcat(buf, buf_size, buf1);
4280 sa = sa->next;
4281 if (sa)
4282 pstrcat(buf, buf_size, ", ");
4284 pstrcat(buf, buf_size, ")");
4285 goto no_var;
4286 case VT_PTR:
4287 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4288 pstrcpy(buf1, sizeof(buf1), "*");
4289 if (varstr)
4290 pstrcat(buf1, sizeof(buf1), varstr);
4291 type_to_str(buf, buf_size, s->t, buf1);
4292 goto no_var;
4294 if (varstr) {
4295 pstrcat(buf, buf_size, " ");
4296 pstrcat(buf, buf_size, varstr);
4298 no_var: ;
4301 /* verify type compatibility to store vtop in 'dt' type, and generate
4302 casts if needed. */
4303 void gen_assign_cast(int dt)
4305 int st;
4306 char buf1[256], buf2[256];
4308 st = vtop->t; /* source type */
4309 if ((dt & VT_BTYPE) == VT_PTR) {
4310 /* special cases for pointers */
4311 /* a function is implicitely a function pointer */
4312 if ((st & VT_BTYPE) == VT_FUNC) {
4313 if (!is_compatible_types(pointed_type(dt), st))
4314 goto error;
4315 else
4316 goto type_ok;
4318 /* '0' can also be a pointer */
4319 if ((st & VT_BTYPE) == VT_INT &&
4320 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
4321 vtop->c.i == 0)
4322 goto type_ok;
4324 if (!is_compatible_types(dt, st)) {
4325 error:
4326 type_to_str(buf1, sizeof(buf1), st, NULL);
4327 type_to_str(buf2, sizeof(buf2), dt, NULL);
4328 error("cannot cast '%s' to '%s'", buf1, buf2);
4330 type_ok:
4331 gen_cast(dt);
4334 /* store vtop in lvalue pushed on stack */
4335 void vstore(void)
4337 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
4338 GFuncContext gf;
4340 ft = vtop[-1].t;
4341 sbt = vtop->t & VT_BTYPE;
4342 dbt = ft & VT_BTYPE;
4343 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
4344 (sbt == VT_INT && dbt == VT_SHORT)) {
4345 /* optimize char/short casts */
4346 delayed_cast = VT_MUSTCAST;
4347 vtop->t = ft & VT_TYPE;
4348 } else {
4349 delayed_cast = 0;
4350 gen_assign_cast(ft & VT_TYPE);
4353 if (sbt == VT_STRUCT) {
4354 /* if structure, only generate pointer */
4355 /* structure assignment : generate memcpy */
4356 /* XXX: optimize if small size */
4357 vdup();
4358 gfunc_start(&gf, FUNC_CDECL);
4359 /* type size */
4360 size = type_size(vtop->t, &align);
4361 vpushi(size);
4362 gfunc_param(&gf);
4363 /* source */
4364 vtop->t = VT_INT;
4365 gaddrof();
4366 gfunc_param(&gf);
4367 /* destination */
4368 vswap();
4369 vtop->t = VT_INT;
4370 gaddrof();
4371 gfunc_param(&gf);
4373 save_regs(0);
4374 vpush_sym(func_old_type, TOK_memcpy);
4375 gfunc_call(&gf);
4376 /* leave source on stack */
4377 } else if (ft & VT_BITFIELD) {
4378 /* bitfield store handling */
4379 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
4380 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4381 /* remove bit field info to avoid loops */
4382 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4384 /* duplicate destination */
4385 vdup();
4386 vtop[-1] = vtop[-2];
4388 /* mask and shift source */
4389 vpushi((1 << bit_size) - 1);
4390 gen_op('&');
4391 vpushi(bit_pos);
4392 gen_op(TOK_SHL);
4393 /* load destination, mask and or with source */
4394 vswap();
4395 vpushi(~(((1 << bit_size) - 1) << bit_pos));
4396 gen_op('&');
4397 gen_op('|');
4398 /* store result */
4399 vstore();
4400 } else {
4401 #ifdef CONFIG_TCC_BCHECK
4402 /* bound check case */
4403 if (vtop[-1].r & VT_MUSTBOUND) {
4404 vswap();
4405 gbound();
4406 vswap();
4408 #endif
4409 rc = RC_INT;
4410 if (is_float(ft))
4411 rc = RC_FLOAT;
4412 r = gv(rc); /* generate value */
4413 /* if lvalue was saved on stack, must read it */
4414 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
4415 SValue sv;
4416 t = get_reg(RC_INT);
4417 sv.t = VT_INT;
4418 sv.r = VT_LOCAL | VT_LVAL;
4419 sv.c.ul = vtop[-1].c.ul;
4420 load(t, &sv);
4421 vtop[-1].r = t | VT_LVAL;
4423 store(r, vtop - 1);
4424 /* two word case handling : store second register at word + 4 */
4425 if ((ft & VT_BTYPE) == VT_LLONG) {
4426 vswap();
4427 /* convert to int to increment easily */
4428 vtop->t = VT_INT;
4429 gaddrof();
4430 vpushi(4);
4431 gen_op('+');
4432 vtop->r |= VT_LVAL;
4433 vswap();
4434 /* XXX: it works because r2 is spilled last ! */
4435 store(vtop->r2, vtop - 1);
4437 vswap();
4438 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4439 vtop->r |= delayed_cast;
4443 /* post defines POST/PRE add. c is the token ++ or -- */
4444 void inc(int post, int c)
4446 test_lvalue();
4447 vdup(); /* save lvalue */
4448 if (post) {
4449 gv_dup(); /* duplicate value */
4450 vrotb(3);
4451 vrotb(3);
4453 /* add constant */
4454 vpushi(c - TOK_MID);
4455 gen_op('+');
4456 vstore(); /* store value */
4457 if (post)
4458 vpop(); /* if post op, return saved value */
4461 /* Parse GNUC __attribute__ extension. Currently, the following
4462 extensions are recognized:
4463 - aligned(n) : set data/function alignment.
4464 - section(x) : generate data/code in this section.
4465 - unused : currently ignored, but may be used someday.
4467 void parse_attribute(AttributeDef *ad)
4469 int t, n;
4471 next();
4472 skip('(');
4473 skip('(');
4474 while (tok != ')') {
4475 if (tok < TOK_IDENT)
4476 expect("attribute name");
4477 t = tok;
4478 next();
4479 switch(t) {
4480 case TOK_SECTION:
4481 case TOK___SECTION__:
4482 skip('(');
4483 if (tok != TOK_STR)
4484 expect("section name");
4485 ad->section = find_section((char *)tokc.cstr->data);
4486 next();
4487 skip(')');
4488 break;
4489 case TOK_ALIGNED:
4490 case TOK___ALIGNED__:
4491 skip('(');
4492 n = expr_const();
4493 if (n <= 0 || (n & (n - 1)) != 0)
4494 error("alignment must be a positive power of two");
4495 ad->aligned = n;
4496 skip(')');
4497 break;
4498 case TOK_UNUSED:
4499 case TOK___UNUSED__:
4500 /* currently, no need to handle it because tcc does not
4501 track unused objects */
4502 break;
4503 case TOK_NORETURN:
4504 case TOK___NORETURN__:
4505 /* currently, no need to handle it because tcc does not
4506 track unused objects */
4507 break;
4508 case TOK_CDECL:
4509 case TOK___CDECL:
4510 case TOK___CDECL__:
4511 ad->func_call = FUNC_CDECL;
4512 break;
4513 case TOK_STDCALL:
4514 case TOK___STDCALL:
4515 case TOK___STDCALL__:
4516 ad->func_call = FUNC_STDCALL;
4517 break;
4518 default:
4519 warning("'%s' attribute ignored", get_tok_str(t, NULL));
4520 /* skip parameters */
4521 /* XXX: skip parenthesis too */
4522 if (tok == '(') {
4523 next();
4524 while (tok != ')' && tok != -1)
4525 next();
4526 next();
4528 break;
4530 if (tok != ',')
4531 break;
4532 next();
4534 skip(')');
4535 skip(')');
4538 /* enum/struct/union declaration */
4539 int struct_decl(int u)
4541 int a, t, b, v, size, align, maxalign, c, offset;
4542 int bit_size, bit_pos, bsize, bt, lbit_pos;
4543 Sym *s, *ss, **ps;
4544 AttributeDef ad;
4546 a = tok; /* save decl type */
4547 next();
4548 if (tok != '{') {
4549 v = tok;
4550 next();
4551 /* struct already defined ? return it */
4552 /* XXX: check consistency */
4553 s = sym_find(v | SYM_STRUCT);
4554 if (s) {
4555 if (s->t != a)
4556 error("invalid type");
4557 goto do_decl;
4559 } else {
4560 v = anon_sym++;
4562 s = sym_push(v | SYM_STRUCT, a, 0, 0);
4563 /* put struct/union/enum name in type */
4564 do_decl:
4565 u = u | (v << VT_STRUCT_SHIFT);
4567 if (tok == '{') {
4568 next();
4569 if (s->c)
4570 error("struct/union/enum already defined");
4571 /* cannot be empty */
4572 c = 0;
4573 maxalign = 0;
4574 ps = &s->next;
4575 bit_pos = 0;
4576 offset = 0;
4577 while (1) {
4578 if (a == TOK_ENUM) {
4579 v = tok;
4580 next();
4581 if (tok == '=') {
4582 next();
4583 c = expr_const();
4585 /* enum symbols have static storage */
4586 sym_push(v, VT_STATIC | VT_INT, VT_CONST, c);
4587 if (tok == ',')
4588 next();
4589 c++;
4590 } else {
4591 parse_btype(&b, &ad);
4592 while (1) {
4593 bit_size = -1;
4594 v = 0;
4595 if (tok != ':') {
4596 t = type_decl(&ad, &v, b, TYPE_DIRECT);
4597 if ((t & VT_BTYPE) == VT_FUNC ||
4598 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
4599 error("invalid type for '%s'",
4600 get_tok_str(v, NULL));
4601 } else {
4602 t = b;
4604 if (tok == ':') {
4605 next();
4606 bit_size = expr_const();
4607 /* XXX: handle v = 0 case for messages */
4608 if (bit_size < 0)
4609 error("negative width in bit-field '%s'",
4610 get_tok_str(v, NULL));
4611 if (v && bit_size == 0)
4612 error("zero width for bit-field '%s'",
4613 get_tok_str(v, NULL));
4615 size = type_size(t, &align);
4616 lbit_pos = 0;
4617 if (bit_size >= 0) {
4618 bt = t & VT_BTYPE;
4619 if (bt != VT_INT &&
4620 bt != VT_BYTE &&
4621 bt != VT_SHORT)
4622 error("bitfields must have scalar type");
4623 bsize = size * 8;
4624 if (bit_size > bsize) {
4625 error("width of '%s' exceeds its type",
4626 get_tok_str(v, NULL));
4627 } else if (bit_size == bsize) {
4628 /* no need for bit fields */
4629 bit_pos = 0;
4630 } else if (bit_size == 0) {
4631 /* XXX: what to do if only padding in a
4632 structure ? */
4633 /* zero size: means to pad */
4634 if (bit_pos > 0)
4635 bit_pos = bsize;
4636 } else {
4637 /* we do not have enough room ? */
4638 if ((bit_pos + bit_size) > bsize)
4639 bit_pos = 0;
4640 lbit_pos = bit_pos;
4641 /* XXX: handle LSB first */
4642 t |= VT_BITFIELD |
4643 (bit_pos << VT_STRUCT_SHIFT) |
4644 (bit_size << (VT_STRUCT_SHIFT + 6));
4645 bit_pos += bit_size;
4647 } else {
4648 bit_pos = 0;
4650 if (v) {
4651 /* add new memory data only if starting
4652 bit field */
4653 if (lbit_pos == 0) {
4654 if (a == TOK_STRUCT) {
4655 c = (c + align - 1) & -align;
4656 offset = c;
4657 c += size;
4658 } else {
4659 offset = 0;
4660 if (size > c)
4661 c = size;
4663 if (align > maxalign)
4664 maxalign = align;
4666 #if 0
4667 printf("add field %s offset=%d",
4668 get_tok_str(v, NULL), offset);
4669 if (t & VT_BITFIELD) {
4670 printf(" pos=%d size=%d",
4671 (t >> VT_STRUCT_SHIFT) & 0x3f,
4672 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
4674 printf("\n");
4675 #endif
4676 ss = sym_push(v | SYM_FIELD, t, 0, offset);
4677 *ps = ss;
4678 ps = &ss->next;
4680 if (tok == ';' || tok == -1)
4681 break;
4682 skip(',');
4684 skip(';');
4686 if (tok == '}')
4687 break;
4689 skip('}');
4690 /* size for struct/union, dummy for enum */
4691 s->c = (c + maxalign - 1) & -maxalign;
4693 return u;
4696 /* return 0 if no type declaration. otherwise, return the basic type
4697 and skip it.
4699 int parse_btype(int *type_ptr, AttributeDef *ad)
4701 int t, u, type_found;
4702 Sym *s;
4704 memset(ad, 0, sizeof(AttributeDef));
4705 type_found = 0;
4706 t = 0;
4707 while(1) {
4708 switch(tok) {
4709 /* basic types */
4710 case TOK_CHAR:
4711 u = VT_BYTE;
4712 basic_type:
4713 next();
4714 basic_type1:
4715 if ((t & VT_BTYPE) != 0)
4716 error("too many basic types");
4717 t |= u;
4718 break;
4719 case TOK_VOID:
4720 u = VT_VOID;
4721 goto basic_type;
4722 case TOK_SHORT:
4723 u = VT_SHORT;
4724 goto basic_type;
4725 case TOK_INT:
4726 next();
4727 break;
4728 case TOK_LONG:
4729 next();
4730 if ((t & VT_BTYPE) == VT_DOUBLE) {
4731 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4732 } else if ((t & VT_BTYPE) == VT_LONG) {
4733 t = (t & ~VT_BTYPE) | VT_LLONG;
4734 } else {
4735 u = VT_LONG;
4736 goto basic_type1;
4738 break;
4739 case TOK_BOOL:
4740 u = VT_BOOL;
4741 goto basic_type;
4742 case TOK_FLOAT:
4743 u = VT_FLOAT;
4744 goto basic_type;
4745 case TOK_DOUBLE:
4746 next();
4747 if ((t & VT_BTYPE) == VT_LONG) {
4748 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4749 } else {
4750 u = VT_DOUBLE;
4751 goto basic_type1;
4753 break;
4754 case TOK_ENUM:
4755 u = struct_decl(VT_ENUM);
4756 goto basic_type1;
4757 case TOK_STRUCT:
4758 case TOK_UNION:
4759 u = struct_decl(VT_STRUCT);
4760 goto basic_type1;
4762 /* type modifiers */
4763 case TOK_CONST:
4764 case TOK_VOLATILE:
4765 case TOK_REGISTER:
4766 case TOK_SIGNED:
4767 case TOK___SIGNED__:
4768 case TOK_AUTO:
4769 case TOK_INLINE:
4770 case TOK___INLINE__:
4771 case TOK_RESTRICT:
4772 next();
4773 break;
4774 case TOK_UNSIGNED:
4775 t |= VT_UNSIGNED;
4776 next();
4777 break;
4779 /* storage */
4780 case TOK_EXTERN:
4781 t |= VT_EXTERN;
4782 next();
4783 break;
4784 case TOK_STATIC:
4785 t |= VT_STATIC;
4786 next();
4787 break;
4788 case TOK_TYPEDEF:
4789 t |= VT_TYPEDEF;
4790 next();
4791 break;
4792 /* GNUC attribute */
4793 case TOK___ATTRIBUTE__:
4794 parse_attribute(ad);
4795 break;
4796 default:
4797 s = sym_find(tok);
4798 if (!s || !(s->t & VT_TYPEDEF))
4799 goto the_end;
4800 t |= (s->t & ~VT_TYPEDEF);
4801 next();
4802 break;
4804 type_found = 1;
4806 the_end:
4807 /* long is never used as type */
4808 if ((t & VT_BTYPE) == VT_LONG)
4809 t = (t & ~VT_BTYPE) | VT_INT;
4810 *type_ptr = t;
4811 return type_found;
4814 int post_type(int t, AttributeDef *ad)
4816 int p, n, pt, l, t1;
4817 Sym **plast, *s, *first;
4818 AttributeDef ad1;
4820 if (tok == '(') {
4821 /* function declaration */
4822 next();
4823 l = 0;
4824 first = NULL;
4825 plast = &first;
4826 while (tok != ')') {
4827 /* read param name and compute offset */
4828 if (l != FUNC_OLD) {
4829 if (!parse_btype(&pt, &ad1)) {
4830 if (l) {
4831 error("invalid type");
4832 } else {
4833 l = FUNC_OLD;
4834 goto old_proto;
4837 l = FUNC_NEW;
4838 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
4839 break;
4840 pt = type_decl(&ad1, &n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
4841 if ((pt & VT_BTYPE) == VT_VOID)
4842 error("parameter declared as void");
4843 } else {
4844 old_proto:
4845 n = tok;
4846 pt = VT_INT;
4847 next();
4849 /* array must be transformed to pointer according to ANSI C */
4850 pt &= ~VT_ARRAY;
4851 s = sym_push(n | SYM_FIELD, pt, 0, 0);
4852 *plast = s;
4853 plast = &s->next;
4854 if (tok == ',') {
4855 next();
4856 if (l == FUNC_NEW && tok == TOK_DOTS) {
4857 l = FUNC_ELLIPSIS;
4858 next();
4859 break;
4863 /* if no parameters, then old type prototype */
4864 if (l == 0)
4865 l = FUNC_OLD;
4866 skip(')');
4867 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4868 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4869 /* we push a anonymous symbol which will contain the function prototype */
4870 p = anon_sym++;
4871 s = sym_push(p, t, ad->func_call, l);
4872 s->next = first;
4873 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
4874 } else if (tok == '[') {
4875 /* array definition */
4876 next();
4877 n = -1;
4878 if (tok != ']') {
4879 n = expr_const();
4880 if (n < 0)
4881 error("invalid array size");
4883 skip(']');
4884 /* parse next post type */
4885 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4886 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4888 /* we push a anonymous symbol which will contain the array
4889 element type */
4890 p = anon_sym++;
4891 sym_push(p, t, 0, n);
4892 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
4894 return t;
4897 /* Read a type declaration (except basic type), and return the
4898 type. 'td' is a bitmask indicating which kind of type decl is
4899 expected. 't' should contain the basic type. 'ad' is the attribute
4900 definition of the basic type. It can be modified by type_decl(). */
4901 int type_decl(AttributeDef *ad, int *v, int t, int td)
4903 int u, p;
4904 Sym *s;
4906 while (tok == '*') {
4907 next();
4908 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
4909 next();
4910 t = mk_pointer(t);
4913 /* recursive type */
4914 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4915 if (tok == '(') {
4916 next();
4917 /* XXX: this is not correct to modify 'ad' at this point, but
4918 the syntax is not clear */
4919 if (tok == TOK___ATTRIBUTE__)
4920 parse_attribute(ad);
4921 u = type_decl(ad, v, 0, td);
4922 skip(')');
4923 } else {
4924 u = 0;
4925 /* type identifier */
4926 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
4927 *v = tok;
4928 next();
4929 } else {
4930 if (!(td & TYPE_ABSTRACT))
4931 expect("identifier");
4932 *v = 0;
4935 /* append t at the end of u */
4936 t = post_type(t, ad);
4937 if (tok == TOK___ATTRIBUTE__)
4938 parse_attribute(ad);
4939 if (!u)
4940 return t;
4941 p = u;
4942 while(1) {
4943 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
4944 p = s->t;
4945 if (!p) {
4946 s->t = t;
4947 break;
4950 return u;
4953 /* define a new external reference to a symbol 'v' of type 'u' */
4954 Sym *external_sym(int v, int u, int r)
4956 Sym *s;
4958 s = sym_find(v);
4959 if (!s) {
4960 /* push forward reference */
4961 s = sym_push1(&global_stack,
4962 v, u | VT_EXTERN, 0);
4963 s->r = r | VT_CONST | VT_SYM;
4965 return s;
4968 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4969 static int lvalue_type(int t)
4971 int bt, r;
4972 r = VT_LVAL;
4973 bt = t & VT_BTYPE;
4974 if (bt == VT_BYTE)
4975 r |= VT_LVAL_BYTE;
4976 else if (bt == VT_SHORT)
4977 r |= VT_LVAL_SHORT;
4978 else
4979 return r;
4980 if (t & VT_UNSIGNED)
4981 r |= VT_LVAL_UNSIGNED;
4982 return r;
4985 /* indirection with full error checking and bound check */
4986 static void indir(void)
4988 if ((vtop->t & VT_BTYPE) != VT_PTR)
4989 expect("pointer");
4990 if (vtop->r & VT_LVAL)
4991 gv(RC_INT);
4992 vtop->t = pointed_type(vtop->t);
4993 /* an array is never an lvalue */
4994 if (!(vtop->t & VT_ARRAY)) {
4995 vtop->r |= lvalue_type(vtop->t);
4996 /* if bound checking, the referenced pointer must be checked */
4997 if (do_bounds_check)
4998 vtop->r |= VT_MUSTBOUND;
5002 /* pass a parameter to a function and do type checking and casting */
5003 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
5005 int func_type;
5006 func_type = func->c;
5007 if (func_type == FUNC_OLD ||
5008 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
5009 /* default casting : only need to convert float to double */
5010 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
5011 gen_cast(VT_DOUBLE);
5012 } else if (arg == NULL) {
5013 error("too many arguments to function");
5014 } else {
5015 gen_assign_cast(arg->t);
5017 gfunc_param(gf);
5020 void unary(void)
5022 int n, t, ft, align, size, r;
5023 Sym *s;
5024 GFuncContext gf;
5025 AttributeDef ad;
5027 if (tok == TOK_CINT || tok == TOK_CCHAR || tok == TOK_LCHAR) {
5028 vpushi(tokc.i);
5029 next();
5030 } else if (tok == TOK_CUINT) {
5031 vsetc(VT_INT | VT_UNSIGNED, VT_CONST, &tokc);
5032 next();
5033 } else if (tok == TOK_CLLONG) {
5034 vsetc(VT_LLONG, VT_CONST, &tokc);
5035 next();
5036 } else if (tok == TOK_CULLONG) {
5037 vsetc(VT_LLONG | VT_UNSIGNED, VT_CONST, &tokc);
5038 next();
5039 } else if (tok == TOK_CFLOAT) {
5040 vsetc(VT_FLOAT, VT_CONST, &tokc);
5041 next();
5042 } else if (tok == TOK_CDOUBLE) {
5043 vsetc(VT_DOUBLE, VT_CONST, &tokc);
5044 next();
5045 } else if (tok == TOK_CLDOUBLE) {
5046 vsetc(VT_LDOUBLE, VT_CONST, &tokc);
5047 next();
5048 } else if (tok == TOK___FUNC__) {
5049 void *ptr;
5050 int len;
5051 /* special function name identifier */
5053 len = strlen(funcname) + 1;
5054 /* generate char[len] type */
5055 t = VT_ARRAY | mk_pointer(VT_BYTE);
5056 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5057 s->c = len;
5058 vpush_ref(t, data_section, data_section->data_offset, len);
5059 ptr = section_ptr_add(data_section, len);
5060 memcpy(ptr, funcname, len);
5061 next();
5062 } else if (tok == TOK_LSTR) {
5063 t = VT_INT;
5064 goto str_init;
5065 } else if (tok == TOK_STR) {
5066 /* string parsing */
5067 t = VT_BYTE;
5068 str_init:
5069 t = VT_ARRAY | mk_pointer(t);
5070 memset(&ad, 0, sizeof(AttributeDef));
5071 decl_initializer_alloc(t, &ad, VT_CONST, 2, 0, 0);
5072 } else {
5073 t = tok;
5074 next();
5075 if (t == '(') {
5076 /* cast ? */
5077 if (parse_btype(&t, &ad)) {
5078 ft = type_decl(&ad, &n, t, TYPE_ABSTRACT);
5079 skip(')');
5080 /* check ISOC99 compound literal */
5081 if (tok == '{') {
5082 /* data is allocated locally by default */
5083 if (global_expr)
5084 r = VT_CONST;
5085 else
5086 r = VT_LOCAL;
5087 /* all except arrays are lvalues */
5088 if (!(ft & VT_ARRAY))
5089 r |= lvalue_type(ft);
5090 memset(&ad, 0, sizeof(AttributeDef));
5091 decl_initializer_alloc(ft, &ad, r, 1, 0, 0);
5092 } else {
5093 unary();
5094 gen_cast(ft);
5096 } else {
5097 gexpr();
5098 skip(')');
5100 } else if (t == '*') {
5101 unary();
5102 indir();
5103 } else if (t == '&') {
5104 unary();
5105 /* functions names must be treated as function pointers,
5106 except for unary '&' and sizeof. Since we consider that
5107 functions are not lvalues, we only have to handle it
5108 there and in function calls. */
5109 /* arrays can also be used although they are not lvalues */
5110 if ((vtop->t & VT_BTYPE) != VT_FUNC &&
5111 !(vtop->t & VT_ARRAY))
5112 test_lvalue();
5113 vtop->t = mk_pointer(vtop->t);
5114 gaddrof();
5115 } else
5116 if (t == '!') {
5117 unary();
5118 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
5119 vtop->c.i = !vtop->c.i;
5120 else if ((vtop->r & VT_VALMASK) == VT_CMP)
5121 vtop->c.i = vtop->c.i ^ 1;
5122 else
5123 vset(VT_INT, VT_JMP, gtst(1, 0));
5124 } else
5125 if (t == '~') {
5126 unary();
5127 vpushi(-1);
5128 gen_op('^');
5129 } else
5130 if (t == '+') {
5131 /* in order to force cast, we add zero */
5132 unary();
5133 if ((vtop->t & VT_BTYPE) == VT_PTR)
5134 error("pointer not accepted for unary plus");
5135 vpushi(0);
5136 gen_op('+');
5137 } else
5138 if (t == TOK_SIZEOF) {
5139 if (tok == '(') {
5140 next();
5141 if (parse_btype(&t, &ad)) {
5142 t = type_decl(&ad, &n, t, TYPE_ABSTRACT);
5143 } else {
5144 /* XXX: some code could be generated: add eval
5145 flag */
5146 gexpr();
5147 t = vtop->t;
5148 vpop();
5150 skip(')');
5151 } else {
5152 unary();
5153 t = vtop->t;
5154 vpop();
5156 vpushi(type_size(t, &t));
5157 } else
5158 if (t == TOK_INC || t == TOK_DEC) {
5159 unary();
5160 inc(0, t);
5161 } else if (t == '-') {
5162 vpushi(0);
5163 unary();
5164 gen_op('-');
5165 } else
5167 if (t < TOK_UIDENT)
5168 expect("identifier");
5169 s = sym_find(t);
5170 if (!s) {
5171 if (tok != '(')
5172 error("'%s' undeclared", get_tok_str(t, NULL));
5173 /* for simple function calls, we tolerate undeclared
5174 external reference to int() function */
5175 s = external_sym(t, func_old_type, 0);
5177 vset(s->t, s->r, s->c);
5178 /* if forward reference, we must point to s */
5179 if (vtop->r & VT_SYM)
5180 vtop->c.sym = s;
5184 /* post operations */
5185 while (1) {
5186 if (tok == TOK_INC || tok == TOK_DEC) {
5187 inc(1, tok);
5188 next();
5189 } else if (tok == '.' || tok == TOK_ARROW) {
5190 /* field */
5191 if (tok == TOK_ARROW)
5192 indir();
5193 test_lvalue();
5194 gaddrof();
5195 next();
5196 /* expect pointer on structure */
5197 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
5198 expect("struct or union");
5199 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5200 /* find field */
5201 tok |= SYM_FIELD;
5202 while ((s = s->next) != NULL) {
5203 if (s->v == tok)
5204 break;
5206 if (!s)
5207 error("field not found");
5208 /* add field offset to pointer */
5209 vtop->t = char_pointer_type; /* change type to 'char *' */
5210 vpushi(s->c);
5211 gen_op('+');
5212 /* change type to field type, and set to lvalue */
5213 vtop->t = s->t;
5214 /* an array is never an lvalue */
5215 if (!(vtop->t & VT_ARRAY))
5216 vtop->r |= lvalue_type(vtop->t);
5217 next();
5218 } else if (tok == '[') {
5219 next();
5220 gexpr();
5221 gen_op('+');
5222 indir();
5223 skip(']');
5224 } else if (tok == '(') {
5225 SValue ret;
5226 Sym *sa;
5228 /* function call */
5229 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
5230 /* pointer test (no array accepted) */
5231 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
5232 vtop->t = pointed_type(vtop->t);
5233 if ((vtop->t & VT_BTYPE) != VT_FUNC)
5234 goto error_func;
5235 } else {
5236 error_func:
5237 expect("function pointer");
5239 } else {
5240 vtop->r &= ~VT_LVAL; /* no lvalue */
5242 /* get return type */
5243 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
5244 save_regs(0); /* save used temporary registers */
5245 gfunc_start(&gf, s->r);
5246 next();
5247 sa = s->next; /* first parameter */
5248 #ifdef INVERT_FUNC_PARAMS
5250 int parlevel;
5251 Sym *args, *s1;
5252 ParseState saved_parse_state;
5253 TokenString str;
5255 /* read each argument and store it on a stack */
5256 /* XXX: merge it with macro args ? */
5257 args = NULL;
5258 if (tok != ')') {
5259 for(;;) {
5260 tok_str_new(&str);
5261 parlevel = 0;
5262 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
5263 tok != -1) {
5264 if (tok == '(')
5265 parlevel++;
5266 else if (tok == ')')
5267 parlevel--;
5268 tok_str_add_tok(&str);
5269 next();
5271 tok_str_add(&str, -1); /* end of file added */
5272 tok_str_add(&str, 0);
5273 s1 = sym_push2(&args, 0, 0, (int)str.str);
5274 s1->next = sa; /* add reference to argument */
5275 if (sa)
5276 sa = sa->next;
5277 if (tok == ')')
5278 break;
5279 skip(',');
5283 /* now generate code in reverse order by reading the stack */
5284 save_parse_state(&saved_parse_state);
5285 while (args) {
5286 macro_ptr = (int *)args->c;
5287 next();
5288 expr_eq();
5289 if (tok != -1)
5290 expect("',' or ')'");
5291 gfunc_param_typed(&gf, s, args->next);
5292 s1 = args->prev;
5293 tok_str_free((int *)args->c);
5294 tcc_free(args);
5295 args = s1;
5297 restore_parse_state(&saved_parse_state);
5299 #endif
5300 /* compute first implicit argument if a structure is returned */
5301 if ((s->t & VT_BTYPE) == VT_STRUCT) {
5302 /* get some space for the returned structure */
5303 size = type_size(s->t, &align);
5304 loc = (loc - size) & -align;
5305 ret.t = s->t;
5306 ret.r = VT_LOCAL | VT_LVAL;
5307 /* pass it as 'int' to avoid structure arg passing
5308 problems */
5309 vset(VT_INT, VT_LOCAL, loc);
5310 ret.c = vtop->c;
5311 gfunc_param(&gf);
5312 } else {
5313 ret.t = s->t;
5314 ret.r2 = VT_CONST;
5315 /* return in register */
5316 if (is_float(ret.t)) {
5317 ret.r = REG_FRET;
5318 } else {
5319 if ((ret.t & VT_BTYPE) == VT_LLONG)
5320 ret.r2 = REG_LRET;
5321 ret.r = REG_IRET;
5323 ret.c.i = 0;
5325 #ifndef INVERT_FUNC_PARAMS
5326 if (tok != ')') {
5327 for(;;) {
5328 expr_eq();
5329 gfunc_param_typed(&gf, s, sa);
5330 if (sa)
5331 sa = sa->next;
5332 if (tok == ')')
5333 break;
5334 skip(',');
5337 #endif
5338 if (sa)
5339 error("too few arguments to function");
5340 skip(')');
5341 gfunc_call(&gf);
5342 /* return value */
5343 vsetc(ret.t, ret.r, &ret.c);
5344 vtop->r2 = ret.r2;
5345 } else {
5346 break;
5351 void uneq(void)
5353 int t;
5355 unary();
5356 if (tok == '=' ||
5357 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5358 tok == TOK_A_XOR || tok == TOK_A_OR ||
5359 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5360 test_lvalue();
5361 t = tok;
5362 next();
5363 if (t == '=') {
5364 expr_eq();
5365 } else {
5366 vdup();
5367 expr_eq();
5368 gen_op(t & 0x7f);
5370 vstore();
5374 void sum(int l)
5376 int t;
5378 if (l == 0)
5379 uneq();
5380 else {
5381 sum(--l);
5382 while ((l == 0 && (tok == '*' || tok == '/' || tok == '%')) ||
5383 (l == 1 && (tok == '+' || tok == '-')) ||
5384 (l == 2 && (tok == TOK_SHL || tok == TOK_SAR)) ||
5385 (l == 3 && ((tok >= TOK_ULE && tok <= TOK_GT) ||
5386 tok == TOK_ULT || tok == TOK_UGE)) ||
5387 (l == 4 && (tok == TOK_EQ || tok == TOK_NE)) ||
5388 (l == 5 && tok == '&') ||
5389 (l == 6 && tok == '^') ||
5390 (l == 7 && tok == '|') ||
5391 (l == 8 && tok == TOK_LAND) ||
5392 (l == 9 && tok == TOK_LOR)) {
5393 t = tok;
5394 next();
5395 sum(l);
5396 gen_op(t);
5401 /* only used if non constant */
5402 void eand(void)
5404 int t;
5406 sum(8);
5407 t = 0;
5408 while (1) {
5409 if (tok != TOK_LAND) {
5410 if (t) {
5411 t = gtst(1, t);
5412 vset(VT_INT, VT_JMPI, t);
5414 break;
5416 t = gtst(1, t);
5417 next();
5418 sum(8);
5422 void eor(void)
5424 int t;
5426 eand();
5427 t = 0;
5428 while (1) {
5429 if (tok != TOK_LOR) {
5430 if (t) {
5431 t = gtst(0, t);
5432 vset(VT_INT, VT_JMP, t);
5434 break;
5436 t = gtst(0, t);
5437 next();
5438 eand();
5442 /* XXX: better constant handling */
5443 void expr_eq(void)
5445 int t, u, c, r1, r2, rc;
5447 if (const_wanted) {
5448 sum(10);
5449 if (tok == '?') {
5450 c = vtop->c.i;
5451 vpop();
5452 next();
5453 gexpr();
5454 t = vtop->c.i;
5455 vpop();
5456 skip(':');
5457 expr_eq();
5458 if (c)
5459 vtop->c.i = t;
5461 } else {
5462 eor();
5463 if (tok == '?') {
5464 next();
5465 save_regs(1); /* we need to save all registers here except
5466 at the top because it is a branch point */
5467 t = gtst(1, 0);
5468 gexpr();
5469 /* XXX: long long handling ? */
5470 rc = RC_INT;
5471 if (is_float(vtop->t))
5472 rc = RC_FLOAT;
5473 r1 = gv(rc);
5474 vtop--; /* no vpop so that FP stack is not flushed */
5475 skip(':');
5476 u = gjmp(0);
5478 gsym(t);
5479 expr_eq();
5480 r2 = gv(rc);
5481 move_reg(r1, r2);
5482 vtop->r = r1;
5483 gsym(u);
5488 void gexpr(void)
5490 while (1) {
5491 expr_eq();
5492 if (tok != ',')
5493 break;
5494 vpop();
5495 next();
5499 /* parse a constant expression and return value in vtop */
5500 void expr_const1(void)
5502 int a;
5503 a = const_wanted;
5504 const_wanted = 1;
5505 expr_eq();
5506 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5507 expect("constant");
5508 const_wanted = a;
5511 /* parse an integer constant and return its value */
5512 int expr_const(void)
5514 int c;
5515 expr_const1();
5516 c = vtop->c.i;
5517 vpop();
5518 return c;
5521 /* return the label token if current token is a label, otherwise
5522 return zero */
5523 int is_label(void)
5525 int t;
5526 CValue c;
5528 /* fast test first */
5529 if (tok < TOK_UIDENT)
5530 return 0;
5531 /* no need to save tokc since we expect an identifier */
5532 t = tok;
5533 c = tokc;
5534 next();
5535 if (tok == ':') {
5536 next();
5537 return t;
5538 } else {
5539 /* XXX: may not work in all cases (macros ?) */
5540 tok1 = tok;
5541 tok1c = tokc;
5542 tok = t;
5543 tokc = c;
5544 return 0;
5548 void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
5550 int a, b, c, d;
5551 Sym *s;
5553 /* generate line number info */
5554 if (do_debug &&
5555 (last_line_num != file->line_num || last_ind != ind)) {
5556 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
5557 last_ind = ind;
5558 last_line_num = file->line_num;
5561 if (tok == TOK_IF) {
5562 /* if test */
5563 next();
5564 skip('(');
5565 gexpr();
5566 skip(')');
5567 a = gtst(1, 0);
5568 block(bsym, csym, case_sym, def_sym, case_reg);
5569 c = tok;
5570 if (c == TOK_ELSE) {
5571 next();
5572 d = gjmp(0);
5573 gsym(a);
5574 block(bsym, csym, case_sym, def_sym, case_reg);
5575 gsym(d); /* patch else jmp */
5576 } else
5577 gsym(a);
5578 } else if (tok == TOK_WHILE) {
5579 next();
5580 d = ind;
5581 skip('(');
5582 gexpr();
5583 skip(')');
5584 a = gtst(1, 0);
5585 b = 0;
5586 block(&a, &b, case_sym, def_sym, case_reg);
5587 gjmp_addr(d);
5588 gsym(a);
5589 gsym_addr(b, d);
5590 } else if (tok == '{') {
5591 next();
5592 /* declarations */
5593 s = local_stack.top;
5594 while (tok != '}') {
5595 decl(VT_LOCAL);
5596 if (tok != '}')
5597 block(bsym, csym, case_sym, def_sym, case_reg);
5599 /* pop locally defined symbols */
5600 sym_pop(&local_stack, s);
5601 next();
5602 } else if (tok == TOK_RETURN) {
5603 next();
5604 if (tok != ';') {
5605 gexpr();
5606 gen_assign_cast(func_vt);
5607 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
5608 /* if returning structure, must copy it to implicit
5609 first pointer arg location */
5610 vset(mk_pointer(func_vt), VT_LOCAL | VT_LVAL, func_vc);
5611 indir();
5612 vswap();
5613 /* copy structure value to pointer */
5614 vstore();
5615 } else if (is_float(func_vt)) {
5616 gv(RC_FRET);
5617 } else {
5618 gv(RC_IRET);
5620 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5622 skip(';');
5623 rsym = gjmp(rsym); /* jmp */
5624 } else if (tok == TOK_BREAK) {
5625 /* compute jump */
5626 if (!bsym)
5627 error("cannot break");
5628 *bsym = gjmp(*bsym);
5629 next();
5630 skip(';');
5631 } else if (tok == TOK_CONTINUE) {
5632 /* compute jump */
5633 if (!csym)
5634 error("cannot continue");
5635 *csym = gjmp(*csym);
5636 next();
5637 skip(';');
5638 } else if (tok == TOK_FOR) {
5639 int e;
5640 next();
5641 skip('(');
5642 if (tok != ';') {
5643 gexpr();
5644 vpop();
5646 skip(';');
5647 d = ind;
5648 c = ind;
5649 a = 0;
5650 b = 0;
5651 if (tok != ';') {
5652 gexpr();
5653 a = gtst(1, 0);
5655 skip(';');
5656 if (tok != ')') {
5657 e = gjmp(0);
5658 c = ind;
5659 gexpr();
5660 vpop();
5661 gjmp_addr(d);
5662 gsym(e);
5664 skip(')');
5665 block(&a, &b, case_sym, def_sym, case_reg);
5666 gjmp_addr(c);
5667 gsym(a);
5668 gsym_addr(b, c);
5669 } else
5670 if (tok == TOK_DO) {
5671 next();
5672 a = 0;
5673 b = 0;
5674 d = ind;
5675 block(&a, &b, case_sym, def_sym, case_reg);
5676 skip(TOK_WHILE);
5677 skip('(');
5678 gsym(b);
5679 gexpr();
5680 c = gtst(0, 0);
5681 gsym_addr(c, d);
5682 skip(')');
5683 gsym(a);
5684 skip(';');
5685 } else
5686 if (tok == TOK_SWITCH) {
5687 next();
5688 skip('(');
5689 gexpr();
5690 /* XXX: other types than integer */
5691 case_reg = gv(RC_INT);
5692 vpop();
5693 skip(')');
5694 a = 0;
5695 b = gjmp(0); /* jump to first case */
5696 c = 0;
5697 block(&a, csym, &b, &c, case_reg);
5698 /* if no default, jmp after switch */
5699 if (c == 0)
5700 c = ind;
5701 /* default label */
5702 gsym_addr(b, c);
5703 /* break label */
5704 gsym(a);
5705 } else
5706 if (tok == TOK_CASE) {
5707 int v1, v2;
5708 if (!case_sym)
5709 expect("switch");
5710 next();
5711 v1 = expr_const();
5712 v2 = v1;
5713 if (gnu_ext && tok == TOK_DOTS) {
5714 next();
5715 v2 = expr_const();
5716 if (v2 < v1)
5717 warning("empty case range");
5719 /* since a case is like a label, we must skip it with a jmp */
5720 b = gjmp(0);
5721 gsym(*case_sym);
5722 vset(VT_INT, case_reg, 0);
5723 vpushi(v1);
5724 if (v1 == v2) {
5725 gen_op(TOK_EQ);
5726 *case_sym = gtst(1, 0);
5727 } else {
5728 gen_op(TOK_GE);
5729 *case_sym = gtst(1, 0);
5730 vset(VT_INT, case_reg, 0);
5731 vpushi(v2);
5732 gen_op(TOK_LE);
5733 *case_sym = gtst(1, *case_sym);
5735 gsym(b);
5736 skip(':');
5737 block(bsym, csym, case_sym, def_sym, case_reg);
5738 } else
5739 if (tok == TOK_DEFAULT) {
5740 next();
5741 skip(':');
5742 if (!def_sym)
5743 expect("switch");
5744 if (*def_sym)
5745 error("too many 'default'");
5746 *def_sym = ind;
5747 block(bsym, csym, case_sym, def_sym, case_reg);
5748 } else
5749 if (tok == TOK_GOTO) {
5750 next();
5751 s = sym_find1(&label_stack, tok);
5752 /* put forward definition if needed */
5753 if (!s)
5754 s = sym_push1(&label_stack, tok, LABEL_FORWARD, 0);
5755 /* label already defined */
5756 if (s->t & LABEL_FORWARD)
5757 s->c = gjmp(s->c);
5758 else
5759 gjmp_addr(s->c);
5760 next();
5761 skip(';');
5762 } else {
5763 b = is_label();
5764 if (b) {
5765 /* label case */
5766 s = sym_find1(&label_stack, b);
5767 if (s) {
5768 if (!(s->t & LABEL_FORWARD))
5769 error("multiple defined label");
5770 gsym(s->c);
5771 s->c = ind;
5772 s->t = 0;
5773 } else {
5774 sym_push1(&label_stack, b, 0, ind);
5776 /* we accept this, but it is a mistake */
5777 if (tok == '}')
5778 warning("deprecated use of label at end of compound statement");
5779 else
5780 block(bsym, csym, case_sym, def_sym, case_reg);
5781 } else {
5782 /* expression case */
5783 if (tok != ';') {
5784 gexpr();
5785 vpop();
5787 skip(';');
5792 /* t is the array or struct type. c is the array or struct
5793 address. cur_index/cur_field is the pointer to the current
5794 value. 'size_only' is true if only size info is needed (only used
5795 in arrays) */
5796 static void decl_designator(int t, Section *sec, unsigned long c,
5797 int *cur_index, Sym **cur_field,
5798 int size_only)
5800 Sym *s, *f;
5801 int notfirst, index, align, l;
5803 notfirst = 0;
5804 if (gnu_ext && (l = is_label()) != 0)
5805 goto struct_field;
5807 while (tok == '[' || tok == '.') {
5808 if (tok == '[') {
5809 if (!(t & VT_ARRAY))
5810 expect("array type");
5811 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5812 next();
5813 index = expr_const();
5814 if (index < 0 || (s->c >= 0 && index >= s->c))
5815 expect("invalid index");
5816 skip(']');
5817 if (!notfirst)
5818 *cur_index = index;
5819 t = pointed_type(t);
5820 c += index * type_size(t, &align);
5821 } else {
5822 next();
5823 l = tok;
5824 next();
5825 struct_field:
5826 if ((t & VT_BTYPE) != VT_STRUCT)
5827 expect("struct/union type");
5828 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5829 l |= SYM_FIELD;
5830 f = s->next;
5831 while (f) {
5832 if (f->v == l)
5833 break;
5834 f = f->next;
5836 if (!f)
5837 expect("field");
5838 if (!notfirst)
5839 *cur_field = f;
5840 t = f->t | (t & ~VT_TYPE);
5841 c += f->c;
5843 notfirst = 1;
5845 if (notfirst) {
5846 if (tok == '=') {
5847 next();
5848 } else {
5849 if (!gnu_ext)
5850 expect("=");
5852 } else {
5853 if (t & VT_ARRAY) {
5854 index = *cur_index;
5855 t = pointed_type(t);
5856 c += index * type_size(t, &align);
5857 } else {
5858 f = *cur_field;
5859 if (!f)
5860 error("too many field init");
5861 t = f->t | (t & ~VT_TYPE);
5862 c += f->c;
5865 decl_initializer(t, sec, c, 0, size_only);
5868 #define EXPR_VAL 0
5869 #define EXPR_CONST 1
5870 #define EXPR_ANY 2
5872 /* store a value or an expression directly in global data or in local array */
5873 static void init_putv(int t, Section *sec, unsigned long c,
5874 int v, int expr_type)
5876 int saved_global_expr, bt;
5877 void *ptr;
5879 switch(expr_type) {
5880 case EXPR_VAL:
5881 vpushi(v);
5882 break;
5883 case EXPR_CONST:
5884 /* compound literals must be allocated globally in this case */
5885 saved_global_expr = global_expr;
5886 global_expr = 1;
5887 expr_const1();
5888 global_expr = saved_global_expr;
5889 break;
5890 case EXPR_ANY:
5891 expr_eq();
5892 break;
5895 if (sec) {
5896 /* XXX: not portable */
5897 /* XXX: generate error if incorrect relocation */
5898 gen_assign_cast(t);
5899 bt = t & VT_BTYPE;
5900 ptr = sec->data + c;
5901 if ((vtop->r & VT_SYM) &&
5902 (bt == VT_BYTE ||
5903 bt == VT_SHORT ||
5904 bt == VT_DOUBLE ||
5905 bt == VT_LDOUBLE ||
5906 bt == VT_LLONG))
5907 error("initializer element is not computable at load time");
5908 switch(bt) {
5909 case VT_BYTE:
5910 *(char *)ptr = vtop->c.i;
5911 break;
5912 case VT_SHORT:
5913 *(short *)ptr = vtop->c.i;
5914 break;
5915 case VT_DOUBLE:
5916 *(double *)ptr = vtop->c.d;
5917 break;
5918 case VT_LDOUBLE:
5919 *(long double *)ptr = vtop->c.ld;
5920 break;
5921 case VT_LLONG:
5922 *(long long *)ptr = vtop->c.ll;
5923 break;
5924 default:
5925 if (vtop->r & VT_SYM) {
5926 greloc(sec, vtop->c.sym, c, R_DATA_32);
5927 *(int *)ptr = 0;
5928 } else {
5929 *(int *)ptr = vtop->c.i;
5931 break;
5933 vtop--;
5934 } else {
5935 vset(t, VT_LOCAL, c);
5936 vswap();
5937 vstore();
5938 vpop();
5942 /* put zeros for variable based init */
5943 static void init_putz(int t, Section *sec, unsigned long c, int size)
5945 GFuncContext gf;
5947 if (sec) {
5948 /* nothing to do because globals are already set to zero */
5949 } else {
5950 gfunc_start(&gf, FUNC_CDECL);
5951 vpushi(size);
5952 gfunc_param(&gf);
5953 vpushi(0);
5954 gfunc_param(&gf);
5955 vset(VT_INT, VT_LOCAL, c);
5956 gfunc_param(&gf);
5957 vpush_sym(func_old_type, TOK_memset);
5958 gfunc_call(&gf);
5962 /* 't' contains the type and storage info. 'c' is the offset of the
5963 object in section 'sec'. If 'sec' is NULL, it means stack based
5964 allocation. 'first' is true if array '{' must be read (multi
5965 dimension implicit array init handling). 'size_only' is true if
5966 size only evaluation is wanted (only for arrays). */
5967 static void decl_initializer(int t, Section *sec, unsigned long c,
5968 int first, int size_only)
5970 int index, array_length, n, no_oblock, nb, parlevel, i;
5971 int t1, size1, align1, expr_type;
5972 Sym *s, *f;
5974 if (t & VT_ARRAY) {
5975 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5976 n = s->c;
5977 array_length = 0;
5978 t1 = pointed_type(t);
5979 size1 = type_size(t1, &align1);
5981 no_oblock = 1;
5982 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
5983 tok == '{') {
5984 skip('{');
5985 no_oblock = 0;
5988 /* only parse strings here if correct type (otherwise: handle
5989 them as ((w)char *) expressions */
5990 if ((tok == TOK_LSTR &&
5991 (t1 & VT_BTYPE) == VT_INT) ||
5992 (tok == TOK_STR &&
5993 (t1 & VT_BTYPE) == VT_BYTE)) {
5994 while (tok == TOK_STR || tok == TOK_LSTR) {
5995 int cstr_len, ch;
5996 CString *cstr;
5998 cstr = tokc.cstr;
5999 /* compute maximum number of chars wanted */
6000 if (tok == TOK_STR)
6001 cstr_len = cstr->size;
6002 else
6003 cstr_len = cstr->size / sizeof(int);
6004 cstr_len--;
6005 nb = cstr_len;
6006 if (n >= 0 && nb > (n - array_length))
6007 nb = n - array_length;
6008 if (!size_only) {
6009 if (cstr_len > nb)
6010 warning("initializer-string for array is too long");
6011 for(i=0;i<nb;i++) {
6012 if (tok == TOK_STR)
6013 ch = ((unsigned char *)cstr->data)[i];
6014 else
6015 ch = ((int *)cstr->data)[i];
6016 init_putv(t1, sec, c + (array_length + i) * size1,
6017 ch, EXPR_VAL);
6020 array_length += nb;
6021 next();
6023 /* only add trailing zero if enough storage (no
6024 warning in this case since it is standard) */
6025 if (n < 0 || array_length < n) {
6026 if (!size_only) {
6027 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
6029 array_length++;
6031 } else {
6032 index = 0;
6033 while (tok != '}') {
6034 decl_designator(t, sec, c, &index, NULL, size_only);
6035 if (n >= 0 && index >= n)
6036 error("index too large");
6037 /* must put zero in holes (note that doing it that way
6038 ensures that it even works with designators) */
6039 if (!size_only && array_length < index) {
6040 init_putz(t1, sec, c + array_length * size1,
6041 (index - array_length) * size1);
6043 index++;
6044 if (index > array_length)
6045 array_length = index;
6046 /* special test for multi dimensional arrays (may not
6047 be strictly correct if designators are used at the
6048 same time) */
6049 if (index >= n && no_oblock)
6050 break;
6051 if (tok == '}')
6052 break;
6053 skip(',');
6056 if (!no_oblock)
6057 skip('}');
6058 /* put zeros at the end */
6059 if (!size_only && n >= 0 && array_length < n) {
6060 init_putz(t1, sec, c + array_length * size1,
6061 (n - array_length) * size1);
6063 /* patch type size if needed */
6064 if (n < 0)
6065 s->c = array_length;
6066 } else if ((t & VT_BTYPE) == VT_STRUCT && tok == '{') {
6067 /* XXX: union needs only one init */
6068 next();
6069 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
6070 f = s->next;
6071 array_length = 0;
6072 index = 0;
6073 n = s->c;
6074 while (tok != '}') {
6075 decl_designator(t, sec, c, NULL, &f, size_only);
6076 /* fill with zero between fields */
6077 index = f->c;
6078 if (!size_only && array_length < index) {
6079 init_putz(t, sec, c + array_length,
6080 index - array_length);
6082 index = index + type_size(f->t, &align1);
6083 if (index > array_length)
6084 array_length = index;
6085 if (tok == '}')
6086 break;
6087 skip(',');
6088 f = f->next;
6090 /* put zeros at the end */
6091 if (!size_only && array_length < n) {
6092 init_putz(t, sec, c + array_length,
6093 n - array_length);
6095 skip('}');
6096 } else if (tok == '{') {
6097 next();
6098 decl_initializer(t, sec, c, first, size_only);
6099 skip('}');
6100 } else if (size_only) {
6101 /* just skip expression */
6102 parlevel = 0;
6103 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
6104 tok != -1) {
6105 if (tok == '(')
6106 parlevel++;
6107 else if (tok == ')')
6108 parlevel--;
6109 next();
6111 } else {
6112 /* currently, we always use constant expression for globals
6113 (may change for scripting case) */
6114 expr_type = EXPR_CONST;
6115 if (!sec)
6116 expr_type = EXPR_ANY;
6117 init_putv(t, sec, c, 0, expr_type);
6121 /* parse an initializer for type 't' if 'has_init' is non zero, and
6122 allocate space in local or global data space ('r' is either
6123 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6124 variable 'v' of scope 'scope' is declared before initializers are
6125 parsed. If 'v' is zero, then a reference to the new object is put
6126 in the value stack. If 'has_init' is 2, a special parsing is done
6127 to handle string constants. */
6128 static void decl_initializer_alloc(int t, AttributeDef *ad, int r,
6129 int has_init, int v, int scope)
6131 int size, align, addr, data_offset;
6132 int level;
6133 ParseState saved_parse_state;
6134 TokenString init_str;
6135 Section *sec;
6137 size = type_size(t, &align);
6138 /* If unknown size, we must evaluate it before
6139 evaluating initializers because
6140 initializers can generate global data too
6141 (e.g. string pointers or ISOC99 compound
6142 literals). It also simplifies local
6143 initializers handling */
6144 tok_str_new(&init_str);
6145 if (size < 0) {
6146 if (!has_init)
6147 error("unknown type size");
6148 /* get all init string */
6149 if (has_init == 2) {
6150 /* only get strings */
6151 while (tok == TOK_STR || tok == TOK_LSTR) {
6152 tok_str_add_tok(&init_str);
6153 next();
6155 } else {
6156 level = 0;
6157 while (level > 0 || (tok != ',' && tok != ';')) {
6158 if (tok < 0)
6159 error("unexpected end of file in initializer");
6160 tok_str_add_tok(&init_str);
6161 if (tok == '{')
6162 level++;
6163 else if (tok == '}') {
6164 if (level == 0)
6165 break;
6166 level--;
6168 next();
6171 tok_str_add(&init_str, -1);
6172 tok_str_add(&init_str, 0);
6174 /* compute size */
6175 save_parse_state(&saved_parse_state);
6177 macro_ptr = init_str.str;
6178 next();
6179 decl_initializer(t, NULL, 0, 1, 1);
6180 /* prepare second initializer parsing */
6181 macro_ptr = init_str.str;
6182 next();
6184 /* if still unknown size, error */
6185 size = type_size(t, &align);
6186 if (size < 0)
6187 error("unknown type size");
6189 /* take into account specified alignment if bigger */
6190 if (ad->aligned > align)
6191 align = ad->aligned;
6192 if ((r & VT_VALMASK) == VT_LOCAL) {
6193 sec = NULL;
6194 if (do_bounds_check && (t & VT_ARRAY))
6195 loc--;
6196 #ifdef TCC_TARGET_IL
6197 /* XXX: ugly patch to allocate local variables for IL, just
6198 for testing */
6199 addr = loc;
6200 loc++;
6201 #else
6202 loc = (loc - size) & -align;
6203 addr = loc;
6204 #endif
6205 /* handles bounds */
6206 /* XXX: currently, since we do only one pass, we cannot track
6207 '&' operators, so we add only arrays */
6208 if (do_bounds_check && (t & VT_ARRAY)) {
6209 unsigned long *bounds_ptr;
6210 /* add padding between regions */
6211 loc--;
6212 /* then add local bound info */
6213 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
6214 bounds_ptr[0] = addr;
6215 bounds_ptr[1] = size;
6217 } else {
6218 /* compute section */
6219 sec = ad->section;
6220 if (!sec) {
6221 if (has_init)
6222 sec = data_section;
6223 else
6224 sec = bss_section;
6226 data_offset = sec->data_offset;
6227 data_offset = (data_offset + align - 1) & -align;
6228 addr = data_offset;
6229 /* very important to increment global pointer at this time
6230 because initializers themselves can create new initializers */
6231 data_offset += size;
6232 /* add padding if bound check */
6233 if (do_bounds_check)
6234 data_offset++;
6235 sec->data_offset = data_offset;
6236 /* allocate section space to put the data */
6237 if (sec->sh_type != SHT_NOBITS &&
6238 data_offset > sec->data_allocated)
6239 section_realloc(sec, data_offset);
6241 if (!sec) {
6242 if (v) {
6243 /* local variable */
6244 sym_push(v, t, r, addr);
6245 } else {
6246 /* push local reference */
6247 vset(t, r, addr);
6249 } else {
6250 Sym *sym;
6252 if (v) {
6253 if (scope == VT_CONST) {
6254 /* global scope: see if already defined */
6255 sym = sym_find(v);
6256 if (!sym)
6257 goto do_def;
6258 if (!is_compatible_types(sym->t, t))
6259 error("incompatible types for redefinition of '%s'",
6260 get_tok_str(v, NULL));
6261 if (!(sym->t & VT_EXTERN))
6262 error("redefinition of '%s'", get_tok_str(v, NULL));
6263 sym->t &= ~VT_EXTERN;
6264 } else {
6265 do_def:
6266 sym = sym_push(v, t, r | VT_SYM, 0);
6268 put_extern_sym(sym, sec, addr, size);
6269 } else {
6270 CValue cval;
6272 /* push global reference */
6273 sym = get_sym_ref(t, sec, addr, size);
6274 cval.sym = sym;
6275 vsetc(t, VT_CONST | VT_SYM, &cval);
6278 /* handles bounds now because the symbol must be defined
6279 before for the relocation */
6280 if (do_bounds_check) {
6281 unsigned long *bounds_ptr;
6283 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
6284 /* then add global bound info */
6285 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
6286 bounds_ptr[0] = 0; /* relocated */
6287 bounds_ptr[1] = size;
6290 if (has_init) {
6291 decl_initializer(t, sec, addr, 1, 0);
6292 /* restore parse state if needed */
6293 if (init_str.str) {
6294 tok_str_free(init_str.str);
6295 restore_parse_state(&saved_parse_state);
6300 void put_func_debug(Sym *sym)
6302 char buf[512];
6304 /* stabs info */
6305 /* XXX: we put here a dummy type */
6306 snprintf(buf, sizeof(buf), "%s:%c1",
6307 funcname, sym->t & VT_STATIC ? 'f' : 'F');
6308 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
6309 cur_text_section, sym->c);
6310 last_ind = 0;
6311 last_line_num = 0;
6314 /* not finished : try to put some local vars in registers */
6315 //#define CONFIG_REG_VARS
6317 #ifdef CONFIG_REG_VARS
6318 void add_var_ref(int t)
6320 printf("%s:%d: &%s\n",
6321 file->filename, file->line_num,
6322 get_tok_str(t, NULL));
6325 /* first pass on a function with heuristic to extract variable usage
6326 and pointer references to local variables for register allocation */
6327 void analyse_function(void)
6329 int level, t;
6331 for(;;) {
6332 if (tok == -1)
6333 break;
6334 /* any symbol coming after '&' is considered as being a
6335 variable whose reference is taken. It is highly unaccurate
6336 but it is difficult to do better without a complete parse */
6337 if (tok == '&') {
6338 next();
6339 /* if '& number', then no need to examine next tokens */
6340 if (tok == TOK_CINT ||
6341 tok == TOK_CUINT ||
6342 tok == TOK_CLLONG ||
6343 tok == TOK_CULLONG) {
6344 continue;
6345 } else if (tok >= TOK_UIDENT) {
6346 /* if '& ident [' or '& ident ->', then ident address
6347 is not needed */
6348 t = tok;
6349 next();
6350 if (tok != '[' && tok != TOK_ARROW)
6351 add_var_ref(t);
6352 } else {
6353 level = 0;
6354 while (tok != '}' && tok != ';' &&
6355 !((tok == ',' || tok == ')') && level == 0)) {
6356 if (tok >= TOK_UIDENT) {
6357 add_var_ref(tok);
6358 } else if (tok == '(') {
6359 level++;
6360 } else if (tok == ')') {
6361 level--;
6363 next();
6366 } else {
6367 next();
6371 #endif
6373 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6374 void decl(int l)
6376 int t, b, v, has_init, r;
6377 Sym *sym;
6378 AttributeDef ad;
6380 while (1) {
6381 if (!parse_btype(&b, &ad)) {
6382 /* skip redundant ';' */
6383 /* XXX: find more elegant solution */
6384 if (tok == ';') {
6385 next();
6386 continue;
6388 /* special test for old K&R protos without explicit int
6389 type. Only accepted when defining global data */
6390 if (l == VT_LOCAL || tok < TOK_DEFINE)
6391 break;
6392 b = VT_INT;
6394 if (((b & VT_BTYPE) == VT_ENUM ||
6395 (b & VT_BTYPE) == VT_STRUCT) &&
6396 tok == ';') {
6397 /* we accept no variable after */
6398 next();
6399 continue;
6401 while (1) { /* iterate thru each declaration */
6402 t = type_decl(&ad, &v, b, TYPE_DIRECT);
6403 #if 0
6405 char buf[500];
6406 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6407 printf("type = '%s'\n", buf);
6409 #endif
6410 if (tok == '{') {
6411 #ifdef CONFIG_REG_VARS
6412 TokenString func_str;
6413 ParseState saved_parse_state;
6414 int block_level;
6415 #endif
6417 if (l == VT_LOCAL)
6418 error("cannot use local functions");
6419 if (!(t & VT_FUNC))
6420 expect("function definition");
6422 #ifdef CONFIG_REG_VARS
6423 /* parse all function code and record it */
6425 tok_str_new(&func_str);
6427 block_level = 0;
6428 for(;;) {
6429 int t;
6430 if (tok == -1)
6431 error("unexpected end of file");
6432 tok_str_add_tok(&func_str);
6433 t = tok;
6434 next();
6435 if (t == '{') {
6436 block_level++;
6437 } else if (t == '}') {
6438 block_level--;
6439 if (block_level == 0)
6440 break;
6443 tok_str_add(&func_str, -1);
6444 tok_str_add(&func_str, 0);
6446 save_parse_state(&saved_parse_state);
6448 macro_ptr = func_str.str;
6449 next();
6450 analyse_function();
6451 #endif
6453 /* compute text section */
6454 cur_text_section = ad.section;
6455 if (!cur_text_section)
6456 cur_text_section = text_section;
6457 ind = cur_text_section->data_offset;
6458 funcname = get_tok_str(v, NULL);
6459 sym = sym_find(v);
6460 if (sym) {
6461 /* if symbol is already defined, then put complete type */
6462 sym->t = t;
6463 } else {
6464 /* put function symbol */
6465 sym = sym_push1(&global_stack, v, t, 0);
6467 /* NOTE: we patch the symbol size later */
6468 put_extern_sym(sym, cur_text_section, ind, 0);
6469 func_ind = ind;
6470 sym->r = VT_SYM | VT_CONST;
6471 /* put debug symbol */
6472 if (do_debug)
6473 put_func_debug(sym);
6474 /* push a dummy symbol to enable local sym storage */
6475 sym_push1(&local_stack, 0, 0, 0);
6476 gfunc_prolog(t);
6477 loc = 0;
6478 rsym = 0;
6479 #ifdef CONFIG_REG_VARS
6480 macro_ptr = func_str.str;
6481 next();
6482 #endif
6483 block(NULL, NULL, NULL, NULL, 0);
6484 gsym(rsym);
6485 gfunc_epilog();
6486 cur_text_section->data_offset = ind;
6487 sym_pop(&label_stack, NULL); /* reset label stack */
6488 sym_pop(&local_stack, NULL); /* reset local stack */
6489 /* end of function */
6490 /* patch symbol size */
6491 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
6492 ind - func_ind;
6493 if (do_debug) {
6494 put_stabn(N_FUN, 0, 0, ind - func_ind);
6496 funcname = ""; /* for safety */
6497 func_vt = VT_VOID; /* for safety */
6498 ind = 0; /* for safety */
6500 #ifdef CONFIG_REG_VARS
6501 tok_str_free(func_str.str);
6502 restore_parse_state(&saved_parse_state);
6503 #endif
6504 break;
6505 } else {
6506 if (b & VT_TYPEDEF) {
6507 /* save typedefed type */
6508 /* XXX: test storage specifiers ? */
6509 sym_push(v, t | VT_TYPEDEF, 0, 0);
6510 } else if ((t & VT_BTYPE) == VT_FUNC) {
6511 /* external function definition */
6512 external_sym(v, t, 0);
6513 } else {
6514 /* not lvalue if array */
6515 r = 0;
6516 if (!(t & VT_ARRAY))
6517 r |= lvalue_type(t);
6518 if (b & VT_EXTERN) {
6519 /* external variable */
6520 external_sym(v, t, r);
6521 } else {
6522 if (t & VT_STATIC)
6523 r |= VT_CONST;
6524 else
6525 r |= l;
6526 has_init = (tok == '=');
6527 if (has_init)
6528 next();
6529 decl_initializer_alloc(t, &ad, r,
6530 has_init, v, l);
6533 if (tok != ',') {
6534 skip(';');
6535 break;
6537 next();
6543 /* compile the C file opened in 'file'. Return non zero if errors. */
6544 static int tcc_compile(TCCState *s)
6546 Sym *define_start, *sym;
6547 char buf[512];
6548 int p, section_sym;
6550 funcname = "";
6551 include_stack_ptr = include_stack;
6552 ifdef_stack_ptr = ifdef_stack;
6554 /* XXX: not ANSI compliant: bound checking says error */
6555 vtop = vstack - 1;
6556 anon_sym = SYM_FIRST_ANOM;
6558 /* file info: full path + filename */
6559 section_sym = 0; /* avoid warning */
6560 if (do_debug) {
6561 section_sym = put_elf_sym(symtab_section, 0, 0,
6562 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
6563 text_section->sh_num, NULL);
6564 getcwd(buf, sizeof(buf));
6565 pstrcat(buf, sizeof(buf), "/");
6566 put_stabs_r(buf, N_SO, 0, 0,
6567 text_section->data_offset, text_section, section_sym);
6568 put_stabs_r(file->filename, N_SO, 0, 0,
6569 text_section->data_offset, text_section, section_sym);
6571 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6572 symbols can be safely used */
6573 put_elf_sym(symtab_section, 0, 0,
6574 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
6575 SHN_ABS, file->filename);
6577 /* define common 'char *' type because it is often used internally
6578 for arrays and struct dereference */
6579 char_pointer_type = mk_pointer(VT_BYTE);
6580 /* define an old type function 'int func()' */
6581 p = anon_sym++;
6582 sym = sym_push1(&global_stack, p, 0, FUNC_OLD);
6583 sym->r = FUNC_CDECL;
6584 func_old_type = VT_FUNC | (p << VT_STRUCT_SHIFT);
6586 define_start = define_stack.top;
6587 inp();
6588 ch = '\n'; /* needed to parse correctly first preprocessor command */
6589 next();
6590 decl(VT_CONST);
6591 if (tok != -1)
6592 expect("declaration");
6594 /* end of translation unit info */
6595 if (do_debug) {
6596 put_stabs_r(NULL, N_SO, 0, 0,
6597 text_section->data_offset, text_section, section_sym);
6600 /* reset define stack, but leave -Dsymbols (may be incorrect if
6601 they are undefined) */
6602 sym_pop(&define_stack, define_start);
6604 sym_pop(&global_stack, NULL);
6606 return 0;
6609 int tcc_compile_string(TCCState *s, const char *str)
6611 BufferedFile bf1, *bf = &bf1;
6612 int ret;
6614 /* init file structure */
6615 bf->fd = -1;
6616 bf->buf_ptr = (char *)str;
6617 bf->buf_end = (char *)str + strlen(bf->buffer);
6618 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
6619 bf->line_num = 1;
6620 file = bf;
6622 ret = tcc_compile(s);
6624 /* currently, no need to close */
6625 return ret;
6628 /* define a symbol. A value can also be provided with the '=' operator */
6629 void tcc_define_symbol(TCCState *s, const char *sym, const char *value)
6631 BufferedFile bf1, *bf = &bf1;
6633 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
6634 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
6635 /* default value */
6636 if (!value)
6637 value = "1";
6638 pstrcat(bf->buffer, IO_BUF_SIZE, value);
6640 /* init file structure */
6641 bf->fd = -1;
6642 bf->buf_ptr = bf->buffer;
6643 bf->buf_end = bf->buffer + strlen(bf->buffer);
6644 bf->filename[0] = '\0';
6645 bf->line_num = 1;
6646 file = bf;
6648 include_stack_ptr = include_stack;
6650 /* parse with define parser */
6651 inp();
6652 ch = '\n'; /* needed to parse correctly first preprocessor command */
6653 next_nomacro();
6654 parse_define();
6655 file = NULL;
6658 void tcc_undefine_symbol(TCCState *s1, const char *sym)
6660 TokenSym *ts;
6661 Sym *s;
6662 ts = tok_alloc(sym, 0);
6663 s = sym_find1(&define_stack, tok);
6664 /* undefine symbol by putting an invalid name */
6665 if (s)
6666 sym_undef(&define_stack, s);
6669 #include "tccelf.c"
6671 /* print the position in the source file of PC value 'pc' by reading
6672 the stabs debug information */
6673 static void rt_printline(unsigned long wanted_pc)
6675 Stab_Sym *sym, *sym_end;
6676 char func_name[128], last_func_name[128];
6677 unsigned long func_addr, last_pc, pc;
6678 const char *incl_files[INCLUDE_STACK_SIZE];
6679 int incl_index, len, last_line_num, i;
6680 const char *str, *p;
6682 func_name[0] = '\0';
6683 func_addr = 0;
6684 incl_index = 0;
6685 last_func_name[0] = '\0';
6686 last_pc = 0xffffffff;
6687 last_line_num = 1;
6688 sym = (Stab_Sym *)stab_section->data + 1;
6689 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
6690 while (sym < sym_end) {
6691 switch(sym->n_type) {
6692 /* function start or end */
6693 case N_FUN:
6694 if (sym->n_strx == 0) {
6695 func_name[0] = '\0';
6696 func_addr = 0;
6697 } else {
6698 str = stabstr_section->data + sym->n_strx;
6699 p = strchr(str, ':');
6700 if (!p) {
6701 pstrcpy(func_name, sizeof(func_name), str);
6702 } else {
6703 len = p - str;
6704 if (len > sizeof(func_name) - 1)
6705 len = sizeof(func_name) - 1;
6706 memcpy(func_name, str, len);
6707 func_name[len] = '\0';
6709 func_addr = sym->n_value;
6711 break;
6712 /* line number info */
6713 case N_SLINE:
6714 pc = sym->n_value + func_addr;
6715 if (wanted_pc >= last_pc && wanted_pc < pc)
6716 goto found;
6717 last_pc = pc;
6718 last_line_num = sym->n_desc;
6719 /* XXX: slow! */
6720 strcpy(last_func_name, func_name);
6721 break;
6722 /* include files */
6723 case N_BINCL:
6724 str = stabstr_section->data + sym->n_strx;
6725 add_incl:
6726 if (incl_index < INCLUDE_STACK_SIZE) {
6727 incl_files[incl_index++] = str;
6729 break;
6730 case N_EINCL:
6731 if (incl_index > 1)
6732 incl_index--;
6733 break;
6734 case N_SO:
6735 if (sym->n_strx == 0) {
6736 incl_index = 0; /* end of translation unit */
6737 } else {
6738 str = stabstr_section->data + sym->n_strx;
6739 /* do not add path */
6740 len = strlen(str);
6741 if (len > 0 && str[len - 1] != '/')
6742 goto add_incl;
6744 break;
6746 sym++;
6748 /* did not find line number info: */
6749 fprintf(stderr, "(no debug info, pc=0x%08lx): ", wanted_pc);
6750 return;
6751 found:
6752 for(i = 0; i < incl_index - 1; i++)
6753 fprintf(stderr, "In file included from %s\n",
6754 incl_files[i]);
6755 if (incl_index > 0) {
6756 fprintf(stderr, "%s:%d: ",
6757 incl_files[incl_index - 1], last_line_num);
6759 if (last_func_name[0] != '\0') {
6760 fprintf(stderr, "in function '%s()': ", last_func_name);
6764 /* emit a run time error at position 'pc' */
6765 void rt_error(unsigned long pc, const char *fmt, ...)
6767 va_list ap;
6768 va_start(ap, fmt);
6770 rt_printline(pc);
6771 vfprintf(stderr, fmt, ap);
6772 fprintf(stderr, "\n");
6773 exit(255);
6774 va_end(ap);
6777 #ifndef WIN32
6778 /* signal handler for fatal errors */
6779 static void sig_error(int signum, siginfo_t *siginf, void *puc)
6781 struct ucontext *uc = puc;
6782 unsigned long pc;
6784 #ifdef __i386__
6785 pc = uc->uc_mcontext.gregs[14];
6786 #else
6787 #error please put the right sigcontext field
6788 #endif
6790 switch(signum) {
6791 case SIGFPE:
6792 switch(siginf->si_code) {
6793 case FPE_INTDIV:
6794 case FPE_FLTDIV:
6795 rt_error(pc, "division by zero");
6796 break;
6797 default:
6798 rt_error(pc, "floating point exception");
6799 break;
6801 break;
6802 case SIGBUS:
6803 case SIGSEGV:
6804 rt_error(pc, "dereferencing invalid pointer");
6805 break;
6806 case SIGILL:
6807 rt_error(pc, "illegal instruction");
6808 break;
6809 case SIGABRT:
6810 rt_error(pc, "abort() called");
6811 break;
6812 default:
6813 rt_error(pc, "caught signal %d", signum);
6814 break;
6816 exit(255);
6818 #endif
6820 /* launch the compiled program with the given arguments */
6821 int tcc_run(TCCState *s1, int argc, char **argv)
6823 Section *s;
6824 int (*prog_main)(int, char **);
6825 int i;
6827 tcc_add_runtime(s1);
6829 relocate_common_syms();
6831 /* compute relocation address : section are relocated in place. We
6832 also alloc the bss space */
6833 for(i = 1; i < nb_sections; i++) {
6834 s = sections[i];
6835 if (s->sh_flags & SHF_ALLOC) {
6836 void *data;
6837 if (s->sh_type == SHT_NOBITS) {
6838 data = tcc_mallocz(s->data_offset);
6839 } else {
6840 data = s->data;
6842 s->sh_addr = (unsigned long)data;
6846 relocate_syms(1);
6848 /* relocate each section */
6849 for(i = 1; i < nb_sections; i++) {
6850 s = sections[i];
6851 if (s->reloc)
6852 relocate_section(s1, s);
6855 prog_main = (void *)get_elf_sym_val("main");
6857 if (do_debug) {
6858 #ifdef WIN32
6859 error("debug mode currently not available for Windows");
6860 #else
6861 struct sigaction sigact;
6862 /* install TCC signal handlers to print debug info on fatal
6863 runtime errors */
6864 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
6865 sigact.sa_sigaction = sig_error;
6866 sigemptyset(&sigact.sa_mask);
6867 sigaction(SIGFPE, &sigact, NULL);
6868 sigaction(SIGILL, &sigact, NULL);
6869 sigaction(SIGSEGV, &sigact, NULL);
6870 sigaction(SIGBUS, &sigact, NULL);
6871 sigaction(SIGABRT, &sigact, NULL);
6872 #endif
6875 #ifdef CONFIG_TCC_BCHECK
6876 if (do_bounds_check) {
6877 void (*bound_init)(void);
6878 void **bound_error_func;
6880 /* set error function */
6881 bound_error_func = (void **)get_elf_sym_val("__bound_error_func");
6882 *bound_error_func = rt_error;
6884 /* XXX: use .init section so that it also work in binary ? */
6885 bound_init = (void *)get_elf_sym_val("__bound_init");
6886 bound_init();
6888 #endif
6889 return (*prog_main)(argc, argv);
6892 TCCState *tcc_new(void)
6894 char *p, *r;
6895 TCCState *s;
6897 s = tcc_malloc(sizeof(TCCState));
6898 if (!s)
6899 return NULL;
6900 s->output_type = TCC_OUTPUT_MEMORY;
6902 /* default include paths */
6903 tcc_add_sysinclude_path(s, "/usr/local/include");
6904 tcc_add_sysinclude_path(s, "/usr/include");
6905 tcc_add_sysinclude_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
6907 /* add all tokens */
6908 tok_ident = TOK_IDENT;
6909 p = tcc_keywords;
6910 while (*p) {
6911 r = p;
6912 while (*r++);
6913 tok_alloc(p, r - p - 1);
6914 p = r;
6917 /* we add dummy defines for some special macros to speed up tests
6918 and to have working defined() */
6919 sym_push1(&define_stack, TOK___LINE__, MACRO_OBJ, 0);
6920 sym_push1(&define_stack, TOK___FILE__, MACRO_OBJ, 0);
6921 sym_push1(&define_stack, TOK___DATE__, MACRO_OBJ, 0);
6922 sym_push1(&define_stack, TOK___TIME__, MACRO_OBJ, 0);
6923 sym_push1(&define_stack, TOK___FUNCTION__, MACRO_OBJ, 0);
6925 /* standard defines */
6926 tcc_define_symbol(s, "__STDC__", NULL);
6927 #if defined(TCC_TARGET_I386)
6928 tcc_define_symbol(s, "__i386__", NULL);
6929 #endif
6930 #if defined(linux)
6931 tcc_define_symbol(s, "linux", NULL);
6932 #endif
6933 /* tiny C specific defines */
6934 tcc_define_symbol(s, "__TINYC__", NULL);
6936 /* default library paths */
6937 tcc_add_library_path(s, "/usr/local/lib");
6938 tcc_add_library_path(s, "/usr/lib");
6939 tcc_add_library_path(s, "/lib");
6941 /* no section zero */
6942 dynarray_add((void ***)&sections, &nb_sections, NULL);
6944 /* create standard sections */
6945 text_section = new_section(".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
6946 data_section = new_section(".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
6947 bss_section = new_section(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
6949 /* symbols are always generated for linking stage */
6950 symtab_section = new_symtab(".symtab", SHT_SYMTAB, 0,
6951 ".strtab",
6952 ".hashtab", SHF_PRIVATE);
6953 strtab_section = symtab_section->link;
6955 /* private symbol table for dynamic symbols */
6956 dynsymtab_section = new_symtab(".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
6957 ".dynstrtab",
6958 ".dynhashtab", SHF_PRIVATE);
6959 return s;
6962 void tcc_delete(TCCState *s)
6964 tcc_free(s);
6967 int tcc_add_include_path(TCCState *s, const char *pathname)
6969 char *pathname1;
6971 pathname1 = tcc_strdup(pathname);
6972 dynarray_add((void ***)&include_paths, &nb_include_paths, pathname1);
6973 return 0;
6976 int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
6978 char *pathname1;
6980 pathname1 = tcc_strdup(pathname);
6981 dynarray_add((void ***)&sysinclude_paths, &nb_sysinclude_paths, pathname1);
6982 return 0;
6985 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags)
6987 const char *ext;
6988 Elf32_Ehdr ehdr;
6989 int fd;
6990 BufferedFile *saved_file;
6992 /* find source file type with extension */
6993 ext = strrchr(filename, '.');
6994 if (ext)
6995 ext++;
6997 /* open the file */
6998 saved_file = file;
6999 file = tcc_open(filename);
7000 if (!file) {
7001 if (flags & AFF_PRINT_ERROR) {
7002 error("file '%s' not found", filename);
7003 } else {
7004 file = saved_file;
7005 return -1;
7009 if (!ext || !strcmp(ext, "c")) {
7010 /* C file assumed */
7011 tcc_compile(s);
7012 } else {
7013 fd = file->fd;
7014 /* assume executable format: auto guess file type */
7015 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
7016 error("could not read header");
7017 lseek(fd, 0, SEEK_SET);
7019 if (ehdr.e_ident[0] == ELFMAG0 &&
7020 ehdr.e_ident[1] == ELFMAG1 &&
7021 ehdr.e_ident[2] == ELFMAG2 &&
7022 ehdr.e_ident[3] == ELFMAG3) {
7023 file->line_num = 0; /* do not display line number if error */
7024 if (ehdr.e_type == ET_REL) {
7025 tcc_load_object_file(s, fd, 0);
7026 } else if (ehdr.e_type == ET_DYN) {
7027 tcc_load_dll(s, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
7028 } else {
7029 error("unrecognized ELF file");
7031 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
7032 file->line_num = 0; /* do not display line number if error */
7033 tcc_load_archive(s, fd);
7034 } else {
7035 /* as GNU ld, consider it is an ld script if not recognized */
7036 if (tcc_load_ldscript(s) < 0)
7037 error("unrecognized file type");
7040 tcc_close(file);
7041 file = saved_file;
7042 return 0;
7045 void tcc_add_file(TCCState *s, const char *filename)
7047 tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
7050 int tcc_add_library_path(TCCState *s, const char *pathname)
7052 char *pathname1;
7054 pathname1 = tcc_strdup(pathname);
7055 dynarray_add((void ***)&library_paths, &nb_library_paths, pathname1);
7056 return 0;
7059 /* find and load a dll. Return non zero if not found */
7060 /* XXX: add '-rpath' option support ? */
7061 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
7063 char buf[1024];
7064 int i;
7066 for(i = 0; i < nb_library_paths; i++) {
7067 snprintf(buf, sizeof(buf), "%s/%s",
7068 library_paths[i], filename);
7069 if (tcc_add_file_internal(s, buf, flags) == 0)
7070 return 0;
7072 return -1;
7075 /* the library name is the same as the argument of the '-l' option */
7076 int tcc_add_library(TCCState *s, const char *libraryname)
7078 char buf[1024];
7079 int i;
7080 void *h;
7082 /* if we output to memory, then we simply we dlopen(). */
7083 if (s->output_type == TCC_OUTPUT_MEMORY) {
7084 /* Since the libc is already loaded, we don't need to load it again */
7085 if (!strcmp(libraryname, "c"))
7086 return 0;
7087 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
7088 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
7089 if (!h)
7090 return -1;
7091 return 0;
7094 /* first we look for the dynamic library if not static linking */
7095 if (!static_link) {
7096 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
7097 if (tcc_add_dll(s, buf, 0) == 0)
7098 return 0;
7101 /* then we look for the static library */
7102 for(i = 0; i < nb_library_paths; i++) {
7103 snprintf(buf, sizeof(buf), "%s/lib%s.a",
7104 library_paths[i], libraryname);
7105 if (tcc_add_file_internal(s, buf, 0) == 0)
7106 return 0;
7108 return -1;
7111 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
7113 add_elf_sym(symtab_section, val, 0,
7114 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7115 SHN_ABS, name);
7116 return 0;
7119 int tcc_set_output_type(TCCState *s, int output_type)
7121 s->output_type = output_type;
7123 /* if bound checking, then add corresponding sections */
7124 #ifdef CONFIG_TCC_BCHECK
7125 if (do_bounds_check) {
7126 /* define symbol */
7127 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
7128 /* create bounds sections */
7129 bounds_section = new_section(".bounds",
7130 SHT_PROGBITS, SHF_ALLOC);
7131 lbounds_section = new_section(".lbounds",
7132 SHT_PROGBITS, SHF_ALLOC);
7134 #endif
7136 /* add debug sections */
7137 if (do_debug) {
7138 /* stab symbols */
7139 stab_section = new_section(".stab", SHT_PROGBITS, 0);
7140 stab_section->sh_entsize = sizeof(Stab_Sym);
7141 stabstr_section = new_section(".stabstr", SHT_STRTAB, 0);
7142 put_elf_str(stabstr_section, "");
7143 stab_section->link = stabstr_section;
7144 /* put first entry */
7145 put_stabs("", 0, 0, 0, 0);
7148 /* add libc crt1/crti objects */
7149 if (output_type == TCC_OUTPUT_EXE ||
7150 output_type == TCC_OUTPUT_DLL) {
7151 if (output_type != TCC_OUTPUT_DLL)
7152 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
7153 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
7155 return 0;
7158 #if !defined(LIBTCC)
7160 void help(void)
7162 printf("tcc version 0.9.10 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7163 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7164 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
7165 " [--] infile1 [infile2... --] [infile_args...]\n"
7166 "\n"
7167 "General options:\n"
7168 " -c compile only - generate an object file\n"
7169 " -o outfile set output filename\n"
7170 " -- allows multiples input files if no -o option given. Also\n"
7171 " separate input files from runtime arguments\n"
7172 " -Bdir set tcc internal library path\n"
7173 " -bench output compilation statistics\n"
7174 "Preprocessor options:\n"
7175 " -Idir add include path 'dir'\n"
7176 " -Dsym[=val] define 'sym' with value 'val'\n"
7177 " -Usym undefine 'sym'\n"
7178 "C compiler options:\n"
7179 " -g generate runtime debug info\n"
7180 #ifdef CONFIG_TCC_BCHECK
7181 " -b compile with built-in memory and bounds checker (implies -g)\n"
7182 #endif
7183 "Linker options:\n"
7184 " -Ldir add library path 'dir'\n"
7185 " -llib link with dynamic or static library 'lib'\n"
7186 " -shared generate a shared library\n"
7187 " -static static linking\n"
7191 int main(int argc, char **argv)
7193 char *r, *outfile;
7194 int optind, output_type, multiple_files, i;
7195 TCCState *s;
7196 char **libraries;
7197 int nb_libraries;
7199 s = tcc_new();
7200 output_type = TCC_OUTPUT_MEMORY;
7202 optind = 1;
7203 outfile = NULL;
7204 multiple_files = 0;
7205 libraries = NULL;
7206 nb_libraries = 0;
7207 while (1) {
7208 if (optind >= argc) {
7209 show_help:
7210 help();
7211 return 1;
7213 r = argv[optind];
7214 if (r[0] != '-')
7215 break;
7216 optind++;
7217 if (r[1] == '-') {
7218 /* '--' enables multiple files input */
7219 multiple_files = 1;
7220 } else if (r[1] == 'h' || r[1] == '?') {
7221 goto show_help;
7222 } else if (r[1] == 'I') {
7223 if (tcc_add_include_path(s, r + 2) < 0)
7224 error("too many include paths");
7225 } else if (r[1] == 'D') {
7226 char *sym, *value;
7227 sym = r + 2;
7228 value = strchr(sym, '=');
7229 if (value) {
7230 *value = '\0';
7231 value++;
7233 tcc_define_symbol(s, sym, value);
7234 } else if (r[1] == 'U') {
7235 tcc_undefine_symbol(s, r + 2);
7236 } else if (r[1] == 'L') {
7237 tcc_add_library_path(s, r + 2);
7238 } else if (r[1] == 'B') {
7239 /* set tcc utilities path (mainly for tcc development) */
7240 tcc_lib_path = r + 2;
7241 } else if (r[1] == 'l') {
7242 dynarray_add((void ***)&libraries, &nb_libraries, r + 2);
7243 } else if (!strcmp(r + 1, "bench")) {
7244 do_bench = 1;
7245 } else
7246 #ifdef CONFIG_TCC_BCHECK
7247 if (r[1] == 'b') {
7248 do_bounds_check = 1;
7249 do_debug = 1;
7250 } else
7251 #endif
7252 if (r[1] == 'g') {
7253 do_debug = 1;
7254 } else if (r[1] == 'c') {
7255 multiple_files = 1;
7256 output_type = TCC_OUTPUT_OBJ;
7257 } else if (!strcmp(r + 1, "static")) {
7258 static_link = 1;
7259 } else if (!strcmp(r + 1, "shared")) {
7260 output_type = TCC_OUTPUT_DLL;
7261 } else if (r[1] == 'o') {
7262 if (optind >= argc)
7263 goto show_help;
7264 multiple_files = 1;
7265 outfile = argv[optind++];
7266 } else {
7267 error("invalid option -- '%s'", r);
7271 /* if outfile provided without other options, we output an
7272 executable */
7273 if (outfile && output_type == TCC_OUTPUT_MEMORY)
7274 output_type = TCC_OUTPUT_EXE;
7276 tcc_set_output_type(s, output_type);
7278 tcc_add_file(s, argv[optind]);
7279 if (multiple_files) {
7280 while ((optind + 1) < argc) {
7281 optind++;
7282 r = argv[optind];
7283 if (r[0] == '-') {
7284 if (r[1] != '-')
7285 error("'--' expected");
7286 break;
7288 tcc_add_file(s, r);
7292 /* add specified libraries */
7293 for(i = 0; i < nb_libraries;i++) {
7294 if (tcc_add_library(s, libraries[i]) < 0)
7295 error("cannot find -l%s", libraries[i]);
7298 if (do_bench) {
7299 printf("total: %d idents, %d lines, %d bytes\n",
7300 tok_ident - TOK_IDENT, total_lines, total_bytes);
7301 #ifdef MEM_DEBUG
7302 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
7303 #endif
7306 if (s->output_type != TCC_OUTPUT_MEMORY) {
7307 tcc_output_file(s, outfile);
7308 return 0;
7309 } else {
7310 return tcc_run(s, argc - optind, argv + optind);
7314 #endif