ignore some gcc options - removed many memory leaks - suppressed many global variables
[tinycc.git] / tcc.c
bloba3cae7eaf51873b8f9ad2aaa315565e6331e4954
1 /*
2 * TCC - Tiny C Compiler
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <math.h>
26 #include <unistd.h>
27 #include <signal.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <setjmp.h>
31 #ifndef WIN32
32 #include <sys/ucontext.h>
33 #endif
34 #include "elf.h"
35 #include "stab.h"
36 #ifndef CONFIG_TCC_STATIC
37 #include <dlfcn.h>
38 #endif
40 #include "libtcc.h"
42 //#define DEBUG
43 /* preprocessor debug */
44 //#define PP_DEBUG
45 /* include file debug */
46 //#define INC_DEBUG
48 //#define MEM_DEBUG
50 /* target selection */
51 //#define TCC_TARGET_I386 /* i386 code generator */
52 //#define TCC_TARGET_IL /* .NET CLI generator */
54 /* default target is I386 */
55 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
56 #define TCC_TARGET_I386
57 #endif
59 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
60 #define CONFIG_TCC_BCHECK /* enable bound checking code */
61 #endif
63 #ifndef CONFIG_TCC_PREFIX
64 #define CONFIG_TCC_PREFIX "/usr/local"
65 #endif
67 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
68 executables or dlls */
69 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
71 #define INCLUDE_STACK_SIZE 32
72 #define IFDEF_STACK_SIZE 64
73 #define VSTACK_SIZE 64
74 #define STRING_MAX_SIZE 1024
76 #define TOK_HASH_SIZE 2048 /* must be a power of two */
77 #define TOK_ALLOC_INCR 512 /* must be a power of two */
78 #define SYM_HASH_SIZE 1031
80 /* token symbol management */
81 typedef struct TokenSym {
82 struct TokenSym *hash_next;
83 int tok; /* token number */
84 int len;
85 char str[1];
86 } TokenSym;
88 typedef struct CString {
89 int size; /* size in bytes */
90 void *data; /* either 'char *' or 'int *' */
91 int size_allocated;
92 void *data_allocated; /* if non NULL, data has been malloced */
93 } CString;
95 /* constant value */
96 typedef union CValue {
97 long double ld;
98 double d;
99 float f;
100 int i;
101 unsigned int ui;
102 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
103 long long ll;
104 unsigned long long ull;
105 struct CString *cstr;
106 void *ptr;
107 int tab[1];
108 } CValue;
110 /* value on stack */
111 typedef struct SValue {
112 int t; /* type */
113 unsigned short r; /* register + flags */
114 unsigned short r2; /* second register, used for 'long long'
115 type. If not used, set to VT_CONST */
116 CValue c; /* constant, if VT_CONST */
117 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
118 } SValue;
120 /* symbol management */
121 typedef struct Sym {
122 int v; /* symbol token */
123 int t; /* associated type */
124 int r; /* associated register */
125 int c; /* associated number */
126 struct Sym *next; /* next related symbol */
127 struct Sym *prev; /* prev symbol in stack */
128 struct Sym *hash_next; /* next symbol in hash table */
129 } Sym;
131 typedef struct SymStack {
132 struct Sym *top;
133 struct Sym *hash[SYM_HASH_SIZE];
134 } SymStack;
136 /* section definition */
137 /* XXX: use directly ELF structure for parameters ? */
138 /* special flag to indicate that the section should not be linked to
139 the other ones */
140 #define SHF_PRIVATE 0x80000000
142 typedef struct Section {
143 unsigned long data_offset; /* current data offset */
144 unsigned char *data; /* section data */
145 unsigned long data_allocated; /* used for realloc() handling */
146 int sh_name; /* elf section name (only used during output) */
147 int sh_num; /* elf section number */
148 int sh_type; /* elf section type */
149 int sh_flags; /* elf section flags */
150 int sh_info; /* elf section info */
151 int sh_addralign; /* elf section alignment */
152 int sh_entsize; /* elf entry size */
153 unsigned long sh_size; /* section size (only used during output) */
154 unsigned long sh_addr; /* address at which the section is relocated */
155 unsigned long sh_offset; /* address at which the section is relocated */
156 int nb_hashed_syms; /* used to resize the hash table */
157 struct Section *link; /* link to another section */
158 struct Section *reloc; /* corresponding section for relocation, if any */
159 struct Section *hash; /* hash table for symbols */
160 struct Section *next;
161 char name[64]; /* section name */
162 } Section;
164 typedef struct DLLReference {
165 int level;
166 char name[1];
167 } DLLReference;
169 /* GNUC attribute definition */
170 typedef struct AttributeDef {
171 int aligned;
172 Section *section;
173 unsigned char func_call; /* FUNC_CDECL or FUNC_STDCALL */
174 } AttributeDef;
176 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
177 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
178 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
180 /* stored in 'Sym.c' field */
181 #define FUNC_NEW 1 /* ansi function prototype */
182 #define FUNC_OLD 2 /* old function prototype */
183 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
185 /* stored in 'Sym.r' field */
186 #define FUNC_CDECL 0 /* standard c call */
187 #define FUNC_STDCALL 1 /* pascal c call */
189 /* field 'Sym.t' for macros */
190 #define MACRO_OBJ 0 /* object like macro */
191 #define MACRO_FUNC 1 /* function like macro */
193 /* field 'Sym.t' for labels */
194 #define LABEL_FORWARD 1 /* label is forward defined */
196 /* type_decl() types */
197 #define TYPE_ABSTRACT 1 /* type without variable */
198 #define TYPE_DIRECT 2 /* type with variable */
200 #define IO_BUF_SIZE 8192
202 typedef struct BufferedFile {
203 unsigned char *buf_ptr;
204 unsigned char *buf_end;
205 int fd;
206 int line_num; /* current line number - here to simply code */
207 int ifndef_macro; /*'#ifndef macro \n #define macro' search */
208 int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
209 char inc_type; /* type of include */
210 char inc_filename[512]; /* filename specified by the user */
211 char filename[1024]; /* current filename - here to simplify code */
212 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
213 } BufferedFile;
215 #define CH_EOB 0 /* end of buffer or '\0' char in file */
216 #define CH_EOF (-1) /* end of file */
218 /* parsing state (used to save parser state to reparse part of the
219 source several times) */
220 typedef struct ParseState {
221 int *macro_ptr;
222 int line_num;
223 int tok;
224 CValue tokc;
225 } ParseState;
227 /* used to record tokens */
228 typedef struct TokenString {
229 int *str;
230 int len;
231 int last_line_num;
232 } TokenString;
234 /* include file cache, used to find files faster and also to eliminate
235 inclusion if the include file is protected by #ifndef ... #endif */
236 typedef struct CachedInclude {
237 int ifndef_macro;
238 char type; /* '"' or '>' to give include type */
239 char filename[1]; /* path specified in #include */
240 } CachedInclude;
242 /* parser */
243 struct BufferedFile *file;
244 int ch, ch1, tok, tok1;
245 CValue tokc, tok1c;
246 CString tokcstr; /* current parsed string, if any */
247 /* if true, line feed is returned as a token. line feed is also
248 returned at eof */
249 int return_linefeed;
250 /* set to TRUE if eof was reached */
251 int eof_seen;
252 Section *text_section, *data_section, *bss_section; /* predefined sections */
253 Section *cur_text_section; /* current section where function code is
254 generated */
255 /* bound check related sections */
256 Section *bounds_section; /* contains global data bound description */
257 Section *lbounds_section; /* contains local data bound description */
258 /* symbol sections */
259 Section *symtab_section, *strtab_section;
261 /* debug sections */
262 Section *stab_section, *stabstr_section;
264 /* loc : local variable index
265 ind : output code index
266 rsym: return symbol
267 anon_sym: anonymous symbol index
269 int rsym, anon_sym,
270 prog, ind, loc;
271 /* expression generation modifiers */
272 int const_wanted; /* true if constant wanted */
273 int global_expr; /* true if compound literals must be allocated
274 globally (used during initializers parsing */
275 int func_vt, func_vc; /* current function return type (used by
276 return instruction) */
277 int last_line_num, last_ind, func_ind; /* debug last line number and pc */
278 int tok_ident;
279 TokenSym **table_ident;
280 TokenSym *hash_ident[TOK_HASH_SIZE];
281 char token_buf[STRING_MAX_SIZE + 1];
282 char *funcname;
283 SymStack define_stack, global_stack, local_stack, label_stack;
285 SValue vstack[VSTACK_SIZE], *vtop;
286 int *macro_ptr, *macro_ptr_allocated;
287 int char_pointer_type;
288 int func_old_type;
290 /* compile with debug symbol (and use them if error during execution) */
291 int do_debug = 0;
293 /* compile with built-in memory and bounds checker */
294 int do_bounds_check = 0;
296 /* display benchmark infos */
297 int do_bench = 0;
298 int total_lines;
299 int total_bytes;
301 /* use GNU C extensions */
302 int gnu_ext = 1;
304 /* use Tiny C extensions */
305 int tcc_ext = 1;
307 /* XXX: suppress that ASAP */
308 static struct TCCState *tcc_state;
310 /* give the path of the tcc libraries */
311 static const char *tcc_lib_path = CONFIG_TCC_PREFIX "/lib/tcc";
313 struct TCCState {
314 int output_type;
316 BufferedFile **include_stack_ptr;
317 int *ifdef_stack_ptr;
319 /* include file handling */
320 char **include_paths;
321 int nb_include_paths;
322 char **sysinclude_paths;
323 int nb_sysinclude_paths;
324 CachedInclude **cached_includes;
325 int nb_cached_includes;
327 char **library_paths;
328 int nb_library_paths;
330 /* array of all loaded dlls (including those referenced by loaded
331 dlls) */
332 DLLReference **loaded_dlls;
333 int nb_loaded_dlls;
335 /* sections */
336 Section **sections;
337 int nb_sections; /* number of sections, including first dummy section */
339 /* got handling */
340 Section *got;
341 unsigned long *got_offsets;
342 int nb_got_offsets;
343 int nb_plt_entries;
344 /* give the correspondance from symtab indexes to dynsym indexes */
345 int *symtab_to_dynsym;
347 /* temporary dynamic symbol sections (for dll loading) */
348 Section *dynsymtab_section;
349 /* exported dynamic symbol section */
350 Section *dynsym;
352 /* if true, static linking is performed */
353 int static_link;
355 /* error handling */
356 void *error_opaque;
357 void (*error_func)(void *opaque, const char *msg);
358 int error_set_jmp_enabled;
359 jmp_buf error_jmp_buf;
360 int nb_errors;
362 /* see include_stack_ptr */
363 BufferedFile *include_stack[INCLUDE_STACK_SIZE];
365 /* see ifdef_stack_ptr */
366 int ifdef_stack[IFDEF_STACK_SIZE];
369 /* The current value can be: */
370 #define VT_VALMASK 0x00ff
371 #define VT_CONST 0x00f0 /* constant in vc
372 (must be first non register value) */
373 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
374 #define VT_LOCAL 0x00f2 /* offset on stack */
375 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
376 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
377 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
378 #define VT_LVAL 0x0100 /* var is an lvalue */
379 #define VT_SYM 0x0200 /* a symbol value is added */
380 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
381 char/short stored in integer registers) */
382 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
383 dereferencing value */
384 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
385 bounding function call point is in vc */
386 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
387 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
388 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
389 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
391 /* types */
392 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
394 #define VT_INT 0 /* integer type */
395 #define VT_BYTE 1 /* signed byte type */
396 #define VT_SHORT 2 /* short type */
397 #define VT_VOID 3 /* void type */
398 #define VT_PTR 4 /* pointer */
399 #define VT_ENUM 5 /* enum definition */
400 #define VT_FUNC 6 /* function type */
401 #define VT_STRUCT 7 /* struct/union definition */
402 #define VT_FLOAT 8 /* IEEE float */
403 #define VT_DOUBLE 9 /* IEEE double */
404 #define VT_LDOUBLE 10 /* IEEE long double */
405 #define VT_BOOL 11 /* ISOC99 boolean type */
406 #define VT_LLONG 12 /* 64 bit integer */
407 #define VT_LONG 13 /* long integer (NEVER USED as type, only
408 during parsing) */
409 #define VT_BTYPE 0x000f /* mask for basic type */
410 #define VT_UNSIGNED 0x0010 /* unsigned type */
411 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
412 #define VT_BITFIELD 0x0040 /* bitfield modifier */
414 /* storage */
415 #define VT_EXTERN 0x00000080 /* extern definition */
416 #define VT_STATIC 0x00000100 /* static variable */
417 #define VT_TYPEDEF 0x00000200 /* typedef definition */
419 /* type mask (except storage) */
420 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
422 /* token values */
424 /* warning: the following compare tokens depend on i386 asm code */
425 #define TOK_ULT 0x92
426 #define TOK_UGE 0x93
427 #define TOK_EQ 0x94
428 #define TOK_NE 0x95
429 #define TOK_ULE 0x96
430 #define TOK_UGT 0x97
431 #define TOK_LT 0x9c
432 #define TOK_GE 0x9d
433 #define TOK_LE 0x9e
434 #define TOK_GT 0x9f
436 #define TOK_LAND 0xa0
437 #define TOK_LOR 0xa1
439 #define TOK_DEC 0xa2
440 #define TOK_MID 0xa3 /* inc/dec, to void constant */
441 #define TOK_INC 0xa4
442 #define TOK_UDIV 0xb0 /* unsigned division */
443 #define TOK_UMOD 0xb1 /* unsigned modulo */
444 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
445 #define TOK_CINT 0xb3 /* number in tokc */
446 #define TOK_CCHAR 0xb4 /* char constant in tokc */
447 #define TOK_STR 0xb5 /* pointer to string in tokc */
448 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
449 #define TOK_LCHAR 0xb7
450 #define TOK_LSTR 0xb8
451 #define TOK_CFLOAT 0xb9 /* float constant */
452 #define TOK_LINENUM 0xba /* line number info */
453 #define TOK_CDOUBLE 0xc0 /* double constant */
454 #define TOK_CLDOUBLE 0xc1 /* long double constant */
455 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
456 #define TOK_ADDC1 0xc3 /* add with carry generation */
457 #define TOK_ADDC2 0xc4 /* add with carry use */
458 #define TOK_SUBC1 0xc5 /* add with carry generation */
459 #define TOK_SUBC2 0xc6 /* add with carry use */
460 #define TOK_CUINT 0xc8 /* unsigned int constant */
461 #define TOK_CLLONG 0xc9 /* long long constant */
462 #define TOK_CULLONG 0xca /* unsigned long long constant */
463 #define TOK_ARROW 0xcb
464 #define TOK_DOTS 0xcc /* three dots */
465 #define TOK_SHR 0xcd /* unsigned shift right */
467 #define TOK_SHL 0x01 /* shift left */
468 #define TOK_SAR 0x02 /* signed shift right */
470 /* assignement operators : normal operator or 0x80 */
471 #define TOK_A_MOD 0xa5
472 #define TOK_A_AND 0xa6
473 #define TOK_A_MUL 0xaa
474 #define TOK_A_ADD 0xab
475 #define TOK_A_SUB 0xad
476 #define TOK_A_DIV 0xaf
477 #define TOK_A_XOR 0xde
478 #define TOK_A_OR 0xfc
479 #define TOK_A_SHL 0x81
480 #define TOK_A_SAR 0x82
482 /* WARNING: the content of this string encodes token numbers */
483 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";
485 #define TOK_EOF (-1) /* end of file */
486 #define TOK_LINEFEED 10 /* line feed */
488 /* all identificators and strings have token above that */
489 #define TOK_IDENT 256
491 enum {
492 TOK_INT = TOK_IDENT,
493 TOK_VOID,
494 TOK_CHAR,
495 TOK_IF,
496 TOK_ELSE,
497 TOK_WHILE,
498 TOK_BREAK,
499 TOK_RETURN,
500 TOK_FOR,
501 TOK_EXTERN,
502 TOK_STATIC,
503 TOK_UNSIGNED,
504 TOK_GOTO,
505 TOK_DO,
506 TOK_CONTINUE,
507 TOK_SWITCH,
508 TOK_CASE,
510 /* ignored types Must have contiguous values */
511 TOK_CONST,
512 TOK_VOLATILE,
513 TOK_LONG,
514 TOK_REGISTER,
515 TOK_SIGNED,
516 TOK___SIGNED__, /* gcc keyword */
517 TOK_AUTO,
518 TOK_INLINE,
519 TOK___INLINE__, /* gcc keyword */
520 TOK_RESTRICT,
522 /* unsupported type */
523 TOK_FLOAT,
524 TOK_DOUBLE,
525 TOK_BOOL,
527 TOK_SHORT,
528 TOK_STRUCT,
529 TOK_UNION,
530 TOK_TYPEDEF,
531 TOK_DEFAULT,
532 TOK_ENUM,
533 TOK_SIZEOF,
534 TOK___ATTRIBUTE__,
536 /* preprocessor only */
537 TOK_UIDENT, /* first "user" ident (not keyword) */
538 TOK_DEFINE = TOK_UIDENT,
539 TOK_INCLUDE,
540 TOK_IFDEF,
541 TOK_IFNDEF,
542 TOK_ELIF,
543 TOK_ENDIF,
544 TOK_DEFINED,
545 TOK_UNDEF,
546 TOK_ERROR,
547 TOK_LINE,
549 #define DEF(id, str) id,
550 #include "tcctok.h"
551 #undef DEF
554 char *tcc_keywords =
555 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
556 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
557 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
558 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
559 "sizeof\0__attribute__\0"
560 /* the following are not keywords. They are included to ease parsing */
561 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
562 "defined\0undef\0error\0line\0"
563 /* builtin functions */
564 #define DEF(id, str) str "\0"
565 #include "tcctok.h"
566 #undef DEF
569 #ifdef WIN32
570 #define snprintf _snprintf
571 #endif
573 #if defined(WIN32) || defined(TCC_UCLIBC)
574 /* currently incorrect */
575 long double strtold(const char *nptr, char **endptr)
577 return (long double)strtod(nptr, endptr);
579 float strtof(const char *nptr, char **endptr)
581 return (float)strtod(nptr, endptr);
583 #else
584 /* XXX: need to define this to use them in non ISOC99 context */
585 extern float strtof (const char *__nptr, char **__endptr);
586 extern long double strtold (const char *__nptr, char **__endptr);
587 #endif
589 static char *pstrcpy(char *buf, int buf_size, const char *s);
590 static char *pstrcat(char *buf, int buf_size, const char *s);
592 void sum(int l);
593 void next(void);
594 void next_nomacro(void);
595 static int expr_const(void);
596 void expr_eq(void);
597 void gexpr(void);
598 void decl(int l);
599 static void decl_initializer(int t, Section *sec, unsigned long c,
600 int first, int size_only);
601 static void decl_initializer_alloc(int t, AttributeDef *ad, int r,
602 int has_init, int v, int scope);
603 int gv(int rc);
604 void gv2(int rc1, int rc2);
605 void move_reg(int r, int s);
606 void save_regs(int n);
607 void save_reg(int r);
608 void vpop(void);
609 void vswap(void);
610 void vdup(void);
611 int get_reg(int rc);
613 static void macro_subst(TokenString *tok_str,
614 Sym **nested_list, int *macro_str);
615 int save_reg_forced(int r);
616 void gen_op(int op);
617 void force_charshort_cast(int t);
618 void gen_cast(int t);
619 void vstore(void);
620 Sym *sym_find(int v);
621 Sym *sym_push(int v, int t, int r, int c);
623 /* type handling */
624 int type_size(int t, int *a);
625 int pointed_type(int t);
626 int pointed_size(int t);
627 static int lvalue_type(int t);
628 int is_compatible_types(int t1, int t2);
629 int parse_btype(int *type_ptr, AttributeDef *ad);
630 int type_decl(AttributeDef *ad, int *v, int t, int td);
632 void error(const char *fmt, ...);
633 void rt_error(unsigned long pc, const char *fmt, ...);
634 void vpushi(int v);
635 void vset(int t, int r, int v);
636 void type_to_str(char *buf, int buf_size,
637 int t, const char *varstr);
638 char *get_tok_str(int v, CValue *cv);
639 static Sym *get_sym_ref(int t, Section *sec,
640 unsigned long offset, unsigned long size);
641 static Sym *external_global_sym(int v, int u, int r);
643 /* section generation */
644 static void section_realloc(Section *sec, unsigned long new_size);
645 static void *section_ptr_add(Section *sec, unsigned long size);
646 static void put_extern_sym(Sym *sym, Section *section,
647 unsigned long value, unsigned long size);
648 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
649 static int put_elf_str(Section *s, const char *sym);
650 static int put_elf_sym(Section *s,
651 unsigned long value, unsigned long size,
652 int info, int other, int shndx, const char *name);
653 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
654 int info, int sh_num, const char *name);
655 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
656 int type, int symbol);
657 static void put_stabs(const char *str, int type, int other, int desc,
658 unsigned long value);
659 static void put_stabs_r(const char *str, int type, int other, int desc,
660 unsigned long value, Section *sec, int sym_index);
661 static void put_stabn(int type, int other, int desc, int value);
662 static void put_stabd(int type, int other, int desc);
663 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
665 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
666 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
667 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
669 /* true if float/double/long double type */
670 static inline int is_float(int t)
672 int bt;
673 bt = t & VT_BTYPE;
674 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
677 #ifdef TCC_TARGET_I386
678 #include "i386-gen.c"
679 #endif
680 #ifdef TCC_TARGET_IL
681 #include "il-gen.c"
682 #endif
684 #ifdef CONFIG_TCC_STATIC
686 #define RTLD_LAZY 0x001
687 #define RTLD_NOW 0x002
688 #define RTLD_GLOBAL 0x100
690 /* dummy function for profiling */
691 void *dlopen(const char *filename, int flag)
693 return NULL;
696 const char *dlerror(void)
698 return "error";
701 typedef struct TCCSyms {
702 char *str;
703 void *ptr;
704 } TCCSyms;
706 #define TCCSYM(a) { #a, &a, },
708 /* add the symbol you want here if no dynamic linking is done */
709 static TCCSyms tcc_syms[] = {
710 TCCSYM(printf)
711 TCCSYM(fprintf)
712 TCCSYM(fopen)
713 TCCSYM(fclose)
714 { NULL, NULL },
717 void *dlsym(void *handle, const char *symbol)
719 TCCSyms *p;
720 p = tcc_syms;
721 while (p->str != NULL) {
722 if (!strcmp(p->str, symbol))
723 return p->ptr;
724 p++;
726 return NULL;
729 #endif
731 /********************************************************/
733 /* we use our own 'finite' function to avoid potential problems with
734 non standard math libs */
735 /* XXX: endianness dependant */
736 int ieee_finite(double d)
738 int *p = (int *)&d;
739 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
742 /* copy a string and truncate it. */
743 static char *pstrcpy(char *buf, int buf_size, const char *s)
745 char *q, *q_end;
746 int c;
748 if (buf_size > 0) {
749 q = buf;
750 q_end = buf + buf_size - 1;
751 while (q < q_end) {
752 c = *s++;
753 if (c == '\0')
754 break;
755 *q++ = c;
757 *q = '\0';
759 return buf;
762 /* strcat and truncate. */
763 static char *pstrcat(char *buf, int buf_size, const char *s)
765 int len;
766 len = strlen(buf);
767 if (len < buf_size)
768 pstrcpy(buf + len, buf_size - len, s);
769 return buf;
772 /* memory management */
773 #ifdef MEM_DEBUG
774 int mem_cur_size;
775 int mem_max_size;
776 #endif
778 static inline void tcc_free(void *ptr)
780 #ifdef MEM_DEBUG
781 mem_cur_size -= malloc_usable_size(ptr);
782 #endif
783 free(ptr);
786 static void *tcc_malloc(unsigned long size)
788 void *ptr;
789 ptr = malloc(size);
790 if (!ptr && size)
791 error("memory full");
792 #ifdef MEM_DEBUG
793 mem_cur_size += malloc_usable_size(ptr);
794 if (mem_cur_size > mem_max_size)
795 mem_max_size = mem_cur_size;
796 #endif
797 return ptr;
800 static void *tcc_mallocz(unsigned long size)
802 void *ptr;
803 ptr = tcc_malloc(size);
804 memset(ptr, 0, size);
805 return ptr;
808 static inline void *tcc_realloc(void *ptr, unsigned long size)
810 void *ptr1;
811 #ifdef MEM_DEBUG
812 mem_cur_size -= malloc_usable_size(ptr);
813 #endif
814 ptr1 = realloc(ptr, size);
815 #ifdef MEM_DEBUG
816 /* NOTE: count not correct if alloc error, but not critical */
817 mem_cur_size += malloc_usable_size(ptr1);
818 if (mem_cur_size > mem_max_size)
819 mem_max_size = mem_cur_size;
820 #endif
821 return ptr1;
824 static char *tcc_strdup(const char *str)
826 char *ptr;
827 ptr = tcc_malloc(strlen(str) + 1);
828 strcpy(ptr, str);
829 return ptr;
832 #define free(p) use_tcc_free(p)
833 #define malloc(s) use_tcc_malloc(s)
834 #define realloc(p, s) use_tcc_realloc(p, s)
836 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
838 int nb, nb_alloc;
839 void **pp;
841 nb = *nb_ptr;
842 pp = *ptab;
843 /* every power of two we double array size */
844 if ((nb & (nb - 1)) == 0) {
845 if (!nb)
846 nb_alloc = 1;
847 else
848 nb_alloc = nb * 2;
849 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
850 if (!pp)
851 error("memory full");
852 *ptab = pp;
854 pp[nb++] = data;
855 *nb_ptr = nb;
858 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
860 Section *sec;
862 sec = tcc_mallocz(sizeof(Section));
863 pstrcpy(sec->name, sizeof(sec->name), name);
864 sec->sh_type = sh_type;
865 sec->sh_flags = sh_flags;
866 switch(sh_type) {
867 case SHT_HASH:
868 case SHT_REL:
869 case SHT_DYNSYM:
870 case SHT_SYMTAB:
871 case SHT_DYNAMIC:
872 sec->sh_addralign = 4;
873 break;
874 case SHT_STRTAB:
875 sec->sh_addralign = 1;
876 break;
877 default:
878 sec->sh_addralign = 32; /* default conservative alignment */
879 break;
882 /* only add section if not private */
883 if (!(sh_flags & SHF_PRIVATE)) {
884 sec->sh_num = s1->nb_sections;
885 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
887 return sec;
890 static void free_section(Section *s)
892 tcc_free(s->data);
893 tcc_free(s);
896 /* realloc section and set its content to zero */
897 static void section_realloc(Section *sec, unsigned long new_size)
899 unsigned long size;
900 unsigned char *data;
902 size = sec->data_allocated;
903 if (size == 0)
904 size = 1;
905 while (size < new_size)
906 size = size * 2;
907 data = tcc_realloc(sec->data, size);
908 if (!data)
909 error("memory full");
910 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
911 sec->data = data;
912 sec->data_allocated = size;
915 /* reserve at least 'size' bytes in section 'sec' from
916 sec->data_offset. */
917 static void *section_ptr_add(Section *sec, unsigned long size)
919 unsigned long offset, offset1;
921 offset = sec->data_offset;
922 offset1 = offset + size;
923 if (offset1 > sec->data_allocated)
924 section_realloc(sec, offset1);
925 sec->data_offset = offset1;
926 return sec->data + offset;
929 /* return a reference to a section, and create it if it does not
930 exists */
931 Section *find_section(TCCState *s1, const char *name)
933 Section *sec;
934 int i;
935 for(i = 1; i < s1->nb_sections; i++) {
936 sec = s1->sections[i];
937 if (!strcmp(name, sec->name))
938 return sec;
940 /* sections are created as PROGBITS */
941 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
944 /* update sym->c so that it points to an external symbol in section
945 'section' with value 'value' */
946 static void put_extern_sym(Sym *sym, Section *section,
947 unsigned long value, unsigned long size)
949 int sym_type, sym_bind, sh_num, info;
950 Elf32_Sym *esym;
951 const char *name;
952 char buf[32];
954 if (section)
955 sh_num = section->sh_num;
956 else
957 sh_num = SHN_UNDEF;
958 if (!sym->c) {
959 if ((sym->t & VT_BTYPE) == VT_FUNC)
960 sym_type = STT_FUNC;
961 else
962 sym_type = STT_OBJECT;
963 if (sym->t & VT_STATIC)
964 sym_bind = STB_LOCAL;
965 else
966 sym_bind = STB_GLOBAL;
968 name = get_tok_str(sym->v, NULL);
969 #ifdef CONFIG_TCC_BCHECK
970 if (do_bounds_check) {
971 /* if bound checking is activated, we change some function
972 names by adding the "__bound" prefix */
973 switch(sym->v) {
974 #if 0
975 /* XXX: we rely only on malloc hooks */
976 case TOK_malloc:
977 case TOK_free:
978 case TOK_realloc:
979 case TOK_memalign:
980 case TOK_calloc:
981 #endif
982 case TOK_memcpy:
983 case TOK_memmove:
984 case TOK_memset:
985 case TOK_strlen:
986 case TOK_strcpy:
987 strcpy(buf, "__bound_");
988 strcat(buf, name);
989 name = buf;
990 break;
993 #endif
994 info = ELF32_ST_INFO(sym_bind, sym_type);
995 sym->c = add_elf_sym(symtab_section, value, size, info, sh_num, name);
996 } else {
997 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
998 esym->st_value = value;
999 esym->st_size = size;
1000 esym->st_shndx = sh_num;
1004 /* add a new relocation entry to symbol 'sym' in section 's' */
1005 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
1007 if (!sym->c)
1008 put_extern_sym(sym, NULL, 0, 0);
1009 /* now we can add ELF relocation info */
1010 put_elf_reloc(symtab_section, s, offset, type, sym->c);
1013 static inline int isid(int c)
1015 return (c >= 'a' && c <= 'z') ||
1016 (c >= 'A' && c <= 'Z') ||
1017 c == '_';
1020 static inline int isnum(int c)
1022 return c >= '0' && c <= '9';
1025 static inline int isoct(int c)
1027 return c >= '0' && c <= '7';
1030 static inline int toup(int c)
1032 if (ch >= 'a' && ch <= 'z')
1033 return ch - 'a' + 'A';
1034 else
1035 return ch;
1038 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
1040 int len;
1041 len = strlen(buf);
1042 vsnprintf(buf + len, buf_size - len, fmt, ap);
1045 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
1047 va_list ap;
1048 va_start(ap, fmt);
1049 strcat_vprintf(buf, buf_size, fmt, ap);
1050 va_end(ap);
1053 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
1055 char buf[2048];
1056 BufferedFile **f;
1058 buf[0] = '\0';
1059 if (file) {
1060 for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1061 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1062 (*f)->filename, (*f)->line_num);
1063 if (file->line_num > 0) {
1064 strcat_printf(buf, sizeof(buf),
1065 "%s:%d: ", file->filename, file->line_num);
1066 } else {
1067 strcat_printf(buf, sizeof(buf),
1068 "%s: ", file->filename);
1070 } else {
1071 strcat_printf(buf, sizeof(buf),
1072 "tcc: ");
1074 if (is_warning)
1075 strcat_printf(buf, sizeof(buf), "warning: ");
1076 strcat_vprintf(buf, sizeof(buf), fmt, ap);
1078 if (!s1->error_func) {
1079 /* default case: stderr */
1080 fprintf(stderr, "%s\n", buf);
1081 } else {
1082 s1->error_func(s1->error_opaque, buf);
1084 s1->nb_errors++;
1087 #ifdef LIBTCC
1088 void tcc_set_error_func(TCCState *s, void *error_opaque,
1089 void (*error_func)(void *opaque, const char *msg))
1091 s->error_opaque = error_opaque;
1092 s->error_func = error_func;
1094 #endif
1096 /* error without aborting current compilation */
1097 void error_noabort(const char *fmt, ...)
1099 TCCState *s1 = tcc_state;
1100 va_list ap;
1102 va_start(ap, fmt);
1103 error1(s1, 0, fmt, ap);
1104 va_end(ap);
1107 void error(const char *fmt, ...)
1109 TCCState *s1 = tcc_state;
1110 va_list ap;
1112 va_start(ap, fmt);
1113 error1(s1, 0, fmt, ap);
1114 va_end(ap);
1115 /* better than nothing: in some cases, we accept to handle errors */
1116 if (s1->error_set_jmp_enabled) {
1117 longjmp(s1->error_jmp_buf, 1);
1118 } else {
1119 /* XXX: suppress it someday */
1120 exit(1);
1124 void expect(const char *msg)
1126 error("%s expected", msg);
1129 void warning(const char *fmt, ...)
1131 TCCState *s1 = tcc_state;
1132 va_list ap;
1134 va_start(ap, fmt);
1135 error1(s1, 1, fmt, ap);
1136 va_end(ap);
1139 void skip(int c)
1141 if (tok != c)
1142 error("'%c' expected", c);
1143 next();
1146 void test_lvalue(void)
1148 if (!(vtop->r & VT_LVAL))
1149 expect("lvalue");
1152 TokenSym *tok_alloc(const char *str, int len)
1154 TokenSym *ts, **pts, **ptable;
1155 int h, i;
1157 h = 1;
1158 for(i=0;i<len;i++)
1159 h = (h * 263 + ((unsigned char *)str)[i]) & (TOK_HASH_SIZE - 1);
1161 pts = &hash_ident[h];
1162 while (1) {
1163 ts = *pts;
1164 if (!ts)
1165 break;
1166 if (ts->len == len && !memcmp(ts->str, str, len))
1167 return ts;
1168 pts = &(ts->hash_next);
1171 if (tok_ident >= SYM_FIRST_ANOM)
1172 error("memory full");
1174 /* expand token table if needed */
1175 i = tok_ident - TOK_IDENT;
1176 if ((i % TOK_ALLOC_INCR) == 0) {
1177 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1178 if (!ptable)
1179 error("memory full");
1180 table_ident = ptable;
1183 ts = tcc_malloc(sizeof(TokenSym) + len);
1184 table_ident[i] = ts;
1185 ts->tok = tok_ident++;
1186 ts->len = len;
1187 ts->hash_next = NULL;
1188 memcpy(ts->str, str, len + 1);
1189 *pts = ts;
1190 return ts;
1193 /* CString handling */
1195 static void cstr_realloc(CString *cstr, int new_size)
1197 int size;
1198 void *data;
1200 size = cstr->size_allocated;
1201 if (size == 0)
1202 size = 8; /* no need to allocate a too small first string */
1203 while (size < new_size)
1204 size = size * 2;
1205 data = tcc_realloc(cstr->data_allocated, size);
1206 if (!data)
1207 error("memory full");
1208 cstr->data_allocated = data;
1209 cstr->size_allocated = size;
1210 cstr->data = data;
1213 /* add a byte */
1214 static void cstr_ccat(CString *cstr, int ch)
1216 int size;
1217 size = cstr->size + 1;
1218 if (size > cstr->size_allocated)
1219 cstr_realloc(cstr, size);
1220 ((unsigned char *)cstr->data)[size - 1] = ch;
1221 cstr->size = size;
1224 static void cstr_cat(CString *cstr, const char *str)
1226 int c;
1227 for(;;) {
1228 c = *str;
1229 if (c == '\0')
1230 break;
1231 cstr_ccat(cstr, c);
1232 str++;
1236 /* add a wide char */
1237 static void cstr_wccat(CString *cstr, int ch)
1239 int size;
1240 size = cstr->size + sizeof(int);
1241 if (size > cstr->size_allocated)
1242 cstr_realloc(cstr, size);
1243 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1244 cstr->size = size;
1247 static void cstr_new(CString *cstr)
1249 memset(cstr, 0, sizeof(CString));
1252 /* free string and reset it to NULL */
1253 static void cstr_free(CString *cstr)
1255 tcc_free(cstr->data_allocated);
1256 cstr_new(cstr);
1259 #define cstr_reset(cstr) cstr_free(cstr)
1261 /* XXX: unicode ? */
1262 static void add_char(CString *cstr, int c)
1264 if (c == '\'' || c == '\"' || c == '\\') {
1265 /* XXX: could be more precise if char or string */
1266 cstr_ccat(cstr, '\\');
1268 if (c >= 32 && c <= 126) {
1269 cstr_ccat(cstr, c);
1270 } else {
1271 cstr_ccat(cstr, '\\');
1272 if (c == '\n') {
1273 cstr_ccat(cstr, 'n');
1274 } else {
1275 cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1276 cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1277 cstr_ccat(cstr, '0' + (c & 7));
1282 /* XXX: buffer overflow */
1283 /* XXX: float tokens */
1284 char *get_tok_str(int v, CValue *cv)
1286 static char buf[STRING_MAX_SIZE + 1];
1287 static CString cstr_buf;
1288 CString *cstr;
1289 unsigned char *q;
1290 char *p;
1291 int i, len;
1293 /* NOTE: to go faster, we give a fixed buffer for small strings */
1294 cstr_reset(&cstr_buf);
1295 cstr_buf.data = buf;
1296 cstr_buf.size_allocated = sizeof(buf);
1297 p = buf;
1299 switch(v) {
1300 case TOK_CINT:
1301 case TOK_CUINT:
1302 /* XXX: not quite exact, but useful for ## in macros */
1303 sprintf(p, "%u", cv->ui);
1304 break;
1305 case TOK_CLLONG:
1306 case TOK_CULLONG:
1307 /* XXX: not quite exact, but useful for ## in macros */
1308 sprintf(p, "%Lu", cv->ull);
1309 break;
1310 case TOK_CCHAR:
1311 case TOK_LCHAR:
1312 cstr_ccat(&cstr_buf, '\'');
1313 add_char(&cstr_buf, cv->i);
1314 cstr_ccat(&cstr_buf, '\'');
1315 cstr_ccat(&cstr_buf, '\0');
1316 break;
1317 case TOK_STR:
1318 case TOK_LSTR:
1319 cstr = cv->cstr;
1320 cstr_ccat(&cstr_buf, '\"');
1321 if (v == TOK_STR) {
1322 len = cstr->size - 1;
1323 for(i=0;i<len;i++)
1324 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1325 } else {
1326 len = (cstr->size / sizeof(int)) - 1;
1327 for(i=0;i<len;i++)
1328 add_char(&cstr_buf, ((int *)cstr->data)[i]);
1330 cstr_ccat(&cstr_buf, '\"');
1331 cstr_ccat(&cstr_buf, '\0');
1332 break;
1333 case TOK_LT:
1334 v = '<';
1335 goto addv;
1336 case TOK_GT:
1337 v = '>';
1338 goto addv;
1339 case TOK_A_SHL:
1340 return strcpy(p, "<<=");
1341 case TOK_A_SAR:
1342 return strcpy(p, ">>=");
1343 default:
1344 if (v < TOK_IDENT) {
1345 /* search in two bytes table */
1346 q = tok_two_chars;
1347 while (*q) {
1348 if (q[2] == v) {
1349 *p++ = q[0];
1350 *p++ = q[1];
1351 *p = '\0';
1352 return buf;
1354 q += 3;
1356 addv:
1357 *p++ = v;
1358 *p = '\0';
1359 } else if (v < tok_ident) {
1360 return table_ident[v - TOK_IDENT]->str;
1361 } else if (v >= SYM_FIRST_ANOM) {
1362 /* special name for anonymous symbol */
1363 sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1364 } else {
1365 /* should never happen */
1366 return NULL;
1368 break;
1370 return cstr_buf.data;
1373 /* push, without hashing */
1374 Sym *sym_push2(Sym **ps, int v, int t, int c)
1376 Sym *s;
1377 s = tcc_malloc(sizeof(Sym));
1378 s->v = v;
1379 s->t = t;
1380 s->c = c;
1381 s->next = NULL;
1382 /* add in stack */
1383 s->prev = *ps;
1384 *ps = s;
1385 return s;
1388 /* find a symbol and return its associated structure. 's' is the top
1389 of the symbol stack */
1390 Sym *sym_find2(Sym *s, int v)
1392 while (s) {
1393 if (s->v == v)
1394 return s;
1395 s = s->prev;
1397 return NULL;
1400 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1402 /* find a symbol and return its associated structure. 'st' is the
1403 symbol stack */
1404 Sym *sym_find1(SymStack *st, int v)
1406 Sym *s;
1408 s = st->hash[HASH_SYM(v)];
1409 while (s) {
1410 if (s->v == v)
1411 return s;
1412 s = s->hash_next;
1414 return NULL;
1417 Sym *sym_push1(SymStack *st, int v, int t, int c)
1419 Sym *s, **ps;
1420 s = sym_push2(&st->top, v, t, c);
1421 /* add in hash table */
1422 if (v) {
1423 ps = &st->hash[HASH_SYM(v)];
1424 s->hash_next = *ps;
1425 *ps = s;
1427 return s;
1430 /* find a symbol in the right symbol space */
1431 Sym *sym_find(int v)
1433 Sym *s;
1434 s = sym_find1(&local_stack, v);
1435 if (!s)
1436 s = sym_find1(&global_stack, v);
1437 return s;
1440 /* push a given symbol on the symbol stack */
1441 Sym *sym_push(int v, int t, int r, int c)
1443 Sym *s;
1444 if (local_stack.top)
1445 s = sym_push1(&local_stack, v, t, c);
1446 else
1447 s = sym_push1(&global_stack, v, t, c);
1448 s->r = r;
1449 return s;
1452 /* pop symbols until top reaches 'b' */
1453 void sym_pop(SymStack *st, Sym *b)
1455 Sym *s, *ss;
1457 s = st->top;
1458 while(s != b) {
1459 ss = s->prev;
1460 /* free hash table entry, except if symbol was freed (only
1461 used for #undef symbols) */
1462 if (s->v)
1463 st->hash[HASH_SYM(s->v)] = s->hash_next;
1464 tcc_free(s);
1465 s = ss;
1467 st->top = b;
1470 /* undefined a hashed symbol (used for #undef). Its name is set to
1471 zero */
1472 void sym_undef(SymStack *st, Sym *s)
1474 Sym **ss;
1475 ss = &st->hash[HASH_SYM(s->v)];
1476 while (*ss != NULL) {
1477 if (*ss == s)
1478 break;
1479 ss = &(*ss)->hash_next;
1481 *ss = s->hash_next;
1482 s->v = 0;
1485 /* I/O layer */
1487 BufferedFile *tcc_open(TCCState *s1, const char *filename)
1489 int fd;
1490 BufferedFile *bf;
1492 fd = open(filename, O_RDONLY);
1493 if (fd < 0)
1494 return NULL;
1495 bf = tcc_malloc(sizeof(BufferedFile));
1496 if (!bf) {
1497 close(fd);
1498 return NULL;
1500 bf->fd = fd;
1501 bf->buf_ptr = bf->buffer;
1502 bf->buf_end = bf->buffer;
1503 bf->buffer[0] = CH_EOB; /* put eob symbol */
1504 pstrcpy(bf->filename, sizeof(bf->filename), filename);
1505 bf->line_num = 1;
1506 bf->ifndef_macro = 0;
1507 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1508 // printf("opening '%s'\n", filename);
1509 return bf;
1512 void tcc_close(BufferedFile *bf)
1514 total_lines += bf->line_num;
1515 close(bf->fd);
1516 tcc_free(bf);
1519 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1520 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1522 /* fill input buffer and return next char */
1523 int tcc_getc_slow(BufferedFile *bf)
1525 int len;
1526 /* only tries to read if really end of buffer */
1527 if (bf->buf_ptr >= bf->buf_end) {
1528 if (bf->fd != -1) {
1529 len = read(bf->fd, bf->buffer, IO_BUF_SIZE);
1530 if (len < 0)
1531 len = 0;
1532 } else {
1533 len = 0;
1535 total_bytes += len;
1536 bf->buf_ptr = bf->buffer;
1537 bf->buf_end = bf->buffer + len;
1538 *bf->buf_end = CH_EOB;
1540 if (bf->buf_ptr < bf->buf_end) {
1541 return *bf->buf_ptr++;
1542 } else {
1543 bf->buf_ptr = bf->buf_end;
1544 return CH_EOF;
1548 /* no need to put that inline */
1549 void handle_eob(void)
1551 TCCState *s1 = tcc_state;
1552 for(;;) {
1553 ch1 = tcc_getc_slow(file);
1554 if (ch1 != CH_EOF)
1555 return;
1556 eof_seen = 1;
1557 if (return_linefeed) {
1558 ch1 = '\n';
1559 return;
1561 if (s1->include_stack_ptr == s1->include_stack)
1562 return;
1563 /* add end of include file debug info */
1564 if (do_debug) {
1565 put_stabd(N_EINCL, 0, 0);
1567 /* pop include stack */
1568 tcc_close(file);
1569 s1->include_stack_ptr--;
1570 file = *s1->include_stack_ptr;
1574 /* read next char from current input file */
1575 static inline void inp(void)
1577 ch1 = TCC_GETC(file);
1578 /* end of buffer/file handling */
1579 if (ch1 == CH_EOB)
1580 handle_eob();
1581 if (ch1 == '\n')
1582 file->line_num++;
1583 // printf("ch1=%c 0x%x\n", ch1, ch1);
1586 /* handle '\\n' and '\\r\n' */
1587 static void handle_stray(void)
1589 do {
1590 if (ch1 == '\n') {
1591 inp();
1592 } else if (ch1 == '\r') {
1593 inp();
1594 if (ch1 != '\n')
1595 error("invalid character after '\\'");
1596 inp();
1597 } else {
1598 break;
1600 ch = ch1;
1601 inp();
1602 } while (ch == '\\');
1605 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1606 case */
1607 static inline void minp(void)
1609 ch = ch1;
1610 inp();
1611 if (ch == '\\')
1612 handle_stray();
1616 /* same as minp, but also skip comments */
1617 static void cinp(void)
1619 int c;
1621 if (ch1 == '/') {
1622 inp();
1623 if (ch1 == '/') {
1624 /* single line C++ comments */
1625 inp();
1626 while (ch1 != '\n' && ch1 != CH_EOF)
1627 inp();
1628 ch = ' '; /* return space */
1629 } else if (ch1 == '*') {
1630 /* C comments */
1631 inp();
1632 while (ch1 != CH_EOF) {
1633 c = ch1;
1634 inp();
1635 if (c == '*' && ch1 == '/') {
1636 inp();
1637 ch = ' '; /* return space */
1638 break;
1641 } else {
1642 ch = '/';
1644 } else {
1645 minp();
1649 /* space exlcuding newline */
1650 static inline int is_space(int ch)
1652 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
1655 static inline void skip_spaces(void)
1657 while (is_space(ch))
1658 cinp();
1661 /* skip block of text until #else, #elif or #endif. skip also pairs of
1662 #if/#endif */
1663 void preprocess_skip(void)
1665 int a;
1666 a = 0;
1667 while (1) {
1668 while (ch != '\n') {
1669 if (ch == CH_EOF)
1670 expect("#endif");
1671 cinp();
1673 cinp();
1674 skip_spaces();
1675 if (ch == '#') {
1676 cinp();
1677 next_nomacro();
1678 if (a == 0 &&
1679 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
1680 break;
1681 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
1682 a++;
1683 else if (tok == TOK_ENDIF)
1684 a--;
1689 /* ParseState handling */
1691 /* XXX: currently, no include file info is stored. Thus, we cannot display
1692 accurate messages if the function or data definition spans multiple
1693 files */
1695 /* save current parse state in 's' */
1696 void save_parse_state(ParseState *s)
1698 s->line_num = file->line_num;
1699 s->macro_ptr = macro_ptr;
1700 s->tok = tok;
1701 s->tokc = tokc;
1704 /* restore parse state from 's' */
1705 void restore_parse_state(ParseState *s)
1707 file->line_num = s->line_num;
1708 macro_ptr = s->macro_ptr;
1709 tok = s->tok;
1710 tokc = s->tokc;
1713 /* return the number of additionnal 'ints' necessary to store the
1714 token */
1715 static inline int tok_ext_size(int t)
1717 switch(t) {
1718 /* 4 bytes */
1719 case TOK_CINT:
1720 case TOK_CUINT:
1721 case TOK_CCHAR:
1722 case TOK_LCHAR:
1723 case TOK_STR:
1724 case TOK_LSTR:
1725 case TOK_CFLOAT:
1726 case TOK_LINENUM:
1727 return 1;
1728 case TOK_CDOUBLE:
1729 case TOK_CLLONG:
1730 case TOK_CULLONG:
1731 return 2;
1732 case TOK_CLDOUBLE:
1733 return LDOUBLE_SIZE / 4;
1734 default:
1735 return 0;
1739 /* token string handling */
1741 static inline void tok_str_new(TokenString *s)
1743 s->str = NULL;
1744 s->len = 0;
1745 s->last_line_num = -1;
1748 static void tok_str_free(int *str)
1750 const int *p;
1751 CString *cstr;
1752 int t;
1754 p = str;
1755 for(;;) {
1756 t = *p++;
1757 if (t == 0)
1758 break;
1759 if (t == TOK_STR || t == TOK_LSTR) {
1760 /* XXX: use a macro to be portable on 64 bit ? */
1761 cstr = (CString *)(*p++);
1762 cstr_free(cstr);
1763 tcc_free(cstr);
1764 } else {
1765 p += tok_ext_size(t);
1768 tcc_free(str);
1771 static void tok_str_add(TokenString *s, int t)
1773 int len, *str;
1775 len = s->len;
1776 str = s->str;
1777 if ((len & 63) == 0) {
1778 str = tcc_realloc(str, (len + 64) * sizeof(int));
1779 if (!str)
1780 return;
1781 s->str = str;
1783 str[len++] = t;
1784 s->len = len;
1787 static void tok_str_add2(TokenString *s, int t, CValue *cv)
1789 int n, i, size;
1790 CString *cstr, *cstr1;
1791 CValue cv1;
1793 tok_str_add(s, t);
1794 if (t == TOK_STR || t == TOK_LSTR) {
1795 /* special case: need to duplicate string */
1796 cstr1 = cv->cstr;
1797 cstr = tcc_malloc(sizeof(CString));
1798 size = cstr1->size;
1799 cstr->size = size;
1800 cstr->size_allocated = size;
1801 cstr->data_allocated = tcc_malloc(size);
1802 cstr->data = cstr->data_allocated;
1803 memcpy(cstr->data_allocated, cstr1->data_allocated, size);
1804 cv1.cstr = cstr;
1805 tok_str_add(s, cv1.tab[0]);
1806 } else {
1807 n = tok_ext_size(t);
1808 for(i=0;i<n;i++)
1809 tok_str_add(s, cv->tab[i]);
1813 /* add the current parse token in token string 's' */
1814 static void tok_str_add_tok(TokenString *s)
1816 CValue cval;
1818 /* save line number info */
1819 if (file->line_num != s->last_line_num) {
1820 s->last_line_num = file->line_num;
1821 cval.i = s->last_line_num;
1822 tok_str_add2(s, TOK_LINENUM, &cval);
1824 tok_str_add2(s, tok, &tokc);
1827 /* get a token from an integer array and increment pointer accordingly */
1828 static int tok_get(int **tok_str, CValue *cv)
1830 int *p, t, n, i;
1832 p = *tok_str;
1833 t = *p++;
1834 n = tok_ext_size(t);
1835 for(i=0;i<n;i++)
1836 cv->tab[i] = *p++;
1837 *tok_str = p;
1838 return t;
1841 /* eval an expression for #if/#elif */
1842 int expr_preprocess(void)
1844 int c, t;
1845 TokenString str;
1847 tok_str_new(&str);
1848 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1849 next(); /* do macro subst */
1850 if (tok == TOK_DEFINED) {
1851 next_nomacro();
1852 t = tok;
1853 if (t == '(')
1854 next_nomacro();
1855 c = sym_find1(&define_stack, tok) != 0;
1856 if (t == '(')
1857 next_nomacro();
1858 tok = TOK_CINT;
1859 tokc.i = c;
1860 } else if (tok >= TOK_IDENT) {
1861 /* if undefined macro */
1862 tok = TOK_CINT;
1863 tokc.i = 0;
1865 tok_str_add_tok(&str);
1867 tok_str_add(&str, -1); /* simulate end of file */
1868 tok_str_add(&str, 0);
1869 /* now evaluate C constant expression */
1870 macro_ptr = str.str;
1871 next();
1872 c = expr_const();
1873 macro_ptr = NULL;
1874 tok_str_free(str.str);
1875 return c != 0;
1878 #if defined(DEBUG) || defined(PP_DEBUG)
1879 void tok_print(int *str)
1881 int t;
1882 CValue cval;
1884 while (1) {
1885 t = tok_get(&str, &cval);
1886 if (!t)
1887 break;
1888 printf(" %s", get_tok_str(t, &cval));
1890 printf("\n");
1892 #endif
1894 /* parse after #define */
1895 void parse_define(void)
1897 Sym *s, *first, **ps;
1898 int v, t, varg, is_vaargs;
1899 TokenString str;
1901 v = tok;
1902 /* XXX: should check if same macro (ANSI) */
1903 first = NULL;
1904 t = MACRO_OBJ;
1905 /* '(' must be just after macro definition for MACRO_FUNC */
1906 if (ch == '(') {
1907 next_nomacro();
1908 next_nomacro();
1909 ps = &first;
1910 while (tok != ')') {
1911 varg = tok;
1912 next_nomacro();
1913 is_vaargs = 0;
1914 if (varg == TOK_DOTS) {
1915 varg = TOK___VA_ARGS__;
1916 is_vaargs = 1;
1917 } else if (tok == TOK_DOTS && gnu_ext) {
1918 is_vaargs = 1;
1919 next_nomacro();
1921 if (varg < TOK_IDENT)
1922 error("badly punctuated parameter list");
1923 s = sym_push1(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
1924 *ps = s;
1925 ps = &s->next;
1926 if (tok != ',')
1927 break;
1928 next_nomacro();
1930 t = MACRO_FUNC;
1932 tok_str_new(&str);
1933 next_nomacro();
1934 /* EOF testing necessary for '-D' handling */
1935 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
1936 tok_str_add2(&str, tok, &tokc);
1937 next_nomacro();
1939 tok_str_add(&str, 0);
1940 #ifdef PP_DEBUG
1941 printf("define %s %d: ", get_tok_str(v, NULL), t);
1942 tok_print(str.str);
1943 #endif
1944 s = sym_push1(&define_stack, v, t, (int)str.str);
1945 s->next = first;
1948 /* XXX: use a token or a hash table to accelerate matching ? */
1949 static CachedInclude *search_cached_include(TCCState *s1,
1950 int type, const char *filename)
1952 CachedInclude *e;
1953 int i;
1955 for(i = 0;i < s1->nb_cached_includes; i++) {
1956 e = s1->cached_includes[i];
1957 if (e->type == type && !strcmp(e->filename, filename))
1958 return e;
1960 return NULL;
1963 static inline void add_cached_include(TCCState *s1, int type,
1964 const char *filename, int ifndef_macro)
1966 CachedInclude *e;
1968 if (search_cached_include(s1, type, filename))
1969 return;
1970 #ifdef INC_DEBUG
1971 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
1972 #endif
1973 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
1974 if (!e)
1975 return;
1976 e->type = type;
1977 strcpy(e->filename, filename);
1978 e->ifndef_macro = ifndef_macro;
1979 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
1983 enum IncludeState {
1984 INCLUDE_STATE_NONE = 0,
1985 INCLUDE_STATE_SEEK_IFNDEF,
1988 void preprocess(void)
1990 TCCState *s1 = tcc_state;
1991 int size, i, c, n;
1992 enum IncludeState state;
1993 char buf[1024], *q, *p;
1994 char buf1[1024];
1995 BufferedFile *f;
1996 Sym *s;
1997 CachedInclude *e;
1999 return_linefeed = 1; /* linefeed will be returned as a
2000 token. EOF is also returned as line feed */
2001 state = INCLUDE_STATE_NONE;
2002 eof_seen = 0;
2003 redo1:
2004 cinp();
2005 next_nomacro();
2006 redo:
2007 if (tok == TOK_DEFINE) {
2008 next_nomacro();
2009 parse_define();
2010 } else if (tok == TOK_UNDEF) {
2011 next_nomacro();
2012 s = sym_find1(&define_stack, tok);
2013 /* undefine symbol by putting an invalid name */
2014 if (s)
2015 sym_undef(&define_stack, s);
2016 } else if (tok == TOK_INCLUDE) {
2017 skip_spaces();
2018 if (ch == '<') {
2019 c = '>';
2020 goto read_name;
2021 } else if (ch == '\"') {
2022 c = ch;
2023 read_name:
2024 minp();
2025 q = buf;
2026 while (ch != c && ch != '\n' && ch != CH_EOF) {
2027 if ((q - buf) < sizeof(buf) - 1)
2028 *q++ = ch;
2029 minp();
2031 *q = '\0';
2032 /* eat all spaces and comments after include */
2033 /* XXX: slightly incorrect */
2034 while (ch1 != '\n' && ch1 != CH_EOF)
2035 inp();
2036 } else {
2037 /* computed #include : either we have only strings or
2038 we have anything enclosed in '<>' */
2039 next();
2040 buf[0] = '\0';
2041 if (tok == TOK_STR) {
2042 while (tok != TOK_LINEFEED) {
2043 if (tok != TOK_STR) {
2044 include_syntax:
2045 error("'#include' expects \"FILENAME\" or <FILENAME>");
2047 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2048 next();
2050 c = '\"';
2051 } else {
2052 int len;
2053 while (tok != TOK_LINEFEED) {
2054 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2055 next();
2057 len = strlen(buf);
2058 /* check syntax and remove '<>' */
2059 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2060 goto include_syntax;
2061 memmove(buf, buf + 1, len - 2);
2062 buf[len - 2] = '\0';
2063 c = '>';
2067 ch = '\n';
2068 e = search_cached_include(s1, c, buf);
2069 if (e && sym_find1(&define_stack, e->ifndef_macro)) {
2070 /* no need to parse the include because the 'ifndef macro'
2071 is defined */
2072 #ifdef INC_DEBUG
2073 printf("%s: skipping %s\n", file->filename, buf);
2074 #endif
2075 } else {
2076 if (c == '\"') {
2077 /* first search in current dir if "header.h" */
2078 size = 0;
2079 p = strrchr(file->filename, '/');
2080 if (p)
2081 size = p + 1 - file->filename;
2082 if (size > sizeof(buf1) - 1)
2083 size = sizeof(buf1) - 1;
2084 memcpy(buf1, file->filename, size);
2085 buf1[size] = '\0';
2086 pstrcat(buf1, sizeof(buf1), buf);
2087 f = tcc_open(s1, buf1);
2088 if (f)
2089 goto found;
2091 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2092 error("#include recursion too deep");
2093 /* now search in all the include paths */
2094 n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2095 for(i = 0; i < n; i++) {
2096 const char *path;
2097 if (i < s1->nb_include_paths)
2098 path = s1->include_paths[i];
2099 else
2100 path = s1->sysinclude_paths[i - s1->nb_include_paths];
2101 pstrcpy(buf1, sizeof(buf1), path);
2102 pstrcat(buf1, sizeof(buf1), "/");
2103 pstrcat(buf1, sizeof(buf1), buf);
2104 f = tcc_open(s1, buf1);
2105 if (f)
2106 goto found;
2108 error("include file '%s' not found", buf);
2109 f = NULL;
2110 found:
2111 #ifdef INC_DEBUG
2112 printf("%s: including %s\n", file->filename, buf1);
2113 #endif
2114 f->inc_type = c;
2115 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2116 /* push current file in stack */
2117 /* XXX: fix current line init */
2118 *s1->include_stack_ptr++ = file;
2119 file = f;
2120 /* add include file debug info */
2121 if (do_debug) {
2122 put_stabs(file->filename, N_BINCL, 0, 0, 0);
2124 /* we check for the construct: #ifndef IDENT \n #define IDENT */
2125 inp();
2126 /* get first non space char */
2127 while (is_space(ch) || ch == '\n')
2128 cinp();
2129 if (ch != '#')
2130 goto the_end;
2131 state = INCLUDE_STATE_SEEK_IFNDEF;
2132 goto redo1;
2134 } else if (tok == TOK_IFNDEF) {
2135 c = 1;
2136 goto do_ifdef;
2137 } else if (tok == TOK_IF) {
2138 c = expr_preprocess();
2139 goto do_if;
2140 } else if (tok == TOK_IFDEF) {
2141 c = 0;
2142 do_ifdef:
2143 next_nomacro();
2144 if (tok < TOK_IDENT)
2145 error("invalid argument for '#if%sdef'", c ? "n" : "");
2146 if (state == INCLUDE_STATE_SEEK_IFNDEF) {
2147 if (c) {
2148 file->ifndef_macro = tok;
2150 state = INCLUDE_STATE_NONE;
2152 c = (sym_find1(&define_stack, tok) != 0) ^ c;
2153 do_if:
2154 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2155 error("memory full");
2156 *s1->ifdef_stack_ptr++ = c;
2157 goto test_skip;
2158 } else if (tok == TOK_ELSE) {
2159 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2160 error("#else without matching #if");
2161 if (s1->ifdef_stack_ptr[-1] & 2)
2162 error("#else after #else");
2163 c = (s1->ifdef_stack_ptr[-1] ^= 3);
2164 goto test_skip;
2165 } else if (tok == TOK_ELIF) {
2166 if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2167 error("#elif without matching #if");
2168 c = s1->ifdef_stack_ptr[-1];
2169 if (c > 1)
2170 error("#elif after #else");
2171 /* last #if/#elif expression was true: we skip */
2172 if (c == 1)
2173 goto skip;
2174 c = expr_preprocess();
2175 s1->ifdef_stack_ptr[-1] = c;
2176 test_skip:
2177 if (!(c & 1)) {
2178 skip:
2179 preprocess_skip();
2180 state = INCLUDE_STATE_NONE;
2181 goto redo;
2183 } else if (tok == TOK_ENDIF) {
2184 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2185 error("#endif without matching #if");
2186 if (file->ifndef_macro &&
2187 s1->ifdef_stack_ptr == (file->ifdef_stack_ptr + 1)) {
2188 /* '#ifndef macro \n #define macro' was at the start of
2189 file. Now we check if an '#endif' is exactly at the end
2190 of file */
2191 while (tok != TOK_LINEFEED)
2192 next_nomacro();
2193 /* XXX: should also skip comments, but it is more complicated */
2194 if (eof_seen) {
2195 add_cached_include(s1, file->inc_type, file->inc_filename,
2196 file->ifndef_macro);
2197 } else {
2198 /* if not end of file, we must desactivate the ifndef
2199 macro search */
2200 file->ifndef_macro = 0;
2203 s1->ifdef_stack_ptr--;
2204 } else if (tok == TOK_LINE) {
2205 int line_num;
2206 next();
2207 if (tok != TOK_CINT)
2208 error("#line");
2209 line_num = tokc.i;
2210 next();
2211 if (tok != TOK_LINEFEED) {
2212 if (tok != TOK_STR)
2213 error("#line");
2214 pstrcpy(file->filename, sizeof(file->filename),
2215 (char *)tokc.cstr->data);
2217 /* NOTE: we do it there to avoid problems with linefeed */
2218 file->line_num = line_num;
2219 } else if (tok == TOK_ERROR) {
2220 error("#error");
2222 /* ignore other preprocess commands or #! for C scripts */
2223 while (tok != TOK_LINEFEED && tok != TOK_EOF)
2224 next_nomacro();
2225 the_end:
2226 return_linefeed = 0;
2229 /* read a number in base b */
2230 static int getn(int b)
2232 int n, t;
2233 n = 0;
2234 while (1) {
2235 if (ch >= 'a' && ch <= 'f')
2236 t = ch - 'a' + 10;
2237 else if (ch >= 'A' && ch <= 'F')
2238 t = ch - 'A' + 10;
2239 else if (isnum(ch))
2240 t = ch - '0';
2241 else
2242 break;
2243 if (t < 0 || t >= b)
2244 break;
2245 n = n * b + t;
2246 cinp();
2248 return n;
2251 /* read a character for string or char constant and eval escape codes */
2252 static int getq(void)
2254 int c;
2256 c = ch;
2257 minp();
2258 if (c == '\\') {
2259 if (isoct(ch)) {
2260 /* at most three octal digits */
2261 c = ch - '0';
2262 minp();
2263 if (isoct(ch)) {
2264 c = c * 8 + ch - '0';
2265 minp();
2266 if (isoct(ch)) {
2267 c = c * 8 + ch - '0';
2268 minp();
2271 return c;
2272 } else if (ch == 'x') {
2273 minp();
2274 return getn(16);
2275 } else {
2276 if (ch == 'a')
2277 c = '\a';
2278 else if (ch == 'b')
2279 c = '\b';
2280 else if (ch == 'f')
2281 c = '\f';
2282 else if (ch == 'n')
2283 c = '\n';
2284 else if (ch == 'r')
2285 c = '\r';
2286 else if (ch == 't')
2287 c = '\t';
2288 else if (ch == 'v')
2289 c = '\v';
2290 else if (ch == 'e' && gnu_ext)
2291 c = 27;
2292 else if (ch == '\'' || ch == '\"' || ch == '\\' || ch == '?')
2293 c = ch;
2294 else
2295 error("invalid escaped char");
2296 minp();
2298 } else if (c == '\r' && ch == '\n') {
2299 minp();
2300 c = '\n';
2302 return c;
2305 /* we use 64 bit numbers */
2306 #define BN_SIZE 2
2308 /* bn = (bn << shift) | or_val */
2309 void bn_lshift(unsigned int *bn, int shift, int or_val)
2311 int i;
2312 unsigned int v;
2313 for(i=0;i<BN_SIZE;i++) {
2314 v = bn[i];
2315 bn[i] = (v << shift) | or_val;
2316 or_val = v >> (32 - shift);
2320 void bn_zero(unsigned int *bn)
2322 int i;
2323 for(i=0;i<BN_SIZE;i++) {
2324 bn[i] = 0;
2328 void parse_number(void)
2330 int b, t, shift, frac_bits, s, exp_val;
2331 char *q;
2332 unsigned int bn[BN_SIZE];
2333 double d;
2335 /* number */
2336 q = token_buf;
2337 t = ch;
2338 cinp();
2339 *q++ = t;
2340 b = 10;
2341 if (t == '.') {
2342 /* special dot handling */
2343 if (ch >= '0' && ch <= '9') {
2344 goto float_frac_parse;
2345 } else if (ch == '.') {
2346 cinp();
2347 if (ch != '.')
2348 expect("'.'");
2349 cinp();
2350 tok = TOK_DOTS;
2351 } else {
2352 /* dots */
2353 tok = t;
2355 return;
2356 } else if (t == '0') {
2357 if (ch == 'x' || ch == 'X') {
2358 q--;
2359 cinp();
2360 b = 16;
2361 } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
2362 q--;
2363 cinp();
2364 b = 2;
2367 /* parse all digits. cannot check octal numbers at this stage
2368 because of floating point constants */
2369 while (1) {
2370 if (ch >= 'a' && ch <= 'f')
2371 t = ch - 'a' + 10;
2372 else if (ch >= 'A' && ch <= 'F')
2373 t = ch - 'A' + 10;
2374 else if (isnum(ch))
2375 t = ch - '0';
2376 else
2377 break;
2378 if (t >= b)
2379 break;
2380 if (q >= token_buf + STRING_MAX_SIZE) {
2381 num_too_long:
2382 error("number too long");
2384 *q++ = ch;
2385 cinp();
2387 if (ch == '.' ||
2388 ((ch == 'e' || ch == 'E') && b == 10) ||
2389 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
2390 if (b != 10) {
2391 /* NOTE: strtox should support that for hexa numbers, but
2392 non ISOC99 libcs do not support it, so we prefer to do
2393 it by hand */
2394 /* hexadecimal or binary floats */
2395 /* XXX: handle overflows */
2396 *q = '\0';
2397 if (b == 16)
2398 shift = 4;
2399 else
2400 shift = 2;
2401 bn_zero(bn);
2402 q = token_buf;
2403 while (1) {
2404 t = *q++;
2405 if (t == '\0') {
2406 break;
2407 } else if (t >= 'a') {
2408 t = t - 'a' + 10;
2409 } else if (t >= 'A') {
2410 t = t - 'A' + 10;
2411 } else {
2412 t = t - '0';
2414 bn_lshift(bn, shift, t);
2416 frac_bits = 0;
2417 if (ch == '.') {
2418 cinp();
2419 while (1) {
2420 t = ch;
2421 if (t >= 'a' && t <= 'f') {
2422 t = t - 'a' + 10;
2423 } else if (t >= 'A' && t <= 'F') {
2424 t = t - 'A' + 10;
2425 } else if (t >= '0' && t <= '9') {
2426 t = t - '0';
2427 } else {
2428 break;
2430 if (t >= b)
2431 error("invalid digit");
2432 bn_lshift(bn, shift, t);
2433 frac_bits += shift;
2434 cinp();
2437 if (ch != 'p' && ch != 'P')
2438 error("exponent expected");
2439 cinp();
2440 s = 1;
2441 exp_val = 0;
2442 if (ch == '+') {
2443 cinp();
2444 } else if (ch == '-') {
2445 s = -1;
2446 cinp();
2448 if (ch < '0' || ch > '9')
2449 error("exponent digits expected");
2450 while (ch >= '0' && ch <= '9') {
2451 exp_val = exp_val * 10 + ch - '0';
2452 cinp();
2454 exp_val = exp_val * s;
2456 /* now we can generate the number */
2457 /* XXX: should patch directly float number */
2458 d = (double)bn[1] * 4294967296.0 + (double)bn[0];
2459 d = ldexp(d, exp_val - frac_bits);
2460 t = toup(ch);
2461 if (t == 'F') {
2462 cinp();
2463 tok = TOK_CFLOAT;
2464 /* float : should handle overflow */
2465 tokc.f = (float)d;
2466 } else if (t == 'L') {
2467 cinp();
2468 tok = TOK_CLDOUBLE;
2469 /* XXX: not large enough */
2470 tokc.ld = (long double)d;
2471 } else {
2472 tok = TOK_CDOUBLE;
2473 tokc.d = d;
2475 } else {
2476 /* decimal floats */
2477 if (ch == '.') {
2478 if (q >= token_buf + STRING_MAX_SIZE)
2479 goto num_too_long;
2480 *q++ = ch;
2481 cinp();
2482 float_frac_parse:
2483 while (ch >= '0' && ch <= '9') {
2484 if (q >= token_buf + STRING_MAX_SIZE)
2485 goto num_too_long;
2486 *q++ = ch;
2487 cinp();
2490 if (ch == 'e' || ch == 'E') {
2491 if (q >= token_buf + STRING_MAX_SIZE)
2492 goto num_too_long;
2493 *q++ = ch;
2494 cinp();
2495 if (ch == '-' || ch == '+') {
2496 if (q >= token_buf + STRING_MAX_SIZE)
2497 goto num_too_long;
2498 *q++ = ch;
2499 cinp();
2501 if (ch < '0' || ch > '9')
2502 error("exponent digits expected");
2503 while (ch >= '0' && ch <= '9') {
2504 if (q >= token_buf + STRING_MAX_SIZE)
2505 goto num_too_long;
2506 *q++ = ch;
2507 cinp();
2510 *q = '\0';
2511 t = toup(ch);
2512 errno = 0;
2513 if (t == 'F') {
2514 cinp();
2515 tok = TOK_CFLOAT;
2516 tokc.f = strtof(token_buf, NULL);
2517 } else if (t == 'L') {
2518 cinp();
2519 tok = TOK_CLDOUBLE;
2520 tokc.ld = strtold(token_buf, NULL);
2521 } else {
2522 tok = TOK_CDOUBLE;
2523 tokc.d = strtod(token_buf, NULL);
2526 } else {
2527 unsigned long long n, n1;
2528 int lcount;
2530 /* integer number */
2531 *q = '\0';
2532 q = token_buf;
2533 if (b == 10 && *q == '0') {
2534 b = 8;
2535 q++;
2537 n = 0;
2538 while(1) {
2539 t = *q++;
2540 /* no need for checks except for base 10 / 8 errors */
2541 if (t == '\0') {
2542 break;
2543 } else if (t >= 'a') {
2544 t = t - 'a' + 10;
2545 } else if (t >= 'A') {
2546 t = t - 'A' + 10;
2547 } else {
2548 t = t - '0';
2549 if (t >= b)
2550 error("invalid digit");
2552 n1 = n;
2553 n = n * b + t;
2554 /* detect overflow */
2555 if (n < n1)
2556 error("integer constant overflow");
2559 /* XXX: not exactly ANSI compliant */
2560 if ((n & 0xffffffff00000000LL) != 0) {
2561 if ((n >> 63) != 0)
2562 tok = TOK_CULLONG;
2563 else
2564 tok = TOK_CLLONG;
2565 } else if (n > 0x7fffffff) {
2566 tok = TOK_CUINT;
2567 } else {
2568 tok = TOK_CINT;
2570 lcount = 0;
2571 for(;;) {
2572 t = toup(ch);
2573 if (t == 'L') {
2574 if (lcount >= 2)
2575 error("three 'l' in integer constant");
2576 lcount++;
2577 if (lcount == 2) {
2578 if (tok == TOK_CINT)
2579 tok = TOK_CLLONG;
2580 else if (tok == TOK_CUINT)
2581 tok = TOK_CULLONG;
2583 cinp();
2584 } else if (t == 'U') {
2585 if (tok == TOK_CINT)
2586 tok = TOK_CUINT;
2587 else if (tok == TOK_CLLONG)
2588 tok = TOK_CULLONG;
2589 cinp();
2590 } else {
2591 break;
2594 if (tok == TOK_CINT || tok == TOK_CUINT)
2595 tokc.ui = n;
2596 else
2597 tokc.ull = n;
2602 /* return next token without macro substitution */
2603 static inline void next_nomacro1(void)
2605 int b;
2606 char *q;
2607 TokenSym *ts;
2609 /* skip spaces */
2610 while(1) {
2611 while (ch == '\n') {
2612 /* during preprocessor parsing, '\n' is a token */
2613 if (return_linefeed) {
2614 tok = TOK_LINEFEED;
2615 return;
2617 cinp();
2618 skip_spaces();
2619 if (ch == '#') {
2620 /* preprocessor command if # at start of line after
2621 spaces */
2622 preprocess();
2625 if (!is_space(ch))
2626 break;
2627 cinp();
2629 if (isid(ch)) {
2630 q = token_buf;
2631 *q++ = ch;
2632 cinp();
2633 if (q[-1] == 'L') {
2634 if (ch == '\'') {
2635 tok = TOK_LCHAR;
2636 goto char_const;
2638 if (ch == '\"') {
2639 tok = TOK_LSTR;
2640 goto str_const;
2643 while (isid(ch) || isnum(ch)) {
2644 if (q >= token_buf + STRING_MAX_SIZE)
2645 error("ident too long");
2646 *q++ = ch;
2647 cinp();
2649 *q = '\0';
2650 ts = tok_alloc(token_buf, q - token_buf);
2651 tok = ts->tok;
2652 } else if (isnum(ch) || ch == '.') {
2653 parse_number();
2654 } else if (ch == '\'') {
2655 tok = TOK_CCHAR;
2656 char_const:
2657 minp();
2658 b = getq();
2659 /* this cast is needed if >= 128 */
2660 if (tok == TOK_CCHAR)
2661 b = (char)b;
2662 tokc.i = b;
2663 if (ch != '\'')
2664 expect("\'");
2665 minp();
2666 } else if (ch == '\"') {
2667 tok = TOK_STR;
2668 str_const:
2669 minp();
2670 cstr_reset(&tokcstr);
2671 while (ch != '\"') {
2672 b = getq();
2673 if (ch == CH_EOF)
2674 error("unterminated string");
2675 if (tok == TOK_STR)
2676 cstr_ccat(&tokcstr, b);
2677 else
2678 cstr_wccat(&tokcstr, b);
2680 if (tok == TOK_STR)
2681 cstr_ccat(&tokcstr, '\0');
2682 else
2683 cstr_wccat(&tokcstr, '\0');
2684 tokc.cstr = &tokcstr;
2685 minp();
2686 } else {
2687 q = tok_two_chars;
2688 /* two chars */
2689 tok = ch;
2690 cinp();
2691 while (*q) {
2692 if (*q == tok && q[1] == ch) {
2693 cinp();
2694 tok = q[2] & 0xff;
2695 /* three chars tests */
2696 if (tok == TOK_SHL || tok == TOK_SAR) {
2697 if (ch == '=') {
2698 tok = tok | 0x80;
2699 cinp();
2701 } else if (tok == TOK_DOTS) {
2702 if (ch != '.')
2703 error("parse error");
2704 cinp();
2706 return;
2708 q = q + 3;
2710 /* single char substitutions */
2711 if (tok == '<')
2712 tok = TOK_LT;
2713 else if (tok == '>')
2714 tok = TOK_GT;
2718 /* return next token without macro substitution. Can read input from
2719 macro_ptr buffer */
2720 void next_nomacro()
2722 if (macro_ptr) {
2723 redo:
2724 tok = *macro_ptr;
2725 if (tok) {
2726 tok = tok_get(&macro_ptr, &tokc);
2727 if (tok == TOK_LINENUM) {
2728 file->line_num = tokc.i;
2729 goto redo;
2732 } else {
2733 next_nomacro1();
2737 /* substitute args in macro_str and return allocated string */
2738 int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
2740 int *st, last_tok, t, notfirst;
2741 Sym *s;
2742 CValue cval;
2743 TokenString str;
2744 CString cstr;
2746 tok_str_new(&str);
2747 last_tok = 0;
2748 while(1) {
2749 t = tok_get(&macro_str, &cval);
2750 if (!t)
2751 break;
2752 if (t == '#') {
2753 /* stringize */
2754 t = tok_get(&macro_str, &cval);
2755 if (!t)
2756 break;
2757 s = sym_find2(args, t);
2758 if (s) {
2759 cstr_new(&cstr);
2760 st = (int *)s->c;
2761 notfirst = 0;
2762 while (*st) {
2763 if (notfirst)
2764 cstr_ccat(&cstr, ' ');
2765 t = tok_get(&st, &cval);
2766 cstr_cat(&cstr, get_tok_str(t, &cval));
2767 notfirst = 1;
2769 cstr_ccat(&cstr, '\0');
2770 #ifdef PP_DEBUG
2771 printf("stringize: %s\n", (char *)cstr.data);
2772 #endif
2773 /* add string */
2774 cval.cstr = &cstr;
2775 tok_str_add2(&str, TOK_STR, &cval);
2776 cstr_free(&cstr);
2777 } else {
2778 tok_str_add2(&str, t, &cval);
2780 } else if (t >= TOK_IDENT) {
2781 s = sym_find2(args, t);
2782 if (s) {
2783 st = (int *)s->c;
2784 /* if '##' is present before or after, no arg substitution */
2785 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
2786 /* special case for var arg macros : ## eats the
2787 ',' if empty VA_ARGS variable. */
2788 /* XXX: test of the ',' is not 100%
2789 reliable. should fix it to avoid security
2790 problems */
2791 if (gnu_ext && s->t &&
2792 last_tok == TOK_TWOSHARPS &&
2793 str.len >= 2 && str.str[str.len - 2] == ',') {
2794 if (*st == 0) {
2795 /* suppress ',' '##' */
2796 str.len -= 2;
2797 } else {
2798 /* suppress '##' and add variable */
2799 str.len--;
2800 goto add_var;
2802 } else {
2803 int t1;
2804 add_var:
2805 for(;;) {
2806 t1 = tok_get(&st, &cval);
2807 if (!t1)
2808 break;
2809 tok_str_add2(&str, t1, &cval);
2812 } else {
2813 macro_subst(&str, nested_list, st);
2815 } else {
2816 tok_str_add(&str, t);
2818 } else {
2819 tok_str_add2(&str, t, &cval);
2821 last_tok = t;
2823 tok_str_add(&str, 0);
2824 return str.str;
2827 /* not inline to save space */
2828 static int is_tok_num(int t)
2830 return (t == TOK_CINT || t == TOK_CUINT ||
2831 t == TOK_CLLONG || t == TOK_CULLONG);
2834 /* handle the '##' operator */
2835 static int *macro_twosharps(void)
2837 TokenSym *ts;
2838 int *macro_ptr1;
2839 int t;
2840 const char *p1, *p2;
2841 CValue cval;
2842 TokenString macro_str1;
2844 tok_str_new(&macro_str1);
2845 tok = 0;
2846 while (1) {
2847 next_nomacro();
2848 if (tok == 0)
2849 break;
2850 while (*macro_ptr == TOK_TWOSHARPS) {
2851 macro_ptr++;
2852 macro_ptr1 = macro_ptr;
2853 t = *macro_ptr;
2854 if (t) {
2855 t = tok_get(&macro_ptr, &cval);
2856 /* XXX: not exact, but cannot do more without
2857 modifying the whole preprocessing architecture ! */
2858 /* XXX: handle arbitrary size */
2859 p1 = get_tok_str(tok, &tokc);
2860 pstrcpy(token_buf, sizeof(token_buf), p1);
2861 p2 = get_tok_str(t, &cval);
2862 if (tok >= TOK_IDENT &&
2863 (t >= TOK_IDENT || is_tok_num(t))) {
2864 pstrcat(token_buf, sizeof(token_buf), p2);
2865 ts = tok_alloc(token_buf, strlen(token_buf));
2866 tok = ts->tok; /* modify current token */
2867 } else if (is_tok_num(tok) && is_tok_num(t)) {
2868 unsigned long long n;
2869 do_num:
2870 pstrcat(token_buf, sizeof(token_buf), p2);
2871 n = strtoull(token_buf, NULL, 10);
2872 if ((n & 0xffffffff00000000LL) != 0) {
2873 if ((n >> 63) != 0)
2874 tok = TOK_CULLONG;
2875 else
2876 tok = TOK_CLLONG;
2877 } else if (n > 0x7fffffff) {
2878 tok = TOK_CUINT;
2879 } else {
2880 tok = TOK_CINT;
2882 if (tok == TOK_CINT || tok == TOK_CUINT)
2883 tokc.ui = n;
2884 else
2885 tokc.ull = n;
2886 } else if (is_tok_num(tok) && t >= TOK_IDENT) {
2887 /* incorrect, but suffisant for '1LL' case */
2888 goto do_num;
2889 } else {
2890 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", token_buf, p2);
2891 /* cannot merge tokens: skip '##' */
2892 macro_ptr = macro_ptr1;
2893 break;
2897 tok_str_add2(&macro_str1, tok, &tokc);
2899 tok_str_add(&macro_str1, 0);
2900 return macro_str1.str;
2904 /* do macro substitution of current token with macro 's' and add
2905 result to (tok_str,tok_len). 'nested_list' is the list of all
2906 macros we got inside to avoid recursing. Return non zero if no
2907 substitution needs to be done */
2908 static int macro_subst_tok(TokenString *tok_str,
2909 Sym **nested_list, Sym *s)
2911 Sym *args, *sa, *sa1;
2912 int mstr_allocated, parlevel, *mstr, t;
2913 TokenString str;
2914 char *cstrval;
2915 CValue cval;
2916 CString cstr;
2918 /* if symbol is a macro, prepare substitution */
2919 /* if nested substitution, do nothing */
2920 if (sym_find2(*nested_list, tok))
2921 return -1;
2923 /* special macros */
2924 if (tok == TOK___LINE__) {
2925 cval.i = file->line_num;
2926 tok_str_add2(tok_str, TOK_CINT, &cval);
2927 } else if (tok == TOK___FILE__) {
2928 cstrval = file->filename;
2929 goto add_cstr;
2930 tok_str_add2(tok_str, TOK_STR, &cval);
2931 } else if (tok == TOK___DATE__) {
2932 cstrval = "Jan 1 2002";
2933 goto add_cstr;
2934 } else if (tok == TOK___TIME__) {
2935 cstrval = "00:00:00";
2936 add_cstr:
2937 cstr_new(&cstr);
2938 cstr_cat(&cstr, cstrval);
2939 cstr_ccat(&cstr, '\0');
2940 cval.cstr = &cstr;
2941 tok_str_add2(tok_str, TOK_STR, &cval);
2942 cstr_free(&cstr);
2943 } else {
2944 mstr = (int *)s->c;
2945 mstr_allocated = 0;
2946 if (s->t == MACRO_FUNC) {
2947 /* NOTE: we do not use next_nomacro to avoid eating the
2948 next token. XXX: find better solution */
2949 if (macro_ptr) {
2950 t = *macro_ptr;
2951 } else {
2952 while (is_space(ch) || ch == '\n')
2953 cinp();
2954 t = ch;
2956 if (t != '(') /* no macro subst */
2957 return -1;
2959 /* argument macro */
2960 next_nomacro();
2961 next_nomacro();
2962 args = NULL;
2963 sa = s->next;
2964 /* NOTE: empty args are allowed, except if no args */
2965 for(;;) {
2966 /* handle '()' case */
2967 if (!args && tok == ')')
2968 break;
2969 if (!sa)
2970 error("macro '%s' used with too many args",
2971 get_tok_str(s->v, 0));
2972 tok_str_new(&str);
2973 parlevel = 0;
2974 /* NOTE: non zero sa->t indicates VA_ARGS */
2975 while ((parlevel > 0 ||
2976 (tok != ')' &&
2977 (tok != ',' || sa->t))) &&
2978 tok != -1) {
2979 if (tok == '(')
2980 parlevel++;
2981 else if (tok == ')')
2982 parlevel--;
2983 tok_str_add2(&str, tok, &tokc);
2984 next_nomacro();
2986 tok_str_add(&str, 0);
2987 sym_push2(&args, sa->v & ~SYM_FIELD, sa->t, (int)str.str);
2988 sa = sa->next;
2989 if (tok == ')') {
2990 /* special case for gcc var args: add an empty
2991 var arg argument if it is omitted */
2992 if (sa && sa->t && gnu_ext)
2993 continue;
2994 else
2995 break;
2997 if (tok != ',')
2998 expect(",");
2999 next_nomacro();
3001 if (sa) {
3002 error("macro '%s' used with too few args",
3003 get_tok_str(s->v, 0));
3006 /* now subst each arg */
3007 mstr = macro_arg_subst(nested_list, mstr, args);
3008 /* free memory */
3009 sa = args;
3010 while (sa) {
3011 sa1 = sa->prev;
3012 tok_str_free((int *)sa->c);
3013 tcc_free(sa);
3014 sa = sa1;
3016 mstr_allocated = 1;
3018 sym_push2(nested_list, s->v, 0, 0);
3019 macro_subst(tok_str, nested_list, mstr);
3020 /* pop nested defined symbol */
3021 sa1 = *nested_list;
3022 *nested_list = sa1->prev;
3023 tcc_free(sa1);
3024 if (mstr_allocated)
3025 tok_str_free(mstr);
3027 return 0;
3030 /* do macro substitution of macro_str and add result to
3031 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3032 inside to avoid recursing. */
3033 static void macro_subst(TokenString *tok_str,
3034 Sym **nested_list, int *macro_str)
3036 Sym *s;
3037 int *saved_macro_ptr;
3038 int *macro_str1;
3040 saved_macro_ptr = macro_ptr;
3041 macro_ptr = macro_str;
3042 /* first scan for '##' operator handling */
3043 macro_str1 = macro_twosharps();
3044 macro_ptr = macro_str1;
3046 while (1) {
3047 next_nomacro();
3048 if (tok == 0)
3049 break;
3050 s = sym_find1(&define_stack, tok);
3051 if (s != NULL) {
3052 if (macro_subst_tok(tok_str, nested_list, s) != 0)
3053 goto no_subst;
3054 } else {
3055 no_subst:
3056 tok_str_add2(tok_str, tok, &tokc);
3059 macro_ptr = saved_macro_ptr;
3060 tok_str_free(macro_str1);
3063 /* return next token with macro substitution */
3064 void next(void)
3066 Sym *nested_list, *s;
3067 TokenString str;
3069 /* special 'ungettok' case for label parsing */
3070 if (tok1) {
3071 tok = tok1;
3072 tokc = tok1c;
3073 tok1 = 0;
3074 } else {
3075 redo:
3076 next_nomacro();
3077 if (!macro_ptr) {
3078 /* if not reading from macro substituted string, then try
3079 to substitute macros */
3080 if (tok >= TOK_IDENT) {
3081 s = sym_find1(&define_stack, tok);
3082 if (s) {
3083 /* we have a macro: we try to substitute */
3084 tok_str_new(&str);
3085 nested_list = NULL;
3086 if (macro_subst_tok(&str, &nested_list, s) == 0) {
3087 /* substitution done, NOTE: maybe empty */
3088 tok_str_add(&str, 0);
3089 macro_ptr = str.str;
3090 macro_ptr_allocated = str.str;
3091 goto redo;
3095 } else {
3096 if (tok == 0) {
3097 /* end of macro string: free it */
3098 tok_str_free(macro_ptr_allocated);
3099 macro_ptr = NULL;
3100 goto redo;
3104 #if defined(DEBUG)
3105 printf("token = %s\n", get_tok_str(tok, &tokc));
3106 #endif
3109 void swap(int *p, int *q)
3111 int t;
3112 t = *p;
3113 *p = *q;
3114 *q = t;
3117 void vsetc(int t, int r, CValue *vc)
3119 int v;
3121 if (vtop >= vstack + VSTACK_SIZE)
3122 error("memory full");
3123 /* cannot let cpu flags if other instruction are generated. Also
3124 avoid leaving VT_JMP anywhere except on the top of the stack
3125 because it would complicate the code generator. */
3126 if (vtop >= vstack) {
3127 v = vtop->r & VT_VALMASK;
3128 if (v == VT_CMP || (v & ~1) == VT_JMP)
3129 gv(RC_INT);
3131 vtop++;
3132 vtop->t = t;
3133 vtop->r = r;
3134 vtop->r2 = VT_CONST;
3135 vtop->c = *vc;
3138 /* push integer constant */
3139 void vpushi(int v)
3141 CValue cval;
3142 cval.i = v;
3143 vsetc(VT_INT, VT_CONST, &cval);
3146 /* Return a static symbol pointing to a section */
3147 static Sym *get_sym_ref(int t, Section *sec,
3148 unsigned long offset, unsigned long size)
3150 int v;
3151 Sym *sym;
3153 v = anon_sym++;
3154 sym = sym_push1(&global_stack, v, t | VT_STATIC, 0);
3155 sym->r = VT_CONST | VT_SYM;
3156 put_extern_sym(sym, sec, offset, size);
3157 return sym;
3160 /* push a reference to a section offset by adding a dummy symbol */
3161 static void vpush_ref(int t, Section *sec, unsigned long offset, unsigned long size)
3163 CValue cval;
3165 cval.ul = 0;
3166 vsetc(t, VT_CONST | VT_SYM, &cval);
3167 vtop->sym = get_sym_ref(t, sec, offset, size);
3170 /* define a new external reference to a symbol 'v' of type 'u' */
3171 static Sym *external_global_sym(int v, int u, int r)
3173 Sym *s;
3175 s = sym_find(v);
3176 if (!s) {
3177 /* push forward reference */
3178 s = sym_push1(&global_stack,
3179 v, u | VT_EXTERN, 0);
3180 s->r = r | VT_CONST | VT_SYM;
3182 return s;
3185 /* define a new external reference to a symbol 'v' of type 'u' */
3186 static Sym *external_sym(int v, int u, int r)
3188 Sym *s;
3190 s = sym_find(v);
3191 if (!s) {
3192 /* push forward reference */
3193 s = sym_push(v, u | VT_EXTERN, r | VT_CONST | VT_SYM, 0);
3195 return s;
3198 /* push a reference to global symbol v */
3199 static void vpush_global_sym(int t, int v)
3201 Sym *sym;
3202 CValue cval;
3204 sym = external_global_sym(v, t, 0);
3205 cval.ul = 0;
3206 vsetc(t, VT_CONST | VT_SYM, &cval);
3207 vtop->sym = sym;
3210 void vset(int t, int r, int v)
3212 CValue cval;
3214 cval.i = v;
3215 vsetc(t, r, &cval);
3218 void vswap(void)
3220 SValue tmp;
3222 tmp = vtop[0];
3223 vtop[0] = vtop[-1];
3224 vtop[-1] = tmp;
3227 void vpushv(SValue *v)
3229 if (vtop >= vstack + VSTACK_SIZE)
3230 error("memory full");
3231 vtop++;
3232 *vtop = *v;
3235 void vdup(void)
3237 vpushv(vtop);
3240 /* save r to the memory stack, and mark it as being free */
3241 void save_reg(int r)
3243 int l, saved, t, size, align;
3244 SValue *p, sv;
3246 /* modify all stack values */
3247 saved = 0;
3248 l = 0;
3249 for(p=vstack;p<=vtop;p++) {
3250 if ((p->r & VT_VALMASK) == r ||
3251 (p->r2 & VT_VALMASK) == r) {
3252 /* must save value on stack if not already done */
3253 if (!saved) {
3254 /* NOTE: must reload 'r' because r might be equal to r2 */
3255 r = p->r & VT_VALMASK;
3256 /* store register in the stack */
3257 t = p->t;
3258 if ((p->r & VT_LVAL) ||
3259 (!is_float(t) && (t & VT_BTYPE) != VT_LLONG))
3260 t = VT_INT;
3261 size = type_size(t, &align);
3262 loc = (loc - size) & -align;
3263 sv.t = t;
3264 sv.r = VT_LOCAL | VT_LVAL;
3265 sv.c.ul = loc;
3266 store(r, &sv);
3267 #ifdef TCC_TARGET_I386
3268 /* x86 specific: need to pop fp register ST0 if saved */
3269 if (r == REG_ST0) {
3270 o(0xd9dd); /* fstp %st(1) */
3272 #endif
3273 /* special long long case */
3274 if ((t & VT_BTYPE) == VT_LLONG) {
3275 sv.c.ul += 4;
3276 store(p->r2, &sv);
3278 l = loc;
3279 saved = 1;
3281 /* mark that stack entry as being saved on the stack */
3282 if (p->r & VT_LVAL) {
3283 /* also suppress the bounded flag because the
3284 relocation address of the function was stored in
3285 p->c.ul */
3286 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
3287 } else {
3288 p->r = lvalue_type(p->t) | VT_LOCAL;
3290 p->r2 = VT_CONST;
3291 p->c.ul = l;
3296 /* find a free register of class 'rc'. If none, save one register */
3297 int get_reg(int rc)
3299 int r;
3300 SValue *p;
3302 /* find a free register */
3303 for(r=0;r<NB_REGS;r++) {
3304 if (reg_classes[r] & rc) {
3305 for(p=vstack;p<=vtop;p++) {
3306 if ((p->r & VT_VALMASK) == r ||
3307 (p->r2 & VT_VALMASK) == r)
3308 goto notfound;
3310 return r;
3312 notfound: ;
3315 /* no register left : free the first one on the stack (VERY
3316 IMPORTANT to start from the bottom to ensure that we don't
3317 spill registers used in gen_opi()) */
3318 for(p=vstack;p<=vtop;p++) {
3319 r = p->r & VT_VALMASK;
3320 if (r < VT_CONST && (reg_classes[r] & rc))
3321 goto save_found;
3322 /* also look at second register (if long long) */
3323 r = p->r2 & VT_VALMASK;
3324 if (r < VT_CONST && (reg_classes[r] & rc)) {
3325 save_found:
3326 save_reg(r);
3327 return r;
3330 /* Should never comes here */
3331 return -1;
3334 /* save registers up to (vtop - n) stack entry */
3335 void save_regs(int n)
3337 int r;
3338 SValue *p, *p1;
3339 p1 = vtop - n;
3340 for(p = vstack;p <= p1; p++) {
3341 r = p->r & VT_VALMASK;
3342 if (r < VT_CONST) {
3343 save_reg(r);
3348 /* move register 's' to 'r', and flush previous value of r to memory
3349 if needed */
3350 void move_reg(int r, int s)
3352 SValue sv;
3354 if (r != s) {
3355 save_reg(r);
3356 sv.t = VT_INT;
3357 sv.r = s;
3358 sv.c.ul = 0;
3359 load(r, &sv);
3363 /* get address of vtop (vtop MUST BE an lvalue) */
3364 void gaddrof(void)
3366 vtop->r &= ~VT_LVAL;
3367 /* tricky: if saved lvalue, then we can go back to lvalue */
3368 if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
3369 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
3372 #ifdef CONFIG_TCC_BCHECK
3373 /* generate lvalue bound code */
3374 void gbound(void)
3376 int lval_type, t1;
3378 vtop->r &= ~VT_MUSTBOUND;
3379 /* if lvalue, then use checking code before dereferencing */
3380 if (vtop->r & VT_LVAL) {
3381 /* if not VT_BOUNDED value, then make one */
3382 if (!(vtop->r & VT_BOUNDED)) {
3383 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
3384 /* must save type because we must set it to int to get pointer */
3385 t1 = vtop->t;
3386 vtop->t = VT_INT;
3387 gaddrof();
3388 vpushi(0);
3389 gen_bounded_ptr_add();
3390 vtop->r |= lval_type;
3391 vtop->t = t1;
3393 /* then check for dereferencing */
3394 gen_bounded_ptr_deref();
3397 #endif
3399 /* store vtop a register belonging to class 'rc'. lvalues are
3400 converted to values. Cannot be used if cannot be converted to
3401 register value (such as structures). */
3402 int gv(int rc)
3404 int r, r2, rc2, bit_pos, bit_size, size, align, i;
3405 unsigned long long ll;
3407 /* NOTE: get_reg can modify vstack[] */
3408 if (vtop->t & VT_BITFIELD) {
3409 bit_pos = (vtop->t >> VT_STRUCT_SHIFT) & 0x3f;
3410 bit_size = (vtop->t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
3411 /* remove bit field info to avoid loops */
3412 vtop->t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
3413 /* generate shifts */
3414 vpushi(32 - (bit_pos + bit_size));
3415 gen_op(TOK_SHL);
3416 vpushi(32 - bit_size);
3417 /* NOTE: transformed to SHR if unsigned */
3418 gen_op(TOK_SAR);
3419 r = gv(rc);
3420 } else {
3421 if (is_float(vtop->t) &&
3422 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3423 Sym *sym;
3424 int *ptr;
3425 unsigned long offset;
3427 /* XXX: unify with initializers handling ? */
3428 /* CPUs usually cannot use float constants, so we store them
3429 generically in data segment */
3430 size = type_size(vtop->t, &align);
3431 offset = (data_section->data_offset + align - 1) & -align;
3432 data_section->data_offset = offset;
3433 /* XXX: not portable yet */
3434 ptr = section_ptr_add(data_section, size);
3435 size = size >> 2;
3436 for(i=0;i<size;i++)
3437 ptr[i] = vtop->c.tab[i];
3438 sym = get_sym_ref(vtop->t, data_section, offset, size << 2);
3439 vtop->r |= VT_LVAL | VT_SYM;
3440 vtop->sym = sym;
3441 vtop->c.ul = 0;
3443 #ifdef CONFIG_TCC_BCHECK
3444 if (vtop->r & VT_MUSTBOUND)
3445 gbound();
3446 #endif
3448 r = vtop->r & VT_VALMASK;
3449 /* need to reload if:
3450 - constant
3451 - lvalue (need to dereference pointer)
3452 - already a register, but not in the right class */
3453 if (r >= VT_CONST ||
3454 (vtop->r & VT_LVAL) ||
3455 !(reg_classes[r] & rc) ||
3456 ((vtop->t & VT_BTYPE) == VT_LLONG &&
3457 !(reg_classes[vtop->r2] & rc))) {
3458 r = get_reg(rc);
3459 if ((vtop->t & VT_BTYPE) == VT_LLONG) {
3460 /* two register type load : expand to two words
3461 temporarily */
3462 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
3463 /* load constant */
3464 ll = vtop->c.ull;
3465 vtop->c.ui = ll; /* first word */
3466 load(r, vtop);
3467 vtop->r = r; /* save register value */
3468 vpushi(ll >> 32); /* second word */
3469 } else if (r >= VT_CONST ||
3470 (vtop->r & VT_LVAL)) {
3471 /* load from memory */
3472 load(r, vtop);
3473 vdup();
3474 vtop[-1].r = r; /* save register value */
3475 /* increment pointer to get second word */
3476 vtop->t = VT_INT;
3477 gaddrof();
3478 vpushi(4);
3479 gen_op('+');
3480 vtop->r |= VT_LVAL;
3481 } else {
3482 /* move registers */
3483 load(r, vtop);
3484 vdup();
3485 vtop[-1].r = r; /* save register value */
3486 vtop->r = vtop[-1].r2;
3488 /* allocate second register */
3489 rc2 = RC_INT;
3490 if (rc == RC_IRET)
3491 rc2 = RC_LRET;
3492 r2 = get_reg(rc2);
3493 load(r2, vtop);
3494 vpop();
3495 /* write second register */
3496 vtop->r2 = r2;
3497 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->t)) {
3498 int t1, t;
3499 /* lvalue of scalar type : need to use lvalue type
3500 because of possible cast */
3501 t = vtop->t;
3502 t1 = t;
3503 /* compute memory access type */
3504 if (vtop->r & VT_LVAL_BYTE)
3505 t = VT_BYTE;
3506 else if (vtop->r & VT_LVAL_SHORT)
3507 t = VT_SHORT;
3508 if (vtop->r & VT_LVAL_UNSIGNED)
3509 t |= VT_UNSIGNED;
3510 vtop->t = t;
3511 load(r, vtop);
3512 /* restore wanted type */
3513 vtop->t = t1;
3514 } else {
3515 /* one register type load */
3516 load(r, vtop);
3519 vtop->r = r;
3521 return r;
3524 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3525 void gv2(int rc1, int rc2)
3527 int v;
3529 /* generate more generic register first. But VT_JMP or VT_CMP
3530 values must be generated first in all cases to avoid possible
3531 reload errors */
3532 v = vtop[0].r & VT_VALMASK;
3533 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
3534 vswap();
3535 gv(rc1);
3536 vswap();
3537 gv(rc2);
3538 /* test if reload is needed for first register */
3539 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
3540 vswap();
3541 gv(rc1);
3542 vswap();
3544 } else {
3545 gv(rc2);
3546 vswap();
3547 gv(rc1);
3548 vswap();
3549 /* test if reload is needed for first register */
3550 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
3551 gv(rc2);
3556 /* expand long long on stack in two int registers */
3557 void lexpand(void)
3559 int u;
3561 u = vtop->t & VT_UNSIGNED;
3562 gv(RC_INT);
3563 vdup();
3564 vtop[0].r = vtop[-1].r2;
3565 vtop[0].r2 = VT_CONST;
3566 vtop[-1].r2 = VT_CONST;
3567 vtop[0].t = VT_INT | u;
3568 vtop[-1].t = VT_INT | u;
3571 /* build a long long from two ints */
3572 void lbuild(int t)
3574 gv2(RC_INT, RC_INT);
3575 vtop[-1].r2 = vtop[0].r;
3576 vtop[-1].t = t;
3577 vpop();
3580 /* rotate n first stack elements to the bottom */
3581 void vrotb(int n)
3583 int i;
3584 SValue tmp;
3586 tmp = vtop[-n + 1];
3587 for(i=-n+1;i!=0;i++)
3588 vtop[i] = vtop[i+1];
3589 vtop[0] = tmp;
3592 /* pop stack value */
3593 void vpop(void)
3595 int v;
3596 v = vtop->r & VT_VALMASK;
3597 #ifdef TCC_TARGET_I386
3598 /* for x86, we need to pop the FP stack */
3599 if (v == REG_ST0) {
3600 o(0xd9dd); /* fstp %st(1) */
3601 } else
3602 #endif
3603 if (v == VT_JMP || v == VT_JMPI) {
3604 /* need to put correct jump if && or || without test */
3605 gsym(vtop->c.ul);
3607 vtop--;
3610 /* convert stack entry to register and duplicate its value in another
3611 register */
3612 void gv_dup(void)
3614 int rc, t, r, r1;
3615 SValue sv;
3617 t = vtop->t;
3618 if ((t & VT_BTYPE) == VT_LLONG) {
3619 lexpand();
3620 gv_dup();
3621 vswap();
3622 vrotb(3);
3623 gv_dup();
3624 vrotb(4);
3625 /* stack: H L L1 H1 */
3626 lbuild(t);
3627 vrotb(3);
3628 vrotb(3);
3629 vswap();
3630 lbuild(t);
3631 vswap();
3632 } else {
3633 /* duplicate value */
3634 rc = RC_INT;
3635 sv.t = VT_INT;
3636 if (is_float(t)) {
3637 rc = RC_FLOAT;
3638 sv.t = t;
3640 r = gv(rc);
3641 r1 = get_reg(rc);
3642 sv.r = r;
3643 sv.c.ul = 0;
3644 load(r1, &sv); /* move r to r1 */
3645 vdup();
3646 /* duplicates value */
3647 vtop->r = r1;
3651 /* generate CPU independent (unsigned) long long operations */
3652 void gen_opl(int op)
3654 int t, a, b, op1, c, i;
3655 int func;
3656 GFuncContext gf;
3657 SValue tmp;
3659 switch(op) {
3660 case '/':
3661 case TOK_PDIV:
3662 func = TOK___divdi3;
3663 goto gen_func;
3664 case TOK_UDIV:
3665 func = TOK___udivdi3;
3666 goto gen_func;
3667 case '%':
3668 func = TOK___moddi3;
3669 goto gen_func;
3670 case TOK_UMOD:
3671 func = TOK___umoddi3;
3672 gen_func:
3673 /* call generic long long function */
3674 gfunc_start(&gf, FUNC_CDECL);
3675 gfunc_param(&gf);
3676 gfunc_param(&gf);
3677 vpush_global_sym(func_old_type, func);
3678 gfunc_call(&gf);
3679 vpushi(0);
3680 vtop->r = REG_IRET;
3681 vtop->r2 = REG_LRET;
3682 break;
3683 case '^':
3684 case '&':
3685 case '|':
3686 case '*':
3687 case '+':
3688 case '-':
3689 t = vtop->t;
3690 vswap();
3691 lexpand();
3692 vrotb(3);
3693 lexpand();
3694 /* stack: L1 H1 L2 H2 */
3695 tmp = vtop[0];
3696 vtop[0] = vtop[-3];
3697 vtop[-3] = tmp;
3698 tmp = vtop[-2];
3699 vtop[-2] = vtop[-3];
3700 vtop[-3] = tmp;
3701 vswap();
3702 /* stack: H1 H2 L1 L2 */
3703 if (op == '*') {
3704 vpushv(vtop - 1);
3705 vpushv(vtop - 1);
3706 gen_op(TOK_UMULL);
3707 lexpand();
3708 /* stack: H1 H2 L1 L2 ML MH */
3709 for(i=0;i<4;i++)
3710 vrotb(6);
3711 /* stack: ML MH H1 H2 L1 L2 */
3712 tmp = vtop[0];
3713 vtop[0] = vtop[-2];
3714 vtop[-2] = tmp;
3715 /* stack: ML MH H1 L2 H2 L1 */
3716 gen_op('*');
3717 vrotb(3);
3718 vrotb(3);
3719 gen_op('*');
3720 /* stack: ML MH M1 M2 */
3721 gen_op('+');
3722 gen_op('+');
3723 } else if (op == '+' || op == '-') {
3724 /* XXX: add non carry method too (for MIPS or alpha) */
3725 if (op == '+')
3726 op1 = TOK_ADDC1;
3727 else
3728 op1 = TOK_SUBC1;
3729 gen_op(op1);
3730 /* stack: H1 H2 (L1 op L2) */
3731 vrotb(3);
3732 vrotb(3);
3733 gen_op(op1 + 1); /* TOK_xxxC2 */
3734 } else {
3735 gen_op(op);
3736 /* stack: H1 H2 (L1 op L2) */
3737 vrotb(3);
3738 vrotb(3);
3739 /* stack: (L1 op L2) H1 H2 */
3740 gen_op(op);
3741 /* stack: (L1 op L2) (H1 op H2) */
3743 /* stack: L H */
3744 lbuild(t);
3745 break;
3746 case TOK_SAR:
3747 case TOK_SHR:
3748 case TOK_SHL:
3749 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
3750 t = vtop[-1].t;
3751 vswap();
3752 lexpand();
3753 vrotb(3);
3754 /* stack: L H shift */
3755 c = (int)vtop->c.i;
3756 /* constant: simpler */
3757 /* NOTE: all comments are for SHL. the other cases are
3758 done by swaping words */
3759 vpop();
3760 if (op != TOK_SHL)
3761 vswap();
3762 if (c >= 32) {
3763 /* stack: L H */
3764 vpop();
3765 if (c > 32) {
3766 vpushi(c - 32);
3767 gen_op(op);
3769 if (op != TOK_SAR) {
3770 vpushi(0);
3771 } else {
3772 gv_dup();
3773 vpushi(31);
3774 gen_op(TOK_SAR);
3776 vswap();
3777 } else {
3778 vswap();
3779 gv_dup();
3780 /* stack: H L L */
3781 vpushi(c);
3782 gen_op(op);
3783 vswap();
3784 vpushi(32 - c);
3785 if (op == TOK_SHL)
3786 gen_op(TOK_SHR);
3787 else
3788 gen_op(TOK_SHL);
3789 vrotb(3);
3790 /* stack: L L H */
3791 vpushi(c);
3792 if (op == TOK_SHL)
3793 gen_op(TOK_SHL);
3794 else
3795 gen_op(TOK_SHR);
3796 gen_op('|');
3798 if (op != TOK_SHL)
3799 vswap();
3800 lbuild(t);
3801 } else {
3802 /* XXX: should provide a faster fallback on x86 ? */
3803 switch(op) {
3804 case TOK_SAR:
3805 func = TOK___sardi3;
3806 goto gen_func;
3807 case TOK_SHR:
3808 func = TOK___shrdi3;
3809 goto gen_func;
3810 case TOK_SHL:
3811 func = TOK___shldi3;
3812 goto gen_func;
3815 break;
3816 default:
3817 /* compare operations */
3818 t = vtop->t;
3819 vswap();
3820 lexpand();
3821 vrotb(3);
3822 lexpand();
3823 /* stack: L1 H1 L2 H2 */
3824 tmp = vtop[-1];
3825 vtop[-1] = vtop[-2];
3826 vtop[-2] = tmp;
3827 /* stack: L1 L2 H1 H2 */
3828 /* compare high */
3829 op1 = op;
3830 /* when values are equal, we need to compare low words. since
3831 the jump is inverted, we invert the test too. */
3832 if (op1 == TOK_LT)
3833 op1 = TOK_LE;
3834 else if (op1 == TOK_GT)
3835 op1 = TOK_GE;
3836 else if (op1 == TOK_ULT)
3837 op1 = TOK_ULE;
3838 else if (op1 == TOK_UGT)
3839 op1 = TOK_UGE;
3840 a = 0;
3841 b = 0;
3842 gen_op(op1);
3843 if (op1 != TOK_NE) {
3844 a = gtst(1, 0);
3846 if (op != TOK_EQ) {
3847 /* generate non equal test */
3848 /* XXX: NOT PORTABLE yet */
3849 if (a == 0) {
3850 b = gtst(0, 0);
3851 } else {
3852 #ifdef TCC_TARGET_I386
3853 b = psym(0x850f, 0);
3854 #else
3855 error("not implemented");
3856 #endif
3859 /* compare low */
3860 gen_op(op);
3861 a = gtst(1, a);
3862 gsym(b);
3863 vset(VT_INT, VT_JMPI, a);
3864 break;
3868 /* handle integer constant optimizations and various machine
3869 independant opt */
3870 void gen_opic(int op)
3872 int fc, c1, c2, n;
3873 SValue *v1, *v2;
3875 v1 = vtop - 1;
3876 v2 = vtop;
3877 /* currently, we cannot do computations with forward symbols */
3878 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3879 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3880 if (c1 && c2) {
3881 fc = v2->c.i;
3882 switch(op) {
3883 case '+': v1->c.i += fc; break;
3884 case '-': v1->c.i -= fc; break;
3885 case '&': v1->c.i &= fc; break;
3886 case '^': v1->c.i ^= fc; break;
3887 case '|': v1->c.i |= fc; break;
3888 case '*': v1->c.i *= fc; break;
3890 case TOK_PDIV:
3891 case '/':
3892 case '%':
3893 case TOK_UDIV:
3894 case TOK_UMOD:
3895 /* if division by zero, generate explicit division */
3896 if (fc == 0) {
3897 if (const_wanted)
3898 error("division by zero in constant");
3899 goto general_case;
3901 switch(op) {
3902 default: v1->c.i /= fc; break;
3903 case '%': v1->c.i %= fc; break;
3904 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
3905 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
3907 break;
3908 case TOK_SHL: v1->c.i <<= fc; break;
3909 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
3910 case TOK_SAR: v1->c.i >>= fc; break;
3911 /* tests */
3912 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
3913 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
3914 case TOK_EQ: v1->c.i = v1->c.i == fc; break;
3915 case TOK_NE: v1->c.i = v1->c.i != fc; break;
3916 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
3917 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
3918 case TOK_LT: v1->c.i = v1->c.i < fc; break;
3919 case TOK_GE: v1->c.i = v1->c.i >= fc; break;
3920 case TOK_LE: v1->c.i = v1->c.i <= fc; break;
3921 case TOK_GT: v1->c.i = v1->c.i > fc; break;
3922 /* logical */
3923 case TOK_LAND: v1->c.i = v1->c.i && fc; break;
3924 case TOK_LOR: v1->c.i = v1->c.i || fc; break;
3925 default:
3926 goto general_case;
3928 vtop--;
3929 } else {
3930 /* if commutative ops, put c2 as constant */
3931 if (c1 && (op == '+' || op == '&' || op == '^' ||
3932 op == '|' || op == '*')) {
3933 vswap();
3934 swap(&c1, &c2);
3936 fc = vtop->c.i;
3937 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
3938 op == TOK_PDIV) &&
3939 fc == 1) ||
3940 ((op == '+' || op == '-' || op == '|' || op == '^' ||
3941 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
3942 fc == 0) ||
3943 (op == '&' &&
3944 fc == -1))) {
3945 /* nothing to do */
3946 vtop--;
3947 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
3948 /* try to use shifts instead of muls or divs */
3949 if (fc > 0 && (fc & (fc - 1)) == 0) {
3950 n = -1;
3951 while (fc) {
3952 fc >>= 1;
3953 n++;
3955 vtop->c.i = n;
3956 if (op == '*')
3957 op = TOK_SHL;
3958 else if (op == TOK_PDIV)
3959 op = TOK_SAR;
3960 else
3961 op = TOK_SHR;
3963 goto general_case;
3964 } else if (c2 && (op == '+' || op == '-') &&
3965 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
3966 (VT_CONST | VT_SYM)) {
3967 /* symbol + constant case */
3968 if (op == '-')
3969 fc = -fc;
3970 vtop--;
3971 vtop->c.i += fc;
3972 } else {
3973 general_case:
3974 /* call low level op generator */
3975 gen_opi(op);
3980 /* generate a floating point operation with constant propagation */
3981 void gen_opif(int op)
3983 int c1, c2;
3984 SValue *v1, *v2;
3985 long double f1, f2;
3987 v1 = vtop - 1;
3988 v2 = vtop;
3989 /* currently, we cannot do computations with forward symbols */
3990 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3991 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
3992 if (c1 && c2) {
3993 if (v1->t == VT_FLOAT) {
3994 f1 = v1->c.f;
3995 f2 = v2->c.f;
3996 } else if (v1->t == VT_DOUBLE) {
3997 f1 = v1->c.d;
3998 f2 = v2->c.d;
3999 } else {
4000 f1 = v1->c.ld;
4001 f2 = v2->c.ld;
4004 /* NOTE: we only do constant propagation if finite number (not
4005 NaN or infinity) (ANSI spec) */
4006 if (!ieee_finite(f1) || !ieee_finite(f2))
4007 goto general_case;
4009 switch(op) {
4010 case '+': f1 += f2; break;
4011 case '-': f1 -= f2; break;
4012 case '*': f1 *= f2; break;
4013 case '/':
4014 if (f2 == 0.0) {
4015 if (const_wanted)
4016 error("division by zero in constant");
4017 goto general_case;
4019 f1 /= f2;
4020 break;
4021 /* XXX: also handles tests ? */
4022 default:
4023 goto general_case;
4025 /* XXX: overflow test ? */
4026 if (v1->t == VT_FLOAT) {
4027 v1->c.f = f1;
4028 } else if (v1->t == VT_DOUBLE) {
4029 v1->c.d = f1;
4030 } else {
4031 v1->c.ld = f1;
4033 vtop--;
4034 } else {
4035 general_case:
4036 gen_opf(op);
4040 int pointed_size(int t)
4042 return type_size(pointed_type(t), &t);
4045 #if 0
4046 void check_pointer_types(SValue *p1, SValue *p2)
4048 char buf1[256], buf2[256];
4049 int t1, t2;
4050 t1 = p1->t;
4051 t2 = p2->t;
4052 if (!is_compatible_types(t1, t2)) {
4053 type_to_str(buf1, sizeof(buf1), t1, NULL);
4054 type_to_str(buf2, sizeof(buf2), t2, NULL);
4055 error("incompatible pointers '%s' and '%s'", buf1, buf2);
4058 #endif
4060 /* generic gen_op: handles types problems */
4061 void gen_op(int op)
4063 int u, t1, t2, bt1, bt2, t;
4065 t1 = vtop[-1].t;
4066 t2 = vtop[0].t;
4067 bt1 = t1 & VT_BTYPE;
4068 bt2 = t2 & VT_BTYPE;
4070 if (bt1 == VT_PTR || bt2 == VT_PTR) {
4071 /* at least one operand is a pointer */
4072 /* relationnal op: must be both pointers */
4073 if (op >= TOK_ULT && op <= TOK_GT) {
4074 // check_pointer_types(vtop, vtop - 1);
4075 /* pointers are handled are unsigned */
4076 t = VT_INT | VT_UNSIGNED;
4077 goto std_op;
4079 /* if both pointers, then it must be the '-' op */
4080 if ((t1 & VT_BTYPE) == VT_PTR &&
4081 (t2 & VT_BTYPE) == VT_PTR) {
4082 if (op != '-')
4083 error("cannot use pointers here");
4084 // check_pointer_types(vtop - 1, vtop);
4085 /* XXX: check that types are compatible */
4086 u = pointed_size(t1);
4087 gen_opic(op);
4088 /* set to integer type */
4089 vtop->t = VT_INT;
4090 vpushi(u);
4091 gen_op(TOK_PDIV);
4092 } else {
4093 /* exactly one pointer : must be '+' or '-'. */
4094 if (op != '-' && op != '+')
4095 error("cannot use pointers here");
4096 /* Put pointer as first operand */
4097 if ((t2 & VT_BTYPE) == VT_PTR) {
4098 vswap();
4099 swap(&t1, &t2);
4101 /* XXX: cast to int ? (long long case) */
4102 vpushi(pointed_size(vtop[-1].t));
4103 gen_op('*');
4104 #ifdef CONFIG_TCC_BCHECK
4105 /* if evaluating constant expression, no code should be
4106 generated, so no bound check */
4107 if (do_bounds_check && !const_wanted) {
4108 /* if bounded pointers, we generate a special code to
4109 test bounds */
4110 if (op == '-') {
4111 vpushi(0);
4112 vswap();
4113 gen_op('-');
4115 gen_bounded_ptr_add();
4116 } else
4117 #endif
4119 gen_opic(op);
4121 /* put again type if gen_opic() swaped operands */
4122 vtop->t = t1;
4124 } else if (is_float(bt1) || is_float(bt2)) {
4125 /* compute bigger type and do implicit casts */
4126 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
4127 t = VT_LDOUBLE;
4128 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
4129 t = VT_DOUBLE;
4130 } else {
4131 t = VT_FLOAT;
4133 /* floats can only be used for a few operations */
4134 if (op != '+' && op != '-' && op != '*' && op != '/' &&
4135 (op < TOK_ULT || op > TOK_GT))
4136 error("invalid operands for binary operation");
4137 goto std_op;
4138 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
4139 /* cast to biggest op */
4140 t = VT_LLONG;
4141 /* convert to unsigned if it does not fit in a long long */
4142 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
4143 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
4144 t |= VT_UNSIGNED;
4145 goto std_op;
4146 } else {
4147 /* integer operations */
4148 t = VT_INT;
4149 /* convert to unsigned if it does not fit in an integer */
4150 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
4151 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
4152 t |= VT_UNSIGNED;
4153 std_op:
4154 /* XXX: currently, some unsigned operations are explicit, so
4155 we modify them here */
4156 if (t & VT_UNSIGNED) {
4157 if (op == TOK_SAR)
4158 op = TOK_SHR;
4159 else if (op == '/')
4160 op = TOK_UDIV;
4161 else if (op == '%')
4162 op = TOK_UMOD;
4163 else if (op == TOK_LT)
4164 op = TOK_ULT;
4165 else if (op == TOK_GT)
4166 op = TOK_UGT;
4167 else if (op == TOK_LE)
4168 op = TOK_ULE;
4169 else if (op == TOK_GE)
4170 op = TOK_UGE;
4172 vswap();
4173 gen_cast(t);
4174 vswap();
4175 /* special case for shifts and long long: we keep the shift as
4176 an integer */
4177 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
4178 gen_cast(VT_INT);
4179 else
4180 gen_cast(t);
4181 if (is_float(t))
4182 gen_opif(op);
4183 else if ((t & VT_BTYPE) == VT_LLONG)
4184 gen_opl(op);
4185 else
4186 gen_opic(op);
4187 if (op >= TOK_ULT && op <= TOK_GT) {
4188 /* relationnal op: the result is an int */
4189 vtop->t = VT_INT;
4190 } else {
4191 vtop->t = t;
4196 /* generic itof for unsigned long long case */
4197 void gen_cvt_itof1(int t)
4199 GFuncContext gf;
4201 if ((vtop->t & (VT_BTYPE | VT_UNSIGNED)) ==
4202 (VT_LLONG | VT_UNSIGNED)) {
4204 gfunc_start(&gf, FUNC_CDECL);
4205 gfunc_param(&gf);
4206 if (t == VT_FLOAT)
4207 vpush_global_sym(func_old_type, TOK___ulltof);
4208 else if (t == VT_DOUBLE)
4209 vpush_global_sym(func_old_type, TOK___ulltod);
4210 else
4211 vpush_global_sym(func_old_type, TOK___ulltold);
4212 gfunc_call(&gf);
4213 vpushi(0);
4214 vtop->r = REG_FRET;
4215 } else {
4216 gen_cvt_itof(t);
4220 /* generic ftoi for unsigned long long case */
4221 void gen_cvt_ftoi1(int t)
4223 GFuncContext gf;
4224 int st;
4226 if (t == (VT_LLONG | VT_UNSIGNED)) {
4227 /* not handled natively */
4228 gfunc_start(&gf, FUNC_CDECL);
4229 st = vtop->t & VT_BTYPE;
4230 gfunc_param(&gf);
4231 if (st == VT_FLOAT)
4232 vpush_global_sym(func_old_type, TOK___fixunssfdi);
4233 else if (st == VT_DOUBLE)
4234 vpush_global_sym(func_old_type, TOK___fixunsdfdi);
4235 else
4236 vpush_global_sym(func_old_type, TOK___fixunsxfdi);
4237 gfunc_call(&gf);
4238 vpushi(0);
4239 vtop->r = REG_IRET;
4240 vtop->r2 = REG_LRET;
4241 } else {
4242 gen_cvt_ftoi(t);
4246 /* force char or short cast */
4247 void force_charshort_cast(int t)
4249 int bits, dbt;
4250 dbt = t & VT_BTYPE;
4251 /* XXX: add optimization if lvalue : just change type and offset */
4252 if (dbt == VT_BYTE)
4253 bits = 8;
4254 else
4255 bits = 16;
4256 if (t & VT_UNSIGNED) {
4257 vpushi((1 << bits) - 1);
4258 gen_op('&');
4259 } else {
4260 bits = 32 - bits;
4261 vpushi(bits);
4262 gen_op(TOK_SHL);
4263 vpushi(bits);
4264 gen_op(TOK_SAR);
4268 /* cast 'vtop' to 't' type */
4269 void gen_cast(int t)
4271 int sbt, dbt, sf, df, c;
4273 /* special delayed cast for char/short */
4274 /* XXX: in some cases (multiple cascaded casts), it may still
4275 be incorrect */
4276 if (vtop->r & VT_MUSTCAST) {
4277 vtop->r &= ~VT_MUSTCAST;
4278 force_charshort_cast(vtop->t);
4281 dbt = t & (VT_BTYPE | VT_UNSIGNED);
4282 sbt = vtop->t & (VT_BTYPE | VT_UNSIGNED);
4284 if (sbt != dbt) {
4285 sf = is_float(sbt);
4286 df = is_float(dbt);
4287 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
4288 if (sf && df) {
4289 /* convert from fp to fp */
4290 if (c) {
4291 /* constant case: we can do it now */
4292 /* XXX: in ISOC, cannot do it if error in convert */
4293 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
4294 vtop->c.f = (float)vtop->c.d;
4295 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
4296 vtop->c.f = (float)vtop->c.ld;
4297 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
4298 vtop->c.d = (double)vtop->c.f;
4299 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
4300 vtop->c.d = (double)vtop->c.ld;
4301 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
4302 vtop->c.ld = (long double)vtop->c.f;
4303 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
4304 vtop->c.ld = (long double)vtop->c.d;
4305 } else {
4306 /* non constant case: generate code */
4307 gen_cvt_ftof(dbt);
4309 } else if (df) {
4310 /* convert int to fp */
4311 if (c) {
4312 switch(sbt) {
4313 case VT_LLONG | VT_UNSIGNED:
4314 case VT_LLONG:
4315 /* XXX: add const cases for long long */
4316 goto do_itof;
4317 case VT_INT | VT_UNSIGNED:
4318 switch(dbt) {
4319 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
4320 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
4321 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
4323 break;
4324 default:
4325 switch(dbt) {
4326 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
4327 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
4328 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
4330 break;
4332 } else {
4333 do_itof:
4334 gen_cvt_itof1(dbt);
4336 } else if (sf) {
4337 /* convert fp to int */
4338 /* we handle char/short/etc... with generic code */
4339 if (dbt != (VT_INT | VT_UNSIGNED) &&
4340 dbt != (VT_LLONG | VT_UNSIGNED) &&
4341 dbt != VT_LLONG)
4342 dbt = VT_INT;
4343 if (c) {
4344 switch(dbt) {
4345 case VT_LLONG | VT_UNSIGNED:
4346 case VT_LLONG:
4347 /* XXX: add const cases for long long */
4348 goto do_ftoi;
4349 case VT_INT | VT_UNSIGNED:
4350 switch(sbt) {
4351 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
4352 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4353 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
4355 break;
4356 default:
4357 /* int case */
4358 switch(sbt) {
4359 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
4360 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
4361 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
4363 break;
4365 } else {
4366 do_ftoi:
4367 gen_cvt_ftoi1(dbt);
4369 if (dbt == VT_INT && (t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
4370 /* additionnal cast for char/short/bool... */
4371 vtop->t = dbt;
4372 gen_cast(t);
4374 } else if ((dbt & VT_BTYPE) == VT_LLONG) {
4375 if ((sbt & VT_BTYPE) != VT_LLONG) {
4376 /* scalar to long long */
4377 if (c) {
4378 if (sbt == (VT_INT | VT_UNSIGNED))
4379 vtop->c.ll = vtop->c.ui;
4380 else
4381 vtop->c.ll = vtop->c.i;
4382 } else {
4383 /* machine independant conversion */
4384 gv(RC_INT);
4385 /* generate high word */
4386 if (sbt == (VT_INT | VT_UNSIGNED)) {
4387 vpushi(0);
4388 gv(RC_INT);
4389 } else {
4390 gv_dup();
4391 vpushi(31);
4392 gen_op(TOK_SAR);
4394 /* patch second register */
4395 vtop[-1].r2 = vtop->r;
4396 vpop();
4399 } else if (dbt == VT_BOOL) {
4400 /* scalar to bool */
4401 vpushi(0);
4402 gen_op(TOK_NE);
4403 } else if ((dbt & VT_BTYPE) == VT_BYTE ||
4404 (dbt & VT_BTYPE) == VT_SHORT) {
4405 force_charshort_cast(t);
4406 } else if ((dbt & VT_BTYPE) == VT_INT) {
4407 /* scalar to int */
4408 if (sbt == VT_LLONG) {
4409 /* from long long: just take low order word */
4410 lexpand();
4411 vpop();
4413 /* if lvalue and single word type, nothing to do because
4414 the lvalue already contains the real type size (see
4415 VT_LVAL_xxx constants) */
4418 vtop->t = t;
4421 /* return type size. Put alignment at 'a' */
4422 int type_size(int t, int *a)
4424 Sym *s;
4425 int bt;
4427 bt = t & VT_BTYPE;
4428 if (bt == VT_STRUCT) {
4429 /* struct/union */
4430 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
4431 *a = 4; /* XXX: cannot store it yet. Doing that is safe */
4432 return s->c;
4433 } else if (bt == VT_PTR) {
4434 if (t & VT_ARRAY) {
4435 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4436 return type_size(s->t, a) * s->c;
4437 } else {
4438 *a = PTR_SIZE;
4439 return PTR_SIZE;
4441 } else if (bt == VT_LDOUBLE) {
4442 *a = LDOUBLE_ALIGN;
4443 return LDOUBLE_SIZE;
4444 } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
4445 *a = 8;
4446 return 8;
4447 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
4448 *a = 4;
4449 return 4;
4450 } else if (bt == VT_SHORT) {
4451 *a = 2;
4452 return 2;
4453 } else {
4454 /* char, void, function, _Bool */
4455 *a = 1;
4456 return 1;
4460 /* return the pointed type of t */
4461 int pointed_type(int t)
4463 Sym *s;
4464 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
4465 return s->t | (t & ~VT_TYPE);
4468 int mk_pointer(int t)
4470 int p;
4471 p = anon_sym++;
4472 sym_push(p, t, 0, -1);
4473 return VT_PTR | (p << VT_STRUCT_SHIFT) | (t & ~VT_TYPE);
4476 int is_compatible_types(int t1, int t2)
4478 Sym *s1, *s2;
4479 int bt1, bt2;
4481 t1 &= VT_TYPE;
4482 t2 &= VT_TYPE;
4483 bt1 = t1 & VT_BTYPE;
4484 bt2 = t2 & VT_BTYPE;
4485 if (bt1 == VT_PTR) {
4486 t1 = pointed_type(t1);
4487 /* if function, then convert implicitely to function pointer */
4488 if (bt2 != VT_FUNC) {
4489 if (bt2 != VT_PTR)
4490 return 0;
4491 t2 = pointed_type(t2);
4493 /* void matches everything */
4494 t1 &= VT_TYPE;
4495 t2 &= VT_TYPE;
4496 if (t1 == VT_VOID || t2 == VT_VOID)
4497 return 1;
4498 return is_compatible_types(t1, t2);
4499 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
4500 return (t2 == t1);
4501 } else if (bt1 == VT_FUNC) {
4502 if (bt2 != VT_FUNC)
4503 return 0;
4504 s1 = sym_find(((unsigned)t1 >> VT_STRUCT_SHIFT));
4505 s2 = sym_find(((unsigned)t2 >> VT_STRUCT_SHIFT));
4506 if (!is_compatible_types(s1->t, s2->t))
4507 return 0;
4508 /* XXX: not complete */
4509 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
4510 return 1;
4511 if (s1->c != s2->c)
4512 return 0;
4513 while (s1 != NULL) {
4514 if (s2 == NULL)
4515 return 0;
4516 if (!is_compatible_types(s1->t, s2->t))
4517 return 0;
4518 s1 = s1->next;
4519 s2 = s2->next;
4521 if (s2)
4522 return 0;
4523 return 1;
4524 } else {
4525 /* XXX: not complete */
4526 return 1;
4530 /* print a type. If 'varstr' is not NULL, then the variable is also
4531 printed in the type */
4532 /* XXX: union */
4533 /* XXX: add array and function pointers */
4534 void type_to_str(char *buf, int buf_size,
4535 int t, const char *varstr)
4537 int bt, v;
4538 Sym *s, *sa;
4539 char buf1[256];
4540 const char *tstr;
4542 t = t & VT_TYPE;
4543 bt = t & VT_BTYPE;
4544 buf[0] = '\0';
4545 if (t & VT_UNSIGNED)
4546 pstrcat(buf, buf_size, "unsigned ");
4547 switch(bt) {
4548 case VT_VOID:
4549 tstr = "void";
4550 goto add_tstr;
4551 case VT_BOOL:
4552 tstr = "_Bool";
4553 goto add_tstr;
4554 case VT_BYTE:
4555 tstr = "char";
4556 goto add_tstr;
4557 case VT_SHORT:
4558 tstr = "short";
4559 goto add_tstr;
4560 case VT_INT:
4561 tstr = "int";
4562 goto add_tstr;
4563 case VT_LONG:
4564 tstr = "long";
4565 goto add_tstr;
4566 case VT_LLONG:
4567 tstr = "long long";
4568 goto add_tstr;
4569 case VT_FLOAT:
4570 tstr = "float";
4571 goto add_tstr;
4572 case VT_DOUBLE:
4573 tstr = "double";
4574 goto add_tstr;
4575 case VT_LDOUBLE:
4576 tstr = "long double";
4577 add_tstr:
4578 pstrcat(buf, buf_size, tstr);
4579 break;
4580 case VT_ENUM:
4581 case VT_STRUCT:
4582 if (bt == VT_STRUCT)
4583 tstr = "struct ";
4584 else
4585 tstr = "enum ";
4586 pstrcat(buf, buf_size, tstr);
4587 v = (unsigned)t >> VT_STRUCT_SHIFT;
4588 if (v >= SYM_FIRST_ANOM)
4589 pstrcat(buf, buf_size, "<anonymous>");
4590 else
4591 pstrcat(buf, buf_size, get_tok_str(v, NULL));
4592 break;
4593 case VT_FUNC:
4594 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4595 type_to_str(buf, buf_size, s->t, varstr);
4596 pstrcat(buf, buf_size, "(");
4597 sa = s->next;
4598 while (sa != NULL) {
4599 type_to_str(buf1, sizeof(buf1), sa->t, NULL);
4600 pstrcat(buf, buf_size, buf1);
4601 sa = sa->next;
4602 if (sa)
4603 pstrcat(buf, buf_size, ", ");
4605 pstrcat(buf, buf_size, ")");
4606 goto no_var;
4607 case VT_PTR:
4608 s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
4609 pstrcpy(buf1, sizeof(buf1), "*");
4610 if (varstr)
4611 pstrcat(buf1, sizeof(buf1), varstr);
4612 type_to_str(buf, buf_size, s->t, buf1);
4613 goto no_var;
4615 if (varstr) {
4616 pstrcat(buf, buf_size, " ");
4617 pstrcat(buf, buf_size, varstr);
4619 no_var: ;
4622 /* verify type compatibility to store vtop in 'dt' type, and generate
4623 casts if needed. */
4624 void gen_assign_cast(int dt)
4626 int st;
4627 char buf1[256], buf2[256];
4629 st = vtop->t; /* source type */
4630 if ((dt & VT_BTYPE) == VT_PTR) {
4631 /* special cases for pointers */
4632 /* a function is implicitely a function pointer */
4633 if ((st & VT_BTYPE) == VT_FUNC) {
4634 if (!is_compatible_types(pointed_type(dt), st))
4635 goto error;
4636 else
4637 goto type_ok;
4639 /* '0' can also be a pointer */
4640 if ((st & VT_BTYPE) == VT_INT &&
4641 ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) &&
4642 vtop->c.i == 0)
4643 goto type_ok;
4645 if (!is_compatible_types(dt, st)) {
4646 error:
4647 type_to_str(buf1, sizeof(buf1), st, NULL);
4648 type_to_str(buf2, sizeof(buf2), dt, NULL);
4649 error("cannot cast '%s' to '%s'", buf1, buf2);
4651 type_ok:
4652 gen_cast(dt);
4655 /* store vtop in lvalue pushed on stack */
4656 void vstore(void)
4658 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
4659 GFuncContext gf;
4661 ft = vtop[-1].t;
4662 sbt = vtop->t & VT_BTYPE;
4663 dbt = ft & VT_BTYPE;
4664 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
4665 (sbt == VT_INT && dbt == VT_SHORT)) {
4666 /* optimize char/short casts */
4667 delayed_cast = VT_MUSTCAST;
4668 vtop->t = ft & VT_TYPE;
4669 } else {
4670 delayed_cast = 0;
4671 gen_assign_cast(ft & VT_TYPE);
4674 if (sbt == VT_STRUCT) {
4675 /* if structure, only generate pointer */
4676 /* structure assignment : generate memcpy */
4677 /* XXX: optimize if small size */
4678 vdup();
4679 gfunc_start(&gf, FUNC_CDECL);
4680 /* type size */
4681 size = type_size(vtop->t, &align);
4682 vpushi(size);
4683 gfunc_param(&gf);
4684 /* source */
4685 vtop->t = VT_INT;
4686 gaddrof();
4687 gfunc_param(&gf);
4688 /* destination */
4689 vswap();
4690 vtop->t = VT_INT;
4691 gaddrof();
4692 gfunc_param(&gf);
4694 save_regs(0);
4695 vpush_global_sym(func_old_type, TOK_memcpy);
4696 gfunc_call(&gf);
4697 /* leave source on stack */
4698 } else if (ft & VT_BITFIELD) {
4699 /* bitfield store handling */
4700 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
4701 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4702 /* remove bit field info to avoid loops */
4703 vtop[-1].t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4705 /* duplicate destination */
4706 vdup();
4707 vtop[-1] = vtop[-2];
4709 /* mask and shift source */
4710 vpushi((1 << bit_size) - 1);
4711 gen_op('&');
4712 vpushi(bit_pos);
4713 gen_op(TOK_SHL);
4714 /* load destination, mask and or with source */
4715 vswap();
4716 vpushi(~(((1 << bit_size) - 1) << bit_pos));
4717 gen_op('&');
4718 gen_op('|');
4719 /* store result */
4720 vstore();
4721 } else {
4722 #ifdef CONFIG_TCC_BCHECK
4723 /* bound check case */
4724 if (vtop[-1].r & VT_MUSTBOUND) {
4725 vswap();
4726 gbound();
4727 vswap();
4729 #endif
4730 rc = RC_INT;
4731 if (is_float(ft))
4732 rc = RC_FLOAT;
4733 r = gv(rc); /* generate value */
4734 /* if lvalue was saved on stack, must read it */
4735 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
4736 SValue sv;
4737 t = get_reg(RC_INT);
4738 sv.t = VT_INT;
4739 sv.r = VT_LOCAL | VT_LVAL;
4740 sv.c.ul = vtop[-1].c.ul;
4741 load(t, &sv);
4742 vtop[-1].r = t | VT_LVAL;
4744 store(r, vtop - 1);
4745 /* two word case handling : store second register at word + 4 */
4746 if ((ft & VT_BTYPE) == VT_LLONG) {
4747 vswap();
4748 /* convert to int to increment easily */
4749 vtop->t = VT_INT;
4750 gaddrof();
4751 vpushi(4);
4752 gen_op('+');
4753 vtop->r |= VT_LVAL;
4754 vswap();
4755 /* XXX: it works because r2 is spilled last ! */
4756 store(vtop->r2, vtop - 1);
4758 vswap();
4759 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
4760 vtop->r |= delayed_cast;
4764 /* post defines POST/PRE add. c is the token ++ or -- */
4765 void inc(int post, int c)
4767 test_lvalue();
4768 vdup(); /* save lvalue */
4769 if (post) {
4770 gv_dup(); /* duplicate value */
4771 vrotb(3);
4772 vrotb(3);
4774 /* add constant */
4775 vpushi(c - TOK_MID);
4776 gen_op('+');
4777 vstore(); /* store value */
4778 if (post)
4779 vpop(); /* if post op, return saved value */
4782 /* Parse GNUC __attribute__ extension. Currently, the following
4783 extensions are recognized:
4784 - aligned(n) : set data/function alignment.
4785 - section(x) : generate data/code in this section.
4786 - unused : currently ignored, but may be used someday.
4788 void parse_attribute(AttributeDef *ad)
4790 int t, n;
4792 next();
4793 skip('(');
4794 skip('(');
4795 while (tok != ')') {
4796 if (tok < TOK_IDENT)
4797 expect("attribute name");
4798 t = tok;
4799 next();
4800 switch(t) {
4801 case TOK_SECTION:
4802 case TOK___SECTION__:
4803 skip('(');
4804 if (tok != TOK_STR)
4805 expect("section name");
4806 ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
4807 next();
4808 skip(')');
4809 break;
4810 case TOK_ALIGNED:
4811 case TOK___ALIGNED__:
4812 skip('(');
4813 n = expr_const();
4814 if (n <= 0 || (n & (n - 1)) != 0)
4815 error("alignment must be a positive power of two");
4816 ad->aligned = n;
4817 skip(')');
4818 break;
4819 case TOK_UNUSED:
4820 case TOK___UNUSED__:
4821 /* currently, no need to handle it because tcc does not
4822 track unused objects */
4823 break;
4824 case TOK_NORETURN:
4825 case TOK___NORETURN__:
4826 /* currently, no need to handle it because tcc does not
4827 track unused objects */
4828 break;
4829 case TOK_CDECL:
4830 case TOK___CDECL:
4831 case TOK___CDECL__:
4832 ad->func_call = FUNC_CDECL;
4833 break;
4834 case TOK_STDCALL:
4835 case TOK___STDCALL:
4836 case TOK___STDCALL__:
4837 ad->func_call = FUNC_STDCALL;
4838 break;
4839 default:
4840 warning("'%s' attribute ignored", get_tok_str(t, NULL));
4841 /* skip parameters */
4842 /* XXX: skip parenthesis too */
4843 if (tok == '(') {
4844 next();
4845 while (tok != ')' && tok != -1)
4846 next();
4847 next();
4849 break;
4851 if (tok != ',')
4852 break;
4853 next();
4855 skip(')');
4856 skip(')');
4859 /* enum/struct/union declaration */
4860 int struct_decl(int u)
4862 int a, t, b, v, size, align, maxalign, c, offset;
4863 int bit_size, bit_pos, bsize, bt, lbit_pos;
4864 Sym *s, *ss, **ps;
4865 AttributeDef ad;
4867 a = tok; /* save decl type */
4868 next();
4869 if (tok != '{') {
4870 v = tok;
4871 next();
4872 /* struct already defined ? return it */
4873 /* XXX: check consistency */
4874 s = sym_find(v | SYM_STRUCT);
4875 if (s) {
4876 if (s->t != a)
4877 error("invalid type");
4878 goto do_decl;
4880 } else {
4881 v = anon_sym++;
4883 s = sym_push(v | SYM_STRUCT, a, 0, 0);
4884 /* put struct/union/enum name in type */
4885 do_decl:
4886 u = u | (v << VT_STRUCT_SHIFT);
4888 if (tok == '{') {
4889 next();
4890 if (s->c)
4891 error("struct/union/enum already defined");
4892 /* cannot be empty */
4893 c = 0;
4894 maxalign = 0;
4895 ps = &s->next;
4896 bit_pos = 0;
4897 offset = 0;
4898 while (1) {
4899 if (a == TOK_ENUM) {
4900 v = tok;
4901 next();
4902 if (tok == '=') {
4903 next();
4904 c = expr_const();
4906 /* enum symbols have static storage */
4907 sym_push(v, VT_STATIC | VT_INT, VT_CONST, c);
4908 if (tok == ',')
4909 next();
4910 c++;
4911 } else {
4912 parse_btype(&b, &ad);
4913 while (1) {
4914 bit_size = -1;
4915 v = 0;
4916 if (tok != ':') {
4917 t = type_decl(&ad, &v, b, TYPE_DIRECT);
4918 if ((t & VT_BTYPE) == VT_FUNC ||
4919 (t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN)))
4920 error("invalid type for '%s'",
4921 get_tok_str(v, NULL));
4922 } else {
4923 t = b;
4925 if (tok == ':') {
4926 next();
4927 bit_size = expr_const();
4928 /* XXX: handle v = 0 case for messages */
4929 if (bit_size < 0)
4930 error("negative width in bit-field '%s'",
4931 get_tok_str(v, NULL));
4932 if (v && bit_size == 0)
4933 error("zero width for bit-field '%s'",
4934 get_tok_str(v, NULL));
4936 size = type_size(t, &align);
4937 lbit_pos = 0;
4938 if (bit_size >= 0) {
4939 bt = t & VT_BTYPE;
4940 if (bt != VT_INT &&
4941 bt != VT_BYTE &&
4942 bt != VT_SHORT)
4943 error("bitfields must have scalar type");
4944 bsize = size * 8;
4945 if (bit_size > bsize) {
4946 error("width of '%s' exceeds its type",
4947 get_tok_str(v, NULL));
4948 } else if (bit_size == bsize) {
4949 /* no need for bit fields */
4950 bit_pos = 0;
4951 } else if (bit_size == 0) {
4952 /* XXX: what to do if only padding in a
4953 structure ? */
4954 /* zero size: means to pad */
4955 if (bit_pos > 0)
4956 bit_pos = bsize;
4957 } else {
4958 /* we do not have enough room ? */
4959 if ((bit_pos + bit_size) > bsize)
4960 bit_pos = 0;
4961 lbit_pos = bit_pos;
4962 /* XXX: handle LSB first */
4963 t |= VT_BITFIELD |
4964 (bit_pos << VT_STRUCT_SHIFT) |
4965 (bit_size << (VT_STRUCT_SHIFT + 6));
4966 bit_pos += bit_size;
4968 } else {
4969 bit_pos = 0;
4971 if (v) {
4972 /* add new memory data only if starting
4973 bit field */
4974 if (lbit_pos == 0) {
4975 if (a == TOK_STRUCT) {
4976 c = (c + align - 1) & -align;
4977 offset = c;
4978 c += size;
4979 } else {
4980 offset = 0;
4981 if (size > c)
4982 c = size;
4984 if (align > maxalign)
4985 maxalign = align;
4987 #if 0
4988 printf("add field %s offset=%d",
4989 get_tok_str(v, NULL), offset);
4990 if (t & VT_BITFIELD) {
4991 printf(" pos=%d size=%d",
4992 (t >> VT_STRUCT_SHIFT) & 0x3f,
4993 (t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
4995 printf("\n");
4996 #endif
4997 ss = sym_push(v | SYM_FIELD, t, 0, offset);
4998 *ps = ss;
4999 ps = &ss->next;
5001 if (tok == ';' || tok == -1)
5002 break;
5003 skip(',');
5005 skip(';');
5007 if (tok == '}')
5008 break;
5010 skip('}');
5011 /* size for struct/union, dummy for enum */
5012 s->c = (c + maxalign - 1) & -maxalign;
5014 return u;
5017 /* return 0 if no type declaration. otherwise, return the basic type
5018 and skip it.
5020 int parse_btype(int *type_ptr, AttributeDef *ad)
5022 int t, u, type_found;
5023 Sym *s;
5025 memset(ad, 0, sizeof(AttributeDef));
5026 type_found = 0;
5027 t = 0;
5028 while(1) {
5029 switch(tok) {
5030 /* basic types */
5031 case TOK_CHAR:
5032 u = VT_BYTE;
5033 basic_type:
5034 next();
5035 basic_type1:
5036 if ((t & VT_BTYPE) != 0)
5037 error("too many basic types");
5038 t |= u;
5039 break;
5040 case TOK_VOID:
5041 u = VT_VOID;
5042 goto basic_type;
5043 case TOK_SHORT:
5044 u = VT_SHORT;
5045 goto basic_type;
5046 case TOK_INT:
5047 next();
5048 break;
5049 case TOK_LONG:
5050 next();
5051 if ((t & VT_BTYPE) == VT_DOUBLE) {
5052 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5053 } else if ((t & VT_BTYPE) == VT_LONG) {
5054 t = (t & ~VT_BTYPE) | VT_LLONG;
5055 } else {
5056 u = VT_LONG;
5057 goto basic_type1;
5059 break;
5060 case TOK_BOOL:
5061 u = VT_BOOL;
5062 goto basic_type;
5063 case TOK_FLOAT:
5064 u = VT_FLOAT;
5065 goto basic_type;
5066 case TOK_DOUBLE:
5067 next();
5068 if ((t & VT_BTYPE) == VT_LONG) {
5069 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
5070 } else {
5071 u = VT_DOUBLE;
5072 goto basic_type1;
5074 break;
5075 case TOK_ENUM:
5076 u = struct_decl(VT_ENUM);
5077 goto basic_type1;
5078 case TOK_STRUCT:
5079 case TOK_UNION:
5080 u = struct_decl(VT_STRUCT);
5081 goto basic_type1;
5083 /* type modifiers */
5084 case TOK_CONST:
5085 case TOK_VOLATILE:
5086 case TOK_REGISTER:
5087 case TOK_SIGNED:
5088 case TOK___SIGNED__:
5089 case TOK_AUTO:
5090 case TOK_INLINE:
5091 case TOK___INLINE__:
5092 case TOK_RESTRICT:
5093 next();
5094 break;
5095 case TOK_UNSIGNED:
5096 t |= VT_UNSIGNED;
5097 next();
5098 break;
5100 /* storage */
5101 case TOK_EXTERN:
5102 t |= VT_EXTERN;
5103 next();
5104 break;
5105 case TOK_STATIC:
5106 t |= VT_STATIC;
5107 next();
5108 break;
5109 case TOK_TYPEDEF:
5110 t |= VT_TYPEDEF;
5111 next();
5112 break;
5113 /* GNUC attribute */
5114 case TOK___ATTRIBUTE__:
5115 parse_attribute(ad);
5116 break;
5117 default:
5118 s = sym_find(tok);
5119 if (!s || !(s->t & VT_TYPEDEF))
5120 goto the_end;
5121 t |= (s->t & ~VT_TYPEDEF);
5122 next();
5123 break;
5125 type_found = 1;
5127 the_end:
5128 /* long is never used as type */
5129 if ((t & VT_BTYPE) == VT_LONG)
5130 t = (t & ~VT_BTYPE) | VT_INT;
5131 *type_ptr = t;
5132 return type_found;
5135 int post_type(int t, AttributeDef *ad)
5137 int p, n, pt, l, t1;
5138 Sym **plast, *s, *first;
5139 AttributeDef ad1;
5141 if (tok == '(') {
5142 /* function declaration */
5143 next();
5144 l = 0;
5145 first = NULL;
5146 plast = &first;
5147 while (tok != ')') {
5148 /* read param name and compute offset */
5149 if (l != FUNC_OLD) {
5150 if (!parse_btype(&pt, &ad1)) {
5151 if (l) {
5152 error("invalid type");
5153 } else {
5154 l = FUNC_OLD;
5155 goto old_proto;
5158 l = FUNC_NEW;
5159 if ((pt & VT_BTYPE) == VT_VOID && tok == ')')
5160 break;
5161 pt = type_decl(&ad1, &n, pt, TYPE_DIRECT | TYPE_ABSTRACT);
5162 if ((pt & VT_BTYPE) == VT_VOID)
5163 error("parameter declared as void");
5164 } else {
5165 old_proto:
5166 n = tok;
5167 pt = VT_INT;
5168 next();
5170 /* array must be transformed to pointer according to ANSI C */
5171 pt &= ~VT_ARRAY;
5172 s = sym_push(n | SYM_FIELD, pt, 0, 0);
5173 *plast = s;
5174 plast = &s->next;
5175 if (tok == ',') {
5176 next();
5177 if (l == FUNC_NEW && tok == TOK_DOTS) {
5178 l = FUNC_ELLIPSIS;
5179 next();
5180 break;
5184 /* if no parameters, then old type prototype */
5185 if (l == 0)
5186 l = FUNC_OLD;
5187 skip(')');
5188 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5189 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
5190 /* we push a anonymous symbol which will contain the function prototype */
5191 p = anon_sym++;
5192 s = sym_push(p, t, ad->func_call, l);
5193 s->next = first;
5194 t = t1 | VT_FUNC | (p << VT_STRUCT_SHIFT);
5195 } else if (tok == '[') {
5196 /* array definition */
5197 next();
5198 n = -1;
5199 if (tok != ']') {
5200 n = expr_const();
5201 if (n < 0)
5202 error("invalid array size");
5204 skip(']');
5205 /* parse next post type */
5206 t1 = t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN);
5207 t = post_type(t & ~(VT_TYPEDEF | VT_STATIC | VT_EXTERN), ad);
5209 /* we push a anonymous symbol which will contain the array
5210 element type */
5211 p = anon_sym++;
5212 sym_push(p, t, 0, n);
5213 t = t1 | VT_ARRAY | VT_PTR | (p << VT_STRUCT_SHIFT);
5215 return t;
5218 /* Read a type declaration (except basic type), and return the
5219 type. 'td' is a bitmask indicating which kind of type decl is
5220 expected. 't' should contain the basic type. 'ad' is the attribute
5221 definition of the basic type. It can be modified by type_decl(). */
5222 int type_decl(AttributeDef *ad, int *v, int t, int td)
5224 int u, p;
5225 Sym *s;
5227 while (tok == '*') {
5228 next();
5229 while (tok == TOK_CONST || tok == TOK_VOLATILE || tok == TOK_RESTRICT)
5230 next();
5231 t = mk_pointer(t);
5234 /* recursive type */
5235 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5236 if (tok == '(') {
5237 next();
5238 /* XXX: this is not correct to modify 'ad' at this point, but
5239 the syntax is not clear */
5240 if (tok == TOK___ATTRIBUTE__)
5241 parse_attribute(ad);
5242 u = type_decl(ad, v, 0, td);
5243 skip(')');
5244 } else {
5245 u = 0;
5246 /* type identifier */
5247 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
5248 *v = tok;
5249 next();
5250 } else {
5251 if (!(td & TYPE_ABSTRACT))
5252 expect("identifier");
5253 *v = 0;
5256 /* append t at the end of u */
5257 t = post_type(t, ad);
5258 if (tok == TOK___ATTRIBUTE__)
5259 parse_attribute(ad);
5260 if (!u)
5261 return t;
5262 p = u;
5263 while(1) {
5264 s = sym_find((unsigned)p >> VT_STRUCT_SHIFT);
5265 p = s->t;
5266 if (!p) {
5267 s->t = t;
5268 break;
5271 return u;
5274 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5275 static int lvalue_type(int t)
5277 int bt, r;
5278 r = VT_LVAL;
5279 bt = t & VT_BTYPE;
5280 if (bt == VT_BYTE)
5281 r |= VT_LVAL_BYTE;
5282 else if (bt == VT_SHORT)
5283 r |= VT_LVAL_SHORT;
5284 else
5285 return r;
5286 if (t & VT_UNSIGNED)
5287 r |= VT_LVAL_UNSIGNED;
5288 return r;
5291 /* indirection with full error checking and bound check */
5292 static void indir(void)
5294 if ((vtop->t & VT_BTYPE) != VT_PTR)
5295 expect("pointer");
5296 if (vtop->r & VT_LVAL)
5297 gv(RC_INT);
5298 vtop->t = pointed_type(vtop->t);
5299 /* an array is never an lvalue */
5300 if (!(vtop->t & VT_ARRAY)) {
5301 vtop->r |= lvalue_type(vtop->t);
5302 /* if bound checking, the referenced pointer must be checked */
5303 if (do_bounds_check)
5304 vtop->r |= VT_MUSTBOUND;
5308 /* pass a parameter to a function and do type checking and casting */
5309 void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
5311 int func_type;
5312 func_type = func->c;
5313 if (func_type == FUNC_OLD ||
5314 (func_type == FUNC_ELLIPSIS && arg == NULL)) {
5315 /* default casting : only need to convert float to double */
5316 if ((vtop->t & VT_BTYPE) == VT_FLOAT)
5317 gen_cast(VT_DOUBLE);
5318 } else if (arg == NULL) {
5319 error("too many arguments to function");
5320 } else {
5321 gen_assign_cast(arg->t);
5323 gfunc_param(gf);
5326 void unary(void)
5328 int n, t, ft, align, size, r;
5329 Sym *s;
5330 GFuncContext gf;
5331 AttributeDef ad;
5333 if (tok == TOK_CINT || tok == TOK_CCHAR || tok == TOK_LCHAR) {
5334 vpushi(tokc.i);
5335 next();
5336 } else if (tok == TOK_CUINT) {
5337 vsetc(VT_INT | VT_UNSIGNED, VT_CONST, &tokc);
5338 next();
5339 } else if (tok == TOK_CLLONG) {
5340 vsetc(VT_LLONG, VT_CONST, &tokc);
5341 next();
5342 } else if (tok == TOK_CULLONG) {
5343 vsetc(VT_LLONG | VT_UNSIGNED, VT_CONST, &tokc);
5344 next();
5345 } else if (tok == TOK_CFLOAT) {
5346 vsetc(VT_FLOAT, VT_CONST, &tokc);
5347 next();
5348 } else if (tok == TOK_CDOUBLE) {
5349 vsetc(VT_DOUBLE, VT_CONST, &tokc);
5350 next();
5351 } else if (tok == TOK_CLDOUBLE) {
5352 vsetc(VT_LDOUBLE, VT_CONST, &tokc);
5353 next();
5354 } else if (tok == TOK___FUNC__ || (tok == TOK___FUNCTION__ && gnu_ext)) {
5355 void *ptr;
5356 int len;
5357 /* special function name identifier */
5359 len = strlen(funcname) + 1;
5360 /* generate char[len] type */
5361 t = VT_ARRAY | mk_pointer(VT_BYTE);
5362 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
5363 s->c = len;
5364 vpush_ref(t, data_section, data_section->data_offset, len);
5365 ptr = section_ptr_add(data_section, len);
5366 memcpy(ptr, funcname, len);
5367 next();
5368 } else if (tok == TOK_LSTR) {
5369 t = VT_INT;
5370 goto str_init;
5371 } else if (tok == TOK_STR) {
5372 /* string parsing */
5373 t = VT_BYTE;
5374 str_init:
5375 t = VT_ARRAY | mk_pointer(t);
5376 memset(&ad, 0, sizeof(AttributeDef));
5377 decl_initializer_alloc(t, &ad, VT_CONST, 2, 0, 0);
5378 } else {
5379 t = tok;
5380 next();
5381 if (t == '(') {
5382 /* cast ? */
5383 if (parse_btype(&t, &ad)) {
5384 ft = type_decl(&ad, &n, t, TYPE_ABSTRACT);
5385 skip(')');
5386 /* check ISOC99 compound literal */
5387 if (tok == '{') {
5388 /* data is allocated locally by default */
5389 if (global_expr)
5390 r = VT_CONST;
5391 else
5392 r = VT_LOCAL;
5393 /* all except arrays are lvalues */
5394 if (!(ft & VT_ARRAY))
5395 r |= lvalue_type(ft);
5396 memset(&ad, 0, sizeof(AttributeDef));
5397 decl_initializer_alloc(ft, &ad, r, 1, 0, 0);
5398 } else {
5399 unary();
5400 gen_cast(ft);
5402 } else {
5403 gexpr();
5404 skip(')');
5406 } else if (t == '*') {
5407 unary();
5408 indir();
5409 } else if (t == '&') {
5410 unary();
5411 /* functions names must be treated as function pointers,
5412 except for unary '&' and sizeof. Since we consider that
5413 functions are not lvalues, we only have to handle it
5414 there and in function calls. */
5415 /* arrays can also be used although they are not lvalues */
5416 if ((vtop->t & VT_BTYPE) != VT_FUNC &&
5417 !(vtop->t & VT_ARRAY))
5418 test_lvalue();
5419 vtop->t = mk_pointer(vtop->t);
5420 gaddrof();
5421 } else
5422 if (t == '!') {
5423 unary();
5424 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
5425 vtop->c.i = !vtop->c.i;
5426 else if ((vtop->r & VT_VALMASK) == VT_CMP)
5427 vtop->c.i = vtop->c.i ^ 1;
5428 else
5429 vset(VT_INT, VT_JMP, gtst(1, 0));
5430 } else
5431 if (t == '~') {
5432 unary();
5433 vpushi(-1);
5434 gen_op('^');
5435 } else
5436 if (t == '+') {
5437 /* in order to force cast, we add zero */
5438 unary();
5439 if ((vtop->t & VT_BTYPE) == VT_PTR)
5440 error("pointer not accepted for unary plus");
5441 vpushi(0);
5442 gen_op('+');
5443 } else
5444 if (t == TOK_SIZEOF) {
5445 if (tok == '(') {
5446 next();
5447 if (parse_btype(&t, &ad)) {
5448 t = type_decl(&ad, &n, t, TYPE_ABSTRACT);
5449 } else {
5450 /* XXX: some code could be generated: add eval
5451 flag */
5452 gexpr();
5453 t = vtop->t;
5454 vpop();
5456 skip(')');
5457 } else {
5458 unary();
5459 t = vtop->t;
5460 vpop();
5462 vpushi(type_size(t, &t));
5463 } else
5464 if (t == TOK_INC || t == TOK_DEC) {
5465 unary();
5466 inc(0, t);
5467 } else if (t == '-') {
5468 vpushi(0);
5469 unary();
5470 gen_op('-');
5471 } else
5473 if (t < TOK_UIDENT)
5474 expect("identifier");
5475 s = sym_find(t);
5476 if (!s) {
5477 if (tok != '(')
5478 error("'%s' undeclared", get_tok_str(t, NULL));
5479 /* for simple function calls, we tolerate undeclared
5480 external reference to int() function */
5481 s = external_global_sym(t, func_old_type, 0);
5483 vset(s->t, s->r, s->c);
5484 /* if forward reference, we must point to s */
5485 if (vtop->r & VT_SYM) {
5486 vtop->sym = s;
5487 vtop->c.ul = 0;
5492 /* post operations */
5493 while (1) {
5494 if (tok == TOK_INC || tok == TOK_DEC) {
5495 inc(1, tok);
5496 next();
5497 } else if (tok == '.' || tok == TOK_ARROW) {
5498 /* field */
5499 if (tok == TOK_ARROW)
5500 indir();
5501 test_lvalue();
5502 gaddrof();
5503 next();
5504 /* expect pointer on structure */
5505 if ((vtop->t & VT_BTYPE) != VT_STRUCT)
5506 expect("struct or union");
5507 s = sym_find(((unsigned)vtop->t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
5508 /* find field */
5509 tok |= SYM_FIELD;
5510 while ((s = s->next) != NULL) {
5511 if (s->v == tok)
5512 break;
5514 if (!s)
5515 error("field not found");
5516 /* add field offset to pointer */
5517 vtop->t = char_pointer_type; /* change type to 'char *' */
5518 vpushi(s->c);
5519 gen_op('+');
5520 /* change type to field type, and set to lvalue */
5521 vtop->t = s->t;
5522 /* an array is never an lvalue */
5523 if (!(vtop->t & VT_ARRAY)) {
5524 vtop->r |= lvalue_type(vtop->t);
5525 /* if bound checking, the referenced pointer must be checked */
5526 if (do_bounds_check)
5527 vtop->r |= VT_MUSTBOUND;
5529 next();
5530 } else if (tok == '[') {
5531 next();
5532 gexpr();
5533 gen_op('+');
5534 indir();
5535 skip(']');
5536 } else if (tok == '(') {
5537 SValue ret;
5538 Sym *sa;
5540 /* function call */
5541 if ((vtop->t & VT_BTYPE) != VT_FUNC) {
5542 /* pointer test (no array accepted) */
5543 if ((vtop->t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
5544 vtop->t = pointed_type(vtop->t);
5545 if ((vtop->t & VT_BTYPE) != VT_FUNC)
5546 goto error_func;
5547 } else {
5548 error_func:
5549 expect("function pointer");
5551 } else {
5552 vtop->r &= ~VT_LVAL; /* no lvalue */
5554 /* get return type */
5555 s = sym_find((unsigned)vtop->t >> VT_STRUCT_SHIFT);
5556 save_regs(0); /* save used temporary registers */
5557 gfunc_start(&gf, s->r);
5558 next();
5559 sa = s->next; /* first parameter */
5560 #ifdef INVERT_FUNC_PARAMS
5562 int parlevel;
5563 Sym *args, *s1;
5564 ParseState saved_parse_state;
5565 TokenString str;
5567 /* read each argument and store it on a stack */
5568 args = NULL;
5569 if (tok != ')') {
5570 for(;;) {
5571 tok_str_new(&str);
5572 parlevel = 0;
5573 while ((parlevel > 0 || (tok != ')' && tok != ',')) &&
5574 tok != TOK_EOF) {
5575 if (tok == '(')
5576 parlevel++;
5577 else if (tok == ')')
5578 parlevel--;
5579 tok_str_add_tok(&str);
5580 next();
5582 tok_str_add(&str, -1); /* end of file added */
5583 tok_str_add(&str, 0);
5584 s1 = sym_push2(&args, 0, 0, (int)str.str);
5585 s1->next = sa; /* add reference to argument */
5586 if (sa)
5587 sa = sa->next;
5588 if (tok == ')')
5589 break;
5590 skip(',');
5594 /* now generate code in reverse order by reading the stack */
5595 save_parse_state(&saved_parse_state);
5596 while (args) {
5597 macro_ptr = (int *)args->c;
5598 next();
5599 expr_eq();
5600 if (tok != -1)
5601 expect("',' or ')'");
5602 gfunc_param_typed(&gf, s, args->next);
5603 s1 = args->prev;
5604 tok_str_free((int *)args->c);
5605 tcc_free(args);
5606 args = s1;
5608 restore_parse_state(&saved_parse_state);
5610 #endif
5611 /* compute first implicit argument if a structure is returned */
5612 if ((s->t & VT_BTYPE) == VT_STRUCT) {
5613 /* get some space for the returned structure */
5614 size = type_size(s->t, &align);
5615 loc = (loc - size) & -align;
5616 ret.t = s->t;
5617 ret.r = VT_LOCAL | VT_LVAL;
5618 /* pass it as 'int' to avoid structure arg passing
5619 problems */
5620 vset(VT_INT, VT_LOCAL, loc);
5621 ret.c = vtop->c;
5622 gfunc_param(&gf);
5623 } else {
5624 ret.t = s->t;
5625 ret.r2 = VT_CONST;
5626 /* return in register */
5627 if (is_float(ret.t)) {
5628 ret.r = REG_FRET;
5629 } else {
5630 if ((ret.t & VT_BTYPE) == VT_LLONG)
5631 ret.r2 = REG_LRET;
5632 ret.r = REG_IRET;
5634 ret.c.i = 0;
5636 #ifndef INVERT_FUNC_PARAMS
5637 if (tok != ')') {
5638 for(;;) {
5639 expr_eq();
5640 gfunc_param_typed(&gf, s, sa);
5641 if (sa)
5642 sa = sa->next;
5643 if (tok == ')')
5644 break;
5645 skip(',');
5648 #endif
5649 if (sa)
5650 error("too few arguments to function");
5651 skip(')');
5652 gfunc_call(&gf);
5653 /* return value */
5654 vsetc(ret.t, ret.r, &ret.c);
5655 vtop->r2 = ret.r2;
5656 } else {
5657 break;
5662 void uneq(void)
5664 int t;
5666 unary();
5667 if (tok == '=' ||
5668 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
5669 tok == TOK_A_XOR || tok == TOK_A_OR ||
5670 tok == TOK_A_SHL || tok == TOK_A_SAR) {
5671 test_lvalue();
5672 t = tok;
5673 next();
5674 if (t == '=') {
5675 expr_eq();
5676 } else {
5677 vdup();
5678 expr_eq();
5679 gen_op(t & 0x7f);
5681 vstore();
5685 void sum(int l)
5687 int t;
5689 if (l == 0)
5690 uneq();
5691 else {
5692 sum(--l);
5693 while ((l == 0 && (tok == '*' || tok == '/' || tok == '%')) ||
5694 (l == 1 && (tok == '+' || tok == '-')) ||
5695 (l == 2 && (tok == TOK_SHL || tok == TOK_SAR)) ||
5696 (l == 3 && ((tok >= TOK_ULE && tok <= TOK_GT) ||
5697 tok == TOK_ULT || tok == TOK_UGE)) ||
5698 (l == 4 && (tok == TOK_EQ || tok == TOK_NE)) ||
5699 (l == 5 && tok == '&') ||
5700 (l == 6 && tok == '^') ||
5701 (l == 7 && tok == '|') ||
5702 (l == 8 && tok == TOK_LAND) ||
5703 (l == 9 && tok == TOK_LOR)) {
5704 t = tok;
5705 next();
5706 sum(l);
5707 gen_op(t);
5712 /* only used if non constant */
5713 void eand(void)
5715 int t;
5717 sum(8);
5718 t = 0;
5719 while (1) {
5720 if (tok != TOK_LAND) {
5721 if (t) {
5722 t = gtst(1, t);
5723 vset(VT_INT, VT_JMPI, t);
5725 break;
5727 t = gtst(1, t);
5728 next();
5729 sum(8);
5733 void eor(void)
5735 int t;
5737 eand();
5738 t = 0;
5739 while (1) {
5740 if (tok != TOK_LOR) {
5741 if (t) {
5742 t = gtst(0, t);
5743 vset(VT_INT, VT_JMP, t);
5745 break;
5747 t = gtst(0, t);
5748 next();
5749 eand();
5753 /* XXX: better constant handling */
5754 void expr_eq(void)
5756 int tt, u, r1, r2, rc, t1, t2, t, bt1, bt2;
5757 SValue sv;
5759 if (const_wanted) {
5760 int c1, c;
5761 sum(10);
5762 if (tok == '?') {
5763 c = vtop->c.i;
5764 vpop();
5765 next();
5766 gexpr();
5767 c1 = vtop->c.i;
5768 vpop();
5769 skip(':');
5770 expr_eq();
5771 if (c)
5772 vtop->c.i = c1;
5774 } else {
5775 eor();
5776 if (tok == '?') {
5777 next();
5778 save_regs(1); /* we need to save all registers here except
5779 at the top because it is a branch point */
5780 tt = gtst(1, 0);
5781 gexpr();
5782 t1 = vtop->t;
5783 bt1 = t1 & VT_BTYPE;
5784 sv = *vtop; /* save value to handle it later */
5785 vtop--; /* no vpop so that FP stack is not flushed */
5786 skip(':');
5787 u = gjmp(0);
5789 gsym(tt);
5790 expr_eq();
5791 t2 = vtop->t;
5793 bt2 = t2 & VT_BTYPE;
5794 /* cast operands to correct type according to ISOC rules */
5795 if (is_float(bt1) || is_float(bt2)) {
5796 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
5797 t = VT_LDOUBLE;
5798 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
5799 t = VT_DOUBLE;
5800 } else {
5801 t = VT_FLOAT;
5803 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
5804 /* cast to biggest op */
5805 t = VT_LLONG;
5806 /* convert to unsigned if it does not fit in a long long */
5807 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
5808 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
5809 t |= VT_UNSIGNED;
5810 } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
5811 /* XXX: test pointer compatibility */
5812 t = t1;
5813 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
5814 /* XXX: test structure compatibility */
5815 t = t1;
5816 } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
5817 /* NOTE: as an extension, we accept void on only one side */
5818 t = VT_VOID;
5819 } else {
5820 /* integer operations */
5821 t = VT_INT;
5822 /* convert to unsigned if it does not fit in an integer */
5823 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
5824 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
5825 t |= VT_UNSIGNED;
5828 /* now we convert second operand */
5829 gen_cast(t);
5830 rc = RC_INT;
5831 if (is_float(t)) {
5832 rc = RC_FLOAT;
5833 } else if ((t & VT_BTYPE) == VT_LLONG) {
5834 /* for long longs, we use fixed registers to avoid having
5835 to handle a complicated move */
5836 rc = RC_IRET;
5838 r2 = gv(rc);
5839 /* this is horrible, but we must also convert first
5840 operand */
5841 tt = gjmp(0);
5842 gsym(u);
5843 /* put again first value and cast it */
5844 *vtop = sv;
5845 gen_cast(t);
5846 r1 = gv(rc);
5847 move_reg(r2, r1);
5848 vtop->r = r2;
5849 gsym(tt);
5854 void gexpr(void)
5856 while (1) {
5857 expr_eq();
5858 if (tok != ',')
5859 break;
5860 vpop();
5861 next();
5865 /* parse a constant expression and return value in vtop. */
5866 static void expr_const1(void)
5868 int a;
5869 a = const_wanted;
5870 const_wanted = 1;
5871 expr_eq();
5872 const_wanted = a;
5875 /* parse an integer constant and return its value. */
5876 static int expr_const(void)
5878 int c;
5879 expr_const1();
5880 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
5881 expect("constant expression");
5882 c = vtop->c.i;
5883 vpop();
5884 return c;
5887 /* return the label token if current token is a label, otherwise
5888 return zero */
5889 int is_label(void)
5891 int t;
5892 CValue c;
5894 /* fast test first */
5895 if (tok < TOK_UIDENT)
5896 return 0;
5897 /* no need to save tokc since we expect an identifier */
5898 t = tok;
5899 c = tokc;
5900 next();
5901 if (tok == ':') {
5902 next();
5903 return t;
5904 } else {
5905 /* XXX: may not work in all cases (macros ?) */
5906 tok1 = tok;
5907 tok1c = tokc;
5908 tok = t;
5909 tokc = c;
5910 return 0;
5914 void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg)
5916 int a, b, c, d;
5917 Sym *s;
5919 /* generate line number info */
5920 if (do_debug &&
5921 (last_line_num != file->line_num || last_ind != ind)) {
5922 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
5923 last_ind = ind;
5924 last_line_num = file->line_num;
5927 if (tok == TOK_IF) {
5928 /* if test */
5929 next();
5930 skip('(');
5931 gexpr();
5932 skip(')');
5933 a = gtst(1, 0);
5934 block(bsym, csym, case_sym, def_sym, case_reg);
5935 c = tok;
5936 if (c == TOK_ELSE) {
5937 next();
5938 d = gjmp(0);
5939 gsym(a);
5940 block(bsym, csym, case_sym, def_sym, case_reg);
5941 gsym(d); /* patch else jmp */
5942 } else
5943 gsym(a);
5944 } else if (tok == TOK_WHILE) {
5945 next();
5946 d = ind;
5947 skip('(');
5948 gexpr();
5949 skip(')');
5950 a = gtst(1, 0);
5951 b = 0;
5952 block(&a, &b, case_sym, def_sym, case_reg);
5953 gjmp_addr(d);
5954 gsym(a);
5955 gsym_addr(b, d);
5956 } else if (tok == '{') {
5957 next();
5958 /* declarations */
5959 s = local_stack.top;
5960 while (tok != '}') {
5961 decl(VT_LOCAL);
5962 if (tok != '}')
5963 block(bsym, csym, case_sym, def_sym, case_reg);
5965 /* pop locally defined symbols */
5966 sym_pop(&local_stack, s);
5967 next();
5968 } else if (tok == TOK_RETURN) {
5969 next();
5970 if (tok != ';') {
5971 gexpr();
5972 gen_assign_cast(func_vt);
5973 if ((func_vt & VT_BTYPE) == VT_STRUCT) {
5974 /* if returning structure, must copy it to implicit
5975 first pointer arg location */
5976 vset(mk_pointer(func_vt), VT_LOCAL | VT_LVAL, func_vc);
5977 indir();
5978 vswap();
5979 /* copy structure value to pointer */
5980 vstore();
5981 } else if (is_float(func_vt)) {
5982 gv(RC_FRET);
5983 } else {
5984 gv(RC_IRET);
5986 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
5988 skip(';');
5989 rsym = gjmp(rsym); /* jmp */
5990 } else if (tok == TOK_BREAK) {
5991 /* compute jump */
5992 if (!bsym)
5993 error("cannot break");
5994 *bsym = gjmp(*bsym);
5995 next();
5996 skip(';');
5997 } else if (tok == TOK_CONTINUE) {
5998 /* compute jump */
5999 if (!csym)
6000 error("cannot continue");
6001 *csym = gjmp(*csym);
6002 next();
6003 skip(';');
6004 } else if (tok == TOK_FOR) {
6005 int e;
6006 next();
6007 skip('(');
6008 if (tok != ';') {
6009 gexpr();
6010 vpop();
6012 skip(';');
6013 d = ind;
6014 c = ind;
6015 a = 0;
6016 b = 0;
6017 if (tok != ';') {
6018 gexpr();
6019 a = gtst(1, 0);
6021 skip(';');
6022 if (tok != ')') {
6023 e = gjmp(0);
6024 c = ind;
6025 gexpr();
6026 vpop();
6027 gjmp_addr(d);
6028 gsym(e);
6030 skip(')');
6031 block(&a, &b, case_sym, def_sym, case_reg);
6032 gjmp_addr(c);
6033 gsym(a);
6034 gsym_addr(b, c);
6035 } else
6036 if (tok == TOK_DO) {
6037 next();
6038 a = 0;
6039 b = 0;
6040 d = ind;
6041 block(&a, &b, case_sym, def_sym, case_reg);
6042 skip(TOK_WHILE);
6043 skip('(');
6044 gsym(b);
6045 gexpr();
6046 c = gtst(0, 0);
6047 gsym_addr(c, d);
6048 skip(')');
6049 gsym(a);
6050 skip(';');
6051 } else
6052 if (tok == TOK_SWITCH) {
6053 next();
6054 skip('(');
6055 gexpr();
6056 /* XXX: other types than integer */
6057 case_reg = gv(RC_INT);
6058 vpop();
6059 skip(')');
6060 a = 0;
6061 b = gjmp(0); /* jump to first case */
6062 c = 0;
6063 block(&a, csym, &b, &c, case_reg);
6064 /* if no default, jmp after switch */
6065 if (c == 0)
6066 c = ind;
6067 /* default label */
6068 gsym_addr(b, c);
6069 /* break label */
6070 gsym(a);
6071 } else
6072 if (tok == TOK_CASE) {
6073 int v1, v2;
6074 if (!case_sym)
6075 expect("switch");
6076 next();
6077 v1 = expr_const();
6078 v2 = v1;
6079 if (gnu_ext && tok == TOK_DOTS) {
6080 next();
6081 v2 = expr_const();
6082 if (v2 < v1)
6083 warning("empty case range");
6085 /* since a case is like a label, we must skip it with a jmp */
6086 b = gjmp(0);
6087 gsym(*case_sym);
6088 vset(VT_INT, case_reg, 0);
6089 vpushi(v1);
6090 if (v1 == v2) {
6091 gen_op(TOK_EQ);
6092 *case_sym = gtst(1, 0);
6093 } else {
6094 gen_op(TOK_GE);
6095 *case_sym = gtst(1, 0);
6096 vset(VT_INT, case_reg, 0);
6097 vpushi(v2);
6098 gen_op(TOK_LE);
6099 *case_sym = gtst(1, *case_sym);
6101 gsym(b);
6102 skip(':');
6103 block(bsym, csym, case_sym, def_sym, case_reg);
6104 } else
6105 if (tok == TOK_DEFAULT) {
6106 next();
6107 skip(':');
6108 if (!def_sym)
6109 expect("switch");
6110 if (*def_sym)
6111 error("too many 'default'");
6112 *def_sym = ind;
6113 block(bsym, csym, case_sym, def_sym, case_reg);
6114 } else
6115 if (tok == TOK_GOTO) {
6116 next();
6117 s = sym_find1(&label_stack, tok);
6118 /* put forward definition if needed */
6119 if (!s)
6120 s = sym_push1(&label_stack, tok, LABEL_FORWARD, 0);
6121 /* label already defined */
6122 if (s->t & LABEL_FORWARD)
6123 s->c = gjmp(s->c);
6124 else
6125 gjmp_addr(s->c);
6126 next();
6127 skip(';');
6128 } else {
6129 b = is_label();
6130 if (b) {
6131 /* label case */
6132 s = sym_find1(&label_stack, b);
6133 if (s) {
6134 if (!(s->t & LABEL_FORWARD))
6135 error("multiple defined label");
6136 gsym(s->c);
6137 s->c = ind;
6138 s->t = 0;
6139 } else {
6140 sym_push1(&label_stack, b, 0, ind);
6142 /* we accept this, but it is a mistake */
6143 if (tok == '}')
6144 warning("deprecated use of label at end of compound statement");
6145 else
6146 block(bsym, csym, case_sym, def_sym, case_reg);
6147 } else {
6148 /* expression case */
6149 if (tok != ';') {
6150 gexpr();
6151 vpop();
6153 skip(';');
6158 /* t is the array or struct type. c is the array or struct
6159 address. cur_index/cur_field is the pointer to the current
6160 value. 'size_only' is true if only size info is needed (only used
6161 in arrays) */
6162 static void decl_designator(int t, Section *sec, unsigned long c,
6163 int *cur_index, Sym **cur_field,
6164 int size_only)
6166 Sym *s, *f;
6167 int notfirst, index, align, l;
6169 notfirst = 0;
6170 if (gnu_ext && (l = is_label()) != 0)
6171 goto struct_field;
6173 while (tok == '[' || tok == '.') {
6174 if (tok == '[') {
6175 if (!(t & VT_ARRAY))
6176 expect("array type");
6177 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
6178 next();
6179 index = expr_const();
6180 if (index < 0 || (s->c >= 0 && index >= s->c))
6181 expect("invalid index");
6182 skip(']');
6183 if (!notfirst)
6184 *cur_index = index;
6185 t = pointed_type(t);
6186 c += index * type_size(t, &align);
6187 } else {
6188 next();
6189 l = tok;
6190 next();
6191 struct_field:
6192 if ((t & VT_BTYPE) != VT_STRUCT)
6193 expect("struct/union type");
6194 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
6195 l |= SYM_FIELD;
6196 f = s->next;
6197 while (f) {
6198 if (f->v == l)
6199 break;
6200 f = f->next;
6202 if (!f)
6203 expect("field");
6204 if (!notfirst)
6205 *cur_field = f;
6206 t = f->t | (t & ~VT_TYPE);
6207 c += f->c;
6209 notfirst = 1;
6211 if (notfirst) {
6212 if (tok == '=') {
6213 next();
6214 } else {
6215 if (!gnu_ext)
6216 expect("=");
6218 } else {
6219 if (t & VT_ARRAY) {
6220 index = *cur_index;
6221 t = pointed_type(t);
6222 c += index * type_size(t, &align);
6223 } else {
6224 f = *cur_field;
6225 if (!f)
6226 error("too many field init");
6227 t = f->t | (t & ~VT_TYPE);
6228 c += f->c;
6231 decl_initializer(t, sec, c, 0, size_only);
6234 #define EXPR_VAL 0
6235 #define EXPR_CONST 1
6236 #define EXPR_ANY 2
6238 /* store a value or an expression directly in global data or in local array */
6239 static void init_putv(int t, Section *sec, unsigned long c,
6240 int v, int expr_type)
6242 int saved_global_expr, bt;
6243 void *ptr;
6245 switch(expr_type) {
6246 case EXPR_VAL:
6247 vpushi(v);
6248 break;
6249 case EXPR_CONST:
6250 /* compound literals must be allocated globally in this case */
6251 saved_global_expr = global_expr;
6252 global_expr = 1;
6253 expr_const1();
6254 global_expr = saved_global_expr;
6255 /* NOTE: symbols are accepted */
6256 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
6257 error("initializer element is not constant");
6258 break;
6259 case EXPR_ANY:
6260 expr_eq();
6261 break;
6264 if (sec) {
6265 /* XXX: not portable */
6266 /* XXX: generate error if incorrect relocation */
6267 gen_assign_cast(t);
6268 bt = t & VT_BTYPE;
6269 ptr = sec->data + c;
6270 if ((vtop->r & VT_SYM) &&
6271 (bt == VT_BYTE ||
6272 bt == VT_SHORT ||
6273 bt == VT_DOUBLE ||
6274 bt == VT_LDOUBLE ||
6275 bt == VT_LLONG))
6276 error("initializer element is not computable at load time");
6277 switch(bt) {
6278 case VT_BYTE:
6279 *(char *)ptr = vtop->c.i;
6280 break;
6281 case VT_SHORT:
6282 *(short *)ptr = vtop->c.i;
6283 break;
6284 case VT_DOUBLE:
6285 *(double *)ptr = vtop->c.d;
6286 break;
6287 case VT_LDOUBLE:
6288 *(long double *)ptr = vtop->c.ld;
6289 break;
6290 case VT_LLONG:
6291 *(long long *)ptr = vtop->c.ll;
6292 break;
6293 default:
6294 if (vtop->r & VT_SYM) {
6295 greloc(sec, vtop->sym, c, R_DATA_32);
6297 *(int *)ptr = vtop->c.i;
6298 break;
6300 vtop--;
6301 } else {
6302 vset(t, VT_LOCAL, c);
6303 vswap();
6304 vstore();
6305 vpop();
6309 /* put zeros for variable based init */
6310 static void init_putz(int t, Section *sec, unsigned long c, int size)
6312 GFuncContext gf;
6314 if (sec) {
6315 /* nothing to do because globals are already set to zero */
6316 } else {
6317 gfunc_start(&gf, FUNC_CDECL);
6318 vpushi(size);
6319 gfunc_param(&gf);
6320 vpushi(0);
6321 gfunc_param(&gf);
6322 vset(VT_INT, VT_LOCAL, c);
6323 gfunc_param(&gf);
6324 vpush_global_sym(func_old_type, TOK_memset);
6325 gfunc_call(&gf);
6329 /* 't' contains the type and storage info. 'c' is the offset of the
6330 object in section 'sec'. If 'sec' is NULL, it means stack based
6331 allocation. 'first' is true if array '{' must be read (multi
6332 dimension implicit array init handling). 'size_only' is true if
6333 size only evaluation is wanted (only for arrays). */
6334 static void decl_initializer(int t, Section *sec, unsigned long c,
6335 int first, int size_only)
6337 int index, array_length, n, no_oblock, nb, parlevel, i;
6338 int t1, size1, align1, expr_type;
6339 Sym *s, *f;
6341 if (t & VT_ARRAY) {
6342 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
6343 n = s->c;
6344 array_length = 0;
6345 t1 = pointed_type(t);
6346 size1 = type_size(t1, &align1);
6348 no_oblock = 1;
6349 if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
6350 tok == '{') {
6351 skip('{');
6352 no_oblock = 0;
6355 /* only parse strings here if correct type (otherwise: handle
6356 them as ((w)char *) expressions */
6357 if ((tok == TOK_LSTR &&
6358 (t1 & VT_BTYPE) == VT_INT) ||
6359 (tok == TOK_STR &&
6360 (t1 & VT_BTYPE) == VT_BYTE)) {
6361 while (tok == TOK_STR || tok == TOK_LSTR) {
6362 int cstr_len, ch;
6363 CString *cstr;
6365 cstr = tokc.cstr;
6366 /* compute maximum number of chars wanted */
6367 if (tok == TOK_STR)
6368 cstr_len = cstr->size;
6369 else
6370 cstr_len = cstr->size / sizeof(int);
6371 cstr_len--;
6372 nb = cstr_len;
6373 if (n >= 0 && nb > (n - array_length))
6374 nb = n - array_length;
6375 if (!size_only) {
6376 if (cstr_len > nb)
6377 warning("initializer-string for array is too long");
6378 /* in order to go faster for common case (char
6379 string in global variable, we handle it
6380 specifically */
6381 if (sec && tok == TOK_STR && size1 == 1) {
6382 memcpy(sec->data + c + array_length, cstr->data, nb);
6383 } else {
6384 for(i=0;i<nb;i++) {
6385 if (tok == TOK_STR)
6386 ch = ((unsigned char *)cstr->data)[i];
6387 else
6388 ch = ((int *)cstr->data)[i];
6389 init_putv(t1, sec, c + (array_length + i) * size1,
6390 ch, EXPR_VAL);
6394 array_length += nb;
6395 next();
6397 /* only add trailing zero if enough storage (no
6398 warning in this case since it is standard) */
6399 if (n < 0 || array_length < n) {
6400 if (!size_only) {
6401 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
6403 array_length++;
6405 } else {
6406 index = 0;
6407 while (tok != '}') {
6408 decl_designator(t, sec, c, &index, NULL, size_only);
6409 if (n >= 0 && index >= n)
6410 error("index too large");
6411 /* must put zero in holes (note that doing it that way
6412 ensures that it even works with designators) */
6413 if (!size_only && array_length < index) {
6414 init_putz(t1, sec, c + array_length * size1,
6415 (index - array_length) * size1);
6417 index++;
6418 if (index > array_length)
6419 array_length = index;
6420 /* special test for multi dimensional arrays (may not
6421 be strictly correct if designators are used at the
6422 same time) */
6423 if (index >= n && no_oblock)
6424 break;
6425 if (tok == '}')
6426 break;
6427 skip(',');
6430 if (!no_oblock)
6431 skip('}');
6432 /* put zeros at the end */
6433 if (!size_only && n >= 0 && array_length < n) {
6434 init_putz(t1, sec, c + array_length * size1,
6435 (n - array_length) * size1);
6437 /* patch type size if needed */
6438 if (n < 0)
6439 s->c = array_length;
6440 } else if ((t & VT_BTYPE) == VT_STRUCT && tok == '{') {
6441 /* XXX: union needs only one init */
6442 next();
6443 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
6444 f = s->next;
6445 array_length = 0;
6446 index = 0;
6447 n = s->c;
6448 while (tok != '}') {
6449 decl_designator(t, sec, c, NULL, &f, size_only);
6450 /* fill with zero between fields */
6451 index = f->c;
6452 if (!size_only && array_length < index) {
6453 init_putz(t, sec, c + array_length,
6454 index - array_length);
6456 index = index + type_size(f->t, &align1);
6457 if (index > array_length)
6458 array_length = index;
6459 if (tok == '}')
6460 break;
6461 skip(',');
6462 f = f->next;
6464 /* put zeros at the end */
6465 if (!size_only && array_length < n) {
6466 init_putz(t, sec, c + array_length,
6467 n - array_length);
6469 skip('}');
6470 } else if (tok == '{') {
6471 next();
6472 decl_initializer(t, sec, c, first, size_only);
6473 skip('}');
6474 } else if (size_only) {
6475 /* just skip expression */
6476 parlevel = 0;
6477 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
6478 tok != -1) {
6479 if (tok == '(')
6480 parlevel++;
6481 else if (tok == ')')
6482 parlevel--;
6483 next();
6485 } else {
6486 /* currently, we always use constant expression for globals
6487 (may change for scripting case) */
6488 expr_type = EXPR_CONST;
6489 if (!sec)
6490 expr_type = EXPR_ANY;
6491 init_putv(t, sec, c, 0, expr_type);
6495 /* parse an initializer for type 't' if 'has_init' is non zero, and
6496 allocate space in local or global data space ('r' is either
6497 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6498 variable 'v' of scope 'scope' is declared before initializers are
6499 parsed. If 'v' is zero, then a reference to the new object is put
6500 in the value stack. If 'has_init' is 2, a special parsing is done
6501 to handle string constants. */
6502 static void decl_initializer_alloc(int t, AttributeDef *ad, int r,
6503 int has_init, int v, int scope)
6505 int size, align, addr, data_offset;
6506 int level;
6507 ParseState saved_parse_state;
6508 TokenString init_str;
6509 Section *sec;
6511 size = type_size(t, &align);
6512 /* If unknown size, we must evaluate it before
6513 evaluating initializers because
6514 initializers can generate global data too
6515 (e.g. string pointers or ISOC99 compound
6516 literals). It also simplifies local
6517 initializers handling */
6518 tok_str_new(&init_str);
6519 if (size < 0) {
6520 if (!has_init)
6521 error("unknown type size");
6522 /* get all init string */
6523 if (has_init == 2) {
6524 /* only get strings */
6525 while (tok == TOK_STR || tok == TOK_LSTR) {
6526 tok_str_add_tok(&init_str);
6527 next();
6529 } else {
6530 level = 0;
6531 while (level > 0 || (tok != ',' && tok != ';')) {
6532 if (tok < 0)
6533 error("unexpected end of file in initializer");
6534 tok_str_add_tok(&init_str);
6535 if (tok == '{')
6536 level++;
6537 else if (tok == '}') {
6538 if (level == 0)
6539 break;
6540 level--;
6542 next();
6545 tok_str_add(&init_str, -1);
6546 tok_str_add(&init_str, 0);
6548 /* compute size */
6549 save_parse_state(&saved_parse_state);
6551 macro_ptr = init_str.str;
6552 next();
6553 decl_initializer(t, NULL, 0, 1, 1);
6554 /* prepare second initializer parsing */
6555 macro_ptr = init_str.str;
6556 next();
6558 /* if still unknown size, error */
6559 size = type_size(t, &align);
6560 if (size < 0)
6561 error("unknown type size");
6563 /* take into account specified alignment if bigger */
6564 if (ad->aligned > align)
6565 align = ad->aligned;
6566 if ((r & VT_VALMASK) == VT_LOCAL) {
6567 sec = NULL;
6568 if (do_bounds_check && (t & VT_ARRAY))
6569 loc--;
6570 #ifdef TCC_TARGET_IL
6571 /* XXX: ugly patch to allocate local variables for IL, just
6572 for testing */
6573 addr = loc;
6574 loc++;
6575 #else
6576 loc = (loc - size) & -align;
6577 addr = loc;
6578 #endif
6579 /* handles bounds */
6580 /* XXX: currently, since we do only one pass, we cannot track
6581 '&' operators, so we add only arrays */
6582 if (do_bounds_check && (t & VT_ARRAY)) {
6583 unsigned long *bounds_ptr;
6584 /* add padding between regions */
6585 loc--;
6586 /* then add local bound info */
6587 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
6588 bounds_ptr[0] = addr;
6589 bounds_ptr[1] = size;
6591 } else {
6592 /* compute section */
6593 sec = ad->section;
6594 if (!sec) {
6595 if (has_init)
6596 sec = data_section;
6597 else
6598 sec = bss_section;
6600 data_offset = sec->data_offset;
6601 data_offset = (data_offset + align - 1) & -align;
6602 addr = data_offset;
6603 /* very important to increment global pointer at this time
6604 because initializers themselves can create new initializers */
6605 data_offset += size;
6606 /* add padding if bound check */
6607 if (do_bounds_check)
6608 data_offset++;
6609 sec->data_offset = data_offset;
6610 /* allocate section space to put the data */
6611 if (sec->sh_type != SHT_NOBITS &&
6612 data_offset > sec->data_allocated)
6613 section_realloc(sec, data_offset);
6615 if (!sec) {
6616 if (v) {
6617 /* local variable */
6618 sym_push(v, t, r, addr);
6619 } else {
6620 /* push local reference */
6621 vset(t, r, addr);
6623 } else {
6624 Sym *sym;
6626 if (v) {
6627 if (scope == VT_CONST) {
6628 /* global scope: see if already defined */
6629 sym = sym_find(v);
6630 if (!sym)
6631 goto do_def;
6632 if (!is_compatible_types(sym->t, t))
6633 error("incompatible types for redefinition of '%s'",
6634 get_tok_str(v, NULL));
6635 if (!(sym->t & VT_EXTERN))
6636 error("redefinition of '%s'", get_tok_str(v, NULL));
6637 sym->t &= ~VT_EXTERN;
6638 } else {
6639 do_def:
6640 sym = sym_push(v, t, r | VT_SYM, 0);
6642 put_extern_sym(sym, sec, addr, size);
6643 } else {
6644 CValue cval;
6646 /* push global reference */
6647 sym = get_sym_ref(t, sec, addr, size);
6648 cval.ul = 0;
6649 vsetc(t, VT_CONST | VT_SYM, &cval);
6650 vtop->sym = sym;
6653 /* handles bounds now because the symbol must be defined
6654 before for the relocation */
6655 if (do_bounds_check) {
6656 unsigned long *bounds_ptr;
6658 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
6659 /* then add global bound info */
6660 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
6661 bounds_ptr[0] = 0; /* relocated */
6662 bounds_ptr[1] = size;
6665 if (has_init) {
6666 decl_initializer(t, sec, addr, 1, 0);
6667 /* restore parse state if needed */
6668 if (init_str.str) {
6669 tok_str_free(init_str.str);
6670 restore_parse_state(&saved_parse_state);
6675 void put_func_debug(Sym *sym)
6677 char buf[512];
6679 /* stabs info */
6680 /* XXX: we put here a dummy type */
6681 snprintf(buf, sizeof(buf), "%s:%c1",
6682 funcname, sym->t & VT_STATIC ? 'f' : 'F');
6683 put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
6684 cur_text_section, sym->c);
6685 last_ind = 0;
6686 last_line_num = 0;
6689 /* not finished : try to put some local vars in registers */
6690 //#define CONFIG_REG_VARS
6692 #ifdef CONFIG_REG_VARS
6693 void add_var_ref(int t)
6695 printf("%s:%d: &%s\n",
6696 file->filename, file->line_num,
6697 get_tok_str(t, NULL));
6700 /* first pass on a function with heuristic to extract variable usage
6701 and pointer references to local variables for register allocation */
6702 void analyse_function(void)
6704 int level, t;
6706 for(;;) {
6707 if (tok == -1)
6708 break;
6709 /* any symbol coming after '&' is considered as being a
6710 variable whose reference is taken. It is highly unaccurate
6711 but it is difficult to do better without a complete parse */
6712 if (tok == '&') {
6713 next();
6714 /* if '& number', then no need to examine next tokens */
6715 if (tok == TOK_CINT ||
6716 tok == TOK_CUINT ||
6717 tok == TOK_CLLONG ||
6718 tok == TOK_CULLONG) {
6719 continue;
6720 } else if (tok >= TOK_UIDENT) {
6721 /* if '& ident [' or '& ident ->', then ident address
6722 is not needed */
6723 t = tok;
6724 next();
6725 if (tok != '[' && tok != TOK_ARROW)
6726 add_var_ref(t);
6727 } else {
6728 level = 0;
6729 while (tok != '}' && tok != ';' &&
6730 !((tok == ',' || tok == ')') && level == 0)) {
6731 if (tok >= TOK_UIDENT) {
6732 add_var_ref(tok);
6733 } else if (tok == '(') {
6734 level++;
6735 } else if (tok == ')') {
6736 level--;
6738 next();
6741 } else {
6742 next();
6746 #endif
6748 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6749 void decl(int l)
6751 int t, b, v, has_init, r;
6752 Sym *sym;
6753 AttributeDef ad;
6755 while (1) {
6756 if (!parse_btype(&b, &ad)) {
6757 /* skip redundant ';' */
6758 /* XXX: find more elegant solution */
6759 if (tok == ';') {
6760 next();
6761 continue;
6763 /* special test for old K&R protos without explicit int
6764 type. Only accepted when defining global data */
6765 if (l == VT_LOCAL || tok < TOK_DEFINE)
6766 break;
6767 b = VT_INT;
6769 if (((b & VT_BTYPE) == VT_ENUM ||
6770 (b & VT_BTYPE) == VT_STRUCT) &&
6771 tok == ';') {
6772 /* we accept no variable after */
6773 next();
6774 continue;
6776 while (1) { /* iterate thru each declaration */
6777 t = type_decl(&ad, &v, b, TYPE_DIRECT);
6778 #if 0
6780 char buf[500];
6781 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
6782 printf("type = '%s'\n", buf);
6784 #endif
6785 if (tok == '{') {
6786 #ifdef CONFIG_REG_VARS
6787 TokenString func_str;
6788 ParseState saved_parse_state;
6789 int block_level;
6790 #endif
6792 if (l == VT_LOCAL)
6793 error("cannot use local functions");
6794 if (!(t & VT_FUNC))
6795 expect("function definition");
6797 #ifdef CONFIG_REG_VARS
6798 /* parse all function code and record it */
6800 tok_str_new(&func_str);
6802 block_level = 0;
6803 for(;;) {
6804 int t;
6805 if (tok == -1)
6806 error("unexpected end of file");
6807 tok_str_add_tok(&func_str);
6808 t = tok;
6809 next();
6810 if (t == '{') {
6811 block_level++;
6812 } else if (t == '}') {
6813 block_level--;
6814 if (block_level == 0)
6815 break;
6818 tok_str_add(&func_str, -1);
6819 tok_str_add(&func_str, 0);
6821 save_parse_state(&saved_parse_state);
6823 macro_ptr = func_str.str;
6824 next();
6825 analyse_function();
6826 #endif
6828 /* compute text section */
6829 cur_text_section = ad.section;
6830 if (!cur_text_section)
6831 cur_text_section = text_section;
6832 ind = cur_text_section->data_offset;
6833 funcname = get_tok_str(v, NULL);
6834 sym = sym_find(v);
6835 if (sym) {
6836 /* if symbol is already defined, then put complete type */
6837 sym->t = t;
6838 } else {
6839 /* put function symbol */
6840 sym = sym_push1(&global_stack, v, t, 0);
6842 /* NOTE: we patch the symbol size later */
6843 put_extern_sym(sym, cur_text_section, ind, 0);
6844 func_ind = ind;
6845 sym->r = VT_SYM | VT_CONST;
6846 /* put debug symbol */
6847 if (do_debug)
6848 put_func_debug(sym);
6849 /* push a dummy symbol to enable local sym storage */
6850 sym_push1(&local_stack, 0, 0, 0);
6851 gfunc_prolog(t);
6852 loc = 0;
6853 rsym = 0;
6854 #ifdef CONFIG_REG_VARS
6855 macro_ptr = func_str.str;
6856 next();
6857 #endif
6858 block(NULL, NULL, NULL, NULL, 0);
6859 gsym(rsym);
6860 gfunc_epilog();
6861 cur_text_section->data_offset = ind;
6862 sym_pop(&label_stack, NULL); /* reset label stack */
6863 sym_pop(&local_stack, NULL); /* reset local stack */
6864 /* end of function */
6865 /* patch symbol size */
6866 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
6867 ind - func_ind;
6868 if (do_debug) {
6869 put_stabn(N_FUN, 0, 0, ind - func_ind);
6871 funcname = ""; /* for safety */
6872 func_vt = VT_VOID; /* for safety */
6873 ind = 0; /* for safety */
6875 #ifdef CONFIG_REG_VARS
6876 tok_str_free(func_str.str);
6877 restore_parse_state(&saved_parse_state);
6878 #endif
6879 break;
6880 } else {
6881 if (b & VT_TYPEDEF) {
6882 /* save typedefed type */
6883 /* XXX: test storage specifiers ? */
6884 sym_push(v, t | VT_TYPEDEF, 0, 0);
6885 } else if ((t & VT_BTYPE) == VT_FUNC) {
6886 /* external function definition */
6887 external_sym(v, t, 0);
6888 } else {
6889 /* not lvalue if array */
6890 r = 0;
6891 if (!(t & VT_ARRAY))
6892 r |= lvalue_type(t);
6893 if (b & VT_EXTERN) {
6894 /* external variable */
6895 external_sym(v, t, r);
6896 } else {
6897 if (t & VT_STATIC)
6898 r |= VT_CONST;
6899 else
6900 r |= l;
6901 has_init = (tok == '=');
6902 if (has_init)
6903 next();
6904 decl_initializer_alloc(t, &ad, r,
6905 has_init, v, l);
6908 if (tok != ',') {
6909 skip(';');
6910 break;
6912 next();
6918 /* free define stack until top reaches 'b' */
6919 static void free_defines(Sym *b)
6921 Sym *top, *top1;
6923 top = define_stack.top;
6924 while (top != b) {
6925 top1 = top->prev;
6926 /* do not free args or predefined defines */
6927 if (top->c)
6928 tok_str_free((int *)top->c);
6929 sym_pop(&define_stack, top1);
6930 top = top1;
6934 /* compile the C file opened in 'file'. Return non zero if errors. */
6935 static int tcc_compile(TCCState *s1)
6937 Sym *define_start, *sym;
6938 char buf[512];
6939 volatile int section_sym;
6940 int p;
6942 #ifdef INC_DEBUG
6943 printf("%s: **** new file\n", file->filename);
6944 #endif
6945 funcname = "";
6946 s1->include_stack_ptr = s1->include_stack;
6947 /* XXX: move that before to avoid having to initialize
6948 file->ifdef_stack_ptr ? */
6949 s1->ifdef_stack_ptr = s1->ifdef_stack;
6950 file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
6952 /* XXX: not ANSI compliant: bound checking says error */
6953 vtop = vstack - 1;
6954 anon_sym = SYM_FIRST_ANOM;
6956 /* file info: full path + filename */
6957 section_sym = 0; /* avoid warning */
6958 if (do_debug) {
6959 section_sym = put_elf_sym(symtab_section, 0, 0,
6960 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
6961 text_section->sh_num, NULL);
6962 getcwd(buf, sizeof(buf));
6963 pstrcat(buf, sizeof(buf), "/");
6964 put_stabs_r(buf, N_SO, 0, 0,
6965 text_section->data_offset, text_section, section_sym);
6966 put_stabs_r(file->filename, N_SO, 0, 0,
6967 text_section->data_offset, text_section, section_sym);
6969 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6970 symbols can be safely used */
6971 put_elf_sym(symtab_section, 0, 0,
6972 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
6973 SHN_ABS, file->filename);
6975 /* define common 'char *' type because it is often used internally
6976 for arrays and struct dereference */
6977 char_pointer_type = mk_pointer(VT_BYTE);
6978 /* define an old type function 'int func()' */
6979 p = anon_sym++;
6980 sym = sym_push(p, 0, FUNC_CDECL, FUNC_OLD);
6981 func_old_type = VT_FUNC | (p << VT_STRUCT_SHIFT);
6982 #if 0
6983 /* define 'void *alloca(unsigned int)' builtin function */
6985 Sym *s1;
6987 p = anon_sym++;
6988 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
6989 s1 = sym_push(0, VT_UNSIGNED | VT_INT, 0, 0);
6990 s1->next = NULL;
6991 sym->next = s1;
6992 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
6994 #endif
6996 define_start = define_stack.top;
6998 if (setjmp(s1->error_jmp_buf) == 0) {
6999 s1->nb_errors = 0;
7000 s1->error_set_jmp_enabled = 1;
7002 inp();
7003 ch = '\n'; /* needed to parse correctly first preprocessor command */
7004 next();
7005 decl(VT_CONST);
7006 if (tok != -1)
7007 expect("declaration");
7009 /* end of translation unit info */
7010 if (do_debug) {
7011 put_stabs_r(NULL, N_SO, 0, 0,
7012 text_section->data_offset, text_section, section_sym);
7015 s1->error_set_jmp_enabled = 0;
7017 /* reset define stack, but leave -Dsymbols (may be incorrect if
7018 they are undefined) */
7019 free_defines(define_start);
7021 sym_pop(&global_stack, NULL);
7023 return s1->nb_errors != 0 ? -1 : 0;
7026 int tcc_compile_string(TCCState *s, const char *str)
7028 BufferedFile bf1, *bf = &bf1;
7029 int ret;
7031 /* init file structure */
7032 bf->fd = -1;
7033 bf->buf_ptr = (char *)str;
7034 bf->buf_end = (char *)str + strlen(bf->buffer);
7035 pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
7036 bf->line_num = 1;
7037 file = bf;
7039 ret = tcc_compile(s);
7041 /* currently, no need to close */
7042 return ret;
7045 /* define a symbol. A value can also be provided with the '=' operator */
7046 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
7048 BufferedFile bf1, *bf = &bf1;
7050 pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
7051 pstrcat(bf->buffer, IO_BUF_SIZE, " ");
7052 /* default value */
7053 if (!value)
7054 value = "1";
7055 pstrcat(bf->buffer, IO_BUF_SIZE, value);
7057 /* init file structure */
7058 bf->fd = -1;
7059 bf->buf_ptr = bf->buffer;
7060 bf->buf_end = bf->buffer + strlen(bf->buffer);
7061 bf->filename[0] = '\0';
7062 bf->line_num = 1;
7063 file = bf;
7065 s1->include_stack_ptr = s1->include_stack;
7067 /* parse with define parser */
7068 inp();
7069 ch = '\n'; /* needed to parse correctly first preprocessor command */
7070 next_nomacro();
7071 parse_define();
7072 file = NULL;
7075 void tcc_undefine_symbol(TCCState *s1, const char *sym)
7077 TokenSym *ts;
7078 Sym *s;
7079 ts = tok_alloc(sym, strlen(sym));
7080 s = sym_find1(&define_stack, tok);
7081 /* undefine symbol by putting an invalid name */
7082 if (s)
7083 sym_undef(&define_stack, s);
7086 #include "tccelf.c"
7088 /* print the position in the source file of PC value 'pc' by reading
7089 the stabs debug information */
7090 static void rt_printline(unsigned long wanted_pc)
7092 Stab_Sym *sym, *sym_end;
7093 char func_name[128], last_func_name[128];
7094 unsigned long func_addr, last_pc, pc;
7095 const char *incl_files[INCLUDE_STACK_SIZE];
7096 int incl_index, len, last_line_num, i;
7097 const char *str, *p;
7099 func_name[0] = '\0';
7100 func_addr = 0;
7101 incl_index = 0;
7102 last_func_name[0] = '\0';
7103 last_pc = 0xffffffff;
7104 last_line_num = 1;
7105 sym = (Stab_Sym *)stab_section->data + 1;
7106 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
7107 while (sym < sym_end) {
7108 switch(sym->n_type) {
7109 /* function start or end */
7110 case N_FUN:
7111 if (sym->n_strx == 0) {
7112 func_name[0] = '\0';
7113 func_addr = 0;
7114 } else {
7115 str = stabstr_section->data + sym->n_strx;
7116 p = strchr(str, ':');
7117 if (!p) {
7118 pstrcpy(func_name, sizeof(func_name), str);
7119 } else {
7120 len = p - str;
7121 if (len > sizeof(func_name) - 1)
7122 len = sizeof(func_name) - 1;
7123 memcpy(func_name, str, len);
7124 func_name[len] = '\0';
7126 func_addr = sym->n_value;
7128 break;
7129 /* line number info */
7130 case N_SLINE:
7131 pc = sym->n_value + func_addr;
7132 if (wanted_pc >= last_pc && wanted_pc < pc)
7133 goto found;
7134 last_pc = pc;
7135 last_line_num = sym->n_desc;
7136 /* XXX: slow! */
7137 strcpy(last_func_name, func_name);
7138 break;
7139 /* include files */
7140 case N_BINCL:
7141 str = stabstr_section->data + sym->n_strx;
7142 add_incl:
7143 if (incl_index < INCLUDE_STACK_SIZE) {
7144 incl_files[incl_index++] = str;
7146 break;
7147 case N_EINCL:
7148 if (incl_index > 1)
7149 incl_index--;
7150 break;
7151 case N_SO:
7152 if (sym->n_strx == 0) {
7153 incl_index = 0; /* end of translation unit */
7154 } else {
7155 str = stabstr_section->data + sym->n_strx;
7156 /* do not add path */
7157 len = strlen(str);
7158 if (len > 0 && str[len - 1] != '/')
7159 goto add_incl;
7161 break;
7163 sym++;
7165 /* did not find line number info: */
7166 fprintf(stderr, "(no debug info, pc=0x%08lx): ", wanted_pc);
7167 return;
7168 found:
7169 for(i = 0; i < incl_index - 1; i++)
7170 fprintf(stderr, "In file included from %s\n",
7171 incl_files[i]);
7172 if (incl_index > 0) {
7173 fprintf(stderr, "%s:%d: ",
7174 incl_files[incl_index - 1], last_line_num);
7176 if (last_func_name[0] != '\0') {
7177 fprintf(stderr, "in function '%s()': ", last_func_name);
7181 /* emit a run time error at position 'pc' */
7182 void rt_error(unsigned long pc, const char *fmt, ...)
7184 va_list ap;
7185 va_start(ap, fmt);
7187 rt_printline(pc);
7188 vfprintf(stderr, fmt, ap);
7189 fprintf(stderr, "\n");
7190 exit(255);
7191 va_end(ap);
7194 #ifndef WIN32
7195 /* signal handler for fatal errors */
7196 static void sig_error(int signum, siginfo_t *siginf, void *puc)
7198 struct ucontext *uc = puc;
7199 unsigned long pc;
7201 #ifdef __i386__
7202 pc = uc->uc_mcontext.gregs[14];
7203 #else
7204 #error please put the right sigcontext field
7205 #endif
7207 switch(signum) {
7208 case SIGFPE:
7209 switch(siginf->si_code) {
7210 case FPE_INTDIV:
7211 case FPE_FLTDIV:
7212 rt_error(pc, "division by zero");
7213 break;
7214 default:
7215 rt_error(pc, "floating point exception");
7216 break;
7218 break;
7219 case SIGBUS:
7220 case SIGSEGV:
7221 rt_error(pc, "dereferencing invalid pointer");
7222 break;
7223 case SIGILL:
7224 rt_error(pc, "illegal instruction");
7225 break;
7226 case SIGABRT:
7227 rt_error(pc, "abort() called");
7228 break;
7229 default:
7230 rt_error(pc, "caught signal %d", signum);
7231 break;
7233 exit(255);
7235 #endif
7237 /* do all relocations (needed before using tcc_get_symbol()) */
7238 int tcc_relocate(TCCState *s1)
7240 Section *s;
7241 int i;
7243 s1->nb_errors = 0;
7245 tcc_add_runtime(s1);
7247 relocate_common_syms();
7249 /* compute relocation address : section are relocated in place. We
7250 also alloc the bss space */
7251 for(i = 1; i < s1->nb_sections; i++) {
7252 s = s1->sections[i];
7253 if (s->sh_flags & SHF_ALLOC) {
7254 if (s->sh_type == SHT_NOBITS)
7255 s->data = tcc_mallocz(s->data_offset);
7256 s->sh_addr = (unsigned long)s->data;
7260 relocate_syms(s1, 1);
7262 if (s1->nb_errors != 0)
7263 return -1;
7265 /* relocate each section */
7266 for(i = 1; i < s1->nb_sections; i++) {
7267 s = s1->sections[i];
7268 if (s->reloc)
7269 relocate_section(s1, s);
7271 return 0;
7274 /* launch the compiled program with the given arguments */
7275 int tcc_run(TCCState *s1, int argc, char **argv)
7277 int (*prog_main)(int, char **);
7279 if (tcc_relocate(s1) < 0)
7280 return -1;
7282 prog_main = tcc_get_symbol(s1, "main");
7284 if (do_debug) {
7285 #ifdef WIN32
7286 error("debug mode currently not available for Windows");
7287 #else
7288 struct sigaction sigact;
7289 /* install TCC signal handlers to print debug info on fatal
7290 runtime errors */
7291 sigact.sa_flags = SA_SIGINFO | SA_ONESHOT;
7292 sigact.sa_sigaction = sig_error;
7293 sigemptyset(&sigact.sa_mask);
7294 sigaction(SIGFPE, &sigact, NULL);
7295 sigaction(SIGILL, &sigact, NULL);
7296 sigaction(SIGSEGV, &sigact, NULL);
7297 sigaction(SIGBUS, &sigact, NULL);
7298 sigaction(SIGABRT, &sigact, NULL);
7299 #endif
7302 #ifdef CONFIG_TCC_BCHECK
7303 if (do_bounds_check) {
7304 void (*bound_init)(void);
7305 void **bound_error_func;
7307 /* set error function */
7308 bound_error_func = (void **)tcc_get_symbol(s1, "__bound_error_func");
7309 *bound_error_func = rt_error;
7311 /* XXX: use .init section so that it also work in binary ? */
7312 bound_init = (void *)tcc_get_symbol(s1, "__bound_init");
7313 bound_init();
7315 #endif
7316 return (*prog_main)(argc, argv);
7319 TCCState *tcc_new(void)
7321 char *p, *r;
7322 TCCState *s;
7324 s = tcc_mallocz(sizeof(TCCState));
7325 if (!s)
7326 return NULL;
7327 tcc_state = s;
7328 s->output_type = TCC_OUTPUT_MEMORY;
7330 /* default include paths */
7331 tcc_add_sysinclude_path(s, "/usr/local/include");
7332 tcc_add_sysinclude_path(s, "/usr/include");
7333 tcc_add_sysinclude_path(s, CONFIG_TCC_PREFIX "/lib/tcc/include");
7335 /* add all tokens */
7336 table_ident = NULL;
7337 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
7339 tok_ident = TOK_IDENT;
7340 p = tcc_keywords;
7341 while (*p) {
7342 r = p;
7343 while (*r++);
7344 tok_alloc(p, r - p - 1);
7345 p = r;
7348 /* we add dummy defines for some special macros to speed up tests
7349 and to have working defined() */
7350 sym_push1(&define_stack, TOK___LINE__, MACRO_OBJ, 0);
7351 sym_push1(&define_stack, TOK___FILE__, MACRO_OBJ, 0);
7352 sym_push1(&define_stack, TOK___DATE__, MACRO_OBJ, 0);
7353 sym_push1(&define_stack, TOK___TIME__, MACRO_OBJ, 0);
7355 /* standard defines */
7356 tcc_define_symbol(s, "__STDC__", NULL);
7357 #if defined(TCC_TARGET_I386)
7358 tcc_define_symbol(s, "__i386__", NULL);
7359 #endif
7360 #if defined(linux)
7361 tcc_define_symbol(s, "linux", NULL);
7362 #endif
7363 /* tiny C specific defines */
7364 tcc_define_symbol(s, "__TINYC__", NULL);
7366 /* default library paths */
7367 tcc_add_library_path(s, "/usr/local/lib");
7368 tcc_add_library_path(s, "/usr/lib");
7369 tcc_add_library_path(s, "/lib");
7371 /* no section zero */
7372 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
7374 /* create standard sections */
7375 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
7376 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
7377 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
7379 /* symbols are always generated for linking stage */
7380 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
7381 ".strtab",
7382 ".hashtab", SHF_PRIVATE);
7383 strtab_section = symtab_section->link;
7385 /* private symbol table for dynamic symbols */
7386 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
7387 ".dynstrtab",
7388 ".dynhashtab", SHF_PRIVATE);
7389 return s;
7392 void tcc_delete(TCCState *s1)
7394 int i, n;
7396 /* free -D defines */
7397 free_defines(NULL);
7399 /* free tokens */
7400 n = tok_ident - TOK_IDENT;
7401 for(i = 0; i < n; i++)
7402 tcc_free(table_ident[i]);
7403 tcc_free(table_ident);
7405 /* free all sections */
7407 free_section(symtab_section->hash);
7409 free_section(s1->dynsymtab_section->hash);
7410 free_section(s1->dynsymtab_section->link);
7411 free_section(s1->dynsymtab_section);
7413 for(i = 1; i < s1->nb_sections; i++)
7414 free_section(s1->sections[i]);
7415 tcc_free(s1->sections);
7417 /* free loaded dlls array */
7418 for(i = 0; i < s1->nb_loaded_dlls; i++)
7419 tcc_free(s1->loaded_dlls[i]);
7420 tcc_free(s1->loaded_dlls);
7422 /* library paths */
7423 for(i = 0; i < s1->nb_library_paths; i++)
7424 tcc_free(s1->library_paths[i]);
7425 tcc_free(s1->library_paths);
7427 /* cached includes */
7428 for(i = 0; i < s1->nb_cached_includes; i++)
7429 tcc_free(s1->cached_includes[i]);
7430 tcc_free(s1->cached_includes);
7432 for(i = 0; i < s1->nb_include_paths; i++)
7433 tcc_free(s1->include_paths[i]);
7434 tcc_free(s1->include_paths);
7436 for(i = 0; i < s1->nb_sysinclude_paths; i++)
7437 tcc_free(s1->sysinclude_paths[i]);
7438 tcc_free(s1->sysinclude_paths);
7440 tcc_free(s1);
7443 int tcc_add_include_path(TCCState *s1, const char *pathname)
7445 char *pathname1;
7447 pathname1 = tcc_strdup(pathname);
7448 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
7449 return 0;
7452 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
7454 char *pathname1;
7456 pathname1 = tcc_strdup(pathname);
7457 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
7458 return 0;
7461 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
7463 const char *ext;
7464 Elf32_Ehdr ehdr;
7465 int fd, ret;
7466 BufferedFile *saved_file;
7468 /* find source file type with extension */
7469 ext = strrchr(filename, '.');
7470 if (ext)
7471 ext++;
7473 /* open the file */
7474 saved_file = file;
7475 file = tcc_open(s1, filename);
7476 if (!file) {
7477 if (flags & AFF_PRINT_ERROR) {
7478 error_noabort("file '%s' not found", filename);
7480 ret = -1;
7481 goto fail1;
7484 if (!ext || !strcmp(ext, "c")) {
7485 /* C file assumed */
7486 ret = tcc_compile(s1);
7487 } else {
7488 fd = file->fd;
7489 /* assume executable format: auto guess file type */
7490 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
7491 error_noabort("could not read header");
7492 goto fail;
7494 lseek(fd, 0, SEEK_SET);
7496 if (ehdr.e_ident[0] == ELFMAG0 &&
7497 ehdr.e_ident[1] == ELFMAG1 &&
7498 ehdr.e_ident[2] == ELFMAG2 &&
7499 ehdr.e_ident[3] == ELFMAG3) {
7500 file->line_num = 0; /* do not display line number if error */
7501 if (ehdr.e_type == ET_REL) {
7502 ret = tcc_load_object_file(s1, fd, 0);
7503 } else if (ehdr.e_type == ET_DYN) {
7504 ret = tcc_load_dll(s1, fd, filename,
7505 (flags & AFF_REFERENCED_DLL) != 0);
7506 } else {
7507 error_noabort("unrecognized ELF file");
7508 goto fail;
7510 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
7511 file->line_num = 0; /* do not display line number if error */
7512 ret = tcc_load_archive(s1, fd);
7513 } else {
7514 /* as GNU ld, consider it is an ld script if not recognized */
7515 ret = tcc_load_ldscript(s1);
7516 if (ret < 0) {
7517 error_noabort("unrecognized file type");
7518 goto fail;
7522 the_end:
7523 tcc_close(file);
7524 fail1:
7525 file = saved_file;
7526 return ret;
7527 fail:
7528 ret = -1;
7529 goto the_end;
7532 int tcc_add_file(TCCState *s, const char *filename)
7534 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
7537 int tcc_add_library_path(TCCState *s, const char *pathname)
7539 char *pathname1;
7541 pathname1 = tcc_strdup(pathname);
7542 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
7543 return 0;
7546 /* find and load a dll. Return non zero if not found */
7547 /* XXX: add '-rpath' option support ? */
7548 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
7550 char buf[1024];
7551 int i;
7553 for(i = 0; i < s->nb_library_paths; i++) {
7554 snprintf(buf, sizeof(buf), "%s/%s",
7555 s->library_paths[i], filename);
7556 if (tcc_add_file_internal(s, buf, flags) == 0)
7557 return 0;
7559 return -1;
7562 /* the library name is the same as the argument of the '-l' option */
7563 int tcc_add_library(TCCState *s, const char *libraryname)
7565 char buf[1024];
7566 int i;
7567 void *h;
7569 /* first we look for the dynamic library if not static linking */
7570 if (!s->static_link) {
7571 snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
7572 /* if we output to memory, then we simply we dlopen(). */
7573 if (s->output_type == TCC_OUTPUT_MEMORY) {
7574 /* Since the libc is already loaded, we don't need to load it again */
7575 if (!strcmp(libraryname, "c"))
7576 return 0;
7577 h = dlopen(buf, RTLD_GLOBAL | RTLD_LAZY);
7578 if (h)
7579 return 0;
7580 } else {
7581 if (tcc_add_dll(s, buf, 0) == 0)
7582 return 0;
7586 /* then we look for the static library */
7587 for(i = 0; i < s->nb_library_paths; i++) {
7588 snprintf(buf, sizeof(buf), "%s/lib%s.a",
7589 s->library_paths[i], libraryname);
7590 if (tcc_add_file_internal(s, buf, 0) == 0)
7591 return 0;
7593 return -1;
7596 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
7598 add_elf_sym(symtab_section, val, 0,
7599 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
7600 SHN_ABS, name);
7601 return 0;
7604 int tcc_set_output_type(TCCState *s, int output_type)
7606 s->output_type = output_type;
7608 /* if bound checking, then add corresponding sections */
7609 #ifdef CONFIG_TCC_BCHECK
7610 if (do_bounds_check) {
7611 /* define symbol */
7612 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
7613 /* create bounds sections */
7614 bounds_section = new_section(s, ".bounds",
7615 SHT_PROGBITS, SHF_ALLOC);
7616 lbounds_section = new_section(s, ".lbounds",
7617 SHT_PROGBITS, SHF_ALLOC);
7619 #endif
7621 /* add debug sections */
7622 if (do_debug) {
7623 /* stab symbols */
7624 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
7625 stab_section->sh_entsize = sizeof(Stab_Sym);
7626 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
7627 put_elf_str(stabstr_section, "");
7628 stab_section->link = stabstr_section;
7629 /* put first entry */
7630 put_stabs("", 0, 0, 0, 0);
7633 /* add libc crt1/crti objects */
7634 if (output_type == TCC_OUTPUT_EXE ||
7635 output_type == TCC_OUTPUT_DLL) {
7636 if (output_type != TCC_OUTPUT_DLL)
7637 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
7638 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
7640 return 0;
7643 #if !defined(LIBTCC)
7645 void help(void)
7647 printf("tcc version 0.9.12 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7648 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7649 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
7650 " [--] infile1 [infile2... --] [infile_args...]\n"
7651 "\n"
7652 "General options:\n"
7653 " -c compile only - generate an object file\n"
7654 " -o outfile set output filename\n"
7655 " -- allows multiples input files if no -o option given. Also\n"
7656 " separate input files from runtime arguments\n"
7657 " -Bdir set tcc internal library path\n"
7658 " -bench output compilation statistics\n"
7659 "Preprocessor options:\n"
7660 " -Idir add include path 'dir'\n"
7661 " -Dsym[=val] define 'sym' with value 'val'\n"
7662 " -Usym undefine 'sym'\n"
7663 "C compiler options:\n"
7664 " -g generate runtime debug info\n"
7665 #ifdef CONFIG_TCC_BCHECK
7666 " -b compile with built-in memory and bounds checker (implies -g)\n"
7667 #endif
7668 "Linker options:\n"
7669 " -Ldir add library path 'dir'\n"
7670 " -llib link with dynamic or static library 'lib'\n"
7671 " -shared generate a shared library\n"
7672 " -static static linking\n"
7673 " -r relocatable output\n"
7677 int main(int argc, char **argv)
7679 char *r, *outfile;
7680 int optind, output_type, multiple_files, i, reloc_output;
7681 TCCState *s;
7682 char **files;
7683 int nb_files, nb_libraries, nb_objfiles, dminus, ret;
7684 char objfilename[1024];
7686 s = tcc_new();
7687 output_type = TCC_OUTPUT_MEMORY;
7689 optind = 1;
7690 outfile = NULL;
7691 multiple_files = 0;
7692 dminus = 0;
7693 files = NULL;
7694 nb_files = 0;
7695 nb_libraries = 0;
7696 reloc_output = 0;
7697 while (1) {
7698 if (optind >= argc) {
7699 if (nb_files == 0)
7700 goto show_help;
7701 else
7702 break;
7704 r = argv[optind++];
7705 if (r[0] != '-') {
7706 /* add a new file */
7707 dynarray_add((void ***)&files, &nb_files, r);
7708 if (!multiple_files) {
7709 optind--;
7710 /* argv[0] will be this file */
7711 break;
7713 } else if (r[1] == '-') {
7714 /* '--' enables multiple files input and also ends several file input */
7715 if (dminus && multiple_files) {
7716 optind--; /* argv[0] will be '--' */
7717 break;
7719 dminus = 1;
7720 multiple_files = 1;
7721 } else if (r[1] == 'h' || r[1] == '?') {
7722 show_help:
7723 help();
7724 return 1;
7725 } else if (r[1] == 'I') {
7726 if (tcc_add_include_path(s, r + 2) < 0)
7727 error("too many include paths");
7728 } else if (r[1] == 'D') {
7729 char *sym, *value;
7730 sym = r + 2;
7731 value = strchr(sym, '=');
7732 if (value) {
7733 *value = '\0';
7734 value++;
7736 tcc_define_symbol(s, sym, value);
7737 } else if (r[1] == 'U') {
7738 tcc_undefine_symbol(s, r + 2);
7739 } else if (r[1] == 'L') {
7740 tcc_add_library_path(s, r + 2);
7741 } else if (r[1] == 'B') {
7742 /* set tcc utilities path (mainly for tcc development) */
7743 tcc_lib_path = r + 2;
7744 } else if (r[1] == 'l') {
7745 dynarray_add((void ***)&files, &nb_files, r);
7746 nb_libraries++;
7747 } else if (!strcmp(r + 1, "bench")) {
7748 do_bench = 1;
7749 } else
7750 #ifdef CONFIG_TCC_BCHECK
7751 if (r[1] == 'b') {
7752 do_bounds_check = 1;
7753 do_debug = 1;
7754 } else
7755 #endif
7756 if (r[1] == 'g') {
7757 do_debug = 1;
7758 } else if (r[1] == 'c') {
7759 multiple_files = 1;
7760 output_type = TCC_OUTPUT_OBJ;
7761 } else if (!strcmp(r + 1, "static")) {
7762 s->static_link = 1;
7763 } else if (!strcmp(r + 1, "shared")) {
7764 output_type = TCC_OUTPUT_DLL;
7765 } else if (r[1] == 'o') {
7766 if (optind >= argc)
7767 goto show_help;
7768 multiple_files = 1;
7769 outfile = argv[optind++];
7770 } else if (r[1] == 'r') {
7771 /* generate a .o merging several output files */
7772 reloc_output = 1;
7773 output_type = TCC_OUTPUT_OBJ;
7774 } else if (r[1] == 'W' || r[1] == 'O' || r[1] == 'm' || r[1] == 'f') {
7775 /* ignore those options to be a drop-in replacement for gcc */
7776 } else {
7777 error("invalid option -- '%s'", r);
7781 nb_objfiles = nb_files - nb_libraries;
7783 /* if outfile provided without other options, we output an
7784 executable */
7785 if (outfile && output_type == TCC_OUTPUT_MEMORY)
7786 output_type = TCC_OUTPUT_EXE;
7788 /* check -c consistency : only single file handled. XXX: checks file type */
7789 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
7790 /* accepts only a single input file */
7791 if (nb_objfiles != 1)
7792 error("cannot specify multiple files with -c");
7793 if (nb_libraries != 0)
7794 error("cannot specify libraries with -c");
7797 /* compute default outfile name */
7798 if (output_type != TCC_OUTPUT_MEMORY && !outfile) {
7799 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
7800 char *ext;
7801 /* add .o extension */
7802 pstrcpy(objfilename, sizeof(objfilename) - 1, files[0]);
7803 ext = strrchr(objfilename, '.');
7804 if (!ext)
7805 goto default_outfile;
7806 strcpy(ext + 1, "o");
7807 } else {
7808 default_outfile:
7809 pstrcpy(objfilename, sizeof(objfilename), "a.out");
7811 outfile = objfilename;
7814 tcc_set_output_type(s, output_type);
7816 /* compile or add each files or library */
7817 for(i = 0;i < nb_files; i++) {
7818 const char *filename;
7820 filename = files[i];
7821 if (filename[0] == '-') {
7822 if (tcc_add_library(s, filename + 2) < 0)
7823 error("cannot find %s", filename);
7824 } else {
7825 if (tcc_add_file(s, filename) < 0) {
7826 ret = 1;
7827 goto the_end;
7832 /* free all files */
7833 tcc_free(files);
7835 if (do_bench) {
7836 printf("total: %d idents, %d lines, %d bytes\n",
7837 tok_ident - TOK_IDENT, total_lines, total_bytes);
7840 if (s->output_type != TCC_OUTPUT_MEMORY) {
7841 tcc_output_file(s, outfile);
7842 ret = 0;
7843 } else {
7844 ret = tcc_run(s, argc - optind, argv + optind);
7846 the_end:
7847 tcc_delete(s);
7849 #ifdef MEM_DEBUG
7850 if (do_bench) {
7851 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
7853 #endif
7854 return ret;
7857 #endif