2 * TCC - Tiny C Compiler
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.
33 #include <sys/timeb.h>
37 #include <sys/ucontext.h>
41 #ifndef CONFIG_TCC_STATIC
49 /* preprocessor debug */
51 /* include file debug */
56 /* target selection */
57 //#define TCC_TARGET_I386 /* i386 code generator */
58 //#define TCC_TARGET_IL /* .NET CLI generator */
60 /* default target is I386 */
61 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
62 #define TCC_TARGET_I386
65 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
66 #define CONFIG_TCC_BCHECK /* enable bound checking code */
69 #ifndef CONFIG_TCC_PREFIX
70 #define CONFIG_TCC_PREFIX "/usr/local"
73 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
74 executables or dlls */
75 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
77 #define INCLUDE_STACK_SIZE 32
78 #define IFDEF_STACK_SIZE 64
79 #define VSTACK_SIZE 64
80 #define STRING_MAX_SIZE 1024
82 #define TOK_HASH_SIZE 2048 /* must be a power of two */
83 #define TOK_ALLOC_INCR 512 /* must be a power of two */
84 #define TOK_STR_ALLOC_INCR_BITS 6
85 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
86 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
88 /* token symbol management */
89 typedef struct TokenSym
{
90 struct TokenSym
*hash_next
;
91 struct Sym
*sym_define
; /* direct pointer to define */
92 struct Sym
*sym_label
; /* direct pointer to label */
93 struct Sym
*sym_struct
; /* direct pointer to structure */
94 struct Sym
*sym_identifier
; /* direct pointer to identifier */
95 int tok
; /* token number */
100 typedef struct CString
{
101 int size
; /* size in bytes */
102 void *data
; /* either 'char *' or 'int *' */
104 void *data_allocated
; /* if non NULL, data has been malloced */
107 /* type definition */
108 typedef struct CType
{
114 typedef union CValue
{
120 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
122 unsigned long long ull
;
123 struct CString
*cstr
;
129 typedef struct SValue
{
130 CType type
; /* type */
131 unsigned short r
; /* register + flags */
132 unsigned short r2
; /* second register, used for 'long long'
133 type. If not used, set to VT_CONST */
134 CValue c
; /* constant, if VT_CONST */
135 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
138 /* symbol management */
140 int v
; /* symbol token */
141 int r
; /* associated register */
142 int c
; /* associated number */
143 CType type
; /* associated type */
144 struct Sym
*next
; /* next related symbol */
145 struct Sym
*prev
; /* prev symbol in stack */
146 struct Sym
*prev_tok
; /* previous symbol for this token */
149 /* section definition */
150 /* XXX: use directly ELF structure for parameters ? */
151 /* special flag to indicate that the section should not be linked to
153 #define SHF_PRIVATE 0x80000000
155 typedef struct Section
{
156 unsigned long data_offset
; /* current data offset */
157 unsigned char *data
; /* section data */
158 unsigned long data_allocated
; /* used for realloc() handling */
159 int sh_name
; /* elf section name (only used during output) */
160 int sh_num
; /* elf section number */
161 int sh_type
; /* elf section type */
162 int sh_flags
; /* elf section flags */
163 int sh_info
; /* elf section info */
164 int sh_addralign
; /* elf section alignment */
165 int sh_entsize
; /* elf entry size */
166 unsigned long sh_size
; /* section size (only used during output) */
167 unsigned long sh_addr
; /* address at which the section is relocated */
168 unsigned long sh_offset
; /* address at which the section is relocated */
169 int nb_hashed_syms
; /* used to resize the hash table */
170 struct Section
*link
; /* link to another section */
171 struct Section
*reloc
; /* corresponding section for relocation, if any */
172 struct Section
*hash
; /* hash table for symbols */
173 struct Section
*next
;
174 char name
[64]; /* section name */
177 typedef struct DLLReference
{
182 /* GNUC attribute definition */
183 typedef struct AttributeDef
{
186 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
189 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
190 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
191 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
193 /* stored in 'Sym.c' field */
194 #define FUNC_NEW 1 /* ansi function prototype */
195 #define FUNC_OLD 2 /* old function prototype */
196 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
198 /* stored in 'Sym.r' field */
199 #define FUNC_CDECL 0 /* standard c call */
200 #define FUNC_STDCALL 1 /* pascal c call */
202 /* field 'Sym.t' for macros */
203 #define MACRO_OBJ 0 /* object like macro */
204 #define MACRO_FUNC 1 /* function like macro */
206 /* field 'Sym.r' for labels */
207 #define LABEL_FORWARD 1 /* label is forward defined */
209 /* type_decl() types */
210 #define TYPE_ABSTRACT 1 /* type without variable */
211 #define TYPE_DIRECT 2 /* type with variable */
213 #define IO_BUF_SIZE 8192
215 typedef struct BufferedFile
{
219 int line_num
; /* current line number - here to simply code */
220 int ifndef_macro
; /* #ifndef macro / #endif search */
221 int ifndef_macro_saved
; /* saved ifndef_macro */
222 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
223 char inc_type
; /* type of include */
224 char inc_filename
[512]; /* filename specified by the user */
225 char filename
[1024]; /* current filename - here to simplify code */
226 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
229 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
230 #define CH_EOF (-1) /* end of file */
232 /* parsing state (used to save parser state to reparse part of the
233 source several times) */
234 typedef struct ParseState
{
241 /* used to record tokens */
242 typedef struct TokenString
{
249 /* include file cache, used to find files faster and also to eliminate
250 inclusion if the include file is protected by #ifndef ... #endif */
251 typedef struct CachedInclude
{
253 char type
; /* '"' or '>' to give include type */
254 char filename
[1]; /* path specified in #include */
258 static struct BufferedFile
*file
;
259 static int ch
, tok
, tok1
;
260 static CValue tokc
, tok1c
;
261 static CString tokcstr
; /* current parsed string, if any */
262 /* additionnal informations about token */
263 static int tok_flags
;
264 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
265 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
266 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
268 /* if true, line feed is returned as a token. line feed is also
270 static int return_linefeed
;
271 static Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
272 static Section
*cur_text_section
; /* current section where function code is
274 /* bound check related sections */
275 static Section
*bounds_section
; /* contains global data bound description */
276 static Section
*lbounds_section
; /* contains local data bound description */
277 /* symbol sections */
278 static Section
*symtab_section
, *strtab_section
;
281 static Section
*stab_section
, *stabstr_section
;
283 /* loc : local variable index
284 ind : output code index
286 anon_sym: anonymous symbol index
288 static int rsym
, anon_sym
, ind
, loc
;
289 /* expression generation modifiers */
290 static int const_wanted
; /* true if constant wanted */
291 static int nocode_wanted
; /* true if no code generation wanted for an expression */
292 static int global_expr
; /* true if compound literals must be allocated
293 globally (used during initializers parsing */
294 static CType func_vt
; /* current function return type (used by return
297 static int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
298 static int tok_ident
;
299 static TokenSym
**table_ident
;
300 static TokenSym
*hash_ident
[TOK_HASH_SIZE
];
301 static char token_buf
[STRING_MAX_SIZE
+ 1];
302 static char *funcname
;
303 static Sym
*global_stack
, *local_stack
;
304 static Sym
*define_stack
;
305 static Sym
*label_stack
;
307 static SValue vstack
[VSTACK_SIZE
], *vtop
;
308 static int *macro_ptr
, *macro_ptr_allocated
;
309 /* some predefined types */
310 static CType char_pointer_type
, func_old_type
, int_type
;
312 /* compile with debug symbol (and use them if error during execution) */
313 static int do_debug
= 0;
315 /* compile with built-in memory and bounds checker */
316 static int do_bounds_check
= 0;
318 /* display benchmark infos */
319 static int do_bench
= 0;
320 static int total_lines
;
321 static int total_bytes
;
323 /* use GNU C extensions */
324 static int gnu_ext
= 1;
326 /* use Tiny C extensions */
327 static int tcc_ext
= 1;
329 /* max number of callers shown if error */
330 static int num_callers
= 6;
331 static const char **rt_bound_error_msg
;
333 /* XXX: suppress that ASAP */
334 static struct TCCState
*tcc_state
;
336 /* give the path of the tcc libraries */
337 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
342 BufferedFile
**include_stack_ptr
;
343 int *ifdef_stack_ptr
;
345 /* include file handling */
346 char **include_paths
;
347 int nb_include_paths
;
348 char **sysinclude_paths
;
349 int nb_sysinclude_paths
;
350 CachedInclude
**cached_includes
;
351 int nb_cached_includes
;
353 char **library_paths
;
354 int nb_library_paths
;
356 /* array of all loaded dlls (including those referenced by loaded
358 DLLReference
**loaded_dlls
;
363 int nb_sections
; /* number of sections, including first dummy section */
367 unsigned long *got_offsets
;
370 /* give the correspondance from symtab indexes to dynsym indexes */
371 int *symtab_to_dynsym
;
373 /* temporary dynamic symbol sections (for dll loading) */
374 Section
*dynsymtab_section
;
375 /* exported dynamic symbol section */
378 /* if true, static linking is performed */
383 void (*error_func
)(void *opaque
, const char *msg
);
384 int error_set_jmp_enabled
;
385 jmp_buf error_jmp_buf
;
388 /* see include_stack_ptr */
389 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
391 /* see ifdef_stack_ptr */
392 int ifdef_stack
[IFDEF_STACK_SIZE
];
395 /* The current value can be: */
396 #define VT_VALMASK 0x00ff
397 #define VT_CONST 0x00f0 /* constant in vc
398 (must be first non register value) */
399 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
400 #define VT_LOCAL 0x00f2 /* offset on stack */
401 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
402 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
403 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
404 #define VT_LVAL 0x0100 /* var is an lvalue */
405 #define VT_SYM 0x0200 /* a symbol value is added */
406 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
407 char/short stored in integer registers) */
408 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
409 dereferencing value */
410 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
411 bounding function call point is in vc */
412 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
413 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
414 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
415 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
418 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
420 #define VT_INT 0 /* integer type */
421 #define VT_BYTE 1 /* signed byte type */
422 #define VT_SHORT 2 /* short type */
423 #define VT_VOID 3 /* void type */
424 #define VT_PTR 4 /* pointer */
425 #define VT_ENUM 5 /* enum definition */
426 #define VT_FUNC 6 /* function type */
427 #define VT_STRUCT 7 /* struct/union definition */
428 #define VT_FLOAT 8 /* IEEE float */
429 #define VT_DOUBLE 9 /* IEEE double */
430 #define VT_LDOUBLE 10 /* IEEE long double */
431 #define VT_BOOL 11 /* ISOC99 boolean type */
432 #define VT_LLONG 12 /* 64 bit integer */
433 #define VT_LONG 13 /* long integer (NEVER USED as type, only
435 #define VT_BTYPE 0x000f /* mask for basic type */
436 #define VT_UNSIGNED 0x0010 /* unsigned type */
437 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
438 #define VT_BITFIELD 0x0040 /* bitfield modifier */
441 #define VT_EXTERN 0x00000080 /* extern definition */
442 #define VT_STATIC 0x00000100 /* static variable */
443 #define VT_TYPEDEF 0x00000200 /* typedef definition */
445 /* type mask (except storage) */
446 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
450 /* warning: the following compare tokens depend on i386 asm code */
462 #define TOK_LAND 0xa0
466 #define TOK_MID 0xa3 /* inc/dec, to void constant */
468 #define TOK_UDIV 0xb0 /* unsigned division */
469 #define TOK_UMOD 0xb1 /* unsigned modulo */
470 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
471 #define TOK_CINT 0xb3 /* number in tokc */
472 #define TOK_CCHAR 0xb4 /* char constant in tokc */
473 #define TOK_STR 0xb5 /* pointer to string in tokc */
474 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
475 #define TOK_LCHAR 0xb7
476 #define TOK_LSTR 0xb8
477 #define TOK_CFLOAT 0xb9 /* float constant */
478 #define TOK_LINENUM 0xba /* line number info */
479 #define TOK_CDOUBLE 0xc0 /* double constant */
480 #define TOK_CLDOUBLE 0xc1 /* long double constant */
481 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
482 #define TOK_ADDC1 0xc3 /* add with carry generation */
483 #define TOK_ADDC2 0xc4 /* add with carry use */
484 #define TOK_SUBC1 0xc5 /* add with carry generation */
485 #define TOK_SUBC2 0xc6 /* add with carry use */
486 #define TOK_CUINT 0xc8 /* unsigned int constant */
487 #define TOK_CLLONG 0xc9 /* long long constant */
488 #define TOK_CULLONG 0xca /* unsigned long long constant */
489 #define TOK_ARROW 0xcb
490 #define TOK_DOTS 0xcc /* three dots */
491 #define TOK_SHR 0xcd /* unsigned shift right */
492 #define TOK_PPNUM 0xce /* preprocessor number */
494 #define TOK_SHL 0x01 /* shift left */
495 #define TOK_SAR 0x02 /* signed shift right */
497 /* assignement operators : normal operator or 0x80 */
498 #define TOK_A_MOD 0xa5
499 #define TOK_A_AND 0xa6
500 #define TOK_A_MUL 0xaa
501 #define TOK_A_ADD 0xab
502 #define TOK_A_SUB 0xad
503 #define TOK_A_DIV 0xaf
504 #define TOK_A_XOR 0xde
505 #define TOK_A_OR 0xfc
506 #define TOK_A_SHL 0x81
507 #define TOK_A_SAR 0x82
509 /* WARNING: the content of this string encodes token numbers */
510 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";
512 #define TOK_EOF (-1) /* end of file */
513 #define TOK_LINEFEED 10 /* line feed */
515 /* all identificators and strings have token above that */
516 #define TOK_IDENT 256
519 TOK_LAST
= TOK_IDENT
- 1,
520 #define DEF(id, str) id,
525 static const char *tcc_keywords
=
526 #define DEF(id, str) str "\0"
531 #define TOK_UIDENT TOK_DEFINE
534 #define snprintf _snprintf
535 #define vsnprintf _vsnprintf
538 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
539 /* currently incorrect */
540 long double strtold(const char *nptr
, char **endptr
)
542 return (long double)strtod(nptr
, endptr
);
544 float strtof(const char *nptr
, char **endptr
)
546 return (float)strtod(nptr
, endptr
);
549 /* XXX: need to define this to use them in non ISOC99 context */
550 extern float strtof (const char *__nptr
, char **__endptr
);
551 extern long double strtold (const char *__nptr
, char **__endptr
);
554 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
555 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
557 static void next(void);
558 static void next_nomacro(void);
559 static void parse_expr_type(CType
*type
);
560 static void expr_type(CType
*type
);
561 static void unary_type(CType
*type
);
562 static int expr_const(void);
563 static void expr_eq(void);
564 static void gexpr(void);
565 static void decl(int l
);
566 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
567 int first
, int size_only
);
568 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
569 int has_init
, int v
, int scope
);
571 void gv2(int rc1
, int rc2
);
572 void move_reg(int r
, int s
);
573 void save_regs(int n
);
574 void save_reg(int r
);
580 static void macro_subst(TokenString
*tok_str
,
581 Sym
**nested_list
, int *macro_str
);
582 int save_reg_forced(int r
);
584 void force_charshort_cast(int t
);
585 static void gen_cast(CType
*type
);
587 static Sym
*sym_find(int v
);
588 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
591 static int type_size(CType
*type
, int *a
);
592 static inline CType
*pointed_type(CType
*type
);
593 static int pointed_size(CType
*type
);
594 static int lvalue_type(int t
);
595 static int is_compatible_types(CType
*type1
, CType
*type2
);
596 static int parse_btype(CType
*type
, AttributeDef
*ad
);
597 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
599 void error(const char *fmt
, ...);
601 void vset(CType
*type
, int r
, int v
);
602 void type_to_str(char *buf
, int buf_size
,
603 CType
*type
, const char *varstr
);
604 char *get_tok_str(int v
, CValue
*cv
);
605 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
606 unsigned long offset
, unsigned long size
);
607 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
609 /* section generation */
610 static void section_realloc(Section
*sec
, unsigned long new_size
);
611 static void *section_ptr_add(Section
*sec
, unsigned long size
);
612 static void put_extern_sym(Sym
*sym
, Section
*section
,
613 unsigned long value
, unsigned long size
);
614 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
615 static int put_elf_str(Section
*s
, const char *sym
);
616 static int put_elf_sym(Section
*s
,
617 unsigned long value
, unsigned long size
,
618 int info
, int other
, int shndx
, const char *name
);
619 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
620 int info
, int sh_num
, const char *name
);
621 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
622 int type
, int symbol
);
623 static void put_stabs(const char *str
, int type
, int other
, int desc
,
624 unsigned long value
);
625 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
626 unsigned long value
, Section
*sec
, int sym_index
);
627 static void put_stabn(int type
, int other
, int desc
, int value
);
628 static void put_stabd(int type
, int other
, int desc
);
629 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
631 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
632 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
633 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
635 /* true if float/double/long double type */
636 static inline int is_float(int t
)
640 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
643 #ifdef TCC_TARGET_I386
644 #include "i386-gen.c"
650 #ifdef CONFIG_TCC_STATIC
652 #define RTLD_LAZY 0x001
653 #define RTLD_NOW 0x002
654 #define RTLD_GLOBAL 0x100
655 #define RTLD_DEFAULT NULL
657 /* dummy function for profiling */
658 void *dlopen(const char *filename
, int flag
)
663 const char *dlerror(void)
668 typedef struct TCCSyms
{
673 #define TCCSYM(a) { #a, &a, },
675 /* add the symbol you want here if no dynamic linking is done */
676 static TCCSyms tcc_syms
[] = {
684 void *dlsym(void *handle
, const char *symbol
)
688 while (p
->str
!= NULL
) {
689 if (!strcmp(p
->str
, symbol
))
698 /********************************************************/
700 /* we use our own 'finite' function to avoid potential problems with
701 non standard math libs */
702 /* XXX: endianness dependant */
703 int ieee_finite(double d
)
706 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
709 /* copy a string and truncate it. */
710 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
717 q_end
= buf
+ buf_size
- 1;
729 /* strcat and truncate. */
730 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
735 pstrcpy(buf
+ len
, buf_size
- len
, s
);
739 /* memory management */
745 static inline void tcc_free(void *ptr
)
748 mem_cur_size
-= malloc_usable_size(ptr
);
753 static void *tcc_malloc(unsigned long size
)
758 error("memory full");
760 mem_cur_size
+= malloc_usable_size(ptr
);
761 if (mem_cur_size
> mem_max_size
)
762 mem_max_size
= mem_cur_size
;
767 static void *tcc_mallocz(unsigned long size
)
770 ptr
= tcc_malloc(size
);
771 memset(ptr
, 0, size
);
775 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
779 mem_cur_size
-= malloc_usable_size(ptr
);
781 ptr1
= realloc(ptr
, size
);
783 /* NOTE: count not correct if alloc error, but not critical */
784 mem_cur_size
+= malloc_usable_size(ptr1
);
785 if (mem_cur_size
> mem_max_size
)
786 mem_max_size
= mem_cur_size
;
791 static char *tcc_strdup(const char *str
)
794 ptr
= tcc_malloc(strlen(str
) + 1);
799 #define free(p) use_tcc_free(p)
800 #define malloc(s) use_tcc_malloc(s)
801 #define realloc(p, s) use_tcc_realloc(p, s)
803 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
810 /* every power of two we double array size */
811 if ((nb
& (nb
- 1)) == 0) {
816 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
818 error("memory full");
825 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
829 sec
= tcc_mallocz(sizeof(Section
));
830 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
831 sec
->sh_type
= sh_type
;
832 sec
->sh_flags
= sh_flags
;
839 sec
->sh_addralign
= 4;
842 sec
->sh_addralign
= 1;
845 sec
->sh_addralign
= 32; /* default conservative alignment */
849 /* only add section if not private */
850 if (!(sh_flags
& SHF_PRIVATE
)) {
851 sec
->sh_num
= s1
->nb_sections
;
852 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
857 static void free_section(Section
*s
)
863 /* realloc section and set its content to zero */
864 static void section_realloc(Section
*sec
, unsigned long new_size
)
869 size
= sec
->data_allocated
;
872 while (size
< new_size
)
874 data
= tcc_realloc(sec
->data
, size
);
876 error("memory full");
877 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
879 sec
->data_allocated
= size
;
882 /* reserve at least 'size' bytes in section 'sec' from
884 static void *section_ptr_add(Section
*sec
, unsigned long size
)
886 unsigned long offset
, offset1
;
888 offset
= sec
->data_offset
;
889 offset1
= offset
+ size
;
890 if (offset1
> sec
->data_allocated
)
891 section_realloc(sec
, offset1
);
892 sec
->data_offset
= offset1
;
893 return sec
->data
+ offset
;
896 /* return a reference to a section, and create it if it does not
898 Section
*find_section(TCCState
*s1
, const char *name
)
902 for(i
= 1; i
< s1
->nb_sections
; i
++) {
903 sec
= s1
->sections
[i
];
904 if (!strcmp(name
, sec
->name
))
907 /* sections are created as PROGBITS */
908 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
911 /* update sym->c so that it points to an external symbol in section
912 'section' with value 'value' */
913 static void put_extern_sym(Sym
*sym
, Section
*section
,
914 unsigned long value
, unsigned long size
)
916 int sym_type
, sym_bind
, sh_num
, info
;
921 sh_num
= section
->sh_num
;
925 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
)
928 sym_type
= STT_OBJECT
;
929 if (sym
->type
.t
& VT_STATIC
)
930 sym_bind
= STB_LOCAL
;
932 sym_bind
= STB_GLOBAL
;
934 name
= get_tok_str(sym
->v
, NULL
);
935 #ifdef CONFIG_TCC_BCHECK
936 if (do_bounds_check
) {
939 /* XXX: avoid doing that for statics ? */
940 /* if bound checking is activated, we change some function
941 names by adding the "__bound" prefix */
944 /* XXX: we rely only on malloc hooks */
956 strcpy(buf
, "__bound_");
963 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
964 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
966 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
967 esym
->st_value
= value
;
968 esym
->st_size
= size
;
969 esym
->st_shndx
= sh_num
;
973 /* add a new relocation entry to symbol 'sym' in section 's' */
974 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
977 put_extern_sym(sym
, NULL
, 0, 0);
978 /* now we can add ELF relocation info */
979 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
982 static inline int isid(int c
)
984 return (c
>= 'a' && c
<= 'z') ||
985 (c
>= 'A' && c
<= 'Z') ||
989 static inline int isnum(int c
)
991 return c
>= '0' && c
<= '9';
994 static inline int isoct(int c
)
996 return c
>= '0' && c
<= '7';
999 static inline int toup(int c
)
1001 if (c
>= 'a' && c
<= 'z')
1002 return c
- 'a' + 'A';
1007 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1011 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1014 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1018 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1022 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1029 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1030 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1031 (*f
)->filename
, (*f
)->line_num
);
1032 if (file
->line_num
> 0) {
1033 strcat_printf(buf
, sizeof(buf
),
1034 "%s:%d: ", file
->filename
, file
->line_num
);
1036 strcat_printf(buf
, sizeof(buf
),
1037 "%s: ", file
->filename
);
1040 strcat_printf(buf
, sizeof(buf
),
1044 strcat_printf(buf
, sizeof(buf
), "warning: ");
1045 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1047 if (!s1
->error_func
) {
1048 /* default case: stderr */
1049 fprintf(stderr
, "%s\n", buf
);
1051 s1
->error_func(s1
->error_opaque
, buf
);
1058 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1059 void (*error_func
)(void *opaque
, const char *msg
))
1061 s
->error_opaque
= error_opaque
;
1062 s
->error_func
= error_func
;
1066 /* error without aborting current compilation */
1067 void error_noabort(const char *fmt
, ...)
1069 TCCState
*s1
= tcc_state
;
1073 error1(s1
, 0, fmt
, ap
);
1077 void error(const char *fmt
, ...)
1079 TCCState
*s1
= tcc_state
;
1083 error1(s1
, 0, fmt
, ap
);
1085 /* better than nothing: in some cases, we accept to handle errors */
1086 if (s1
->error_set_jmp_enabled
) {
1087 longjmp(s1
->error_jmp_buf
, 1);
1089 /* XXX: suppress it someday */
1094 void expect(const char *msg
)
1096 error("%s expected", msg
);
1099 void warning(const char *fmt
, ...)
1101 TCCState
*s1
= tcc_state
;
1105 error1(s1
, 1, fmt
, ap
);
1112 error("'%c' expected", c
);
1116 void test_lvalue(void)
1118 if (!(vtop
->r
& VT_LVAL
))
1122 /* allocate a new token */
1123 static TokenSym
*tok_alloc_new(TokenSym
**pts
, const char *str
, int len
)
1125 TokenSym
*ts
, **ptable
;
1128 if (tok_ident
>= SYM_FIRST_ANOM
)
1129 error("memory full");
1131 /* expand token table if needed */
1132 i
= tok_ident
- TOK_IDENT
;
1133 if ((i
% TOK_ALLOC_INCR
) == 0) {
1134 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1136 error("memory full");
1137 table_ident
= ptable
;
1140 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1141 table_ident
[i
] = ts
;
1142 ts
->tok
= tok_ident
++;
1143 ts
->sym_define
= NULL
;
1144 ts
->sym_label
= NULL
;
1145 ts
->sym_struct
= NULL
;
1146 ts
->sym_identifier
= NULL
;
1148 ts
->hash_next
= NULL
;
1149 memcpy(ts
->str
, str
, len
);
1150 ts
->str
[len
] = '\0';
1155 #define TOK_HASH_INIT 1
1156 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1158 /* find a token and add it if not found */
1159 static TokenSym
*tok_alloc(const char *str
, int len
)
1161 TokenSym
*ts
, **pts
;
1167 h
= TOK_HASH_FUNC(h
, ((unsigned char *)str
)[i
]);
1168 h
&= (TOK_HASH_SIZE
- 1);
1170 pts
= &hash_ident
[h
];
1175 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1177 pts
= &(ts
->hash_next
);
1179 return tok_alloc_new(pts
, str
, len
);
1182 /* CString handling */
1184 static void cstr_realloc(CString
*cstr
, int new_size
)
1189 size
= cstr
->size_allocated
;
1191 size
= 8; /* no need to allocate a too small first string */
1192 while (size
< new_size
)
1194 data
= tcc_realloc(cstr
->data_allocated
, size
);
1196 error("memory full");
1197 cstr
->data_allocated
= data
;
1198 cstr
->size_allocated
= size
;
1203 static void cstr_ccat(CString
*cstr
, int ch
)
1206 size
= cstr
->size
+ 1;
1207 if (size
> cstr
->size_allocated
)
1208 cstr_realloc(cstr
, size
);
1209 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1213 static void cstr_cat(CString
*cstr
, const char *str
)
1225 /* add a wide char */
1226 static void cstr_wccat(CString
*cstr
, int ch
)
1229 size
= cstr
->size
+ sizeof(int);
1230 if (size
> cstr
->size_allocated
)
1231 cstr_realloc(cstr
, size
);
1232 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1236 static void cstr_new(CString
*cstr
)
1238 memset(cstr
, 0, sizeof(CString
));
1241 /* free string and reset it to NULL */
1242 static void cstr_free(CString
*cstr
)
1244 tcc_free(cstr
->data_allocated
);
1248 #define cstr_reset(cstr) cstr_free(cstr)
1250 static CString
*cstr_dup(CString
*cstr1
)
1255 cstr
= tcc_malloc(sizeof(CString
));
1258 cstr
->size_allocated
= size
;
1259 cstr
->data_allocated
= tcc_malloc(size
);
1260 cstr
->data
= cstr
->data_allocated
;
1261 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1265 /* XXX: unicode ? */
1266 static void add_char(CString
*cstr
, int c
)
1268 if (c
== '\'' || c
== '\"' || c
== '\\') {
1269 /* XXX: could be more precise if char or string */
1270 cstr_ccat(cstr
, '\\');
1272 if (c
>= 32 && c
<= 126) {
1275 cstr_ccat(cstr
, '\\');
1277 cstr_ccat(cstr
, 'n');
1279 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1280 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1281 cstr_ccat(cstr
, '0' + (c
& 7));
1286 /* XXX: buffer overflow */
1287 /* XXX: float tokens */
1288 char *get_tok_str(int v
, CValue
*cv
)
1290 static char buf
[STRING_MAX_SIZE
+ 1];
1291 static CString cstr_buf
;
1297 /* NOTE: to go faster, we give a fixed buffer for small strings */
1298 cstr_reset(&cstr_buf
);
1299 cstr_buf
.data
= buf
;
1300 cstr_buf
.size_allocated
= sizeof(buf
);
1306 /* XXX: not quite exact, but only useful for testing */
1307 sprintf(p
, "%u", cv
->ui
);
1311 /* XXX: not quite exact, but only useful for testing */
1312 sprintf(p
, "%Lu", cv
->ull
);
1316 cstr_ccat(&cstr_buf
, '\'');
1317 add_char(&cstr_buf
, cv
->i
);
1318 cstr_ccat(&cstr_buf
, '\'');
1319 cstr_ccat(&cstr_buf
, '\0');
1323 len
= cstr
->size
- 1;
1325 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1326 cstr_ccat(&cstr_buf
, '\0');
1331 cstr_ccat(&cstr_buf
, '\"');
1333 len
= cstr
->size
- 1;
1335 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1337 len
= (cstr
->size
/ sizeof(int)) - 1;
1339 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1341 cstr_ccat(&cstr_buf
, '\"');
1342 cstr_ccat(&cstr_buf
, '\0');
1351 return strcpy(p
, "<<=");
1353 return strcpy(p
, ">>=");
1355 if (v
< TOK_IDENT
) {
1356 /* search in two bytes table */
1370 } else if (v
< tok_ident
) {
1371 return table_ident
[v
- TOK_IDENT
]->str
;
1372 } else if (v
>= SYM_FIRST_ANOM
) {
1373 /* special name for anonymous symbol */
1374 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1376 /* should never happen */
1381 return cstr_buf
.data
;
1384 /* push, without hashing */
1385 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1388 s
= tcc_malloc(sizeof(Sym
));
1399 /* find a symbol and return its associated structure. 's' is the top
1400 of the symbol stack */
1401 static Sym
*sym_find2(Sym
*s
, int v
)
1411 /* structure lookup */
1412 static Sym
*struct_find(int v
)
1415 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1417 return table_ident
[v
]->sym_struct
;
1420 /* find an identifier */
1421 static inline Sym
*sym_find(int v
)
1424 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1426 return table_ident
[v
]->sym_identifier
;
1429 /* push a given symbol on the symbol stack */
1430 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1439 s
= sym_push2(ps
, v
, type
->t
, c
);
1440 s
->type
.ref
= type
->ref
;
1442 /* don't record fields or anonymous symbols */
1444 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1445 /* record symbol in token array */
1446 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1448 ps
= &ts
->sym_struct
;
1450 ps
= &ts
->sym_identifier
;
1457 /* push a global identifier */
1458 static Sym
*global_identifier_push(int v
, int t
, int c
)
1461 s
= sym_push2(&global_stack
, v
, t
, c
);
1462 /* don't record anonymous symbol */
1463 if (v
< SYM_FIRST_ANOM
) {
1464 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1465 /* modify the top most local identifier, so that
1466 sym_identifier will point to 's' when popped */
1468 ps
= &(*ps
)->prev_tok
;
1475 /* pop symbols until top reaches 'b' */
1476 static void sym_pop(Sym
**ptop
, Sym
*b
)
1486 /* remove symbol in token array */
1488 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1489 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1491 ps
= &ts
->sym_struct
;
1493 ps
= &ts
->sym_identifier
;
1504 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1509 fd
= open(filename
, O_RDONLY
);
1512 bf
= tcc_malloc(sizeof(BufferedFile
));
1518 bf
->buf_ptr
= bf
->buffer
;
1519 bf
->buf_end
= bf
->buffer
;
1520 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1521 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1523 bf
->ifndef_macro
= 0;
1524 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1525 // printf("opening '%s'\n", filename);
1529 void tcc_close(BufferedFile
*bf
)
1531 total_lines
+= bf
->line_num
;
1536 /* fill input buffer and peek next char */
1537 static int tcc_peekc_slow(BufferedFile
*bf
)
1540 /* only tries to read if really end of buffer */
1541 if (bf
->buf_ptr
>= bf
->buf_end
) {
1543 #if defined(PARSE_DEBUG)
1548 len
= read(bf
->fd
, bf
->buffer
, len
);
1555 bf
->buf_ptr
= bf
->buffer
;
1556 bf
->buf_end
= bf
->buffer
+ len
;
1557 *bf
->buf_end
= CH_EOB
;
1559 if (bf
->buf_ptr
< bf
->buf_end
) {
1560 return bf
->buf_ptr
[0];
1562 bf
->buf_ptr
= bf
->buf_end
;
1567 /* return the current character, handling end of block if necessary
1569 static int handle_eob(void)
1571 return tcc_peekc_slow(file
);
1574 /* read next char from current input file and handle end of input buffer */
1575 static inline void inp(void)
1577 ch
= *(++(file
->buf_ptr
));
1578 /* end of buffer/file handling */
1583 /* handle '\[\r]\n' */
1584 static void handle_stray(void)
1586 while (ch
== '\\') {
1591 } else if (ch
== '\r') {
1599 error("stray '\\' in program");
1604 /* skip the stray and handle the \\n case. Output an error if
1605 incorrect char after the stray */
1606 static int handle_stray1(uint8_t *p
)
1610 if (p
>= file
->buf_end
) {
1627 /* handle the complicated stray case */
1628 #define PEEKC(c, p)\
1633 c = handle_stray1(p);\
1638 /* input with '\[\r]\n' handling. Note that this function cannot
1639 handle other characters after '\', so you cannot call it inside
1640 strings or comments */
1641 static void minp(void)
1649 static void parse_line_comment(void)
1651 /* single line C++ comments */
1652 /* XXX: accept '\\\n' ? */
1654 while (ch
!= '\n' && ch
!= CH_EOF
)
1658 static void parse_comment(void)
1667 /* fast skip loop */
1670 if (c
== '\n' || c
== '*' || c
== '\\')
1674 if (c
== '\n' || c
== '*' || c
== '\\')
1678 /* now we can handle all the cases */
1682 } else if (c
== '*') {
1688 } else if (c
== '/') {
1689 goto end_of_comment
;
1690 } else if (c
== '\\') {
1694 /* skip '\\n', but if '\' followed but another
1695 char, behave asif a stray was parsed */
1696 ch
= file
->buf_ptr
[0];
1697 while (ch
== '\\') {
1702 } else if (ch
== '\r') {
1720 /* stray, eob or eof */
1725 error("unexpected end of file in comment");
1726 } else if (c
== '\\') {
1739 /* space exlcuding newline */
1740 static inline int is_space(int ch
)
1742 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1745 static inline void skip_spaces(void)
1747 while (is_space(ch
))
1751 /* skip block of text until #else, #elif or #endif. skip also pairs of
1753 void preprocess_skip(void)
1755 int a
, start_of_line
, sep
, c
;
1782 } else if (c
== '\\') {
1783 /* XXX: incorrect: should not give an error */
1784 ch
= file
->buf_ptr
[0];
1798 } else if (c
== '\\') {
1803 /* XXX: better error message */
1804 error("unterminated string");
1805 } else if (c
== '\\') {
1806 /* ignore next char */
1816 else if (c
!= CH_EOF
)
1819 } else if (c
== '\n') {
1835 } else if (ch
== '/') {
1836 parse_line_comment();
1843 if (start_of_line
) {
1848 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1850 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1852 else if (tok
== TOK_ENDIF
)
1866 /* ParseState handling */
1868 /* XXX: currently, no include file info is stored. Thus, we cannot display
1869 accurate messages if the function or data definition spans multiple
1872 /* save current parse state in 's' */
1873 void save_parse_state(ParseState
*s
)
1875 s
->line_num
= file
->line_num
;
1876 s
->macro_ptr
= macro_ptr
;
1881 /* restore parse state from 's' */
1882 void restore_parse_state(ParseState
*s
)
1884 file
->line_num
= s
->line_num
;
1885 macro_ptr
= s
->macro_ptr
;
1890 /* return the number of additionnal 'ints' necessary to store the
1892 static inline int tok_ext_size(int t
)
1911 return LDOUBLE_SIZE
/ 4;
1917 /* token string handling */
1919 static inline void tok_str_new(TokenString
*s
)
1923 s
->allocated_len
= 0;
1924 s
->last_line_num
= -1;
1927 static void tok_str_free(int *str
)
1936 /* NOTE: we test zero separately so that GCC can generate a
1937 table for the following switch */
1952 /* XXX: use a macro to be portable on 64 bit ? */
1953 cstr
= (CString
*)p
[1];
1964 p
+= 1 + (LDOUBLE_SIZE
/ 4);
1974 static int *tok_str_realloc(TokenString
*s
)
1978 len
= s
->allocated_len
+ TOK_STR_ALLOC_INCR
;
1979 str
= tcc_realloc(s
->str
, len
* sizeof(int));
1981 error("memory full");
1982 s
->allocated_len
= len
;
1987 static void tok_str_add(TokenString
*s
, int t
)
1993 if (len
>= s
->allocated_len
)
1994 str
= tok_str_realloc(s
);
1999 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
2006 /* allocate space for worst case */
2007 if (len
+ TOK_MAX_SIZE
> s
->allocated_len
)
2008 str
= tok_str_realloc(s
);
2017 str
[len
++] = cv
->tab
[0];
2022 str
[len
++] = (int)cstr_dup(cv
->cstr
);
2027 str
[len
++] = cv
->tab
[0];
2028 str
[len
++] = cv
->tab
[1];
2031 #if LDOUBLE_SIZE == 12
2032 str
[len
++] = cv
->tab
[0];
2033 str
[len
++] = cv
->tab
[1];
2034 str
[len
++] = cv
->tab
[2];
2036 #error add long double size support
2045 /* add the current parse token in token string 's' */
2046 static void tok_str_add_tok(TokenString
*s
)
2050 /* save line number info */
2051 if (file
->line_num
!= s
->last_line_num
) {
2052 s
->last_line_num
= file
->line_num
;
2053 cval
.i
= s
->last_line_num
;
2054 tok_str_add2(s
, TOK_LINENUM
, &cval
);
2056 tok_str_add2(s
, tok
, &tokc
);
2059 #if LDOUBLE_SIZE == 12
2060 #define LDOUBLE_GET(p, cv) \
2065 #error add long double size support
2069 /* get a token from an integer array and increment pointer
2070 accordingly. we code it as a macro to avoid pointer aliasing. */
2071 #define TOK_GET(t, p, cv) \
2093 case TOK_CLDOUBLE: \
2094 LDOUBLE_GET(p, cv); \
2095 p += LDOUBLE_SIZE / 4; \
2102 /* defines handling */
2103 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
2107 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
2108 s
->next
= first_arg
;
2109 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
2112 /* undefined a define symbol. Its name is just set to zero */
2113 static void define_undef(Sym
*s
)
2117 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2118 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2122 static inline Sym
*define_find(int v
)
2125 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2127 return table_ident
[v
]->sym_define
;
2130 /* free define stack until top reaches 'b' */
2131 static void free_defines(Sym
*b
)
2139 /* do not free args or predefined defines */
2141 tok_str_free((int *)top
->c
);
2143 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2144 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2152 static Sym
*label_find(int v
)
2155 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2157 return table_ident
[v
]->sym_label
;
2160 static Sym
*label_push(int v
, int flags
)
2163 s
= sym_push2(&label_stack
, v
, 0, 0);
2165 table_ident
[v
- TOK_IDENT
]->sym_label
= s
;
2169 /* eval an expression for #if/#elif */
2170 static int expr_preprocess(void)
2176 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2177 next(); /* do macro subst */
2178 if (tok
== TOK_DEFINED
) {
2183 c
= define_find(tok
) != 0;
2188 } else if (tok
>= TOK_IDENT
) {
2189 /* if undefined macro */
2193 tok_str_add_tok(&str
);
2195 tok_str_add(&str
, -1); /* simulate end of file */
2196 tok_str_add(&str
, 0);
2197 /* now evaluate C constant expression */
2198 macro_ptr
= str
.str
;
2202 tok_str_free(str
.str
);
2206 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2207 static void tok_print(int *str
)
2213 TOK_GET(t
, str
, cval
);
2216 printf(" %s", get_tok_str(t
, &cval
));
2222 /* parse after #define */
2223 static void parse_define(void)
2225 Sym
*s
, *first
, **ps
;
2226 int v
, t
, varg
, is_vaargs
, c
;
2231 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2232 /* XXX: should check if same macro (ANSI) */
2235 /* '(' must be just after macro definition for MACRO_FUNC */
2236 c
= file
->buf_ptr
[0];
2238 c
= handle_stray1(file
->buf_ptr
);
2243 while (tok
!= ')') {
2247 if (varg
== TOK_DOTS
) {
2248 varg
= TOK___VA_ARGS__
;
2250 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2254 if (varg
< TOK_IDENT
)
2255 error("badly punctuated parameter list");
2256 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2267 /* EOF testing necessary for '-D' handling */
2268 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2269 tok_str_add2(&str
, tok
, &tokc
);
2272 tok_str_add(&str
, 0);
2274 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2277 define_push(v
, t
, str
.str
, first
);
2280 /* XXX: use a token or a hash table to accelerate matching ? */
2281 static CachedInclude
*search_cached_include(TCCState
*s1
,
2282 int type
, const char *filename
)
2287 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
2288 e
= s1
->cached_includes
[i
];
2289 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2295 static inline void add_cached_include(TCCState
*s1
, int type
,
2296 const char *filename
, int ifndef_macro
)
2300 if (search_cached_include(s1
, type
, filename
))
2303 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2305 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2309 strcpy(e
->filename
, filename
);
2310 e
->ifndef_macro
= ifndef_macro
;
2311 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2314 /* is_bof is true if first non space token at beginning of file */
2315 static void preprocess(int is_bof
)
2317 TCCState
*s1
= tcc_state
;
2319 char buf
[1024], *q
, *p
;
2325 return_linefeed
= 1; /* linefeed will be returned as a
2326 token. EOF is also returned as line feed */
2336 s
= define_find(tok
);
2337 /* undefine symbol by putting an invalid name */
2342 ch
= file
->buf_ptr
[0];
2343 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2348 } else if (ch
== '\"') {
2351 /* XXX: better stray handling */
2354 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2355 if ((q
- buf
) < sizeof(buf
) - 1)
2362 /* eat all spaces and comments after include */
2363 /* XXX: slightly incorrect */
2364 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2368 /* computed #include : either we have only strings or
2369 we have anything enclosed in '<>' */
2372 if (tok
== TOK_STR
) {
2373 while (tok
!= TOK_LINEFEED
) {
2374 if (tok
!= TOK_STR
) {
2376 error("'#include' expects \"FILENAME\" or <FILENAME>");
2378 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2384 while (tok
!= TOK_LINEFEED
) {
2385 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2389 /* check syntax and remove '<>' */
2390 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2391 goto include_syntax
;
2392 memmove(buf
, buf
+ 1, len
- 2);
2393 buf
[len
- 2] = '\0';
2398 e
= search_cached_include(s1
, c
, buf
);
2399 if (e
&& define_find(e
->ifndef_macro
)) {
2400 /* no need to parse the include because the 'ifndef macro'
2403 printf("%s: skipping %s\n", file
->filename
, buf
);
2407 /* first search in current dir if "header.h" */
2409 p
= strrchr(file
->filename
, '/');
2411 size
= p
+ 1 - file
->filename
;
2412 if (size
> sizeof(buf1
) - 1)
2413 size
= sizeof(buf1
) - 1;
2414 memcpy(buf1
, file
->filename
, size
);
2416 pstrcat(buf1
, sizeof(buf1
), buf
);
2417 f
= tcc_open(s1
, buf1
);
2421 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2422 error("#include recursion too deep");
2423 /* now search in all the include paths */
2424 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2425 for(i
= 0; i
< n
; i
++) {
2427 if (i
< s1
->nb_include_paths
)
2428 path
= s1
->include_paths
[i
];
2430 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2431 pstrcpy(buf1
, sizeof(buf1
), path
);
2432 pstrcat(buf1
, sizeof(buf1
), "/");
2433 pstrcat(buf1
, sizeof(buf1
), buf
);
2434 f
= tcc_open(s1
, buf1
);
2438 error("include file '%s' not found", buf
);
2442 printf("%s: including %s\n", file
->filename
, buf1
);
2445 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2446 /* push current file in stack */
2447 /* XXX: fix current line init */
2448 *s1
->include_stack_ptr
++ = file
;
2450 /* add include file debug info */
2452 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2454 tok_flags
|= TOK_FLAG_BOF
| TOK_FLAG_BOL
;
2455 ch
= file
->buf_ptr
[0];
2463 c
= expr_preprocess();
2469 if (tok
< TOK_IDENT
)
2470 error("invalid argument for '#if%sdef'", c
? "n" : "");
2474 printf("#ifndef %s\n", get_tok_str(tok
, NULL
));
2476 file
->ifndef_macro
= tok
;
2479 c
= (define_find(tok
) != 0) ^ c
;
2481 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2482 error("memory full");
2483 *s1
->ifdef_stack_ptr
++ = c
;
2486 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2487 error("#else without matching #if");
2488 if (s1
->ifdef_stack_ptr
[-1] & 2)
2489 error("#else after #else");
2490 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2493 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2494 error("#elif without matching #if");
2495 c
= s1
->ifdef_stack_ptr
[-1];
2497 error("#elif after #else");
2498 /* last #if/#elif expression was true: we skip */
2501 c
= expr_preprocess();
2502 s1
->ifdef_stack_ptr
[-1] = c
;
2512 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2513 error("#endif without matching #if");
2514 s1
->ifdef_stack_ptr
--;
2515 /* '#ifndef macro' was at the start of file. Now we check if
2516 an '#endif' is exactly at the end of file */
2517 if (file
->ifndef_macro
&&
2518 s1
->ifdef_stack_ptr
== file
->ifdef_stack_ptr
) {
2519 file
->ifndef_macro_saved
= file
->ifndef_macro
;
2520 /* need to set to zero to avoid false matches if another
2521 #ifndef at middle of file */
2522 file
->ifndef_macro
= 0;
2523 while (tok
!= TOK_LINEFEED
)
2525 tok_flags
|= TOK_FLAG_ENDIF
;
2531 if (tok
!= TOK_CINT
)
2533 file
->line_num
= tokc
.i
- 1; /* the line number will be incremented after */
2535 if (tok
!= TOK_LINEFEED
) {
2538 pstrcpy(file
->filename
, sizeof(file
->filename
),
2539 (char *)tokc
.cstr
->data
);
2545 ch
= file
->buf_ptr
[0];
2548 while (ch
!= '\n' && ch
!= CH_EOF
) {
2549 if ((q
- buf
) < sizeof(buf
) - 1)
2555 error("#error %s", buf
);
2557 warning("#warning %s", buf
);
2563 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
2564 /* '!' is ignored to allow C scripts. numbers are ignored
2565 to emulate cpp behaviour */
2567 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
2571 /* ignore other preprocess commands or #! for C scripts */
2572 while (tok
!= TOK_LINEFEED
)
2575 return_linefeed
= 0;
2578 /* read a number in base b */
2579 static int getn(int b
)
2584 if (ch
>= 'a' && ch
<= 'f')
2586 else if (ch
>= 'A' && ch
<= 'F')
2592 if (t
< 0 || t
>= b
)
2600 /* read a character for string or char constant and eval escape codes */
2601 static int getq(void)
2610 case '0': case '1': case '2': case '3':
2611 case '4': case '5': case '6': case '7':
2612 /* at most three octal digits */
2616 c
= c
* 8 + ch
- '0';
2619 c
= c
* 8 + ch
- '0';
2650 goto invalid_escape
;
2665 goto invalid_escape
;
2670 error("invalid escaped char");
2673 } else if (c
== '\r' && ch
== '\n') {
2680 /* we use 64 bit numbers */
2683 /* bn = (bn << shift) | or_val */
2684 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2688 for(i
=0;i
<BN_SIZE
;i
++) {
2690 bn
[i
] = (v
<< shift
) | or_val
;
2691 or_val
= v
>> (32 - shift
);
2695 void bn_zero(unsigned int *bn
)
2698 for(i
=0;i
<BN_SIZE
;i
++) {
2703 /* parse number in null terminated string 'p' and return it in the
2705 void parse_number(const char *p
)
2707 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
2709 unsigned int bn
[BN_SIZE
];
2720 goto float_frac_parse
;
2721 } else if (t
== '0') {
2722 if (ch
== 'x' || ch
== 'X') {
2726 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2732 /* parse all digits. cannot check octal numbers at this stage
2733 because of floating point constants */
2735 if (ch
>= 'a' && ch
<= 'f')
2737 else if (ch
>= 'A' && ch
<= 'F')
2745 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2747 error("number too long");
2753 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2754 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2756 /* NOTE: strtox should support that for hexa numbers, but
2757 non ISOC99 libcs do not support it, so we prefer to do
2759 /* hexadecimal or binary floats */
2760 /* XXX: handle overflows */
2772 } else if (t
>= 'a') {
2774 } else if (t
>= 'A') {
2779 bn_lshift(bn
, shift
, t
);
2786 if (t
>= 'a' && t
<= 'f') {
2788 } else if (t
>= 'A' && t
<= 'F') {
2790 } else if (t
>= '0' && t
<= '9') {
2796 error("invalid digit");
2797 bn_lshift(bn
, shift
, t
);
2802 if (ch
!= 'p' && ch
!= 'P')
2809 } else if (ch
== '-') {
2813 if (ch
< '0' || ch
> '9')
2814 expect("exponent digits");
2815 while (ch
>= '0' && ch
<= '9') {
2816 exp_val
= exp_val
* 10 + ch
- '0';
2819 exp_val
= exp_val
* s
;
2821 /* now we can generate the number */
2822 /* XXX: should patch directly float number */
2823 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
2824 d
= ldexp(d
, exp_val
- frac_bits
);
2829 /* float : should handle overflow */
2831 } else if (t
== 'L') {
2834 /* XXX: not large enough */
2835 tokc
.ld
= (long double)d
;
2841 /* decimal floats */
2843 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2848 while (ch
>= '0' && ch
<= '9') {
2849 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2855 if (ch
== 'e' || ch
== 'E') {
2856 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2860 if (ch
== '-' || ch
== '+') {
2861 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2866 if (ch
< '0' || ch
> '9')
2867 expect("exponent digits");
2868 while (ch
>= '0' && ch
<= '9') {
2869 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2881 tokc
.f
= strtof(token_buf
, NULL
);
2882 } else if (t
== 'L') {
2885 tokc
.ld
= strtold(token_buf
, NULL
);
2888 tokc
.d
= strtod(token_buf
, NULL
);
2892 unsigned long long n
, n1
;
2895 /* integer number */
2898 if (b
== 10 && *q
== '0') {
2905 /* no need for checks except for base 10 / 8 errors */
2908 } else if (t
>= 'a') {
2910 } else if (t
>= 'A') {
2915 error("invalid digit");
2919 /* detect overflow */
2920 /* XXX: this test is not reliable */
2922 error("integer constant overflow");
2925 /* XXX: not exactly ANSI compliant */
2926 if ((n
& 0xffffffff00000000LL
) != 0) {
2931 } else if (n
> 0x7fffffff) {
2942 error("three 'l's in integer constant");
2945 if (tok
== TOK_CINT
)
2947 else if (tok
== TOK_CUINT
)
2951 } else if (t
== 'U') {
2953 error("two 'u's in integer constant");
2955 if (tok
== TOK_CINT
)
2957 else if (tok
== TOK_CLLONG
)
2964 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2972 #define PARSE2(c1, tok1, c2, tok2) \
2983 /* return next token without macro substitution */
2984 static inline void next_nomacro1(void)
3004 /* first look if it is in fact an end of buffer */
3005 if (p
>= file
->buf_end
) {
3009 if (p
>= file
->buf_end
)
3022 TCCState
*s1
= tcc_state
;
3024 if (return_linefeed
) {
3026 } else if (s1
->include_stack_ptr
== s1
->include_stack
) {
3027 /* no include left : end of file */
3030 /* pop include file */
3032 /* test if previous '#endif' was after a #ifdef at
3034 if (tok_flags
& TOK_FLAG_ENDIF
) {
3036 printf("#endif %s\n", get_tok_str(file
->ifndef_macro_saved
, NULL
));
3038 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
3039 file
->ifndef_macro_saved
);
3042 /* add end of include file debug info */
3044 put_stabd(N_EINCL
, 0, 0);
3046 /* pop include stack */
3048 s1
->include_stack_ptr
--;
3049 file
= *s1
->include_stack_ptr
;
3057 if (return_linefeed
) {
3061 tok_flags
|= TOK_FLAG_BOL
;
3070 if (tok_flags
& TOK_FLAG_BOL
) {
3072 preprocess(tok_flags
& TOK_FLAG_BOF
);
3078 tok
= TOK_TWOSHARPS
;
3085 case 'a': case 'b': case 'c': case 'd':
3086 case 'e': case 'f': case 'g': case 'h':
3087 case 'i': case 'j': case 'k': case 'l':
3088 case 'm': case 'n': case 'o': case 'p':
3089 case 'q': case 'r': case 's': case 't':
3090 case 'u': case 'v': case 'w': case 'x':
3092 case 'A': case 'B': case 'C': case 'D':
3093 case 'E': case 'F': case 'G': case 'H':
3094 case 'I': case 'J': case 'K':
3095 case 'M': case 'N': case 'O': case 'P':
3096 case 'Q': case 'R': case 'S': case 'T':
3097 case 'U': case 'V': case 'W': case 'X':
3103 h
= TOK_HASH_FUNC(h
, c
);
3107 if (!isid(c
) && !isnum(c
))
3109 h
= TOK_HASH_FUNC(h
, c
);
3116 /* fast case : no stray found, so we have the full token
3117 and we have already hashed it */
3119 h
&= (TOK_HASH_SIZE
- 1);
3120 pts
= &hash_ident
[h
];
3125 if (ts
->len
== len
&& !memcmp(ts
->str
, p1
, len
))
3127 pts
= &(ts
->hash_next
);
3129 ts
= tok_alloc_new(pts
, p1
, len
);
3133 cstr_reset(&tokcstr
);
3136 cstr_ccat(&tokcstr
, *p1
);
3142 while (isid(c
) || isnum(c
)) {
3143 cstr_ccat(&tokcstr
, c
);
3146 ts
= tok_alloc(tokcstr
.data
, tokcstr
.size
);
3152 if (t
!= '\\' && t
!= '\'' && t
!= '\"') {
3154 goto parse_ident_fast
;
3160 } else if (c
== '\"') {
3164 cstr_reset(&tokcstr
);
3165 cstr_ccat(&tokcstr
, 'L');
3166 goto parse_ident_slow
;
3170 case '0': case '1': case '2': case '3':
3171 case '4': case '5': case '6': case '7':
3174 cstr_reset(&tokcstr
);
3175 /* after the first digit, accept digits, alpha, '.' or sign if
3176 prefixed by 'eEpP' */
3180 cstr_ccat(&tokcstr
, c
);
3182 if (!(isnum(c
) || isid(c
) || c
== '.' ||
3183 ((c
== '+' || c
== '-') &&
3184 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
3187 /* We add a trailing '\0' to ease parsing */
3188 cstr_ccat(&tokcstr
, '\0');
3189 tokc
.cstr
= &tokcstr
;
3193 /* special dot handling because it can also start a number */
3196 cstr_reset(&tokcstr
);
3197 cstr_ccat(&tokcstr
, '.');
3199 } else if (c
== '.') {
3215 /* this cast is needed if >= 128 */
3216 if (tok
== TOK_CCHAR
)
3220 error("unterminated character constant");
3229 cstr_reset(&tokcstr
);
3230 while (ch
!= '\"') {
3233 error("unterminated string");
3235 cstr_ccat(&tokcstr
, b
);
3237 cstr_wccat(&tokcstr
, b
);
3240 cstr_ccat(&tokcstr
, '\0');
3242 cstr_wccat(&tokcstr
, '\0');
3243 tokc
.cstr
= &tokcstr
;
3253 } else if (c
== '<') {
3271 } else if (c
== '>') {
3289 } else if (c
== '=') {
3302 } else if (c
== '=') {
3315 } else if (c
== '=') {
3328 } else if (c
== '=') {
3331 } else if (c
== '>') {
3339 PARSE2('!', '!', '=', TOK_NE
)
3340 PARSE2('=', '=', '=', TOK_EQ
)
3341 PARSE2('*', '*', '=', TOK_A_MUL
)
3342 PARSE2('%', '%', '=', TOK_A_MOD
)
3343 PARSE2('^', '^', '=', TOK_A_XOR
)
3345 /* comments or operator */
3353 } else if (c
== '/') {
3355 parse_line_comment();
3358 } else if (c
== '=') {
3382 error("unrecognized character \\x%02x", c
);
3387 #if defined(PARSE_DEBUG)
3388 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3392 /* return next token without macro substitution. Can read input from
3394 static void next_nomacro(void)
3400 TOK_GET(tok
, macro_ptr
, tokc
);
3401 if (tok
== TOK_LINENUM
) {
3402 file
->line_num
= tokc
.i
;
3411 /* substitute args in macro_str and return allocated string */
3412 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
3414 int *st
, last_tok
, t
, notfirst
;
3423 TOK_GET(t
, macro_str
, cval
);
3428 TOK_GET(t
, macro_str
, cval
);
3431 s
= sym_find2(args
, t
);
3438 cstr_ccat(&cstr
, ' ');
3439 TOK_GET(t
, st
, cval
);
3440 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
3443 cstr_ccat(&cstr
, '\0');
3445 printf("stringize: %s\n", (char *)cstr
.data
);
3449 tok_str_add2(&str
, TOK_STR
, &cval
);
3452 tok_str_add2(&str
, t
, &cval
);
3454 } else if (t
>= TOK_IDENT
) {
3455 s
= sym_find2(args
, t
);
3458 /* if '##' is present before or after, no arg substitution */
3459 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
3460 /* special case for var arg macros : ## eats the
3461 ',' if empty VA_ARGS variable. */
3462 /* XXX: test of the ',' is not 100%
3463 reliable. should fix it to avoid security
3465 if (gnu_ext
&& s
->type
.t
&&
3466 last_tok
== TOK_TWOSHARPS
&&
3467 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
3469 /* suppress ',' '##' */
3472 /* suppress '##' and add variable */
3480 TOK_GET(t1
, st
, cval
);
3483 tok_str_add2(&str
, t1
, &cval
);
3487 macro_subst(&str
, nested_list
, st
);
3490 tok_str_add(&str
, t
);
3493 tok_str_add2(&str
, t
, &cval
);
3497 tok_str_add(&str
, 0);
3501 /* handle the '##' operator */
3502 static int *macro_twosharps(void)
3507 const char *p1
, *p2
;
3509 TokenString macro_str1
;
3513 tok_str_new(¯o_str1
);
3519 while (*macro_ptr
== TOK_TWOSHARPS
) {
3521 macro_ptr1
= macro_ptr
;
3524 TOK_GET(t
, macro_ptr
, cval
);
3526 /* We concatenate the two tokens if we have an
3527 identifier or a preprocessing number */
3529 p1
= get_tok_str(tok
, &tokc
);
3530 cstr_cat(&cstr
, p1
);
3531 p2
= get_tok_str(t
, &cval
);
3532 cstr_cat(&cstr
, p2
);
3533 cstr_ccat(&cstr
, '\0');
3535 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
3536 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
3537 if (tok
== TOK_PPNUM
) {
3538 /* if number, then create a number token */
3539 /* NOTE: no need to allocate because
3540 tok_str_add2() does it */
3543 /* if identifier, we must do a test to
3544 validate we have a correct identifier */
3545 if (t
== TOK_PPNUM
) {
3555 if (!isnum(c
) && !isid(c
))
3559 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
3560 tok
= ts
->tok
; /* modify current token */
3563 const char *str
= cstr
.data
;
3564 const unsigned char *q
;
3566 /* we look for a valid token */
3567 /* XXX: do more extensive checks */
3568 if (!strcmp(str
, ">>=")) {
3570 } else if (!strcmp(str
, "<<=")) {
3572 } else if (strlen(str
) == 2) {
3573 /* search in two bytes table */
3578 if (q
[0] == str
[0] && q
[1] == str
[1])
3585 /* NOTE: because get_tok_str use a static buffer,
3588 p1
= get_tok_str(tok
, &tokc
);
3589 cstr_cat(&cstr
, p1
);
3590 cstr_ccat(&cstr
, '\0');
3591 p2
= get_tok_str(t
, &cval
);
3592 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
3593 /* cannot merge tokens: just add them separately */
3594 tok_str_add2(¯o_str1
, tok
, &tokc
);
3595 /* XXX: free associated memory ? */
3602 tok_str_add2(¯o_str1
, tok
, &tokc
);
3605 tok_str_add(¯o_str1
, 0);
3606 return macro_str1
.str
;
3610 /* do macro substitution of current token with macro 's' and add
3611 result to (tok_str,tok_len). 'nested_list' is the list of all
3612 macros we got inside to avoid recursing. Return non zero if no
3613 substitution needs to be done */
3614 static int macro_subst_tok(TokenString
*tok_str
,
3615 Sym
**nested_list
, Sym
*s
)
3617 Sym
*args
, *sa
, *sa1
;
3618 int mstr_allocated
, parlevel
, *mstr
, t
;
3624 /* if symbol is a macro, prepare substitution */
3625 /* if nested substitution, do nothing */
3626 if (sym_find2(*nested_list
, tok
))
3629 /* special macros */
3630 if (tok
== TOK___LINE__
) {
3631 cval
.i
= file
->line_num
;
3632 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
3633 } else if (tok
== TOK___FILE__
) {
3634 cstrval
= file
->filename
;
3636 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3637 } else if (tok
== TOK___DATE__
) {
3638 cstrval
= "Jan 1 2002";
3640 } else if (tok
== TOK___TIME__
) {
3641 cstrval
= "00:00:00";
3644 cstr_cat(&cstr
, cstrval
);
3645 cstr_ccat(&cstr
, '\0');
3647 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3652 if (s
->type
.t
== MACRO_FUNC
) {
3653 /* NOTE: we do not use next_nomacro to avoid eating the
3654 next token. XXX: find better solution */
3658 /* XXX: incorrect with comments */
3659 ch
= file
->buf_ptr
[0];
3660 while (is_space(ch
) || ch
== '\n')
3664 if (t
!= '(') /* no macro subst */
3667 /* argument macro */
3672 /* NOTE: empty args are allowed, except if no args */
3674 /* handle '()' case */
3675 if (!args
&& tok
== ')')
3678 error("macro '%s' used with too many args",
3679 get_tok_str(s
->v
, 0));
3682 /* NOTE: non zero sa->t indicates VA_ARGS */
3683 while ((parlevel
> 0 ||
3685 (tok
!= ',' || sa
->type
.t
))) &&
3689 else if (tok
== ')')
3691 tok_str_add2(&str
, tok
, &tokc
);
3694 tok_str_add(&str
, 0);
3695 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
3698 /* special case for gcc var args: add an empty
3699 var arg argument if it is omitted */
3700 if (sa
&& sa
->type
.t
&& gnu_ext
)
3710 error("macro '%s' used with too few args",
3711 get_tok_str(s
->v
, 0));
3714 /* now subst each arg */
3715 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3720 tok_str_free((int *)sa
->c
);
3726 sym_push2(nested_list
, s
->v
, 0, 0);
3727 macro_subst(tok_str
, nested_list
, mstr
);
3728 /* pop nested defined symbol */
3730 *nested_list
= sa1
->prev
;
3738 /* do macro substitution of macro_str and add result to
3739 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3740 inside to avoid recursing. */
3741 static void macro_subst(TokenString
*tok_str
,
3742 Sym
**nested_list
, int *macro_str
)
3745 int *saved_macro_ptr
;
3748 saved_macro_ptr
= macro_ptr
;
3749 macro_ptr
= macro_str
;
3750 /* first scan for '##' operator handling */
3751 macro_str1
= macro_twosharps();
3752 macro_ptr
= macro_str1
;
3758 s
= define_find(tok
);
3760 if (macro_subst_tok(tok_str
, nested_list
, s
) != 0)
3764 tok_str_add2(tok_str
, tok
, &tokc
);
3767 macro_ptr
= saved_macro_ptr
;
3768 tok_str_free(macro_str1
);
3771 /* return next token with macro substitution */
3772 static void next(void)
3774 Sym
*nested_list
, *s
;
3777 /* special 'ungettok' case for label parsing */
3786 /* if not reading from macro substituted string, then try
3787 to substitute macros */
3788 if (tok
>= TOK_IDENT
) {
3789 s
= define_find(tok
);
3791 /* we have a macro: we try to substitute */
3794 if (macro_subst_tok(&str
, &nested_list
, s
) == 0) {
3795 /* substitution done, NOTE: maybe empty */
3796 tok_str_add(&str
, 0);
3797 macro_ptr
= str
.str
;
3798 macro_ptr_allocated
= str
.str
;
3805 /* end of macro string: free it */
3806 tok_str_free(macro_ptr_allocated
);
3812 /* convert preprocessor tokens into C tokens */
3813 if (tok
== TOK_PPNUM
) {
3814 parse_number((char *)tokc
.cstr
->data
);
3819 void swap(int *p
, int *q
)
3827 void vsetc(CType
*type
, int r
, CValue
*vc
)
3831 if (vtop
>= vstack
+ VSTACK_SIZE
)
3832 error("memory full");
3833 /* cannot let cpu flags if other instruction are generated. Also
3834 avoid leaving VT_JMP anywhere except on the top of the stack
3835 because it would complicate the code generator. */
3836 if (vtop
>= vstack
) {
3837 v
= vtop
->r
& VT_VALMASK
;
3838 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
3844 vtop
->r2
= VT_CONST
;
3848 /* push integer constant */
3853 vsetc(&int_type
, VT_CONST
, &cval
);
3856 /* Return a static symbol pointing to a section */
3857 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
3858 unsigned long offset
, unsigned long size
)
3864 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
3865 sym
->type
.ref
= type
->ref
;
3866 sym
->r
= VT_CONST
| VT_SYM
;
3867 put_extern_sym(sym
, sec
, offset
, size
);
3871 /* push a reference to a section offset by adding a dummy symbol */
3872 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
3877 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
3878 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
3881 /* define a new external reference to a symbol 'v' of type 'u' */
3882 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
3888 /* push forward reference */
3889 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
3890 s
->type
.ref
= type
->ref
;
3891 s
->r
= r
| VT_CONST
| VT_SYM
;
3896 /* define a new external reference to a symbol 'v' of type 'u' */
3897 static Sym
*external_sym(int v
, CType
*type
, int r
)
3903 /* push forward reference */
3904 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
3905 s
->type
.t
|= VT_EXTERN
;
3910 /* push a reference to global symbol v */
3911 static void vpush_global_sym(CType
*type
, int v
)
3916 sym
= external_global_sym(v
, type
, 0);
3918 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
3922 void vset(CType
*type
, int r
, int v
)
3927 vsetc(type
, r
, &cval
);
3930 void vseti(int r
, int v
)
3946 void vpushv(SValue
*v
)
3948 if (vtop
>= vstack
+ VSTACK_SIZE
)
3949 error("memory full");
3959 /* save r to the memory stack, and mark it as being free */
3960 void save_reg(int r
)
3962 int l
, saved
, size
, align
;
3966 /* modify all stack values */
3969 for(p
=vstack
;p
<=vtop
;p
++) {
3970 if ((p
->r
& VT_VALMASK
) == r
||
3971 (p
->r2
& VT_VALMASK
) == r
) {
3972 /* must save value on stack if not already done */
3974 /* NOTE: must reload 'r' because r might be equal to r2 */
3975 r
= p
->r
& VT_VALMASK
;
3976 /* store register in the stack */
3978 if ((p
->r
& VT_LVAL
) ||
3979 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
3981 size
= type_size(type
, &align
);
3982 loc
= (loc
- size
) & -align
;
3983 sv
.type
.t
= type
->t
;
3984 sv
.r
= VT_LOCAL
| VT_LVAL
;
3987 #ifdef TCC_TARGET_I386
3988 /* x86 specific: need to pop fp register ST0 if saved */
3989 if (r
== TREG_ST0
) {
3990 o(0xd9dd); /* fstp %st(1) */
3993 /* special long long case */
3994 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
4001 /* mark that stack entry as being saved on the stack */
4002 if (p
->r
& VT_LVAL
) {
4003 /* also suppress the bounded flag because the
4004 relocation address of the function was stored in
4006 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
4008 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
4016 /* find a free register of class 'rc'. If none, save one register */
4022 /* find a free register */
4023 for(r
=0;r
<NB_REGS
;r
++) {
4024 if (reg_classes
[r
] & rc
) {
4025 for(p
=vstack
;p
<=vtop
;p
++) {
4026 if ((p
->r
& VT_VALMASK
) == r
||
4027 (p
->r2
& VT_VALMASK
) == r
)
4035 /* no register left : free the first one on the stack (VERY
4036 IMPORTANT to start from the bottom to ensure that we don't
4037 spill registers used in gen_opi()) */
4038 for(p
=vstack
;p
<=vtop
;p
++) {
4039 r
= p
->r
& VT_VALMASK
;
4040 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
4042 /* also look at second register (if long long) */
4043 r
= p
->r2
& VT_VALMASK
;
4044 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
4050 /* Should never comes here */
4054 /* save registers up to (vtop - n) stack entry */
4055 void save_regs(int n
)
4060 for(p
= vstack
;p
<= p1
; p
++) {
4061 r
= p
->r
& VT_VALMASK
;
4068 /* move register 's' to 'r', and flush previous value of r to memory
4070 void move_reg(int r
, int s
)
4083 /* get address of vtop (vtop MUST BE an lvalue) */
4086 vtop
->r
&= ~VT_LVAL
;
4087 /* tricky: if saved lvalue, then we can go back to lvalue */
4088 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
4089 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
4092 #ifdef CONFIG_TCC_BCHECK
4093 /* generate lvalue bound code */
4099 vtop
->r
&= ~VT_MUSTBOUND
;
4100 /* if lvalue, then use checking code before dereferencing */
4101 if (vtop
->r
& VT_LVAL
) {
4102 /* if not VT_BOUNDED value, then make one */
4103 if (!(vtop
->r
& VT_BOUNDED
)) {
4104 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
4105 /* must save type because we must set it to int to get pointer */
4107 vtop
->type
.t
= VT_INT
;
4110 gen_bounded_ptr_add();
4111 vtop
->r
|= lval_type
;
4114 /* then check for dereferencing */
4115 gen_bounded_ptr_deref();
4120 /* store vtop a register belonging to class 'rc'. lvalues are
4121 converted to values. Cannot be used if cannot be converted to
4122 register value (such as structures). */
4125 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
4126 unsigned long long ll
;
4128 /* NOTE: get_reg can modify vstack[] */
4129 if (vtop
->type
.t
& VT_BITFIELD
) {
4130 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
4131 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4132 /* remove bit field info to avoid loops */
4133 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4134 /* generate shifts */
4135 vpushi(32 - (bit_pos
+ bit_size
));
4137 vpushi(32 - bit_size
);
4138 /* NOTE: transformed to SHR if unsigned */
4142 if (is_float(vtop
->type
.t
) &&
4143 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4146 unsigned long offset
;
4148 /* XXX: unify with initializers handling ? */
4149 /* CPUs usually cannot use float constants, so we store them
4150 generically in data segment */
4151 size
= type_size(&vtop
->type
, &align
);
4152 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
4153 data_section
->data_offset
= offset
;
4154 /* XXX: not portable yet */
4155 ptr
= section_ptr_add(data_section
, size
);
4158 ptr
[i
] = vtop
->c
.tab
[i
];
4159 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
4160 vtop
->r
|= VT_LVAL
| VT_SYM
;
4164 #ifdef CONFIG_TCC_BCHECK
4165 if (vtop
->r
& VT_MUSTBOUND
)
4169 r
= vtop
->r
& VT_VALMASK
;
4170 /* need to reload if:
4172 - lvalue (need to dereference pointer)
4173 - already a register, but not in the right class */
4174 if (r
>= VT_CONST
||
4175 (vtop
->r
& VT_LVAL
) ||
4176 !(reg_classes
[r
] & rc
) ||
4177 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
4178 !(reg_classes
[vtop
->r2
] & rc
))) {
4180 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
4181 /* two register type load : expand to two words
4183 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4186 vtop
->c
.ui
= ll
; /* first word */
4188 vtop
->r
= r
; /* save register value */
4189 vpushi(ll
>> 32); /* second word */
4190 } else if (r
>= VT_CONST
||
4191 (vtop
->r
& VT_LVAL
)) {
4192 /* load from memory */
4195 vtop
[-1].r
= r
; /* save register value */
4196 /* increment pointer to get second word */
4197 vtop
->type
.t
= VT_INT
;
4203 /* move registers */
4206 vtop
[-1].r
= r
; /* save register value */
4207 vtop
->r
= vtop
[-1].r2
;
4209 /* allocate second register */
4216 /* write second register */
4218 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
4220 /* lvalue of scalar type : need to use lvalue type
4221 because of possible cast */
4224 /* compute memory access type */
4225 if (vtop
->r
& VT_LVAL_BYTE
)
4227 else if (vtop
->r
& VT_LVAL_SHORT
)
4229 if (vtop
->r
& VT_LVAL_UNSIGNED
)
4233 /* restore wanted type */
4236 /* one register type load */
4245 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4246 void gv2(int rc1
, int rc2
)
4250 /* generate more generic register first. But VT_JMP or VT_CMP
4251 values must be generated first in all cases to avoid possible
4253 v
= vtop
[0].r
& VT_VALMASK
;
4254 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
4259 /* test if reload is needed for first register */
4260 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
4270 /* test if reload is needed for first register */
4271 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
4277 /* expand long long on stack in two int registers */
4282 u
= vtop
->type
.t
& VT_UNSIGNED
;
4285 vtop
[0].r
= vtop
[-1].r2
;
4286 vtop
[0].r2
= VT_CONST
;
4287 vtop
[-1].r2
= VT_CONST
;
4288 vtop
[0].type
.t
= VT_INT
| u
;
4289 vtop
[-1].type
.t
= VT_INT
| u
;
4292 /* build a long long from two ints */
4295 gv2(RC_INT
, RC_INT
);
4296 vtop
[-1].r2
= vtop
[0].r
;
4297 vtop
[-1].type
.t
= t
;
4301 /* rotate n first stack elements to the bottom */
4308 for(i
=-n
+1;i
!=0;i
++)
4309 vtop
[i
] = vtop
[i
+1];
4313 /* pop stack value */
4317 v
= vtop
->r
& VT_VALMASK
;
4318 #ifdef TCC_TARGET_I386
4319 /* for x86, we need to pop the FP stack */
4320 if (v
== TREG_ST0
&& !nocode_wanted
) {
4321 o(0xd9dd); /* fstp %st(1) */
4324 if (v
== VT_JMP
|| v
== VT_JMPI
) {
4325 /* need to put correct jump if && or || without test */
4331 /* convert stack entry to register and duplicate its value in another
4339 if ((t
& VT_BTYPE
) == VT_LLONG
) {
4346 /* stack: H L L1 H1 */
4354 /* duplicate value */
4365 load(r1
, &sv
); /* move r to r1 */
4367 /* duplicates value */
4372 /* generate CPU independent (unsigned) long long operations */
4373 void gen_opl(int op
)
4375 int t
, a
, b
, op1
, c
, i
;
4383 func
= TOK___divdi3
;
4386 func
= TOK___udivdi3
;
4389 func
= TOK___moddi3
;
4392 func
= TOK___umoddi3
;
4394 /* call generic long long function */
4395 gfunc_start(&gf
, FUNC_CDECL
);
4398 vpush_global_sym(&func_old_type
, func
);
4402 vtop
->r2
= REG_LRET
;
4415 /* stack: L1 H1 L2 H2 */
4420 vtop
[-2] = vtop
[-3];
4423 /* stack: H1 H2 L1 L2 */
4429 /* stack: H1 H2 L1 L2 ML MH */
4432 /* stack: ML MH H1 H2 L1 L2 */
4436 /* stack: ML MH H1 L2 H2 L1 */
4441 /* stack: ML MH M1 M2 */
4444 } else if (op
== '+' || op
== '-') {
4445 /* XXX: add non carry method too (for MIPS or alpha) */
4451 /* stack: H1 H2 (L1 op L2) */
4454 gen_op(op1
+ 1); /* TOK_xxxC2 */
4457 /* stack: H1 H2 (L1 op L2) */
4460 /* stack: (L1 op L2) H1 H2 */
4462 /* stack: (L1 op L2) (H1 op H2) */
4470 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4471 t
= vtop
[-1].type
.t
;
4475 /* stack: L H shift */
4477 /* constant: simpler */
4478 /* NOTE: all comments are for SHL. the other cases are
4479 done by swaping words */
4490 if (op
!= TOK_SAR
) {
4523 /* XXX: should provide a faster fallback on x86 ? */
4526 func
= TOK___sardi3
;
4529 func
= TOK___shrdi3
;
4532 func
= TOK___shldi3
;
4538 /* compare operations */
4544 /* stack: L1 H1 L2 H2 */
4546 vtop
[-1] = vtop
[-2];
4548 /* stack: L1 L2 H1 H2 */
4551 /* when values are equal, we need to compare low words. since
4552 the jump is inverted, we invert the test too. */
4555 else if (op1
== TOK_GT
)
4557 else if (op1
== TOK_ULT
)
4559 else if (op1
== TOK_UGT
)
4564 if (op1
!= TOK_NE
) {
4568 /* generate non equal test */
4569 /* XXX: NOT PORTABLE yet */
4573 #ifdef TCC_TARGET_I386
4574 b
= psym(0x850f, 0);
4576 error("not implemented");
4580 /* compare low. Always unsigned */
4584 else if (op1
== TOK_LE
)
4586 else if (op1
== TOK_GT
)
4588 else if (op1
== TOK_GE
)
4598 /* handle integer constant optimizations and various machine
4600 void gen_opic(int op
)
4607 /* currently, we cannot do computations with forward symbols */
4608 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4609 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4613 case '+': v1
->c
.i
+= fc
; break;
4614 case '-': v1
->c
.i
-= fc
; break;
4615 case '&': v1
->c
.i
&= fc
; break;
4616 case '^': v1
->c
.i
^= fc
; break;
4617 case '|': v1
->c
.i
|= fc
; break;
4618 case '*': v1
->c
.i
*= fc
; break;
4625 /* if division by zero, generate explicit division */
4628 error("division by zero in constant");
4632 default: v1
->c
.i
/= fc
; break;
4633 case '%': v1
->c
.i
%= fc
; break;
4634 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
4635 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
4638 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
4639 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
4640 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
4642 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
4643 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
4644 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
4645 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
4646 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
4647 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
4648 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
4649 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
4650 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
4651 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
4653 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
4654 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
4660 /* if commutative ops, put c2 as constant */
4661 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
4662 op
== '|' || op
== '*')) {
4667 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
4670 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
4671 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
4677 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
4678 /* try to use shifts instead of muls or divs */
4679 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
4688 else if (op
== TOK_PDIV
)
4694 } else if (c2
&& (op
== '+' || op
== '-') &&
4695 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
4696 (VT_CONST
| VT_SYM
)) {
4697 /* symbol + constant case */
4704 if (!nocode_wanted
) {
4705 /* call low level op generator */
4714 /* generate a floating point operation with constant propagation */
4715 void gen_opif(int op
)
4723 /* currently, we cannot do computations with forward symbols */
4724 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4725 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4727 if (v1
->type
.t
== VT_FLOAT
) {
4730 } else if (v1
->type
.t
== VT_DOUBLE
) {
4738 /* NOTE: we only do constant propagation if finite number (not
4739 NaN or infinity) (ANSI spec) */
4740 if (!ieee_finite(f1
) || !ieee_finite(f2
))
4744 case '+': f1
+= f2
; break;
4745 case '-': f1
-= f2
; break;
4746 case '*': f1
*= f2
; break;
4750 error("division by zero in constant");
4755 /* XXX: also handles tests ? */
4759 /* XXX: overflow test ? */
4760 if (v1
->type
.t
== VT_FLOAT
) {
4762 } else if (v1
->type
.t
== VT_DOUBLE
) {
4770 if (!nocode_wanted
) {
4778 static int pointed_size(CType
*type
)
4781 return type_size(pointed_type(type
), &align
);
4785 void check_pointer_types(SValue
*p1
, SValue
*p2
)
4787 char buf1
[256], buf2
[256];
4791 if (!is_compatible_types(t1
, t2
)) {
4792 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
4793 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
4794 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
4799 /* generic gen_op: handles types problems */
4802 int u
, t1
, t2
, bt1
, bt2
, t
;
4805 t1
= vtop
[-1].type
.t
;
4806 t2
= vtop
[0].type
.t
;
4807 bt1
= t1
& VT_BTYPE
;
4808 bt2
= t2
& VT_BTYPE
;
4810 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
4811 /* at least one operand is a pointer */
4812 /* relationnal op: must be both pointers */
4813 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4814 // check_pointer_types(vtop, vtop - 1);
4815 /* pointers are handled are unsigned */
4816 t
= VT_INT
| VT_UNSIGNED
;
4819 /* if both pointers, then it must be the '-' op */
4820 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
4822 error("cannot use pointers here");
4823 // check_pointer_types(vtop - 1, vtop);
4824 /* XXX: check that types are compatible */
4825 u
= pointed_size(&vtop
[-1].type
);
4827 /* set to integer type */
4828 vtop
->type
.t
= VT_INT
;
4832 /* exactly one pointer : must be '+' or '-'. */
4833 if (op
!= '-' && op
!= '+')
4834 error("cannot use pointers here");
4835 /* Put pointer as first operand */
4836 if (bt2
== VT_PTR
) {
4840 type1
= vtop
[-1].type
;
4841 /* XXX: cast to int ? (long long case) */
4842 vpushi(pointed_size(&vtop
[-1].type
));
4844 #ifdef CONFIG_TCC_BCHECK
4845 /* if evaluating constant expression, no code should be
4846 generated, so no bound check */
4847 if (do_bounds_check
&& !const_wanted
) {
4848 /* if bounded pointers, we generate a special code to
4855 gen_bounded_ptr_add();
4861 /* put again type if gen_opic() swaped operands */
4864 } else if (is_float(bt1
) || is_float(bt2
)) {
4865 /* compute bigger type and do implicit casts */
4866 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
4868 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
4873 /* floats can only be used for a few operations */
4874 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
4875 (op
< TOK_ULT
|| op
> TOK_GT
))
4876 error("invalid operands for binary operation");
4878 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
4879 /* cast to biggest op */
4881 /* convert to unsigned if it does not fit in a long long */
4882 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4883 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4887 /* integer operations */
4889 /* convert to unsigned if it does not fit in an integer */
4890 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4891 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4894 /* XXX: currently, some unsigned operations are explicit, so
4895 we modify them here */
4896 if (t
& VT_UNSIGNED
) {
4903 else if (op
== TOK_LT
)
4905 else if (op
== TOK_GT
)
4907 else if (op
== TOK_LE
)
4909 else if (op
== TOK_GE
)
4916 /* special case for shifts and long long: we keep the shift as
4918 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
4923 else if ((t
& VT_BTYPE
) == VT_LLONG
)
4927 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4928 /* relationnal op: the result is an int */
4929 vtop
->type
.t
= VT_INT
;
4936 /* generic itof for unsigned long long case */
4937 void gen_cvt_itof1(int t
)
4941 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
4942 (VT_LLONG
| VT_UNSIGNED
)) {
4944 gfunc_start(&gf
, FUNC_CDECL
);
4947 vpush_global_sym(&func_old_type
, TOK___ulltof
);
4948 else if (t
== VT_DOUBLE
)
4949 vpush_global_sym(&func_old_type
, TOK___ulltod
);
4951 vpush_global_sym(&func_old_type
, TOK___ulltold
);
4960 /* generic ftoi for unsigned long long case */
4961 void gen_cvt_ftoi1(int t
)
4966 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
4967 /* not handled natively */
4968 gfunc_start(&gf
, FUNC_CDECL
);
4969 st
= vtop
->type
.t
& VT_BTYPE
;
4972 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
4973 else if (st
== VT_DOUBLE
)
4974 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
4976 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
4980 vtop
->r2
= REG_LRET
;
4986 /* force char or short cast */
4987 void force_charshort_cast(int t
)
4991 /* XXX: add optimization if lvalue : just change type and offset */
4996 if (t
& VT_UNSIGNED
) {
4997 vpushi((1 << bits
) - 1);
5008 /* cast 'vtop' to 'type' */
5009 static void gen_cast(CType
*type
)
5011 int sbt
, dbt
, sf
, df
, c
;
5013 /* special delayed cast for char/short */
5014 /* XXX: in some cases (multiple cascaded casts), it may still
5016 if (vtop
->r
& VT_MUSTCAST
) {
5017 vtop
->r
&= ~VT_MUSTCAST
;
5018 force_charshort_cast(vtop
->type
.t
);
5021 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
5022 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5024 if (sbt
!= dbt
&& !nocode_wanted
) {
5027 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5029 /* convert from fp to fp */
5031 /* constant case: we can do it now */
5032 /* XXX: in ISOC, cannot do it if error in convert */
5033 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
5034 vtop
->c
.f
= (float)vtop
->c
.d
;
5035 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
5036 vtop
->c
.f
= (float)vtop
->c
.ld
;
5037 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
5038 vtop
->c
.d
= (double)vtop
->c
.f
;
5039 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
5040 vtop
->c
.d
= (double)vtop
->c
.ld
;
5041 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
5042 vtop
->c
.ld
= (long double)vtop
->c
.f
;
5043 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
5044 vtop
->c
.ld
= (long double)vtop
->c
.d
;
5046 /* non constant case: generate code */
5050 /* convert int to fp */
5053 case VT_LLONG
| VT_UNSIGNED
:
5055 /* XXX: add const cases for long long */
5057 case VT_INT
| VT_UNSIGNED
:
5059 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
5060 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
5061 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
5066 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
5067 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
5068 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
5077 /* convert fp to int */
5078 /* we handle char/short/etc... with generic code */
5079 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
5080 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
5085 case VT_LLONG
| VT_UNSIGNED
:
5087 /* XXX: add const cases for long long */
5089 case VT_INT
| VT_UNSIGNED
:
5091 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5092 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5093 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5099 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5100 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5101 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5109 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
5110 /* additionnal cast for char/short/bool... */
5114 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
5115 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
5116 /* scalar to long long */
5118 if (sbt
== (VT_INT
| VT_UNSIGNED
))
5119 vtop
->c
.ll
= vtop
->c
.ui
;
5121 vtop
->c
.ll
= vtop
->c
.i
;
5123 /* machine independant conversion */
5125 /* generate high word */
5126 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
5134 /* patch second register */
5135 vtop
[-1].r2
= vtop
->r
;
5139 } else if (dbt
== VT_BOOL
) {
5140 /* scalar to bool */
5143 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
5144 (dbt
& VT_BTYPE
) == VT_SHORT
) {
5145 force_charshort_cast(dbt
);
5146 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
5148 if (sbt
== VT_LLONG
) {
5149 /* from long long: just take low order word */
5153 /* if lvalue and single word type, nothing to do because
5154 the lvalue already contains the real type size (see
5155 VT_LVAL_xxx constants) */
5161 /* return type size. Put alignment at 'a' */
5162 static int type_size(CType
*type
, int *a
)
5167 bt
= type
->t
& VT_BTYPE
;
5168 if (bt
== VT_STRUCT
) {
5173 } else if (bt
== VT_PTR
) {
5174 if (type
->t
& VT_ARRAY
) {
5176 return type_size(&s
->type
, a
) * s
->c
;
5181 } else if (bt
== VT_LDOUBLE
) {
5183 return LDOUBLE_SIZE
;
5184 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
5185 *a
= 4; /* XXX: i386 specific */
5187 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
5190 } else if (bt
== VT_SHORT
) {
5194 /* char, void, function, _Bool */
5200 /* return the pointed type of t */
5201 static inline CType
*pointed_type(CType
*type
)
5203 return &type
->ref
->type
;
5206 /* modify type so that its it is a pointer to type. */
5207 static void mk_pointer(CType
*type
)
5210 s
= sym_push(SYM_FIELD
, type
, 0, -1);
5211 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
5215 static int is_compatible_types(CType
*type1
, CType
*type2
)
5218 int bt1
, bt2
, t1
, t2
;
5220 t1
= type1
->t
& VT_TYPE
;
5221 t2
= type2
->t
& VT_TYPE
;
5222 bt1
= t1
& VT_BTYPE
;
5223 bt2
= t2
& VT_BTYPE
;
5224 if (bt1
== VT_PTR
) {
5225 type1
= pointed_type(type1
);
5226 /* if function, then convert implicitely to function pointer */
5227 if (bt2
!= VT_FUNC
) {
5230 type2
= pointed_type(type2
);
5232 /* void matches everything */
5233 /* XXX: not fully compliant */
5234 if ((type1
->t
& VT_TYPE
) == VT_VOID
|| (type2
->t
& VT_TYPE
) == VT_VOID
)
5236 return is_compatible_types(type1
, type2
);
5237 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
5238 return (type1
->ref
== type2
->ref
);
5239 } else if (bt1
== VT_FUNC
) {
5244 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5246 /* XXX: not complete */
5247 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
5251 while (s1
!= NULL
) {
5254 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5263 /* XXX: not complete */
5268 /* print a type. If 'varstr' is not NULL, then the variable is also
5269 printed in the type */
5271 /* XXX: add array and function pointers */
5272 void type_to_str(char *buf
, int buf_size
,
5273 CType
*type
, const char *varstr
)
5280 t
= type
->t
& VT_TYPE
;
5283 if (t
& VT_UNSIGNED
)
5284 pstrcat(buf
, buf_size
, "unsigned ");
5314 tstr
= "long double";
5316 pstrcat(buf
, buf_size
, tstr
);
5320 if (bt
== VT_STRUCT
)
5324 pstrcat(buf
, buf_size
, tstr
);
5325 v
= type
->ref
->v
& ~SYM_STRUCT
;
5326 if (v
>= SYM_FIRST_ANOM
)
5327 pstrcat(buf
, buf_size
, "<anonymous>");
5329 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
5333 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
5334 pstrcat(buf
, buf_size
, "(");
5336 while (sa
!= NULL
) {
5337 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
5338 pstrcat(buf
, buf_size
, buf1
);
5341 pstrcat(buf
, buf_size
, ", ");
5343 pstrcat(buf
, buf_size
, ")");
5347 pstrcpy(buf1
, sizeof(buf1
), "*");
5349 pstrcat(buf1
, sizeof(buf1
), varstr
);
5350 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
5354 pstrcat(buf
, buf_size
, " ");
5355 pstrcat(buf
, buf_size
, varstr
);
5360 /* verify type compatibility to store vtop in 'dt' type, and generate
5362 static void gen_assign_cast(CType
*dt
)
5365 char buf1
[256], buf2
[256];
5368 st
= &vtop
->type
; /* source type */
5369 dbt
= dt
->t
& VT_BTYPE
;
5370 sbt
= st
->t
& VT_BTYPE
;
5371 if (dbt
== VT_PTR
) {
5372 /* special cases for pointers */
5373 /* a function is implicitely a function pointer */
5374 if (sbt
== VT_FUNC
) {
5375 if (!is_compatible_types(pointed_type(dt
), st
))
5380 /* '0' can also be a pointer */
5381 if (sbt
== VT_INT
&&
5382 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
5385 /* accept implicit pointer to integer cast with warning */
5386 if (sbt
== VT_BYTE
|| sbt
== VT_SHORT
||
5387 sbt
== VT_INT
|| sbt
== VT_LLONG
) {
5388 warning("assignment makes pointer from integer without a cast");
5391 } else if (dbt
== VT_BYTE
|| dbt
== VT_SHORT
||
5392 dbt
== VT_INT
|| dbt
== VT_LLONG
) {
5393 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
5394 warning("assignment makes integer from pointer without a cast");
5398 if (!is_compatible_types(dt
, st
)) {
5400 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
5401 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
5402 error("cannot cast '%s' to '%s'", buf1
, buf2
);
5408 /* store vtop in lvalue pushed on stack */
5411 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
5414 ft
= vtop
[-1].type
.t
;
5415 sbt
= vtop
->type
.t
& VT_BTYPE
;
5416 dbt
= ft
& VT_BTYPE
;
5417 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
5418 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
5419 /* optimize char/short casts */
5420 delayed_cast
= VT_MUSTCAST
;
5421 vtop
->type
.t
= ft
& VT_TYPE
;
5424 gen_assign_cast(&vtop
[-1].type
);
5427 if (sbt
== VT_STRUCT
) {
5428 /* if structure, only generate pointer */
5429 /* structure assignment : generate memcpy */
5430 /* XXX: optimize if small size */
5431 if (!nocode_wanted
) {
5433 gfunc_start(&gf
, FUNC_CDECL
);
5435 size
= type_size(&vtop
->type
, &align
);
5439 vtop
->type
.t
= VT_INT
;
5444 vtop
->type
.t
= VT_INT
;
5449 vpush_global_sym(&func_old_type
, TOK_memcpy
);
5455 /* leave source on stack */
5456 } else if (ft
& VT_BITFIELD
) {
5457 /* bitfield store handling */
5458 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
5459 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
5460 /* remove bit field info to avoid loops */
5461 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
5463 /* duplicate destination */
5465 vtop
[-1] = vtop
[-2];
5467 /* mask and shift source */
5468 vpushi((1 << bit_size
) - 1);
5472 /* load destination, mask and or with source */
5474 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
5480 #ifdef CONFIG_TCC_BCHECK
5481 /* bound check case */
5482 if (vtop
[-1].r
& VT_MUSTBOUND
) {
5488 if (!nocode_wanted
) {
5492 r
= gv(rc
); /* generate value */
5493 /* if lvalue was saved on stack, must read it */
5494 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
5496 t
= get_reg(RC_INT
);
5498 sv
.r
= VT_LOCAL
| VT_LVAL
;
5499 sv
.c
.ul
= vtop
[-1].c
.ul
;
5501 vtop
[-1].r
= t
| VT_LVAL
;
5504 /* two word case handling : store second register at word + 4 */
5505 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
5507 /* convert to int to increment easily */
5508 vtop
->type
.t
= VT_INT
;
5514 /* XXX: it works because r2 is spilled last ! */
5515 store(vtop
->r2
, vtop
- 1);
5519 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5520 vtop
->r
|= delayed_cast
;
5524 /* post defines POST/PRE add. c is the token ++ or -- */
5525 void inc(int post
, int c
)
5528 vdup(); /* save lvalue */
5530 gv_dup(); /* duplicate value */
5535 vpushi(c
- TOK_MID
);
5537 vstore(); /* store value */
5539 vpop(); /* if post op, return saved value */
5542 /* Parse GNUC __attribute__ extension. Currently, the following
5543 extensions are recognized:
5544 - aligned(n) : set data/function alignment.
5545 - section(x) : generate data/code in this section.
5546 - unused : currently ignored, but may be used someday.
5548 void parse_attribute(AttributeDef
*ad
)
5555 while (tok
!= ')') {
5556 if (tok
< TOK_IDENT
)
5557 expect("attribute name");
5562 case TOK___SECTION__
:
5565 expect("section name");
5566 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
5571 case TOK___ALIGNED__
:
5575 if (n
<= 0 || (n
& (n
- 1)) != 0)
5576 error("alignment must be a positive power of two");
5584 case TOK___UNUSED__
:
5585 /* currently, no need to handle it because tcc does not
5586 track unused objects */
5589 case TOK___NORETURN__
:
5590 /* currently, no need to handle it because tcc does not
5591 track unused objects */
5596 ad
->func_call
= FUNC_CDECL
;
5600 case TOK___STDCALL__
:
5601 ad
->func_call
= FUNC_STDCALL
;
5604 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
5605 /* skip parameters */
5606 /* XXX: skip parenthesis too */
5609 while (tok
!= ')' && tok
!= -1)
5623 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5624 static void struct_decl(CType
*type
, int u
)
5626 int a
, v
, size
, align
, maxalign
, c
, offset
;
5627 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
5632 a
= tok
; /* save decl type */
5637 /* struct already defined ? return it */
5638 /* XXX: check consistency */
5642 error("invalid type");
5649 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, 0);
5650 /* put struct/union/enum name in type */
5658 error("struct/union/enum already defined");
5659 /* cannot be empty */
5661 /* non empty enums are not allowed */
5662 if (a
== TOK_ENUM
) {
5666 expect("identifier");
5672 /* enum symbols have static storage */
5673 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
5674 ss
->type
.t
|= VT_STATIC
;
5679 /* NOTE: we accept a trailing comma */
5689 while (tok
!= '}') {
5690 parse_btype(&btype
, &ad
);
5696 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
);
5697 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
5698 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
5699 error("invalid type for '%s'",
5700 get_tok_str(v
, NULL
));
5704 bit_size
= expr_const();
5705 /* XXX: handle v = 0 case for messages */
5707 error("negative width in bit-field '%s'",
5708 get_tok_str(v
, NULL
));
5709 if (v
&& bit_size
== 0)
5710 error("zero width for bit-field '%s'",
5711 get_tok_str(v
, NULL
));
5713 size
= type_size(&type1
, &align
);
5715 if (bit_size
>= 0) {
5716 bt
= type1
.t
& VT_BTYPE
;
5721 error("bitfields must have scalar type");
5723 if (bit_size
> bsize
) {
5724 error("width of '%s' exceeds its type",
5725 get_tok_str(v
, NULL
));
5726 } else if (bit_size
== bsize
) {
5727 /* no need for bit fields */
5729 } else if (bit_size
== 0) {
5730 /* XXX: what to do if only padding in a
5732 /* zero size: means to pad */
5736 /* we do not have enough room ? */
5737 if ((bit_pos
+ bit_size
) > bsize
)
5740 /* XXX: handle LSB first */
5741 type1
.t
|= VT_BITFIELD
|
5742 (bit_pos
<< VT_STRUCT_SHIFT
) |
5743 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
5744 bit_pos
+= bit_size
;
5750 /* add new memory data only if starting
5752 if (lbit_pos
== 0) {
5753 if (a
== TOK_STRUCT
) {
5754 c
= (c
+ align
- 1) & -align
;
5762 if (align
> maxalign
)
5766 printf("add field %s offset=%d",
5767 get_tok_str(v
, NULL
), offset
);
5768 if (type1
.t
& VT_BITFIELD
) {
5769 printf(" pos=%d size=%d",
5770 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
5771 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
5775 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
5779 if (tok
== ';' || tok
== TOK_EOF
)
5786 /* store size and alignment */
5787 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
5793 /* return 0 if no type declaration. otherwise, return the basic type
5796 static int parse_btype(CType
*type
, AttributeDef
*ad
)
5798 int t
, u
, type_found
;
5802 memset(ad
, 0, sizeof(AttributeDef
));
5813 if ((t
& VT_BTYPE
) != 0)
5814 error("too many basic types");
5828 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
5829 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5830 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
5831 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
5845 if ((t
& VT_BTYPE
) == VT_LONG
) {
5846 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5853 struct_decl(&type1
, VT_ENUM
);
5856 type
->ref
= type1
.ref
;
5860 struct_decl(&type1
, VT_STRUCT
);
5863 /* type modifiers */
5868 case TOK___SIGNED__
:
5871 case TOK___INLINE__
:
5893 /* GNUC attribute */
5894 case TOK___ATTRIBUTE__
:
5895 parse_attribute(ad
);
5900 parse_expr_type(&type1
);
5904 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
5906 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
5907 type
->ref
= s
->type
.ref
;
5914 /* long is never used as type */
5915 if ((t
& VT_BTYPE
) == VT_LONG
)
5916 t
= (t
& ~VT_BTYPE
) | VT_INT
;
5921 static void post_type(CType
*type
, AttributeDef
*ad
)
5924 Sym
**plast
, *s
, *first
;
5929 /* function declaration */
5934 while (tok
!= ')') {
5935 /* read param name and compute offset */
5936 if (l
!= FUNC_OLD
) {
5937 if (!parse_btype(&pt
, &ad1
)) {
5939 error("invalid type");
5946 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5948 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
5949 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
5950 error("parameter declared as void");
5957 /* array must be transformed to pointer according to ANSI C */
5959 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
5964 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5971 /* if no parameters, then old type prototype */
5975 t1
= type
->t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5976 type
->t
&= ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5977 post_type(type
, ad
);
5978 /* we push a anonymous symbol which will contain the function prototype */
5979 s
= sym_push(SYM_FIELD
, type
, ad
->func_call
, l
);
5981 type
->t
= t1
| VT_FUNC
;
5983 } else if (tok
== '[') {
5984 /* array definition */
5990 error("invalid array size");
5993 /* parse next post type */
5994 t1
= type
->t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5995 type
->t
&= ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5996 post_type(type
, ad
);
5998 /* we push a anonymous symbol which will contain the array
6000 s
= sym_push(SYM_FIELD
, type
, 0, n
);
6001 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
6006 /* Parse a type declaration (except basic type), and return the type
6007 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6008 expected. 'type' should contain the basic type. 'ad' is the
6009 attribute definition of the basic type. It can be modified by
6012 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
6015 CType type1
, *type2
;
6017 while (tok
== '*') {
6019 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
6024 /* recursive type */
6025 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6026 type1
.t
= 0; /* XXX: same as int */
6029 /* XXX: this is not correct to modify 'ad' at this point, but
6030 the syntax is not clear */
6031 if (tok
== TOK___ATTRIBUTE__
)
6032 parse_attribute(ad
);
6033 type_decl(&type1
, ad
, v
, td
);
6036 /* type identifier */
6037 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
6041 if (!(td
& TYPE_ABSTRACT
))
6042 expect("identifier");
6046 post_type(type
, ad
);
6047 if (tok
== TOK___ATTRIBUTE__
)
6048 parse_attribute(ad
);
6051 /* append type at the end of type1 */
6064 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6065 static int lvalue_type(int t
)
6072 else if (bt
== VT_SHORT
)
6076 if (t
& VT_UNSIGNED
)
6077 r
|= VT_LVAL_UNSIGNED
;
6081 /* indirection with full error checking and bound check */
6082 static void indir(void)
6084 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
6086 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
6088 vtop
->type
= *pointed_type(&vtop
->type
);
6089 /* an array is never an lvalue */
6090 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6091 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6092 /* if bound checking, the referenced pointer must be checked */
6093 if (do_bounds_check
)
6094 vtop
->r
|= VT_MUSTBOUND
;
6098 /* pass a parameter to a function and do type checking and casting */
6099 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
6104 func_type
= func
->c
;
6105 if (func_type
== FUNC_OLD
||
6106 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
6107 /* default casting : only need to convert float to double */
6108 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
6112 } else if (arg
== NULL
) {
6113 error("too many arguments to function");
6115 gen_assign_cast(&arg
->type
);
6117 if (!nocode_wanted
) {
6124 /* parse an expression of the form '(type)' or '(expr)' and return its
6126 static void parse_expr_type(CType
*type
)
6132 if (parse_btype(type
, &ad
)) {
6133 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
6140 static void vpush_tokc(int t
)
6144 vsetc(&type
, VT_CONST
, &tokc
);
6147 static void unary(void)
6149 int n
, t
, align
, size
, r
;
6155 /* XXX: GCC 2.95.3 does not generate a table although it should be
6165 vpush_tokc(VT_INT
| VT_UNSIGNED
);
6169 vpush_tokc(VT_LLONG
);
6173 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
6177 vpush_tokc(VT_FLOAT
);
6181 vpush_tokc(VT_DOUBLE
);
6185 vpush_tokc(VT_LDOUBLE
);
6188 case TOK___FUNCTION__
:
6190 goto tok_identifier
;
6196 /* special function name identifier */
6197 len
= strlen(funcname
) + 1;
6198 /* generate char[len] type */
6203 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
6204 ptr
= section_ptr_add(data_section
, len
);
6205 memcpy(ptr
, funcname
, len
);
6213 /* string parsing */
6219 memset(&ad
, 0, sizeof(AttributeDef
));
6220 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
6225 if (parse_btype(&type
, &ad
)) {
6226 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
6228 /* check ISOC99 compound literal */
6230 /* data is allocated locally by default */
6235 /* all except arrays are lvalues */
6236 if (!(type
.t
& VT_ARRAY
))
6237 r
|= lvalue_type(type
.t
);
6238 memset(&ad
, 0, sizeof(AttributeDef
));
6239 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
6257 /* functions names must be treated as function pointers,
6258 except for unary '&' and sizeof. Since we consider that
6259 functions are not lvalues, we only have to handle it
6260 there and in function calls. */
6261 /* arrays can also be used although they are not lvalues */
6262 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
6263 !(vtop
->type
.t
& VT_ARRAY
))
6265 mk_pointer(&vtop
->type
);
6271 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
6272 vtop
->c
.i
= !vtop
->c
.i
;
6273 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
6274 vtop
->c
.i
= vtop
->c
.i
^ 1;
6276 vseti(VT_JMP
, gtst(1, 0));
6286 /* in order to force cast, we add zero */
6288 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
6289 error("pointer not accepted for unary plus");
6298 parse_expr_type(&type
);
6302 size
= type_size(&type
, &align
);
6303 if (t
== TOK_SIZEOF
)
6324 goto tok_identifier
;
6326 /* allow to take the address of a label */
6327 if (tok
< TOK_UIDENT
)
6328 expect("label identifier");
6329 s
= label_find(tok
);
6331 s
= label_push(tok
, LABEL_FORWARD
);
6334 s
->type
.t
= VT_VOID
;
6335 mk_pointer(&s
->type
);
6336 s
->type
.t
|= VT_STATIC
;
6338 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
6347 expect("identifier");
6351 error("'%s' undeclared", get_tok_str(t
, NULL
));
6352 /* for simple function calls, we tolerate undeclared
6353 external reference to int() function */
6354 s
= external_global_sym(t
, &func_old_type
, 0);
6356 vset(&s
->type
, s
->r
, s
->c
);
6357 /* if forward reference, we must point to s */
6358 if (vtop
->r
& VT_SYM
) {
6365 /* post operations */
6367 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
6370 } else if (tok
== '.' || tok
== TOK_ARROW
) {
6372 if (tok
== TOK_ARROW
)
6377 /* expect pointer on structure */
6378 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
6379 expect("struct or union");
6383 while ((s
= s
->next
) != NULL
) {
6388 error("field not found");
6389 /* add field offset to pointer */
6390 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
6393 /* change type to field type, and set to lvalue */
6394 vtop
->type
= s
->type
;
6395 /* an array is never an lvalue */
6396 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6397 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6398 /* if bound checking, the referenced pointer must be checked */
6399 if (do_bounds_check
)
6400 vtop
->r
|= VT_MUSTBOUND
;
6403 } else if (tok
== '[') {
6409 } else if (tok
== '(') {
6414 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
6415 /* pointer test (no array accepted) */
6416 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
6417 vtop
->type
= *pointed_type(&vtop
->type
);
6418 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
6422 expect("function pointer");
6425 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
6427 /* get return type */
6429 if (!nocode_wanted
) {
6430 save_regs(0); /* save used temporary registers */
6431 gfunc_start(&gf
, s
->r
);
6434 sa
= s
->next
; /* first parameter */
6435 #ifdef INVERT_FUNC_PARAMS
6439 ParseState saved_parse_state
;
6442 /* read each argument and store it on a stack */
6448 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
6452 else if (tok
== ')')
6454 tok_str_add_tok(&str
);
6457 tok_str_add(&str
, -1); /* end of file added */
6458 tok_str_add(&str
, 0);
6459 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
6460 s1
->next
= sa
; /* add reference to argument */
6469 /* now generate code in reverse order by reading the stack */
6470 save_parse_state(&saved_parse_state
);
6472 macro_ptr
= (int *)args
->c
;
6476 expect("',' or ')'");
6477 gfunc_param_typed(&gf
, s
, args
->next
);
6479 tok_str_free((int *)args
->c
);
6483 restore_parse_state(&saved_parse_state
);
6486 /* compute first implicit argument if a structure is returned */
6487 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
6488 /* get some space for the returned structure */
6489 size
= type_size(&s
->type
, &align
);
6490 loc
= (loc
- size
) & -align
;
6492 ret
.r
= VT_LOCAL
| VT_LVAL
;
6493 /* pass it as 'int' to avoid structure arg passing
6495 vseti(VT_LOCAL
, loc
);
6504 /* return in register */
6505 if (is_float(ret
.type
.t
)) {
6508 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
6514 #ifndef INVERT_FUNC_PARAMS
6518 gfunc_param_typed(&gf
, s
, sa
);
6528 error("too few arguments to function");
6535 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
6543 static void uneq(void)
6549 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
6550 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
6551 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
6566 static void expr_prod(void)
6571 while (tok
== '*' || tok
== '/' || tok
== '%') {
6579 static void expr_sum(void)
6584 while (tok
== '+' || tok
== '-') {
6592 static void expr_shift(void)
6597 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
6605 static void expr_cmp(void)
6610 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
6611 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
6619 static void expr_cmpeq(void)
6624 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
6632 static void expr_and(void)
6635 while (tok
== '&') {
6642 static void expr_xor(void)
6645 while (tok
== '^') {
6652 static void expr_or(void)
6655 while (tok
== '|') {
6662 /* XXX: suppress this mess */
6663 static void expr_land_const(void)
6666 while (tok
== TOK_LAND
) {
6673 /* XXX: suppress this mess */
6674 static void expr_lor_const(void)
6677 while (tok
== TOK_LOR
) {
6684 /* only used if non constant */
6685 static void expr_land(void)
6690 if (tok
== TOK_LAND
) {
6694 if (tok
!= TOK_LAND
) {
6704 static void expr_lor(void)
6709 if (tok
== TOK_LOR
) {
6713 if (tok
!= TOK_LOR
) {
6723 /* XXX: better constant handling */
6724 static void expr_eq(void)
6726 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
6728 CType type
, type1
, type2
;
6749 if (vtop
!= vstack
) {
6750 /* needed to avoid having different registers saved in
6752 if (is_float(vtop
->type
.t
))
6762 sv
= *vtop
; /* save value to handle it later */
6763 vtop
--; /* no vpop so that FP stack is not flushed */
6771 bt1
= t1
& VT_BTYPE
;
6773 bt2
= t2
& VT_BTYPE
;
6774 /* cast operands to correct type according to ISOC rules */
6775 if (is_float(bt1
) || is_float(bt2
)) {
6776 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
6777 type
.t
= VT_LDOUBLE
;
6778 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
6783 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
6784 /* cast to biggest op */
6786 /* convert to unsigned if it does not fit in a long long */
6787 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
6788 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
6789 type
.t
|= VT_UNSIGNED
;
6790 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
6791 /* XXX: test pointer compatibility */
6793 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
6794 /* XXX: test structure compatibility */
6796 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
6797 /* NOTE: as an extension, we accept void on only one side */
6800 /* integer operations */
6802 /* convert to unsigned if it does not fit in an integer */
6803 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
6804 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
6805 type
.t
|= VT_UNSIGNED
;
6808 /* now we convert second operand */
6811 if (is_float(type
.t
)) {
6813 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
6814 /* for long longs, we use fixed registers to avoid having
6815 to handle a complicated move */
6820 /* this is horrible, but we must also convert first
6824 /* put again first value and cast it */
6835 static void gexpr(void)
6846 /* parse an expression and return its type without any side effect. */
6847 static void expr_type(CType
*type
)
6859 /* parse a unary expression and return its type without any side
6861 static void unary_type(CType
*type
)
6873 /* parse a constant expression and return value in vtop. */
6874 static void expr_const1(void)
6883 /* parse an integer constant and return its value. */
6884 static int expr_const(void)
6888 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
6889 expect("constant expression");
6895 /* return the label token if current token is a label, otherwise
6897 static int is_label(void)
6902 /* fast test first */
6903 if (tok
< TOK_UIDENT
)
6905 /* no need to save tokc since we expect an identifier */
6913 /* XXX: may not work in all cases (macros ?) */
6922 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
6927 /* generate line number info */
6929 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
6930 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
6932 last_line_num
= file
->line_num
;
6935 if (tok
== TOK_IF
) {
6942 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6944 if (c
== TOK_ELSE
) {
6948 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6949 gsym(d
); /* patch else jmp */
6952 } else if (tok
== TOK_WHILE
) {
6960 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6964 } else if (tok
== '{') {
6968 while (tok
!= '}') {
6971 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6973 /* pop locally defined symbols */
6974 sym_pop(&local_stack
, s
);
6976 } else if (tok
== TOK_RETURN
) {
6980 gen_assign_cast(&func_vt
);
6981 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
6983 /* if returning structure, must copy it to implicit
6984 first pointer arg location */
6987 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
6990 /* copy structure value to pointer */
6992 } else if (is_float(func_vt
.t
)) {
6997 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
7000 rsym
= gjmp(rsym
); /* jmp */
7001 } else if (tok
== TOK_BREAK
) {
7004 error("cannot break");
7005 *bsym
= gjmp(*bsym
);
7008 } else if (tok
== TOK_CONTINUE
) {
7011 error("cannot continue");
7012 *csym
= gjmp(*csym
);
7015 } else if (tok
== TOK_FOR
) {
7042 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
7047 if (tok
== TOK_DO
) {
7052 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
7063 if (tok
== TOK_SWITCH
) {
7067 /* XXX: other types than integer */
7068 case_reg
= gv(RC_INT
);
7072 b
= gjmp(0); /* jump to first case */
7074 block(&a
, csym
, &b
, &c
, case_reg
);
7075 /* if no default, jmp after switch */
7083 if (tok
== TOK_CASE
) {
7090 if (gnu_ext
&& tok
== TOK_DOTS
) {
7094 warning("empty case range");
7096 /* since a case is like a label, we must skip it with a jmp */
7103 *case_sym
= gtst(1, 0);
7106 *case_sym
= gtst(1, 0);
7110 *case_sym
= gtst(1, *case_sym
);
7114 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
7116 if (tok
== TOK_DEFAULT
) {
7122 error("too many 'default'");
7124 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
7126 if (tok
== TOK_GOTO
) {
7128 if (tok
== '*' && gnu_ext
) {
7132 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
7135 } else if (tok
>= TOK_UIDENT
) {
7136 s
= label_find(tok
);
7137 /* put forward definition if needed */
7139 s
= label_push(tok
, LABEL_FORWARD
);
7141 /* label already defined */
7142 if (s
->r
& LABEL_FORWARD
)
7143 s
->next
= (void *)gjmp((long)s
->next
);
7145 gjmp_addr((long)s
->next
);
7148 expect("label identifier");
7157 if (!(s
->r
& LABEL_FORWARD
))
7158 error("multiple defined label");
7159 gsym((long)s
->next
);
7161 s
= label_push(b
, 0);
7163 s
->next
= (void *)ind
;
7165 /* we accept this, but it is a mistake */
7167 warning("deprecated use of label at end of compound statement");
7169 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
7171 /* expression case */
7181 /* t is the array or struct type. c is the array or struct
7182 address. cur_index/cur_field is the pointer to the current
7183 value. 'size_only' is true if only size info is needed (only used
7185 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
7186 int *cur_index
, Sym
**cur_field
,
7190 int notfirst
, index
, align
, l
;
7194 if (gnu_ext
&& (l
= is_label()) != 0)
7197 while (tok
== '[' || tok
== '.') {
7199 if (!(type
->t
& VT_ARRAY
))
7200 expect("array type");
7203 index
= expr_const();
7204 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
7205 expect("invalid index");
7209 type
= pointed_type(type
);
7210 c
+= index
* type_size(type
, &align
);
7216 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
7217 expect("struct/union type");
7230 /* XXX: suppress this mess by using explicit storage field */
7232 type1
.t
|= (type
->t
& ~VT_TYPE
);
7246 if (type
->t
& VT_ARRAY
) {
7248 type
= pointed_type(type
);
7249 c
+= index
* type_size(type
, &align
);
7253 error("too many field init");
7254 /* XXX: suppress this mess by using explicit storage field */
7256 type1
.t
|= (type
->t
& ~VT_TYPE
);
7261 decl_initializer(type
, sec
, c
, 0, size_only
);
7265 #define EXPR_CONST 1
7268 /* store a value or an expression directly in global data or in local array */
7269 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
7270 int v
, int expr_type
)
7272 int saved_global_expr
, bt
, bit_pos
, bit_size
;
7274 unsigned long long bit_mask
;
7281 /* compound literals must be allocated globally in this case */
7282 saved_global_expr
= global_expr
;
7285 global_expr
= saved_global_expr
;
7286 /* NOTE: symbols are accepted */
7287 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
7288 error("initializer element is not constant");
7296 /* XXX: not portable */
7297 /* XXX: generate error if incorrect relocation */
7298 gen_assign_cast(type
);
7299 bt
= type
->t
& VT_BTYPE
;
7300 ptr
= sec
->data
+ c
;
7301 /* XXX: make code faster ? */
7302 if (!(type
->t
& VT_BITFIELD
)) {
7307 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
7308 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
7309 bit_mask
= (1LL << bit_size
) - 1;
7311 if ((vtop
->r
& VT_SYM
) &&
7317 (bt
== VT_INT
&& bit_size
!= 32)))
7318 error("initializer element is not computable at load time");
7321 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
7324 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
7327 *(double *)ptr
= vtop
->c
.d
;
7330 *(long double *)ptr
= vtop
->c
.ld
;
7333 *(long long *)ptr
|= (vtop
->c
.ll
& bit_mask
) << bit_pos
;
7336 if (vtop
->r
& VT_SYM
) {
7337 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
7339 *(int *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
7344 vset(type
, VT_LOCAL
, c
);
7351 /* put zeros for variable based init */
7352 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
7357 /* nothing to do because globals are already set to zero */
7359 gfunc_start(&gf
, FUNC_CDECL
);
7366 vpush_global_sym(&func_old_type
, TOK_memset
);
7371 /* 't' contains the type and storage info. 'c' is the offset of the
7372 object in section 'sec'. If 'sec' is NULL, it means stack based
7373 allocation. 'first' is true if array '{' must be read (multi
7374 dimension implicit array init handling). 'size_only' is true if
7375 size only evaluation is wanted (only for arrays). */
7376 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
7377 int first
, int size_only
)
7379 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
7380 int size1
, align1
, expr_type
;
7384 if (type
->t
& VT_ARRAY
) {
7388 t1
= pointed_type(type
);
7389 size1
= type_size(t1
, &align1
);
7392 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
7398 /* only parse strings here if correct type (otherwise: handle
7399 them as ((w)char *) expressions */
7400 if ((tok
== TOK_LSTR
&&
7401 (t1
->t
& VT_BTYPE
) == VT_INT
) ||
7403 (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
7404 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
7409 /* compute maximum number of chars wanted */
7411 cstr_len
= cstr
->size
;
7413 cstr_len
= cstr
->size
/ sizeof(int);
7416 if (n
>= 0 && nb
> (n
- array_length
))
7417 nb
= n
- array_length
;
7420 warning("initializer-string for array is too long");
7421 /* in order to go faster for common case (char
7422 string in global variable, we handle it
7424 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
7425 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
7429 ch
= ((unsigned char *)cstr
->data
)[i
];
7431 ch
= ((int *)cstr
->data
)[i
];
7432 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
7440 /* only add trailing zero if enough storage (no
7441 warning in this case since it is standard) */
7442 if (n
< 0 || array_length
< n
) {
7444 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
7450 while (tok
!= '}') {
7451 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
7452 if (n
>= 0 && index
>= n
)
7453 error("index too large");
7454 /* must put zero in holes (note that doing it that way
7455 ensures that it even works with designators) */
7456 if (!size_only
&& array_length
< index
) {
7457 init_putz(t1
, sec
, c
+ array_length
* size1
,
7458 (index
- array_length
) * size1
);
7461 if (index
> array_length
)
7462 array_length
= index
;
7463 /* special test for multi dimensional arrays (may not
7464 be strictly correct if designators are used at the
7466 if (index
>= n
&& no_oblock
)
7475 /* put zeros at the end */
7476 if (!size_only
&& n
>= 0 && array_length
< n
) {
7477 init_putz(t1
, sec
, c
+ array_length
* size1
,
7478 (n
- array_length
) * size1
);
7480 /* patch type size if needed */
7482 s
->c
= array_length
;
7483 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
7484 (sec
|| !first
|| tok
== '{')) {
7485 /* NOTE: the previous test is a specific case for automatic
7486 struct/union init */
7487 /* XXX: union needs only one init */
7489 if (first
|| tok
== '{') {
7498 while (tok
!= '}') {
7499 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
7501 if (!size_only
&& array_length
< index
) {
7502 init_putz(type
, sec
, c
+ array_length
,
7503 index
- array_length
);
7505 index
= index
+ type_size(&f
->type
, &align1
);
7506 if (index
> array_length
)
7507 array_length
= index
;
7509 if (no_oblock
&& f
== NULL
)
7515 /* put zeros at the end */
7516 if (!size_only
&& array_length
< n
) {
7517 init_putz(type
, sec
, c
+ array_length
,
7522 } else if (tok
== '{') {
7524 decl_initializer(type
, sec
, c
, first
, size_only
);
7526 } else if (size_only
) {
7527 /* just skip expression */
7529 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
7533 else if (tok
== ')')
7538 /* currently, we always use constant expression for globals
7539 (may change for scripting case) */
7540 expr_type
= EXPR_CONST
;
7542 expr_type
= EXPR_ANY
;
7543 init_putv(type
, sec
, c
, 0, expr_type
);
7547 /* parse an initializer for type 't' if 'has_init' is non zero, and
7548 allocate space in local or global data space ('r' is either
7549 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7550 variable 'v' of scope 'scope' is declared before initializers are
7551 parsed. If 'v' is zero, then a reference to the new object is put
7552 in the value stack. If 'has_init' is 2, a special parsing is done
7553 to handle string constants. */
7554 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
7555 int has_init
, int v
, int scope
)
7557 int size
, align
, addr
, data_offset
;
7559 ParseState saved_parse_state
;
7560 TokenString init_str
;
7563 size
= type_size(type
, &align
);
7564 /* If unknown size, we must evaluate it before
7565 evaluating initializers because
7566 initializers can generate global data too
7567 (e.g. string pointers or ISOC99 compound
7568 literals). It also simplifies local
7569 initializers handling */
7570 tok_str_new(&init_str
);
7573 error("unknown type size");
7574 /* get all init string */
7575 if (has_init
== 2) {
7576 /* only get strings */
7577 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
7578 tok_str_add_tok(&init_str
);
7583 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
7585 error("unexpected end of file in initializer");
7586 tok_str_add_tok(&init_str
);
7589 else if (tok
== '}') {
7597 tok_str_add(&init_str
, -1);
7598 tok_str_add(&init_str
, 0);
7601 save_parse_state(&saved_parse_state
);
7603 macro_ptr
= init_str
.str
;
7605 decl_initializer(type
, NULL
, 0, 1, 1);
7606 /* prepare second initializer parsing */
7607 macro_ptr
= init_str
.str
;
7610 /* if still unknown size, error */
7611 size
= type_size(type
, &align
);
7613 error("unknown type size");
7615 /* take into account specified alignment if bigger */
7616 if (ad
->aligned
> align
)
7617 align
= ad
->aligned
;
7618 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
7620 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
7622 #ifdef TCC_TARGET_IL
7623 /* XXX: ugly patch to allocate local variables for IL, just
7628 loc
= (loc
- size
) & -align
;
7631 /* handles bounds */
7632 /* XXX: currently, since we do only one pass, we cannot track
7633 '&' operators, so we add only arrays */
7634 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
7635 unsigned long *bounds_ptr
;
7636 /* add padding between regions */
7638 /* then add local bound info */
7639 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
7640 bounds_ptr
[0] = addr
;
7641 bounds_ptr
[1] = size
;
7644 /* compute section */
7652 data_offset
= sec
->data_offset
;
7653 data_offset
= (data_offset
+ align
- 1) & -align
;
7655 /* very important to increment global pointer at this time
7656 because initializers themselves can create new initializers */
7657 data_offset
+= size
;
7658 /* add padding if bound check */
7659 if (do_bounds_check
)
7661 sec
->data_offset
= data_offset
;
7662 /* allocate section space to put the data */
7663 if (sec
->sh_type
!= SHT_NOBITS
&&
7664 data_offset
> sec
->data_allocated
)
7665 section_realloc(sec
, data_offset
);
7669 /* local variable */
7670 sym_push(v
, type
, r
, addr
);
7672 /* push local reference */
7673 vset(type
, r
, addr
);
7679 if (scope
== VT_CONST
) {
7680 /* global scope: see if already defined */
7684 if (!is_compatible_types(&sym
->type
, type
))
7685 error("incompatible types for redefinition of '%s'",
7686 get_tok_str(v
, NULL
));
7687 if (!(sym
->type
.t
& VT_EXTERN
))
7688 error("redefinition of '%s'", get_tok_str(v
, NULL
));
7689 sym
->type
.t
&= ~VT_EXTERN
;
7692 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
7694 put_extern_sym(sym
, sec
, addr
, size
);
7698 /* push global reference */
7699 sym
= get_sym_ref(type
, sec
, addr
, size
);
7701 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
7705 /* handles bounds now because the symbol must be defined
7706 before for the relocation */
7707 if (do_bounds_check
) {
7708 unsigned long *bounds_ptr
;
7710 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
7711 /* then add global bound info */
7712 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
7713 bounds_ptr
[0] = 0; /* relocated */
7714 bounds_ptr
[1] = size
;
7718 decl_initializer(type
, sec
, addr
, 1, 0);
7719 /* restore parse state if needed */
7721 tok_str_free(init_str
.str
);
7722 restore_parse_state(&saved_parse_state
);
7727 void put_func_debug(Sym
*sym
)
7732 /* XXX: we put here a dummy type */
7733 snprintf(buf
, sizeof(buf
), "%s:%c1",
7734 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
7735 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
7736 cur_text_section
, sym
->c
);
7741 /* not finished : try to put some local vars in registers */
7742 //#define CONFIG_REG_VARS
7744 #ifdef CONFIG_REG_VARS
7745 void add_var_ref(int t
)
7747 printf("%s:%d: &%s\n",
7748 file
->filename
, file
->line_num
,
7749 get_tok_str(t
, NULL
));
7752 /* first pass on a function with heuristic to extract variable usage
7753 and pointer references to local variables for register allocation */
7754 void analyse_function(void)
7761 /* any symbol coming after '&' is considered as being a
7762 variable whose reference is taken. It is highly unaccurate
7763 but it is difficult to do better without a complete parse */
7766 /* if '& number', then no need to examine next tokens */
7767 if (tok
== TOK_CINT
||
7769 tok
== TOK_CLLONG
||
7770 tok
== TOK_CULLONG
) {
7772 } else if (tok
>= TOK_UIDENT
) {
7773 /* if '& ident [' or '& ident ->', then ident address
7777 if (tok
!= '[' && tok
!= TOK_ARROW
)
7781 while (tok
!= '}' && tok
!= ';' &&
7782 !((tok
== ',' || tok
== ')') && level
== 0)) {
7783 if (tok
>= TOK_UIDENT
) {
7785 } else if (tok
== '(') {
7787 } else if (tok
== ')') {
7800 /* parse an old style function declaration list */
7801 /* XXX: check multiple parameter */
7802 static void func_decl_list(Sym
*func_sym
)
7809 /* parse each declaration */
7810 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
) {
7811 if (!parse_btype(&btype
, &ad
))
7812 expect("declaration list");
7813 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
7814 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
7816 /* we accept no variable after */
7820 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
7821 /* find parameter in function parameter list */
7824 if ((s
->v
& ~SYM_FIELD
) == v
)
7828 error("declaration for parameter '%s' but no such parameter",
7829 get_tok_str(v
, NULL
));
7831 /* check that no storage specifier except 'register' was given */
7832 if (type
.t
& (VT_EXTERN
| VT_STATIC
| VT_TYPEDEF
))
7833 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
7834 /* we can add the type (NOTE: it could be local to the function) */
7836 /* accept other parameters */
7847 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
7848 static void decl(int l
)
7856 if (!parse_btype(&btype
, &ad
)) {
7857 /* skip redundant ';' */
7858 /* XXX: find more elegant solution */
7863 /* special test for old K&R protos without explicit int
7864 type. Only accepted when defining global data */
7865 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
7869 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
7870 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
7872 /* we accept no variable after */
7876 while (1) { /* iterate thru each declaration */
7878 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
7882 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
7883 printf("type = '%s'\n", buf
);
7886 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
7887 /* if old style function prototype, we accept a
7890 if (sym
->c
== FUNC_OLD
)
7891 func_decl_list(sym
);
7895 #ifdef CONFIG_REG_VARS
7896 TokenString func_str
;
7897 ParseState saved_parse_state
;
7902 error("cannot use local functions");
7903 if (!(type
.t
& VT_FUNC
))
7904 expect("function definition");
7906 #ifdef CONFIG_REG_VARS
7907 /* parse all function code and record it */
7909 tok_str_new(&func_str
);
7915 error("unexpected end of file");
7916 tok_str_add_tok(&func_str
);
7921 } else if (t
== '}') {
7923 if (block_level
== 0)
7927 tok_str_add(&func_str
, -1);
7928 tok_str_add(&func_str
, 0);
7930 save_parse_state(&saved_parse_state
);
7932 macro_ptr
= func_str
.str
;
7937 /* compute text section */
7938 cur_text_section
= ad
.section
;
7939 if (!cur_text_section
)
7940 cur_text_section
= text_section
;
7941 ind
= cur_text_section
->data_offset
;
7942 funcname
= get_tok_str(v
, NULL
);
7945 /* if symbol is already defined, then put complete type */
7948 /* put function symbol */
7949 sym
= global_identifier_push(v
, type
.t
, 0);
7950 sym
->type
.ref
= type
.ref
;
7952 /* NOTE: we patch the symbol size later */
7953 put_extern_sym(sym
, cur_text_section
, ind
, 0);
7955 sym
->r
= VT_SYM
| VT_CONST
;
7956 /* put debug symbol */
7958 put_func_debug(sym
);
7959 /* push a dummy symbol to enable local sym storage */
7960 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
7961 gfunc_prolog(&type
);
7964 #ifdef CONFIG_REG_VARS
7965 macro_ptr
= func_str
.str
;
7968 block(NULL
, NULL
, NULL
, NULL
, 0);
7971 cur_text_section
->data_offset
= ind
;
7972 /* look if any labels are undefined. Define symbols if
7973 '&&label' was used. */
7976 for(s
= label_stack
; s
!= NULL
; s
= s1
) {
7978 if (s
->r
& LABEL_FORWARD
) {
7979 error("label '%s' used but not defined",
7980 get_tok_str(s
->v
, NULL
));
7983 /* define corresponding symbol. A size of
7985 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
7988 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= NULL
;
7993 sym_pop(&local_stack
, NULL
); /* reset local stack */
7994 /* end of function */
7995 /* patch symbol size */
7996 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
7999 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
8001 funcname
= ""; /* for safety */
8002 func_vt
.t
= VT_VOID
; /* for safety */
8003 ind
= 0; /* for safety */
8005 #ifdef CONFIG_REG_VARS
8006 tok_str_free(func_str
.str
);
8007 restore_parse_state(&saved_parse_state
);
8011 if (btype
.t
& VT_TYPEDEF
) {
8012 /* save typedefed type */
8013 /* XXX: test storage specifiers ? */
8014 sym
= sym_push(v
, &type
, 0, 0);
8015 sym
->type
.t
|= VT_TYPEDEF
;
8016 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8017 /* external function definition */
8018 external_sym(v
, &type
, 0);
8020 /* not lvalue if array */
8022 if (!(type
.t
& VT_ARRAY
))
8023 r
|= lvalue_type(type
.t
);
8024 if (btype
.t
& VT_EXTERN
) {
8025 /* external variable */
8026 external_sym(v
, &type
, r
);
8028 if (type
.t
& VT_STATIC
)
8032 has_init
= (tok
== '=');
8035 decl_initializer_alloc(&type
, &ad
, r
,
8049 /* compile the C file opened in 'file'. Return non zero if errors. */
8050 static int tcc_compile(TCCState
*s1
)
8054 volatile int section_sym
;
8057 printf("%s: **** new file\n", file
->filename
);
8060 s1
->include_stack_ptr
= s1
->include_stack
;
8061 /* XXX: move that before to avoid having to initialize
8062 file->ifdef_stack_ptr ? */
8063 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
8064 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
8066 /* XXX: not ANSI compliant: bound checking says error */
8068 anon_sym
= SYM_FIRST_ANOM
;
8070 /* file info: full path + filename */
8071 section_sym
= 0; /* avoid warning */
8073 section_sym
= put_elf_sym(symtab_section
, 0, 0,
8074 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
8075 text_section
->sh_num
, NULL
);
8076 getcwd(buf
, sizeof(buf
));
8077 pstrcat(buf
, sizeof(buf
), "/");
8078 put_stabs_r(buf
, N_SO
, 0, 0,
8079 text_section
->data_offset
, text_section
, section_sym
);
8080 put_stabs_r(file
->filename
, N_SO
, 0, 0,
8081 text_section
->data_offset
, text_section
, section_sym
);
8083 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8084 symbols can be safely used */
8085 put_elf_sym(symtab_section
, 0, 0,
8086 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
8087 SHN_ABS
, file
->filename
);
8089 /* define some often used types */
8090 int_type
.t
= VT_INT
;
8092 char_pointer_type
.t
= VT_BYTE
;
8093 mk_pointer(&char_pointer_type
);
8095 func_old_type
.t
= VT_FUNC
;
8096 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
8099 /* define 'void *alloca(unsigned int)' builtin function */
8104 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
8105 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
8108 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
8112 define_start
= define_stack
;
8114 if (setjmp(s1
->error_jmp_buf
) == 0) {
8116 s1
->error_set_jmp_enabled
= 1;
8118 ch
= file
->buf_ptr
[0];
8119 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
8123 expect("declaration");
8125 /* end of translation unit info */
8127 put_stabs_r(NULL
, N_SO
, 0, 0,
8128 text_section
->data_offset
, text_section
, section_sym
);
8131 s1
->error_set_jmp_enabled
= 0;
8133 /* reset define stack, but leave -Dsymbols (may be incorrect if
8134 they are undefined) */
8135 free_defines(define_start
);
8137 sym_pop(&global_stack
, NULL
);
8139 return s1
->nb_errors
!= 0 ? -1 : 0;
8143 int tcc_compile_string(TCCState
*s
, const char *str
)
8145 BufferedFile bf1
, *bf
= &bf1
;
8149 /* init file structure */
8151 /* XXX: avoid copying */
8153 buf
= tcc_malloc(len
+ 1);
8156 memcpy(buf
, str
, len
);
8159 bf
->buf_end
= buf
+ len
;
8160 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
8164 ret
= tcc_compile(s
);
8168 /* currently, no need to close */
8173 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8174 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
8176 BufferedFile bf1
, *bf
= &bf1
;
8178 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
8179 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
8183 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
8185 /* init file structure */
8187 bf
->buf_ptr
= bf
->buffer
;
8188 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
8189 *bf
->buf_end
= CH_EOB
;
8190 bf
->filename
[0] = '\0';
8194 s1
->include_stack_ptr
= s1
->include_stack
;
8196 /* parse with define parser */
8197 ch
= file
->buf_ptr
[0];
8203 /* undefine a preprocessor symbol */
8204 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
8208 ts
= tok_alloc(sym
, strlen(sym
));
8209 s
= define_find(ts
->tok
);
8210 /* undefine symbol by putting an invalid name */
8217 /* print the position in the source file of PC value 'pc' by reading
8218 the stabs debug information */
8219 static void rt_printline(unsigned long wanted_pc
)
8221 Stab_Sym
*sym
, *sym_end
;
8222 char func_name
[128], last_func_name
[128];
8223 unsigned long func_addr
, last_pc
, pc
;
8224 const char *incl_files
[INCLUDE_STACK_SIZE
];
8225 int incl_index
, len
, last_line_num
, i
;
8226 const char *str
, *p
;
8228 fprintf(stderr
, "0x%08lx:", wanted_pc
);
8230 func_name
[0] = '\0';
8233 last_func_name
[0] = '\0';
8234 last_pc
= 0xffffffff;
8236 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
8237 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
8238 while (sym
< sym_end
) {
8239 switch(sym
->n_type
) {
8240 /* function start or end */
8242 if (sym
->n_strx
== 0) {
8243 /* we test if between last line and end of function */
8244 pc
= sym
->n_value
+ func_addr
;
8245 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
8247 func_name
[0] = '\0';
8250 str
= stabstr_section
->data
+ sym
->n_strx
;
8251 p
= strchr(str
, ':');
8253 pstrcpy(func_name
, sizeof(func_name
), str
);
8256 if (len
> sizeof(func_name
) - 1)
8257 len
= sizeof(func_name
) - 1;
8258 memcpy(func_name
, str
, len
);
8259 func_name
[len
] = '\0';
8261 func_addr
= sym
->n_value
;
8264 /* line number info */
8266 pc
= sym
->n_value
+ func_addr
;
8267 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
8270 last_line_num
= sym
->n_desc
;
8272 strcpy(last_func_name
, func_name
);
8276 str
= stabstr_section
->data
+ sym
->n_strx
;
8278 if (incl_index
< INCLUDE_STACK_SIZE
) {
8279 incl_files
[incl_index
++] = str
;
8287 if (sym
->n_strx
== 0) {
8288 incl_index
= 0; /* end of translation unit */
8290 str
= stabstr_section
->data
+ sym
->n_strx
;
8291 /* do not add path */
8293 if (len
> 0 && str
[len
- 1] != '/')
8301 /* second pass: we try symtab symbols (no line number info) */
8304 Elf32_Sym
*sym
, *sym_end
;
8307 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
8308 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
8311 type
= ELF32_ST_TYPE(sym
->st_info
);
8312 if (type
== STT_FUNC
) {
8313 if (wanted_pc
>= sym
->st_value
&&
8314 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
8315 pstrcpy(last_func_name
, sizeof(last_func_name
),
8316 strtab_section
->data
+ sym
->st_name
);
8322 /* did not find any info: */
8323 fprintf(stderr
, " ???\n");
8326 if (last_func_name
[0] != '\0') {
8327 fprintf(stderr
, " %s()", last_func_name
);
8329 if (incl_index
> 0) {
8330 fprintf(stderr
, " (%s:%d",
8331 incl_files
[incl_index
- 1], last_line_num
);
8332 for(i
= incl_index
- 2; i
>= 0; i
--)
8333 fprintf(stderr
, ", included from %s", incl_files
[i
]);
8334 fprintf(stderr
, ")");
8336 fprintf(stderr
, "\n");
8343 /* fix for glibc 2.1 */
8349 /* return the PC at frame level 'level'. Return non zero if not found */
8350 static int rt_get_caller_pc(unsigned long *paddr
,
8351 ucontext_t
*uc
, int level
)
8358 *paddr
= uc
->uc_mcontext
.mc_eip
;
8360 *paddr
= uc
->uc_mcontext
.gregs
[REG_EIP
];
8365 fp
= uc
->uc_mcontext
.mc_ebp
;
8367 fp
= uc
->uc_mcontext
.gregs
[REG_EBP
];
8369 for(i
=1;i
<level
;i
++) {
8370 /* XXX: check address validity with program info */
8371 if (fp
<= 0x1000 || fp
>= 0xc0000000)
8373 fp
= ((unsigned long *)fp
)[0];
8375 *paddr
= ((unsigned long *)fp
)[1];
8380 #error add arch specific rt_get_caller_pc()
8383 /* emit a run time error at position 'pc' */
8384 void rt_error(ucontext_t
*uc
, const char *fmt
, ...)
8391 fprintf(stderr
, "Runtime error: ");
8392 vfprintf(stderr
, fmt
, ap
);
8393 fprintf(stderr
, "\n");
8394 for(i
=0;i
<num_callers
;i
++) {
8395 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
8398 fprintf(stderr
, "at ");
8400 fprintf(stderr
, "by ");
8407 /* signal handler for fatal errors */
8408 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
8410 ucontext_t
*uc
= puc
;
8414 switch(siginf
->si_code
) {
8417 rt_error(uc
, "division by zero");
8420 rt_error(uc
, "floating point exception");
8426 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
8427 rt_error(uc
, *rt_bound_error_msg
);
8429 rt_error(uc
, "dereferencing invalid pointer");
8432 rt_error(uc
, "illegal instruction");
8435 rt_error(uc
, "abort() called");
8438 rt_error(uc
, "caught signal %d", signum
);
8445 /* do all relocations (needed before using tcc_get_symbol()) */
8446 int tcc_relocate(TCCState
*s1
)
8453 tcc_add_runtime(s1
);
8455 relocate_common_syms();
8457 /* compute relocation address : section are relocated in place. We
8458 also alloc the bss space */
8459 for(i
= 1; i
< s1
->nb_sections
; i
++) {
8460 s
= s1
->sections
[i
];
8461 if (s
->sh_flags
& SHF_ALLOC
) {
8462 if (s
->sh_type
== SHT_NOBITS
)
8463 s
->data
= tcc_mallocz(s
->data_offset
);
8464 s
->sh_addr
= (unsigned long)s
->data
;
8468 relocate_syms(s1
, 1);
8470 if (s1
->nb_errors
!= 0)
8473 /* relocate each section */
8474 for(i
= 1; i
< s1
->nb_sections
; i
++) {
8475 s
= s1
->sections
[i
];
8477 relocate_section(s1
, s
);
8482 /* launch the compiled program with the given arguments */
8483 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
8485 int (*prog_main
)(int, char **);
8487 if (tcc_relocate(s1
) < 0)
8490 prog_main
= tcc_get_symbol(s1
, "main");
8494 error("debug mode currently not available for Windows");
8496 struct sigaction sigact
;
8497 /* install TCC signal handlers to print debug info on fatal
8499 sigact
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
8500 sigact
.sa_sigaction
= sig_error
;
8501 sigemptyset(&sigact
.sa_mask
);
8502 sigaction(SIGFPE
, &sigact
, NULL
);
8503 sigaction(SIGILL
, &sigact
, NULL
);
8504 sigaction(SIGSEGV
, &sigact
, NULL
);
8505 sigaction(SIGBUS
, &sigact
, NULL
);
8506 sigaction(SIGABRT
, &sigact
, NULL
);
8510 #ifdef CONFIG_TCC_BCHECK
8511 if (do_bounds_check
) {
8512 void (*bound_init
)(void);
8514 /* set error function */
8515 rt_bound_error_msg
= (void *)tcc_get_symbol(s1
, "__bound_error_msg");
8517 /* XXX: use .init section so that it also work in binary ? */
8518 bound_init
= (void *)tcc_get_symbol(s1
, "__bound_init");
8522 return (*prog_main
)(argc
, argv
);
8525 TCCState
*tcc_new(void)
8530 s
= tcc_mallocz(sizeof(TCCState
));
8534 s
->output_type
= TCC_OUTPUT_MEMORY
;
8536 /* default include paths */
8537 tcc_add_sysinclude_path(s
, "/usr/local/include");
8538 tcc_add_sysinclude_path(s
, "/usr/include");
8539 tcc_add_sysinclude_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
8541 /* add all tokens */
8543 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
8545 tok_ident
= TOK_IDENT
;
8550 tok_alloc(p
, r
- p
- 1);
8554 /* we add dummy defines for some special macros to speed up tests
8555 and to have working defined() */
8556 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
8557 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
8558 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
8559 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
8561 /* standard defines */
8562 tcc_define_symbol(s
, "__STDC__", NULL
);
8563 #if defined(TCC_TARGET_I386)
8564 tcc_define_symbol(s
, "__i386__", NULL
);
8567 tcc_define_symbol(s
, "linux", NULL
);
8569 /* tiny C specific defines */
8570 tcc_define_symbol(s
, "__TINYC__", NULL
);
8572 /* tiny C & gcc defines */
8573 tcc_define_symbol(s
, "__SIZE_TYPE__", "unsigned int");
8574 tcc_define_symbol(s
, "__PTRDIFF_TYPE__", "int");
8575 tcc_define_symbol(s
, "__WCHAR_TYPE__", "int");
8577 /* default library paths */
8578 tcc_add_library_path(s
, "/usr/local/lib");
8579 tcc_add_library_path(s
, "/usr/lib");
8580 tcc_add_library_path(s
, "/lib");
8582 /* no section zero */
8583 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
8585 /* create standard sections */
8586 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
8587 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
8588 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
8590 /* symbols are always generated for linking stage */
8591 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
8593 ".hashtab", SHF_PRIVATE
);
8594 strtab_section
= symtab_section
->link
;
8596 /* private symbol table for dynamic symbols */
8597 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
8599 ".dynhashtab", SHF_PRIVATE
);
8603 void tcc_delete(TCCState
*s1
)
8607 /* free -D defines */
8611 n
= tok_ident
- TOK_IDENT
;
8612 for(i
= 0; i
< n
; i
++)
8613 tcc_free(table_ident
[i
]);
8614 tcc_free(table_ident
);
8616 /* free all sections */
8618 free_section(symtab_section
->hash
);
8620 free_section(s1
->dynsymtab_section
->hash
);
8621 free_section(s1
->dynsymtab_section
->link
);
8622 free_section(s1
->dynsymtab_section
);
8624 for(i
= 1; i
< s1
->nb_sections
; i
++)
8625 free_section(s1
->sections
[i
]);
8626 tcc_free(s1
->sections
);
8628 /* free loaded dlls array */
8629 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
8630 tcc_free(s1
->loaded_dlls
[i
]);
8631 tcc_free(s1
->loaded_dlls
);
8634 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
8635 tcc_free(s1
->library_paths
[i
]);
8636 tcc_free(s1
->library_paths
);
8638 /* cached includes */
8639 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
8640 tcc_free(s1
->cached_includes
[i
]);
8641 tcc_free(s1
->cached_includes
);
8643 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
8644 tcc_free(s1
->include_paths
[i
]);
8645 tcc_free(s1
->include_paths
);
8647 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
8648 tcc_free(s1
->sysinclude_paths
[i
]);
8649 tcc_free(s1
->sysinclude_paths
);
8654 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
8658 pathname1
= tcc_strdup(pathname
);
8659 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
8663 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
8667 pathname1
= tcc_strdup(pathname
);
8668 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
8672 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
8674 const char *ext
, *filename1
;
8677 BufferedFile
*saved_file
;
8679 /* find source file type with extension */
8680 filename1
= strrchr(filename
, '/');
8684 filename1
= filename
;
8685 ext
= strrchr(filename1
, '.');
8691 file
= tcc_open(s1
, filename
);
8693 if (flags
& AFF_PRINT_ERROR
) {
8694 error_noabort("file '%s' not found", filename
);
8700 if (!ext
|| !strcmp(ext
, "c")) {
8701 /* C file assumed */
8702 ret
= tcc_compile(s1
);
8705 /* assume executable format: auto guess file type */
8706 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
)) {
8707 error_noabort("could not read header");
8710 lseek(fd
, 0, SEEK_SET
);
8712 if (ehdr
.e_ident
[0] == ELFMAG0
&&
8713 ehdr
.e_ident
[1] == ELFMAG1
&&
8714 ehdr
.e_ident
[2] == ELFMAG2
&&
8715 ehdr
.e_ident
[3] == ELFMAG3
) {
8716 file
->line_num
= 0; /* do not display line number if error */
8717 if (ehdr
.e_type
== ET_REL
) {
8718 ret
= tcc_load_object_file(s1
, fd
, 0);
8719 } else if (ehdr
.e_type
== ET_DYN
) {
8720 ret
= tcc_load_dll(s1
, fd
, filename
,
8721 (flags
& AFF_REFERENCED_DLL
) != 0);
8723 error_noabort("unrecognized ELF file");
8726 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
8727 file
->line_num
= 0; /* do not display line number if error */
8728 ret
= tcc_load_archive(s1
, fd
);
8730 /* as GNU ld, consider it is an ld script if not recognized */
8731 ret
= tcc_load_ldscript(s1
);
8733 error_noabort("unrecognized file type");
8748 int tcc_add_file(TCCState
*s
, const char *filename
)
8750 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
8753 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
8757 pathname1
= tcc_strdup(pathname
);
8758 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
8762 /* find and load a dll. Return non zero if not found */
8763 /* XXX: add '-rpath' option support ? */
8764 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
8769 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
8770 snprintf(buf
, sizeof(buf
), "%s/%s",
8771 s
->library_paths
[i
], filename
);
8772 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
8778 /* the library name is the same as the argument of the '-l' option */
8779 int tcc_add_library(TCCState
*s
, const char *libraryname
)
8785 /* first we look for the dynamic library if not static linking */
8786 if (!s
->static_link
) {
8787 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8788 /* if we output to memory, then we simply we dlopen(). */
8789 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
8790 /* Since the libc is already loaded, we don't need to load it again */
8791 if (!strcmp(libraryname
, "c"))
8793 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
8797 if (tcc_add_dll(s
, buf
, 0) == 0)
8802 /* then we look for the static library */
8803 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
8804 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
8805 s
->library_paths
[i
], libraryname
);
8806 if (tcc_add_file_internal(s
, buf
, 0) == 0)
8812 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
8814 add_elf_sym(symtab_section
, val
, 0,
8815 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
8820 int tcc_set_output_type(TCCState
*s
, int output_type
)
8822 s
->output_type
= output_type
;
8824 /* if bound checking, then add corresponding sections */
8825 #ifdef CONFIG_TCC_BCHECK
8826 if (do_bounds_check
) {
8828 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
8829 /* create bounds sections */
8830 bounds_section
= new_section(s
, ".bounds",
8831 SHT_PROGBITS
, SHF_ALLOC
);
8832 lbounds_section
= new_section(s
, ".lbounds",
8833 SHT_PROGBITS
, SHF_ALLOC
);
8837 /* add debug sections */
8840 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
8841 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
8842 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
8843 put_elf_str(stabstr_section
, "");
8844 stab_section
->link
= stabstr_section
;
8845 /* put first entry */
8846 put_stabs("", 0, 0, 0, 0);
8849 /* add libc crt1/crti objects */
8850 if (output_type
== TCC_OUTPUT_EXE
||
8851 output_type
== TCC_OUTPUT_DLL
) {
8852 if (output_type
!= TCC_OUTPUT_DLL
)
8853 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
8854 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
8859 #if !defined(LIBTCC)
8861 static int64_t getclock_us(void)
8866 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
8869 gettimeofday(&tv
, NULL
);
8870 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
8876 printf("tcc version 0.9.15 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8877 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8878 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
8879 " [--] infile1 [infile2... --] [infile_args...]\n"
8881 "General options:\n"
8882 " -c compile only - generate an object file\n"
8883 " -o outfile set output filename\n"
8884 " -- allows multiples input files if no -o option given. Also\n"
8885 " separate input files from runtime arguments\n"
8886 " -Bdir set tcc internal library path\n"
8887 " -bench output compilation statistics\n"
8888 "Preprocessor options:\n"
8889 " -Idir add include path 'dir'\n"
8890 " -Dsym[=val] define 'sym' with value 'val'\n"
8891 " -Usym undefine 'sym'\n"
8893 " -Ldir add library path 'dir'\n"
8894 " -llib link with dynamic or static library 'lib'\n"
8895 " -shared generate a shared library\n"
8896 " -static static linking\n"
8897 " -r relocatable output\n"
8898 "Debugger options:\n"
8899 " -g generate runtime debug info\n"
8900 #ifdef CONFIG_TCC_BCHECK
8901 " -b compile with built-in memory and bounds checker (implies -g)\n"
8903 " -bt N show N callers in stack traces\n"
8907 int main(int argc
, char **argv
)
8910 int optind
, output_type
, multiple_files
, i
, reloc_output
;
8913 int nb_files
, nb_libraries
, nb_objfiles
, dminus
, ret
;
8914 char objfilename
[1024];
8915 int64_t start_time
= 0;
8918 output_type
= TCC_OUTPUT_MEMORY
;
8929 if (optind
>= argc
) {
8937 /* add a new file */
8938 dynarray_add((void ***)&files
, &nb_files
, r
);
8939 if (!multiple_files
) {
8941 /* argv[0] will be this file */
8944 } else if (r
[1] == '-') {
8945 /* '--' enables multiple files input and also ends several file input */
8946 if (dminus
&& multiple_files
) {
8947 optind
--; /* argv[0] will be '--' */
8952 } else if (r
[1] == 'h' || r
[1] == '?') {
8956 } else if (r
[1] == 'I') {
8957 if (tcc_add_include_path(s
, r
+ 2) < 0)
8958 error("too many include paths");
8959 } else if (r
[1] == 'D') {
8962 value
= strchr(sym
, '=');
8967 tcc_define_symbol(s
, sym
, value
);
8968 } else if (r
[1] == 'U') {
8969 tcc_undefine_symbol(s
, r
+ 2);
8970 } else if (r
[1] == 'L') {
8971 tcc_add_library_path(s
, r
+ 2);
8972 } else if (r
[1] == 'B') {
8973 /* set tcc utilities path (mainly for tcc development) */
8974 tcc_lib_path
= r
+ 2;
8975 } else if (r
[1] == 'l') {
8976 dynarray_add((void ***)&files
, &nb_files
, r
);
8978 } else if (!strcmp(r
+ 1, "bench")) {
8980 } else if (!strcmp(r
+ 1, "bt")) {
8981 num_callers
= atoi(argv
[optind
++]);
8983 #ifdef CONFIG_TCC_BCHECK
8985 do_bounds_check
= 1;
8991 } else if (r
[1] == 'c') {
8993 output_type
= TCC_OUTPUT_OBJ
;
8994 } else if (!strcmp(r
+ 1, "static")) {
8996 } else if (!strcmp(r
+ 1, "shared")) {
8997 output_type
= TCC_OUTPUT_DLL
;
8998 } else if (r
[1] == 'o') {
9002 outfile
= argv
[optind
++];
9003 } else if (r
[1] == 'r') {
9004 /* generate a .o merging several output files */
9006 output_type
= TCC_OUTPUT_OBJ
;
9007 } else if (r
[1] == 'W' || r
[1] == 'O' || r
[1] == 'm' || r
[1] == 'f') {
9008 /* ignore those options to be a drop-in replacement for gcc */
9010 error("invalid option -- '%s'", r
);
9014 nb_objfiles
= nb_files
- nb_libraries
;
9016 /* if outfile provided without other options, we output an
9018 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
9019 output_type
= TCC_OUTPUT_EXE
;
9021 /* check -c consistency : only single file handled. XXX: checks file type */
9022 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
9023 /* accepts only a single input file */
9024 if (nb_objfiles
!= 1)
9025 error("cannot specify multiple files with -c");
9026 if (nb_libraries
!= 0)
9027 error("cannot specify libraries with -c");
9030 /* compute default outfile name */
9031 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
9032 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
9034 /* add .o extension */
9035 pstrcpy(objfilename
, sizeof(objfilename
) - 1, files
[0]);
9036 ext
= strrchr(objfilename
, '.');
9038 goto default_outfile
;
9039 strcpy(ext
+ 1, "o");
9042 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
9044 outfile
= objfilename
;
9048 start_time
= getclock_us();
9051 tcc_set_output_type(s
, output_type
);
9053 /* compile or add each files or library */
9054 for(i
= 0;i
< nb_files
; i
++) {
9055 const char *filename
;
9057 filename
= files
[i
];
9058 if (filename
[0] == '-') {
9059 if (tcc_add_library(s
, filename
+ 2) < 0)
9060 error("cannot find %s", filename
);
9062 if (tcc_add_file(s
, filename
) < 0) {
9069 /* free all files */
9074 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
9075 if (total_time
< 0.001)
9077 if (total_bytes
< 1)
9079 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
9080 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
9081 total_time
, (int)(total_lines
/ total_time
),
9082 total_bytes
/ total_time
/ 1000000.0);
9085 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
9086 tcc_output_file(s
, outfile
);
9089 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
9092 /* XXX: cannot do it with bound checking because of the malloc hooks */
9093 if (!do_bounds_check
)
9098 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);