2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 #include <sys/timeb.h>
37 #include <sys/ucontext.h>
41 #ifndef CONFIG_TCC_STATIC
49 /* preprocessor debug */
51 /* include file debug */
59 /* target selection */
60 //#define TCC_TARGET_I386 /* i386 code generator */
62 /* default target is I386 */
63 #if !defined(TCC_TARGET_I386)
64 #define TCC_TARGET_I386
67 #if !defined(WIN32) && !defined(TCC_UCLIBC)
68 #define CONFIG_TCC_BCHECK /* enable bound checking code */
71 /* define it to include assembler support */
72 #define CONFIG_TCC_ASM
74 #ifndef CONFIG_TCC_PREFIX
75 #define CONFIG_TCC_PREFIX "/usr/local"
78 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
79 executables or dlls */
80 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
82 #define INCLUDE_STACK_SIZE 32
83 #define IFDEF_STACK_SIZE 64
84 #define VSTACK_SIZE 64
85 #define STRING_MAX_SIZE 1024
87 #define TOK_HASH_SIZE 2048 /* must be a power of two */
88 #define TOK_ALLOC_INCR 512 /* must be a power of two */
89 #define TOK_STR_ALLOC_INCR_BITS 6
90 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
91 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
93 /* token symbol management */
94 typedef struct TokenSym
{
95 struct TokenSym
*hash_next
;
96 struct Sym
*sym_define
; /* direct pointer to define */
97 struct Sym
*sym_label
; /* direct pointer to label */
98 struct Sym
*sym_struct
; /* direct pointer to structure */
99 struct Sym
*sym_identifier
; /* direct pointer to identifier */
100 int tok
; /* token number */
105 typedef struct CString
{
106 int size
; /* size in bytes */
107 void *data
; /* either 'char *' or 'int *' */
109 void *data_allocated
; /* if non NULL, data has been malloced */
112 /* type definition */
113 typedef struct CType
{
119 typedef union CValue
{
125 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
127 unsigned long long ull
;
128 struct CString
*cstr
;
134 typedef struct SValue
{
135 CType type
; /* type */
136 unsigned short r
; /* register + flags */
137 unsigned short r2
; /* second register, used for 'long long'
138 type. If not used, set to VT_CONST */
139 CValue c
; /* constant, if VT_CONST */
140 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
143 /* symbol management */
145 int v
; /* symbol token */
146 int r
; /* associated register */
147 int c
; /* associated number */
148 CType type
; /* associated type */
149 struct Sym
*next
; /* next related symbol */
150 struct Sym
*prev
; /* prev symbol in stack */
151 struct Sym
*prev_tok
; /* previous symbol for this token */
154 /* section definition */
155 /* XXX: use directly ELF structure for parameters ? */
156 /* special flag to indicate that the section should not be linked to
158 #define SHF_PRIVATE 0x80000000
160 typedef struct Section
{
161 unsigned long data_offset
; /* current data offset */
162 unsigned char *data
; /* section data */
163 unsigned long data_allocated
; /* used for realloc() handling */
164 int sh_name
; /* elf section name (only used during output) */
165 int sh_num
; /* elf section number */
166 int sh_type
; /* elf section type */
167 int sh_flags
; /* elf section flags */
168 int sh_info
; /* elf section info */
169 int sh_addralign
; /* elf section alignment */
170 int sh_entsize
; /* elf entry size */
171 unsigned long sh_size
; /* section size (only used during output) */
172 unsigned long sh_addr
; /* address at which the section is relocated */
173 unsigned long sh_offset
; /* address at which the section is relocated */
174 int nb_hashed_syms
; /* used to resize the hash table */
175 struct Section
*link
; /* link to another section */
176 struct Section
*reloc
; /* corresponding section for relocation, if any */
177 struct Section
*hash
; /* hash table for symbols */
178 struct Section
*next
;
179 char name
[64]; /* section name */
182 typedef struct DLLReference
{
187 /* GNUC attribute definition */
188 typedef struct AttributeDef
{
191 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
194 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
195 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
196 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
198 /* stored in 'Sym.c' field */
199 #define FUNC_NEW 1 /* ansi function prototype */
200 #define FUNC_OLD 2 /* old function prototype */
201 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
203 /* stored in 'Sym.r' field */
204 #define FUNC_CDECL 0 /* standard c call */
205 #define FUNC_STDCALL 1 /* pascal c call */
207 /* field 'Sym.t' for macros */
208 #define MACRO_OBJ 0 /* object like macro */
209 #define MACRO_FUNC 1 /* function like macro */
211 /* field 'Sym.r' for C labels */
212 #define LABEL_DEFINED 0 /* label is defined */
213 #define LABEL_FORWARD 1 /* label is forward defined */
214 #define LABEL_DECLARED 2 /* label is declared but never used */
216 /* type_decl() types */
217 #define TYPE_ABSTRACT 1 /* type without variable */
218 #define TYPE_DIRECT 2 /* type with variable */
220 #define IO_BUF_SIZE 8192
222 typedef struct BufferedFile
{
226 int line_num
; /* current line number - here to simplify code */
227 int ifndef_macro
; /* #ifndef macro / #endif search */
228 int ifndef_macro_saved
; /* saved ifndef_macro */
229 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
230 char inc_type
; /* type of include */
231 char inc_filename
[512]; /* filename specified by the user */
232 char filename
[1024]; /* current filename - here to simplify code */
233 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
236 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
237 #define CH_EOF (-1) /* end of file */
239 /* parsing state (used to save parser state to reparse part of the
240 source several times) */
241 typedef struct ParseState
{
248 /* used to record tokens */
249 typedef struct TokenString
{
256 /* include file cache, used to find files faster and also to eliminate
257 inclusion if the include file is protected by #ifndef ... #endif */
258 typedef struct CachedInclude
{
260 char type
; /* '"' or '>' to give include type */
261 char filename
[1]; /* path specified in #include */
265 static struct BufferedFile
*file
;
268 static CString tokcstr
; /* current parsed string, if any */
269 /* additional informations about token */
270 static int tok_flags
;
271 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
272 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
273 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
275 static int *macro_ptr
, *macro_ptr_allocated
;
276 static int *unget_saved_macro_ptr
;
277 static int unget_saved_buffer
[TOK_MAX_SIZE
+ 1];
278 static int unget_buffer_enabled
;
279 static int parse_flags
;
280 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
281 #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
282 #define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
283 token. line feed is also
286 static Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
287 static Section
*cur_text_section
; /* current section where function code is
289 /* bound check related sections */
290 static Section
*bounds_section
; /* contains global data bound description */
291 static Section
*lbounds_section
; /* contains local data bound description */
292 /* symbol sections */
293 static Section
*symtab_section
, *strtab_section
;
296 static Section
*stab_section
, *stabstr_section
;
298 /* loc : local variable index
299 ind : output code index
301 anon_sym: anonymous symbol index
303 static int rsym
, anon_sym
, ind
, loc
;
304 /* expression generation modifiers */
305 static int const_wanted
; /* true if constant wanted */
306 static int nocode_wanted
; /* true if no code generation wanted for an expression */
307 static int global_expr
; /* true if compound literals must be allocated
308 globally (used during initializers parsing */
309 static CType func_vt
; /* current function return type (used by return
312 static int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
313 static int tok_ident
;
314 static TokenSym
**table_ident
;
315 static TokenSym
*hash_ident
[TOK_HASH_SIZE
];
316 static char token_buf
[STRING_MAX_SIZE
+ 1];
317 static char *funcname
;
318 static Sym
*global_stack
, *local_stack
;
319 static Sym
*define_stack
;
320 static Sym
*global_label_stack
, *local_label_stack
;
322 static SValue vstack
[VSTACK_SIZE
], *vtop
;
323 /* some predefined types */
324 static CType char_pointer_type
, func_old_type
, int_type
;
325 /* true if isid(c) || isnum(c) */
326 static unsigned char isidnum_table
[256];
328 /* compile with debug symbol (and use them if error during execution) */
329 static int do_debug
= 0;
331 /* compile with built-in memory and bounds checker */
332 static int do_bounds_check
= 0;
334 /* display benchmark infos */
335 static int do_bench
= 0;
336 static int total_lines
;
337 static int total_bytes
;
339 /* use GNU C extensions */
340 static int gnu_ext
= 1;
342 /* use Tiny C extensions */
343 static int tcc_ext
= 1;
345 /* max number of callers shown if error */
346 static int num_callers
= 6;
347 static const char **rt_bound_error_msg
;
349 /* XXX: get rid of this ASAP */
350 static struct TCCState
*tcc_state
;
352 /* give the path of the tcc libraries */
353 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
358 BufferedFile
**include_stack_ptr
;
359 int *ifdef_stack_ptr
;
361 /* include file handling */
362 char **include_paths
;
363 int nb_include_paths
;
364 char **sysinclude_paths
;
365 int nb_sysinclude_paths
;
366 CachedInclude
**cached_includes
;
367 int nb_cached_includes
;
369 char **library_paths
;
370 int nb_library_paths
;
372 /* array of all loaded dlls (including those referenced by loaded
374 DLLReference
**loaded_dlls
;
379 int nb_sections
; /* number of sections, including first dummy section */
384 unsigned long *got_offsets
;
386 /* give the correspondance from symtab indexes to dynsym indexes */
387 int *symtab_to_dynsym
;
389 /* temporary dynamic symbol sections (for dll loading) */
390 Section
*dynsymtab_section
;
391 /* exported dynamic symbol section */
394 /* if true, no standard headers are added */
397 /* if true, static linking is performed */
402 void (*error_func
)(void *opaque
, const char *msg
);
403 int error_set_jmp_enabled
;
404 jmp_buf error_jmp_buf
;
407 /* tiny assembler state */
410 /* see include_stack_ptr */
411 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
413 /* see ifdef_stack_ptr */
414 int ifdef_stack
[IFDEF_STACK_SIZE
];
417 /* The current value can be: */
418 #define VT_VALMASK 0x00ff
419 #define VT_CONST 0x00f0 /* constant in vc
420 (must be first non register value) */
421 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
422 #define VT_LOCAL 0x00f2 /* offset on stack */
423 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
424 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
425 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
426 #define VT_LVAL 0x0100 /* var is an lvalue */
427 #define VT_SYM 0x0200 /* a symbol value is added */
428 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
429 char/short stored in integer registers) */
430 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
431 dereferencing value */
432 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
433 bounding function call point is in vc */
434 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
435 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
436 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
437 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
440 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
442 #define VT_INT 0 /* integer type */
443 #define VT_BYTE 1 /* signed byte type */
444 #define VT_SHORT 2 /* short type */
445 #define VT_VOID 3 /* void type */
446 #define VT_PTR 4 /* pointer */
447 #define VT_ENUM 5 /* enum definition */
448 #define VT_FUNC 6 /* function type */
449 #define VT_STRUCT 7 /* struct/union definition */
450 #define VT_FLOAT 8 /* IEEE float */
451 #define VT_DOUBLE 9 /* IEEE double */
452 #define VT_LDOUBLE 10 /* IEEE long double */
453 #define VT_BOOL 11 /* ISOC99 boolean type */
454 #define VT_LLONG 12 /* 64 bit integer */
455 #define VT_LONG 13 /* long integer (NEVER USED as type, only
457 #define VT_BTYPE 0x000f /* mask for basic type */
458 #define VT_UNSIGNED 0x0010 /* unsigned type */
459 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
460 #define VT_BITFIELD 0x0040 /* bitfield modifier */
463 #define VT_EXTERN 0x00000080 /* extern definition */
464 #define VT_STATIC 0x00000100 /* static variable */
465 #define VT_TYPEDEF 0x00000200 /* typedef definition */
466 #define VT_INLINE 0x00000400 /* inline definition */
468 /* type mask (except storage) */
469 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
470 #define VT_TYPE (~(VT_STORAGE))
474 /* warning: the following compare tokens depend on i386 asm code */
486 #define TOK_LAND 0xa0
490 #define TOK_MID 0xa3 /* inc/dec, to void constant */
492 #define TOK_UDIV 0xb0 /* unsigned division */
493 #define TOK_UMOD 0xb1 /* unsigned modulo */
494 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
495 #define TOK_CINT 0xb3 /* number in tokc */
496 #define TOK_CCHAR 0xb4 /* char constant in tokc */
497 #define TOK_STR 0xb5 /* pointer to string in tokc */
498 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
499 #define TOK_LCHAR 0xb7
500 #define TOK_LSTR 0xb8
501 #define TOK_CFLOAT 0xb9 /* float constant */
502 #define TOK_LINENUM 0xba /* line number info */
503 #define TOK_CDOUBLE 0xc0 /* double constant */
504 #define TOK_CLDOUBLE 0xc1 /* long double constant */
505 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
506 #define TOK_ADDC1 0xc3 /* add with carry generation */
507 #define TOK_ADDC2 0xc4 /* add with carry use */
508 #define TOK_SUBC1 0xc5 /* add with carry generation */
509 #define TOK_SUBC2 0xc6 /* add with carry use */
510 #define TOK_CUINT 0xc8 /* unsigned int constant */
511 #define TOK_CLLONG 0xc9 /* long long constant */
512 #define TOK_CULLONG 0xca /* unsigned long long constant */
513 #define TOK_ARROW 0xcb
514 #define TOK_DOTS 0xcc /* three dots */
515 #define TOK_SHR 0xcd /* unsigned shift right */
516 #define TOK_PPNUM 0xce /* preprocessor number */
518 #define TOK_SHL 0x01 /* shift left */
519 #define TOK_SAR 0x02 /* signed shift right */
521 /* assignement operators : normal operator or 0x80 */
522 #define TOK_A_MOD 0xa5
523 #define TOK_A_AND 0xa6
524 #define TOK_A_MUL 0xaa
525 #define TOK_A_ADD 0xab
526 #define TOK_A_SUB 0xad
527 #define TOK_A_DIV 0xaf
528 #define TOK_A_XOR 0xde
529 #define TOK_A_OR 0xfc
530 #define TOK_A_SHL 0x81
531 #define TOK_A_SAR 0x82
533 /* WARNING: the content of this string encodes token numbers */
534 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";
536 #define TOK_EOF (-1) /* end of file */
537 #define TOK_LINEFEED 10 /* line feed */
539 /* all identificators and strings have token above that */
540 #define TOK_IDENT 256
542 /* only used for i386 asm opcodes definitions */
543 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
546 DEF(TOK_ASM_ ## x ## b, #x "b") \
547 DEF(TOK_ASM_ ## x ## w, #x "w") \
548 DEF(TOK_ASM_ ## x ## l, #x "l") \
549 DEF(TOK_ASM_ ## x, #x)
552 DEF(TOK_ASM_ ## x ## w, #x "w") \
553 DEF(TOK_ASM_ ## x ## l, #x "l") \
554 DEF(TOK_ASM_ ## x, #x)
557 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
558 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
559 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
560 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
563 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
564 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
567 #define DEF_ASMTEST(x) \
599 #define TOK_ASM_int TOK_INT
602 TOK_LAST
= TOK_IDENT
- 1,
603 #define DEF(id, str) id,
608 static const char tcc_keywords
[] =
609 #define DEF(id, str) str "\0"
614 #define TOK_UIDENT TOK_DEFINE
617 #define snprintf _snprintf
618 #define vsnprintf _vsnprintf
621 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
622 /* currently incorrect */
623 long double strtold(const char *nptr
, char **endptr
)
625 return (long double)strtod(nptr
, endptr
);
627 float strtof(const char *nptr
, char **endptr
)
629 return (float)strtod(nptr
, endptr
);
632 /* XXX: need to define this to use them in non ISOC99 context */
633 extern float strtof (const char *__nptr
, char **__endptr
);
634 extern long double strtold (const char *__nptr
, char **__endptr
);
637 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
638 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
640 static void next(void);
641 static void next_nomacro(void);
642 static void parse_expr_type(CType
*type
);
643 static void expr_type(CType
*type
);
644 static void unary_type(CType
*type
);
645 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
646 int case_reg
, int is_expr
);
647 static int expr_const(void);
648 static void expr_eq(void);
649 static void gexpr(void);
650 static void decl(int l
);
651 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
652 int first
, int size_only
);
653 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
654 int has_init
, int v
, int scope
);
656 void gv2(int rc1
, int rc2
);
657 void move_reg(int r
, int s
);
658 void save_regs(int n
);
659 void save_reg(int r
);
665 static void macro_subst(TokenString
*tok_str
,
666 Sym
**nested_list
, const int *macro_str
);
667 int save_reg_forced(int r
);
669 void force_charshort_cast(int t
);
670 static void gen_cast(CType
*type
);
672 static Sym
*sym_find(int v
);
673 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
676 static int type_size(CType
*type
, int *a
);
677 static inline CType
*pointed_type(CType
*type
);
678 static int pointed_size(CType
*type
);
679 static int lvalue_type(int t
);
680 static int is_compatible_types(CType
*type1
, CType
*type2
);
681 static int parse_btype(CType
*type
, AttributeDef
*ad
);
682 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
684 void error(const char *fmt
, ...);
686 void vset(CType
*type
, int r
, int v
);
687 void type_to_str(char *buf
, int buf_size
,
688 CType
*type
, const char *varstr
);
689 char *get_tok_str(int v
, CValue
*cv
);
690 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
691 unsigned long offset
, unsigned long size
);
692 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
694 /* section generation */
695 static void section_realloc(Section
*sec
, unsigned long new_size
);
696 static void *section_ptr_add(Section
*sec
, unsigned long size
);
697 static void put_extern_sym(Sym
*sym
, Section
*section
,
698 unsigned long value
, unsigned long size
);
699 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
700 static int put_elf_str(Section
*s
, const char *sym
);
701 static int put_elf_sym(Section
*s
,
702 unsigned long value
, unsigned long size
,
703 int info
, int other
, int shndx
, const char *name
);
704 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
705 int info
, int sh_num
, const char *name
);
706 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
707 int type
, int symbol
);
708 static void put_stabs(const char *str
, int type
, int other
, int desc
,
709 unsigned long value
);
710 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
711 unsigned long value
, Section
*sec
, int sym_index
);
712 static void put_stabn(int type
, int other
, int desc
, int value
);
713 static void put_stabd(int type
, int other
, int desc
);
714 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
716 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
717 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
718 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
722 #ifdef CONFIG_TCC_ASM
724 typedef struct ExprValue
{
729 #define MAX_ASM_OPERANDS 30
731 typedef struct ASMOperand
{
732 int id
; /* GCC 3 optionnal identifier (0 if number only supported */
734 char asm_str
[16]; /* computed asm string for operand */
735 SValue
*vt
; /* C value of the expression */
736 int ref_index
; /* if >= 0, gives reference to a output constraint */
737 int priority
; /* priority, used to assign registers */
738 int reg
; /* if >= 0, register number used for this operand */
741 static void asm_expr(TCCState
*s1
, ExprValue
*pe
);
742 static int asm_int_expr(TCCState
*s1
);
743 static int find_constraint(ASMOperand
*operands
, int nb_operands
,
744 const char *name
, const char **pp
);
746 static int tcc_assemble(TCCState
*s1
, int do_preprocess
);
750 static void asm_instr(void);
752 /* true if float/double/long double type */
753 static inline int is_float(int t
)
757 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
760 #ifdef TCC_TARGET_I386
761 #include "i386-gen.c"
764 #ifdef CONFIG_TCC_STATIC
766 #define RTLD_LAZY 0x001
767 #define RTLD_NOW 0x002
768 #define RTLD_GLOBAL 0x100
769 #define RTLD_DEFAULT NULL
771 /* dummy function for profiling */
772 void *dlopen(const char *filename
, int flag
)
777 const char *dlerror(void)
782 typedef struct TCCSyms
{
787 #define TCCSYM(a) { #a, &a, },
789 /* add the symbol you want here if no dynamic linking is done */
790 static TCCSyms tcc_syms
[] = {
798 void *dlsym(void *handle
, const char *symbol
)
802 while (p
->str
!= NULL
) {
803 if (!strcmp(p
->str
, symbol
))
812 /********************************************************/
814 /* we use our own 'finite' function to avoid potential problems with
815 non standard math libs */
816 /* XXX: endianness dependent */
817 int ieee_finite(double d
)
820 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
823 /* copy a string and truncate it. */
824 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
831 q_end
= buf
+ buf_size
- 1;
843 /* strcat and truncate. */
844 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
849 pstrcpy(buf
+ len
, buf_size
- len
, s
);
853 /* memory management */
859 static inline void tcc_free(void *ptr
)
862 mem_cur_size
-= malloc_usable_size(ptr
);
867 static void *tcc_malloc(unsigned long size
)
872 error("memory full");
874 mem_cur_size
+= malloc_usable_size(ptr
);
875 if (mem_cur_size
> mem_max_size
)
876 mem_max_size
= mem_cur_size
;
881 static void *tcc_mallocz(unsigned long size
)
884 ptr
= tcc_malloc(size
);
885 memset(ptr
, 0, size
);
889 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
893 mem_cur_size
-= malloc_usable_size(ptr
);
895 ptr1
= realloc(ptr
, size
);
897 /* NOTE: count not correct if alloc error, but not critical */
898 mem_cur_size
+= malloc_usable_size(ptr1
);
899 if (mem_cur_size
> mem_max_size
)
900 mem_max_size
= mem_cur_size
;
905 static char *tcc_strdup(const char *str
)
908 ptr
= tcc_malloc(strlen(str
) + 1);
913 #define free(p) use_tcc_free(p)
914 #define malloc(s) use_tcc_malloc(s)
915 #define realloc(p, s) use_tcc_realloc(p, s)
917 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
924 /* every power of two we double array size */
925 if ((nb
& (nb
- 1)) == 0) {
930 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
932 error("memory full");
939 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
943 sec
= tcc_mallocz(sizeof(Section
));
944 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
945 sec
->sh_type
= sh_type
;
946 sec
->sh_flags
= sh_flags
;
953 sec
->sh_addralign
= 4;
956 sec
->sh_addralign
= 1;
959 sec
->sh_addralign
= 32; /* default conservative alignment */
963 /* only add section if not private */
964 if (!(sh_flags
& SHF_PRIVATE
)) {
965 sec
->sh_num
= s1
->nb_sections
;
966 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
971 static void free_section(Section
*s
)
977 /* realloc section and set its content to zero */
978 static void section_realloc(Section
*sec
, unsigned long new_size
)
983 size
= sec
->data_allocated
;
986 while (size
< new_size
)
988 data
= tcc_realloc(sec
->data
, size
);
990 error("memory full");
991 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
993 sec
->data_allocated
= size
;
996 /* reserve at least 'size' bytes in section 'sec' from
998 static void *section_ptr_add(Section
*sec
, unsigned long size
)
1000 unsigned long offset
, offset1
;
1002 offset
= sec
->data_offset
;
1003 offset1
= offset
+ size
;
1004 if (offset1
> sec
->data_allocated
)
1005 section_realloc(sec
, offset1
);
1006 sec
->data_offset
= offset1
;
1007 return sec
->data
+ offset
;
1010 /* return a reference to a section, and create it if it does not
1012 Section
*find_section(TCCState
*s1
, const char *name
)
1016 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1017 sec
= s1
->sections
[i
];
1018 if (!strcmp(name
, sec
->name
))
1021 /* sections are created as PROGBITS */
1022 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
1025 /* update sym->c so that it points to an external symbol in section
1026 'section' with value 'value' */
1027 static void put_extern_sym(Sym
*sym
, Section
*section
,
1028 unsigned long value
, unsigned long size
)
1030 int sym_type
, sym_bind
, sh_num
, info
;
1035 sh_num
= section
->sh_num
;
1039 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
)
1040 sym_type
= STT_FUNC
;
1042 sym_type
= STT_OBJECT
;
1043 if (sym
->type
.t
& VT_STATIC
)
1044 sym_bind
= STB_LOCAL
;
1046 sym_bind
= STB_GLOBAL
;
1048 name
= get_tok_str(sym
->v
, NULL
);
1049 #ifdef CONFIG_TCC_BCHECK
1050 if (do_bounds_check
) {
1053 /* XXX: avoid doing that for statics ? */
1054 /* if bound checking is activated, we change some function
1055 names by adding the "__bound" prefix */
1058 /* XXX: we rely only on malloc hooks */
1070 strcpy(buf
, "__bound_");
1077 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
1078 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
1080 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
1081 esym
->st_value
= value
;
1082 esym
->st_size
= size
;
1083 esym
->st_shndx
= sh_num
;
1087 /* add a new relocation entry to symbol 'sym' in section 's' */
1088 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
1091 put_extern_sym(sym
, NULL
, 0, 0);
1092 /* now we can add ELF relocation info */
1093 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
1096 static inline int isid(int c
)
1098 return (c
>= 'a' && c
<= 'z') ||
1099 (c
>= 'A' && c
<= 'Z') ||
1103 static inline int isnum(int c
)
1105 return c
>= '0' && c
<= '9';
1108 static inline int isoct(int c
)
1110 return c
>= '0' && c
<= '7';
1113 static inline int toup(int c
)
1115 if (c
>= 'a' && c
<= 'z')
1116 return c
- 'a' + 'A';
1121 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1125 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1128 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1132 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1136 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1143 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1144 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1145 (*f
)->filename
, (*f
)->line_num
);
1146 if (file
->line_num
> 0) {
1147 strcat_printf(buf
, sizeof(buf
),
1148 "%s:%d: ", file
->filename
, file
->line_num
);
1150 strcat_printf(buf
, sizeof(buf
),
1151 "%s: ", file
->filename
);
1154 strcat_printf(buf
, sizeof(buf
),
1158 strcat_printf(buf
, sizeof(buf
), "warning: ");
1159 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1161 if (!s1
->error_func
) {
1162 /* default case: stderr */
1163 fprintf(stderr
, "%s\n", buf
);
1165 s1
->error_func(s1
->error_opaque
, buf
);
1172 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1173 void (*error_func
)(void *opaque
, const char *msg
))
1175 s
->error_opaque
= error_opaque
;
1176 s
->error_func
= error_func
;
1180 /* error without aborting current compilation */
1181 void error_noabort(const char *fmt
, ...)
1183 TCCState
*s1
= tcc_state
;
1187 error1(s1
, 0, fmt
, ap
);
1191 void error(const char *fmt
, ...)
1193 TCCState
*s1
= tcc_state
;
1197 error1(s1
, 0, fmt
, ap
);
1199 /* better than nothing: in some cases, we accept to handle errors */
1200 if (s1
->error_set_jmp_enabled
) {
1201 longjmp(s1
->error_jmp_buf
, 1);
1203 /* XXX: eliminate this someday */
1208 void expect(const char *msg
)
1210 error("%s expected", msg
);
1213 void warning(const char *fmt
, ...)
1215 TCCState
*s1
= tcc_state
;
1219 error1(s1
, 1, fmt
, ap
);
1226 error("'%c' expected", c
);
1230 static void test_lvalue(void)
1232 if (!(vtop
->r
& VT_LVAL
))
1236 /* allocate a new token */
1237 static TokenSym
*tok_alloc_new(TokenSym
**pts
, const char *str
, int len
)
1239 TokenSym
*ts
, **ptable
;
1242 if (tok_ident
>= SYM_FIRST_ANOM
)
1243 error("memory full");
1245 /* expand token table if needed */
1246 i
= tok_ident
- TOK_IDENT
;
1247 if ((i
% TOK_ALLOC_INCR
) == 0) {
1248 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1250 error("memory full");
1251 table_ident
= ptable
;
1254 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1255 table_ident
[i
] = ts
;
1256 ts
->tok
= tok_ident
++;
1257 ts
->sym_define
= NULL
;
1258 ts
->sym_label
= NULL
;
1259 ts
->sym_struct
= NULL
;
1260 ts
->sym_identifier
= NULL
;
1262 ts
->hash_next
= NULL
;
1263 memcpy(ts
->str
, str
, len
);
1264 ts
->str
[len
] = '\0';
1269 #define TOK_HASH_INIT 1
1270 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1272 /* find a token and add it if not found */
1273 static TokenSym
*tok_alloc(const char *str
, int len
)
1275 TokenSym
*ts
, **pts
;
1281 h
= TOK_HASH_FUNC(h
, ((unsigned char *)str
)[i
]);
1282 h
&= (TOK_HASH_SIZE
- 1);
1284 pts
= &hash_ident
[h
];
1289 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1291 pts
= &(ts
->hash_next
);
1293 return tok_alloc_new(pts
, str
, len
);
1296 /* CString handling */
1298 static void cstr_realloc(CString
*cstr
, int new_size
)
1303 size
= cstr
->size_allocated
;
1305 size
= 8; /* no need to allocate a too small first string */
1306 while (size
< new_size
)
1308 data
= tcc_realloc(cstr
->data_allocated
, size
);
1310 error("memory full");
1311 cstr
->data_allocated
= data
;
1312 cstr
->size_allocated
= size
;
1317 static void cstr_ccat(CString
*cstr
, int ch
)
1320 size
= cstr
->size
+ 1;
1321 if (size
> cstr
->size_allocated
)
1322 cstr_realloc(cstr
, size
);
1323 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1327 static void cstr_cat(CString
*cstr
, const char *str
)
1339 /* add a wide char */
1340 static void cstr_wccat(CString
*cstr
, int ch
)
1343 size
= cstr
->size
+ sizeof(int);
1344 if (size
> cstr
->size_allocated
)
1345 cstr_realloc(cstr
, size
);
1346 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1350 static void cstr_new(CString
*cstr
)
1352 memset(cstr
, 0, sizeof(CString
));
1355 /* free string and reset it to NULL */
1356 static void cstr_free(CString
*cstr
)
1358 tcc_free(cstr
->data_allocated
);
1362 #define cstr_reset(cstr) cstr_free(cstr)
1364 static CString
*cstr_dup(CString
*cstr1
)
1369 cstr
= tcc_malloc(sizeof(CString
));
1372 cstr
->size_allocated
= size
;
1373 cstr
->data_allocated
= tcc_malloc(size
);
1374 cstr
->data
= cstr
->data_allocated
;
1375 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1379 /* XXX: unicode ? */
1380 static void add_char(CString
*cstr
, int c
)
1382 if (c
== '\'' || c
== '\"' || c
== '\\') {
1383 /* XXX: could be more precise if char or string */
1384 cstr_ccat(cstr
, '\\');
1386 if (c
>= 32 && c
<= 126) {
1389 cstr_ccat(cstr
, '\\');
1391 cstr_ccat(cstr
, 'n');
1393 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1394 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1395 cstr_ccat(cstr
, '0' + (c
& 7));
1400 /* XXX: buffer overflow */
1401 /* XXX: float tokens */
1402 char *get_tok_str(int v
, CValue
*cv
)
1404 static char buf
[STRING_MAX_SIZE
+ 1];
1405 static CString cstr_buf
;
1411 /* NOTE: to go faster, we give a fixed buffer for small strings */
1412 cstr_reset(&cstr_buf
);
1413 cstr_buf
.data
= buf
;
1414 cstr_buf
.size_allocated
= sizeof(buf
);
1420 /* XXX: not quite exact, but only useful for testing */
1421 sprintf(p
, "%u", cv
->ui
);
1425 /* XXX: not quite exact, but only useful for testing */
1426 sprintf(p
, "%Lu", cv
->ull
);
1430 cstr_ccat(&cstr_buf
, '\'');
1431 add_char(&cstr_buf
, cv
->i
);
1432 cstr_ccat(&cstr_buf
, '\'');
1433 cstr_ccat(&cstr_buf
, '\0');
1437 len
= cstr
->size
- 1;
1439 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1440 cstr_ccat(&cstr_buf
, '\0');
1445 cstr_ccat(&cstr_buf
, '\"');
1447 len
= cstr
->size
- 1;
1449 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1451 len
= (cstr
->size
/ sizeof(int)) - 1;
1453 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1455 cstr_ccat(&cstr_buf
, '\"');
1456 cstr_ccat(&cstr_buf
, '\0');
1465 return strcpy(p
, "<<=");
1467 return strcpy(p
, ">>=");
1469 if (v
< TOK_IDENT
) {
1470 /* search in two bytes table */
1484 } else if (v
< tok_ident
) {
1485 return table_ident
[v
- TOK_IDENT
]->str
;
1486 } else if (v
>= SYM_FIRST_ANOM
) {
1487 /* special name for anonymous symbol */
1488 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1490 /* should never happen */
1495 return cstr_buf
.data
;
1498 /* push, without hashing */
1499 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1502 s
= tcc_malloc(sizeof(Sym
));
1513 /* find a symbol and return its associated structure. 's' is the top
1514 of the symbol stack */
1515 static Sym
*sym_find2(Sym
*s
, int v
)
1525 /* structure lookup */
1526 static inline Sym
*struct_find(int v
)
1529 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1531 return table_ident
[v
]->sym_struct
;
1534 /* find an identifier */
1535 static inline Sym
*sym_find(int v
)
1538 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1540 return table_ident
[v
]->sym_identifier
;
1543 /* push a given symbol on the symbol stack */
1544 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1553 s
= sym_push2(ps
, v
, type
->t
, c
);
1554 s
->type
.ref
= type
->ref
;
1556 /* don't record fields or anonymous symbols */
1558 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1559 /* record symbol in token array */
1560 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1562 ps
= &ts
->sym_struct
;
1564 ps
= &ts
->sym_identifier
;
1571 /* push a global identifier */
1572 static Sym
*global_identifier_push(int v
, int t
, int c
)
1575 s
= sym_push2(&global_stack
, v
, t
, c
);
1576 /* don't record anonymous symbol */
1577 if (v
< SYM_FIRST_ANOM
) {
1578 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1579 /* modify the top most local identifier, so that
1580 sym_identifier will point to 's' when popped */
1582 ps
= &(*ps
)->prev_tok
;
1589 /* pop symbols until top reaches 'b' */
1590 static void sym_pop(Sym
**ptop
, Sym
*b
)
1600 /* remove symbol in token array */
1602 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1603 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1605 ps
= &ts
->sym_struct
;
1607 ps
= &ts
->sym_identifier
;
1618 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1623 fd
= open(filename
, O_RDONLY
);
1626 bf
= tcc_malloc(sizeof(BufferedFile
));
1632 bf
->buf_ptr
= bf
->buffer
;
1633 bf
->buf_end
= bf
->buffer
;
1634 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1635 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1637 bf
->ifndef_macro
= 0;
1638 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1639 // printf("opening '%s'\n", filename);
1643 void tcc_close(BufferedFile
*bf
)
1645 total_lines
+= bf
->line_num
;
1650 /* fill input buffer and peek next char */
1651 static int tcc_peekc_slow(BufferedFile
*bf
)
1654 /* only tries to read if really end of buffer */
1655 if (bf
->buf_ptr
>= bf
->buf_end
) {
1657 #if defined(PARSE_DEBUG)
1662 len
= read(bf
->fd
, bf
->buffer
, len
);
1669 bf
->buf_ptr
= bf
->buffer
;
1670 bf
->buf_end
= bf
->buffer
+ len
;
1671 *bf
->buf_end
= CH_EOB
;
1673 if (bf
->buf_ptr
< bf
->buf_end
) {
1674 return bf
->buf_ptr
[0];
1676 bf
->buf_ptr
= bf
->buf_end
;
1681 /* return the current character, handling end of block if necessary
1683 static int handle_eob(void)
1685 return tcc_peekc_slow(file
);
1688 /* read next char from current input file and handle end of input buffer */
1689 static inline void inp(void)
1691 ch
= *(++(file
->buf_ptr
));
1692 /* end of buffer/file handling */
1697 /* handle '\[\r]\n' */
1698 static void handle_stray(void)
1700 while (ch
== '\\') {
1705 } else if (ch
== '\r') {
1713 error("stray '\\' in program");
1718 /* skip the stray and handle the \\n case. Output an error if
1719 incorrect char after the stray */
1720 static int handle_stray1(uint8_t *p
)
1724 if (p
>= file
->buf_end
) {
1741 /* handle just the EOB case, but not stray */
1742 #define PEEKC_EOB(c, p)\
1753 /* handle the complicated stray case */
1754 #define PEEKC(c, p)\
1759 c = handle_stray1(p);\
1764 /* input with '\[\r]\n' handling. Note that this function cannot
1765 handle other characters after '\', so you cannot call it inside
1766 strings or comments */
1767 static void minp(void)
1775 static void parse_line_comment(void)
1777 /* single line C++ comments */
1778 /* XXX: accept '\\\n' ? */
1780 while (ch
!= '\n' && ch
!= CH_EOF
)
1784 static void parse_comment(void)
1793 /* fast skip loop */
1796 if (c
== '\n' || c
== '*' || c
== '\\')
1800 if (c
== '\n' || c
== '*' || c
== '\\')
1804 /* now we can handle all the cases */
1808 } else if (c
== '*') {
1814 } else if (c
== '/') {
1815 goto end_of_comment
;
1816 } else if (c
== '\\') {
1820 /* skip '\\n', but if '\' followed but another
1821 char, behave asif a stray was parsed */
1822 ch
= file
->buf_ptr
[0];
1823 while (ch
== '\\') {
1828 } else if (ch
== '\r') {
1846 /* stray, eob or eof */
1851 error("unexpected end of file in comment");
1852 } else if (c
== '\\') {
1865 /* space exlcuding newline */
1866 static inline int is_space(int ch
)
1868 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1871 static inline void skip_spaces(void)
1873 while (is_space(ch
))
1877 /* parse a string without interpreting escapes */
1878 static uint8_t *parse_pp_string(uint8_t *p
,
1879 int sep
, CString
*str
)
1887 } else if (c
== '\\') {
1892 unterminated_string
:
1893 /* XXX: indicate line number of start of string */
1894 error("missing terminating %c character", sep
);
1895 } else if (c
== '\\') {
1896 /* escape : just skip \[\r]\n */
1901 } else if (c
== '\r') {
1904 expect("'\n' after '\r'");
1907 } else if (c
== CH_EOF
) {
1908 goto unterminated_string
;
1911 cstr_ccat(str
, '\\');
1917 } else if (c
== '\n') {
1920 } else if (c
== '\r') {
1923 cstr_ccat(str
, '\r');
1939 /* skip block of text until #else, #elif or #endif. skip also pairs of
1941 void preprocess_skip(void)
1943 int a
, start_of_line
, c
;
1970 } else if (c
== '\\') {
1971 /* XXX: incorrect: should not give an error */
1972 ch
= file
->buf_ptr
[0];
1980 p
= parse_pp_string(p
, c
, NULL
);
1989 } else if (ch
== '/') {
1990 parse_line_comment();
1997 if (start_of_line
) {
2002 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
2004 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
2006 else if (tok
== TOK_ENDIF
)
2020 /* ParseState handling */
2022 /* XXX: currently, no include file info is stored. Thus, we cannot display
2023 accurate messages if the function or data definition spans multiple
2026 /* save current parse state in 's' */
2027 void save_parse_state(ParseState
*s
)
2029 s
->line_num
= file
->line_num
;
2030 s
->macro_ptr
= macro_ptr
;
2035 /* restore parse state from 's' */
2036 void restore_parse_state(ParseState
*s
)
2038 file
->line_num
= s
->line_num
;
2039 macro_ptr
= s
->macro_ptr
;
2044 /* return the number of additional 'ints' necessary to store the
2046 static inline int tok_ext_size(int t
)
2065 return LDOUBLE_SIZE
/ 4;
2071 /* token string handling */
2073 static inline void tok_str_new(TokenString
*s
)
2077 s
->allocated_len
= 0;
2078 s
->last_line_num
= -1;
2081 static void tok_str_free(int *str
)
2090 /* NOTE: we test zero separately so that GCC can generate a
2091 table for the following switch */
2106 /* XXX: use a macro to be portable on 64 bit ? */
2107 cstr
= (CString
*)p
[1];
2118 p
+= 1 + (LDOUBLE_SIZE
/ 4);
2128 static int *tok_str_realloc(TokenString
*s
)
2132 len
= s
->allocated_len
+ TOK_STR_ALLOC_INCR
;
2133 str
= tcc_realloc(s
->str
, len
* sizeof(int));
2135 error("memory full");
2136 s
->allocated_len
= len
;
2141 static void tok_str_add(TokenString
*s
, int t
)
2147 if (len
>= s
->allocated_len
)
2148 str
= tok_str_realloc(s
);
2153 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
2160 /* allocate space for worst case */
2161 if (len
+ TOK_MAX_SIZE
> s
->allocated_len
)
2162 str
= tok_str_realloc(s
);
2171 str
[len
++] = cv
->tab
[0];
2176 str
[len
++] = (int)cstr_dup(cv
->cstr
);
2181 str
[len
++] = cv
->tab
[0];
2182 str
[len
++] = cv
->tab
[1];
2185 #if LDOUBLE_SIZE == 12
2186 str
[len
++] = cv
->tab
[0];
2187 str
[len
++] = cv
->tab
[1];
2188 str
[len
++] = cv
->tab
[2];
2190 #error add long double size support
2199 /* add the current parse token in token string 's' */
2200 static void tok_str_add_tok(TokenString
*s
)
2204 /* save line number info */
2205 if (file
->line_num
!= s
->last_line_num
) {
2206 s
->last_line_num
= file
->line_num
;
2207 cval
.i
= s
->last_line_num
;
2208 tok_str_add2(s
, TOK_LINENUM
, &cval
);
2210 tok_str_add2(s
, tok
, &tokc
);
2213 #if LDOUBLE_SIZE == 12
2214 #define LDOUBLE_GET(p, cv) \
2219 #error add long double size support
2223 /* get a token from an integer array and increment pointer
2224 accordingly. we code it as a macro to avoid pointer aliasing. */
2225 #define TOK_GET(t, p, cv) \
2247 case TOK_CLDOUBLE: \
2248 LDOUBLE_GET(p, cv); \
2249 p += LDOUBLE_SIZE / 4; \
2256 /* defines handling */
2257 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
2261 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
2262 s
->next
= first_arg
;
2263 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
2266 /* undefined a define symbol. Its name is just set to zero */
2267 static void define_undef(Sym
*s
)
2271 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2272 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2276 static inline Sym
*define_find(int v
)
2279 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2281 return table_ident
[v
]->sym_define
;
2284 /* free define stack until top reaches 'b' */
2285 static void free_defines(Sym
*b
)
2293 /* do not free args or predefined defines */
2295 tok_str_free((int *)top
->c
);
2297 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2298 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2306 static Sym
*label_find(int v
)
2309 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2311 return table_ident
[v
]->sym_label
;
2314 static Sym
*label_push(Sym
**ptop
, int v
, int flags
)
2317 s
= sym_push2(ptop
, v
, 0, 0);
2319 ps
= &table_ident
[v
- TOK_IDENT
]->sym_label
;
2320 if (ptop
== &global_label_stack
) {
2321 /* modify the top most local identifier, so that
2322 sym_identifier will point to 's' when popped */
2324 ps
= &(*ps
)->prev_tok
;
2331 /* pop labels until element last is reached. Look if any labels are
2332 undefined. Define symbols if '&&label' was used. */
2333 static void label_pop(Sym
**ptop
, Sym
*slast
)
2336 for(s
= *ptop
; s
!= slast
; s
= s1
) {
2338 if (s
->r
== LABEL_DECLARED
) {
2339 warning("label '%s' declared but not used", get_tok_str(s
->v
, NULL
));
2340 } else if (s
->r
== LABEL_FORWARD
) {
2341 error("label '%s' used but not defined",
2342 get_tok_str(s
->v
, NULL
));
2345 /* define corresponding symbol. A size of
2347 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
2351 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= s
->prev_tok
;
2357 /* eval an expression for #if/#elif */
2358 static int expr_preprocess(void)
2364 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2365 next(); /* do macro subst */
2366 if (tok
== TOK_DEFINED
) {
2371 c
= define_find(tok
) != 0;
2376 } else if (tok
>= TOK_IDENT
) {
2377 /* if undefined macro */
2381 tok_str_add_tok(&str
);
2383 tok_str_add(&str
, -1); /* simulate end of file */
2384 tok_str_add(&str
, 0);
2385 /* now evaluate C constant expression */
2386 macro_ptr
= str
.str
;
2390 tok_str_free(str
.str
);
2394 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2395 static void tok_print(int *str
)
2401 TOK_GET(t
, str
, cval
);
2404 printf(" %s", get_tok_str(t
, &cval
));
2410 /* parse after #define */
2411 static void parse_define(void)
2413 Sym
*s
, *first
, **ps
;
2414 int v
, t
, varg
, is_vaargs
, c
;
2419 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2420 /* XXX: should check if same macro (ANSI) */
2423 /* '(' must be just after macro definition for MACRO_FUNC */
2424 c
= file
->buf_ptr
[0];
2426 c
= handle_stray1(file
->buf_ptr
);
2431 while (tok
!= ')') {
2435 if (varg
== TOK_DOTS
) {
2436 varg
= TOK___VA_ARGS__
;
2438 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2442 if (varg
< TOK_IDENT
)
2443 error("badly punctuated parameter list");
2444 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2455 /* EOF testing necessary for '-D' handling */
2456 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2457 tok_str_add2(&str
, tok
, &tokc
);
2460 tok_str_add(&str
, 0);
2462 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2465 define_push(v
, t
, str
.str
, first
);
2468 /* XXX: use a token or a hash table to accelerate matching ? */
2469 static CachedInclude
*search_cached_include(TCCState
*s1
,
2470 int type
, const char *filename
)
2475 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
2476 e
= s1
->cached_includes
[i
];
2477 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2483 static inline void add_cached_include(TCCState
*s1
, int type
,
2484 const char *filename
, int ifndef_macro
)
2488 if (search_cached_include(s1
, type
, filename
))
2491 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2493 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2497 strcpy(e
->filename
, filename
);
2498 e
->ifndef_macro
= ifndef_macro
;
2499 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2502 /* is_bof is true if first non space token at beginning of file */
2503 static void preprocess(int is_bof
)
2505 TCCState
*s1
= tcc_state
;
2506 int size
, i
, c
, n
, saved_parse_flags
;
2507 char buf
[1024], *q
, *p
;
2513 saved_parse_flags
= parse_flags
;
2514 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
|
2515 PARSE_FLAG_LINEFEED
;
2525 s
= define_find(tok
);
2526 /* undefine symbol by putting an invalid name */
2531 ch
= file
->buf_ptr
[0];
2532 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2537 } else if (ch
== '\"') {
2540 /* XXX: better stray handling */
2543 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2544 if ((q
- buf
) < sizeof(buf
) - 1)
2551 /* eat all spaces and comments after include */
2552 /* XXX: slightly incorrect */
2553 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2557 /* computed #include : either we have only strings or
2558 we have anything enclosed in '<>' */
2561 if (tok
== TOK_STR
) {
2562 while (tok
!= TOK_LINEFEED
) {
2563 if (tok
!= TOK_STR
) {
2565 error("'#include' expects \"FILENAME\" or <FILENAME>");
2567 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2573 while (tok
!= TOK_LINEFEED
) {
2574 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2578 /* check syntax and remove '<>' */
2579 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2580 goto include_syntax
;
2581 memmove(buf
, buf
+ 1, len
- 2);
2582 buf
[len
- 2] = '\0';
2587 e
= search_cached_include(s1
, c
, buf
);
2588 if (e
&& define_find(e
->ifndef_macro
)) {
2589 /* no need to parse the include because the 'ifndef macro'
2592 printf("%s: skipping %s\n", file
->filename
, buf
);
2596 /* first search in current dir if "header.h" */
2598 p
= strrchr(file
->filename
, '/');
2600 size
= p
+ 1 - file
->filename
;
2601 if (size
> sizeof(buf1
) - 1)
2602 size
= sizeof(buf1
) - 1;
2603 memcpy(buf1
, file
->filename
, size
);
2605 pstrcat(buf1
, sizeof(buf1
), buf
);
2606 f
= tcc_open(s1
, buf1
);
2610 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2611 error("#include recursion too deep");
2612 /* now search in all the include paths */
2613 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2614 for(i
= 0; i
< n
; i
++) {
2616 if (i
< s1
->nb_include_paths
)
2617 path
= s1
->include_paths
[i
];
2619 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2620 pstrcpy(buf1
, sizeof(buf1
), path
);
2621 pstrcat(buf1
, sizeof(buf1
), "/");
2622 pstrcat(buf1
, sizeof(buf1
), buf
);
2623 f
= tcc_open(s1
, buf1
);
2627 error("include file '%s' not found", buf
);
2631 printf("%s: including %s\n", file
->filename
, buf1
);
2634 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2635 /* push current file in stack */
2636 /* XXX: fix current line init */
2637 *s1
->include_stack_ptr
++ = file
;
2639 /* add include file debug info */
2641 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2643 tok_flags
|= TOK_FLAG_BOF
| TOK_FLAG_BOL
;
2644 ch
= file
->buf_ptr
[0];
2652 c
= expr_preprocess();
2658 if (tok
< TOK_IDENT
)
2659 error("invalid argument for '#if%sdef'", c
? "n" : "");
2663 printf("#ifndef %s\n", get_tok_str(tok
, NULL
));
2665 file
->ifndef_macro
= tok
;
2668 c
= (define_find(tok
) != 0) ^ c
;
2670 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2671 error("memory full");
2672 *s1
->ifdef_stack_ptr
++ = c
;
2675 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2676 error("#else without matching #if");
2677 if (s1
->ifdef_stack_ptr
[-1] & 2)
2678 error("#else after #else");
2679 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2682 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2683 error("#elif without matching #if");
2684 c
= s1
->ifdef_stack_ptr
[-1];
2686 error("#elif after #else");
2687 /* last #if/#elif expression was true: we skip */
2690 c
= expr_preprocess();
2691 s1
->ifdef_stack_ptr
[-1] = c
;
2701 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2702 error("#endif without matching #if");
2703 s1
->ifdef_stack_ptr
--;
2704 /* '#ifndef macro' was at the start of file. Now we check if
2705 an '#endif' is exactly at the end of file */
2706 if (file
->ifndef_macro
&&
2707 s1
->ifdef_stack_ptr
== file
->ifdef_stack_ptr
) {
2708 file
->ifndef_macro_saved
= file
->ifndef_macro
;
2709 /* need to set to zero to avoid false matches if another
2710 #ifndef at middle of file */
2711 file
->ifndef_macro
= 0;
2712 while (tok
!= TOK_LINEFEED
)
2714 tok_flags
|= TOK_FLAG_ENDIF
;
2720 if (tok
!= TOK_CINT
)
2722 file
->line_num
= tokc
.i
- 1; /* the line number will be incremented after */
2724 if (tok
!= TOK_LINEFEED
) {
2727 pstrcpy(file
->filename
, sizeof(file
->filename
),
2728 (char *)tokc
.cstr
->data
);
2734 ch
= file
->buf_ptr
[0];
2737 while (ch
!= '\n' && ch
!= CH_EOF
) {
2738 if ((q
- buf
) < sizeof(buf
) - 1)
2744 error("#error %s", buf
);
2746 warning("#warning %s", buf
);
2752 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
2753 /* '!' is ignored to allow C scripts. numbers are ignored
2754 to emulate cpp behaviour */
2756 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
2760 /* ignore other preprocess commands or #! for C scripts */
2761 while (tok
!= TOK_LINEFEED
)
2764 parse_flags
= saved_parse_flags
;
2767 /* evaluate escape codes in a string. */
2768 static void parse_escape_string(CString
*outstr
, const uint8_t *buf
, int is_long
)
2783 case '0': case '1': case '2': case '3':
2784 case '4': case '5': case '6': case '7':
2785 /* at most three octal digits */
2790 n
= n
* 8 + c
- '0';
2794 n
= n
* 8 + c
- '0';
2799 goto add_char_nonext
;
2805 if (c
>= 'a' && c
<= 'f')
2807 else if (c
>= 'A' && c
<= 'F')
2817 goto add_char_nonext
;
2841 goto invalid_escape
;
2851 error("invalid escaped char");
2857 cstr_ccat(outstr
, c
);
2859 cstr_wccat(outstr
, c
);
2861 /* add a trailing '\0' */
2863 cstr_ccat(outstr
, '\0');
2865 cstr_wccat(outstr
, '\0');
2868 /* we use 64 bit numbers */
2871 /* bn = (bn << shift) | or_val */
2872 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2876 for(i
=0;i
<BN_SIZE
;i
++) {
2878 bn
[i
] = (v
<< shift
) | or_val
;
2879 or_val
= v
>> (32 - shift
);
2883 void bn_zero(unsigned int *bn
)
2886 for(i
=0;i
<BN_SIZE
;i
++) {
2891 /* parse number in null terminated string 'p' and return it in the
2893 void parse_number(const char *p
)
2895 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
2897 unsigned int bn
[BN_SIZE
];
2908 goto float_frac_parse
;
2909 } else if (t
== '0') {
2910 if (ch
== 'x' || ch
== 'X') {
2914 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2920 /* parse all digits. cannot check octal numbers at this stage
2921 because of floating point constants */
2923 if (ch
>= 'a' && ch
<= 'f')
2925 else if (ch
>= 'A' && ch
<= 'F')
2933 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2935 error("number too long");
2941 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2942 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2944 /* NOTE: strtox should support that for hexa numbers, but
2945 non ISOC99 libcs do not support it, so we prefer to do
2947 /* hexadecimal or binary floats */
2948 /* XXX: handle overflows */
2960 } else if (t
>= 'a') {
2962 } else if (t
>= 'A') {
2967 bn_lshift(bn
, shift
, t
);
2974 if (t
>= 'a' && t
<= 'f') {
2976 } else if (t
>= 'A' && t
<= 'F') {
2978 } else if (t
>= '0' && t
<= '9') {
2984 error("invalid digit");
2985 bn_lshift(bn
, shift
, t
);
2990 if (ch
!= 'p' && ch
!= 'P')
2997 } else if (ch
== '-') {
3001 if (ch
< '0' || ch
> '9')
3002 expect("exponent digits");
3003 while (ch
>= '0' && ch
<= '9') {
3004 exp_val
= exp_val
* 10 + ch
- '0';
3007 exp_val
= exp_val
* s
;
3009 /* now we can generate the number */
3010 /* XXX: should patch directly float number */
3011 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
3012 d
= ldexp(d
, exp_val
- frac_bits
);
3017 /* float : should handle overflow */
3019 } else if (t
== 'L') {
3022 /* XXX: not large enough */
3023 tokc
.ld
= (long double)d
;
3029 /* decimal floats */
3031 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3036 while (ch
>= '0' && ch
<= '9') {
3037 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3043 if (ch
== 'e' || ch
== 'E') {
3044 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3048 if (ch
== '-' || ch
== '+') {
3049 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3054 if (ch
< '0' || ch
> '9')
3055 expect("exponent digits");
3056 while (ch
>= '0' && ch
<= '9') {
3057 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3069 tokc
.f
= strtof(token_buf
, NULL
);
3070 } else if (t
== 'L') {
3073 tokc
.ld
= strtold(token_buf
, NULL
);
3076 tokc
.d
= strtod(token_buf
, NULL
);
3080 unsigned long long n
, n1
;
3083 /* integer number */
3086 if (b
== 10 && *q
== '0') {
3093 /* no need for checks except for base 10 / 8 errors */
3096 } else if (t
>= 'a') {
3098 } else if (t
>= 'A') {
3103 error("invalid digit");
3107 /* detect overflow */
3108 /* XXX: this test is not reliable */
3110 error("integer constant overflow");
3113 /* XXX: not exactly ANSI compliant */
3114 if ((n
& 0xffffffff00000000LL
) != 0) {
3119 } else if (n
> 0x7fffffff) {
3130 error("three 'l's in integer constant");
3133 if (tok
== TOK_CINT
)
3135 else if (tok
== TOK_CUINT
)
3139 } else if (t
== 'U') {
3141 error("two 'u's in integer constant");
3143 if (tok
== TOK_CINT
)
3145 else if (tok
== TOK_CLLONG
)
3152 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
3160 #define PARSE2(c1, tok1, c2, tok2) \
3171 /* return next token without macro substitution */
3172 static inline void next_nomacro1(void)
3192 /* first look if it is in fact an end of buffer */
3193 if (p
>= file
->buf_end
) {
3197 if (p
>= file
->buf_end
)
3210 TCCState
*s1
= tcc_state
;
3211 if (parse_flags
& PARSE_FLAG_LINEFEED
) {
3213 } else if (s1
->include_stack_ptr
== s1
->include_stack
||
3214 !(parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3215 /* no include left : end of file. */
3218 /* pop include file */
3220 /* test if previous '#endif' was after a #ifdef at
3222 if (tok_flags
& TOK_FLAG_ENDIF
) {
3224 printf("#endif %s\n", get_tok_str(file
->ifndef_macro_saved
, NULL
));
3226 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
3227 file
->ifndef_macro_saved
);
3230 /* add end of include file debug info */
3232 put_stabd(N_EINCL
, 0, 0);
3234 /* pop include stack */
3236 s1
->include_stack_ptr
--;
3237 file
= *s1
->include_stack_ptr
;
3245 if (parse_flags
& PARSE_FLAG_LINEFEED
) {
3249 tok_flags
|= TOK_FLAG_BOL
;
3258 if ((tok_flags
& TOK_FLAG_BOL
) &&
3259 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3261 preprocess(tok_flags
& TOK_FLAG_BOF
);
3267 tok
= TOK_TWOSHARPS
;
3274 case 'a': case 'b': case 'c': case 'd':
3275 case 'e': case 'f': case 'g': case 'h':
3276 case 'i': case 'j': case 'k': case 'l':
3277 case 'm': case 'n': case 'o': case 'p':
3278 case 'q': case 'r': case 's': case 't':
3279 case 'u': case 'v': case 'w': case 'x':
3281 case 'A': case 'B': case 'C': case 'D':
3282 case 'E': case 'F': case 'G': case 'H':
3283 case 'I': case 'J': case 'K':
3284 case 'M': case 'N': case 'O': case 'P':
3285 case 'Q': case 'R': case 'S': case 'T':
3286 case 'U': case 'V': case 'W': case 'X':
3292 h
= TOK_HASH_FUNC(h
, c
);
3296 if (!isidnum_table
[c
])
3298 h
= TOK_HASH_FUNC(h
, c
);
3305 /* fast case : no stray found, so we have the full token
3306 and we have already hashed it */
3308 h
&= (TOK_HASH_SIZE
- 1);
3309 pts
= &hash_ident
[h
];
3314 if (ts
->len
== len
&& !memcmp(ts
->str
, p1
, len
))
3316 pts
= &(ts
->hash_next
);
3318 ts
= tok_alloc_new(pts
, p1
, len
);
3322 cstr_reset(&tokcstr
);
3325 cstr_ccat(&tokcstr
, *p1
);
3331 while (isidnum_table
[c
]) {
3332 cstr_ccat(&tokcstr
, c
);
3335 ts
= tok_alloc(tokcstr
.data
, tokcstr
.size
);
3341 if (t
!= '\\' && t
!= '\'' && t
!= '\"') {
3343 goto parse_ident_fast
;
3346 if (c
== '\'' || c
== '\"') {
3350 cstr_reset(&tokcstr
);
3351 cstr_ccat(&tokcstr
, 'L');
3352 goto parse_ident_slow
;
3356 case '0': case '1': case '2': case '3':
3357 case '4': case '5': case '6': case '7':
3360 cstr_reset(&tokcstr
);
3361 /* after the first digit, accept digits, alpha, '.' or sign if
3362 prefixed by 'eEpP' */
3366 cstr_ccat(&tokcstr
, c
);
3368 if (!(isnum(c
) || isid(c
) || c
== '.' ||
3369 ((c
== '+' || c
== '-') &&
3370 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
3373 /* We add a trailing '\0' to ease parsing */
3374 cstr_ccat(&tokcstr
, '\0');
3375 tokc
.cstr
= &tokcstr
;
3379 /* special dot handling because it can also start a number */
3382 cstr_reset(&tokcstr
);
3383 cstr_ccat(&tokcstr
, '.');
3385 } else if (c
== '.') {
3405 /* parse the string */
3407 p
= parse_pp_string(p
, sep
, &str
);
3408 cstr_ccat(&str
, '\0');
3410 /* eval the escape (should be done as TOK_PPNUM) */
3411 cstr_reset(&tokcstr
);
3412 parse_escape_string(&tokcstr
, str
.data
, is_long
);
3417 /* XXX: make it portable */
3421 char_size
= sizeof(int);
3422 if (tokcstr
.size
<= char_size
)
3423 error("empty character constant");
3424 if (tokcstr
.size
> 2 * char_size
)
3425 warning("multi-character character constant");
3427 tokc
.i
= *(int8_t *)tokcstr
.data
;
3430 tokc
.i
= *(int *)tokcstr
.data
;
3434 tokc
.cstr
= &tokcstr
;
3448 } else if (c
== '<') {
3466 } else if (c
== '>') {
3484 } else if (c
== '=') {
3497 } else if (c
== '=') {
3510 } else if (c
== '=') {
3523 } else if (c
== '=') {
3526 } else if (c
== '>') {
3534 PARSE2('!', '!', '=', TOK_NE
)
3535 PARSE2('=', '=', '=', TOK_EQ
)
3536 PARSE2('*', '*', '=', TOK_A_MUL
)
3537 PARSE2('%', '%', '=', TOK_A_MOD
)
3538 PARSE2('^', '^', '=', TOK_A_XOR
)
3540 /* comments or operator */
3548 } else if (c
== '/') {
3550 parse_line_comment();
3553 } else if (c
== '=') {
3573 case '$': /* only used in assembler */
3578 error("unrecognized character \\x%02x", c
);
3583 #if defined(PARSE_DEBUG)
3584 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3588 /* return next token without macro substitution. Can read input from
3590 static void next_nomacro(void)
3596 TOK_GET(tok
, macro_ptr
, tokc
);
3597 if (tok
== TOK_LINENUM
) {
3598 file
->line_num
= tokc
.i
;
3607 /* substitute args in macro_str and return allocated string */
3608 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
3610 int *st
, last_tok
, t
, notfirst
;
3619 TOK_GET(t
, macro_str
, cval
);
3624 TOK_GET(t
, macro_str
, cval
);
3627 s
= sym_find2(args
, t
);
3634 cstr_ccat(&cstr
, ' ');
3635 TOK_GET(t
, st
, cval
);
3636 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
3639 cstr_ccat(&cstr
, '\0');
3641 printf("stringize: %s\n", (char *)cstr
.data
);
3645 tok_str_add2(&str
, TOK_STR
, &cval
);
3648 tok_str_add2(&str
, t
, &cval
);
3650 } else if (t
>= TOK_IDENT
) {
3651 s
= sym_find2(args
, t
);
3654 /* if '##' is present before or after, no arg substitution */
3655 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
3656 /* special case for var arg macros : ## eats the
3657 ',' if empty VA_ARGS variable. */
3658 /* XXX: test of the ',' is not 100%
3659 reliable. should fix it to avoid security
3661 if (gnu_ext
&& s
->type
.t
&&
3662 last_tok
== TOK_TWOSHARPS
&&
3663 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
3665 /* suppress ',' '##' */
3668 /* suppress '##' and add variable */
3676 TOK_GET(t1
, st
, cval
);
3679 tok_str_add2(&str
, t1
, &cval
);
3683 macro_subst(&str
, nested_list
, st
);
3686 tok_str_add(&str
, t
);
3689 tok_str_add2(&str
, t
, &cval
);
3693 tok_str_add(&str
, 0);
3697 /* do macro substitution of current token with macro 's' and add
3698 result to (tok_str,tok_len). 'nested_list' is the list of all
3699 macros we got inside to avoid recursing. Return non zero if no
3700 substitution needs to be done */
3701 static int macro_subst_tok(TokenString
*tok_str
,
3702 Sym
**nested_list
, Sym
*s
)
3704 Sym
*args
, *sa
, *sa1
;
3705 int mstr_allocated
, parlevel
, *mstr
, t
;
3711 /* if symbol is a macro, prepare substitution */
3713 /* special macros */
3714 if (tok
== TOK___LINE__
) {
3715 cval
.i
= file
->line_num
;
3716 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
3717 } else if (tok
== TOK___FILE__
) {
3718 cstrval
= file
->filename
;
3720 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3721 } else if (tok
== TOK___DATE__
) {
3722 cstrval
= "Jan 1 2002";
3724 } else if (tok
== TOK___TIME__
) {
3725 cstrval
= "00:00:00";
3728 cstr_cat(&cstr
, cstrval
);
3729 cstr_ccat(&cstr
, '\0');
3731 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3736 if (s
->type
.t
== MACRO_FUNC
) {
3737 /* NOTE: we do not use next_nomacro to avoid eating the
3738 next token. XXX: find better solution */
3742 /* XXX: incorrect with comments */
3743 ch
= file
->buf_ptr
[0];
3744 while (is_space(ch
) || ch
== '\n')
3748 if (t
!= '(') /* no macro subst */
3751 /* argument macro */
3756 /* NOTE: empty args are allowed, except if no args */
3758 /* handle '()' case */
3759 if (!args
&& tok
== ')')
3762 error("macro '%s' used with too many args",
3763 get_tok_str(s
->v
, 0));
3766 /* NOTE: non zero sa->t indicates VA_ARGS */
3767 while ((parlevel
> 0 ||
3769 (tok
!= ',' || sa
->type
.t
))) &&
3773 else if (tok
== ')')
3775 tok_str_add2(&str
, tok
, &tokc
);
3778 tok_str_add(&str
, 0);
3779 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
3782 /* special case for gcc var args: add an empty
3783 var arg argument if it is omitted */
3784 if (sa
&& sa
->type
.t
&& gnu_ext
)
3794 error("macro '%s' used with too few args",
3795 get_tok_str(s
->v
, 0));
3798 /* now subst each arg */
3799 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3804 tok_str_free((int *)sa
->c
);
3810 sym_push2(nested_list
, s
->v
, 0, 0);
3811 macro_subst(tok_str
, nested_list
, mstr
);
3812 /* pop nested defined symbol */
3814 *nested_list
= sa1
->prev
;
3822 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
3823 return the resulting string (which must be freed). */
3824 static inline int *macro_twosharps(const int *macro_str
)
3827 const int *macro_ptr1
, *start_macro_ptr
, *ptr
, *saved_macro_ptr
;
3829 const char *p1
, *p2
;
3831 TokenString macro_str1
;
3834 start_macro_ptr
= macro_str
;
3835 /* we search the first '##' */
3837 macro_ptr1
= macro_str
;
3838 TOK_GET(t
, macro_str
, cval
);
3839 /* nothing more to do if end of string */
3842 if (*macro_str
== TOK_TWOSHARPS
)
3846 /* we saw '##', so we need more processing to handle it */
3848 tok_str_new(¯o_str1
);
3852 /* add all tokens seen so far */
3853 for(ptr
= start_macro_ptr
; ptr
< macro_ptr1
;) {
3854 TOK_GET(t
, ptr
, cval
);
3855 tok_str_add2(¯o_str1
, t
, &cval
);
3857 saved_macro_ptr
= macro_ptr
;
3858 /* XXX: get rid of the use of macro_ptr here */
3859 macro_ptr
= (int *)macro_str
;
3861 while (*macro_ptr
== TOK_TWOSHARPS
) {
3863 macro_ptr1
= macro_ptr
;
3866 TOK_GET(t
, macro_ptr
, cval
);
3867 /* We concatenate the two tokens if we have an
3868 identifier or a preprocessing number */
3870 p1
= get_tok_str(tok
, &tokc
);
3871 cstr_cat(&cstr
, p1
);
3872 p2
= get_tok_str(t
, &cval
);
3873 cstr_cat(&cstr
, p2
);
3874 cstr_ccat(&cstr
, '\0');
3876 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
3877 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
3878 if (tok
== TOK_PPNUM
) {
3879 /* if number, then create a number token */
3880 /* NOTE: no need to allocate because
3881 tok_str_add2() does it */
3884 /* if identifier, we must do a test to
3885 validate we have a correct identifier */
3886 if (t
== TOK_PPNUM
) {
3896 if (!isnum(c
) && !isid(c
))
3900 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
3901 tok
= ts
->tok
; /* modify current token */
3904 const char *str
= cstr
.data
;
3905 const unsigned char *q
;
3907 /* we look for a valid token */
3908 /* XXX: do more extensive checks */
3909 if (!strcmp(str
, ">>=")) {
3911 } else if (!strcmp(str
, "<<=")) {
3913 } else if (strlen(str
) == 2) {
3914 /* search in two bytes table */
3919 if (q
[0] == str
[0] && q
[1] == str
[1])
3926 /* NOTE: because get_tok_str use a static buffer,
3929 p1
= get_tok_str(tok
, &tokc
);
3930 cstr_cat(&cstr
, p1
);
3931 cstr_ccat(&cstr
, '\0');
3932 p2
= get_tok_str(t
, &cval
);
3933 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
3934 /* cannot merge tokens: just add them separately */
3935 tok_str_add2(¯o_str1
, tok
, &tokc
);
3936 /* XXX: free associated memory ? */
3943 tok_str_add2(¯o_str1
, tok
, &tokc
);
3948 macro_ptr
= (int *)saved_macro_ptr
;
3950 tok_str_add(¯o_str1
, 0);
3951 return macro_str1
.str
;
3955 /* do macro substitution of macro_str and add result to
3956 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3957 inside to avoid recursing. */
3958 static void macro_subst(TokenString
*tok_str
,
3959 Sym
**nested_list
, const int *macro_str
)
3962 int *saved_macro_ptr
, *macro_str1
;
3967 /* first scan for '##' operator handling */
3969 macro_str1
= macro_twosharps(ptr
);
3973 TOK_GET(t
, ptr
, cval
);
3978 /* if nested substitution, do nothing */
3979 if (sym_find2(*nested_list
, t
))
3981 saved_macro_ptr
= macro_ptr
;
3982 macro_ptr
= (int *)ptr
;
3984 ret
= macro_subst_tok(tok_str
, nested_list
, s
);
3985 ptr
= (int *)macro_ptr
;
3986 macro_ptr
= saved_macro_ptr
;
3991 tok_str_add2(tok_str
, t
, &cval
);
3995 tok_str_free(macro_str1
);
3998 /* return next token with macro substitution */
3999 static void next(void)
4001 Sym
*nested_list
, *s
;
4007 /* if not reading from macro substituted string, then try
4008 to substitute macros */
4009 if (tok
>= TOK_IDENT
&&
4010 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
4011 s
= define_find(tok
);
4013 /* we have a macro: we try to substitute */
4016 if (macro_subst_tok(&str
, &nested_list
, s
) == 0) {
4017 /* substitution done, NOTE: maybe empty */
4018 tok_str_add(&str
, 0);
4019 macro_ptr
= str
.str
;
4020 macro_ptr_allocated
= str
.str
;
4027 /* end of macro or end of unget buffer */
4028 if (unget_buffer_enabled
) {
4029 macro_ptr
= unget_saved_macro_ptr
;
4030 unget_buffer_enabled
= 0;
4032 /* end of macro string: free it */
4033 tok_str_free(macro_ptr_allocated
);
4040 /* convert preprocessor tokens into C tokens */
4041 if (tok
== TOK_PPNUM
&&
4042 (parse_flags
& PARSE_FLAG_TOK_NUM
)) {
4043 parse_number((char *)tokc
.cstr
->data
);
4047 /* push back current token and set current token to 'last_tok'. Only
4048 identifier case handled for labels. */
4049 static inline void unget_tok(int last_tok
)
4053 unget_saved_macro_ptr
= macro_ptr
;
4054 unget_buffer_enabled
= 1;
4055 q
= unget_saved_buffer
;
4058 n
= tok_ext_size(tok
) - 1;
4061 *q
= 0; /* end of token string */
4066 void swap(int *p
, int *q
)
4074 void vsetc(CType
*type
, int r
, CValue
*vc
)
4078 if (vtop
>= vstack
+ VSTACK_SIZE
)
4079 error("memory full");
4080 /* cannot let cpu flags if other instruction are generated. Also
4081 avoid leaving VT_JMP anywhere except on the top of the stack
4082 because it would complicate the code generator. */
4083 if (vtop
>= vstack
) {
4084 v
= vtop
->r
& VT_VALMASK
;
4085 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
4091 vtop
->r2
= VT_CONST
;
4095 /* push integer constant */
4100 vsetc(&int_type
, VT_CONST
, &cval
);
4103 /* Return a static symbol pointing to a section */
4104 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
4105 unsigned long offset
, unsigned long size
)
4111 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
4112 sym
->type
.ref
= type
->ref
;
4113 sym
->r
= VT_CONST
| VT_SYM
;
4114 put_extern_sym(sym
, sec
, offset
, size
);
4118 /* push a reference to a section offset by adding a dummy symbol */
4119 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
4124 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4125 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
4128 /* define a new external reference to a symbol 'v' of type 'u' */
4129 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
4135 /* push forward reference */
4136 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
4137 s
->type
.ref
= type
->ref
;
4138 s
->r
= r
| VT_CONST
| VT_SYM
;
4143 /* define a new external reference to a symbol 'v' of type 'u' */
4144 static Sym
*external_sym(int v
, CType
*type
, int r
)
4150 /* push forward reference */
4151 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
4152 s
->type
.t
|= VT_EXTERN
;
4154 if (!is_compatible_types(&s
->type
, type
))
4155 error("incompatible types for redefinition of '%s'",
4156 get_tok_str(v
, NULL
));
4161 /* push a reference to global symbol v */
4162 static void vpush_global_sym(CType
*type
, int v
)
4167 sym
= external_global_sym(v
, type
, 0);
4169 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4173 void vset(CType
*type
, int r
, int v
)
4178 vsetc(type
, r
, &cval
);
4181 void vseti(int r
, int v
)
4197 void vpushv(SValue
*v
)
4199 if (vtop
>= vstack
+ VSTACK_SIZE
)
4200 error("memory full");
4210 /* save r to the memory stack, and mark it as being free */
4211 void save_reg(int r
)
4213 int l
, saved
, size
, align
;
4217 /* modify all stack values */
4220 for(p
=vstack
;p
<=vtop
;p
++) {
4221 if ((p
->r
& VT_VALMASK
) == r
||
4222 (p
->r2
& VT_VALMASK
) == r
) {
4223 /* must save value on stack if not already done */
4225 /* NOTE: must reload 'r' because r might be equal to r2 */
4226 r
= p
->r
& VT_VALMASK
;
4227 /* store register in the stack */
4229 if ((p
->r
& VT_LVAL
) ||
4230 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
4232 size
= type_size(type
, &align
);
4233 loc
= (loc
- size
) & -align
;
4234 sv
.type
.t
= type
->t
;
4235 sv
.r
= VT_LOCAL
| VT_LVAL
;
4238 #ifdef TCC_TARGET_I386
4239 /* x86 specific: need to pop fp register ST0 if saved */
4240 if (r
== TREG_ST0
) {
4241 o(0xd9dd); /* fstp %st(1) */
4244 /* special long long case */
4245 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
4252 /* mark that stack entry as being saved on the stack */
4253 if (p
->r
& VT_LVAL
) {
4254 /* also clear the bounded flag because the
4255 relocation address of the function was stored in
4257 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
4259 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
4267 /* find a free register of class 'rc'. If none, save one register */
4273 /* find a free register */
4274 for(r
=0;r
<NB_REGS
;r
++) {
4275 if (reg_classes
[r
] & rc
) {
4276 for(p
=vstack
;p
<=vtop
;p
++) {
4277 if ((p
->r
& VT_VALMASK
) == r
||
4278 (p
->r2
& VT_VALMASK
) == r
)
4286 /* no register left : free the first one on the stack (VERY
4287 IMPORTANT to start from the bottom to ensure that we don't
4288 spill registers used in gen_opi()) */
4289 for(p
=vstack
;p
<=vtop
;p
++) {
4290 r
= p
->r
& VT_VALMASK
;
4291 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
4293 /* also look at second register (if long long) */
4294 r
= p
->r2
& VT_VALMASK
;
4295 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
4301 /* Should never comes here */
4305 /* save registers up to (vtop - n) stack entry */
4306 void save_regs(int n
)
4311 for(p
= vstack
;p
<= p1
; p
++) {
4312 r
= p
->r
& VT_VALMASK
;
4319 /* move register 's' to 'r', and flush previous value of r to memory
4321 void move_reg(int r
, int s
)
4334 /* get address of vtop (vtop MUST BE an lvalue) */
4337 vtop
->r
&= ~VT_LVAL
;
4338 /* tricky: if saved lvalue, then we can go back to lvalue */
4339 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
4340 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
4343 #ifdef CONFIG_TCC_BCHECK
4344 /* generate lvalue bound code */
4350 vtop
->r
&= ~VT_MUSTBOUND
;
4351 /* if lvalue, then use checking code before dereferencing */
4352 if (vtop
->r
& VT_LVAL
) {
4353 /* if not VT_BOUNDED value, then make one */
4354 if (!(vtop
->r
& VT_BOUNDED
)) {
4355 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
4356 /* must save type because we must set it to int to get pointer */
4358 vtop
->type
.t
= VT_INT
;
4361 gen_bounded_ptr_add();
4362 vtop
->r
|= lval_type
;
4365 /* then check for dereferencing */
4366 gen_bounded_ptr_deref();
4371 /* store vtop a register belonging to class 'rc'. lvalues are
4372 converted to values. Cannot be used if cannot be converted to
4373 register value (such as structures). */
4376 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
4377 unsigned long long ll
;
4379 /* NOTE: get_reg can modify vstack[] */
4380 if (vtop
->type
.t
& VT_BITFIELD
) {
4381 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
4382 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4383 /* remove bit field info to avoid loops */
4384 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4385 /* generate shifts */
4386 vpushi(32 - (bit_pos
+ bit_size
));
4388 vpushi(32 - bit_size
);
4389 /* NOTE: transformed to SHR if unsigned */
4393 if (is_float(vtop
->type
.t
) &&
4394 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4397 unsigned long offset
;
4399 /* XXX: unify with initializers handling ? */
4400 /* CPUs usually cannot use float constants, so we store them
4401 generically in data segment */
4402 size
= type_size(&vtop
->type
, &align
);
4403 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
4404 data_section
->data_offset
= offset
;
4405 /* XXX: not portable yet */
4406 ptr
= section_ptr_add(data_section
, size
);
4409 ptr
[i
] = vtop
->c
.tab
[i
];
4410 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
4411 vtop
->r
|= VT_LVAL
| VT_SYM
;
4415 #ifdef CONFIG_TCC_BCHECK
4416 if (vtop
->r
& VT_MUSTBOUND
)
4420 r
= vtop
->r
& VT_VALMASK
;
4421 /* need to reload if:
4423 - lvalue (need to dereference pointer)
4424 - already a register, but not in the right class */
4425 if (r
>= VT_CONST
||
4426 (vtop
->r
& VT_LVAL
) ||
4427 !(reg_classes
[r
] & rc
) ||
4428 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
4429 !(reg_classes
[vtop
->r2
] & rc
))) {
4431 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
4432 /* two register type load : expand to two words
4434 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4437 vtop
->c
.ui
= ll
; /* first word */
4439 vtop
->r
= r
; /* save register value */
4440 vpushi(ll
>> 32); /* second word */
4441 } else if (r
>= VT_CONST
||
4442 (vtop
->r
& VT_LVAL
)) {
4443 /* load from memory */
4446 vtop
[-1].r
= r
; /* save register value */
4447 /* increment pointer to get second word */
4448 vtop
->type
.t
= VT_INT
;
4454 /* move registers */
4457 vtop
[-1].r
= r
; /* save register value */
4458 vtop
->r
= vtop
[-1].r2
;
4460 /* allocate second register */
4467 /* write second register */
4469 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
4471 /* lvalue of scalar type : need to use lvalue type
4472 because of possible cast */
4475 /* compute memory access type */
4476 if (vtop
->r
& VT_LVAL_BYTE
)
4478 else if (vtop
->r
& VT_LVAL_SHORT
)
4480 if (vtop
->r
& VT_LVAL_UNSIGNED
)
4484 /* restore wanted type */
4487 /* one register type load */
4496 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4497 void gv2(int rc1
, int rc2
)
4501 /* generate more generic register first. But VT_JMP or VT_CMP
4502 values must be generated first in all cases to avoid possible
4504 v
= vtop
[0].r
& VT_VALMASK
;
4505 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
4510 /* test if reload is needed for first register */
4511 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
4521 /* test if reload is needed for first register */
4522 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
4528 /* expand long long on stack in two int registers */
4533 u
= vtop
->type
.t
& VT_UNSIGNED
;
4536 vtop
[0].r
= vtop
[-1].r2
;
4537 vtop
[0].r2
= VT_CONST
;
4538 vtop
[-1].r2
= VT_CONST
;
4539 vtop
[0].type
.t
= VT_INT
| u
;
4540 vtop
[-1].type
.t
= VT_INT
| u
;
4543 /* build a long long from two ints */
4546 gv2(RC_INT
, RC_INT
);
4547 vtop
[-1].r2
= vtop
[0].r
;
4548 vtop
[-1].type
.t
= t
;
4552 /* rotate n first stack elements to the bottom */
4559 for(i
=-n
+1;i
!=0;i
++)
4560 vtop
[i
] = vtop
[i
+1];
4564 /* pop stack value */
4568 v
= vtop
->r
& VT_VALMASK
;
4569 #ifdef TCC_TARGET_I386
4570 /* for x86, we need to pop the FP stack */
4571 if (v
== TREG_ST0
&& !nocode_wanted
) {
4572 o(0xd9dd); /* fstp %st(1) */
4575 if (v
== VT_JMP
|| v
== VT_JMPI
) {
4576 /* need to put correct jump if && or || without test */
4582 /* convert stack entry to register and duplicate its value in another
4590 if ((t
& VT_BTYPE
) == VT_LLONG
) {
4597 /* stack: H L L1 H1 */
4605 /* duplicate value */
4616 load(r1
, &sv
); /* move r to r1 */
4618 /* duplicates value */
4623 /* generate CPU independent (unsigned) long long operations */
4624 void gen_opl(int op
)
4626 int t
, a
, b
, op1
, c
, i
;
4634 func
= TOK___divdi3
;
4637 func
= TOK___udivdi3
;
4640 func
= TOK___moddi3
;
4643 func
= TOK___umoddi3
;
4645 /* call generic long long function */
4646 gfunc_start(&gf
, FUNC_CDECL
);
4649 vpush_global_sym(&func_old_type
, func
);
4653 vtop
->r2
= REG_LRET
;
4666 /* stack: L1 H1 L2 H2 */
4671 vtop
[-2] = vtop
[-3];
4674 /* stack: H1 H2 L1 L2 */
4680 /* stack: H1 H2 L1 L2 ML MH */
4683 /* stack: ML MH H1 H2 L1 L2 */
4687 /* stack: ML MH H1 L2 H2 L1 */
4692 /* stack: ML MH M1 M2 */
4695 } else if (op
== '+' || op
== '-') {
4696 /* XXX: add non carry method too (for MIPS or alpha) */
4702 /* stack: H1 H2 (L1 op L2) */
4705 gen_op(op1
+ 1); /* TOK_xxxC2 */
4708 /* stack: H1 H2 (L1 op L2) */
4711 /* stack: (L1 op L2) H1 H2 */
4713 /* stack: (L1 op L2) (H1 op H2) */
4721 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4722 t
= vtop
[-1].type
.t
;
4726 /* stack: L H shift */
4728 /* constant: simpler */
4729 /* NOTE: all comments are for SHL. the other cases are
4730 done by swaping words */
4741 if (op
!= TOK_SAR
) {
4774 /* XXX: should provide a faster fallback on x86 ? */
4777 func
= TOK___sardi3
;
4780 func
= TOK___shrdi3
;
4783 func
= TOK___shldi3
;
4789 /* compare operations */
4795 /* stack: L1 H1 L2 H2 */
4797 vtop
[-1] = vtop
[-2];
4799 /* stack: L1 L2 H1 H2 */
4802 /* when values are equal, we need to compare low words. since
4803 the jump is inverted, we invert the test too. */
4806 else if (op1
== TOK_GT
)
4808 else if (op1
== TOK_ULT
)
4810 else if (op1
== TOK_UGT
)
4815 if (op1
!= TOK_NE
) {
4819 /* generate non equal test */
4820 /* XXX: NOT PORTABLE yet */
4824 #ifdef TCC_TARGET_I386
4825 b
= psym(0x850f, 0);
4827 error("not implemented");
4831 /* compare low. Always unsigned */
4835 else if (op1
== TOK_LE
)
4837 else if (op1
== TOK_GT
)
4839 else if (op1
== TOK_GE
)
4849 /* handle integer constant optimizations and various machine
4851 void gen_opic(int op
)
4858 /* currently, we cannot do computations with forward symbols */
4859 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4860 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4864 case '+': v1
->c
.i
+= fc
; break;
4865 case '-': v1
->c
.i
-= fc
; break;
4866 case '&': v1
->c
.i
&= fc
; break;
4867 case '^': v1
->c
.i
^= fc
; break;
4868 case '|': v1
->c
.i
|= fc
; break;
4869 case '*': v1
->c
.i
*= fc
; break;
4876 /* if division by zero, generate explicit division */
4879 error("division by zero in constant");
4883 default: v1
->c
.i
/= fc
; break;
4884 case '%': v1
->c
.i
%= fc
; break;
4885 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
4886 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
4889 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
4890 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
4891 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
4893 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
4894 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
4895 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
4896 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
4897 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
4898 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
4899 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
4900 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
4901 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
4902 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
4904 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
4905 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
4911 /* if commutative ops, put c2 as constant */
4912 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
4913 op
== '|' || op
== '*')) {
4918 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
4921 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
4922 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
4928 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
4929 /* try to use shifts instead of muls or divs */
4930 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
4939 else if (op
== TOK_PDIV
)
4945 } else if (c2
&& (op
== '+' || op
== '-') &&
4946 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
4947 (VT_CONST
| VT_SYM
)) {
4948 /* symbol + constant case */
4955 if (!nocode_wanted
) {
4956 /* call low level op generator */
4965 /* generate a floating point operation with constant propagation */
4966 void gen_opif(int op
)
4974 /* currently, we cannot do computations with forward symbols */
4975 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4976 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4978 if (v1
->type
.t
== VT_FLOAT
) {
4981 } else if (v1
->type
.t
== VT_DOUBLE
) {
4989 /* NOTE: we only do constant propagation if finite number (not
4990 NaN or infinity) (ANSI spec) */
4991 if (!ieee_finite(f1
) || !ieee_finite(f2
))
4995 case '+': f1
+= f2
; break;
4996 case '-': f1
-= f2
; break;
4997 case '*': f1
*= f2
; break;
5001 error("division by zero in constant");
5006 /* XXX: also handles tests ? */
5010 /* XXX: overflow test ? */
5011 if (v1
->type
.t
== VT_FLOAT
) {
5013 } else if (v1
->type
.t
== VT_DOUBLE
) {
5021 if (!nocode_wanted
) {
5029 static int pointed_size(CType
*type
)
5032 return type_size(pointed_type(type
), &align
);
5036 void check_pointer_types(SValue
*p1
, SValue
*p2
)
5038 char buf1
[256], buf2
[256];
5042 if (!is_compatible_types(t1
, t2
)) {
5043 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
5044 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
5045 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
5050 /* generic gen_op: handles types problems */
5053 int u
, t1
, t2
, bt1
, bt2
, t
;
5056 t1
= vtop
[-1].type
.t
;
5057 t2
= vtop
[0].type
.t
;
5058 bt1
= t1
& VT_BTYPE
;
5059 bt2
= t2
& VT_BTYPE
;
5061 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5062 /* at least one operand is a pointer */
5063 /* relationnal op: must be both pointers */
5064 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5065 // check_pointer_types(vtop, vtop - 1);
5066 /* pointers are handled are unsigned */
5067 t
= VT_INT
| VT_UNSIGNED
;
5070 /* if both pointers, then it must be the '-' op */
5071 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
5073 error("cannot use pointers here");
5074 // check_pointer_types(vtop - 1, vtop);
5075 /* XXX: check that types are compatible */
5076 u
= pointed_size(&vtop
[-1].type
);
5078 /* set to integer type */
5079 vtop
->type
.t
= VT_INT
;
5083 /* exactly one pointer : must be '+' or '-'. */
5084 if (op
!= '-' && op
!= '+')
5085 error("cannot use pointers here");
5086 /* Put pointer as first operand */
5087 if (bt2
== VT_PTR
) {
5091 type1
= vtop
[-1].type
;
5092 /* XXX: cast to int ? (long long case) */
5093 vpushi(pointed_size(&vtop
[-1].type
));
5095 #ifdef CONFIG_TCC_BCHECK
5096 /* if evaluating constant expression, no code should be
5097 generated, so no bound check */
5098 if (do_bounds_check
&& !const_wanted
) {
5099 /* if bounded pointers, we generate a special code to
5106 gen_bounded_ptr_add();
5112 /* put again type if gen_opic() swaped operands */
5115 } else if (is_float(bt1
) || is_float(bt2
)) {
5116 /* compute bigger type and do implicit casts */
5117 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5119 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5124 /* floats can only be used for a few operations */
5125 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
5126 (op
< TOK_ULT
|| op
> TOK_GT
))
5127 error("invalid operands for binary operation");
5129 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5130 /* cast to biggest op */
5132 /* convert to unsigned if it does not fit in a long long */
5133 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5134 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5138 /* integer operations */
5140 /* convert to unsigned if it does not fit in an integer */
5141 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5142 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5145 /* XXX: currently, some unsigned operations are explicit, so
5146 we modify them here */
5147 if (t
& VT_UNSIGNED
) {
5154 else if (op
== TOK_LT
)
5156 else if (op
== TOK_GT
)
5158 else if (op
== TOK_LE
)
5160 else if (op
== TOK_GE
)
5167 /* special case for shifts and long long: we keep the shift as
5169 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
5174 else if ((t
& VT_BTYPE
) == VT_LLONG
)
5178 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5179 /* relationnal op: the result is an int */
5180 vtop
->type
.t
= VT_INT
;
5187 /* generic itof for unsigned long long case */
5188 void gen_cvt_itof1(int t
)
5192 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
5193 (VT_LLONG
| VT_UNSIGNED
)) {
5195 gfunc_start(&gf
, FUNC_CDECL
);
5198 vpush_global_sym(&func_old_type
, TOK___ulltof
);
5199 else if (t
== VT_DOUBLE
)
5200 vpush_global_sym(&func_old_type
, TOK___ulltod
);
5202 vpush_global_sym(&func_old_type
, TOK___ulltold
);
5211 /* generic ftoi for unsigned long long case */
5212 void gen_cvt_ftoi1(int t
)
5217 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
5218 /* not handled natively */
5219 gfunc_start(&gf
, FUNC_CDECL
);
5220 st
= vtop
->type
.t
& VT_BTYPE
;
5223 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
5224 else if (st
== VT_DOUBLE
)
5225 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
5227 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
5231 vtop
->r2
= REG_LRET
;
5237 /* force char or short cast */
5238 void force_charshort_cast(int t
)
5242 /* XXX: add optimization if lvalue : just change type and offset */
5247 if (t
& VT_UNSIGNED
) {
5248 vpushi((1 << bits
) - 1);
5259 /* cast 'vtop' to 'type' */
5260 static void gen_cast(CType
*type
)
5262 int sbt
, dbt
, sf
, df
, c
;
5264 /* special delayed cast for char/short */
5265 /* XXX: in some cases (multiple cascaded casts), it may still
5267 if (vtop
->r
& VT_MUSTCAST
) {
5268 vtop
->r
&= ~VT_MUSTCAST
;
5269 force_charshort_cast(vtop
->type
.t
);
5272 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
5273 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5275 if (sbt
!= dbt
&& !nocode_wanted
) {
5278 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5280 /* convert from fp to fp */
5282 /* constant case: we can do it now */
5283 /* XXX: in ISOC, cannot do it if error in convert */
5284 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
5285 vtop
->c
.f
= (float)vtop
->c
.d
;
5286 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
5287 vtop
->c
.f
= (float)vtop
->c
.ld
;
5288 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
5289 vtop
->c
.d
= (double)vtop
->c
.f
;
5290 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
5291 vtop
->c
.d
= (double)vtop
->c
.ld
;
5292 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
5293 vtop
->c
.ld
= (long double)vtop
->c
.f
;
5294 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
5295 vtop
->c
.ld
= (long double)vtop
->c
.d
;
5297 /* non constant case: generate code */
5301 /* convert int to fp */
5304 case VT_LLONG
| VT_UNSIGNED
:
5306 /* XXX: add const cases for long long */
5308 case VT_INT
| VT_UNSIGNED
:
5310 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
5311 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
5312 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
5317 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
5318 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
5319 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
5328 /* convert fp to int */
5329 /* we handle char/short/etc... with generic code */
5330 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
5331 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
5336 case VT_LLONG
| VT_UNSIGNED
:
5338 /* XXX: add const cases for long long */
5340 case VT_INT
| VT_UNSIGNED
:
5342 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5343 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5344 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5350 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5351 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5352 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5360 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
5361 /* additional cast for char/short/bool... */
5365 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
5366 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
5367 /* scalar to long long */
5369 if (sbt
== (VT_INT
| VT_UNSIGNED
))
5370 vtop
->c
.ll
= vtop
->c
.ui
;
5372 vtop
->c
.ll
= vtop
->c
.i
;
5374 /* machine independent conversion */
5376 /* generate high word */
5377 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
5385 /* patch second register */
5386 vtop
[-1].r2
= vtop
->r
;
5390 } else if (dbt
== VT_BOOL
) {
5391 /* scalar to bool */
5394 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
5395 (dbt
& VT_BTYPE
) == VT_SHORT
) {
5396 force_charshort_cast(dbt
);
5397 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
5399 if (sbt
== VT_LLONG
) {
5400 /* from long long: just take low order word */
5404 /* if lvalue and single word type, nothing to do because
5405 the lvalue already contains the real type size (see
5406 VT_LVAL_xxx constants) */
5412 /* return type size. Put alignment at 'a' */
5413 static int type_size(CType
*type
, int *a
)
5418 bt
= type
->t
& VT_BTYPE
;
5419 if (bt
== VT_STRUCT
) {
5424 } else if (bt
== VT_PTR
) {
5425 if (type
->t
& VT_ARRAY
) {
5427 return type_size(&s
->type
, a
) * s
->c
;
5432 } else if (bt
== VT_LDOUBLE
) {
5434 return LDOUBLE_SIZE
;
5435 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
5436 *a
= 4; /* XXX: i386 specific */
5438 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
5441 } else if (bt
== VT_SHORT
) {
5445 /* char, void, function, _Bool */
5451 /* return the pointed type of t */
5452 static inline CType
*pointed_type(CType
*type
)
5454 return &type
->ref
->type
;
5457 /* modify type so that its it is a pointer to type. */
5458 static void mk_pointer(CType
*type
)
5461 s
= sym_push(SYM_FIELD
, type
, 0, -1);
5462 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
5466 static int is_compatible_types(CType
*type1
, CType
*type2
)
5469 int bt1
, bt2
, t1
, t2
;
5471 t1
= type1
->t
& VT_TYPE
;
5472 t2
= type2
->t
& VT_TYPE
;
5473 bt1
= t1
& VT_BTYPE
;
5474 bt2
= t2
& VT_BTYPE
;
5475 if (bt1
== VT_PTR
) {
5476 type1
= pointed_type(type1
);
5477 /* if function, then convert implicitely to function pointer */
5478 if (bt2
!= VT_FUNC
) {
5481 type2
= pointed_type(type2
);
5483 /* void matches everything */
5484 /* XXX: not fully compliant */
5485 if ((type1
->t
& VT_TYPE
) == VT_VOID
|| (type2
->t
& VT_TYPE
) == VT_VOID
)
5487 return is_compatible_types(type1
, type2
);
5488 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
5489 return (type1
->ref
== type2
->ref
);
5490 } else if (bt1
== VT_FUNC
) {
5495 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5497 /* XXX: not complete */
5498 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
5502 while (s1
!= NULL
) {
5505 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5514 /* XXX: not complete */
5519 /* print a type. If 'varstr' is not NULL, then the variable is also
5520 printed in the type */
5522 /* XXX: add array and function pointers */
5523 void type_to_str(char *buf
, int buf_size
,
5524 CType
*type
, const char *varstr
)
5531 t
= type
->t
& VT_TYPE
;
5534 if (t
& VT_UNSIGNED
)
5535 pstrcat(buf
, buf_size
, "unsigned ");
5565 tstr
= "long double";
5567 pstrcat(buf
, buf_size
, tstr
);
5571 if (bt
== VT_STRUCT
)
5575 pstrcat(buf
, buf_size
, tstr
);
5576 v
= type
->ref
->v
& ~SYM_STRUCT
;
5577 if (v
>= SYM_FIRST_ANOM
)
5578 pstrcat(buf
, buf_size
, "<anonymous>");
5580 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
5584 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
5585 pstrcat(buf
, buf_size
, "(");
5587 while (sa
!= NULL
) {
5588 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
5589 pstrcat(buf
, buf_size
, buf1
);
5592 pstrcat(buf
, buf_size
, ", ");
5594 pstrcat(buf
, buf_size
, ")");
5598 pstrcpy(buf1
, sizeof(buf1
), "*");
5600 pstrcat(buf1
, sizeof(buf1
), varstr
);
5601 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
5605 pstrcat(buf
, buf_size
, " ");
5606 pstrcat(buf
, buf_size
, varstr
);
5611 /* verify type compatibility to store vtop in 'dt' type, and generate
5613 static void gen_assign_cast(CType
*dt
)
5616 char buf1
[256], buf2
[256];
5619 st
= &vtop
->type
; /* source type */
5620 dbt
= dt
->t
& VT_BTYPE
;
5621 sbt
= st
->t
& VT_BTYPE
;
5622 if (dbt
== VT_PTR
) {
5623 /* special cases for pointers */
5624 /* a function is implicitely a function pointer */
5625 if (sbt
== VT_FUNC
) {
5626 if (!is_compatible_types(pointed_type(dt
), st
))
5631 /* '0' can also be a pointer */
5632 if (sbt
== VT_INT
&&
5633 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
5636 /* accept implicit pointer to integer cast with warning */
5637 if (sbt
== VT_BYTE
|| sbt
== VT_SHORT
||
5638 sbt
== VT_INT
|| sbt
== VT_LLONG
) {
5639 warning("assignment makes pointer from integer without a cast");
5642 } else if (dbt
== VT_BYTE
|| dbt
== VT_SHORT
||
5643 dbt
== VT_INT
|| dbt
== VT_LLONG
) {
5644 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
5645 warning("assignment makes integer from pointer without a cast");
5649 if (!is_compatible_types(dt
, st
)) {
5651 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
5652 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
5653 error("cannot cast '%s' to '%s'", buf1
, buf2
);
5659 /* store vtop in lvalue pushed on stack */
5662 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
5665 ft
= vtop
[-1].type
.t
;
5666 sbt
= vtop
->type
.t
& VT_BTYPE
;
5667 dbt
= ft
& VT_BTYPE
;
5668 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
5669 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
5670 /* optimize char/short casts */
5671 delayed_cast
= VT_MUSTCAST
;
5672 vtop
->type
.t
= ft
& VT_TYPE
;
5675 gen_assign_cast(&vtop
[-1].type
);
5678 if (sbt
== VT_STRUCT
) {
5679 /* if structure, only generate pointer */
5680 /* structure assignment : generate memcpy */
5681 /* XXX: optimize if small size */
5682 if (!nocode_wanted
) {
5684 gfunc_start(&gf
, FUNC_CDECL
);
5686 size
= type_size(&vtop
->type
, &align
);
5690 vtop
->type
.t
= VT_INT
;
5695 vtop
->type
.t
= VT_INT
;
5700 vpush_global_sym(&func_old_type
, TOK_memcpy
);
5706 /* leave source on stack */
5707 } else if (ft
& VT_BITFIELD
) {
5708 /* bitfield store handling */
5709 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
5710 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
5711 /* remove bit field info to avoid loops */
5712 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
5714 /* duplicate destination */
5716 vtop
[-1] = vtop
[-2];
5718 /* mask and shift source */
5719 vpushi((1 << bit_size
) - 1);
5723 /* load destination, mask and or with source */
5725 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
5731 #ifdef CONFIG_TCC_BCHECK
5732 /* bound check case */
5733 if (vtop
[-1].r
& VT_MUSTBOUND
) {
5739 if (!nocode_wanted
) {
5743 r
= gv(rc
); /* generate value */
5744 /* if lvalue was saved on stack, must read it */
5745 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
5747 t
= get_reg(RC_INT
);
5749 sv
.r
= VT_LOCAL
| VT_LVAL
;
5750 sv
.c
.ul
= vtop
[-1].c
.ul
;
5752 vtop
[-1].r
= t
| VT_LVAL
;
5755 /* two word case handling : store second register at word + 4 */
5756 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
5758 /* convert to int to increment easily */
5759 vtop
->type
.t
= VT_INT
;
5765 /* XXX: it works because r2 is spilled last ! */
5766 store(vtop
->r2
, vtop
- 1);
5770 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5771 vtop
->r
|= delayed_cast
;
5775 /* post defines POST/PRE add. c is the token ++ or -- */
5776 void inc(int post
, int c
)
5779 vdup(); /* save lvalue */
5781 gv_dup(); /* duplicate value */
5786 vpushi(c
- TOK_MID
);
5788 vstore(); /* store value */
5790 vpop(); /* if post op, return saved value */
5793 /* Parse GNUC __attribute__ extension. Currently, the following
5794 extensions are recognized:
5795 - aligned(n) : set data/function alignment.
5796 - section(x) : generate data/code in this section.
5797 - unused : currently ignored, but may be used someday.
5799 static void parse_attribute(AttributeDef
*ad
)
5803 while (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
5807 while (tok
!= ')') {
5808 if (tok
< TOK_IDENT
)
5809 expect("attribute name");
5817 expect("section name");
5818 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
5827 if (n
<= 0 || (n
& (n
- 1)) != 0)
5828 error("alignment must be a positive power of two");
5837 /* currently, no need to handle it because tcc does not
5838 track unused objects */
5842 /* currently, no need to handle it because tcc does not
5843 track unused objects */
5848 ad
->func_call
= FUNC_CDECL
;
5853 ad
->func_call
= FUNC_STDCALL
;
5856 // warning("'%s' attribute ignored", get_tok_str(t, NULL));
5857 /* skip parameters */
5858 /* XXX: skip parenthesis too */
5861 while (tok
!= ')' && tok
!= -1)
5876 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5877 static void struct_decl(CType
*type
, int u
)
5879 int a
, v
, size
, align
, maxalign
, c
, offset
;
5880 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
5885 a
= tok
; /* save decl type */
5890 /* struct already defined ? return it */
5892 expect("struct/union/enum name");
5896 error("invalid type");
5903 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, 0);
5904 /* put struct/union/enum name in type */
5912 error("struct/union/enum already defined");
5913 /* cannot be empty */
5915 /* non empty enums are not allowed */
5916 if (a
== TOK_ENUM
) {
5920 expect("identifier");
5926 /* enum symbols have static storage */
5927 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
5928 ss
->type
.t
|= VT_STATIC
;
5933 /* NOTE: we accept a trailing comma */
5943 while (tok
!= '}') {
5944 parse_btype(&btype
, &ad
);
5950 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
);
5951 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
5952 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
| VT_INLINE
)))
5953 error("invalid type for '%s'",
5954 get_tok_str(v
, NULL
));
5958 bit_size
= expr_const();
5959 /* XXX: handle v = 0 case for messages */
5961 error("negative width in bit-field '%s'",
5962 get_tok_str(v
, NULL
));
5963 if (v
&& bit_size
== 0)
5964 error("zero width for bit-field '%s'",
5965 get_tok_str(v
, NULL
));
5967 size
= type_size(&type1
, &align
);
5969 if (bit_size
>= 0) {
5970 bt
= type1
.t
& VT_BTYPE
;
5975 error("bitfields must have scalar type");
5977 if (bit_size
> bsize
) {
5978 error("width of '%s' exceeds its type",
5979 get_tok_str(v
, NULL
));
5980 } else if (bit_size
== bsize
) {
5981 /* no need for bit fields */
5983 } else if (bit_size
== 0) {
5984 /* XXX: what to do if only padding in a
5986 /* zero size: means to pad */
5990 /* we do not have enough room ? */
5991 if ((bit_pos
+ bit_size
) > bsize
)
5994 /* XXX: handle LSB first */
5995 type1
.t
|= VT_BITFIELD
|
5996 (bit_pos
<< VT_STRUCT_SHIFT
) |
5997 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
5998 bit_pos
+= bit_size
;
6004 /* add new memory data only if starting
6006 if (lbit_pos
== 0) {
6007 if (a
== TOK_STRUCT
) {
6008 c
= (c
+ align
- 1) & -align
;
6016 if (align
> maxalign
)
6020 printf("add field %s offset=%d",
6021 get_tok_str(v
, NULL
), offset
);
6022 if (type1
.t
& VT_BITFIELD
) {
6023 printf(" pos=%d size=%d",
6024 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
6025 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
6029 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
6033 if (tok
== ';' || tok
== TOK_EOF
)
6040 /* store size and alignment */
6041 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
6047 /* return 0 if no type declaration. otherwise, return the basic type
6050 static int parse_btype(CType
*type
, AttributeDef
*ad
)
6052 int t
, u
, type_found
;
6056 memset(ad
, 0, sizeof(AttributeDef
));
6062 /* currently, we really ignore extension */
6072 if ((t
& VT_BTYPE
) != 0)
6073 error("too many basic types");
6087 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
6088 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6089 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
6090 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
6104 if ((t
& VT_BTYPE
) == VT_LONG
) {
6105 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6112 struct_decl(&type1
, VT_ENUM
);
6115 type
->ref
= type1
.ref
;
6119 struct_decl(&type1
, VT_STRUCT
);
6122 /* type modifiers */
6164 /* GNUC attribute */
6165 case TOK_ATTRIBUTE1
:
6166 case TOK_ATTRIBUTE2
:
6167 parse_attribute(ad
);
6174 parse_expr_type(&type1
);
6178 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
6180 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
6181 type
->ref
= s
->type
.ref
;
6188 /* long is never used as type */
6189 if ((t
& VT_BTYPE
) == VT_LONG
)
6190 t
= (t
& ~VT_BTYPE
) | VT_INT
;
6195 /* convert a function parameter type (array to pointer and function to
6196 function pointer) */
6197 static inline void convert_parameter_type(CType
*pt
)
6199 /* array must be transformed to pointer according to ANSI C */
6201 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
6206 static void post_type(CType
*type
, AttributeDef
*ad
)
6209 Sym
**plast
, *s
, *first
;
6214 /* function declaration */
6219 while (tok
!= ')') {
6220 /* read param name and compute offset */
6221 if (l
!= FUNC_OLD
) {
6222 if (!parse_btype(&pt
, &ad1
)) {
6224 error("invalid type");
6231 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
6233 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
6234 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
6235 error("parameter declared as void");
6242 convert_parameter_type(&pt
);
6243 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
6248 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
6255 /* if no parameters, then old type prototype */
6259 t1
= type
->t
& VT_STORAGE
;
6260 type
->t
&= ~VT_STORAGE
;
6261 post_type(type
, ad
);
6262 /* we push a anonymous symbol which will contain the function prototype */
6263 s
= sym_push(SYM_FIELD
, type
, ad
->func_call
, l
);
6265 type
->t
= t1
| VT_FUNC
;
6267 } else if (tok
== '[') {
6268 /* array definition */
6274 error("invalid array size");
6277 /* parse next post type */
6278 t1
= type
->t
& VT_STORAGE
;
6279 type
->t
&= ~VT_STORAGE
;
6280 post_type(type
, ad
);
6282 /* we push a anonymous symbol which will contain the array
6284 s
= sym_push(SYM_FIELD
, type
, 0, n
);
6285 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
6290 /* Parse a type declaration (except basic type), and return the type
6291 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6292 expected. 'type' should contain the basic type. 'ad' is the
6293 attribute definition of the basic type. It can be modified by
6296 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
6299 CType type1
, *type2
;
6301 while (tok
== '*') {
6320 /* XXX: clarify attribute handling */
6321 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6322 parse_attribute(ad
);
6324 /* recursive type */
6325 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6326 type1
.t
= 0; /* XXX: same as int */
6329 /* XXX: this is not correct to modify 'ad' at this point, but
6330 the syntax is not clear */
6331 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6332 parse_attribute(ad
);
6333 type_decl(&type1
, ad
, v
, td
);
6336 /* type identifier */
6337 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
6341 if (!(td
& TYPE_ABSTRACT
))
6342 expect("identifier");
6346 post_type(type
, ad
);
6347 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6348 parse_attribute(ad
);
6351 /* append type at the end of type1 */
6364 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6365 static int lvalue_type(int t
)
6370 if (bt
== VT_BYTE
|| bt
== VT_BOOL
)
6372 else if (bt
== VT_SHORT
)
6376 if (t
& VT_UNSIGNED
)
6377 r
|= VT_LVAL_UNSIGNED
;
6381 /* indirection with full error checking and bound check */
6382 static void indir(void)
6384 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
6386 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
6388 vtop
->type
= *pointed_type(&vtop
->type
);
6389 /* an array is never an lvalue */
6390 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6391 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6392 /* if bound checking, the referenced pointer must be checked */
6393 if (do_bounds_check
)
6394 vtop
->r
|= VT_MUSTBOUND
;
6398 /* pass a parameter to a function and do type checking and casting */
6399 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
6404 func_type
= func
->c
;
6405 if (func_type
== FUNC_OLD
||
6406 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
6407 /* default casting : only need to convert float to double */
6408 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
6412 } else if (arg
== NULL
) {
6413 error("too many arguments to function");
6415 gen_assign_cast(&arg
->type
);
6417 if (!nocode_wanted
) {
6424 /* parse an expression of the form '(type)' or '(expr)' and return its
6426 static void parse_expr_type(CType
*type
)
6432 if (parse_btype(type
, &ad
)) {
6433 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
6440 static void vpush_tokc(int t
)
6444 vsetc(&type
, VT_CONST
, &tokc
);
6447 static void unary(void)
6449 int n
, t
, align
, size
, r
;
6455 /* XXX: GCC 2.95.3 does not generate a table although it should be
6469 vpush_tokc(VT_INT
| VT_UNSIGNED
);
6473 vpush_tokc(VT_LLONG
);
6477 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
6481 vpush_tokc(VT_FLOAT
);
6485 vpush_tokc(VT_DOUBLE
);
6489 vpush_tokc(VT_LDOUBLE
);
6492 case TOK___FUNCTION__
:
6494 goto tok_identifier
;
6500 /* special function name identifier */
6501 len
= strlen(funcname
) + 1;
6502 /* generate char[len] type */
6507 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
6508 ptr
= section_ptr_add(data_section
, len
);
6509 memcpy(ptr
, funcname
, len
);
6517 /* string parsing */
6523 memset(&ad
, 0, sizeof(AttributeDef
));
6524 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
6529 if (parse_btype(&type
, &ad
)) {
6530 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
6532 /* check ISOC99 compound literal */
6534 /* data is allocated locally by default */
6539 /* all except arrays are lvalues */
6540 if (!(type
.t
& VT_ARRAY
))
6541 r
|= lvalue_type(type
.t
);
6542 memset(&ad
, 0, sizeof(AttributeDef
));
6543 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
6548 } else if (tok
== '{') {
6549 /* save all registers */
6551 /* statement expression : we do not accept break/continue
6552 inside as GCC does */
6553 block(NULL
, NULL
, NULL
, NULL
, 0, 1);
6568 /* functions names must be treated as function pointers,
6569 except for unary '&' and sizeof. Since we consider that
6570 functions are not lvalues, we only have to handle it
6571 there and in function calls. */
6572 /* arrays can also be used although they are not lvalues */
6573 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
6574 !(vtop
->type
.t
& VT_ARRAY
))
6576 mk_pointer(&vtop
->type
);
6582 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
6583 vtop
->c
.i
= !vtop
->c
.i
;
6584 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
6585 vtop
->c
.i
= vtop
->c
.i
^ 1;
6587 vseti(VT_JMP
, gtst(1, 0));
6597 /* in order to force cast, we add zero */
6599 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
6600 error("pointer not accepted for unary plus");
6610 parse_expr_type(&type
);
6614 size
= type_size(&type
, &align
);
6615 if (t
== TOK_SIZEOF
)
6636 goto tok_identifier
;
6638 /* allow to take the address of a label */
6639 if (tok
< TOK_UIDENT
)
6640 expect("label identifier");
6641 s
= label_find(tok
);
6643 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
6645 if (s
->r
== LABEL_DECLARED
)
6646 s
->r
= LABEL_FORWARD
;
6649 s
->type
.t
= VT_VOID
;
6650 mk_pointer(&s
->type
);
6651 s
->type
.t
|= VT_STATIC
;
6653 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
6662 expect("identifier");
6666 error("'%s' undeclared", get_tok_str(t
, NULL
));
6667 /* for simple function calls, we tolerate undeclared
6668 external reference to int() function */
6669 s
= external_global_sym(t
, &func_old_type
, 0);
6671 vset(&s
->type
, s
->r
, s
->c
);
6672 /* if forward reference, we must point to s */
6673 if (vtop
->r
& VT_SYM
) {
6680 /* post operations */
6682 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
6685 } else if (tok
== '.' || tok
== TOK_ARROW
) {
6687 if (tok
== TOK_ARROW
)
6692 /* expect pointer on structure */
6693 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
6694 expect("struct or union");
6698 while ((s
= s
->next
) != NULL
) {
6703 error("field not found");
6704 /* add field offset to pointer */
6705 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
6708 /* change type to field type, and set to lvalue */
6709 vtop
->type
= s
->type
;
6710 /* an array is never an lvalue */
6711 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6712 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6713 /* if bound checking, the referenced pointer must be checked */
6714 if (do_bounds_check
)
6715 vtop
->r
|= VT_MUSTBOUND
;
6718 } else if (tok
== '[') {
6724 } else if (tok
== '(') {
6729 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
6730 /* pointer test (no array accepted) */
6731 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
6732 vtop
->type
= *pointed_type(&vtop
->type
);
6733 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
6737 expect("function pointer");
6740 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
6742 /* get return type */
6744 if (!nocode_wanted
) {
6745 save_regs(0); /* save used temporary registers */
6746 gfunc_start(&gf
, s
->r
);
6749 sa
= s
->next
; /* first parameter */
6750 #ifdef INVERT_FUNC_PARAMS
6754 ParseState saved_parse_state
;
6757 /* read each argument and store it on a stack */
6763 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
6767 else if (tok
== ')')
6769 tok_str_add_tok(&str
);
6772 tok_str_add(&str
, -1); /* end of file added */
6773 tok_str_add(&str
, 0);
6774 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
6775 s1
->next
= sa
; /* add reference to argument */
6784 /* now generate code in reverse order by reading the stack */
6785 save_parse_state(&saved_parse_state
);
6787 macro_ptr
= (int *)args
->c
;
6791 expect("',' or ')'");
6792 gfunc_param_typed(&gf
, s
, args
->next
);
6794 tok_str_free((int *)args
->c
);
6798 restore_parse_state(&saved_parse_state
);
6801 /* compute first implicit argument if a structure is returned */
6802 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
6803 /* get some space for the returned structure */
6804 size
= type_size(&s
->type
, &align
);
6805 loc
= (loc
- size
) & -align
;
6807 ret
.r
= VT_LOCAL
| VT_LVAL
;
6808 /* pass it as 'int' to avoid structure arg passing
6810 vseti(VT_LOCAL
, loc
);
6819 /* return in register */
6820 if (is_float(ret
.type
.t
)) {
6823 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
6829 #ifndef INVERT_FUNC_PARAMS
6833 gfunc_param_typed(&gf
, s
, sa
);
6843 error("too few arguments to function");
6850 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
6858 static void uneq(void)
6864 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
6865 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
6866 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
6881 static void expr_prod(void)
6886 while (tok
== '*' || tok
== '/' || tok
== '%') {
6894 static void expr_sum(void)
6899 while (tok
== '+' || tok
== '-') {
6907 static void expr_shift(void)
6912 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
6920 static void expr_cmp(void)
6925 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
6926 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
6934 static void expr_cmpeq(void)
6939 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
6947 static void expr_and(void)
6950 while (tok
== '&') {
6957 static void expr_xor(void)
6960 while (tok
== '^') {
6967 static void expr_or(void)
6970 while (tok
== '|') {
6977 /* XXX: fix this mess */
6978 static void expr_land_const(void)
6981 while (tok
== TOK_LAND
) {
6988 /* XXX: fix this mess */
6989 static void expr_lor_const(void)
6992 while (tok
== TOK_LOR
) {
6999 /* only used if non constant */
7000 static void expr_land(void)
7005 if (tok
== TOK_LAND
) {
7009 if (tok
!= TOK_LAND
) {
7019 static void expr_lor(void)
7024 if (tok
== TOK_LOR
) {
7028 if (tok
!= TOK_LOR
) {
7038 /* XXX: better constant handling */
7039 static void expr_eq(void)
7041 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
7043 CType type
, type1
, type2
;
7052 if (tok
== ':' && gnu_ext
) {
7068 if (vtop
!= vstack
) {
7069 /* needed to avoid having different registers saved in
7071 if (is_float(vtop
->type
.t
))
7078 if (tok
== ':' && gnu_ext
) {
7086 sv
= *vtop
; /* save value to handle it later */
7087 vtop
--; /* no vpop so that FP stack is not flushed */
7095 bt1
= t1
& VT_BTYPE
;
7097 bt2
= t2
& VT_BTYPE
;
7098 /* cast operands to correct type according to ISOC rules */
7099 if (is_float(bt1
) || is_float(bt2
)) {
7100 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
7101 type
.t
= VT_LDOUBLE
;
7102 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
7107 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
7108 /* cast to biggest op */
7110 /* convert to unsigned if it does not fit in a long long */
7111 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
7112 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
7113 type
.t
|= VT_UNSIGNED
;
7114 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
7115 /* XXX: test pointer compatibility */
7117 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
7118 /* XXX: test structure compatibility */
7120 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
7121 /* NOTE: as an extension, we accept void on only one side */
7124 /* integer operations */
7126 /* convert to unsigned if it does not fit in an integer */
7127 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
7128 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
7129 type
.t
|= VT_UNSIGNED
;
7132 /* now we convert second operand */
7135 if (is_float(type
.t
)) {
7137 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
7138 /* for long longs, we use fixed registers to avoid having
7139 to handle a complicated move */
7144 /* this is horrible, but we must also convert first
7148 /* put again first value and cast it */
7159 static void gexpr(void)
7170 /* parse an expression and return its type without any side effect. */
7171 static void expr_type(CType
*type
)
7183 /* parse a unary expression and return its type without any side
7185 static void unary_type(CType
*type
)
7197 /* parse a constant expression and return value in vtop. */
7198 static void expr_const1(void)
7207 /* parse an integer constant and return its value. */
7208 static int expr_const(void)
7212 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
7213 expect("constant expression");
7219 /* return the label token if current token is a label, otherwise
7221 static int is_label(void)
7225 /* fast test first */
7226 if (tok
< TOK_UIDENT
)
7228 /* no need to save tokc because tok is an identifier */
7235 unget_tok(last_tok
);
7240 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
7241 int case_reg
, int is_expr
)
7246 /* generate line number info */
7248 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
7249 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
7251 last_line_num
= file
->line_num
;
7255 /* default return value is (void) */
7257 vtop
->type
.t
= VT_VOID
;
7260 if (tok
== TOK_IF
) {
7267 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7269 if (c
== TOK_ELSE
) {
7273 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7274 gsym(d
); /* patch else jmp */
7277 } else if (tok
== TOK_WHILE
) {
7285 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7289 } else if (tok
== '{') {
7293 /* record local declaration stack position */
7295 llabel
= local_label_stack
;
7296 /* handle local labels declarations */
7297 if (tok
== TOK_LABEL
) {
7300 if (tok
< TOK_UIDENT
)
7301 expect("label identifier");
7302 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
7312 while (tok
!= '}') {
7317 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
7320 /* pop locally defined labels */
7321 label_pop(&local_label_stack
, llabel
);
7322 /* pop locally defined symbols */
7323 sym_pop(&local_stack
, s
);
7325 } else if (tok
== TOK_RETURN
) {
7329 gen_assign_cast(&func_vt
);
7330 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
7332 /* if returning structure, must copy it to implicit
7333 first pointer arg location */
7336 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
7339 /* copy structure value to pointer */
7341 } else if (is_float(func_vt
.t
)) {
7346 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
7349 rsym
= gjmp(rsym
); /* jmp */
7350 } else if (tok
== TOK_BREAK
) {
7353 error("cannot break");
7354 *bsym
= gjmp(*bsym
);
7357 } else if (tok
== TOK_CONTINUE
) {
7360 error("cannot continue");
7361 *csym
= gjmp(*csym
);
7364 } else if (tok
== TOK_FOR
) {
7391 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7396 if (tok
== TOK_DO
) {
7401 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7412 if (tok
== TOK_SWITCH
) {
7416 /* XXX: other types than integer */
7417 case_reg
= gv(RC_INT
);
7421 b
= gjmp(0); /* jump to first case */
7423 block(&a
, csym
, &b
, &c
, case_reg
, 0);
7424 /* if no default, jmp after switch */
7432 if (tok
== TOK_CASE
) {
7439 if (gnu_ext
&& tok
== TOK_DOTS
) {
7443 warning("empty case range");
7445 /* since a case is like a label, we must skip it with a jmp */
7452 *case_sym
= gtst(1, 0);
7455 *case_sym
= gtst(1, 0);
7459 *case_sym
= gtst(1, *case_sym
);
7463 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7465 if (tok
== TOK_DEFAULT
) {
7471 error("too many 'default'");
7473 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7475 if (tok
== TOK_GOTO
) {
7477 if (tok
== '*' && gnu_ext
) {
7481 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
7484 } else if (tok
>= TOK_UIDENT
) {
7485 s
= label_find(tok
);
7486 /* put forward definition if needed */
7488 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7490 if (s
->r
== LABEL_DECLARED
)
7491 s
->r
= LABEL_FORWARD
;
7493 /* label already defined */
7494 if (s
->r
& LABEL_FORWARD
)
7495 s
->next
= (void *)gjmp((long)s
->next
);
7497 gjmp_addr((long)s
->next
);
7500 expect("label identifier");
7503 } else if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
7511 if (s
->r
== LABEL_DEFINED
)
7512 error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
7513 gsym((long)s
->next
);
7514 s
->r
= LABEL_DEFINED
;
7516 s
= label_push(&global_label_stack
, b
, LABEL_DEFINED
);
7518 s
->next
= (void *)ind
;
7519 /* we accept this, but it is a mistake */
7521 warning("deprecated use of label at end of compound statement");
7525 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
7528 /* expression case */
7543 /* t is the array or struct type. c is the array or struct
7544 address. cur_index/cur_field is the pointer to the current
7545 value. 'size_only' is true if only size info is needed (only used
7547 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
7548 int *cur_index
, Sym
**cur_field
,
7552 int notfirst
, index
, index_last
, align
, l
, nb_elems
, elem_size
;
7558 if (gnu_ext
&& (l
= is_label()) != 0)
7560 while (tok
== '[' || tok
== '.') {
7562 if (!(type
->t
& VT_ARRAY
))
7563 expect("array type");
7566 index
= expr_const();
7567 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
7568 expect("invalid index");
7569 if (tok
== TOK_DOTS
&& gnu_ext
) {
7571 index_last
= expr_const();
7572 if (index_last
< 0 ||
7573 (s
->c
>= 0 && index_last
>= s
->c
) ||
7575 expect("invalid index");
7581 *cur_index
= index_last
;
7582 type
= pointed_type(type
);
7583 elem_size
= type_size(type
, &align
);
7584 c
+= index
* elem_size
;
7585 /* NOTE: we only support ranges for last designator */
7586 nb_elems
= index_last
- index
+ 1;
7587 if (nb_elems
!= 1) {
7596 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
7597 expect("struct/union type");
7610 /* XXX: fix this mess by using explicit storage field */
7612 type1
.t
|= (type
->t
& ~VT_TYPE
);
7626 if (type
->t
& VT_ARRAY
) {
7628 type
= pointed_type(type
);
7629 c
+= index
* type_size(type
, &align
);
7633 error("too many field init");
7634 /* XXX: fix this mess by using explicit storage field */
7636 type1
.t
|= (type
->t
& ~VT_TYPE
);
7641 decl_initializer(type
, sec
, c
, 0, size_only
);
7643 /* XXX: make it more general */
7644 if (!size_only
&& nb_elems
> 1) {
7645 unsigned long c_end
;
7650 error("range init not supported yet for dynamic storage");
7651 c_end
= c
+ nb_elems
* elem_size
;
7652 if (c_end
> sec
->data_allocated
)
7653 section_realloc(sec
, c_end
);
7654 src
= sec
->data
+ c
;
7656 for(i
= 1; i
< nb_elems
; i
++) {
7658 memcpy(dst
, src
, elem_size
);
7664 #define EXPR_CONST 1
7667 /* store a value or an expression directly in global data or in local array */
7668 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
7669 int v
, int expr_type
)
7671 int saved_global_expr
, bt
, bit_pos
, bit_size
;
7673 unsigned long long bit_mask
;
7680 /* compound literals must be allocated globally in this case */
7681 saved_global_expr
= global_expr
;
7684 global_expr
= saved_global_expr
;
7685 /* NOTE: symbols are accepted */
7686 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
7687 error("initializer element is not constant");
7695 /* XXX: not portable */
7696 /* XXX: generate error if incorrect relocation */
7697 gen_assign_cast(type
);
7698 bt
= type
->t
& VT_BTYPE
;
7699 ptr
= sec
->data
+ c
;
7700 /* XXX: make code faster ? */
7701 if (!(type
->t
& VT_BITFIELD
)) {
7706 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
7707 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
7708 bit_mask
= (1LL << bit_size
) - 1;
7710 if ((vtop
->r
& VT_SYM
) &&
7716 (bt
== VT_INT
&& bit_size
!= 32)))
7717 error("initializer element is not computable at load time");
7720 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
7723 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
7726 *(double *)ptr
= vtop
->c
.d
;
7729 *(long double *)ptr
= vtop
->c
.ld
;
7732 *(long long *)ptr
|= (vtop
->c
.ll
& bit_mask
) << bit_pos
;
7735 if (vtop
->r
& VT_SYM
) {
7736 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
7738 *(int *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
7743 vset(type
, VT_LOCAL
, c
);
7750 /* put zeros for variable based init */
7751 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
7756 /* nothing to do because globals are already set to zero */
7758 gfunc_start(&gf
, FUNC_CDECL
);
7765 vpush_global_sym(&func_old_type
, TOK_memset
);
7770 /* 't' contains the type and storage info. 'c' is the offset of the
7771 object in section 'sec'. If 'sec' is NULL, it means stack based
7772 allocation. 'first' is true if array '{' must be read (multi
7773 dimension implicit array init handling). 'size_only' is true if
7774 size only evaluation is wanted (only for arrays). */
7775 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
7776 int first
, int size_only
)
7778 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
7779 int size1
, align1
, expr_type
;
7783 if (type
->t
& VT_ARRAY
) {
7787 t1
= pointed_type(type
);
7788 size1
= type_size(t1
, &align1
);
7791 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
7797 /* only parse strings here if correct type (otherwise: handle
7798 them as ((w)char *) expressions */
7799 if ((tok
== TOK_LSTR
&&
7800 (t1
->t
& VT_BTYPE
) == VT_INT
) ||
7802 (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
7803 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
7808 /* compute maximum number of chars wanted */
7810 cstr_len
= cstr
->size
;
7812 cstr_len
= cstr
->size
/ sizeof(int);
7815 if (n
>= 0 && nb
> (n
- array_length
))
7816 nb
= n
- array_length
;
7819 warning("initializer-string for array is too long");
7820 /* in order to go faster for common case (char
7821 string in global variable, we handle it
7823 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
7824 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
7828 ch
= ((unsigned char *)cstr
->data
)[i
];
7830 ch
= ((int *)cstr
->data
)[i
];
7831 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
7839 /* only add trailing zero if enough storage (no
7840 warning in this case since it is standard) */
7841 if (n
< 0 || array_length
< n
) {
7843 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
7849 while (tok
!= '}') {
7850 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
7851 if (n
>= 0 && index
>= n
)
7852 error("index too large");
7853 /* must put zero in holes (note that doing it that way
7854 ensures that it even works with designators) */
7855 if (!size_only
&& array_length
< index
) {
7856 init_putz(t1
, sec
, c
+ array_length
* size1
,
7857 (index
- array_length
) * size1
);
7860 if (index
> array_length
)
7861 array_length
= index
;
7862 /* special test for multi dimensional arrays (may not
7863 be strictly correct if designators are used at the
7865 if (index
>= n
&& no_oblock
)
7874 /* put zeros at the end */
7875 if (!size_only
&& n
>= 0 && array_length
< n
) {
7876 init_putz(t1
, sec
, c
+ array_length
* size1
,
7877 (n
- array_length
) * size1
);
7879 /* patch type size if needed */
7881 s
->c
= array_length
;
7882 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
7883 (sec
|| !first
|| tok
== '{')) {
7886 /* NOTE: the previous test is a specific case for automatic
7887 struct/union init */
7888 /* XXX: union needs only one init */
7890 /* XXX: this test is incorrect for local initializers
7891 beginning with ( without {. It would be much more difficult
7892 to do it correctly (ideally, the expression parser should
7893 be used in all cases) */
7899 while (tok
== '(') {
7903 if (!parse_btype(&type1
, &ad1
))
7905 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
7906 if (!is_compatible_types(type
, &type1
))
7907 error("invalid type for cast");
7911 if (first
|| tok
== '{') {
7920 while (tok
!= '}') {
7921 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
7923 if (!size_only
&& array_length
< index
) {
7924 init_putz(type
, sec
, c
+ array_length
,
7925 index
- array_length
);
7927 index
= index
+ type_size(&f
->type
, &align1
);
7928 if (index
> array_length
)
7929 array_length
= index
;
7931 if (no_oblock
&& f
== NULL
)
7937 /* put zeros at the end */
7938 if (!size_only
&& array_length
< n
) {
7939 init_putz(type
, sec
, c
+ array_length
,
7948 } else if (tok
== '{') {
7950 decl_initializer(type
, sec
, c
, first
, size_only
);
7952 } else if (size_only
) {
7953 /* just skip expression */
7955 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
7959 else if (tok
== ')')
7964 /* currently, we always use constant expression for globals
7965 (may change for scripting case) */
7966 expr_type
= EXPR_CONST
;
7968 expr_type
= EXPR_ANY
;
7969 init_putv(type
, sec
, c
, 0, expr_type
);
7973 /* parse an initializer for type 't' if 'has_init' is non zero, and
7974 allocate space in local or global data space ('r' is either
7975 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7976 variable 'v' of scope 'scope' is declared before initializers are
7977 parsed. If 'v' is zero, then a reference to the new object is put
7978 in the value stack. If 'has_init' is 2, a special parsing is done
7979 to handle string constants. */
7980 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
7981 int has_init
, int v
, int scope
)
7983 int size
, align
, addr
, data_offset
;
7985 ParseState saved_parse_state
;
7986 TokenString init_str
;
7989 size
= type_size(type
, &align
);
7990 /* If unknown size, we must evaluate it before
7991 evaluating initializers because
7992 initializers can generate global data too
7993 (e.g. string pointers or ISOC99 compound
7994 literals). It also simplifies local
7995 initializers handling */
7996 tok_str_new(&init_str
);
7999 error("unknown type size");
8000 /* get all init string */
8001 if (has_init
== 2) {
8002 /* only get strings */
8003 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8004 tok_str_add_tok(&init_str
);
8009 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
8011 error("unexpected end of file in initializer");
8012 tok_str_add_tok(&init_str
);
8015 else if (tok
== '}') {
8023 tok_str_add(&init_str
, -1);
8024 tok_str_add(&init_str
, 0);
8027 save_parse_state(&saved_parse_state
);
8029 macro_ptr
= init_str
.str
;
8031 decl_initializer(type
, NULL
, 0, 1, 1);
8032 /* prepare second initializer parsing */
8033 macro_ptr
= init_str
.str
;
8036 /* if still unknown size, error */
8037 size
= type_size(type
, &align
);
8039 error("unknown type size");
8041 /* take into account specified alignment if bigger */
8042 if (ad
->aligned
> align
)
8043 align
= ad
->aligned
;
8044 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
8046 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
8048 loc
= (loc
- size
) & -align
;
8050 /* handles bounds */
8051 /* XXX: currently, since we do only one pass, we cannot track
8052 '&' operators, so we add only arrays */
8053 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
8054 unsigned long *bounds_ptr
;
8055 /* add padding between regions */
8057 /* then add local bound info */
8058 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
8059 bounds_ptr
[0] = addr
;
8060 bounds_ptr
[1] = size
;
8063 /* local variable */
8064 sym_push(v
, type
, r
, addr
);
8066 /* push local reference */
8067 vset(type
, r
, addr
);
8073 if (v
&& scope
== VT_CONST
) {
8074 /* see if the symbol was already defined */
8077 if (!is_compatible_types(&sym
->type
, type
))
8078 error("incompatible types for redefinition of '%s'",
8079 get_tok_str(v
, NULL
));
8080 if (sym
->type
.t
& VT_EXTERN
) {
8081 /* if the variable is extern, it was not allocated */
8082 sym
->type
.t
&= ~VT_EXTERN
;
8084 /* we accept several definitions of the same
8085 global variable. this is tricky, because we
8086 must play with the SHN_COMMON type of the symbol */
8087 /* XXX: should check if the variable was already
8088 initialized. It is incorrect to initialized it
8090 /* no init data, we won't add more to the symbol */
8097 /* allocate symbol in corresponding section */
8104 data_offset
= sec
->data_offset
;
8105 data_offset
= (data_offset
+ align
- 1) & -align
;
8107 /* very important to increment global pointer at this time
8108 because initializers themselves can create new initializers */
8109 data_offset
+= size
;
8110 /* add padding if bound check */
8111 if (do_bounds_check
)
8113 sec
->data_offset
= data_offset
;
8114 /* allocate section space to put the data */
8115 if (sec
->sh_type
!= SHT_NOBITS
&&
8116 data_offset
> sec
->data_allocated
)
8117 section_realloc(sec
, data_offset
);
8119 addr
= 0; /* avoid warning */
8123 if (scope
== VT_CONST
) {
8128 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
8130 /* update symbol definition */
8132 put_extern_sym(sym
, sec
, addr
, size
);
8135 /* put a common area */
8136 put_extern_sym(sym
, NULL
, align
, size
);
8137 /* XXX: find a nicer way */
8138 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
8139 esym
->st_shndx
= SHN_COMMON
;
8144 /* push global reference */
8145 sym
= get_sym_ref(type
, sec
, addr
, size
);
8147 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
8151 /* handles bounds now because the symbol must be defined
8152 before for the relocation */
8153 if (do_bounds_check
) {
8154 unsigned long *bounds_ptr
;
8156 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
8157 /* then add global bound info */
8158 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
8159 bounds_ptr
[0] = 0; /* relocated */
8160 bounds_ptr
[1] = size
;
8164 decl_initializer(type
, sec
, addr
, 1, 0);
8165 /* restore parse state if needed */
8167 tok_str_free(init_str
.str
);
8168 restore_parse_state(&saved_parse_state
);
8174 void put_func_debug(Sym
*sym
)
8179 /* XXX: we put here a dummy type */
8180 snprintf(buf
, sizeof(buf
), "%s:%c1",
8181 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
8182 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
8183 cur_text_section
, sym
->c
);
8188 /* not finished : try to put some local vars in registers */
8189 //#define CONFIG_REG_VARS
8191 #ifdef CONFIG_REG_VARS
8192 void add_var_ref(int t
)
8194 printf("%s:%d: &%s\n",
8195 file
->filename
, file
->line_num
,
8196 get_tok_str(t
, NULL
));
8199 /* first pass on a function with heuristic to extract variable usage
8200 and pointer references to local variables for register allocation */
8201 void analyse_function(void)
8208 /* any symbol coming after '&' is considered as being a
8209 variable whose reference is taken. It is highly unaccurate
8210 but it is difficult to do better without a complete parse */
8213 /* if '& number', then no need to examine next tokens */
8214 if (tok
== TOK_CINT
||
8216 tok
== TOK_CLLONG
||
8217 tok
== TOK_CULLONG
) {
8219 } else if (tok
>= TOK_UIDENT
) {
8220 /* if '& ident [' or '& ident ->', then ident address
8224 if (tok
!= '[' && tok
!= TOK_ARROW
)
8228 while (tok
!= '}' && tok
!= ';' &&
8229 !((tok
== ',' || tok
== ')') && level
== 0)) {
8230 if (tok
>= TOK_UIDENT
) {
8232 } else if (tok
== '(') {
8234 } else if (tok
== ')') {
8247 /* parse an old style function declaration list */
8248 /* XXX: check multiple parameter */
8249 static void func_decl_list(Sym
*func_sym
)
8256 /* parse each declaration */
8257 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
) {
8258 if (!parse_btype(&btype
, &ad
))
8259 expect("declaration list");
8260 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
8261 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
8263 /* we accept no variable after */
8267 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8268 /* find parameter in function parameter list */
8271 if ((s
->v
& ~SYM_FIELD
) == v
)
8275 error("declaration for parameter '%s' but no such parameter",
8276 get_tok_str(v
, NULL
));
8278 /* check that no storage specifier except 'register' was given */
8279 if (type
.t
& VT_STORAGE
)
8280 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
8281 convert_parameter_type(&type
);
8282 /* we can add the type (NOTE: it could be local to the function) */
8284 /* accept other parameters */
8295 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
8296 static void decl(int l
)
8304 if (!parse_btype(&btype
, &ad
)) {
8305 /* skip redundant ';' */
8306 /* XXX: find more elegant solution */
8311 /* special test for old K&R protos without explicit int
8312 type. Only accepted when defining global data */
8313 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
8317 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
8318 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
8320 /* we accept no variable after */
8324 while (1) { /* iterate thru each declaration */
8326 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8330 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
8331 printf("type = '%s'\n", buf
);
8334 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8335 /* if old style function prototype, we accept a
8338 if (sym
->c
== FUNC_OLD
)
8339 func_decl_list(sym
);
8343 #ifdef CONFIG_REG_VARS
8344 TokenString func_str
;
8345 ParseState saved_parse_state
;
8350 error("cannot use local functions");
8351 if (!(type
.t
& VT_FUNC
))
8352 expect("function definition");
8353 /* XXX: cannot do better now: convert extern line to static inline */
8354 if ((type
.t
& (VT_EXTERN
| VT_INLINE
)) == (VT_EXTERN
| VT_INLINE
))
8355 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
8357 #ifdef CONFIG_REG_VARS
8358 /* parse all function code and record it */
8360 tok_str_new(&func_str
);
8366 error("unexpected end of file");
8367 tok_str_add_tok(&func_str
);
8372 } else if (t
== '}') {
8374 if (block_level
== 0)
8378 tok_str_add(&func_str
, -1);
8379 tok_str_add(&func_str
, 0);
8381 save_parse_state(&saved_parse_state
);
8383 macro_ptr
= func_str
.str
;
8388 /* compute text section */
8389 cur_text_section
= ad
.section
;
8390 if (!cur_text_section
)
8391 cur_text_section
= text_section
;
8392 ind
= cur_text_section
->data_offset
;
8393 funcname
= get_tok_str(v
, NULL
);
8396 /* if symbol is already defined, then put complete type */
8399 /* put function symbol */
8400 sym
= global_identifier_push(v
, type
.t
, 0);
8401 sym
->type
.ref
= type
.ref
;
8403 /* NOTE: we patch the symbol size later */
8404 put_extern_sym(sym
, cur_text_section
, ind
, 0);
8406 sym
->r
= VT_SYM
| VT_CONST
;
8407 /* put debug symbol */
8409 put_func_debug(sym
);
8410 /* push a dummy symbol to enable local sym storage */
8411 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
8412 gfunc_prolog(&type
);
8415 #ifdef CONFIG_REG_VARS
8416 macro_ptr
= func_str
.str
;
8419 block(NULL
, NULL
, NULL
, NULL
, 0, 0);
8422 cur_text_section
->data_offset
= ind
;
8423 label_pop(&global_label_stack
, NULL
);
8424 sym_pop(&local_stack
, NULL
); /* reset local stack */
8425 /* end of function */
8426 /* patch symbol size */
8427 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
8430 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
8432 funcname
= ""; /* for safety */
8433 func_vt
.t
= VT_VOID
; /* for safety */
8434 ind
= 0; /* for safety */
8436 #ifdef CONFIG_REG_VARS
8437 tok_str_free(func_str
.str
);
8438 restore_parse_state(&saved_parse_state
);
8442 if (btype
.t
& VT_TYPEDEF
) {
8443 /* save typedefed type */
8444 /* XXX: test storage specifiers ? */
8445 sym
= sym_push(v
, &type
, 0, 0);
8446 sym
->type
.t
|= VT_TYPEDEF
;
8447 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8448 /* external function definition */
8449 external_sym(v
, &type
, 0);
8451 /* not lvalue if array */
8453 if (!(type
.t
& VT_ARRAY
))
8454 r
|= lvalue_type(type
.t
);
8455 has_init
= (tok
== '=');
8456 if ((btype
.t
& VT_EXTERN
) ||
8457 ((type
.t
& VT_ARRAY
) && (type
.t
& VT_STATIC
) &&
8458 !has_init
&& l
== VT_CONST
&& type
.ref
->c
< 0)) {
8459 /* external variable */
8460 /* NOTE: as GCC, uninitialized global static
8461 arrays of null size are considered as
8463 external_sym(v
, &type
, r
);
8465 if (type
.t
& VT_STATIC
)
8471 decl_initializer_alloc(&type
, &ad
, r
,
8485 /* better than nothing, but needs extension to handle '-E' option
8487 static void preprocess_init(TCCState
*s1
)
8489 s1
->include_stack_ptr
= s1
->include_stack
;
8490 /* XXX: move that before to avoid having to initialize
8491 file->ifdef_stack_ptr ? */
8492 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
8493 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
8495 /* XXX: not ANSI compliant: bound checking says error */
8499 /* compile the C file opened in 'file'. Return non zero if errors. */
8500 static int tcc_compile(TCCState
*s1
)
8504 volatile int section_sym
;
8507 printf("%s: **** new file\n", file
->filename
);
8509 preprocess_init(s1
);
8512 anon_sym
= SYM_FIRST_ANOM
;
8514 /* file info: full path + filename */
8515 section_sym
= 0; /* avoid warning */
8517 section_sym
= put_elf_sym(symtab_section
, 0, 0,
8518 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
8519 text_section
->sh_num
, NULL
);
8520 getcwd(buf
, sizeof(buf
));
8521 pstrcat(buf
, sizeof(buf
), "/");
8522 put_stabs_r(buf
, N_SO
, 0, 0,
8523 text_section
->data_offset
, text_section
, section_sym
);
8524 put_stabs_r(file
->filename
, N_SO
, 0, 0,
8525 text_section
->data_offset
, text_section
, section_sym
);
8527 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8528 symbols can be safely used */
8529 put_elf_sym(symtab_section
, 0, 0,
8530 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
8531 SHN_ABS
, file
->filename
);
8533 /* define some often used types */
8534 int_type
.t
= VT_INT
;
8536 char_pointer_type
.t
= VT_BYTE
;
8537 mk_pointer(&char_pointer_type
);
8539 func_old_type
.t
= VT_FUNC
;
8540 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
8543 /* define 'void *alloca(unsigned int)' builtin function */
8548 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
8549 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
8552 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
8556 define_start
= define_stack
;
8558 if (setjmp(s1
->error_jmp_buf
) == 0) {
8560 s1
->error_set_jmp_enabled
= 1;
8562 ch
= file
->buf_ptr
[0];
8563 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
8564 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
;
8568 expect("declaration");
8570 /* end of translation unit info */
8572 put_stabs_r(NULL
, N_SO
, 0, 0,
8573 text_section
->data_offset
, text_section
, section_sym
);
8576 s1
->error_set_jmp_enabled
= 0;
8578 /* reset define stack, but leave -Dsymbols (may be incorrect if
8579 they are undefined) */
8580 free_defines(define_start
);
8582 sym_pop(&global_stack
, NULL
);
8584 return s1
->nb_errors
!= 0 ? -1 : 0;
8588 int tcc_compile_string(TCCState
*s
, const char *str
)
8590 BufferedFile bf1
, *bf
= &bf1
;
8594 /* init file structure */
8596 /* XXX: avoid copying */
8598 buf
= tcc_malloc(len
+ 1);
8601 memcpy(buf
, str
, len
);
8604 bf
->buf_end
= buf
+ len
;
8605 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
8609 ret
= tcc_compile(s
);
8613 /* currently, no need to close */
8618 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8619 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
8621 BufferedFile bf1
, *bf
= &bf1
;
8623 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
8624 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
8628 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
8630 /* init file structure */
8632 bf
->buf_ptr
= bf
->buffer
;
8633 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
8634 *bf
->buf_end
= CH_EOB
;
8635 bf
->filename
[0] = '\0';
8639 s1
->include_stack_ptr
= s1
->include_stack
;
8641 /* parse with define parser */
8642 ch
= file
->buf_ptr
[0];
8648 /* undefine a preprocessor symbol */
8649 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
8653 ts
= tok_alloc(sym
, strlen(sym
));
8654 s
= define_find(ts
->tok
);
8655 /* undefine symbol by putting an invalid name */
8660 #ifdef CONFIG_TCC_ASM
8662 #include "i386-asm.c"
8666 static void asm_instr(void)
8668 error("inline asm() not supported");
8674 /* print the position in the source file of PC value 'pc' by reading
8675 the stabs debug information */
8676 static void rt_printline(unsigned long wanted_pc
)
8678 Stab_Sym
*sym
, *sym_end
;
8679 char func_name
[128], last_func_name
[128];
8680 unsigned long func_addr
, last_pc
, pc
;
8681 const char *incl_files
[INCLUDE_STACK_SIZE
];
8682 int incl_index
, len
, last_line_num
, i
;
8683 const char *str
, *p
;
8685 fprintf(stderr
, "0x%08lx:", wanted_pc
);
8687 func_name
[0] = '\0';
8690 last_func_name
[0] = '\0';
8691 last_pc
= 0xffffffff;
8693 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
8694 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
8695 while (sym
< sym_end
) {
8696 switch(sym
->n_type
) {
8697 /* function start or end */
8699 if (sym
->n_strx
== 0) {
8700 /* we test if between last line and end of function */
8701 pc
= sym
->n_value
+ func_addr
;
8702 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
8704 func_name
[0] = '\0';
8707 str
= stabstr_section
->data
+ sym
->n_strx
;
8708 p
= strchr(str
, ':');
8710 pstrcpy(func_name
, sizeof(func_name
), str
);
8713 if (len
> sizeof(func_name
) - 1)
8714 len
= sizeof(func_name
) - 1;
8715 memcpy(func_name
, str
, len
);
8716 func_name
[len
] = '\0';
8718 func_addr
= sym
->n_value
;
8721 /* line number info */
8723 pc
= sym
->n_value
+ func_addr
;
8724 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
8727 last_line_num
= sym
->n_desc
;
8729 strcpy(last_func_name
, func_name
);
8733 str
= stabstr_section
->data
+ sym
->n_strx
;
8735 if (incl_index
< INCLUDE_STACK_SIZE
) {
8736 incl_files
[incl_index
++] = str
;
8744 if (sym
->n_strx
== 0) {
8745 incl_index
= 0; /* end of translation unit */
8747 str
= stabstr_section
->data
+ sym
->n_strx
;
8748 /* do not add path */
8750 if (len
> 0 && str
[len
- 1] != '/')
8758 /* second pass: we try symtab symbols (no line number info) */
8761 Elf32_Sym
*sym
, *sym_end
;
8764 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
8765 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
8768 type
= ELF32_ST_TYPE(sym
->st_info
);
8769 if (type
== STT_FUNC
) {
8770 if (wanted_pc
>= sym
->st_value
&&
8771 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
8772 pstrcpy(last_func_name
, sizeof(last_func_name
),
8773 strtab_section
->data
+ sym
->st_name
);
8779 /* did not find any info: */
8780 fprintf(stderr
, " ???\n");
8783 if (last_func_name
[0] != '\0') {
8784 fprintf(stderr
, " %s()", last_func_name
);
8786 if (incl_index
> 0) {
8787 fprintf(stderr
, " (%s:%d",
8788 incl_files
[incl_index
- 1], last_line_num
);
8789 for(i
= incl_index
- 2; i
>= 0; i
--)
8790 fprintf(stderr
, ", included from %s", incl_files
[i
]);
8791 fprintf(stderr
, ")");
8793 fprintf(stderr
, "\n");
8800 /* fix for glibc 2.1 */
8806 /* return the PC at frame level 'level'. Return non zero if not found */
8807 static int rt_get_caller_pc(unsigned long *paddr
,
8808 ucontext_t
*uc
, int level
)
8815 *paddr
= uc
->uc_mcontext
.mc_eip
;
8817 *paddr
= uc
->uc_mcontext
.gregs
[REG_EIP
];
8822 fp
= uc
->uc_mcontext
.mc_ebp
;
8824 fp
= uc
->uc_mcontext
.gregs
[REG_EBP
];
8826 for(i
=1;i
<level
;i
++) {
8827 /* XXX: check address validity with program info */
8828 if (fp
<= 0x1000 || fp
>= 0xc0000000)
8830 fp
= ((unsigned long *)fp
)[0];
8832 *paddr
= ((unsigned long *)fp
)[1];
8837 #error add arch specific rt_get_caller_pc()
8840 /* emit a run time error at position 'pc' */
8841 void rt_error(ucontext_t
*uc
, const char *fmt
, ...)
8848 fprintf(stderr
, "Runtime error: ");
8849 vfprintf(stderr
, fmt
, ap
);
8850 fprintf(stderr
, "\n");
8851 for(i
=0;i
<num_callers
;i
++) {
8852 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
8855 fprintf(stderr
, "at ");
8857 fprintf(stderr
, "by ");
8864 /* signal handler for fatal errors */
8865 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
8867 ucontext_t
*uc
= puc
;
8871 switch(siginf
->si_code
) {
8874 rt_error(uc
, "division by zero");
8877 rt_error(uc
, "floating point exception");
8883 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
8884 rt_error(uc
, *rt_bound_error_msg
);
8886 rt_error(uc
, "dereferencing invalid pointer");
8889 rt_error(uc
, "illegal instruction");
8892 rt_error(uc
, "abort() called");
8895 rt_error(uc
, "caught signal %d", signum
);
8902 /* do all relocations (needed before using tcc_get_symbol()) */
8903 int tcc_relocate(TCCState
*s1
)
8910 tcc_add_runtime(s1
);
8912 relocate_common_syms();
8914 /* compute relocation address : section are relocated in place. We
8915 also alloc the bss space */
8916 for(i
= 1; i
< s1
->nb_sections
; i
++) {
8917 s
= s1
->sections
[i
];
8918 if (s
->sh_flags
& SHF_ALLOC
) {
8919 if (s
->sh_type
== SHT_NOBITS
)
8920 s
->data
= tcc_mallocz(s
->data_offset
);
8921 s
->sh_addr
= (unsigned long)s
->data
;
8925 relocate_syms(s1
, 1);
8927 if (s1
->nb_errors
!= 0)
8930 /* relocate each section */
8931 for(i
= 1; i
< s1
->nb_sections
; i
++) {
8932 s
= s1
->sections
[i
];
8934 relocate_section(s1
, s
);
8939 /* launch the compiled program with the given arguments */
8940 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
8942 int (*prog_main
)(int, char **);
8944 if (tcc_relocate(s1
) < 0)
8947 prog_main
= tcc_get_symbol(s1
, "main");
8951 error("debug mode currently not available for Windows");
8953 struct sigaction sigact
;
8954 /* install TCC signal handlers to print debug info on fatal
8956 sigact
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
8957 sigact
.sa_sigaction
= sig_error
;
8958 sigemptyset(&sigact
.sa_mask
);
8959 sigaction(SIGFPE
, &sigact
, NULL
);
8960 sigaction(SIGILL
, &sigact
, NULL
);
8961 sigaction(SIGSEGV
, &sigact
, NULL
);
8962 sigaction(SIGBUS
, &sigact
, NULL
);
8963 sigaction(SIGABRT
, &sigact
, NULL
);
8967 #ifdef CONFIG_TCC_BCHECK
8968 if (do_bounds_check
) {
8969 void (*bound_init
)(void);
8971 /* set error function */
8972 rt_bound_error_msg
= (void *)tcc_get_symbol(s1
, "__bound_error_msg");
8974 /* XXX: use .init section so that it also work in binary ? */
8975 bound_init
= (void *)tcc_get_symbol(s1
, "__bound_init");
8979 return (*prog_main
)(argc
, argv
);
8982 TCCState
*tcc_new(void)
8989 s
= tcc_mallocz(sizeof(TCCState
));
8993 s
->output_type
= TCC_OUTPUT_MEMORY
;
8995 /* init isid table */
8997 isidnum_table
[i
] = isid(i
) || isnum(i
);
8999 /* add all tokens */
9001 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
9003 tok_ident
= TOK_IDENT
;
9012 ts
= tok_alloc(p
, r
- p
- 1);
9016 /* we add dummy defines for some special macros to speed up tests
9017 and to have working defined() */
9018 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
9019 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
9020 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
9021 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
9023 /* standard defines */
9024 tcc_define_symbol(s
, "__STDC__", NULL
);
9025 #if defined(TCC_TARGET_I386)
9026 tcc_define_symbol(s
, "__i386__", NULL
);
9029 tcc_define_symbol(s
, "__linux__", NULL
);
9030 tcc_define_symbol(s
, "linux", NULL
);
9032 /* tiny C specific defines */
9033 tcc_define_symbol(s
, "__TINYC__", NULL
);
9035 /* tiny C & gcc defines */
9036 tcc_define_symbol(s
, "__SIZE_TYPE__", "unsigned int");
9037 tcc_define_symbol(s
, "__PTRDIFF_TYPE__", "int");
9038 tcc_define_symbol(s
, "__WCHAR_TYPE__", "int");
9040 /* default library paths */
9041 tcc_add_library_path(s
, "/usr/local/lib");
9042 tcc_add_library_path(s
, "/usr/lib");
9043 tcc_add_library_path(s
, "/lib");
9045 /* no section zero */
9046 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
9048 /* create standard sections */
9049 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
9050 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
9051 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
9053 /* symbols are always generated for linking stage */
9054 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
9056 ".hashtab", SHF_PRIVATE
);
9057 strtab_section
= symtab_section
->link
;
9059 /* private symbol table for dynamic symbols */
9060 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
9062 ".dynhashtab", SHF_PRIVATE
);
9066 void tcc_delete(TCCState
*s1
)
9070 /* free -D defines */
9074 n
= tok_ident
- TOK_IDENT
;
9075 for(i
= 0; i
< n
; i
++)
9076 tcc_free(table_ident
[i
]);
9077 tcc_free(table_ident
);
9079 /* free all sections */
9081 free_section(symtab_section
->hash
);
9083 free_section(s1
->dynsymtab_section
->hash
);
9084 free_section(s1
->dynsymtab_section
->link
);
9085 free_section(s1
->dynsymtab_section
);
9087 for(i
= 1; i
< s1
->nb_sections
; i
++)
9088 free_section(s1
->sections
[i
]);
9089 tcc_free(s1
->sections
);
9091 /* free loaded dlls array */
9092 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
9093 tcc_free(s1
->loaded_dlls
[i
]);
9094 tcc_free(s1
->loaded_dlls
);
9097 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
9098 tcc_free(s1
->library_paths
[i
]);
9099 tcc_free(s1
->library_paths
);
9101 /* cached includes */
9102 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
9103 tcc_free(s1
->cached_includes
[i
]);
9104 tcc_free(s1
->cached_includes
);
9106 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
9107 tcc_free(s1
->include_paths
[i
]);
9108 tcc_free(s1
->include_paths
);
9110 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
9111 tcc_free(s1
->sysinclude_paths
[i
]);
9112 tcc_free(s1
->sysinclude_paths
);
9117 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
9121 pathname1
= tcc_strdup(pathname
);
9122 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
9126 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
9130 pathname1
= tcc_strdup(pathname
);
9131 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
9135 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
9137 const char *ext
, *filename1
;
9140 BufferedFile
*saved_file
;
9142 /* find source file type with extension */
9143 filename1
= strrchr(filename
, '/');
9147 filename1
= filename
;
9148 ext
= strrchr(filename1
, '.');
9154 file
= tcc_open(s1
, filename
);
9156 if (flags
& AFF_PRINT_ERROR
) {
9157 error_noabort("file '%s' not found", filename
);
9163 if (!ext
|| !strcmp(ext
, "c")) {
9164 /* C file assumed */
9165 ret
= tcc_compile(s1
);
9167 #ifdef CONFIG_TCC_ASM
9168 if (!strcmp(ext
, "S")) {
9169 /* preprocessed assembler */
9170 ret
= tcc_assemble(s1
, 1);
9171 } else if (!strcmp(ext
, "s")) {
9172 /* non preprocessed assembler */
9173 ret
= tcc_assemble(s1
, 0);
9178 /* assume executable format: auto guess file type */
9179 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
)) {
9180 error_noabort("could not read header");
9183 lseek(fd
, 0, SEEK_SET
);
9185 if (ehdr
.e_ident
[0] == ELFMAG0
&&
9186 ehdr
.e_ident
[1] == ELFMAG1
&&
9187 ehdr
.e_ident
[2] == ELFMAG2
&&
9188 ehdr
.e_ident
[3] == ELFMAG3
) {
9189 file
->line_num
= 0; /* do not display line number if error */
9190 if (ehdr
.e_type
== ET_REL
) {
9191 ret
= tcc_load_object_file(s1
, fd
, 0);
9192 } else if (ehdr
.e_type
== ET_DYN
) {
9193 ret
= tcc_load_dll(s1
, fd
, filename
,
9194 (flags
& AFF_REFERENCED_DLL
) != 0);
9196 error_noabort("unrecognized ELF file");
9199 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
9200 file
->line_num
= 0; /* do not display line number if error */
9201 ret
= tcc_load_archive(s1
, fd
);
9203 /* as GNU ld, consider it is an ld script if not recognized */
9204 ret
= tcc_load_ldscript(s1
);
9206 error_noabort("unrecognized file type");
9221 int tcc_add_file(TCCState
*s
, const char *filename
)
9223 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
9226 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
9230 pathname1
= tcc_strdup(pathname
);
9231 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
9235 /* find and load a dll. Return non zero if not found */
9236 /* XXX: add '-rpath' option support ? */
9237 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
9242 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
9243 snprintf(buf
, sizeof(buf
), "%s/%s",
9244 s
->library_paths
[i
], filename
);
9245 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
9251 /* the library name is the same as the argument of the '-l' option */
9252 int tcc_add_library(TCCState
*s
, const char *libraryname
)
9258 /* first we look for the dynamic library if not static linking */
9259 if (!s
->static_link
) {
9260 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
9261 /* if we output to memory, then we simply we dlopen(). */
9262 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
9263 /* Since the libc is already loaded, we don't need to load it again */
9264 if (!strcmp(libraryname
, "c"))
9266 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
9270 if (tcc_add_dll(s
, buf
, 0) == 0)
9275 /* then we look for the static library */
9276 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
9277 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
9278 s
->library_paths
[i
], libraryname
);
9279 if (tcc_add_file_internal(s
, buf
, 0) == 0)
9285 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
9287 add_elf_sym(symtab_section
, val
, 0,
9288 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
9293 int tcc_set_output_type(TCCState
*s
, int output_type
)
9297 s
->output_type
= output_type
;
9300 /* default include paths */
9301 /* XXX: reverse order needed if -isystem support */
9302 tcc_add_sysinclude_path(s
, "/usr/local/include");
9303 tcc_add_sysinclude_path(s
, "/usr/include");
9304 snprintf(buf
, sizeof(buf
), "%s/include", tcc_lib_path
);
9305 tcc_add_sysinclude_path(s
, buf
);
9308 /* if bound checking, then add corresponding sections */
9309 #ifdef CONFIG_TCC_BCHECK
9310 if (do_bounds_check
) {
9312 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
9313 /* create bounds sections */
9314 bounds_section
= new_section(s
, ".bounds",
9315 SHT_PROGBITS
, SHF_ALLOC
);
9316 lbounds_section
= new_section(s
, ".lbounds",
9317 SHT_PROGBITS
, SHF_ALLOC
);
9321 /* add debug sections */
9324 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
9325 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
9326 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
9327 put_elf_str(stabstr_section
, "");
9328 stab_section
->link
= stabstr_section
;
9329 /* put first entry */
9330 put_stabs("", 0, 0, 0, 0);
9333 /* add libc crt1/crti objects */
9334 if (output_type
== TCC_OUTPUT_EXE
||
9335 output_type
== TCC_OUTPUT_DLL
) {
9336 if (output_type
!= TCC_OUTPUT_DLL
)
9337 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
9338 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
9343 #if !defined(LIBTCC)
9345 static int64_t getclock_us(void)
9350 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
9353 gettimeofday(&tv
, NULL
);
9354 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
9360 printf("tcc version 0.9.16 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
9361 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
9362 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
9363 " [--] infile1 [infile2... --] [infile_args...]\n"
9365 "General options:\n"
9366 " -c compile only - generate an object file\n"
9367 " -o outfile set output filename\n"
9368 " -- allows multiples input files if no -o option given. Also\n"
9369 " separate input files from runtime arguments\n"
9370 " -Bdir set tcc internal library path\n"
9371 " -bench output compilation statistics\n"
9372 "Preprocessor options:\n"
9373 " -Idir add include path 'dir'\n"
9374 " -Dsym[=val] define 'sym' with value 'val'\n"
9375 " -Usym undefine 'sym'\n"
9377 " -Ldir add library path 'dir'\n"
9378 " -llib link with dynamic or static library 'lib'\n"
9379 " -shared generate a shared library\n"
9380 " -static static linking\n"
9381 " -r relocatable output\n"
9382 "Debugger options:\n"
9383 " -g generate runtime debug info\n"
9384 #ifdef CONFIG_TCC_BCHECK
9385 " -b compile with built-in memory and bounds checker (implies -g)\n"
9387 " -bt N show N callers in stack traces\n"
9391 #define TCC_OPTION_HAS_ARG 0x0001
9392 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
9394 typedef struct TCCOption
{
9422 TCC_OPTION_nostdinc
,
9423 TCC_OPTION_print_search_dirs
,
9424 TCC_OPTION_rdynamic
,
9427 static const TCCOption tcc_options
[] = {
9428 { "h", TCC_OPTION_HELP
, 0 },
9429 { "?", TCC_OPTION_HELP
, 0 },
9430 { "-", TCC_OPTION_MARKER
, 0 },
9431 { "I", TCC_OPTION_I
, TCC_OPTION_HAS_ARG
},
9432 { "D", TCC_OPTION_D
, TCC_OPTION_HAS_ARG
},
9433 { "U", TCC_OPTION_U
, TCC_OPTION_HAS_ARG
},
9434 { "L", TCC_OPTION_L
, TCC_OPTION_HAS_ARG
},
9435 { "B", TCC_OPTION_B
, TCC_OPTION_HAS_ARG
},
9436 { "l", TCC_OPTION_l
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9437 { "bench", TCC_OPTION_bench
, 0 },
9438 { "bt", TCC_OPTION_bt
, TCC_OPTION_HAS_ARG
},
9439 #ifdef CONFIG_TCC_BCHECK
9440 { "b", TCC_OPTION_b
, 0 },
9442 { "g", TCC_OPTION_g
, 0 },
9443 { "c", TCC_OPTION_c
, 0 },
9444 { "static", TCC_OPTION_static
, 0 },
9445 { "shared", TCC_OPTION_shared
, 0 },
9446 { "o", TCC_OPTION_o
, TCC_OPTION_HAS_ARG
},
9447 { "rdynamic", TCC_OPTION_rdynamic
, 0 }, /* currently ignored */
9448 { "r", TCC_OPTION_r
, 0 },
9449 { "W", TCC_OPTION_W
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9450 { "O", TCC_OPTION_O
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9451 { "m", TCC_OPTION_m
, TCC_OPTION_HAS_ARG
},
9452 { "f", TCC_OPTION_f
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9453 { "nostdinc", TCC_OPTION_nostdinc
, 0 },
9454 { "print-search-dirs", TCC_OPTION_print_search_dirs
, 0 },
9458 int main(int argc
, char **argv
)
9461 int optind
, output_type
, multiple_files
, i
, reloc_output
;
9464 int nb_files
, nb_libraries
, nb_objfiles
, dminus
, ret
;
9465 char objfilename
[1024];
9466 int64_t start_time
= 0;
9467 const TCCOption
*popt
;
9468 const char *optarg
, *p1
, *r1
, *outfile
;
9469 int print_search_dirs
;
9472 output_type
= TCC_OUTPUT_MEMORY
;
9482 print_search_dirs
= 0;
9484 if (optind
>= argc
) {
9485 if (nb_files
== 0 && !print_search_dirs
)
9492 /* add a new file */
9493 dynarray_add((void ***)&files
, &nb_files
, r
);
9494 if (!multiple_files
) {
9496 /* argv[0] will be this file */
9500 /* find option in table (match only the first chars */
9505 error("invalid option -- '%s'", r
);
9518 if (popt
->flags
& TCC_OPTION_HAS_ARG
) {
9519 if (*r1
!= '\0' || (popt
->flags
& TCC_OPTION_NOSEP
)) {
9523 error("argument to '%s' is missing", r
);
9524 optarg
= argv
[optind
++];
9532 switch(popt
->index
) {
9533 case TCC_OPTION_HELP
:
9537 case TCC_OPTION_MARKER
:
9538 /* '--' enables multiple files input and also ends several
9540 if (dminus
&& multiple_files
) {
9541 optind
--; /* argv[0] will be '--' */
9547 if (tcc_add_include_path(s
, optarg
) < 0)
9548 error("too many include paths");
9553 sym
= (char *)optarg
;
9554 value
= strchr(sym
, '=');
9559 tcc_define_symbol(s
, sym
, value
);
9563 tcc_undefine_symbol(s
, optarg
);
9566 tcc_add_library_path(s
, optarg
);
9569 /* set tcc utilities path (mainly for tcc development) */
9570 tcc_lib_path
= optarg
;
9573 dynarray_add((void ***)&files
, &nb_files
, r
);
9576 case TCC_OPTION_bench
:
9580 num_callers
= atoi(optarg
);
9582 #ifdef CONFIG_TCC_BCHECK
9584 do_bounds_check
= 1;
9593 output_type
= TCC_OUTPUT_OBJ
;
9595 case TCC_OPTION_static
:
9598 case TCC_OPTION_shared
:
9599 output_type
= TCC_OUTPUT_DLL
;
9606 /* generate a .o merging several output files */
9608 output_type
= TCC_OUTPUT_OBJ
;
9610 case TCC_OPTION_nostdinc
:
9613 case TCC_OPTION_print_search_dirs
:
9614 print_search_dirs
= 1;
9622 if (print_search_dirs
) {
9623 /* enough for Linux kernel */
9624 printf("install: %s/\n", tcc_lib_path
);
9628 nb_objfiles
= nb_files
- nb_libraries
;
9630 /* if outfile provided without other options, we output an
9632 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
9633 output_type
= TCC_OUTPUT_EXE
;
9635 /* check -c consistency : only single file handled. XXX: checks file type */
9636 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
9637 /* accepts only a single input file */
9638 if (nb_objfiles
!= 1)
9639 error("cannot specify multiple files with -c");
9640 if (nb_libraries
!= 0)
9641 error("cannot specify libraries with -c");
9644 /* compute default outfile name */
9645 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
9646 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
9648 /* add .o extension */
9649 pstrcpy(objfilename
, sizeof(objfilename
) - 1, files
[0]);
9650 ext
= strrchr(objfilename
, '.');
9652 goto default_outfile
;
9653 strcpy(ext
+ 1, "o");
9656 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
9658 outfile
= objfilename
;
9662 start_time
= getclock_us();
9665 tcc_set_output_type(s
, output_type
);
9667 /* compile or add each files or library */
9668 for(i
= 0;i
< nb_files
; i
++) {
9669 const char *filename
;
9671 filename
= files
[i
];
9672 if (filename
[0] == '-') {
9673 if (tcc_add_library(s
, filename
+ 2) < 0)
9674 error("cannot find %s", filename
);
9676 if (tcc_add_file(s
, filename
) < 0) {
9683 /* free all files */
9688 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
9689 if (total_time
< 0.001)
9691 if (total_bytes
< 1)
9693 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
9694 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
9695 total_time
, (int)(total_lines
/ total_time
),
9696 total_bytes
/ total_time
/ 1000000.0);
9699 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
9700 tcc_output_file(s
, outfile
);
9703 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
9706 /* XXX: cannot do it with bound checking because of the malloc hooks */
9707 if (!do_bounds_check
)
9712 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);