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.
32 #include <sys/timeb.h>
36 #include <sys/ucontext.h>
40 #ifndef CONFIG_TCC_STATIC
48 /* preprocessor debug */
50 /* include file debug */
55 /* target selection */
56 //#define TCC_TARGET_I386 /* i386 code generator */
57 //#define TCC_TARGET_IL /* .NET CLI generator */
59 /* default target is I386 */
60 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
61 #define TCC_TARGET_I386
64 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
65 #define CONFIG_TCC_BCHECK /* enable bound checking code */
68 #ifndef CONFIG_TCC_PREFIX
69 #define CONFIG_TCC_PREFIX "/usr/local"
72 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
73 executables or dlls */
74 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
76 #define INCLUDE_STACK_SIZE 32
77 #define IFDEF_STACK_SIZE 64
78 #define VSTACK_SIZE 64
79 #define STRING_MAX_SIZE 1024
81 #define TOK_HASH_SIZE 2048 /* must be a power of two */
82 #define TOK_ALLOC_INCR 512 /* must be a power of two */
83 #define TOK_STR_ALLOC_INCR_BITS 6
84 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
85 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
87 /* token symbol management */
88 typedef struct TokenSym
{
89 struct TokenSym
*hash_next
;
90 struct Sym
*sym_define
; /* direct pointer to define */
91 struct Sym
*sym_label
; /* direct pointer to label */
92 struct Sym
*sym_struct
; /* direct pointer to structure */
93 struct Sym
*sym_identifier
; /* direct pointer to identifier */
94 int tok
; /* token number */
99 typedef struct CString
{
100 int size
; /* size in bytes */
101 void *data
; /* either 'char *' or 'int *' */
103 void *data_allocated
; /* if non NULL, data has been malloced */
106 /* type definition */
107 typedef struct CType
{
113 typedef union CValue
{
119 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
121 unsigned long long ull
;
122 struct CString
*cstr
;
128 typedef struct SValue
{
129 CType type
; /* type */
130 unsigned short r
; /* register + flags */
131 unsigned short r2
; /* second register, used for 'long long'
132 type. If not used, set to VT_CONST */
133 CValue c
; /* constant, if VT_CONST */
134 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
137 /* symbol management */
139 int v
; /* symbol token */
140 int r
; /* associated register */
141 int c
; /* associated number */
142 CType type
; /* associated type */
143 struct Sym
*next
; /* next related symbol */
144 struct Sym
*prev
; /* prev symbol in stack */
145 struct Sym
*prev_tok
; /* previous symbol for this token */
148 /* section definition */
149 /* XXX: use directly ELF structure for parameters ? */
150 /* special flag to indicate that the section should not be linked to
152 #define SHF_PRIVATE 0x80000000
154 typedef struct Section
{
155 unsigned long data_offset
; /* current data offset */
156 unsigned char *data
; /* section data */
157 unsigned long data_allocated
; /* used for realloc() handling */
158 int sh_name
; /* elf section name (only used during output) */
159 int sh_num
; /* elf section number */
160 int sh_type
; /* elf section type */
161 int sh_flags
; /* elf section flags */
162 int sh_info
; /* elf section info */
163 int sh_addralign
; /* elf section alignment */
164 int sh_entsize
; /* elf entry size */
165 unsigned long sh_size
; /* section size (only used during output) */
166 unsigned long sh_addr
; /* address at which the section is relocated */
167 unsigned long sh_offset
; /* address at which the section is relocated */
168 int nb_hashed_syms
; /* used to resize the hash table */
169 struct Section
*link
; /* link to another section */
170 struct Section
*reloc
; /* corresponding section for relocation, if any */
171 struct Section
*hash
; /* hash table for symbols */
172 struct Section
*next
;
173 char name
[64]; /* section name */
176 typedef struct DLLReference
{
181 /* GNUC attribute definition */
182 typedef struct AttributeDef
{
185 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
188 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
189 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
190 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
192 /* stored in 'Sym.c' field */
193 #define FUNC_NEW 1 /* ansi function prototype */
194 #define FUNC_OLD 2 /* old function prototype */
195 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
197 /* stored in 'Sym.r' field */
198 #define FUNC_CDECL 0 /* standard c call */
199 #define FUNC_STDCALL 1 /* pascal c call */
201 /* field 'Sym.t' for macros */
202 #define MACRO_OBJ 0 /* object like macro */
203 #define MACRO_FUNC 1 /* function like macro */
205 /* field 'Sym.r' for labels */
206 #define LABEL_FORWARD 1 /* label is forward defined */
208 /* type_decl() types */
209 #define TYPE_ABSTRACT 1 /* type without variable */
210 #define TYPE_DIRECT 2 /* type with variable */
212 #define IO_BUF_SIZE 8192
214 typedef struct BufferedFile
{
218 int line_num
; /* current line number - here to simply code */
219 int ifndef_macro
; /* #ifndef macro / #endif search */
220 int ifndef_macro_saved
; /* saved ifndef_macro */
221 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
222 char inc_type
; /* type of include */
223 char inc_filename
[512]; /* filename specified by the user */
224 char filename
[1024]; /* current filename - here to simplify code */
225 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
228 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
229 #define CH_EOF (-1) /* end of file */
231 /* parsing state (used to save parser state to reparse part of the
232 source several times) */
233 typedef struct ParseState
{
240 /* used to record tokens */
241 typedef struct TokenString
{
248 /* include file cache, used to find files faster and also to eliminate
249 inclusion if the include file is protected by #ifndef ... #endif */
250 typedef struct CachedInclude
{
252 char type
; /* '"' or '>' to give include type */
253 char filename
[1]; /* path specified in #include */
257 static struct BufferedFile
*file
;
258 static int ch
, tok
, tok1
;
259 static CValue tokc
, tok1c
;
260 static CString tokcstr
; /* current parsed string, if any */
261 /* additionnal informations about token */
262 static int tok_flags
;
263 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
264 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
265 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
267 /* if true, line feed is returned as a token. line feed is also
269 static int return_linefeed
;
270 static Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
271 static Section
*cur_text_section
; /* current section where function code is
273 /* bound check related sections */
274 static Section
*bounds_section
; /* contains global data bound description */
275 static Section
*lbounds_section
; /* contains local data bound description */
276 /* symbol sections */
277 static Section
*symtab_section
, *strtab_section
;
280 static Section
*stab_section
, *stabstr_section
;
282 /* loc : local variable index
283 ind : output code index
285 anon_sym: anonymous symbol index
287 static int rsym
, anon_sym
, ind
, loc
;
288 /* expression generation modifiers */
289 static int const_wanted
; /* true if constant wanted */
290 static int nocode_wanted
; /* true if no code generation wanted for an expression */
291 static int global_expr
; /* true if compound literals must be allocated
292 globally (used during initializers parsing */
293 static CType func_vt
; /* current function return type (used by return
296 static int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
297 static int tok_ident
;
298 static TokenSym
**table_ident
;
299 static TokenSym
*hash_ident
[TOK_HASH_SIZE
];
300 static char token_buf
[STRING_MAX_SIZE
+ 1];
301 static char *funcname
;
302 static Sym
*global_stack
, *local_stack
;
303 static Sym
*define_stack
;
304 static Sym
*label_stack
;
306 static SValue vstack
[VSTACK_SIZE
], *vtop
;
307 static int *macro_ptr
, *macro_ptr_allocated
;
308 /* some predefined types */
309 static CType char_pointer_type
, func_old_type
, int_type
;
311 /* compile with debug symbol (and use them if error during execution) */
312 static int do_debug
= 0;
314 /* compile with built-in memory and bounds checker */
315 static int do_bounds_check
= 0;
317 /* display benchmark infos */
318 static int do_bench
= 0;
319 static int total_lines
;
320 static int total_bytes
;
322 /* use GNU C extensions */
323 static int gnu_ext
= 1;
325 /* use Tiny C extensions */
326 static int tcc_ext
= 1;
328 /* max number of callers shown if error */
329 static int num_callers
= 6;
330 static const char **rt_bound_error_msg
;
332 /* XXX: suppress that ASAP */
333 static struct TCCState
*tcc_state
;
335 /* give the path of the tcc libraries */
336 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
341 BufferedFile
**include_stack_ptr
;
342 int *ifdef_stack_ptr
;
344 /* include file handling */
345 char **include_paths
;
346 int nb_include_paths
;
347 char **sysinclude_paths
;
348 int nb_sysinclude_paths
;
349 CachedInclude
**cached_includes
;
350 int nb_cached_includes
;
352 char **library_paths
;
353 int nb_library_paths
;
355 /* array of all loaded dlls (including those referenced by loaded
357 DLLReference
**loaded_dlls
;
362 int nb_sections
; /* number of sections, including first dummy section */
366 unsigned long *got_offsets
;
369 /* give the correspondance from symtab indexes to dynsym indexes */
370 int *symtab_to_dynsym
;
372 /* temporary dynamic symbol sections (for dll loading) */
373 Section
*dynsymtab_section
;
374 /* exported dynamic symbol section */
377 /* if true, static linking is performed */
382 void (*error_func
)(void *opaque
, const char *msg
);
383 int error_set_jmp_enabled
;
384 jmp_buf error_jmp_buf
;
387 /* see include_stack_ptr */
388 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
390 /* see ifdef_stack_ptr */
391 int ifdef_stack
[IFDEF_STACK_SIZE
];
394 /* The current value can be: */
395 #define VT_VALMASK 0x00ff
396 #define VT_CONST 0x00f0 /* constant in vc
397 (must be first non register value) */
398 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
399 #define VT_LOCAL 0x00f2 /* offset on stack */
400 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
401 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
402 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
403 #define VT_LVAL 0x0100 /* var is an lvalue */
404 #define VT_SYM 0x0200 /* a symbol value is added */
405 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
406 char/short stored in integer registers) */
407 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
408 dereferencing value */
409 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
410 bounding function call point is in vc */
411 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
412 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
413 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
414 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
417 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
419 #define VT_INT 0 /* integer type */
420 #define VT_BYTE 1 /* signed byte type */
421 #define VT_SHORT 2 /* short type */
422 #define VT_VOID 3 /* void type */
423 #define VT_PTR 4 /* pointer */
424 #define VT_ENUM 5 /* enum definition */
425 #define VT_FUNC 6 /* function type */
426 #define VT_STRUCT 7 /* struct/union definition */
427 #define VT_FLOAT 8 /* IEEE float */
428 #define VT_DOUBLE 9 /* IEEE double */
429 #define VT_LDOUBLE 10 /* IEEE long double */
430 #define VT_BOOL 11 /* ISOC99 boolean type */
431 #define VT_LLONG 12 /* 64 bit integer */
432 #define VT_LONG 13 /* long integer (NEVER USED as type, only
434 #define VT_BTYPE 0x000f /* mask for basic type */
435 #define VT_UNSIGNED 0x0010 /* unsigned type */
436 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
437 #define VT_BITFIELD 0x0040 /* bitfield modifier */
440 #define VT_EXTERN 0x00000080 /* extern definition */
441 #define VT_STATIC 0x00000100 /* static variable */
442 #define VT_TYPEDEF 0x00000200 /* typedef definition */
444 /* type mask (except storage) */
445 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
449 /* warning: the following compare tokens depend on i386 asm code */
461 #define TOK_LAND 0xa0
465 #define TOK_MID 0xa3 /* inc/dec, to void constant */
467 #define TOK_UDIV 0xb0 /* unsigned division */
468 #define TOK_UMOD 0xb1 /* unsigned modulo */
469 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
470 #define TOK_CINT 0xb3 /* number in tokc */
471 #define TOK_CCHAR 0xb4 /* char constant in tokc */
472 #define TOK_STR 0xb5 /* pointer to string in tokc */
473 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
474 #define TOK_LCHAR 0xb7
475 #define TOK_LSTR 0xb8
476 #define TOK_CFLOAT 0xb9 /* float constant */
477 #define TOK_LINENUM 0xba /* line number info */
478 #define TOK_CDOUBLE 0xc0 /* double constant */
479 #define TOK_CLDOUBLE 0xc1 /* long double constant */
480 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
481 #define TOK_ADDC1 0xc3 /* add with carry generation */
482 #define TOK_ADDC2 0xc4 /* add with carry use */
483 #define TOK_SUBC1 0xc5 /* add with carry generation */
484 #define TOK_SUBC2 0xc6 /* add with carry use */
485 #define TOK_CUINT 0xc8 /* unsigned int constant */
486 #define TOK_CLLONG 0xc9 /* long long constant */
487 #define TOK_CULLONG 0xca /* unsigned long long constant */
488 #define TOK_ARROW 0xcb
489 #define TOK_DOTS 0xcc /* three dots */
490 #define TOK_SHR 0xcd /* unsigned shift right */
491 #define TOK_PPNUM 0xce /* preprocessor number */
493 #define TOK_SHL 0x01 /* shift left */
494 #define TOK_SAR 0x02 /* signed shift right */
496 /* assignement operators : normal operator or 0x80 */
497 #define TOK_A_MOD 0xa5
498 #define TOK_A_AND 0xa6
499 #define TOK_A_MUL 0xaa
500 #define TOK_A_ADD 0xab
501 #define TOK_A_SUB 0xad
502 #define TOK_A_DIV 0xaf
503 #define TOK_A_XOR 0xde
504 #define TOK_A_OR 0xfc
505 #define TOK_A_SHL 0x81
506 #define TOK_A_SAR 0x82
508 /* WARNING: the content of this string encodes token numbers */
509 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";
511 #define TOK_EOF (-1) /* end of file */
512 #define TOK_LINEFEED 10 /* line feed */
514 /* all identificators and strings have token above that */
515 #define TOK_IDENT 256
518 TOK_LAST
= TOK_IDENT
- 1,
519 #define DEF(id, str) id,
524 static const char *tcc_keywords
=
525 #define DEF(id, str) str "\0"
530 #define TOK_UIDENT TOK_DEFINE
533 #define snprintf _snprintf
534 #define vsnprintf _vsnprintf
537 #if defined(WIN32) || defined(TCC_UCLIBC)
538 /* currently incorrect */
539 long double strtold(const char *nptr
, char **endptr
)
541 return (long double)strtod(nptr
, endptr
);
543 float strtof(const char *nptr
, char **endptr
)
545 return (float)strtod(nptr
, endptr
);
548 /* XXX: need to define this to use them in non ISOC99 context */
549 extern float strtof (const char *__nptr
, char **__endptr
);
550 extern long double strtold (const char *__nptr
, char **__endptr
);
553 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
554 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
556 static void next(void);
557 static void next_nomacro(void);
558 static void parse_expr_type(CType
*type
);
559 static void expr_type(CType
*type
);
560 static void unary_type(CType
*type
);
561 static int expr_const(void);
562 static void expr_eq(void);
563 static void gexpr(void);
564 static void decl(int l
);
565 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
566 int first
, int size_only
);
567 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
568 int has_init
, int v
, int scope
);
570 void gv2(int rc1
, int rc2
);
571 void move_reg(int r
, int s
);
572 void save_regs(int n
);
573 void save_reg(int r
);
579 static void macro_subst(TokenString
*tok_str
,
580 Sym
**nested_list
, int *macro_str
);
581 int save_reg_forced(int r
);
583 void force_charshort_cast(int t
);
584 static void gen_cast(CType
*type
);
586 static Sym
*sym_find(int v
);
587 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
590 static int type_size(CType
*type
, int *a
);
591 static inline CType
*pointed_type(CType
*type
);
592 static int pointed_size(CType
*type
);
593 static int lvalue_type(int t
);
594 static int is_compatible_types(CType
*type1
, CType
*type2
);
595 static int parse_btype(CType
*type
, AttributeDef
*ad
);
596 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
598 void error(const char *fmt
, ...);
600 void vset(CType
*type
, int r
, int v
);
601 void type_to_str(char *buf
, int buf_size
,
602 CType
*type
, const char *varstr
);
603 char *get_tok_str(int v
, CValue
*cv
);
604 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
605 unsigned long offset
, unsigned long size
);
606 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
608 /* section generation */
609 static void section_realloc(Section
*sec
, unsigned long new_size
);
610 static void *section_ptr_add(Section
*sec
, unsigned long size
);
611 static void put_extern_sym(Sym
*sym
, Section
*section
,
612 unsigned long value
, unsigned long size
);
613 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
614 static int put_elf_str(Section
*s
, const char *sym
);
615 static int put_elf_sym(Section
*s
,
616 unsigned long value
, unsigned long size
,
617 int info
, int other
, int shndx
, const char *name
);
618 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
619 int info
, int sh_num
, const char *name
);
620 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
621 int type
, int symbol
);
622 static void put_stabs(const char *str
, int type
, int other
, int desc
,
623 unsigned long value
);
624 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
625 unsigned long value
, Section
*sec
, int sym_index
);
626 static void put_stabn(int type
, int other
, int desc
, int value
);
627 static void put_stabd(int type
, int other
, int desc
);
628 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
630 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
631 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
632 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
634 /* true if float/double/long double type */
635 static inline int is_float(int t
)
639 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
642 #ifdef TCC_TARGET_I386
643 #include "i386-gen.c"
649 #ifdef CONFIG_TCC_STATIC
651 #define RTLD_LAZY 0x001
652 #define RTLD_NOW 0x002
653 #define RTLD_GLOBAL 0x100
654 #define RTLD_DEFAULT NULL
656 /* dummy function for profiling */
657 void *dlopen(const char *filename
, int flag
)
662 const char *dlerror(void)
667 typedef struct TCCSyms
{
672 #define TCCSYM(a) { #a, &a, },
674 /* add the symbol you want here if no dynamic linking is done */
675 static TCCSyms tcc_syms
[] = {
683 void *dlsym(void *handle
, const char *symbol
)
687 while (p
->str
!= NULL
) {
688 if (!strcmp(p
->str
, symbol
))
697 /********************************************************/
699 /* we use our own 'finite' function to avoid potential problems with
700 non standard math libs */
701 /* XXX: endianness dependant */
702 int ieee_finite(double d
)
705 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
708 /* copy a string and truncate it. */
709 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
716 q_end
= buf
+ buf_size
- 1;
728 /* strcat and truncate. */
729 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
734 pstrcpy(buf
+ len
, buf_size
- len
, s
);
738 /* memory management */
744 static inline void tcc_free(void *ptr
)
747 mem_cur_size
-= malloc_usable_size(ptr
);
752 static void *tcc_malloc(unsigned long size
)
757 error("memory full");
759 mem_cur_size
+= malloc_usable_size(ptr
);
760 if (mem_cur_size
> mem_max_size
)
761 mem_max_size
= mem_cur_size
;
766 static void *tcc_mallocz(unsigned long size
)
769 ptr
= tcc_malloc(size
);
770 memset(ptr
, 0, size
);
774 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
778 mem_cur_size
-= malloc_usable_size(ptr
);
780 ptr1
= realloc(ptr
, size
);
782 /* NOTE: count not correct if alloc error, but not critical */
783 mem_cur_size
+= malloc_usable_size(ptr1
);
784 if (mem_cur_size
> mem_max_size
)
785 mem_max_size
= mem_cur_size
;
790 static char *tcc_strdup(const char *str
)
793 ptr
= tcc_malloc(strlen(str
) + 1);
798 #define free(p) use_tcc_free(p)
799 #define malloc(s) use_tcc_malloc(s)
800 #define realloc(p, s) use_tcc_realloc(p, s)
802 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
809 /* every power of two we double array size */
810 if ((nb
& (nb
- 1)) == 0) {
815 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
817 error("memory full");
824 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
828 sec
= tcc_mallocz(sizeof(Section
));
829 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
830 sec
->sh_type
= sh_type
;
831 sec
->sh_flags
= sh_flags
;
838 sec
->sh_addralign
= 4;
841 sec
->sh_addralign
= 1;
844 sec
->sh_addralign
= 32; /* default conservative alignment */
848 /* only add section if not private */
849 if (!(sh_flags
& SHF_PRIVATE
)) {
850 sec
->sh_num
= s1
->nb_sections
;
851 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
856 static void free_section(Section
*s
)
862 /* realloc section and set its content to zero */
863 static void section_realloc(Section
*sec
, unsigned long new_size
)
868 size
= sec
->data_allocated
;
871 while (size
< new_size
)
873 data
= tcc_realloc(sec
->data
, size
);
875 error("memory full");
876 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
878 sec
->data_allocated
= size
;
881 /* reserve at least 'size' bytes in section 'sec' from
883 static void *section_ptr_add(Section
*sec
, unsigned long size
)
885 unsigned long offset
, offset1
;
887 offset
= sec
->data_offset
;
888 offset1
= offset
+ size
;
889 if (offset1
> sec
->data_allocated
)
890 section_realloc(sec
, offset1
);
891 sec
->data_offset
= offset1
;
892 return sec
->data
+ offset
;
895 /* return a reference to a section, and create it if it does not
897 Section
*find_section(TCCState
*s1
, const char *name
)
901 for(i
= 1; i
< s1
->nb_sections
; i
++) {
902 sec
= s1
->sections
[i
];
903 if (!strcmp(name
, sec
->name
))
906 /* sections are created as PROGBITS */
907 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
910 /* update sym->c so that it points to an external symbol in section
911 'section' with value 'value' */
912 static void put_extern_sym(Sym
*sym
, Section
*section
,
913 unsigned long value
, unsigned long size
)
915 int sym_type
, sym_bind
, sh_num
, info
;
920 sh_num
= section
->sh_num
;
924 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
)
927 sym_type
= STT_OBJECT
;
928 if (sym
->type
.t
& VT_STATIC
)
929 sym_bind
= STB_LOCAL
;
931 sym_bind
= STB_GLOBAL
;
933 name
= get_tok_str(sym
->v
, NULL
);
934 #ifdef CONFIG_TCC_BCHECK
935 if (do_bounds_check
) {
938 /* XXX: avoid doing that for statics ? */
939 /* if bound checking is activated, we change some function
940 names by adding the "__bound" prefix */
943 /* XXX: we rely only on malloc hooks */
955 strcpy(buf
, "__bound_");
962 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
963 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
965 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
966 esym
->st_value
= value
;
967 esym
->st_size
= size
;
968 esym
->st_shndx
= sh_num
;
972 /* add a new relocation entry to symbol 'sym' in section 's' */
973 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
976 put_extern_sym(sym
, NULL
, 0, 0);
977 /* now we can add ELF relocation info */
978 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
981 static inline int isid(int c
)
983 return (c
>= 'a' && c
<= 'z') ||
984 (c
>= 'A' && c
<= 'Z') ||
988 static inline int isnum(int c
)
990 return c
>= '0' && c
<= '9';
993 static inline int isoct(int c
)
995 return c
>= '0' && c
<= '7';
998 static inline int toup(int c
)
1000 if (c
>= 'a' && c
<= 'z')
1001 return c
- 'a' + 'A';
1006 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1010 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1013 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1017 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1021 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1028 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1029 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1030 (*f
)->filename
, (*f
)->line_num
);
1031 if (file
->line_num
> 0) {
1032 strcat_printf(buf
, sizeof(buf
),
1033 "%s:%d: ", file
->filename
, file
->line_num
);
1035 strcat_printf(buf
, sizeof(buf
),
1036 "%s: ", file
->filename
);
1039 strcat_printf(buf
, sizeof(buf
),
1043 strcat_printf(buf
, sizeof(buf
), "warning: ");
1044 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1046 if (!s1
->error_func
) {
1047 /* default case: stderr */
1048 fprintf(stderr
, "%s\n", buf
);
1050 s1
->error_func(s1
->error_opaque
, buf
);
1057 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1058 void (*error_func
)(void *opaque
, const char *msg
))
1060 s
->error_opaque
= error_opaque
;
1061 s
->error_func
= error_func
;
1065 /* error without aborting current compilation */
1066 void error_noabort(const char *fmt
, ...)
1068 TCCState
*s1
= tcc_state
;
1072 error1(s1
, 0, fmt
, ap
);
1076 void error(const char *fmt
, ...)
1078 TCCState
*s1
= tcc_state
;
1082 error1(s1
, 0, fmt
, ap
);
1084 /* better than nothing: in some cases, we accept to handle errors */
1085 if (s1
->error_set_jmp_enabled
) {
1086 longjmp(s1
->error_jmp_buf
, 1);
1088 /* XXX: suppress it someday */
1093 void expect(const char *msg
)
1095 error("%s expected", msg
);
1098 void warning(const char *fmt
, ...)
1100 TCCState
*s1
= tcc_state
;
1104 error1(s1
, 1, fmt
, ap
);
1111 error("'%c' expected", c
);
1115 void test_lvalue(void)
1117 if (!(vtop
->r
& VT_LVAL
))
1121 /* allocate a new token */
1122 static TokenSym
*tok_alloc_new(TokenSym
**pts
, const char *str
, int len
)
1124 TokenSym
*ts
, **ptable
;
1127 if (tok_ident
>= SYM_FIRST_ANOM
)
1128 error("memory full");
1130 /* expand token table if needed */
1131 i
= tok_ident
- TOK_IDENT
;
1132 if ((i
% TOK_ALLOC_INCR
) == 0) {
1133 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1135 error("memory full");
1136 table_ident
= ptable
;
1139 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1140 table_ident
[i
] = ts
;
1141 ts
->tok
= tok_ident
++;
1142 ts
->sym_define
= NULL
;
1143 ts
->sym_label
= NULL
;
1144 ts
->sym_struct
= NULL
;
1145 ts
->sym_identifier
= NULL
;
1147 ts
->hash_next
= NULL
;
1148 memcpy(ts
->str
, str
, len
);
1149 ts
->str
[len
] = '\0';
1154 #define TOK_HASH_INIT 1
1155 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1157 /* find a token and add it if not found */
1158 static TokenSym
*tok_alloc(const char *str
, int len
)
1160 TokenSym
*ts
, **pts
;
1166 h
= TOK_HASH_FUNC(h
, ((unsigned char *)str
)[i
]);
1167 h
&= (TOK_HASH_SIZE
- 1);
1169 pts
= &hash_ident
[h
];
1174 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1176 pts
= &(ts
->hash_next
);
1178 return tok_alloc_new(pts
, str
, len
);
1181 /* CString handling */
1183 static void cstr_realloc(CString
*cstr
, int new_size
)
1188 size
= cstr
->size_allocated
;
1190 size
= 8; /* no need to allocate a too small first string */
1191 while (size
< new_size
)
1193 data
= tcc_realloc(cstr
->data_allocated
, size
);
1195 error("memory full");
1196 cstr
->data_allocated
= data
;
1197 cstr
->size_allocated
= size
;
1202 static void cstr_ccat(CString
*cstr
, int ch
)
1205 size
= cstr
->size
+ 1;
1206 if (size
> cstr
->size_allocated
)
1207 cstr_realloc(cstr
, size
);
1208 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1212 static void cstr_cat(CString
*cstr
, const char *str
)
1224 /* add a wide char */
1225 static void cstr_wccat(CString
*cstr
, int ch
)
1228 size
= cstr
->size
+ sizeof(int);
1229 if (size
> cstr
->size_allocated
)
1230 cstr_realloc(cstr
, size
);
1231 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1235 static void cstr_new(CString
*cstr
)
1237 memset(cstr
, 0, sizeof(CString
));
1240 /* free string and reset it to NULL */
1241 static void cstr_free(CString
*cstr
)
1243 tcc_free(cstr
->data_allocated
);
1247 #define cstr_reset(cstr) cstr_free(cstr)
1249 static CString
*cstr_dup(CString
*cstr1
)
1254 cstr
= tcc_malloc(sizeof(CString
));
1257 cstr
->size_allocated
= size
;
1258 cstr
->data_allocated
= tcc_malloc(size
);
1259 cstr
->data
= cstr
->data_allocated
;
1260 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1264 /* XXX: unicode ? */
1265 static void add_char(CString
*cstr
, int c
)
1267 if (c
== '\'' || c
== '\"' || c
== '\\') {
1268 /* XXX: could be more precise if char or string */
1269 cstr_ccat(cstr
, '\\');
1271 if (c
>= 32 && c
<= 126) {
1274 cstr_ccat(cstr
, '\\');
1276 cstr_ccat(cstr
, 'n');
1278 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1279 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1280 cstr_ccat(cstr
, '0' + (c
& 7));
1285 /* XXX: buffer overflow */
1286 /* XXX: float tokens */
1287 char *get_tok_str(int v
, CValue
*cv
)
1289 static char buf
[STRING_MAX_SIZE
+ 1];
1290 static CString cstr_buf
;
1296 /* NOTE: to go faster, we give a fixed buffer for small strings */
1297 cstr_reset(&cstr_buf
);
1298 cstr_buf
.data
= buf
;
1299 cstr_buf
.size_allocated
= sizeof(buf
);
1305 /* XXX: not quite exact, but only useful for testing */
1306 sprintf(p
, "%u", cv
->ui
);
1310 /* XXX: not quite exact, but only useful for testing */
1311 sprintf(p
, "%Lu", cv
->ull
);
1315 cstr_ccat(&cstr_buf
, '\'');
1316 add_char(&cstr_buf
, cv
->i
);
1317 cstr_ccat(&cstr_buf
, '\'');
1318 cstr_ccat(&cstr_buf
, '\0');
1322 len
= cstr
->size
- 1;
1324 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1325 cstr_ccat(&cstr_buf
, '\0');
1330 cstr_ccat(&cstr_buf
, '\"');
1332 len
= cstr
->size
- 1;
1334 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1336 len
= (cstr
->size
/ sizeof(int)) - 1;
1338 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1340 cstr_ccat(&cstr_buf
, '\"');
1341 cstr_ccat(&cstr_buf
, '\0');
1350 return strcpy(p
, "<<=");
1352 return strcpy(p
, ">>=");
1354 if (v
< TOK_IDENT
) {
1355 /* search in two bytes table */
1369 } else if (v
< tok_ident
) {
1370 return table_ident
[v
- TOK_IDENT
]->str
;
1371 } else if (v
>= SYM_FIRST_ANOM
) {
1372 /* special name for anonymous symbol */
1373 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1375 /* should never happen */
1380 return cstr_buf
.data
;
1383 /* push, without hashing */
1384 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1387 s
= tcc_malloc(sizeof(Sym
));
1398 /* find a symbol and return its associated structure. 's' is the top
1399 of the symbol stack */
1400 static Sym
*sym_find2(Sym
*s
, int v
)
1410 /* structure lookup */
1411 static Sym
*struct_find(int v
)
1414 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1416 return table_ident
[v
]->sym_struct
;
1419 /* find an identifier */
1420 static inline Sym
*sym_find(int v
)
1423 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1425 return table_ident
[v
]->sym_identifier
;
1428 /* push a given symbol on the symbol stack */
1429 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1438 s
= sym_push2(ps
, v
, type
->t
, c
);
1439 s
->type
.ref
= type
->ref
;
1441 /* don't record fields or anonymous symbols */
1443 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1444 /* record symbol in token array */
1445 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1447 ps
= &ts
->sym_struct
;
1449 ps
= &ts
->sym_identifier
;
1456 /* push a global identifier */
1457 static Sym
*global_identifier_push(int v
, int t
, int c
)
1460 s
= sym_push2(&global_stack
, v
, t
, c
);
1461 /* don't record anonymous symbol */
1462 if (v
< SYM_FIRST_ANOM
) {
1463 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1464 /* modify the top most local identifier, so that
1465 sym_identifier will point to 's' when popped */
1467 ps
= &(*ps
)->prev_tok
;
1474 /* pop symbols until top reaches 'b' */
1475 static void sym_pop(Sym
**ptop
, Sym
*b
)
1485 /* remove symbol in token array */
1487 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1488 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1490 ps
= &ts
->sym_struct
;
1492 ps
= &ts
->sym_identifier
;
1503 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1508 fd
= open(filename
, O_RDONLY
);
1511 bf
= tcc_malloc(sizeof(BufferedFile
));
1517 bf
->buf_ptr
= bf
->buffer
;
1518 bf
->buf_end
= bf
->buffer
;
1519 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1520 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1522 bf
->ifndef_macro
= 0;
1523 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1524 // printf("opening '%s'\n", filename);
1528 void tcc_close(BufferedFile
*bf
)
1530 total_lines
+= bf
->line_num
;
1535 /* fill input buffer and peek next char */
1536 static int tcc_peekc_slow(BufferedFile
*bf
)
1539 /* only tries to read if really end of buffer */
1540 if (bf
->buf_ptr
>= bf
->buf_end
) {
1542 #if defined(PARSE_DEBUG)
1547 len
= read(bf
->fd
, bf
->buffer
, len
);
1554 bf
->buf_ptr
= bf
->buffer
;
1555 bf
->buf_end
= bf
->buffer
+ len
;
1556 *bf
->buf_end
= CH_EOB
;
1558 if (bf
->buf_ptr
< bf
->buf_end
) {
1559 return bf
->buf_ptr
[0];
1561 bf
->buf_ptr
= bf
->buf_end
;
1566 /* return the current character, handling end of block if necessary
1568 static int handle_eob(void)
1570 return tcc_peekc_slow(file
);
1573 /* read next char from current input file and handle end of input buffer */
1574 static inline void inp(void)
1576 ch
= *(++(file
->buf_ptr
));
1577 /* end of buffer/file handling */
1582 /* handle '\[\r]\n' */
1583 static void handle_stray(void)
1585 while (ch
== '\\') {
1590 } else if (ch
== '\r') {
1598 error("stray '\\' in program");
1603 /* skip the stray and handle the \\n case. Output an error if
1604 incorrect char after the stray */
1605 static int handle_stray1(uint8_t *p
)
1609 if (p
>= file
->buf_end
) {
1626 /* handle the complicated stray case */
1627 #define PEEKC(c, p)\
1632 c = handle_stray1(p);\
1637 /* input with '\[\r]\n' handling. Note that this function cannot
1638 handle other characters after '\', so you cannot call it inside
1639 strings or comments */
1640 static void minp(void)
1648 static void parse_line_comment(void)
1650 /* single line C++ comments */
1651 /* XXX: accept '\\\n' ? */
1653 while (ch
!= '\n' && ch
!= CH_EOF
)
1657 static void parse_comment(void)
1666 /* fast skip loop */
1669 if (c
== '\n' || c
== '*' || c
== '\\')
1673 if (c
== '\n' || c
== '*' || c
== '\\')
1677 /* now we can handle all the cases */
1681 } else if (c
== '*') {
1687 } else if (c
== '/') {
1688 goto end_of_comment
;
1689 } else if (c
== '\\') {
1693 /* skip '\\n', but if '\' followed but another
1694 char, behave asif a stray was parsed */
1695 ch
= file
->buf_ptr
[0];
1696 while (ch
== '\\') {
1701 } else if (ch
== '\r') {
1719 /* stray, eob or eof */
1724 error("unexpected end of file in comment");
1725 } else if (c
== '\\') {
1738 /* space exlcuding newline */
1739 static inline int is_space(int ch
)
1741 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1744 static inline void skip_spaces(void)
1746 while (is_space(ch
))
1750 /* skip block of text until #else, #elif or #endif. skip also pairs of
1752 void preprocess_skip(void)
1754 int a
, start_of_line
, sep
, c
;
1781 } else if (c
== '\\') {
1782 /* XXX: incorrect: should not give an error */
1783 ch
= file
->buf_ptr
[0];
1797 } else if (c
== '\\') {
1802 /* XXX: better error message */
1803 error("unterminated string");
1804 } else if (c
== '\\') {
1805 /* ignore next char */
1815 else if (c
!= CH_EOF
)
1818 } else if (c
== '\n') {
1834 } else if (ch
== '/') {
1835 parse_line_comment();
1842 if (start_of_line
) {
1847 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1849 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1851 else if (tok
== TOK_ENDIF
)
1865 /* ParseState handling */
1867 /* XXX: currently, no include file info is stored. Thus, we cannot display
1868 accurate messages if the function or data definition spans multiple
1871 /* save current parse state in 's' */
1872 void save_parse_state(ParseState
*s
)
1874 s
->line_num
= file
->line_num
;
1875 s
->macro_ptr
= macro_ptr
;
1880 /* restore parse state from 's' */
1881 void restore_parse_state(ParseState
*s
)
1883 file
->line_num
= s
->line_num
;
1884 macro_ptr
= s
->macro_ptr
;
1889 /* return the number of additionnal 'ints' necessary to store the
1891 static inline int tok_ext_size(int t
)
1910 return LDOUBLE_SIZE
/ 4;
1916 /* token string handling */
1918 static inline void tok_str_new(TokenString
*s
)
1922 s
->allocated_len
= 0;
1923 s
->last_line_num
= -1;
1926 static void tok_str_free(int *str
)
1935 /* NOTE: we test zero separately so that GCC can generate a
1936 table for the following switch */
1951 /* XXX: use a macro to be portable on 64 bit ? */
1952 cstr
= (CString
*)p
[1];
1963 p
+= 1 + (LDOUBLE_SIZE
/ 4);
1973 static int *tok_str_realloc(TokenString
*s
)
1977 len
= s
->allocated_len
+ TOK_STR_ALLOC_INCR
;
1978 str
= tcc_realloc(s
->str
, len
* sizeof(int));
1980 error("memory full");
1981 s
->allocated_len
= len
;
1986 static void tok_str_add(TokenString
*s
, int t
)
1992 if (len
>= s
->allocated_len
)
1993 str
= tok_str_realloc(s
);
1998 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
2005 /* allocate space for worst case */
2006 if (len
+ TOK_MAX_SIZE
> s
->allocated_len
)
2007 str
= tok_str_realloc(s
);
2016 str
[len
++] = cv
->tab
[0];
2021 str
[len
++] = (int)cstr_dup(cv
->cstr
);
2026 str
[len
++] = cv
->tab
[0];
2027 str
[len
++] = cv
->tab
[1];
2030 #if LDOUBLE_SIZE == 12
2031 str
[len
++] = cv
->tab
[0];
2032 str
[len
++] = cv
->tab
[1];
2033 str
[len
++] = cv
->tab
[2];
2035 #error add long double size support
2044 /* add the current parse token in token string 's' */
2045 static void tok_str_add_tok(TokenString
*s
)
2049 /* save line number info */
2050 if (file
->line_num
!= s
->last_line_num
) {
2051 s
->last_line_num
= file
->line_num
;
2052 cval
.i
= s
->last_line_num
;
2053 tok_str_add2(s
, TOK_LINENUM
, &cval
);
2055 tok_str_add2(s
, tok
, &tokc
);
2058 #if LDOUBLE_SIZE == 12
2059 #define LDOUBLE_GET(p, cv) \
2064 #error add long double size support
2068 /* get a token from an integer array and increment pointer
2069 accordingly. we code it as a macro to avoid pointer aliasing. */
2070 #define TOK_GET(t, p, cv) \
2092 case TOK_CLDOUBLE: \
2093 LDOUBLE_GET(p, cv); \
2094 p += LDOUBLE_SIZE / 4; \
2101 /* defines handling */
2102 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
2106 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
2107 s
->next
= first_arg
;
2108 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
2111 /* undefined a define symbol. Its name is just set to zero */
2112 static void define_undef(Sym
*s
)
2116 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2117 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2121 static inline Sym
*define_find(int v
)
2124 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2126 return table_ident
[v
]->sym_define
;
2129 /* free define stack until top reaches 'b' */
2130 static void free_defines(Sym
*b
)
2138 /* do not free args or predefined defines */
2140 tok_str_free((int *)top
->c
);
2142 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2143 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2151 static Sym
*label_find(int v
)
2154 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2156 return table_ident
[v
]->sym_label
;
2159 static Sym
*label_push(int v
, int flags
)
2162 s
= sym_push2(&label_stack
, v
, 0, 0);
2164 table_ident
[v
- TOK_IDENT
]->sym_label
= s
;
2168 /* eval an expression for #if/#elif */
2169 static int expr_preprocess(void)
2175 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2176 next(); /* do macro subst */
2177 if (tok
== TOK_DEFINED
) {
2182 c
= define_find(tok
) != 0;
2187 } else if (tok
>= TOK_IDENT
) {
2188 /* if undefined macro */
2192 tok_str_add_tok(&str
);
2194 tok_str_add(&str
, -1); /* simulate end of file */
2195 tok_str_add(&str
, 0);
2196 /* now evaluate C constant expression */
2197 macro_ptr
= str
.str
;
2201 tok_str_free(str
.str
);
2205 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2206 static void tok_print(int *str
)
2212 TOK_GET(t
, str
, cval
);
2215 printf(" %s", get_tok_str(t
, &cval
));
2221 /* parse after #define */
2222 static void parse_define(void)
2224 Sym
*s
, *first
, **ps
;
2225 int v
, t
, varg
, is_vaargs
, c
;
2230 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2231 /* XXX: should check if same macro (ANSI) */
2234 /* '(' must be just after macro definition for MACRO_FUNC */
2235 c
= file
->buf_ptr
[0];
2237 c
= handle_stray1(file
->buf_ptr
);
2242 while (tok
!= ')') {
2246 if (varg
== TOK_DOTS
) {
2247 varg
= TOK___VA_ARGS__
;
2249 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2253 if (varg
< TOK_IDENT
)
2254 error("badly punctuated parameter list");
2255 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2266 /* EOF testing necessary for '-D' handling */
2267 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2268 tok_str_add2(&str
, tok
, &tokc
);
2271 tok_str_add(&str
, 0);
2273 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2276 define_push(v
, t
, str
.str
, first
);
2279 /* XXX: use a token or a hash table to accelerate matching ? */
2280 static CachedInclude
*search_cached_include(TCCState
*s1
,
2281 int type
, const char *filename
)
2286 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
2287 e
= s1
->cached_includes
[i
];
2288 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2294 static inline void add_cached_include(TCCState
*s1
, int type
,
2295 const char *filename
, int ifndef_macro
)
2299 if (search_cached_include(s1
, type
, filename
))
2302 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2304 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2308 strcpy(e
->filename
, filename
);
2309 e
->ifndef_macro
= ifndef_macro
;
2310 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2313 /* is_bof is true if first non space token at beginning of file */
2314 static void preprocess(int is_bof
)
2316 TCCState
*s1
= tcc_state
;
2318 char buf
[1024], *q
, *p
;
2324 return_linefeed
= 1; /* linefeed will be returned as a
2325 token. EOF is also returned as line feed */
2335 s
= define_find(tok
);
2336 /* undefine symbol by putting an invalid name */
2341 ch
= file
->buf_ptr
[0];
2342 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2347 } else if (ch
== '\"') {
2350 /* XXX: better stray handling */
2353 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2354 if ((q
- buf
) < sizeof(buf
) - 1)
2361 /* eat all spaces and comments after include */
2362 /* XXX: slightly incorrect */
2363 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2367 /* computed #include : either we have only strings or
2368 we have anything enclosed in '<>' */
2371 if (tok
== TOK_STR
) {
2372 while (tok
!= TOK_LINEFEED
) {
2373 if (tok
!= TOK_STR
) {
2375 error("'#include' expects \"FILENAME\" or <FILENAME>");
2377 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2383 while (tok
!= TOK_LINEFEED
) {
2384 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2388 /* check syntax and remove '<>' */
2389 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2390 goto include_syntax
;
2391 memmove(buf
, buf
+ 1, len
- 2);
2392 buf
[len
- 2] = '\0';
2397 e
= search_cached_include(s1
, c
, buf
);
2398 if (e
&& define_find(e
->ifndef_macro
)) {
2399 /* no need to parse the include because the 'ifndef macro'
2402 printf("%s: skipping %s\n", file
->filename
, buf
);
2406 /* first search in current dir if "header.h" */
2408 p
= strrchr(file
->filename
, '/');
2410 size
= p
+ 1 - file
->filename
;
2411 if (size
> sizeof(buf1
) - 1)
2412 size
= sizeof(buf1
) - 1;
2413 memcpy(buf1
, file
->filename
, size
);
2415 pstrcat(buf1
, sizeof(buf1
), buf
);
2416 f
= tcc_open(s1
, buf1
);
2420 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2421 error("#include recursion too deep");
2422 /* now search in all the include paths */
2423 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2424 for(i
= 0; i
< n
; i
++) {
2426 if (i
< s1
->nb_include_paths
)
2427 path
= s1
->include_paths
[i
];
2429 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2430 pstrcpy(buf1
, sizeof(buf1
), path
);
2431 pstrcat(buf1
, sizeof(buf1
), "/");
2432 pstrcat(buf1
, sizeof(buf1
), buf
);
2433 f
= tcc_open(s1
, buf1
);
2437 error("include file '%s' not found", buf
);
2441 printf("%s: including %s\n", file
->filename
, buf1
);
2444 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2445 /* push current file in stack */
2446 /* XXX: fix current line init */
2447 *s1
->include_stack_ptr
++ = file
;
2449 /* add include file debug info */
2451 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2453 tok_flags
|= TOK_FLAG_BOF
| TOK_FLAG_BOL
;
2454 ch
= file
->buf_ptr
[0];
2462 c
= expr_preprocess();
2468 if (tok
< TOK_IDENT
)
2469 error("invalid argument for '#if%sdef'", c
? "n" : "");
2473 printf("#ifndef %s\n", get_tok_str(tok
, NULL
));
2475 file
->ifndef_macro
= tok
;
2478 c
= (define_find(tok
) != 0) ^ c
;
2480 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2481 error("memory full");
2482 *s1
->ifdef_stack_ptr
++ = c
;
2485 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2486 error("#else without matching #if");
2487 if (s1
->ifdef_stack_ptr
[-1] & 2)
2488 error("#else after #else");
2489 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2492 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2493 error("#elif without matching #if");
2494 c
= s1
->ifdef_stack_ptr
[-1];
2496 error("#elif after #else");
2497 /* last #if/#elif expression was true: we skip */
2500 c
= expr_preprocess();
2501 s1
->ifdef_stack_ptr
[-1] = c
;
2511 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2512 error("#endif without matching #if");
2513 s1
->ifdef_stack_ptr
--;
2514 /* '#ifndef macro' was at the start of file. Now we check if
2515 an '#endif' is exactly at the end of file */
2516 if (file
->ifndef_macro
&&
2517 s1
->ifdef_stack_ptr
== file
->ifdef_stack_ptr
) {
2518 file
->ifndef_macro_saved
= file
->ifndef_macro
;
2519 /* need to set to zero to avoid false matches if another
2520 #ifndef at middle of file */
2521 file
->ifndef_macro
= 0;
2522 while (tok
!= TOK_LINEFEED
)
2524 tok_flags
|= TOK_FLAG_ENDIF
;
2530 if (tok
!= TOK_CINT
)
2532 file
->line_num
= tokc
.i
- 1; /* the line number will be incremented after */
2534 if (tok
!= TOK_LINEFEED
) {
2537 pstrcpy(file
->filename
, sizeof(file
->filename
),
2538 (char *)tokc
.cstr
->data
);
2546 while (ch
!= '\n' && ch
!= CH_EOF
) {
2547 if ((q
- buf
) < sizeof(buf
) - 1)
2553 error("#error %s", buf
);
2555 warning("#warning %s", buf
);
2561 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
2562 /* '!' is ignored to allow C scripts. numbers are ignored
2563 to emulate cpp behaviour */
2565 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
2569 /* ignore other preprocess commands or #! for C scripts */
2570 while (tok
!= TOK_LINEFEED
)
2573 return_linefeed
= 0;
2576 /* read a number in base b */
2577 static int getn(int b
)
2582 if (ch
>= 'a' && ch
<= 'f')
2584 else if (ch
>= 'A' && ch
<= 'F')
2590 if (t
< 0 || t
>= b
)
2598 /* read a character for string or char constant and eval escape codes */
2599 static int getq(void)
2608 case '0': case '1': case '2': case '3':
2609 case '4': case '5': case '6': case '7':
2610 /* at most three octal digits */
2614 c
= c
* 8 + ch
- '0';
2617 c
= c
* 8 + ch
- '0';
2648 goto invalid_escape
;
2663 goto invalid_escape
;
2668 error("invalid escaped char");
2671 } else if (c
== '\r' && ch
== '\n') {
2678 /* we use 64 bit numbers */
2681 /* bn = (bn << shift) | or_val */
2682 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2686 for(i
=0;i
<BN_SIZE
;i
++) {
2688 bn
[i
] = (v
<< shift
) | or_val
;
2689 or_val
= v
>> (32 - shift
);
2693 void bn_zero(unsigned int *bn
)
2696 for(i
=0;i
<BN_SIZE
;i
++) {
2701 /* parse number in null terminated string 'p' and return it in the
2703 void parse_number(const char *p
)
2705 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
2707 unsigned int bn
[BN_SIZE
];
2718 goto float_frac_parse
;
2719 } else if (t
== '0') {
2720 if (ch
== 'x' || ch
== 'X') {
2724 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2730 /* parse all digits. cannot check octal numbers at this stage
2731 because of floating point constants */
2733 if (ch
>= 'a' && ch
<= 'f')
2735 else if (ch
>= 'A' && ch
<= 'F')
2743 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2745 error("number too long");
2751 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2752 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2754 /* NOTE: strtox should support that for hexa numbers, but
2755 non ISOC99 libcs do not support it, so we prefer to do
2757 /* hexadecimal or binary floats */
2758 /* XXX: handle overflows */
2770 } else if (t
>= 'a') {
2772 } else if (t
>= 'A') {
2777 bn_lshift(bn
, shift
, t
);
2784 if (t
>= 'a' && t
<= 'f') {
2786 } else if (t
>= 'A' && t
<= 'F') {
2788 } else if (t
>= '0' && t
<= '9') {
2794 error("invalid digit");
2795 bn_lshift(bn
, shift
, t
);
2800 if (ch
!= 'p' && ch
!= 'P')
2807 } else if (ch
== '-') {
2811 if (ch
< '0' || ch
> '9')
2812 expect("exponent digits");
2813 while (ch
>= '0' && ch
<= '9') {
2814 exp_val
= exp_val
* 10 + ch
- '0';
2817 exp_val
= exp_val
* s
;
2819 /* now we can generate the number */
2820 /* XXX: should patch directly float number */
2821 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
2822 d
= ldexp(d
, exp_val
- frac_bits
);
2827 /* float : should handle overflow */
2829 } else if (t
== 'L') {
2832 /* XXX: not large enough */
2833 tokc
.ld
= (long double)d
;
2839 /* decimal floats */
2841 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2846 while (ch
>= '0' && ch
<= '9') {
2847 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2853 if (ch
== 'e' || ch
== 'E') {
2854 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2858 if (ch
== '-' || ch
== '+') {
2859 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2864 if (ch
< '0' || ch
> '9')
2865 expect("exponent digits");
2866 while (ch
>= '0' && ch
<= '9') {
2867 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2879 tokc
.f
= strtof(token_buf
, NULL
);
2880 } else if (t
== 'L') {
2883 tokc
.ld
= strtold(token_buf
, NULL
);
2886 tokc
.d
= strtod(token_buf
, NULL
);
2890 unsigned long long n
, n1
;
2893 /* integer number */
2896 if (b
== 10 && *q
== '0') {
2903 /* no need for checks except for base 10 / 8 errors */
2906 } else if (t
>= 'a') {
2908 } else if (t
>= 'A') {
2913 error("invalid digit");
2917 /* detect overflow */
2918 /* XXX: this test is not reliable */
2920 error("integer constant overflow");
2923 /* XXX: not exactly ANSI compliant */
2924 if ((n
& 0xffffffff00000000LL
) != 0) {
2929 } else if (n
> 0x7fffffff) {
2940 error("three 'l's in integer constant");
2943 if (tok
== TOK_CINT
)
2945 else if (tok
== TOK_CUINT
)
2949 } else if (t
== 'U') {
2951 error("two 'u's in integer constant");
2953 if (tok
== TOK_CINT
)
2955 else if (tok
== TOK_CLLONG
)
2962 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2970 #define PARSE2(c1, tok1, c2, tok2) \
2981 /* return next token without macro substitution */
2982 static inline void next_nomacro1(void)
3002 /* first look if it is in fact an end of buffer */
3003 if (p
>= file
->buf_end
) {
3007 if (p
>= file
->buf_end
)
3020 TCCState
*s1
= tcc_state
;
3022 if (return_linefeed
) {
3024 } else if (s1
->include_stack_ptr
== s1
->include_stack
) {
3025 /* no include left : end of file */
3028 /* pop include file */
3030 /* test if previous '#endif' was after a #ifdef at
3032 if (tok_flags
& TOK_FLAG_ENDIF
) {
3034 printf("#endif %s\n", get_tok_str(file
->ifndef_macro_saved
, NULL
));
3036 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
3037 file
->ifndef_macro_saved
);
3040 /* add end of include file debug info */
3042 put_stabd(N_EINCL
, 0, 0);
3044 /* pop include stack */
3046 s1
->include_stack_ptr
--;
3047 file
= *s1
->include_stack_ptr
;
3055 if (return_linefeed
) {
3059 tok_flags
|= TOK_FLAG_BOL
;
3068 if (tok_flags
& TOK_FLAG_BOL
) {
3070 preprocess(tok_flags
& TOK_FLAG_BOF
);
3076 tok
= TOK_TWOSHARPS
;
3083 case 'a': case 'b': case 'c': case 'd':
3084 case 'e': case 'f': case 'g': case 'h':
3085 case 'i': case 'j': case 'k': case 'l':
3086 case 'm': case 'n': case 'o': case 'p':
3087 case 'q': case 'r': case 's': case 't':
3088 case 'u': case 'v': case 'w': case 'x':
3090 case 'A': case 'B': case 'C': case 'D':
3091 case 'E': case 'F': case 'G': case 'H':
3092 case 'I': case 'J': case 'K':
3093 case 'M': case 'N': case 'O': case 'P':
3094 case 'Q': case 'R': case 'S': case 'T':
3095 case 'U': case 'V': case 'W': case 'X':
3101 h
= TOK_HASH_FUNC(h
, c
);
3105 if (!isid(c
) && !isnum(c
))
3107 h
= TOK_HASH_FUNC(h
, c
);
3114 /* fast case : no stray found, so we have the full token
3115 and we have already hashed it */
3117 h
&= (TOK_HASH_SIZE
- 1);
3118 pts
= &hash_ident
[h
];
3123 if (ts
->len
== len
&& !memcmp(ts
->str
, p1
, len
))
3125 pts
= &(ts
->hash_next
);
3127 ts
= tok_alloc_new(pts
, p1
, len
);
3131 cstr_reset(&tokcstr
);
3134 cstr_ccat(&tokcstr
, *p1
);
3140 while (isid(c
) || isnum(c
)) {
3141 cstr_ccat(&tokcstr
, c
);
3144 ts
= tok_alloc(tokcstr
.data
, tokcstr
.size
);
3150 if (t
!= '\\' && t
!= '\'' && t
!= '\"') {
3152 goto parse_ident_fast
;
3158 } else if (c
== '\"') {
3162 cstr_reset(&tokcstr
);
3163 cstr_ccat(&tokcstr
, 'L');
3164 goto parse_ident_slow
;
3168 case '0': case '1': case '2': case '3':
3169 case '4': case '5': case '6': case '7':
3172 cstr_reset(&tokcstr
);
3173 /* after the first digit, accept digits, alpha, '.' or sign if
3174 prefixed by 'eEpP' */
3178 cstr_ccat(&tokcstr
, c
);
3180 if (!(isnum(c
) || isid(c
) || c
== '.' ||
3181 ((c
== '+' || c
== '-') &&
3182 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
3185 /* We add a trailing '\0' to ease parsing */
3186 cstr_ccat(&tokcstr
, '\0');
3187 tokc
.cstr
= &tokcstr
;
3191 /* special dot handling because it can also start a number */
3194 cstr_reset(&tokcstr
);
3195 cstr_ccat(&tokcstr
, '.');
3197 } else if (c
== '.') {
3213 /* this cast is needed if >= 128 */
3214 if (tok
== TOK_CCHAR
)
3218 error("unterminated character constant");
3227 cstr_reset(&tokcstr
);
3228 while (ch
!= '\"') {
3231 error("unterminated string");
3233 cstr_ccat(&tokcstr
, b
);
3235 cstr_wccat(&tokcstr
, b
);
3238 cstr_ccat(&tokcstr
, '\0');
3240 cstr_wccat(&tokcstr
, '\0');
3241 tokc
.cstr
= &tokcstr
;
3251 } else if (c
== '<') {
3269 } else if (c
== '>') {
3287 } else if (c
== '=') {
3300 } else if (c
== '=') {
3313 } else if (c
== '=') {
3326 } else if (c
== '=') {
3329 } else if (c
== '>') {
3337 PARSE2('!', '!', '=', TOK_NE
)
3338 PARSE2('=', '=', '=', TOK_EQ
)
3339 PARSE2('*', '*', '=', TOK_A_MUL
)
3340 PARSE2('%', '%', '=', TOK_A_MOD
)
3341 PARSE2('^', '^', '=', TOK_A_XOR
)
3343 /* comments or operator */
3351 } else if (c
== '/') {
3353 parse_line_comment();
3356 } else if (c
== '=') {
3380 error("unrecognized character \\x%02x", c
);
3385 #if defined(PARSE_DEBUG)
3386 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3390 /* return next token without macro substitution. Can read input from
3392 static void next_nomacro(void)
3398 TOK_GET(tok
, macro_ptr
, tokc
);
3399 if (tok
== TOK_LINENUM
) {
3400 file
->line_num
= tokc
.i
;
3409 /* substitute args in macro_str and return allocated string */
3410 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
3412 int *st
, last_tok
, t
, notfirst
;
3421 TOK_GET(t
, macro_str
, cval
);
3426 TOK_GET(t
, macro_str
, cval
);
3429 s
= sym_find2(args
, t
);
3436 cstr_ccat(&cstr
, ' ');
3437 TOK_GET(t
, st
, cval
);
3438 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
3441 cstr_ccat(&cstr
, '\0');
3443 printf("stringize: %s\n", (char *)cstr
.data
);
3447 tok_str_add2(&str
, TOK_STR
, &cval
);
3450 tok_str_add2(&str
, t
, &cval
);
3452 } else if (t
>= TOK_IDENT
) {
3453 s
= sym_find2(args
, t
);
3456 /* if '##' is present before or after, no arg substitution */
3457 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
3458 /* special case for var arg macros : ## eats the
3459 ',' if empty VA_ARGS variable. */
3460 /* XXX: test of the ',' is not 100%
3461 reliable. should fix it to avoid security
3463 if (gnu_ext
&& s
->type
.t
&&
3464 last_tok
== TOK_TWOSHARPS
&&
3465 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
3467 /* suppress ',' '##' */
3470 /* suppress '##' and add variable */
3478 TOK_GET(t1
, st
, cval
);
3481 tok_str_add2(&str
, t1
, &cval
);
3485 macro_subst(&str
, nested_list
, st
);
3488 tok_str_add(&str
, t
);
3491 tok_str_add2(&str
, t
, &cval
);
3495 tok_str_add(&str
, 0);
3499 /* handle the '##' operator */
3500 static int *macro_twosharps(void)
3505 const char *p1
, *p2
;
3507 TokenString macro_str1
;
3511 tok_str_new(¯o_str1
);
3517 while (*macro_ptr
== TOK_TWOSHARPS
) {
3519 macro_ptr1
= macro_ptr
;
3522 TOK_GET(t
, macro_ptr
, cval
);
3524 /* We concatenate the two tokens if we have an
3525 identifier or a preprocessing number */
3527 p1
= get_tok_str(tok
, &tokc
);
3528 cstr_cat(&cstr
, p1
);
3529 p2
= get_tok_str(t
, &cval
);
3530 cstr_cat(&cstr
, p2
);
3531 cstr_ccat(&cstr
, '\0');
3533 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
3534 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
3535 if (tok
== TOK_PPNUM
) {
3536 /* if number, then create a number token */
3537 /* NOTE: no need to allocate because
3538 tok_str_add2() does it */
3541 /* if identifier, we must do a test to
3542 validate we have a correct identifier */
3543 if (t
== TOK_PPNUM
) {
3553 if (!isnum(c
) && !isid(c
))
3557 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
3558 tok
= ts
->tok
; /* modify current token */
3561 const char *str
= cstr
.data
;
3562 const unsigned char *q
;
3564 /* we look for a valid token */
3565 /* XXX: do more extensive checks */
3566 if (!strcmp(str
, ">>=")) {
3568 } else if (!strcmp(str
, "<<=")) {
3570 } else if (strlen(str
) == 2) {
3571 /* search in two bytes table */
3576 if (q
[0] == str
[0] && q
[1] == str
[1])
3583 /* NOTE: because get_tok_str use a static buffer,
3586 p1
= get_tok_str(tok
, &tokc
);
3587 cstr_cat(&cstr
, p1
);
3588 cstr_ccat(&cstr
, '\0');
3589 p2
= get_tok_str(t
, &cval
);
3590 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
3591 /* cannot merge tokens: just add them separately */
3592 tok_str_add2(¯o_str1
, tok
, &tokc
);
3593 /* XXX: free associated memory ? */
3600 tok_str_add2(¯o_str1
, tok
, &tokc
);
3603 tok_str_add(¯o_str1
, 0);
3604 return macro_str1
.str
;
3608 /* do macro substitution of current token with macro 's' and add
3609 result to (tok_str,tok_len). 'nested_list' is the list of all
3610 macros we got inside to avoid recursing. Return non zero if no
3611 substitution needs to be done */
3612 static int macro_subst_tok(TokenString
*tok_str
,
3613 Sym
**nested_list
, Sym
*s
)
3615 Sym
*args
, *sa
, *sa1
;
3616 int mstr_allocated
, parlevel
, *mstr
, t
;
3622 /* if symbol is a macro, prepare substitution */
3623 /* if nested substitution, do nothing */
3624 if (sym_find2(*nested_list
, tok
))
3627 /* special macros */
3628 if (tok
== TOK___LINE__
) {
3629 cval
.i
= file
->line_num
;
3630 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
3631 } else if (tok
== TOK___FILE__
) {
3632 cstrval
= file
->filename
;
3634 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3635 } else if (tok
== TOK___DATE__
) {
3636 cstrval
= "Jan 1 2002";
3638 } else if (tok
== TOK___TIME__
) {
3639 cstrval
= "00:00:00";
3642 cstr_cat(&cstr
, cstrval
);
3643 cstr_ccat(&cstr
, '\0');
3645 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3650 if (s
->type
.t
== MACRO_FUNC
) {
3651 /* NOTE: we do not use next_nomacro to avoid eating the
3652 next token. XXX: find better solution */
3656 /* XXX: incorrect with comments */
3657 ch
= file
->buf_ptr
[0];
3658 while (is_space(ch
) || ch
== '\n')
3662 if (t
!= '(') /* no macro subst */
3665 /* argument macro */
3670 /* NOTE: empty args are allowed, except if no args */
3672 /* handle '()' case */
3673 if (!args
&& tok
== ')')
3676 error("macro '%s' used with too many args",
3677 get_tok_str(s
->v
, 0));
3680 /* NOTE: non zero sa->t indicates VA_ARGS */
3681 while ((parlevel
> 0 ||
3683 (tok
!= ',' || sa
->type
.t
))) &&
3687 else if (tok
== ')')
3689 tok_str_add2(&str
, tok
, &tokc
);
3692 tok_str_add(&str
, 0);
3693 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
3696 /* special case for gcc var args: add an empty
3697 var arg argument if it is omitted */
3698 if (sa
&& sa
->type
.t
&& gnu_ext
)
3708 error("macro '%s' used with too few args",
3709 get_tok_str(s
->v
, 0));
3712 /* now subst each arg */
3713 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3718 tok_str_free((int *)sa
->c
);
3724 sym_push2(nested_list
, s
->v
, 0, 0);
3725 macro_subst(tok_str
, nested_list
, mstr
);
3726 /* pop nested defined symbol */
3728 *nested_list
= sa1
->prev
;
3736 /* do macro substitution of macro_str and add result to
3737 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3738 inside to avoid recursing. */
3739 static void macro_subst(TokenString
*tok_str
,
3740 Sym
**nested_list
, int *macro_str
)
3743 int *saved_macro_ptr
;
3746 saved_macro_ptr
= macro_ptr
;
3747 macro_ptr
= macro_str
;
3748 /* first scan for '##' operator handling */
3749 macro_str1
= macro_twosharps();
3750 macro_ptr
= macro_str1
;
3756 s
= define_find(tok
);
3758 if (macro_subst_tok(tok_str
, nested_list
, s
) != 0)
3762 tok_str_add2(tok_str
, tok
, &tokc
);
3765 macro_ptr
= saved_macro_ptr
;
3766 tok_str_free(macro_str1
);
3769 /* return next token with macro substitution */
3770 static void next(void)
3772 Sym
*nested_list
, *s
;
3775 /* special 'ungettok' case for label parsing */
3784 /* if not reading from macro substituted string, then try
3785 to substitute macros */
3786 if (tok
>= TOK_IDENT
) {
3787 s
= define_find(tok
);
3789 /* we have a macro: we try to substitute */
3792 if (macro_subst_tok(&str
, &nested_list
, s
) == 0) {
3793 /* substitution done, NOTE: maybe empty */
3794 tok_str_add(&str
, 0);
3795 macro_ptr
= str
.str
;
3796 macro_ptr_allocated
= str
.str
;
3803 /* end of macro string: free it */
3804 tok_str_free(macro_ptr_allocated
);
3810 /* convert preprocessor tokens into C tokens */
3811 if (tok
== TOK_PPNUM
) {
3812 parse_number((char *)tokc
.cstr
->data
);
3817 void swap(int *p
, int *q
)
3825 void vsetc(CType
*type
, int r
, CValue
*vc
)
3829 if (vtop
>= vstack
+ VSTACK_SIZE
)
3830 error("memory full");
3831 /* cannot let cpu flags if other instruction are generated. Also
3832 avoid leaving VT_JMP anywhere except on the top of the stack
3833 because it would complicate the code generator. */
3834 if (vtop
>= vstack
) {
3835 v
= vtop
->r
& VT_VALMASK
;
3836 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
3842 vtop
->r2
= VT_CONST
;
3846 /* push integer constant */
3851 vsetc(&int_type
, VT_CONST
, &cval
);
3854 /* Return a static symbol pointing to a section */
3855 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
3856 unsigned long offset
, unsigned long size
)
3862 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
3863 sym
->type
.ref
= type
->ref
;
3864 sym
->r
= VT_CONST
| VT_SYM
;
3865 put_extern_sym(sym
, sec
, offset
, size
);
3869 /* push a reference to a section offset by adding a dummy symbol */
3870 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
3875 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
3876 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
3879 /* define a new external reference to a symbol 'v' of type 'u' */
3880 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
3886 /* push forward reference */
3887 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
3888 s
->type
.ref
= type
->ref
;
3889 s
->r
= r
| VT_CONST
| VT_SYM
;
3894 /* define a new external reference to a symbol 'v' of type 'u' */
3895 static Sym
*external_sym(int v
, CType
*type
, int r
)
3901 /* push forward reference */
3902 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
3903 s
->type
.t
|= VT_EXTERN
;
3908 /* push a reference to global symbol v */
3909 static void vpush_global_sym(CType
*type
, int v
)
3914 sym
= external_global_sym(v
, type
, 0);
3916 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
3920 void vset(CType
*type
, int r
, int v
)
3925 vsetc(type
, r
, &cval
);
3928 void vseti(int r
, int v
)
3944 void vpushv(SValue
*v
)
3946 if (vtop
>= vstack
+ VSTACK_SIZE
)
3947 error("memory full");
3957 /* save r to the memory stack, and mark it as being free */
3958 void save_reg(int r
)
3960 int l
, saved
, size
, align
;
3964 /* modify all stack values */
3967 for(p
=vstack
;p
<=vtop
;p
++) {
3968 if ((p
->r
& VT_VALMASK
) == r
||
3969 (p
->r2
& VT_VALMASK
) == r
) {
3970 /* must save value on stack if not already done */
3972 /* NOTE: must reload 'r' because r might be equal to r2 */
3973 r
= p
->r
& VT_VALMASK
;
3974 /* store register in the stack */
3976 if ((p
->r
& VT_LVAL
) ||
3977 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
3979 size
= type_size(type
, &align
);
3980 loc
= (loc
- size
) & -align
;
3981 sv
.type
.t
= type
->t
;
3982 sv
.r
= VT_LOCAL
| VT_LVAL
;
3985 #ifdef TCC_TARGET_I386
3986 /* x86 specific: need to pop fp register ST0 if saved */
3988 o(0xd9dd); /* fstp %st(1) */
3991 /* special long long case */
3992 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
3999 /* mark that stack entry as being saved on the stack */
4000 if (p
->r
& VT_LVAL
) {
4001 /* also suppress the bounded flag because the
4002 relocation address of the function was stored in
4004 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
4006 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
4014 /* find a free register of class 'rc'. If none, save one register */
4020 /* find a free register */
4021 for(r
=0;r
<NB_REGS
;r
++) {
4022 if (reg_classes
[r
] & rc
) {
4023 for(p
=vstack
;p
<=vtop
;p
++) {
4024 if ((p
->r
& VT_VALMASK
) == r
||
4025 (p
->r2
& VT_VALMASK
) == r
)
4033 /* no register left : free the first one on the stack (VERY
4034 IMPORTANT to start from the bottom to ensure that we don't
4035 spill registers used in gen_opi()) */
4036 for(p
=vstack
;p
<=vtop
;p
++) {
4037 r
= p
->r
& VT_VALMASK
;
4038 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
4040 /* also look at second register (if long long) */
4041 r
= p
->r2
& VT_VALMASK
;
4042 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
4048 /* Should never comes here */
4052 /* save registers up to (vtop - n) stack entry */
4053 void save_regs(int n
)
4058 for(p
= vstack
;p
<= p1
; p
++) {
4059 r
= p
->r
& VT_VALMASK
;
4066 /* move register 's' to 'r', and flush previous value of r to memory
4068 void move_reg(int r
, int s
)
4081 /* get address of vtop (vtop MUST BE an lvalue) */
4084 vtop
->r
&= ~VT_LVAL
;
4085 /* tricky: if saved lvalue, then we can go back to lvalue */
4086 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
4087 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
4090 #ifdef CONFIG_TCC_BCHECK
4091 /* generate lvalue bound code */
4097 vtop
->r
&= ~VT_MUSTBOUND
;
4098 /* if lvalue, then use checking code before dereferencing */
4099 if (vtop
->r
& VT_LVAL
) {
4100 /* if not VT_BOUNDED value, then make one */
4101 if (!(vtop
->r
& VT_BOUNDED
)) {
4102 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
4103 /* must save type because we must set it to int to get pointer */
4105 vtop
->type
.t
= VT_INT
;
4108 gen_bounded_ptr_add();
4109 vtop
->r
|= lval_type
;
4112 /* then check for dereferencing */
4113 gen_bounded_ptr_deref();
4118 /* store vtop a register belonging to class 'rc'. lvalues are
4119 converted to values. Cannot be used if cannot be converted to
4120 register value (such as structures). */
4123 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
4124 unsigned long long ll
;
4126 /* NOTE: get_reg can modify vstack[] */
4127 if (vtop
->type
.t
& VT_BITFIELD
) {
4128 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
4129 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4130 /* remove bit field info to avoid loops */
4131 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4132 /* generate shifts */
4133 vpushi(32 - (bit_pos
+ bit_size
));
4135 vpushi(32 - bit_size
);
4136 /* NOTE: transformed to SHR if unsigned */
4140 if (is_float(vtop
->type
.t
) &&
4141 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4144 unsigned long offset
;
4146 /* XXX: unify with initializers handling ? */
4147 /* CPUs usually cannot use float constants, so we store them
4148 generically in data segment */
4149 size
= type_size(&vtop
->type
, &align
);
4150 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
4151 data_section
->data_offset
= offset
;
4152 /* XXX: not portable yet */
4153 ptr
= section_ptr_add(data_section
, size
);
4156 ptr
[i
] = vtop
->c
.tab
[i
];
4157 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
4158 vtop
->r
|= VT_LVAL
| VT_SYM
;
4162 #ifdef CONFIG_TCC_BCHECK
4163 if (vtop
->r
& VT_MUSTBOUND
)
4167 r
= vtop
->r
& VT_VALMASK
;
4168 /* need to reload if:
4170 - lvalue (need to dereference pointer)
4171 - already a register, but not in the right class */
4172 if (r
>= VT_CONST
||
4173 (vtop
->r
& VT_LVAL
) ||
4174 !(reg_classes
[r
] & rc
) ||
4175 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
4176 !(reg_classes
[vtop
->r2
] & rc
))) {
4178 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
4179 /* two register type load : expand to two words
4181 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4184 vtop
->c
.ui
= ll
; /* first word */
4186 vtop
->r
= r
; /* save register value */
4187 vpushi(ll
>> 32); /* second word */
4188 } else if (r
>= VT_CONST
||
4189 (vtop
->r
& VT_LVAL
)) {
4190 /* load from memory */
4193 vtop
[-1].r
= r
; /* save register value */
4194 /* increment pointer to get second word */
4195 vtop
->type
.t
= VT_INT
;
4201 /* move registers */
4204 vtop
[-1].r
= r
; /* save register value */
4205 vtop
->r
= vtop
[-1].r2
;
4207 /* allocate second register */
4214 /* write second register */
4216 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
4218 /* lvalue of scalar type : need to use lvalue type
4219 because of possible cast */
4222 /* compute memory access type */
4223 if (vtop
->r
& VT_LVAL_BYTE
)
4225 else if (vtop
->r
& VT_LVAL_SHORT
)
4227 if (vtop
->r
& VT_LVAL_UNSIGNED
)
4231 /* restore wanted type */
4234 /* one register type load */
4243 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4244 void gv2(int rc1
, int rc2
)
4248 /* generate more generic register first. But VT_JMP or VT_CMP
4249 values must be generated first in all cases to avoid possible
4251 v
= vtop
[0].r
& VT_VALMASK
;
4252 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
4257 /* test if reload is needed for first register */
4258 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
4268 /* test if reload is needed for first register */
4269 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
4275 /* expand long long on stack in two int registers */
4280 u
= vtop
->type
.t
& VT_UNSIGNED
;
4283 vtop
[0].r
= vtop
[-1].r2
;
4284 vtop
[0].r2
= VT_CONST
;
4285 vtop
[-1].r2
= VT_CONST
;
4286 vtop
[0].type
.t
= VT_INT
| u
;
4287 vtop
[-1].type
.t
= VT_INT
| u
;
4290 /* build a long long from two ints */
4293 gv2(RC_INT
, RC_INT
);
4294 vtop
[-1].r2
= vtop
[0].r
;
4295 vtop
[-1].type
.t
= t
;
4299 /* rotate n first stack elements to the bottom */
4306 for(i
=-n
+1;i
!=0;i
++)
4307 vtop
[i
] = vtop
[i
+1];
4311 /* pop stack value */
4315 v
= vtop
->r
& VT_VALMASK
;
4316 #ifdef TCC_TARGET_I386
4317 /* for x86, we need to pop the FP stack */
4318 if (v
== REG_ST0
&& !nocode_wanted
) {
4319 o(0xd9dd); /* fstp %st(1) */
4322 if (v
== VT_JMP
|| v
== VT_JMPI
) {
4323 /* need to put correct jump if && or || without test */
4329 /* convert stack entry to register and duplicate its value in another
4337 if ((t
& VT_BTYPE
) == VT_LLONG
) {
4344 /* stack: H L L1 H1 */
4352 /* duplicate value */
4363 load(r1
, &sv
); /* move r to r1 */
4365 /* duplicates value */
4370 /* generate CPU independent (unsigned) long long operations */
4371 void gen_opl(int op
)
4373 int t
, a
, b
, op1
, c
, i
;
4381 func
= TOK___divdi3
;
4384 func
= TOK___udivdi3
;
4387 func
= TOK___moddi3
;
4390 func
= TOK___umoddi3
;
4392 /* call generic long long function */
4393 gfunc_start(&gf
, FUNC_CDECL
);
4396 vpush_global_sym(&func_old_type
, func
);
4400 vtop
->r2
= REG_LRET
;
4413 /* stack: L1 H1 L2 H2 */
4418 vtop
[-2] = vtop
[-3];
4421 /* stack: H1 H2 L1 L2 */
4427 /* stack: H1 H2 L1 L2 ML MH */
4430 /* stack: ML MH H1 H2 L1 L2 */
4434 /* stack: ML MH H1 L2 H2 L1 */
4439 /* stack: ML MH M1 M2 */
4442 } else if (op
== '+' || op
== '-') {
4443 /* XXX: add non carry method too (for MIPS or alpha) */
4449 /* stack: H1 H2 (L1 op L2) */
4452 gen_op(op1
+ 1); /* TOK_xxxC2 */
4455 /* stack: H1 H2 (L1 op L2) */
4458 /* stack: (L1 op L2) H1 H2 */
4460 /* stack: (L1 op L2) (H1 op H2) */
4468 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4469 t
= vtop
[-1].type
.t
;
4473 /* stack: L H shift */
4475 /* constant: simpler */
4476 /* NOTE: all comments are for SHL. the other cases are
4477 done by swaping words */
4488 if (op
!= TOK_SAR
) {
4521 /* XXX: should provide a faster fallback on x86 ? */
4524 func
= TOK___sardi3
;
4527 func
= TOK___shrdi3
;
4530 func
= TOK___shldi3
;
4536 /* compare operations */
4542 /* stack: L1 H1 L2 H2 */
4544 vtop
[-1] = vtop
[-2];
4546 /* stack: L1 L2 H1 H2 */
4549 /* when values are equal, we need to compare low words. since
4550 the jump is inverted, we invert the test too. */
4553 else if (op1
== TOK_GT
)
4555 else if (op1
== TOK_ULT
)
4557 else if (op1
== TOK_UGT
)
4562 if (op1
!= TOK_NE
) {
4566 /* generate non equal test */
4567 /* XXX: NOT PORTABLE yet */
4571 #ifdef TCC_TARGET_I386
4572 b
= psym(0x850f, 0);
4574 error("not implemented");
4578 /* compare low. Always unsigned */
4582 else if (op1
== TOK_LE
)
4584 else if (op1
== TOK_GT
)
4586 else if (op1
== TOK_GE
)
4596 /* handle integer constant optimizations and various machine
4598 void gen_opic(int op
)
4605 /* currently, we cannot do computations with forward symbols */
4606 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4607 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4611 case '+': v1
->c
.i
+= fc
; break;
4612 case '-': v1
->c
.i
-= fc
; break;
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;
4623 /* if division by zero, generate explicit division */
4626 error("division by zero in constant");
4630 default: v1
->c
.i
/= fc
; break;
4631 case '%': v1
->c
.i
%= fc
; break;
4632 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
4633 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
4636 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
4637 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
4638 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
4640 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
4641 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
4642 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
4643 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
4644 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
4645 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
4646 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
4647 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
4648 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
4649 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
4651 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
4652 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
4658 /* if commutative ops, put c2 as constant */
4659 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
4660 op
== '|' || op
== '*')) {
4665 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
4668 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
4669 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
4675 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
4676 /* try to use shifts instead of muls or divs */
4677 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
4686 else if (op
== TOK_PDIV
)
4692 } else if (c2
&& (op
== '+' || op
== '-') &&
4693 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
4694 (VT_CONST
| VT_SYM
)) {
4695 /* symbol + constant case */
4702 if (!nocode_wanted
) {
4703 /* call low level op generator */
4712 /* generate a floating point operation with constant propagation */
4713 void gen_opif(int op
)
4721 /* currently, we cannot do computations with forward symbols */
4722 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4723 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4725 if (v1
->type
.t
== VT_FLOAT
) {
4728 } else if (v1
->type
.t
== VT_DOUBLE
) {
4736 /* NOTE: we only do constant propagation if finite number (not
4737 NaN or infinity) (ANSI spec) */
4738 if (!ieee_finite(f1
) || !ieee_finite(f2
))
4742 case '+': f1
+= f2
; break;
4743 case '-': f1
-= f2
; break;
4744 case '*': f1
*= f2
; break;
4748 error("division by zero in constant");
4753 /* XXX: also handles tests ? */
4757 /* XXX: overflow test ? */
4758 if (v1
->type
.t
== VT_FLOAT
) {
4760 } else if (v1
->type
.t
== VT_DOUBLE
) {
4768 if (!nocode_wanted
) {
4776 static int pointed_size(CType
*type
)
4779 return type_size(pointed_type(type
), &align
);
4783 void check_pointer_types(SValue
*p1
, SValue
*p2
)
4785 char buf1
[256], buf2
[256];
4789 if (!is_compatible_types(t1
, t2
)) {
4790 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
4791 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
4792 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
4797 /* generic gen_op: handles types problems */
4800 int u
, t1
, t2
, bt1
, bt2
, t
;
4803 t1
= vtop
[-1].type
.t
;
4804 t2
= vtop
[0].type
.t
;
4805 bt1
= t1
& VT_BTYPE
;
4806 bt2
= t2
& VT_BTYPE
;
4808 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
4809 /* at least one operand is a pointer */
4810 /* relationnal op: must be both pointers */
4811 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4812 // check_pointer_types(vtop, vtop - 1);
4813 /* pointers are handled are unsigned */
4814 t
= VT_INT
| VT_UNSIGNED
;
4817 /* if both pointers, then it must be the '-' op */
4818 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
4820 error("cannot use pointers here");
4821 // check_pointer_types(vtop - 1, vtop);
4822 /* XXX: check that types are compatible */
4823 u
= pointed_size(&vtop
[-1].type
);
4825 /* set to integer type */
4826 vtop
->type
.t
= VT_INT
;
4830 /* exactly one pointer : must be '+' or '-'. */
4831 if (op
!= '-' && op
!= '+')
4832 error("cannot use pointers here");
4833 /* Put pointer as first operand */
4834 if (bt2
== VT_PTR
) {
4838 type1
= vtop
[-1].type
;
4839 /* XXX: cast to int ? (long long case) */
4840 vpushi(pointed_size(&vtop
[-1].type
));
4842 #ifdef CONFIG_TCC_BCHECK
4843 /* if evaluating constant expression, no code should be
4844 generated, so no bound check */
4845 if (do_bounds_check
&& !const_wanted
) {
4846 /* if bounded pointers, we generate a special code to
4853 gen_bounded_ptr_add();
4859 /* put again type if gen_opic() swaped operands */
4862 } else if (is_float(bt1
) || is_float(bt2
)) {
4863 /* compute bigger type and do implicit casts */
4864 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
4866 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
4871 /* floats can only be used for a few operations */
4872 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
4873 (op
< TOK_ULT
|| op
> TOK_GT
))
4874 error("invalid operands for binary operation");
4876 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
4877 /* cast to biggest op */
4879 /* convert to unsigned if it does not fit in a long long */
4880 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4881 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4885 /* integer operations */
4887 /* convert to unsigned if it does not fit in an integer */
4888 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4889 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4892 /* XXX: currently, some unsigned operations are explicit, so
4893 we modify them here */
4894 if (t
& VT_UNSIGNED
) {
4901 else if (op
== TOK_LT
)
4903 else if (op
== TOK_GT
)
4905 else if (op
== TOK_LE
)
4907 else if (op
== TOK_GE
)
4914 /* special case for shifts and long long: we keep the shift as
4916 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
4921 else if ((t
& VT_BTYPE
) == VT_LLONG
)
4925 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4926 /* relationnal op: the result is an int */
4927 vtop
->type
.t
= VT_INT
;
4934 /* generic itof for unsigned long long case */
4935 void gen_cvt_itof1(int t
)
4939 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
4940 (VT_LLONG
| VT_UNSIGNED
)) {
4942 gfunc_start(&gf
, FUNC_CDECL
);
4945 vpush_global_sym(&func_old_type
, TOK___ulltof
);
4946 else if (t
== VT_DOUBLE
)
4947 vpush_global_sym(&func_old_type
, TOK___ulltod
);
4949 vpush_global_sym(&func_old_type
, TOK___ulltold
);
4958 /* generic ftoi for unsigned long long case */
4959 void gen_cvt_ftoi1(int t
)
4964 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
4965 /* not handled natively */
4966 gfunc_start(&gf
, FUNC_CDECL
);
4967 st
= vtop
->type
.t
& VT_BTYPE
;
4970 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
4971 else if (st
== VT_DOUBLE
)
4972 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
4974 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
4978 vtop
->r2
= REG_LRET
;
4984 /* force char or short cast */
4985 void force_charshort_cast(int t
)
4989 /* XXX: add optimization if lvalue : just change type and offset */
4994 if (t
& VT_UNSIGNED
) {
4995 vpushi((1 << bits
) - 1);
5006 /* cast 'vtop' to 'type' */
5007 static void gen_cast(CType
*type
)
5009 int sbt
, dbt
, sf
, df
, c
;
5011 /* special delayed cast for char/short */
5012 /* XXX: in some cases (multiple cascaded casts), it may still
5014 if (vtop
->r
& VT_MUSTCAST
) {
5015 vtop
->r
&= ~VT_MUSTCAST
;
5016 force_charshort_cast(vtop
->type
.t
);
5019 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
5020 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5022 if (sbt
!= dbt
&& !nocode_wanted
) {
5025 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5027 /* convert from fp to fp */
5029 /* constant case: we can do it now */
5030 /* XXX: in ISOC, cannot do it if error in convert */
5031 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
5032 vtop
->c
.f
= (float)vtop
->c
.d
;
5033 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
5034 vtop
->c
.f
= (float)vtop
->c
.ld
;
5035 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
5036 vtop
->c
.d
= (double)vtop
->c
.f
;
5037 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
5038 vtop
->c
.d
= (double)vtop
->c
.ld
;
5039 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
5040 vtop
->c
.ld
= (long double)vtop
->c
.f
;
5041 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
5042 vtop
->c
.ld
= (long double)vtop
->c
.d
;
5044 /* non constant case: generate code */
5048 /* convert int to fp */
5051 case VT_LLONG
| VT_UNSIGNED
:
5053 /* XXX: add const cases for long long */
5055 case VT_INT
| VT_UNSIGNED
:
5057 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
5058 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
5059 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
5064 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
5065 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
5066 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
5075 /* convert fp to int */
5076 /* we handle char/short/etc... with generic code */
5077 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
5078 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
5083 case VT_LLONG
| VT_UNSIGNED
:
5085 /* XXX: add const cases for long long */
5087 case VT_INT
| VT_UNSIGNED
:
5089 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5090 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5091 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5097 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5098 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5099 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5107 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
5108 /* additionnal cast for char/short/bool... */
5112 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
5113 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
5114 /* scalar to long long */
5116 if (sbt
== (VT_INT
| VT_UNSIGNED
))
5117 vtop
->c
.ll
= vtop
->c
.ui
;
5119 vtop
->c
.ll
= vtop
->c
.i
;
5121 /* machine independant conversion */
5123 /* generate high word */
5124 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
5132 /* patch second register */
5133 vtop
[-1].r2
= vtop
->r
;
5137 } else if (dbt
== VT_BOOL
) {
5138 /* scalar to bool */
5141 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
5142 (dbt
& VT_BTYPE
) == VT_SHORT
) {
5143 force_charshort_cast(dbt
);
5144 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
5146 if (sbt
== VT_LLONG
) {
5147 /* from long long: just take low order word */
5151 /* if lvalue and single word type, nothing to do because
5152 the lvalue already contains the real type size (see
5153 VT_LVAL_xxx constants) */
5159 /* return type size. Put alignment at 'a' */
5160 static int type_size(CType
*type
, int *a
)
5165 bt
= type
->t
& VT_BTYPE
;
5166 if (bt
== VT_STRUCT
) {
5171 } else if (bt
== VT_PTR
) {
5172 if (type
->t
& VT_ARRAY
) {
5174 return type_size(&s
->type
, a
) * s
->c
;
5179 } else if (bt
== VT_LDOUBLE
) {
5181 return LDOUBLE_SIZE
;
5182 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
5183 *a
= 4; /* XXX: i386 specific */
5185 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
5188 } else if (bt
== VT_SHORT
) {
5192 /* char, void, function, _Bool */
5198 /* return the pointed type of t */
5199 static inline CType
*pointed_type(CType
*type
)
5201 return &type
->ref
->type
;
5204 /* modify type so that its it is a pointer to type. */
5205 static void mk_pointer(CType
*type
)
5208 s
= sym_push(SYM_FIELD
, type
, 0, -1);
5209 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
5213 static int is_compatible_types(CType
*type1
, CType
*type2
)
5216 int bt1
, bt2
, t1
, t2
;
5218 t1
= type1
->t
& VT_TYPE
;
5219 t2
= type2
->t
& VT_TYPE
;
5220 bt1
= t1
& VT_BTYPE
;
5221 bt2
= t2
& VT_BTYPE
;
5222 if (bt1
== VT_PTR
) {
5223 type1
= pointed_type(type1
);
5224 /* if function, then convert implicitely to function pointer */
5225 if (bt2
!= VT_FUNC
) {
5228 type2
= pointed_type(type2
);
5230 /* void matches everything */
5231 /* XXX: not fully compliant */
5232 if ((type1
->t
& VT_TYPE
) == VT_VOID
|| (type2
->t
& VT_TYPE
) == VT_VOID
)
5234 return is_compatible_types(type1
, type2
);
5235 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
5237 } else if (bt1
== VT_FUNC
) {
5242 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5244 /* XXX: not complete */
5245 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
5249 while (s1
!= NULL
) {
5252 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5261 /* XXX: not complete */
5266 /* print a type. If 'varstr' is not NULL, then the variable is also
5267 printed in the type */
5269 /* XXX: add array and function pointers */
5270 void type_to_str(char *buf
, int buf_size
,
5271 CType
*type
, const char *varstr
)
5278 t
= type
->t
& VT_TYPE
;
5281 if (t
& VT_UNSIGNED
)
5282 pstrcat(buf
, buf_size
, "unsigned ");
5312 tstr
= "long double";
5314 pstrcat(buf
, buf_size
, tstr
);
5318 if (bt
== VT_STRUCT
)
5322 pstrcat(buf
, buf_size
, tstr
);
5323 v
= type
->ref
->v
& ~SYM_STRUCT
;
5324 if (v
>= SYM_FIRST_ANOM
)
5325 pstrcat(buf
, buf_size
, "<anonymous>");
5327 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
5331 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
5332 pstrcat(buf
, buf_size
, "(");
5334 while (sa
!= NULL
) {
5335 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
5336 pstrcat(buf
, buf_size
, buf1
);
5339 pstrcat(buf
, buf_size
, ", ");
5341 pstrcat(buf
, buf_size
, ")");
5345 pstrcpy(buf1
, sizeof(buf1
), "*");
5347 pstrcat(buf1
, sizeof(buf1
), varstr
);
5348 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
5352 pstrcat(buf
, buf_size
, " ");
5353 pstrcat(buf
, buf_size
, varstr
);
5358 /* verify type compatibility to store vtop in 'dt' type, and generate
5360 void gen_assign_cast(CType
*dt
)
5363 char buf1
[256], buf2
[256];
5365 st
= &vtop
->type
; /* source type */
5366 if ((dt
->t
& VT_BTYPE
) == VT_PTR
) {
5367 /* special cases for pointers */
5368 /* a function is implicitely a function pointer */
5369 if ((st
->t
& VT_BTYPE
) == VT_FUNC
) {
5370 if (!is_compatible_types(pointed_type(dt
), st
))
5375 /* '0' can also be a pointer */
5376 if ((st
->t
& VT_BTYPE
) == VT_INT
&&
5377 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
5381 if (!is_compatible_types(dt
, st
)) {
5383 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
5384 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
5385 error("cannot cast '%s' to '%s'", buf1
, buf2
);
5391 /* store vtop in lvalue pushed on stack */
5394 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
5397 ft
= vtop
[-1].type
.t
;
5398 sbt
= vtop
->type
.t
& VT_BTYPE
;
5399 dbt
= ft
& VT_BTYPE
;
5400 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
5401 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
5402 /* optimize char/short casts */
5403 delayed_cast
= VT_MUSTCAST
;
5404 vtop
->type
.t
= ft
& VT_TYPE
;
5407 gen_assign_cast(&vtop
[-1].type
);
5410 if (sbt
== VT_STRUCT
) {
5411 /* if structure, only generate pointer */
5412 /* structure assignment : generate memcpy */
5413 /* XXX: optimize if small size */
5414 if (!nocode_wanted
) {
5416 gfunc_start(&gf
, FUNC_CDECL
);
5418 size
= type_size(&vtop
->type
, &align
);
5422 vtop
->type
.t
= VT_INT
;
5427 vtop
->type
.t
= VT_INT
;
5432 vpush_global_sym(&func_old_type
, TOK_memcpy
);
5438 /* leave source on stack */
5439 } else if (ft
& VT_BITFIELD
) {
5440 /* bitfield store handling */
5441 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
5442 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
5443 /* remove bit field info to avoid loops */
5444 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
5446 /* duplicate destination */
5448 vtop
[-1] = vtop
[-2];
5450 /* mask and shift source */
5451 vpushi((1 << bit_size
) - 1);
5455 /* load destination, mask and or with source */
5457 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
5463 #ifdef CONFIG_TCC_BCHECK
5464 /* bound check case */
5465 if (vtop
[-1].r
& VT_MUSTBOUND
) {
5471 if (!nocode_wanted
) {
5475 r
= gv(rc
); /* generate value */
5476 /* if lvalue was saved on stack, must read it */
5477 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
5479 t
= get_reg(RC_INT
);
5481 sv
.r
= VT_LOCAL
| VT_LVAL
;
5482 sv
.c
.ul
= vtop
[-1].c
.ul
;
5484 vtop
[-1].r
= t
| VT_LVAL
;
5487 /* two word case handling : store second register at word + 4 */
5488 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
5490 /* convert to int to increment easily */
5491 vtop
->type
.t
= VT_INT
;
5497 /* XXX: it works because r2 is spilled last ! */
5498 store(vtop
->r2
, vtop
- 1);
5502 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5503 vtop
->r
|= delayed_cast
;
5507 /* post defines POST/PRE add. c is the token ++ or -- */
5508 void inc(int post
, int c
)
5511 vdup(); /* save lvalue */
5513 gv_dup(); /* duplicate value */
5518 vpushi(c
- TOK_MID
);
5520 vstore(); /* store value */
5522 vpop(); /* if post op, return saved value */
5525 /* Parse GNUC __attribute__ extension. Currently, the following
5526 extensions are recognized:
5527 - aligned(n) : set data/function alignment.
5528 - section(x) : generate data/code in this section.
5529 - unused : currently ignored, but may be used someday.
5531 void parse_attribute(AttributeDef
*ad
)
5538 while (tok
!= ')') {
5539 if (tok
< TOK_IDENT
)
5540 expect("attribute name");
5545 case TOK___SECTION__
:
5548 expect("section name");
5549 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
5554 case TOK___ALIGNED__
:
5557 if (n
<= 0 || (n
& (n
- 1)) != 0)
5558 error("alignment must be a positive power of two");
5563 case TOK___UNUSED__
:
5564 /* currently, no need to handle it because tcc does not
5565 track unused objects */
5568 case TOK___NORETURN__
:
5569 /* currently, no need to handle it because tcc does not
5570 track unused objects */
5575 ad
->func_call
= FUNC_CDECL
;
5579 case TOK___STDCALL__
:
5580 ad
->func_call
= FUNC_STDCALL
;
5583 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
5584 /* skip parameters */
5585 /* XXX: skip parenthesis too */
5588 while (tok
!= ')' && tok
!= -1)
5602 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5603 static void struct_decl(CType
*type
, int u
)
5605 int a
, v
, size
, align
, maxalign
, c
, offset
;
5606 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
5611 a
= tok
; /* save decl type */
5616 /* struct already defined ? return it */
5617 /* XXX: check consistency */
5621 error("invalid type");
5628 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, 0);
5629 /* put struct/union/enum name in type */
5637 error("struct/union/enum already defined");
5638 /* cannot be empty */
5640 /* non empty enums are not allowed */
5641 if (a
== TOK_ENUM
) {
5649 /* enum symbols have static storage */
5650 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
5651 ss
->type
.t
|= VT_STATIC
;
5664 while (tok
!= '}') {
5665 parse_btype(&btype
, &ad
);
5671 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
);
5672 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
5673 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
5674 error("invalid type for '%s'",
5675 get_tok_str(v
, NULL
));
5679 bit_size
= expr_const();
5680 /* XXX: handle v = 0 case for messages */
5682 error("negative width in bit-field '%s'",
5683 get_tok_str(v
, NULL
));
5684 if (v
&& bit_size
== 0)
5685 error("zero width for bit-field '%s'",
5686 get_tok_str(v
, NULL
));
5688 size
= type_size(&type1
, &align
);
5690 if (bit_size
>= 0) {
5691 bt
= type1
.t
& VT_BTYPE
;
5696 error("bitfields must have scalar type");
5698 if (bit_size
> bsize
) {
5699 error("width of '%s' exceeds its type",
5700 get_tok_str(v
, NULL
));
5701 } else if (bit_size
== bsize
) {
5702 /* no need for bit fields */
5704 } else if (bit_size
== 0) {
5705 /* XXX: what to do if only padding in a
5707 /* zero size: means to pad */
5711 /* we do not have enough room ? */
5712 if ((bit_pos
+ bit_size
) > bsize
)
5715 /* XXX: handle LSB first */
5716 type1
.t
|= VT_BITFIELD
|
5717 (bit_pos
<< VT_STRUCT_SHIFT
) |
5718 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
5719 bit_pos
+= bit_size
;
5725 /* add new memory data only if starting
5727 if (lbit_pos
== 0) {
5728 if (a
== TOK_STRUCT
) {
5729 c
= (c
+ align
- 1) & -align
;
5737 if (align
> maxalign
)
5741 printf("add field %s offset=%d",
5742 get_tok_str(v
, NULL
), offset
);
5743 if (type1
.t
& VT_BITFIELD
) {
5744 printf(" pos=%d size=%d",
5745 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
5746 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
5750 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
5754 if (tok
== ';' || tok
== TOK_EOF
)
5761 /* store size and alignment */
5762 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
5768 /* return 0 if no type declaration. otherwise, return the basic type
5771 static int parse_btype(CType
*type
, AttributeDef
*ad
)
5773 int t
, u
, type_found
;
5777 memset(ad
, 0, sizeof(AttributeDef
));
5788 if ((t
& VT_BTYPE
) != 0)
5789 error("too many basic types");
5803 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
5804 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5805 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
5806 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
5820 if ((t
& VT_BTYPE
) == VT_LONG
) {
5821 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5828 struct_decl(&type1
, VT_ENUM
);
5831 type
->ref
= type1
.ref
;
5835 struct_decl(&type1
, VT_STRUCT
);
5838 /* type modifiers */
5843 case TOK___SIGNED__
:
5846 case TOK___INLINE__
:
5868 /* GNUC attribute */
5869 case TOK___ATTRIBUTE__
:
5870 parse_attribute(ad
);
5875 parse_expr_type(&type1
);
5879 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
5881 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
5882 type
->ref
= s
->type
.ref
;
5889 /* long is never used as type */
5890 if ((t
& VT_BTYPE
) == VT_LONG
)
5891 t
= (t
& ~VT_BTYPE
) | VT_INT
;
5896 static void post_type(CType
*type
, AttributeDef
*ad
)
5899 Sym
**plast
, *s
, *first
;
5904 /* function declaration */
5909 while (tok
!= ')') {
5910 /* read param name and compute offset */
5911 if (l
!= FUNC_OLD
) {
5912 if (!parse_btype(&pt
, &ad1
)) {
5914 error("invalid type");
5921 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5923 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
5924 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
5925 error("parameter declared as void");
5932 /* array must be transformed to pointer according to ANSI C */
5934 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
5939 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5946 /* if no parameters, then old type prototype */
5950 t1
= type
->t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5951 type
->t
&= ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5952 post_type(type
, ad
);
5953 /* we push a anonymous symbol which will contain the function prototype */
5954 s
= sym_push(SYM_FIELD
, type
, ad
->func_call
, l
);
5956 type
->t
= t1
| VT_FUNC
;
5958 } else if (tok
== '[') {
5959 /* array definition */
5965 error("invalid array size");
5968 /* parse next post type */
5969 t1
= type
->t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5970 type
->t
&= ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5971 post_type(type
, ad
);
5973 /* we push a anonymous symbol which will contain the array
5975 s
= sym_push(SYM_FIELD
, type
, 0, n
);
5976 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
5981 /* Parse a type declaration (except basic type), and return the type
5982 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5983 expected. 'type' should contain the basic type. 'ad' is the
5984 attribute definition of the basic type. It can be modified by
5987 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
5990 CType type1
, *type2
;
5992 while (tok
== '*') {
5994 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
5999 /* recursive type */
6000 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6001 type1
.t
= 0; /* XXX: same as int */
6004 /* XXX: this is not correct to modify 'ad' at this point, but
6005 the syntax is not clear */
6006 if (tok
== TOK___ATTRIBUTE__
)
6007 parse_attribute(ad
);
6008 type_decl(&type1
, ad
, v
, td
);
6011 /* type identifier */
6012 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
6016 if (!(td
& TYPE_ABSTRACT
))
6017 expect("identifier");
6021 post_type(type
, ad
);
6022 if (tok
== TOK___ATTRIBUTE__
)
6023 parse_attribute(ad
);
6026 /* append type at the end of type1 */
6039 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6040 static int lvalue_type(int t
)
6047 else if (bt
== VT_SHORT
)
6051 if (t
& VT_UNSIGNED
)
6052 r
|= VT_LVAL_UNSIGNED
;
6056 /* indirection with full error checking and bound check */
6057 static void indir(void)
6059 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
6061 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
6063 vtop
->type
= *pointed_type(&vtop
->type
);
6064 /* an array is never an lvalue */
6065 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6066 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6067 /* if bound checking, the referenced pointer must be checked */
6068 if (do_bounds_check
)
6069 vtop
->r
|= VT_MUSTBOUND
;
6073 /* pass a parameter to a function and do type checking and casting */
6074 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
6079 func_type
= func
->c
;
6080 if (func_type
== FUNC_OLD
||
6081 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
6082 /* default casting : only need to convert float to double */
6083 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
6087 } else if (arg
== NULL
) {
6088 error("too many arguments to function");
6090 gen_assign_cast(&arg
->type
);
6092 if (!nocode_wanted
) {
6099 /* parse an expression of the form '(type)' or '(expr)' and return its
6101 static void parse_expr_type(CType
*type
)
6107 if (parse_btype(type
, &ad
)) {
6108 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
6115 static void vpush_tokc(int t
)
6119 vsetc(&type
, VT_CONST
, &tokc
);
6122 static void unary(void)
6124 int n
, t
, align
, size
, r
;
6130 /* XXX: GCC 2.95.3 does not generate a table although it should be
6140 vpush_tokc(VT_INT
| VT_UNSIGNED
);
6144 vpush_tokc(VT_LLONG
);
6148 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
6152 vpush_tokc(VT_FLOAT
);
6156 vpush_tokc(VT_DOUBLE
);
6160 vpush_tokc(VT_LDOUBLE
);
6163 case TOK___FUNCTION__
:
6165 goto tok_identifier
;
6171 /* special function name identifier */
6172 len
= strlen(funcname
) + 1;
6173 /* generate char[len] type */
6178 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
6179 ptr
= section_ptr_add(data_section
, len
);
6180 memcpy(ptr
, funcname
, len
);
6188 /* string parsing */
6194 memset(&ad
, 0, sizeof(AttributeDef
));
6195 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
6200 if (parse_btype(&type
, &ad
)) {
6201 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
6203 /* check ISOC99 compound literal */
6205 /* data is allocated locally by default */
6210 /* all except arrays are lvalues */
6211 if (!(type
.t
& VT_ARRAY
))
6212 r
|= lvalue_type(type
.t
);
6213 memset(&ad
, 0, sizeof(AttributeDef
));
6214 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
6232 /* functions names must be treated as function pointers,
6233 except for unary '&' and sizeof. Since we consider that
6234 functions are not lvalues, we only have to handle it
6235 there and in function calls. */
6236 /* arrays can also be used although they are not lvalues */
6237 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
6238 !(vtop
->type
.t
& VT_ARRAY
))
6240 mk_pointer(&vtop
->type
);
6246 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
6247 vtop
->c
.i
= !vtop
->c
.i
;
6248 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
6249 vtop
->c
.i
= vtop
->c
.i
^ 1;
6251 vseti(VT_JMP
, gtst(1, 0));
6261 /* in order to force cast, we add zero */
6263 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
6264 error("pointer not accepted for unary plus");
6273 parse_expr_type(&type
);
6277 size
= type_size(&type
, &align
);
6278 if (t
== TOK_SIZEOF
)
6299 goto tok_identifier
;
6301 /* allow to take the address of a label */
6302 if (tok
< TOK_UIDENT
)
6303 expect("label identifier");
6304 s
= label_find(tok
);
6306 s
= label_push(tok
, LABEL_FORWARD
);
6309 s
->type
.t
= VT_VOID
;
6310 mk_pointer(&s
->type
);
6311 s
->type
.t
|= VT_STATIC
;
6313 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
6322 expect("identifier");
6326 error("'%s' undeclared", get_tok_str(t
, NULL
));
6327 /* for simple function calls, we tolerate undeclared
6328 external reference to int() function */
6329 s
= external_global_sym(t
, &func_old_type
, 0);
6331 vset(&s
->type
, s
->r
, s
->c
);
6332 /* if forward reference, we must point to s */
6333 if (vtop
->r
& VT_SYM
) {
6340 /* post operations */
6342 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
6345 } else if (tok
== '.' || tok
== TOK_ARROW
) {
6347 if (tok
== TOK_ARROW
)
6352 /* expect pointer on structure */
6353 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
6354 expect("struct or union");
6358 while ((s
= s
->next
) != NULL
) {
6363 error("field not found");
6364 /* add field offset to pointer */
6365 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
6368 /* change type to field type, and set to lvalue */
6369 vtop
->type
= s
->type
;
6370 /* an array is never an lvalue */
6371 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6372 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6373 /* if bound checking, the referenced pointer must be checked */
6374 if (do_bounds_check
)
6375 vtop
->r
|= VT_MUSTBOUND
;
6378 } else if (tok
== '[') {
6384 } else if (tok
== '(') {
6389 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
6390 /* pointer test (no array accepted) */
6391 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
6392 vtop
->type
= *pointed_type(&vtop
->type
);
6393 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
6397 expect("function pointer");
6400 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
6402 /* get return type */
6404 if (!nocode_wanted
) {
6405 save_regs(0); /* save used temporary registers */
6406 gfunc_start(&gf
, s
->r
);
6409 sa
= s
->next
; /* first parameter */
6410 #ifdef INVERT_FUNC_PARAMS
6414 ParseState saved_parse_state
;
6417 /* read each argument and store it on a stack */
6423 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
6427 else if (tok
== ')')
6429 tok_str_add_tok(&str
);
6432 tok_str_add(&str
, -1); /* end of file added */
6433 tok_str_add(&str
, 0);
6434 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
6435 s1
->next
= sa
; /* add reference to argument */
6444 /* now generate code in reverse order by reading the stack */
6445 save_parse_state(&saved_parse_state
);
6447 macro_ptr
= (int *)args
->c
;
6451 expect("',' or ')'");
6452 gfunc_param_typed(&gf
, s
, args
->next
);
6454 tok_str_free((int *)args
->c
);
6458 restore_parse_state(&saved_parse_state
);
6461 /* compute first implicit argument if a structure is returned */
6462 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
6463 /* get some space for the returned structure */
6464 size
= type_size(&s
->type
, &align
);
6465 loc
= (loc
- size
) & -align
;
6467 ret
.r
= VT_LOCAL
| VT_LVAL
;
6468 /* pass it as 'int' to avoid structure arg passing
6470 vseti(VT_LOCAL
, loc
);
6479 /* return in register */
6480 if (is_float(ret
.type
.t
)) {
6483 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
6489 #ifndef INVERT_FUNC_PARAMS
6493 gfunc_param_typed(&gf
, s
, sa
);
6503 error("too few arguments to function");
6510 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
6518 static void uneq(void)
6524 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
6525 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
6526 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
6541 static void expr_prod(void)
6546 while (tok
== '*' || tok
== '/' || tok
== '%') {
6554 static void expr_sum(void)
6559 while (tok
== '+' || tok
== '-') {
6567 static void expr_shift(void)
6572 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
6580 static void expr_cmp(void)
6585 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
6586 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
6594 static void expr_cmpeq(void)
6599 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
6607 static void expr_and(void)
6610 while (tok
== '&') {
6617 static void expr_xor(void)
6620 while (tok
== '^') {
6627 static void expr_or(void)
6630 while (tok
== '|') {
6637 /* XXX: suppress this mess */
6638 static void expr_land_const(void)
6641 while (tok
== TOK_LAND
) {
6648 /* XXX: suppress this mess */
6649 static void expr_lor_const(void)
6652 while (tok
== TOK_LOR
) {
6659 /* only used if non constant */
6660 static void expr_land(void)
6665 if (tok
== TOK_LAND
) {
6669 if (tok
!= TOK_LAND
) {
6679 static void expr_lor(void)
6684 if (tok
== TOK_LOR
) {
6688 if (tok
!= TOK_LOR
) {
6698 /* XXX: better constant handling */
6699 static void expr_eq(void)
6701 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
6703 CType type
, type1
, type2
;
6724 if (vtop
!= vstack
) {
6725 /* needed to avoid having different registers saved in
6727 if (is_float(vtop
->type
.t
))
6737 sv
= *vtop
; /* save value to handle it later */
6738 vtop
--; /* no vpop so that FP stack is not flushed */
6746 bt1
= t1
& VT_BTYPE
;
6748 bt2
= t2
& VT_BTYPE
;
6749 /* cast operands to correct type according to ISOC rules */
6750 if (is_float(bt1
) || is_float(bt2
)) {
6751 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
6752 type
.t
= VT_LDOUBLE
;
6753 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
6758 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
6759 /* cast to biggest op */
6761 /* convert to unsigned if it does not fit in a long long */
6762 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
6763 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
6764 type
.t
|= VT_UNSIGNED
;
6765 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
6766 /* XXX: test pointer compatibility */
6768 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
6769 /* XXX: test structure compatibility */
6771 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
6772 /* NOTE: as an extension, we accept void on only one side */
6775 /* integer operations */
6777 /* convert to unsigned if it does not fit in an integer */
6778 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
6779 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
6780 type
.t
|= VT_UNSIGNED
;
6783 /* now we convert second operand */
6786 if (is_float(type
.t
)) {
6788 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
6789 /* for long longs, we use fixed registers to avoid having
6790 to handle a complicated move */
6795 /* this is horrible, but we must also convert first
6799 /* put again first value and cast it */
6810 static void gexpr(void)
6821 /* parse an expression and return its type without any side effect. */
6822 static void expr_type(CType
*type
)
6834 /* parse a unary expression and return its type without any side
6836 static void unary_type(CType
*type
)
6848 /* parse a constant expression and return value in vtop. */
6849 static void expr_const1(void)
6858 /* parse an integer constant and return its value. */
6859 static int expr_const(void)
6863 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
6864 expect("constant expression");
6870 /* return the label token if current token is a label, otherwise
6872 static int is_label(void)
6877 /* fast test first */
6878 if (tok
< TOK_UIDENT
)
6880 /* no need to save tokc since we expect an identifier */
6888 /* XXX: may not work in all cases (macros ?) */
6897 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
6902 /* generate line number info */
6904 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
6905 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
6907 last_line_num
= file
->line_num
;
6910 if (tok
== TOK_IF
) {
6917 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6919 if (c
== TOK_ELSE
) {
6923 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6924 gsym(d
); /* patch else jmp */
6927 } else if (tok
== TOK_WHILE
) {
6935 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6939 } else if (tok
== '{') {
6943 while (tok
!= '}') {
6946 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6948 /* pop locally defined symbols */
6949 sym_pop(&local_stack
, s
);
6951 } else if (tok
== TOK_RETURN
) {
6955 gen_assign_cast(&func_vt
);
6956 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
6958 /* if returning structure, must copy it to implicit
6959 first pointer arg location */
6962 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
6965 /* copy structure value to pointer */
6967 } else if (is_float(func_vt
.t
)) {
6972 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6975 rsym
= gjmp(rsym
); /* jmp */
6976 } else if (tok
== TOK_BREAK
) {
6979 error("cannot break");
6980 *bsym
= gjmp(*bsym
);
6983 } else if (tok
== TOK_CONTINUE
) {
6986 error("cannot continue");
6987 *csym
= gjmp(*csym
);
6990 } else if (tok
== TOK_FOR
) {
7017 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
7022 if (tok
== TOK_DO
) {
7027 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
7038 if (tok
== TOK_SWITCH
) {
7042 /* XXX: other types than integer */
7043 case_reg
= gv(RC_INT
);
7047 b
= gjmp(0); /* jump to first case */
7049 block(&a
, csym
, &b
, &c
, case_reg
);
7050 /* if no default, jmp after switch */
7058 if (tok
== TOK_CASE
) {
7065 if (gnu_ext
&& tok
== TOK_DOTS
) {
7069 warning("empty case range");
7071 /* since a case is like a label, we must skip it with a jmp */
7078 *case_sym
= gtst(1, 0);
7081 *case_sym
= gtst(1, 0);
7085 *case_sym
= gtst(1, *case_sym
);
7089 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
7091 if (tok
== TOK_DEFAULT
) {
7097 error("too many 'default'");
7099 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
7101 if (tok
== TOK_GOTO
) {
7103 if (tok
== '*' && gnu_ext
) {
7107 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
7110 } else if (tok
>= TOK_UIDENT
) {
7111 s
= label_find(tok
);
7112 /* put forward definition if needed */
7114 s
= label_push(tok
, LABEL_FORWARD
);
7116 /* label already defined */
7117 if (s
->r
& LABEL_FORWARD
)
7118 s
->next
= (void *)gjmp((long)s
->next
);
7120 gjmp_addr((long)s
->next
);
7123 expect("label identifier");
7132 if (!(s
->r
& LABEL_FORWARD
))
7133 error("multiple defined label");
7134 gsym((long)s
->next
);
7136 s
= label_push(b
, 0);
7138 s
->next
= (void *)ind
;
7140 /* we accept this, but it is a mistake */
7142 warning("deprecated use of label at end of compound statement");
7144 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
7146 /* expression case */
7156 /* t is the array or struct type. c is the array or struct
7157 address. cur_index/cur_field is the pointer to the current
7158 value. 'size_only' is true if only size info is needed (only used
7160 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
7161 int *cur_index
, Sym
**cur_field
,
7165 int notfirst
, index
, align
, l
;
7169 if (gnu_ext
&& (l
= is_label()) != 0)
7172 while (tok
== '[' || tok
== '.') {
7174 if (!(type
->t
& VT_ARRAY
))
7175 expect("array type");
7178 index
= expr_const();
7179 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
7180 expect("invalid index");
7184 type
= pointed_type(type
);
7185 c
+= index
* type_size(type
, &align
);
7191 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
7192 expect("struct/union type");
7205 /* XXX: suppress this mess by using explicit storage field */
7207 type1
.t
|= (type
->t
& ~VT_TYPE
);
7221 if (type
->t
& VT_ARRAY
) {
7223 type
= pointed_type(type
);
7224 c
+= index
* type_size(type
, &align
);
7228 error("too many field init");
7229 /* XXX: suppress this mess by using explicit storage field */
7231 type1
.t
|= (type
->t
& ~VT_TYPE
);
7236 decl_initializer(type
, sec
, c
, 0, size_only
);
7240 #define EXPR_CONST 1
7243 /* store a value or an expression directly in global data or in local array */
7244 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
7245 int v
, int expr_type
)
7247 int saved_global_expr
, bt
;
7255 /* compound literals must be allocated globally in this case */
7256 saved_global_expr
= global_expr
;
7259 global_expr
= saved_global_expr
;
7260 /* NOTE: symbols are accepted */
7261 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
7262 error("initializer element is not constant");
7270 /* XXX: not portable */
7271 /* XXX: generate error if incorrect relocation */
7272 gen_assign_cast(type
);
7273 bt
= type
->t
& VT_BTYPE
;
7274 ptr
= sec
->data
+ c
;
7275 if ((vtop
->r
& VT_SYM
) &&
7281 error("initializer element is not computable at load time");
7284 *(char *)ptr
= vtop
->c
.i
;
7287 *(short *)ptr
= vtop
->c
.i
;
7290 *(double *)ptr
= vtop
->c
.d
;
7293 *(long double *)ptr
= vtop
->c
.ld
;
7296 *(long long *)ptr
= vtop
->c
.ll
;
7299 if (vtop
->r
& VT_SYM
) {
7300 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
7302 *(int *)ptr
= vtop
->c
.i
;
7307 vset(type
, VT_LOCAL
, c
);
7314 /* put zeros for variable based init */
7315 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
7320 /* nothing to do because globals are already set to zero */
7322 gfunc_start(&gf
, FUNC_CDECL
);
7329 vpush_global_sym(&func_old_type
, TOK_memset
);
7334 /* 't' contains the type and storage info. 'c' is the offset of the
7335 object in section 'sec'. If 'sec' is NULL, it means stack based
7336 allocation. 'first' is true if array '{' must be read (multi
7337 dimension implicit array init handling). 'size_only' is true if
7338 size only evaluation is wanted (only for arrays). */
7339 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
7340 int first
, int size_only
)
7342 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
7343 int size1
, align1
, expr_type
;
7347 if (type
->t
& VT_ARRAY
) {
7351 t1
= pointed_type(type
);
7352 size1
= type_size(t1
, &align1
);
7355 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
7361 /* only parse strings here if correct type (otherwise: handle
7362 them as ((w)char *) expressions */
7363 if ((tok
== TOK_LSTR
&&
7364 (t1
->t
& VT_BTYPE
) == VT_INT
) ||
7366 (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
7367 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
7372 /* compute maximum number of chars wanted */
7374 cstr_len
= cstr
->size
;
7376 cstr_len
= cstr
->size
/ sizeof(int);
7379 if (n
>= 0 && nb
> (n
- array_length
))
7380 nb
= n
- array_length
;
7383 warning("initializer-string for array is too long");
7384 /* in order to go faster for common case (char
7385 string in global variable, we handle it
7387 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
7388 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
7392 ch
= ((unsigned char *)cstr
->data
)[i
];
7394 ch
= ((int *)cstr
->data
)[i
];
7395 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
7403 /* only add trailing zero if enough storage (no
7404 warning in this case since it is standard) */
7405 if (n
< 0 || array_length
< n
) {
7407 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
7413 while (tok
!= '}') {
7414 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
7415 if (n
>= 0 && index
>= n
)
7416 error("index too large");
7417 /* must put zero in holes (note that doing it that way
7418 ensures that it even works with designators) */
7419 if (!size_only
&& array_length
< index
) {
7420 init_putz(t1
, sec
, c
+ array_length
* size1
,
7421 (index
- array_length
) * size1
);
7424 if (index
> array_length
)
7425 array_length
= index
;
7426 /* special test for multi dimensional arrays (may not
7427 be strictly correct if designators are used at the
7429 if (index
>= n
&& no_oblock
)
7438 /* put zeros at the end */
7439 if (!size_only
&& n
>= 0 && array_length
< n
) {
7440 init_putz(t1
, sec
, c
+ array_length
* size1
,
7441 (n
- array_length
) * size1
);
7443 /* patch type size if needed */
7445 s
->c
= array_length
;
7446 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
7447 (sec
|| !first
|| tok
== '{')) {
7448 /* NOTE: the previous test is a specific case for automatic
7449 struct/union init */
7450 /* XXX: union needs only one init */
7451 /* XXX: handle bit fields */
7453 if (first
|| tok
== '{') {
7462 while (tok
!= '}') {
7463 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
7464 /* XXX: bitfields ? */
7465 /* fill with zero between fields */
7467 if (!size_only
&& array_length
< index
) {
7468 init_putz(type
, sec
, c
+ array_length
,
7469 index
- array_length
);
7471 index
= index
+ type_size(&f
->type
, &align1
);
7472 if (index
> array_length
)
7473 array_length
= index
;
7474 if (no_oblock
&& f
->next
== NULL
)
7481 /* put zeros at the end */
7482 if (!size_only
&& array_length
< n
) {
7483 init_putz(type
, sec
, c
+ array_length
,
7488 } else if (tok
== '{') {
7490 decl_initializer(type
, sec
, c
, first
, size_only
);
7492 } else if (size_only
) {
7493 /* just skip expression */
7495 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
7499 else if (tok
== ')')
7504 /* currently, we always use constant expression for globals
7505 (may change for scripting case) */
7506 expr_type
= EXPR_CONST
;
7508 expr_type
= EXPR_ANY
;
7509 init_putv(type
, sec
, c
, 0, expr_type
);
7513 /* parse an initializer for type 't' if 'has_init' is non zero, and
7514 allocate space in local or global data space ('r' is either
7515 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7516 variable 'v' of scope 'scope' is declared before initializers are
7517 parsed. If 'v' is zero, then a reference to the new object is put
7518 in the value stack. If 'has_init' is 2, a special parsing is done
7519 to handle string constants. */
7520 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
7521 int has_init
, int v
, int scope
)
7523 int size
, align
, addr
, data_offset
;
7525 ParseState saved_parse_state
;
7526 TokenString init_str
;
7529 size
= type_size(type
, &align
);
7530 /* If unknown size, we must evaluate it before
7531 evaluating initializers because
7532 initializers can generate global data too
7533 (e.g. string pointers or ISOC99 compound
7534 literals). It also simplifies local
7535 initializers handling */
7536 tok_str_new(&init_str
);
7539 error("unknown type size");
7540 /* get all init string */
7541 if (has_init
== 2) {
7542 /* only get strings */
7543 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
7544 tok_str_add_tok(&init_str
);
7549 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
7551 error("unexpected end of file in initializer");
7552 tok_str_add_tok(&init_str
);
7555 else if (tok
== '}') {
7563 tok_str_add(&init_str
, -1);
7564 tok_str_add(&init_str
, 0);
7567 save_parse_state(&saved_parse_state
);
7569 macro_ptr
= init_str
.str
;
7571 decl_initializer(type
, NULL
, 0, 1, 1);
7572 /* prepare second initializer parsing */
7573 macro_ptr
= init_str
.str
;
7576 /* if still unknown size, error */
7577 size
= type_size(type
, &align
);
7579 error("unknown type size");
7581 /* take into account specified alignment if bigger */
7582 if (ad
->aligned
> align
)
7583 align
= ad
->aligned
;
7584 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
7586 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
7588 #ifdef TCC_TARGET_IL
7589 /* XXX: ugly patch to allocate local variables for IL, just
7594 loc
= (loc
- size
) & -align
;
7597 /* handles bounds */
7598 /* XXX: currently, since we do only one pass, we cannot track
7599 '&' operators, so we add only arrays */
7600 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
7601 unsigned long *bounds_ptr
;
7602 /* add padding between regions */
7604 /* then add local bound info */
7605 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
7606 bounds_ptr
[0] = addr
;
7607 bounds_ptr
[1] = size
;
7610 /* compute section */
7618 data_offset
= sec
->data_offset
;
7619 data_offset
= (data_offset
+ align
- 1) & -align
;
7621 /* very important to increment global pointer at this time
7622 because initializers themselves can create new initializers */
7623 data_offset
+= size
;
7624 /* add padding if bound check */
7625 if (do_bounds_check
)
7627 sec
->data_offset
= data_offset
;
7628 /* allocate section space to put the data */
7629 if (sec
->sh_type
!= SHT_NOBITS
&&
7630 data_offset
> sec
->data_allocated
)
7631 section_realloc(sec
, data_offset
);
7635 /* local variable */
7636 sym_push(v
, type
, r
, addr
);
7638 /* push local reference */
7639 vset(type
, r
, addr
);
7645 if (scope
== VT_CONST
) {
7646 /* global scope: see if already defined */
7650 if (!is_compatible_types(&sym
->type
, type
))
7651 error("incompatible types for redefinition of '%s'",
7652 get_tok_str(v
, NULL
));
7653 if (!(sym
->type
.t
& VT_EXTERN
))
7654 error("redefinition of '%s'", get_tok_str(v
, NULL
));
7655 sym
->type
.t
&= ~VT_EXTERN
;
7658 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
7660 put_extern_sym(sym
, sec
, addr
, size
);
7664 /* push global reference */
7665 sym
= get_sym_ref(type
, sec
, addr
, size
);
7667 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
7671 /* handles bounds now because the symbol must be defined
7672 before for the relocation */
7673 if (do_bounds_check
) {
7674 unsigned long *bounds_ptr
;
7676 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
7677 /* then add global bound info */
7678 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
7679 bounds_ptr
[0] = 0; /* relocated */
7680 bounds_ptr
[1] = size
;
7684 decl_initializer(type
, sec
, addr
, 1, 0);
7685 /* restore parse state if needed */
7687 tok_str_free(init_str
.str
);
7688 restore_parse_state(&saved_parse_state
);
7693 void put_func_debug(Sym
*sym
)
7698 /* XXX: we put here a dummy type */
7699 snprintf(buf
, sizeof(buf
), "%s:%c1",
7700 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
7701 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
7702 cur_text_section
, sym
->c
);
7707 /* not finished : try to put some local vars in registers */
7708 //#define CONFIG_REG_VARS
7710 #ifdef CONFIG_REG_VARS
7711 void add_var_ref(int t
)
7713 printf("%s:%d: &%s\n",
7714 file
->filename
, file
->line_num
,
7715 get_tok_str(t
, NULL
));
7718 /* first pass on a function with heuristic to extract variable usage
7719 and pointer references to local variables for register allocation */
7720 void analyse_function(void)
7727 /* any symbol coming after '&' is considered as being a
7728 variable whose reference is taken. It is highly unaccurate
7729 but it is difficult to do better without a complete parse */
7732 /* if '& number', then no need to examine next tokens */
7733 if (tok
== TOK_CINT
||
7735 tok
== TOK_CLLONG
||
7736 tok
== TOK_CULLONG
) {
7738 } else if (tok
>= TOK_UIDENT
) {
7739 /* if '& ident [' or '& ident ->', then ident address
7743 if (tok
!= '[' && tok
!= TOK_ARROW
)
7747 while (tok
!= '}' && tok
!= ';' &&
7748 !((tok
== ',' || tok
== ')') && level
== 0)) {
7749 if (tok
>= TOK_UIDENT
) {
7751 } else if (tok
== '(') {
7753 } else if (tok
== ')') {
7766 /* parse an old style function declaration list */
7767 /* XXX: check multiple parameter */
7768 static void func_decl_list(Sym
*func_sym
)
7775 /* parse each declaration */
7776 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
) {
7777 if (!parse_btype(&btype
, &ad
))
7778 expect("declaration list");
7779 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
7780 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
7782 /* we accept no variable after */
7786 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
7787 /* find parameter in function parameter list */
7790 if ((s
->v
& ~SYM_FIELD
) == v
)
7794 error("declaration for parameter '%s' but no such parameter",
7795 get_tok_str(v
, NULL
));
7797 /* check that no storage specifier except 'register' was given */
7798 if (type
.t
& (VT_EXTERN
| VT_STATIC
| VT_TYPEDEF
))
7799 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
7800 /* we can add the type (NOTE: it could be local to the function) */
7802 /* accept other parameters */
7813 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
7814 static void decl(int l
)
7822 if (!parse_btype(&btype
, &ad
)) {
7823 /* skip redundant ';' */
7824 /* XXX: find more elegant solution */
7829 /* special test for old K&R protos without explicit int
7830 type. Only accepted when defining global data */
7831 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
7835 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
7836 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
7838 /* we accept no variable after */
7842 while (1) { /* iterate thru each declaration */
7844 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
7848 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
7849 printf("type = '%s'\n", buf
);
7852 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
7853 /* if old style function prototype, we accept a
7856 if (sym
->c
== FUNC_OLD
)
7857 func_decl_list(sym
);
7861 #ifdef CONFIG_REG_VARS
7862 TokenString func_str
;
7863 ParseState saved_parse_state
;
7868 error("cannot use local functions");
7869 if (!(type
.t
& VT_FUNC
))
7870 expect("function definition");
7872 #ifdef CONFIG_REG_VARS
7873 /* parse all function code and record it */
7875 tok_str_new(&func_str
);
7881 error("unexpected end of file");
7882 tok_str_add_tok(&func_str
);
7887 } else if (t
== '}') {
7889 if (block_level
== 0)
7893 tok_str_add(&func_str
, -1);
7894 tok_str_add(&func_str
, 0);
7896 save_parse_state(&saved_parse_state
);
7898 macro_ptr
= func_str
.str
;
7903 /* compute text section */
7904 cur_text_section
= ad
.section
;
7905 if (!cur_text_section
)
7906 cur_text_section
= text_section
;
7907 ind
= cur_text_section
->data_offset
;
7908 funcname
= get_tok_str(v
, NULL
);
7911 /* if symbol is already defined, then put complete type */
7914 /* put function symbol */
7915 sym
= global_identifier_push(v
, type
.t
, 0);
7916 sym
->type
.ref
= type
.ref
;
7918 /* NOTE: we patch the symbol size later */
7919 put_extern_sym(sym
, cur_text_section
, ind
, 0);
7921 sym
->r
= VT_SYM
| VT_CONST
;
7922 /* put debug symbol */
7924 put_func_debug(sym
);
7925 /* push a dummy symbol to enable local sym storage */
7926 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
7927 gfunc_prolog(&type
);
7930 #ifdef CONFIG_REG_VARS
7931 macro_ptr
= func_str
.str
;
7934 block(NULL
, NULL
, NULL
, NULL
, 0);
7937 cur_text_section
->data_offset
= ind
;
7938 /* look if any labels are undefined. Define symbols if
7939 '&&label' was used. */
7942 for(s
= label_stack
; s
!= NULL
; s
= s1
) {
7944 if (s
->r
& LABEL_FORWARD
) {
7945 error("label '%s' used but not defined",
7946 get_tok_str(s
->v
, NULL
));
7949 /* define corresponding symbol. A size of
7951 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
7954 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= NULL
;
7959 sym_pop(&local_stack
, NULL
); /* reset local stack */
7960 /* end of function */
7961 /* patch symbol size */
7962 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
7965 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
7967 funcname
= ""; /* for safety */
7968 func_vt
.t
= VT_VOID
; /* for safety */
7969 ind
= 0; /* for safety */
7971 #ifdef CONFIG_REG_VARS
7972 tok_str_free(func_str
.str
);
7973 restore_parse_state(&saved_parse_state
);
7977 if (btype
.t
& VT_TYPEDEF
) {
7978 /* save typedefed type */
7979 /* XXX: test storage specifiers ? */
7980 sym
= sym_push(v
, &type
, 0, 0);
7981 sym
->type
.t
|= VT_TYPEDEF
;
7982 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
7983 /* external function definition */
7984 external_sym(v
, &type
, 0);
7986 /* not lvalue if array */
7988 if (!(type
.t
& VT_ARRAY
))
7989 r
|= lvalue_type(type
.t
);
7990 if (btype
.t
& VT_EXTERN
) {
7991 /* external variable */
7992 external_sym(v
, &type
, r
);
7994 if (type
.t
& VT_STATIC
)
7998 has_init
= (tok
== '=');
8001 decl_initializer_alloc(&type
, &ad
, r
,
8015 /* compile the C file opened in 'file'. Return non zero if errors. */
8016 static int tcc_compile(TCCState
*s1
)
8020 volatile int section_sym
;
8023 printf("%s: **** new file\n", file
->filename
);
8026 s1
->include_stack_ptr
= s1
->include_stack
;
8027 /* XXX: move that before to avoid having to initialize
8028 file->ifdef_stack_ptr ? */
8029 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
8030 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
8032 /* XXX: not ANSI compliant: bound checking says error */
8034 anon_sym
= SYM_FIRST_ANOM
;
8036 /* file info: full path + filename */
8037 section_sym
= 0; /* avoid warning */
8039 section_sym
= put_elf_sym(symtab_section
, 0, 0,
8040 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
8041 text_section
->sh_num
, NULL
);
8042 getcwd(buf
, sizeof(buf
));
8043 pstrcat(buf
, sizeof(buf
), "/");
8044 put_stabs_r(buf
, N_SO
, 0, 0,
8045 text_section
->data_offset
, text_section
, section_sym
);
8046 put_stabs_r(file
->filename
, N_SO
, 0, 0,
8047 text_section
->data_offset
, text_section
, section_sym
);
8049 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8050 symbols can be safely used */
8051 put_elf_sym(symtab_section
, 0, 0,
8052 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
8053 SHN_ABS
, file
->filename
);
8055 /* define some often used types */
8056 int_type
.t
= VT_INT
;
8058 char_pointer_type
.t
= VT_BYTE
;
8059 mk_pointer(&char_pointer_type
);
8061 func_old_type
.t
= VT_FUNC
;
8062 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
8065 /* define 'void *alloca(unsigned int)' builtin function */
8070 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
8071 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
8074 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
8078 define_start
= define_stack
;
8080 if (setjmp(s1
->error_jmp_buf
) == 0) {
8082 s1
->error_set_jmp_enabled
= 1;
8084 ch
= file
->buf_ptr
[0];
8085 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
8089 expect("declaration");
8091 /* end of translation unit info */
8093 put_stabs_r(NULL
, N_SO
, 0, 0,
8094 text_section
->data_offset
, text_section
, section_sym
);
8097 s1
->error_set_jmp_enabled
= 0;
8099 /* reset define stack, but leave -Dsymbols (may be incorrect if
8100 they are undefined) */
8101 free_defines(define_start
);
8103 sym_pop(&global_stack
, NULL
);
8105 return s1
->nb_errors
!= 0 ? -1 : 0;
8109 int tcc_compile_string(TCCState
*s
, const char *str
)
8111 BufferedFile bf1
, *bf
= &bf1
;
8115 /* init file structure */
8117 /* XXX: avoid copying */
8119 buf
= tcc_malloc(len
+ 1);
8124 bf
->buf_end
= buf
+ len
;
8125 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
8129 ret
= tcc_compile(s
);
8133 /* currently, no need to close */
8138 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8139 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
8141 BufferedFile bf1
, *bf
= &bf1
;
8143 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
8144 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
8148 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
8150 /* init file structure */
8152 bf
->buf_ptr
= bf
->buffer
;
8153 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
8154 *bf
->buf_end
= CH_EOB
;
8155 bf
->filename
[0] = '\0';
8159 s1
->include_stack_ptr
= s1
->include_stack
;
8161 /* parse with define parser */
8162 ch
= file
->buf_ptr
[0];
8168 /* undefine a preprocessor symbol */
8169 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
8173 ts
= tok_alloc(sym
, strlen(sym
));
8174 s
= define_find(ts
->tok
);
8175 /* undefine symbol by putting an invalid name */
8182 /* print the position in the source file of PC value 'pc' by reading
8183 the stabs debug information */
8184 static void rt_printline(unsigned long wanted_pc
)
8186 Stab_Sym
*sym
, *sym_end
;
8187 char func_name
[128], last_func_name
[128];
8188 unsigned long func_addr
, last_pc
, pc
;
8189 const char *incl_files
[INCLUDE_STACK_SIZE
];
8190 int incl_index
, len
, last_line_num
, i
;
8191 const char *str
, *p
;
8193 fprintf(stderr
, "0x%08lx:", wanted_pc
);
8195 func_name
[0] = '\0';
8198 last_func_name
[0] = '\0';
8199 last_pc
= 0xffffffff;
8201 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
8202 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
8203 while (sym
< sym_end
) {
8204 switch(sym
->n_type
) {
8205 /* function start or end */
8207 if (sym
->n_strx
== 0) {
8208 /* we test if between last line and end of function */
8209 pc
= sym
->n_value
+ func_addr
;
8210 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
8212 func_name
[0] = '\0';
8215 str
= stabstr_section
->data
+ sym
->n_strx
;
8216 p
= strchr(str
, ':');
8218 pstrcpy(func_name
, sizeof(func_name
), str
);
8221 if (len
> sizeof(func_name
) - 1)
8222 len
= sizeof(func_name
) - 1;
8223 memcpy(func_name
, str
, len
);
8224 func_name
[len
] = '\0';
8226 func_addr
= sym
->n_value
;
8229 /* line number info */
8231 pc
= sym
->n_value
+ func_addr
;
8232 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
8235 last_line_num
= sym
->n_desc
;
8237 strcpy(last_func_name
, func_name
);
8241 str
= stabstr_section
->data
+ sym
->n_strx
;
8243 if (incl_index
< INCLUDE_STACK_SIZE
) {
8244 incl_files
[incl_index
++] = str
;
8252 if (sym
->n_strx
== 0) {
8253 incl_index
= 0; /* end of translation unit */
8255 str
= stabstr_section
->data
+ sym
->n_strx
;
8256 /* do not add path */
8258 if (len
> 0 && str
[len
- 1] != '/')
8266 /* second pass: we try symtab symbols (no line number info) */
8269 Elf32_Sym
*sym
, *sym_end
;
8272 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
8273 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
8276 type
= ELF32_ST_TYPE(sym
->st_info
);
8277 if (type
== STT_FUNC
) {
8278 if (wanted_pc
>= sym
->st_value
&&
8279 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
8280 pstrcpy(last_func_name
, sizeof(last_func_name
),
8281 strtab_section
->data
+ sym
->st_name
);
8287 /* did not find any info: */
8288 fprintf(stderr
, " ???\n");
8291 if (last_func_name
[0] != '\0') {
8292 fprintf(stderr
, " %s()", last_func_name
);
8294 if (incl_index
> 0) {
8295 fprintf(stderr
, " (%s:%d",
8296 incl_files
[incl_index
- 1], last_line_num
);
8297 for(i
= incl_index
- 2; i
>= 0; i
--)
8298 fprintf(stderr
, ", included from %s", incl_files
[i
]);
8299 fprintf(stderr
, ")");
8301 fprintf(stderr
, "\n");
8313 /* return the PC at frame level 'level'. Return non zero if not found */
8314 static int rt_get_caller_pc(unsigned long *paddr
,
8315 struct ucontext
*uc
, int level
)
8321 *paddr
= uc
->uc_mcontext
.gregs
[EIP
];
8324 fp
= uc
->uc_mcontext
.gregs
[EBP
];
8325 for(i
=1;i
<level
;i
++) {
8326 /* XXX: check address validity with program info */
8327 if (fp
<= 0x1000 || fp
>= 0xc0000000)
8329 fp
= ((unsigned long *)fp
)[0];
8331 *paddr
= ((unsigned long *)fp
)[1];
8336 #error add arch specific rt_get_caller_pc()
8339 /* emit a run time error at position 'pc' */
8340 void rt_error(struct ucontext
*uc
, const char *fmt
, ...)
8347 fprintf(stderr
, "Runtime error: ");
8348 vfprintf(stderr
, fmt
, ap
);
8349 fprintf(stderr
, "\n");
8350 for(i
=0;i
<num_callers
;i
++) {
8351 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
8354 fprintf(stderr
, "at ");
8356 fprintf(stderr
, "by ");
8363 /* signal handler for fatal errors */
8364 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
8366 struct ucontext
*uc
= puc
;
8370 switch(siginf
->si_code
) {
8373 rt_error(uc
, "division by zero");
8376 rt_error(uc
, "floating point exception");
8382 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
8383 rt_error(uc
, *rt_bound_error_msg
);
8385 rt_error(uc
, "dereferencing invalid pointer");
8388 rt_error(uc
, "illegal instruction");
8391 rt_error(uc
, "abort() called");
8394 rt_error(uc
, "caught signal %d", signum
);
8401 /* do all relocations (needed before using tcc_get_symbol()) */
8402 int tcc_relocate(TCCState
*s1
)
8409 tcc_add_runtime(s1
);
8411 relocate_common_syms();
8413 /* compute relocation address : section are relocated in place. We
8414 also alloc the bss space */
8415 for(i
= 1; i
< s1
->nb_sections
; i
++) {
8416 s
= s1
->sections
[i
];
8417 if (s
->sh_flags
& SHF_ALLOC
) {
8418 if (s
->sh_type
== SHT_NOBITS
)
8419 s
->data
= tcc_mallocz(s
->data_offset
);
8420 s
->sh_addr
= (unsigned long)s
->data
;
8424 relocate_syms(s1
, 1);
8426 if (s1
->nb_errors
!= 0)
8429 /* relocate each section */
8430 for(i
= 1; i
< s1
->nb_sections
; i
++) {
8431 s
= s1
->sections
[i
];
8433 relocate_section(s1
, s
);
8438 /* launch the compiled program with the given arguments */
8439 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
8441 int (*prog_main
)(int, char **);
8443 if (tcc_relocate(s1
) < 0)
8446 prog_main
= tcc_get_symbol(s1
, "main");
8450 error("debug mode currently not available for Windows");
8452 struct sigaction sigact
;
8453 /* install TCC signal handlers to print debug info on fatal
8455 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
8456 sigact
.sa_sigaction
= sig_error
;
8457 sigemptyset(&sigact
.sa_mask
);
8458 sigaction(SIGFPE
, &sigact
, NULL
);
8459 sigaction(SIGILL
, &sigact
, NULL
);
8460 sigaction(SIGSEGV
, &sigact
, NULL
);
8461 sigaction(SIGBUS
, &sigact
, NULL
);
8462 sigaction(SIGABRT
, &sigact
, NULL
);
8466 #ifdef CONFIG_TCC_BCHECK
8467 if (do_bounds_check
) {
8468 void (*bound_init
)(void);
8470 /* set error function */
8471 rt_bound_error_msg
= (void *)tcc_get_symbol(s1
, "__bound_error_msg");
8473 /* XXX: use .init section so that it also work in binary ? */
8474 bound_init
= (void *)tcc_get_symbol(s1
, "__bound_init");
8478 return (*prog_main
)(argc
, argv
);
8481 TCCState
*tcc_new(void)
8486 s
= tcc_mallocz(sizeof(TCCState
));
8490 s
->output_type
= TCC_OUTPUT_MEMORY
;
8492 /* default include paths */
8493 tcc_add_sysinclude_path(s
, "/usr/local/include");
8494 tcc_add_sysinclude_path(s
, "/usr/include");
8495 tcc_add_sysinclude_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
8497 /* add all tokens */
8499 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
8501 tok_ident
= TOK_IDENT
;
8506 tok_alloc(p
, r
- p
- 1);
8510 /* we add dummy defines for some special macros to speed up tests
8511 and to have working defined() */
8512 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
8513 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
8514 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
8515 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
8517 /* standard defines */
8518 tcc_define_symbol(s
, "__STDC__", NULL
);
8519 #if defined(TCC_TARGET_I386)
8520 tcc_define_symbol(s
, "__i386__", NULL
);
8523 tcc_define_symbol(s
, "linux", NULL
);
8525 /* tiny C specific defines */
8526 tcc_define_symbol(s
, "__TINYC__", NULL
);
8528 /* tiny C & gcc defines */
8529 tcc_define_symbol(s
, "__SIZE_TYPE__", "unsigned int");
8530 tcc_define_symbol(s
, "__PTRDIFF_TYPE__", "int");
8531 tcc_define_symbol(s
, "__WCHAR_TYPE__", "int");
8533 /* default library paths */
8534 tcc_add_library_path(s
, "/usr/local/lib");
8535 tcc_add_library_path(s
, "/usr/lib");
8536 tcc_add_library_path(s
, "/lib");
8538 /* no section zero */
8539 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
8541 /* create standard sections */
8542 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
8543 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
8544 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
8546 /* symbols are always generated for linking stage */
8547 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
8549 ".hashtab", SHF_PRIVATE
);
8550 strtab_section
= symtab_section
->link
;
8552 /* private symbol table for dynamic symbols */
8553 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
8555 ".dynhashtab", SHF_PRIVATE
);
8559 void tcc_delete(TCCState
*s1
)
8563 /* free -D defines */
8567 n
= tok_ident
- TOK_IDENT
;
8568 for(i
= 0; i
< n
; i
++)
8569 tcc_free(table_ident
[i
]);
8570 tcc_free(table_ident
);
8572 /* free all sections */
8574 free_section(symtab_section
->hash
);
8576 free_section(s1
->dynsymtab_section
->hash
);
8577 free_section(s1
->dynsymtab_section
->link
);
8578 free_section(s1
->dynsymtab_section
);
8580 for(i
= 1; i
< s1
->nb_sections
; i
++)
8581 free_section(s1
->sections
[i
]);
8582 tcc_free(s1
->sections
);
8584 /* free loaded dlls array */
8585 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
8586 tcc_free(s1
->loaded_dlls
[i
]);
8587 tcc_free(s1
->loaded_dlls
);
8590 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
8591 tcc_free(s1
->library_paths
[i
]);
8592 tcc_free(s1
->library_paths
);
8594 /* cached includes */
8595 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
8596 tcc_free(s1
->cached_includes
[i
]);
8597 tcc_free(s1
->cached_includes
);
8599 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
8600 tcc_free(s1
->include_paths
[i
]);
8601 tcc_free(s1
->include_paths
);
8603 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
8604 tcc_free(s1
->sysinclude_paths
[i
]);
8605 tcc_free(s1
->sysinclude_paths
);
8610 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
8614 pathname1
= tcc_strdup(pathname
);
8615 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
8619 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
8623 pathname1
= tcc_strdup(pathname
);
8624 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
8628 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
8633 BufferedFile
*saved_file
;
8635 /* find source file type with extension */
8636 ext
= strrchr(filename
, '.');
8642 file
= tcc_open(s1
, filename
);
8644 if (flags
& AFF_PRINT_ERROR
) {
8645 error_noabort("file '%s' not found", filename
);
8651 if (!ext
|| !strcmp(ext
, "c")) {
8652 /* C file assumed */
8653 ret
= tcc_compile(s1
);
8656 /* assume executable format: auto guess file type */
8657 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
)) {
8658 error_noabort("could not read header");
8661 lseek(fd
, 0, SEEK_SET
);
8663 if (ehdr
.e_ident
[0] == ELFMAG0
&&
8664 ehdr
.e_ident
[1] == ELFMAG1
&&
8665 ehdr
.e_ident
[2] == ELFMAG2
&&
8666 ehdr
.e_ident
[3] == ELFMAG3
) {
8667 file
->line_num
= 0; /* do not display line number if error */
8668 if (ehdr
.e_type
== ET_REL
) {
8669 ret
= tcc_load_object_file(s1
, fd
, 0);
8670 } else if (ehdr
.e_type
== ET_DYN
) {
8671 ret
= tcc_load_dll(s1
, fd
, filename
,
8672 (flags
& AFF_REFERENCED_DLL
) != 0);
8674 error_noabort("unrecognized ELF file");
8677 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
8678 file
->line_num
= 0; /* do not display line number if error */
8679 ret
= tcc_load_archive(s1
, fd
);
8681 /* as GNU ld, consider it is an ld script if not recognized */
8682 ret
= tcc_load_ldscript(s1
);
8684 error_noabort("unrecognized file type");
8699 int tcc_add_file(TCCState
*s
, const char *filename
)
8701 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
8704 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
8708 pathname1
= tcc_strdup(pathname
);
8709 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
8713 /* find and load a dll. Return non zero if not found */
8714 /* XXX: add '-rpath' option support ? */
8715 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
8720 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
8721 snprintf(buf
, sizeof(buf
), "%s/%s",
8722 s
->library_paths
[i
], filename
);
8723 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
8729 /* the library name is the same as the argument of the '-l' option */
8730 int tcc_add_library(TCCState
*s
, const char *libraryname
)
8736 /* first we look for the dynamic library if not static linking */
8737 if (!s
->static_link
) {
8738 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8739 /* if we output to memory, then we simply we dlopen(). */
8740 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
8741 /* Since the libc is already loaded, we don't need to load it again */
8742 if (!strcmp(libraryname
, "c"))
8744 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
8748 if (tcc_add_dll(s
, buf
, 0) == 0)
8753 /* then we look for the static library */
8754 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
8755 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
8756 s
->library_paths
[i
], libraryname
);
8757 if (tcc_add_file_internal(s
, buf
, 0) == 0)
8763 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
8765 add_elf_sym(symtab_section
, val
, 0,
8766 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
8771 int tcc_set_output_type(TCCState
*s
, int output_type
)
8773 s
->output_type
= output_type
;
8775 /* if bound checking, then add corresponding sections */
8776 #ifdef CONFIG_TCC_BCHECK
8777 if (do_bounds_check
) {
8779 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
8780 /* create bounds sections */
8781 bounds_section
= new_section(s
, ".bounds",
8782 SHT_PROGBITS
, SHF_ALLOC
);
8783 lbounds_section
= new_section(s
, ".lbounds",
8784 SHT_PROGBITS
, SHF_ALLOC
);
8788 /* add debug sections */
8791 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
8792 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
8793 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
8794 put_elf_str(stabstr_section
, "");
8795 stab_section
->link
= stabstr_section
;
8796 /* put first entry */
8797 put_stabs("", 0, 0, 0, 0);
8800 /* add libc crt1/crti objects */
8801 if (output_type
== TCC_OUTPUT_EXE
||
8802 output_type
== TCC_OUTPUT_DLL
) {
8803 if (output_type
!= TCC_OUTPUT_DLL
)
8804 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
8805 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
8810 #if !defined(LIBTCC)
8812 static int64_t getclock_us(void)
8817 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
8820 gettimeofday(&tv
, NULL
);
8821 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
8827 printf("tcc version 0.9.13 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8828 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8829 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
8830 " [--] infile1 [infile2... --] [infile_args...]\n"
8832 "General options:\n"
8833 " -c compile only - generate an object file\n"
8834 " -o outfile set output filename\n"
8835 " -- allows multiples input files if no -o option given. Also\n"
8836 " separate input files from runtime arguments\n"
8837 " -Bdir set tcc internal library path\n"
8838 " -bench output compilation statistics\n"
8839 "Preprocessor options:\n"
8840 " -Idir add include path 'dir'\n"
8841 " -Dsym[=val] define 'sym' with value 'val'\n"
8842 " -Usym undefine 'sym'\n"
8844 " -Ldir add library path 'dir'\n"
8845 " -llib link with dynamic or static library 'lib'\n"
8846 " -shared generate a shared library\n"
8847 " -static static linking\n"
8848 " -r relocatable output\n"
8849 "Debugger options:\n"
8850 " -g generate runtime debug info\n"
8851 #ifdef CONFIG_TCC_BCHECK
8852 " -b compile with built-in memory and bounds checker (implies -g)\n"
8854 " -bt N show N callers in stack traces\n"
8858 int main(int argc
, char **argv
)
8861 int optind
, output_type
, multiple_files
, i
, reloc_output
;
8864 int nb_files
, nb_libraries
, nb_objfiles
, dminus
, ret
;
8865 char objfilename
[1024];
8866 int64_t start_time
= 0;
8869 output_type
= TCC_OUTPUT_MEMORY
;
8880 if (optind
>= argc
) {
8888 /* add a new file */
8889 dynarray_add((void ***)&files
, &nb_files
, r
);
8890 if (!multiple_files
) {
8892 /* argv[0] will be this file */
8895 } else if (r
[1] == '-') {
8896 /* '--' enables multiple files input and also ends several file input */
8897 if (dminus
&& multiple_files
) {
8898 optind
--; /* argv[0] will be '--' */
8903 } else if (r
[1] == 'h' || r
[1] == '?') {
8907 } else if (r
[1] == 'I') {
8908 if (tcc_add_include_path(s
, r
+ 2) < 0)
8909 error("too many include paths");
8910 } else if (r
[1] == 'D') {
8913 value
= strchr(sym
, '=');
8918 tcc_define_symbol(s
, sym
, value
);
8919 } else if (r
[1] == 'U') {
8920 tcc_undefine_symbol(s
, r
+ 2);
8921 } else if (r
[1] == 'L') {
8922 tcc_add_library_path(s
, r
+ 2);
8923 } else if (r
[1] == 'B') {
8924 /* set tcc utilities path (mainly for tcc development) */
8925 tcc_lib_path
= r
+ 2;
8926 } else if (r
[1] == 'l') {
8927 dynarray_add((void ***)&files
, &nb_files
, r
);
8929 } else if (!strcmp(r
+ 1, "bench")) {
8931 } else if (!strcmp(r
+ 1, "bt")) {
8932 num_callers
= atoi(argv
[optind
++]);
8934 #ifdef CONFIG_TCC_BCHECK
8936 do_bounds_check
= 1;
8942 } else if (r
[1] == 'c') {
8944 output_type
= TCC_OUTPUT_OBJ
;
8945 } else if (!strcmp(r
+ 1, "static")) {
8947 } else if (!strcmp(r
+ 1, "shared")) {
8948 output_type
= TCC_OUTPUT_DLL
;
8949 } else if (r
[1] == 'o') {
8953 outfile
= argv
[optind
++];
8954 } else if (r
[1] == 'r') {
8955 /* generate a .o merging several output files */
8957 output_type
= TCC_OUTPUT_OBJ
;
8958 } else if (r
[1] == 'W' || r
[1] == 'O' || r
[1] == 'm' || r
[1] == 'f') {
8959 /* ignore those options to be a drop-in replacement for gcc */
8961 error("invalid option -- '%s'", r
);
8965 nb_objfiles
= nb_files
- nb_libraries
;
8967 /* if outfile provided without other options, we output an
8969 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
8970 output_type
= TCC_OUTPUT_EXE
;
8972 /* check -c consistency : only single file handled. XXX: checks file type */
8973 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
8974 /* accepts only a single input file */
8975 if (nb_objfiles
!= 1)
8976 error("cannot specify multiple files with -c");
8977 if (nb_libraries
!= 0)
8978 error("cannot specify libraries with -c");
8981 /* compute default outfile name */
8982 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
8983 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
8985 /* add .o extension */
8986 pstrcpy(objfilename
, sizeof(objfilename
) - 1, files
[0]);
8987 ext
= strrchr(objfilename
, '.');
8989 goto default_outfile
;
8990 strcpy(ext
+ 1, "o");
8993 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
8995 outfile
= objfilename
;
8999 start_time
= getclock_us();
9002 tcc_set_output_type(s
, output_type
);
9004 /* compile or add each files or library */
9005 for(i
= 0;i
< nb_files
; i
++) {
9006 const char *filename
;
9008 filename
= files
[i
];
9009 if (filename
[0] == '-') {
9010 if (tcc_add_library(s
, filename
+ 2) < 0)
9011 error("cannot find %s", filename
);
9013 if (tcc_add_file(s
, filename
) < 0) {
9020 /* free all files */
9025 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
9026 if (total_time
< 0.001)
9028 if (total_bytes
< 1)
9030 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
9031 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
9032 total_time
, (int)(total_lines
/ total_time
),
9033 total_bytes
/ total_time
/ 1000000.0);
9036 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
9037 tcc_output_file(s
, outfile
);
9040 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
9043 /* XXX: cannot do it with bound checking because of the malloc hooks */
9044 if (!do_bounds_check
)
9049 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);