added support for standalone operation
[tinycc.git] / tcc.c
blob2895cc94ff82c7891e5da21b76d7e952bbd0e492
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,
504 TOK___LINE__,
505 TOK___FILE__,
506 TOK___DATE__,
507 TOK___TIME__,
508 TOK___VA_ARGS__,
510 /* special identifiers */
511 TOK___FUNC__,
512 TOK_MAIN,
513 #define DEF(id, str) id,
514 #include "tcctok.h"
515 #undef DEF
518 char *tcc_keywords =
519 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
520 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
521 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
522 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
523 "sizeof\0__attribute__\0"
524 /* the following are not keywords. They are included to ease parsing */
525 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
526 "defined\0undef\0error\0line\0"
527 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
528 "__func__\0main\0"
529 /* builtin functions */
530 #define DEF(id, str) str "\0"
531 #include "tcctok.h"
532 #undef DEF
535 #ifdef WIN32
536 #define snprintf _snprintf
537 #endif
539 #if defined(WIN32) || defined(TCC_UCLIBC)
540 /* currently incorrect */
541 long double strtold(const char *nptr, char **endptr)
543 return (long double)strtod(nptr, endptr);
545 float strtof(const char *nptr, char **endptr)
547 return (float)strtod(nptr, endptr);
549 #else
550 /* XXX: need to define this to use them in non ISOC99 context */
551 extern float strtof (const char *__nptr, char **__endptr);
552 extern long double strtold (const char *__nptr, char **__endptr);
553 #endif
555 static char *pstrcpy(char *buf, int buf_size, const char *s);
556 static char *pstrcat(char *buf, int buf_size, const char *s);
558 void sum(int l);
559 void next(void);
560 void next_nomacro(void);
561 int expr_const(void);
562 void expr_eq(void);
563 void gexpr(void);
564 void decl(int l);
565 void decl_initializer(int t, Section *sec, unsigned long c, int first, int size_only);
566 void decl_initializer_alloc(int t, AttributeDef *ad, int r, int has_init,
567 int v, int scope);
568 int gv(int rc);
569 void gv2(int rc1, int rc2);
570 void move_reg(int r, int s);
571 void save_regs(int n);
572 void save_reg(int r);
573 void vpop(void);
574 void vswap(void);
575 void vdup(void);
576 int get_reg(int rc);
578 void macro_subst(TokenString *tok_str,
579 Sym **nested_list, int *macro_str);
580 int save_reg_forced(int r);
581 void gen_op(int op);
582 void force_charshort_cast(int t);
583 void gen_cast(int t);
584 void vstore(void);
585 Sym *sym_find(int v);
586 Sym *sym_push(int v, int t, int r, int c);
588 /* type handling */
589 int type_size(int t, int *a);
590 int pointed_type(int t);
591 int pointed_size(int t);
592 static int lvalue_type(int t);
593 int is_compatible_types(int t1, int t2);
594 int parse_btype(int *type_ptr, AttributeDef *ad);
595 int type_decl(AttributeDef *ad, int *v, int t, int td);
597 void error(const char *fmt, ...);
598 void rt_error(unsigned long pc, const char *fmt, ...);
599 void vpushi(int v);
600 void vset(int t, int r, int v);
601 void type_to_str(char *buf, int buf_size,
602 int t, const char *varstr);
603 char *get_tok_str(int v, CValue *cv);
604 Sym *external_sym(int v, int u, int r);
605 static Sym *get_sym_ref(int t, Section *sec,
606 unsigned long offset, unsigned long size);
608 /* section generation */
609 static void section_realloc(Section *sec, unsigned long new_size);
610 static void *section_ptr(Section *sec, unsigned long size);
611 static void *section_ptr_add(Section *sec, unsigned long size);
612 static void put_extern_sym(Sym *sym, Section *section,
613 unsigned long value, unsigned long size);
614 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
615 static int put_elf_str(Section *s, const char *sym);
616 static int put_elf_sym(Section *s,
617 unsigned long value, unsigned long size,
618 int info, int other, int shndx, const char *name);
619 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
620 int info, int sh_num, const char *name);
621 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
622 int type, int symbol);
623 static void put_stabs(const char *str, int type, int other, int desc,
624 unsigned long value);
625 static void put_stabs_r(const char *str, int type, int other, int desc,
626 unsigned long value, Section *sec, int sym_index);
627 static void put_stabn(int type, int other, int desc, int value);
628 static void put_stabd(int type, int other, int desc);
629 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
631 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
632 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
633 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
635 /* true if float/double/long double type */
636 static inline int is_float(int t)
638 int bt;
639 bt = t & VT_BTYPE;
640 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
643 #ifdef TCC_TARGET_I386
644 #include "i386-gen.c"
645 #endif
646 #ifdef TCC_TARGET_IL
647 #include "il-gen.c"
648 #endif
650 #ifdef CONFIG_TCC_STATIC
652 #define RTLD_LAZY 0x001
653 #define RTLD_NOW 0x002
654 #define RTLD_GLOBAL 0x100
656 /* dummy function for profiling */
657 void *dlopen(const char *filename, int flag)
659 return NULL;
662 const char *dlerror(void)
664 return "error";
667 typedef struct TCCSyms {
668 char *str;
669 void *ptr;
670 } TCCSyms;
672 #define TCCSYM(a) { #a, &a, },
674 /* add the symbol you want here if no dynamic linking is done */
675 static TCCSyms tcc_syms[] = {
676 TCCSYM(printf)
677 TCCSYM(fprintf)
678 TCCSYM(fopen)
679 TCCSYM(fclose)
680 { NULL, NULL },
683 void *dlsym(void *handle, const char *symbol)
685 TCCSyms *p;
686 p = tcc_syms;
687 while (p->str != NULL) {
688 if (!strcmp(p->str, symbol))
689 return p->ptr;
690 p++;
692 return NULL;
695 #endif
697 /********************************************************/
699 /* we use our own 'finite' function to avoid potential problems with
700 non standard math libs */
701 /* XXX: endianness dependant */
702 int ieee_finite(double d)
704 int *p = (int *)&d;
705 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
708 /* copy a string and truncate it. */
709 static char *pstrcpy(char *buf, int buf_size, const char *s)
711 char *q, *q_end;
712 int c;
714 if (buf_size > 0) {
715 q = buf;
716 q_end = buf + buf_size - 1;
717 while (q < q_end) {
718 c = *s++;
719 if (c == '\0')
720 break;
721 *q++ = c;
723 *q = '\0';
725 return buf;
728 /* strcat and truncate. */
729 static char *pstrcat(char *buf, int buf_size, const char *s)
731 int len;
732 len = strlen(buf);
733 if (len < buf_size)
734 pstrcpy(buf + len, buf_size - len, s);
735 return buf;
738 /* memory management */
739 #ifdef MEM_DEBUG
740 int mem_cur_size;
741 int mem_max_size;
742 #endif
744 static inline void tcc_free(void *ptr)
746 #ifdef MEM_DEBUG
747 mem_cur_size -= malloc_usable_size(ptr);
748 #endif
749 free(ptr);
752 static void *tcc_malloc(unsigned long size)
754 void *ptr;
755 ptr = malloc(size);
756 if (!ptr)
757 error("memory full");
758 #ifdef MEM_DEBUG
759 mem_cur_size += malloc_usable_size(ptr);
760 if (mem_cur_size > mem_max_size)
761 mem_max_size = mem_cur_size;
762 #endif
763 return ptr;
766 static void *tcc_mallocz(unsigned long size)
768 void *ptr;
769 ptr = tcc_malloc(size);
770 memset(ptr, 0, size);
771 return ptr;
774 static inline void *tcc_realloc(void *ptr, unsigned long size)
776 void *ptr1;
777 #ifdef MEM_DEBUG
778 mem_cur_size -= malloc_usable_size(ptr);
779 #endif
780 ptr1 = realloc(ptr, size);
781 #ifdef MEM_DEBUG
782 /* NOTE: count not correct if alloc error, but not critical */
783 mem_cur_size += malloc_usable_size(ptr1);
784 if (mem_cur_size > mem_max_size)
785 mem_max_size = mem_cur_size;
786 #endif
787 return ptr1;
790 static char *tcc_strdup(const char *str)
792 char *ptr;
793 ptr = tcc_malloc(strlen(str) + 1);
794 strcpy(ptr, str);
795 return ptr;
798 #define free(p) use_tcc_free(p)
799 #define malloc(s) use_tcc_malloc(s)
800 #define realloc(p, s) use_tcc_realloc(p, s)
802 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
804 int nb, nb_alloc;
805 void **pp;
807 nb = *nb_ptr;
808 pp = *ptab;
809 /* every power of two we double array size */
810 if ((nb & (nb - 1)) == 0) {
811 if (!nb)
812 nb_alloc = 1;
813 else
814 nb_alloc = nb * 2;
815 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
816 if (!pp)
817 error("memory full");
818 *ptab = pp;
820 pp[nb++] = data;
821 *nb_ptr = nb;
824 Section *new_section(const char *name, int sh_type, int sh_flags)
826 Section *sec;
828 sec = tcc_mallocz(sizeof(Section));
829 pstrcpy(sec->name, sizeof(sec->name), name);
830 sec->sh_type = sh_type;
831 sec->sh_flags = sh_flags;
832 switch(sh_type) {
833 case SHT_HASH:
834 case SHT_REL:
835 case SHT_DYNSYM:
836 case SHT_SYMTAB:
837 case SHT_DYNAMIC:
838 sec->sh_addralign = 4;
839 break;
840 case SHT_STRTAB:
841 sec->sh_addralign = 1;
842 break;
843 default:
844 sec->sh_addralign = 32; /* default conservative alignment */
845 break;
848 /* only add section if not private */
849 if (!(sh_flags & SHF_PRIVATE)) {
850 sec->sh_num = nb_sections;
851 dynarray_add((void ***)&sections, &nb_sections, sec);
853 return sec;
856 /* realloc section and set its content to zero */
857 static void section_realloc(Section *sec, unsigned long new_size)
859 unsigned long size;
860 unsigned char *data;
862 size = sec->data_allocated;
863 if (size == 0)
864 size = 1;
865 while (size < new_size)
866 size = size * 2;
867 data = tcc_realloc(sec->data, size);
868 if (!data)
869 error("memory full");
870 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
871 sec->data = data;
872 sec->data_allocated = size;
875 /* reserve at least 'size' bytes in section 'sec' from
876 sec->data_offset. Optimized for speed */
877 static inline void *section_ptr(Section *sec, unsigned long size)
879 unsigned long offset, offset1;
880 offset = sec->data_offset;
881 offset1 = offset + size;
882 if (offset1 > sec->data_allocated)
883 section_realloc(sec, offset1);
884 return sec->data + offset;
887 static void *section_ptr_add(Section *sec, unsigned long size)
889 unsigned long offset, offset1;
891 offset = sec->data_offset;
892 offset1 = offset + size;
893 if (offset1 > sec->data_allocated)
894 section_realloc(sec, offset1);
895 sec->data_offset = offset1;
896 return sec->data + offset;
899 /* return a reference to a section, and create it if it does not
900 exists */
901 Section *find_section(const char *name)
903 Section *sec;
904 int i;
905 for(i = 1; i < nb_sections; i++) {
906 sec = sections[i];
907 if (!strcmp(name, sec->name))
908 return sec;
910 /* sections are created as PROGBITS */
911 return new_section(name, SHT_PROGBITS, SHF_ALLOC);
914 /* update sym->c so that it points to an external symbol in section
915 'section' with value 'value' */
916 static void put_extern_sym(Sym *sym, Section *section,
917 unsigned long value, unsigned long size)
919 int sym_type, sym_bind, sh_num, info;
920 Elf32_Sym *esym;
921 const char *name;
922 char buf[32];
924 if (section)
925 sh_num = section->sh_num;
926 else
927 sh_num = SHN_UNDEF;
928 if (!sym->c) {
929 if ((sym->t & VT_BTYPE) == VT_FUNC)
930 sym_type = STT_FUNC;
931 else
932 sym_type = STT_OBJECT;
933 if (sym->t & VT_STATIC)
934 sym_bind = STB_LOCAL;
935 else
936 sym_bind = STB_GLOBAL;
938 name = get_tok_str(sym->v, NULL);
939 #ifdef CONFIG_TCC_BCHECK
940 if (do_bounds_check) {
941 /* if bound checking is activated, we change some function
942 names by adding the "__bound" prefix */
943 switch(sym->v) {
944 case TOK_malloc:
945 case TOK_free:
946 case TOK_realloc:
947 case TOK_memalign:
948 case TOK_calloc:
949 case TOK_memcpy:
950 case TOK_memmove:
951 case TOK_memset:
952 case TOK_strlen:
953 case TOK_strcpy:
954 strcpy(buf, "__bound_");
955 strcat(buf, name);
956 name = buf;
957 break;
960 #endif
961 info = ELF32_ST_INFO(sym_bind, sym_type);
962 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
963 } else {
964 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
965 esym->st_value = value;
966 esym->st_size = size;
967 esym->st_shndx = sh_num;
971 /* add a new relocation entry to symbol 'sym' in section 's' */
972 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
974 if (!sym->c)
975 put_extern_sym(sym, NULL, 0, 0);
976 /* now we can add ELF relocation info */
977 put_elf_reloc(symtab_section, s, offset, type, sym->c);
980 static inline int isid(int c)
982 return (c >= 'a' && c <= 'z') ||
983 (c >= 'A' && c <= 'Z') ||
984 c == '_';
987 static inline int isnum(int c)
989 return c >= '0' && c <= '9';
992 static inline int toup(int c)
994 if (ch >= 'a' && ch <= 'z')
995 return ch - 'a' + 'A';
996 else
997 return ch;
1000 void printline(void)
1002 BufferedFile **f;
1004 if (file) {
1005 for(f = include_stack; f < include_stack_ptr; f++)
1006 fprintf(stderr, "In file included from %s:%d:\n",
1007 (*f)->filename, (*f)->line_num);
1008 if (file->line_num > 0) {
1009 fprintf(stderr, "%s:%d: ", file->filename, file->line_num);
1010 } else {
1011 fprintf(stderr, "%s: ", file->filename);
1013 } else {
1014 fprintf(stderr, "tcc: ");
1018 void error(const char *fmt, ...)
1020 va_list ap;
1021 va_start(ap, fmt);
1022 printline();
1023 vfprintf(stderr, fmt, ap);
1024 fprintf(stderr, "\n");
1025 exit(1);
1026 va_end(ap);
1029 void expect(const char *msg)
1031 error("%s expected", msg);
1034 void warning(const char *fmt, ...)
1036 va_list ap;
1038 va_start(ap, fmt);
1039 printline();
1040 fprintf(stderr, "warning: ");
1041 vfprintf(stderr, fmt, ap);
1042 fprintf(stderr, "\n");
1043 va_end(ap);
1046 void skip(int c)
1048 if (tok != c)
1049 error("'%c' expected", c);
1050 next();
1053 void test_lvalue(void)
1055 if (!(vtop->r & VT_LVAL))
1056 expect("lvalue");
1059 TokenSym *tok_alloc(const char *str, int len)
1061 TokenSym *ts, **pts, **ptable;
1062 int h, i;
1064 if (len <= 0)
1065 len = strlen(str);
1066 h = 1;
1067 for(i=0;i<len;i++)
1068 h = (h * 263 + ((unsigned char *)str)[i]) & (TOK_HASH_SIZE - 1);
1070 pts = &hash_ident[h];
1071 while (1) {
1072 ts = *pts;
1073 if (!ts)
1074 break;
1075 if (ts->len == len && !memcmp(ts->str, str, len))
1076 return ts;
1077 pts = &(ts->hash_next);
1080 if (tok_ident >= SYM_FIRST_ANOM)
1081 error("memory full");
1083 /* expand token table if needed */
1084 i = tok_ident - TOK_IDENT;
1085 if ((i % TOK_ALLOC_INCR) == 0) {
1086 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1087 if (!ptable)
1088 error("memory full");
1089 table_ident = ptable;
1092 ts = tcc_malloc(sizeof(TokenSym) + len);
1093 table_ident[i] = ts;
1094 ts->tok = tok_ident++;
1095 ts->len = len;
1096 ts->hash_next = NULL;
1097 memcpy(ts->str, str, len + 1);
1098 *pts = ts;
1099 return ts;
1102 /* CString handling */
1104 static void cstr_realloc(CString *cstr, int new_size)
1106 int size;
1107 void *data;
1109 size = cstr->size_allocated;
1110 if (size == 0)
1111 size = 8; /* no need to allocate a too small first string */
1112 while (size < new_size)
1113 size = size * 2;
1114 data = tcc_realloc(cstr->data_allocated, size);
1115 if (!data)
1116 error("memory full");
1117 cstr->data_allocated = data;
1118 cstr->size_allocated = size;
1119 cstr->data = data;
1122 /* add a byte */
1123 static void cstr_ccat(CString *cstr, int ch)
1125 int size;
1126 size = cstr->size + 1;
1127 if (size > cstr->size_allocated)
1128 cstr_realloc(cstr, size);
1129 ((unsigned char *)cstr->data)[size - 1] = ch;
1130 cstr->size = size;
1133 static void cstr_cat(CString *cstr, const char *str)
1135 int c;
1136 for(;;) {
1137 c = *str;
1138 if (c == '\0')
1139 break;
1140 cstr_ccat(cstr, c);
1141 str++;
1145 /* add a wide char */
1146 static void cstr_wccat(CString *cstr, int ch)
1148 int size;
1149 size = cstr->size + sizeof(int);
1150 if (size > cstr->size_allocated)
1151 cstr_realloc(cstr, size);
1152 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1153 cstr->size = size;
1156 static void cstr_new(CString *cstr)
1158 memset(cstr, 0, sizeof(CString));
1161 /* free string and reset it to NULL */
1162 static void cstr_free(CString *cstr)
1164 tcc_free(cstr->data_allocated);
1165 cstr_new(cstr);
1168 #define cstr_reset(cstr) cstr_free(cstr)
1170 /* XXX: unicode ? */
1171 static void add_char(CString *cstr, int c)
1173 if (c == '\'' || c == '\"' || c == '\\') {
1174 /* XXX: could be more precise if char or string */
1175 cstr_ccat(cstr, '\\');
1177 if (c >= 32 && c <= 126) {
1178 cstr_ccat(cstr, c);
1179 } else {
1180 cstr_ccat(cstr, '\\');
1181 if (c == '\n') {
1182 cstr_ccat(cstr, 'n');
1183 } else {
1184 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1185 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1186 cstr_ccat(cstr, '0' + (c & 7));
1191 /* XXX: buffer overflow */
1192 /* XXX: float tokens */
1193 char *get_tok_str(int v, CValue *cv)
1195 static char buf[STRING_MAX_SIZE + 1];
1196 static CString cstr_buf;
1197 CString *cstr;
1198 unsigned char *q;
1199 char *p;
1200 int i, len;
1202 /* NOTE: to go faster, we give a fixed buffer for small strings */
1203 cstr_reset(&cstr_buf);
1204 cstr_buf.data = buf;
1205 cstr_buf.size_allocated = sizeof(buf);
1206 p = buf;
1208 switch(v) {
1209 case TOK_CINT:
1210 case TOK_CUINT:
1211 /* XXX: not exact */
1212 sprintf(p, "%u", cv->ui);
1213 break;
1214 case TOK_CCHAR:
1215 case TOK_LCHAR:
1216 cstr_ccat(&cstr_buf, '\'');
1217 add_char(&cstr_buf, cv->i);
1218 cstr_ccat(&cstr_buf, '\'');
1219 cstr_ccat(&cstr_buf, '\0');
1220 break;
1221 case TOK_STR:
1222 case TOK_LSTR:
1223 cstr = cv->cstr;
1224 cstr_ccat(&cstr_buf, '\"');
1225 if (v == TOK_STR) {
1226 len = cstr->size - 1;
1227 for(i=0;i<len;i++)
1228 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1229 } else {
1230 len = (cstr->size / sizeof(int)) - 1;
1231 for(i=0;i<len;i++)
1232 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1234 cstr_ccat(&cstr_buf, '\"');
1235 cstr_ccat(&cstr_buf, '\0');
1236 break;
1237 case TOK_LT:
1238 v = '<';
1239 goto addv;
1240 case TOK_GT:
1241 v = '>';
1242 goto addv;
1243 case TOK_A_SHL:
1244 return strcpy(p, "<<=");
1245 case TOK_A_SAR:
1246 return strcpy(p, ">>=");
1247 default:
1248 if (v < TOK_IDENT) {
1249 /* search in two bytes table */
1250 q = tok_two_chars;
1251 while (*q) {
1252 if (q[2] == v) {
1253 *p++ = q[0];
1254 *p++ = q[1];
1255 *p = '\0';
1256 return buf;
1258 q += 3;
1260 addv:
1261 *p++ = v;
1262 *p = '\0';
1263 } else if (v < tok_ident) {
1264 return table_ident[v - TOK_IDENT]->str;
1265 } else if (v >= SYM_FIRST_ANOM) {
1266 /* special name for anonymous symbol */
1267 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1268 } else {
1269 /* should never happen */
1270 return NULL;
1272 break;
1274 return cstr_buf.data;
1277 /* push, without hashing */
1278 Sym *sym_push2(Sym **ps, int v, int t, int c)
1280 Sym *s;
1281 s = tcc_malloc(sizeof(Sym));
1282 s->v = v;
1283 s->t = t;
1284 s->c = c;
1285 s->next = NULL;
1286 /* add in stack */
1287 s->prev = *ps;
1288 *ps = s;
1289 return s;
1292 /* find a symbol and return its associated structure. 's' is the top
1293 of the symbol stack */
1294 Sym *sym_find2(Sym *s, int v)
1296 while (s) {
1297 if (s->v == v)
1298 return s;
1299 s = s->prev;
1301 return NULL;
1304 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1306 /* find a symbol and return its associated structure. 'st' is the
1307 symbol stack */
1308 Sym *sym_find1(SymStack *st, int v)
1310 Sym *s;
1312 s = st->hash[HASH_SYM(v)];
1313 while (s) {
1314 if (s->v == v)
1315 return s;
1316 s = s->hash_next;
1318 return NULL;
1321 Sym *sym_push1(SymStack *st, int v, int t, int c)
1323 Sym *s, **ps;
1324 s = sym_push2(&st->top, v, t, c);
1325 /* add in hash table */
1326 if (v) {
1327 ps = &st->hash[HASH_SYM(v)];
1328 s->hash_next = *ps;
1329 *ps = s;
1331 return s;
1334 /* find a symbol in the right symbol space */
1335 Sym *sym_find(int v)
1337 Sym *s;
1338 s = sym_find1(&local_stack, v);
1339 if (!s)
1340 s = sym_find1(&global_stack, v);
1341 return s;
1344 /* push a given symbol on the symbol stack */
1345 Sym *sym_push(int v, int t, int r, int c)
1347 Sym *s;
1348 if (local_stack.top)
1349 s = sym_push1(&local_stack, v, t, c);
1350 else
1351 s = sym_push1(&global_stack, v, t, c);
1352 s->r = r;
1353 return s;
1356 /* pop symbols until top reaches 'b' */
1357 void sym_pop(SymStack *st, Sym *b)
1359 Sym *s, *ss;
1361 s = st->top;
1362 while(s != b) {
1363 ss = s->prev;
1364 /* free hash table entry, except if symbol was freed (only
1365 used for #undef symbols) */
1366 if (s->v)
1367 st->hash[HASH_SYM(s->v)] = s->hash_next;
1368 tcc_free(s);
1369 s = ss;
1371 st->top = b;
1374 /* undefined a hashed symbol (used for #undef). Its name is set to
1375 zero */
1376 void sym_undef(SymStack *st, Sym *s)
1378 Sym **ss;
1379 ss = &st->hash[HASH_SYM(s->v)];
1380 while (*ss != NULL) {
1381 if (*ss == s)
1382 break;
1383 ss = &(*ss)->hash_next;
1385 *ss = s->hash_next;
1386 s->v = 0;
1389 /* I/O layer */
1391 BufferedFile *tcc_open(const char *filename)
1393 int fd;
1394 BufferedFile *bf;
1396 fd = open(filename, O_RDONLY);
1397 if (fd < 0)
1398 return NULL;
1399 bf = tcc_malloc(sizeof(BufferedFile));
1400 if (!bf) {
1401 close(fd);
1402 return NULL;
1404 bf->fd = fd;
1405 bf->buf_ptr = bf->buffer;
1406 bf->buf_end = bf->buffer;
1407 bf->buffer[0] = CH_EOB; /* put eob symbol */
1408 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1409 bf->line_num = 1;
1410 // printf("opening '%s'\n", filename);
1411 return bf;
1414 void tcc_close(BufferedFile *bf)
1416 total_lines += bf->line_num;
1417 close(bf->fd);
1418 tcc_free(bf);
1421 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1422 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1424 /* fill input buffer and return next char */
1425 int tcc_getc_slow(BufferedFile *bf)
1427 int len;
1428 /* only tries to read if really end of buffer */
1429 if (bf->buf_ptr >= bf->buf_end) {
1430 if (bf->fd != -1) {
1431 len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
1432 if (len < 0)
1433 len = 0;
1434 } else {
1435 len = 0;
1437 total_bytes += len;
1438 bf->buf_ptr = bf->buffer;
1439 bf->buf_end = bf->buffer + len;
1440 *bf->buf_end = CH_EOB;
1442 if (bf->buf_ptr < bf->buf_end) {
1443 return *bf->buf_ptr++;
1444 } else {
1445 bf->buf_ptr = bf->buf_end;
1446 return CH_EOF;
1450 /* no need to put that inline */
1451 void handle_eob(void)
1453 for(;;) {
1454 ch1 = tcc_getc_slow(file);
1455 if (ch1 != CH_EOF)
1456 return;
1458 if (include_stack_ptr == include_stack)
1459 return;
1460 /* add end of include file debug info */
1461 if (do_debug) {
1462 put_stabd(N_EINCL, 0, 0);
1464 /* pop include stack */
1465 tcc_close(file);
1466 include_stack_ptr--;
1467 file = *include_stack_ptr;
1471 /* read next char from current input file */
1472 static inline void inp(void)
1474 ch1 = TCC_GETC(file);
1475 /* end of buffer/file handling */
1476 if (ch1 == CH_EOB)
1477 handle_eob();
1478 if (ch1 == '\n')
1479 file->line_num++;
1480 // printf("ch1=%c 0x%x\n", ch1, ch1);
1483 /* input with '\\n' handling */
1484 static inline void minp(void)
1486 redo:
1487 ch = ch1;
1488 inp();
1489 if (ch == '\\' && ch1 == '\n') {
1490 inp();
1491 goto redo;
1493 //printf("ch=%c 0x%x\n", ch, ch);
1497 /* same as minp, but also skip comments */
1498 void cinp(void)
1500 int c;
1502 if (ch1 == '/') {
1503 inp();
1504 if (ch1 == '/') {
1505 /* single line C++ comments */
1506 inp();
1507 while (ch1 != '\n' && ch1 != -1)
1508 inp();
1509 inp();
1510 ch = ' '; /* return space */
1511 } else if (ch1 == '*') {
1512 /* C comments */
1513 inp();
1514 while (ch1 != -1) {
1515 c = ch1;
1516 inp();
1517 if (c == '*' && ch1 == '/') {
1518 inp();
1519 ch = ' '; /* return space */
1520 break;
1523 } else {
1524 ch = '/';
1526 } else {
1527 minp();
1531 void skip_spaces(void)
1533 while (ch == ' ' || ch == '\t')
1534 cinp();
1537 /* skip block of text until #else, #elif or #endif. skip also pairs of
1538 #if/#endif */
1539 void preprocess_skip(void)
1541 int a;
1542 a = 0;
1543 while (1) {
1544 while (ch != '\n') {
1545 if (ch == -1)
1546 expect("#endif");
1547 cinp();
1549 cinp();
1550 skip_spaces();
1551 if (ch == '#') {
1552 cinp();
1553 next_nomacro();
1554 if (a == 0 &&
1555 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1556 break;
1557 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1558 a++;
1559 else if (tok == TOK_ENDIF)
1560 a--;
1565 /* ParseState handling */
1567 /* XXX: currently, no include file info is stored. Thus, we cannot display
1568 accurate messages if the function or data definition spans multiple
1569 files */
1571 /* save current parse state in 's' */
1572 void save_parse_state(ParseState *s)
1574 s->line_num = file->line_num;
1575 s->macro_ptr = macro_ptr;
1576 s->tok = tok;
1577 s->tokc = tokc;
1580 /* restore parse state from 's' */
1581 void restore_parse_state(ParseState *s)
1583 file->line_num = s->line_num;
1584 macro_ptr = s->macro_ptr;
1585 tok = s->tok;
1586 tokc = s->tokc;
1589 /* return the number of additionnal 'ints' necessary to store the
1590 token */
1591 static inline int tok_ext_size(int t)
1593 switch(t) {
1594 /* 4 bytes */
1595 case TOK_CINT:
1596 case TOK_CUINT:
1597 case TOK_CCHAR:
1598 case TOK_LCHAR:
1599 case TOK_STR:
1600 case TOK_LSTR:
1601 case TOK_CFLOAT:
1602 case TOK_LINENUM:
1603 return 1;
1604 case TOK_CDOUBLE:
1605 case TOK_CLLONG:
1606 case TOK_CULLONG:
1607 return 2;
1608 case TOK_CLDOUBLE:
1609 return LDOUBLE_SIZE / 4;
1610 default:
1611 return 0;
1615 /* token string handling */
1617 static inline void tok_str_new(TokenString *s)
1619 s->str = NULL;
1620 s->len = 0;
1621 s->last_line_num = -1;
1624 static void tok_str_free(int *str)
1626 const int *p;
1627 CString *cstr;
1628 int t;
1630 p = str;
1631 for(;;) {
1632 t = *p++;
1633 if (t == 0)
1634 break;
1635 if (t == TOK_STR || t == TOK_LSTR) {
1636 /* XXX: use a macro to be portable on 64 bit ? */
1637 cstr = (CString *)(*p++);
1638 cstr_free(cstr);
1639 tcc_free(cstr);
1640 } else {
1641 p += tok_ext_size(t);
1644 tcc_free(str);
1647 static void tok_str_add(TokenString *s, int t)
1649 int len, *str;
1651 len = s->len;
1652 str = s->str;
1653 if ((len & 63) == 0) {
1654 str = tcc_realloc(str, (len + 64) * sizeof(int));
1655 if (!str)
1656 return;
1657 s->str = str;
1659 str[len++] = t;
1660 s->len = len;
1663 static void tok_str_add2(TokenString *s, int t, CValue *cv)
1665 int n, i, size;
1666 CString *cstr, *cstr1;
1667 CValue cv1;
1669 tok_str_add(s, t);
1670 if (t == TOK_STR || t == TOK_LSTR) {
1671 /* special case: need to duplicate string */
1672 cstr1 = cv->cstr;
1673 cstr = tcc_malloc(sizeof(CString));
1674 size = cstr1->size;
1675 cstr->size = size;
1676 cstr->size_allocated = size;
1677 cstr->data_allocated = tcc_malloc(size);
1678 cstr->data = cstr->data_allocated;
1679 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1680 cv1.cstr = cstr;
1681 tok_str_add(s, cv1.tab[0]);
1682 } else {
1683 n = tok_ext_size(t);
1684 for(i=0;i<n;i++)
1685 tok_str_add(s, cv->tab[i]);
1689 /* add the current parse token in token string 's' */
1690 static void tok_str_add_tok(TokenString *s)
1692 CValue cval;
1694 /* save line number info */
1695 if (file->line_num != s->last_line_num) {
1696 s->last_line_num = file->line_num;
1697 cval.i = s->last_line_num;
1698 tok_str_add2(s, TOK_LINENUM, &cval);
1700 tok_str_add2(s, tok, &tokc);
1703 /* get a token from an integer array and increment pointer accordingly */
1704 static int tok_get(int **tok_str, CValue *cv)
1706 int *p, t, n, i;
1708 p = *tok_str;
1709 t = *p++;
1710 n = tok_ext_size(t);
1711 for(i=0;i<n;i++)
1712 cv->tab[i] = *p++;
1713 *tok_str = p;
1714 return t;
1717 /* eval an expression for #if/#elif */
1718 int expr_preprocess(void)
1720 int c, t;
1721 TokenString str;
1723 tok_str_new(&str);
1724 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1725 next(); /* do macro subst */
1726 if (tok == TOK_DEFINED) {
1727 next_nomacro();
1728 t = tok;
1729 if (t == '(')
1730 next_nomacro();
1731 c = sym_find1(&define_stack, tok) != 0;
1732 if (t == '(')
1733 next_nomacro();
1734 tok = TOK_CINT;
1735 tokc.i = c;
1736 } else if (tok >= TOK_IDENT) {
1737 /* if undefined macro */
1738 tok = TOK_CINT;
1739 tokc.i = 0;
1741 tok_str_add_tok(&str);
1743 tok_str_add(&str, -1); /* simulate end of file */
1744 tok_str_add(&str, 0);
1745 /* now evaluate C constant expression */
1746 macro_ptr = str.str;
1747 next();
1748 c = expr_const();
1749 macro_ptr = NULL;
1750 tok_str_free(str.str);
1751 return c != 0;
1754 #if defined(DEBUG) || defined(PP_DEBUG)
1755 void tok_print(int *str)
1757 int t;
1758 CValue cval;
1760 while (1) {
1761 t = tok_get(&str, &cval);
1762 if (!t)
1763 break;
1764 printf(" %s", get_tok_str(t, &cval));
1766 printf("\n");
1768 #endif
1770 /* parse after #define */
1771 void parse_define(void)
1773 Sym *s, *first, **ps;
1774 int v, t, varg, is_vaargs;
1775 TokenString str;
1777 v = tok;
1778 /* XXX: should check if same macro (ANSI) */
1779 first = NULL;
1780 t = MACRO_OBJ;
1781 /* '(' must be just after macro definition for MACRO_FUNC */
1782 if (ch == '(') {
1783 next_nomacro();
1784 next_nomacro();
1785 ps = &first;
1786 while (tok != ')') {
1787 varg = tok;
1788 next_nomacro();
1789 is_vaargs = 0;
1790 if (varg == TOK_DOTS) {
1791 varg = TOK___VA_ARGS__;
1792 is_vaargs = 1;
1793 } else if (tok == TOK_DOTS && gnu_ext) {
1794 is_vaargs = 1;
1795 next_nomacro();
1797 if (varg < TOK_IDENT)
1798 error("badly punctuated parameter list");
1799 s = sym_push1(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
1800 *ps = s;
1801 ps = &s->next;
1802 if (tok != ',')
1803 break;
1804 next_nomacro();
1806 t = MACRO_FUNC;
1808 tok_str_new(&str);
1809 while (1) {
1810 skip_spaces();
1811 if (ch == '\n' || ch == -1)
1812 break;
1813 next_nomacro();
1814 tok_str_add2(&str, tok, &tokc);
1816 tok_str_add(&str, 0);
1817 #ifdef PP_DEBUG
1818 printf("define %s %d: ", get_tok_str(v, NULL), t);
1819 tok_print(str.str);
1820 #endif
1821 s = sym_push1(&define_stack, v, t, (int)str.str);
1822 s->next = first;
1825 void preprocess(void)
1827 int size, i, c, n;
1828 char buf[1024], *q, *p;
1829 char buf1[1024];
1830 BufferedFile *f;
1831 Sym *s;
1833 return_linefeed = 1; /* linefeed will be returned as a token */
1834 cinp();
1835 next_nomacro();
1836 redo:
1837 if (tok == TOK_DEFINE) {
1838 next_nomacro();
1839 parse_define();
1840 } else if (tok == TOK_UNDEF) {
1841 next_nomacro();
1842 s = sym_find1(&define_stack, tok);
1843 /* undefine symbol by putting an invalid name */
1844 if (s)
1845 sym_undef(&define_stack, s);
1846 } else if (tok == TOK_INCLUDE) {
1847 skip_spaces();
1848 if (ch == '<') {
1849 c = '>';
1850 goto read_name;
1851 } else if (ch == '\"') {
1852 c = ch;
1853 read_name:
1854 minp();
1855 q = buf;
1856 while (ch != c && ch != '\n' && ch != CH_EOF) {
1857 if ((q - buf) < sizeof(buf) - 1)
1858 *q++ = ch;
1859 minp();
1861 *q = '\0';
1862 /* eat all spaces and comments after include */
1863 /* XXX: slightly incorrect */
1864 while (ch1 != '\n' && ch1 != CH_EOF)
1865 inp();
1866 } else {
1867 /* computed #include : either we have only strings or
1868 we have anything enclosed in '<>' */
1869 next();
1870 buf[0] = '\0';
1871 if (tok == TOK_STR) {
1872 while (tok != TOK_LINEFEED) {
1873 if (tok != TOK_STR) {
1874 include_syntax:
1875 error("'#include' expects \"FILENAME\" or <FILENAME>");
1877 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
1878 next();
1880 c = '\"';
1881 } else {
1882 int len;
1883 while (tok != TOK_LINEFEED) {
1884 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
1885 next();
1887 len = strlen(buf);
1888 /* check syntax and remove '<>' */
1889 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
1890 goto include_syntax;
1891 memmove(buf, buf + 1, len - 2);
1892 buf[len - 2] = '\0';
1893 c = '>';
1897 if (include_stack_ptr >= include_stack + INCLUDE_STACK_SIZE)
1898 error("memory full");
1899 if (c == '\"') {
1900 /* first search in current dir if "header.h" */
1901 size = 0;
1902 p = strrchr(file->filename, '/');
1903 if (p)
1904 size = p + 1 - file->filename;
1905 if (size > sizeof(buf1) - 1)
1906 size = sizeof(buf1) - 1;
1907 memcpy(buf1, file->filename, size);
1908 buf1[size] = '\0';
1909 pstrcat(buf1, sizeof(buf1), buf);
1910 f = tcc_open(buf1);
1911 if (f)
1912 goto found;
1914 /* now search in all the include paths */
1915 n = nb_include_paths + nb_sysinclude_paths;
1916 for(i = 0; i < n; i++) {
1917 const char *path;
1918 if (i < nb_include_paths)
1919 path = include_paths[i];
1920 else
1921 path = sysinclude_paths[i - nb_include_paths];
1922 pstrcpy(buf1, sizeof(buf1), path);
1923 pstrcat(buf1, sizeof(buf1), "/");
1924 pstrcat(buf1, sizeof(buf1), buf);
1925 f = tcc_open(buf1);
1926 if (f)
1927 goto found;
1929 error("include file '%s' not found", buf);
1930 f = NULL;
1931 found:
1932 /* push current file in stack */
1933 /* XXX: fix current line init */
1934 *include_stack_ptr++ = file;
1935 file = f;
1936 /* add include file debug info */
1937 if (do_debug) {
1938 put_stabs(file->filename, N_BINCL, 0, 0, 0);
1940 ch = '\n';
1941 goto the_end;
1942 } else if (tok == TOK_IFNDEF) {
1943 c = 1;
1944 goto do_ifdef;
1945 } else if (tok == TOK_IF) {
1946 c = expr_preprocess();
1947 goto do_if;
1948 } else if (tok == TOK_IFDEF) {
1949 c = 0;
1950 do_ifdef:
1951 next_nomacro();
1952 c = (sym_find1(&define_stack, tok) != 0) ^ c;
1953 do_if:
1954 if (ifdef_stack_ptr >= ifdef_stack + IFDEF_STACK_SIZE)
1955 error("memory full");
1956 *ifdef_stack_ptr++ = c;
1957 goto test_skip;
1958 } else if (tok == TOK_ELSE) {
1959 if (ifdef_stack_ptr == ifdef_stack)
1960 error("#else without matching #if");
1961 if (ifdef_stack_ptr[-1] & 2)
1962 error("#else after #else");
1963 c = (ifdef_stack_ptr[-1] ^= 3);
1964 goto test_skip;
1965 } else if (tok == TOK_ELIF) {
1966 if (ifdef_stack_ptr == ifdef_stack)
1967 error("#elif without matching #if");
1968 c = ifdef_stack_ptr[-1];
1969 if (c > 1)
1970 error("#elif after #else");
1971 /* last #if/#elif expression was true: we skip */
1972 if (c == 1)
1973 goto skip;
1974 c = expr_preprocess();
1975 ifdef_stack_ptr[-1] = c;
1976 test_skip:
1977 if (!(c & 1)) {
1978 skip:
1979 preprocess_skip();
1980 goto redo;
1982 } else if (tok == TOK_ENDIF) {
1983 if (ifdef_stack_ptr == ifdef_stack)
1984 error("#endif without matching #if");
1985 ifdef_stack_ptr--;
1986 } else if (tok == TOK_LINE) {
1987 int line_num;
1988 next();
1989 if (tok != TOK_CINT)
1990 error("#line");
1991 line_num = tokc.i;
1992 next();
1993 if (tok != TOK_LINEFEED) {
1994 if (tok != TOK_STR)
1995 error("#line");
1996 pstrcpy(file->filename, sizeof(file->filename),
1997 (char *)tokc.cstr->data);
1999 /* NOTE: we do it there to avoid problems with linefeed */
2000 file->line_num = line_num;
2001 } else if (tok == TOK_ERROR) {
2002 error("#error");
2004 /* ignore other preprocess commands or #! for C scripts */
2005 while (tok != TOK_LINEFEED && tok != TOK_EOF)
2006 next_nomacro();
2007 the_end:
2008 return_linefeed = 0;
2011 /* read a number in base b */
2012 static int getn(int b)
2014 int n, t;
2015 n = 0;
2016 while (1) {
2017 if (ch >= 'a' && ch <= 'f')
2018 t = ch - 'a' + 10;
2019 else if (ch >= 'A' && ch <= 'F')
2020 t = ch - 'A' + 10;
2021 else if (isnum(ch))
2022 t = ch - '0';
2023 else
2024 break;
2025 if (t < 0 || t >= b)
2026 break;
2027 n = n * b + t;
2028 cinp();
2030 return n;
2033 /* read a character for string or char constant and eval escape codes */
2034 static int getq(void)
2036 int c;
2038 c = ch;
2039 minp();
2040 if (c == '\\') {
2041 if (isnum(ch)) {
2042 /* at most three octal digits */
2043 c = ch - '0';
2044 minp();
2045 if (isnum(ch)) {
2046 c = c * 8 + ch - '0';
2047 minp();
2048 if (isnum(ch)) {
2049 c = c * 8 + ch - '0';
2050 minp();
2053 return c;
2054 } else if (ch == 'x') {
2055 minp();
2056 return getn(16);
2057 } else {
2058 if (ch == 'a')
2059 c = '\a';
2060 else if (ch == 'b')
2061 c = '\b';
2062 else if (ch == 'f')
2063 c = '\f';
2064 else if (ch == 'n')
2065 c = '\n';
2066 else if (ch == 'r')
2067 c = '\r';
2068 else if (ch == 't')
2069 c = '\t';
2070 else if (ch == 'v')
2071 c = '\v';
2072 else if (ch == 'e' && gnu_ext)
2073 c = 27;
2074 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
2075 c = ch;
2076 else
2077 error("invalid escaped char");
2078 minp();
2081 return c;
2084 /* we use 64 bit numbers */
2085 #define BN_SIZE 2
2087 /* bn = (bn << shift) | or_val */
2088 void bn_lshift(unsigned int *bn, int shift, int or_val)
2090 int i;
2091 unsigned int v;
2092 for(i=0;i<BN_SIZE;i++) {
2093 v = bn[i];
2094 bn[i] = (v << shift) | or_val;
2095 or_val = v >> (32 - shift);
2099 void bn_zero(unsigned int *bn)
2101 int i;
2102 for(i=0;i<BN_SIZE;i++) {
2103 bn[i] = 0;
2107 void parse_number(void)
2109 int b, t, shift, frac_bits, s, exp_val;
2110 char *q;
2111 unsigned int bn[BN_SIZE];
2112 double d;
2114 /* number */
2115 q = token_buf;
2116 t = ch;
2117 cinp();
2118 *q++ = t;
2119 b = 10;
2120 if (t == '.') {
2121 /* special dot handling */
2122 if (ch >= '0' && ch <= '9') {
2123 goto float_frac_parse;
2124 } else if (ch == '.') {
2125 cinp();
2126 if (ch != '.')
2127 expect("'.'");
2128 cinp();
2129 tok = TOK_DOTS;
2130 } else {
2131 /* dots */
2132 tok = t;
2134 return;
2135 } else if (t == '0') {
2136 if (ch == 'x' || ch == 'X') {
2137 q--;
2138 cinp();
2139 b = 16;
2140 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2141 q--;
2142 cinp();
2143 b = 2;
2146 /* parse all digits. cannot check octal numbers at this stage
2147 because of floating point constants */
2148 while (1) {
2149 if (ch >= 'a' && ch <= 'f')
2150 t = ch - 'a' + 10;
2151 else if (ch >= 'A' && ch <= 'F')
2152 t = ch - 'A' + 10;
2153 else if (isnum(ch))
2154 t = ch - '0';
2155 else
2156 break;
2157 if (t >= b)
2158 break;
2159 if (q >= token_buf + STRING_MAX_SIZE) {
2160 num_too_long:
2161 error("number too long");
2163 *q++ = ch;
2164 cinp();
2166 if (ch == '.' ||
2167 ((ch == 'e' || ch == 'E') && b == 10) ||
2168 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2169 if (b != 10) {
2170 /* NOTE: strtox should support that for hexa numbers, but
2171 non ISOC99 libcs do not support it, so we prefer to do
2172 it by hand */
2173 /* hexadecimal or binary floats */
2174 /* XXX: handle overflows */
2175 *q = '\0';
2176 if (b == 16)
2177 shift = 4;
2178 else
2179 shift = 2;
2180 bn_zero(bn);
2181 q = token_buf;
2182 while (1) {
2183 t = *q++;
2184 if (t == '\0') {
2185 break;
2186 } else if (t >= 'a') {
2187 t = t - 'a' + 10;
2188 } else if (t >= 'A') {
2189 t = t - 'A' + 10;
2190 } else {
2191 t = t - '0';
2193 bn_lshift(bn, shift, t);
2195 frac_bits = 0;
2196 if (ch == '.') {
2197 cinp();
2198 while (1) {
2199 t = ch;
2200 if (t >= 'a' && t <= 'f') {
2201 t = t - 'a' + 10;
2202 } else if (t >= 'A' && t <= 'F') {
2203 t = t - 'A' + 10;
2204 } else if (t >= '0' && t <= '9') {
2205 t = t - '0';
2206 } else {
2207 break;
2209 if (t >= b)
2210 error("invalid digit");
2211 bn_lshift(bn, shift, t);
2212 frac_bits += shift;
2213 cinp();
2216 if (ch != 'p' && ch != 'P')
2217 error("exponent expected");
2218 cinp();
2219 s = 1;
2220 exp_val = 0;
2221 if (ch == '+') {
2222 cinp();
2223 } else if (ch == '-') {
2224 s = -1;
2225 cinp();
2227 if (ch < '0' || ch > '9')
2228 error("exponent digits expected");
2229 while (ch >= '0' && ch <= '9') {
2230 exp_val = exp_val * 10 + ch - '0';
2231 cinp();
2233 exp_val = exp_val * s;
2235 /* now we can generate the number */
2236 /* XXX: should patch directly float number */
2237 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
2238 d = ldexp(d, exp_val - frac_bits);
2239 t = toup(ch);
2240 if (t == 'F') {
2241 cinp();
2242 tok = TOK_CFLOAT;
2243 /* float : should handle overflow */
2244 tokc.f = (float)d;
2245 } else if (t == 'L') {
2246 cinp();
2247 tok = TOK_CLDOUBLE;
2248 /* XXX: not large enough */
2249 tokc.ld = (long double)d;
2250 } else {
2251 tok = TOK_CDOUBLE;
2252 tokc.d = d;
2254 } else {
2255 /* decimal floats */
2256 if (ch == '.') {
2257 if (q >= token_buf + STRING_MAX_SIZE)
2258 goto num_too_long;
2259 *q++ = ch;
2260 cinp();
2261 float_frac_parse:
2262 while (ch >= '0' && ch <= '9') {
2263 if (q >= token_buf + STRING_MAX_SIZE)
2264 goto num_too_long;
2265 *q++ = ch;
2266 cinp();
2269 if (ch == 'e' || ch == 'E') {
2270 if (q >= token_buf + STRING_MAX_SIZE)
2271 goto num_too_long;
2272 *q++ = ch;
2273 cinp();
2274 if (ch == '-' || ch == '+') {
2275 if (q >= token_buf + STRING_MAX_SIZE)
2276 goto num_too_long;
2277 *q++ = ch;
2278 cinp();
2280 if (ch < '0' || ch > '9')
2281 error("exponent digits expected");
2282 while (ch >= '0' && ch <= '9') {
2283 if (q >= token_buf + STRING_MAX_SIZE)
2284 goto num_too_long;
2285 *q++ = ch;
2286 cinp();
2289 *q = '\0';
2290 t = toup(ch);
2291 errno = 0;
2292 if (t == 'F') {
2293 cinp();
2294 tok = TOK_CFLOAT;
2295 tokc.f = strtof(token_buf, NULL);
2296 } else if (t == 'L') {
2297 cinp();
2298 tok = TOK_CLDOUBLE;
2299 tokc.ld = strtold(token_buf, NULL);
2300 } else {
2301 tok = TOK_CDOUBLE;
2302 tokc.d = strtod(token_buf, NULL);
2305 } else {
2306 unsigned long long n, n1;
2307 int lcount;
2309 /* integer number */
2310 *q = '\0';
2311 q = token_buf;
2312 if (b == 10 && *q == '0') {
2313 b = 8;
2314 q++;
2316 n = 0;
2317 while(1) {
2318 t = *q++;
2319 /* no need for checks except for base 10 / 8 errors */
2320 if (t == '\0') {
2321 break;
2322 } else if (t >= 'a') {
2323 t = t - 'a' + 10;
2324 } else if (t >= 'A') {
2325 t = t - 'A' + 10;
2326 } else {
2327 t = t - '0';
2328 if (t >= b)
2329 error("invalid digit");
2331 n1 = n;
2332 n = n * b + t;
2333 /* detect overflow */
2334 if (n < n1)
2335 error("integer constant overflow");
2338 /* XXX: not exactly ANSI compliant */
2339 if ((n & 0xffffffff00000000LL) != 0) {
2340 if ((n >> 63) != 0)
2341 tok = TOK_CULLONG;
2342 else
2343 tok = TOK_CLLONG;
2344 } else if (n > 0x7fffffff) {
2345 tok = TOK_CUINT;
2346 } else {
2347 tok = TOK_CINT;
2349 lcount = 0;
2350 for(;;) {
2351 t = toup(ch);
2352 if (t == 'L') {
2353 if (lcount >= 2)
2354 error("three 'l' in integer constant");
2355 lcount++;
2356 if (lcount == 2) {
2357 if (tok == TOK_CINT)
2358 tok = TOK_CLLONG;
2359 else if (tok == TOK_CUINT)
2360 tok = TOK_CULLONG;
2362 cinp();
2363 } else if (t == 'U') {
2364 if (tok == TOK_CINT)
2365 tok = TOK_CUINT;
2366 else if (tok == TOK_CLLONG)
2367 tok = TOK_CULLONG;
2368 cinp();
2369 } else {
2370 break;
2373 if (tok == TOK_CINT || tok == TOK_CUINT)
2374 tokc.ui = n;
2375 else
2376 tokc.ull = n;
2381 /* return next token without macro substitution */
2382 void next_nomacro1(void)
2384 int b;
2385 char *q;
2386 TokenSym *ts;
2388 /* skip spaces */
2389 while(1) {
2390 while (ch == '\n') {
2391 /* during preprocessor parsing, '\n' is a token */
2392 if (return_linefeed) {
2393 tok = TOK_LINEFEED;
2394 return;
2396 cinp();
2397 while (ch == ' ' || ch == '\t')
2398 cinp();
2399 if (ch == '#') {
2400 /* preprocessor command if # at start of line after
2401 spaces */
2402 preprocess();
2405 if (ch != ' ' && ch != '\t' && ch != '\f')
2406 break;
2407 cinp();
2409 if (isid(ch)) {
2410 q = token_buf;
2411 *q++ = ch;
2412 cinp();
2413 if (q[-1] == 'L') {
2414 if (ch == '\'') {
2415 tok = TOK_LCHAR;
2416 goto char_const;
2418 if (ch == '\"') {
2419 tok = TOK_LSTR;
2420 goto str_const;
2423 while (isid(ch) || isnum(ch)) {
2424 if (q >= token_buf + STRING_MAX_SIZE)
2425 error("ident too long");
2426 *q++ = ch;
2427 cinp();
2429 *q = '\0';
2430 ts = tok_alloc(token_buf, q - token_buf);
2431 tok = ts->tok;
2432 } else if (isnum(ch) || ch == '.') {
2433 parse_number();
2434 } else if (ch == '\'') {
2435 tok = TOK_CCHAR;
2436 char_const:
2437 minp();
2438 b = getq();
2439 /* this cast is needed if >= 128 */
2440 if (tok == TOK_CCHAR)
2441 b = (char)b;
2442 tokc.i = b;
2443 if (ch != '\'')
2444 expect("\'");
2445 minp();
2446 } else if (ch == '\"') {
2447 tok = TOK_STR;
2448 str_const:
2449 minp();
2450 cstr_reset(&tokcstr);
2451 while (ch != '\"') {
2452 b = getq();
2453 if (ch == CH_EOF)
2454 error("unterminated string");
2455 if (tok == TOK_STR)
2456 cstr_ccat(&tokcstr, b);
2457 else
2458 cstr_wccat(&tokcstr, b);
2460 if (tok == TOK_STR)
2461 cstr_ccat(&tokcstr, '\0');
2462 else
2463 cstr_wccat(&tokcstr, '\0');
2464 tokc.cstr = &tokcstr;
2465 minp();
2466 } else {
2467 q = tok_two_chars;
2468 /* two chars */
2469 tok = ch;
2470 cinp();
2471 while (*q) {
2472 if (*q == tok && q[1] == ch) {
2473 cinp();
2474 tok = q[2] & 0xff;
2475 /* three chars tests */
2476 if (tok == TOK_SHL || tok == TOK_SAR) {
2477 if (ch == '=') {
2478 tok = tok | 0x80;
2479 cinp();
2481 } else if (tok == TOK_DOTS) {
2482 if (ch != '.')
2483 error("parse error");
2484 cinp();
2486 return;
2488 q = q + 3;
2490 /* single char substitutions */
2491 if (tok == '<')
2492 tok = TOK_LT;
2493 else if (tok == '>')
2494 tok = TOK_GT;
2498 /* return next token without macro substitution. Can read input from
2499 macro_ptr buffer */
2500 void next_nomacro()
2502 if (macro_ptr) {
2503 redo:
2504 tok = *macro_ptr;
2505 if (tok) {
2506 tok = tok_get(&macro_ptr, &tokc);
2507 if (tok == TOK_LINENUM) {
2508 file->line_num = tokc.i;
2509 goto redo;
2512 } else {
2513 next_nomacro1();
2517 /* substitute args in macro_str and return allocated string */
2518 int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
2520 int *st, last_tok, t, notfirst;
2521 Sym *s;
2522 CValue cval;
2523 TokenString str;
2524 CString cstr;
2526 tok_str_new(&str);
2527 last_tok = 0;
2528 while(1) {
2529 t = tok_get(&macro_str, &cval);
2530 if (!t)
2531 break;
2532 if (t == '#') {
2533 /* stringize */
2534 t = tok_get(&macro_str, &cval);
2535 if (!t)
2536 break;
2537 s = sym_find2(args, t);
2538 if (s) {
2539 cstr_new(&cstr);
2540 st = (int *)s->c;
2541 notfirst = 0;
2542 while (*st) {
2543 if (notfirst)
2544 cstr_ccat(&cstr, ' ');
2545 t = tok_get(&st, &cval);
2546 cstr_cat(&cstr, get_tok_str(t, &cval));
2547 notfirst = 1;
2549 cstr_ccat(&cstr, '\0');
2550 #ifdef PP_DEBUG
2551 printf("stringize: %s\n", (char *)cstr.data);
2552 #endif
2553 /* add string */
2554 cval.cstr = &cstr;
2555 tok_str_add2(&str, TOK_STR, &cval);
2556 cstr_free(&cstr);
2557 } else {
2558 tok_str_add2(&str, t, &cval);
2560 } else if (t >= TOK_IDENT) {
2561 s = sym_find2(args, t);
2562 if (s) {
2563 st = (int *)s->c;
2564 /* if '##' is present before or after, no arg substitution */
2565 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
2566 /* special case for var arg macros : ## eats the
2567 ',' if empty VA_ARGS riable. */
2568 /* XXX: test of the ',' is not 100%
2569 reliable. should fix it to avoid security
2570 problems */
2571 if (gnu_ext && s->t && *st == 0 &&
2572 last_tok == TOK_TWOSHARPS &&
2573 str.len >= 2 && str.str[str.len - 2] == ',') {
2574 /* suppress ',' '##' */
2575 str.len -= 2;
2576 } else {
2577 int t1;
2578 for(;;) {
2579 t1 = tok_get(&st, &cval);
2580 if (!t1)
2581 break;
2582 tok_str_add2(&str, t1, &cval);
2585 } else {
2586 macro_subst(&str, nested_list, st);
2588 } else {
2589 tok_str_add(&str, t);
2591 } else {
2592 tok_str_add2(&str, t, &cval);
2594 last_tok = t;
2596 tok_str_add(&str, 0);
2597 return str.str;
2600 /* handle the '##' operator */
2601 int *macro_twosharps(int *macro_str)
2603 TokenSym *ts;
2604 int *macro_ptr1;
2605 int t;
2606 char *p;
2607 CValue cval;
2608 TokenString macro_str1;
2610 tok_str_new(&macro_str1);
2611 tok = 0;
2612 while (1) {
2613 next_nomacro();
2614 if (tok == 0)
2615 break;
2616 while (*macro_ptr == TOK_TWOSHARPS) {
2617 macro_ptr++;
2618 macro_ptr1 = macro_ptr;
2619 t = *macro_ptr;
2620 if (t) {
2621 t = tok_get(&macro_ptr, &cval);
2622 /* XXX: we handle only most common cases:
2623 ident + ident or ident + number */
2624 if (tok >= TOK_IDENT &&
2625 (t >= TOK_IDENT || t == TOK_CINT)) {
2626 p = get_tok_str(tok, &tokc);
2627 pstrcpy(token_buf, sizeof(token_buf), p);
2628 p = get_tok_str(t, &cval);
2629 pstrcat(token_buf, sizeof(token_buf), p);
2630 ts = tok_alloc(token_buf, 0);
2631 tok = ts->tok; /* modify current token */
2632 } else {
2633 /* cannot merge tokens: skip '##' */
2634 macro_ptr = macro_ptr1;
2635 break;
2639 tok_str_add2(&macro_str1, tok, &tokc);
2641 tok_str_add(&macro_str1, 0);
2642 return macro_str1.str;
2645 /* do macro substitution of macro_str and add result to
2646 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2647 substituted. 'nested_list' is the list of all macros we got inside
2648 to avoid recursing. */
2649 void macro_subst(TokenString *tok_str,
2650 Sym **nested_list, int *macro_str)
2652 Sym *s, *args, *sa, *sa1;
2653 int parlevel, *mstr, t, *saved_macro_ptr;
2654 int mstr_allocated, *macro_str1;
2655 CString cstr;
2656 CValue cval;
2657 TokenString str;
2658 char *cstrval;
2660 saved_macro_ptr = macro_ptr;
2661 macro_ptr = macro_str;
2662 macro_str1 = NULL;
2663 if (macro_str) {
2664 /* first scan for '##' operator handling */
2665 macro_str1 = macro_twosharps(macro_str);
2666 macro_ptr = macro_str1;
2669 while (1) {
2670 next_nomacro();
2671 if (tok == 0)
2672 break;
2673 /* special macros */
2674 if (tok == TOK___LINE__) {
2675 cval.i = file->line_num;
2676 tok_str_add2(tok_str, TOK_CINT, &cval);
2677 } else if (tok == TOK___FILE__) {
2678 cstrval = file->filename;
2679 goto add_cstr;
2680 tok_str_add2(tok_str, TOK_STR, &cval);
2681 } else if (tok == TOK___DATE__) {
2682 cstrval = "Jan 1 1970";
2683 goto add_cstr;
2684 } else if (tok == TOK___TIME__) {
2685 cstrval = "00:00:00";
2686 add_cstr:
2687 cstr_new(&cstr);
2688 cstr_cat(&cstr, cstrval);
2689 cstr_ccat(&cstr, '\0');
2690 cval.cstr = &cstr;
2691 tok_str_add2(tok_str, TOK_STR, &cval);
2692 cstr_free(&cstr);
2693 } else if ((s = sym_find1(&define_stack, tok)) != NULL) {
2694 /* if symbol is a macro, prepare substitution */
2695 /* if nested substitution, do nothing */
2696 if (sym_find2(*nested_list, tok))
2697 goto no_subst;
2698 mstr = (int *)s->c;
2699 mstr_allocated = 0;
2700 if (s->t == MACRO_FUNC) {
2701 /* NOTE: we do not use next_nomacro to avoid eating the
2702 next token. XXX: find better solution */
2703 if (macro_ptr) {
2704 t = *macro_ptr;
2705 } else {
2706 while (ch == ' ' || ch == '\t' || ch == '\n')
2707 cinp();
2708 t = ch;
2710 if (t != '(') /* no macro subst */
2711 goto no_subst;
2713 /* argument macro */
2714 next_nomacro();
2715 next_nomacro();
2716 args = NULL;
2717 sa = s->next;
2718 /* NOTE: empty args are allowed, except if no args */
2719 for(;;) {
2720 /* handle '()' case */
2721 if (!args && tok == ')')
2722 break;
2723 if (!sa)
2724 error("macro '%s' used with too many args",
2725 get_tok_str(s->v, 0));
2726 tok_str_new(&str);
2727 parlevel = 0;
2728 /* NOTE: non zero sa->t indicates VA_ARGS */
2729 while ((parlevel > 0 ||
2730 (tok != ')' &&
2731 (tok != ',' || sa->t))) &&
2732 tok != -1) {
2733 if (tok == '(')
2734 parlevel++;
2735 else if (tok == ')')
2736 parlevel--;
2737 tok_str_add2(&str, tok, &tokc);
2738 next_nomacro();
2740 tok_str_add(&str, 0);
2741 sym_push2(&args, sa->v & ~SYM_FIELD, sa->t, (int)str.str);
2742 sa = sa->next;
2743 if (tok == ')') {
2744 /* special case for gcc var args: add an empty
2745 var arg argument if it is omitted */
2746 if (sa && sa->t && gnu_ext)
2747 continue;
2748 else
2749 break;
2751 if (tok != ',')
2752 expect(",");
2753 next_nomacro();
2755 if (sa) {
2756 error("macro '%s' used with too few args",
2757 get_tok_str(s->v, 0));
2760 /* now subst each arg */
2761 mstr = macro_arg_subst(nested_list, mstr, args);
2762 /* free memory */
2763 sa = args;
2764 while (sa) {
2765 sa1 = sa->prev;
2766 tok_str_free((int *)sa->c);
2767 tcc_free(sa);
2768 sa = sa1;
2770 mstr_allocated = 1;
2772 sym_push2(nested_list, s->v, 0, 0);
2773 macro_subst(tok_str, nested_list, mstr);
2774 /* pop nested defined symbol */
2775 sa1 = *nested_list;
2776 *nested_list = sa1->prev;
2777 tcc_free(sa1);
2778 if (mstr_allocated)
2779 tok_str_free(mstr);
2780 } else {
2781 no_subst:
2782 /* no need to add if reading input stream */
2783 if (!macro_str)
2784 return;
2785 tok_str_add2(tok_str, tok, &tokc);
2787 /* only replace one macro while parsing input stream */
2788 if (!macro_str)
2789 return;
2791 macro_ptr = saved_macro_ptr;
2792 if (macro_str1)
2793 tok_str_free(macro_str1);
2796 /* return next token with macro substitution */
2797 void next(void)
2799 Sym *nested_list;
2800 TokenString str;
2802 /* special 'ungettok' case for label parsing */
2803 if (tok1) {
2804 tok = tok1;
2805 tokc = tok1c;
2806 tok1 = 0;
2807 } else {
2808 redo:
2809 if (!macro_ptr) {
2810 /* if not reading from macro substituted string, then try
2811 to substitute */
2812 /* XXX: optimize non macro case */
2813 tok_str_new(&str);
2814 nested_list = NULL;
2815 macro_subst(&str, &nested_list, NULL);
2816 if (str.str) {
2817 tok_str_add(&str, 0);
2818 macro_ptr = str.str;
2819 macro_ptr_allocated = str.str;
2820 goto redo;
2822 if (tok == 0)
2823 goto redo;
2824 } else {
2825 next_nomacro();
2826 if (tok == 0) {
2827 /* end of macro string: free it */
2828 tok_str_free(macro_ptr_allocated);
2829 macro_ptr = NULL;
2830 goto redo;
2834 #if defined(DEBUG)
2835 printf("token = %s\n", get_tok_str(tok, &tokc));
2836 #endif
2839 void swap(int *p, int *q)
2841 int t;
2842 t = *p;
2843 *p = *q;
2844 *q = t;
2847 void vsetc(int t, int r, CValue *vc)
2849 if (vtop >= vstack + VSTACK_SIZE)
2850 error("memory full");
2851 /* cannot let cpu flags if other instruction are generated */
2852 /* XXX: VT_JMP test too ? */
2853 if ((vtop->r & VT_VALMASK) == VT_CMP)
2854 gv(RC_INT);
2855 vtop++;
2856 vtop->t = t;
2857 vtop->r = r;
2858 vtop->r2 = VT_CONST;
2859 vtop->c = *vc;
2862 /* push integer constant */
2863 void vpushi(int v)
2865 CValue cval;
2866 cval.i = v;
2867 vsetc(VT_INT, VT_CONST, &cval);
2870 /* Return a static symbol pointing to a section */
2871 static Sym *get_sym_ref(int t, Section *sec,
2872 unsigned long offset, unsigned long size)
2874 int v;
2875 Sym *sym;
2877 v = anon_sym++;
2878 sym = sym_push1(&global_stack, v, t | VT_STATIC, 0);
2879 sym->r = VT_CONST | VT_SYM;
2880 put_extern_sym(sym, sec, offset, size);
2881 return sym;
2884 /* push a reference to a section offset by adding a dummy symbol */
2885 void vpush_ref(int t, Section *sec, unsigned long offset, unsigned long size)
2887 CValue cval;
2889 cval.sym = get_sym_ref(t, sec, offset, size);
2890 vsetc(t, VT_CONST | VT_SYM, &cval);
2893 /* push a reference to symbol v */
2894 void vpush_sym(int t, int v)
2896 Sym *sym;
2897 CValue cval;
2899 sym = external_sym(v, t, 0);
2900 cval.sym = sym;
2901 vsetc(t, VT_CONST | VT_SYM, &cval);
2904 void vset(int t, int r, int v)
2906 CValue cval;
2908 cval.i = v;
2909 vsetc(t, r, &cval);
2912 void vswap(void)
2914 SValue tmp;
2916 tmp = vtop[0];
2917 vtop[0] = vtop[-1];
2918 vtop[-1] = tmp;
2921 void vpushv(SValue *v)
2923 if (vtop >= vstack + VSTACK_SIZE)
2924 error("memory full");
2925 vtop++;
2926 *vtop = *v;
2929 void vdup(void)
2931 vpushv(vtop);
2934 /* save r to the memory stack, and mark it as being free */
2935 void save_reg(int r)
2937 int l, saved, t, size, align;
2938 SValue *p, sv;
2940 /* modify all stack values */
2941 saved = 0;
2942 l = 0;
2943 for(p=vstack;p<=vtop;p++) {
2944 if ((p->r & VT_VALMASK) == r ||
2945 (p->r2 & VT_VALMASK) == r) {
2946 /* must save value on stack if not already done */
2947 if (!saved) {
2948 /* store register in the stack */
2949 t = p->t;
2950 if ((p->r & VT_LVAL) ||
2951 (!is_float(t) && (t & VT_BTYPE) != VT_LLONG))
2952 t = VT_INT;
2953 size = type_size(t, &align);
2954 loc = (loc - size) & -align;
2955 sv.t = t;
2956 sv.r = VT_LOCAL | VT_LVAL;
2957 sv.c.ul = loc;
2958 store(r, &sv);
2959 #ifdef TCC_TARGET_I386
2960 /* x86 specific: need to pop fp register ST0 if saved */
2961 if (r == REG_ST0) {
2962 o(0xd9dd); /* fstp %st(1) */
2964 #endif
2965 /* special long long case */
2966 if ((t & VT_BTYPE) == VT_LLONG) {
2967 sv.c.ul += 4;
2968 store(p->r2, &sv);
2970 l = loc;
2971 saved = 1;
2973 /* mark that stack entry as being saved on the stack */
2974 if (p->r & VT_LVAL) {
2975 /* also suppress the bounded flag because the
2976 relocation address of the function was stored in
2977 p->c.ul */
2978 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
2979 } else {
2980 p->r = lvalue_type(p->t) | VT_LOCAL;
2982 p->r2 = VT_CONST;
2983 p->c.ul = l;
2988 /* find a free register of class 'rc'. If none, save one register */
2989 int get_reg(int rc)
2991 int r;
2992 SValue *p;
2994 /* find a free register */
2995 for(r=0;r<NB_REGS;r++) {
2996 if (reg_classes[r] & rc) {
2997 for(p=vstack;p<=vtop;p++) {
2998 if ((p->r & VT_VALMASK) == r ||
2999 (p->r2 & VT_VALMASK) == r)
3000 goto notfound;
3002 return r;
3004 notfound: ;
3007 /* no register left : free the first one on the stack (VERY
3008 IMPORTANT to start from the bottom to ensure that we don't
3009 spill registers used in gen_opi()) */
3010 for(p=vstack;p<=vtop;p++) {
3011 r = p->r & VT_VALMASK;
3012 if (r < VT_CONST && (reg_classes[r] & rc)) {
3013 save_reg(r);
3014 break;
3017 return r;
3020 /* save registers up to (vtop - n) stack entry */
3021 void save_regs(int n)
3023 int r;
3024 SValue *p, *p1;
3025 p1 = vtop - n;
3026 for(p = vstack;p <= p1; p++) {
3027 r = p->r & VT_VALMASK;
3028 if (r < VT_CONST) {
3029 save_reg(r);
3034 /* move register 's' to 'r', and flush previous value of r to memory
3035 if needed */
3036 void move_reg(int r, int s)
3038 SValue sv;
3040 if (r != s) {
3041 save_reg(r);
3042 sv.t = VT_INT;
3043 sv.r = s;
3044 sv.c.ul = 0;
3045 load(r, &sv);
3049 /* get address of vtop (vtop MUST BE an lvalue) */
3050 void gaddrof(void)
3052 vtop->r &= ~VT_LVAL;
3053 /* tricky: if saved lvalue, then we can go back to lvalue */
3054 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
3055 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
3058 #ifdef CONFIG_TCC_BCHECK
3059 /* generate lvalue bound code */
3060 void gbound(void)
3062 int lval_type, t1;
3064 vtop->r &= ~VT_MUSTBOUND;
3065 /* if lvalue, then use checking code before dereferencing */
3066 if (vtop->r & VT_LVAL) {
3067 /* if not VT_BOUNDED value, then make one */
3068 if (!(vtop->r & VT_BOUNDED)) {
3069 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
3070 /* must save type because we must set it to int to get pointer */
3071 t1 = vtop->t;
3072 vtop->t = VT_INT;
3073 gaddrof();
3074 vpushi(0);
3075 gen_bounded_ptr_add();
3076 vtop->r |= lval_type;
3077 vtop->t = t1;
3079 /* then check for dereferencing */
3080 gen_bounded_ptr_deref();
3083 #endif
3085 /* store vtop a register belonging to class 'rc'. lvalues are
3086 converted to values. Cannot be used if cannot be converted to
3087 register value (such as structures). */
3088 int gv(int rc)
3090 int r, r2, rc2, bit_pos, bit_size, size, align, i;
3091 unsigned long long ll;
3093 /* NOTE: get_reg can modify vstack[] */
3094 if (vtop->t & VT_BITFIELD) {
3095 bit_pos = (vtop->t >> VT_STRUCT_SHIFT) & 0x3f;
3096 bit_size = (vtop->t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
3097 /* remove bit field info to avoid loops */
3098 vtop->t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
3099 /* generate shifts */
3100 vpushi(32 - (bit_pos + bit_size));
3101 gen_op(TOK_SHL);
3102 vpushi(32 - bit_size);
3103 /* NOTE: transformed to SHR if unsigned */
3104 gen_op(TOK_SAR);
3105 r = gv(rc);
3106 } else {
3107 if (is_float(vtop->t) &&
3108 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3109 Sym *sym;
3110 int *ptr;
3111 unsigned long offset;
3113 /* XXX: unify with initializers handling ? */
3114 /* CPUs usually cannot use float constants, so we store them
3115 generically in data segment */
3116 size = type_size(vtop->t, &align);
3117 offset = (data_section->data_offset + align - 1) & -align;
3118 data_section->data_offset = offset;
3119 /* XXX: not portable yet */
3120 ptr = section_ptr_add(data_section, size);
3121 size = size >> 2;
3122 for(i=0;i<size;i++)
3123 ptr[i] = vtop->c.tab[i];
3124 sym = get_sym_ref(vtop->t, data_section, offset, size << 2);
3125 vtop->r |= VT_LVAL | VT_SYM;
3126 vtop->c.sym = sym;
3128 #ifdef CONFIG_TCC_BCHECK
3129 if (vtop->r & VT_MUSTBOUND)
3130 gbound();
3131 #endif
3133 r = vtop->r & VT_VALMASK;
3134 /* need to reload if:
3135 - constant
3136 - lvalue (need to dereference pointer)
3137 - already a register, but not in the right class */
3138 if (r >= VT_CONST ||
3139 (vtop->r & VT_LVAL) ||
3140 !(reg_classes[r] & rc) ||
3141 ((vtop->t & VT_BTYPE) == VT_LLONG &&
3142 !(reg_classes[vtop->r2] & rc))) {
3143 r = get_reg(rc);
3144 if ((vtop->t & VT_BTYPE) == VT_LLONG) {
3145 /* two register type load : expand to two words
3146 temporarily */
3147 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3148 /* load constant */
3149 ll = vtop->c.ull;
3150 vtop->c.ui = ll; /* first word */
3151 load(r, vtop);
3152 vtop->r = r; /* save register value */
3153 vpushi(ll >> 32); /* second word */
3154 } else if (r >= VT_CONST ||
3155 (vtop->r & VT_LVAL)) {
3156 /* load from memory */
3157 load(r, vtop);
3158 vdup();
3159 vtop[-1].r = r; /* save register value */
3160 /* increment pointer to get second word */
3161 vtop->t = VT_INT;
3162 gaddrof();
3163 vpushi(4);
3164 gen_op('+');
3165 vtop->r |= VT_LVAL;
3166 } else {
3167 /* move registers */
3168 load(r, vtop);
3169 vdup();
3170 vtop[-1].r = r; /* save register value */
3171 vtop->r = vtop[-1].r2;
3173 /* allocate second register */
3174 rc2 = RC_INT;
3175 if (rc == RC_IRET)
3176 rc2 = RC_LRET;
3177 r2 = get_reg(rc2);
3178 load(r2, vtop);
3179 vpop();
3180 /* write second register */
3181 vtop->r2 = r2;
3182 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->t)) {
3183 int t1, t;
3184 /* lvalue of scalar type : need to use lvalue type
3185 because of possible cast */
3186 t = vtop->t;
3187 t1 = t;
3188 /* compute memory access type */
3189 if (vtop->r & VT_LVAL_BYTE)
3190 t = VT_BYTE;
3191 else if (vtop->r & VT_LVAL_SHORT)
3192 t = VT_SHORT;
3193 if (vtop->r & VT_LVAL_UNSIGNED)
3194 t |= VT_UNSIGNED;
3195 vtop->t = t;
3196 load(r, vtop);
3197 /* restore wanted type */
3198 vtop->t = t1;
3199 } else {
3200 /* one register type load */
3201 load(r, vtop);
3204 vtop->r = r;
3206 return r;
3209 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3210 void gv2(int rc1, int rc2)
3212 /* generate more generic register first */
3213 if (rc1 <= rc2) {
3214 vswap();
3215 gv(rc1);
3216 vswap();
3217 gv(rc2);
3218 /* test if reload is needed for first register */
3219 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
3220 vswap();
3221 gv(rc1);
3222 vswap();
3224 } else {
3225 gv(rc2);
3226 vswap();
3227 gv(rc1);
3228 vswap();
3229 /* test if reload is needed for first register */
3230 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
3231 gv(rc2);
3236 /* expand long long on stack in two int registers */
3237 void lexpand(void)
3239 int u;
3241 u = vtop->t & VT_UNSIGNED;
3242 gv(RC_INT);
3243 vdup();
3244 vtop[0].r = vtop[-1].r2;
3245 vtop[0].r2 = VT_CONST;
3246 vtop[-1].r2 = VT_CONST;
3247 vtop[0].t = VT_INT | u;
3248 vtop[-1].t = VT_INT | u;
3251 /* build a long long from two ints */
3252 void lbuild(int t)
3254 gv2(RC_INT, RC_INT);
3255 vtop[-1].r2 = vtop[0].r;
3256 vtop[-1].t = t;
3257 vpop();
3260 /* rotate n first stack elements to the bottom */
3261 void vrotb(int n)
3263 int i;
3264 SValue tmp;
3266 tmp = vtop[-n + 1];
3267 for(i=-n+1;i!=0;i++)
3268 vtop[i] = vtop[i+1];
3269 vtop[0] = tmp;
3272 /* pop stack value */
3273 void vpop(void)
3275 int v;
3276 v = vtop->r & VT_VALMASK;
3277 #ifdef TCC_TARGET_I386
3278 /* for x86, we need to pop the FP stack */
3279 if (v == REG_ST0) {
3280 o(0xd9dd); /* fstp %st(1) */
3281 } else
3282 #endif
3283 if (v == VT_JMP || v == VT_JMPI) {
3284 /* need to put correct jump if && or || without test */
3285 gsym(vtop->c.ul);
3287 vtop--;
3290 /* convert stack entry to register and duplicate its value in another
3291 register */
3292 void gv_dup(void)
3294 int rc, t, r, r1;
3295 SValue sv;
3297 t = vtop->t;
3298 if ((t & VT_BTYPE) == VT_LLONG) {
3299 lexpand();
3300 gv_dup();
3301 vswap();
3302 vrotb(3);
3303 gv_dup();
3304 vrotb(4);
3305 /* stack: H L L1 H1 */
3306 lbuild(t);
3307 vrotb(3);
3308 vrotb(3);
3309 vswap();
3310 lbuild(t);
3311 vswap();
3312 } else {
3313 /* duplicate value */
3314 rc = RC_INT;
3315 sv.t = VT_INT;
3316 if (is_float(t)) {
3317 rc = RC_FLOAT;
3318 sv.t = t;
3320 r = gv(rc);
3321 r1 = get_reg(rc);
3322 sv.r = r;
3323 sv.c.ul = 0;
3324 load(r1, &sv); /* move r to r1 */
3325 vdup();
3326 /* duplicates value */
3327 vtop->r = r1;
3331 /* generate CPU independent (unsigned) long long operations */
3332 void gen_opl(int op)
3334 int t, a, b, op1, c, i;
3335 int func;
3336 GFuncContext gf;
3337 SValue tmp;
3339 switch(op) {
3340 case '/':
3341 case TOK_PDIV:
3342 func = TOK___divdi3;
3343 goto gen_func;
3344 case TOK_UDIV:
3345 func = TOK___udivdi3;
3346 goto gen_func;
3347 case '%':
3348 func = TOK___moddi3;
3349 goto gen_func;
3350 case TOK_UMOD:
3351 func = TOK___umoddi3;
3352 gen_func:
3353 /* call generic long long function */
3354 gfunc_start(&gf, FUNC_CDECL);
3355 gfunc_param(&gf);
3356 gfunc_param(&gf);
3357 vpush_sym(func_old_type, func);
3358 gfunc_call(&gf);
3359 vpushi(0);
3360 vtop->r = REG_IRET;
3361 vtop->r2 = REG_LRET;
3362 break;
3363 case '^':
3364 case '&':
3365 case '|':
3366 case '*':
3367 case '+':
3368 case '-':
3369 t = vtop->t;
3370 vswap();
3371 lexpand();
3372 vrotb(3);
3373 lexpand();
3374 /* stack: L1 H1 L2 H2 */
3375 tmp = vtop[0];
3376 vtop[0] = vtop[-3];
3377 vtop[-3] = tmp;
3378 tmp = vtop[-2];
3379 vtop[-2] = vtop[-3];
3380 vtop[-3] = tmp;
3381 vswap();
3382 /* stack: H1 H2 L1 L2 */
3383 if (op == '*') {
3384 vpushv(vtop - 1);
3385 vpushv(vtop - 1);
3386 gen_op(TOK_UMULL);
3387 lexpand();
3388 /* stack: H1 H2 L1 L2 ML MH */
3389 for(i=0;i<4;i++)
3390 vrotb(6);
3391 /* stack: ML MH H1 H2 L1 L2 */
3392 tmp = vtop[0];
3393 vtop[0] = vtop[-2];
3394 vtop[-2] = tmp;
3395 /* stack: ML MH H1 L2 H2 L1 */
3396 gen_op('*');
3397 vrotb(3);
3398 vrotb(3);
3399 gen_op('*');
3400 /* stack: ML MH M1 M2 */
3401 gen_op('+');
3402 gen_op('+');
3403 } else if (op == '+' || op == '-') {
3404 /* XXX: add non carry method too (for MIPS or alpha) */
3405 if (op == '+')
3406 op1 = TOK_ADDC1;
3407 else
3408 op1 = TOK_SUBC1;
3409 gen_op(op1);
3410 /* stack: H1 H2 (L1 op L2) */
3411 vrotb(3);
3412 vrotb(3);
3413 gen_op(op1 + 1); /* TOK_xxxC2 */
3414 } else {
3415 gen_op(op);
3416 /* stack: H1 H2 (L1 op L2) */
3417 vrotb(3);
3418 vrotb(3);
3419 /* stack: (L1 op L2) H1 H2 */
3420 gen_op(op);
3421 /* stack: (L1 op L2) (H1 op H2) */
3423 /* stack: L H */
3424 lbuild(t);
3425 break;
3426 case TOK_SAR:
3427 case TOK_SHR:
3428 case TOK_SHL:
3429 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3430 t = vtop[-1].t;
3431 vswap();
3432 lexpand();
3433 vrotb(3);
3434 /* stack: L H shift */
3435 c = (int)vtop->c.i;
3436 /* constant: simpler */
3437 /* NOTE: all comments are for SHL. the other cases are
3438 done by swaping words */
3439 vpop();
3440 if (op != TOK_SHL)
3441 vswap();
3442 if (c >= 32) {
3443 /* stack: L H */
3444 vpop();
3445 if (c > 32) {
3446 vpushi(c - 32);
3447 gen_op(op);
3449 if (op != TOK_SAR) {
3450 vpushi(0);
3451 } else {
3452 gv_dup();
3453 vpushi(31);
3454 gen_op(TOK_SAR);
3456 vswap();
3457 } else {
3458 vswap();
3459 gv_dup();
3460 /* stack: H L L */
3461 vpushi(c);
3462 gen_op(op);
3463 vswap();
3464 vpushi(32 - c);
3465 if (op == TOK_SHL)
3466 gen_op(TOK_SHR);
3467 else
3468 gen_op(TOK_SHL);
3469 vrotb(3);
3470 /* stack: L L H */
3471 vpushi(c);
3472 gen_op(op);
3473 gen_op('|');
3475 if (op != TOK_SHL)
3476 vswap();
3477 lbuild(t);
3478 } else {
3479 /* XXX: should provide a faster fallback on x86 ? */
3480 switch(op) {
3481 case TOK_SAR:
3482 func = TOK___sardi3;
3483 goto gen_func;
3484 case TOK_SHR:
3485 func = TOK___shrdi3;
3486 goto gen_func;
3487 case TOK_SHL:
3488 func = TOK___shldi3;
3489 goto gen_func;
3492 break;
3493 default:
3494 /* compare operations */
3495 t = vtop->t;
3496 vswap();
3497 lexpand();
3498 vrotb(3);
3499 lexpand();
3500 /* stack: L1 H1 L2 H2 */
3501 tmp = vtop[-1];
3502 vtop[-1] = vtop[-2];
3503 vtop[-2] = tmp;
3504 /* stack: L1 L2 H1 H2 */
3505 /* compare high */
3506 op1 = op;
3507 /* when values are equal, we need to compare low words. since
3508 the jump is inverted, we invert the test too. */
3509 if (op1 == TOK_LT)
3510 op1 = TOK_LE;
3511 else if (op1 == TOK_GT)
3512 op1 = TOK_GE;
3513 else if (op1 == TOK_ULT)
3514 op1 = TOK_ULE;
3515 else if (op1 == TOK_UGT)
3516 op1 = TOK_UGE;
3517 a = 0;
3518 b = 0;
3519 gen_op(op1);
3520 if (op1 != TOK_NE) {
3521 a = gtst(1, 0);
3523 if (op != TOK_EQ) {
3524 /* generate non equal test */
3525 /* XXX: NOT PORTABLE yet */
3526 if (a == 0) {
3527 b = gtst(0, 0);
3528 } else {
3529 #ifdef TCC_TARGET_I386
3530 b = psym(0x850f, 0);
3531 #else
3532 error("not implemented");
3533 #endif
3536 /* compare low */
3537 gen_op(op);
3538 a = gtst(1, a);
3539 gsym(b);
3540 vset(VT_INT, VT_JMPI, a);
3541 break;
3545 /* handle integer constant optimizations and various machine
3546 independant opt */
3547 void gen_opic(int op)
3549 int fc, c1, c2, n;
3550 SValue *v1, *v2;
3552 v1 = vtop - 1;
3553 v2 = vtop;
3554 /* currently, we cannot do computations with forward symbols */
3555 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3556 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3557 if (c1 && c2) {
3558 fc = v2->c.i;
3559 switch(op) {
3560 case '+': v1->c.i += fc; break;
3561 case '-': v1->c.i -= fc; break;
3562 case '&': v1->c.i &= fc; break;
3563 case '^': v1->c.i ^= fc; break;
3564 case '|': v1->c.i |= fc; break;
3565 case '*': v1->c.i *= fc; break;
3567 case TOK_PDIV:
3568 case '/':
3569 case '%':
3570 case TOK_UDIV:
3571 case TOK_UMOD:
3572 /* if division by zero, generate explicit division */
3573 if (fc == 0) {
3574 if (const_wanted)
3575 error("division by zero in constant");
3576 goto general_case;
3578 switch(op) {
3579 default: v1->c.i /= fc; break;
3580 case '%': v1->c.i %= fc; break;
3581 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
3582 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
3584 break;
3585 case TOK_SHL: v1->c.i <<= fc; break;
3586 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
3587 case TOK_SAR: v1->c.i >>= fc; break;
3588 /* tests */
3589 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
3590 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
3591 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
3592 case TOK_NE: v1->c.i = v1->c.i != fc; break;
3593 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
3594 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
3595 case TOK_LT: v1->c.i = v1->c.i < fc; break;
3596 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
3597 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
3598 case TOK_GT: v1->c.i = v1->c.i > fc; break;
3599 /* logical */
3600 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
3601 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
3602 default:
3603 goto general_case;
3605 vtop--;
3606 } else {
3607 /* if commutative ops, put c2 as constant */
3608 if (c1 && (op == '+' || op == '&' || op == '^' ||
3609 op == '|' || op == '*')) {
3610 vswap();
3611 swap(&c1, &c2);
3613 fc = vtop->c.i;
3614 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
3615 op == TOK_PDIV) &&
3616 fc == 1) ||
3617 ((op == '+' || op == '-' || op == '|' || op == '^' ||
3618 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
3619 fc == 0) ||
3620 (op == '&' &&
3621 fc == -1))) {
3622 /* nothing to do */
3623 vtop--;
3624 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
3625 /* try to use shifts instead of muls or divs */
3626 if (fc > 0 && (fc & (fc - 1)) == 0) {
3627 n = -1;
3628 while (fc) {
3629 fc >>= 1;
3630 n++;
3632 vtop->c.i = n;
3633 if (op == '*')
3634 op = TOK_SHL;
3635 else if (op == TOK_PDIV)
3636 op = TOK_SAR;
3637 else
3638 op = TOK_SHR;
3640 goto general_case;
3641 } else {
3642 general_case:
3643 /* call low level op generator */
3644 gen_opi(op);
3649 /* generate a floating point operation with constant propagation */
3650 void gen_opif(int op)
3652 int c1, c2;
3653 SValue *v1, *v2;
3654 long double f1, f2;
3656 v1 = vtop - 1;
3657 v2 = vtop;
3658 /* currently, we cannot do computations with forward symbols */
3659 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3660 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3661 if (c1 && c2) {
3662 if (v1->t == VT_FLOAT) {
3663 f1 = v1->c.f;
3664 f2 = v2->c.f;
3665 } else if (v1->t == VT_DOUBLE) {
3666 f1 = v1->c.d;
3667 f2 = v2->c.d;
3668 } else {
3669 f1 = v1->c.ld;
3670 f2 = v2->c.ld;
3673 /* NOTE: we only do constant propagation if finite number (not
3674 NaN or infinity) (ANSI spec) */
3675 if (!ieee_finite(f1) || !ieee_finite(f2))
3676 goto general_case;
3678 switch(op) {
3679 case '+': f1 += f2; break;
3680 case '-': f1 -= f2; break;
3681 case '*': f1 *= f2; break;
3682 case '/':
3683 if (f2 == 0.0) {
3684 if (const_wanted)
3685 error("division by zero in constant");
3686 goto general_case;
3688 f1 /= f2;
3689 break;
3690 /* XXX: also handles tests ? */
3691 default:
3692 goto general_case;
3694 /* XXX: overflow test ? */
3695 if (v1->t == VT_FLOAT) {
3696 v1->c.f = f1;
3697 } else if (v1->t == VT_DOUBLE) {
3698 v1->c.d = f1;
3699 } else {
3700 v1->c.ld = f1;
3702 vtop--;
3703 } else {
3704 general_case:
3705 gen_opf(op);
3710 int pointed_size(int t)
3712 return type_size(pointed_type(t), &t);
3715 #if 0
3716 void check_pointer_types(SValue *p1, SValue *p2)
3718 char buf1[256], buf2[256];
3719 int t1, t2;
3720 t1 = p1->t;
3721 t2 = p2->t;
3722 if (!is_compatible_types(t1, t2)) {
3723 type_to_str(buf1, sizeof(buf1), t1, NULL);
3724 type_to_str(buf2, sizeof(buf2), t2, NULL);
3725 error("incompatible pointers '%s' and '%s'", buf1, buf2);
3728 #endif
3730 /* generic gen_op: handles types problems */
3731 void gen_op(int op)
3733 int u, t1, t2, bt1, bt2, t;
3735 t1 = vtop[-1].t;
3736 t2 = vtop[0].t;
3737 bt1 = t1 & VT_BTYPE;
3738 bt2 = t2 & VT_BTYPE;
3740 if (bt1 == VT_PTR || bt2 == VT_PTR) {
3741 /* at least one operand is a pointer */
3742 /* relationnal op: must be both pointers */
3743 if (op >= TOK_ULT && op <= TOK_GT) {
3744 // check_pointer_types(vtop, vtop - 1);
3745 /* pointers are handled are unsigned */
3746 t = VT_INT | VT_UNSIGNED;
3747 goto std_op;
3749 /* if both pointers, then it must be the '-' op */
3750 if ((t1 & VT_BTYPE) == VT_PTR &&
3751 (t2 & VT_BTYPE) == VT_PTR) {
3752 if (op != '-')
3753 error("cannot use pointers here");
3754 // check_pointer_types(vtop - 1, vtop);
3755 /* XXX: check that types are compatible */
3756 u = pointed_size(t1);
3757 gen_opic(op);
3758 /* set to integer type */
3759 vtop->t = VT_INT;
3760 vpushi(u);
3761 gen_op(TOK_PDIV);
3762 } else {
3763 /* exactly one pointer : must be '+' or '-'. */
3764 if (op != '-' && op != '+')
3765 error("cannot use pointers here");
3766 /* Put pointer as first operand */
3767 if ((t2 & VT_BTYPE) == VT_PTR) {
3768 vswap();
3769 swap(&t1, &t2);
3771 /* XXX: cast to int ? (long long case) */
3772 vpushi(pointed_size(vtop[-1].t));
3773 gen_op('*');
3774 #ifdef CONFIG_TCC_BCHECK
3775 /* if evaluating constant expression, no code should be
3776 generated, so no bound check */
3777 if (do_bounds_check && !const_wanted) {
3778 /* if bounded pointers, we generate a special code to
3779 test bounds */
3780 if (op == '-') {
3781 vpushi(0);
3782 vswap();
3783 gen_op('-');
3785 gen_bounded_ptr_add();
3786 } else
3787 #endif
3789 gen_opic(op);
3791 /* put again type if gen_opic() swaped operands */
3792 vtop->t = t1;
3794 } else if (is_float(bt1) || is_float(bt2)) {
3795 /* compute bigger type and do implicit casts */
3796 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
3797 t = VT_LDOUBLE;
3798 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
3799 t = VT_DOUBLE;
3800 } else {
3801 t = VT_FLOAT;
3803 /* floats can only be used for a few operations */
3804 if (op != '+' && op != '-' && op != '*' && op != '/' &&
3805 (op < TOK_ULT || op > TOK_GT))
3806 error("invalid operands for binary operation");
3807 goto std_op;
3808 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
3809 /* cast to biggest op */
3810 t = VT_LLONG;
3811 /* convert to unsigned if it does not fit in a long long */
3812 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
3813 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
3814 t |= VT_UNSIGNED;
3815 goto std_op;
3816 } else {
3817 /* integer operations */
3818 t = VT_INT;
3819 /* convert to unsigned if it does not fit in an integer */
3820 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
3821 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
3822 t |= VT_UNSIGNED;
3823 std_op:
3824 /* XXX: currently, some unsigned operations are explicit, so
3825 we modify them here */
3826 if (t & VT_UNSIGNED) {
3827 if (op == TOK_SAR)
3828 op = TOK_SHR;
3829 else if (op == '/')
3830 op = TOK_UDIV;
3831 else if (op == '%')
3832 op = TOK_UMOD;
3833 else if (op == TOK_LT)
3834 op = TOK_ULT;
3835 else if (op == TOK_GT)
3836 op = TOK_UGT;
3837 else if (op == TOK_LE)
3838 op = TOK_ULE;
3839 else if (op == TOK_GE)
3840 op = TOK_UGE;
3842 vswap();
3843 gen_cast(t);
3844 vswap();
3845 /* special case for shifts and long long: we keep the shift as
3846 an integer */
3847 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
3848 gen_cast(VT_INT);
3849 else
3850 gen_cast(t);
3851 if (is_float(t))
3852 gen_opif(op);
3853 else if ((t & VT_BTYPE) == VT_LLONG)
3854 gen_opl(op);
3855 else
3856 gen_opic(op);
3857 if (op >= TOK_ULT && op <= TOK_GT) {
3858 /* relationnal op: the result is an int */
3859 vtop->t = VT_INT;
3860 } else {
3861 vtop->t = t;
3866 /* generic itof for unsigned long long case */
3867 void gen_cvt_itof1(int t)
3869 GFuncContext gf;
3871 if ((vtop->t & (VT_BTYPE | VT_UNSIGNED)) ==
3872 (VT_LLONG | VT_UNSIGNED)) {
3874 gfunc_start(&gf, FUNC_CDECL);
3875 gfunc_param(&gf);
3876 if (t == VT_FLOAT)
3877 vpush_sym(func_old_type, TOK___ulltof);
3878 else if (t == VT_DOUBLE)
3879 vpush_sym(func_old_type, TOK___ulltod);
3880 else
3881 vpush_sym(func_old_type, TOK___ulltold);
3882 gfunc_call(&gf);
3883 vpushi(0);
3884 vtop->r = REG_FRET;
3885 } else {
3886 gen_cvt_itof(t);
3890 /* generic ftoi for unsigned long long case */
3891 void gen_cvt_ftoi1(int t)
3893 GFuncContext gf;
3894 int st;
3896 if (t == (VT_LLONG | VT_UNSIGNED)) {
3897 /* not handled natively */
3898 gfunc_start(&gf, FUNC_CDECL);
3899 st = vtop->t & VT_BTYPE;
3900 gfunc_param(&gf);
3901 if (st == VT_FLOAT)
3902 vpush_sym(func_old_type, TOK___fixunssfdi);
3903 else if (st == VT_DOUBLE)
3904 vpush_sym(func_old_type, TOK___fixunsdfdi);
3905 else
3906 vpush_sym(func_old_type, TOK___fixunsxfdi);
3907 gfunc_call(&gf);
3908 vpushi(0);
3909 vtop->r = REG_IRET;
3910 vtop->r2 = REG_LRET;
3911 } else {
3912 gen_cvt_ftoi(t);
3916 /* force char or short cast */
3917 void force_charshort_cast(int t)
3919 int bits, dbt;
3920 dbt = t & VT_BTYPE;
3921 /* XXX: add optimization if lvalue : just change type and offset */
3922 if (dbt == VT_BYTE)
3923 bits = 8;
3924 else
3925 bits = 16;
3926 if (t & VT_UNSIGNED) {
3927 vpushi((1 << bits) - 1);
3928 gen_op('&');
3929 } else {
3930 bits = 32 - bits;
3931 vpushi(bits);
3932 gen_op(TOK_SHL);
3933 vpushi(bits);
3934 gen_op(TOK_SAR);
3938 /* cast 'vtop' to 't' type */
3939 void gen_cast(int t)
3941 int sbt, dbt, sf, df, c;
3943 /* special delayed cast for char/short */
3944 /* XXX: in some cases (multiple cascaded casts), it may still
3945 be incorrect */
3946 if (vtop->r & VT_MUSTCAST) {
3947 vtop->r &= ~VT_MUSTCAST;
3948 force_charshort_cast(vtop->t);
3951 dbt = t & (VT_BTYPE | VT_UNSIGNED);
3952 sbt = vtop->t & (VT_BTYPE | VT_UNSIGNED);
3954 if (sbt != dbt) {
3955 sf = is_float(sbt);
3956 df = is_float(dbt);
3957 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3958 if (sf && df) {
3959 /* convert from fp to fp */
3960 if (c) {
3961 /* constant case: we can do it now */
3962 /* XXX: in ISOC, cannot do it if error in convert */
3963 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
3964 vtop->c.f = (float)vtop->c.d;
3965 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
3966 vtop->c.f = (float)vtop->c.ld;
3967 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
3968 vtop->c.d = (double)vtop->c.f;
3969 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
3970 vtop->c.d = (double)vtop->c.ld;
3971 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
3972 vtop->c.ld = (long double)vtop->c.f;
3973 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
3974 vtop->c.ld = (long double)vtop->c.d;
3975 } else {
3976 /* non constant case: generate code */
3977 gen_cvt_ftof(dbt);
3979 } else if (df) {
3980 /* convert int to fp */
3981 if (c) {
3982 switch(sbt) {
3983 case VT_LLONG | VT_UNSIGNED:
3984 case VT_LLONG:
3985 /* XXX: add const cases for long long */
3986 goto do_itof;
3987 case VT_INT | VT_UNSIGNED:
3988 switch(dbt) {
3989 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
3990 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
3991 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
3993 break;
3994 default:
3995 switch(dbt) {
3996 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
3997 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
3998 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
4000 break;
4002 } else {
4003 do_itof:
4004 gen_cvt_itof1(dbt);
4006 } else if (sf) {
4007 /* convert fp to int */
4008 /* we handle char/short/etc... with generic code */
4009 if (dbt != (VT_INT | VT_UNSIGNED) &&
4010 dbt != (VT_LLONG | VT_UNSIGNED) &&
4011 dbt != VT_LLONG)
4012 dbt = VT_INT;
4013 if (c) {
4014 switch(dbt) {
4015 case VT_LLONG | VT_UNSIGNED:
4016 case VT_LLONG:
4017 /* XXX: add const cases for long long */
4018 goto do_ftoi;
4019 case VT_INT | VT_UNSIGNED:
4020 switch(sbt) {
4021 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
4022 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4023 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4025 break;
4026 default:
4027 /* int case */
4028 switch(sbt) {
4029 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
4030 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
4031 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
4033 break;
4035 } else {
4036 do_ftoi:
4037 gen_cvt_ftoi1(dbt);
4039 if (dbt == VT_INT && (t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
4040 /* additionnal cast for char/short/bool... */
4041 vtop->t = dbt;
4042 gen_cast(t);
4044 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
4045 if ((sbt & VT_BTYPE) != VT_LLONG) {
4046 /* scalar to long long */
4047 if (c) {
4048 if (sbt == (VT_INT | VT_UNSIGNED))
4049 vtop->c.ll = vtop->c.ui;
4050 else
4051 vtop->c.ll = vtop->c.i;
4052 } else {
4053 /* machine independant conversion */
4054 gv(RC_INT);
4055 /* generate high word */
4056 if (sbt == (VT_INT | VT_UNSIGNED)) {
4057 vpushi(0);
4058 gv(RC_INT);
4059 } else {
4060 gv_dup();
4061 vpushi(31);
4062 gen_op(TOK_SAR);
4064 /* patch second register */
4065 vtop[-1].r2 = vtop->r;
4066 vpop();
4069 } else if (dbt == VT_BOOL) {
4070 /* scalar to bool */
4071 vpushi(0);
4072 gen_op(TOK_NE);
4073 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
4074 (dbt & VT_BTYPE) == VT_SHORT) {
4075 force_charshort_cast(t);
4076 } else if ((dbt & VT_BTYPE) == VT_INT) {
4077 /* scalar to int */
4078 if (sbt == VT_LLONG) {
4079 /* from long long: just take low order word */
4080 lexpand();
4081 vpop();
4083 /* if lvalue and single word type, nothing to do because
4084 the lvalue already contains the real type size (see
4085 VT_LVAL_xxx constants) */
4088 vtop->t = t;
4091 /* return type size. Put alignment at 'a' */
4092 int type_size(int t, int *a)
4094 Sym *s;
4095 int bt;
4097 bt = t & VT_BTYPE;
4098 if (bt == VT_STRUCT) {
4099 /* struct/union */
4100 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4101 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
4102 return s->c;
4103 } else if (bt == VT_PTR) {
4104 if (t & VT_ARRAY) {
4105 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4106 return type_size(s->t, a) * s->c;
4107 } else {
4108 *a = PTR_SIZE;
4109 return PTR_SIZE;
4111 } else if (bt == VT_LDOUBLE) {
4112 *a = LDOUBLE_ALIGN;
4113 return LDOUBLE_SIZE;
4114 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
4115 *a = 8;
4116 return 8;
4117 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
4118 *a = 4;
4119 return 4;
4120 } else if (bt == VT_SHORT) {
4121 *a = 2;
4122 return 2;
4123 } else {
4124 /* char, void, function, _Bool */
4125 *a = 1;
4126 return 1;
4130 /* return the pointed type of t */
4131 int pointed_type(int t)
4133 Sym *s;
4134 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4135 return s->t | (t & ~VT_TYPE);
4138 int mk_pointer(int t)
4140 int p;
4141 p = anon_sym++;
4142 sym_push(p, t, 0, -1);
4143 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
4146 int is_compatible_types(int t1, int t2)
4148 Sym *s1, *s2;
4149 int bt1, bt2;
4151 t1 &= VT_TYPE;
4152 t2 &= VT_TYPE;
4153 bt1 = t1 & VT_BTYPE;
4154 bt2 = t2 & VT_BTYPE;
4155 if (bt1 == VT_PTR) {
4156 t1 = pointed_type(t1);
4157 /* if function, then convert implicitely to function pointer */
4158 if (bt2 != VT_FUNC) {
4159 if (bt2 != VT_PTR)
4160 return 0;
4161 t2 = pointed_type(t2);
4163 /* void matches everything */
4164 t1 &= VT_TYPE;
4165 t2 &= VT_TYPE;
4166 if (t1 == VT_VOID || t2 == VT_VOID)
4167 return 1;
4168 return is_compatible_types(t1, t2);
4169 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4170 return (t2 == t1);
4171 } else if (bt1 == VT_FUNC) {
4172 if (bt2 != VT_FUNC)
4173 return 0;
4174 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
4175 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
4176 if (!is_compatible_types(s1->t, s2->t))
4177 return 0;
4178 /* XXX: not complete */
4179 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
4180 return 1;
4181 if (s1->c != s2->c)
4182 return 0;
4183 while (s1 != NULL) {
4184 if (s2 == NULL)
4185 return 0;
4186 if (!is_compatible_types(s1->t, s2->t))
4187 return 0;
4188 s1 = s1->next;
4189 s2 = s2->next;
4191 if (s2)
4192 return 0;
4193 return 1;
4194 } else {
4195 /* XXX: not complete */
4196 return 1;
4200 /* print a type. If 'varstr' is not NULL, then the variable is also
4201 printed in the type */
4202 /* XXX: union */
4203 /* XXX: add array and function pointers */
4204 void type_to_str(char *buf, int buf_size,
4205 int t, const char *varstr)
4207 int bt, v;
4208 Sym *s, *sa;
4209 char buf1[256];
4210 const char *tstr;
4212 t = t & VT_TYPE;
4213 bt = t & VT_BTYPE;
4214 buf[0] = '\0';
4215 if (t & VT_UNSIGNED)
4216 pstrcat(buf, buf_size, "unsigned ");
4217 switch(bt) {
4218 case VT_VOID:
4219 tstr = "void";
4220 goto add_tstr;
4221 case VT_BOOL:
4222 tstr = "_Bool";
4223 goto add_tstr;
4224 case VT_BYTE:
4225 tstr = "char";
4226 goto add_tstr;
4227 case VT_SHORT:
4228 tstr = "short";
4229 goto add_tstr;
4230 case VT_INT:
4231 tstr = "int";
4232 goto add_tstr;
4233 case VT_LONG:
4234 tstr = "long";
4235 goto add_tstr;
4236 case VT_LLONG:
4237 tstr = "long long";
4238 goto add_tstr;
4239 case VT_FLOAT:
4240 tstr = "float";
4241 goto add_tstr;
4242 case VT_DOUBLE:
4243 tstr = "double";
4244 goto add_tstr;
4245 case VT_LDOUBLE:
4246 tstr = "long double";
4247 add_tstr:
4248 pstrcat(buf, buf_size, tstr);
4249 break;
4250 case VT_ENUM:
4251 case VT_STRUCT:
4252 if (bt == VT_STRUCT)
4253 tstr = "struct ";
4254 else
4255 tstr = "enum ";
4256 pstrcat(buf, buf_size, tstr);
4257 v = (unsigned)t >> VT_STRUCT_SHIFT;
4258 if (v >= SYM_FIRST_ANOM)
4259 pstrcat(buf, buf_size, "<anonymous>");
4260 else
4261 pstrcat(buf, buf_size, get_tok_str(v, NULL));
4262 break;
4263 case VT_FUNC:
4264 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4265 type_to_str(buf, buf_size, s->t, varstr);
4266 pstrcat(buf, buf_size, "(");
4267 sa = s->next;
4268 while (sa != NULL) {
4269 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
4270 pstrcat(buf, buf_size, buf1);
4271 sa = sa->next;
4272 if (sa)
4273 pstrcat(buf, buf_size, ", ");
4275 pstrcat(buf, buf_size, ")");
4276 goto no_var;
4277 case VT_PTR:
4278 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4279 pstrcpy(buf1, sizeof(buf1), "*");
4280 if (varstr)
4281 pstrcat(buf1, sizeof(buf1), varstr);
4282 type_to_str(buf, buf_size, s->t, buf1);
4283 goto no_var;
4285 if (varstr) {
4286 pstrcat(buf, buf_size, " ");
4287 pstrcat(buf, buf_size, varstr);
4289 no_var: ;
4292 /* verify type compatibility to store vtop in 'dt' type, and generate
4293 casts if needed. */
4294 void gen_assign_cast(int dt)
4296 int st;
4297 char buf1[256], buf2[256];
4299 st = vtop->t; /* source type */
4300 if ((dt & VT_BTYPE) == VT_PTR) {
4301 /* special cases for pointers */
4302 /* a function is implicitely a function pointer */
4303 if ((st & VT_BTYPE) == VT_FUNC) {
4304 if (!is_compatible_types(pointed_type(dt), st))
4305 goto error;
4306 else
4307 goto type_ok;
4309 /* '0' can also be a pointer */
4310 if ((st & VT_BTYPE) == VT_INT &&
4311 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
4312 vtop->c.i == 0)
4313 goto type_ok;
4315 if (!is_compatible_types(dt, st)) {
4316 error:
4317 type_to_str(buf1, sizeof(buf1), st, NULL);
4318 type_to_str(buf2, sizeof(buf2), dt, NULL);
4319 error("cannot cast '%s' to '%s'", buf1, buf2);
4321 type_ok:
4322 gen_cast(dt);
4325 /* store vtop in lvalue pushed on stack */
4326 void vstore(void)
4328 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
4329 GFuncContext gf;
4331 ft = vtop[-1].t;
4332 sbt = vtop->t & VT_BTYPE;
4333 dbt = ft & VT_BTYPE;
4334 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
4335 (sbt == VT_INT && dbt == VT_SHORT)) {
4336 /* optimize char/short casts */
4337 delayed_cast = VT_MUSTCAST;
4338 vtop->t = ft & VT_TYPE;
4339 } else {
4340 delayed_cast = 0;
4341 gen_assign_cast(ft & VT_TYPE);
4344 if (sbt == VT_STRUCT) {
4345 /* if structure, only generate pointer */
4346 /* structure assignment : generate memcpy */
4347 /* XXX: optimize if small size */
4348 vdup();
4349 gfunc_start(&gf, FUNC_CDECL);
4350 /* type size */
4351 size = type_size(vtop->t, &align);
4352 vpushi(size);
4353 gfunc_param(&gf);
4354 /* source */
4355 vtop->t = VT_INT;
4356 gaddrof();
4357 gfunc_param(&gf);
4358 /* destination */
4359 vswap();
4360 vtop->t = VT_INT;
4361 gaddrof();
4362 gfunc_param(&gf);
4364 save_regs(0);
4365 vpush_sym(func_old_type, TOK_memcpy);
4366 gfunc_call(&gf);
4367 /* leave source on stack */
4368 } else if (ft & VT_BITFIELD) {
4369 /* bitfield store handling */
4370 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
4371 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4372 /* remove bit field info to avoid loops */
4373 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4375 /* duplicate destination */
4376 vdup();
4377 vtop[-1] = vtop[-2];
4379 /* mask and shift source */
4380 vpushi((1 << bit_size) - 1);
4381 gen_op('&');
4382 vpushi(bit_pos);
4383 gen_op(TOK_SHL);
4384 /* load destination, mask and or with source */
4385 vswap();
4386 vpushi(~(((1 << bit_size) - 1) << bit_pos));
4387 gen_op('&');
4388 gen_op('|');
4389 /* store result */
4390 vstore();
4391 } else {
4392 #ifdef CONFIG_TCC_BCHECK
4393 /* bound check case */
4394 if (vtop[-1].r & VT_MUSTBOUND) {
4395 vswap();
4396 gbound();
4397 vswap();
4399 #endif
4400 rc = RC_INT;
4401 if (is_float(ft))
4402 rc = RC_FLOAT;
4403 r = gv(rc); /* generate value */
4404 /* if lvalue was saved on stack, must read it */
4405 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
4406 SValue sv;
4407 t = get_reg(RC_INT);
4408 sv.t = VT_INT;
4409 sv.r = VT_LOCAL | VT_LVAL;
4410 sv.c.ul = vtop[-1].c.ul;
4411 load(t, &sv);
4412 vtop[-1].r = t | VT_LVAL;
4414 store(r, vtop - 1);
4415 /* two word case handling : store second register at word + 4 */
4416 if ((ft & VT_BTYPE) == VT_LLONG) {
4417 vswap();
4418 /* convert to int to increment easily */
4419 vtop->t = VT_INT;
4420 gaddrof();
4421 vpushi(4);
4422 gen_op('+');
4423 vtop->r |= VT_LVAL;
4424 vswap();
4425 /* XXX: it works because r2 is spilled last ! */
4426 store(vtop->r2, vtop - 1);
4428 vswap();
4429 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4430 vtop->r |= delayed_cast;
4434 /* post defines POST/PRE add. c is the token ++ or -- */
4435 void inc(int post, int c)
4437 test_lvalue();
4438 vdup(); /* save lvalue */
4439 if (post) {
4440 gv_dup(); /* duplicate value */
4441 vrotb(3);
4442 vrotb(3);
4444 /* add constant */
4445 vpushi(c - TOK_MID);
4446 gen_op('+');
4447 vstore(); /* store value */
4448 if (post)
4449 vpop(); /* if post op, return saved value */
4452 /* Parse GNUC __attribute__ extension. Currently, the following
4453 extensions are recognized:
4454 - aligned(n) : set data/function alignment.
4455 - section(x) : generate data/code in this section.
4456 - unused : currently ignored, but may be used someday.
4458 void parse_attribute(AttributeDef *ad)
4460 int t, n;
4462 next();
4463 skip('(');
4464 skip('(');
4465 while (tok != ')') {
4466 if (tok < TOK_IDENT)
4467 expect("attribute name");
4468 t = tok;
4469 next();
4470 switch(t) {
4471 case TOK_SECTION:
4472 case TOK___SECTION__:
4473 skip('(');
4474 if (tok != TOK_STR)
4475 expect("section name");
4476 ad->section = find_section((char *)tokc.cstr->data);
4477 next();
4478 skip(')');
4479 break;
4480 case TOK_ALIGNED:
4481 case TOK___ALIGNED__:
4482 skip('(');
4483 n = expr_const();
4484 if (n <= 0 || (n & (n - 1)) != 0)
4485 error("alignment must be a positive power of two");
4486 ad->aligned = n;
4487 skip(')');
4488 break;
4489 case TOK_UNUSED:
4490 case TOK___UNUSED__:
4491 /* currently, no need to handle it because tcc does not
4492 track unused objects */
4493 break;
4494 case TOK_NORETURN:
4495 case TOK___NORETURN__:
4496 /* currently, no need to handle it because tcc does not
4497 track unused objects */
4498 break;
4499 case TOK_CDECL:
4500 case TOK___CDECL:
4501 case TOK___CDECL__:
4502 ad->func_call = FUNC_CDECL;
4503 break;
4504 case TOK_STDCALL:
4505 case TOK___STDCALL:
4506 case TOK___STDCALL__:
4507 ad->func_call = FUNC_STDCALL;
4508 break;
4509 default:
4510 warning("'%s' attribute ignored", get_tok_str(t, NULL));
4511 /* skip parameters */
4512 /* XXX: skip parenthesis too */
4513 if (tok == '(') {
4514 next();
4515 while (tok != ')' && tok != -1)
4516 next();
4517 next();
4519 break;
4521 if (tok != ',')
4522 break;
4523 next();
4525 skip(')');
4526 skip(')');
4529 /* enum/struct/union declaration */
4530 int struct_decl(int u)
4532 int a, t, b, v, size, align, maxalign, c, offset;
4533 int bit_size, bit_pos, bsize, bt, lbit_pos;
4534 Sym *s, *ss, **ps;
4535 AttributeDef ad;
4537 a = tok; /* save decl type */
4538 next();
4539 if (tok != '{') {
4540 v = tok;
4541 next();
4542 /* struct already defined ? return it */
4543 /* XXX: check consistency */
4544 s = sym_find(v | SYM_STRUCT);
4545 if (s) {
4546 if (s->t != a)
4547 error("invalid type");
4548 goto do_decl;
4550 } else {
4551 v = anon_sym++;
4553 s = sym_push(v | SYM_STRUCT, a, 0, 0);
4554 /* put struct/union/enum name in type */
4555 do_decl:
4556 u = u | (v << VT_STRUCT_SHIFT);
4558 if (tok == '{') {
4559 next();
4560 if (s->c)
4561 error("struct/union/enum already defined");
4562 /* cannot be empty */
4563 c = 0;
4564 maxalign = 0;
4565 ps = &s->next;
4566 bit_pos = 0;
4567 offset = 0;
4568 while (1) {
4569 if (a == TOK_ENUM) {
4570 v = tok;
4571 next();
4572 if (tok == '=') {
4573 next();
4574 c = expr_const();
4576 /* enum symbols have static storage */
4577 sym_push(v, VT_STATIC | VT_INT, VT_CONST, c);
4578 if (tok == ',')
4579 next();
4580 c++;
4581 } else {
4582 parse_btype(&b, &ad);
4583 while (1) {
4584 bit_size = -1;
4585 v = 0;
4586 if (tok != ':') {
4587 t = type_decl(&ad, &v, b, TYPE_DIRECT);
4588 if ((t & VT_BTYPE) == VT_FUNC ||
4589 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
4590 error("invalid type for '%s'",
4591 get_tok_str(v, NULL));
4592 } else {
4593 t = b;
4595 if (tok == ':') {
4596 next();
4597 bit_size = expr_const();
4598 /* XXX: handle v = 0 case for messages */
4599 if (bit_size < 0)
4600 error("negative width in bit-field '%s'",
4601 get_tok_str(v, NULL));
4602 if (v && bit_size == 0)
4603 error("zero width for bit-field '%s'",
4604 get_tok_str(v, NULL));
4606 size = type_size(t, &align);
4607 lbit_pos = 0;
4608 if (bit_size >= 0) {
4609 bt = t & VT_BTYPE;
4610 if (bt != VT_INT &&
4611 bt != VT_BYTE &&
4612 bt != VT_SHORT)
4613 error("bitfields must have scalar type");
4614 bsize = size * 8;
4615 if (bit_size > bsize) {
4616 error("width of '%s' exceeds its type",
4617 get_tok_str(v, NULL));
4618 } else if (bit_size == bsize) {
4619 /* no need for bit fields */
4620 bit_pos = 0;
4621 } else if (bit_size == 0) {
4622 /* XXX: what to do if only padding in a
4623 structure ? */
4624 /* zero size: means to pad */
4625 if (bit_pos > 0)
4626 bit_pos = bsize;
4627 } else {
4628 /* we do not have enough room ? */
4629 if ((bit_pos + bit_size) > bsize)
4630 bit_pos = 0;
4631 lbit_pos = bit_pos;
4632 /* XXX: handle LSB first */
4633 t |= VT_BITFIELD |
4634 (bit_pos << VT_STRUCT_SHIFT) |
4635 (bit_size << (VT_STRUCT_SHIFT + 6));
4636 bit_pos += bit_size;
4638 } else {
4639 bit_pos = 0;
4641 if (v) {
4642 /* add new memory data only if starting
4643 bit field */
4644 if (lbit_pos == 0) {
4645 if (a == TOK_STRUCT) {
4646 c = (c + align - 1) & -align;
4647 offset = c;
4648 c += size;
4649 } else {
4650 offset = 0;
4651 if (size > c)
4652 c = size;
4654 if (align > maxalign)
4655 maxalign = align;
4657 #if 0
4658 printf("add field %s offset=%d",
4659 get_tok_str(v, NULL), offset);
4660 if (t & VT_BITFIELD) {
4661 printf(" pos=%d size=%d",
4662 (t >> VT_STRUCT_SHIFT) & 0x3f,
4663 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
4665 printf("\n");
4666 #endif
4667 ss = sym_push(v | SYM_FIELD, t, 0, offset);
4668 *ps = ss;
4669 ps = &ss->next;
4671 if (tok == ';' || tok == -1)
4672 break;
4673 skip(',');
4675 skip(';');
4677 if (tok == '}')
4678 break;
4680 skip('}');
4681 /* size for struct/union, dummy for enum */
4682 s->c = (c + maxalign - 1) & -maxalign;
4684 return u;
4687 /* return 0 if no type declaration. otherwise, return the basic type
4688 and skip it.
4690 int parse_btype(int *type_ptr, AttributeDef *ad)
4692 int t, u, type_found;
4693 Sym *s;
4695 memset(ad, 0, sizeof(AttributeDef));
4696 type_found = 0;
4697 t = 0;
4698 while(1) {
4699 switch(tok) {
4700 /* basic types */
4701 case TOK_CHAR:
4702 u = VT_BYTE;
4703 basic_type:
4704 next();
4705 basic_type1:
4706 if ((t & VT_BTYPE) != 0)
4707 error("too many basic types");
4708 t |= u;
4709 break;
4710 case TOK_VOID:
4711 u = VT_VOID;
4712 goto basic_type;
4713 case TOK_SHORT:
4714 u = VT_SHORT;
4715 goto basic_type;
4716 case TOK_INT:
4717 next();
4718 break;
4719 case TOK_LONG:
4720 next();
4721 if ((t & VT_BTYPE) == VT_DOUBLE) {
4722 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4723 } else if ((t & VT_BTYPE) == VT_LONG) {
4724 t = (t & ~VT_BTYPE) | VT_LLONG;
4725 } else {
4726 u = VT_LONG;
4727 goto basic_type1;
4729 break;
4730 case TOK_BOOL:
4731 u = VT_BOOL;
4732 goto basic_type;
4733 case TOK_FLOAT:
4734 u = VT_FLOAT;
4735 goto basic_type;
4736 case TOK_DOUBLE:
4737 next();
4738 if ((t & VT_BTYPE) == VT_LONG) {
4739 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
4740 } else {
4741 u = VT_DOUBLE;
4742 goto basic_type1;
4744 break;
4745 case TOK_ENUM:
4746 u = struct_decl(VT_ENUM);
4747 goto basic_type1;
4748 case TOK_STRUCT:
4749 case TOK_UNION:
4750 u = struct_decl(VT_STRUCT);
4751 goto basic_type1;
4753 /* type modifiers */
4754 case TOK_CONST:
4755 case TOK_VOLATILE:
4756 case TOK_REGISTER:
4757 case TOK_SIGNED:
4758 case TOK___SIGNED__:
4759 case TOK_AUTO:
4760 case TOK_INLINE:
4761 case TOK___INLINE__:
4762 case TOK_RESTRICT:
4763 next();
4764 break;
4765 case TOK_UNSIGNED:
4766 t |= VT_UNSIGNED;
4767 next();
4768 break;
4770 /* storage */
4771 case TOK_EXTERN:
4772 t |= VT_EXTERN;
4773 next();
4774 break;
4775 case TOK_STATIC:
4776 t |= VT_STATIC;
4777 next();
4778 break;
4779 case TOK_TYPEDEF:
4780 t |= VT_TYPEDEF;
4781 next();
4782 break;
4783 /* GNUC attribute */
4784 case TOK___ATTRIBUTE__:
4785 parse_attribute(ad);
4786 break;
4787 default:
4788 s = sym_find(tok);
4789 if (!s || !(s->t & VT_TYPEDEF))
4790 goto the_end;
4791 t |= (s->t & ~VT_TYPEDEF);
4792 next();
4793 break;
4795 type_found = 1;
4797 the_end:
4798 /* long is never used as type */
4799 if ((t & VT_BTYPE) == VT_LONG)
4800 t = (t & ~VT_BTYPE) | VT_INT;
4801 *type_ptr = t;
4802 return type_found;
4805 int post_type(int t, AttributeDef *ad)
4807 int p, n, pt, l, t1;
4808 Sym **plast, *s, *first;
4809 AttributeDef ad1;
4811 if (tok == '(') {
4812 /* function declaration */
4813 next();
4814 l = 0;
4815 first = NULL;
4816 plast = &first;
4817 while (tok != ')') {
4818 /* read param name and compute offset */
4819 if (l != FUNC_OLD) {
4820 if (!parse_btype(&pt, &ad1)) {
4821 if (l) {
4822 error("invalid type");
4823 } else {
4824 l = FUNC_OLD;
4825 goto old_proto;
4828 l = FUNC_NEW;
4829 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
4830 break;
4831 pt = type_decl(&ad1, &n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
4832 if ((pt & VT_BTYPE) == VT_VOID)
4833 error("parameter declared as void");
4834 } else {
4835 old_proto:
4836 n = tok;
4837 pt = VT_INT;
4838 next();
4840 /* array must be transformed to pointer according to ANSI C */
4841 pt &= ~VT_ARRAY;
4842 s = sym_push(n | SYM_FIELD, pt, 0, 0);
4843 *plast = s;
4844 plast = &s->next;
4845 if (tok == ',') {
4846 next();
4847 if (l == FUNC_NEW && tok == TOK_DOTS) {
4848 l = FUNC_ELLIPSIS;
4849 next();
4850 break;
4854 /* if no parameters, then old type prototype */
4855 if (l == 0)
4856 l = FUNC_OLD;
4857 skip(')');
4858 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4859 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4860 /* we push a anonymous symbol which will contain the function prototype */
4861 p = anon_sym++;
4862 s = sym_push(p, t, ad->func_call, l);
4863 s->next = first;
4864 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
4865 } else if (tok == '[') {
4866 /* array definition */
4867 next();
4868 n = -1;
4869 if (tok != ']') {
4870 n = expr_const();
4871 if (n < 0)
4872 error("invalid array size");
4874 skip(']');
4875 /* parse next post type */
4876 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
4877 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
4879 /* we push a anonymous symbol which will contain the array
4880 element type */
4881 p = anon_sym++;
4882 sym_push(p, t, 0, n);
4883 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
4885 return t;
4888 /* Read a type declaration (except basic type), and return the
4889 type. 'td' is a bitmask indicating which kind of type decl is
4890 expected. 't' should contain the basic type. 'ad' is the attribute
4891 definition of the basic type. It can be modified by type_decl(). */
4892 int type_decl(AttributeDef *ad, int *v, int t, int td)
4894 int u, p;
4895 Sym *s;
4897 while (tok == '*') {
4898 next();
4899 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
4900 next();
4901 t = mk_pointer(t);
4904 /* recursive type */
4905 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4906 if (tok == '(') {
4907 next();
4908 /* XXX: this is not correct to modify 'ad' at this point, but
4909 the syntax is not clear */
4910 if (tok == TOK___ATTRIBUTE__)
4911 parse_attribute(ad);
4912 u = type_decl(ad, v, 0, td);
4913 skip(')');
4914 } else {
4915 u = 0;
4916 /* type identifier */
4917 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
4918 *v = tok;
4919 next();
4920 } else {
4921 if (!(td & TYPE_ABSTRACT))
4922 expect("identifier");
4923 *v = 0;
4926 /* append t at the end of u */
4927 t = post_type(t, ad);
4928 if (tok == TOK___ATTRIBUTE__)
4929 parse_attribute(ad);
4930 if (!u)
4931 return t;
4932 p = u;
4933 while(1) {
4934 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
4935 p = s->t;
4936 if (!p) {
4937 s->t = t;
4938 break;
4941 return u;
4944 /* define a new external reference to a symbol 'v' of type 'u' */
4945 Sym *external_sym(int v, int u, int r)
4947 Sym *s;
4949 s = sym_find(v);
4950 if (!s) {
4951 /* push forward reference */
4952 s = sym_push1(&global_stack,
4953 v, u | VT_EXTERN, 0);
4954 s->r = r | VT_CONST | VT_SYM;
4956 return s;
4959 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4960 static int lvalue_type(int t)
4962 int bt, r;
4963 r = VT_LVAL;
4964 bt = t & VT_BTYPE;
4965 if (bt == VT_BYTE)
4966 r |= VT_LVAL_BYTE;
4967 else if (bt == VT_SHORT)
4968 r |= VT_LVAL_SHORT;
4969 else
4970 return r;
4971 if (t & VT_UNSIGNED)
4972 r |= VT_LVAL_UNSIGNED;
4973 return r;
4976 /* indirection with full error checking and bound check */
4977 static void indir(void)
4979 if ((vtop->t & VT_BTYPE) != VT_PTR)
4980 expect("pointer");
4981 if (vtop->r & VT_LVAL)
4982 gv(RC_INT);
4983 vtop->t = pointed_type(vtop->t);
4984 /* an array is never an lvalue */
4985 if (!(vtop->t & VT_ARRAY)) {
4986 vtop->r |= lvalue_type(vtop->t);
4987 /* if bound checking, the referenced pointer must be checked */
4988 if (do_bounds_check)
4989 vtop->r |= VT_MUSTBOUND;
4993 /* pass a parameter to a function and do type checking and casting */
4994 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
4996 int func_type;
4997 func_type = func->c;
4998 if (func_type == FUNC_OLD ||
4999 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
5000 /* default casting : only need to convert float to double */
5001 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
5002 gen_cast(VT_DOUBLE);
5003 } else if (arg == NULL) {
5004 error("too many arguments to function");
5005 } else {
5006 gen_assign_cast(arg->t);
5008 gfunc_param(gf);
5011 void unary(void)
5013 int n, t, ft, fc, align, size, r, data_offset;
5014 Sym *s;
5015 GFuncContext gf;
5016 AttributeDef ad;
5018 if (tok == TOK_CINT || tok == TOK_CCHAR || tok == TOK_LCHAR) {
5019 vpushi(tokc.i);
5020 next();
5021 } else if (tok == TOK_CUINT) {
5022 vsetc(VT_INT | VT_UNSIGNED, VT_CONST, &tokc);
5023 next();
5024 } else if (tok == TOK_CLLONG) {
5025 vsetc(VT_LLONG, VT_CONST, &tokc);
5026 next();
5027 } else if (tok == TOK_CULLONG) {
5028 vsetc(VT_LLONG | VT_UNSIGNED, VT_CONST, &tokc);
5029 next();
5030 } else if (tok == TOK_CFLOAT) {
5031 vsetc(VT_FLOAT, VT_CONST, &tokc);
5032 next();
5033 } else if (tok == TOK_CDOUBLE) {
5034 vsetc(VT_DOUBLE, VT_CONST, &tokc);
5035 next();
5036 } else if (tok == TOK_CLDOUBLE) {
5037 vsetc(VT_LDOUBLE, VT_CONST, &tokc);
5038 next();
5039 } else if (tok == TOK___FUNC__) {
5040 void *ptr;
5041 int len;
5042 /* special function name identifier */
5044 len = strlen(funcname) + 1;
5045 /* generate char[len] type */
5046 t = VT_ARRAY | mk_pointer(VT_BYTE);
5047 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5048 s->c = len;
5049 vpush_ref(t, data_section, data_section->data_offset, len);
5050 ptr = section_ptr_add(data_section, len);
5051 memcpy(ptr, funcname, len);
5052 next();
5053 } else if (tok == TOK_LSTR) {
5054 t = VT_INT;
5055 goto str_init;
5056 } else if (tok == TOK_STR) {
5057 /* string parsing */
5058 t = VT_BYTE;
5059 str_init:
5060 type_size(t, &align);
5061 data_offset = data_section->data_offset;
5062 data_offset = (data_offset + align - 1) & -align;
5063 fc = data_offset;
5064 /* we must declare it as an array first to use initializer parser */
5065 t = VT_ARRAY | mk_pointer(t);
5066 /* XXX: fix it */
5067 section_ptr(data_section, 1024);
5068 decl_initializer(t, data_section, data_offset, 1, 0);
5069 size = type_size(t, &align);
5070 data_offset += size;
5071 vpush_ref(t, data_section, fc, size);
5072 data_section->data_offset = data_offset;
5073 } else {
5074 t = tok;
5075 next();
5076 if (t == '(') {
5077 /* cast ? */
5078 if (parse_btype(&t, &ad)) {
5079 ft = type_decl(&ad, &n, t, TYPE_ABSTRACT);
5080 skip(')');
5081 /* check ISOC99 compound literal */
5082 if (tok == '{') {
5083 /* data is allocated locally by default */
5084 if (global_expr)
5085 r = VT_CONST;
5086 else
5087 r = VT_LOCAL;
5088 /* all except arrays are lvalues */
5089 if (!(ft & VT_ARRAY))
5090 r |= lvalue_type(ft);
5091 memset(&ad, 0, sizeof(AttributeDef));
5092 decl_initializer_alloc(ft, &ad, r, 1, 0, 0);
5093 } else {
5094 unary();
5095 gen_cast(ft);
5097 } else {
5098 gexpr();
5099 skip(')');
5101 } else if (t == '*') {
5102 unary();
5103 indir();
5104 } else if (t == '&') {
5105 unary();
5106 /* functions names must be treated as function pointers,
5107 except for unary '&' and sizeof. Since we consider that
5108 functions are not lvalues, we only have to handle it
5109 there and in function calls. */
5110 /* arrays can also be used although they are not lvalues */
5111 if ((vtop->t & VT_BTYPE) != VT_FUNC &&
5112 !(vtop->t & VT_ARRAY))
5113 test_lvalue();
5114 vtop->t = mk_pointer(vtop->t);
5115 gaddrof();
5116 } else
5117 if (t == '!') {
5118 unary();
5119 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
5120 vtop->c.i = !vtop->c.i;
5121 else if ((vtop->r & VT_VALMASK) == VT_CMP)
5122 vtop->c.i = vtop->c.i ^ 1;
5123 else
5124 vset(VT_INT, VT_JMP, gtst(1, 0));
5125 } else
5126 if (t == '~') {
5127 unary();
5128 vpushi(-1);
5129 gen_op('^');
5130 } else
5131 if (t == '+') {
5132 /* in order to force cast, we add zero */
5133 unary();
5134 if ((vtop->t & VT_BTYPE) == VT_PTR)
5135 error("pointer not accepted for unary plus");
5136 vpushi(0);
5137 gen_op('+');
5138 } else
5139 if (t == TOK_SIZEOF) {
5140 if (tok == '(') {
5141 next();
5142 if (parse_btype(&t, &ad)) {
5143 t = type_decl(&ad, &n, t, TYPE_ABSTRACT);
5144 } else {
5145 /* XXX: some code could be generated: add eval
5146 flag */
5147 gexpr();
5148 t = vtop->t;
5149 vpop();
5151 skip(')');
5152 } else {
5153 unary();
5154 t = vtop->t;
5155 vpop();
5157 vpushi(type_size(t, &t));
5158 } else
5159 if (t == TOK_INC || t == TOK_DEC) {
5160 unary();
5161 inc(0, t);
5162 } else if (t == '-') {
5163 vpushi(0);
5164 unary();
5165 gen_op('-');
5166 } else
5168 if (t < TOK_UIDENT)
5169 expect("identifier");
5170 s = sym_find(t);
5171 if (!s) {
5172 if (tok != '(')
5173 error("'%s' undeclared", get_tok_str(t, NULL));
5174 /* for simple function calls, we tolerate undeclared
5175 external reference to int() function */
5176 s = external_sym(t, func_old_type, 0);
5178 vset(s->t, s->r, s->c);
5179 /* if forward reference, we must point to s */
5180 if (vtop->r & VT_SYM)
5181 vtop->c.sym = s;
5185 /* post operations */
5186 while (1) {
5187 if (tok == TOK_INC || tok == TOK_DEC) {
5188 inc(1, tok);
5189 next();
5190 } else if (tok == '.' || tok == TOK_ARROW) {
5191 /* field */
5192 if (tok == TOK_ARROW)
5193 indir();
5194 test_lvalue();
5195 gaddrof();
5196 next();
5197 /* expect pointer on structure */
5198 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
5199 expect("struct or union");
5200 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5201 /* find field */
5202 tok |= SYM_FIELD;
5203 while ((s = s->next) != NULL) {
5204 if (s->v == tok)
5205 break;
5207 if (!s)
5208 error("field not found");
5209 /* add field offset to pointer */
5210 vtop->t = char_pointer_type; /* change type to 'char *' */
5211 vpushi(s->c);
5212 gen_op('+');
5213 /* change type to field type, and set to lvalue */
5214 vtop->t = s->t;
5215 /* an array is never an lvalue */
5216 if (!(vtop->t & VT_ARRAY))
5217 vtop->r |= lvalue_type(vtop->t);
5218 next();
5219 } else if (tok == '[') {
5220 next();
5221 gexpr();
5222 gen_op('+');
5223 indir();
5224 skip(']');
5225 } else if (tok == '(') {
5226 SValue ret;
5227 Sym *sa;
5229 /* function call */
5230 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
5231 /* pointer test (no array accepted) */
5232 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
5233 vtop->t = pointed_type(vtop->t);
5234 if ((vtop->t & VT_BTYPE) != VT_FUNC)
5235 goto error_func;
5236 } else {
5237 error_func:
5238 expect("function pointer");
5240 } else {
5241 vtop->r &= ~VT_LVAL; /* no lvalue */
5243 /* get return type */
5244 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
5245 save_regs(0); /* save used temporary registers */
5246 gfunc_start(&gf, s->r);
5247 next();
5248 sa = s->next; /* first parameter */
5249 #ifdef INVERT_FUNC_PARAMS
5251 int parlevel;
5252 Sym *args, *s1;
5253 ParseState saved_parse_state;
5254 TokenString str;
5256 /* read each argument and store it on a stack */
5257 /* XXX: merge it with macro args ? */
5258 args = NULL;
5259 if (tok != ')') {
5260 for(;;) {
5261 tok_str_new(&str);
5262 parlevel = 0;
5263 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
5264 tok != -1) {
5265 if (tok == '(')
5266 parlevel++;
5267 else if (tok == ')')
5268 parlevel--;
5269 tok_str_add_tok(&str);
5270 next();
5272 tok_str_add(&str, -1); /* end of file added */
5273 tok_str_add(&str, 0);
5274 s1 = sym_push2(&args, 0, 0, (int)str.str);
5275 s1->next = sa; /* add reference to argument */
5276 if (sa)
5277 sa = sa->next;
5278 if (tok == ')')
5279 break;
5280 skip(',');
5284 /* now generate code in reverse order by reading the stack */
5285 save_parse_state(&saved_parse_state);
5286 while (args) {
5287 macro_ptr = (int *)args->c;
5288 next();
5289 expr_eq();
5290 if (tok != -1)
5291 expect("',' or ')'");
5292 gfunc_param_typed(&gf, s, args->next);
5293 s1 = args->prev;
5294 tok_str_free((int *)args->c);
5295 tcc_free(args);
5296 args = s1;
5298 restore_parse_state(&saved_parse_state);
5300 #endif
5301 /* compute first implicit argument if a structure is returned */
5302 if ((s->t & VT_BTYPE) == VT_STRUCT) {
5303 /* get some space for the returned structure */
5304 size = type_size(s->t, &align);
5305 loc = (loc - size) & -align;
5306 ret.t = s->t;
5307 ret.r = VT_LOCAL | VT_LVAL;
5308 /* pass it as 'int' to avoid structure arg passing
5309 problems */
5310 vset(VT_INT, VT_LOCAL, loc);
5311 ret.c = vtop->c;
5312 gfunc_param(&gf);
5313 } else {
5314 ret.t = s->t;
5315 ret.r2 = VT_CONST;
5316 /* return in register */
5317 if (is_float(ret.t)) {
5318 ret.r = REG_FRET;
5319 } else {
5320 if ((ret.t & VT_BTYPE) == VT_LLONG)
5321 ret.r2 = REG_LRET;
5322 ret.r = REG_IRET;
5324 ret.c.i = 0;
5326 #ifndef INVERT_FUNC_PARAMS
5327 if (tok != ')') {
5328 for(;;) {
5329 expr_eq();
5330 gfunc_param_typed(&gf, s, sa);
5331 if (sa)
5332 sa = sa->next;
5333 if (tok == ')')
5334 break;
5335 skip(',');
5338 #endif
5339 if (sa)
5340 error("too few arguments to function");
5341 skip(')');
5342 gfunc_call(&gf);
5343 /* return value */
5344 vsetc(ret.t, ret.r, &ret.c);
5345 vtop->r2 = ret.r2;
5346 } else {
5347 break;
5352 void uneq(void)
5354 int t;
5356 unary();
5357 if (tok == '=' ||
5358 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5359 tok == TOK_A_XOR || tok == TOK_A_OR ||
5360 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5361 test_lvalue();
5362 t = tok;
5363 next();
5364 if (t == '=') {
5365 expr_eq();
5366 } else {
5367 vdup();
5368 expr_eq();
5369 gen_op(t & 0x7f);
5371 vstore();
5375 void sum(int l)
5377 int t;
5379 if (l == 0)
5380 uneq();
5381 else {
5382 sum(--l);
5383 while ((l == 0 && (tok == '*' || tok == '/' || tok == '%')) ||
5384 (l == 1 && (tok == '+' || tok == '-')) ||
5385 (l == 2 && (tok == TOK_SHL || tok == TOK_SAR)) ||
5386 (l == 3 && ((tok >= TOK_ULE && tok <= TOK_GT) ||
5387 tok == TOK_ULT || tok == TOK_UGE)) ||
5388 (l == 4 && (tok == TOK_EQ || tok == TOK_NE)) ||
5389 (l == 5 && tok == '&') ||
5390 (l == 6 && tok == '^') ||
5391 (l == 7 && tok == '|') ||
5392 (l == 8 && tok == TOK_LAND) ||
5393 (l == 9 && tok == TOK_LOR)) {
5394 t = tok;
5395 next();
5396 sum(l);
5397 gen_op(t);
5402 /* only used if non constant */
5403 void eand(void)
5405 int t;
5407 sum(8);
5408 t = 0;
5409 while (1) {
5410 if (tok != TOK_LAND) {
5411 if (t) {
5412 t = gtst(1, t);
5413 vset(VT_INT, VT_JMPI, t);
5415 break;
5417 t = gtst(1, t);
5418 next();
5419 sum(8);
5423 void eor(void)
5425 int t;
5427 eand();
5428 t = 0;
5429 while (1) {
5430 if (tok != TOK_LOR) {
5431 if (t) {
5432 t = gtst(0, t);
5433 vset(VT_INT, VT_JMP, t);
5435 break;
5437 t = gtst(0, t);
5438 next();
5439 eand();
5443 /* XXX: better constant handling */
5444 void expr_eq(void)
5446 int t, u, c, r1, r2, rc;
5448 if (const_wanted) {
5449 sum(10);
5450 if (tok == '?') {
5451 c = vtop->c.i;
5452 vpop();
5453 next();
5454 gexpr();
5455 t = vtop->c.i;
5456 vpop();
5457 skip(':');
5458 expr_eq();
5459 if (c)
5460 vtop->c.i = t;
5462 } else {
5463 eor();
5464 if (tok == '?') {
5465 next();
5466 save_regs(1); /* we need to save all registers here except
5467 at the top because it is a branch point */
5468 t = gtst(1, 0);
5469 gexpr();
5470 /* XXX: long long handling ? */
5471 rc = RC_INT;
5472 if (is_float(vtop->t))
5473 rc = RC_FLOAT;
5474 r1 = gv(rc);
5475 vtop--; /* no vpop so that FP stack is not flushed */
5476 skip(':');
5477 u = gjmp(0);
5479 gsym(t);
5480 expr_eq();
5481 r2 = gv(rc);
5482 move_reg(r1, r2);
5483 vtop->r = r1;
5484 gsym(u);
5489 void gexpr(void)
5491 while (1) {
5492 expr_eq();
5493 if (tok != ',')
5494 break;
5495 vpop();
5496 next();
5500 /* parse a constant expression and return value in vtop */
5501 void expr_const1(void)
5503 int a;
5504 a = const_wanted;
5505 const_wanted = 1;
5506 expr_eq();
5507 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
5508 expect("constant");
5509 const_wanted = a;
5512 /* parse an integer constant and return its value */
5513 int expr_const(void)
5515 int c;
5516 expr_const1();
5517 c = vtop->c.i;
5518 vpop();
5519 return c;
5522 /* return the label token if current token is a label, otherwise
5523 return zero */
5524 int is_label(void)
5526 int t;
5527 CValue c;
5529 /* fast test first */
5530 if (tok < TOK_UIDENT)
5531 return 0;
5532 /* no need to save tokc since we expect an identifier */
5533 t = tok;
5534 c = tokc;
5535 next();
5536 if (tok == ':') {
5537 next();
5538 return t;
5539 } else {
5540 /* XXX: may not work in all cases (macros ?) */
5541 tok1 = tok;
5542 tok1c = tokc;
5543 tok = t;
5544 tokc = c;
5545 return 0;
5549 void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
5551 int a, b, c, d;
5552 Sym *s;
5554 /* generate line number info */
5555 if (do_debug &&
5556 (last_line_num != file->line_num || last_ind != ind)) {
5557 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
5558 last_ind = ind;
5559 last_line_num = file->line_num;
5562 if (tok == TOK_IF) {
5563 /* if test */
5564 next();
5565 skip('(');
5566 gexpr();
5567 skip(')');
5568 a = gtst(1, 0);
5569 block(bsym, csym, case_sym, def_sym, case_reg);
5570 c = tok;
5571 if (c == TOK_ELSE) {
5572 next();
5573 d = gjmp(0);
5574 gsym(a);
5575 block(bsym, csym, case_sym, def_sym, case_reg);
5576 gsym(d); /* patch else jmp */
5577 } else
5578 gsym(a);
5579 } else if (tok == TOK_WHILE) {
5580 next();
5581 d = ind;
5582 skip('(');
5583 gexpr();
5584 skip(')');
5585 a = gtst(1, 0);
5586 b = 0;
5587 block(&a, &b, case_sym, def_sym, case_reg);
5588 gjmp_addr(d);
5589 gsym(a);
5590 gsym_addr(b, d);
5591 } else if (tok == '{') {
5592 next();
5593 /* declarations */
5594 s = local_stack.top;
5595 while (tok != '}') {
5596 decl(VT_LOCAL);
5597 if (tok != '}')
5598 block(bsym, csym, case_sym, def_sym, case_reg);
5600 /* pop locally defined symbols */
5601 sym_pop(&local_stack, s);
5602 next();
5603 } else if (tok == TOK_RETURN) {
5604 next();
5605 if (tok != ';') {
5606 gexpr();
5607 gen_assign_cast(func_vt);
5608 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
5609 /* if returning structure, must copy it to implicit
5610 first pointer arg location */
5611 vset(mk_pointer(func_vt), VT_LOCAL | VT_LVAL, func_vc);
5612 indir();
5613 vswap();
5614 /* copy structure value to pointer */
5615 vstore();
5616 } else if (is_float(func_vt)) {
5617 gv(RC_FRET);
5618 } else {
5619 gv(RC_IRET);
5621 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5623 skip(';');
5624 rsym = gjmp(rsym); /* jmp */
5625 } else if (tok == TOK_BREAK) {
5626 /* compute jump */
5627 if (!bsym)
5628 error("cannot break");
5629 *bsym = gjmp(*bsym);
5630 next();
5631 skip(';');
5632 } else if (tok == TOK_CONTINUE) {
5633 /* compute jump */
5634 if (!csym)
5635 error("cannot continue");
5636 *csym = gjmp(*csym);
5637 next();
5638 skip(';');
5639 } else if (tok == TOK_FOR) {
5640 int e;
5641 next();
5642 skip('(');
5643 if (tok != ';') {
5644 gexpr();
5645 vpop();
5647 skip(';');
5648 d = ind;
5649 c = ind;
5650 a = 0;
5651 b = 0;
5652 if (tok != ';') {
5653 gexpr();
5654 a = gtst(1, 0);
5656 skip(';');
5657 if (tok != ')') {
5658 e = gjmp(0);
5659 c = ind;
5660 gexpr();
5661 vpop();
5662 gjmp_addr(d);
5663 gsym(e);
5665 skip(')');
5666 block(&a, &b, case_sym, def_sym, case_reg);
5667 gjmp_addr(c);
5668 gsym(a);
5669 gsym_addr(b, c);
5670 } else
5671 if (tok == TOK_DO) {
5672 next();
5673 a = 0;
5674 b = 0;
5675 d = ind;
5676 block(&a, &b, case_sym, def_sym, case_reg);
5677 skip(TOK_WHILE);
5678 skip('(');
5679 gsym(b);
5680 gexpr();
5681 c = gtst(0, 0);
5682 gsym_addr(c, d);
5683 skip(')');
5684 gsym(a);
5685 skip(';');
5686 } else
5687 if (tok == TOK_SWITCH) {
5688 next();
5689 skip('(');
5690 gexpr();
5691 /* XXX: other types than integer */
5692 case_reg = gv(RC_INT);
5693 vpop();
5694 skip(')');
5695 a = 0;
5696 b = gjmp(0); /* jump to first case */
5697 c = 0;
5698 block(&a, csym, &b, &c, case_reg);
5699 /* if no default, jmp after switch */
5700 if (c == 0)
5701 c = ind;
5702 /* default label */
5703 gsym_addr(b, c);
5704 /* break label */
5705 gsym(a);
5706 } else
5707 if (tok == TOK_CASE) {
5708 int v1, v2;
5709 if (!case_sym)
5710 expect("switch");
5711 next();
5712 v1 = expr_const();
5713 v2 = v1;
5714 if (gnu_ext && tok == TOK_DOTS) {
5715 next();
5716 v2 = expr_const();
5717 if (v2 < v1)
5718 warning("empty case range");
5720 /* since a case is like a label, we must skip it with a jmp */
5721 b = gjmp(0);
5722 gsym(*case_sym);
5723 vset(VT_INT, case_reg, 0);
5724 vpushi(v1);
5725 if (v1 == v2) {
5726 gen_op(TOK_EQ);
5727 *case_sym = gtst(1, 0);
5728 } else {
5729 gen_op(TOK_GE);
5730 *case_sym = gtst(1, 0);
5731 vset(VT_INT, case_reg, 0);
5732 vpushi(v2);
5733 gen_op(TOK_LE);
5734 *case_sym = gtst(1, *case_sym);
5736 gsym(b);
5737 skip(':');
5738 block(bsym, csym, case_sym, def_sym, case_reg);
5739 } else
5740 if (tok == TOK_DEFAULT) {
5741 next();
5742 skip(':');
5743 if (!def_sym)
5744 expect("switch");
5745 if (*def_sym)
5746 error("too many 'default'");
5747 *def_sym = ind;
5748 block(bsym, csym, case_sym, def_sym, case_reg);
5749 } else
5750 if (tok == TOK_GOTO) {
5751 next();
5752 s = sym_find1(&label_stack, tok);
5753 /* put forward definition if needed */
5754 if (!s)
5755 s = sym_push1(&label_stack, tok, LABEL_FORWARD, 0);
5756 /* label already defined */
5757 if (s->t & LABEL_FORWARD)
5758 s->c = gjmp(s->c);
5759 else
5760 gjmp_addr(s->c);
5761 next();
5762 skip(';');
5763 } else {
5764 b = is_label();
5765 if (b) {
5766 /* label case */
5767 s = sym_find1(&label_stack, b);
5768 if (s) {
5769 if (!(s->t & LABEL_FORWARD))
5770 error("multiple defined label");
5771 gsym(s->c);
5772 s->c = ind;
5773 s->t = 0;
5774 } else {
5775 sym_push1(&label_stack, b, 0, ind);
5777 /* we accept this, but it is a mistake */
5778 if (tok == '}')
5779 warning("deprecated use of label at end of compound statement");
5780 else
5781 block(bsym, csym, case_sym, def_sym, case_reg);
5782 } else {
5783 /* expression case */
5784 if (tok != ';') {
5785 gexpr();
5786 vpop();
5788 skip(';');
5793 /* t is the array or struct type. c is the array or struct
5794 address. cur_index/cur_field is the pointer to the current
5795 value. 'size_only' is true if only size info is needed (only used
5796 in arrays) */
5797 void decl_designator(int t, Section *sec, unsigned long c,
5798 int *cur_index, Sym **cur_field,
5799 int size_only)
5801 Sym *s, *f;
5802 int notfirst, index, align, l;
5804 notfirst = 0;
5805 if (gnu_ext && (l = is_label()) != 0)
5806 goto struct_field;
5808 while (tok == '[' || tok == '.') {
5809 if (tok == '[') {
5810 if (!(t & VT_ARRAY))
5811 expect("array type");
5812 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5813 next();
5814 index = expr_const();
5815 if (index < 0 || (s->c >= 0 && index >= s->c))
5816 expect("invalid index");
5817 skip(']');
5818 if (!notfirst)
5819 *cur_index = index;
5820 t = pointed_type(t);
5821 c += index * type_size(t, &align);
5822 } else {
5823 next();
5824 l = tok;
5825 next();
5826 struct_field:
5827 if ((t & VT_BTYPE) != VT_STRUCT)
5828 expect("struct/union type");
5829 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5830 l |= SYM_FIELD;
5831 f = s->next;
5832 while (f) {
5833 if (f->v == l)
5834 break;
5835 f = f->next;
5837 if (!f)
5838 expect("field");
5839 if (!notfirst)
5840 *cur_field = f;
5841 t = f->t | (t & ~VT_TYPE);
5842 c += f->c;
5844 notfirst = 1;
5846 if (notfirst) {
5847 if (tok == '=') {
5848 next();
5849 } else {
5850 if (!gnu_ext)
5851 expect("=");
5853 } else {
5854 if (t & VT_ARRAY) {
5855 index = *cur_index;
5856 t = pointed_type(t);
5857 c += index * type_size(t, &align);
5858 } else {
5859 f = *cur_field;
5860 if (!f)
5861 error("too many field init");
5862 t = f->t | (t & ~VT_TYPE);
5863 c += f->c;
5866 decl_initializer(t, sec, c, 0, size_only);
5869 #define EXPR_VAL 0
5870 #define EXPR_CONST 1
5871 #define EXPR_ANY 2
5873 /* store a value or an expression directly in global data or in local array */
5874 void init_putv(int t, Section *sec, unsigned long c,
5875 int v, int expr_type)
5877 int saved_global_expr, bt;
5878 void *ptr;
5880 switch(expr_type) {
5881 case EXPR_VAL:
5882 vpushi(v);
5883 break;
5884 case EXPR_CONST:
5885 /* compound literals must be allocated globally in this case */
5886 saved_global_expr = global_expr;
5887 global_expr = 1;
5888 expr_const1();
5889 global_expr = saved_global_expr;
5890 break;
5891 case EXPR_ANY:
5892 expr_eq();
5893 break;
5896 if (sec) {
5897 /* XXX: not portable */
5898 /* XXX: generate error if incorrect relocation */
5899 gen_assign_cast(t);
5900 bt = t & VT_BTYPE;
5901 ptr = sec->data + c;
5902 if ((vtop->r & VT_SYM) &&
5903 (bt == VT_BYTE ||
5904 bt == VT_SHORT ||
5905 bt == VT_DOUBLE ||
5906 bt == VT_LDOUBLE ||
5907 bt == VT_LLONG))
5908 error("initializer element is not computable at load time");
5909 switch(bt) {
5910 case VT_BYTE:
5911 *(char *)ptr = vtop->c.i;
5912 break;
5913 case VT_SHORT:
5914 *(short *)ptr = vtop->c.i;
5915 break;
5916 case VT_DOUBLE:
5917 *(double *)ptr = vtop->c.d;
5918 break;
5919 case VT_LDOUBLE:
5920 *(long double *)ptr = vtop->c.ld;
5921 break;
5922 case VT_LLONG:
5923 *(long long *)ptr = vtop->c.ll;
5924 break;
5925 default:
5926 if (vtop->r & VT_SYM) {
5927 greloc(sec, vtop->c.sym, c, R_DATA_32);
5928 *(int *)ptr = 0;
5929 } else {
5930 *(int *)ptr = vtop->c.i;
5932 break;
5934 vtop--;
5935 } else {
5936 vset(t, VT_LOCAL, c);
5937 vswap();
5938 vstore();
5939 vpop();
5943 /* put zeros for variable based init */
5944 void init_putz(int t, Section *sec, unsigned long c, int size)
5946 GFuncContext gf;
5948 if (sec) {
5949 /* nothing to do because globals are already set to zero */
5950 } else {
5951 gfunc_start(&gf, FUNC_CDECL);
5952 vpushi(size);
5953 gfunc_param(&gf);
5954 vpushi(0);
5955 gfunc_param(&gf);
5956 vset(VT_INT, VT_LOCAL, c);
5957 gfunc_param(&gf);
5958 vpush_sym(func_old_type, TOK_memset);
5959 gfunc_call(&gf);
5963 /* 't' contains the type and storage info. 'c' is the offset of the
5964 object in section 'sec'. If 'sec' is NULL, it means stack based
5965 allocation. 'first' is true if array '{' must be read (multi
5966 dimension implicit array init handling). 'size_only' is true if
5967 size only evaluation is wanted (only for arrays). */
5968 void decl_initializer(int t, Section *sec, unsigned long c, 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 true, 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. */
6127 void decl_initializer_alloc(int t, AttributeDef *ad, int r, int has_init,
6128 int v, int scope)
6130 int size, align, addr, data_offset;
6131 int level;
6132 ParseState saved_parse_state;
6133 TokenString init_str;
6134 Section *sec;
6136 size = type_size(t, &align);
6137 /* If unknown size, we must evaluate it before
6138 evaluating initializers because
6139 initializers can generate global data too
6140 (e.g. string pointers or ISOC99 compound
6141 literals). It also simplifies local
6142 initializers handling */
6143 tok_str_new(&init_str);
6144 if (size < 0) {
6145 if (!has_init)
6146 error("unknown type size");
6147 /* get all init string */
6148 level = 0;
6149 while (level > 0 || (tok != ',' && tok != ';')) {
6150 if (tok < 0)
6151 error("unexpected end of file in initializer");
6152 tok_str_add_tok(&init_str);
6153 if (tok == '{')
6154 level++;
6155 else if (tok == '}') {
6156 if (level == 0)
6157 break;
6158 level--;
6160 next();
6162 tok_str_add(&init_str, -1);
6163 tok_str_add(&init_str, 0);
6165 /* compute size */
6166 save_parse_state(&saved_parse_state);
6168 macro_ptr = init_str.str;
6169 next();
6170 decl_initializer(t, NULL, 0, 1, 1);
6171 /* prepare second initializer parsing */
6172 macro_ptr = init_str.str;
6173 next();
6175 /* if still unknown size, error */
6176 size = type_size(t, &align);
6177 if (size < 0)
6178 error("unknown type size");
6180 /* take into account specified alignment if bigger */
6181 if (ad->aligned > align)
6182 align = ad->aligned;
6183 if ((r & VT_VALMASK) == VT_LOCAL) {
6184 sec = NULL;
6185 if (do_bounds_check && (t & VT_ARRAY))
6186 loc--;
6187 #ifdef TCC_TARGET_IL
6188 /* XXX: ugly patch to allocate local variables for IL, just
6189 for testing */
6190 addr = loc;
6191 loc++;
6192 #else
6193 loc = (loc - size) & -align;
6194 addr = loc;
6195 #endif
6196 /* handles bounds */
6197 /* XXX: currently, since we do only one pass, we cannot track
6198 '&' operators, so we add only arrays */
6199 if (do_bounds_check && (t & VT_ARRAY)) {
6200 unsigned long *bounds_ptr;
6201 /* add padding between regions */
6202 loc--;
6203 /* then add local bound info */
6204 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
6205 bounds_ptr[0] = addr;
6206 bounds_ptr[1] = size;
6208 } else {
6209 /* compute section */
6210 sec = ad->section;
6211 if (!sec) {
6212 if (has_init)
6213 sec = data_section;
6214 else
6215 sec = bss_section;
6217 data_offset = sec->data_offset;
6218 data_offset = (data_offset + align - 1) & -align;
6219 addr = data_offset;
6220 /* very important to increment global pointer at this time
6221 because initializers themselves can create new initializers */
6222 data_offset += size;
6223 /* add padding if bound check */
6224 if (do_bounds_check)
6225 data_offset++;
6226 sec->data_offset = data_offset;
6227 /* allocate section space to put the data */
6228 if (sec->sh_type != SHT_NOBITS &&
6229 data_offset > sec->data_allocated)
6230 section_realloc(sec, data_offset);
6232 if (!sec) {
6233 if (v) {
6234 /* local variable */
6235 sym_push(v, t, r, addr);
6236 } else {
6237 /* push local reference */
6238 vset(t, r, addr);
6240 } else {
6241 Sym *sym;
6243 if (v) {
6244 if (scope == VT_CONST) {
6245 /* global scope: see if already defined */
6246 sym = sym_find(v);
6247 if (!sym)
6248 goto do_def;
6249 if (!is_compatible_types(sym->t, t))
6250 error("incompatible types for redefinition of '%s'",
6251 get_tok_str(v, NULL));
6252 if (!(sym->t & VT_EXTERN))
6253 error("redefinition of '%s'", get_tok_str(v, NULL));
6254 sym->t &= ~VT_EXTERN;
6255 } else {
6256 do_def:
6257 sym = sym_push(v, t, r | VT_SYM, 0);
6259 put_extern_sym(sym, sec, addr, size);
6260 } else {
6261 CValue cval;
6263 /* push global reference */
6264 sym = get_sym_ref(t, sec, addr, size);
6265 cval.sym = sym;
6266 vsetc(t, VT_CONST | VT_SYM, &cval);
6269 /* handles bounds now because the symbol must be defined
6270 before for the relocation */
6271 if (do_bounds_check) {
6272 unsigned long *bounds_ptr;
6274 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
6275 /* then add global bound info */
6276 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
6277 bounds_ptr[0] = 0; /* relocated */
6278 bounds_ptr[1] = size;
6281 if (has_init) {
6282 decl_initializer(t, sec, addr, 1, 0);
6283 /* restore parse state if needed */
6284 if (init_str.str) {
6285 tok_str_free(init_str.str);
6286 restore_parse_state(&saved_parse_state);
6291 void put_func_debug(Sym *sym)
6293 char buf[512];
6295 /* stabs info */
6296 /* XXX: we put here a dummy type */
6297 snprintf(buf, sizeof(buf), "%s:%c1",
6298 funcname, sym->t & VT_STATIC ? 'f' : 'F');
6299 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
6300 cur_text_section, sym->c);
6301 last_ind = 0;
6302 last_line_num = 0;
6305 /* not finished : try to put some local vars in registers */
6306 //#define CONFIG_REG_VARS
6308 #ifdef CONFIG_REG_VARS
6309 void add_var_ref(int t)
6311 printf("%s:%d: &%s\n",
6312 file->filename, file->line_num,
6313 get_tok_str(t, NULL));
6316 /* first pass on a function with heuristic to extract variable usage
6317 and pointer references to local variables for register allocation */
6318 void analyse_function(void)
6320 int level, t;
6322 for(;;) {
6323 if (tok == -1)
6324 break;
6325 /* any symbol coming after '&' is considered as being a
6326 variable whose reference is taken. It is highly unaccurate
6327 but it is difficult to do better without a complete parse */
6328 if (tok == '&') {
6329 next();
6330 /* if '& number', then no need to examine next tokens */
6331 if (tok == TOK_CINT ||
6332 tok == TOK_CUINT ||
6333 tok == TOK_CLLONG ||
6334 tok == TOK_CULLONG) {
6335 continue;
6336 } else if (tok >= TOK_UIDENT) {
6337 /* if '& ident [' or '& ident ->', then ident address
6338 is not needed */
6339 t = tok;
6340 next();
6341 if (tok != '[' && tok != TOK_ARROW)
6342 add_var_ref(t);
6343 } else {
6344 level = 0;
6345 while (tok != '}' && tok != ';' &&
6346 !((tok == ',' || tok == ')') && level == 0)) {
6347 if (tok >= TOK_UIDENT) {
6348 add_var_ref(tok);
6349 } else if (tok == '(') {
6350 level++;
6351 } else if (tok == ')') {
6352 level--;
6354 next();
6357 } else {
6358 next();
6362 #endif
6364 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6365 void decl(int l)
6367 int t, b, v, has_init, r;
6368 Sym *sym;
6369 AttributeDef ad;
6371 while (1) {
6372 if (!parse_btype(&b, &ad)) {
6373 /* skip redundant ';' */
6374 /* XXX: find more elegant solution */
6375 if (tok == ';') {
6376 next();
6377 continue;
6379 /* special test for old K&R protos without explicit int
6380 type. Only accepted when defining global data */
6381 if (l == VT_LOCAL || tok < TOK_DEFINE)
6382 break;
6383 b = VT_INT;
6385 if (((b & VT_BTYPE) == VT_ENUM ||
6386 (b & VT_BTYPE) == VT_STRUCT) &&
6387 tok == ';') {
6388 /* we accept no variable after */
6389 next();
6390 continue;
6392 while (1) { /* iterate thru each declaration */
6393 t = type_decl(&ad, &v, b, TYPE_DIRECT);
6394 #if 0
6396 char buf[500];
6397 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6398 printf("type = '%s'\n", buf);
6400 #endif
6401 if (tok == '{') {
6402 #ifdef CONFIG_REG_VARS
6403 TokenString func_str;
6404 ParseState saved_parse_state;
6405 int block_level;
6406 #endif
6408 if (l == VT_LOCAL)
6409 error("cannot use local functions");
6410 if (!(t & VT_FUNC))
6411 expect("function definition");
6413 #ifdef CONFIG_REG_VARS
6414 /* parse all function code and record it */
6416 tok_str_new(&func_str);
6418 block_level = 0;
6419 for(;;) {
6420 int t;
6421 if (tok == -1)
6422 error("unexpected end of file");
6423 tok_str_add_tok(&func_str);
6424 t = tok;
6425 next();
6426 if (t == '{') {
6427 block_level++;
6428 } else if (t == '}') {
6429 block_level--;
6430 if (block_level == 0)
6431 break;
6434 tok_str_add(&func_str, -1);
6435 tok_str_add(&func_str, 0);
6437 save_parse_state(&saved_parse_state);
6439 macro_ptr = func_str.str;
6440 next();
6441 analyse_function();
6442 #endif
6444 /* compute text section */
6445 cur_text_section = ad.section;
6446 if (!cur_text_section)
6447 cur_text_section = text_section;
6448 ind = cur_text_section->data_offset;
6449 funcname = get_tok_str(v, NULL);
6450 sym = sym_find(v);
6451 if (sym) {
6452 /* if symbol is already defined, then put complete type */
6453 sym->t = t;
6454 } else {
6455 /* put function symbol */
6456 sym = sym_push1(&global_stack, v, t, 0);
6458 /* NOTE: we patch the symbol size later */
6459 put_extern_sym(sym, cur_text_section, ind, 0);
6460 func_ind = ind;
6461 sym->r = VT_SYM | VT_CONST;
6462 /* put debug symbol */
6463 if (do_debug)
6464 put_func_debug(sym);
6465 /* push a dummy symbol to enable local sym storage */
6466 sym_push1(&local_stack, 0, 0, 0);
6467 gfunc_prolog(t);
6468 loc = 0;
6469 rsym = 0;
6470 #ifdef CONFIG_REG_VARS
6471 macro_ptr = func_str.str;
6472 next();
6473 #endif
6474 block(NULL, NULL, NULL, NULL, 0);
6475 gsym(rsym);
6476 gfunc_epilog();
6477 cur_text_section->data_offset = ind;
6478 sym_pop(&label_stack, NULL); /* reset label stack */
6479 sym_pop(&local_stack, NULL); /* reset local stack */
6480 /* end of function */
6481 /* patch symbol size */
6482 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
6483 ind - func_ind;
6484 if (do_debug) {
6485 put_stabn(N_FUN, 0, 0, ind - func_ind);
6487 funcname = ""; /* for safety */
6488 func_vt = VT_VOID; /* for safety */
6489 ind = 0; /* for safety */
6491 #ifdef CONFIG_REG_VARS
6492 tok_str_free(func_str.str);
6493 restore_parse_state(&saved_parse_state);
6494 #endif
6495 break;
6496 } else {
6497 if (b & VT_TYPEDEF) {
6498 /* save typedefed type */
6499 /* XXX: test storage specifiers ? */
6500 sym_push(v, t | VT_TYPEDEF, 0, 0);
6501 } else if ((t & VT_BTYPE) == VT_FUNC) {
6502 /* external function definition */
6503 external_sym(v, t, 0);
6504 } else {
6505 /* not lvalue if array */
6506 r = 0;
6507 if (!(t & VT_ARRAY))
6508 r |= lvalue_type(t);
6509 if (b & VT_EXTERN) {
6510 /* external variable */
6511 external_sym(v, t, r);
6512 } else {
6513 if (t & VT_STATIC)
6514 r |= VT_CONST;
6515 else
6516 r |= l;
6517 has_init = (tok == '=');
6518 if (has_init)
6519 next();
6520 decl_initializer_alloc(t, &ad, r,
6521 has_init, v, l);
6524 if (tok != ',') {
6525 skip(';');
6526 break;
6528 next();
6534 /* compile the C file opened in 'file'. Return non zero if errors. */
6535 static int tcc_compile(TCCState *s)
6537 Sym *define_start;
6538 char buf[512];
6539 int p, section_sym;
6541 funcname = "";
6542 include_stack_ptr = include_stack;
6543 ifdef_stack_ptr = ifdef_stack;
6545 /* XXX: not ANSI compliant: bound checking says error */
6546 vtop = vstack - 1;
6547 anon_sym = SYM_FIRST_ANOM;
6549 /* file info: full path + filename */
6550 section_sym = 0; /* avoid warning */
6551 if (do_debug) {
6552 section_sym = put_elf_sym(symtab_section, 0, 0,
6553 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
6554 text_section->sh_num, NULL);
6555 getcwd(buf, sizeof(buf));
6556 pstrcat(buf, sizeof(buf), "/");
6557 put_stabs_r(buf, N_SO, 0, 0,
6558 text_section->data_offset, text_section, section_sym);
6559 put_stabs_r(file->filename, N_SO, 0, 0,
6560 text_section->data_offset, text_section, section_sym);
6562 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6563 symbols can be safely used */
6564 put_elf_sym(symtab_section, 0, 0,
6565 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
6566 SHN_ABS, file->filename);
6568 /* define common 'char *' type because it is often used internally
6569 for arrays and struct dereference */
6570 char_pointer_type = mk_pointer(VT_BYTE);
6571 /* define an old type function 'int func()' */
6572 p = anon_sym++;
6573 sym_push1(&global_stack, p, 0, FUNC_OLD);
6574 func_old_type = VT_FUNC | (p << VT_STRUCT_SHIFT);
6576 define_start = define_stack.top;
6577 inp();
6578 ch = '\n'; /* needed to parse correctly first preprocessor command */
6579 next();
6580 decl(VT_CONST);
6581 if (tok != -1)
6582 expect("declaration");
6584 /* end of translation unit info */
6585 if (do_debug) {
6586 put_stabs_r(NULL, N_SO, 0, 0,
6587 text_section->data_offset, text_section, section_sym);
6590 /* reset define stack, but leave -Dsymbols (may be incorrect if
6591 they are undefined) */
6592 sym_pop(&define_stack, define_start);
6594 sym_pop(&global_stack, NULL);
6596 return 0;
6599 int tcc_compile_string(TCCState *s, const char *str)
6601 BufferedFile bf1, *bf = &bf1;
6602 int ret;
6604 /* init file structure */
6605 bf->fd = -1;
6606 bf->buf_ptr = (char *)str;
6607 bf->buf_end = (char *)str + strlen(bf->buffer);
6608 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
6609 bf->line_num = 1;
6610 file = bf;
6612 ret = tcc_compile(s);
6614 /* currently, no need to close */
6615 return ret;
6618 /* define a symbol. A value can also be provided with the '=' operator */
6619 void tcc_define_symbol(TCCState *s, const char *sym, const char *value)
6621 BufferedFile bf1, *bf = &bf1;
6623 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
6624 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
6625 /* default value */
6626 if (!value)
6627 value = "1";
6628 pstrcat(bf->buffer, IO_BUF_SIZE, value);
6630 /* init file structure */
6631 bf->fd = -1;
6632 bf->buf_ptr = bf->buffer;
6633 bf->buf_end = bf->buffer + strlen(bf->buffer);
6634 bf->filename[0] = '\0';
6635 bf->line_num = 1;
6636 file = bf;
6638 include_stack_ptr = include_stack;
6640 /* parse with define parser */
6641 inp();
6642 ch = '\n'; /* needed to parse correctly first preprocessor command */
6643 next_nomacro();
6644 parse_define();
6645 file = NULL;
6648 void tcc_undefine_symbol(TCCState *s1, const char *sym)
6650 TokenSym *ts;
6651 Sym *s;
6652 ts = tok_alloc(sym, 0);
6653 s = sym_find1(&define_stack, tok);
6654 /* undefine symbol by putting an invalid name */
6655 if (s)
6656 sym_undef(&define_stack, s);
6659 #include "tccelf.c"
6661 /* print the position in the source file of PC value 'pc' by reading
6662 the stabs debug information */
6663 static void rt_printline(unsigned long wanted_pc)
6665 Stab_Sym *sym, *sym_end;
6666 char func_name[128], last_func_name[128];
6667 unsigned long func_addr, last_pc, pc;
6668 const char *incl_files[INCLUDE_STACK_SIZE];
6669 int incl_index, len, last_line_num, i;
6670 const char *str, *p;
6672 func_name[0] = '\0';
6673 func_addr = 0;
6674 incl_index = 0;
6675 last_func_name[0] = '\0';
6676 last_pc = 0xffffffff;
6677 last_line_num = 1;
6678 sym = (Stab_Sym *)stab_section->data + 1;
6679 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
6680 while (sym < sym_end) {
6681 switch(sym->n_type) {
6682 /* function start or end */
6683 case N_FUN:
6684 if (sym->n_strx == 0) {
6685 func_name[0] = '\0';
6686 func_addr = 0;
6687 } else {
6688 str = stabstr_section->data + sym->n_strx;
6689 p = strchr(str, ':');
6690 if (!p) {
6691 pstrcpy(func_name, sizeof(func_name), str);
6692 } else {
6693 len = p - str;
6694 if (len > sizeof(func_name) - 1)
6695 len = sizeof(func_name) - 1;
6696 memcpy(func_name, str, len);
6697 func_name[len] = '\0';
6699 func_addr = sym->n_value;
6701 break;
6702 /* line number info */
6703 case N_SLINE:
6704 pc = sym->n_value + func_addr;
6705 if (wanted_pc >= last_pc && wanted_pc < pc)
6706 goto found;
6707 last_pc = pc;
6708 last_line_num = sym->n_desc;
6709 /* XXX: slow! */
6710 strcpy(last_func_name, func_name);
6711 break;
6712 /* include files */
6713 case N_BINCL:
6714 str = stabstr_section->data + sym->n_strx;
6715 add_incl:
6716 if (incl_index < INCLUDE_STACK_SIZE) {
6717 incl_files[incl_index++] = str;
6719 break;
6720 case N_EINCL:
6721 if (incl_index > 1)
6722 incl_index--;
6723 break;
6724 case N_SO:
6725 if (sym->n_strx == 0) {
6726 incl_index = 0; /* end of translation unit */
6727 } else {
6728 str = stabstr_section->data + sym->n_strx;
6729 /* do not add path */
6730 len = strlen(str);
6731 if (len > 0 && str[len - 1] != '/')
6732 goto add_incl;
6734 break;
6736 sym++;
6738 /* did not find line number info: */
6739 fprintf(stderr, "(no debug info, pc=0x%08lx): ", wanted_pc);
6740 return;
6741 found:
6742 for(i = 0; i < incl_index - 1; i++)
6743 fprintf(stderr, "In file included from %s\n",
6744 incl_files[i]);
6745 if (incl_index > 0) {
6746 fprintf(stderr, "%s:%d: ",
6747 incl_files[incl_index - 1], last_line_num);
6749 if (last_func_name[0] != '\0') {
6750 fprintf(stderr, "in function '%s()': ", last_func_name);
6754 /* emit a run time error at position 'pc' */
6755 void rt_error(unsigned long pc, const char *fmt, ...)
6757 va_list ap;
6758 va_start(ap, fmt);
6760 rt_printline(pc);
6761 vfprintf(stderr, fmt, ap);
6762 fprintf(stderr, "\n");
6763 exit(255);
6764 va_end(ap);
6767 #ifndef WIN32
6768 /* signal handler for fatal errors */
6769 static void sig_error(int signum, siginfo_t *siginf, void *puc)
6771 struct ucontext *uc = puc;
6772 unsigned long pc;
6774 #ifdef __i386__
6775 pc = uc->uc_mcontext.gregs[14];
6776 #else
6777 #error please put the right sigcontext field
6778 #endif
6780 switch(signum) {
6781 case SIGFPE:
6782 switch(siginf->si_code) {
6783 case FPE_INTDIV:
6784 case FPE_FLTDIV:
6785 rt_error(pc, "division by zero");
6786 break;
6787 default:
6788 rt_error(pc, "floating point exception");
6789 break;
6791 break;
6792 case SIGBUS:
6793 case SIGSEGV:
6794 rt_error(pc, "dereferencing invalid pointer");
6795 break;
6796 case SIGILL:
6797 rt_error(pc, "illegal instruction");
6798 break;
6799 case SIGABRT:
6800 rt_error(pc, "abort() called");
6801 break;
6802 default:
6803 rt_error(pc, "caught signal %d", signum);
6804 break;
6806 exit(255);
6808 #endif
6810 /* launch the compiled program with the given arguments */
6811 int tcc_run(TCCState *s1, int argc, char **argv)
6813 Section *s;
6814 int (*prog_main)(int, char **);
6815 int i;
6817 tcc_add_runtime(s1);
6819 relocate_common_syms();
6821 /* compute relocation address : section are relocated in place. We
6822 also alloc the bss space */
6823 for(i = 1; i < nb_sections; i++) {
6824 s = sections[i];
6825 if (s->sh_flags & SHF_ALLOC) {
6826 void *data;
6827 if (s->sh_type == SHT_NOBITS) {
6828 data = tcc_mallocz(s->data_offset);
6829 } else {
6830 data = s->data;
6832 s->sh_addr = (unsigned long)data;
6836 relocate_syms(1);
6838 /* relocate each section */
6839 for(i = 1; i < nb_sections; i++) {
6840 s = sections[i];
6841 if (s->reloc)
6842 relocate_section(s1, s);
6845 prog_main = (void *)get_elf_sym_val("main");
6847 if (do_debug) {
6848 #ifdef WIN32
6849 error("debug mode currently not available for Windows");
6850 #else
6851 struct sigaction sigact;
6852 /* install TCC signal handlers to print debug info on fatal
6853 runtime errors */
6854 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
6855 sigact.sa_sigaction = sig_error;
6856 sigemptyset(&sigact.sa_mask);
6857 sigaction(SIGFPE, &sigact, NULL);
6858 sigaction(SIGILL, &sigact, NULL);
6859 sigaction(SIGSEGV, &sigact, NULL);
6860 sigaction(SIGBUS, &sigact, NULL);
6861 sigaction(SIGABRT, &sigact, NULL);
6862 #endif
6865 #ifdef CONFIG_TCC_BCHECK
6866 if (do_bounds_check) {
6867 void (*bound_init)(void);
6868 void **bound_error_func;
6870 /* set error function */
6871 bound_error_func = (void **)get_elf_sym_val("__bound_error_func");
6872 *bound_error_func = rt_error;
6874 /* XXX: use .init section so that it also work in binary ? */
6875 bound_init = (void *)get_elf_sym_val("__bound_init");
6876 bound_init();
6878 #endif
6879 return (*prog_main)(argc, argv);
6882 TCCState *tcc_new(void)
6884 char *p, *r;
6885 TCCState *s;
6887 s = tcc_malloc(sizeof(TCCState));
6888 if (!s)
6889 return NULL;
6890 s->output_type = TCC_OUTPUT_MEMORY;
6892 /* default include paths */
6893 tcc_add_sysinclude_path(s, "/usr/local/include");
6894 tcc_add_sysinclude_path(s, "/usr/include");
6895 tcc_add_sysinclude_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
6897 /* add all tokens */
6898 tok_ident = TOK_IDENT;
6899 p = tcc_keywords;
6900 while (*p) {
6901 r = p;
6902 while (*r++);
6903 tok_alloc(p, r - p - 1);
6904 p = r;
6907 /* standard defines */
6908 tcc_define_symbol(s, "__STDC__", NULL);
6909 #if defined(TCC_TARGET_I386)
6910 tcc_define_symbol(s, "__i386__", NULL);
6911 #endif
6912 /* tiny C specific defines */
6913 tcc_define_symbol(s, "__TINYC__", NULL);
6915 /* default library paths */
6916 tcc_add_library_path(s, "/usr/local/lib");
6917 tcc_add_library_path(s, "/usr/lib");
6918 tcc_add_library_path(s, "/lib");
6920 /* no section zero */
6921 dynarray_add((void ***)&sections, &nb_sections, NULL);
6923 /* create standard sections */
6924 text_section = new_section(".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
6925 data_section = new_section(".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
6926 bss_section = new_section(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
6928 /* symbols are always generated for linking stage */
6929 symtab_section = new_symtab(".symtab", SHT_SYMTAB, 0,
6930 ".strtab",
6931 ".hashtab", SHF_PRIVATE);
6932 strtab_section = symtab_section->link;
6934 /* private symbol table for dynamic symbols */
6935 dynsymtab_section = new_symtab(".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
6936 ".dynstrtab",
6937 ".dynhashtab", SHF_PRIVATE);
6938 return s;
6941 void tcc_delete(TCCState *s)
6943 tcc_free(s);
6946 int tcc_add_include_path(TCCState *s, const char *pathname)
6948 char *pathname1;
6950 pathname1 = tcc_strdup(pathname);
6951 dynarray_add((void ***)&include_paths, &nb_include_paths, pathname1);
6952 return 0;
6955 int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
6957 char *pathname1;
6959 pathname1 = tcc_strdup(pathname);
6960 dynarray_add((void ***)&sysinclude_paths, &nb_sysinclude_paths, pathname1);
6961 return 0;
6964 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags)
6966 const char *ext;
6967 Elf32_Ehdr ehdr;
6968 int fd;
6969 BufferedFile *saved_file;
6971 /* find source file type with extension */
6972 ext = strrchr(filename, '.');
6973 if (ext)
6974 ext++;
6976 /* open the file */
6977 saved_file = file;
6978 file = tcc_open(filename);
6979 if (!file) {
6980 if (flags & AFF_PRINT_ERROR) {
6981 error("file '%s' not found", filename);
6982 } else {
6983 file = saved_file;
6984 return -1;
6988 if (!ext || !strcmp(ext, "c")) {
6989 /* C file assumed */
6990 tcc_compile(s);
6991 } else {
6992 fd = file->fd;
6993 /* assume executable format: auto guess file type */
6994 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
6995 error("could not read header");
6996 lseek(fd, 0, SEEK_SET);
6998 if (ehdr.e_ident[0] == ELFMAG0 &&
6999 ehdr.e_ident[1] == ELFMAG1 &&
7000 ehdr.e_ident[2] == ELFMAG2 &&
7001 ehdr.e_ident[3] == ELFMAG3) {
7002 file->line_num = 0; /* do not display line number if error */
7003 if (ehdr.e_type == ET_REL) {
7004 tcc_load_object_file(s, fd, 0);
7005 } else if (ehdr.e_type == ET_DYN) {
7006 tcc_load_dll(s, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
7007 } else {
7008 error("unrecognized ELF file");
7010 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
7011 file->line_num = 0; /* do not display line number if error */
7012 tcc_load_archive(s, fd);
7013 } else {
7014 /* as GNU ld, consider it is an ld script if not recognized */
7015 if (tcc_load_ldscript(s) < 0)
7016 error("unrecognized file type");
7019 tcc_close(file);
7020 file = saved_file;
7021 return 0;
7024 void tcc_add_file(TCCState *s, const char *filename)
7026 tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
7029 int tcc_add_library_path(TCCState *s, const char *pathname)
7031 char *pathname1;
7033 pathname1 = tcc_strdup(pathname);
7034 dynarray_add((void ***)&library_paths, &nb_library_paths, pathname1);
7035 return 0;
7038 /* find and load a dll. Return non zero if not found */
7039 /* XXX: add '-rpath' option support ? */
7040 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
7042 char buf[1024];
7043 int i;
7045 for(i = 0; i < nb_library_paths; i++) {
7046 snprintf(buf, sizeof(buf), "%s/%s",
7047 library_paths[i], filename);
7048 if (tcc_add_file_internal(s, buf, flags) == 0)
7049 return 0;
7051 return -1;
7054 /* the library name is the same as the argument of the '-l' option */
7055 int tcc_add_library(TCCState *s, const char *libraryname)
7057 char buf[1024];
7058 int i;
7059 void *h;
7061 /* if we output to memory, then we simply we dlopen(). */
7062 if (s->output_type == TCC_OUTPUT_MEMORY) {
7063 /* Since the libc is already loaded, we don't need to load it again */
7064 if (!strcmp(libraryname, "c"))
7065 return 0;
7066 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
7067 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
7068 if (!h)
7069 return -1;
7070 return 0;
7073 /* first we look for the dynamic library if not static linking */
7074 if (!static_link) {
7075 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
7076 if (tcc_add_dll(s, buf, 0) == 0)
7077 return 0;
7080 /* then we look for the static library */
7081 for(i = 0; i < nb_library_paths; i++) {
7082 snprintf(buf, sizeof(buf), "%s/lib%s.a",
7083 library_paths[i], libraryname);
7084 if (tcc_add_file_internal(s, buf, 0) == 0)
7085 return 0;
7087 return -1;
7090 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
7092 add_elf_sym(symtab_section, val, 0,
7093 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7094 SHN_ABS, name);
7095 return 0;
7098 int tcc_set_output_type(TCCState *s, int output_type)
7100 s->output_type = output_type;
7102 /* if bound checking, then add corresponding sections */
7103 #ifdef CONFIG_TCC_BCHECK
7104 if (do_bounds_check) {
7105 /* define symbol */
7106 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
7107 /* create bounds sections */
7108 bounds_section = new_section(".bounds",
7109 SHT_PROGBITS, SHF_ALLOC);
7110 lbounds_section = new_section(".lbounds",
7111 SHT_PROGBITS, SHF_ALLOC);
7113 #endif
7115 /* add debug sections */
7116 if (do_debug) {
7117 /* stab symbols */
7118 stab_section = new_section(".stab", SHT_PROGBITS, 0);
7119 stab_section->sh_entsize = sizeof(Stab_Sym);
7120 stabstr_section = new_section(".stabstr", SHT_STRTAB, 0);
7121 put_elf_str(stabstr_section, "");
7122 stab_section->link = stabstr_section;
7123 /* put first entry */
7124 put_stabs("", 0, 0, 0, 0);
7127 /* add libc crt1/crti objects */
7128 if (output_type == TCC_OUTPUT_EXE ||
7129 output_type == TCC_OUTPUT_DLL) {
7130 if (output_type != TCC_OUTPUT_DLL)
7131 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
7132 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
7134 return 0;
7137 #if !defined(LIBTCC)
7139 void help(void)
7141 printf("tcc version 0.9.10pre1 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7142 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7143 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
7144 " [--] infile1 [infile2... --] [infile_args...]\n"
7145 "\n"
7146 "General options:\n"
7147 " -c compile only - generate an object file\n"
7148 " -o outfile set output filename\n"
7149 " -- allows multiples input files if no -o option given. Also\n"
7150 " separate input files from runtime arguments\n"
7151 " -Bdir set tcc internal library path\n"
7152 " -bench output compilation statistics\n"
7153 "Preprocessor options:\n"
7154 " -Idir add include path 'dir'\n"
7155 " -Dsym[=val] define 'sym' with value 'val'\n"
7156 " -Usym undefine 'sym'\n"
7157 "C compiler options:\n"
7158 " -g generate runtime debug info\n"
7159 #ifdef CONFIG_TCC_BCHECK
7160 " -b compile with built-in memory and bounds checker (implies -g)\n"
7161 #endif
7162 "Linker options:\n"
7163 " -Ldir add library path 'dir'\n"
7164 " -llib link with dynamic or static library 'lib'\n"
7165 " -shared generate a shared library\n"
7166 " -static static linking\n"
7170 int main(int argc, char **argv)
7172 char *r, *outfile;
7173 int optind, output_type, multiple_files, i;
7174 TCCState *s;
7175 char **libraries;
7176 int nb_libraries;
7178 s = tcc_new();
7179 output_type = TCC_OUTPUT_MEMORY;
7181 optind = 1;
7182 outfile = NULL;
7183 multiple_files = 0;
7184 libraries = NULL;
7185 nb_libraries = 0;
7186 while (1) {
7187 if (optind >= argc) {
7188 show_help:
7189 help();
7190 return 1;
7192 r = argv[optind];
7193 if (r[0] != '-')
7194 break;
7195 optind++;
7196 if (r[1] == '-') {
7197 /* '--' enables multiple files input */
7198 multiple_files = 1;
7199 } else if (r[1] == 'h' || r[1] == '?') {
7200 goto show_help;
7201 } else if (r[1] == 'I') {
7202 if (tcc_add_include_path(s, r + 2) < 0)
7203 error("too many include paths");
7204 } else if (r[1] == 'D') {
7205 char *sym, *value;
7206 sym = r + 2;
7207 value = strchr(sym, '=');
7208 if (value) {
7209 *value = '\0';
7210 value++;
7212 tcc_define_symbol(s, sym, value);
7213 } else if (r[1] == 'U') {
7214 tcc_undefine_symbol(s, r + 2);
7215 } else if (r[1] == 'L') {
7216 tcc_add_library_path(s, r + 2);
7217 } else if (r[1] == 'B') {
7218 /* set tcc utilities path (mainly for tcc development) */
7219 tcc_lib_path = r + 2;
7220 } else if (r[1] == 'l') {
7221 dynarray_add((void ***)&libraries, &nb_libraries, r + 2);
7222 } else if (!strcmp(r + 1, "bench")) {
7223 do_bench = 1;
7224 } else
7225 #ifdef CONFIG_TCC_BCHECK
7226 if (r[1] == 'b') {
7227 do_bounds_check = 1;
7228 do_debug = 1;
7229 } else
7230 #endif
7231 if (r[1] == 'g') {
7232 do_debug = 1;
7233 } else if (r[1] == 'c') {
7234 multiple_files = 1;
7235 output_type = TCC_OUTPUT_OBJ;
7236 } else if (!strcmp(r + 1, "static")) {
7237 static_link = 1;
7238 } else if (!strcmp(r + 1, "shared")) {
7239 output_type = TCC_OUTPUT_DLL;
7240 } else if (r[1] == 'o') {
7241 if (optind >= argc)
7242 goto show_help;
7243 multiple_files = 1;
7244 outfile = argv[optind++];
7245 } else {
7246 error("invalid option -- '%s'", r);
7250 /* if outfile provided without other options, we output an
7251 executable */
7252 if (outfile && output_type == TCC_OUTPUT_MEMORY)
7253 output_type = TCC_OUTPUT_EXE;
7255 tcc_set_output_type(s, output_type);
7257 tcc_add_file(s, argv[optind]);
7258 if (multiple_files) {
7259 while ((optind + 1) < argc) {
7260 optind++;
7261 r = argv[optind];
7262 if (r[0] == '-') {
7263 if (r[1] != '-')
7264 error("'--' expected");
7265 break;
7267 tcc_add_file(s, r);
7271 /* add specified libraries */
7272 for(i = 0; i < nb_libraries;i++) {
7273 if (tcc_add_library(s, libraries[i]) < 0)
7274 error("cannot find -l%s", libraries[i]);
7277 if (do_bench) {
7278 printf("total: %d idents, %d lines, %d bytes\n",
7279 tok_ident - TOK_IDENT, total_lines, total_bytes);
7280 #ifdef MEM_DEBUG
7281 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
7282 #endif
7285 if (s->output_type != TCC_OUTPUT_MEMORY) {
7286 tcc_output_file(s, outfile);
7287 return 0;
7288 } else {
7289 return tcc_run(s, argc - optind, argv + optind);
7293 #endif