2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library 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 GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #define CONFIG_TCC_STATIC
42 #include <sys/timeb.h>
47 #include <sys/ucontext.h>
51 #endif /* !CONFIG_TCCBOOT */
68 /* preprocessor debug */
70 /* include file debug */
78 /* target selection */
79 //#define TCC_TARGET_I386 /* i386 code generator */
80 //#define TCC_TARGET_ARM /* ARMv4 code generator */
81 //#define TCC_TARGET_C67 /* TMS320C67xx code generator */
83 /* default target is I386 */
84 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
85 !defined(TCC_TARGET_C67)
86 #define TCC_TARGET_I386
89 #if !defined(_WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
90 !defined(TCC_TARGET_C67)
91 #define CONFIG_TCC_BCHECK /* enable bound checking code */
94 #if defined(_WIN32) && !defined(TCC_TARGET_PE)
95 #define CONFIG_TCC_STATIC
98 /* define it to include assembler support */
99 #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
100 #define CONFIG_TCC_ASM
103 /* object format selection */
104 #if defined(TCC_TARGET_C67)
105 #define TCC_TARGET_COFF
114 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
115 executables or dlls */
116 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
118 #define INCLUDE_STACK_SIZE 32
119 #define IFDEF_STACK_SIZE 64
120 #define VSTACK_SIZE 256
121 #define STRING_MAX_SIZE 1024
122 #define PACK_STACK_SIZE 8
124 #define TOK_HASH_SIZE 8192 /* must be a power of two */
125 #define TOK_ALLOC_INCR 512 /* must be a power of two */
126 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
128 /* token symbol management */
129 typedef struct TokenSym
{
130 struct TokenSym
*hash_next
;
131 struct Sym
*sym_define
; /* direct pointer to define */
132 struct Sym
*sym_label
; /* direct pointer to label */
133 struct Sym
*sym_struct
; /* direct pointer to structure */
134 struct Sym
*sym_identifier
; /* direct pointer to identifier */
135 int tok
; /* token number */
141 typedef unsigned short nwchar_t
;
143 typedef int nwchar_t
;
146 typedef struct CString
{
147 int size
; /* size in bytes */
148 void *data
; /* either 'char *' or 'nwchar_t *' */
150 void *data_allocated
; /* if non NULL, data has been malloced */
153 /* type definition */
154 typedef struct CType
{
160 typedef union CValue
{
166 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
168 unsigned long long ull
;
169 struct CString
*cstr
;
175 typedef struct SValue
{
176 CType type
; /* type */
177 unsigned short r
; /* register + flags */
178 unsigned short r2
; /* second register, used for 'long long'
179 type. If not used, set to VT_CONST */
180 CValue c
; /* constant, if VT_CONST */
181 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
184 /* symbol management */
186 int v
; /* symbol token */
187 int r
; /* associated register */
188 int c
; /* associated number */
189 CType type
; /* associated type */
190 struct Sym
*next
; /* next related symbol */
191 struct Sym
*prev
; /* prev symbol in stack */
192 struct Sym
*prev_tok
; /* previous symbol for this token */
195 /* section definition */
196 /* XXX: use directly ELF structure for parameters ? */
197 /* special flag to indicate that the section should not be linked to
199 #define SHF_PRIVATE 0x80000000
201 typedef struct Section
{
202 unsigned long data_offset
; /* current data offset */
203 unsigned char *data
; /* section data */
204 unsigned long data_allocated
; /* used for realloc() handling */
205 int sh_name
; /* elf section name (only used during output) */
206 int sh_num
; /* elf section number */
207 int sh_type
; /* elf section type */
208 int sh_flags
; /* elf section flags */
209 int sh_info
; /* elf section info */
210 int sh_addralign
; /* elf section alignment */
211 int sh_entsize
; /* elf entry size */
212 unsigned long sh_size
; /* section size (only used during output) */
213 unsigned long sh_addr
; /* address at which the section is relocated */
214 unsigned long sh_offset
; /* file offset */
215 int nb_hashed_syms
; /* used to resize the hash table */
216 struct Section
*link
; /* link to another section */
217 struct Section
*reloc
; /* corresponding section for relocation, if any */
218 struct Section
*hash
; /* hash table for symbols */
219 struct Section
*next
;
220 char name
[1]; /* section name */
223 typedef struct DLLReference
{
228 /* GNUC attribute definition */
229 typedef struct AttributeDef
{
233 int func_attr
; /* calling convention, exports, ... */
236 /* -------------------------------------------------- */
237 /* gr: wrappers for casting sym->r for other purposes */
245 #define FUNC_CALL(r) (((func_attr_t*)&(r))->func_call)
246 #define FUNC_EXPORT(r) (((func_attr_t*)&(r))->func_export)
247 #define FUNC_ARGS(r) (((func_attr_t*)&(r))->func_args)
248 #define INLINE_DEF(r) (*(int **)&(r))
249 /* -------------------------------------------------- */
251 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
252 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
253 #define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
255 /* stored in 'Sym.c' field */
256 #define FUNC_NEW 1 /* ansi function prototype */
257 #define FUNC_OLD 2 /* old function prototype */
258 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
260 /* stored in 'Sym.r' field */
261 #define FUNC_CDECL 0 /* standard c call */
262 #define FUNC_STDCALL 1 /* pascal c call */
263 #define FUNC_FASTCALL1 2 /* first param in %eax */
264 #define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
265 #define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
266 #define FUNC_FASTCALLW 5 /* first parameter in %ecx, %edx */
268 /* field 'Sym.t' for macros */
269 #define MACRO_OBJ 0 /* object like macro */
270 #define MACRO_FUNC 1 /* function like macro */
272 /* field 'Sym.r' for C labels */
273 #define LABEL_DEFINED 0 /* label is defined */
274 #define LABEL_FORWARD 1 /* label is forward defined */
275 #define LABEL_DECLARED 2 /* label is declared but never used */
277 /* type_decl() types */
278 #define TYPE_ABSTRACT 1 /* type without variable */
279 #define TYPE_DIRECT 2 /* type with variable */
281 #define IO_BUF_SIZE 8192
283 typedef struct BufferedFile
{
287 int line_num
; /* current line number - here to simplify code */
288 int ifndef_macro
; /* #ifndef macro / #endif search */
289 int ifndef_macro_saved
; /* saved ifndef_macro */
290 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
291 char inc_type
; /* type of include */
292 char inc_filename
[512]; /* filename specified by the user */
293 char filename
[1024]; /* current filename - here to simplify code */
294 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
297 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
298 #define CH_EOF (-1) /* end of file */
300 /* parsing state (used to save parser state to reparse part of the
301 source several times) */
302 typedef struct ParseState
{
309 /* used to record tokens */
310 typedef struct TokenString
{
317 /* include file cache, used to find files faster and also to eliminate
318 inclusion if the include file is protected by #ifndef ... #endif */
319 typedef struct CachedInclude
{
321 int hash_next
; /* -1 if none */
322 char type
; /* '"' or '>' to give include type */
323 char filename
[1]; /* path specified in #include */
326 #define CACHED_INCLUDES_HASH_SIZE 512
329 static struct BufferedFile
*file
;
332 static CString tokcstr
; /* current parsed string, if any */
333 /* additional informations about token */
334 static int tok_flags
;
335 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
336 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
337 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
338 #define TOK_FLAG_EOF 0x0008 /* end of file */
340 static int *macro_ptr
, *macro_ptr_allocated
;
341 static int *unget_saved_macro_ptr
;
342 static int unget_saved_buffer
[TOK_MAX_SIZE
+ 1];
343 static int unget_buffer_enabled
;
344 static int parse_flags
;
345 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
346 #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
347 #define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
348 token. line feed is also
350 #define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
352 static Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
353 static Section
*cur_text_section
; /* current section where function code is
355 #ifdef CONFIG_TCC_ASM
356 static Section
*last_text_section
; /* to handle .previous asm directive */
358 /* bound check related sections */
359 static Section
*bounds_section
; /* contains global data bound description */
360 static Section
*lbounds_section
; /* contains local data bound description */
361 /* symbol sections */
362 static Section
*symtab_section
, *strtab_section
;
365 static Section
*stab_section
, *stabstr_section
;
367 /* loc : local variable index
368 ind : output code index
370 anon_sym: anonymous symbol index
372 static int rsym
, anon_sym
, ind
, loc
;
373 /* expression generation modifiers */
374 static int const_wanted
; /* true if constant wanted */
375 static int nocode_wanted
; /* true if no code generation wanted for an expression */
376 static int global_expr
; /* true if compound literals must be allocated
377 globally (used during initializers parsing */
378 static CType func_vt
; /* current function return type (used by return
381 static int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
382 static int tok_ident
;
383 static TokenSym
**table_ident
;
384 static TokenSym
*hash_ident
[TOK_HASH_SIZE
];
385 static char token_buf
[STRING_MAX_SIZE
+ 1];
386 static char *funcname
;
387 static Sym
*global_stack
, *local_stack
;
388 static Sym
*define_stack
;
389 static Sym
*global_label_stack
, *local_label_stack
;
390 /* symbol allocator */
391 #define SYM_POOL_NB (8192 / sizeof(Sym))
392 static Sym
*sym_free_first
;
393 static void **sym_pools
;
394 static int nb_sym_pools
;
396 static SValue vstack
[VSTACK_SIZE
], *vtop
;
397 /* some predefined types */
398 static CType char_pointer_type
, func_old_type
, int_type
;
399 /* true if isid(c) || isnum(c) */
400 static unsigned char isidnum_table
[256];
402 /* display some information during compilation */
403 static int verbose
= 0;
405 /* compile with debug symbol (and use them if error during execution) */
406 static int do_debug
= 0;
408 /* compile with built-in memory and bounds checker */
409 static int do_bounds_check
= 0;
411 /* display benchmark infos */
413 static int do_bench
= 0;
415 static int total_lines
;
416 static int total_bytes
;
418 /* use GNU C extensions */
419 static int gnu_ext
= 1;
421 /* use Tiny C extensions */
422 static int tcc_ext
= 1;
424 /* max number of callers shown if error */
425 static int num_callers
= 6;
426 static const char **rt_bound_error_msg
;
428 /* XXX: get rid of this ASAP */
429 static struct TCCState
*tcc_state
;
431 /* give the path of the tcc libraries */
432 static const char *tcc_lib_path
= CONFIG_TCCDIR
;
437 BufferedFile
**include_stack_ptr
;
438 int *ifdef_stack_ptr
;
440 /* include file handling */
441 char **include_paths
;
442 int nb_include_paths
;
443 char **sysinclude_paths
;
444 int nb_sysinclude_paths
;
445 CachedInclude
**cached_includes
;
446 int nb_cached_includes
;
448 char **library_paths
;
449 int nb_library_paths
;
451 /* array of all loaded dlls (including those referenced by loaded
453 DLLReference
**loaded_dlls
;
458 int nb_sections
; /* number of sections, including first dummy section */
463 unsigned long *got_offsets
;
465 /* give the correspondance from symtab indexes to dynsym indexes */
466 int *symtab_to_dynsym
;
468 /* temporary dynamic symbol sections (for dll loading) */
469 Section
*dynsymtab_section
;
470 /* exported dynamic symbol section */
473 int nostdinc
; /* if true, no standard headers are added */
474 int nostdlib
; /* if true, no standard libraries are added */
476 int nocommon
; /* if true, do not use common symbols for .bss data */
478 /* if true, static linking is performed */
481 /* soname as specified on the command line (-soname) */
484 /* if true, all symbols are exported */
487 /* if true, only link in referenced objects from archive */
490 /* address of text section */
491 unsigned long text_addr
;
494 /* output format, see TCC_OUTPUT_FORMAT_xxx */
497 /* C language options */
498 int char_is_unsigned
;
499 int leading_underscore
;
501 /* warning switches */
502 int warn_write_strings
;
503 int warn_unsupported
;
506 int warn_implicit_function_declaration
;
510 void (*error_func
)(void *opaque
, const char *msg
);
511 int error_set_jmp_enabled
;
512 jmp_buf error_jmp_buf
;
515 /* tiny assembler state */
518 /* see include_stack_ptr */
519 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
521 /* see ifdef_stack_ptr */
522 int ifdef_stack
[IFDEF_STACK_SIZE
];
524 /* see cached_includes */
525 int cached_includes_hash
[CACHED_INCLUDES_HASH_SIZE
];
528 int pack_stack
[PACK_STACK_SIZE
];
531 /* output file for preprocessing */
535 /* The current value can be: */
536 #define VT_VALMASK 0x00ff
537 #define VT_CONST 0x00f0 /* constant in vc
538 (must be first non register value) */
539 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
540 #define VT_LOCAL 0x00f2 /* offset on stack */
541 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
542 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
543 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
544 #define VT_LVAL 0x0100 /* var is an lvalue */
545 #define VT_SYM 0x0200 /* a symbol value is added */
546 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
547 char/short stored in integer registers) */
548 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
549 dereferencing value */
550 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
551 bounding function call point is in vc */
552 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
553 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
554 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
555 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
558 #define VT_INT 0 /* integer type */
559 #define VT_BYTE 1 /* signed byte type */
560 #define VT_SHORT 2 /* short type */
561 #define VT_VOID 3 /* void type */
562 #define VT_PTR 4 /* pointer */
563 #define VT_ENUM 5 /* enum definition */
564 #define VT_FUNC 6 /* function type */
565 #define VT_STRUCT 7 /* struct/union definition */
566 #define VT_FLOAT 8 /* IEEE float */
567 #define VT_DOUBLE 9 /* IEEE double */
568 #define VT_LDOUBLE 10 /* IEEE long double */
569 #define VT_BOOL 11 /* ISOC99 boolean type */
570 #define VT_LLONG 12 /* 64 bit integer */
571 #define VT_LONG 13 /* long integer (NEVER USED as type, only
573 #define VT_BTYPE 0x000f /* mask for basic type */
574 #define VT_UNSIGNED 0x0010 /* unsigned type */
575 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
576 #define VT_BITFIELD 0x0040 /* bitfield modifier */
577 #define VT_CONSTANT 0x0800 /* const modifier */
578 #define VT_VOLATILE 0x1000 /* volatile modifier */
579 #define VT_SIGNED 0x2000 /* signed type */
582 #define VT_EXTERN 0x00000080 /* extern definition */
583 #define VT_STATIC 0x00000100 /* static variable */
584 #define VT_TYPEDEF 0x00000200 /* typedef definition */
585 #define VT_INLINE 0x00000400 /* inline definition */
587 #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */
589 /* type mask (except storage) */
590 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
591 #define VT_TYPE (~(VT_STORAGE))
595 /* warning: the following compare tokens depend on i386 asm code */
602 #define TOK_Nset 0x98
603 #define TOK_Nclear 0x99
609 #define TOK_LAND 0xa0
613 #define TOK_MID 0xa3 /* inc/dec, to void constant */
615 #define TOK_UDIV 0xb0 /* unsigned division */
616 #define TOK_UMOD 0xb1 /* unsigned modulo */
617 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
618 #define TOK_CINT 0xb3 /* number in tokc */
619 #define TOK_CCHAR 0xb4 /* char constant in tokc */
620 #define TOK_STR 0xb5 /* pointer to string in tokc */
621 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
622 #define TOK_LCHAR 0xb7
623 #define TOK_LSTR 0xb8
624 #define TOK_CFLOAT 0xb9 /* float constant */
625 #define TOK_LINENUM 0xba /* line number info */
626 #define TOK_CDOUBLE 0xc0 /* double constant */
627 #define TOK_CLDOUBLE 0xc1 /* long double constant */
628 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
629 #define TOK_ADDC1 0xc3 /* add with carry generation */
630 #define TOK_ADDC2 0xc4 /* add with carry use */
631 #define TOK_SUBC1 0xc5 /* add with carry generation */
632 #define TOK_SUBC2 0xc6 /* add with carry use */
633 #define TOK_CUINT 0xc8 /* unsigned int constant */
634 #define TOK_CLLONG 0xc9 /* long long constant */
635 #define TOK_CULLONG 0xca /* unsigned long long constant */
636 #define TOK_ARROW 0xcb
637 #define TOK_DOTS 0xcc /* three dots */
638 #define TOK_SHR 0xcd /* unsigned shift right */
639 #define TOK_PPNUM 0xce /* preprocessor number */
641 #define TOK_SHL 0x01 /* shift left */
642 #define TOK_SAR 0x02 /* signed shift right */
644 /* assignement operators : normal operator or 0x80 */
645 #define TOK_A_MOD 0xa5
646 #define TOK_A_AND 0xa6
647 #define TOK_A_MUL 0xaa
648 #define TOK_A_ADD 0xab
649 #define TOK_A_SUB 0xad
650 #define TOK_A_DIV 0xaf
651 #define TOK_A_XOR 0xde
652 #define TOK_A_OR 0xfc
653 #define TOK_A_SHL 0x81
654 #define TOK_A_SAR 0x82
657 #define offsetof(type, field) ((size_t) &((type *)0)->field)
661 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
664 /* WARNING: the content of this string encodes token numbers */
665 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";
667 #define TOK_EOF (-1) /* end of file */
668 #define TOK_LINEFEED 10 /* line feed */
670 /* all identificators and strings have token above that */
671 #define TOK_IDENT 256
673 /* only used for i386 asm opcodes definitions */
674 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
677 DEF(TOK_ASM_ ## x ## b, #x "b") \
678 DEF(TOK_ASM_ ## x ## w, #x "w") \
679 DEF(TOK_ASM_ ## x ## l, #x "l") \
680 DEF(TOK_ASM_ ## x, #x)
683 DEF(TOK_ASM_ ## x ## w, #x "w") \
684 DEF(TOK_ASM_ ## x ## l, #x "l") \
685 DEF(TOK_ASM_ ## x, #x)
688 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
689 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
690 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
691 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
694 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
695 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
698 #define DEF_ASMTEST(x) \
730 #define TOK_ASM_int TOK_INT
733 TOK_LAST
= TOK_IDENT
- 1,
734 #define DEF(id, str) id,
739 static const char tcc_keywords
[] =
740 #define DEF(id, str) str "\0"
745 #define TOK_UIDENT TOK_DEFINE
748 #define snprintf _snprintf
749 #define vsnprintf _vsnprintf
751 #define strtold (long double)strtod
752 #define strtof (float)strtod
753 #define strtoll (long long)strtol
755 #elif defined(TCC_UCLIBC) || defined(__FreeBSD__) || defined(__DragonFly__) \
756 || defined(__OpenBSD__)
757 /* currently incorrect */
758 long double strtold(const char *nptr
, char **endptr
)
760 return (long double)strtod(nptr
, endptr
);
762 float strtof(const char *nptr
, char **endptr
)
764 return (float)strtod(nptr
, endptr
);
767 /* XXX: need to define this to use them in non ISOC99 context */
768 extern float strtof (const char *__nptr
, char **__endptr
);
769 extern long double strtold (const char *__nptr
, char **__endptr
);
772 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
773 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
774 static char *tcc_basename(const char *name
);
775 static char *tcc_fileextension (const char *p
);
777 static void next(void);
778 static void next_nomacro(void);
779 static void parse_expr_type(CType
*type
);
780 static void expr_type(CType
*type
);
781 static void unary_type(CType
*type
);
782 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
783 int case_reg
, int is_expr
);
784 static int expr_const(void);
785 static void expr_eq(void);
786 static void gexpr(void);
787 static void gen_inline_functions(void);
788 static void decl(int l
);
789 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
790 int first
, int size_only
);
791 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
792 int has_init
, int v
, int scope
);
794 void gv2(int rc1
, int rc2
);
795 void move_reg(int r
, int s
);
796 void save_regs(int n
);
797 void save_reg(int r
);
802 int get_reg_ex(int rc
,int rc2
);
805 struct macro_level
*prev
;
809 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
810 const int *macro_str
, struct macro_level
**can_read_stream
);
812 void force_charshort_cast(int t
);
813 static void gen_cast(CType
*type
);
815 static Sym
*sym_find(int v
);
816 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
819 static int type_size(CType
*type
, int *a
);
820 static inline CType
*pointed_type(CType
*type
);
821 static int pointed_size(CType
*type
);
822 static int lvalue_type(int t
);
823 static int parse_btype(CType
*type
, AttributeDef
*ad
);
824 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
825 static int compare_types(CType
*type1
, CType
*type2
, int unqualified
);
826 static int is_compatible_types(CType
*type1
, CType
*type2
);
827 static int is_compatible_parameter_types(CType
*type1
, CType
*type2
);
829 int ieee_finite(double d
);
830 void error(const char *fmt
, ...);
834 void lexpand_nr(void);
835 static void vpush_global_sym(CType
*type
, int v
);
836 void vset(CType
*type
, int r
, int v
);
837 void type_to_str(char *buf
, int buf_size
,
838 CType
*type
, const char *varstr
);
839 char *get_tok_str(int v
, CValue
*cv
);
840 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
841 unsigned long offset
, unsigned long size
);
842 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
844 /* section generation */
845 static void section_realloc(Section
*sec
, unsigned long new_size
);
846 static void *section_ptr_add(Section
*sec
, unsigned long size
);
847 static void put_extern_sym(Sym
*sym
, Section
*section
,
848 unsigned long value
, unsigned long size
);
849 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
850 static int put_elf_str(Section
*s
, const char *sym
);
851 static int put_elf_sym(Section
*s
,
852 unsigned long value
, unsigned long size
,
853 int info
, int other
, int shndx
, const char *name
);
854 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
855 int info
, int other
, int sh_num
, const char *name
);
856 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
857 int type
, int symbol
);
858 static void put_stabs(const char *str
, int type
, int other
, int desc
,
859 unsigned long value
);
860 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
861 unsigned long value
, Section
*sec
, int sym_index
);
862 static void put_stabn(int type
, int other
, int desc
, int value
);
863 static void put_stabd(int type
, int other
, int desc
);
864 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
866 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
867 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
868 #define AFF_PREPROCESS 0x0004 /* preprocess file */
869 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
872 int tcc_output_coff(TCCState
*s1
, FILE *f
);
875 void *resolve_sym(TCCState
*s1
, const char *sym
, int type
);
876 int pe_load_def_file(struct TCCState
*s1
, int fd
);
877 int pe_test_res_file(void *v
, int size
);
878 int pe_load_res_file(struct TCCState
*s1
, int fd
);
879 void pe_add_runtime(struct TCCState
*s1
);
880 void pe_guess_outfile(char *objfilename
, int output_type
);
881 int pe_output_file(struct TCCState
*s1
, const char *filename
);
885 #ifdef CONFIG_TCC_ASM
887 typedef struct ExprValue
{
892 #define MAX_ASM_OPERANDS 30
894 typedef struct ASMOperand
{
895 int id
; /* GCC 3 optionnal identifier (0 if number only supported */
897 char asm_str
[16]; /* computed asm string for operand */
898 SValue
*vt
; /* C value of the expression */
899 int ref_index
; /* if >= 0, gives reference to a output constraint */
900 int input_index
; /* if >= 0, gives reference to an input constraint */
901 int priority
; /* priority, used to assign registers */
902 int reg
; /* if >= 0, register number used for this operand */
903 int is_llong
; /* true if double register value */
904 int is_memory
; /* true if memory operand */
905 int is_rw
; /* for '+' modifier */
908 static void asm_expr(TCCState
*s1
, ExprValue
*pe
);
909 static int asm_int_expr(TCCState
*s1
);
910 static int find_constraint(ASMOperand
*operands
, int nb_operands
,
911 const char *name
, const char **pp
);
913 static int tcc_assemble(TCCState
*s1
, int do_preprocess
);
917 static void asm_instr(void);
918 static void asm_global_instr(void);
920 /* true if float/double/long double type */
921 static inline int is_float(int t
)
925 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
928 #ifdef TCC_TARGET_I386
929 #include "i386-gen.c"
932 #ifdef TCC_TARGET_ARM
936 #ifdef TCC_TARGET_C67
940 #ifdef CONFIG_TCC_STATIC
942 #define RTLD_LAZY 0x001
943 #define RTLD_NOW 0x002
944 #define RTLD_GLOBAL 0x100
945 #define RTLD_DEFAULT NULL
947 /* dummy function for profiling */
948 void *dlopen(const char *filename
, int flag
)
953 const char *dlerror(void)
958 typedef struct TCCSyms
{
963 #define TCCSYM(a) { #a, &a, },
965 /* add the symbol you want here if no dynamic linking is done */
966 static TCCSyms tcc_syms
[] = {
967 #if !defined(CONFIG_TCCBOOT)
976 void *resolve_sym(TCCState
*s1
, const char *symbol
, int type
)
980 while (p
->str
!= NULL
) {
981 if (!strcmp(p
->str
, symbol
))
988 #elif !defined(_WIN32)
992 void *resolve_sym(TCCState
*s1
, const char *sym
, int type
)
994 return dlsym(RTLD_DEFAULT
, sym
);
999 /********************************************************/
1001 /* we use our own 'finite' function to avoid potential problems with
1002 non standard math libs */
1003 /* XXX: endianness dependent */
1004 int ieee_finite(double d
)
1007 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
1010 /* copy a string and truncate it. */
1011 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
1018 q_end
= buf
+ buf_size
- 1;
1030 /* strcat and truncate. */
1031 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
1036 pstrcpy(buf
+ len
, buf_size
- len
, s
);
1041 static int strstart(const char *str
, const char *val
, const char **ptr
)
1046 while (*q
!= '\0') {
1058 /* extract the basename of a file */
1059 static char *tcc_basename(const char *name
)
1061 char *p
= strchr(name
, 0);
1072 static char *tcc_fileextension (const char *name
)
1074 char *b
= tcc_basename(name
);
1075 char *e
= strrchr(b
, '.');
1076 return e
? e
: strchr(b
, 0);
1080 char *normalize_slashes(char *path
)
1083 for (p
= path
; *p
; ++p
)
1089 char *w32_tcc_lib_path(void)
1091 /* on win32, we suppose the lib and includes are at the location
1093 char path
[1024], *p
;
1094 GetModuleFileNameA(NULL
, path
, sizeof path
);
1095 p
= tcc_basename(normalize_slashes(strlwr(path
)));
1096 if (p
- 5 > path
&& 0 == strncmp(p
- 5, "/bin/", 5))
1101 return strdup(path
);
1105 void set_pages_executable(void *ptr
, unsigned long length
)
1108 unsigned long old_protect
;
1109 VirtualProtect(ptr
, length
, PAGE_EXECUTE_READWRITE
, &old_protect
);
1111 unsigned long start
, end
;
1112 start
= (unsigned long)ptr
& ~(PAGESIZE
- 1);
1113 end
= (unsigned long)ptr
+ length
;
1114 end
= (end
+ PAGESIZE
- 1) & ~(PAGESIZE
- 1);
1115 mprotect((void *)start
, end
- start
, PROT_READ
| PROT_WRITE
| PROT_EXEC
);
1119 /* memory management */
1123 unsigned malloc_usable_size(void*);
1126 static inline void tcc_free(void *ptr
)
1129 mem_cur_size
-= malloc_usable_size(ptr
);
1134 static void *tcc_malloc(unsigned long size
)
1139 error("memory full");
1141 mem_cur_size
+= malloc_usable_size(ptr
);
1142 if (mem_cur_size
> mem_max_size
)
1143 mem_max_size
= mem_cur_size
;
1148 static void *tcc_mallocz(unsigned long size
)
1151 ptr
= tcc_malloc(size
);
1152 memset(ptr
, 0, size
);
1156 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
1160 mem_cur_size
-= malloc_usable_size(ptr
);
1162 ptr1
= realloc(ptr
, size
);
1164 /* NOTE: count not correct if alloc error, but not critical */
1165 mem_cur_size
+= malloc_usable_size(ptr1
);
1166 if (mem_cur_size
> mem_max_size
)
1167 mem_max_size
= mem_cur_size
;
1172 static char *tcc_strdup(const char *str
)
1175 ptr
= tcc_malloc(strlen(str
) + 1);
1180 #define free(p) use_tcc_free(p)
1181 #define malloc(s) use_tcc_malloc(s)
1182 #define realloc(p, s) use_tcc_realloc(p, s)
1184 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
1191 /* every power of two we double array size */
1192 if ((nb
& (nb
- 1)) == 0) {
1197 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
1199 error("memory full");
1206 static void dynarray_reset(void *pp
, int *n
)
1209 for (p
= *(void***)pp
; *n
; ++p
, --*n
)
1212 tcc_free(*(void**)pp
);
1216 /* symbol allocator */
1217 static Sym
*__sym_malloc(void)
1219 Sym
*sym_pool
, *sym
, *last_sym
;
1222 sym_pool
= tcc_malloc(SYM_POOL_NB
* sizeof(Sym
));
1223 dynarray_add(&sym_pools
, &nb_sym_pools
, sym_pool
);
1225 last_sym
= sym_free_first
;
1227 for(i
= 0; i
< SYM_POOL_NB
; i
++) {
1228 sym
->next
= last_sym
;
1232 sym_free_first
= last_sym
;
1236 static inline Sym
*sym_malloc(void)
1239 sym
= sym_free_first
;
1241 sym
= __sym_malloc();
1242 sym_free_first
= sym
->next
;
1246 static inline void sym_free(Sym
*sym
)
1248 sym
->next
= sym_free_first
;
1249 sym_free_first
= sym
;
1252 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
1256 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
1257 strcpy(sec
->name
, name
);
1258 sec
->sh_type
= sh_type
;
1259 sec
->sh_flags
= sh_flags
;
1266 sec
->sh_addralign
= 4;
1269 sec
->sh_addralign
= 1;
1272 sec
->sh_addralign
= 32; /* default conservative alignment */
1276 /* only add section if not private */
1277 if (!(sh_flags
& SHF_PRIVATE
)) {
1278 sec
->sh_num
= s1
->nb_sections
;
1279 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
1284 static void free_section(Section
*s
)
1286 if (s
->link
&& 0 == s
->link
->sh_num
)
1287 free_section(s
->link
);
1288 if (s
->hash
&& 0 == s
->hash
->sh_num
)
1289 s
->hash
->link
= NULL
, free_section(s
->hash
);
1294 /* realloc section and set its content to zero */
1295 static void section_realloc(Section
*sec
, unsigned long new_size
)
1298 unsigned char *data
;
1300 size
= sec
->data_allocated
;
1303 while (size
< new_size
)
1305 data
= tcc_realloc(sec
->data
, size
);
1307 error("memory full");
1308 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
1310 sec
->data_allocated
= size
;
1313 /* reserve at least 'size' bytes in section 'sec' from
1314 sec->data_offset. */
1315 static void *section_ptr_add(Section
*sec
, unsigned long size
)
1317 unsigned long offset
, offset1
;
1319 offset
= sec
->data_offset
;
1320 offset1
= offset
+ size
;
1321 if (offset1
> sec
->data_allocated
)
1322 section_realloc(sec
, offset1
);
1323 sec
->data_offset
= offset1
;
1324 return sec
->data
+ offset
;
1327 /* return a reference to a section, and create it if it does not
1329 Section
*find_section(TCCState
*s1
, const char *name
)
1333 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1334 sec
= s1
->sections
[i
];
1335 if (!strcmp(name
, sec
->name
))
1338 /* sections are created as PROGBITS */
1339 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
1342 #define SECTION_ABS ((void *)1)
1344 /* update sym->c so that it points to an external symbol in section
1345 'section' with value 'value' */
1346 static void put_extern_sym2(Sym
*sym
, Section
*section
,
1347 unsigned long value
, unsigned long size
,
1348 int can_add_underscore
)
1350 int sym_type
, sym_bind
, sh_num
, info
, other
, attr
;
1355 if (section
== NULL
)
1357 else if (section
== SECTION_ABS
)
1360 sh_num
= section
->sh_num
;
1364 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
) {
1365 sym_type
= STT_FUNC
;
1366 #ifdef TCC_TARGET_PE
1368 attr
= sym
->type
.ref
->r
;
1369 if (FUNC_EXPORT(attr
))
1371 if (FUNC_CALL(attr
) == FUNC_STDCALL
)
1375 sym_type
= STT_OBJECT
;
1378 if (sym
->type
.t
& VT_STATIC
)
1379 sym_bind
= STB_LOCAL
;
1381 sym_bind
= STB_GLOBAL
;
1384 name
= get_tok_str(sym
->v
, NULL
);
1385 #ifdef CONFIG_TCC_BCHECK
1386 if (do_bounds_check
) {
1389 /* XXX: avoid doing that for statics ? */
1390 /* if bound checking is activated, we change some function
1391 names by adding the "__bound" prefix */
1394 /* XXX: we rely only on malloc hooks */
1407 strcpy(buf
, "__bound_");
1415 #ifdef TCC_TARGET_PE
1416 if ((other
& 2) && can_add_underscore
) {
1417 sprintf(buf1
, "_%s@%d", name
, FUNC_ARGS(attr
));
1421 if (tcc_state
->leading_underscore
&& can_add_underscore
) {
1423 pstrcpy(buf1
+ 1, sizeof(buf1
) - 1, name
);
1426 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
1427 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, other
, sh_num
, name
);
1429 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
1430 esym
->st_value
= value
;
1431 esym
->st_size
= size
;
1432 esym
->st_shndx
= sh_num
;
1433 esym
->st_other
|= other
;
1437 static void put_extern_sym(Sym
*sym
, Section
*section
,
1438 unsigned long value
, unsigned long size
)
1440 put_extern_sym2(sym
, section
, value
, size
, 1);
1443 /* add a new relocation entry to symbol 'sym' in section 's' */
1444 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
1447 put_extern_sym(sym
, NULL
, 0, 0);
1448 /* now we can add ELF relocation info */
1449 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
1452 static inline int isid(int c
)
1454 return (c
>= 'a' && c
<= 'z') ||
1455 (c
>= 'A' && c
<= 'Z') ||
1459 static inline int isnum(int c
)
1461 return c
>= '0' && c
<= '9';
1464 static inline int isoct(int c
)
1466 return c
>= '0' && c
<= '7';
1469 static inline int toup(int c
)
1471 if (c
>= 'a' && c
<= 'z')
1472 return c
- 'a' + 'A';
1477 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1481 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1484 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1488 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1492 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1499 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1500 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1501 (*f
)->filename
, (*f
)->line_num
);
1502 if (file
->line_num
> 0) {
1503 strcat_printf(buf
, sizeof(buf
),
1504 "%s:%d: ", file
->filename
, file
->line_num
);
1506 strcat_printf(buf
, sizeof(buf
),
1507 "%s: ", file
->filename
);
1510 strcat_printf(buf
, sizeof(buf
),
1514 strcat_printf(buf
, sizeof(buf
), "warning: ");
1515 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1517 if (!s1
->error_func
) {
1518 /* default case: stderr */
1519 fprintf(stderr
, "%s\n", buf
);
1521 s1
->error_func(s1
->error_opaque
, buf
);
1523 if (!is_warning
|| s1
->warn_error
)
1528 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1529 void (*error_func
)(void *opaque
, const char *msg
))
1531 s
->error_opaque
= error_opaque
;
1532 s
->error_func
= error_func
;
1536 /* error without aborting current compilation */
1537 void error_noabort(const char *fmt
, ...)
1539 TCCState
*s1
= tcc_state
;
1543 error1(s1
, 0, fmt
, ap
);
1547 void error(const char *fmt
, ...)
1549 TCCState
*s1
= tcc_state
;
1553 error1(s1
, 0, fmt
, ap
);
1555 /* better than nothing: in some cases, we accept to handle errors */
1556 if (s1
->error_set_jmp_enabled
) {
1557 longjmp(s1
->error_jmp_buf
, 1);
1559 /* XXX: eliminate this someday */
1564 void expect(const char *msg
)
1566 error("%s expected", msg
);
1569 void warning(const char *fmt
, ...)
1571 TCCState
*s1
= tcc_state
;
1578 error1(s1
, 1, fmt
, ap
);
1585 error("'%c' expected", c
);
1589 static void test_lvalue(void)
1591 if (!(vtop
->r
& VT_LVAL
))
1595 /* allocate a new token */
1596 static TokenSym
*tok_alloc_new(TokenSym
**pts
, const char *str
, int len
)
1598 TokenSym
*ts
, **ptable
;
1601 if (tok_ident
>= SYM_FIRST_ANOM
)
1602 error("memory full");
1604 /* expand token table if needed */
1605 i
= tok_ident
- TOK_IDENT
;
1606 if ((i
% TOK_ALLOC_INCR
) == 0) {
1607 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1609 error("memory full");
1610 table_ident
= ptable
;
1613 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1614 table_ident
[i
] = ts
;
1615 ts
->tok
= tok_ident
++;
1616 ts
->sym_define
= NULL
;
1617 ts
->sym_label
= NULL
;
1618 ts
->sym_struct
= NULL
;
1619 ts
->sym_identifier
= NULL
;
1621 ts
->hash_next
= NULL
;
1622 memcpy(ts
->str
, str
, len
);
1623 ts
->str
[len
] = '\0';
1628 #define TOK_HASH_INIT 1
1629 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1631 /* find a token and add it if not found */
1632 static TokenSym
*tok_alloc(const char *str
, int len
)
1634 TokenSym
*ts
, **pts
;
1640 h
= TOK_HASH_FUNC(h
, ((unsigned char *)str
)[i
]);
1641 h
&= (TOK_HASH_SIZE
- 1);
1643 pts
= &hash_ident
[h
];
1648 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1650 pts
= &(ts
->hash_next
);
1652 return tok_alloc_new(pts
, str
, len
);
1655 /* CString handling */
1657 static void cstr_realloc(CString
*cstr
, int new_size
)
1662 size
= cstr
->size_allocated
;
1664 size
= 8; /* no need to allocate a too small first string */
1665 while (size
< new_size
)
1667 data
= tcc_realloc(cstr
->data_allocated
, size
);
1669 error("memory full");
1670 cstr
->data_allocated
= data
;
1671 cstr
->size_allocated
= size
;
1676 static inline void cstr_ccat(CString
*cstr
, int ch
)
1679 size
= cstr
->size
+ 1;
1680 if (size
> cstr
->size_allocated
)
1681 cstr_realloc(cstr
, size
);
1682 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1686 static void cstr_cat(CString
*cstr
, const char *str
)
1698 /* add a wide char */
1699 static void cstr_wccat(CString
*cstr
, int ch
)
1702 size
= cstr
->size
+ sizeof(nwchar_t
);
1703 if (size
> cstr
->size_allocated
)
1704 cstr_realloc(cstr
, size
);
1705 *(nwchar_t
*)(((unsigned char *)cstr
->data
) + size
- sizeof(nwchar_t
)) = ch
;
1709 static void cstr_new(CString
*cstr
)
1711 memset(cstr
, 0, sizeof(CString
));
1714 /* free string and reset it to NULL */
1715 static void cstr_free(CString
*cstr
)
1717 tcc_free(cstr
->data_allocated
);
1721 #define cstr_reset(cstr) cstr_free(cstr)
1723 /* XXX: unicode ? */
1724 static void add_char(CString
*cstr
, int c
)
1726 if (c
== '\'' || c
== '\"' || c
== '\\') {
1727 /* XXX: could be more precise if char or string */
1728 cstr_ccat(cstr
, '\\');
1730 if (c
>= 32 && c
<= 126) {
1733 cstr_ccat(cstr
, '\\');
1735 cstr_ccat(cstr
, 'n');
1737 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1738 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1739 cstr_ccat(cstr
, '0' + (c
& 7));
1744 /* XXX: buffer overflow */
1745 /* XXX: float tokens */
1746 char *get_tok_str(int v
, CValue
*cv
)
1748 static char buf
[STRING_MAX_SIZE
+ 1];
1749 static CString cstr_buf
;
1755 /* NOTE: to go faster, we give a fixed buffer for small strings */
1756 cstr_reset(&cstr_buf
);
1757 cstr_buf
.data
= buf
;
1758 cstr_buf
.size_allocated
= sizeof(buf
);
1764 /* XXX: not quite exact, but only useful for testing */
1765 sprintf(p
, "%u", cv
->ui
);
1769 /* XXX: not quite exact, but only useful for testing */
1770 sprintf(p
, "%Lu", cv
->ull
);
1774 cstr_ccat(&cstr_buf
, '\'');
1775 add_char(&cstr_buf
, cv
->i
);
1776 cstr_ccat(&cstr_buf
, '\'');
1777 cstr_ccat(&cstr_buf
, '\0');
1781 len
= cstr
->size
- 1;
1783 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1784 cstr_ccat(&cstr_buf
, '\0');
1789 cstr_ccat(&cstr_buf
, '\"');
1791 len
= cstr
->size
- 1;
1793 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1795 len
= (cstr
->size
/ sizeof(nwchar_t
)) - 1;
1797 add_char(&cstr_buf
, ((nwchar_t
*)cstr
->data
)[i
]);
1799 cstr_ccat(&cstr_buf
, '\"');
1800 cstr_ccat(&cstr_buf
, '\0');
1809 return strcpy(p
, "...");
1811 return strcpy(p
, "<<=");
1813 return strcpy(p
, ">>=");
1815 if (v
< TOK_IDENT
) {
1816 /* search in two bytes table */
1830 } else if (v
< tok_ident
) {
1831 return table_ident
[v
- TOK_IDENT
]->str
;
1832 } else if (v
>= SYM_FIRST_ANOM
) {
1833 /* special name for anonymous symbol */
1834 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1836 /* should never happen */
1841 return cstr_buf
.data
;
1844 /* push, without hashing */
1845 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1859 /* find a symbol and return its associated structure. 's' is the top
1860 of the symbol stack */
1861 static Sym
*sym_find2(Sym
*s
, int v
)
1871 /* structure lookup */
1872 static inline Sym
*struct_find(int v
)
1875 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1877 return table_ident
[v
]->sym_struct
;
1880 /* find an identifier */
1881 static inline Sym
*sym_find(int v
)
1884 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1886 return table_ident
[v
]->sym_identifier
;
1889 /* push a given symbol on the symbol stack */
1890 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1899 s
= sym_push2(ps
, v
, type
->t
, c
);
1900 s
->type
.ref
= type
->ref
;
1902 /* don't record fields or anonymous symbols */
1904 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1905 /* record symbol in token array */
1906 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1908 ps
= &ts
->sym_struct
;
1910 ps
= &ts
->sym_identifier
;
1917 /* push a global identifier */
1918 static Sym
*global_identifier_push(int v
, int t
, int c
)
1921 s
= sym_push2(&global_stack
, v
, t
, c
);
1922 /* don't record anonymous symbol */
1923 if (v
< SYM_FIRST_ANOM
) {
1924 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1925 /* modify the top most local identifier, so that
1926 sym_identifier will point to 's' when popped */
1928 ps
= &(*ps
)->prev_tok
;
1935 /* pop symbols until top reaches 'b' */
1936 static void sym_pop(Sym
**ptop
, Sym
*b
)
1946 /* remove symbol in token array */
1948 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1949 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1951 ps
= &ts
->sym_struct
;
1953 ps
= &ts
->sym_identifier
;
1964 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1969 if (strcmp(filename
, "-") == 0)
1970 fd
= 0, filename
= "stdin";
1972 fd
= open(filename
, O_RDONLY
| O_BINARY
);
1973 if ((verbose
== 2 && fd
>= 0) || verbose
== 3)
1974 printf("%s %*s%s\n", fd
< 0 ? "nf":"->",
1975 (s1
->include_stack_ptr
- s1
->include_stack
), "", filename
);
1978 bf
= tcc_malloc(sizeof(BufferedFile
));
1980 bf
->buf_ptr
= bf
->buffer
;
1981 bf
->buf_end
= bf
->buffer
;
1982 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1983 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1985 normalize_slashes(bf
->filename
);
1988 bf
->ifndef_macro
= 0;
1989 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1990 // printf("opening '%s'\n", filename);
1994 void tcc_close(BufferedFile
*bf
)
1996 total_lines
+= bf
->line_num
;
2001 /* fill input buffer and peek next char */
2002 static int tcc_peekc_slow(BufferedFile
*bf
)
2005 /* only tries to read if really end of buffer */
2006 if (bf
->buf_ptr
>= bf
->buf_end
) {
2008 #if defined(PARSE_DEBUG)
2013 len
= read(bf
->fd
, bf
->buffer
, len
);
2020 bf
->buf_ptr
= bf
->buffer
;
2021 bf
->buf_end
= bf
->buffer
+ len
;
2022 *bf
->buf_end
= CH_EOB
;
2024 if (bf
->buf_ptr
< bf
->buf_end
) {
2025 return bf
->buf_ptr
[0];
2027 bf
->buf_ptr
= bf
->buf_end
;
2032 /* return the current character, handling end of block if necessary
2034 static int handle_eob(void)
2036 return tcc_peekc_slow(file
);
2039 /* read next char from current input file and handle end of input buffer */
2040 static inline void inp(void)
2042 ch
= *(++(file
->buf_ptr
));
2043 /* end of buffer/file handling */
2048 /* handle '\[\r]\n' */
2049 static int handle_stray_noerror(void)
2051 while (ch
== '\\') {
2056 } else if (ch
== '\r') {
2070 static void handle_stray(void)
2072 if (handle_stray_noerror())
2073 error("stray '\\' in program");
2076 /* skip the stray and handle the \\n case. Output an error if
2077 incorrect char after the stray */
2078 static int handle_stray1(uint8_t *p
)
2082 if (p
>= file
->buf_end
) {
2099 /* handle just the EOB case, but not stray */
2100 #define PEEKC_EOB(c, p)\
2111 /* handle the complicated stray case */
2112 #define PEEKC(c, p)\
2117 c = handle_stray1(p);\
2122 /* input with '\[\r]\n' handling. Note that this function cannot
2123 handle other characters after '\', so you cannot call it inside
2124 strings or comments */
2125 static void minp(void)
2133 /* single line C++ comments */
2134 static uint8_t *parse_line_comment(uint8_t *p
)
2142 if (c
== '\n' || c
== CH_EOF
) {
2144 } else if (c
== '\\') {
2153 } else if (c
== '\r') {
2171 static uint8_t *parse_comment(uint8_t *p
)
2177 /* fast skip loop */
2180 if (c
== '\n' || c
== '*' || c
== '\\')
2184 if (c
== '\n' || c
== '*' || c
== '\\')
2188 /* now we can handle all the cases */
2192 } else if (c
== '*') {
2198 } else if (c
== '/') {
2199 goto end_of_comment
;
2200 } else if (c
== '\\') {
2205 /* skip '\[\r]\n', otherwise just skip the stray */
2211 } else if (c
== '\r') {
2228 /* stray, eob or eof */
2233 error("unexpected end of file in comment");
2234 } else if (c
== '\\') {
2246 /* space exlcuding newline */
2247 static inline int is_space(int ch
)
2249 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
2252 static inline void skip_spaces(void)
2254 while (is_space(ch
))
2258 /* parse a string without interpreting escapes */
2259 static uint8_t *parse_pp_string(uint8_t *p
,
2260 int sep
, CString
*str
)
2268 } else if (c
== '\\') {
2273 unterminated_string
:
2274 /* XXX: indicate line number of start of string */
2275 error("missing terminating %c character", sep
);
2276 } else if (c
== '\\') {
2277 /* escape : just skip \[\r]\n */
2282 } else if (c
== '\r') {
2285 expect("'\n' after '\r'");
2288 } else if (c
== CH_EOF
) {
2289 goto unterminated_string
;
2292 cstr_ccat(str
, '\\');
2298 } else if (c
== '\n') {
2301 } else if (c
== '\r') {
2305 cstr_ccat(str
, '\r');
2321 /* skip block of text until #else, #elif or #endif. skip also pairs of
2323 void preprocess_skip(void)
2325 int a
, start_of_line
, c
, in_warn_or_error
;
2332 in_warn_or_error
= 0;
2353 } else if (c
== '\\') {
2354 ch
= file
->buf_ptr
[0];
2355 handle_stray_noerror();
2362 if (in_warn_or_error
)
2364 p
= parse_pp_string(p
, c
, NULL
);
2368 if (in_warn_or_error
)
2375 p
= parse_comment(p
);
2376 } else if (ch
== '/') {
2377 p
= parse_line_comment(p
);
2382 if (start_of_line
) {
2387 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
2389 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
2391 else if (tok
== TOK_ENDIF
)
2393 else if( tok
== TOK_ERROR
|| tok
== TOK_WARNING
)
2394 in_warn_or_error
= 1;
2408 /* ParseState handling */
2410 /* XXX: currently, no include file info is stored. Thus, we cannot display
2411 accurate messages if the function or data definition spans multiple
2414 /* save current parse state in 's' */
2415 void save_parse_state(ParseState
*s
)
2417 s
->line_num
= file
->line_num
;
2418 s
->macro_ptr
= macro_ptr
;
2423 /* restore parse state from 's' */
2424 void restore_parse_state(ParseState
*s
)
2426 file
->line_num
= s
->line_num
;
2427 macro_ptr
= s
->macro_ptr
;
2432 /* return the number of additional 'ints' necessary to store the
2434 static inline int tok_ext_size(int t
)
2448 error("unsupported token");
2455 return LDOUBLE_SIZE
/ 4;
2461 /* token string handling */
2463 static inline void tok_str_new(TokenString
*s
)
2467 s
->allocated_len
= 0;
2468 s
->last_line_num
= -1;
2471 static void tok_str_free(int *str
)
2476 static int *tok_str_realloc(TokenString
*s
)
2480 if (s
->allocated_len
== 0) {
2483 len
= s
->allocated_len
* 2;
2485 str
= tcc_realloc(s
->str
, len
* sizeof(int));
2487 error("memory full");
2488 s
->allocated_len
= len
;
2493 static void tok_str_add(TokenString
*s
, int t
)
2499 if (len
>= s
->allocated_len
)
2500 str
= tok_str_realloc(s
);
2505 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
2512 /* allocate space for worst case */
2513 if (len
+ TOK_MAX_SIZE
> s
->allocated_len
)
2514 str
= tok_str_realloc(s
);
2523 str
[len
++] = cv
->tab
[0];
2532 nb_words
= (sizeof(CString
) + cv
->cstr
->size
+ 3) >> 2;
2533 while ((len
+ nb_words
) > s
->allocated_len
)
2534 str
= tok_str_realloc(s
);
2535 cstr
= (CString
*)(str
+ len
);
2537 cstr
->size
= cv
->cstr
->size
;
2538 cstr
->data_allocated
= NULL
;
2539 cstr
->size_allocated
= cstr
->size
;
2540 memcpy((char *)cstr
+ sizeof(CString
),
2541 cv
->cstr
->data
, cstr
->size
);
2548 #if LDOUBLE_SIZE == 8
2551 str
[len
++] = cv
->tab
[0];
2552 str
[len
++] = cv
->tab
[1];
2554 #if LDOUBLE_SIZE == 12
2556 str
[len
++] = cv
->tab
[0];
2557 str
[len
++] = cv
->tab
[1];
2558 str
[len
++] = cv
->tab
[2];
2559 #elif LDOUBLE_SIZE != 8
2560 #error add long double size support
2569 /* add the current parse token in token string 's' */
2570 static void tok_str_add_tok(TokenString
*s
)
2574 /* save line number info */
2575 if (file
->line_num
!= s
->last_line_num
) {
2576 s
->last_line_num
= file
->line_num
;
2577 cval
.i
= s
->last_line_num
;
2578 tok_str_add2(s
, TOK_LINENUM
, &cval
);
2580 tok_str_add2(s
, tok
, &tokc
);
2583 #if LDOUBLE_SIZE == 12
2584 #define LDOUBLE_GET(p, cv) \
2588 #elif LDOUBLE_SIZE == 8
2589 #define LDOUBLE_GET(p, cv) \
2593 #error add long double size support
2597 /* get a token from an integer array and increment pointer
2598 accordingly. we code it as a macro to avoid pointer aliasing. */
2599 #define TOK_GET(t, p, cv) \
2614 cv.cstr = (CString *)p; \
2615 cv.cstr->data = (char *)p + sizeof(CString);\
2616 p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\
2625 case TOK_CLDOUBLE: \
2626 LDOUBLE_GET(p, cv); \
2627 p += LDOUBLE_SIZE / 4; \
2634 /* defines handling */
2635 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
2639 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
2640 s
->next
= first_arg
;
2641 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
2644 /* undefined a define symbol. Its name is just set to zero */
2645 static void define_undef(Sym
*s
)
2649 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2650 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2654 static inline Sym
*define_find(int v
)
2657 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2659 return table_ident
[v
]->sym_define
;
2662 /* free define stack until top reaches 'b' */
2663 static void free_defines(Sym
*b
)
2671 /* do not free args or predefined defines */
2673 tok_str_free((int *)top
->c
);
2675 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2676 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2684 static Sym
*label_find(int v
)
2687 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2689 return table_ident
[v
]->sym_label
;
2692 static Sym
*label_push(Sym
**ptop
, int v
, int flags
)
2695 s
= sym_push2(ptop
, v
, 0, 0);
2697 ps
= &table_ident
[v
- TOK_IDENT
]->sym_label
;
2698 if (ptop
== &global_label_stack
) {
2699 /* modify the top most local identifier, so that
2700 sym_identifier will point to 's' when popped */
2702 ps
= &(*ps
)->prev_tok
;
2709 /* pop labels until element last is reached. Look if any labels are
2710 undefined. Define symbols if '&&label' was used. */
2711 static void label_pop(Sym
**ptop
, Sym
*slast
)
2714 for(s
= *ptop
; s
!= slast
; s
= s1
) {
2716 if (s
->r
== LABEL_DECLARED
) {
2717 warning("label '%s' declared but not used", get_tok_str(s
->v
, NULL
));
2718 } else if (s
->r
== LABEL_FORWARD
) {
2719 error("label '%s' used but not defined",
2720 get_tok_str(s
->v
, NULL
));
2723 /* define corresponding symbol. A size of
2725 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
2729 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= s
->prev_tok
;
2735 /* eval an expression for #if/#elif */
2736 static int expr_preprocess(void)
2742 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2743 next(); /* do macro subst */
2744 if (tok
== TOK_DEFINED
) {
2749 c
= define_find(tok
) != 0;
2754 } else if (tok
>= TOK_IDENT
) {
2755 /* if undefined macro */
2759 tok_str_add_tok(&str
);
2761 tok_str_add(&str
, -1); /* simulate end of file */
2762 tok_str_add(&str
, 0);
2763 /* now evaluate C constant expression */
2764 macro_ptr
= str
.str
;
2768 tok_str_free(str
.str
);
2772 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2773 static void tok_print(int *str
)
2779 TOK_GET(t
, str
, cval
);
2782 printf(" %s", get_tok_str(t
, &cval
));
2788 /* parse after #define */
2789 static void parse_define(void)
2791 Sym
*s
, *first
, **ps
;
2792 int v
, t
, varg
, is_vaargs
, c
;
2797 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2798 /* XXX: should check if same macro (ANSI) */
2801 /* '(' must be just after macro definition for MACRO_FUNC */
2802 c
= file
->buf_ptr
[0];
2804 c
= handle_stray1(file
->buf_ptr
);
2809 while (tok
!= ')') {
2813 if (varg
== TOK_DOTS
) {
2814 varg
= TOK___VA_ARGS__
;
2816 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2820 if (varg
< TOK_IDENT
)
2821 error("badly punctuated parameter list");
2822 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2833 /* EOF testing necessary for '-D' handling */
2834 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2835 tok_str_add2(&str
, tok
, &tokc
);
2838 tok_str_add(&str
, 0);
2840 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2843 define_push(v
, t
, str
.str
, first
);
2846 static inline int hash_cached_include(int type
, const char *filename
)
2848 const unsigned char *s
;
2852 h
= TOK_HASH_FUNC(h
, type
);
2855 h
= TOK_HASH_FUNC(h
, *s
);
2858 h
&= (CACHED_INCLUDES_HASH_SIZE
- 1);
2862 /* XXX: use a token or a hash table to accelerate matching ? */
2863 static CachedInclude
*search_cached_include(TCCState
*s1
,
2864 int type
, const char *filename
)
2868 h
= hash_cached_include(type
, filename
);
2869 i
= s1
->cached_includes_hash
[h
];
2873 e
= s1
->cached_includes
[i
- 1];
2874 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2881 static inline void add_cached_include(TCCState
*s1
, int type
,
2882 const char *filename
, int ifndef_macro
)
2887 if (search_cached_include(s1
, type
, filename
))
2890 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2892 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2896 strcpy(e
->filename
, filename
);
2897 e
->ifndef_macro
= ifndef_macro
;
2898 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2899 /* add in hash table */
2900 h
= hash_cached_include(type
, filename
);
2901 e
->hash_next
= s1
->cached_includes_hash
[h
];
2902 s1
->cached_includes_hash
[h
] = s1
->nb_cached_includes
;
2905 static void pragma_parse(TCCState
*s1
)
2910 if (tok
== TOK_pack
) {
2913 #pragma pack(1) // set
2914 #pragma pack() // reset to default
2915 #pragma pack(push,1) // push & set
2916 #pragma pack(pop) // restore previous
2920 if (tok
== TOK_ASM_pop
) {
2922 if (s1
->pack_stack_ptr
<= s1
->pack_stack
) {
2924 error("out of pack stack");
2926 s1
->pack_stack_ptr
--;
2930 if (tok
== TOK_ASM_push
) {
2932 if (s1
->pack_stack_ptr
>= s1
->pack_stack
+ PACK_STACK_SIZE
- 1)
2934 s1
->pack_stack_ptr
++;
2937 if (tok
!= TOK_CINT
) {
2939 error("invalid pack pragma");
2942 if (val
< 1 || val
> 16 || (val
& (val
- 1)) != 0)
2946 *s1
->pack_stack_ptr
= val
;
2952 /* is_bof is true if first non space token at beginning of file */
2953 static void preprocess(int is_bof
)
2955 TCCState
*s1
= tcc_state
;
2956 int size
, i
, c
, n
, saved_parse_flags
;
2963 saved_parse_flags
= parse_flags
;
2964 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
|
2965 PARSE_FLAG_LINEFEED
;
2975 s
= define_find(tok
);
2976 /* undefine symbol by putting an invalid name */
2981 case TOK_INCLUDE_NEXT
:
2982 ch
= file
->buf_ptr
[0];
2983 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2988 } else if (ch
== '\"') {
2993 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2994 if ((q
- buf
) < sizeof(buf
) - 1)
2997 if (handle_stray_noerror() == 0)
3005 /* eat all spaces and comments after include */
3006 /* XXX: slightly incorrect */
3007 while (ch1
!= '\n' && ch1
!= CH_EOF
)
3011 /* computed #include : either we have only strings or
3012 we have anything enclosed in '<>' */
3015 if (tok
== TOK_STR
) {
3016 while (tok
!= TOK_LINEFEED
) {
3017 if (tok
!= TOK_STR
) {
3019 error("'#include' expects \"FILENAME\" or <FILENAME>");
3021 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
3027 while (tok
!= TOK_LINEFEED
) {
3028 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
3032 /* check syntax and remove '<>' */
3033 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
3034 goto include_syntax
;
3035 memmove(buf
, buf
+ 1, len
- 2);
3036 buf
[len
- 2] = '\0';
3041 e
= search_cached_include(s1
, c
, buf
);
3042 if (e
&& define_find(e
->ifndef_macro
)) {
3043 /* no need to parse the include because the 'ifndef macro'
3046 printf("%s: skipping %s\n", file
->filename
, buf
);
3049 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
3050 error("#include recursion too deep");
3051 /* push current file in stack */
3052 /* XXX: fix current line init */
3053 *s1
->include_stack_ptr
++ = file
;
3055 /* first search in current dir if "header.h" */
3056 size
= tcc_basename(file
->filename
) - file
->filename
;
3057 if (size
> sizeof(buf1
) - 1)
3058 size
= sizeof(buf1
) - 1;
3059 memcpy(buf1
, file
->filename
, size
);
3061 pstrcat(buf1
, sizeof(buf1
), buf
);
3062 f
= tcc_open(s1
, buf1
);
3064 if (tok
== TOK_INCLUDE_NEXT
)
3070 /* now search in all the include paths */
3071 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
3072 for(i
= 0; i
< n
; i
++) {
3074 if (i
< s1
->nb_include_paths
)
3075 path
= s1
->include_paths
[i
];
3077 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
3078 pstrcpy(buf1
, sizeof(buf1
), path
);
3079 pstrcat(buf1
, sizeof(buf1
), "/");
3080 pstrcat(buf1
, sizeof(buf1
), buf
);
3081 f
= tcc_open(s1
, buf1
);
3083 if (tok
== TOK_INCLUDE_NEXT
)
3089 --s1
->include_stack_ptr
;
3090 error("include file '%s' not found", buf
);
3094 printf("%s: including %s\n", file
->filename
, buf1
);
3097 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
3099 /* add include file debug info */
3101 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
3103 tok_flags
|= TOK_FLAG_BOF
| TOK_FLAG_BOL
;
3104 ch
= file
->buf_ptr
[0];
3112 c
= expr_preprocess();
3118 if (tok
< TOK_IDENT
)
3119 error("invalid argument for '#if%sdef'", c
? "n" : "");
3123 printf("#ifndef %s\n", get_tok_str(tok
, NULL
));
3125 file
->ifndef_macro
= tok
;
3128 c
= (define_find(tok
) != 0) ^ c
;
3130 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
3131 error("memory full");
3132 *s1
->ifdef_stack_ptr
++ = c
;
3135 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
3136 error("#else without matching #if");
3137 if (s1
->ifdef_stack_ptr
[-1] & 2)
3138 error("#else after #else");
3139 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
3142 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
3143 error("#elif without matching #if");
3144 c
= s1
->ifdef_stack_ptr
[-1];
3146 error("#elif after #else");
3147 /* last #if/#elif expression was true: we skip */
3150 c
= expr_preprocess();
3151 s1
->ifdef_stack_ptr
[-1] = c
;
3161 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
3162 error("#endif without matching #if");
3163 s1
->ifdef_stack_ptr
--;
3164 /* '#ifndef macro' was at the start of file. Now we check if
3165 an '#endif' is exactly at the end of file */
3166 if (file
->ifndef_macro
&&
3167 s1
->ifdef_stack_ptr
== file
->ifdef_stack_ptr
) {
3168 file
->ifndef_macro_saved
= file
->ifndef_macro
;
3169 /* need to set to zero to avoid false matches if another
3170 #ifndef at middle of file */
3171 file
->ifndef_macro
= 0;
3172 while (tok
!= TOK_LINEFEED
)
3174 tok_flags
|= TOK_FLAG_ENDIF
;
3180 if (tok
!= TOK_CINT
)
3182 file
->line_num
= tokc
.i
- 1; /* the line number will be incremented after */
3184 if (tok
!= TOK_LINEFEED
) {
3187 pstrcpy(file
->filename
, sizeof(file
->filename
),
3188 (char *)tokc
.cstr
->data
);
3194 ch
= file
->buf_ptr
[0];
3197 while (ch
!= '\n' && ch
!= CH_EOF
) {
3198 if ((q
- buf
) < sizeof(buf
) - 1)
3201 if (handle_stray_noerror() == 0)
3208 error("#error %s", buf
);
3210 warning("#warning %s", buf
);
3216 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
3217 /* '!' is ignored to allow C scripts. numbers are ignored
3218 to emulate cpp behaviour */
3220 if (!(saved_parse_flags
& PARSE_FLAG_ASM_COMMENTS
))
3221 warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok
, &tokc
));
3225 /* ignore other preprocess commands or #! for C scripts */
3226 while (tok
!= TOK_LINEFEED
)
3229 parse_flags
= saved_parse_flags
;
3232 /* evaluate escape codes in a string. */
3233 static void parse_escape_string(CString
*outstr
, const uint8_t *buf
, int is_long
)
3248 case '0': case '1': case '2': case '3':
3249 case '4': case '5': case '6': case '7':
3250 /* at most three octal digits */
3255 n
= n
* 8 + c
- '0';
3259 n
= n
* 8 + c
- '0';
3264 goto add_char_nonext
;
3272 if (c
>= 'a' && c
<= 'f')
3274 else if (c
>= 'A' && c
<= 'F')
3284 goto add_char_nonext
;
3308 goto invalid_escape
;
3318 if (c
>= '!' && c
<= '~')
3319 warning("unknown escape sequence: \'\\%c\'", c
);
3321 warning("unknown escape sequence: \'\\x%x\'", c
);
3328 cstr_ccat(outstr
, c
);
3330 cstr_wccat(outstr
, c
);
3332 /* add a trailing '\0' */
3334 cstr_ccat(outstr
, '\0');
3336 cstr_wccat(outstr
, '\0');
3339 /* we use 64 bit numbers */
3342 /* bn = (bn << shift) | or_val */
3343 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
3347 for(i
=0;i
<BN_SIZE
;i
++) {
3349 bn
[i
] = (v
<< shift
) | or_val
;
3350 or_val
= v
>> (32 - shift
);
3354 void bn_zero(unsigned int *bn
)
3357 for(i
=0;i
<BN_SIZE
;i
++) {
3362 /* parse number in null terminated string 'p' and return it in the
3364 void parse_number(const char *p
)
3366 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
3368 unsigned int bn
[BN_SIZE
];
3379 goto float_frac_parse
;
3380 } else if (t
== '0') {
3381 if (ch
== 'x' || ch
== 'X') {
3385 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
3391 /* parse all digits. cannot check octal numbers at this stage
3392 because of floating point constants */
3394 if (ch
>= 'a' && ch
<= 'f')
3396 else if (ch
>= 'A' && ch
<= 'F')
3404 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
3406 error("number too long");
3412 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
3413 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
3415 /* NOTE: strtox should support that for hexa numbers, but
3416 non ISOC99 libcs do not support it, so we prefer to do
3418 /* hexadecimal or binary floats */
3419 /* XXX: handle overflows */
3431 } else if (t
>= 'a') {
3433 } else if (t
>= 'A') {
3438 bn_lshift(bn
, shift
, t
);
3445 if (t
>= 'a' && t
<= 'f') {
3447 } else if (t
>= 'A' && t
<= 'F') {
3449 } else if (t
>= '0' && t
<= '9') {
3455 error("invalid digit");
3456 bn_lshift(bn
, shift
, t
);
3461 if (ch
!= 'p' && ch
!= 'P')
3468 } else if (ch
== '-') {
3472 if (ch
< '0' || ch
> '9')
3473 expect("exponent digits");
3474 while (ch
>= '0' && ch
<= '9') {
3475 exp_val
= exp_val
* 10 + ch
- '0';
3478 exp_val
= exp_val
* s
;
3480 /* now we can generate the number */
3481 /* XXX: should patch directly float number */
3482 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
3483 d
= ldexp(d
, exp_val
- frac_bits
);
3488 /* float : should handle overflow */
3490 } else if (t
== 'L') {
3493 /* XXX: not large enough */
3494 tokc
.ld
= (long double)d
;
3500 /* decimal floats */
3502 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3507 while (ch
>= '0' && ch
<= '9') {
3508 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3514 if (ch
== 'e' || ch
== 'E') {
3515 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3519 if (ch
== '-' || ch
== '+') {
3520 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3525 if (ch
< '0' || ch
> '9')
3526 expect("exponent digits");
3527 while (ch
>= '0' && ch
<= '9') {
3528 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3540 tokc
.f
= strtof(token_buf
, NULL
);
3541 } else if (t
== 'L') {
3544 tokc
.ld
= strtold(token_buf
, NULL
);
3547 tokc
.d
= strtod(token_buf
, NULL
);
3551 unsigned long long n
, n1
;
3554 /* integer number */
3557 if (b
== 10 && *q
== '0') {
3564 /* no need for checks except for base 10 / 8 errors */
3567 } else if (t
>= 'a') {
3569 } else if (t
>= 'A') {
3574 error("invalid digit");
3578 /* detect overflow */
3579 /* XXX: this test is not reliable */
3581 error("integer constant overflow");
3584 /* XXX: not exactly ANSI compliant */
3585 if ((n
& 0xffffffff00000000LL
) != 0) {
3590 } else if (n
> 0x7fffffff) {
3601 error("three 'l's in integer constant");
3604 if (tok
== TOK_CINT
)
3606 else if (tok
== TOK_CUINT
)
3610 } else if (t
== 'U') {
3612 error("two 'u's in integer constant");
3614 if (tok
== TOK_CINT
)
3616 else if (tok
== TOK_CLLONG
)
3623 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
3631 #define PARSE2(c1, tok1, c2, tok2) \
3642 /* return next token without macro substitution */
3643 static inline void next_nomacro1(void)
3663 /* first look if it is in fact an end of buffer */
3664 if (p
>= file
->buf_end
) {
3668 if (p
>= file
->buf_end
)
3681 TCCState
*s1
= tcc_state
;
3682 if ((parse_flags
& PARSE_FLAG_LINEFEED
)
3683 && !(tok_flags
& TOK_FLAG_EOF
)) {
3684 tok_flags
|= TOK_FLAG_EOF
;
3686 goto keep_tok_flags
;
3687 } else if (s1
->include_stack_ptr
== s1
->include_stack
||
3688 !(parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3689 /* no include left : end of file. */
3692 tok_flags
&= ~TOK_FLAG_EOF
;
3693 /* pop include file */
3695 /* test if previous '#endif' was after a #ifdef at
3697 if (tok_flags
& TOK_FLAG_ENDIF
) {
3699 printf("#endif %s\n", get_tok_str(file
->ifndef_macro_saved
, NULL
));
3701 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
3702 file
->ifndef_macro_saved
);
3705 /* add end of include file debug info */
3707 put_stabd(N_EINCL
, 0, 0);
3709 /* pop include stack */
3711 s1
->include_stack_ptr
--;
3712 file
= *s1
->include_stack_ptr
;
3721 tok_flags
|= TOK_FLAG_BOL
;
3723 if (0 == (parse_flags
& PARSE_FLAG_LINEFEED
))
3726 goto keep_tok_flags
;
3731 if ((tok_flags
& TOK_FLAG_BOL
) &&
3732 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3734 preprocess(tok_flags
& TOK_FLAG_BOF
);
3740 tok
= TOK_TWOSHARPS
;
3742 if (parse_flags
& PARSE_FLAG_ASM_COMMENTS
) {
3743 p
= parse_line_comment(p
- 1);
3752 case 'a': case 'b': case 'c': case 'd':
3753 case 'e': case 'f': case 'g': case 'h':
3754 case 'i': case 'j': case 'k': case 'l':
3755 case 'm': case 'n': case 'o': case 'p':
3756 case 'q': case 'r': case 's': case 't':
3757 case 'u': case 'v': case 'w': case 'x':
3759 case 'A': case 'B': case 'C': case 'D':
3760 case 'E': case 'F': case 'G': case 'H':
3761 case 'I': case 'J': case 'K':
3762 case 'M': case 'N': case 'O': case 'P':
3763 case 'Q': case 'R': case 'S': case 'T':
3764 case 'U': case 'V': case 'W': case 'X':
3770 h
= TOK_HASH_FUNC(h
, c
);
3774 if (!isidnum_table
[c
])
3776 h
= TOK_HASH_FUNC(h
, c
);
3783 /* fast case : no stray found, so we have the full token
3784 and we have already hashed it */
3786 h
&= (TOK_HASH_SIZE
- 1);
3787 pts
= &hash_ident
[h
];
3792 if (ts
->len
== len
&& !memcmp(ts
->str
, p1
, len
))
3794 pts
= &(ts
->hash_next
);
3796 ts
= tok_alloc_new(pts
, p1
, len
);
3800 cstr_reset(&tokcstr
);
3803 cstr_ccat(&tokcstr
, *p1
);
3809 while (isidnum_table
[c
]) {
3810 cstr_ccat(&tokcstr
, c
);
3813 ts
= tok_alloc(tokcstr
.data
, tokcstr
.size
);
3819 if (t
!= '\\' && t
!= '\'' && t
!= '\"') {
3821 goto parse_ident_fast
;
3824 if (c
== '\'' || c
== '\"') {
3828 cstr_reset(&tokcstr
);
3829 cstr_ccat(&tokcstr
, 'L');
3830 goto parse_ident_slow
;
3834 case '0': case '1': case '2': case '3':
3835 case '4': case '5': case '6': case '7':
3838 cstr_reset(&tokcstr
);
3839 /* after the first digit, accept digits, alpha, '.' or sign if
3840 prefixed by 'eEpP' */
3844 cstr_ccat(&tokcstr
, c
);
3846 if (!(isnum(c
) || isid(c
) || c
== '.' ||
3847 ((c
== '+' || c
== '-') &&
3848 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
3851 /* We add a trailing '\0' to ease parsing */
3852 cstr_ccat(&tokcstr
, '\0');
3853 tokc
.cstr
= &tokcstr
;
3857 /* special dot handling because it can also start a number */
3860 cstr_reset(&tokcstr
);
3861 cstr_ccat(&tokcstr
, '.');
3863 } else if (c
== '.') {
3883 /* parse the string */
3885 p
= parse_pp_string(p
, sep
, &str
);
3886 cstr_ccat(&str
, '\0');
3888 /* eval the escape (should be done as TOK_PPNUM) */
3889 cstr_reset(&tokcstr
);
3890 parse_escape_string(&tokcstr
, str
.data
, is_long
);
3895 /* XXX: make it portable */
3899 char_size
= sizeof(nwchar_t
);
3900 if (tokcstr
.size
<= char_size
)
3901 error("empty character constant");
3902 if (tokcstr
.size
> 2 * char_size
)
3903 warning("multi-character character constant");
3905 tokc
.i
= *(int8_t *)tokcstr
.data
;
3908 tokc
.i
= *(nwchar_t
*)tokcstr
.data
;
3912 tokc
.cstr
= &tokcstr
;
3926 } else if (c
== '<') {
3944 } else if (c
== '>') {
3962 } else if (c
== '=') {
3975 } else if (c
== '=') {
3988 } else if (c
== '=') {
4001 } else if (c
== '=') {
4004 } else if (c
== '>') {
4012 PARSE2('!', '!', '=', TOK_NE
)
4013 PARSE2('=', '=', '=', TOK_EQ
)
4014 PARSE2('*', '*', '=', TOK_A_MUL
)
4015 PARSE2('%', '%', '=', TOK_A_MOD
)
4016 PARSE2('^', '^', '=', TOK_A_XOR
)
4018 /* comments or operator */
4022 p
= parse_comment(p
);
4024 } else if (c
== '/') {
4025 p
= parse_line_comment(p
);
4027 } else if (c
== '=') {
4047 case '$': /* only used in assembler */
4048 case '@': /* dito */
4053 error("unrecognized character \\x%02x", c
);
4059 #if defined(PARSE_DEBUG)
4060 printf("token = %s\n", get_tok_str(tok
, &tokc
));
4064 /* return next token without macro substitution. Can read input from
4066 static void next_nomacro(void)
4072 TOK_GET(tok
, macro_ptr
, tokc
);
4073 if (tok
== TOK_LINENUM
) {
4074 file
->line_num
= tokc
.i
;
4083 /* substitute args in macro_str and return allocated string */
4084 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
4086 int *st
, last_tok
, t
, notfirst
;
4095 TOK_GET(t
, macro_str
, cval
);
4100 TOK_GET(t
, macro_str
, cval
);
4103 s
= sym_find2(args
, t
);
4110 cstr_ccat(&cstr
, ' ');
4111 TOK_GET(t
, st
, cval
);
4112 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
4117 cstr_ccat(&cstr
, '\0');
4119 printf("stringize: %s\n", (char *)cstr
.data
);
4123 tok_str_add2(&str
, TOK_STR
, &cval
);
4126 tok_str_add2(&str
, t
, &cval
);
4128 } else if (t
>= TOK_IDENT
) {
4129 s
= sym_find2(args
, t
);
4132 /* if '##' is present before or after, no arg substitution */
4133 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
4134 /* special case for var arg macros : ## eats the
4135 ',' if empty VA_ARGS variable. */
4136 /* XXX: test of the ',' is not 100%
4137 reliable. should fix it to avoid security
4139 if (gnu_ext
&& s
->type
.t
&&
4140 last_tok
== TOK_TWOSHARPS
&&
4141 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
4143 /* suppress ',' '##' */
4146 /* suppress '##' and add variable */
4154 TOK_GET(t1
, st
, cval
);
4157 tok_str_add2(&str
, t1
, &cval
);
4161 /* NOTE: the stream cannot be read when macro
4162 substituing an argument */
4163 macro_subst(&str
, nested_list
, st
, NULL
);
4166 tok_str_add(&str
, t
);
4169 tok_str_add2(&str
, t
, &cval
);
4173 tok_str_add(&str
, 0);
4177 static char const ab_month_name
[12][4] =
4179 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
4180 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
4183 /* do macro substitution of current token with macro 's' and add
4184 result to (tok_str,tok_len). 'nested_list' is the list of all
4185 macros we got inside to avoid recursing. Return non zero if no
4186 substitution needs to be done */
4187 static int macro_subst_tok(TokenString
*tok_str
,
4188 Sym
**nested_list
, Sym
*s
, struct macro_level
**can_read_stream
)
4190 Sym
*args
, *sa
, *sa1
;
4191 int mstr_allocated
, parlevel
, *mstr
, t
, t1
;
4198 /* if symbol is a macro, prepare substitution */
4199 /* special macros */
4200 if (tok
== TOK___LINE__
) {
4201 snprintf(buf
, sizeof(buf
), "%d", file
->line_num
);
4205 } else if (tok
== TOK___FILE__
) {
4206 cstrval
= file
->filename
;
4208 } else if (tok
== TOK___DATE__
|| tok
== TOK___TIME__
) {
4213 tm
= localtime(&ti
);
4214 if (tok
== TOK___DATE__
) {
4215 snprintf(buf
, sizeof(buf
), "%s %2d %d",
4216 ab_month_name
[tm
->tm_mon
], tm
->tm_mday
, tm
->tm_year
+ 1900);
4218 snprintf(buf
, sizeof(buf
), "%02d:%02d:%02d",
4219 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
4226 cstr_cat(&cstr
, cstrval
);
4227 cstr_ccat(&cstr
, '\0');
4229 tok_str_add2(tok_str
, t1
, &cval
);
4234 if (s
->type
.t
== MACRO_FUNC
) {
4235 /* NOTE: we do not use next_nomacro to avoid eating the
4236 next token. XXX: find better solution */
4240 if (t
== 0 && can_read_stream
) {
4241 /* end of macro stream: we must look at the token
4242 after in the file */
4243 struct macro_level
*ml
= *can_read_stream
;
4249 *can_read_stream
= ml
-> prev
;
4254 /* XXX: incorrect with comments */
4255 ch
= file
->buf_ptr
[0];
4256 while (is_space(ch
) || ch
== '\n')
4260 if (t
!= '(') /* no macro subst */
4263 /* argument macro */
4268 /* NOTE: empty args are allowed, except if no args */
4270 /* handle '()' case */
4271 if (!args
&& !sa
&& tok
== ')')
4274 error("macro '%s' used with too many args",
4275 get_tok_str(s
->v
, 0));
4278 /* NOTE: non zero sa->t indicates VA_ARGS */
4279 while ((parlevel
> 0 ||
4281 (tok
!= ',' || sa
->type
.t
))) &&
4285 else if (tok
== ')')
4287 if (tok
!= TOK_LINEFEED
)
4288 tok_str_add2(&str
, tok
, &tokc
);
4291 tok_str_add(&str
, 0);
4292 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
4295 /* special case for gcc var args: add an empty
4296 var arg argument if it is omitted */
4297 if (sa
&& sa
->type
.t
&& gnu_ext
)
4307 error("macro '%s' used with too few args",
4308 get_tok_str(s
->v
, 0));
4311 /* now subst each arg */
4312 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
4317 tok_str_free((int *)sa
->c
);
4323 sym_push2(nested_list
, s
->v
, 0, 0);
4324 macro_subst(tok_str
, nested_list
, mstr
, can_read_stream
);
4325 /* pop nested defined symbol */
4327 *nested_list
= sa1
->prev
;
4335 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
4336 return the resulting string (which must be freed). */
4337 static inline int *macro_twosharps(const int *macro_str
)
4340 const int *macro_ptr1
, *start_macro_ptr
, *ptr
, *saved_macro_ptr
;
4342 const char *p1
, *p2
;
4344 TokenString macro_str1
;
4347 start_macro_ptr
= macro_str
;
4348 /* we search the first '##' */
4350 macro_ptr1
= macro_str
;
4351 TOK_GET(t
, macro_str
, cval
);
4352 /* nothing more to do if end of string */
4355 if (*macro_str
== TOK_TWOSHARPS
)
4359 /* we saw '##', so we need more processing to handle it */
4361 tok_str_new(¯o_str1
);
4365 /* add all tokens seen so far */
4366 for(ptr
= start_macro_ptr
; ptr
< macro_ptr1
;) {
4367 TOK_GET(t
, ptr
, cval
);
4368 tok_str_add2(¯o_str1
, t
, &cval
);
4370 saved_macro_ptr
= macro_ptr
;
4371 /* XXX: get rid of the use of macro_ptr here */
4372 macro_ptr
= (int *)macro_str
;
4374 while (*macro_ptr
== TOK_TWOSHARPS
) {
4376 macro_ptr1
= macro_ptr
;
4379 TOK_GET(t
, macro_ptr
, cval
);
4380 /* We concatenate the two tokens if we have an
4381 identifier or a preprocessing number */
4383 p1
= get_tok_str(tok
, &tokc
);
4384 cstr_cat(&cstr
, p1
);
4385 p2
= get_tok_str(t
, &cval
);
4386 cstr_cat(&cstr
, p2
);
4387 cstr_ccat(&cstr
, '\0');
4389 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
4390 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
4391 if (tok
== TOK_PPNUM
) {
4392 /* if number, then create a number token */
4393 /* NOTE: no need to allocate because
4394 tok_str_add2() does it */
4395 cstr_reset(&tokcstr
);
4398 tokc
.cstr
= &tokcstr
;
4400 /* if identifier, we must do a test to
4401 validate we have a correct identifier */
4402 if (t
== TOK_PPNUM
) {
4412 if (!isnum(c
) && !isid(c
))
4416 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
4417 tok
= ts
->tok
; /* modify current token */
4420 const char *str
= cstr
.data
;
4421 const unsigned char *q
;
4423 /* we look for a valid token */
4424 /* XXX: do more extensive checks */
4425 if (!strcmp(str
, ">>=")) {
4427 } else if (!strcmp(str
, "<<=")) {
4429 } else if (strlen(str
) == 2) {
4430 /* search in two bytes table */
4435 if (q
[0] == str
[0] && q
[1] == str
[1])
4442 /* NOTE: because get_tok_str use a static buffer,
4445 p1
= get_tok_str(tok
, &tokc
);
4446 cstr_cat(&cstr
, p1
);
4447 cstr_ccat(&cstr
, '\0');
4448 p2
= get_tok_str(t
, &cval
);
4449 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
4450 /* cannot merge tokens: just add them separately */
4451 tok_str_add2(¯o_str1
, tok
, &tokc
);
4452 /* XXX: free associated memory ? */
4459 tok_str_add2(¯o_str1
, tok
, &tokc
);
4464 macro_ptr
= (int *)saved_macro_ptr
;
4466 tok_str_add(¯o_str1
, 0);
4467 return macro_str1
.str
;
4471 /* do macro substitution of macro_str and add result to
4472 (tok_str,tok_len). 'nested_list' is the list of all macros we got
4473 inside to avoid recursing. */
4474 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
4475 const int *macro_str
, struct macro_level
** can_read_stream
)
4482 struct macro_level ml
;
4484 /* first scan for '##' operator handling */
4486 macro_str1
= macro_twosharps(ptr
);
4490 /* NOTE: ptr == NULL can only happen if tokens are read from
4491 file stream due to a macro function call */
4494 TOK_GET(t
, ptr
, cval
);
4499 /* if nested substitution, do nothing */
4500 if (sym_find2(*nested_list
, t
))
4503 if (can_read_stream
)
4504 ml
.prev
= *can_read_stream
, *can_read_stream
= &ml
;
4505 macro_ptr
= (int *)ptr
;
4507 ret
= macro_subst_tok(tok_str
, nested_list
, s
, can_read_stream
);
4508 ptr
= (int *)macro_ptr
;
4510 if (can_read_stream
&& *can_read_stream
== &ml
)
4511 *can_read_stream
= ml
.prev
;
4516 tok_str_add2(tok_str
, t
, &cval
);
4520 tok_str_free(macro_str1
);
4523 /* return next token with macro substitution */
4524 static void next(void)
4526 Sym
*nested_list
, *s
;
4528 struct macro_level
*ml
;
4533 /* if not reading from macro substituted string, then try
4534 to substitute macros */
4535 if (tok
>= TOK_IDENT
&&
4536 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
4537 s
= define_find(tok
);
4539 /* we have a macro: we try to substitute */
4543 if (macro_subst_tok(&str
, &nested_list
, s
, &ml
) == 0) {
4544 /* substitution done, NOTE: maybe empty */
4545 tok_str_add(&str
, 0);
4546 macro_ptr
= str
.str
;
4547 macro_ptr_allocated
= str
.str
;
4554 /* end of macro or end of unget buffer */
4555 if (unget_buffer_enabled
) {
4556 macro_ptr
= unget_saved_macro_ptr
;
4557 unget_buffer_enabled
= 0;
4559 /* end of macro string: free it */
4560 tok_str_free(macro_ptr_allocated
);
4567 /* convert preprocessor tokens into C tokens */
4568 if (tok
== TOK_PPNUM
&&
4569 (parse_flags
& PARSE_FLAG_TOK_NUM
)) {
4570 parse_number((char *)tokc
.cstr
->data
);
4574 /* push back current token and set current token to 'last_tok'. Only
4575 identifier case handled for labels. */
4576 static inline void unget_tok(int last_tok
)
4580 unget_saved_macro_ptr
= macro_ptr
;
4581 unget_buffer_enabled
= 1;
4582 q
= unget_saved_buffer
;
4585 n
= tok_ext_size(tok
) - 1;
4588 *q
= 0; /* end of token string */
4593 void swap(int *p
, int *q
)
4601 void vsetc(CType
*type
, int r
, CValue
*vc
)
4605 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
4606 error("memory full");
4607 /* cannot let cpu flags if other instruction are generated. Also
4608 avoid leaving VT_JMP anywhere except on the top of the stack
4609 because it would complicate the code generator. */
4610 if (vtop
>= vstack
) {
4611 v
= vtop
->r
& VT_VALMASK
;
4612 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
4618 vtop
->r2
= VT_CONST
;
4622 /* push integer constant */
4627 vsetc(&int_type
, VT_CONST
, &cval
);
4630 /* Return a static symbol pointing to a section */
4631 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
4632 unsigned long offset
, unsigned long size
)
4638 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
4639 sym
->type
.ref
= type
->ref
;
4640 sym
->r
= VT_CONST
| VT_SYM
;
4641 put_extern_sym(sym
, sec
, offset
, size
);
4645 /* push a reference to a section offset by adding a dummy symbol */
4646 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
4651 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4652 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
4655 /* define a new external reference to a symbol 'v' of type 'u' */
4656 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
4662 /* push forward reference */
4663 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
4664 s
->type
.ref
= type
->ref
;
4665 s
->r
= r
| VT_CONST
| VT_SYM
;
4670 /* define a new external reference to a symbol 'v' of type 'u' */
4671 static Sym
*external_sym(int v
, CType
*type
, int r
)
4677 /* push forward reference */
4678 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
4679 s
->type
.t
|= VT_EXTERN
;
4681 if (!is_compatible_types(&s
->type
, type
))
4682 error("incompatible types for redefinition of '%s'",
4683 get_tok_str(v
, NULL
));
4688 /* push a reference to global symbol v */
4689 static void vpush_global_sym(CType
*type
, int v
)
4694 sym
= external_global_sym(v
, type
, 0);
4696 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4700 void vset(CType
*type
, int r
, int v
)
4705 vsetc(type
, r
, &cval
);
4708 void vseti(int r
, int v
)
4724 void vpushv(SValue
*v
)
4726 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
4727 error("memory full");
4737 /* save r to the memory stack, and mark it as being free */
4738 void save_reg(int r
)
4740 int l
, saved
, size
, align
;
4744 /* modify all stack values */
4747 for(p
=vstack
;p
<=vtop
;p
++) {
4748 if ((p
->r
& VT_VALMASK
) == r
||
4749 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& (p
->r2
& VT_VALMASK
) == r
)) {
4750 /* must save value on stack if not already done */
4752 /* NOTE: must reload 'r' because r might be equal to r2 */
4753 r
= p
->r
& VT_VALMASK
;
4754 /* store register in the stack */
4756 if ((p
->r
& VT_LVAL
) ||
4757 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
4759 size
= type_size(type
, &align
);
4760 loc
= (loc
- size
) & -align
;
4761 sv
.type
.t
= type
->t
;
4762 sv
.r
= VT_LOCAL
| VT_LVAL
;
4765 #ifdef TCC_TARGET_I386
4766 /* x86 specific: need to pop fp register ST0 if saved */
4767 if (r
== TREG_ST0
) {
4768 o(0xd9dd); /* fstp %st(1) */
4771 /* special long long case */
4772 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
4779 /* mark that stack entry as being saved on the stack */
4780 if (p
->r
& VT_LVAL
) {
4781 /* also clear the bounded flag because the
4782 relocation address of the function was stored in
4784 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
4786 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
4794 /* find a register of class 'rc2' with at most one reference on stack.
4795 * If none, call get_reg(rc) */
4796 int get_reg_ex(int rc
, int rc2
)
4801 for(r
=0;r
<NB_REGS
;r
++) {
4802 if (reg_classes
[r
] & rc2
) {
4805 for(p
= vstack
; p
<= vtop
; p
++) {
4806 if ((p
->r
& VT_VALMASK
) == r
||
4807 (p
->r2
& VT_VALMASK
) == r
)
4817 /* find a free register of class 'rc'. If none, save one register */
4823 /* find a free register */
4824 for(r
=0;r
<NB_REGS
;r
++) {
4825 if (reg_classes
[r
] & rc
) {
4826 for(p
=vstack
;p
<=vtop
;p
++) {
4827 if ((p
->r
& VT_VALMASK
) == r
||
4828 (p
->r2
& VT_VALMASK
) == r
)
4836 /* no register left : free the first one on the stack (VERY
4837 IMPORTANT to start from the bottom to ensure that we don't
4838 spill registers used in gen_opi()) */
4839 for(p
=vstack
;p
<=vtop
;p
++) {
4840 r
= p
->r
& VT_VALMASK
;
4841 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
4843 /* also look at second register (if long long) */
4844 r
= p
->r2
& VT_VALMASK
;
4845 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
4851 /* Should never comes here */
4855 /* save registers up to (vtop - n) stack entry */
4856 void save_regs(int n
)
4861 for(p
= vstack
;p
<= p1
; p
++) {
4862 r
= p
->r
& VT_VALMASK
;
4869 /* move register 's' to 'r', and flush previous value of r to memory
4871 void move_reg(int r
, int s
)
4884 /* get address of vtop (vtop MUST BE an lvalue) */
4887 vtop
->r
&= ~VT_LVAL
;
4888 /* tricky: if saved lvalue, then we can go back to lvalue */
4889 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
4890 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
4893 #ifdef CONFIG_TCC_BCHECK
4894 /* generate lvalue bound code */
4900 vtop
->r
&= ~VT_MUSTBOUND
;
4901 /* if lvalue, then use checking code before dereferencing */
4902 if (vtop
->r
& VT_LVAL
) {
4903 /* if not VT_BOUNDED value, then make one */
4904 if (!(vtop
->r
& VT_BOUNDED
)) {
4905 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
4906 /* must save type because we must set it to int to get pointer */
4908 vtop
->type
.t
= VT_INT
;
4911 gen_bounded_ptr_add();
4912 vtop
->r
|= lval_type
;
4915 /* then check for dereferencing */
4916 gen_bounded_ptr_deref();
4921 /* store vtop a register belonging to class 'rc'. lvalues are
4922 converted to values. Cannot be used if cannot be converted to
4923 register value (such as structures). */
4926 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
4927 unsigned long long ll
;
4929 /* NOTE: get_reg can modify vstack[] */
4930 if (vtop
->type
.t
& VT_BITFIELD
) {
4931 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
4932 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4933 /* remove bit field info to avoid loops */
4934 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4935 /* generate shifts */
4936 vpushi(32 - (bit_pos
+ bit_size
));
4938 vpushi(32 - bit_size
);
4939 /* NOTE: transformed to SHR if unsigned */
4943 if (is_float(vtop
->type
.t
) &&
4944 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4947 unsigned long offset
;
4948 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
4952 /* XXX: unify with initializers handling ? */
4953 /* CPUs usually cannot use float constants, so we store them
4954 generically in data segment */
4955 size
= type_size(&vtop
->type
, &align
);
4956 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
4957 data_section
->data_offset
= offset
;
4958 /* XXX: not portable yet */
4960 /* Zero pad x87 tenbyte long doubles */
4962 vtop
->c
.tab
[2] &= 0xffff;
4964 ptr
= section_ptr_add(data_section
, size
);
4966 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
4970 ptr
[i
] = vtop
->c
.tab
[size
-1-i
];
4974 ptr
[i
] = vtop
->c
.tab
[i
];
4975 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
4976 vtop
->r
|= VT_LVAL
| VT_SYM
;
4980 #ifdef CONFIG_TCC_BCHECK
4981 if (vtop
->r
& VT_MUSTBOUND
)
4985 r
= vtop
->r
& VT_VALMASK
;
4986 /* need to reload if:
4988 - lvalue (need to dereference pointer)
4989 - already a register, but not in the right class */
4990 if (r
>= VT_CONST
||
4991 (vtop
->r
& VT_LVAL
) ||
4992 !(reg_classes
[r
] & rc
) ||
4993 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
4994 !(reg_classes
[vtop
->r2
] & rc
))) {
4996 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
4997 /* two register type load : expand to two words
4999 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
5002 vtop
->c
.ui
= ll
; /* first word */
5004 vtop
->r
= r
; /* save register value */
5005 vpushi(ll
>> 32); /* second word */
5006 } else if (r
>= VT_CONST
|| /* XXX: test to VT_CONST incorrect ? */
5007 (vtop
->r
& VT_LVAL
)) {
5008 /* We do not want to modifier the long long
5009 pointer here, so the safest (and less
5010 efficient) is to save all the other registers
5011 in the stack. XXX: totally inefficient. */
5013 /* load from memory */
5016 vtop
[-1].r
= r
; /* save register value */
5017 /* increment pointer to get second word */
5018 vtop
->type
.t
= VT_INT
;
5024 /* move registers */
5027 vtop
[-1].r
= r
; /* save register value */
5028 vtop
->r
= vtop
[-1].r2
;
5030 /* allocate second register */
5037 /* write second register */
5039 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
5041 /* lvalue of scalar type : need to use lvalue type
5042 because of possible cast */
5045 /* compute memory access type */
5046 if (vtop
->r
& VT_LVAL_BYTE
)
5048 else if (vtop
->r
& VT_LVAL_SHORT
)
5050 if (vtop
->r
& VT_LVAL_UNSIGNED
)
5054 /* restore wanted type */
5057 /* one register type load */
5062 #ifdef TCC_TARGET_C67
5063 /* uses register pairs for doubles */
5064 if ((vtop
->type
.t
& VT_BTYPE
) == VT_DOUBLE
)
5071 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
5072 void gv2(int rc1
, int rc2
)
5076 /* generate more generic register first. But VT_JMP or VT_CMP
5077 values must be generated first in all cases to avoid possible
5079 v
= vtop
[0].r
& VT_VALMASK
;
5080 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
5085 /* test if reload is needed for first register */
5086 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
5096 /* test if reload is needed for first register */
5097 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
5103 /* expand long long on stack in two int registers */
5108 u
= vtop
->type
.t
& VT_UNSIGNED
;
5111 vtop
[0].r
= vtop
[-1].r2
;
5112 vtop
[0].r2
= VT_CONST
;
5113 vtop
[-1].r2
= VT_CONST
;
5114 vtop
[0].type
.t
= VT_INT
| u
;
5115 vtop
[-1].type
.t
= VT_INT
| u
;
5118 #ifdef TCC_TARGET_ARM
5119 /* expand long long on stack */
5120 void lexpand_nr(void)
5124 u
= vtop
->type
.t
& VT_UNSIGNED
;
5126 vtop
->r2
= VT_CONST
;
5127 vtop
->type
.t
= VT_INT
| u
;
5128 v
=vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
);
5129 if (v
== VT_CONST
) {
5130 vtop
[-1].c
.ui
= vtop
->c
.ull
;
5131 vtop
->c
.ui
= vtop
->c
.ull
>> 32;
5133 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
5135 vtop
->r
= vtop
[-1].r
;
5136 } else if (v
> VT_CONST
) {
5140 vtop
->r
= vtop
[-1].r2
;
5141 vtop
[-1].r2
= VT_CONST
;
5142 vtop
[-1].type
.t
= VT_INT
| u
;
5146 /* build a long long from two ints */
5149 gv2(RC_INT
, RC_INT
);
5150 vtop
[-1].r2
= vtop
[0].r
;
5151 vtop
[-1].type
.t
= t
;
5155 /* rotate n first stack elements to the bottom
5156 I1 ... In -> I2 ... In I1 [top is right]
5164 for(i
=-n
+1;i
!=0;i
++)
5165 vtop
[i
] = vtop
[i
+1];
5169 /* rotate n first stack elements to the top
5170 I1 ... In -> In I1 ... I(n-1) [top is right]
5178 for(i
= 0;i
< n
- 1; i
++)
5179 vtop
[-i
] = vtop
[-i
- 1];
5183 #ifdef TCC_TARGET_ARM
5184 /* like vrott but in other direction
5185 In ... I1 -> I(n-1) ... I1 In [top is right]
5193 for(i
= n
- 1; i
> 0; i
--)
5194 vtop
[-i
] = vtop
[-i
+ 1];
5199 /* pop stack value */
5203 v
= vtop
->r
& VT_VALMASK
;
5204 #ifdef TCC_TARGET_I386
5205 /* for x86, we need to pop the FP stack */
5206 if (v
== TREG_ST0
&& !nocode_wanted
) {
5207 o(0xd9dd); /* fstp %st(1) */
5210 if (v
== VT_JMP
|| v
== VT_JMPI
) {
5211 /* need to put correct jump if && or || without test */
5217 /* convert stack entry to register and duplicate its value in another
5225 if ((t
& VT_BTYPE
) == VT_LLONG
) {
5232 /* stack: H L L1 H1 */
5240 /* duplicate value */
5251 load(r1
, &sv
); /* move r to r1 */
5253 /* duplicates value */
5258 /* generate CPU independent (unsigned) long long operations */
5259 void gen_opl(int op
)
5261 int t
, a
, b
, op1
, c
, i
;
5268 func
= TOK___divdi3
;
5271 func
= TOK___udivdi3
;
5274 func
= TOK___moddi3
;
5277 func
= TOK___umoddi3
;
5279 /* call generic long long function */
5280 vpush_global_sym(&func_old_type
, func
);
5285 vtop
->r2
= REG_LRET
;
5298 /* stack: L1 H1 L2 H2 */
5303 vtop
[-2] = vtop
[-3];
5306 /* stack: H1 H2 L1 L2 */
5312 /* stack: H1 H2 L1 L2 ML MH */
5315 /* stack: ML MH H1 H2 L1 L2 */
5319 /* stack: ML MH H1 L2 H2 L1 */
5324 /* stack: ML MH M1 M2 */
5327 } else if (op
== '+' || op
== '-') {
5328 /* XXX: add non carry method too (for MIPS or alpha) */
5334 /* stack: H1 H2 (L1 op L2) */
5337 gen_op(op1
+ 1); /* TOK_xxxC2 */
5340 /* stack: H1 H2 (L1 op L2) */
5343 /* stack: (L1 op L2) H1 H2 */
5345 /* stack: (L1 op L2) (H1 op H2) */
5353 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
5354 t
= vtop
[-1].type
.t
;
5358 /* stack: L H shift */
5360 /* constant: simpler */
5361 /* NOTE: all comments are for SHL. the other cases are
5362 done by swaping words */
5373 if (op
!= TOK_SAR
) {
5406 /* XXX: should provide a faster fallback on x86 ? */
5409 func
= TOK___sardi3
;
5412 func
= TOK___shrdi3
;
5415 func
= TOK___shldi3
;
5421 /* compare operations */
5427 /* stack: L1 H1 L2 H2 */
5429 vtop
[-1] = vtop
[-2];
5431 /* stack: L1 L2 H1 H2 */
5434 /* when values are equal, we need to compare low words. since
5435 the jump is inverted, we invert the test too. */
5438 else if (op1
== TOK_GT
)
5440 else if (op1
== TOK_ULT
)
5442 else if (op1
== TOK_UGT
)
5447 if (op1
!= TOK_NE
) {
5451 /* generate non equal test */
5452 /* XXX: NOT PORTABLE yet */
5456 #if defined(TCC_TARGET_I386)
5457 b
= psym(0x850f, 0);
5458 #elif defined(TCC_TARGET_ARM)
5460 o(0x1A000000 | encbranch(ind
, 0, 1));
5461 #elif defined(TCC_TARGET_C67)
5462 error("not implemented");
5464 #error not supported
5468 /* compare low. Always unsigned */
5472 else if (op1
== TOK_LE
)
5474 else if (op1
== TOK_GT
)
5476 else if (op1
== TOK_GE
)
5486 /* handle integer constant optimizations and various machine
5488 void gen_opic(int op
)
5490 int c1
, c2
, t1
, t2
, n
;
5493 typedef unsigned long long U
;
5497 t1
= v1
->type
.t
& VT_BTYPE
;
5498 t2
= v2
->type
.t
& VT_BTYPE
;
5499 l1
= (t1
== VT_LLONG
) ? v1
->c
.ll
: v1
->c
.i
;
5500 l2
= (t2
== VT_LLONG
) ? v2
->c
.ll
: v2
->c
.i
;
5502 /* currently, we cannot do computations with forward symbols */
5503 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5504 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5507 case '+': l1
+= l2
; break;
5508 case '-': l1
-= l2
; break;
5509 case '&': l1
&= l2
; break;
5510 case '^': l1
^= l2
; break;
5511 case '|': l1
|= l2
; break;
5512 case '*': l1
*= l2
; break;
5519 /* if division by zero, generate explicit division */
5522 error("division by zero in constant");
5526 default: l1
/= l2
; break;
5527 case '%': l1
%= l2
; break;
5528 case TOK_UDIV
: l1
= (U
)l1
/ l2
; break;
5529 case TOK_UMOD
: l1
= (U
)l1
% l2
; break;
5532 case TOK_SHL
: l1
<<= l2
; break;
5533 case TOK_SHR
: l1
= (U
)l1
>> l2
; break;
5534 case TOK_SAR
: l1
>>= l2
; break;
5536 case TOK_ULT
: l1
= (U
)l1
< (U
)l2
; break;
5537 case TOK_UGE
: l1
= (U
)l1
>= (U
)l2
; break;
5538 case TOK_EQ
: l1
= l1
== l2
; break;
5539 case TOK_NE
: l1
= l1
!= l2
; break;
5540 case TOK_ULE
: l1
= (U
)l1
<= (U
)l2
; break;
5541 case TOK_UGT
: l1
= (U
)l1
> (U
)l2
; break;
5542 case TOK_LT
: l1
= l1
< l2
; break;
5543 case TOK_GE
: l1
= l1
>= l2
; break;
5544 case TOK_LE
: l1
= l1
<= l2
; break;
5545 case TOK_GT
: l1
= l1
> l2
; break;
5547 case TOK_LAND
: l1
= l1
&& l2
; break;
5548 case TOK_LOR
: l1
= l1
|| l2
; break;
5555 /* if commutative ops, put c2 as constant */
5556 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
5557 op
== '|' || op
== '*')) {
5559 c2
= c1
; //c = c1, c1 = c2, c2 = c;
5560 l2
= l1
; //l = l1, l1 = l2, l2 = l;
5562 /* Filter out NOP operations like x*1, x-0, x&-1... */
5563 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
5566 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
5567 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
5573 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
5574 /* try to use shifts instead of muls or divs */
5575 if (l2
> 0 && (l2
& (l2
- 1)) == 0) {
5584 else if (op
== TOK_PDIV
)
5590 } else if (c2
&& (op
== '+' || op
== '-') &&
5591 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
5592 (VT_CONST
| VT_SYM
)) {
5593 /* symbol + constant case */
5600 if (!nocode_wanted
) {
5601 /* call low level op generator */
5602 if (t1
== VT_LLONG
|| t2
== VT_LLONG
)
5613 /* generate a floating point operation with constant propagation */
5614 void gen_opif(int op
)
5622 /* currently, we cannot do computations with forward symbols */
5623 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5624 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5626 if (v1
->type
.t
== VT_FLOAT
) {
5629 } else if (v1
->type
.t
== VT_DOUBLE
) {
5637 /* NOTE: we only do constant propagation if finite number (not
5638 NaN or infinity) (ANSI spec) */
5639 if (!ieee_finite(f1
) || !ieee_finite(f2
))
5643 case '+': f1
+= f2
; break;
5644 case '-': f1
-= f2
; break;
5645 case '*': f1
*= f2
; break;
5649 error("division by zero in constant");
5654 /* XXX: also handles tests ? */
5658 /* XXX: overflow test ? */
5659 if (v1
->type
.t
== VT_FLOAT
) {
5661 } else if (v1
->type
.t
== VT_DOUBLE
) {
5669 if (!nocode_wanted
) {
5677 static int pointed_size(CType
*type
)
5680 return type_size(pointed_type(type
), &align
);
5683 static inline int is_null_pointer(SValue
*p
)
5685 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
5687 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& p
->c
.i
== 0) ||
5688 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.ll
== 0);
5691 static inline int is_integer_btype(int bt
)
5693 return (bt
== VT_BYTE
|| bt
== VT_SHORT
||
5694 bt
== VT_INT
|| bt
== VT_LLONG
);
5697 /* check types for comparison or substraction of pointers */
5698 static void check_comparison_pointer_types(SValue
*p1
, SValue
*p2
, int op
)
5700 CType
*type1
, *type2
, tmp_type1
, tmp_type2
;
5703 /* null pointers are accepted for all comparisons as gcc */
5704 if (is_null_pointer(p1
) || is_null_pointer(p2
))
5708 bt1
= type1
->t
& VT_BTYPE
;
5709 bt2
= type2
->t
& VT_BTYPE
;
5710 /* accept comparison between pointer and integer with a warning */
5711 if ((is_integer_btype(bt1
) || is_integer_btype(bt2
)) && op
!= '-') {
5712 if (op
!= TOK_LOR
&& op
!= TOK_LAND
)
5713 warning("comparison between pointer and integer");
5717 /* both must be pointers or implicit function pointers */
5718 if (bt1
== VT_PTR
) {
5719 type1
= pointed_type(type1
);
5720 } else if (bt1
!= VT_FUNC
)
5721 goto invalid_operands
;
5723 if (bt2
== VT_PTR
) {
5724 type2
= pointed_type(type2
);
5725 } else if (bt2
!= VT_FUNC
) {
5727 error("invalid operands to binary %s", get_tok_str(op
, NULL
));
5729 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
5730 (type2
->t
& VT_BTYPE
) == VT_VOID
)
5734 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5735 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5736 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
5737 /* gcc-like error if '-' is used */
5739 goto invalid_operands
;
5741 warning("comparison of distinct pointer types lacks a cast");
5745 /* generic gen_op: handles types problems */
5748 int u
, t1
, t2
, bt1
, bt2
, t
;
5751 t1
= vtop
[-1].type
.t
;
5752 t2
= vtop
[0].type
.t
;
5753 bt1
= t1
& VT_BTYPE
;
5754 bt2
= t2
& VT_BTYPE
;
5756 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5757 /* at least one operand is a pointer */
5758 /* relationnal op: must be both pointers */
5759 if (op
>= TOK_ULT
&& op
<= TOK_LOR
) {
5760 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5761 /* pointers are handled are unsigned */
5762 t
= VT_INT
| VT_UNSIGNED
;
5765 /* if both pointers, then it must be the '-' op */
5766 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
5768 error("cannot use pointers here");
5769 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5770 /* XXX: check that types are compatible */
5771 u
= pointed_size(&vtop
[-1].type
);
5773 /* set to integer type */
5774 vtop
->type
.t
= VT_INT
;
5778 /* exactly one pointer : must be '+' or '-'. */
5779 if (op
!= '-' && op
!= '+')
5780 error("cannot use pointers here");
5781 /* Put pointer as first operand */
5782 if (bt2
== VT_PTR
) {
5786 type1
= vtop
[-1].type
;
5787 /* XXX: cast to int ? (long long case) */
5788 vpushi(pointed_size(&vtop
[-1].type
));
5790 #ifdef CONFIG_TCC_BCHECK
5791 /* if evaluating constant expression, no code should be
5792 generated, so no bound check */
5793 if (do_bounds_check
&& !const_wanted
) {
5794 /* if bounded pointers, we generate a special code to
5801 gen_bounded_ptr_add();
5807 /* put again type if gen_opic() swaped operands */
5810 } else if (is_float(bt1
) || is_float(bt2
)) {
5811 /* compute bigger type and do implicit casts */
5812 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5814 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5819 /* floats can only be used for a few operations */
5820 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
5821 (op
< TOK_ULT
|| op
> TOK_GT
))
5822 error("invalid operands for binary operation");
5824 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5825 /* cast to biggest op */
5827 /* convert to unsigned if it does not fit in a long long */
5828 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5829 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5833 /* integer operations */
5835 /* convert to unsigned if it does not fit in an integer */
5836 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5837 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5840 /* XXX: currently, some unsigned operations are explicit, so
5841 we modify them here */
5842 if (t
& VT_UNSIGNED
) {
5849 else if (op
== TOK_LT
)
5851 else if (op
== TOK_GT
)
5853 else if (op
== TOK_LE
)
5855 else if (op
== TOK_GE
)
5862 /* special case for shifts and long long: we keep the shift as
5864 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
5871 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5872 /* relationnal op: the result is an int */
5873 vtop
->type
.t
= VT_INT
;
5880 /* generic itof for unsigned long long case */
5881 void gen_cvt_itof1(int t
)
5883 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
5884 (VT_LLONG
| VT_UNSIGNED
)) {
5887 vpush_global_sym(&func_old_type
, TOK___ulltof
);
5888 else if (t
== VT_DOUBLE
)
5889 vpush_global_sym(&func_old_type
, TOK___ulltod
);
5891 vpush_global_sym(&func_old_type
, TOK___ulltold
);
5901 /* generic ftoi for unsigned long long case */
5902 void gen_cvt_ftoi1(int t
)
5906 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
5907 /* not handled natively */
5908 st
= vtop
->type
.t
& VT_BTYPE
;
5910 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
5911 else if (st
== VT_DOUBLE
)
5912 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
5914 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
5919 vtop
->r2
= REG_LRET
;
5925 /* force char or short cast */
5926 void force_charshort_cast(int t
)
5930 /* XXX: add optimization if lvalue : just change type and offset */
5935 if (t
& VT_UNSIGNED
) {
5936 vpushi((1 << bits
) - 1);
5942 /* result must be signed or the SAR is converted to an SHL
5943 This was not the case when "t" was a signed short
5944 and the last value on the stack was an unsigned int */
5945 vtop
->type
.t
&= ~VT_UNSIGNED
;
5951 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
5952 static void gen_cast(CType
*type
)
5954 int sbt
, dbt
, sf
, df
, c
;
5956 /* special delayed cast for char/short */
5957 /* XXX: in some cases (multiple cascaded casts), it may still
5959 if (vtop
->r
& VT_MUSTCAST
) {
5960 vtop
->r
&= ~VT_MUSTCAST
;
5961 force_charshort_cast(vtop
->type
.t
);
5964 /* bitfields first get cast to ints */
5965 if (vtop
->type
.t
& VT_BITFIELD
) {
5969 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
5970 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5972 if (sbt
!= dbt
&& !nocode_wanted
) {
5975 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5977 /* convert from fp to fp */
5979 /* constant case: we can do it now */
5980 /* XXX: in ISOC, cannot do it if error in convert */
5981 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
5982 vtop
->c
.f
= (float)vtop
->c
.d
;
5983 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
5984 vtop
->c
.f
= (float)vtop
->c
.ld
;
5985 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
5986 vtop
->c
.d
= (double)vtop
->c
.f
;
5987 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
5988 vtop
->c
.d
= (double)vtop
->c
.ld
;
5989 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
5990 vtop
->c
.ld
= (long double)vtop
->c
.f
;
5991 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
5992 vtop
->c
.ld
= (long double)vtop
->c
.d
;
5994 /* non constant case: generate code */
5998 /* convert int to fp */
6001 case VT_LLONG
| VT_UNSIGNED
:
6003 /* XXX: add const cases for long long */
6005 case VT_INT
| VT_UNSIGNED
:
6007 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
6008 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
6009 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
6014 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
6015 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
6016 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
6022 #if !defined(TCC_TARGET_ARM)
6029 /* convert fp to int */
6030 if (dbt
== VT_BOOL
) {
6034 /* we handle char/short/etc... with generic code */
6035 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
6036 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
6041 case VT_LLONG
| VT_UNSIGNED
:
6043 /* XXX: add const cases for long long */
6045 case VT_INT
| VT_UNSIGNED
:
6047 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
6048 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
6049 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
6055 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
6056 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
6057 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
6065 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
6066 /* additional cast for char/short... */
6071 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
6072 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
6073 /* scalar to long long */
6075 if (sbt
== (VT_INT
| VT_UNSIGNED
))
6076 vtop
->c
.ll
= vtop
->c
.ui
;
6078 vtop
->c
.ll
= vtop
->c
.i
;
6080 /* machine independent conversion */
6082 /* generate high word */
6083 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
6091 /* patch second register */
6092 vtop
[-1].r2
= vtop
->r
;
6096 } else if (dbt
== VT_BOOL
) {
6097 /* scalar to bool */
6100 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
6101 (dbt
& VT_BTYPE
) == VT_SHORT
) {
6102 if (sbt
== VT_PTR
) {
6103 vtop
->type
.t
= VT_INT
;
6104 warning("nonportable conversion from pointer to char/short");
6106 force_charshort_cast(dbt
);
6107 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
6109 if (sbt
== VT_LLONG
) {
6110 /* from long long: just take low order word */
6114 /* if lvalue and single word type, nothing to do because
6115 the lvalue already contains the real type size (see
6116 VT_LVAL_xxx constants) */
6118 } else if ((dbt
& VT_BTYPE
) == VT_PTR
&& !(vtop
->r
& VT_LVAL
)) {
6119 /* if we are casting between pointer types,
6120 we must update the VT_LVAL_xxx size */
6121 vtop
->r
= (vtop
->r
& ~VT_LVAL_TYPE
)
6122 | (lvalue_type(type
->ref
->type
.t
) & VT_LVAL_TYPE
);
6127 /* return type size. Put alignment at 'a' */
6128 static int type_size(CType
*type
, int *a
)
6133 bt
= type
->t
& VT_BTYPE
;
6134 if (bt
== VT_STRUCT
) {
6139 } else if (bt
== VT_PTR
) {
6140 if (type
->t
& VT_ARRAY
) {
6142 return type_size(&s
->type
, a
) * s
->c
;
6147 } else if (bt
== VT_LDOUBLE
) {
6149 return LDOUBLE_SIZE
;
6150 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
6151 #ifdef TCC_TARGET_I386
6153 #elif defined(TCC_TARGET_ARM)
6163 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
6166 } else if (bt
== VT_SHORT
) {
6170 /* char, void, function, _Bool */
6176 /* return the pointed type of t */
6177 static inline CType
*pointed_type(CType
*type
)
6179 return &type
->ref
->type
;
6182 /* modify type so that its it is a pointer to type. */
6183 static void mk_pointer(CType
*type
)
6186 s
= sym_push(SYM_FIELD
, type
, 0, -1);
6187 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
6191 /* compare function types. OLD functions match any new functions */
6192 static int is_compatible_func(CType
*type1
, CType
*type2
)
6198 if (!is_compatible_types(&s1
->type
, &s2
->type
))
6200 /* check func_call */
6201 if (FUNC_CALL(s1
->r
) != FUNC_CALL(s2
->r
))
6203 /* XXX: not complete */
6204 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
6208 while (s1
!= NULL
) {
6211 if (!is_compatible_parameter_types(&s1
->type
, &s2
->type
))
6221 /* return true if type1 and type2 are the same. If unqualified is
6222 true, qualifiers on the types are ignored.
6224 - enums are not checked as gcc __builtin_types_compatible_p ()
6226 static int compare_types(CType
*type1
, CType
*type2
, int unqualified
)
6230 t1
= type1
->t
& VT_TYPE
;
6231 t2
= type2
->t
& VT_TYPE
;
6233 /* strip qualifiers before comparing */
6234 t1
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6235 t2
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6237 /* XXX: bitfields ? */
6240 /* test more complicated cases */
6241 bt1
= t1
& VT_BTYPE
;
6242 if (bt1
== VT_PTR
) {
6243 type1
= pointed_type(type1
);
6244 type2
= pointed_type(type2
);
6245 return is_compatible_types(type1
, type2
);
6246 } else if (bt1
== VT_STRUCT
) {
6247 return (type1
->ref
== type2
->ref
);
6248 } else if (bt1
== VT_FUNC
) {
6249 return is_compatible_func(type1
, type2
);
6255 /* return true if type1 and type2 are exactly the same (including
6258 static int is_compatible_types(CType
*type1
, CType
*type2
)
6260 return compare_types(type1
,type2
,0);
6263 /* return true if type1 and type2 are the same (ignoring qualifiers).
6265 static int is_compatible_parameter_types(CType
*type1
, CType
*type2
)
6267 return compare_types(type1
,type2
,1);
6270 /* print a type. If 'varstr' is not NULL, then the variable is also
6271 printed in the type */
6273 /* XXX: add array and function pointers */
6274 void type_to_str(char *buf
, int buf_size
,
6275 CType
*type
, const char *varstr
)
6282 t
= type
->t
& VT_TYPE
;
6285 if (t
& VT_CONSTANT
)
6286 pstrcat(buf
, buf_size
, "const ");
6287 if (t
& VT_VOLATILE
)
6288 pstrcat(buf
, buf_size
, "volatile ");
6289 if (t
& VT_UNSIGNED
)
6290 pstrcat(buf
, buf_size
, "unsigned ");
6320 tstr
= "long double";
6322 pstrcat(buf
, buf_size
, tstr
);
6326 if (bt
== VT_STRUCT
)
6330 pstrcat(buf
, buf_size
, tstr
);
6331 v
= type
->ref
->v
& ~SYM_STRUCT
;
6332 if (v
>= SYM_FIRST_ANOM
)
6333 pstrcat(buf
, buf_size
, "<anonymous>");
6335 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
6339 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
6340 pstrcat(buf
, buf_size
, "(");
6342 while (sa
!= NULL
) {
6343 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
6344 pstrcat(buf
, buf_size
, buf1
);
6347 pstrcat(buf
, buf_size
, ", ");
6349 pstrcat(buf
, buf_size
, ")");
6353 pstrcpy(buf1
, sizeof(buf1
), "*");
6355 pstrcat(buf1
, sizeof(buf1
), varstr
);
6356 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
6360 pstrcat(buf
, buf_size
, " ");
6361 pstrcat(buf
, buf_size
, varstr
);
6366 /* verify type compatibility to store vtop in 'dt' type, and generate
6368 static void gen_assign_cast(CType
*dt
)
6370 CType
*st
, *type1
, *type2
, tmp_type1
, tmp_type2
;
6371 char buf1
[256], buf2
[256];
6374 st
= &vtop
->type
; /* source type */
6375 dbt
= dt
->t
& VT_BTYPE
;
6376 sbt
= st
->t
& VT_BTYPE
;
6377 if (dt
->t
& VT_CONSTANT
)
6378 warning("assignment of read-only location");
6381 /* special cases for pointers */
6382 /* '0' can also be a pointer */
6383 if (is_null_pointer(vtop
))
6385 /* accept implicit pointer to integer cast with warning */
6386 if (is_integer_btype(sbt
)) {
6387 warning("assignment makes pointer from integer without a cast");
6390 type1
= pointed_type(dt
);
6391 /* a function is implicitely a function pointer */
6392 if (sbt
== VT_FUNC
) {
6393 if ((type1
->t
& VT_BTYPE
) != VT_VOID
&&
6394 !is_compatible_types(pointed_type(dt
), st
))
6401 type2
= pointed_type(st
);
6402 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
6403 (type2
->t
& VT_BTYPE
) == VT_VOID
) {
6404 /* void * can match anything */
6406 /* exact type match, except for unsigned */
6409 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
6410 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
6411 if (!is_compatible_types(&tmp_type1
, &tmp_type2
))
6412 warning("assignment from incompatible pointer type");
6414 /* check const and volatile */
6415 if ((!(type1
->t
& VT_CONSTANT
) && (type2
->t
& VT_CONSTANT
)) ||
6416 (!(type1
->t
& VT_VOLATILE
) && (type2
->t
& VT_VOLATILE
)))
6417 warning("assignment discards qualifiers from pointer target type");
6423 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
6424 warning("assignment makes integer from pointer without a cast");
6426 /* XXX: more tests */
6431 tmp_type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6432 tmp_type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6433 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
6435 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
6436 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
6437 error("cannot cast '%s' to '%s'", buf1
, buf2
);
6445 /* store vtop in lvalue pushed on stack */
6448 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
6450 ft
= vtop
[-1].type
.t
;
6451 sbt
= vtop
->type
.t
& VT_BTYPE
;
6452 dbt
= ft
& VT_BTYPE
;
6453 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
6454 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
6455 /* optimize char/short casts */
6456 delayed_cast
= VT_MUSTCAST
;
6457 vtop
->type
.t
= ft
& VT_TYPE
;
6458 /* XXX: factorize */
6459 if (ft
& VT_CONSTANT
)
6460 warning("assignment of read-only location");
6463 if (!(ft
& VT_BITFIELD
))
6464 gen_assign_cast(&vtop
[-1].type
);
6467 if (sbt
== VT_STRUCT
) {
6468 /* if structure, only generate pointer */
6469 /* structure assignment : generate memcpy */
6470 /* XXX: optimize if small size */
6471 if (!nocode_wanted
) {
6472 size
= type_size(&vtop
->type
, &align
);
6476 vpush_global_sym(&func_old_type
, TOK_memcpy8
);
6477 else if(!(align
& 3))
6478 vpush_global_sym(&func_old_type
, TOK_memcpy4
);
6481 vpush_global_sym(&func_old_type
, TOK_memcpy
);
6485 vtop
->type
.t
= VT_INT
;
6489 vtop
->type
.t
= VT_INT
;
6501 /* leave source on stack */
6502 } else if (ft
& VT_BITFIELD
) {
6503 /* bitfield store handling */
6504 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
6505 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
6506 /* remove bit field info to avoid loops */
6507 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
6509 /* duplicate source into other register */
6514 /* duplicate destination */
6516 vtop
[-1] = vtop
[-2];
6518 /* mask and shift source */
6519 vpushi((1 << bit_size
) - 1);
6523 /* load destination, mask and or with source */
6525 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
6531 /* pop off shifted source from "duplicate source..." above */
6535 #ifdef CONFIG_TCC_BCHECK
6536 /* bound check case */
6537 if (vtop
[-1].r
& VT_MUSTBOUND
) {
6543 if (!nocode_wanted
) {
6547 r
= gv(rc
); /* generate value */
6548 /* if lvalue was saved on stack, must read it */
6549 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
6551 t
= get_reg(RC_INT
);
6553 sv
.r
= VT_LOCAL
| VT_LVAL
;
6554 sv
.c
.ul
= vtop
[-1].c
.ul
;
6556 vtop
[-1].r
= t
| VT_LVAL
;
6559 /* two word case handling : store second register at word + 4 */
6560 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
6562 /* convert to int to increment easily */
6563 vtop
->type
.t
= VT_INT
;
6569 /* XXX: it works because r2 is spilled last ! */
6570 store(vtop
->r2
, vtop
- 1);
6574 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6575 vtop
->r
|= delayed_cast
;
6579 /* post defines POST/PRE add. c is the token ++ or -- */
6580 void inc(int post
, int c
)
6583 vdup(); /* save lvalue */
6585 gv_dup(); /* duplicate value */
6590 vpushi(c
- TOK_MID
);
6592 vstore(); /* store value */
6594 vpop(); /* if post op, return saved value */
6597 /* Parse GNUC __attribute__ extension. Currently, the following
6598 extensions are recognized:
6599 - aligned(n) : set data/function alignment.
6600 - packed : force data alignment to 1
6601 - section(x) : generate data/code in this section.
6602 - unused : currently ignored, but may be used someday.
6603 - regparm(n) : pass function parameters in registers (i386 only)
6605 static void parse_attribute(AttributeDef
*ad
)
6609 while (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
6613 while (tok
!= ')') {
6614 if (tok
< TOK_IDENT
)
6615 expect("attribute name");
6623 expect("section name");
6624 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
6633 if (n
<= 0 || (n
& (n
- 1)) != 0)
6634 error("alignment must be a positive power of two");
6647 /* currently, no need to handle it because tcc does not
6648 track unused objects */
6652 /* currently, no need to handle it because tcc does not
6653 track unused objects */
6658 FUNC_CALL(ad
->func_attr
) = FUNC_CDECL
;
6663 FUNC_CALL(ad
->func_attr
) = FUNC_STDCALL
;
6665 #ifdef TCC_TARGET_I386
6675 FUNC_CALL(ad
->func_attr
) = FUNC_FASTCALL1
+ n
- 1;
6681 FUNC_CALL(ad
->func_attr
) = FUNC_FASTCALLW
;
6685 FUNC_EXPORT(ad
->func_attr
) = 1;
6688 if (tcc_state
->warn_unsupported
)
6689 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
6690 /* skip parameters */
6692 int parenthesis
= 0;
6696 else if (tok
== ')')
6699 } while (parenthesis
&& tok
!= -1);
6712 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
6713 static void struct_decl(CType
*type
, int u
)
6715 int a
, v
, size
, align
, maxalign
, c
, offset
;
6716 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
6717 Sym
*s
, *ss
, *ass
, **ps
;
6721 a
= tok
; /* save decl type */
6726 /* struct already defined ? return it */
6728 expect("struct/union/enum name");
6732 error("invalid type");
6739 /* we put an undefined size for struct/union */
6740 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
6741 s
->r
= 0; /* default alignment is zero as gcc */
6742 /* put struct/union/enum name in type */
6750 error("struct/union/enum already defined");
6751 /* cannot be empty */
6753 /* non empty enums are not allowed */
6754 if (a
== TOK_ENUM
) {
6758 expect("identifier");
6764 /* enum symbols have static storage */
6765 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
6766 ss
->type
.t
|= VT_STATIC
;
6771 /* NOTE: we accept a trailing comma */
6781 while (tok
!= '}') {
6782 parse_btype(&btype
, &ad
);
6788 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
| TYPE_ABSTRACT
);
6789 if (v
== 0 && (type1
.t
& VT_BTYPE
) != VT_STRUCT
)
6790 expect("identifier");
6791 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
6792 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
| VT_INLINE
)))
6793 error("invalid type for '%s'",
6794 get_tok_str(v
, NULL
));
6798 bit_size
= expr_const();
6799 /* XXX: handle v = 0 case for messages */
6801 error("negative width in bit-field '%s'",
6802 get_tok_str(v
, NULL
));
6803 if (v
&& bit_size
== 0)
6804 error("zero width for bit-field '%s'",
6805 get_tok_str(v
, NULL
));
6807 size
= type_size(&type1
, &align
);
6809 if (align
< ad
.aligned
)
6811 } else if (ad
.packed
) {
6813 } else if (*tcc_state
->pack_stack_ptr
) {
6814 if (align
> *tcc_state
->pack_stack_ptr
)
6815 align
= *tcc_state
->pack_stack_ptr
;
6818 if (bit_size
>= 0) {
6819 bt
= type1
.t
& VT_BTYPE
;
6825 error("bitfields must have scalar type");
6827 if (bit_size
> bsize
) {
6828 error("width of '%s' exceeds its type",
6829 get_tok_str(v
, NULL
));
6830 } else if (bit_size
== bsize
) {
6831 /* no need for bit fields */
6833 } else if (bit_size
== 0) {
6834 /* XXX: what to do if only padding in a
6836 /* zero size: means to pad */
6840 /* we do not have enough room ? */
6841 if ((bit_pos
+ bit_size
) > bsize
)
6844 /* XXX: handle LSB first */
6845 type1
.t
|= VT_BITFIELD
|
6846 (bit_pos
<< VT_STRUCT_SHIFT
) |
6847 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
6848 bit_pos
+= bit_size
;
6853 if (v
!= 0 || (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
6854 /* add new memory data only if starting
6856 if (lbit_pos
== 0) {
6857 if (a
== TOK_STRUCT
) {
6858 c
= (c
+ align
- 1) & -align
;
6867 if (align
> maxalign
)
6871 printf("add field %s offset=%d",
6872 get_tok_str(v
, NULL
), offset
);
6873 if (type1
.t
& VT_BITFIELD
) {
6874 printf(" pos=%d size=%d",
6875 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
6876 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
6881 if (v
== 0 && (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
6883 while ((ass
= ass
->next
) != NULL
) {
6884 ss
= sym_push(ass
->v
, &ass
->type
, 0, offset
+ ass
->c
);
6889 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
6893 if (tok
== ';' || tok
== TOK_EOF
)
6900 /* store size and alignment */
6901 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
6907 /* return 0 if no type declaration. otherwise, return the basic type
6910 static int parse_btype(CType
*type
, AttributeDef
*ad
)
6912 int t
, u
, type_found
, typespec_found
, typedef_found
;
6916 memset(ad
, 0, sizeof(AttributeDef
));
6924 /* currently, we really ignore extension */
6934 if ((t
& VT_BTYPE
) != 0)
6935 error("too many basic types");
6951 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
6952 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6953 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
6954 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
6968 if ((t
& VT_BTYPE
) == VT_LONG
) {
6969 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6976 struct_decl(&type1
, VT_ENUM
);
6979 type
->ref
= type1
.ref
;
6983 struct_decl(&type1
, VT_STRUCT
);
6986 /* type modifiers */
7039 /* GNUC attribute */
7040 case TOK_ATTRIBUTE1
:
7041 case TOK_ATTRIBUTE2
:
7042 parse_attribute(ad
);
7049 parse_expr_type(&type1
);
7052 if (typespec_found
|| typedef_found
)
7055 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
7058 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
7059 type
->ref
= s
->type
.ref
;
7067 if ((t
& (VT_SIGNED
|VT_UNSIGNED
)) == (VT_SIGNED
|VT_UNSIGNED
))
7068 error("signed and unsigned modifier");
7069 if (tcc_state
->char_is_unsigned
) {
7070 if ((t
& (VT_SIGNED
|VT_UNSIGNED
|VT_BTYPE
)) == VT_BYTE
)
7075 /* long is never used as type */
7076 if ((t
& VT_BTYPE
) == VT_LONG
)
7077 t
= (t
& ~VT_BTYPE
) | VT_INT
;
7082 /* convert a function parameter type (array to pointer and function to
7083 function pointer) */
7084 static inline void convert_parameter_type(CType
*pt
)
7086 /* remove const and volatile qualifiers (XXX: const could be used
7087 to indicate a const function parameter */
7088 pt
->t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7089 /* array must be transformed to pointer according to ANSI C */
7091 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
7096 static void post_type(CType
*type
, AttributeDef
*ad
)
7098 int n
, l
, t1
, arg_size
, align
;
7099 Sym
**plast
, *s
, *first
;
7104 /* function declaration */
7112 /* read param name and compute offset */
7113 if (l
!= FUNC_OLD
) {
7114 if (!parse_btype(&pt
, &ad1
)) {
7116 error("invalid type");
7123 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
7125 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
7126 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
7127 error("parameter declared as void");
7128 arg_size
+= (type_size(&pt
, &align
) + 3) & ~3;
7133 expect("identifier");
7137 convert_parameter_type(&pt
);
7138 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
7144 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
7151 /* if no parameters, then old type prototype */
7155 t1
= type
->t
& VT_STORAGE
;
7156 /* NOTE: const is ignored in returned type as it has a special
7157 meaning in gcc / C++ */
7158 type
->t
&= ~(VT_STORAGE
| VT_CONSTANT
);
7159 post_type(type
, ad
);
7160 /* we push a anonymous symbol which will contain the function prototype */
7161 FUNC_ARGS(ad
->func_attr
) = arg_size
;
7162 s
= sym_push(SYM_FIELD
, type
, ad
->func_attr
, l
);
7164 type
->t
= t1
| VT_FUNC
;
7166 } else if (tok
== '[') {
7167 /* array definition */
7173 error("invalid array size");
7176 /* parse next post type */
7177 t1
= type
->t
& VT_STORAGE
;
7178 type
->t
&= ~VT_STORAGE
;
7179 post_type(type
, ad
);
7181 /* we push a anonymous symbol which will contain the array
7183 s
= sym_push(SYM_FIELD
, type
, 0, n
);
7184 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
7189 /* Parse a type declaration (except basic type), and return the type
7190 in 'type'. 'td' is a bitmask indicating which kind of type decl is
7191 expected. 'type' should contain the basic type. 'ad' is the
7192 attribute definition of the basic type. It can be modified by
7195 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
7198 CType type1
, *type2
;
7201 while (tok
== '*') {
7209 qualifiers
|= VT_CONSTANT
;
7214 qualifiers
|= VT_VOLATILE
;
7222 type
->t
|= qualifiers
;
7225 /* XXX: clarify attribute handling */
7226 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
7227 parse_attribute(ad
);
7229 /* recursive type */
7230 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
7231 type1
.t
= 0; /* XXX: same as int */
7234 /* XXX: this is not correct to modify 'ad' at this point, but
7235 the syntax is not clear */
7236 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
7237 parse_attribute(ad
);
7238 type_decl(&type1
, ad
, v
, td
);
7241 /* type identifier */
7242 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
7246 if (!(td
& TYPE_ABSTRACT
))
7247 expect("identifier");
7251 post_type(type
, ad
);
7252 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
7253 parse_attribute(ad
);
7256 /* append type at the end of type1 */
7269 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
7270 static int lvalue_type(int t
)
7275 if (bt
== VT_BYTE
|| bt
== VT_BOOL
)
7277 else if (bt
== VT_SHORT
)
7281 if (t
& VT_UNSIGNED
)
7282 r
|= VT_LVAL_UNSIGNED
;
7286 /* indirection with full error checking and bound check */
7287 static void indir(void)
7289 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
7290 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
7294 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
7296 vtop
->type
= *pointed_type(&vtop
->type
);
7297 /* Arrays and functions are never lvalues */
7298 if (!(vtop
->type
.t
& VT_ARRAY
)
7299 && (vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
7300 vtop
->r
|= lvalue_type(vtop
->type
.t
);
7301 /* if bound checking, the referenced pointer must be checked */
7302 if (do_bounds_check
)
7303 vtop
->r
|= VT_MUSTBOUND
;
7307 /* pass a parameter to a function and do type checking and casting */
7308 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
7313 func_type
= func
->c
;
7314 if (func_type
== FUNC_OLD
||
7315 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
7316 /* default casting : only need to convert float to double */
7317 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
7321 } else if (arg
== NULL
) {
7322 error("too many arguments to function");
7325 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
7326 gen_assign_cast(&type
);
7330 /* parse an expression of the form '(type)' or '(expr)' and return its
7332 static void parse_expr_type(CType
*type
)
7338 if (parse_btype(type
, &ad
)) {
7339 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
7346 static void parse_type(CType
*type
)
7351 if (!parse_btype(type
, &ad
)) {
7354 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
7357 static void vpush_tokc(int t
)
7361 vsetc(&type
, VT_CONST
, &tokc
);
7364 static void unary(void)
7366 int n
, t
, align
, size
, r
;
7371 /* XXX: GCC 2.95.3 does not generate a table although it should be
7385 vpush_tokc(VT_INT
| VT_UNSIGNED
);
7389 vpush_tokc(VT_LLONG
);
7393 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
7397 vpush_tokc(VT_FLOAT
);
7401 vpush_tokc(VT_DOUBLE
);
7405 vpush_tokc(VT_LDOUBLE
);
7408 case TOK___FUNCTION__
:
7410 goto tok_identifier
;
7416 /* special function name identifier */
7417 len
= strlen(funcname
) + 1;
7418 /* generate char[len] type */
7423 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
7424 ptr
= section_ptr_add(data_section
, len
);
7425 memcpy(ptr
, funcname
, len
);
7430 #ifdef TCC_TARGET_PE
7431 t
= VT_SHORT
| VT_UNSIGNED
;
7437 /* string parsing */
7440 if (tcc_state
->warn_write_strings
)
7445 memset(&ad
, 0, sizeof(AttributeDef
));
7446 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
7451 if (parse_btype(&type
, &ad
)) {
7452 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
7454 /* check ISOC99 compound literal */
7456 /* data is allocated locally by default */
7461 /* all except arrays are lvalues */
7462 if (!(type
.t
& VT_ARRAY
))
7463 r
|= lvalue_type(type
.t
);
7464 memset(&ad
, 0, sizeof(AttributeDef
));
7465 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
7470 } else if (tok
== '{') {
7471 /* save all registers */
7473 /* statement expression : we do not accept break/continue
7474 inside as GCC does */
7475 block(NULL
, NULL
, NULL
, NULL
, 0, 1);
7490 /* functions names must be treated as function pointers,
7491 except for unary '&' and sizeof. Since we consider that
7492 functions are not lvalues, we only have to handle it
7493 there and in function calls. */
7494 /* arrays can also be used although they are not lvalues */
7495 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
7496 !(vtop
->type
.t
& VT_ARRAY
) && !(vtop
->type
.t
& VT_LLOCAL
))
7498 mk_pointer(&vtop
->type
);
7504 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
7505 vtop
->c
.i
= !vtop
->c
.i
;
7506 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
7507 vtop
->c
.i
= vtop
->c
.i
^ 1;
7510 vseti(VT_JMP
, gtst(1, 0));
7521 /* in order to force cast, we add zero */
7523 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
7524 error("pointer not accepted for unary plus");
7534 parse_expr_type(&type
);
7538 size
= type_size(&type
, &align
);
7539 if (t
== TOK_SIZEOF
) {
7541 error("sizeof applied to an incomplete type");
7546 vtop
->type
.t
|= VT_UNSIGNED
;
7549 case TOK_builtin_types_compatible_p
:
7558 type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7559 type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7560 vpushi(is_compatible_types(&type1
, &type2
));
7563 case TOK_builtin_constant_p
:
7565 int saved_nocode_wanted
, res
;
7568 saved_nocode_wanted
= nocode_wanted
;
7571 res
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
7573 nocode_wanted
= saved_nocode_wanted
;
7593 goto tok_identifier
;
7595 /* allow to take the address of a label */
7596 if (tok
< TOK_UIDENT
)
7597 expect("label identifier");
7598 s
= label_find(tok
);
7600 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7602 if (s
->r
== LABEL_DECLARED
)
7603 s
->r
= LABEL_FORWARD
;
7606 s
->type
.t
= VT_VOID
;
7607 mk_pointer(&s
->type
);
7608 s
->type
.t
|= VT_STATIC
;
7610 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
7619 expect("identifier");
7623 error("'%s' undeclared", get_tok_str(t
, NULL
));
7624 /* for simple function calls, we tolerate undeclared
7625 external reference to int() function */
7626 if (tcc_state
->warn_implicit_function_declaration
)
7627 warning("implicit declaration of function '%s'",
7628 get_tok_str(t
, NULL
));
7629 s
= external_global_sym(t
, &func_old_type
, 0);
7631 if ((s
->type
.t
& (VT_STATIC
| VT_INLINE
| VT_BTYPE
)) ==
7632 (VT_STATIC
| VT_INLINE
| VT_FUNC
)) {
7633 /* if referencing an inline function, then we generate a
7634 symbol to it if not already done. It will have the
7635 effect to generate code for it at the end of the
7636 compilation unit. Inline function as always
7637 generated in the text section. */
7639 put_extern_sym(s
, text_section
, 0, 0);
7640 r
= VT_SYM
| VT_CONST
;
7644 vset(&s
->type
, r
, s
->c
);
7645 /* if forward reference, we must point to s */
7646 if (vtop
->r
& VT_SYM
) {
7653 /* post operations */
7655 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
7658 } else if (tok
== '.' || tok
== TOK_ARROW
) {
7660 if (tok
== TOK_ARROW
)
7665 /* expect pointer on structure */
7666 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
7667 expect("struct or union");
7671 while ((s
= s
->next
) != NULL
) {
7676 error("field not found: %s", get_tok_str(tok
& ~SYM_FIELD
, NULL
));
7677 /* add field offset to pointer */
7678 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
7681 /* change type to field type, and set to lvalue */
7682 vtop
->type
= s
->type
;
7683 /* an array is never an lvalue */
7684 if (!(vtop
->type
.t
& VT_ARRAY
)) {
7685 vtop
->r
|= lvalue_type(vtop
->type
.t
);
7686 /* if bound checking, the referenced pointer must be checked */
7687 if (do_bounds_check
)
7688 vtop
->r
|= VT_MUSTBOUND
;
7691 } else if (tok
== '[') {
7697 } else if (tok
== '(') {
7703 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
7704 /* pointer test (no array accepted) */
7705 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
7706 vtop
->type
= *pointed_type(&vtop
->type
);
7707 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
7711 expect("function pointer");
7714 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
7716 /* get return type */
7719 sa
= s
->next
; /* first parameter */
7722 /* compute first implicit argument if a structure is returned */
7723 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
7724 /* get some space for the returned structure */
7725 size
= type_size(&s
->type
, &align
);
7726 loc
= (loc
- size
) & -align
;
7728 ret
.r
= VT_LOCAL
| VT_LVAL
;
7729 /* pass it as 'int' to avoid structure arg passing
7731 vseti(VT_LOCAL
, loc
);
7736 /* return in register */
7737 if (is_float(ret
.type
.t
)) {
7740 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
7749 gfunc_param_typed(s
, sa
);
7759 error("too few arguments to function");
7761 if (!nocode_wanted
) {
7762 gfunc_call(nb_args
);
7764 vtop
-= (nb_args
+ 1);
7767 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
7775 static void uneq(void)
7781 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
7782 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
7783 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
7798 static void expr_prod(void)
7803 while (tok
== '*' || tok
== '/' || tok
== '%') {
7811 static void expr_sum(void)
7816 while (tok
== '+' || tok
== '-') {
7824 static void expr_shift(void)
7829 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
7837 static void expr_cmp(void)
7842 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
7843 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
7851 static void expr_cmpeq(void)
7856 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
7864 static void expr_and(void)
7867 while (tok
== '&') {
7874 static void expr_xor(void)
7877 while (tok
== '^') {
7884 static void expr_or(void)
7887 while (tok
== '|') {
7894 /* XXX: fix this mess */
7895 static void expr_land_const(void)
7898 while (tok
== TOK_LAND
) {
7905 /* XXX: fix this mess */
7906 static void expr_lor_const(void)
7909 while (tok
== TOK_LOR
) {
7916 /* only used if non constant */
7917 static void expr_land(void)
7922 if (tok
== TOK_LAND
) {
7927 if (tok
!= TOK_LAND
) {
7937 static void expr_lor(void)
7942 if (tok
== TOK_LOR
) {
7947 if (tok
!= TOK_LOR
) {
7957 /* XXX: better constant handling */
7958 static void expr_eq(void)
7960 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
7962 CType type
, type1
, type2
;
7971 if (tok
== ':' && gnu_ext
) {
7987 if (vtop
!= vstack
) {
7988 /* needed to avoid having different registers saved in
7990 if (is_float(vtop
->type
.t
))
7997 if (tok
== ':' && gnu_ext
) {
8005 sv
= *vtop
; /* save value to handle it later */
8006 vtop
--; /* no vpop so that FP stack is not flushed */
8014 bt1
= t1
& VT_BTYPE
;
8016 bt2
= t2
& VT_BTYPE
;
8017 /* cast operands to correct type according to ISOC rules */
8018 if (is_float(bt1
) || is_float(bt2
)) {
8019 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
8020 type
.t
= VT_LDOUBLE
;
8021 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
8026 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
8027 /* cast to biggest op */
8029 /* convert to unsigned if it does not fit in a long long */
8030 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
8031 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
8032 type
.t
|= VT_UNSIGNED
;
8033 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
8034 /* XXX: test pointer compatibility */
8036 } else if (bt1
== VT_FUNC
|| bt2
== VT_FUNC
) {
8037 /* XXX: test function pointer compatibility */
8039 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
8040 /* XXX: test structure compatibility */
8042 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
8043 /* NOTE: as an extension, we accept void on only one side */
8046 /* integer operations */
8048 /* convert to unsigned if it does not fit in an integer */
8049 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
8050 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
8051 type
.t
|= VT_UNSIGNED
;
8054 /* now we convert second operand */
8056 if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
8059 if (is_float(type
.t
)) {
8061 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
8062 /* for long longs, we use fixed registers to avoid having
8063 to handle a complicated move */
8068 /* this is horrible, but we must also convert first
8072 /* put again first value and cast it */
8075 if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
8085 static void gexpr(void)
8096 /* parse an expression and return its type without any side effect. */
8097 static void expr_type(CType
*type
)
8099 int saved_nocode_wanted
;
8101 saved_nocode_wanted
= nocode_wanted
;
8106 nocode_wanted
= saved_nocode_wanted
;
8109 /* parse a unary expression and return its type without any side
8111 static void unary_type(CType
*type
)
8123 /* parse a constant expression and return value in vtop. */
8124 static void expr_const1(void)
8133 /* parse an integer constant and return its value. */
8134 static int expr_const(void)
8138 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
8139 expect("constant expression");
8145 /* return the label token if current token is a label, otherwise
8147 static int is_label(void)
8151 /* fast test first */
8152 if (tok
< TOK_UIDENT
)
8154 /* no need to save tokc because tok is an identifier */
8161 unget_tok(last_tok
);
8166 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
8167 int case_reg
, int is_expr
)
8172 /* generate line number info */
8174 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
8175 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
8177 last_line_num
= file
->line_num
;
8181 /* default return value is (void) */
8183 vtop
->type
.t
= VT_VOID
;
8186 if (tok
== TOK_IF
) {
8193 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
8195 if (c
== TOK_ELSE
) {
8199 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
8200 gsym(d
); /* patch else jmp */
8203 } else if (tok
== TOK_WHILE
) {
8211 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
8215 } else if (tok
== '{') {
8219 /* record local declaration stack position */
8221 llabel
= local_label_stack
;
8222 /* handle local labels declarations */
8223 if (tok
== TOK_LABEL
) {
8226 if (tok
< TOK_UIDENT
)
8227 expect("label identifier");
8228 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
8238 while (tok
!= '}') {
8243 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
8246 /* pop locally defined labels */
8247 label_pop(&local_label_stack
, llabel
);
8248 /* pop locally defined symbols */
8249 sym_pop(&local_stack
, s
);
8251 } else if (tok
== TOK_RETURN
) {
8255 gen_assign_cast(&func_vt
);
8256 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
8258 /* if returning structure, must copy it to implicit
8259 first pointer arg location */
8262 size
= type_size(&func_vt
,&align
);
8265 if((vtop
->r
!= (VT_LOCAL
| VT_LVAL
) || (vtop
->c
.i
& 3))
8269 loc
= (loc
- size
) & -4;
8272 vset(&type
, VT_LOCAL
| VT_LVAL
, addr
);
8275 vset(&int_type
, VT_LOCAL
| VT_LVAL
, addr
);
8277 vtop
->type
= int_type
;
8283 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
8286 /* copy structure value to pointer */
8291 } else if (is_float(func_vt
.t
)) {
8296 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
8299 rsym
= gjmp(rsym
); /* jmp */
8300 } else if (tok
== TOK_BREAK
) {
8303 error("cannot break");
8304 *bsym
= gjmp(*bsym
);
8307 } else if (tok
== TOK_CONTINUE
) {
8310 error("cannot continue");
8311 *csym
= gjmp(*csym
);
8314 } else if (tok
== TOK_FOR
) {
8341 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
8346 if (tok
== TOK_DO
) {
8351 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
8362 if (tok
== TOK_SWITCH
) {
8366 /* XXX: other types than integer */
8367 case_reg
= gv(RC_INT
);
8371 b
= gjmp(0); /* jump to first case */
8373 block(&a
, csym
, &b
, &c
, case_reg
, 0);
8374 /* if no default, jmp after switch */
8382 if (tok
== TOK_CASE
) {
8389 if (gnu_ext
&& tok
== TOK_DOTS
) {
8393 warning("empty case range");
8395 /* since a case is like a label, we must skip it with a jmp */
8402 *case_sym
= gtst(1, 0);
8405 *case_sym
= gtst(1, 0);
8409 *case_sym
= gtst(1, *case_sym
);
8414 goto block_after_label
;
8416 if (tok
== TOK_DEFAULT
) {
8422 error("too many 'default'");
8425 goto block_after_label
;
8427 if (tok
== TOK_GOTO
) {
8429 if (tok
== '*' && gnu_ext
) {
8433 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
8436 } else if (tok
>= TOK_UIDENT
) {
8437 s
= label_find(tok
);
8438 /* put forward definition if needed */
8440 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
8442 if (s
->r
== LABEL_DECLARED
)
8443 s
->r
= LABEL_FORWARD
;
8445 /* label already defined */
8446 if (s
->r
& LABEL_FORWARD
)
8447 s
->next
= (void *)gjmp((long)s
->next
);
8449 gjmp_addr((long)s
->next
);
8452 expect("label identifier");
8455 } else if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
8463 if (s
->r
== LABEL_DEFINED
)
8464 error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
8465 gsym((long)s
->next
);
8466 s
->r
= LABEL_DEFINED
;
8468 s
= label_push(&global_label_stack
, b
, LABEL_DEFINED
);
8470 s
->next
= (void *)ind
;
8471 /* we accept this, but it is a mistake */
8474 warning("deprecated use of label at end of compound statement");
8478 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
8481 /* expression case */
8496 /* t is the array or struct type. c is the array or struct
8497 address. cur_index/cur_field is the pointer to the current
8498 value. 'size_only' is true if only size info is needed (only used
8500 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
8501 int *cur_index
, Sym
**cur_field
,
8505 int notfirst
, index
, index_last
, align
, l
, nb_elems
, elem_size
;
8511 if (gnu_ext
&& (l
= is_label()) != 0)
8513 while (tok
== '[' || tok
== '.') {
8515 if (!(type
->t
& VT_ARRAY
))
8516 expect("array type");
8519 index
= expr_const();
8520 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
8521 expect("invalid index");
8522 if (tok
== TOK_DOTS
&& gnu_ext
) {
8524 index_last
= expr_const();
8525 if (index_last
< 0 ||
8526 (s
->c
>= 0 && index_last
>= s
->c
) ||
8528 expect("invalid index");
8534 *cur_index
= index_last
;
8535 type
= pointed_type(type
);
8536 elem_size
= type_size(type
, &align
);
8537 c
+= index
* elem_size
;
8538 /* NOTE: we only support ranges for last designator */
8539 nb_elems
= index_last
- index
+ 1;
8540 if (nb_elems
!= 1) {
8549 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
8550 expect("struct/union type");
8563 /* XXX: fix this mess by using explicit storage field */
8565 type1
.t
|= (type
->t
& ~VT_TYPE
);
8579 if (type
->t
& VT_ARRAY
) {
8581 type
= pointed_type(type
);
8582 c
+= index
* type_size(type
, &align
);
8586 error("too many field init");
8587 /* XXX: fix this mess by using explicit storage field */
8589 type1
.t
|= (type
->t
& ~VT_TYPE
);
8594 decl_initializer(type
, sec
, c
, 0, size_only
);
8596 /* XXX: make it more general */
8597 if (!size_only
&& nb_elems
> 1) {
8598 unsigned long c_end
;
8603 error("range init not supported yet for dynamic storage");
8604 c_end
= c
+ nb_elems
* elem_size
;
8605 if (c_end
> sec
->data_allocated
)
8606 section_realloc(sec
, c_end
);
8607 src
= sec
->data
+ c
;
8609 for(i
= 1; i
< nb_elems
; i
++) {
8611 memcpy(dst
, src
, elem_size
);
8617 #define EXPR_CONST 1
8620 /* store a value or an expression directly in global data or in local array */
8621 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
8622 int v
, int expr_type
)
8624 int saved_global_expr
, bt
, bit_pos
, bit_size
;
8626 unsigned long long bit_mask
;
8634 /* compound literals must be allocated globally in this case */
8635 saved_global_expr
= global_expr
;
8638 global_expr
= saved_global_expr
;
8639 /* NOTE: symbols are accepted */
8640 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
8641 error("initializer element is not constant");
8649 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
8652 /* XXX: not portable */
8653 /* XXX: generate error if incorrect relocation */
8654 gen_assign_cast(&dtype
);
8655 bt
= type
->t
& VT_BTYPE
;
8656 ptr
= sec
->data
+ c
;
8657 /* XXX: make code faster ? */
8658 if (!(type
->t
& VT_BITFIELD
)) {
8663 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
8664 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
8665 bit_mask
= (1LL << bit_size
) - 1;
8667 if ((vtop
->r
& VT_SYM
) &&
8673 (bt
== VT_INT
&& bit_size
!= 32)))
8674 error("initializer element is not computable at load time");
8677 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8680 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8683 *(double *)ptr
= vtop
->c
.d
;
8686 *(long double *)ptr
= vtop
->c
.ld
;
8689 *(long long *)ptr
|= (vtop
->c
.ll
& bit_mask
) << bit_pos
;
8692 if (vtop
->r
& VT_SYM
) {
8693 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
8695 *(int *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8700 vset(&dtype
, VT_LOCAL
|VT_LVAL
, c
);
8707 /* put zeros for variable based init */
8708 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
8711 /* nothing to do because globals are already set to zero */
8713 vpush_global_sym(&func_old_type
, TOK_memset
);
8721 /* 't' contains the type and storage info. 'c' is the offset of the
8722 object in section 'sec'. If 'sec' is NULL, it means stack based
8723 allocation. 'first' is true if array '{' must be read (multi
8724 dimension implicit array init handling). 'size_only' is true if
8725 size only evaluation is wanted (only for arrays). */
8726 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
8727 int first
, int size_only
)
8729 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
8730 int size1
, align1
, expr_type
;
8734 if (type
->t
& VT_ARRAY
) {
8738 t1
= pointed_type(type
);
8739 size1
= type_size(t1
, &align1
);
8742 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
8748 /* only parse strings here if correct type (otherwise: handle
8749 them as ((w)char *) expressions */
8750 if ((tok
== TOK_LSTR
&&
8751 #ifdef TCC_TARGET_PE
8752 (t1
->t
& VT_BTYPE
) == VT_SHORT
&& (t1
->t
& VT_UNSIGNED
)
8754 (t1
->t
& VT_BTYPE
) == VT_INT
8756 ) || (tok
== TOK_STR
&& (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
8757 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8762 /* compute maximum number of chars wanted */
8764 cstr_len
= cstr
->size
;
8766 cstr_len
= cstr
->size
/ sizeof(nwchar_t
);
8769 if (n
>= 0 && nb
> (n
- array_length
))
8770 nb
= n
- array_length
;
8773 warning("initializer-string for array is too long");
8774 /* in order to go faster for common case (char
8775 string in global variable, we handle it
8777 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
8778 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
8782 ch
= ((unsigned char *)cstr
->data
)[i
];
8784 ch
= ((nwchar_t
*)cstr
->data
)[i
];
8785 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
8793 /* only add trailing zero if enough storage (no
8794 warning in this case since it is standard) */
8795 if (n
< 0 || array_length
< n
) {
8797 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
8803 while (tok
!= '}') {
8804 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
8805 if (n
>= 0 && index
>= n
)
8806 error("index too large");
8807 /* must put zero in holes (note that doing it that way
8808 ensures that it even works with designators) */
8809 if (!size_only
&& array_length
< index
) {
8810 init_putz(t1
, sec
, c
+ array_length
* size1
,
8811 (index
- array_length
) * size1
);
8814 if (index
> array_length
)
8815 array_length
= index
;
8816 /* special test for multi dimensional arrays (may not
8817 be strictly correct if designators are used at the
8819 if (index
>= n
&& no_oblock
)
8828 /* put zeros at the end */
8829 if (!size_only
&& n
>= 0 && array_length
< n
) {
8830 init_putz(t1
, sec
, c
+ array_length
* size1
,
8831 (n
- array_length
) * size1
);
8833 /* patch type size if needed */
8835 s
->c
= array_length
;
8836 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
8837 (sec
|| !first
|| tok
== '{')) {
8840 /* NOTE: the previous test is a specific case for automatic
8841 struct/union init */
8842 /* XXX: union needs only one init */
8844 /* XXX: this test is incorrect for local initializers
8845 beginning with ( without {. It would be much more difficult
8846 to do it correctly (ideally, the expression parser should
8847 be used in all cases) */
8853 while (tok
== '(') {
8857 if (!parse_btype(&type1
, &ad1
))
8859 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
8861 if (!is_assignable_types(type
, &type1
))
8862 error("invalid type for cast");
8867 if (first
|| tok
== '{') {
8876 while (tok
!= '}') {
8877 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
8879 if (!size_only
&& array_length
< index
) {
8880 init_putz(type
, sec
, c
+ array_length
,
8881 index
- array_length
);
8883 index
= index
+ type_size(&f
->type
, &align1
);
8884 if (index
> array_length
)
8885 array_length
= index
;
8887 if (no_oblock
&& f
== NULL
)
8893 /* put zeros at the end */
8894 if (!size_only
&& array_length
< n
) {
8895 init_putz(type
, sec
, c
+ array_length
,
8904 } else if (tok
== '{') {
8906 decl_initializer(type
, sec
, c
, first
, size_only
);
8908 } else if (size_only
) {
8909 /* just skip expression */
8911 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
8915 else if (tok
== ')')
8920 /* currently, we always use constant expression for globals
8921 (may change for scripting case) */
8922 expr_type
= EXPR_CONST
;
8924 expr_type
= EXPR_ANY
;
8925 init_putv(type
, sec
, c
, 0, expr_type
);
8929 /* parse an initializer for type 't' if 'has_init' is non zero, and
8930 allocate space in local or global data space ('r' is either
8931 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8932 variable 'v' of scope 'scope' is declared before initializers are
8933 parsed. If 'v' is zero, then a reference to the new object is put
8934 in the value stack. If 'has_init' is 2, a special parsing is done
8935 to handle string constants. */
8936 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
8937 int has_init
, int v
, int scope
)
8939 int size
, align
, addr
, data_offset
;
8941 ParseState saved_parse_state
;
8942 TokenString init_str
;
8945 size
= type_size(type
, &align
);
8946 /* If unknown size, we must evaluate it before
8947 evaluating initializers because
8948 initializers can generate global data too
8949 (e.g. string pointers or ISOC99 compound
8950 literals). It also simplifies local
8951 initializers handling */
8952 tok_str_new(&init_str
);
8955 error("unknown type size");
8956 /* get all init string */
8957 if (has_init
== 2) {
8958 /* only get strings */
8959 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8960 tok_str_add_tok(&init_str
);
8965 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
8967 error("unexpected end of file in initializer");
8968 tok_str_add_tok(&init_str
);
8971 else if (tok
== '}') {
8979 tok_str_add(&init_str
, -1);
8980 tok_str_add(&init_str
, 0);
8983 save_parse_state(&saved_parse_state
);
8985 macro_ptr
= init_str
.str
;
8987 decl_initializer(type
, NULL
, 0, 1, 1);
8988 /* prepare second initializer parsing */
8989 macro_ptr
= init_str
.str
;
8992 /* if still unknown size, error */
8993 size
= type_size(type
, &align
);
8995 error("unknown type size");
8997 /* take into account specified alignment if bigger */
8999 if (ad
->aligned
> align
)
9000 align
= ad
->aligned
;
9001 } else if (ad
->packed
) {
9004 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
9006 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
9008 loc
= (loc
- size
) & -align
;
9010 /* handles bounds */
9011 /* XXX: currently, since we do only one pass, we cannot track
9012 '&' operators, so we add only arrays */
9013 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
9014 unsigned long *bounds_ptr
;
9015 /* add padding between regions */
9017 /* then add local bound info */
9018 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
9019 bounds_ptr
[0] = addr
;
9020 bounds_ptr
[1] = size
;
9023 /* local variable */
9024 sym_push(v
, type
, r
, addr
);
9026 /* push local reference */
9027 vset(type
, r
, addr
);
9033 if (v
&& scope
== VT_CONST
) {
9034 /* see if the symbol was already defined */
9037 if (!is_compatible_types(&sym
->type
, type
))
9038 error("incompatible types for redefinition of '%s'",
9039 get_tok_str(v
, NULL
));
9040 if (sym
->type
.t
& VT_EXTERN
) {
9041 /* if the variable is extern, it was not allocated */
9042 sym
->type
.t
&= ~VT_EXTERN
;
9043 /* set array size if it was ommited in extern
9045 if ((sym
->type
.t
& VT_ARRAY
) &&
9046 sym
->type
.ref
->c
< 0 &&
9048 sym
->type
.ref
->c
= type
->ref
->c
;
9050 /* we accept several definitions of the same
9051 global variable. this is tricky, because we
9052 must play with the SHN_COMMON type of the symbol */
9053 /* XXX: should check if the variable was already
9054 initialized. It is incorrect to initialized it
9056 /* no init data, we won't add more to the symbol */
9063 /* allocate symbol in corresponding section */
9068 else if (tcc_state
->nocommon
)
9072 data_offset
= sec
->data_offset
;
9073 data_offset
= (data_offset
+ align
- 1) & -align
;
9075 /* very important to increment global pointer at this time
9076 because initializers themselves can create new initializers */
9077 data_offset
+= size
;
9078 /* add padding if bound check */
9079 if (do_bounds_check
)
9081 sec
->data_offset
= data_offset
;
9082 /* allocate section space to put the data */
9083 if (sec
->sh_type
!= SHT_NOBITS
&&
9084 data_offset
> sec
->data_allocated
)
9085 section_realloc(sec
, data_offset
);
9086 /* align section if needed */
9087 if (align
> sec
->sh_addralign
)
9088 sec
->sh_addralign
= align
;
9090 addr
= 0; /* avoid warning */
9094 if (scope
!= VT_CONST
|| !sym
) {
9095 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
9097 /* update symbol definition */
9099 put_extern_sym(sym
, sec
, addr
, size
);
9102 /* put a common area */
9103 put_extern_sym(sym
, NULL
, align
, size
);
9104 /* XXX: find a nicer way */
9105 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
9106 esym
->st_shndx
= SHN_COMMON
;
9111 /* push global reference */
9112 sym
= get_sym_ref(type
, sec
, addr
, size
);
9114 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
9118 /* handles bounds now because the symbol must be defined
9119 before for the relocation */
9120 if (do_bounds_check
) {
9121 unsigned long *bounds_ptr
;
9123 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
9124 /* then add global bound info */
9125 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
9126 bounds_ptr
[0] = 0; /* relocated */
9127 bounds_ptr
[1] = size
;
9131 decl_initializer(type
, sec
, addr
, 1, 0);
9132 /* restore parse state if needed */
9134 tok_str_free(init_str
.str
);
9135 restore_parse_state(&saved_parse_state
);
9141 void put_func_debug(Sym
*sym
)
9146 /* XXX: we put here a dummy type */
9147 snprintf(buf
, sizeof(buf
), "%s:%c1",
9148 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
9149 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
9150 cur_text_section
, sym
->c
);
9155 /* parse an old style function declaration list */
9156 /* XXX: check multiple parameter */
9157 static void func_decl_list(Sym
*func_sym
)
9164 /* parse each declaration */
9165 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
) {
9166 if (!parse_btype(&btype
, &ad
))
9167 expect("declaration list");
9168 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
9169 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
9171 /* we accept no variable after */
9175 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
9176 /* find parameter in function parameter list */
9179 if ((s
->v
& ~SYM_FIELD
) == v
)
9183 error("declaration for parameter '%s' but no such parameter",
9184 get_tok_str(v
, NULL
));
9186 /* check that no storage specifier except 'register' was given */
9187 if (type
.t
& VT_STORAGE
)
9188 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
9189 convert_parameter_type(&type
);
9190 /* we can add the type (NOTE: it could be local to the function) */
9192 /* accept other parameters */
9203 /* parse a function defined by symbol 'sym' and generate its code in
9204 'cur_text_section' */
9205 static void gen_function(Sym
*sym
)
9207 int saved_nocode_wanted
= nocode_wanted
;
9209 ind
= cur_text_section
->data_offset
;
9210 /* NOTE: we patch the symbol size later */
9211 put_extern_sym(sym
, cur_text_section
, ind
, 0);
9212 funcname
= get_tok_str(sym
->v
, NULL
);
9214 /* put debug symbol */
9216 put_func_debug(sym
);
9217 /* push a dummy symbol to enable local sym storage */
9218 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
9219 gfunc_prolog(&sym
->type
);
9221 block(NULL
, NULL
, NULL
, NULL
, 0, 0);
9224 cur_text_section
->data_offset
= ind
;
9225 label_pop(&global_label_stack
, NULL
);
9226 sym_pop(&local_stack
, NULL
); /* reset local stack */
9227 /* end of function */
9228 /* patch symbol size */
9229 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
9232 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
9234 funcname
= ""; /* for safety */
9235 func_vt
.t
= VT_VOID
; /* for safety */
9236 ind
= 0; /* for safety */
9237 nocode_wanted
= saved_nocode_wanted
;
9240 static void gen_inline_functions(void)
9244 int *str
, inline_generated
;
9246 /* iterate while inline function are referenced */
9248 inline_generated
= 0;
9249 for(sym
= global_stack
; sym
!= NULL
; sym
= sym
->prev
) {
9251 if (((type
->t
& VT_BTYPE
) == VT_FUNC
) &&
9252 (type
->t
& (VT_STATIC
| VT_INLINE
)) ==
9253 (VT_STATIC
| VT_INLINE
) &&
9255 /* the function was used: generate its code and
9256 convert it to a normal function */
9257 str
= INLINE_DEF(sym
->r
);
9258 sym
->r
= VT_SYM
| VT_CONST
;
9259 sym
->type
.t
&= ~VT_INLINE
;
9263 cur_text_section
= text_section
;
9265 macro_ptr
= NULL
; /* fail safe */
9268 inline_generated
= 1;
9271 if (!inline_generated
)
9275 /* free all remaining inline function tokens */
9276 for(sym
= global_stack
; sym
!= NULL
; sym
= sym
->prev
) {
9278 if (((type
->t
& VT_BTYPE
) == VT_FUNC
) &&
9279 (type
->t
& (VT_STATIC
| VT_INLINE
)) ==
9280 (VT_STATIC
| VT_INLINE
)) {
9281 //gr printf("sym %d %s\n", sym->r, get_tok_str(sym->v, NULL));
9282 if (sym
->r
== (VT_SYM
| VT_CONST
)) //gr beware!
9284 str
= INLINE_DEF(sym
->r
);
9286 sym
->r
= 0; /* fail safe */
9291 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
9292 static void decl(int l
)
9300 if (!parse_btype(&btype
, &ad
)) {
9301 /* skip redundant ';' */
9302 /* XXX: find more elegant solution */
9307 if (l
== VT_CONST
&&
9308 (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
9309 /* global asm block */
9313 /* special test for old K&R protos without explicit int
9314 type. Only accepted when defining global data */
9315 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
9319 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
9320 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
9322 /* we accept no variable after */
9326 while (1) { /* iterate thru each declaration */
9328 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
9332 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
9333 printf("type = '%s'\n", buf
);
9336 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
9337 /* if old style function prototype, we accept a
9340 if (sym
->c
== FUNC_OLD
)
9341 func_decl_list(sym
);
9346 error("cannot use local functions");
9347 if ((type
.t
& VT_BTYPE
) != VT_FUNC
)
9348 expect("function definition");
9350 /* reject abstract declarators in function definition */
9352 while ((sym
= sym
->next
) != NULL
)
9353 if (!(sym
->v
& ~SYM_FIELD
))
9354 expect("identifier");
9356 /* XXX: cannot do better now: convert extern line to static inline */
9357 if ((type
.t
& (VT_EXTERN
| VT_INLINE
)) == (VT_EXTERN
| VT_INLINE
))
9358 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
9362 if ((sym
->type
.t
& VT_BTYPE
) != VT_FUNC
)
9364 /* specific case: if not func_call defined, we put
9365 the one of the prototype */
9366 /* XXX: should have default value */
9367 r
= sym
->type
.ref
->r
;
9368 if (FUNC_CALL(r
) != FUNC_CDECL
9369 && FUNC_CALL(type
.ref
->r
) == FUNC_CDECL
)
9370 FUNC_CALL(type
.ref
->r
) = FUNC_CALL(r
);
9372 FUNC_EXPORT(type
.ref
->r
) = 1;
9374 if (!is_compatible_types(&sym
->type
, &type
)) {
9376 error("incompatible types for redefinition of '%s'",
9377 get_tok_str(v
, NULL
));
9379 /* if symbol is already defined, then put complete type */
9382 /* put function symbol */
9383 sym
= global_identifier_push(v
, type
.t
, 0);
9384 sym
->type
.ref
= type
.ref
;
9387 /* static inline functions are just recorded as a kind
9388 of macro. Their code will be emitted at the end of
9389 the compilation unit only if they are used */
9390 if ((type
.t
& (VT_INLINE
| VT_STATIC
)) ==
9391 (VT_INLINE
| VT_STATIC
)) {
9392 TokenString func_str
;
9395 tok_str_new(&func_str
);
9401 error("unexpected end of file");
9402 tok_str_add_tok(&func_str
);
9407 } else if (t
== '}') {
9409 if (block_level
== 0)
9413 tok_str_add(&func_str
, -1);
9414 tok_str_add(&func_str
, 0);
9415 INLINE_DEF(sym
->r
) = func_str
.str
;
9417 /* compute text section */
9418 cur_text_section
= ad
.section
;
9419 if (!cur_text_section
)
9420 cur_text_section
= text_section
;
9421 sym
->r
= VT_SYM
| VT_CONST
;
9426 if (btype
.t
& VT_TYPEDEF
) {
9427 /* save typedefed type */
9428 /* XXX: test storage specifiers ? */
9429 sym
= sym_push(v
, &type
, 0, 0);
9430 sym
->type
.t
|= VT_TYPEDEF
;
9431 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
9432 /* external function definition */
9433 /* specific case for func_call attribute */
9435 type
.ref
->r
= ad
.func_attr
;
9436 external_sym(v
, &type
, 0);
9438 /* not lvalue if array */
9440 if (!(type
.t
& VT_ARRAY
))
9441 r
|= lvalue_type(type
.t
);
9442 has_init
= (tok
== '=');
9443 if ((btype
.t
& VT_EXTERN
) ||
9444 ((type
.t
& VT_ARRAY
) && (type
.t
& VT_STATIC
) &&
9445 !has_init
&& l
== VT_CONST
&& type
.ref
->c
< 0)) {
9446 /* external variable */
9447 /* NOTE: as GCC, uninitialized global static
9448 arrays of null size are considered as
9450 external_sym(v
, &type
, r
);
9452 type
.t
|= (btype
.t
& VT_STATIC
); /* Retain "static". */
9453 if (type
.t
& VT_STATIC
)
9459 decl_initializer_alloc(&type
, &ad
, r
,
9473 /* better than nothing, but needs extension to handle '-E' option
9475 static void preprocess_init(TCCState
*s1
)
9477 s1
->include_stack_ptr
= s1
->include_stack
;
9478 /* XXX: move that before to avoid having to initialize
9479 file->ifdef_stack_ptr ? */
9480 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
9481 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
9483 /* XXX: not ANSI compliant: bound checking says error */
9485 s1
->pack_stack
[0] = 0;
9486 s1
->pack_stack_ptr
= s1
->pack_stack
;
9491 /* compile the C file opened in 'file'. Return non zero if errors. */
9492 static int tcc_compile(TCCState
*s1
)
9496 volatile int section_sym
;
9499 printf("%s: **** new file\n", file
->filename
);
9501 preprocess_init(s1
);
9504 anon_sym
= SYM_FIRST_ANOM
;
9506 /* file info: full path + filename */
9507 section_sym
= 0; /* avoid warning */
9509 section_sym
= put_elf_sym(symtab_section
, 0, 0,
9510 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
9511 text_section
->sh_num
, NULL
);
9512 getcwd(buf
, sizeof(buf
));
9514 normalize_slashes(buf
);
9516 pstrcat(buf
, sizeof(buf
), "/");
9517 put_stabs_r(buf
, N_SO
, 0, 0,
9518 text_section
->data_offset
, text_section
, section_sym
);
9519 put_stabs_r(file
->filename
, N_SO
, 0, 0,
9520 text_section
->data_offset
, text_section
, section_sym
);
9522 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
9523 symbols can be safely used */
9524 put_elf_sym(symtab_section
, 0, 0,
9525 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
9526 SHN_ABS
, file
->filename
);
9528 /* define some often used types */
9529 int_type
.t
= VT_INT
;
9531 char_pointer_type
.t
= VT_BYTE
;
9532 mk_pointer(&char_pointer_type
);
9534 func_old_type
.t
= VT_FUNC
;
9535 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
9537 #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
9538 float_type
.t
= VT_FLOAT
;
9539 double_type
.t
= VT_DOUBLE
;
9541 func_float_type
.t
= VT_FUNC
;
9542 func_float_type
.ref
= sym_push(SYM_FIELD
, &float_type
, FUNC_CDECL
, FUNC_OLD
);
9543 func_double_type
.t
= VT_FUNC
;
9544 func_double_type
.ref
= sym_push(SYM_FIELD
, &double_type
, FUNC_CDECL
, FUNC_OLD
);
9548 /* define 'void *alloca(unsigned int)' builtin function */
9553 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
9554 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
9557 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
9561 define_start
= define_stack
;
9564 if (setjmp(s1
->error_jmp_buf
) == 0) {
9566 s1
->error_set_jmp_enabled
= 1;
9568 ch
= file
->buf_ptr
[0];
9569 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
9570 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
;
9574 expect("declaration");
9576 /* end of translation unit info */
9578 put_stabs_r(NULL
, N_SO
, 0, 0,
9579 text_section
->data_offset
, text_section
, section_sym
);
9582 s1
->error_set_jmp_enabled
= 0;
9584 /* reset define stack, but leave -Dsymbols (may be incorrect if
9585 they are undefined) */
9586 free_defines(define_start
);
9588 gen_inline_functions();
9590 sym_pop(&global_stack
, NULL
);
9591 sym_pop(&local_stack
, NULL
);
9593 return s1
->nb_errors
!= 0 ? -1 : 0;
9596 /* Preprocess the current file */
9597 /* XXX: add line and file infos, add options to preserve spaces */
9598 static int tcc_preprocess(TCCState
*s1
)
9603 preprocess_init(s1
);
9605 define_start
= define_stack
;
9607 ch
= file
->buf_ptr
[0];
9608 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
9609 parse_flags
= PARSE_FLAG_ASM_COMMENTS
| PARSE_FLAG_PREPROCESS
|
9610 PARSE_FLAG_LINEFEED
;
9614 if (tok
== TOK_EOF
) {
9616 } else if (tok
== TOK_LINEFEED
) {
9620 fputc(' ', s1
->outfile
);
9623 fputs(get_tok_str(tok
, &tokc
), s1
->outfile
);
9626 free_defines(define_start
);
9631 int tcc_compile_string(TCCState
*s
, const char *str
)
9633 BufferedFile bf1
, *bf
= &bf1
;
9637 /* init file structure */
9639 /* XXX: avoid copying */
9641 buf
= tcc_malloc(len
+ 1);
9644 memcpy(buf
, str
, len
);
9647 bf
->buf_end
= buf
+ len
;
9648 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
9651 ret
= tcc_compile(s
);
9655 /* currently, no need to close */
9660 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
9661 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
9663 BufferedFile bf1
, *bf
= &bf1
;
9665 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
9666 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
9670 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
9672 /* init file structure */
9674 bf
->buf_ptr
= bf
->buffer
;
9675 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
9676 *bf
->buf_end
= CH_EOB
;
9677 bf
->filename
[0] = '\0';
9681 s1
->include_stack_ptr
= s1
->include_stack
;
9683 /* parse with define parser */
9684 ch
= file
->buf_ptr
[0];
9690 /* undefine a preprocessor symbol */
9691 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
9695 ts
= tok_alloc(sym
, strlen(sym
));
9696 s
= define_find(ts
->tok
);
9697 /* undefine symbol by putting an invalid name */
9702 #ifdef CONFIG_TCC_ASM
9704 #ifdef TCC_TARGET_I386
9705 #include "i386-asm.c"
9710 static void asm_instr(void)
9712 error("inline asm() not supported");
9714 static void asm_global_instr(void)
9716 error("inline asm() not supported");
9722 #ifdef TCC_TARGET_COFF
9723 #include "tcccoff.c"
9726 #ifdef TCC_TARGET_PE
9730 /* print the position in the source file of PC value 'pc' by reading
9731 the stabs debug information */
9732 static void rt_printline(unsigned long wanted_pc
)
9734 Stab_Sym
*sym
, *sym_end
;
9735 char func_name
[128], last_func_name
[128];
9736 unsigned long func_addr
, last_pc
, pc
;
9737 const char *incl_files
[INCLUDE_STACK_SIZE
];
9738 int incl_index
, len
, last_line_num
, i
;
9739 const char *str
, *p
;
9741 fprintf(stderr
, "0x%08lx:", wanted_pc
);
9743 func_name
[0] = '\0';
9746 last_func_name
[0] = '\0';
9747 last_pc
= 0xffffffff;
9749 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
9750 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
9751 while (sym
< sym_end
) {
9752 switch(sym
->n_type
) {
9753 /* function start or end */
9755 if (sym
->n_strx
== 0) {
9756 /* we test if between last line and end of function */
9757 pc
= sym
->n_value
+ func_addr
;
9758 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9760 func_name
[0] = '\0';
9763 str
= stabstr_section
->data
+ sym
->n_strx
;
9764 p
= strchr(str
, ':');
9766 pstrcpy(func_name
, sizeof(func_name
), str
);
9769 if (len
> sizeof(func_name
) - 1)
9770 len
= sizeof(func_name
) - 1;
9771 memcpy(func_name
, str
, len
);
9772 func_name
[len
] = '\0';
9774 func_addr
= sym
->n_value
;
9777 /* line number info */
9779 pc
= sym
->n_value
+ func_addr
;
9780 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9783 last_line_num
= sym
->n_desc
;
9785 strcpy(last_func_name
, func_name
);
9789 str
= stabstr_section
->data
+ sym
->n_strx
;
9791 if (incl_index
< INCLUDE_STACK_SIZE
) {
9792 incl_files
[incl_index
++] = str
;
9800 if (sym
->n_strx
== 0) {
9801 incl_index
= 0; /* end of translation unit */
9803 str
= stabstr_section
->data
+ sym
->n_strx
;
9804 /* do not add path */
9806 if (len
> 0 && str
[len
- 1] != '/')
9814 /* second pass: we try symtab symbols (no line number info) */
9817 Elf32_Sym
*sym
, *sym_end
;
9820 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
9821 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
9824 type
= ELF32_ST_TYPE(sym
->st_info
);
9825 if (type
== STT_FUNC
) {
9826 if (wanted_pc
>= sym
->st_value
&&
9827 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
9828 pstrcpy(last_func_name
, sizeof(last_func_name
),
9829 strtab_section
->data
+ sym
->st_name
);
9835 /* did not find any info: */
9836 fprintf(stderr
, " ???\n");
9839 if (last_func_name
[0] != '\0') {
9840 fprintf(stderr
, " %s()", last_func_name
);
9842 if (incl_index
> 0) {
9843 fprintf(stderr
, " (%s:%d",
9844 incl_files
[incl_index
- 1], last_line_num
);
9845 for(i
= incl_index
- 2; i
>= 0; i
--)
9846 fprintf(stderr
, ", included from %s", incl_files
[i
]);
9847 fprintf(stderr
, ")");
9849 fprintf(stderr
, "\n");
9852 #if !defined(_WIN32) && !defined(CONFIG_TCCBOOT)
9856 /* fix for glibc 2.1 */
9862 /* return the PC at frame level 'level'. Return non zero if not found */
9863 static int rt_get_caller_pc(unsigned long *paddr
,
9864 ucontext_t
*uc
, int level
)
9870 #if defined(__FreeBSD__)
9871 *paddr
= uc
->uc_mcontext
.mc_eip
;
9872 #elif defined(__dietlibc__)
9873 *paddr
= uc
->uc_mcontext
.eip
;
9875 *paddr
= uc
->uc_mcontext
.gregs
[REG_EIP
];
9879 #if defined(__FreeBSD__)
9880 fp
= uc
->uc_mcontext
.mc_ebp
;
9881 #elif defined(__dietlibc__)
9882 fp
= uc
->uc_mcontext
.ebp
;
9884 fp
= uc
->uc_mcontext
.gregs
[REG_EBP
];
9886 for(i
=1;i
<level
;i
++) {
9887 /* XXX: check address validity with program info */
9888 if (fp
<= 0x1000 || fp
>= 0xc0000000)
9890 fp
= ((unsigned long *)fp
)[0];
9892 *paddr
= ((unsigned long *)fp
)[1];
9898 #warning add arch specific rt_get_caller_pc()
9900 static int rt_get_caller_pc(unsigned long *paddr
,
9901 ucontext_t
*uc
, int level
)
9907 /* emit a run time error at position 'pc' */
9908 void rt_error(ucontext_t
*uc
, const char *fmt
, ...)
9915 fprintf(stderr
, "Runtime error: ");
9916 vfprintf(stderr
, fmt
, ap
);
9917 fprintf(stderr
, "\n");
9918 for(i
=0;i
<num_callers
;i
++) {
9919 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
9922 fprintf(stderr
, "at ");
9924 fprintf(stderr
, "by ");
9931 /* signal handler for fatal errors */
9932 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
9934 ucontext_t
*uc
= puc
;
9938 switch(siginf
->si_code
) {
9941 rt_error(uc
, "division by zero");
9944 rt_error(uc
, "floating point exception");
9950 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
9951 rt_error(uc
, *rt_bound_error_msg
);
9953 rt_error(uc
, "dereferencing invalid pointer");
9956 rt_error(uc
, "illegal instruction");
9959 rt_error(uc
, "abort() called");
9962 rt_error(uc
, "caught signal %d", signum
);
9969 /* do all relocations (needed before using tcc_get_symbol()) */
9970 int tcc_relocate(TCCState
*s1
)
9977 #ifdef TCC_TARGET_PE
9980 tcc_add_runtime(s1
);
9983 relocate_common_syms();
9985 tcc_add_linker_symbols(s1
);
9986 #ifndef TCC_TARGET_PE
9987 build_got_entries(s1
);
9989 /* compute relocation address : section are relocated in place. We
9990 also alloc the bss space */
9991 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9992 s
= s1
->sections
[i
];
9993 if (s
->sh_flags
& SHF_ALLOC
) {
9994 if (s
->sh_type
== SHT_NOBITS
)
9995 s
->data
= tcc_mallocz(s
->data_offset
);
9996 s
->sh_addr
= (unsigned long)s
->data
;
10000 relocate_syms(s1
, 1);
10002 if (s1
->nb_errors
!= 0)
10005 /* relocate each section */
10006 for(i
= 1; i
< s1
->nb_sections
; i
++) {
10007 s
= s1
->sections
[i
];
10009 relocate_section(s1
, s
);
10012 /* mark executable sections as executable in memory */
10013 for(i
= 1; i
< s1
->nb_sections
; i
++) {
10014 s
= s1
->sections
[i
];
10015 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_EXECINSTR
)) ==
10016 (SHF_ALLOC
| SHF_EXECINSTR
))
10017 set_pages_executable(s
->data
, s
->data_offset
);
10022 /* launch the compiled program with the given arguments */
10023 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
10025 int (*prog_main
)(int, char **);
10027 if (tcc_relocate(s1
) < 0)
10030 prog_main
= tcc_get_symbol_err(s1
, "main");
10033 #if defined(_WIN32) || defined(CONFIG_TCCBOOT)
10034 error("debug mode currently not available for Windows");
10036 struct sigaction sigact
;
10037 /* install TCC signal handlers to print debug info on fatal
10039 sigact
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
10040 sigact
.sa_sigaction
= sig_error
;
10041 sigemptyset(&sigact
.sa_mask
);
10042 sigaction(SIGFPE
, &sigact
, NULL
);
10043 sigaction(SIGILL
, &sigact
, NULL
);
10044 sigaction(SIGSEGV
, &sigact
, NULL
);
10045 sigaction(SIGBUS
, &sigact
, NULL
);
10046 sigaction(SIGABRT
, &sigact
, NULL
);
10050 #ifdef CONFIG_TCC_BCHECK
10051 if (do_bounds_check
) {
10052 void (*bound_init
)(void);
10054 /* set error function */
10055 rt_bound_error_msg
= (void *)tcc_get_symbol_err(s1
,
10056 "__bound_error_msg");
10058 /* XXX: use .init section so that it also work in binary ? */
10059 bound_init
= (void *)tcc_get_symbol_err(s1
, "__bound_init");
10063 return (*prog_main
)(argc
, argv
);
10066 void tcc_memstats(void)
10069 printf("memory in use: %d\n", mem_cur_size
);
10073 static void tcc_cleanup(void)
10077 if (NULL
== tcc_state
)
10081 /* free -D defines */
10082 free_defines(NULL
);
10085 n
= tok_ident
- TOK_IDENT
;
10086 for(i
= 0; i
< n
; i
++)
10087 tcc_free(table_ident
[i
]);
10088 tcc_free(table_ident
);
10090 /* free sym_pools */
10091 dynarray_reset(&sym_pools
, &nb_sym_pools
);
10092 /* string buffer */
10093 cstr_free(&tokcstr
);
10094 /* reset symbol stack */
10095 sym_free_first
= NULL
;
10098 TCCState
*tcc_new(void)
10107 s
= tcc_mallocz(sizeof(TCCState
));
10111 s
->output_type
= TCC_OUTPUT_MEMORY
;
10113 /* init isid table */
10115 isidnum_table
[i
] = isid(i
) || isnum(i
);
10117 /* add all tokens */
10118 table_ident
= NULL
;
10119 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
10121 tok_ident
= TOK_IDENT
;
10130 ts
= tok_alloc(p
, r
- p
- 1);
10134 /* we add dummy defines for some special macros to speed up tests
10135 and to have working defined() */
10136 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
10137 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
10138 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
10139 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
10141 /* standard defines */
10142 tcc_define_symbol(s
, "__STDC__", NULL
);
10143 tcc_define_symbol(s
, "__STDC_VERSION__", "199901L");
10144 #if defined(TCC_TARGET_I386)
10145 tcc_define_symbol(s
, "__i386__", NULL
);
10147 #if defined(TCC_TARGET_ARM)
10148 tcc_define_symbol(s
, "__ARM_ARCH_4__", NULL
);
10149 tcc_define_symbol(s
, "__arm_elf__", NULL
);
10150 tcc_define_symbol(s
, "__arm_elf", NULL
);
10151 tcc_define_symbol(s
, "arm_elf", NULL
);
10152 tcc_define_symbol(s
, "__arm__", NULL
);
10153 tcc_define_symbol(s
, "__arm", NULL
);
10154 tcc_define_symbol(s
, "arm", NULL
);
10155 tcc_define_symbol(s
, "__APCS_32__", NULL
);
10157 #ifdef TCC_TARGET_PE
10158 tcc_define_symbol(s
, "_WIN32", NULL
);
10160 tcc_define_symbol(s
, "__unix__", NULL
);
10161 tcc_define_symbol(s
, "__unix", NULL
);
10162 #if defined(__linux)
10163 tcc_define_symbol(s
, "__linux__", NULL
);
10164 tcc_define_symbol(s
, "__linux", NULL
);
10167 /* tiny C specific defines */
10168 tcc_define_symbol(s
, "__TINYC__", NULL
);
10170 /* tiny C & gcc defines */
10171 tcc_define_symbol(s
, "__SIZE_TYPE__", "unsigned int");
10172 tcc_define_symbol(s
, "__PTRDIFF_TYPE__", "int");
10173 #ifdef TCC_TARGET_PE
10174 tcc_define_symbol(s
, "__WCHAR_TYPE__", "unsigned short");
10176 tcc_define_symbol(s
, "__WCHAR_TYPE__", "int");
10179 #ifndef TCC_TARGET_PE
10180 /* default library paths */
10181 tcc_add_library_path(s
, "/usr/local/lib");
10182 tcc_add_library_path(s
, "/usr/lib");
10183 tcc_add_library_path(s
, "/lib");
10186 /* no section zero */
10187 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
10189 /* create standard sections */
10190 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
10191 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
10192 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
10194 /* symbols are always generated for linking stage */
10195 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
10197 ".hashtab", SHF_PRIVATE
);
10198 strtab_section
= symtab_section
->link
;
10200 /* private symbol table for dynamic symbols */
10201 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
10203 ".dynhashtab", SHF_PRIVATE
);
10204 s
->alacarte_link
= 1;
10206 #ifdef CHAR_IS_UNSIGNED
10207 s
->char_is_unsigned
= 1;
10209 #if defined(TCC_TARGET_PE) && 0
10210 /* XXX: currently the PE linker is not ready to support that */
10211 s
->leading_underscore
= 1;
10216 void tcc_delete(TCCState
*s1
)
10222 /* free all sections */
10223 free_section(s1
->dynsymtab_section
);
10225 for(i
= 1; i
< s1
->nb_sections
; i
++)
10226 free_section(s1
->sections
[i
]);
10227 tcc_free(s1
->sections
);
10229 /* free loaded dlls array */
10230 dynarray_reset(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
);
10232 /* free library paths */
10233 dynarray_reset(&s1
->library_paths
, &s1
->nb_library_paths
);
10235 /* free include paths */
10236 dynarray_reset(&s1
->cached_includes
, &s1
->nb_cached_includes
);
10237 dynarray_reset(&s1
->include_paths
, &s1
->nb_include_paths
);
10238 dynarray_reset(&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
);
10243 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
10247 pathname1
= tcc_strdup(pathname
);
10248 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
10252 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
10256 pathname1
= tcc_strdup(pathname
);
10257 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
10261 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
10266 BufferedFile
*saved_file
;
10268 /* find source file type with extension */
10269 ext
= tcc_fileextension(filename
);
10273 /* open the file */
10275 file
= tcc_open(s1
, filename
);
10277 if (flags
& AFF_PRINT_ERROR
) {
10278 error_noabort("file '%s' not found", filename
);
10284 if (flags
& AFF_PREPROCESS
) {
10285 ret
= tcc_preprocess(s1
);
10286 } else if (!ext
[0] || !strcmp(ext
, "c")) {
10287 /* C file assumed */
10288 ret
= tcc_compile(s1
);
10290 #ifdef CONFIG_TCC_ASM
10291 if (!strcmp(ext
, "S")) {
10292 /* preprocessed assembler */
10293 ret
= tcc_assemble(s1
, 1);
10294 } else if (!strcmp(ext
, "s")) {
10295 /* non preprocessed assembler */
10296 ret
= tcc_assemble(s1
, 0);
10299 #ifdef TCC_TARGET_PE
10300 if (!strcmp(ext
, "def")) {
10301 ret
= pe_load_def_file(s1
, file
->fd
);
10306 /* assume executable format: auto guess file type */
10307 ret
= read(fd
, &ehdr
, sizeof(ehdr
));
10308 lseek(fd
, 0, SEEK_SET
);
10310 error_noabort("could not read header");
10312 } else if (ret
!= sizeof(ehdr
)) {
10313 goto try_load_script
;
10316 if (ehdr
.e_ident
[0] == ELFMAG0
&&
10317 ehdr
.e_ident
[1] == ELFMAG1
&&
10318 ehdr
.e_ident
[2] == ELFMAG2
&&
10319 ehdr
.e_ident
[3] == ELFMAG3
) {
10320 file
->line_num
= 0; /* do not display line number if error */
10321 if (ehdr
.e_type
== ET_REL
) {
10322 ret
= tcc_load_object_file(s1
, fd
, 0);
10323 } else if (ehdr
.e_type
== ET_DYN
) {
10324 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
10325 #ifdef TCC_TARGET_PE
10329 h
= dlopen(filename
, RTLD_GLOBAL
| RTLD_LAZY
);
10336 ret
= tcc_load_dll(s1
, fd
, filename
,
10337 (flags
& AFF_REFERENCED_DLL
) != 0);
10340 error_noabort("unrecognized ELF file");
10343 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
10344 file
->line_num
= 0; /* do not display line number if error */
10345 ret
= tcc_load_archive(s1
, fd
);
10347 #ifdef TCC_TARGET_COFF
10348 if (*(uint16_t *)(&ehdr
) == COFF_C67_MAGIC
) {
10349 ret
= tcc_load_coff(s1
, fd
);
10352 #ifdef TCC_TARGET_PE
10353 if (pe_test_res_file(&ehdr
, ret
)) {
10354 ret
= pe_load_res_file(s1
, fd
);
10358 /* as GNU ld, consider it is an ld script if not recognized */
10360 ret
= tcc_load_ldscript(s1
);
10362 error_noabort("unrecognized file type");
10377 int tcc_add_file(TCCState
*s
, const char *filename
)
10379 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
10382 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
10386 pathname1
= tcc_strdup(pathname
);
10387 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
10391 /* find and load a dll. Return non zero if not found */
10392 /* XXX: add '-rpath' option support ? */
10393 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
10398 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
10399 snprintf(buf
, sizeof(buf
), "%s/%s",
10400 s
->library_paths
[i
], filename
);
10401 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
10407 /* the library name is the same as the argument of the '-l' option */
10408 int tcc_add_library(TCCState
*s
, const char *libraryname
)
10413 /* first we look for the dynamic library if not static linking */
10414 if (!s
->static_link
) {
10415 #ifdef TCC_TARGET_PE
10416 snprintf(buf
, sizeof(buf
), "%s.def", libraryname
);
10418 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
10420 if (tcc_add_dll(s
, buf
, 0) == 0)
10424 /* then we look for the static library */
10425 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
10426 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
10427 s
->library_paths
[i
], libraryname
);
10428 if (tcc_add_file_internal(s
, buf
, 0) == 0)
10434 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
10436 add_elf_sym(symtab_section
, val
, 0,
10437 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
), 0,
10442 int tcc_set_output_type(TCCState
*s
, int output_type
)
10446 s
->output_type
= output_type
;
10448 if (!s
->nostdinc
) {
10449 /* default include paths */
10450 /* XXX: reverse order needed if -isystem support */
10451 #ifndef TCC_TARGET_PE
10452 tcc_add_sysinclude_path(s
, "/usr/local/include");
10453 tcc_add_sysinclude_path(s
, "/usr/include");
10455 snprintf(buf
, sizeof(buf
), "%s/include", tcc_lib_path
);
10456 tcc_add_sysinclude_path(s
, buf
);
10457 #ifdef TCC_TARGET_PE
10458 snprintf(buf
, sizeof(buf
), "%s/include/winapi", tcc_lib_path
);
10459 tcc_add_sysinclude_path(s
, buf
);
10463 /* if bound checking, then add corresponding sections */
10464 #ifdef CONFIG_TCC_BCHECK
10465 if (do_bounds_check
) {
10466 /* define symbol */
10467 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
10468 /* create bounds sections */
10469 bounds_section
= new_section(s
, ".bounds",
10470 SHT_PROGBITS
, SHF_ALLOC
);
10471 lbounds_section
= new_section(s
, ".lbounds",
10472 SHT_PROGBITS
, SHF_ALLOC
);
10476 if (s
->char_is_unsigned
) {
10477 tcc_define_symbol(s
, "__CHAR_UNSIGNED__", NULL
);
10480 /* add debug sections */
10483 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
10484 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
10485 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
10486 put_elf_str(stabstr_section
, "");
10487 stab_section
->link
= stabstr_section
;
10488 /* put first entry */
10489 put_stabs("", 0, 0, 0, 0);
10492 /* add libc crt1/crti objects */
10493 #ifndef TCC_TARGET_PE
10494 if ((output_type
== TCC_OUTPUT_EXE
|| output_type
== TCC_OUTPUT_DLL
) &&
10496 if (output_type
!= TCC_OUTPUT_DLL
)
10497 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
10498 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
10502 #ifdef TCC_TARGET_PE
10503 snprintf(buf
, sizeof(buf
), "%s/lib", tcc_lib_path
);
10504 tcc_add_library_path(s
, buf
);
10510 #define WD_ALL 0x0001 /* warning is activated when using -Wall */
10511 #define FD_INVERT 0x0002 /* invert value before storing */
10513 typedef struct FlagDef
{
10519 static const FlagDef warning_defs
[] = {
10520 { offsetof(TCCState
, warn_unsupported
), 0, "unsupported" },
10521 { offsetof(TCCState
, warn_write_strings
), 0, "write-strings" },
10522 { offsetof(TCCState
, warn_error
), 0, "error" },
10523 { offsetof(TCCState
, warn_implicit_function_declaration
), WD_ALL
,
10524 "implicit-function-declaration" },
10527 static int set_flag(TCCState
*s
, const FlagDef
*flags
, int nb_flags
,
10528 const char *name
, int value
)
10535 if (r
[0] == 'n' && r
[1] == 'o' && r
[2] == '-') {
10539 for(i
= 0, p
= flags
; i
< nb_flags
; i
++, p
++) {
10540 if (!strcmp(r
, p
->name
))
10545 if (p
->flags
& FD_INVERT
)
10547 *(int *)((uint8_t *)s
+ p
->offset
) = value
;
10552 /* set/reset a warning */
10553 int tcc_set_warning(TCCState
*s
, const char *warning_name
, int value
)
10558 if (!strcmp(warning_name
, "all")) {
10559 for(i
= 0, p
= warning_defs
; i
< countof(warning_defs
); i
++, p
++) {
10560 if (p
->flags
& WD_ALL
)
10561 *(int *)((uint8_t *)s
+ p
->offset
) = 1;
10565 return set_flag(s
, warning_defs
, countof(warning_defs
),
10566 warning_name
, value
);
10570 static const FlagDef flag_defs
[] = {
10571 { offsetof(TCCState
, char_is_unsigned
), 0, "unsigned-char" },
10572 { offsetof(TCCState
, char_is_unsigned
), FD_INVERT
, "signed-char" },
10573 { offsetof(TCCState
, nocommon
), FD_INVERT
, "common" },
10574 { offsetof(TCCState
, leading_underscore
), 0, "leading-underscore" },
10577 /* set/reset a flag */
10578 int tcc_set_flag(TCCState
*s
, const char *flag_name
, int value
)
10580 return set_flag(s
, flag_defs
, countof(flag_defs
),
10584 #if !defined(LIBTCC)
10586 static int64_t getclock_us(void)
10591 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
10594 gettimeofday(&tv
, NULL
);
10595 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
10601 printf("tcc version " TCC_VERSION
" - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n"
10602 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
10603 " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-soname name]\n"
10604 " [-static] [infile1 infile2...] [-run infile args...]\n"
10606 "General options:\n"
10607 " -v display current version, increase verbosity\n"
10608 " -c compile only - generate an object file\n"
10609 " -o outfile set output filename\n"
10610 " -Bdir set tcc internal library path\n"
10611 " -bench output compilation statistics\n"
10612 " -run run compiled source\n"
10613 " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
10614 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
10615 " -w disable all warnings\n"
10616 "Preprocessor options:\n"
10617 " -E preprocess only\n"
10618 " -Idir add include path 'dir'\n"
10619 " -Dsym[=val] define 'sym' with value 'val'\n"
10620 " -Usym undefine 'sym'\n"
10621 "Linker options:\n"
10622 " -Ldir add library path 'dir'\n"
10623 " -llib link with dynamic or static library 'lib'\n"
10624 " -shared generate a shared library\n"
10625 " -soname set name for shared library to be used at runtime\n"
10626 " -static static linking\n"
10627 " -rdynamic export all global symbols to dynamic linker\n"
10628 " -r generate (relocatable) object file\n"
10629 "Debugger options:\n"
10630 " -g generate runtime debug info\n"
10631 #ifdef CONFIG_TCC_BCHECK
10632 " -b compile with built-in memory and bounds checker (implies -g)\n"
10634 " -bt N show N callers in stack traces\n"
10638 #define TCC_OPTION_HAS_ARG 0x0001
10639 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
10641 typedef struct TCCOption
{
10670 TCC_OPTION_nostdinc
,
10671 TCC_OPTION_nostdlib
,
10672 TCC_OPTION_print_search_dirs
,
10673 TCC_OPTION_rdynamic
,
10681 static const TCCOption tcc_options
[] = {
10682 { "h", TCC_OPTION_HELP
, 0 },
10683 { "?", TCC_OPTION_HELP
, 0 },
10684 { "I", TCC_OPTION_I
, TCC_OPTION_HAS_ARG
},
10685 { "D", TCC_OPTION_D
, TCC_OPTION_HAS_ARG
},
10686 { "U", TCC_OPTION_U
, TCC_OPTION_HAS_ARG
},
10687 { "L", TCC_OPTION_L
, TCC_OPTION_HAS_ARG
},
10688 { "B", TCC_OPTION_B
, TCC_OPTION_HAS_ARG
},
10689 { "l", TCC_OPTION_l
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10690 { "bench", TCC_OPTION_bench
, 0 },
10691 { "bt", TCC_OPTION_bt
, TCC_OPTION_HAS_ARG
},
10692 #ifdef CONFIG_TCC_BCHECK
10693 { "b", TCC_OPTION_b
, 0 },
10695 { "g", TCC_OPTION_g
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10696 { "c", TCC_OPTION_c
, 0 },
10697 { "static", TCC_OPTION_static
, 0 },
10698 { "shared", TCC_OPTION_shared
, 0 },
10699 { "soname", TCC_OPTION_soname
, TCC_OPTION_HAS_ARG
},
10700 { "o", TCC_OPTION_o
, TCC_OPTION_HAS_ARG
},
10701 { "run", TCC_OPTION_run
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10702 { "rdynamic", TCC_OPTION_rdynamic
, 0 },
10703 { "r", TCC_OPTION_r
, 0 },
10704 { "Wl,", TCC_OPTION_Wl
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10705 { "W", TCC_OPTION_W
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10706 { "O", TCC_OPTION_O
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10707 { "m", TCC_OPTION_m
, TCC_OPTION_HAS_ARG
},
10708 { "f", TCC_OPTION_f
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10709 { "nostdinc", TCC_OPTION_nostdinc
, 0 },
10710 { "nostdlib", TCC_OPTION_nostdlib
, 0 },
10711 { "print-search-dirs", TCC_OPTION_print_search_dirs
, 0 },
10712 { "v", TCC_OPTION_v
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10713 { "w", TCC_OPTION_w
, 0 },
10714 { "pipe", TCC_OPTION_pipe
, 0},
10715 { "E", TCC_OPTION_E
, 0},
10719 /* convert 'str' into an array of space separated strings */
10720 static int expand_args(char ***pargv
, const char *str
)
10729 while (is_space(*str
))
10734 while (*str
!= '\0' && !is_space(*str
))
10737 arg
= tcc_malloc(len
+ 1);
10738 memcpy(arg
, s1
, len
);
10740 dynarray_add((void ***)&argv
, &argc
, arg
);
10746 static char **files
;
10747 static int nb_files
, nb_libraries
;
10748 static int multiple_files
;
10749 static int print_search_dirs
;
10750 static int output_type
;
10751 static int reloc_output
;
10752 static const char *outfile
;
10754 int parse_args(TCCState
*s
, int argc
, char **argv
)
10757 const TCCOption
*popt
;
10758 const char *optarg
, *p1
, *r1
;
10763 if (optind
>= argc
) {
10764 if (nb_files
== 0 && !print_search_dirs
) {
10771 r
= argv
[optind
++];
10772 if (r
[0] != '-' || r
[1] == '\0') {
10773 /* add a new file */
10774 dynarray_add((void ***)&files
, &nb_files
, r
);
10775 if (!multiple_files
) {
10777 /* argv[0] will be this file */
10781 /* find option in table (match only the first chars */
10782 popt
= tcc_options
;
10786 error("invalid option -- '%s'", r
);
10799 if (popt
->flags
& TCC_OPTION_HAS_ARG
) {
10800 if (*r1
!= '\0' || (popt
->flags
& TCC_OPTION_NOSEP
)) {
10803 if (optind
>= argc
)
10804 error("argument to '%s' is missing", r
);
10805 optarg
= argv
[optind
++];
10813 switch(popt
->index
) {
10814 case TCC_OPTION_HELP
:
10819 if (tcc_add_include_path(s
, optarg
) < 0)
10820 error("too many include paths");
10825 sym
= (char *)optarg
;
10826 value
= strchr(sym
, '=');
10831 tcc_define_symbol(s
, sym
, value
);
10835 tcc_undefine_symbol(s
, optarg
);
10838 tcc_add_library_path(s
, optarg
);
10841 /* set tcc utilities path (mainly for tcc development) */
10842 tcc_lib_path
= optarg
;
10845 dynarray_add((void ***)&files
, &nb_files
, r
);
10848 case TCC_OPTION_bench
:
10851 case TCC_OPTION_bt
:
10852 num_callers
= atoi(optarg
);
10854 #ifdef CONFIG_TCC_BCHECK
10856 do_bounds_check
= 1;
10864 multiple_files
= 1;
10865 output_type
= TCC_OUTPUT_OBJ
;
10867 case TCC_OPTION_static
:
10868 s
->static_link
= 1;
10870 case TCC_OPTION_shared
:
10871 output_type
= TCC_OUTPUT_DLL
;
10873 case TCC_OPTION_soname
:
10874 s
->soname
= optarg
;
10877 multiple_files
= 1;
10881 /* generate a .o merging several output files */
10883 output_type
= TCC_OUTPUT_OBJ
;
10885 case TCC_OPTION_nostdinc
:
10888 case TCC_OPTION_nostdlib
:
10891 case TCC_OPTION_print_search_dirs
:
10892 print_search_dirs
= 1;
10894 case TCC_OPTION_run
:
10898 argc1
= expand_args(&argv1
, optarg
);
10900 parse_args(s
, argc1
, argv1
);
10902 multiple_files
= 0;
10903 output_type
= TCC_OUTPUT_MEMORY
;
10908 if (0 == verbose
++)
10909 printf("tcc version %s\n", TCC_VERSION
);
10910 } while (*optarg
++ == 'v');
10913 if (tcc_set_flag(s
, optarg
, 1) < 0 && s
->warn_unsupported
)
10914 goto unsupported_option
;
10917 if (tcc_set_warning(s
, optarg
, 1) < 0 &&
10918 s
->warn_unsupported
)
10919 goto unsupported_option
;
10924 case TCC_OPTION_rdynamic
:
10927 case TCC_OPTION_Wl
:
10930 if (strstart(optarg
, "-Ttext,", &p
)) {
10931 s
->text_addr
= strtoul(p
, NULL
, 16);
10932 s
->has_text_addr
= 1;
10933 } else if (strstart(optarg
, "--oformat,", &p
)) {
10934 if (strstart(p
, "elf32-", NULL
)) {
10935 s
->output_format
= TCC_OUTPUT_FORMAT_ELF
;
10936 } else if (!strcmp(p
, "binary")) {
10937 s
->output_format
= TCC_OUTPUT_FORMAT_BINARY
;
10939 #ifdef TCC_TARGET_COFF
10940 if (!strcmp(p
, "coff")) {
10941 s
->output_format
= TCC_OUTPUT_FORMAT_COFF
;
10945 error("target %s not found", p
);
10948 error("unsupported linker option '%s'", optarg
);
10953 output_type
= TCC_OUTPUT_PREPROCESS
;
10956 if (s
->warn_unsupported
) {
10957 unsupported_option
:
10958 warning("unsupported option '%s'", r
);
10967 int main(int argc
, char **argv
)
10971 int nb_objfiles
, ret
, optind
;
10972 char objfilename
[1024];
10973 int64_t start_time
= 0;
10976 tcc_lib_path
= w32_tcc_lib_path();
10980 output_type
= TCC_OUTPUT_EXE
;
10982 multiple_files
= 1;
10987 print_search_dirs
= 0;
10990 optind
= parse_args(s
, argc
- 1, argv
+ 1) + 1;
10992 if (print_search_dirs
) {
10993 /* enough for Linux kernel */
10994 printf("install: %s/\n", tcc_lib_path
);
10998 nb_objfiles
= nb_files
- nb_libraries
;
11000 /* if outfile provided without other options, we output an
11002 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
11003 output_type
= TCC_OUTPUT_EXE
;
11005 /* check -c consistency : only single file handled. XXX: checks file type */
11006 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
11007 /* accepts only a single input file */
11008 if (nb_objfiles
!= 1)
11009 error("cannot specify multiple files with -c");
11010 if (nb_libraries
!= 0)
11011 error("cannot specify libraries with -c");
11015 if (output_type
== TCC_OUTPUT_PREPROCESS
) {
11017 s
->outfile
= stdout
;
11019 s
->outfile
= fopen(outfile
, "w");
11021 error("could not open '%s", outfile
);
11023 } else if (output_type
!= TCC_OUTPUT_MEMORY
) {
11025 /* compute default outfile name */
11028 strcmp(files
[0], "-") == 0 ? "a" : tcc_basename(files
[0]);
11029 pstrcpy(objfilename
, sizeof(objfilename
), name
);
11030 ext
= tcc_fileextension(objfilename
);
11031 #ifdef TCC_TARGET_PE
11032 if (output_type
== TCC_OUTPUT_DLL
)
11033 strcpy(ext
, ".dll");
11035 if (output_type
== TCC_OUTPUT_EXE
)
11036 strcpy(ext
, ".exe");
11039 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
&& *ext
)
11042 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
11043 outfile
= objfilename
;
11048 start_time
= getclock_us();
11051 tcc_set_output_type(s
, output_type
);
11053 /* compile or add each files or library */
11054 for(i
= 0; i
< nb_files
&& ret
== 0; i
++) {
11055 const char *filename
;
11057 filename
= files
[i
];
11058 if (output_type
== TCC_OUTPUT_PREPROCESS
) {
11059 if (tcc_add_file_internal(s
, filename
,
11060 AFF_PRINT_ERROR
| AFF_PREPROCESS
) < 0)
11062 } else if (filename
[0] == '-' && filename
[1]) {
11063 if (tcc_add_library(s
, filename
+ 2) < 0)
11064 error("cannot find %s", filename
);
11067 printf("-> %s\n", filename
);
11068 if (tcc_add_file(s
, filename
) < 0)
11073 /* free all files */
11081 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
11082 if (total_time
< 0.001)
11083 total_time
= 0.001;
11084 if (total_bytes
< 1)
11086 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
11087 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
11088 total_time
, (int)(total_lines
/ total_time
),
11089 total_bytes
/ total_time
/ 1000000.0);
11092 if (s
->output_type
== TCC_OUTPUT_PREPROCESS
) {
11094 fclose(s
->outfile
);
11095 } else if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
11096 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
11098 #ifdef TCC_TARGET_PE
11099 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
11100 ret
= pe_output_file(s
, outfile
);
11104 ret
= tcc_output_file(s
, outfile
) ? 1 : 0;
11107 /* XXX: cannot do it with bound checking because of the malloc hooks */
11108 if (!do_bounds_check
)
11113 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);