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
;
394 static SValue vstack
[VSTACK_SIZE
], *vtop
;
395 /* some predefined types */
396 static CType char_pointer_type
, func_old_type
, int_type
;
397 /* true if isid(c) || isnum(c) */
398 static unsigned char isidnum_table
[256];
400 /* display some information during compilation */
401 static int verbose
= 0;
403 /* compile with debug symbol (and use them if error during execution) */
404 static int do_debug
= 0;
406 /* compile with built-in memory and bounds checker */
407 static int do_bounds_check
= 0;
409 /* display benchmark infos */
411 static int do_bench
= 0;
413 static int total_lines
;
414 static int total_bytes
;
416 /* use GNU C extensions */
417 static int gnu_ext
= 1;
419 /* use Tiny C extensions */
420 static int tcc_ext
= 1;
422 /* max number of callers shown if error */
423 static int num_callers
= 6;
424 static const char **rt_bound_error_msg
;
426 /* XXX: get rid of this ASAP */
427 static struct TCCState
*tcc_state
;
429 /* give the path of the tcc libraries */
430 static const char *tcc_lib_path
= CONFIG_TCCDIR
;
435 BufferedFile
**include_stack_ptr
;
436 int *ifdef_stack_ptr
;
438 /* include file handling */
439 char **include_paths
;
440 int nb_include_paths
;
441 char **sysinclude_paths
;
442 int nb_sysinclude_paths
;
443 CachedInclude
**cached_includes
;
444 int nb_cached_includes
;
446 char **library_paths
;
447 int nb_library_paths
;
449 /* array of all loaded dlls (including those referenced by loaded
451 DLLReference
**loaded_dlls
;
456 int nb_sections
; /* number of sections, including first dummy section */
461 unsigned long *got_offsets
;
463 /* give the correspondance from symtab indexes to dynsym indexes */
464 int *symtab_to_dynsym
;
466 /* temporary dynamic symbol sections (for dll loading) */
467 Section
*dynsymtab_section
;
468 /* exported dynamic symbol section */
471 int nostdinc
; /* if true, no standard headers are added */
472 int nostdlib
; /* if true, no standard libraries are added */
474 int nocommon
; /* if true, do not use common symbols for .bss data */
476 /* if true, static linking is performed */
479 /* if true, all symbols are exported */
482 /* if true, only link in referenced objects from archive */
485 /* address of text section */
486 unsigned long text_addr
;
489 /* output format, see TCC_OUTPUT_FORMAT_xxx */
492 /* C language options */
493 int char_is_unsigned
;
494 int leading_underscore
;
496 /* warning switches */
497 int warn_write_strings
;
498 int warn_unsupported
;
501 int warn_implicit_function_declaration
;
505 void (*error_func
)(void *opaque
, const char *msg
);
506 int error_set_jmp_enabled
;
507 jmp_buf error_jmp_buf
;
510 /* tiny assembler state */
513 /* see include_stack_ptr */
514 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
516 /* see ifdef_stack_ptr */
517 int ifdef_stack
[IFDEF_STACK_SIZE
];
519 /* see cached_includes */
520 int cached_includes_hash
[CACHED_INCLUDES_HASH_SIZE
];
523 int pack_stack
[PACK_STACK_SIZE
];
526 /* output file for preprocessing */
530 /* The current value can be: */
531 #define VT_VALMASK 0x00ff
532 #define VT_CONST 0x00f0 /* constant in vc
533 (must be first non register value) */
534 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
535 #define VT_LOCAL 0x00f2 /* offset on stack */
536 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
537 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
538 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
539 #define VT_LVAL 0x0100 /* var is an lvalue */
540 #define VT_SYM 0x0200 /* a symbol value is added */
541 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
542 char/short stored in integer registers) */
543 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
544 dereferencing value */
545 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
546 bounding function call point is in vc */
547 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
548 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
549 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
550 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
553 #define VT_INT 0 /* integer type */
554 #define VT_BYTE 1 /* signed byte type */
555 #define VT_SHORT 2 /* short type */
556 #define VT_VOID 3 /* void type */
557 #define VT_PTR 4 /* pointer */
558 #define VT_ENUM 5 /* enum definition */
559 #define VT_FUNC 6 /* function type */
560 #define VT_STRUCT 7 /* struct/union definition */
561 #define VT_FLOAT 8 /* IEEE float */
562 #define VT_DOUBLE 9 /* IEEE double */
563 #define VT_LDOUBLE 10 /* IEEE long double */
564 #define VT_BOOL 11 /* ISOC99 boolean type */
565 #define VT_LLONG 12 /* 64 bit integer */
566 #define VT_LONG 13 /* long integer (NEVER USED as type, only
568 #define VT_BTYPE 0x000f /* mask for basic type */
569 #define VT_UNSIGNED 0x0010 /* unsigned type */
570 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
571 #define VT_BITFIELD 0x0040 /* bitfield modifier */
572 #define VT_CONSTANT 0x0800 /* const modifier */
573 #define VT_VOLATILE 0x1000 /* volatile modifier */
574 #define VT_SIGNED 0x2000 /* signed type */
577 #define VT_EXTERN 0x00000080 /* extern definition */
578 #define VT_STATIC 0x00000100 /* static variable */
579 #define VT_TYPEDEF 0x00000200 /* typedef definition */
580 #define VT_INLINE 0x00000400 /* inline definition */
582 #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */
584 /* type mask (except storage) */
585 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
586 #define VT_TYPE (~(VT_STORAGE))
590 /* warning: the following compare tokens depend on i386 asm code */
597 #define TOK_Nset 0x98
598 #define TOK_Nclear 0x99
604 #define TOK_LAND 0xa0
608 #define TOK_MID 0xa3 /* inc/dec, to void constant */
610 #define TOK_UDIV 0xb0 /* unsigned division */
611 #define TOK_UMOD 0xb1 /* unsigned modulo */
612 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
613 #define TOK_CINT 0xb3 /* number in tokc */
614 #define TOK_CCHAR 0xb4 /* char constant in tokc */
615 #define TOK_STR 0xb5 /* pointer to string in tokc */
616 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
617 #define TOK_LCHAR 0xb7
618 #define TOK_LSTR 0xb8
619 #define TOK_CFLOAT 0xb9 /* float constant */
620 #define TOK_LINENUM 0xba /* line number info */
621 #define TOK_CDOUBLE 0xc0 /* double constant */
622 #define TOK_CLDOUBLE 0xc1 /* long double constant */
623 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
624 #define TOK_ADDC1 0xc3 /* add with carry generation */
625 #define TOK_ADDC2 0xc4 /* add with carry use */
626 #define TOK_SUBC1 0xc5 /* add with carry generation */
627 #define TOK_SUBC2 0xc6 /* add with carry use */
628 #define TOK_CUINT 0xc8 /* unsigned int constant */
629 #define TOK_CLLONG 0xc9 /* long long constant */
630 #define TOK_CULLONG 0xca /* unsigned long long constant */
631 #define TOK_ARROW 0xcb
632 #define TOK_DOTS 0xcc /* three dots */
633 #define TOK_SHR 0xcd /* unsigned shift right */
634 #define TOK_PPNUM 0xce /* preprocessor number */
636 #define TOK_SHL 0x01 /* shift left */
637 #define TOK_SAR 0x02 /* signed shift right */
639 /* assignement operators : normal operator or 0x80 */
640 #define TOK_A_MOD 0xa5
641 #define TOK_A_AND 0xa6
642 #define TOK_A_MUL 0xaa
643 #define TOK_A_ADD 0xab
644 #define TOK_A_SUB 0xad
645 #define TOK_A_DIV 0xaf
646 #define TOK_A_XOR 0xde
647 #define TOK_A_OR 0xfc
648 #define TOK_A_SHL 0x81
649 #define TOK_A_SAR 0x82
652 #define offsetof(type, field) ((size_t) &((type *)0)->field)
656 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
659 /* WARNING: the content of this string encodes token numbers */
660 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";
662 #define TOK_EOF (-1) /* end of file */
663 #define TOK_LINEFEED 10 /* line feed */
665 /* all identificators and strings have token above that */
666 #define TOK_IDENT 256
668 /* only used for i386 asm opcodes definitions */
669 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
672 DEF(TOK_ASM_ ## x ## b, #x "b") \
673 DEF(TOK_ASM_ ## x ## w, #x "w") \
674 DEF(TOK_ASM_ ## x ## l, #x "l") \
675 DEF(TOK_ASM_ ## x, #x)
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_ ## f ## x ## s, "f" #x "s") \
684 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
685 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
686 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
689 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
690 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
693 #define DEF_ASMTEST(x) \
725 #define TOK_ASM_int TOK_INT
728 TOK_LAST
= TOK_IDENT
- 1,
729 #define DEF(id, str) id,
734 static const char tcc_keywords
[] =
735 #define DEF(id, str) str "\0"
740 #define TOK_UIDENT TOK_DEFINE
743 #define snprintf _snprintf
744 #define vsnprintf _vsnprintf
746 #define strtold (long double)strtod
747 #define strtof (float)strtod
748 #define strtoll (long long)strtol
750 #elif defined(TCC_UCLIBC) || defined(__FreeBSD__) || defined(__DragonFly__) \
751 || defined(__OpenBSD__)
752 /* currently incorrect */
753 long double strtold(const char *nptr
, char **endptr
)
755 return (long double)strtod(nptr
, endptr
);
757 float strtof(const char *nptr
, char **endptr
)
759 return (float)strtod(nptr
, endptr
);
762 /* XXX: need to define this to use them in non ISOC99 context */
763 extern float strtof (const char *__nptr
, char **__endptr
);
764 extern long double strtold (const char *__nptr
, char **__endptr
);
767 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
768 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
769 static char *tcc_basename(const char *name
);
770 static char *tcc_fileextension (const char *p
);
772 static void next(void);
773 static void next_nomacro(void);
774 static void parse_expr_type(CType
*type
);
775 static void expr_type(CType
*type
);
776 static void unary_type(CType
*type
);
777 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
778 int case_reg
, int is_expr
);
779 static int expr_const(void);
780 static void expr_eq(void);
781 static void gexpr(void);
782 static void gen_inline_functions(void);
783 static void decl(int l
);
784 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
785 int first
, int size_only
);
786 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
787 int has_init
, int v
, int scope
);
789 void gv2(int rc1
, int rc2
);
790 void move_reg(int r
, int s
);
791 void save_regs(int n
);
792 void save_reg(int r
);
797 int get_reg_ex(int rc
,int rc2
);
800 struct macro_level
*prev
;
804 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
805 const int *macro_str
, struct macro_level
**can_read_stream
);
807 void force_charshort_cast(int t
);
808 static void gen_cast(CType
*type
);
810 static Sym
*sym_find(int v
);
811 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
814 static int type_size(CType
*type
, int *a
);
815 static inline CType
*pointed_type(CType
*type
);
816 static int pointed_size(CType
*type
);
817 static int lvalue_type(int t
);
818 static int parse_btype(CType
*type
, AttributeDef
*ad
);
819 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
820 static int compare_types(CType
*type1
, CType
*type2
, int unqualified
);
821 static int is_compatible_types(CType
*type1
, CType
*type2
);
822 static int is_compatible_parameter_types(CType
*type1
, CType
*type2
);
824 int ieee_finite(double d
);
825 void error(const char *fmt
, ...);
829 void lexpand_nr(void);
830 static void vpush_global_sym(CType
*type
, int v
);
831 void vset(CType
*type
, int r
, int v
);
832 void type_to_str(char *buf
, int buf_size
,
833 CType
*type
, const char *varstr
);
834 char *get_tok_str(int v
, CValue
*cv
);
835 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
836 unsigned long offset
, unsigned long size
);
837 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
839 /* section generation */
840 static void section_realloc(Section
*sec
, unsigned long new_size
);
841 static void *section_ptr_add(Section
*sec
, unsigned long size
);
842 static void put_extern_sym(Sym
*sym
, Section
*section
,
843 unsigned long value
, unsigned long size
);
844 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
845 static int put_elf_str(Section
*s
, const char *sym
);
846 static int put_elf_sym(Section
*s
,
847 unsigned long value
, unsigned long size
,
848 int info
, int other
, int shndx
, const char *name
);
849 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
850 int info
, int other
, int sh_num
, const char *name
);
851 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
852 int type
, int symbol
);
853 static void put_stabs(const char *str
, int type
, int other
, int desc
,
854 unsigned long value
);
855 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
856 unsigned long value
, Section
*sec
, int sym_index
);
857 static void put_stabn(int type
, int other
, int desc
, int value
);
858 static void put_stabd(int type
, int other
, int desc
);
859 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
861 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
862 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
863 #define AFF_PREPROCESS 0x0004 /* preprocess file */
864 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
867 int tcc_output_coff(TCCState
*s1
, FILE *f
);
870 void *resolve_sym(TCCState
*s1
, const char *sym
, int type
);
871 int pe_load_def_file(struct TCCState
*s1
, int fd
);
872 int pe_test_res_file(void *v
, int size
);
873 int pe_load_res_file(struct TCCState
*s1
, int fd
);
874 void pe_add_runtime(struct TCCState
*s1
);
875 void pe_guess_outfile(char *objfilename
, int output_type
);
876 int pe_output_file(struct TCCState
*s1
, const char *filename
);
880 #ifdef CONFIG_TCC_ASM
882 typedef struct ExprValue
{
887 #define MAX_ASM_OPERANDS 30
889 typedef struct ASMOperand
{
890 int id
; /* GCC 3 optionnal identifier (0 if number only supported */
892 char asm_str
[16]; /* computed asm string for operand */
893 SValue
*vt
; /* C value of the expression */
894 int ref_index
; /* if >= 0, gives reference to a output constraint */
895 int input_index
; /* if >= 0, gives reference to an input constraint */
896 int priority
; /* priority, used to assign registers */
897 int reg
; /* if >= 0, register number used for this operand */
898 int is_llong
; /* true if double register value */
899 int is_memory
; /* true if memory operand */
900 int is_rw
; /* for '+' modifier */
903 static void asm_expr(TCCState
*s1
, ExprValue
*pe
);
904 static int asm_int_expr(TCCState
*s1
);
905 static int find_constraint(ASMOperand
*operands
, int nb_operands
,
906 const char *name
, const char **pp
);
908 static int tcc_assemble(TCCState
*s1
, int do_preprocess
);
912 static void asm_instr(void);
913 static void asm_global_instr(void);
915 /* true if float/double/long double type */
916 static inline int is_float(int t
)
920 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
923 #ifdef TCC_TARGET_I386
924 #include "i386-gen.c"
927 #ifdef TCC_TARGET_ARM
931 #ifdef TCC_TARGET_C67
935 #ifdef CONFIG_TCC_STATIC
937 #define RTLD_LAZY 0x001
938 #define RTLD_NOW 0x002
939 #define RTLD_GLOBAL 0x100
940 #define RTLD_DEFAULT NULL
942 /* dummy function for profiling */
943 void *dlopen(const char *filename
, int flag
)
948 const char *dlerror(void)
953 typedef struct TCCSyms
{
958 #define TCCSYM(a) { #a, &a, },
960 /* add the symbol you want here if no dynamic linking is done */
961 static TCCSyms tcc_syms
[] = {
962 #if !defined(CONFIG_TCCBOOT)
971 void *resolve_sym(TCCState
*s1
, const char *symbol
, int type
)
975 while (p
->str
!= NULL
) {
976 if (!strcmp(p
->str
, symbol
))
983 #elif !defined(_WIN32)
987 void *resolve_sym(TCCState
*s1
, const char *sym
, int type
)
989 return dlsym(RTLD_DEFAULT
, sym
);
994 /********************************************************/
996 /* we use our own 'finite' function to avoid potential problems with
997 non standard math libs */
998 /* XXX: endianness dependent */
999 int ieee_finite(double d
)
1002 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
1005 /* copy a string and truncate it. */
1006 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
1013 q_end
= buf
+ buf_size
- 1;
1025 /* strcat and truncate. */
1026 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
1031 pstrcpy(buf
+ len
, buf_size
- len
, s
);
1035 static int strstart(const char *str
, const char *val
, const char **ptr
)
1040 while (*q
!= '\0') {
1051 /* extract the basename of a file */
1052 static char *tcc_basename(const char *name
)
1054 char *p
= strchr(name
, 0);
1065 static char *tcc_fileextension (const char *name
)
1067 char *b
= tcc_basename(name
);
1068 char *e
= strrchr(b
, '.');
1069 return e
? e
: strchr(b
, 0);
1073 char *normalize_slashes(char *path
)
1076 for (p
= path
; *p
; ++p
)
1082 char *w32_tcc_lib_path(void)
1084 /* on win32, we suppose the lib and includes are at the location
1086 char path
[1024], *p
;
1087 GetModuleFileNameA(NULL
, path
, sizeof path
);
1088 p
= tcc_basename(normalize_slashes(strlwr(path
)));
1089 if (p
- 5 > path
&& 0 == strncmp(p
- 5, "/bin/", 5))
1094 return strdup(path
);
1098 void set_pages_executable(void *ptr
, unsigned long length
)
1101 unsigned long old_protect
;
1102 VirtualProtect(ptr
, length
, PAGE_EXECUTE_READWRITE
, &old_protect
);
1104 unsigned long start
, end
;
1105 start
= (unsigned long)ptr
& ~(PAGESIZE
- 1);
1106 end
= (unsigned long)ptr
+ length
;
1107 end
= (end
+ PAGESIZE
- 1) & ~(PAGESIZE
- 1);
1108 mprotect((void *)start
, end
- start
, PROT_READ
| PROT_WRITE
| PROT_EXEC
);
1112 /* memory management */
1118 static inline void tcc_free(void *ptr
)
1121 mem_cur_size
-= malloc_usable_size(ptr
);
1126 static void *tcc_malloc(unsigned long size
)
1131 error("memory full");
1133 mem_cur_size
+= malloc_usable_size(ptr
);
1134 if (mem_cur_size
> mem_max_size
)
1135 mem_max_size
= mem_cur_size
;
1140 static void *tcc_mallocz(unsigned long size
)
1143 ptr
= tcc_malloc(size
);
1144 memset(ptr
, 0, size
);
1148 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
1152 mem_cur_size
-= malloc_usable_size(ptr
);
1154 ptr1
= realloc(ptr
, size
);
1156 /* NOTE: count not correct if alloc error, but not critical */
1157 mem_cur_size
+= malloc_usable_size(ptr1
);
1158 if (mem_cur_size
> mem_max_size
)
1159 mem_max_size
= mem_cur_size
;
1164 static char *tcc_strdup(const char *str
)
1167 ptr
= tcc_malloc(strlen(str
) + 1);
1172 #define free(p) use_tcc_free(p)
1173 #define malloc(s) use_tcc_malloc(s)
1174 #define realloc(p, s) use_tcc_realloc(p, s)
1176 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
1183 /* every power of two we double array size */
1184 if ((nb
& (nb
- 1)) == 0) {
1189 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
1191 error("memory full");
1198 static void dynarray_reset(void *pp
, int *n
)
1201 for (p
= *(void***)pp
; *n
; ++p
, --*n
)
1204 tcc_free(*(void**)pp
);
1208 /* symbol allocator */
1209 static Sym
*__sym_malloc(void)
1211 Sym
*sym_pool
, *sym
, *last_sym
;
1214 sym_pool
= tcc_malloc(SYM_POOL_NB
* sizeof(Sym
));
1216 last_sym
= sym_free_first
;
1218 for(i
= 0; i
< SYM_POOL_NB
; i
++) {
1219 sym
->next
= last_sym
;
1223 sym_free_first
= last_sym
;
1227 static inline Sym
*sym_malloc(void)
1230 sym
= sym_free_first
;
1232 sym
= __sym_malloc();
1233 sym_free_first
= sym
->next
;
1237 static inline void sym_free(Sym
*sym
)
1239 sym
->next
= sym_free_first
;
1240 sym_free_first
= sym
;
1243 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
1247 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
1248 strcpy(sec
->name
, name
);
1249 sec
->sh_type
= sh_type
;
1250 sec
->sh_flags
= sh_flags
;
1257 sec
->sh_addralign
= 4;
1260 sec
->sh_addralign
= 1;
1263 sec
->sh_addralign
= 32; /* default conservative alignment */
1267 /* only add section if not private */
1268 if (!(sh_flags
& SHF_PRIVATE
)) {
1269 sec
->sh_num
= s1
->nb_sections
;
1270 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
1275 static void free_section(Section
*s
)
1281 /* realloc section and set its content to zero */
1282 static void section_realloc(Section
*sec
, unsigned long new_size
)
1285 unsigned char *data
;
1287 size
= sec
->data_allocated
;
1290 while (size
< new_size
)
1292 data
= tcc_realloc(sec
->data
, size
);
1294 error("memory full");
1295 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
1297 sec
->data_allocated
= size
;
1300 /* reserve at least 'size' bytes in section 'sec' from
1301 sec->data_offset. */
1302 static void *section_ptr_add(Section
*sec
, unsigned long size
)
1304 unsigned long offset
, offset1
;
1306 offset
= sec
->data_offset
;
1307 offset1
= offset
+ size
;
1308 if (offset1
> sec
->data_allocated
)
1309 section_realloc(sec
, offset1
);
1310 sec
->data_offset
= offset1
;
1311 return sec
->data
+ offset
;
1314 /* return a reference to a section, and create it if it does not
1316 Section
*find_section(TCCState
*s1
, const char *name
)
1320 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1321 sec
= s1
->sections
[i
];
1322 if (!strcmp(name
, sec
->name
))
1325 /* sections are created as PROGBITS */
1326 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
1329 #define SECTION_ABS ((void *)1)
1331 /* update sym->c so that it points to an external symbol in section
1332 'section' with value 'value' */
1333 static void put_extern_sym2(Sym
*sym
, Section
*section
,
1334 unsigned long value
, unsigned long size
,
1335 int can_add_underscore
)
1337 int sym_type
, sym_bind
, sh_num
, info
, other
, attr
;
1342 if (section
== NULL
)
1344 else if (section
== SECTION_ABS
)
1347 sh_num
= section
->sh_num
;
1351 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
) {
1352 sym_type
= STT_FUNC
;
1353 #ifdef TCC_TARGET_PE
1355 attr
= sym
->type
.ref
->r
;
1356 if (FUNC_EXPORT(attr
))
1358 if (FUNC_CALL(attr
) == FUNC_STDCALL
)
1362 sym_type
= STT_OBJECT
;
1365 if (sym
->type
.t
& VT_STATIC
)
1366 sym_bind
= STB_LOCAL
;
1368 sym_bind
= STB_GLOBAL
;
1371 name
= get_tok_str(sym
->v
, NULL
);
1372 #ifdef CONFIG_TCC_BCHECK
1373 if (do_bounds_check
) {
1376 /* XXX: avoid doing that for statics ? */
1377 /* if bound checking is activated, we change some function
1378 names by adding the "__bound" prefix */
1381 /* XXX: we rely only on malloc hooks */
1394 strcpy(buf
, "__bound_");
1402 #ifdef TCC_TARGET_PE
1403 if ((other
& 2) && can_add_underscore
) {
1404 sprintf(buf1
, "_%s@%d", name
, FUNC_ARGS(attr
));
1408 if (tcc_state
->leading_underscore
&& can_add_underscore
) {
1410 pstrcpy(buf1
+ 1, sizeof(buf1
) - 1, name
);
1413 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
1414 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, other
, sh_num
, name
);
1416 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
1417 esym
->st_value
= value
;
1418 esym
->st_size
= size
;
1419 esym
->st_shndx
= sh_num
;
1420 esym
->st_other
|= other
;
1424 static void put_extern_sym(Sym
*sym
, Section
*section
,
1425 unsigned long value
, unsigned long size
)
1427 put_extern_sym2(sym
, section
, value
, size
, 1);
1430 /* add a new relocation entry to symbol 'sym' in section 's' */
1431 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
1434 put_extern_sym(sym
, NULL
, 0, 0);
1435 /* now we can add ELF relocation info */
1436 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
1439 static inline int isid(int c
)
1441 return (c
>= 'a' && c
<= 'z') ||
1442 (c
>= 'A' && c
<= 'Z') ||
1446 static inline int isnum(int c
)
1448 return c
>= '0' && c
<= '9';
1451 static inline int isoct(int c
)
1453 return c
>= '0' && c
<= '7';
1456 static inline int toup(int c
)
1458 if (c
>= 'a' && c
<= 'z')
1459 return c
- 'a' + 'A';
1464 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1468 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1471 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1475 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1479 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1486 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1487 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1488 (*f
)->filename
, (*f
)->line_num
);
1489 if (file
->line_num
> 0) {
1490 strcat_printf(buf
, sizeof(buf
),
1491 "%s:%d: ", file
->filename
, file
->line_num
);
1493 strcat_printf(buf
, sizeof(buf
),
1494 "%s: ", file
->filename
);
1497 strcat_printf(buf
, sizeof(buf
),
1501 strcat_printf(buf
, sizeof(buf
), "warning: ");
1502 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1504 if (!s1
->error_func
) {
1505 /* default case: stderr */
1506 fprintf(stderr
, "%s\n", buf
);
1508 s1
->error_func(s1
->error_opaque
, buf
);
1510 if (!is_warning
|| s1
->warn_error
)
1515 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1516 void (*error_func
)(void *opaque
, const char *msg
))
1518 s
->error_opaque
= error_opaque
;
1519 s
->error_func
= error_func
;
1523 /* error without aborting current compilation */
1524 void error_noabort(const char *fmt
, ...)
1526 TCCState
*s1
= tcc_state
;
1530 error1(s1
, 0, fmt
, ap
);
1534 void error(const char *fmt
, ...)
1536 TCCState
*s1
= tcc_state
;
1540 error1(s1
, 0, fmt
, ap
);
1542 /* better than nothing: in some cases, we accept to handle errors */
1543 if (s1
->error_set_jmp_enabled
) {
1544 longjmp(s1
->error_jmp_buf
, 1);
1546 /* XXX: eliminate this someday */
1551 void expect(const char *msg
)
1553 error("%s expected", msg
);
1556 void warning(const char *fmt
, ...)
1558 TCCState
*s1
= tcc_state
;
1565 error1(s1
, 1, fmt
, ap
);
1572 error("'%c' expected", c
);
1576 static void test_lvalue(void)
1578 if (!(vtop
->r
& VT_LVAL
))
1582 /* allocate a new token */
1583 static TokenSym
*tok_alloc_new(TokenSym
**pts
, const char *str
, int len
)
1585 TokenSym
*ts
, **ptable
;
1588 if (tok_ident
>= SYM_FIRST_ANOM
)
1589 error("memory full");
1591 /* expand token table if needed */
1592 i
= tok_ident
- TOK_IDENT
;
1593 if ((i
% TOK_ALLOC_INCR
) == 0) {
1594 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1596 error("memory full");
1597 table_ident
= ptable
;
1600 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1601 table_ident
[i
] = ts
;
1602 ts
->tok
= tok_ident
++;
1603 ts
->sym_define
= NULL
;
1604 ts
->sym_label
= NULL
;
1605 ts
->sym_struct
= NULL
;
1606 ts
->sym_identifier
= NULL
;
1608 ts
->hash_next
= NULL
;
1609 memcpy(ts
->str
, str
, len
);
1610 ts
->str
[len
] = '\0';
1615 #define TOK_HASH_INIT 1
1616 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1618 /* find a token and add it if not found */
1619 static TokenSym
*tok_alloc(const char *str
, int len
)
1621 TokenSym
*ts
, **pts
;
1627 h
= TOK_HASH_FUNC(h
, ((unsigned char *)str
)[i
]);
1628 h
&= (TOK_HASH_SIZE
- 1);
1630 pts
= &hash_ident
[h
];
1635 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1637 pts
= &(ts
->hash_next
);
1639 return tok_alloc_new(pts
, str
, len
);
1642 /* CString handling */
1644 static void cstr_realloc(CString
*cstr
, int new_size
)
1649 size
= cstr
->size_allocated
;
1651 size
= 8; /* no need to allocate a too small first string */
1652 while (size
< new_size
)
1654 data
= tcc_realloc(cstr
->data_allocated
, size
);
1656 error("memory full");
1657 cstr
->data_allocated
= data
;
1658 cstr
->size_allocated
= size
;
1663 static inline void cstr_ccat(CString
*cstr
, int ch
)
1666 size
= cstr
->size
+ 1;
1667 if (size
> cstr
->size_allocated
)
1668 cstr_realloc(cstr
, size
);
1669 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1673 static void cstr_cat(CString
*cstr
, const char *str
)
1685 /* add a wide char */
1686 static void cstr_wccat(CString
*cstr
, int ch
)
1689 size
= cstr
->size
+ sizeof(nwchar_t
);
1690 if (size
> cstr
->size_allocated
)
1691 cstr_realloc(cstr
, size
);
1692 *(nwchar_t
*)(((unsigned char *)cstr
->data
) + size
- sizeof(nwchar_t
)) = ch
;
1696 static void cstr_new(CString
*cstr
)
1698 memset(cstr
, 0, sizeof(CString
));
1701 /* free string and reset it to NULL */
1702 static void cstr_free(CString
*cstr
)
1704 tcc_free(cstr
->data_allocated
);
1708 #define cstr_reset(cstr) cstr_free(cstr)
1710 /* XXX: unicode ? */
1711 static void add_char(CString
*cstr
, int c
)
1713 if (c
== '\'' || c
== '\"' || c
== '\\') {
1714 /* XXX: could be more precise if char or string */
1715 cstr_ccat(cstr
, '\\');
1717 if (c
>= 32 && c
<= 126) {
1720 cstr_ccat(cstr
, '\\');
1722 cstr_ccat(cstr
, 'n');
1724 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1725 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1726 cstr_ccat(cstr
, '0' + (c
& 7));
1731 /* XXX: buffer overflow */
1732 /* XXX: float tokens */
1733 char *get_tok_str(int v
, CValue
*cv
)
1735 static char buf
[STRING_MAX_SIZE
+ 1];
1736 static CString cstr_buf
;
1742 /* NOTE: to go faster, we give a fixed buffer for small strings */
1743 cstr_reset(&cstr_buf
);
1744 cstr_buf
.data
= buf
;
1745 cstr_buf
.size_allocated
= sizeof(buf
);
1751 /* XXX: not quite exact, but only useful for testing */
1752 sprintf(p
, "%u", cv
->ui
);
1756 /* XXX: not quite exact, but only useful for testing */
1757 sprintf(p
, "%Lu", cv
->ull
);
1761 cstr_ccat(&cstr_buf
, '\'');
1762 add_char(&cstr_buf
, cv
->i
);
1763 cstr_ccat(&cstr_buf
, '\'');
1764 cstr_ccat(&cstr_buf
, '\0');
1768 len
= cstr
->size
- 1;
1770 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1771 cstr_ccat(&cstr_buf
, '\0');
1776 cstr_ccat(&cstr_buf
, '\"');
1778 len
= cstr
->size
- 1;
1780 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1782 len
= (cstr
->size
/ sizeof(nwchar_t
)) - 1;
1784 add_char(&cstr_buf
, ((nwchar_t
*)cstr
->data
)[i
]);
1786 cstr_ccat(&cstr_buf
, '\"');
1787 cstr_ccat(&cstr_buf
, '\0');
1796 return strcpy(p
, "...");
1798 return strcpy(p
, "<<=");
1800 return strcpy(p
, ">>=");
1802 if (v
< TOK_IDENT
) {
1803 /* search in two bytes table */
1817 } else if (v
< tok_ident
) {
1818 return table_ident
[v
- TOK_IDENT
]->str
;
1819 } else if (v
>= SYM_FIRST_ANOM
) {
1820 /* special name for anonymous symbol */
1821 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1823 /* should never happen */
1828 return cstr_buf
.data
;
1831 /* push, without hashing */
1832 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1846 /* find a symbol and return its associated structure. 's' is the top
1847 of the symbol stack */
1848 static Sym
*sym_find2(Sym
*s
, int v
)
1858 /* structure lookup */
1859 static inline Sym
*struct_find(int v
)
1862 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1864 return table_ident
[v
]->sym_struct
;
1867 /* find an identifier */
1868 static inline Sym
*sym_find(int v
)
1871 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1873 return table_ident
[v
]->sym_identifier
;
1876 /* push a given symbol on the symbol stack */
1877 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1886 s
= sym_push2(ps
, v
, type
->t
, c
);
1887 s
->type
.ref
= type
->ref
;
1889 /* don't record fields or anonymous symbols */
1891 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1892 /* record symbol in token array */
1893 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1895 ps
= &ts
->sym_struct
;
1897 ps
= &ts
->sym_identifier
;
1904 /* push a global identifier */
1905 static Sym
*global_identifier_push(int v
, int t
, int c
)
1908 s
= sym_push2(&global_stack
, v
, t
, c
);
1909 /* don't record anonymous symbol */
1910 if (v
< SYM_FIRST_ANOM
) {
1911 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1912 /* modify the top most local identifier, so that
1913 sym_identifier will point to 's' when popped */
1915 ps
= &(*ps
)->prev_tok
;
1922 /* pop symbols until top reaches 'b' */
1923 static void sym_pop(Sym
**ptop
, Sym
*b
)
1933 /* remove symbol in token array */
1935 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1936 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1938 ps
= &ts
->sym_struct
;
1940 ps
= &ts
->sym_identifier
;
1951 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1956 fd
= open(filename
, O_RDONLY
| O_BINARY
);
1959 bf
= tcc_malloc(sizeof(BufferedFile
));
1965 bf
->buf_ptr
= bf
->buffer
;
1966 bf
->buf_end
= bf
->buffer
;
1967 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1968 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1970 normalize_slashes(bf
->filename
);
1973 bf
->ifndef_macro
= 0;
1974 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1975 // printf("opening '%s'\n", filename);
1979 void tcc_close(BufferedFile
*bf
)
1981 total_lines
+= bf
->line_num
;
1986 /* fill input buffer and peek next char */
1987 static int tcc_peekc_slow(BufferedFile
*bf
)
1990 /* only tries to read if really end of buffer */
1991 if (bf
->buf_ptr
>= bf
->buf_end
) {
1993 #if defined(PARSE_DEBUG)
1998 len
= read(bf
->fd
, bf
->buffer
, len
);
2005 bf
->buf_ptr
= bf
->buffer
;
2006 bf
->buf_end
= bf
->buffer
+ len
;
2007 *bf
->buf_end
= CH_EOB
;
2009 if (bf
->buf_ptr
< bf
->buf_end
) {
2010 return bf
->buf_ptr
[0];
2012 bf
->buf_ptr
= bf
->buf_end
;
2017 /* return the current character, handling end of block if necessary
2019 static int handle_eob(void)
2021 return tcc_peekc_slow(file
);
2024 /* read next char from current input file and handle end of input buffer */
2025 static inline void inp(void)
2027 ch
= *(++(file
->buf_ptr
));
2028 /* end of buffer/file handling */
2033 /* handle '\[\r]\n' */
2034 static int handle_stray_noerror(void)
2036 while (ch
== '\\') {
2041 } else if (ch
== '\r') {
2055 static void handle_stray(void)
2057 if (handle_stray_noerror())
2058 error("stray '\\' in program");
2061 /* skip the stray and handle the \\n case. Output an error if
2062 incorrect char after the stray */
2063 static int handle_stray1(uint8_t *p
)
2067 if (p
>= file
->buf_end
) {
2084 /* handle just the EOB case, but not stray */
2085 #define PEEKC_EOB(c, p)\
2096 /* handle the complicated stray case */
2097 #define PEEKC(c, p)\
2102 c = handle_stray1(p);\
2107 /* input with '\[\r]\n' handling. Note that this function cannot
2108 handle other characters after '\', so you cannot call it inside
2109 strings or comments */
2110 static void minp(void)
2118 /* single line C++ comments */
2119 static uint8_t *parse_line_comment(uint8_t *p
)
2127 if (c
== '\n' || c
== CH_EOF
) {
2129 } else if (c
== '\\') {
2138 } else if (c
== '\r') {
2156 static uint8_t *parse_comment(uint8_t *p
)
2162 /* fast skip loop */
2165 if (c
== '\n' || c
== '*' || c
== '\\')
2169 if (c
== '\n' || c
== '*' || c
== '\\')
2173 /* now we can handle all the cases */
2177 } else if (c
== '*') {
2183 } else if (c
== '/') {
2184 goto end_of_comment
;
2185 } else if (c
== '\\') {
2190 /* skip '\[\r]\n', otherwise just skip the stray */
2196 } else if (c
== '\r') {
2213 /* stray, eob or eof */
2218 error("unexpected end of file in comment");
2219 } else if (c
== '\\') {
2231 /* space exlcuding newline */
2232 static inline int is_space(int ch
)
2234 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
2237 static inline void skip_spaces(void)
2239 while (is_space(ch
))
2243 /* parse a string without interpreting escapes */
2244 static uint8_t *parse_pp_string(uint8_t *p
,
2245 int sep
, CString
*str
)
2253 } else if (c
== '\\') {
2258 unterminated_string
:
2259 /* XXX: indicate line number of start of string */
2260 error("missing terminating %c character", sep
);
2261 } else if (c
== '\\') {
2262 /* escape : just skip \[\r]\n */
2267 } else if (c
== '\r') {
2270 expect("'\n' after '\r'");
2273 } else if (c
== CH_EOF
) {
2274 goto unterminated_string
;
2277 cstr_ccat(str
, '\\');
2283 } else if (c
== '\n') {
2286 } else if (c
== '\r') {
2290 cstr_ccat(str
, '\r');
2306 /* skip block of text until #else, #elif or #endif. skip also pairs of
2308 void preprocess_skip(void)
2310 int a
, start_of_line
, c
, in_warn_or_error
;
2317 in_warn_or_error
= 0;
2338 } else if (c
== '\\') {
2339 ch
= file
->buf_ptr
[0];
2340 handle_stray_noerror();
2347 if (in_warn_or_error
)
2349 p
= parse_pp_string(p
, c
, NULL
);
2353 if (in_warn_or_error
)
2360 p
= parse_comment(p
);
2361 } else if (ch
== '/') {
2362 p
= parse_line_comment(p
);
2367 if (start_of_line
) {
2372 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
2374 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
2376 else if (tok
== TOK_ENDIF
)
2378 else if( tok
== TOK_ERROR
|| tok
== TOK_WARNING
)
2379 in_warn_or_error
= 1;
2393 /* ParseState handling */
2395 /* XXX: currently, no include file info is stored. Thus, we cannot display
2396 accurate messages if the function or data definition spans multiple
2399 /* save current parse state in 's' */
2400 void save_parse_state(ParseState
*s
)
2402 s
->line_num
= file
->line_num
;
2403 s
->macro_ptr
= macro_ptr
;
2408 /* restore parse state from 's' */
2409 void restore_parse_state(ParseState
*s
)
2411 file
->line_num
= s
->line_num
;
2412 macro_ptr
= s
->macro_ptr
;
2417 /* return the number of additional 'ints' necessary to store the
2419 static inline int tok_ext_size(int t
)
2433 error("unsupported token");
2440 return LDOUBLE_SIZE
/ 4;
2446 /* token string handling */
2448 static inline void tok_str_new(TokenString
*s
)
2452 s
->allocated_len
= 0;
2453 s
->last_line_num
= -1;
2456 static void tok_str_free(int *str
)
2461 static int *tok_str_realloc(TokenString
*s
)
2465 if (s
->allocated_len
== 0) {
2468 len
= s
->allocated_len
* 2;
2470 str
= tcc_realloc(s
->str
, len
* sizeof(int));
2472 error("memory full");
2473 s
->allocated_len
= len
;
2478 static void tok_str_add(TokenString
*s
, int t
)
2484 if (len
>= s
->allocated_len
)
2485 str
= tok_str_realloc(s
);
2490 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
2497 /* allocate space for worst case */
2498 if (len
+ TOK_MAX_SIZE
> s
->allocated_len
)
2499 str
= tok_str_realloc(s
);
2508 str
[len
++] = cv
->tab
[0];
2517 nb_words
= (sizeof(CString
) + cv
->cstr
->size
+ 3) >> 2;
2518 while ((len
+ nb_words
) > s
->allocated_len
)
2519 str
= tok_str_realloc(s
);
2520 cstr
= (CString
*)(str
+ len
);
2522 cstr
->size
= cv
->cstr
->size
;
2523 cstr
->data_allocated
= NULL
;
2524 cstr
->size_allocated
= cstr
->size
;
2525 memcpy((char *)cstr
+ sizeof(CString
),
2526 cv
->cstr
->data
, cstr
->size
);
2533 #if LDOUBLE_SIZE == 8
2536 str
[len
++] = cv
->tab
[0];
2537 str
[len
++] = cv
->tab
[1];
2539 #if LDOUBLE_SIZE == 12
2541 str
[len
++] = cv
->tab
[0];
2542 str
[len
++] = cv
->tab
[1];
2543 str
[len
++] = cv
->tab
[2];
2544 #elif LDOUBLE_SIZE != 8
2545 #error add long double size support
2554 /* add the current parse token in token string 's' */
2555 static void tok_str_add_tok(TokenString
*s
)
2559 /* save line number info */
2560 if (file
->line_num
!= s
->last_line_num
) {
2561 s
->last_line_num
= file
->line_num
;
2562 cval
.i
= s
->last_line_num
;
2563 tok_str_add2(s
, TOK_LINENUM
, &cval
);
2565 tok_str_add2(s
, tok
, &tokc
);
2568 #if LDOUBLE_SIZE == 12
2569 #define LDOUBLE_GET(p, cv) \
2573 #elif LDOUBLE_SIZE == 8
2574 #define LDOUBLE_GET(p, cv) \
2578 #error add long double size support
2582 /* get a token from an integer array and increment pointer
2583 accordingly. we code it as a macro to avoid pointer aliasing. */
2584 #define TOK_GET(t, p, cv) \
2599 cv.cstr = (CString *)p; \
2600 cv.cstr->data = (char *)p + sizeof(CString);\
2601 p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\
2610 case TOK_CLDOUBLE: \
2611 LDOUBLE_GET(p, cv); \
2612 p += LDOUBLE_SIZE / 4; \
2619 /* defines handling */
2620 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
2624 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
2625 s
->next
= first_arg
;
2626 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
2629 /* undefined a define symbol. Its name is just set to zero */
2630 static void define_undef(Sym
*s
)
2634 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2635 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2639 static inline Sym
*define_find(int v
)
2642 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2644 return table_ident
[v
]->sym_define
;
2647 /* free define stack until top reaches 'b' */
2648 static void free_defines(Sym
*b
)
2656 /* do not free args or predefined defines */
2658 tok_str_free((int *)top
->c
);
2660 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2661 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2669 static Sym
*label_find(int v
)
2672 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2674 return table_ident
[v
]->sym_label
;
2677 static Sym
*label_push(Sym
**ptop
, int v
, int flags
)
2680 s
= sym_push2(ptop
, v
, 0, 0);
2682 ps
= &table_ident
[v
- TOK_IDENT
]->sym_label
;
2683 if (ptop
== &global_label_stack
) {
2684 /* modify the top most local identifier, so that
2685 sym_identifier will point to 's' when popped */
2687 ps
= &(*ps
)->prev_tok
;
2694 /* pop labels until element last is reached. Look if any labels are
2695 undefined. Define symbols if '&&label' was used. */
2696 static void label_pop(Sym
**ptop
, Sym
*slast
)
2699 for(s
= *ptop
; s
!= slast
; s
= s1
) {
2701 if (s
->r
== LABEL_DECLARED
) {
2702 warning("label '%s' declared but not used", get_tok_str(s
->v
, NULL
));
2703 } else if (s
->r
== LABEL_FORWARD
) {
2704 error("label '%s' used but not defined",
2705 get_tok_str(s
->v
, NULL
));
2708 /* define corresponding symbol. A size of
2710 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
2714 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= s
->prev_tok
;
2720 /* eval an expression for #if/#elif */
2721 static int expr_preprocess(void)
2727 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2728 next(); /* do macro subst */
2729 if (tok
== TOK_DEFINED
) {
2734 c
= define_find(tok
) != 0;
2739 } else if (tok
>= TOK_IDENT
) {
2740 /* if undefined macro */
2744 tok_str_add_tok(&str
);
2746 tok_str_add(&str
, -1); /* simulate end of file */
2747 tok_str_add(&str
, 0);
2748 /* now evaluate C constant expression */
2749 macro_ptr
= str
.str
;
2753 tok_str_free(str
.str
);
2757 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2758 static void tok_print(int *str
)
2764 TOK_GET(t
, str
, cval
);
2767 printf(" %s", get_tok_str(t
, &cval
));
2773 /* parse after #define */
2774 static void parse_define(void)
2776 Sym
*s
, *first
, **ps
;
2777 int v
, t
, varg
, is_vaargs
, c
;
2782 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2783 /* XXX: should check if same macro (ANSI) */
2786 /* '(' must be just after macro definition for MACRO_FUNC */
2787 c
= file
->buf_ptr
[0];
2789 c
= handle_stray1(file
->buf_ptr
);
2794 while (tok
!= ')') {
2798 if (varg
== TOK_DOTS
) {
2799 varg
= TOK___VA_ARGS__
;
2801 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2805 if (varg
< TOK_IDENT
)
2806 error("badly punctuated parameter list");
2807 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2818 /* EOF testing necessary for '-D' handling */
2819 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2820 tok_str_add2(&str
, tok
, &tokc
);
2823 tok_str_add(&str
, 0);
2825 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2828 define_push(v
, t
, str
.str
, first
);
2831 static inline int hash_cached_include(int type
, const char *filename
)
2833 const unsigned char *s
;
2837 h
= TOK_HASH_FUNC(h
, type
);
2840 h
= TOK_HASH_FUNC(h
, *s
);
2843 h
&= (CACHED_INCLUDES_HASH_SIZE
- 1);
2847 /* XXX: use a token or a hash table to accelerate matching ? */
2848 static CachedInclude
*search_cached_include(TCCState
*s1
,
2849 int type
, const char *filename
)
2853 h
= hash_cached_include(type
, filename
);
2854 i
= s1
->cached_includes_hash
[h
];
2858 e
= s1
->cached_includes
[i
- 1];
2859 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2866 static inline void add_cached_include(TCCState
*s1
, int type
,
2867 const char *filename
, int ifndef_macro
)
2872 if (search_cached_include(s1
, type
, filename
))
2875 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2877 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2881 strcpy(e
->filename
, filename
);
2882 e
->ifndef_macro
= ifndef_macro
;
2883 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2884 /* add in hash table */
2885 h
= hash_cached_include(type
, filename
);
2886 e
->hash_next
= s1
->cached_includes_hash
[h
];
2887 s1
->cached_includes_hash
[h
] = s1
->nb_cached_includes
;
2890 static void pragma_parse(TCCState
*s1
)
2895 if (tok
== TOK_pack
) {
2898 #pragma pack(1) // set
2899 #pragma pack() // reset to default
2900 #pragma pack(push,1) // push & set
2901 #pragma pack(pop) // restore previous
2905 if (tok
== TOK_ASM_pop
) {
2907 if (s1
->pack_stack_ptr
<= s1
->pack_stack
) {
2909 error("out of pack stack");
2911 s1
->pack_stack_ptr
--;
2915 if (tok
== TOK_ASM_push
) {
2917 if (s1
->pack_stack_ptr
>= s1
->pack_stack
+ PACK_STACK_SIZE
- 1)
2919 s1
->pack_stack_ptr
++;
2922 if (tok
!= TOK_CINT
) {
2924 error("invalid pack pragma");
2927 if (val
< 1 || val
> 16 || (val
& (val
- 1)) != 0)
2931 *s1
->pack_stack_ptr
= val
;
2937 /* is_bof is true if first non space token at beginning of file */
2938 static void preprocess(int is_bof
)
2940 TCCState
*s1
= tcc_state
;
2941 int size
, i
, c
, n
, saved_parse_flags
;
2948 saved_parse_flags
= parse_flags
;
2949 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
|
2950 PARSE_FLAG_LINEFEED
;
2960 s
= define_find(tok
);
2961 /* undefine symbol by putting an invalid name */
2966 case TOK_INCLUDE_NEXT
:
2967 ch
= file
->buf_ptr
[0];
2968 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2973 } else if (ch
== '\"') {
2978 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2979 if ((q
- buf
) < sizeof(buf
) - 1)
2982 if (handle_stray_noerror() == 0)
2990 /* eat all spaces and comments after include */
2991 /* XXX: slightly incorrect */
2992 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2996 /* computed #include : either we have only strings or
2997 we have anything enclosed in '<>' */
3000 if (tok
== TOK_STR
) {
3001 while (tok
!= TOK_LINEFEED
) {
3002 if (tok
!= TOK_STR
) {
3004 error("'#include' expects \"FILENAME\" or <FILENAME>");
3006 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
3012 while (tok
!= TOK_LINEFEED
) {
3013 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
3017 /* check syntax and remove '<>' */
3018 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
3019 goto include_syntax
;
3020 memmove(buf
, buf
+ 1, len
- 2);
3021 buf
[len
- 2] = '\0';
3026 e
= search_cached_include(s1
, c
, buf
);
3027 if (e
&& define_find(e
->ifndef_macro
)) {
3028 /* no need to parse the include because the 'ifndef macro'
3031 printf("%s: skipping %s\n", file
->filename
, buf
);
3035 /* first search in current dir if "header.h" */
3036 size
= tcc_basename(file
->filename
) - file
->filename
;
3037 if (size
> sizeof(buf1
) - 1)
3038 size
= sizeof(buf1
) - 1;
3039 memcpy(buf1
, file
->filename
, size
);
3041 pstrcat(buf1
, sizeof(buf1
), buf
);
3042 f
= tcc_open(s1
, buf1
);
3044 if (tok
== TOK_INCLUDE_NEXT
)
3050 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
3051 error("#include recursion too deep");
3052 /* now search in all the include paths */
3053 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
3054 for(i
= 0; i
< n
; i
++) {
3056 if (i
< s1
->nb_include_paths
)
3057 path
= s1
->include_paths
[i
];
3059 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
3060 pstrcpy(buf1
, sizeof(buf1
), path
);
3061 pstrcat(buf1
, sizeof(buf1
), "/");
3062 pstrcat(buf1
, sizeof(buf1
), buf
);
3063 f
= tcc_open(s1
, buf1
);
3065 if (tok
== TOK_INCLUDE_NEXT
)
3071 error("include file '%s' not found", buf
);
3075 printf("%s: including %s\n", file
->filename
, buf1
);
3078 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
3079 /* push current file in stack */
3080 /* XXX: fix current line init */
3081 *s1
->include_stack_ptr
++ = file
;
3083 /* add include file debug info */
3085 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
3087 tok_flags
|= TOK_FLAG_BOF
| TOK_FLAG_BOL
;
3088 ch
= file
->buf_ptr
[0];
3096 c
= expr_preprocess();
3102 if (tok
< TOK_IDENT
)
3103 error("invalid argument for '#if%sdef'", c
? "n" : "");
3107 printf("#ifndef %s\n", get_tok_str(tok
, NULL
));
3109 file
->ifndef_macro
= tok
;
3112 c
= (define_find(tok
) != 0) ^ c
;
3114 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
3115 error("memory full");
3116 *s1
->ifdef_stack_ptr
++ = c
;
3119 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
3120 error("#else without matching #if");
3121 if (s1
->ifdef_stack_ptr
[-1] & 2)
3122 error("#else after #else");
3123 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
3126 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
3127 error("#elif without matching #if");
3128 c
= s1
->ifdef_stack_ptr
[-1];
3130 error("#elif after #else");
3131 /* last #if/#elif expression was true: we skip */
3134 c
= expr_preprocess();
3135 s1
->ifdef_stack_ptr
[-1] = c
;
3145 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
3146 error("#endif without matching #if");
3147 s1
->ifdef_stack_ptr
--;
3148 /* '#ifndef macro' was at the start of file. Now we check if
3149 an '#endif' is exactly at the end of file */
3150 if (file
->ifndef_macro
&&
3151 s1
->ifdef_stack_ptr
== file
->ifdef_stack_ptr
) {
3152 file
->ifndef_macro_saved
= file
->ifndef_macro
;
3153 /* need to set to zero to avoid false matches if another
3154 #ifndef at middle of file */
3155 file
->ifndef_macro
= 0;
3156 while (tok
!= TOK_LINEFEED
)
3158 tok_flags
|= TOK_FLAG_ENDIF
;
3164 if (tok
!= TOK_CINT
)
3166 file
->line_num
= tokc
.i
- 1; /* the line number will be incremented after */
3168 if (tok
!= TOK_LINEFEED
) {
3171 pstrcpy(file
->filename
, sizeof(file
->filename
),
3172 (char *)tokc
.cstr
->data
);
3178 ch
= file
->buf_ptr
[0];
3181 while (ch
!= '\n' && ch
!= CH_EOF
) {
3182 if ((q
- buf
) < sizeof(buf
) - 1)
3185 if (handle_stray_noerror() == 0)
3192 error("#error %s", buf
);
3194 warning("#warning %s", buf
);
3200 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
3201 /* '!' is ignored to allow C scripts. numbers are ignored
3202 to emulate cpp behaviour */
3204 if (!(saved_parse_flags
& PARSE_FLAG_ASM_COMMENTS
))
3205 warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok
, &tokc
));
3209 /* ignore other preprocess commands or #! for C scripts */
3210 while (tok
!= TOK_LINEFEED
)
3213 parse_flags
= saved_parse_flags
;
3216 /* evaluate escape codes in a string. */
3217 static void parse_escape_string(CString
*outstr
, const uint8_t *buf
, int is_long
)
3232 case '0': case '1': case '2': case '3':
3233 case '4': case '5': case '6': case '7':
3234 /* at most three octal digits */
3239 n
= n
* 8 + c
- '0';
3243 n
= n
* 8 + c
- '0';
3248 goto add_char_nonext
;
3256 if (c
>= 'a' && c
<= 'f')
3258 else if (c
>= 'A' && c
<= 'F')
3268 goto add_char_nonext
;
3292 goto invalid_escape
;
3302 if (c
>= '!' && c
<= '~')
3303 warning("unknown escape sequence: \'\\%c\'", c
);
3305 warning("unknown escape sequence: \'\\x%x\'", c
);
3312 cstr_ccat(outstr
, c
);
3314 cstr_wccat(outstr
, c
);
3316 /* add a trailing '\0' */
3318 cstr_ccat(outstr
, '\0');
3320 cstr_wccat(outstr
, '\0');
3323 /* we use 64 bit numbers */
3326 /* bn = (bn << shift) | or_val */
3327 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
3331 for(i
=0;i
<BN_SIZE
;i
++) {
3333 bn
[i
] = (v
<< shift
) | or_val
;
3334 or_val
= v
>> (32 - shift
);
3338 void bn_zero(unsigned int *bn
)
3341 for(i
=0;i
<BN_SIZE
;i
++) {
3346 /* parse number in null terminated string 'p' and return it in the
3348 void parse_number(const char *p
)
3350 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
3352 unsigned int bn
[BN_SIZE
];
3363 goto float_frac_parse
;
3364 } else if (t
== '0') {
3365 if (ch
== 'x' || ch
== 'X') {
3369 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
3375 /* parse all digits. cannot check octal numbers at this stage
3376 because of floating point constants */
3378 if (ch
>= 'a' && ch
<= 'f')
3380 else if (ch
>= 'A' && ch
<= 'F')
3388 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
3390 error("number too long");
3396 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
3397 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
3399 /* NOTE: strtox should support that for hexa numbers, but
3400 non ISOC99 libcs do not support it, so we prefer to do
3402 /* hexadecimal or binary floats */
3403 /* XXX: handle overflows */
3415 } else if (t
>= 'a') {
3417 } else if (t
>= 'A') {
3422 bn_lshift(bn
, shift
, t
);
3429 if (t
>= 'a' && t
<= 'f') {
3431 } else if (t
>= 'A' && t
<= 'F') {
3433 } else if (t
>= '0' && t
<= '9') {
3439 error("invalid digit");
3440 bn_lshift(bn
, shift
, t
);
3445 if (ch
!= 'p' && ch
!= 'P')
3452 } else if (ch
== '-') {
3456 if (ch
< '0' || ch
> '9')
3457 expect("exponent digits");
3458 while (ch
>= '0' && ch
<= '9') {
3459 exp_val
= exp_val
* 10 + ch
- '0';
3462 exp_val
= exp_val
* s
;
3464 /* now we can generate the number */
3465 /* XXX: should patch directly float number */
3466 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
3467 d
= ldexp(d
, exp_val
- frac_bits
);
3472 /* float : should handle overflow */
3474 } else if (t
== 'L') {
3477 /* XXX: not large enough */
3478 tokc
.ld
= (long double)d
;
3484 /* decimal floats */
3486 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3491 while (ch
>= '0' && ch
<= '9') {
3492 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3498 if (ch
== 'e' || ch
== 'E') {
3499 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3503 if (ch
== '-' || ch
== '+') {
3504 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3509 if (ch
< '0' || ch
> '9')
3510 expect("exponent digits");
3511 while (ch
>= '0' && ch
<= '9') {
3512 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3524 tokc
.f
= strtof(token_buf
, NULL
);
3525 } else if (t
== 'L') {
3528 tokc
.ld
= strtold(token_buf
, NULL
);
3531 tokc
.d
= strtod(token_buf
, NULL
);
3535 unsigned long long n
, n1
;
3538 /* integer number */
3541 if (b
== 10 && *q
== '0') {
3548 /* no need for checks except for base 10 / 8 errors */
3551 } else if (t
>= 'a') {
3553 } else if (t
>= 'A') {
3558 error("invalid digit");
3562 /* detect overflow */
3563 /* XXX: this test is not reliable */
3565 error("integer constant overflow");
3568 /* XXX: not exactly ANSI compliant */
3569 if ((n
& 0xffffffff00000000LL
) != 0) {
3574 } else if (n
> 0x7fffffff) {
3585 error("three 'l's in integer constant");
3588 if (tok
== TOK_CINT
)
3590 else if (tok
== TOK_CUINT
)
3594 } else if (t
== 'U') {
3596 error("two 'u's in integer constant");
3598 if (tok
== TOK_CINT
)
3600 else if (tok
== TOK_CLLONG
)
3607 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
3615 #define PARSE2(c1, tok1, c2, tok2) \
3626 /* return next token without macro substitution */
3627 static inline void next_nomacro1(void)
3647 /* first look if it is in fact an end of buffer */
3648 if (p
>= file
->buf_end
) {
3652 if (p
>= file
->buf_end
)
3665 TCCState
*s1
= tcc_state
;
3666 if ((parse_flags
& PARSE_FLAG_LINEFEED
)
3667 && !(tok_flags
& TOK_FLAG_EOF
)) {
3668 tok_flags
|= TOK_FLAG_EOF
;
3670 goto keep_tok_flags
;
3671 } else if (s1
->include_stack_ptr
== s1
->include_stack
||
3672 !(parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3673 /* no include left : end of file. */
3676 tok_flags
&= ~TOK_FLAG_EOF
;
3677 /* pop include file */
3679 /* test if previous '#endif' was after a #ifdef at
3681 if (tok_flags
& TOK_FLAG_ENDIF
) {
3683 printf("#endif %s\n", get_tok_str(file
->ifndef_macro_saved
, NULL
));
3685 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
3686 file
->ifndef_macro_saved
);
3689 /* add end of include file debug info */
3691 put_stabd(N_EINCL
, 0, 0);
3693 /* pop include stack */
3695 s1
->include_stack_ptr
--;
3696 file
= *s1
->include_stack_ptr
;
3705 tok_flags
|= TOK_FLAG_BOL
;
3707 if (0 == (parse_flags
& PARSE_FLAG_LINEFEED
))
3710 goto keep_tok_flags
;
3715 if ((tok_flags
& TOK_FLAG_BOL
) &&
3716 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3718 preprocess(tok_flags
& TOK_FLAG_BOF
);
3724 tok
= TOK_TWOSHARPS
;
3726 if (parse_flags
& PARSE_FLAG_ASM_COMMENTS
) {
3727 p
= parse_line_comment(p
- 1);
3736 case 'a': case 'b': case 'c': case 'd':
3737 case 'e': case 'f': case 'g': case 'h':
3738 case 'i': case 'j': case 'k': case 'l':
3739 case 'm': case 'n': case 'o': case 'p':
3740 case 'q': case 'r': case 's': case 't':
3741 case 'u': case 'v': case 'w': case 'x':
3743 case 'A': case 'B': case 'C': case 'D':
3744 case 'E': case 'F': case 'G': case 'H':
3745 case 'I': case 'J': case 'K':
3746 case 'M': case 'N': case 'O': case 'P':
3747 case 'Q': case 'R': case 'S': case 'T':
3748 case 'U': case 'V': case 'W': case 'X':
3754 h
= TOK_HASH_FUNC(h
, c
);
3758 if (!isidnum_table
[c
])
3760 h
= TOK_HASH_FUNC(h
, c
);
3767 /* fast case : no stray found, so we have the full token
3768 and we have already hashed it */
3770 h
&= (TOK_HASH_SIZE
- 1);
3771 pts
= &hash_ident
[h
];
3776 if (ts
->len
== len
&& !memcmp(ts
->str
, p1
, len
))
3778 pts
= &(ts
->hash_next
);
3780 ts
= tok_alloc_new(pts
, p1
, len
);
3784 cstr_reset(&tokcstr
);
3787 cstr_ccat(&tokcstr
, *p1
);
3793 while (isidnum_table
[c
]) {
3794 cstr_ccat(&tokcstr
, c
);
3797 ts
= tok_alloc(tokcstr
.data
, tokcstr
.size
);
3803 if (t
!= '\\' && t
!= '\'' && t
!= '\"') {
3805 goto parse_ident_fast
;
3808 if (c
== '\'' || c
== '\"') {
3812 cstr_reset(&tokcstr
);
3813 cstr_ccat(&tokcstr
, 'L');
3814 goto parse_ident_slow
;
3818 case '0': case '1': case '2': case '3':
3819 case '4': case '5': case '6': case '7':
3822 cstr_reset(&tokcstr
);
3823 /* after the first digit, accept digits, alpha, '.' or sign if
3824 prefixed by 'eEpP' */
3828 cstr_ccat(&tokcstr
, c
);
3830 if (!(isnum(c
) || isid(c
) || c
== '.' ||
3831 ((c
== '+' || c
== '-') &&
3832 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
3835 /* We add a trailing '\0' to ease parsing */
3836 cstr_ccat(&tokcstr
, '\0');
3837 tokc
.cstr
= &tokcstr
;
3841 /* special dot handling because it can also start a number */
3844 cstr_reset(&tokcstr
);
3845 cstr_ccat(&tokcstr
, '.');
3847 } else if (c
== '.') {
3867 /* parse the string */
3869 p
= parse_pp_string(p
, sep
, &str
);
3870 cstr_ccat(&str
, '\0');
3872 /* eval the escape (should be done as TOK_PPNUM) */
3873 cstr_reset(&tokcstr
);
3874 parse_escape_string(&tokcstr
, str
.data
, is_long
);
3879 /* XXX: make it portable */
3883 char_size
= sizeof(nwchar_t
);
3884 if (tokcstr
.size
<= char_size
)
3885 error("empty character constant");
3886 if (tokcstr
.size
> 2 * char_size
)
3887 warning("multi-character character constant");
3889 tokc
.i
= *(int8_t *)tokcstr
.data
;
3892 tokc
.i
= *(nwchar_t
*)tokcstr
.data
;
3896 tokc
.cstr
= &tokcstr
;
3910 } else if (c
== '<') {
3928 } else if (c
== '>') {
3946 } else if (c
== '=') {
3959 } else if (c
== '=') {
3972 } else if (c
== '=') {
3985 } else if (c
== '=') {
3988 } else if (c
== '>') {
3996 PARSE2('!', '!', '=', TOK_NE
)
3997 PARSE2('=', '=', '=', TOK_EQ
)
3998 PARSE2('*', '*', '=', TOK_A_MUL
)
3999 PARSE2('%', '%', '=', TOK_A_MOD
)
4000 PARSE2('^', '^', '=', TOK_A_XOR
)
4002 /* comments or operator */
4006 p
= parse_comment(p
);
4008 } else if (c
== '/') {
4009 p
= parse_line_comment(p
);
4011 } else if (c
== '=') {
4031 case '$': /* only used in assembler */
4032 case '@': /* dito */
4037 error("unrecognized character \\x%02x", c
);
4043 #if defined(PARSE_DEBUG)
4044 printf("token = %s\n", get_tok_str(tok
, &tokc
));
4048 /* return next token without macro substitution. Can read input from
4050 static void next_nomacro(void)
4056 TOK_GET(tok
, macro_ptr
, tokc
);
4057 if (tok
== TOK_LINENUM
) {
4058 file
->line_num
= tokc
.i
;
4067 /* substitute args in macro_str and return allocated string */
4068 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
4070 int *st
, last_tok
, t
, notfirst
;
4079 TOK_GET(t
, macro_str
, cval
);
4084 TOK_GET(t
, macro_str
, cval
);
4087 s
= sym_find2(args
, t
);
4094 cstr_ccat(&cstr
, ' ');
4095 TOK_GET(t
, st
, cval
);
4096 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
4101 cstr_ccat(&cstr
, '\0');
4103 printf("stringize: %s\n", (char *)cstr
.data
);
4107 tok_str_add2(&str
, TOK_STR
, &cval
);
4110 tok_str_add2(&str
, t
, &cval
);
4112 } else if (t
>= TOK_IDENT
) {
4113 s
= sym_find2(args
, t
);
4116 /* if '##' is present before or after, no arg substitution */
4117 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
4118 /* special case for var arg macros : ## eats the
4119 ',' if empty VA_ARGS variable. */
4120 /* XXX: test of the ',' is not 100%
4121 reliable. should fix it to avoid security
4123 if (gnu_ext
&& s
->type
.t
&&
4124 last_tok
== TOK_TWOSHARPS
&&
4125 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
4127 /* suppress ',' '##' */
4130 /* suppress '##' and add variable */
4138 TOK_GET(t1
, st
, cval
);
4141 tok_str_add2(&str
, t1
, &cval
);
4145 /* NOTE: the stream cannot be read when macro
4146 substituing an argument */
4147 macro_subst(&str
, nested_list
, st
, NULL
);
4150 tok_str_add(&str
, t
);
4153 tok_str_add2(&str
, t
, &cval
);
4157 tok_str_add(&str
, 0);
4161 static char const ab_month_name
[12][4] =
4163 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
4164 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
4167 /* do macro substitution of current token with macro 's' and add
4168 result to (tok_str,tok_len). 'nested_list' is the list of all
4169 macros we got inside to avoid recursing. Return non zero if no
4170 substitution needs to be done */
4171 static int macro_subst_tok(TokenString
*tok_str
,
4172 Sym
**nested_list
, Sym
*s
, struct macro_level
**can_read_stream
)
4174 Sym
*args
, *sa
, *sa1
;
4175 int mstr_allocated
, parlevel
, *mstr
, t
, t1
;
4182 /* if symbol is a macro, prepare substitution */
4183 /* special macros */
4184 if (tok
== TOK___LINE__
) {
4185 snprintf(buf
, sizeof(buf
), "%d", file
->line_num
);
4189 } else if (tok
== TOK___FILE__
) {
4190 cstrval
= file
->filename
;
4192 } else if (tok
== TOK___DATE__
|| tok
== TOK___TIME__
) {
4197 tm
= localtime(&ti
);
4198 if (tok
== TOK___DATE__
) {
4199 snprintf(buf
, sizeof(buf
), "%s %2d %d",
4200 ab_month_name
[tm
->tm_mon
], tm
->tm_mday
, tm
->tm_year
+ 1900);
4202 snprintf(buf
, sizeof(buf
), "%02d:%02d:%02d",
4203 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
4210 cstr_cat(&cstr
, cstrval
);
4211 cstr_ccat(&cstr
, '\0');
4213 tok_str_add2(tok_str
, t1
, &cval
);
4218 if (s
->type
.t
== MACRO_FUNC
) {
4219 /* NOTE: we do not use next_nomacro to avoid eating the
4220 next token. XXX: find better solution */
4224 if (t
== 0 && can_read_stream
) {
4225 /* end of macro stream: we must look at the token
4226 after in the file */
4227 struct macro_level
*ml
= *can_read_stream
;
4233 *can_read_stream
= ml
-> prev
;
4238 /* XXX: incorrect with comments */
4239 ch
= file
->buf_ptr
[0];
4240 while (is_space(ch
) || ch
== '\n')
4244 if (t
!= '(') /* no macro subst */
4247 /* argument macro */
4252 /* NOTE: empty args are allowed, except if no args */
4254 /* handle '()' case */
4255 if (!args
&& !sa
&& tok
== ')')
4258 error("macro '%s' used with too many args",
4259 get_tok_str(s
->v
, 0));
4262 /* NOTE: non zero sa->t indicates VA_ARGS */
4263 while ((parlevel
> 0 ||
4265 (tok
!= ',' || sa
->type
.t
))) &&
4269 else if (tok
== ')')
4271 if (tok
!= TOK_LINEFEED
)
4272 tok_str_add2(&str
, tok
, &tokc
);
4275 tok_str_add(&str
, 0);
4276 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
4279 /* special case for gcc var args: add an empty
4280 var arg argument if it is omitted */
4281 if (sa
&& sa
->type
.t
&& gnu_ext
)
4291 error("macro '%s' used with too few args",
4292 get_tok_str(s
->v
, 0));
4295 /* now subst each arg */
4296 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
4301 tok_str_free((int *)sa
->c
);
4307 sym_push2(nested_list
, s
->v
, 0, 0);
4308 macro_subst(tok_str
, nested_list
, mstr
, can_read_stream
);
4309 /* pop nested defined symbol */
4311 *nested_list
= sa1
->prev
;
4319 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
4320 return the resulting string (which must be freed). */
4321 static inline int *macro_twosharps(const int *macro_str
)
4324 const int *macro_ptr1
, *start_macro_ptr
, *ptr
, *saved_macro_ptr
;
4326 const char *p1
, *p2
;
4328 TokenString macro_str1
;
4331 start_macro_ptr
= macro_str
;
4332 /* we search the first '##' */
4334 macro_ptr1
= macro_str
;
4335 TOK_GET(t
, macro_str
, cval
);
4336 /* nothing more to do if end of string */
4339 if (*macro_str
== TOK_TWOSHARPS
)
4343 /* we saw '##', so we need more processing to handle it */
4345 tok_str_new(¯o_str1
);
4349 /* add all tokens seen so far */
4350 for(ptr
= start_macro_ptr
; ptr
< macro_ptr1
;) {
4351 TOK_GET(t
, ptr
, cval
);
4352 tok_str_add2(¯o_str1
, t
, &cval
);
4354 saved_macro_ptr
= macro_ptr
;
4355 /* XXX: get rid of the use of macro_ptr here */
4356 macro_ptr
= (int *)macro_str
;
4358 while (*macro_ptr
== TOK_TWOSHARPS
) {
4360 macro_ptr1
= macro_ptr
;
4363 TOK_GET(t
, macro_ptr
, cval
);
4364 /* We concatenate the two tokens if we have an
4365 identifier or a preprocessing number */
4367 p1
= get_tok_str(tok
, &tokc
);
4368 cstr_cat(&cstr
, p1
);
4369 p2
= get_tok_str(t
, &cval
);
4370 cstr_cat(&cstr
, p2
);
4371 cstr_ccat(&cstr
, '\0');
4373 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
4374 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
4375 if (tok
== TOK_PPNUM
) {
4376 /* if number, then create a number token */
4377 /* NOTE: no need to allocate because
4378 tok_str_add2() does it */
4379 cstr_reset(&tokcstr
);
4382 tokc
.cstr
= &tokcstr
;
4384 /* if identifier, we must do a test to
4385 validate we have a correct identifier */
4386 if (t
== TOK_PPNUM
) {
4396 if (!isnum(c
) && !isid(c
))
4400 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
4401 tok
= ts
->tok
; /* modify current token */
4404 const char *str
= cstr
.data
;
4405 const unsigned char *q
;
4407 /* we look for a valid token */
4408 /* XXX: do more extensive checks */
4409 if (!strcmp(str
, ">>=")) {
4411 } else if (!strcmp(str
, "<<=")) {
4413 } else if (strlen(str
) == 2) {
4414 /* search in two bytes table */
4419 if (q
[0] == str
[0] && q
[1] == str
[1])
4426 /* NOTE: because get_tok_str use a static buffer,
4429 p1
= get_tok_str(tok
, &tokc
);
4430 cstr_cat(&cstr
, p1
);
4431 cstr_ccat(&cstr
, '\0');
4432 p2
= get_tok_str(t
, &cval
);
4433 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
4434 /* cannot merge tokens: just add them separately */
4435 tok_str_add2(¯o_str1
, tok
, &tokc
);
4436 /* XXX: free associated memory ? */
4443 tok_str_add2(¯o_str1
, tok
, &tokc
);
4448 macro_ptr
= (int *)saved_macro_ptr
;
4450 tok_str_add(¯o_str1
, 0);
4451 return macro_str1
.str
;
4455 /* do macro substitution of macro_str and add result to
4456 (tok_str,tok_len). 'nested_list' is the list of all macros we got
4457 inside to avoid recursing. */
4458 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
4459 const int *macro_str
, struct macro_level
** can_read_stream
)
4466 struct macro_level ml
;
4468 /* first scan for '##' operator handling */
4470 macro_str1
= macro_twosharps(ptr
);
4474 /* NOTE: ptr == NULL can only happen if tokens are read from
4475 file stream due to a macro function call */
4478 TOK_GET(t
, ptr
, cval
);
4483 /* if nested substitution, do nothing */
4484 if (sym_find2(*nested_list
, t
))
4487 if (can_read_stream
)
4488 ml
.prev
= *can_read_stream
, *can_read_stream
= &ml
;
4489 macro_ptr
= (int *)ptr
;
4491 ret
= macro_subst_tok(tok_str
, nested_list
, s
, can_read_stream
);
4492 ptr
= (int *)macro_ptr
;
4494 if (can_read_stream
&& *can_read_stream
== &ml
)
4495 *can_read_stream
= ml
.prev
;
4500 tok_str_add2(tok_str
, t
, &cval
);
4504 tok_str_free(macro_str1
);
4507 /* return next token with macro substitution */
4508 static void next(void)
4510 Sym
*nested_list
, *s
;
4512 struct macro_level
*ml
;
4517 /* if not reading from macro substituted string, then try
4518 to substitute macros */
4519 if (tok
>= TOK_IDENT
&&
4520 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
4521 s
= define_find(tok
);
4523 /* we have a macro: we try to substitute */
4527 if (macro_subst_tok(&str
, &nested_list
, s
, &ml
) == 0) {
4528 /* substitution done, NOTE: maybe empty */
4529 tok_str_add(&str
, 0);
4530 macro_ptr
= str
.str
;
4531 macro_ptr_allocated
= str
.str
;
4538 /* end of macro or end of unget buffer */
4539 if (unget_buffer_enabled
) {
4540 macro_ptr
= unget_saved_macro_ptr
;
4541 unget_buffer_enabled
= 0;
4543 /* end of macro string: free it */
4544 tok_str_free(macro_ptr_allocated
);
4551 /* convert preprocessor tokens into C tokens */
4552 if (tok
== TOK_PPNUM
&&
4553 (parse_flags
& PARSE_FLAG_TOK_NUM
)) {
4554 parse_number((char *)tokc
.cstr
->data
);
4558 /* push back current token and set current token to 'last_tok'. Only
4559 identifier case handled for labels. */
4560 static inline void unget_tok(int last_tok
)
4564 unget_saved_macro_ptr
= macro_ptr
;
4565 unget_buffer_enabled
= 1;
4566 q
= unget_saved_buffer
;
4569 n
= tok_ext_size(tok
) - 1;
4572 *q
= 0; /* end of token string */
4577 void swap(int *p
, int *q
)
4585 void vsetc(CType
*type
, int r
, CValue
*vc
)
4589 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
4590 error("memory full");
4591 /* cannot let cpu flags if other instruction are generated. Also
4592 avoid leaving VT_JMP anywhere except on the top of the stack
4593 because it would complicate the code generator. */
4594 if (vtop
>= vstack
) {
4595 v
= vtop
->r
& VT_VALMASK
;
4596 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
4602 vtop
->r2
= VT_CONST
;
4606 /* push integer constant */
4611 vsetc(&int_type
, VT_CONST
, &cval
);
4614 /* Return a static symbol pointing to a section */
4615 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
4616 unsigned long offset
, unsigned long size
)
4622 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
4623 sym
->type
.ref
= type
->ref
;
4624 sym
->r
= VT_CONST
| VT_SYM
;
4625 put_extern_sym(sym
, sec
, offset
, size
);
4629 /* push a reference to a section offset by adding a dummy symbol */
4630 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
4635 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4636 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
4639 /* define a new external reference to a symbol 'v' of type 'u' */
4640 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
4646 /* push forward reference */
4647 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
4648 s
->type
.ref
= type
->ref
;
4649 s
->r
= r
| VT_CONST
| VT_SYM
;
4654 /* define a new external reference to a symbol 'v' of type 'u' */
4655 static Sym
*external_sym(int v
, CType
*type
, int r
)
4661 /* push forward reference */
4662 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
4663 s
->type
.t
|= VT_EXTERN
;
4665 if (!is_compatible_types(&s
->type
, type
))
4666 error("incompatible types for redefinition of '%s'",
4667 get_tok_str(v
, NULL
));
4672 /* push a reference to global symbol v */
4673 static void vpush_global_sym(CType
*type
, int v
)
4678 sym
= external_global_sym(v
, type
, 0);
4680 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4684 void vset(CType
*type
, int r
, int v
)
4689 vsetc(type
, r
, &cval
);
4692 void vseti(int r
, int v
)
4708 void vpushv(SValue
*v
)
4710 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
4711 error("memory full");
4721 /* save r to the memory stack, and mark it as being free */
4722 void save_reg(int r
)
4724 int l
, saved
, size
, align
;
4728 /* modify all stack values */
4731 for(p
=vstack
;p
<=vtop
;p
++) {
4732 if ((p
->r
& VT_VALMASK
) == r
||
4733 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& (p
->r2
& VT_VALMASK
) == r
)) {
4734 /* must save value on stack if not already done */
4736 /* NOTE: must reload 'r' because r might be equal to r2 */
4737 r
= p
->r
& VT_VALMASK
;
4738 /* store register in the stack */
4740 if ((p
->r
& VT_LVAL
) ||
4741 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
4743 size
= type_size(type
, &align
);
4744 loc
= (loc
- size
) & -align
;
4745 sv
.type
.t
= type
->t
;
4746 sv
.r
= VT_LOCAL
| VT_LVAL
;
4749 #ifdef TCC_TARGET_I386
4750 /* x86 specific: need to pop fp register ST0 if saved */
4751 if (r
== TREG_ST0
) {
4752 o(0xd9dd); /* fstp %st(1) */
4755 /* special long long case */
4756 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
4763 /* mark that stack entry as being saved on the stack */
4764 if (p
->r
& VT_LVAL
) {
4765 /* also clear the bounded flag because the
4766 relocation address of the function was stored in
4768 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
4770 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
4778 /* find a register of class 'rc2' with at most one reference on stack.
4779 * If none, call get_reg(rc) */
4780 int get_reg_ex(int rc
, int rc2
)
4785 for(r
=0;r
<NB_REGS
;r
++) {
4786 if (reg_classes
[r
] & rc2
) {
4789 for(p
= vstack
; p
<= vtop
; p
++) {
4790 if ((p
->r
& VT_VALMASK
) == r
||
4791 (p
->r2
& VT_VALMASK
) == r
)
4801 /* find a free register of class 'rc'. If none, save one register */
4807 /* find a free register */
4808 for(r
=0;r
<NB_REGS
;r
++) {
4809 if (reg_classes
[r
] & rc
) {
4810 for(p
=vstack
;p
<=vtop
;p
++) {
4811 if ((p
->r
& VT_VALMASK
) == r
||
4812 (p
->r2
& VT_VALMASK
) == r
)
4820 /* no register left : free the first one on the stack (VERY
4821 IMPORTANT to start from the bottom to ensure that we don't
4822 spill registers used in gen_opi()) */
4823 for(p
=vstack
;p
<=vtop
;p
++) {
4824 r
= p
->r
& VT_VALMASK
;
4825 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
4827 /* also look at second register (if long long) */
4828 r
= p
->r2
& VT_VALMASK
;
4829 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
4835 /* Should never comes here */
4839 /* save registers up to (vtop - n) stack entry */
4840 void save_regs(int n
)
4845 for(p
= vstack
;p
<= p1
; p
++) {
4846 r
= p
->r
& VT_VALMASK
;
4853 /* move register 's' to 'r', and flush previous value of r to memory
4855 void move_reg(int r
, int s
)
4868 /* get address of vtop (vtop MUST BE an lvalue) */
4871 vtop
->r
&= ~VT_LVAL
;
4872 /* tricky: if saved lvalue, then we can go back to lvalue */
4873 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
4874 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
4877 #ifdef CONFIG_TCC_BCHECK
4878 /* generate lvalue bound code */
4884 vtop
->r
&= ~VT_MUSTBOUND
;
4885 /* if lvalue, then use checking code before dereferencing */
4886 if (vtop
->r
& VT_LVAL
) {
4887 /* if not VT_BOUNDED value, then make one */
4888 if (!(vtop
->r
& VT_BOUNDED
)) {
4889 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
4890 /* must save type because we must set it to int to get pointer */
4892 vtop
->type
.t
= VT_INT
;
4895 gen_bounded_ptr_add();
4896 vtop
->r
|= lval_type
;
4899 /* then check for dereferencing */
4900 gen_bounded_ptr_deref();
4905 /* store vtop a register belonging to class 'rc'. lvalues are
4906 converted to values. Cannot be used if cannot be converted to
4907 register value (such as structures). */
4910 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
4911 unsigned long long ll
;
4913 /* NOTE: get_reg can modify vstack[] */
4914 if (vtop
->type
.t
& VT_BITFIELD
) {
4915 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
4916 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4917 /* remove bit field info to avoid loops */
4918 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4919 /* generate shifts */
4920 vpushi(32 - (bit_pos
+ bit_size
));
4922 vpushi(32 - bit_size
);
4923 /* NOTE: transformed to SHR if unsigned */
4927 if (is_float(vtop
->type
.t
) &&
4928 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4931 unsigned long offset
;
4932 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
4936 /* XXX: unify with initializers handling ? */
4937 /* CPUs usually cannot use float constants, so we store them
4938 generically in data segment */
4939 size
= type_size(&vtop
->type
, &align
);
4940 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
4941 data_section
->data_offset
= offset
;
4942 /* XXX: not portable yet */
4944 /* Zero pad x87 tenbyte long doubles */
4946 vtop
->c
.tab
[2] &= 0xffff;
4948 ptr
= section_ptr_add(data_section
, size
);
4950 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
4954 ptr
[i
] = vtop
->c
.tab
[size
-1-i
];
4958 ptr
[i
] = vtop
->c
.tab
[i
];
4959 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
4960 vtop
->r
|= VT_LVAL
| VT_SYM
;
4964 #ifdef CONFIG_TCC_BCHECK
4965 if (vtop
->r
& VT_MUSTBOUND
)
4969 r
= vtop
->r
& VT_VALMASK
;
4970 /* need to reload if:
4972 - lvalue (need to dereference pointer)
4973 - already a register, but not in the right class */
4974 if (r
>= VT_CONST
||
4975 (vtop
->r
& VT_LVAL
) ||
4976 !(reg_classes
[r
] & rc
) ||
4977 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
4978 !(reg_classes
[vtop
->r2
] & rc
))) {
4980 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
4981 /* two register type load : expand to two words
4983 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4986 vtop
->c
.ui
= ll
; /* first word */
4988 vtop
->r
= r
; /* save register value */
4989 vpushi(ll
>> 32); /* second word */
4990 } else if (r
>= VT_CONST
|| /* XXX: test to VT_CONST incorrect ? */
4991 (vtop
->r
& VT_LVAL
)) {
4992 /* We do not want to modifier the long long
4993 pointer here, so the safest (and less
4994 efficient) is to save all the other registers
4995 in the stack. XXX: totally inefficient. */
4997 /* load from memory */
5000 vtop
[-1].r
= r
; /* save register value */
5001 /* increment pointer to get second word */
5002 vtop
->type
.t
= VT_INT
;
5008 /* move registers */
5011 vtop
[-1].r
= r
; /* save register value */
5012 vtop
->r
= vtop
[-1].r2
;
5014 /* allocate second register */
5021 /* write second register */
5023 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
5025 /* lvalue of scalar type : need to use lvalue type
5026 because of possible cast */
5029 /* compute memory access type */
5030 if (vtop
->r
& VT_LVAL_BYTE
)
5032 else if (vtop
->r
& VT_LVAL_SHORT
)
5034 if (vtop
->r
& VT_LVAL_UNSIGNED
)
5038 /* restore wanted type */
5041 /* one register type load */
5046 #ifdef TCC_TARGET_C67
5047 /* uses register pairs for doubles */
5048 if ((vtop
->type
.t
& VT_BTYPE
) == VT_DOUBLE
)
5055 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
5056 void gv2(int rc1
, int rc2
)
5060 /* generate more generic register first. But VT_JMP or VT_CMP
5061 values must be generated first in all cases to avoid possible
5063 v
= vtop
[0].r
& VT_VALMASK
;
5064 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
5069 /* test if reload is needed for first register */
5070 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
5080 /* test if reload is needed for first register */
5081 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
5087 /* expand long long on stack in two int registers */
5092 u
= vtop
->type
.t
& VT_UNSIGNED
;
5095 vtop
[0].r
= vtop
[-1].r2
;
5096 vtop
[0].r2
= VT_CONST
;
5097 vtop
[-1].r2
= VT_CONST
;
5098 vtop
[0].type
.t
= VT_INT
| u
;
5099 vtop
[-1].type
.t
= VT_INT
| u
;
5102 #ifdef TCC_TARGET_ARM
5103 /* expand long long on stack */
5104 void lexpand_nr(void)
5108 u
= vtop
->type
.t
& VT_UNSIGNED
;
5110 vtop
->r2
= VT_CONST
;
5111 vtop
->type
.t
= VT_INT
| u
;
5112 v
=vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
);
5113 if (v
== VT_CONST
) {
5114 vtop
[-1].c
.ui
= vtop
->c
.ull
;
5115 vtop
->c
.ui
= vtop
->c
.ull
>> 32;
5117 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
5119 vtop
->r
= vtop
[-1].r
;
5120 } else if (v
> VT_CONST
) {
5124 vtop
->r
= vtop
[-1].r2
;
5125 vtop
[-1].r2
= VT_CONST
;
5126 vtop
[-1].type
.t
= VT_INT
| u
;
5130 /* build a long long from two ints */
5133 gv2(RC_INT
, RC_INT
);
5134 vtop
[-1].r2
= vtop
[0].r
;
5135 vtop
[-1].type
.t
= t
;
5139 /* rotate n first stack elements to the bottom
5140 I1 ... In -> I2 ... In I1 [top is right]
5148 for(i
=-n
+1;i
!=0;i
++)
5149 vtop
[i
] = vtop
[i
+1];
5153 /* rotate n first stack elements to the top
5154 I1 ... In -> In I1 ... I(n-1) [top is right]
5162 for(i
= 0;i
< n
- 1; i
++)
5163 vtop
[-i
] = vtop
[-i
- 1];
5167 #ifdef TCC_TARGET_ARM
5168 /* like vrott but in other direction
5169 In ... I1 -> I(n-1) ... I1 In [top is right]
5177 for(i
= n
- 1; i
> 0; i
--)
5178 vtop
[-i
] = vtop
[-i
+ 1];
5183 /* pop stack value */
5187 v
= vtop
->r
& VT_VALMASK
;
5188 #ifdef TCC_TARGET_I386
5189 /* for x86, we need to pop the FP stack */
5190 if (v
== TREG_ST0
&& !nocode_wanted
) {
5191 o(0xd9dd); /* fstp %st(1) */
5194 if (v
== VT_JMP
|| v
== VT_JMPI
) {
5195 /* need to put correct jump if && or || without test */
5201 /* convert stack entry to register and duplicate its value in another
5209 if ((t
& VT_BTYPE
) == VT_LLONG
) {
5216 /* stack: H L L1 H1 */
5224 /* duplicate value */
5235 load(r1
, &sv
); /* move r to r1 */
5237 /* duplicates value */
5242 /* generate CPU independent (unsigned) long long operations */
5243 void gen_opl(int op
)
5245 int t
, a
, b
, op1
, c
, i
;
5252 func
= TOK___divdi3
;
5255 func
= TOK___udivdi3
;
5258 func
= TOK___moddi3
;
5261 func
= TOK___umoddi3
;
5263 /* call generic long long function */
5264 vpush_global_sym(&func_old_type
, func
);
5269 vtop
->r2
= REG_LRET
;
5282 /* stack: L1 H1 L2 H2 */
5287 vtop
[-2] = vtop
[-3];
5290 /* stack: H1 H2 L1 L2 */
5296 /* stack: H1 H2 L1 L2 ML MH */
5299 /* stack: ML MH H1 H2 L1 L2 */
5303 /* stack: ML MH H1 L2 H2 L1 */
5308 /* stack: ML MH M1 M2 */
5311 } else if (op
== '+' || op
== '-') {
5312 /* XXX: add non carry method too (for MIPS or alpha) */
5318 /* stack: H1 H2 (L1 op L2) */
5321 gen_op(op1
+ 1); /* TOK_xxxC2 */
5324 /* stack: H1 H2 (L1 op L2) */
5327 /* stack: (L1 op L2) H1 H2 */
5329 /* stack: (L1 op L2) (H1 op H2) */
5337 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
5338 t
= vtop
[-1].type
.t
;
5342 /* stack: L H shift */
5344 /* constant: simpler */
5345 /* NOTE: all comments are for SHL. the other cases are
5346 done by swaping words */
5357 if (op
!= TOK_SAR
) {
5390 /* XXX: should provide a faster fallback on x86 ? */
5393 func
= TOK___sardi3
;
5396 func
= TOK___shrdi3
;
5399 func
= TOK___shldi3
;
5405 /* compare operations */
5411 /* stack: L1 H1 L2 H2 */
5413 vtop
[-1] = vtop
[-2];
5415 /* stack: L1 L2 H1 H2 */
5418 /* when values are equal, we need to compare low words. since
5419 the jump is inverted, we invert the test too. */
5422 else if (op1
== TOK_GT
)
5424 else if (op1
== TOK_ULT
)
5426 else if (op1
== TOK_UGT
)
5431 if (op1
!= TOK_NE
) {
5435 /* generate non equal test */
5436 /* XXX: NOT PORTABLE yet */
5440 #if defined(TCC_TARGET_I386)
5441 b
= psym(0x850f, 0);
5442 #elif defined(TCC_TARGET_ARM)
5444 o(0x1A000000 | encbranch(ind
, 0, 1));
5445 #elif defined(TCC_TARGET_C67)
5446 error("not implemented");
5448 #error not supported
5452 /* compare low. Always unsigned */
5456 else if (op1
== TOK_LE
)
5458 else if (op1
== TOK_GT
)
5460 else if (op1
== TOK_GE
)
5470 /* handle integer constant optimizations and various machine
5472 void gen_opic(int op
)
5474 int c1
, c2
, t1
, t2
, n
;
5477 typedef unsigned long long U
;
5481 t1
= v1
->type
.t
& VT_BTYPE
;
5482 t2
= v2
->type
.t
& VT_BTYPE
;
5483 l1
= (t1
== VT_LLONG
) ? v1
->c
.ll
: v1
->c
.i
;
5484 l2
= (t2
== VT_LLONG
) ? v2
->c
.ll
: v2
->c
.i
;
5486 /* currently, we cannot do computations with forward symbols */
5487 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5488 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5491 case '+': l1
+= l2
; break;
5492 case '-': l1
-= l2
; break;
5493 case '&': l1
&= l2
; break;
5494 case '^': l1
^= l2
; break;
5495 case '|': l1
|= l2
; break;
5496 case '*': l1
*= l2
; break;
5503 /* if division by zero, generate explicit division */
5506 error("division by zero in constant");
5510 default: l1
/= l2
; break;
5511 case '%': l1
%= l2
; break;
5512 case TOK_UDIV
: l1
= (U
)l1
/ l2
; break;
5513 case TOK_UMOD
: l1
= (U
)l1
% l2
; break;
5516 case TOK_SHL
: l1
<<= l2
; break;
5517 case TOK_SHR
: l1
= (U
)l1
>> l2
; break;
5518 case TOK_SAR
: l1
>>= l2
; break;
5520 case TOK_ULT
: l1
= (U
)l1
< (U
)l2
; break;
5521 case TOK_UGE
: l1
= (U
)l1
>= (U
)l2
; break;
5522 case TOK_EQ
: l1
= l1
== l2
; break;
5523 case TOK_NE
: l1
= l1
!= l2
; break;
5524 case TOK_ULE
: l1
= (U
)l1
<= (U
)l2
; break;
5525 case TOK_UGT
: l1
= (U
)l1
> (U
)l2
; break;
5526 case TOK_LT
: l1
= l1
< l2
; break;
5527 case TOK_GE
: l1
= l1
>= l2
; break;
5528 case TOK_LE
: l1
= l1
<= l2
; break;
5529 case TOK_GT
: l1
= l1
> l2
; break;
5531 case TOK_LAND
: l1
= l1
&& l2
; break;
5532 case TOK_LOR
: l1
= l1
|| l2
; break;
5539 /* if commutative ops, put c2 as constant */
5540 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
5541 op
== '|' || op
== '*')) {
5543 c2
= c1
; //c = c1, c1 = c2, c2 = c;
5544 l2
= l1
; //l = l1, l1 = l2, l2 = l;
5546 /* Filter out NOP operations like x*1, x-0, x&-1... */
5547 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
5550 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
5551 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
5557 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
5558 /* try to use shifts instead of muls or divs */
5559 if (l2
> 0 && (l2
& (l2
- 1)) == 0) {
5568 else if (op
== TOK_PDIV
)
5574 } else if (c2
&& (op
== '+' || op
== '-') &&
5575 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
5576 (VT_CONST
| VT_SYM
)) {
5577 /* symbol + constant case */
5584 if (!nocode_wanted
) {
5585 /* call low level op generator */
5586 if (t1
== VT_LLONG
|| t2
== VT_LLONG
)
5597 /* generate a floating point operation with constant propagation */
5598 void gen_opif(int op
)
5606 /* currently, we cannot do computations with forward symbols */
5607 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5608 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5610 if (v1
->type
.t
== VT_FLOAT
) {
5613 } else if (v1
->type
.t
== VT_DOUBLE
) {
5621 /* NOTE: we only do constant propagation if finite number (not
5622 NaN or infinity) (ANSI spec) */
5623 if (!ieee_finite(f1
) || !ieee_finite(f2
))
5627 case '+': f1
+= f2
; break;
5628 case '-': f1
-= f2
; break;
5629 case '*': f1
*= f2
; break;
5633 error("division by zero in constant");
5638 /* XXX: also handles tests ? */
5642 /* XXX: overflow test ? */
5643 if (v1
->type
.t
== VT_FLOAT
) {
5645 } else if (v1
->type
.t
== VT_DOUBLE
) {
5653 if (!nocode_wanted
) {
5661 static int pointed_size(CType
*type
)
5664 return type_size(pointed_type(type
), &align
);
5667 static inline int is_null_pointer(SValue
*p
)
5669 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
5671 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& p
->c
.i
== 0) ||
5672 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.ll
== 0);
5675 static inline int is_integer_btype(int bt
)
5677 return (bt
== VT_BYTE
|| bt
== VT_SHORT
||
5678 bt
== VT_INT
|| bt
== VT_LLONG
);
5681 /* check types for comparison or substraction of pointers */
5682 static void check_comparison_pointer_types(SValue
*p1
, SValue
*p2
, int op
)
5684 CType
*type1
, *type2
, tmp_type1
, tmp_type2
;
5687 /* null pointers are accepted for all comparisons as gcc */
5688 if (is_null_pointer(p1
) || is_null_pointer(p2
))
5692 bt1
= type1
->t
& VT_BTYPE
;
5693 bt2
= type2
->t
& VT_BTYPE
;
5694 /* accept comparison between pointer and integer with a warning */
5695 if ((is_integer_btype(bt1
) || is_integer_btype(bt2
)) && op
!= '-') {
5696 if (op
!= TOK_LOR
&& op
!= TOK_LAND
)
5697 warning("comparison between pointer and integer");
5701 /* both must be pointers or implicit function pointers */
5702 if (bt1
== VT_PTR
) {
5703 type1
= pointed_type(type1
);
5704 } else if (bt1
!= VT_FUNC
)
5705 goto invalid_operands
;
5707 if (bt2
== VT_PTR
) {
5708 type2
= pointed_type(type2
);
5709 } else if (bt2
!= VT_FUNC
) {
5711 error("invalid operands to binary %s", get_tok_str(op
, NULL
));
5713 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
5714 (type2
->t
& VT_BTYPE
) == VT_VOID
)
5718 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5719 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5720 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
5721 /* gcc-like error if '-' is used */
5723 goto invalid_operands
;
5725 warning("comparison of distinct pointer types lacks a cast");
5729 /* generic gen_op: handles types problems */
5732 int u
, t1
, t2
, bt1
, bt2
, t
;
5735 t1
= vtop
[-1].type
.t
;
5736 t2
= vtop
[0].type
.t
;
5737 bt1
= t1
& VT_BTYPE
;
5738 bt2
= t2
& VT_BTYPE
;
5740 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5741 /* at least one operand is a pointer */
5742 /* relationnal op: must be both pointers */
5743 if (op
>= TOK_ULT
&& op
<= TOK_LOR
) {
5744 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5745 /* pointers are handled are unsigned */
5746 t
= VT_INT
| VT_UNSIGNED
;
5749 /* if both pointers, then it must be the '-' op */
5750 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
5752 error("cannot use pointers here");
5753 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5754 /* XXX: check that types are compatible */
5755 u
= pointed_size(&vtop
[-1].type
);
5757 /* set to integer type */
5758 vtop
->type
.t
= VT_INT
;
5762 /* exactly one pointer : must be '+' or '-'. */
5763 if (op
!= '-' && op
!= '+')
5764 error("cannot use pointers here");
5765 /* Put pointer as first operand */
5766 if (bt2
== VT_PTR
) {
5770 type1
= vtop
[-1].type
;
5771 /* XXX: cast to int ? (long long case) */
5772 vpushi(pointed_size(&vtop
[-1].type
));
5774 #ifdef CONFIG_TCC_BCHECK
5775 /* if evaluating constant expression, no code should be
5776 generated, so no bound check */
5777 if (do_bounds_check
&& !const_wanted
) {
5778 /* if bounded pointers, we generate a special code to
5785 gen_bounded_ptr_add();
5791 /* put again type if gen_opic() swaped operands */
5794 } else if (is_float(bt1
) || is_float(bt2
)) {
5795 /* compute bigger type and do implicit casts */
5796 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5798 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5803 /* floats can only be used for a few operations */
5804 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
5805 (op
< TOK_ULT
|| op
> TOK_GT
))
5806 error("invalid operands for binary operation");
5808 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5809 /* cast to biggest op */
5811 /* convert to unsigned if it does not fit in a long long */
5812 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5813 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5817 /* integer operations */
5819 /* convert to unsigned if it does not fit in an integer */
5820 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5821 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5824 /* XXX: currently, some unsigned operations are explicit, so
5825 we modify them here */
5826 if (t
& VT_UNSIGNED
) {
5833 else if (op
== TOK_LT
)
5835 else if (op
== TOK_GT
)
5837 else if (op
== TOK_LE
)
5839 else if (op
== TOK_GE
)
5846 /* special case for shifts and long long: we keep the shift as
5848 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
5855 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5856 /* relationnal op: the result is an int */
5857 vtop
->type
.t
= VT_INT
;
5864 /* generic itof for unsigned long long case */
5865 void gen_cvt_itof1(int t
)
5867 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
5868 (VT_LLONG
| VT_UNSIGNED
)) {
5871 vpush_global_sym(&func_old_type
, TOK___ulltof
);
5872 else if (t
== VT_DOUBLE
)
5873 vpush_global_sym(&func_old_type
, TOK___ulltod
);
5875 vpush_global_sym(&func_old_type
, TOK___ulltold
);
5885 /* generic ftoi for unsigned long long case */
5886 void gen_cvt_ftoi1(int t
)
5890 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
5891 /* not handled natively */
5892 st
= vtop
->type
.t
& VT_BTYPE
;
5894 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
5895 else if (st
== VT_DOUBLE
)
5896 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
5898 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
5903 vtop
->r2
= REG_LRET
;
5909 /* force char or short cast */
5910 void force_charshort_cast(int t
)
5914 /* XXX: add optimization if lvalue : just change type and offset */
5919 if (t
& VT_UNSIGNED
) {
5920 vpushi((1 << bits
) - 1);
5926 /* result must be signed or the SAR is converted to an SHL
5927 This was not the case when "t" was a signed short
5928 and the last value on the stack was an unsigned int */
5929 vtop
->type
.t
&= ~VT_UNSIGNED
;
5935 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
5936 static void gen_cast(CType
*type
)
5938 int sbt
, dbt
, sf
, df
, c
;
5940 /* special delayed cast for char/short */
5941 /* XXX: in some cases (multiple cascaded casts), it may still
5943 if (vtop
->r
& VT_MUSTCAST
) {
5944 vtop
->r
&= ~VT_MUSTCAST
;
5945 force_charshort_cast(vtop
->type
.t
);
5948 /* bitfields first get cast to ints */
5949 if (vtop
->type
.t
& VT_BITFIELD
) {
5953 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
5954 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5956 if (sbt
!= dbt
&& !nocode_wanted
) {
5959 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5961 /* convert from fp to fp */
5963 /* constant case: we can do it now */
5964 /* XXX: in ISOC, cannot do it if error in convert */
5965 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
5966 vtop
->c
.f
= (float)vtop
->c
.d
;
5967 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
5968 vtop
->c
.f
= (float)vtop
->c
.ld
;
5969 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
5970 vtop
->c
.d
= (double)vtop
->c
.f
;
5971 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
5972 vtop
->c
.d
= (double)vtop
->c
.ld
;
5973 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
5974 vtop
->c
.ld
= (long double)vtop
->c
.f
;
5975 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
5976 vtop
->c
.ld
= (long double)vtop
->c
.d
;
5978 /* non constant case: generate code */
5982 /* convert int to fp */
5985 case VT_LLONG
| VT_UNSIGNED
:
5987 /* XXX: add const cases for long long */
5989 case VT_INT
| VT_UNSIGNED
:
5991 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
5992 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
5993 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
5998 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
5999 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
6000 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
6006 #if !defined(TCC_TARGET_ARM)
6013 /* convert fp to int */
6014 if (dbt
== VT_BOOL
) {
6018 /* we handle char/short/etc... with generic code */
6019 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
6020 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
6025 case VT_LLONG
| VT_UNSIGNED
:
6027 /* XXX: add const cases for long long */
6029 case VT_INT
| VT_UNSIGNED
:
6031 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
6032 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
6033 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
6039 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
6040 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
6041 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
6049 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
6050 /* additional cast for char/short... */
6055 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
6056 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
6057 /* scalar to long long */
6059 if (sbt
== (VT_INT
| VT_UNSIGNED
))
6060 vtop
->c
.ll
= vtop
->c
.ui
;
6062 vtop
->c
.ll
= vtop
->c
.i
;
6064 /* machine independent conversion */
6066 /* generate high word */
6067 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
6075 /* patch second register */
6076 vtop
[-1].r2
= vtop
->r
;
6080 } else if (dbt
== VT_BOOL
) {
6081 /* scalar to bool */
6084 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
6085 (dbt
& VT_BTYPE
) == VT_SHORT
) {
6086 if (sbt
== VT_PTR
) {
6087 vtop
->type
.t
= VT_INT
;
6088 warning("nonportable conversion from pointer to char/short");
6090 force_charshort_cast(dbt
);
6091 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
6093 if (sbt
== VT_LLONG
) {
6094 /* from long long: just take low order word */
6098 /* if lvalue and single word type, nothing to do because
6099 the lvalue already contains the real type size (see
6100 VT_LVAL_xxx constants) */
6102 } else if ((dbt
& VT_BTYPE
) == VT_PTR
&& !(vtop
->r
& VT_LVAL
)) {
6103 /* if we are casting between pointer types,
6104 we must update the VT_LVAL_xxx size */
6105 vtop
->r
= (vtop
->r
& ~VT_LVAL_TYPE
)
6106 | (lvalue_type(type
->ref
->type
.t
) & VT_LVAL_TYPE
);
6111 /* return type size. Put alignment at 'a' */
6112 static int type_size(CType
*type
, int *a
)
6117 bt
= type
->t
& VT_BTYPE
;
6118 if (bt
== VT_STRUCT
) {
6123 } else if (bt
== VT_PTR
) {
6124 if (type
->t
& VT_ARRAY
) {
6126 return type_size(&s
->type
, a
) * s
->c
;
6131 } else if (bt
== VT_LDOUBLE
) {
6133 return LDOUBLE_SIZE
;
6134 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
6135 #ifdef TCC_TARGET_I386
6137 #elif defined(TCC_TARGET_ARM)
6147 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
6150 } else if (bt
== VT_SHORT
) {
6154 /* char, void, function, _Bool */
6160 /* return the pointed type of t */
6161 static inline CType
*pointed_type(CType
*type
)
6163 return &type
->ref
->type
;
6166 /* modify type so that its it is a pointer to type. */
6167 static void mk_pointer(CType
*type
)
6170 s
= sym_push(SYM_FIELD
, type
, 0, -1);
6171 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
6175 /* compare function types. OLD functions match any new functions */
6176 static int is_compatible_func(CType
*type1
, CType
*type2
)
6182 if (!is_compatible_types(&s1
->type
, &s2
->type
))
6184 /* check func_call */
6185 if (FUNC_CALL(s1
->r
) != FUNC_CALL(s2
->r
))
6187 /* XXX: not complete */
6188 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
6192 while (s1
!= NULL
) {
6195 if (!is_compatible_parameter_types(&s1
->type
, &s2
->type
))
6205 /* return true if type1 and type2 are the same. If unqualified is
6206 true, qualifiers on the types are ignored.
6208 - enums are not checked as gcc __builtin_types_compatible_p ()
6210 static int compare_types(CType
*type1
, CType
*type2
, int unqualified
)
6214 t1
= type1
->t
& VT_TYPE
;
6215 t2
= type2
->t
& VT_TYPE
;
6217 /* strip qualifiers before comparing */
6218 t1
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6219 t2
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6221 /* XXX: bitfields ? */
6224 /* test more complicated cases */
6225 bt1
= t1
& VT_BTYPE
;
6226 if (bt1
== VT_PTR
) {
6227 type1
= pointed_type(type1
);
6228 type2
= pointed_type(type2
);
6229 return is_compatible_types(type1
, type2
);
6230 } else if (bt1
== VT_STRUCT
) {
6231 return (type1
->ref
== type2
->ref
);
6232 } else if (bt1
== VT_FUNC
) {
6233 return is_compatible_func(type1
, type2
);
6239 /* return true if type1 and type2 are exactly the same (including
6242 static int is_compatible_types(CType
*type1
, CType
*type2
)
6244 return compare_types(type1
,type2
,0);
6247 /* return true if type1 and type2 are the same (ignoring qualifiers).
6249 static int is_compatible_parameter_types(CType
*type1
, CType
*type2
)
6251 return compare_types(type1
,type2
,1);
6254 /* print a type. If 'varstr' is not NULL, then the variable is also
6255 printed in the type */
6257 /* XXX: add array and function pointers */
6258 void type_to_str(char *buf
, int buf_size
,
6259 CType
*type
, const char *varstr
)
6266 t
= type
->t
& VT_TYPE
;
6269 if (t
& VT_CONSTANT
)
6270 pstrcat(buf
, buf_size
, "const ");
6271 if (t
& VT_VOLATILE
)
6272 pstrcat(buf
, buf_size
, "volatile ");
6273 if (t
& VT_UNSIGNED
)
6274 pstrcat(buf
, buf_size
, "unsigned ");
6304 tstr
= "long double";
6306 pstrcat(buf
, buf_size
, tstr
);
6310 if (bt
== VT_STRUCT
)
6314 pstrcat(buf
, buf_size
, tstr
);
6315 v
= type
->ref
->v
& ~SYM_STRUCT
;
6316 if (v
>= SYM_FIRST_ANOM
)
6317 pstrcat(buf
, buf_size
, "<anonymous>");
6319 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
6323 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
6324 pstrcat(buf
, buf_size
, "(");
6326 while (sa
!= NULL
) {
6327 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
6328 pstrcat(buf
, buf_size
, buf1
);
6331 pstrcat(buf
, buf_size
, ", ");
6333 pstrcat(buf
, buf_size
, ")");
6337 pstrcpy(buf1
, sizeof(buf1
), "*");
6339 pstrcat(buf1
, sizeof(buf1
), varstr
);
6340 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
6344 pstrcat(buf
, buf_size
, " ");
6345 pstrcat(buf
, buf_size
, varstr
);
6350 /* verify type compatibility to store vtop in 'dt' type, and generate
6352 static void gen_assign_cast(CType
*dt
)
6354 CType
*st
, *type1
, *type2
, tmp_type1
, tmp_type2
;
6355 char buf1
[256], buf2
[256];
6358 st
= &vtop
->type
; /* source type */
6359 dbt
= dt
->t
& VT_BTYPE
;
6360 sbt
= st
->t
& VT_BTYPE
;
6361 if (dt
->t
& VT_CONSTANT
)
6362 warning("assignment of read-only location");
6365 /* special cases for pointers */
6366 /* '0' can also be a pointer */
6367 if (is_null_pointer(vtop
))
6369 /* accept implicit pointer to integer cast with warning */
6370 if (is_integer_btype(sbt
)) {
6371 warning("assignment makes pointer from integer without a cast");
6374 type1
= pointed_type(dt
);
6375 /* a function is implicitely a function pointer */
6376 if (sbt
== VT_FUNC
) {
6377 if ((type1
->t
& VT_BTYPE
) != VT_VOID
&&
6378 !is_compatible_types(pointed_type(dt
), st
))
6385 type2
= pointed_type(st
);
6386 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
6387 (type2
->t
& VT_BTYPE
) == VT_VOID
) {
6388 /* void * can match anything */
6390 /* exact type match, except for unsigned */
6393 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
6394 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
6395 if (!is_compatible_types(&tmp_type1
, &tmp_type2
))
6396 warning("assignment from incompatible pointer type");
6398 /* check const and volatile */
6399 if ((!(type1
->t
& VT_CONSTANT
) && (type2
->t
& VT_CONSTANT
)) ||
6400 (!(type1
->t
& VT_VOLATILE
) && (type2
->t
& VT_VOLATILE
)))
6401 warning("assignment discards qualifiers from pointer target type");
6407 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
6408 warning("assignment makes integer from pointer without a cast");
6410 /* XXX: more tests */
6415 tmp_type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6416 tmp_type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6417 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
6419 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
6420 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
6421 error("cannot cast '%s' to '%s'", buf1
, buf2
);
6429 /* store vtop in lvalue pushed on stack */
6432 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
6434 ft
= vtop
[-1].type
.t
;
6435 sbt
= vtop
->type
.t
& VT_BTYPE
;
6436 dbt
= ft
& VT_BTYPE
;
6437 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
6438 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
6439 /* optimize char/short casts */
6440 delayed_cast
= VT_MUSTCAST
;
6441 vtop
->type
.t
= ft
& VT_TYPE
;
6442 /* XXX: factorize */
6443 if (ft
& VT_CONSTANT
)
6444 warning("assignment of read-only location");
6447 if (!(ft
& VT_BITFIELD
))
6448 gen_assign_cast(&vtop
[-1].type
);
6451 if (sbt
== VT_STRUCT
) {
6452 /* if structure, only generate pointer */
6453 /* structure assignment : generate memcpy */
6454 /* XXX: optimize if small size */
6455 if (!nocode_wanted
) {
6456 size
= type_size(&vtop
->type
, &align
);
6460 vpush_global_sym(&func_old_type
, TOK_memcpy8
);
6461 else if(!(align
& 3))
6462 vpush_global_sym(&func_old_type
, TOK_memcpy4
);
6465 vpush_global_sym(&func_old_type
, TOK_memcpy
);
6469 vtop
->type
.t
= VT_INT
;
6473 vtop
->type
.t
= VT_INT
;
6485 /* leave source on stack */
6486 } else if (ft
& VT_BITFIELD
) {
6487 /* bitfield store handling */
6488 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
6489 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
6490 /* remove bit field info to avoid loops */
6491 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
6493 /* duplicate source into other register */
6498 /* duplicate destination */
6500 vtop
[-1] = vtop
[-2];
6502 /* mask and shift source */
6503 vpushi((1 << bit_size
) - 1);
6507 /* load destination, mask and or with source */
6509 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
6515 /* pop off shifted source from "duplicate source..." above */
6519 #ifdef CONFIG_TCC_BCHECK
6520 /* bound check case */
6521 if (vtop
[-1].r
& VT_MUSTBOUND
) {
6527 if (!nocode_wanted
) {
6531 r
= gv(rc
); /* generate value */
6532 /* if lvalue was saved on stack, must read it */
6533 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
6535 t
= get_reg(RC_INT
);
6537 sv
.r
= VT_LOCAL
| VT_LVAL
;
6538 sv
.c
.ul
= vtop
[-1].c
.ul
;
6540 vtop
[-1].r
= t
| VT_LVAL
;
6543 /* two word case handling : store second register at word + 4 */
6544 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
6546 /* convert to int to increment easily */
6547 vtop
->type
.t
= VT_INT
;
6553 /* XXX: it works because r2 is spilled last ! */
6554 store(vtop
->r2
, vtop
- 1);
6558 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6559 vtop
->r
|= delayed_cast
;
6563 /* post defines POST/PRE add. c is the token ++ or -- */
6564 void inc(int post
, int c
)
6567 vdup(); /* save lvalue */
6569 gv_dup(); /* duplicate value */
6574 vpushi(c
- TOK_MID
);
6576 vstore(); /* store value */
6578 vpop(); /* if post op, return saved value */
6581 /* Parse GNUC __attribute__ extension. Currently, the following
6582 extensions are recognized:
6583 - aligned(n) : set data/function alignment.
6584 - packed : force data alignment to 1
6585 - section(x) : generate data/code in this section.
6586 - unused : currently ignored, but may be used someday.
6587 - regparm(n) : pass function parameters in registers (i386 only)
6589 static void parse_attribute(AttributeDef
*ad
)
6593 while (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
6597 while (tok
!= ')') {
6598 if (tok
< TOK_IDENT
)
6599 expect("attribute name");
6607 expect("section name");
6608 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
6617 if (n
<= 0 || (n
& (n
- 1)) != 0)
6618 error("alignment must be a positive power of two");
6631 /* currently, no need to handle it because tcc does not
6632 track unused objects */
6636 /* currently, no need to handle it because tcc does not
6637 track unused objects */
6642 FUNC_CALL(ad
->func_attr
) = FUNC_CDECL
;
6647 FUNC_CALL(ad
->func_attr
) = FUNC_STDCALL
;
6649 #ifdef TCC_TARGET_I386
6659 FUNC_CALL(ad
->func_attr
) = FUNC_FASTCALL1
+ n
- 1;
6665 FUNC_CALL(ad
->func_attr
) = FUNC_FASTCALLW
;
6669 FUNC_EXPORT(ad
->func_attr
) = 1;
6672 if (tcc_state
->warn_unsupported
)
6673 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
6674 /* skip parameters */
6676 int parenthesis
= 0;
6680 else if (tok
== ')')
6683 } while (parenthesis
&& tok
!= -1);
6696 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
6697 static void struct_decl(CType
*type
, int u
)
6699 int a
, v
, size
, align
, maxalign
, c
, offset
;
6700 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
6701 Sym
*s
, *ss
, *ass
, **ps
;
6705 a
= tok
; /* save decl type */
6710 /* struct already defined ? return it */
6712 expect("struct/union/enum name");
6716 error("invalid type");
6723 /* we put an undefined size for struct/union */
6724 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
6725 s
->r
= 0; /* default alignment is zero as gcc */
6726 /* put struct/union/enum name in type */
6734 error("struct/union/enum already defined");
6735 /* cannot be empty */
6737 /* non empty enums are not allowed */
6738 if (a
== TOK_ENUM
) {
6742 expect("identifier");
6748 /* enum symbols have static storage */
6749 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
6750 ss
->type
.t
|= VT_STATIC
;
6755 /* NOTE: we accept a trailing comma */
6765 while (tok
!= '}') {
6766 parse_btype(&btype
, &ad
);
6772 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
| TYPE_ABSTRACT
);
6773 if (v
== 0 && (type1
.t
& VT_BTYPE
) != VT_STRUCT
)
6774 expect("identifier");
6775 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
6776 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
| VT_INLINE
)))
6777 error("invalid type for '%s'",
6778 get_tok_str(v
, NULL
));
6782 bit_size
= expr_const();
6783 /* XXX: handle v = 0 case for messages */
6785 error("negative width in bit-field '%s'",
6786 get_tok_str(v
, NULL
));
6787 if (v
&& bit_size
== 0)
6788 error("zero width for bit-field '%s'",
6789 get_tok_str(v
, NULL
));
6791 size
= type_size(&type1
, &align
);
6793 if (align
< ad
.aligned
)
6795 } else if (ad
.packed
) {
6797 } else if (*tcc_state
->pack_stack_ptr
) {
6798 if (align
> *tcc_state
->pack_stack_ptr
)
6799 align
= *tcc_state
->pack_stack_ptr
;
6802 if (bit_size
>= 0) {
6803 bt
= type1
.t
& VT_BTYPE
;
6809 error("bitfields must have scalar type");
6811 if (bit_size
> bsize
) {
6812 error("width of '%s' exceeds its type",
6813 get_tok_str(v
, NULL
));
6814 } else if (bit_size
== bsize
) {
6815 /* no need for bit fields */
6817 } else if (bit_size
== 0) {
6818 /* XXX: what to do if only padding in a
6820 /* zero size: means to pad */
6824 /* we do not have enough room ? */
6825 if ((bit_pos
+ bit_size
) > bsize
)
6828 /* XXX: handle LSB first */
6829 type1
.t
|= VT_BITFIELD
|
6830 (bit_pos
<< VT_STRUCT_SHIFT
) |
6831 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
6832 bit_pos
+= bit_size
;
6837 if (v
!= 0 || (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
6838 /* add new memory data only if starting
6840 if (lbit_pos
== 0) {
6841 if (a
== TOK_STRUCT
) {
6842 c
= (c
+ align
- 1) & -align
;
6851 if (align
> maxalign
)
6855 printf("add field %s offset=%d",
6856 get_tok_str(v
, NULL
), offset
);
6857 if (type1
.t
& VT_BITFIELD
) {
6858 printf(" pos=%d size=%d",
6859 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
6860 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
6865 if (v
== 0 && (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
6867 while ((ass
= ass
->next
) != NULL
) {
6868 ss
= sym_push(ass
->v
, &ass
->type
, 0, offset
+ ass
->c
);
6873 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
6877 if (tok
== ';' || tok
== TOK_EOF
)
6884 /* store size and alignment */
6885 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
6891 /* return 0 if no type declaration. otherwise, return the basic type
6894 static int parse_btype(CType
*type
, AttributeDef
*ad
)
6896 int t
, u
, type_found
, typespec_found
, typedef_found
;
6900 memset(ad
, 0, sizeof(AttributeDef
));
6908 /* currently, we really ignore extension */
6918 if ((t
& VT_BTYPE
) != 0)
6919 error("too many basic types");
6935 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
6936 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6937 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
6938 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
6952 if ((t
& VT_BTYPE
) == VT_LONG
) {
6953 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6960 struct_decl(&type1
, VT_ENUM
);
6963 type
->ref
= type1
.ref
;
6967 struct_decl(&type1
, VT_STRUCT
);
6970 /* type modifiers */
7023 /* GNUC attribute */
7024 case TOK_ATTRIBUTE1
:
7025 case TOK_ATTRIBUTE2
:
7026 parse_attribute(ad
);
7033 parse_expr_type(&type1
);
7036 if (typespec_found
|| typedef_found
)
7039 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
7042 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
7043 type
->ref
= s
->type
.ref
;
7051 if ((t
& (VT_SIGNED
|VT_UNSIGNED
)) == (VT_SIGNED
|VT_UNSIGNED
))
7052 error("signed and unsigned modifier");
7053 if (tcc_state
->char_is_unsigned
) {
7054 if ((t
& (VT_SIGNED
|VT_UNSIGNED
|VT_BTYPE
)) == VT_BYTE
)
7059 /* long is never used as type */
7060 if ((t
& VT_BTYPE
) == VT_LONG
)
7061 t
= (t
& ~VT_BTYPE
) | VT_INT
;
7066 /* convert a function parameter type (array to pointer and function to
7067 function pointer) */
7068 static inline void convert_parameter_type(CType
*pt
)
7070 /* remove const and volatile qualifiers (XXX: const could be used
7071 to indicate a const function parameter */
7072 pt
->t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7073 /* array must be transformed to pointer according to ANSI C */
7075 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
7080 static void post_type(CType
*type
, AttributeDef
*ad
)
7082 int n
, l
, t1
, arg_size
, align
;
7083 Sym
**plast
, *s
, *first
;
7088 /* function declaration */
7096 /* read param name and compute offset */
7097 if (l
!= FUNC_OLD
) {
7098 if (!parse_btype(&pt
, &ad1
)) {
7100 error("invalid type");
7107 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
7109 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
7110 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
7111 error("parameter declared as void");
7112 arg_size
+= (type_size(&pt
, &align
) + 3) & ~3;
7117 expect("identifier");
7121 convert_parameter_type(&pt
);
7122 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
7128 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
7135 /* if no parameters, then old type prototype */
7139 t1
= type
->t
& VT_STORAGE
;
7140 /* NOTE: const is ignored in returned type as it has a special
7141 meaning in gcc / C++ */
7142 type
->t
&= ~(VT_STORAGE
| VT_CONSTANT
);
7143 post_type(type
, ad
);
7144 /* we push a anonymous symbol which will contain the function prototype */
7145 FUNC_ARGS(ad
->func_attr
) = arg_size
;
7146 s
= sym_push(SYM_FIELD
, type
, ad
->func_attr
, l
);
7148 type
->t
= t1
| VT_FUNC
;
7150 } else if (tok
== '[') {
7151 /* array definition */
7157 error("invalid array size");
7160 /* parse next post type */
7161 t1
= type
->t
& VT_STORAGE
;
7162 type
->t
&= ~VT_STORAGE
;
7163 post_type(type
, ad
);
7165 /* we push a anonymous symbol which will contain the array
7167 s
= sym_push(SYM_FIELD
, type
, 0, n
);
7168 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
7173 /* Parse a type declaration (except basic type), and return the type
7174 in 'type'. 'td' is a bitmask indicating which kind of type decl is
7175 expected. 'type' should contain the basic type. 'ad' is the
7176 attribute definition of the basic type. It can be modified by
7179 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
7182 CType type1
, *type2
;
7185 while (tok
== '*') {
7193 qualifiers
|= VT_CONSTANT
;
7198 qualifiers
|= VT_VOLATILE
;
7206 type
->t
|= qualifiers
;
7209 /* XXX: clarify attribute handling */
7210 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
7211 parse_attribute(ad
);
7213 /* recursive type */
7214 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
7215 type1
.t
= 0; /* XXX: same as int */
7218 /* XXX: this is not correct to modify 'ad' at this point, but
7219 the syntax is not clear */
7220 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
7221 parse_attribute(ad
);
7222 type_decl(&type1
, ad
, v
, td
);
7225 /* type identifier */
7226 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
7230 if (!(td
& TYPE_ABSTRACT
))
7231 expect("identifier");
7235 post_type(type
, ad
);
7236 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
7237 parse_attribute(ad
);
7240 /* append type at the end of type1 */
7253 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
7254 static int lvalue_type(int t
)
7259 if (bt
== VT_BYTE
|| bt
== VT_BOOL
)
7261 else if (bt
== VT_SHORT
)
7265 if (t
& VT_UNSIGNED
)
7266 r
|= VT_LVAL_UNSIGNED
;
7270 /* indirection with full error checking and bound check */
7271 static void indir(void)
7273 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
7274 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
7278 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
7280 vtop
->type
= *pointed_type(&vtop
->type
);
7281 /* Arrays and functions are never lvalues */
7282 if (!(vtop
->type
.t
& VT_ARRAY
)
7283 && (vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
7284 vtop
->r
|= lvalue_type(vtop
->type
.t
);
7285 /* if bound checking, the referenced pointer must be checked */
7286 if (do_bounds_check
)
7287 vtop
->r
|= VT_MUSTBOUND
;
7291 /* pass a parameter to a function and do type checking and casting */
7292 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
7297 func_type
= func
->c
;
7298 if (func_type
== FUNC_OLD
||
7299 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
7300 /* default casting : only need to convert float to double */
7301 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
7305 } else if (arg
== NULL
) {
7306 error("too many arguments to function");
7309 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
7310 gen_assign_cast(&type
);
7314 /* parse an expression of the form '(type)' or '(expr)' and return its
7316 static void parse_expr_type(CType
*type
)
7322 if (parse_btype(type
, &ad
)) {
7323 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
7330 static void parse_type(CType
*type
)
7335 if (!parse_btype(type
, &ad
)) {
7338 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
7341 static void vpush_tokc(int t
)
7345 vsetc(&type
, VT_CONST
, &tokc
);
7348 static void unary(void)
7350 int n
, t
, align
, size
, r
;
7355 /* XXX: GCC 2.95.3 does not generate a table although it should be
7369 vpush_tokc(VT_INT
| VT_UNSIGNED
);
7373 vpush_tokc(VT_LLONG
);
7377 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
7381 vpush_tokc(VT_FLOAT
);
7385 vpush_tokc(VT_DOUBLE
);
7389 vpush_tokc(VT_LDOUBLE
);
7392 case TOK___FUNCTION__
:
7394 goto tok_identifier
;
7400 /* special function name identifier */
7401 len
= strlen(funcname
) + 1;
7402 /* generate char[len] type */
7407 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
7408 ptr
= section_ptr_add(data_section
, len
);
7409 memcpy(ptr
, funcname
, len
);
7414 #ifdef TCC_TARGET_PE
7415 t
= VT_SHORT
| VT_UNSIGNED
;
7421 /* string parsing */
7424 if (tcc_state
->warn_write_strings
)
7429 memset(&ad
, 0, sizeof(AttributeDef
));
7430 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
7435 if (parse_btype(&type
, &ad
)) {
7436 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
7438 /* check ISOC99 compound literal */
7440 /* data is allocated locally by default */
7445 /* all except arrays are lvalues */
7446 if (!(type
.t
& VT_ARRAY
))
7447 r
|= lvalue_type(type
.t
);
7448 memset(&ad
, 0, sizeof(AttributeDef
));
7449 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
7454 } else if (tok
== '{') {
7455 /* save all registers */
7457 /* statement expression : we do not accept break/continue
7458 inside as GCC does */
7459 block(NULL
, NULL
, NULL
, NULL
, 0, 1);
7474 /* functions names must be treated as function pointers,
7475 except for unary '&' and sizeof. Since we consider that
7476 functions are not lvalues, we only have to handle it
7477 there and in function calls. */
7478 /* arrays can also be used although they are not lvalues */
7479 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
7480 !(vtop
->type
.t
& VT_ARRAY
) && !(vtop
->type
.t
& VT_LLOCAL
))
7482 mk_pointer(&vtop
->type
);
7488 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
7489 vtop
->c
.i
= !vtop
->c
.i
;
7490 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
7491 vtop
->c
.i
= vtop
->c
.i
^ 1;
7494 vseti(VT_JMP
, gtst(1, 0));
7505 /* in order to force cast, we add zero */
7507 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
7508 error("pointer not accepted for unary plus");
7518 parse_expr_type(&type
);
7522 size
= type_size(&type
, &align
);
7523 if (t
== TOK_SIZEOF
) {
7525 error("sizeof applied to an incomplete type");
7530 vtop
->type
.t
|= VT_UNSIGNED
;
7533 case TOK_builtin_types_compatible_p
:
7542 type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7543 type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7544 vpushi(is_compatible_types(&type1
, &type2
));
7547 case TOK_builtin_constant_p
:
7549 int saved_nocode_wanted
, res
;
7552 saved_nocode_wanted
= nocode_wanted
;
7555 res
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
7557 nocode_wanted
= saved_nocode_wanted
;
7577 goto tok_identifier
;
7579 /* allow to take the address of a label */
7580 if (tok
< TOK_UIDENT
)
7581 expect("label identifier");
7582 s
= label_find(tok
);
7584 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7586 if (s
->r
== LABEL_DECLARED
)
7587 s
->r
= LABEL_FORWARD
;
7590 s
->type
.t
= VT_VOID
;
7591 mk_pointer(&s
->type
);
7592 s
->type
.t
|= VT_STATIC
;
7594 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
7603 expect("identifier");
7607 error("'%s' undeclared", get_tok_str(t
, NULL
));
7608 /* for simple function calls, we tolerate undeclared
7609 external reference to int() function */
7610 if (tcc_state
->warn_implicit_function_declaration
)
7611 warning("implicit declaration of function '%s'",
7612 get_tok_str(t
, NULL
));
7613 s
= external_global_sym(t
, &func_old_type
, 0);
7615 if ((s
->type
.t
& (VT_STATIC
| VT_INLINE
| VT_BTYPE
)) ==
7616 (VT_STATIC
| VT_INLINE
| VT_FUNC
)) {
7617 /* if referencing an inline function, then we generate a
7618 symbol to it if not already done. It will have the
7619 effect to generate code for it at the end of the
7620 compilation unit. Inline function as always
7621 generated in the text section. */
7623 put_extern_sym(s
, text_section
, 0, 0);
7624 r
= VT_SYM
| VT_CONST
;
7628 vset(&s
->type
, r
, s
->c
);
7629 /* if forward reference, we must point to s */
7630 if (vtop
->r
& VT_SYM
) {
7637 /* post operations */
7639 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
7642 } else if (tok
== '.' || tok
== TOK_ARROW
) {
7644 if (tok
== TOK_ARROW
)
7649 /* expect pointer on structure */
7650 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
7651 expect("struct or union");
7655 while ((s
= s
->next
) != NULL
) {
7660 error("field not found: %s", get_tok_str(tok
& ~SYM_FIELD
, NULL
));
7661 /* add field offset to pointer */
7662 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
7665 /* change type to field type, and set to lvalue */
7666 vtop
->type
= s
->type
;
7667 /* an array is never an lvalue */
7668 if (!(vtop
->type
.t
& VT_ARRAY
)) {
7669 vtop
->r
|= lvalue_type(vtop
->type
.t
);
7670 /* if bound checking, the referenced pointer must be checked */
7671 if (do_bounds_check
)
7672 vtop
->r
|= VT_MUSTBOUND
;
7675 } else if (tok
== '[') {
7681 } else if (tok
== '(') {
7687 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
7688 /* pointer test (no array accepted) */
7689 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
7690 vtop
->type
= *pointed_type(&vtop
->type
);
7691 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
7695 expect("function pointer");
7698 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
7700 /* get return type */
7703 sa
= s
->next
; /* first parameter */
7706 /* compute first implicit argument if a structure is returned */
7707 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
7708 /* get some space for the returned structure */
7709 size
= type_size(&s
->type
, &align
);
7710 loc
= (loc
- size
) & -align
;
7712 ret
.r
= VT_LOCAL
| VT_LVAL
;
7713 /* pass it as 'int' to avoid structure arg passing
7715 vseti(VT_LOCAL
, loc
);
7720 /* return in register */
7721 if (is_float(ret
.type
.t
)) {
7724 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
7733 gfunc_param_typed(s
, sa
);
7743 error("too few arguments to function");
7745 if (!nocode_wanted
) {
7746 gfunc_call(nb_args
);
7748 vtop
-= (nb_args
+ 1);
7751 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
7759 static void uneq(void)
7765 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
7766 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
7767 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
7782 static void expr_prod(void)
7787 while (tok
== '*' || tok
== '/' || tok
== '%') {
7795 static void expr_sum(void)
7800 while (tok
== '+' || tok
== '-') {
7808 static void expr_shift(void)
7813 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
7821 static void expr_cmp(void)
7826 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
7827 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
7835 static void expr_cmpeq(void)
7840 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
7848 static void expr_and(void)
7851 while (tok
== '&') {
7858 static void expr_xor(void)
7861 while (tok
== '^') {
7868 static void expr_or(void)
7871 while (tok
== '|') {
7878 /* XXX: fix this mess */
7879 static void expr_land_const(void)
7882 while (tok
== TOK_LAND
) {
7889 /* XXX: fix this mess */
7890 static void expr_lor_const(void)
7893 while (tok
== TOK_LOR
) {
7900 /* only used if non constant */
7901 static void expr_land(void)
7906 if (tok
== TOK_LAND
) {
7911 if (tok
!= TOK_LAND
) {
7921 static void expr_lor(void)
7926 if (tok
== TOK_LOR
) {
7931 if (tok
!= TOK_LOR
) {
7941 /* XXX: better constant handling */
7942 static void expr_eq(void)
7944 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
7946 CType type
, type1
, type2
;
7955 if (tok
== ':' && gnu_ext
) {
7971 if (vtop
!= vstack
) {
7972 /* needed to avoid having different registers saved in
7974 if (is_float(vtop
->type
.t
))
7981 if (tok
== ':' && gnu_ext
) {
7989 sv
= *vtop
; /* save value to handle it later */
7990 vtop
--; /* no vpop so that FP stack is not flushed */
7998 bt1
= t1
& VT_BTYPE
;
8000 bt2
= t2
& VT_BTYPE
;
8001 /* cast operands to correct type according to ISOC rules */
8002 if (is_float(bt1
) || is_float(bt2
)) {
8003 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
8004 type
.t
= VT_LDOUBLE
;
8005 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
8010 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
8011 /* cast to biggest op */
8013 /* convert to unsigned if it does not fit in a long long */
8014 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
8015 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
8016 type
.t
|= VT_UNSIGNED
;
8017 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
8018 /* XXX: test pointer compatibility */
8020 } else if (bt1
== VT_FUNC
|| bt2
== VT_FUNC
) {
8021 /* XXX: test function pointer compatibility */
8023 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
8024 /* XXX: test structure compatibility */
8026 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
8027 /* NOTE: as an extension, we accept void on only one side */
8030 /* integer operations */
8032 /* convert to unsigned if it does not fit in an integer */
8033 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
8034 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
8035 type
.t
|= VT_UNSIGNED
;
8038 /* now we convert second operand */
8040 if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
8043 if (is_float(type
.t
)) {
8045 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
8046 /* for long longs, we use fixed registers to avoid having
8047 to handle a complicated move */
8052 /* this is horrible, but we must also convert first
8056 /* put again first value and cast it */
8059 if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
8069 static void gexpr(void)
8080 /* parse an expression and return its type without any side effect. */
8081 static void expr_type(CType
*type
)
8083 int saved_nocode_wanted
;
8085 saved_nocode_wanted
= nocode_wanted
;
8090 nocode_wanted
= saved_nocode_wanted
;
8093 /* parse a unary expression and return its type without any side
8095 static void unary_type(CType
*type
)
8107 /* parse a constant expression and return value in vtop. */
8108 static void expr_const1(void)
8117 /* parse an integer constant and return its value. */
8118 static int expr_const(void)
8122 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
8123 expect("constant expression");
8129 /* return the label token if current token is a label, otherwise
8131 static int is_label(void)
8135 /* fast test first */
8136 if (tok
< TOK_UIDENT
)
8138 /* no need to save tokc because tok is an identifier */
8145 unget_tok(last_tok
);
8150 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
8151 int case_reg
, int is_expr
)
8156 /* generate line number info */
8158 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
8159 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
8161 last_line_num
= file
->line_num
;
8165 /* default return value is (void) */
8167 vtop
->type
.t
= VT_VOID
;
8170 if (tok
== TOK_IF
) {
8177 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
8179 if (c
== TOK_ELSE
) {
8183 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
8184 gsym(d
); /* patch else jmp */
8187 } else if (tok
== TOK_WHILE
) {
8195 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
8199 } else if (tok
== '{') {
8203 /* record local declaration stack position */
8205 llabel
= local_label_stack
;
8206 /* handle local labels declarations */
8207 if (tok
== TOK_LABEL
) {
8210 if (tok
< TOK_UIDENT
)
8211 expect("label identifier");
8212 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
8222 while (tok
!= '}') {
8227 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
8230 /* pop locally defined labels */
8231 label_pop(&local_label_stack
, llabel
);
8232 /* pop locally defined symbols */
8233 sym_pop(&local_stack
, s
);
8235 } else if (tok
== TOK_RETURN
) {
8239 gen_assign_cast(&func_vt
);
8240 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
8242 /* if returning structure, must copy it to implicit
8243 first pointer arg location */
8246 size
= type_size(&func_vt
,&align
);
8249 if((vtop
->r
!= (VT_LOCAL
| VT_LVAL
) || (vtop
->c
.i
& 3))
8253 loc
= (loc
- size
) & -4;
8256 vset(&type
, VT_LOCAL
| VT_LVAL
, addr
);
8259 vset(&int_type
, VT_LOCAL
| VT_LVAL
, addr
);
8261 vtop
->type
= int_type
;
8267 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
8270 /* copy structure value to pointer */
8275 } else if (is_float(func_vt
.t
)) {
8280 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
8283 rsym
= gjmp(rsym
); /* jmp */
8284 } else if (tok
== TOK_BREAK
) {
8287 error("cannot break");
8288 *bsym
= gjmp(*bsym
);
8291 } else if (tok
== TOK_CONTINUE
) {
8294 error("cannot continue");
8295 *csym
= gjmp(*csym
);
8298 } else if (tok
== TOK_FOR
) {
8325 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
8330 if (tok
== TOK_DO
) {
8335 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
8346 if (tok
== TOK_SWITCH
) {
8350 /* XXX: other types than integer */
8351 case_reg
= gv(RC_INT
);
8355 b
= gjmp(0); /* jump to first case */
8357 block(&a
, csym
, &b
, &c
, case_reg
, 0);
8358 /* if no default, jmp after switch */
8366 if (tok
== TOK_CASE
) {
8373 if (gnu_ext
&& tok
== TOK_DOTS
) {
8377 warning("empty case range");
8379 /* since a case is like a label, we must skip it with a jmp */
8386 *case_sym
= gtst(1, 0);
8389 *case_sym
= gtst(1, 0);
8393 *case_sym
= gtst(1, *case_sym
);
8398 goto block_after_label
;
8400 if (tok
== TOK_DEFAULT
) {
8406 error("too many 'default'");
8409 goto block_after_label
;
8411 if (tok
== TOK_GOTO
) {
8413 if (tok
== '*' && gnu_ext
) {
8417 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
8420 } else if (tok
>= TOK_UIDENT
) {
8421 s
= label_find(tok
);
8422 /* put forward definition if needed */
8424 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
8426 if (s
->r
== LABEL_DECLARED
)
8427 s
->r
= LABEL_FORWARD
;
8429 /* label already defined */
8430 if (s
->r
& LABEL_FORWARD
)
8431 s
->next
= (void *)gjmp((long)s
->next
);
8433 gjmp_addr((long)s
->next
);
8436 expect("label identifier");
8439 } else if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
8447 if (s
->r
== LABEL_DEFINED
)
8448 error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
8449 gsym((long)s
->next
);
8450 s
->r
= LABEL_DEFINED
;
8452 s
= label_push(&global_label_stack
, b
, LABEL_DEFINED
);
8454 s
->next
= (void *)ind
;
8455 /* we accept this, but it is a mistake */
8458 warning("deprecated use of label at end of compound statement");
8462 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
8465 /* expression case */
8480 /* t is the array or struct type. c is the array or struct
8481 address. cur_index/cur_field is the pointer to the current
8482 value. 'size_only' is true if only size info is needed (only used
8484 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
8485 int *cur_index
, Sym
**cur_field
,
8489 int notfirst
, index
, index_last
, align
, l
, nb_elems
, elem_size
;
8495 if (gnu_ext
&& (l
= is_label()) != 0)
8497 while (tok
== '[' || tok
== '.') {
8499 if (!(type
->t
& VT_ARRAY
))
8500 expect("array type");
8503 index
= expr_const();
8504 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
8505 expect("invalid index");
8506 if (tok
== TOK_DOTS
&& gnu_ext
) {
8508 index_last
= expr_const();
8509 if (index_last
< 0 ||
8510 (s
->c
>= 0 && index_last
>= s
->c
) ||
8512 expect("invalid index");
8518 *cur_index
= index_last
;
8519 type
= pointed_type(type
);
8520 elem_size
= type_size(type
, &align
);
8521 c
+= index
* elem_size
;
8522 /* NOTE: we only support ranges for last designator */
8523 nb_elems
= index_last
- index
+ 1;
8524 if (nb_elems
!= 1) {
8533 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
8534 expect("struct/union type");
8547 /* XXX: fix this mess by using explicit storage field */
8549 type1
.t
|= (type
->t
& ~VT_TYPE
);
8563 if (type
->t
& VT_ARRAY
) {
8565 type
= pointed_type(type
);
8566 c
+= index
* type_size(type
, &align
);
8570 error("too many field init");
8571 /* XXX: fix this mess by using explicit storage field */
8573 type1
.t
|= (type
->t
& ~VT_TYPE
);
8578 decl_initializer(type
, sec
, c
, 0, size_only
);
8580 /* XXX: make it more general */
8581 if (!size_only
&& nb_elems
> 1) {
8582 unsigned long c_end
;
8587 error("range init not supported yet for dynamic storage");
8588 c_end
= c
+ nb_elems
* elem_size
;
8589 if (c_end
> sec
->data_allocated
)
8590 section_realloc(sec
, c_end
);
8591 src
= sec
->data
+ c
;
8593 for(i
= 1; i
< nb_elems
; i
++) {
8595 memcpy(dst
, src
, elem_size
);
8601 #define EXPR_CONST 1
8604 /* store a value or an expression directly in global data or in local array */
8605 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
8606 int v
, int expr_type
)
8608 int saved_global_expr
, bt
, bit_pos
, bit_size
;
8610 unsigned long long bit_mask
;
8618 /* compound literals must be allocated globally in this case */
8619 saved_global_expr
= global_expr
;
8622 global_expr
= saved_global_expr
;
8623 /* NOTE: symbols are accepted */
8624 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
8625 error("initializer element is not constant");
8633 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
8636 /* XXX: not portable */
8637 /* XXX: generate error if incorrect relocation */
8638 gen_assign_cast(&dtype
);
8639 bt
= type
->t
& VT_BTYPE
;
8640 ptr
= sec
->data
+ c
;
8641 /* XXX: make code faster ? */
8642 if (!(type
->t
& VT_BITFIELD
)) {
8647 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
8648 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
8649 bit_mask
= (1LL << bit_size
) - 1;
8651 if ((vtop
->r
& VT_SYM
) &&
8657 (bt
== VT_INT
&& bit_size
!= 32)))
8658 error("initializer element is not computable at load time");
8661 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8664 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8667 *(double *)ptr
= vtop
->c
.d
;
8670 *(long double *)ptr
= vtop
->c
.ld
;
8673 *(long long *)ptr
|= (vtop
->c
.ll
& bit_mask
) << bit_pos
;
8676 if (vtop
->r
& VT_SYM
) {
8677 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
8679 *(int *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8684 vset(&dtype
, VT_LOCAL
|VT_LVAL
, c
);
8691 /* put zeros for variable based init */
8692 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
8695 /* nothing to do because globals are already set to zero */
8697 vpush_global_sym(&func_old_type
, TOK_memset
);
8705 /* 't' contains the type and storage info. 'c' is the offset of the
8706 object in section 'sec'. If 'sec' is NULL, it means stack based
8707 allocation. 'first' is true if array '{' must be read (multi
8708 dimension implicit array init handling). 'size_only' is true if
8709 size only evaluation is wanted (only for arrays). */
8710 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
8711 int first
, int size_only
)
8713 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
8714 int size1
, align1
, expr_type
;
8718 if (type
->t
& VT_ARRAY
) {
8722 t1
= pointed_type(type
);
8723 size1
= type_size(t1
, &align1
);
8726 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
8732 /* only parse strings here if correct type (otherwise: handle
8733 them as ((w)char *) expressions */
8734 if ((tok
== TOK_LSTR
&&
8735 #ifdef TCC_TARGET_PE
8736 (t1
->t
& VT_BTYPE
) == VT_SHORT
&& (t1
->t
& VT_UNSIGNED
)
8738 (t1
->t
& VT_BTYPE
) == VT_INT
8740 ) || (tok
== TOK_STR
&& (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
8741 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8746 /* compute maximum number of chars wanted */
8748 cstr_len
= cstr
->size
;
8750 cstr_len
= cstr
->size
/ sizeof(nwchar_t
);
8753 if (n
>= 0 && nb
> (n
- array_length
))
8754 nb
= n
- array_length
;
8757 warning("initializer-string for array is too long");
8758 /* in order to go faster for common case (char
8759 string in global variable, we handle it
8761 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
8762 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
8766 ch
= ((unsigned char *)cstr
->data
)[i
];
8768 ch
= ((nwchar_t
*)cstr
->data
)[i
];
8769 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
8777 /* only add trailing zero if enough storage (no
8778 warning in this case since it is standard) */
8779 if (n
< 0 || array_length
< n
) {
8781 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
8787 while (tok
!= '}') {
8788 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
8789 if (n
>= 0 && index
>= n
)
8790 error("index too large");
8791 /* must put zero in holes (note that doing it that way
8792 ensures that it even works with designators) */
8793 if (!size_only
&& array_length
< index
) {
8794 init_putz(t1
, sec
, c
+ array_length
* size1
,
8795 (index
- array_length
) * size1
);
8798 if (index
> array_length
)
8799 array_length
= index
;
8800 /* special test for multi dimensional arrays (may not
8801 be strictly correct if designators are used at the
8803 if (index
>= n
&& no_oblock
)
8812 /* put zeros at the end */
8813 if (!size_only
&& n
>= 0 && array_length
< n
) {
8814 init_putz(t1
, sec
, c
+ array_length
* size1
,
8815 (n
- array_length
) * size1
);
8817 /* patch type size if needed */
8819 s
->c
= array_length
;
8820 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
8821 (sec
|| !first
|| tok
== '{')) {
8824 /* NOTE: the previous test is a specific case for automatic
8825 struct/union init */
8826 /* XXX: union needs only one init */
8828 /* XXX: this test is incorrect for local initializers
8829 beginning with ( without {. It would be much more difficult
8830 to do it correctly (ideally, the expression parser should
8831 be used in all cases) */
8837 while (tok
== '(') {
8841 if (!parse_btype(&type1
, &ad1
))
8843 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
8845 if (!is_assignable_types(type
, &type1
))
8846 error("invalid type for cast");
8851 if (first
|| tok
== '{') {
8860 while (tok
!= '}') {
8861 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
8863 if (!size_only
&& array_length
< index
) {
8864 init_putz(type
, sec
, c
+ array_length
,
8865 index
- array_length
);
8867 index
= index
+ type_size(&f
->type
, &align1
);
8868 if (index
> array_length
)
8869 array_length
= index
;
8871 if (no_oblock
&& f
== NULL
)
8877 /* put zeros at the end */
8878 if (!size_only
&& array_length
< n
) {
8879 init_putz(type
, sec
, c
+ array_length
,
8888 } else if (tok
== '{') {
8890 decl_initializer(type
, sec
, c
, first
, size_only
);
8892 } else if (size_only
) {
8893 /* just skip expression */
8895 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
8899 else if (tok
== ')')
8904 /* currently, we always use constant expression for globals
8905 (may change for scripting case) */
8906 expr_type
= EXPR_CONST
;
8908 expr_type
= EXPR_ANY
;
8909 init_putv(type
, sec
, c
, 0, expr_type
);
8913 /* parse an initializer for type 't' if 'has_init' is non zero, and
8914 allocate space in local or global data space ('r' is either
8915 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8916 variable 'v' of scope 'scope' is declared before initializers are
8917 parsed. If 'v' is zero, then a reference to the new object is put
8918 in the value stack. If 'has_init' is 2, a special parsing is done
8919 to handle string constants. */
8920 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
8921 int has_init
, int v
, int scope
)
8923 int size
, align
, addr
, data_offset
;
8925 ParseState saved_parse_state
;
8926 TokenString init_str
;
8929 size
= type_size(type
, &align
);
8930 /* If unknown size, we must evaluate it before
8931 evaluating initializers because
8932 initializers can generate global data too
8933 (e.g. string pointers or ISOC99 compound
8934 literals). It also simplifies local
8935 initializers handling */
8936 tok_str_new(&init_str
);
8939 error("unknown type size");
8940 /* get all init string */
8941 if (has_init
== 2) {
8942 /* only get strings */
8943 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8944 tok_str_add_tok(&init_str
);
8949 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
8951 error("unexpected end of file in initializer");
8952 tok_str_add_tok(&init_str
);
8955 else if (tok
== '}') {
8963 tok_str_add(&init_str
, -1);
8964 tok_str_add(&init_str
, 0);
8967 save_parse_state(&saved_parse_state
);
8969 macro_ptr
= init_str
.str
;
8971 decl_initializer(type
, NULL
, 0, 1, 1);
8972 /* prepare second initializer parsing */
8973 macro_ptr
= init_str
.str
;
8976 /* if still unknown size, error */
8977 size
= type_size(type
, &align
);
8979 error("unknown type size");
8981 /* take into account specified alignment if bigger */
8983 if (ad
->aligned
> align
)
8984 align
= ad
->aligned
;
8985 } else if (ad
->packed
) {
8988 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
8990 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
8992 loc
= (loc
- size
) & -align
;
8994 /* handles bounds */
8995 /* XXX: currently, since we do only one pass, we cannot track
8996 '&' operators, so we add only arrays */
8997 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
8998 unsigned long *bounds_ptr
;
8999 /* add padding between regions */
9001 /* then add local bound info */
9002 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
9003 bounds_ptr
[0] = addr
;
9004 bounds_ptr
[1] = size
;
9007 /* local variable */
9008 sym_push(v
, type
, r
, addr
);
9010 /* push local reference */
9011 vset(type
, r
, addr
);
9017 if (v
&& scope
== VT_CONST
) {
9018 /* see if the symbol was already defined */
9021 if (!is_compatible_types(&sym
->type
, type
))
9022 error("incompatible types for redefinition of '%s'",
9023 get_tok_str(v
, NULL
));
9024 if (sym
->type
.t
& VT_EXTERN
) {
9025 /* if the variable is extern, it was not allocated */
9026 sym
->type
.t
&= ~VT_EXTERN
;
9027 /* set array size if it was ommited in extern
9029 if ((sym
->type
.t
& VT_ARRAY
) &&
9030 sym
->type
.ref
->c
< 0 &&
9032 sym
->type
.ref
->c
= type
->ref
->c
;
9034 /* we accept several definitions of the same
9035 global variable. this is tricky, because we
9036 must play with the SHN_COMMON type of the symbol */
9037 /* XXX: should check if the variable was already
9038 initialized. It is incorrect to initialized it
9040 /* no init data, we won't add more to the symbol */
9047 /* allocate symbol in corresponding section */
9052 else if (tcc_state
->nocommon
)
9056 data_offset
= sec
->data_offset
;
9057 data_offset
= (data_offset
+ align
- 1) & -align
;
9059 /* very important to increment global pointer at this time
9060 because initializers themselves can create new initializers */
9061 data_offset
+= size
;
9062 /* add padding if bound check */
9063 if (do_bounds_check
)
9065 sec
->data_offset
= data_offset
;
9066 /* allocate section space to put the data */
9067 if (sec
->sh_type
!= SHT_NOBITS
&&
9068 data_offset
> sec
->data_allocated
)
9069 section_realloc(sec
, data_offset
);
9070 /* align section if needed */
9071 if (align
> sec
->sh_addralign
)
9072 sec
->sh_addralign
= align
;
9074 addr
= 0; /* avoid warning */
9078 if (scope
!= VT_CONST
|| !sym
) {
9079 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
9081 /* update symbol definition */
9083 put_extern_sym(sym
, sec
, addr
, size
);
9086 /* put a common area */
9087 put_extern_sym(sym
, NULL
, align
, size
);
9088 /* XXX: find a nicer way */
9089 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
9090 esym
->st_shndx
= SHN_COMMON
;
9095 /* push global reference */
9096 sym
= get_sym_ref(type
, sec
, addr
, size
);
9098 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
9102 /* handles bounds now because the symbol must be defined
9103 before for the relocation */
9104 if (do_bounds_check
) {
9105 unsigned long *bounds_ptr
;
9107 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
9108 /* then add global bound info */
9109 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
9110 bounds_ptr
[0] = 0; /* relocated */
9111 bounds_ptr
[1] = size
;
9115 decl_initializer(type
, sec
, addr
, 1, 0);
9116 /* restore parse state if needed */
9118 tok_str_free(init_str
.str
);
9119 restore_parse_state(&saved_parse_state
);
9125 void put_func_debug(Sym
*sym
)
9130 /* XXX: we put here a dummy type */
9131 snprintf(buf
, sizeof(buf
), "%s:%c1",
9132 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
9133 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
9134 cur_text_section
, sym
->c
);
9139 /* parse an old style function declaration list */
9140 /* XXX: check multiple parameter */
9141 static void func_decl_list(Sym
*func_sym
)
9148 /* parse each declaration */
9149 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
) {
9150 if (!parse_btype(&btype
, &ad
))
9151 expect("declaration list");
9152 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
9153 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
9155 /* we accept no variable after */
9159 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
9160 /* find parameter in function parameter list */
9163 if ((s
->v
& ~SYM_FIELD
) == v
)
9167 error("declaration for parameter '%s' but no such parameter",
9168 get_tok_str(v
, NULL
));
9170 /* check that no storage specifier except 'register' was given */
9171 if (type
.t
& VT_STORAGE
)
9172 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
9173 convert_parameter_type(&type
);
9174 /* we can add the type (NOTE: it could be local to the function) */
9176 /* accept other parameters */
9187 /* parse a function defined by symbol 'sym' and generate its code in
9188 'cur_text_section' */
9189 static void gen_function(Sym
*sym
)
9191 int saved_nocode_wanted
= nocode_wanted
;
9193 ind
= cur_text_section
->data_offset
;
9194 /* NOTE: we patch the symbol size later */
9195 put_extern_sym(sym
, cur_text_section
, ind
, 0);
9196 funcname
= get_tok_str(sym
->v
, NULL
);
9198 /* put debug symbol */
9200 put_func_debug(sym
);
9201 /* push a dummy symbol to enable local sym storage */
9202 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
9203 gfunc_prolog(&sym
->type
);
9205 block(NULL
, NULL
, NULL
, NULL
, 0, 0);
9208 cur_text_section
->data_offset
= ind
;
9209 label_pop(&global_label_stack
, NULL
);
9210 sym_pop(&local_stack
, NULL
); /* reset local stack */
9211 /* end of function */
9212 /* patch symbol size */
9213 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
9216 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
9218 funcname
= ""; /* for safety */
9219 func_vt
.t
= VT_VOID
; /* for safety */
9220 ind
= 0; /* for safety */
9221 nocode_wanted
= saved_nocode_wanted
;
9224 static void gen_inline_functions(void)
9228 int *str
, inline_generated
;
9230 /* iterate while inline function are referenced */
9232 inline_generated
= 0;
9233 for(sym
= global_stack
; sym
!= NULL
; sym
= sym
->prev
) {
9235 if (((type
->t
& VT_BTYPE
) == VT_FUNC
) &&
9236 (type
->t
& (VT_STATIC
| VT_INLINE
)) ==
9237 (VT_STATIC
| VT_INLINE
) &&
9239 /* the function was used: generate its code and
9240 convert it to a normal function */
9241 str
= INLINE_DEF(sym
->r
);
9242 sym
->r
= VT_SYM
| VT_CONST
;
9243 sym
->type
.t
&= ~VT_INLINE
;
9247 cur_text_section
= text_section
;
9249 macro_ptr
= NULL
; /* fail safe */
9252 inline_generated
= 1;
9255 if (!inline_generated
)
9259 /* free all remaining inline function tokens */
9260 for(sym
= global_stack
; sym
!= NULL
; sym
= sym
->prev
) {
9262 if (((type
->t
& VT_BTYPE
) == VT_FUNC
) &&
9263 (type
->t
& (VT_STATIC
| VT_INLINE
)) ==
9264 (VT_STATIC
| VT_INLINE
)) {
9265 //gr printf("sym %d %s\n", sym->r, get_tok_str(sym->v, NULL));
9266 if (sym
->r
== (VT_SYM
| VT_CONST
)) //gr beware!
9268 str
= INLINE_DEF(sym
->r
);
9270 sym
->r
= 0; /* fail safe */
9275 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
9276 static void decl(int l
)
9284 if (!parse_btype(&btype
, &ad
)) {
9285 /* skip redundant ';' */
9286 /* XXX: find more elegant solution */
9291 if (l
== VT_CONST
&&
9292 (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
9293 /* global asm block */
9297 /* special test for old K&R protos without explicit int
9298 type. Only accepted when defining global data */
9299 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
9303 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
9304 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
9306 /* we accept no variable after */
9310 while (1) { /* iterate thru each declaration */
9312 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
9316 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
9317 printf("type = '%s'\n", buf
);
9320 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
9321 /* if old style function prototype, we accept a
9324 if (sym
->c
== FUNC_OLD
)
9325 func_decl_list(sym
);
9330 error("cannot use local functions");
9331 if ((type
.t
& VT_BTYPE
) != VT_FUNC
)
9332 expect("function definition");
9334 /* reject abstract declarators in function definition */
9336 while ((sym
= sym
->next
) != NULL
)
9337 if (!(sym
->v
& ~SYM_FIELD
))
9338 expect("identifier");
9340 /* XXX: cannot do better now: convert extern line to static inline */
9341 if ((type
.t
& (VT_EXTERN
| VT_INLINE
)) == (VT_EXTERN
| VT_INLINE
))
9342 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
9346 if ((sym
->type
.t
& VT_BTYPE
) != VT_FUNC
)
9348 /* specific case: if not func_call defined, we put
9349 the one of the prototype */
9350 /* XXX: should have default value */
9351 r
= sym
->type
.ref
->r
;
9352 if (FUNC_CALL(r
) != FUNC_CDECL
9353 && FUNC_CALL(type
.ref
->r
) == FUNC_CDECL
)
9354 FUNC_CALL(type
.ref
->r
) = FUNC_CALL(r
);
9356 FUNC_EXPORT(type
.ref
->r
) = 1;
9358 if (!is_compatible_types(&sym
->type
, &type
)) {
9360 error("incompatible types for redefinition of '%s'",
9361 get_tok_str(v
, NULL
));
9363 /* if symbol is already defined, then put complete type */
9366 /* put function symbol */
9367 sym
= global_identifier_push(v
, type
.t
, 0);
9368 sym
->type
.ref
= type
.ref
;
9371 /* static inline functions are just recorded as a kind
9372 of macro. Their code will be emitted at the end of
9373 the compilation unit only if they are used */
9374 if ((type
.t
& (VT_INLINE
| VT_STATIC
)) ==
9375 (VT_INLINE
| VT_STATIC
)) {
9376 TokenString func_str
;
9379 tok_str_new(&func_str
);
9385 error("unexpected end of file");
9386 tok_str_add_tok(&func_str
);
9391 } else if (t
== '}') {
9393 if (block_level
== 0)
9397 tok_str_add(&func_str
, -1);
9398 tok_str_add(&func_str
, 0);
9399 INLINE_DEF(sym
->r
) = func_str
.str
;
9401 /* compute text section */
9402 cur_text_section
= ad
.section
;
9403 if (!cur_text_section
)
9404 cur_text_section
= text_section
;
9405 sym
->r
= VT_SYM
| VT_CONST
;
9410 if (btype
.t
& VT_TYPEDEF
) {
9411 /* save typedefed type */
9412 /* XXX: test storage specifiers ? */
9413 sym
= sym_push(v
, &type
, 0, 0);
9414 sym
->type
.t
|= VT_TYPEDEF
;
9415 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
9416 /* external function definition */
9417 /* specific case for func_call attribute */
9419 type
.ref
->r
= ad
.func_attr
;
9420 external_sym(v
, &type
, 0);
9422 /* not lvalue if array */
9424 if (!(type
.t
& VT_ARRAY
))
9425 r
|= lvalue_type(type
.t
);
9426 has_init
= (tok
== '=');
9427 if ((btype
.t
& VT_EXTERN
) ||
9428 ((type
.t
& VT_ARRAY
) && (type
.t
& VT_STATIC
) &&
9429 !has_init
&& l
== VT_CONST
&& type
.ref
->c
< 0)) {
9430 /* external variable */
9431 /* NOTE: as GCC, uninitialized global static
9432 arrays of null size are considered as
9434 external_sym(v
, &type
, r
);
9436 type
.t
|= (btype
.t
& VT_STATIC
); /* Retain "static". */
9437 if (type
.t
& VT_STATIC
)
9443 decl_initializer_alloc(&type
, &ad
, r
,
9457 /* better than nothing, but needs extension to handle '-E' option
9459 static void preprocess_init(TCCState
*s1
)
9461 s1
->include_stack_ptr
= s1
->include_stack
;
9462 /* XXX: move that before to avoid having to initialize
9463 file->ifdef_stack_ptr ? */
9464 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
9465 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
9467 /* XXX: not ANSI compliant: bound checking says error */
9469 s1
->pack_stack
[0] = 0;
9470 s1
->pack_stack_ptr
= s1
->pack_stack
;
9473 /* compile the C file opened in 'file'. Return non zero if errors. */
9474 static int tcc_compile(TCCState
*s1
)
9478 volatile int section_sym
;
9481 printf("%s: **** new file\n", file
->filename
);
9483 preprocess_init(s1
);
9486 anon_sym
= SYM_FIRST_ANOM
;
9488 /* file info: full path + filename */
9489 section_sym
= 0; /* avoid warning */
9491 section_sym
= put_elf_sym(symtab_section
, 0, 0,
9492 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
9493 text_section
->sh_num
, NULL
);
9494 getcwd(buf
, sizeof(buf
));
9496 normalize_slashes(buf
);
9498 pstrcat(buf
, sizeof(buf
), "/");
9499 put_stabs_r(buf
, N_SO
, 0, 0,
9500 text_section
->data_offset
, text_section
, section_sym
);
9501 put_stabs_r(file
->filename
, N_SO
, 0, 0,
9502 text_section
->data_offset
, text_section
, section_sym
);
9504 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
9505 symbols can be safely used */
9506 put_elf_sym(symtab_section
, 0, 0,
9507 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
9508 SHN_ABS
, file
->filename
);
9510 /* define some often used types */
9511 int_type
.t
= VT_INT
;
9513 char_pointer_type
.t
= VT_BYTE
;
9514 mk_pointer(&char_pointer_type
);
9516 func_old_type
.t
= VT_FUNC
;
9517 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
9519 #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
9520 float_type
.t
= VT_FLOAT
;
9521 double_type
.t
= VT_DOUBLE
;
9523 func_float_type
.t
= VT_FUNC
;
9524 func_float_type
.ref
= sym_push(SYM_FIELD
, &float_type
, FUNC_CDECL
, FUNC_OLD
);
9525 func_double_type
.t
= VT_FUNC
;
9526 func_double_type
.ref
= sym_push(SYM_FIELD
, &double_type
, FUNC_CDECL
, FUNC_OLD
);
9530 /* define 'void *alloca(unsigned int)' builtin function */
9535 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
9536 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
9539 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
9543 define_start
= define_stack
;
9546 if (setjmp(s1
->error_jmp_buf
) == 0) {
9548 s1
->error_set_jmp_enabled
= 1;
9550 ch
= file
->buf_ptr
[0];
9551 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
9552 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
;
9556 expect("declaration");
9558 /* end of translation unit info */
9560 put_stabs_r(NULL
, N_SO
, 0, 0,
9561 text_section
->data_offset
, text_section
, section_sym
);
9564 s1
->error_set_jmp_enabled
= 0;
9566 /* reset define stack, but leave -Dsymbols (may be incorrect if
9567 they are undefined) */
9568 free_defines(define_start
);
9570 gen_inline_functions();
9572 sym_pop(&global_stack
, NULL
);
9574 return s1
->nb_errors
!= 0 ? -1 : 0;
9577 /* Preprocess the current file */
9578 /* XXX: add line and file infos, add options to preserve spaces */
9579 static int tcc_preprocess(TCCState
*s1
)
9584 preprocess_init(s1
);
9586 define_start
= define_stack
;
9588 ch
= file
->buf_ptr
[0];
9589 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
9590 parse_flags
= PARSE_FLAG_ASM_COMMENTS
| PARSE_FLAG_PREPROCESS
|
9591 PARSE_FLAG_LINEFEED
;
9595 if (tok
== TOK_EOF
) {
9597 } else if (tok
== TOK_LINEFEED
) {
9601 fputc(' ', s1
->outfile
);
9604 fputs(get_tok_str(tok
, &tokc
), s1
->outfile
);
9607 free_defines(define_start
);
9612 int tcc_compile_string(TCCState
*s
, const char *str
)
9614 BufferedFile bf1
, *bf
= &bf1
;
9618 /* init file structure */
9620 /* XXX: avoid copying */
9622 buf
= tcc_malloc(len
+ 1);
9625 memcpy(buf
, str
, len
);
9628 bf
->buf_end
= buf
+ len
;
9629 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
9633 ret
= tcc_compile(s
);
9637 /* currently, no need to close */
9642 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
9643 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
9645 BufferedFile bf1
, *bf
= &bf1
;
9647 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
9648 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
9652 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
9654 /* init file structure */
9656 bf
->buf_ptr
= bf
->buffer
;
9657 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
9658 *bf
->buf_end
= CH_EOB
;
9659 bf
->filename
[0] = '\0';
9663 s1
->include_stack_ptr
= s1
->include_stack
;
9665 /* parse with define parser */
9666 ch
= file
->buf_ptr
[0];
9672 /* undefine a preprocessor symbol */
9673 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
9677 ts
= tok_alloc(sym
, strlen(sym
));
9678 s
= define_find(ts
->tok
);
9679 /* undefine symbol by putting an invalid name */
9684 #ifdef CONFIG_TCC_ASM
9686 #ifdef TCC_TARGET_I386
9687 #include "i386-asm.c"
9692 static void asm_instr(void)
9694 error("inline asm() not supported");
9696 static void asm_global_instr(void)
9698 error("inline asm() not supported");
9704 #ifdef TCC_TARGET_COFF
9705 #include "tcccoff.c"
9708 #ifdef TCC_TARGET_PE
9712 /* print the position in the source file of PC value 'pc' by reading
9713 the stabs debug information */
9714 static void rt_printline(unsigned long wanted_pc
)
9716 Stab_Sym
*sym
, *sym_end
;
9717 char func_name
[128], last_func_name
[128];
9718 unsigned long func_addr
, last_pc
, pc
;
9719 const char *incl_files
[INCLUDE_STACK_SIZE
];
9720 int incl_index
, len
, last_line_num
, i
;
9721 const char *str
, *p
;
9723 fprintf(stderr
, "0x%08lx:", wanted_pc
);
9725 func_name
[0] = '\0';
9728 last_func_name
[0] = '\0';
9729 last_pc
= 0xffffffff;
9731 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
9732 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
9733 while (sym
< sym_end
) {
9734 switch(sym
->n_type
) {
9735 /* function start or end */
9737 if (sym
->n_strx
== 0) {
9738 /* we test if between last line and end of function */
9739 pc
= sym
->n_value
+ func_addr
;
9740 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9742 func_name
[0] = '\0';
9745 str
= stabstr_section
->data
+ sym
->n_strx
;
9746 p
= strchr(str
, ':');
9748 pstrcpy(func_name
, sizeof(func_name
), str
);
9751 if (len
> sizeof(func_name
) - 1)
9752 len
= sizeof(func_name
) - 1;
9753 memcpy(func_name
, str
, len
);
9754 func_name
[len
] = '\0';
9756 func_addr
= sym
->n_value
;
9759 /* line number info */
9761 pc
= sym
->n_value
+ func_addr
;
9762 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9765 last_line_num
= sym
->n_desc
;
9767 strcpy(last_func_name
, func_name
);
9771 str
= stabstr_section
->data
+ sym
->n_strx
;
9773 if (incl_index
< INCLUDE_STACK_SIZE
) {
9774 incl_files
[incl_index
++] = str
;
9782 if (sym
->n_strx
== 0) {
9783 incl_index
= 0; /* end of translation unit */
9785 str
= stabstr_section
->data
+ sym
->n_strx
;
9786 /* do not add path */
9788 if (len
> 0 && str
[len
- 1] != '/')
9796 /* second pass: we try symtab symbols (no line number info) */
9799 Elf32_Sym
*sym
, *sym_end
;
9802 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
9803 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
9806 type
= ELF32_ST_TYPE(sym
->st_info
);
9807 if (type
== STT_FUNC
) {
9808 if (wanted_pc
>= sym
->st_value
&&
9809 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
9810 pstrcpy(last_func_name
, sizeof(last_func_name
),
9811 strtab_section
->data
+ sym
->st_name
);
9817 /* did not find any info: */
9818 fprintf(stderr
, " ???\n");
9821 if (last_func_name
[0] != '\0') {
9822 fprintf(stderr
, " %s()", last_func_name
);
9824 if (incl_index
> 0) {
9825 fprintf(stderr
, " (%s:%d",
9826 incl_files
[incl_index
- 1], last_line_num
);
9827 for(i
= incl_index
- 2; i
>= 0; i
--)
9828 fprintf(stderr
, ", included from %s", incl_files
[i
]);
9829 fprintf(stderr
, ")");
9831 fprintf(stderr
, "\n");
9834 #if !defined(_WIN32) && !defined(CONFIG_TCCBOOT)
9838 /* fix for glibc 2.1 */
9844 /* return the PC at frame level 'level'. Return non zero if not found */
9845 static int rt_get_caller_pc(unsigned long *paddr
,
9846 ucontext_t
*uc
, int level
)
9852 #if defined(__FreeBSD__)
9853 *paddr
= uc
->uc_mcontext
.mc_eip
;
9854 #elif defined(__dietlibc__)
9855 *paddr
= uc
->uc_mcontext
.eip
;
9857 *paddr
= uc
->uc_mcontext
.gregs
[REG_EIP
];
9861 #if defined(__FreeBSD__)
9862 fp
= uc
->uc_mcontext
.mc_ebp
;
9863 #elif defined(__dietlibc__)
9864 fp
= uc
->uc_mcontext
.ebp
;
9866 fp
= uc
->uc_mcontext
.gregs
[REG_EBP
];
9868 for(i
=1;i
<level
;i
++) {
9869 /* XXX: check address validity with program info */
9870 if (fp
<= 0x1000 || fp
>= 0xc0000000)
9872 fp
= ((unsigned long *)fp
)[0];
9874 *paddr
= ((unsigned long *)fp
)[1];
9880 #warning add arch specific rt_get_caller_pc()
9882 static int rt_get_caller_pc(unsigned long *paddr
,
9883 ucontext_t
*uc
, int level
)
9889 /* emit a run time error at position 'pc' */
9890 void rt_error(ucontext_t
*uc
, const char *fmt
, ...)
9897 fprintf(stderr
, "Runtime error: ");
9898 vfprintf(stderr
, fmt
, ap
);
9899 fprintf(stderr
, "\n");
9900 for(i
=0;i
<num_callers
;i
++) {
9901 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
9904 fprintf(stderr
, "at ");
9906 fprintf(stderr
, "by ");
9913 /* signal handler for fatal errors */
9914 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
9916 ucontext_t
*uc
= puc
;
9920 switch(siginf
->si_code
) {
9923 rt_error(uc
, "division by zero");
9926 rt_error(uc
, "floating point exception");
9932 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
9933 rt_error(uc
, *rt_bound_error_msg
);
9935 rt_error(uc
, "dereferencing invalid pointer");
9938 rt_error(uc
, "illegal instruction");
9941 rt_error(uc
, "abort() called");
9944 rt_error(uc
, "caught signal %d", signum
);
9951 /* do all relocations (needed before using tcc_get_symbol()) */
9952 int tcc_relocate(TCCState
*s1
)
9959 #ifdef TCC_TARGET_PE
9962 tcc_add_runtime(s1
);
9965 relocate_common_syms();
9967 tcc_add_linker_symbols(s1
);
9968 #ifndef TCC_TARGET_PE
9969 build_got_entries(s1
);
9971 /* compute relocation address : section are relocated in place. We
9972 also alloc the bss space */
9973 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9974 s
= s1
->sections
[i
];
9975 if (s
->sh_flags
& SHF_ALLOC
) {
9976 if (s
->sh_type
== SHT_NOBITS
)
9977 s
->data
= tcc_mallocz(s
->data_offset
);
9978 s
->sh_addr
= (unsigned long)s
->data
;
9982 relocate_syms(s1
, 1);
9984 if (s1
->nb_errors
!= 0)
9987 /* relocate each section */
9988 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9989 s
= s1
->sections
[i
];
9991 relocate_section(s1
, s
);
9994 /* mark executable sections as executable in memory */
9995 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9996 s
= s1
->sections
[i
];
9997 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_EXECINSTR
)) ==
9998 (SHF_ALLOC
| SHF_EXECINSTR
))
9999 set_pages_executable(s
->data
, s
->data_offset
);
10004 /* launch the compiled program with the given arguments */
10005 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
10007 int (*prog_main
)(int, char **);
10009 if (tcc_relocate(s1
) < 0)
10012 prog_main
= tcc_get_symbol_err(s1
, "main");
10015 #if defined(_WIN32) || defined(CONFIG_TCCBOOT)
10016 error("debug mode currently not available for Windows");
10018 struct sigaction sigact
;
10019 /* install TCC signal handlers to print debug info on fatal
10021 sigact
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
10022 sigact
.sa_sigaction
= sig_error
;
10023 sigemptyset(&sigact
.sa_mask
);
10024 sigaction(SIGFPE
, &sigact
, NULL
);
10025 sigaction(SIGILL
, &sigact
, NULL
);
10026 sigaction(SIGSEGV
, &sigact
, NULL
);
10027 sigaction(SIGBUS
, &sigact
, NULL
);
10028 sigaction(SIGABRT
, &sigact
, NULL
);
10032 #ifdef CONFIG_TCC_BCHECK
10033 if (do_bounds_check
) {
10034 void (*bound_init
)(void);
10036 /* set error function */
10037 rt_bound_error_msg
= (void *)tcc_get_symbol_err(s1
,
10038 "__bound_error_msg");
10040 /* XXX: use .init section so that it also work in binary ? */
10041 bound_init
= (void *)tcc_get_symbol_err(s1
, "__bound_init");
10045 return (*prog_main
)(argc
, argv
);
10048 TCCState
*tcc_new(void)
10055 s
= tcc_mallocz(sizeof(TCCState
));
10059 s
->output_type
= TCC_OUTPUT_MEMORY
;
10061 /* init isid table */
10063 isidnum_table
[i
] = isid(i
) || isnum(i
);
10065 /* add all tokens */
10066 table_ident
= NULL
;
10067 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
10069 tok_ident
= TOK_IDENT
;
10078 ts
= tok_alloc(p
, r
- p
- 1);
10082 /* we add dummy defines for some special macros to speed up tests
10083 and to have working defined() */
10084 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
10085 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
10086 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
10087 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
10089 /* standard defines */
10090 tcc_define_symbol(s
, "__STDC__", NULL
);
10091 tcc_define_symbol(s
, "__STDC_VERSION__", "199901L");
10092 #if defined(TCC_TARGET_I386)
10093 tcc_define_symbol(s
, "__i386__", NULL
);
10095 #if defined(TCC_TARGET_ARM)
10096 tcc_define_symbol(s
, "__ARM_ARCH_4__", NULL
);
10097 tcc_define_symbol(s
, "__arm_elf__", NULL
);
10098 tcc_define_symbol(s
, "__arm_elf", NULL
);
10099 tcc_define_symbol(s
, "arm_elf", NULL
);
10100 tcc_define_symbol(s
, "__arm__", NULL
);
10101 tcc_define_symbol(s
, "__arm", NULL
);
10102 tcc_define_symbol(s
, "arm", NULL
);
10103 tcc_define_symbol(s
, "__APCS_32__", NULL
);
10105 #ifdef TCC_TARGET_PE
10106 tcc_define_symbol(s
, "_WIN32", NULL
);
10108 tcc_define_symbol(s
, "__unix__", NULL
);
10109 tcc_define_symbol(s
, "__unix", NULL
);
10110 #if defined(__linux)
10111 tcc_define_symbol(s
, "__linux__", NULL
);
10112 tcc_define_symbol(s
, "__linux", NULL
);
10115 /* tiny C specific defines */
10116 tcc_define_symbol(s
, "__TINYC__", NULL
);
10118 /* tiny C & gcc defines */
10119 tcc_define_symbol(s
, "__SIZE_TYPE__", "unsigned int");
10120 tcc_define_symbol(s
, "__PTRDIFF_TYPE__", "int");
10121 #ifdef TCC_TARGET_PE
10122 tcc_define_symbol(s
, "__WCHAR_TYPE__", "unsigned short");
10124 tcc_define_symbol(s
, "__WCHAR_TYPE__", "int");
10127 /* default library paths */
10128 #ifdef TCC_TARGET_PE
10131 snprintf(buf
, sizeof(buf
), "%s/lib", tcc_lib_path
);
10132 tcc_add_library_path(s
, buf
);
10135 tcc_add_library_path(s
, "/usr/local/lib");
10136 tcc_add_library_path(s
, "/usr/lib");
10137 tcc_add_library_path(s
, "/lib");
10140 /* no section zero */
10141 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
10143 /* create standard sections */
10144 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
10145 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
10146 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
10148 /* symbols are always generated for linking stage */
10149 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
10151 ".hashtab", SHF_PRIVATE
);
10152 strtab_section
= symtab_section
->link
;
10154 /* private symbol table for dynamic symbols */
10155 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
10157 ".dynhashtab", SHF_PRIVATE
);
10158 s
->alacarte_link
= 1;
10160 #ifdef CHAR_IS_UNSIGNED
10161 s
->char_is_unsigned
= 1;
10163 #if defined(TCC_TARGET_PE) && 0
10164 /* XXX: currently the PE linker is not ready to support that */
10165 s
->leading_underscore
= 1;
10170 void tcc_delete(TCCState
*s1
)
10174 /* free -D defines */
10175 free_defines(NULL
);
10178 n
= tok_ident
- TOK_IDENT
;
10179 for(i
= 0; i
< n
; i
++)
10180 tcc_free(table_ident
[i
]);
10181 tcc_free(table_ident
);
10183 /* free all sections */
10185 free_section(symtab_section
->hash
);
10187 free_section(s1
->dynsymtab_section
->hash
);
10188 free_section(s1
->dynsymtab_section
->link
);
10189 free_section(s1
->dynsymtab_section
);
10191 for(i
= 1; i
< s1
->nb_sections
; i
++)
10192 free_section(s1
->sections
[i
]);
10193 tcc_free(s1
->sections
);
10195 /* free loaded dlls array */
10196 dynarray_reset(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
);
10198 /* free library paths */
10199 dynarray_reset(&s1
->library_paths
, &s1
->nb_library_paths
);
10201 /* free include paths */
10202 dynarray_reset(&s1
->cached_includes
, &s1
->nb_cached_includes
);
10203 dynarray_reset(&s1
->include_paths
, &s1
->nb_include_paths
);
10204 dynarray_reset(&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
);
10209 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
10213 pathname1
= tcc_strdup(pathname
);
10214 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
10218 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
10222 pathname1
= tcc_strdup(pathname
);
10223 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
10227 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
10232 BufferedFile
*saved_file
;
10234 /* find source file type with extension */
10235 ext
= tcc_fileextension(filename
);
10239 /* open the file */
10241 file
= tcc_open(s1
, filename
);
10243 if (flags
& AFF_PRINT_ERROR
) {
10244 error_noabort("file '%s' not found", filename
);
10250 if (flags
& AFF_PREPROCESS
) {
10251 ret
= tcc_preprocess(s1
);
10252 } else if (!ext
[0] || !strcmp(ext
, "c")) {
10253 /* C file assumed */
10254 ret
= tcc_compile(s1
);
10256 #ifdef CONFIG_TCC_ASM
10257 if (!strcmp(ext
, "S")) {
10258 /* preprocessed assembler */
10259 ret
= tcc_assemble(s1
, 1);
10260 } else if (!strcmp(ext
, "s")) {
10261 /* non preprocessed assembler */
10262 ret
= tcc_assemble(s1
, 0);
10265 #ifdef TCC_TARGET_PE
10266 if (!strcmp(ext
, "def")) {
10267 ret
= pe_load_def_file(s1
, file
->fd
);
10272 /* assume executable format: auto guess file type */
10273 ret
= read(fd
, &ehdr
, sizeof(ehdr
));
10274 lseek(fd
, 0, SEEK_SET
);
10276 error_noabort("could not read header");
10278 } else if (ret
!= sizeof(ehdr
)) {
10279 goto try_load_script
;
10282 if (ehdr
.e_ident
[0] == ELFMAG0
&&
10283 ehdr
.e_ident
[1] == ELFMAG1
&&
10284 ehdr
.e_ident
[2] == ELFMAG2
&&
10285 ehdr
.e_ident
[3] == ELFMAG3
) {
10286 file
->line_num
= 0; /* do not display line number if error */
10287 if (ehdr
.e_type
== ET_REL
) {
10288 ret
= tcc_load_object_file(s1
, fd
, 0);
10289 } else if (ehdr
.e_type
== ET_DYN
) {
10290 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
10291 #ifdef TCC_TARGET_PE
10295 h
= dlopen(filename
, RTLD_GLOBAL
| RTLD_LAZY
);
10302 ret
= tcc_load_dll(s1
, fd
, filename
,
10303 (flags
& AFF_REFERENCED_DLL
) != 0);
10306 error_noabort("unrecognized ELF file");
10309 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
10310 file
->line_num
= 0; /* do not display line number if error */
10311 ret
= tcc_load_archive(s1
, fd
);
10313 #ifdef TCC_TARGET_COFF
10314 if (*(uint16_t *)(&ehdr
) == COFF_C67_MAGIC
) {
10315 ret
= tcc_load_coff(s1
, fd
);
10318 #ifdef TCC_TARGET_PE
10319 if (pe_test_res_file(&ehdr
, ret
)) {
10320 ret
= pe_load_res_file(s1
, fd
);
10324 /* as GNU ld, consider it is an ld script if not recognized */
10326 ret
= tcc_load_ldscript(s1
);
10328 error_noabort("unrecognized file type");
10343 int tcc_add_file(TCCState
*s
, const char *filename
)
10345 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
10348 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
10352 pathname1
= tcc_strdup(pathname
);
10353 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
10357 /* find and load a dll. Return non zero if not found */
10358 /* XXX: add '-rpath' option support ? */
10359 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
10364 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
10365 snprintf(buf
, sizeof(buf
), "%s/%s",
10366 s
->library_paths
[i
], filename
);
10367 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
10373 /* the library name is the same as the argument of the '-l' option */
10374 int tcc_add_library(TCCState
*s
, const char *libraryname
)
10379 /* first we look for the dynamic library if not static linking */
10380 if (!s
->static_link
) {
10381 #ifdef TCC_TARGET_PE
10382 snprintf(buf
, sizeof(buf
), "%s.def", libraryname
);
10384 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
10386 if (tcc_add_dll(s
, buf
, 0) == 0)
10390 /* then we look for the static library */
10391 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
10392 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
10393 s
->library_paths
[i
], libraryname
);
10394 if (tcc_add_file_internal(s
, buf
, 0) == 0)
10400 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
10402 add_elf_sym(symtab_section
, val
, 0,
10403 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
), 0,
10408 int tcc_set_output_type(TCCState
*s
, int output_type
)
10410 s
->output_type
= output_type
;
10412 if (!s
->nostdinc
) {
10415 /* default include paths */
10416 /* XXX: reverse order needed if -isystem support */
10417 #ifndef TCC_TARGET_PE
10418 tcc_add_sysinclude_path(s
, "/usr/local/include");
10419 tcc_add_sysinclude_path(s
, "/usr/include");
10421 snprintf(buf
, sizeof(buf
), "%s/include", tcc_lib_path
);
10422 tcc_add_sysinclude_path(s
, buf
);
10423 #ifdef TCC_TARGET_PE
10424 snprintf(buf
, sizeof(buf
), "%s/include/winapi", tcc_lib_path
);
10425 tcc_add_sysinclude_path(s
, buf
);
10429 /* if bound checking, then add corresponding sections */
10430 #ifdef CONFIG_TCC_BCHECK
10431 if (do_bounds_check
) {
10432 /* define symbol */
10433 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
10434 /* create bounds sections */
10435 bounds_section
= new_section(s
, ".bounds",
10436 SHT_PROGBITS
, SHF_ALLOC
);
10437 lbounds_section
= new_section(s
, ".lbounds",
10438 SHT_PROGBITS
, SHF_ALLOC
);
10442 if (s
->char_is_unsigned
) {
10443 tcc_define_symbol(s
, "__CHAR_UNSIGNED__", NULL
);
10446 /* add debug sections */
10449 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
10450 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
10451 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
10452 put_elf_str(stabstr_section
, "");
10453 stab_section
->link
= stabstr_section
;
10454 /* put first entry */
10455 put_stabs("", 0, 0, 0, 0);
10458 /* add libc crt1/crti objects */
10459 #ifndef TCC_TARGET_PE
10460 if ((output_type
== TCC_OUTPUT_EXE
|| output_type
== TCC_OUTPUT_DLL
) &&
10462 if (output_type
!= TCC_OUTPUT_DLL
)
10463 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
10464 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
10470 #define WD_ALL 0x0001 /* warning is activated when using -Wall */
10471 #define FD_INVERT 0x0002 /* invert value before storing */
10473 typedef struct FlagDef
{
10479 static const FlagDef warning_defs
[] = {
10480 { offsetof(TCCState
, warn_unsupported
), 0, "unsupported" },
10481 { offsetof(TCCState
, warn_write_strings
), 0, "write-strings" },
10482 { offsetof(TCCState
, warn_error
), 0, "error" },
10483 { offsetof(TCCState
, warn_implicit_function_declaration
), WD_ALL
,
10484 "implicit-function-declaration" },
10487 static int set_flag(TCCState
*s
, const FlagDef
*flags
, int nb_flags
,
10488 const char *name
, int value
)
10495 if (r
[0] == 'n' && r
[1] == 'o' && r
[2] == '-') {
10499 for(i
= 0, p
= flags
; i
< nb_flags
; i
++, p
++) {
10500 if (!strcmp(r
, p
->name
))
10505 if (p
->flags
& FD_INVERT
)
10507 *(int *)((uint8_t *)s
+ p
->offset
) = value
;
10512 /* set/reset a warning */
10513 int tcc_set_warning(TCCState
*s
, const char *warning_name
, int value
)
10518 if (!strcmp(warning_name
, "all")) {
10519 for(i
= 0, p
= warning_defs
; i
< countof(warning_defs
); i
++, p
++) {
10520 if (p
->flags
& WD_ALL
)
10521 *(int *)((uint8_t *)s
+ p
->offset
) = 1;
10525 return set_flag(s
, warning_defs
, countof(warning_defs
),
10526 warning_name
, value
);
10530 static const FlagDef flag_defs
[] = {
10531 { offsetof(TCCState
, char_is_unsigned
), 0, "unsigned-char" },
10532 { offsetof(TCCState
, char_is_unsigned
), FD_INVERT
, "signed-char" },
10533 { offsetof(TCCState
, nocommon
), FD_INVERT
, "common" },
10534 { offsetof(TCCState
, leading_underscore
), 0, "leading-underscore" },
10537 /* set/reset a flag */
10538 int tcc_set_flag(TCCState
*s
, const char *flag_name
, int value
)
10540 return set_flag(s
, flag_defs
, countof(flag_defs
),
10544 #if !defined(LIBTCC)
10546 static int64_t getclock_us(void)
10551 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
10554 gettimeofday(&tv
, NULL
);
10555 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
10561 printf("tcc version " TCC_VERSION
" - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n"
10562 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
10563 " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
10564 " [infile1 infile2...] [-run infile args...]\n"
10566 "General options:\n"
10567 " -v display current version\n"
10568 " -c compile only - generate an object file\n"
10569 " -o outfile set output filename\n"
10570 " -Bdir set tcc internal library path\n"
10571 " -bench output compilation statistics\n"
10572 " -run run compiled source\n"
10573 " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
10574 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
10575 " -w disable all warnings\n"
10576 "Preprocessor options:\n"
10577 " -E preprocess only\n"
10578 " -Idir add include path 'dir'\n"
10579 " -Dsym[=val] define 'sym' with value 'val'\n"
10580 " -Usym undefine 'sym'\n"
10581 "Linker options:\n"
10582 " -Ldir add library path 'dir'\n"
10583 " -llib link with dynamic or static library 'lib'\n"
10584 " -shared generate a shared library\n"
10585 " -static static linking\n"
10586 " -rdynamic export all global symbols to dynamic linker\n"
10587 " -r generate (relocatable) object file\n"
10588 "Debugger options:\n"
10589 " -g generate runtime debug info\n"
10590 #ifdef CONFIG_TCC_BCHECK
10591 " -b compile with built-in memory and bounds checker (implies -g)\n"
10593 " -bt N show N callers in stack traces\n"
10597 #define TCC_OPTION_HAS_ARG 0x0001
10598 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
10600 typedef struct TCCOption
{
10628 TCC_OPTION_nostdinc
,
10629 TCC_OPTION_nostdlib
,
10630 TCC_OPTION_print_search_dirs
,
10631 TCC_OPTION_rdynamic
,
10639 static const TCCOption tcc_options
[] = {
10640 { "h", TCC_OPTION_HELP
, 0 },
10641 { "?", TCC_OPTION_HELP
, 0 },
10642 { "I", TCC_OPTION_I
, TCC_OPTION_HAS_ARG
},
10643 { "D", TCC_OPTION_D
, TCC_OPTION_HAS_ARG
},
10644 { "U", TCC_OPTION_U
, TCC_OPTION_HAS_ARG
},
10645 { "L", TCC_OPTION_L
, TCC_OPTION_HAS_ARG
},
10646 { "B", TCC_OPTION_B
, TCC_OPTION_HAS_ARG
},
10647 { "l", TCC_OPTION_l
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10648 { "bench", TCC_OPTION_bench
, 0 },
10649 { "bt", TCC_OPTION_bt
, TCC_OPTION_HAS_ARG
},
10650 #ifdef CONFIG_TCC_BCHECK
10651 { "b", TCC_OPTION_b
, 0 },
10653 { "g", TCC_OPTION_g
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10654 { "c", TCC_OPTION_c
, 0 },
10655 { "static", TCC_OPTION_static
, 0 },
10656 { "shared", TCC_OPTION_shared
, 0 },
10657 { "o", TCC_OPTION_o
, TCC_OPTION_HAS_ARG
},
10658 { "run", TCC_OPTION_run
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10659 { "rdynamic", TCC_OPTION_rdynamic
, 0 },
10660 { "r", TCC_OPTION_r
, 0 },
10661 { "Wl,", TCC_OPTION_Wl
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10662 { "W", TCC_OPTION_W
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10663 { "O", TCC_OPTION_O
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10664 { "m", TCC_OPTION_m
, TCC_OPTION_HAS_ARG
},
10665 { "f", TCC_OPTION_f
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10666 { "nostdinc", TCC_OPTION_nostdinc
, 0 },
10667 { "nostdlib", TCC_OPTION_nostdlib
, 0 },
10668 { "print-search-dirs", TCC_OPTION_print_search_dirs
, 0 },
10669 { "v", TCC_OPTION_v
, 0 },
10670 { "w", TCC_OPTION_w
, 0 },
10671 { "pipe", TCC_OPTION_pipe
, 0},
10672 { "E", TCC_OPTION_E
, 0},
10676 /* convert 'str' into an array of space separated strings */
10677 static int expand_args(char ***pargv
, const char *str
)
10686 while (is_space(*str
))
10691 while (*str
!= '\0' && !is_space(*str
))
10694 arg
= tcc_malloc(len
+ 1);
10695 memcpy(arg
, s1
, len
);
10697 dynarray_add((void ***)&argv
, &argc
, arg
);
10703 static char **files
;
10704 static int nb_files
, nb_libraries
;
10705 static int multiple_files
;
10706 static int print_search_dirs
;
10707 static int output_type
;
10708 static int reloc_output
;
10709 static const char *outfile
;
10711 int parse_args(TCCState
*s
, int argc
, char **argv
)
10714 const TCCOption
*popt
;
10715 const char *optarg
, *p1
, *r1
;
10720 if (optind
>= argc
) {
10721 if (nb_files
== 0 && !print_search_dirs
)
10726 r
= argv
[optind
++];
10728 /* add a new file */
10729 dynarray_add((void ***)&files
, &nb_files
, r
);
10730 if (!multiple_files
) {
10732 /* argv[0] will be this file */
10736 /* find option in table (match only the first chars */
10737 popt
= tcc_options
;
10741 error("invalid option -- '%s'", r
);
10754 if (popt
->flags
& TCC_OPTION_HAS_ARG
) {
10755 if (*r1
!= '\0' || (popt
->flags
& TCC_OPTION_NOSEP
)) {
10758 if (optind
>= argc
)
10759 error("argument to '%s' is missing", r
);
10760 optarg
= argv
[optind
++];
10768 switch(popt
->index
) {
10769 case TCC_OPTION_HELP
:
10774 if (tcc_add_include_path(s
, optarg
) < 0)
10775 error("too many include paths");
10780 sym
= (char *)optarg
;
10781 value
= strchr(sym
, '=');
10786 tcc_define_symbol(s
, sym
, value
);
10790 tcc_undefine_symbol(s
, optarg
);
10793 tcc_add_library_path(s
, optarg
);
10796 /* set tcc utilities path (mainly for tcc development) */
10797 tcc_lib_path
= optarg
;
10800 dynarray_add((void ***)&files
, &nb_files
, r
);
10803 case TCC_OPTION_bench
:
10806 case TCC_OPTION_bt
:
10807 num_callers
= atoi(optarg
);
10809 #ifdef CONFIG_TCC_BCHECK
10811 do_bounds_check
= 1;
10819 multiple_files
= 1;
10820 output_type
= TCC_OUTPUT_OBJ
;
10822 case TCC_OPTION_static
:
10823 s
->static_link
= 1;
10825 case TCC_OPTION_shared
:
10826 output_type
= TCC_OUTPUT_DLL
;
10829 multiple_files
= 1;
10833 /* generate a .o merging several output files */
10835 output_type
= TCC_OUTPUT_OBJ
;
10837 case TCC_OPTION_nostdinc
:
10840 case TCC_OPTION_nostdlib
:
10843 case TCC_OPTION_print_search_dirs
:
10844 print_search_dirs
= 1;
10846 case TCC_OPTION_run
:
10850 argc1
= expand_args(&argv1
, optarg
);
10852 parse_args(s
, argc1
, argv1
);
10854 multiple_files
= 0;
10855 output_type
= TCC_OUTPUT_MEMORY
;
10859 printf("tcc version %s\n", TCC_VERSION
);
10862 if (tcc_set_flag(s
, optarg
, 1) < 0 && s
->warn_unsupported
)
10863 goto unsupported_option
;
10866 if (tcc_set_warning(s
, optarg
, 1) < 0 &&
10867 s
->warn_unsupported
)
10868 goto unsupported_option
;
10873 case TCC_OPTION_rdynamic
:
10876 case TCC_OPTION_Wl
:
10879 if (strstart(optarg
, "-Ttext,", &p
)) {
10880 s
->text_addr
= strtoul(p
, NULL
, 16);
10881 s
->has_text_addr
= 1;
10882 } else if (strstart(optarg
, "--oformat,", &p
)) {
10883 if (strstart(p
, "elf32-", NULL
)) {
10884 s
->output_format
= TCC_OUTPUT_FORMAT_ELF
;
10885 } else if (!strcmp(p
, "binary")) {
10886 s
->output_format
= TCC_OUTPUT_FORMAT_BINARY
;
10888 #ifdef TCC_TARGET_COFF
10889 if (!strcmp(p
, "coff")) {
10890 s
->output_format
= TCC_OUTPUT_FORMAT_COFF
;
10894 error("target %s not found", p
);
10897 error("unsupported linker option '%s'", optarg
);
10902 output_type
= TCC_OUTPUT_PREPROCESS
;
10905 if (s
->warn_unsupported
) {
10906 unsupported_option
:
10907 warning("unsupported option '%s'", r
);
10916 int main(int argc
, char **argv
)
10920 int nb_objfiles
, ret
, optind
;
10921 char objfilename
[1024];
10922 int64_t start_time
= 0;
10925 tcc_lib_path
= w32_tcc_lib_path();
10929 output_type
= TCC_OUTPUT_EXE
;
10931 multiple_files
= 1;
10936 print_search_dirs
= 0;
10939 optind
= parse_args(s
, argc
- 1, argv
+ 1) + 1;
10941 if (print_search_dirs
) {
10942 /* enough for Linux kernel */
10943 printf("install: %s/\n", tcc_lib_path
);
10947 nb_objfiles
= nb_files
- nb_libraries
;
10949 /* if outfile provided without other options, we output an
10951 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
10952 output_type
= TCC_OUTPUT_EXE
;
10954 /* check -c consistency : only single file handled. XXX: checks file type */
10955 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
10956 /* accepts only a single input file */
10957 if (nb_objfiles
!= 1)
10958 error("cannot specify multiple files with -c");
10959 if (nb_libraries
!= 0)
10960 error("cannot specify libraries with -c");
10964 if (output_type
== TCC_OUTPUT_PREPROCESS
) {
10966 s
->outfile
= stdout
;
10968 s
->outfile
= fopen(outfile
, "w");
10970 error("could not open '%s", outfile
);
10972 } else if (output_type
!= TCC_OUTPUT_MEMORY
) {
10974 /* compute default outfile name */
10976 pstrcpy(objfilename
, sizeof(objfilename
), tcc_basename(files
[0]));
10977 ext
= tcc_fileextension(objfilename
);
10978 #ifdef TCC_TARGET_PE
10979 if (output_type
== TCC_OUTPUT_DLL
)
10980 strcpy(ext
, ".dll");
10982 if (output_type
== TCC_OUTPUT_EXE
)
10983 strcpy(ext
, ".exe");
10986 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
&& *ext
)
10989 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
10990 outfile
= objfilename
;
10995 start_time
= getclock_us();
10998 tcc_set_output_type(s
, output_type
);
11000 /* compile or add each files or library */
11001 for(i
= 0; i
< nb_files
&& ret
== 0; i
++) {
11002 const char *filename
;
11004 filename
= files
[i
];
11005 if (output_type
== TCC_OUTPUT_PREPROCESS
) {
11006 if (tcc_add_file_internal(s
, filename
,
11007 AFF_PRINT_ERROR
| AFF_PREPROCESS
) < 0)
11009 } else if (filename
[0] == '-') {
11010 if (tcc_add_library(s
, filename
+ 2) < 0)
11011 error("cannot find %s", filename
);
11013 if (tcc_add_file(s
, filename
) < 0)
11018 /* free all files */
11026 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
11027 if (total_time
< 0.001)
11028 total_time
= 0.001;
11029 if (total_bytes
< 1)
11031 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
11032 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
11033 total_time
, (int)(total_lines
/ total_time
),
11034 total_bytes
/ total_time
/ 1000000.0);
11037 if (s
->output_type
== TCC_OUTPUT_PREPROCESS
) {
11039 fclose(s
->outfile
);
11040 } else if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
11041 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
11043 #ifdef TCC_TARGET_PE
11044 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
11045 ret
= pe_output_file(s
, outfile
);
11049 ret
= tcc_output_file(s
, outfile
) ? 1 : 0;
11052 /* XXX: cannot do it with bound checking because of the malloc hooks */
11053 if (!do_bounds_check
)
11058 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);