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
;
2337 } else if (c
== '\\') {
2338 ch
= file
->buf_ptr
[0];
2339 handle_stray_noerror();
2346 p
= parse_pp_string(p
, c
, NULL
);
2355 p
= parse_comment(p
);
2356 } else if (ch
== '/') {
2357 p
= parse_line_comment(p
);
2363 if (start_of_line
) {
2368 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
2370 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
2372 else if (tok
== TOK_ENDIF
)
2386 /* ParseState handling */
2388 /* XXX: currently, no include file info is stored. Thus, we cannot display
2389 accurate messages if the function or data definition spans multiple
2392 /* save current parse state in 's' */
2393 void save_parse_state(ParseState
*s
)
2395 s
->line_num
= file
->line_num
;
2396 s
->macro_ptr
= macro_ptr
;
2401 /* restore parse state from 's' */
2402 void restore_parse_state(ParseState
*s
)
2404 file
->line_num
= s
->line_num
;
2405 macro_ptr
= s
->macro_ptr
;
2410 /* return the number of additional 'ints' necessary to store the
2412 static inline int tok_ext_size(int t
)
2426 error("unsupported token");
2433 return LDOUBLE_SIZE
/ 4;
2439 /* token string handling */
2441 static inline void tok_str_new(TokenString
*s
)
2445 s
->allocated_len
= 0;
2446 s
->last_line_num
= -1;
2449 static void tok_str_free(int *str
)
2454 static int *tok_str_realloc(TokenString
*s
)
2458 if (s
->allocated_len
== 0) {
2461 len
= s
->allocated_len
* 2;
2463 str
= tcc_realloc(s
->str
, len
* sizeof(int));
2465 error("memory full");
2466 s
->allocated_len
= len
;
2471 static void tok_str_add(TokenString
*s
, int t
)
2477 if (len
>= s
->allocated_len
)
2478 str
= tok_str_realloc(s
);
2483 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
2490 /* allocate space for worst case */
2491 if (len
+ TOK_MAX_SIZE
> s
->allocated_len
)
2492 str
= tok_str_realloc(s
);
2501 str
[len
++] = cv
->tab
[0];
2510 nb_words
= (sizeof(CString
) + cv
->cstr
->size
+ 3) >> 2;
2511 while ((len
+ nb_words
) > s
->allocated_len
)
2512 str
= tok_str_realloc(s
);
2513 cstr
= (CString
*)(str
+ len
);
2515 cstr
->size
= cv
->cstr
->size
;
2516 cstr
->data_allocated
= NULL
;
2517 cstr
->size_allocated
= cstr
->size
;
2518 memcpy((char *)cstr
+ sizeof(CString
),
2519 cv
->cstr
->data
, cstr
->size
);
2526 #if LDOUBLE_SIZE == 8
2529 str
[len
++] = cv
->tab
[0];
2530 str
[len
++] = cv
->tab
[1];
2532 #if LDOUBLE_SIZE == 12
2534 str
[len
++] = cv
->tab
[0];
2535 str
[len
++] = cv
->tab
[1];
2536 str
[len
++] = cv
->tab
[2];
2537 #elif LDOUBLE_SIZE != 8
2538 #error add long double size support
2547 /* add the current parse token in token string 's' */
2548 static void tok_str_add_tok(TokenString
*s
)
2552 /* save line number info */
2553 if (file
->line_num
!= s
->last_line_num
) {
2554 s
->last_line_num
= file
->line_num
;
2555 cval
.i
= s
->last_line_num
;
2556 tok_str_add2(s
, TOK_LINENUM
, &cval
);
2558 tok_str_add2(s
, tok
, &tokc
);
2561 #if LDOUBLE_SIZE == 12
2562 #define LDOUBLE_GET(p, cv) \
2566 #elif LDOUBLE_SIZE == 8
2567 #define LDOUBLE_GET(p, cv) \
2571 #error add long double size support
2575 /* get a token from an integer array and increment pointer
2576 accordingly. we code it as a macro to avoid pointer aliasing. */
2577 #define TOK_GET(t, p, cv) \
2592 cv.cstr = (CString *)p; \
2593 cv.cstr->data = (char *)p + sizeof(CString);\
2594 p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\
2603 case TOK_CLDOUBLE: \
2604 LDOUBLE_GET(p, cv); \
2605 p += LDOUBLE_SIZE / 4; \
2612 /* defines handling */
2613 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
2617 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
2618 s
->next
= first_arg
;
2619 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
2622 /* undefined a define symbol. Its name is just set to zero */
2623 static void define_undef(Sym
*s
)
2627 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2628 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2632 static inline Sym
*define_find(int v
)
2635 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2637 return table_ident
[v
]->sym_define
;
2640 /* free define stack until top reaches 'b' */
2641 static void free_defines(Sym
*b
)
2649 /* do not free args or predefined defines */
2651 tok_str_free((int *)top
->c
);
2653 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2654 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2662 static Sym
*label_find(int v
)
2665 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2667 return table_ident
[v
]->sym_label
;
2670 static Sym
*label_push(Sym
**ptop
, int v
, int flags
)
2673 s
= sym_push2(ptop
, v
, 0, 0);
2675 ps
= &table_ident
[v
- TOK_IDENT
]->sym_label
;
2676 if (ptop
== &global_label_stack
) {
2677 /* modify the top most local identifier, so that
2678 sym_identifier will point to 's' when popped */
2680 ps
= &(*ps
)->prev_tok
;
2687 /* pop labels until element last is reached. Look if any labels are
2688 undefined. Define symbols if '&&label' was used. */
2689 static void label_pop(Sym
**ptop
, Sym
*slast
)
2692 for(s
= *ptop
; s
!= slast
; s
= s1
) {
2694 if (s
->r
== LABEL_DECLARED
) {
2695 warning("label '%s' declared but not used", get_tok_str(s
->v
, NULL
));
2696 } else if (s
->r
== LABEL_FORWARD
) {
2697 error("label '%s' used but not defined",
2698 get_tok_str(s
->v
, NULL
));
2701 /* define corresponding symbol. A size of
2703 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
2707 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= s
->prev_tok
;
2713 /* eval an expression for #if/#elif */
2714 static int expr_preprocess(void)
2720 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2721 next(); /* do macro subst */
2722 if (tok
== TOK_DEFINED
) {
2727 c
= define_find(tok
) != 0;
2732 } else if (tok
>= TOK_IDENT
) {
2733 /* if undefined macro */
2737 tok_str_add_tok(&str
);
2739 tok_str_add(&str
, -1); /* simulate end of file */
2740 tok_str_add(&str
, 0);
2741 /* now evaluate C constant expression */
2742 macro_ptr
= str
.str
;
2746 tok_str_free(str
.str
);
2750 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2751 static void tok_print(int *str
)
2757 TOK_GET(t
, str
, cval
);
2760 printf(" %s", get_tok_str(t
, &cval
));
2766 /* parse after #define */
2767 static void parse_define(void)
2769 Sym
*s
, *first
, **ps
;
2770 int v
, t
, varg
, is_vaargs
, c
;
2775 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2776 /* XXX: should check if same macro (ANSI) */
2779 /* '(' must be just after macro definition for MACRO_FUNC */
2780 c
= file
->buf_ptr
[0];
2782 c
= handle_stray1(file
->buf_ptr
);
2787 while (tok
!= ')') {
2791 if (varg
== TOK_DOTS
) {
2792 varg
= TOK___VA_ARGS__
;
2794 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2798 if (varg
< TOK_IDENT
)
2799 error("badly punctuated parameter list");
2800 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2811 /* EOF testing necessary for '-D' handling */
2812 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2813 tok_str_add2(&str
, tok
, &tokc
);
2816 tok_str_add(&str
, 0);
2818 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2821 define_push(v
, t
, str
.str
, first
);
2824 static inline int hash_cached_include(int type
, const char *filename
)
2826 const unsigned char *s
;
2830 h
= TOK_HASH_FUNC(h
, type
);
2833 h
= TOK_HASH_FUNC(h
, *s
);
2836 h
&= (CACHED_INCLUDES_HASH_SIZE
- 1);
2840 /* XXX: use a token or a hash table to accelerate matching ? */
2841 static CachedInclude
*search_cached_include(TCCState
*s1
,
2842 int type
, const char *filename
)
2846 h
= hash_cached_include(type
, filename
);
2847 i
= s1
->cached_includes_hash
[h
];
2851 e
= s1
->cached_includes
[i
- 1];
2852 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2859 static inline void add_cached_include(TCCState
*s1
, int type
,
2860 const char *filename
, int ifndef_macro
)
2865 if (search_cached_include(s1
, type
, filename
))
2868 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2870 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2874 strcpy(e
->filename
, filename
);
2875 e
->ifndef_macro
= ifndef_macro
;
2876 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2877 /* add in hash table */
2878 h
= hash_cached_include(type
, filename
);
2879 e
->hash_next
= s1
->cached_includes_hash
[h
];
2880 s1
->cached_includes_hash
[h
] = s1
->nb_cached_includes
;
2883 static void pragma_parse(TCCState
*s1
)
2888 if (tok
== TOK_pack
) {
2891 #pragma pack(1) // set
2892 #pragma pack() // reset to default
2893 #pragma pack(push,1) // push & set
2894 #pragma pack(pop) // restore previous
2898 if (tok
== TOK_ASM_pop
) {
2900 if (s1
->pack_stack_ptr
<= s1
->pack_stack
) {
2902 error("out of pack stack");
2904 s1
->pack_stack_ptr
--;
2908 if (tok
== TOK_ASM_push
) {
2910 if (s1
->pack_stack_ptr
>= s1
->pack_stack
+ PACK_STACK_SIZE
- 1)
2912 s1
->pack_stack_ptr
++;
2915 if (tok
!= TOK_CINT
) {
2917 error("invalid pack pragma");
2920 if (val
< 1 || val
> 16 || (val
& (val
- 1)) != 0)
2924 *s1
->pack_stack_ptr
= val
;
2930 /* is_bof is true if first non space token at beginning of file */
2931 static void preprocess(int is_bof
)
2933 TCCState
*s1
= tcc_state
;
2934 int size
, i
, c
, n
, saved_parse_flags
;
2941 saved_parse_flags
= parse_flags
;
2942 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
|
2943 PARSE_FLAG_LINEFEED
;
2953 s
= define_find(tok
);
2954 /* undefine symbol by putting an invalid name */
2959 case TOK_INCLUDE_NEXT
:
2960 ch
= file
->buf_ptr
[0];
2961 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2966 } else if (ch
== '\"') {
2971 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2972 if ((q
- buf
) < sizeof(buf
) - 1)
2975 if (handle_stray_noerror() == 0)
2983 /* eat all spaces and comments after include */
2984 /* XXX: slightly incorrect */
2985 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2989 /* computed #include : either we have only strings or
2990 we have anything enclosed in '<>' */
2993 if (tok
== TOK_STR
) {
2994 while (tok
!= TOK_LINEFEED
) {
2995 if (tok
!= TOK_STR
) {
2997 error("'#include' expects \"FILENAME\" or <FILENAME>");
2999 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
3005 while (tok
!= TOK_LINEFEED
) {
3006 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
3010 /* check syntax and remove '<>' */
3011 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
3012 goto include_syntax
;
3013 memmove(buf
, buf
+ 1, len
- 2);
3014 buf
[len
- 2] = '\0';
3019 e
= search_cached_include(s1
, c
, buf
);
3020 if (e
&& define_find(e
->ifndef_macro
)) {
3021 /* no need to parse the include because the 'ifndef macro'
3024 printf("%s: skipping %s\n", file
->filename
, buf
);
3028 /* first search in current dir if "header.h" */
3029 size
= tcc_basename(file
->filename
) - file
->filename
;
3030 if (size
> sizeof(buf1
) - 1)
3031 size
= sizeof(buf1
) - 1;
3032 memcpy(buf1
, file
->filename
, size
);
3034 pstrcat(buf1
, sizeof(buf1
), buf
);
3035 f
= tcc_open(s1
, buf1
);
3037 if (tok
== TOK_INCLUDE_NEXT
)
3043 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
3044 error("#include recursion too deep");
3045 /* now search in all the include paths */
3046 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
3047 for(i
= 0; i
< n
; i
++) {
3049 if (i
< s1
->nb_include_paths
)
3050 path
= s1
->include_paths
[i
];
3052 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
3053 pstrcpy(buf1
, sizeof(buf1
), path
);
3054 pstrcat(buf1
, sizeof(buf1
), "/");
3055 pstrcat(buf1
, sizeof(buf1
), buf
);
3056 f
= tcc_open(s1
, buf1
);
3058 if (tok
== TOK_INCLUDE_NEXT
)
3064 error("include file '%s' not found", buf
);
3068 printf("%s: including %s\n", file
->filename
, buf1
);
3071 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
3072 /* push current file in stack */
3073 /* XXX: fix current line init */
3074 *s1
->include_stack_ptr
++ = file
;
3076 /* add include file debug info */
3078 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
3080 tok_flags
|= TOK_FLAG_BOF
| TOK_FLAG_BOL
;
3081 ch
= file
->buf_ptr
[0];
3089 c
= expr_preprocess();
3095 if (tok
< TOK_IDENT
)
3096 error("invalid argument for '#if%sdef'", c
? "n" : "");
3100 printf("#ifndef %s\n", get_tok_str(tok
, NULL
));
3102 file
->ifndef_macro
= tok
;
3105 c
= (define_find(tok
) != 0) ^ c
;
3107 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
3108 error("memory full");
3109 *s1
->ifdef_stack_ptr
++ = c
;
3112 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
3113 error("#else without matching #if");
3114 if (s1
->ifdef_stack_ptr
[-1] & 2)
3115 error("#else after #else");
3116 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
3119 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
3120 error("#elif without matching #if");
3121 c
= s1
->ifdef_stack_ptr
[-1];
3123 error("#elif after #else");
3124 /* last #if/#elif expression was true: we skip */
3127 c
= expr_preprocess();
3128 s1
->ifdef_stack_ptr
[-1] = c
;
3138 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
3139 error("#endif without matching #if");
3140 s1
->ifdef_stack_ptr
--;
3141 /* '#ifndef macro' was at the start of file. Now we check if
3142 an '#endif' is exactly at the end of file */
3143 if (file
->ifndef_macro
&&
3144 s1
->ifdef_stack_ptr
== file
->ifdef_stack_ptr
) {
3145 file
->ifndef_macro_saved
= file
->ifndef_macro
;
3146 /* need to set to zero to avoid false matches if another
3147 #ifndef at middle of file */
3148 file
->ifndef_macro
= 0;
3149 while (tok
!= TOK_LINEFEED
)
3151 tok_flags
|= TOK_FLAG_ENDIF
;
3157 if (tok
!= TOK_CINT
)
3159 file
->line_num
= tokc
.i
- 1; /* the line number will be incremented after */
3161 if (tok
!= TOK_LINEFEED
) {
3164 pstrcpy(file
->filename
, sizeof(file
->filename
),
3165 (char *)tokc
.cstr
->data
);
3171 ch
= file
->buf_ptr
[0];
3174 while (ch
!= '\n' && ch
!= CH_EOF
) {
3175 if ((q
- buf
) < sizeof(buf
) - 1)
3178 if (handle_stray_noerror() == 0)
3185 error("#error %s", buf
);
3187 warning("#warning %s", buf
);
3193 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
3194 /* '!' is ignored to allow C scripts. numbers are ignored
3195 to emulate cpp behaviour */
3197 if (!(saved_parse_flags
& PARSE_FLAG_ASM_COMMENTS
))
3198 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
3202 /* ignore other preprocess commands or #! for C scripts */
3203 while (tok
!= TOK_LINEFEED
)
3206 parse_flags
= saved_parse_flags
;
3209 /* evaluate escape codes in a string. */
3210 static void parse_escape_string(CString
*outstr
, const uint8_t *buf
, int is_long
)
3225 case '0': case '1': case '2': case '3':
3226 case '4': case '5': case '6': case '7':
3227 /* at most three octal digits */
3232 n
= n
* 8 + c
- '0';
3236 n
= n
* 8 + c
- '0';
3241 goto add_char_nonext
;
3249 if (c
>= 'a' && c
<= 'f')
3251 else if (c
>= 'A' && c
<= 'F')
3261 goto add_char_nonext
;
3285 goto invalid_escape
;
3295 if (c
>= '!' && c
<= '~')
3296 warning("unknown escape sequence: \'\\%c\'", c
);
3298 warning("unknown escape sequence: \'\\x%x\'", c
);
3305 cstr_ccat(outstr
, c
);
3307 cstr_wccat(outstr
, c
);
3309 /* add a trailing '\0' */
3311 cstr_ccat(outstr
, '\0');
3313 cstr_wccat(outstr
, '\0');
3316 /* we use 64 bit numbers */
3319 /* bn = (bn << shift) | or_val */
3320 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
3324 for(i
=0;i
<BN_SIZE
;i
++) {
3326 bn
[i
] = (v
<< shift
) | or_val
;
3327 or_val
= v
>> (32 - shift
);
3331 void bn_zero(unsigned int *bn
)
3334 for(i
=0;i
<BN_SIZE
;i
++) {
3339 /* parse number in null terminated string 'p' and return it in the
3341 void parse_number(const char *p
)
3343 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
3345 unsigned int bn
[BN_SIZE
];
3356 goto float_frac_parse
;
3357 } else if (t
== '0') {
3358 if (ch
== 'x' || ch
== 'X') {
3362 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
3368 /* parse all digits. cannot check octal numbers at this stage
3369 because of floating point constants */
3371 if (ch
>= 'a' && ch
<= 'f')
3373 else if (ch
>= 'A' && ch
<= 'F')
3381 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
3383 error("number too long");
3389 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
3390 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
3392 /* NOTE: strtox should support that for hexa numbers, but
3393 non ISOC99 libcs do not support it, so we prefer to do
3395 /* hexadecimal or binary floats */
3396 /* XXX: handle overflows */
3408 } else if (t
>= 'a') {
3410 } else if (t
>= 'A') {
3415 bn_lshift(bn
, shift
, t
);
3422 if (t
>= 'a' && t
<= 'f') {
3424 } else if (t
>= 'A' && t
<= 'F') {
3426 } else if (t
>= '0' && t
<= '9') {
3432 error("invalid digit");
3433 bn_lshift(bn
, shift
, t
);
3438 if (ch
!= 'p' && ch
!= 'P')
3445 } else if (ch
== '-') {
3449 if (ch
< '0' || ch
> '9')
3450 expect("exponent digits");
3451 while (ch
>= '0' && ch
<= '9') {
3452 exp_val
= exp_val
* 10 + ch
- '0';
3455 exp_val
= exp_val
* s
;
3457 /* now we can generate the number */
3458 /* XXX: should patch directly float number */
3459 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
3460 d
= ldexp(d
, exp_val
- frac_bits
);
3465 /* float : should handle overflow */
3467 } else if (t
== 'L') {
3470 /* XXX: not large enough */
3471 tokc
.ld
= (long double)d
;
3477 /* decimal floats */
3479 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3484 while (ch
>= '0' && ch
<= '9') {
3485 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3491 if (ch
== 'e' || ch
== 'E') {
3492 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3496 if (ch
== '-' || ch
== '+') {
3497 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3502 if (ch
< '0' || ch
> '9')
3503 expect("exponent digits");
3504 while (ch
>= '0' && ch
<= '9') {
3505 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3517 tokc
.f
= strtof(token_buf
, NULL
);
3518 } else if (t
== 'L') {
3521 tokc
.ld
= strtold(token_buf
, NULL
);
3524 tokc
.d
= strtod(token_buf
, NULL
);
3528 unsigned long long n
, n1
;
3531 /* integer number */
3534 if (b
== 10 && *q
== '0') {
3541 /* no need for checks except for base 10 / 8 errors */
3544 } else if (t
>= 'a') {
3546 } else if (t
>= 'A') {
3551 error("invalid digit");
3555 /* detect overflow */
3556 /* XXX: this test is not reliable */
3558 error("integer constant overflow");
3561 /* XXX: not exactly ANSI compliant */
3562 if ((n
& 0xffffffff00000000LL
) != 0) {
3567 } else if (n
> 0x7fffffff) {
3578 error("three 'l's in integer constant");
3581 if (tok
== TOK_CINT
)
3583 else if (tok
== TOK_CUINT
)
3587 } else if (t
== 'U') {
3589 error("two 'u's in integer constant");
3591 if (tok
== TOK_CINT
)
3593 else if (tok
== TOK_CLLONG
)
3600 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
3608 #define PARSE2(c1, tok1, c2, tok2) \
3619 /* return next token without macro substitution */
3620 static inline void next_nomacro1(void)
3640 /* first look if it is in fact an end of buffer */
3641 if (p
>= file
->buf_end
) {
3645 if (p
>= file
->buf_end
)
3658 TCCState
*s1
= tcc_state
;
3659 if ((parse_flags
& PARSE_FLAG_LINEFEED
)
3660 && !(tok_flags
& TOK_FLAG_EOF
)) {
3661 tok_flags
|= TOK_FLAG_EOF
;
3663 goto keep_tok_flags
;
3664 } else if (s1
->include_stack_ptr
== s1
->include_stack
||
3665 !(parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3666 /* no include left : end of file. */
3669 tok_flags
&= ~TOK_FLAG_EOF
;
3670 /* pop include file */
3672 /* test if previous '#endif' was after a #ifdef at
3674 if (tok_flags
& TOK_FLAG_ENDIF
) {
3676 printf("#endif %s\n", get_tok_str(file
->ifndef_macro_saved
, NULL
));
3678 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
3679 file
->ifndef_macro_saved
);
3682 /* add end of include file debug info */
3684 put_stabd(N_EINCL
, 0, 0);
3686 /* pop include stack */
3688 s1
->include_stack_ptr
--;
3689 file
= *s1
->include_stack_ptr
;
3698 tok_flags
|= TOK_FLAG_BOL
;
3700 if (0 == (parse_flags
& PARSE_FLAG_LINEFEED
))
3703 goto keep_tok_flags
;
3708 if ((tok_flags
& TOK_FLAG_BOL
) &&
3709 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3711 preprocess(tok_flags
& TOK_FLAG_BOF
);
3717 tok
= TOK_TWOSHARPS
;
3719 if (parse_flags
& PARSE_FLAG_ASM_COMMENTS
) {
3720 p
= parse_line_comment(p
- 1);
3729 case 'a': case 'b': case 'c': case 'd':
3730 case 'e': case 'f': case 'g': case 'h':
3731 case 'i': case 'j': case 'k': case 'l':
3732 case 'm': case 'n': case 'o': case 'p':
3733 case 'q': case 'r': case 's': case 't':
3734 case 'u': case 'v': case 'w': case 'x':
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':
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':
3747 h
= TOK_HASH_FUNC(h
, c
);
3751 if (!isidnum_table
[c
])
3753 h
= TOK_HASH_FUNC(h
, c
);
3760 /* fast case : no stray found, so we have the full token
3761 and we have already hashed it */
3763 h
&= (TOK_HASH_SIZE
- 1);
3764 pts
= &hash_ident
[h
];
3769 if (ts
->len
== len
&& !memcmp(ts
->str
, p1
, len
))
3771 pts
= &(ts
->hash_next
);
3773 ts
= tok_alloc_new(pts
, p1
, len
);
3777 cstr_reset(&tokcstr
);
3780 cstr_ccat(&tokcstr
, *p1
);
3786 while (isidnum_table
[c
]) {
3787 cstr_ccat(&tokcstr
, c
);
3790 ts
= tok_alloc(tokcstr
.data
, tokcstr
.size
);
3796 if (t
!= '\\' && t
!= '\'' && t
!= '\"') {
3798 goto parse_ident_fast
;
3801 if (c
== '\'' || c
== '\"') {
3805 cstr_reset(&tokcstr
);
3806 cstr_ccat(&tokcstr
, 'L');
3807 goto parse_ident_slow
;
3811 case '0': case '1': case '2': case '3':
3812 case '4': case '5': case '6': case '7':
3815 cstr_reset(&tokcstr
);
3816 /* after the first digit, accept digits, alpha, '.' or sign if
3817 prefixed by 'eEpP' */
3821 cstr_ccat(&tokcstr
, c
);
3823 if (!(isnum(c
) || isid(c
) || c
== '.' ||
3824 ((c
== '+' || c
== '-') &&
3825 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
3828 /* We add a trailing '\0' to ease parsing */
3829 cstr_ccat(&tokcstr
, '\0');
3830 tokc
.cstr
= &tokcstr
;
3834 /* special dot handling because it can also start a number */
3837 cstr_reset(&tokcstr
);
3838 cstr_ccat(&tokcstr
, '.');
3840 } else if (c
== '.') {
3860 /* parse the string */
3862 p
= parse_pp_string(p
, sep
, &str
);
3863 cstr_ccat(&str
, '\0');
3865 /* eval the escape (should be done as TOK_PPNUM) */
3866 cstr_reset(&tokcstr
);
3867 parse_escape_string(&tokcstr
, str
.data
, is_long
);
3872 /* XXX: make it portable */
3876 char_size
= sizeof(nwchar_t
);
3877 if (tokcstr
.size
<= char_size
)
3878 error("empty character constant");
3879 if (tokcstr
.size
> 2 * char_size
)
3880 warning("multi-character character constant");
3882 tokc
.i
= *(int8_t *)tokcstr
.data
;
3885 tokc
.i
= *(nwchar_t
*)tokcstr
.data
;
3889 tokc
.cstr
= &tokcstr
;
3903 } else if (c
== '<') {
3921 } else if (c
== '>') {
3939 } else if (c
== '=') {
3952 } else if (c
== '=') {
3965 } else if (c
== '=') {
3978 } else if (c
== '=') {
3981 } else if (c
== '>') {
3989 PARSE2('!', '!', '=', TOK_NE
)
3990 PARSE2('=', '=', '=', TOK_EQ
)
3991 PARSE2('*', '*', '=', TOK_A_MUL
)
3992 PARSE2('%', '%', '=', TOK_A_MOD
)
3993 PARSE2('^', '^', '=', TOK_A_XOR
)
3995 /* comments or operator */
3999 p
= parse_comment(p
);
4001 } else if (c
== '/') {
4002 p
= parse_line_comment(p
);
4004 } else if (c
== '=') {
4024 case '$': /* only used in assembler */
4025 case '@': /* dito */
4030 error("unrecognized character \\x%02x", c
);
4036 #if defined(PARSE_DEBUG)
4037 printf("token = %s\n", get_tok_str(tok
, &tokc
));
4041 /* return next token without macro substitution. Can read input from
4043 static void next_nomacro(void)
4049 TOK_GET(tok
, macro_ptr
, tokc
);
4050 if (tok
== TOK_LINENUM
) {
4051 file
->line_num
= tokc
.i
;
4060 /* substitute args in macro_str and return allocated string */
4061 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
4063 int *st
, last_tok
, t
, notfirst
;
4072 TOK_GET(t
, macro_str
, cval
);
4077 TOK_GET(t
, macro_str
, cval
);
4080 s
= sym_find2(args
, t
);
4087 cstr_ccat(&cstr
, ' ');
4088 TOK_GET(t
, st
, cval
);
4089 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
4094 cstr_ccat(&cstr
, '\0');
4096 printf("stringize: %s\n", (char *)cstr
.data
);
4100 tok_str_add2(&str
, TOK_STR
, &cval
);
4103 tok_str_add2(&str
, t
, &cval
);
4105 } else if (t
>= TOK_IDENT
) {
4106 s
= sym_find2(args
, t
);
4109 /* if '##' is present before or after, no arg substitution */
4110 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
4111 /* special case for var arg macros : ## eats the
4112 ',' if empty VA_ARGS variable. */
4113 /* XXX: test of the ',' is not 100%
4114 reliable. should fix it to avoid security
4116 if (gnu_ext
&& s
->type
.t
&&
4117 last_tok
== TOK_TWOSHARPS
&&
4118 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
4120 /* suppress ',' '##' */
4123 /* suppress '##' and add variable */
4131 TOK_GET(t1
, st
, cval
);
4134 tok_str_add2(&str
, t1
, &cval
);
4138 /* NOTE: the stream cannot be read when macro
4139 substituing an argument */
4140 macro_subst(&str
, nested_list
, st
, NULL
);
4143 tok_str_add(&str
, t
);
4146 tok_str_add2(&str
, t
, &cval
);
4150 tok_str_add(&str
, 0);
4154 static char const ab_month_name
[12][4] =
4156 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
4157 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
4160 /* do macro substitution of current token with macro 's' and add
4161 result to (tok_str,tok_len). 'nested_list' is the list of all
4162 macros we got inside to avoid recursing. Return non zero if no
4163 substitution needs to be done */
4164 static int macro_subst_tok(TokenString
*tok_str
,
4165 Sym
**nested_list
, Sym
*s
, struct macro_level
**can_read_stream
)
4167 Sym
*args
, *sa
, *sa1
;
4168 int mstr_allocated
, parlevel
, *mstr
, t
, t1
;
4175 /* if symbol is a macro, prepare substitution */
4176 /* special macros */
4177 if (tok
== TOK___LINE__
) {
4178 snprintf(buf
, sizeof(buf
), "%d", file
->line_num
);
4182 } else if (tok
== TOK___FILE__
) {
4183 cstrval
= file
->filename
;
4185 } else if (tok
== TOK___DATE__
|| tok
== TOK___TIME__
) {
4190 tm
= localtime(&ti
);
4191 if (tok
== TOK___DATE__
) {
4192 snprintf(buf
, sizeof(buf
), "%s %2d %d",
4193 ab_month_name
[tm
->tm_mon
], tm
->tm_mday
, tm
->tm_year
+ 1900);
4195 snprintf(buf
, sizeof(buf
), "%02d:%02d:%02d",
4196 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
4203 cstr_cat(&cstr
, cstrval
);
4204 cstr_ccat(&cstr
, '\0');
4206 tok_str_add2(tok_str
, t1
, &cval
);
4211 if (s
->type
.t
== MACRO_FUNC
) {
4212 /* NOTE: we do not use next_nomacro to avoid eating the
4213 next token. XXX: find better solution */
4217 if (t
== 0 && can_read_stream
) {
4218 /* end of macro stream: we must look at the token
4219 after in the file */
4220 struct macro_level
*ml
= *can_read_stream
;
4226 *can_read_stream
= ml
-> prev
;
4231 /* XXX: incorrect with comments */
4232 ch
= file
->buf_ptr
[0];
4233 while (is_space(ch
) || ch
== '\n')
4237 if (t
!= '(') /* no macro subst */
4240 /* argument macro */
4245 /* NOTE: empty args are allowed, except if no args */
4247 /* handle '()' case */
4248 if (!args
&& !sa
&& tok
== ')')
4251 error("macro '%s' used with too many args",
4252 get_tok_str(s
->v
, 0));
4255 /* NOTE: non zero sa->t indicates VA_ARGS */
4256 while ((parlevel
> 0 ||
4258 (tok
!= ',' || sa
->type
.t
))) &&
4262 else if (tok
== ')')
4264 if (tok
!= TOK_LINEFEED
)
4265 tok_str_add2(&str
, tok
, &tokc
);
4268 tok_str_add(&str
, 0);
4269 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
4272 /* special case for gcc var args: add an empty
4273 var arg argument if it is omitted */
4274 if (sa
&& sa
->type
.t
&& gnu_ext
)
4284 error("macro '%s' used with too few args",
4285 get_tok_str(s
->v
, 0));
4288 /* now subst each arg */
4289 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
4294 tok_str_free((int *)sa
->c
);
4300 sym_push2(nested_list
, s
->v
, 0, 0);
4301 macro_subst(tok_str
, nested_list
, mstr
, can_read_stream
);
4302 /* pop nested defined symbol */
4304 *nested_list
= sa1
->prev
;
4312 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
4313 return the resulting string (which must be freed). */
4314 static inline int *macro_twosharps(const int *macro_str
)
4317 const int *macro_ptr1
, *start_macro_ptr
, *ptr
, *saved_macro_ptr
;
4319 const char *p1
, *p2
;
4321 TokenString macro_str1
;
4324 start_macro_ptr
= macro_str
;
4325 /* we search the first '##' */
4327 macro_ptr1
= macro_str
;
4328 TOK_GET(t
, macro_str
, cval
);
4329 /* nothing more to do if end of string */
4332 if (*macro_str
== TOK_TWOSHARPS
)
4336 /* we saw '##', so we need more processing to handle it */
4338 tok_str_new(¯o_str1
);
4342 /* add all tokens seen so far */
4343 for(ptr
= start_macro_ptr
; ptr
< macro_ptr1
;) {
4344 TOK_GET(t
, ptr
, cval
);
4345 tok_str_add2(¯o_str1
, t
, &cval
);
4347 saved_macro_ptr
= macro_ptr
;
4348 /* XXX: get rid of the use of macro_ptr here */
4349 macro_ptr
= (int *)macro_str
;
4351 while (*macro_ptr
== TOK_TWOSHARPS
) {
4353 macro_ptr1
= macro_ptr
;
4356 TOK_GET(t
, macro_ptr
, cval
);
4357 /* We concatenate the two tokens if we have an
4358 identifier or a preprocessing number */
4360 p1
= get_tok_str(tok
, &tokc
);
4361 cstr_cat(&cstr
, p1
);
4362 p2
= get_tok_str(t
, &cval
);
4363 cstr_cat(&cstr
, p2
);
4364 cstr_ccat(&cstr
, '\0');
4366 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
4367 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
4368 if (tok
== TOK_PPNUM
) {
4369 /* if number, then create a number token */
4370 /* NOTE: no need to allocate because
4371 tok_str_add2() does it */
4372 cstr_reset(&tokcstr
);
4375 tokc
.cstr
= &tokcstr
;
4377 /* if identifier, we must do a test to
4378 validate we have a correct identifier */
4379 if (t
== TOK_PPNUM
) {
4389 if (!isnum(c
) && !isid(c
))
4393 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
4394 tok
= ts
->tok
; /* modify current token */
4397 const char *str
= cstr
.data
;
4398 const unsigned char *q
;
4400 /* we look for a valid token */
4401 /* XXX: do more extensive checks */
4402 if (!strcmp(str
, ">>=")) {
4404 } else if (!strcmp(str
, "<<=")) {
4406 } else if (strlen(str
) == 2) {
4407 /* search in two bytes table */
4412 if (q
[0] == str
[0] && q
[1] == str
[1])
4419 /* NOTE: because get_tok_str use a static buffer,
4422 p1
= get_tok_str(tok
, &tokc
);
4423 cstr_cat(&cstr
, p1
);
4424 cstr_ccat(&cstr
, '\0');
4425 p2
= get_tok_str(t
, &cval
);
4426 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
4427 /* cannot merge tokens: just add them separately */
4428 tok_str_add2(¯o_str1
, tok
, &tokc
);
4429 /* XXX: free associated memory ? */
4436 tok_str_add2(¯o_str1
, tok
, &tokc
);
4441 macro_ptr
= (int *)saved_macro_ptr
;
4443 tok_str_add(¯o_str1
, 0);
4444 return macro_str1
.str
;
4448 /* do macro substitution of macro_str and add result to
4449 (tok_str,tok_len). 'nested_list' is the list of all macros we got
4450 inside to avoid recursing. */
4451 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
4452 const int *macro_str
, struct macro_level
** can_read_stream
)
4459 struct macro_level ml
;
4461 /* first scan for '##' operator handling */
4463 macro_str1
= macro_twosharps(ptr
);
4467 /* NOTE: ptr == NULL can only happen if tokens are read from
4468 file stream due to a macro function call */
4471 TOK_GET(t
, ptr
, cval
);
4476 /* if nested substitution, do nothing */
4477 if (sym_find2(*nested_list
, t
))
4480 if (can_read_stream
)
4481 ml
.prev
= *can_read_stream
, *can_read_stream
= &ml
;
4482 macro_ptr
= (int *)ptr
;
4484 ret
= macro_subst_tok(tok_str
, nested_list
, s
, can_read_stream
);
4485 ptr
= (int *)macro_ptr
;
4487 if (can_read_stream
&& *can_read_stream
== &ml
)
4488 *can_read_stream
= ml
.prev
;
4493 tok_str_add2(tok_str
, t
, &cval
);
4497 tok_str_free(macro_str1
);
4500 /* return next token with macro substitution */
4501 static void next(void)
4503 Sym
*nested_list
, *s
;
4505 struct macro_level
*ml
;
4510 /* if not reading from macro substituted string, then try
4511 to substitute macros */
4512 if (tok
>= TOK_IDENT
&&
4513 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
4514 s
= define_find(tok
);
4516 /* we have a macro: we try to substitute */
4520 if (macro_subst_tok(&str
, &nested_list
, s
, &ml
) == 0) {
4521 /* substitution done, NOTE: maybe empty */
4522 tok_str_add(&str
, 0);
4523 macro_ptr
= str
.str
;
4524 macro_ptr_allocated
= str
.str
;
4531 /* end of macro or end of unget buffer */
4532 if (unget_buffer_enabled
) {
4533 macro_ptr
= unget_saved_macro_ptr
;
4534 unget_buffer_enabled
= 0;
4536 /* end of macro string: free it */
4537 tok_str_free(macro_ptr_allocated
);
4544 /* convert preprocessor tokens into C tokens */
4545 if (tok
== TOK_PPNUM
&&
4546 (parse_flags
& PARSE_FLAG_TOK_NUM
)) {
4547 parse_number((char *)tokc
.cstr
->data
);
4551 /* push back current token and set current token to 'last_tok'. Only
4552 identifier case handled for labels. */
4553 static inline void unget_tok(int last_tok
)
4557 unget_saved_macro_ptr
= macro_ptr
;
4558 unget_buffer_enabled
= 1;
4559 q
= unget_saved_buffer
;
4562 n
= tok_ext_size(tok
) - 1;
4565 *q
= 0; /* end of token string */
4570 void swap(int *p
, int *q
)
4578 void vsetc(CType
*type
, int r
, CValue
*vc
)
4582 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
4583 error("memory full");
4584 /* cannot let cpu flags if other instruction are generated. Also
4585 avoid leaving VT_JMP anywhere except on the top of the stack
4586 because it would complicate the code generator. */
4587 if (vtop
>= vstack
) {
4588 v
= vtop
->r
& VT_VALMASK
;
4589 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
4595 vtop
->r2
= VT_CONST
;
4599 /* push integer constant */
4604 vsetc(&int_type
, VT_CONST
, &cval
);
4607 /* Return a static symbol pointing to a section */
4608 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
4609 unsigned long offset
, unsigned long size
)
4615 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
4616 sym
->type
.ref
= type
->ref
;
4617 sym
->r
= VT_CONST
| VT_SYM
;
4618 put_extern_sym(sym
, sec
, offset
, size
);
4622 /* push a reference to a section offset by adding a dummy symbol */
4623 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
4628 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4629 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
4632 /* define a new external reference to a symbol 'v' of type 'u' */
4633 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
4639 /* push forward reference */
4640 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
4641 s
->type
.ref
= type
->ref
;
4642 s
->r
= r
| VT_CONST
| VT_SYM
;
4647 /* define a new external reference to a symbol 'v' of type 'u' */
4648 static Sym
*external_sym(int v
, CType
*type
, int r
)
4654 /* push forward reference */
4655 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
4656 s
->type
.t
|= VT_EXTERN
;
4658 if (!is_compatible_types(&s
->type
, type
))
4659 error("incompatible types for redefinition of '%s'",
4660 get_tok_str(v
, NULL
));
4665 /* push a reference to global symbol v */
4666 static void vpush_global_sym(CType
*type
, int v
)
4671 sym
= external_global_sym(v
, type
, 0);
4673 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4677 void vset(CType
*type
, int r
, int v
)
4682 vsetc(type
, r
, &cval
);
4685 void vseti(int r
, int v
)
4701 void vpushv(SValue
*v
)
4703 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
4704 error("memory full");
4714 /* save r to the memory stack, and mark it as being free */
4715 void save_reg(int r
)
4717 int l
, saved
, size
, align
;
4721 /* modify all stack values */
4724 for(p
=vstack
;p
<=vtop
;p
++) {
4725 if ((p
->r
& VT_VALMASK
) == r
||
4726 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& (p
->r2
& VT_VALMASK
) == r
)) {
4727 /* must save value on stack if not already done */
4729 /* NOTE: must reload 'r' because r might be equal to r2 */
4730 r
= p
->r
& VT_VALMASK
;
4731 /* store register in the stack */
4733 if ((p
->r
& VT_LVAL
) ||
4734 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
4736 size
= type_size(type
, &align
);
4737 loc
= (loc
- size
) & -align
;
4738 sv
.type
.t
= type
->t
;
4739 sv
.r
= VT_LOCAL
| VT_LVAL
;
4742 #ifdef TCC_TARGET_I386
4743 /* x86 specific: need to pop fp register ST0 if saved */
4744 if (r
== TREG_ST0
) {
4745 o(0xd9dd); /* fstp %st(1) */
4748 /* special long long case */
4749 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
4756 /* mark that stack entry as being saved on the stack */
4757 if (p
->r
& VT_LVAL
) {
4758 /* also clear the bounded flag because the
4759 relocation address of the function was stored in
4761 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
4763 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
4771 /* find a register of class 'rc2' with at most one reference on stack.
4772 * If none, call get_reg(rc) */
4773 int get_reg_ex(int rc
, int rc2
)
4778 for(r
=0;r
<NB_REGS
;r
++) {
4779 if (reg_classes
[r
] & rc2
) {
4782 for(p
= vstack
; p
<= vtop
; p
++) {
4783 if ((p
->r
& VT_VALMASK
) == r
||
4784 (p
->r2
& VT_VALMASK
) == r
)
4794 /* find a free register of class 'rc'. If none, save one register */
4800 /* find a free register */
4801 for(r
=0;r
<NB_REGS
;r
++) {
4802 if (reg_classes
[r
] & rc
) {
4803 for(p
=vstack
;p
<=vtop
;p
++) {
4804 if ((p
->r
& VT_VALMASK
) == r
||
4805 (p
->r2
& VT_VALMASK
) == r
)
4813 /* no register left : free the first one on the stack (VERY
4814 IMPORTANT to start from the bottom to ensure that we don't
4815 spill registers used in gen_opi()) */
4816 for(p
=vstack
;p
<=vtop
;p
++) {
4817 r
= p
->r
& VT_VALMASK
;
4818 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
4820 /* also look at second register (if long long) */
4821 r
= p
->r2
& VT_VALMASK
;
4822 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
4828 /* Should never comes here */
4832 /* save registers up to (vtop - n) stack entry */
4833 void save_regs(int n
)
4838 for(p
= vstack
;p
<= p1
; p
++) {
4839 r
= p
->r
& VT_VALMASK
;
4846 /* move register 's' to 'r', and flush previous value of r to memory
4848 void move_reg(int r
, int s
)
4861 /* get address of vtop (vtop MUST BE an lvalue) */
4864 vtop
->r
&= ~VT_LVAL
;
4865 /* tricky: if saved lvalue, then we can go back to lvalue */
4866 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
4867 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
4870 #ifdef CONFIG_TCC_BCHECK
4871 /* generate lvalue bound code */
4877 vtop
->r
&= ~VT_MUSTBOUND
;
4878 /* if lvalue, then use checking code before dereferencing */
4879 if (vtop
->r
& VT_LVAL
) {
4880 /* if not VT_BOUNDED value, then make one */
4881 if (!(vtop
->r
& VT_BOUNDED
)) {
4882 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
4883 /* must save type because we must set it to int to get pointer */
4885 vtop
->type
.t
= VT_INT
;
4888 gen_bounded_ptr_add();
4889 vtop
->r
|= lval_type
;
4892 /* then check for dereferencing */
4893 gen_bounded_ptr_deref();
4898 /* store vtop a register belonging to class 'rc'. lvalues are
4899 converted to values. Cannot be used if cannot be converted to
4900 register value (such as structures). */
4903 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
4904 unsigned long long ll
;
4906 /* NOTE: get_reg can modify vstack[] */
4907 if (vtop
->type
.t
& VT_BITFIELD
) {
4908 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
4909 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4910 /* remove bit field info to avoid loops */
4911 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4912 /* generate shifts */
4913 vpushi(32 - (bit_pos
+ bit_size
));
4915 vpushi(32 - bit_size
);
4916 /* NOTE: transformed to SHR if unsigned */
4920 if (is_float(vtop
->type
.t
) &&
4921 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4924 unsigned long offset
;
4925 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
4929 /* XXX: unify with initializers handling ? */
4930 /* CPUs usually cannot use float constants, so we store them
4931 generically in data segment */
4932 size
= type_size(&vtop
->type
, &align
);
4933 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
4934 data_section
->data_offset
= offset
;
4935 /* XXX: not portable yet */
4937 /* Zero pad x87 tenbyte long doubles */
4939 vtop
->c
.tab
[2] &= 0xffff;
4941 ptr
= section_ptr_add(data_section
, size
);
4943 #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
4947 ptr
[i
] = vtop
->c
.tab
[size
-1-i
];
4951 ptr
[i
] = vtop
->c
.tab
[i
];
4952 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
4953 vtop
->r
|= VT_LVAL
| VT_SYM
;
4957 #ifdef CONFIG_TCC_BCHECK
4958 if (vtop
->r
& VT_MUSTBOUND
)
4962 r
= vtop
->r
& VT_VALMASK
;
4963 /* need to reload if:
4965 - lvalue (need to dereference pointer)
4966 - already a register, but not in the right class */
4967 if (r
>= VT_CONST
||
4968 (vtop
->r
& VT_LVAL
) ||
4969 !(reg_classes
[r
] & rc
) ||
4970 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
4971 !(reg_classes
[vtop
->r2
] & rc
))) {
4973 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
4974 /* two register type load : expand to two words
4976 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4979 vtop
->c
.ui
= ll
; /* first word */
4981 vtop
->r
= r
; /* save register value */
4982 vpushi(ll
>> 32); /* second word */
4983 } else if (r
>= VT_CONST
|| /* XXX: test to VT_CONST incorrect ? */
4984 (vtop
->r
& VT_LVAL
)) {
4985 /* We do not want to modifier the long long
4986 pointer here, so the safest (and less
4987 efficient) is to save all the other registers
4988 in the stack. XXX: totally inefficient. */
4990 /* load from memory */
4993 vtop
[-1].r
= r
; /* save register value */
4994 /* increment pointer to get second word */
4995 vtop
->type
.t
= VT_INT
;
5001 /* move registers */
5004 vtop
[-1].r
= r
; /* save register value */
5005 vtop
->r
= vtop
[-1].r2
;
5007 /* allocate second register */
5014 /* write second register */
5016 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
5018 /* lvalue of scalar type : need to use lvalue type
5019 because of possible cast */
5022 /* compute memory access type */
5023 if (vtop
->r
& VT_LVAL_BYTE
)
5025 else if (vtop
->r
& VT_LVAL_SHORT
)
5027 if (vtop
->r
& VT_LVAL_UNSIGNED
)
5031 /* restore wanted type */
5034 /* one register type load */
5039 #ifdef TCC_TARGET_C67
5040 /* uses register pairs for doubles */
5041 if ((vtop
->type
.t
& VT_BTYPE
) == VT_DOUBLE
)
5048 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
5049 void gv2(int rc1
, int rc2
)
5053 /* generate more generic register first. But VT_JMP or VT_CMP
5054 values must be generated first in all cases to avoid possible
5056 v
= vtop
[0].r
& VT_VALMASK
;
5057 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
5062 /* test if reload is needed for first register */
5063 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
5073 /* test if reload is needed for first register */
5074 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
5080 /* expand long long on stack in two int registers */
5085 u
= vtop
->type
.t
& VT_UNSIGNED
;
5088 vtop
[0].r
= vtop
[-1].r2
;
5089 vtop
[0].r2
= VT_CONST
;
5090 vtop
[-1].r2
= VT_CONST
;
5091 vtop
[0].type
.t
= VT_INT
| u
;
5092 vtop
[-1].type
.t
= VT_INT
| u
;
5095 #ifdef TCC_TARGET_ARM
5096 /* expand long long on stack */
5097 void lexpand_nr(void)
5101 u
= vtop
->type
.t
& VT_UNSIGNED
;
5103 vtop
->r2
= VT_CONST
;
5104 vtop
->type
.t
= VT_INT
| u
;
5105 v
=vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
);
5106 if (v
== VT_CONST
) {
5107 vtop
[-1].c
.ui
= vtop
->c
.ull
;
5108 vtop
->c
.ui
= vtop
->c
.ull
>> 32;
5110 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
5112 vtop
->r
= vtop
[-1].r
;
5113 } else if (v
> VT_CONST
) {
5117 vtop
->r
= vtop
[-1].r2
;
5118 vtop
[-1].r2
= VT_CONST
;
5119 vtop
[-1].type
.t
= VT_INT
| u
;
5123 /* build a long long from two ints */
5126 gv2(RC_INT
, RC_INT
);
5127 vtop
[-1].r2
= vtop
[0].r
;
5128 vtop
[-1].type
.t
= t
;
5132 /* rotate n first stack elements to the bottom
5133 I1 ... In -> I2 ... In I1 [top is right]
5141 for(i
=-n
+1;i
!=0;i
++)
5142 vtop
[i
] = vtop
[i
+1];
5146 /* rotate n first stack elements to the top
5147 I1 ... In -> In I1 ... I(n-1) [top is right]
5155 for(i
= 0;i
< n
- 1; i
++)
5156 vtop
[-i
] = vtop
[-i
- 1];
5160 #ifdef TCC_TARGET_ARM
5161 /* like vrott but in other direction
5162 In ... I1 -> I(n-1) ... I1 In [top is right]
5170 for(i
= n
- 1; i
> 0; i
--)
5171 vtop
[-i
] = vtop
[-i
+ 1];
5176 /* pop stack value */
5180 v
= vtop
->r
& VT_VALMASK
;
5181 #ifdef TCC_TARGET_I386
5182 /* for x86, we need to pop the FP stack */
5183 if (v
== TREG_ST0
&& !nocode_wanted
) {
5184 o(0xd9dd); /* fstp %st(1) */
5187 if (v
== VT_JMP
|| v
== VT_JMPI
) {
5188 /* need to put correct jump if && or || without test */
5194 /* convert stack entry to register and duplicate its value in another
5202 if ((t
& VT_BTYPE
) == VT_LLONG
) {
5209 /* stack: H L L1 H1 */
5217 /* duplicate value */
5228 load(r1
, &sv
); /* move r to r1 */
5230 /* duplicates value */
5235 /* generate CPU independent (unsigned) long long operations */
5236 void gen_opl(int op
)
5238 int t
, a
, b
, op1
, c
, i
;
5245 func
= TOK___divdi3
;
5248 func
= TOK___udivdi3
;
5251 func
= TOK___moddi3
;
5254 func
= TOK___umoddi3
;
5256 /* call generic long long function */
5257 vpush_global_sym(&func_old_type
, func
);
5262 vtop
->r2
= REG_LRET
;
5275 /* stack: L1 H1 L2 H2 */
5280 vtop
[-2] = vtop
[-3];
5283 /* stack: H1 H2 L1 L2 */
5289 /* stack: H1 H2 L1 L2 ML MH */
5292 /* stack: ML MH H1 H2 L1 L2 */
5296 /* stack: ML MH H1 L2 H2 L1 */
5301 /* stack: ML MH M1 M2 */
5304 } else if (op
== '+' || op
== '-') {
5305 /* XXX: add non carry method too (for MIPS or alpha) */
5311 /* stack: H1 H2 (L1 op L2) */
5314 gen_op(op1
+ 1); /* TOK_xxxC2 */
5317 /* stack: H1 H2 (L1 op L2) */
5320 /* stack: (L1 op L2) H1 H2 */
5322 /* stack: (L1 op L2) (H1 op H2) */
5330 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
5331 t
= vtop
[-1].type
.t
;
5335 /* stack: L H shift */
5337 /* constant: simpler */
5338 /* NOTE: all comments are for SHL. the other cases are
5339 done by swaping words */
5350 if (op
!= TOK_SAR
) {
5383 /* XXX: should provide a faster fallback on x86 ? */
5386 func
= TOK___sardi3
;
5389 func
= TOK___shrdi3
;
5392 func
= TOK___shldi3
;
5398 /* compare operations */
5404 /* stack: L1 H1 L2 H2 */
5406 vtop
[-1] = vtop
[-2];
5408 /* stack: L1 L2 H1 H2 */
5411 /* when values are equal, we need to compare low words. since
5412 the jump is inverted, we invert the test too. */
5415 else if (op1
== TOK_GT
)
5417 else if (op1
== TOK_ULT
)
5419 else if (op1
== TOK_UGT
)
5424 if (op1
!= TOK_NE
) {
5428 /* generate non equal test */
5429 /* XXX: NOT PORTABLE yet */
5433 #if defined(TCC_TARGET_I386)
5434 b
= psym(0x850f, 0);
5435 #elif defined(TCC_TARGET_ARM)
5437 o(0x1A000000 | encbranch(ind
, 0, 1));
5438 #elif defined(TCC_TARGET_C67)
5439 error("not implemented");
5441 #error not supported
5445 /* compare low. Always unsigned */
5449 else if (op1
== TOK_LE
)
5451 else if (op1
== TOK_GT
)
5453 else if (op1
== TOK_GE
)
5463 /* handle integer constant optimizations and various machine
5465 void gen_opic(int op
)
5467 int c1
, c2
, t1
, t2
, n
, c
;
5469 long long l1
, l2
, l
;
5470 typedef unsigned long long U
;
5474 t1
= v1
->type
.t
& VT_BTYPE
;
5475 t2
= v2
->type
.t
& VT_BTYPE
;
5476 l1
= (t1
== VT_LLONG
) ? v1
->c
.ll
: v1
->c
.i
;
5477 l2
= (t2
== VT_LLONG
) ? v2
->c
.ll
: v2
->c
.i
;
5479 /* currently, we cannot do computations with forward symbols */
5480 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5481 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5484 case '+': l1
+= l2
; break;
5485 case '-': l1
-= l2
; break;
5486 case '&': l1
&= l2
; break;
5487 case '^': l1
^= l2
; break;
5488 case '|': l1
|= l2
; break;
5489 case '*': l1
*= l2
; break;
5496 /* if division by zero, generate explicit division */
5499 error("division by zero in constant");
5503 default: l1
/= l2
; break;
5504 case '%': l1
%= l2
; break;
5505 case TOK_UDIV
: l1
= (U
)l1
/ l2
; break;
5506 case TOK_UMOD
: l1
= (U
)l1
% l2
; break;
5509 case TOK_SHL
: l1
<<= l2
; break;
5510 case TOK_SHR
: l1
= (U
)l1
>> l2
; break;
5511 case TOK_SAR
: l1
>>= l2
; break;
5513 case TOK_ULT
: l1
= (U
)l1
< (U
)l2
; break;
5514 case TOK_UGE
: l1
= (U
)l1
>= (U
)l2
; break;
5515 case TOK_EQ
: l1
= l1
== l2
; break;
5516 case TOK_NE
: l1
= l1
!= l2
; break;
5517 case TOK_ULE
: l1
= (U
)l1
<= (U
)l2
; break;
5518 case TOK_UGT
: l1
= (U
)l1
> (U
)l2
; break;
5519 case TOK_LT
: l1
= l1
< l2
; break;
5520 case TOK_GE
: l1
= l1
>= l2
; break;
5521 case TOK_LE
: l1
= l1
<= l2
; break;
5522 case TOK_GT
: l1
= l1
> l2
; break;
5524 case TOK_LAND
: l1
= l1
&& l2
; break;
5525 case TOK_LOR
: l1
= l1
|| l2
; break;
5532 /* if commutative ops, put c2 as constant */
5533 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
5534 op
== '|' || op
== '*')) {
5536 c
= c1
, c1
= c2
, c2
= c
;
5537 l
= l1
, l1
= l2
, l2
= l
;
5539 /* Filter out NOP operations like x*1, x-0, x&-1... */
5540 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
5543 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
5544 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
5550 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
5551 /* try to use shifts instead of muls or divs */
5552 if (l2
> 0 && (l2
& (l2
- 1)) == 0) {
5561 else if (op
== TOK_PDIV
)
5567 } else if (c2
&& (op
== '+' || op
== '-') &&
5568 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
5569 (VT_CONST
| VT_SYM
)) {
5570 /* symbol + constant case */
5577 if (!nocode_wanted
) {
5578 /* call low level op generator */
5579 if (t1
== VT_LLONG
|| t2
== VT_LLONG
)
5590 /* generate a floating point operation with constant propagation */
5591 void gen_opif(int op
)
5599 /* currently, we cannot do computations with forward symbols */
5600 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5601 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5603 if (v1
->type
.t
== VT_FLOAT
) {
5606 } else if (v1
->type
.t
== VT_DOUBLE
) {
5614 /* NOTE: we only do constant propagation if finite number (not
5615 NaN or infinity) (ANSI spec) */
5616 if (!ieee_finite(f1
) || !ieee_finite(f2
))
5620 case '+': f1
+= f2
; break;
5621 case '-': f1
-= f2
; break;
5622 case '*': f1
*= f2
; break;
5626 error("division by zero in constant");
5631 /* XXX: also handles tests ? */
5635 /* XXX: overflow test ? */
5636 if (v1
->type
.t
== VT_FLOAT
) {
5638 } else if (v1
->type
.t
== VT_DOUBLE
) {
5646 if (!nocode_wanted
) {
5654 static int pointed_size(CType
*type
)
5657 return type_size(pointed_type(type
), &align
);
5660 static inline int is_null_pointer(SValue
*p
)
5662 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
5664 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& p
->c
.i
== 0) ||
5665 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.ll
== 0);
5668 static inline int is_integer_btype(int bt
)
5670 return (bt
== VT_BYTE
|| bt
== VT_SHORT
||
5671 bt
== VT_INT
|| bt
== VT_LLONG
);
5674 /* check types for comparison or substraction of pointers */
5675 static void check_comparison_pointer_types(SValue
*p1
, SValue
*p2
, int op
)
5677 CType
*type1
, *type2
, tmp_type1
, tmp_type2
;
5680 /* null pointers are accepted for all comparisons as gcc */
5681 if (is_null_pointer(p1
) || is_null_pointer(p2
))
5685 bt1
= type1
->t
& VT_BTYPE
;
5686 bt2
= type2
->t
& VT_BTYPE
;
5687 /* accept comparison between pointer and integer with a warning */
5688 if ((is_integer_btype(bt1
) || is_integer_btype(bt2
)) && op
!= '-') {
5689 if (op
!= TOK_LOR
&& op
!= TOK_LAND
)
5690 warning("comparison between pointer and integer");
5694 /* both must be pointers or implicit function pointers */
5695 if (bt1
== VT_PTR
) {
5696 type1
= pointed_type(type1
);
5697 } else if (bt1
!= VT_FUNC
)
5698 goto invalid_operands
;
5700 if (bt2
== VT_PTR
) {
5701 type2
= pointed_type(type2
);
5702 } else if (bt2
!= VT_FUNC
) {
5704 error("invalid operands to binary %s", get_tok_str(op
, NULL
));
5706 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
5707 (type2
->t
& VT_BTYPE
) == VT_VOID
)
5711 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5712 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5713 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
5714 /* gcc-like error if '-' is used */
5716 goto invalid_operands
;
5718 warning("comparison of distinct pointer types lacks a cast");
5722 /* generic gen_op: handles types problems */
5725 int u
, t1
, t2
, bt1
, bt2
, t
;
5728 t1
= vtop
[-1].type
.t
;
5729 t2
= vtop
[0].type
.t
;
5730 bt1
= t1
& VT_BTYPE
;
5731 bt2
= t2
& VT_BTYPE
;
5733 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5734 /* at least one operand is a pointer */
5735 /* relationnal op: must be both pointers */
5736 if (op
>= TOK_ULT
&& op
<= TOK_LOR
) {
5737 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5738 /* pointers are handled are unsigned */
5739 t
= VT_INT
| VT_UNSIGNED
;
5742 /* if both pointers, then it must be the '-' op */
5743 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
5745 error("cannot use pointers here");
5746 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5747 /* XXX: check that types are compatible */
5748 u
= pointed_size(&vtop
[-1].type
);
5750 /* set to integer type */
5751 vtop
->type
.t
= VT_INT
;
5755 /* exactly one pointer : must be '+' or '-'. */
5756 if (op
!= '-' && op
!= '+')
5757 error("cannot use pointers here");
5758 /* Put pointer as first operand */
5759 if (bt2
== VT_PTR
) {
5763 type1
= vtop
[-1].type
;
5764 /* XXX: cast to int ? (long long case) */
5765 vpushi(pointed_size(&vtop
[-1].type
));
5767 #ifdef CONFIG_TCC_BCHECK
5768 /* if evaluating constant expression, no code should be
5769 generated, so no bound check */
5770 if (do_bounds_check
&& !const_wanted
) {
5771 /* if bounded pointers, we generate a special code to
5778 gen_bounded_ptr_add();
5784 /* put again type if gen_opic() swaped operands */
5787 } else if (is_float(bt1
) || is_float(bt2
)) {
5788 /* compute bigger type and do implicit casts */
5789 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5791 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5796 /* floats can only be used for a few operations */
5797 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
5798 (op
< TOK_ULT
|| op
> TOK_GT
))
5799 error("invalid operands for binary operation");
5801 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5802 /* cast to biggest op */
5804 /* convert to unsigned if it does not fit in a long long */
5805 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5806 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5810 /* integer operations */
5812 /* convert to unsigned if it does not fit in an integer */
5813 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5814 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5817 /* XXX: currently, some unsigned operations are explicit, so
5818 we modify them here */
5819 if (t
& VT_UNSIGNED
) {
5826 else if (op
== TOK_LT
)
5828 else if (op
== TOK_GT
)
5830 else if (op
== TOK_LE
)
5832 else if (op
== TOK_GE
)
5839 /* special case for shifts and long long: we keep the shift as
5841 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
5848 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5849 /* relationnal op: the result is an int */
5850 vtop
->type
.t
= VT_INT
;
5857 /* generic itof for unsigned long long case */
5858 void gen_cvt_itof1(int t
)
5860 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
5861 (VT_LLONG
| VT_UNSIGNED
)) {
5864 vpush_global_sym(&func_old_type
, TOK___ulltof
);
5865 else if (t
== VT_DOUBLE
)
5866 vpush_global_sym(&func_old_type
, TOK___ulltod
);
5868 vpush_global_sym(&func_old_type
, TOK___ulltold
);
5878 /* generic ftoi for unsigned long long case */
5879 void gen_cvt_ftoi1(int t
)
5883 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
5884 /* not handled natively */
5885 st
= vtop
->type
.t
& VT_BTYPE
;
5887 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
5888 else if (st
== VT_DOUBLE
)
5889 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
5891 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
5896 vtop
->r2
= REG_LRET
;
5902 /* force char or short cast */
5903 void force_charshort_cast(int t
)
5907 /* XXX: add optimization if lvalue : just change type and offset */
5912 if (t
& VT_UNSIGNED
) {
5913 vpushi((1 << bits
) - 1);
5919 /* result must be signed or the SAR is converted to an SHL
5920 This was not the case when "t" was a signed short
5921 and the last value on the stack was an unsigned int */
5922 vtop
->type
.t
&= ~VT_UNSIGNED
;
5928 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
5929 static void gen_cast(CType
*type
)
5931 int sbt
, dbt
, sf
, df
, c
;
5933 /* special delayed cast for char/short */
5934 /* XXX: in some cases (multiple cascaded casts), it may still
5936 if (vtop
->r
& VT_MUSTCAST
) {
5937 vtop
->r
&= ~VT_MUSTCAST
;
5938 force_charshort_cast(vtop
->type
.t
);
5941 /* bitfields first get cast to ints */
5942 if (vtop
->type
.t
& VT_BITFIELD
) {
5946 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
5947 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5949 if (sbt
!= dbt
&& !nocode_wanted
) {
5952 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5954 /* convert from fp to fp */
5956 /* constant case: we can do it now */
5957 /* XXX: in ISOC, cannot do it if error in convert */
5958 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
5959 vtop
->c
.f
= (float)vtop
->c
.d
;
5960 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
5961 vtop
->c
.f
= (float)vtop
->c
.ld
;
5962 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
5963 vtop
->c
.d
= (double)vtop
->c
.f
;
5964 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
5965 vtop
->c
.d
= (double)vtop
->c
.ld
;
5966 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
5967 vtop
->c
.ld
= (long double)vtop
->c
.f
;
5968 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
5969 vtop
->c
.ld
= (long double)vtop
->c
.d
;
5971 /* non constant case: generate code */
5975 /* convert int to fp */
5978 case VT_LLONG
| VT_UNSIGNED
:
5980 /* XXX: add const cases for long long */
5982 case VT_INT
| VT_UNSIGNED
:
5984 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
5985 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
5986 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
5991 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
5992 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
5993 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
5999 #if !defined(TCC_TARGET_ARM)
6006 /* convert fp to int */
6007 if (dbt
== VT_BOOL
) {
6011 /* we handle char/short/etc... with generic code */
6012 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
6013 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
6018 case VT_LLONG
| VT_UNSIGNED
:
6020 /* XXX: add const cases for long long */
6022 case VT_INT
| VT_UNSIGNED
:
6024 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
6025 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
6026 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
6032 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
6033 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
6034 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
6042 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
6043 /* additional cast for char/short... */
6048 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
6049 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
6050 /* scalar to long long */
6052 if (sbt
== (VT_INT
| VT_UNSIGNED
))
6053 vtop
->c
.ll
= vtop
->c
.ui
;
6055 vtop
->c
.ll
= vtop
->c
.i
;
6057 /* machine independent conversion */
6059 /* generate high word */
6060 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
6068 /* patch second register */
6069 vtop
[-1].r2
= vtop
->r
;
6073 } else if (dbt
== VT_BOOL
) {
6074 /* scalar to bool */
6077 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
6078 (dbt
& VT_BTYPE
) == VT_SHORT
) {
6079 if (sbt
== VT_PTR
) {
6080 vtop
->type
.t
= VT_INT
;
6081 warning("nonportable conversion from pointer to char/short");
6083 force_charshort_cast(dbt
);
6084 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
6086 if (sbt
== VT_LLONG
) {
6087 /* from long long: just take low order word */
6091 /* if lvalue and single word type, nothing to do because
6092 the lvalue already contains the real type size (see
6093 VT_LVAL_xxx constants) */
6095 } else if ((dbt
& VT_BTYPE
) == VT_PTR
&& !(vtop
->r
& VT_LVAL
)) {
6096 /* if we are casting between pointer types,
6097 we must update the VT_LVAL_xxx size */
6098 vtop
->r
= (vtop
->r
& ~VT_LVAL_TYPE
)
6099 | (lvalue_type(type
->ref
->type
.t
) & VT_LVAL_TYPE
);
6104 /* return type size. Put alignment at 'a' */
6105 static int type_size(CType
*type
, int *a
)
6110 bt
= type
->t
& VT_BTYPE
;
6111 if (bt
== VT_STRUCT
) {
6116 } else if (bt
== VT_PTR
) {
6117 if (type
->t
& VT_ARRAY
) {
6119 return type_size(&s
->type
, a
) * s
->c
;
6124 } else if (bt
== VT_LDOUBLE
) {
6126 return LDOUBLE_SIZE
;
6127 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
6128 #ifdef TCC_TARGET_I386
6130 #elif defined(TCC_TARGET_ARM)
6140 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
6143 } else if (bt
== VT_SHORT
) {
6147 /* char, void, function, _Bool */
6153 /* return the pointed type of t */
6154 static inline CType
*pointed_type(CType
*type
)
6156 return &type
->ref
->type
;
6159 /* modify type so that its it is a pointer to type. */
6160 static void mk_pointer(CType
*type
)
6163 s
= sym_push(SYM_FIELD
, type
, 0, -1);
6164 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
6168 /* compare function types. OLD functions match any new functions */
6169 static int is_compatible_func(CType
*type1
, CType
*type2
)
6175 if (!is_compatible_types(&s1
->type
, &s2
->type
))
6177 /* check func_call */
6178 if (FUNC_CALL(s1
->r
) != FUNC_CALL(s2
->r
))
6180 /* XXX: not complete */
6181 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
6185 while (s1
!= NULL
) {
6188 if (!is_compatible_parameter_types(&s1
->type
, &s2
->type
))
6198 /* return true if type1 and type2 are the same. If unqualified is
6199 true, qualifiers on the types are ignored.
6201 - enums are not checked as gcc __builtin_types_compatible_p ()
6203 static int compare_types(CType
*type1
, CType
*type2
, int unqualified
)
6207 t1
= type1
->t
& VT_TYPE
;
6208 t2
= type2
->t
& VT_TYPE
;
6210 /* strip qualifiers before comparing */
6211 t1
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6212 t2
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6214 /* XXX: bitfields ? */
6217 /* test more complicated cases */
6218 bt1
= t1
& VT_BTYPE
;
6219 if (bt1
== VT_PTR
) {
6220 type1
= pointed_type(type1
);
6221 type2
= pointed_type(type2
);
6222 return is_compatible_types(type1
, type2
);
6223 } else if (bt1
== VT_STRUCT
) {
6224 return (type1
->ref
== type2
->ref
);
6225 } else if (bt1
== VT_FUNC
) {
6226 return is_compatible_func(type1
, type2
);
6232 /* return true if type1 and type2 are exactly the same (including
6235 static int is_compatible_types(CType
*type1
, CType
*type2
)
6237 return compare_types(type1
,type2
,0);
6240 /* return true if type1 and type2 are the same (ignoring qualifiers).
6242 static int is_compatible_parameter_types(CType
*type1
, CType
*type2
)
6244 return compare_types(type1
,type2
,1);
6247 /* print a type. If 'varstr' is not NULL, then the variable is also
6248 printed in the type */
6250 /* XXX: add array and function pointers */
6251 void type_to_str(char *buf
, int buf_size
,
6252 CType
*type
, const char *varstr
)
6259 t
= type
->t
& VT_TYPE
;
6262 if (t
& VT_CONSTANT
)
6263 pstrcat(buf
, buf_size
, "const ");
6264 if (t
& VT_VOLATILE
)
6265 pstrcat(buf
, buf_size
, "volatile ");
6266 if (t
& VT_UNSIGNED
)
6267 pstrcat(buf
, buf_size
, "unsigned ");
6297 tstr
= "long double";
6299 pstrcat(buf
, buf_size
, tstr
);
6303 if (bt
== VT_STRUCT
)
6307 pstrcat(buf
, buf_size
, tstr
);
6308 v
= type
->ref
->v
& ~SYM_STRUCT
;
6309 if (v
>= SYM_FIRST_ANOM
)
6310 pstrcat(buf
, buf_size
, "<anonymous>");
6312 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
6316 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
6317 pstrcat(buf
, buf_size
, "(");
6319 while (sa
!= NULL
) {
6320 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
6321 pstrcat(buf
, buf_size
, buf1
);
6324 pstrcat(buf
, buf_size
, ", ");
6326 pstrcat(buf
, buf_size
, ")");
6330 pstrcpy(buf1
, sizeof(buf1
), "*");
6332 pstrcat(buf1
, sizeof(buf1
), varstr
);
6333 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
6337 pstrcat(buf
, buf_size
, " ");
6338 pstrcat(buf
, buf_size
, varstr
);
6343 /* verify type compatibility to store vtop in 'dt' type, and generate
6345 static void gen_assign_cast(CType
*dt
)
6347 CType
*st
, *type1
, *type2
, tmp_type1
, tmp_type2
;
6348 char buf1
[256], buf2
[256];
6351 st
= &vtop
->type
; /* source type */
6352 dbt
= dt
->t
& VT_BTYPE
;
6353 sbt
= st
->t
& VT_BTYPE
;
6354 if (dt
->t
& VT_CONSTANT
)
6355 warning("assignment of read-only location");
6358 /* special cases for pointers */
6359 /* '0' can also be a pointer */
6360 if (is_null_pointer(vtop
))
6362 /* accept implicit pointer to integer cast with warning */
6363 if (is_integer_btype(sbt
)) {
6364 warning("assignment makes pointer from integer without a cast");
6367 type1
= pointed_type(dt
);
6368 /* a function is implicitely a function pointer */
6369 if (sbt
== VT_FUNC
) {
6370 if ((type1
->t
& VT_BTYPE
) != VT_VOID
&&
6371 !is_compatible_types(pointed_type(dt
), st
))
6378 type2
= pointed_type(st
);
6379 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
6380 (type2
->t
& VT_BTYPE
) == VT_VOID
) {
6381 /* void * can match anything */
6383 /* exact type match, except for unsigned */
6386 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
6387 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
6388 if (!is_compatible_types(&tmp_type1
, &tmp_type2
))
6389 warning("assignment from incompatible pointer type");
6391 /* check const and volatile */
6392 if ((!(type1
->t
& VT_CONSTANT
) && (type2
->t
& VT_CONSTANT
)) ||
6393 (!(type1
->t
& VT_VOLATILE
) && (type2
->t
& VT_VOLATILE
)))
6394 warning("assignment discards qualifiers from pointer target type");
6400 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
6401 warning("assignment makes integer from pointer without a cast");
6403 /* XXX: more tests */
6408 tmp_type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6409 tmp_type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6410 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
6412 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
6413 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
6414 error("cannot cast '%s' to '%s'", buf1
, buf2
);
6422 /* store vtop in lvalue pushed on stack */
6425 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
6427 ft
= vtop
[-1].type
.t
;
6428 sbt
= vtop
->type
.t
& VT_BTYPE
;
6429 dbt
= ft
& VT_BTYPE
;
6430 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
6431 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
6432 /* optimize char/short casts */
6433 delayed_cast
= VT_MUSTCAST
;
6434 vtop
->type
.t
= ft
& VT_TYPE
;
6435 /* XXX: factorize */
6436 if (ft
& VT_CONSTANT
)
6437 warning("assignment of read-only location");
6440 if (!(ft
& VT_BITFIELD
))
6441 gen_assign_cast(&vtop
[-1].type
);
6444 if (sbt
== VT_STRUCT
) {
6445 /* if structure, only generate pointer */
6446 /* structure assignment : generate memcpy */
6447 /* XXX: optimize if small size */
6448 if (!nocode_wanted
) {
6449 size
= type_size(&vtop
->type
, &align
);
6453 vpush_global_sym(&func_old_type
, TOK_memcpy8
);
6454 else if(!(align
& 3))
6455 vpush_global_sym(&func_old_type
, TOK_memcpy4
);
6458 vpush_global_sym(&func_old_type
, TOK_memcpy
);
6462 vtop
->type
.t
= VT_INT
;
6466 vtop
->type
.t
= VT_INT
;
6478 /* leave source on stack */
6479 } else if (ft
& VT_BITFIELD
) {
6480 /* bitfield store handling */
6481 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
6482 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
6483 /* remove bit field info to avoid loops */
6484 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
6486 /* duplicate source into other register */
6491 /* duplicate destination */
6493 vtop
[-1] = vtop
[-2];
6495 /* mask and shift source */
6496 vpushi((1 << bit_size
) - 1);
6500 /* load destination, mask and or with source */
6502 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
6508 /* pop off shifted source from "duplicate source..." above */
6512 #ifdef CONFIG_TCC_BCHECK
6513 /* bound check case */
6514 if (vtop
[-1].r
& VT_MUSTBOUND
) {
6520 if (!nocode_wanted
) {
6524 r
= gv(rc
); /* generate value */
6525 /* if lvalue was saved on stack, must read it */
6526 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
6528 t
= get_reg(RC_INT
);
6530 sv
.r
= VT_LOCAL
| VT_LVAL
;
6531 sv
.c
.ul
= vtop
[-1].c
.ul
;
6533 vtop
[-1].r
= t
| VT_LVAL
;
6536 /* two word case handling : store second register at word + 4 */
6537 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
6539 /* convert to int to increment easily */
6540 vtop
->type
.t
= VT_INT
;
6546 /* XXX: it works because r2 is spilled last ! */
6547 store(vtop
->r2
, vtop
- 1);
6551 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6552 vtop
->r
|= delayed_cast
;
6556 /* post defines POST/PRE add. c is the token ++ or -- */
6557 void inc(int post
, int c
)
6560 vdup(); /* save lvalue */
6562 gv_dup(); /* duplicate value */
6567 vpushi(c
- TOK_MID
);
6569 vstore(); /* store value */
6571 vpop(); /* if post op, return saved value */
6574 /* Parse GNUC __attribute__ extension. Currently, the following
6575 extensions are recognized:
6576 - aligned(n) : set data/function alignment.
6577 - packed : force data alignment to 1
6578 - section(x) : generate data/code in this section.
6579 - unused : currently ignored, but may be used someday.
6580 - regparm(n) : pass function parameters in registers (i386 only)
6582 static void parse_attribute(AttributeDef
*ad
)
6586 while (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
6590 while (tok
!= ')') {
6591 if (tok
< TOK_IDENT
)
6592 expect("attribute name");
6600 expect("section name");
6601 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
6610 if (n
<= 0 || (n
& (n
- 1)) != 0)
6611 error("alignment must be a positive power of two");
6624 /* currently, no need to handle it because tcc does not
6625 track unused objects */
6629 /* currently, no need to handle it because tcc does not
6630 track unused objects */
6635 FUNC_CALL(ad
->func_attr
) = FUNC_CDECL
;
6640 FUNC_CALL(ad
->func_attr
) = FUNC_STDCALL
;
6642 #ifdef TCC_TARGET_I386
6652 FUNC_CALL(ad
->func_attr
) = FUNC_FASTCALL1
+ n
- 1;
6658 FUNC_CALL(ad
->func_attr
) = FUNC_FASTCALLW
;
6662 FUNC_EXPORT(ad
->func_attr
) = 1;
6665 if (tcc_state
->warn_unsupported
)
6666 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
6667 /* skip parameters */
6669 int parenthesis
= 0;
6673 else if (tok
== ')')
6676 } while (parenthesis
&& tok
!= -1);
6689 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
6690 static void struct_decl(CType
*type
, int u
)
6692 int a
, v
, size
, align
, maxalign
, c
, offset
;
6693 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
6694 Sym
*s
, *ss
, *ass
, **ps
;
6698 a
= tok
; /* save decl type */
6703 /* struct already defined ? return it */
6705 expect("struct/union/enum name");
6709 error("invalid type");
6716 /* we put an undefined size for struct/union */
6717 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
6718 s
->r
= 0; /* default alignment is zero as gcc */
6719 /* put struct/union/enum name in type */
6727 error("struct/union/enum already defined");
6728 /* cannot be empty */
6730 /* non empty enums are not allowed */
6731 if (a
== TOK_ENUM
) {
6735 expect("identifier");
6741 /* enum symbols have static storage */
6742 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
6743 ss
->type
.t
|= VT_STATIC
;
6748 /* NOTE: we accept a trailing comma */
6758 while (tok
!= '}') {
6759 parse_btype(&btype
, &ad
);
6765 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
| TYPE_ABSTRACT
);
6766 if (v
== 0 && (type1
.t
& VT_BTYPE
) != VT_STRUCT
)
6767 expect("identifier");
6768 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
6769 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
| VT_INLINE
)))
6770 error("invalid type for '%s'",
6771 get_tok_str(v
, NULL
));
6775 bit_size
= expr_const();
6776 /* XXX: handle v = 0 case for messages */
6778 error("negative width in bit-field '%s'",
6779 get_tok_str(v
, NULL
));
6780 if (v
&& bit_size
== 0)
6781 error("zero width for bit-field '%s'",
6782 get_tok_str(v
, NULL
));
6784 size
= type_size(&type1
, &align
);
6786 if (align
< ad
.aligned
)
6788 } else if (ad
.packed
) {
6790 } else if (*tcc_state
->pack_stack_ptr
) {
6791 if (align
> *tcc_state
->pack_stack_ptr
)
6792 align
= *tcc_state
->pack_stack_ptr
;
6795 if (bit_size
>= 0) {
6796 bt
= type1
.t
& VT_BTYPE
;
6802 error("bitfields must have scalar type");
6804 if (bit_size
> bsize
) {
6805 error("width of '%s' exceeds its type",
6806 get_tok_str(v
, NULL
));
6807 } else if (bit_size
== bsize
) {
6808 /* no need for bit fields */
6810 } else if (bit_size
== 0) {
6811 /* XXX: what to do if only padding in a
6813 /* zero size: means to pad */
6817 /* we do not have enough room ? */
6818 if ((bit_pos
+ bit_size
) > bsize
)
6821 /* XXX: handle LSB first */
6822 type1
.t
|= VT_BITFIELD
|
6823 (bit_pos
<< VT_STRUCT_SHIFT
) |
6824 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
6825 bit_pos
+= bit_size
;
6830 if (v
!= 0 || (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
6831 /* add new memory data only if starting
6833 if (lbit_pos
== 0) {
6834 if (a
== TOK_STRUCT
) {
6835 c
= (c
+ align
- 1) & -align
;
6844 if (align
> maxalign
)
6848 printf("add field %s offset=%d",
6849 get_tok_str(v
, NULL
), offset
);
6850 if (type1
.t
& VT_BITFIELD
) {
6851 printf(" pos=%d size=%d",
6852 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
6853 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
6858 if (v
== 0 && (type1
.t
& VT_BTYPE
) == VT_STRUCT
) {
6860 while ((ass
= ass
->next
) != NULL
) {
6861 ss
= sym_push(ass
->v
, &ass
->type
, 0, offset
+ ass
->c
);
6866 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
6870 if (tok
== ';' || tok
== TOK_EOF
)
6877 /* store size and alignment */
6878 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
6884 /* return 0 if no type declaration. otherwise, return the basic type
6887 static int parse_btype(CType
*type
, AttributeDef
*ad
)
6889 int t
, u
, type_found
, typespec_found
, typedef_found
;
6893 memset(ad
, 0, sizeof(AttributeDef
));
6901 /* currently, we really ignore extension */
6911 if ((t
& VT_BTYPE
) != 0)
6912 error("too many basic types");
6928 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
6929 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6930 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
6931 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
6945 if ((t
& VT_BTYPE
) == VT_LONG
) {
6946 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6953 struct_decl(&type1
, VT_ENUM
);
6956 type
->ref
= type1
.ref
;
6960 struct_decl(&type1
, VT_STRUCT
);
6963 /* type modifiers */
7016 /* GNUC attribute */
7017 case TOK_ATTRIBUTE1
:
7018 case TOK_ATTRIBUTE2
:
7019 parse_attribute(ad
);
7026 parse_expr_type(&type1
);
7029 if (typespec_found
|| typedef_found
)
7032 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
7035 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
7036 type
->ref
= s
->type
.ref
;
7044 if ((t
& (VT_SIGNED
|VT_UNSIGNED
)) == (VT_SIGNED
|VT_UNSIGNED
))
7045 error("signed and unsigned modifier");
7046 if (tcc_state
->char_is_unsigned
) {
7047 if ((t
& (VT_SIGNED
|VT_UNSIGNED
|VT_BTYPE
)) == VT_BYTE
)
7052 /* long is never used as type */
7053 if ((t
& VT_BTYPE
) == VT_LONG
)
7054 t
= (t
& ~VT_BTYPE
) | VT_INT
;
7059 /* convert a function parameter type (array to pointer and function to
7060 function pointer) */
7061 static inline void convert_parameter_type(CType
*pt
)
7063 /* remove const and volatile qualifiers (XXX: const could be used
7064 to indicate a const function parameter */
7065 pt
->t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7066 /* array must be transformed to pointer according to ANSI C */
7068 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
7073 static void post_type(CType
*type
, AttributeDef
*ad
)
7075 int n
, l
, t1
, arg_size
, align
;
7076 Sym
**plast
, *s
, *first
;
7081 /* function declaration */
7089 /* read param name and compute offset */
7090 if (l
!= FUNC_OLD
) {
7091 if (!parse_btype(&pt
, &ad1
)) {
7093 error("invalid type");
7100 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
7102 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
7103 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
7104 error("parameter declared as void");
7105 arg_size
+= (type_size(&pt
, &align
) + 3) & ~3;
7110 expect("identifier");
7114 convert_parameter_type(&pt
);
7115 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
7121 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
7128 /* if no parameters, then old type prototype */
7132 t1
= type
->t
& VT_STORAGE
;
7133 /* NOTE: const is ignored in returned type as it has a special
7134 meaning in gcc / C++ */
7135 type
->t
&= ~(VT_STORAGE
| VT_CONSTANT
);
7136 post_type(type
, ad
);
7137 /* we push a anonymous symbol which will contain the function prototype */
7138 FUNC_ARGS(ad
->func_attr
) = arg_size
;
7139 s
= sym_push(SYM_FIELD
, type
, ad
->func_attr
, l
);
7141 type
->t
= t1
| VT_FUNC
;
7143 } else if (tok
== '[') {
7144 /* array definition */
7150 error("invalid array size");
7153 /* parse next post type */
7154 t1
= type
->t
& VT_STORAGE
;
7155 type
->t
&= ~VT_STORAGE
;
7156 post_type(type
, ad
);
7158 /* we push a anonymous symbol which will contain the array
7160 s
= sym_push(SYM_FIELD
, type
, 0, n
);
7161 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
7166 /* Parse a type declaration (except basic type), and return the type
7167 in 'type'. 'td' is a bitmask indicating which kind of type decl is
7168 expected. 'type' should contain the basic type. 'ad' is the
7169 attribute definition of the basic type. It can be modified by
7172 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
7175 CType type1
, *type2
;
7178 while (tok
== '*') {
7186 qualifiers
|= VT_CONSTANT
;
7191 qualifiers
|= VT_VOLATILE
;
7199 type
->t
|= qualifiers
;
7202 /* XXX: clarify attribute handling */
7203 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
7204 parse_attribute(ad
);
7206 /* recursive type */
7207 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
7208 type1
.t
= 0; /* XXX: same as int */
7211 /* XXX: this is not correct to modify 'ad' at this point, but
7212 the syntax is not clear */
7213 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
7214 parse_attribute(ad
);
7215 type_decl(&type1
, ad
, v
, td
);
7218 /* type identifier */
7219 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
7223 if (!(td
& TYPE_ABSTRACT
))
7224 expect("identifier");
7228 post_type(type
, ad
);
7229 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
7230 parse_attribute(ad
);
7233 /* append type at the end of type1 */
7246 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
7247 static int lvalue_type(int t
)
7252 if (bt
== VT_BYTE
|| bt
== VT_BOOL
)
7254 else if (bt
== VT_SHORT
)
7258 if (t
& VT_UNSIGNED
)
7259 r
|= VT_LVAL_UNSIGNED
;
7263 /* indirection with full error checking and bound check */
7264 static void indir(void)
7266 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
) {
7267 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FUNC
)
7271 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
7273 vtop
->type
= *pointed_type(&vtop
->type
);
7274 /* Arrays and functions are never lvalues */
7275 if (!(vtop
->type
.t
& VT_ARRAY
)
7276 && (vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
7277 vtop
->r
|= lvalue_type(vtop
->type
.t
);
7278 /* if bound checking, the referenced pointer must be checked */
7279 if (do_bounds_check
)
7280 vtop
->r
|= VT_MUSTBOUND
;
7284 /* pass a parameter to a function and do type checking and casting */
7285 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
7290 func_type
= func
->c
;
7291 if (func_type
== FUNC_OLD
||
7292 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
7293 /* default casting : only need to convert float to double */
7294 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
7298 } else if (arg
== NULL
) {
7299 error("too many arguments to function");
7302 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
7303 gen_assign_cast(&type
);
7307 /* parse an expression of the form '(type)' or '(expr)' and return its
7309 static void parse_expr_type(CType
*type
)
7315 if (parse_btype(type
, &ad
)) {
7316 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
7323 static void parse_type(CType
*type
)
7328 if (!parse_btype(type
, &ad
)) {
7331 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
7334 static void vpush_tokc(int t
)
7338 vsetc(&type
, VT_CONST
, &tokc
);
7341 static void unary(void)
7343 int n
, t
, align
, size
, r
;
7348 /* XXX: GCC 2.95.3 does not generate a table although it should be
7362 vpush_tokc(VT_INT
| VT_UNSIGNED
);
7366 vpush_tokc(VT_LLONG
);
7370 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
7374 vpush_tokc(VT_FLOAT
);
7378 vpush_tokc(VT_DOUBLE
);
7382 vpush_tokc(VT_LDOUBLE
);
7385 case TOK___FUNCTION__
:
7387 goto tok_identifier
;
7393 /* special function name identifier */
7394 len
= strlen(funcname
) + 1;
7395 /* generate char[len] type */
7400 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
7401 ptr
= section_ptr_add(data_section
, len
);
7402 memcpy(ptr
, funcname
, len
);
7407 #ifdef TCC_TARGET_PE
7408 t
= VT_SHORT
| VT_UNSIGNED
;
7414 /* string parsing */
7417 if (tcc_state
->warn_write_strings
)
7422 memset(&ad
, 0, sizeof(AttributeDef
));
7423 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
7428 if (parse_btype(&type
, &ad
)) {
7429 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
7431 /* check ISOC99 compound literal */
7433 /* data is allocated locally by default */
7438 /* all except arrays are lvalues */
7439 if (!(type
.t
& VT_ARRAY
))
7440 r
|= lvalue_type(type
.t
);
7441 memset(&ad
, 0, sizeof(AttributeDef
));
7442 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
7447 } else if (tok
== '{') {
7448 /* save all registers */
7450 /* statement expression : we do not accept break/continue
7451 inside as GCC does */
7452 block(NULL
, NULL
, NULL
, NULL
, 0, 1);
7467 /* functions names must be treated as function pointers,
7468 except for unary '&' and sizeof. Since we consider that
7469 functions are not lvalues, we only have to handle it
7470 there and in function calls. */
7471 /* arrays can also be used although they are not lvalues */
7472 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
7473 !(vtop
->type
.t
& VT_ARRAY
) && !(vtop
->type
.t
& VT_LLOCAL
))
7475 mk_pointer(&vtop
->type
);
7481 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
7482 vtop
->c
.i
= !vtop
->c
.i
;
7483 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
7484 vtop
->c
.i
= vtop
->c
.i
^ 1;
7487 vseti(VT_JMP
, gtst(1, 0));
7498 /* in order to force cast, we add zero */
7500 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
7501 error("pointer not accepted for unary plus");
7511 parse_expr_type(&type
);
7515 size
= type_size(&type
, &align
);
7516 if (t
== TOK_SIZEOF
) {
7518 error("sizeof applied to an incomplete type");
7523 vtop
->type
.t
|= VT_UNSIGNED
;
7526 case TOK_builtin_types_compatible_p
:
7535 type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7536 type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7537 vpushi(is_compatible_types(&type1
, &type2
));
7540 case TOK_builtin_constant_p
:
7542 int saved_nocode_wanted
, res
;
7545 saved_nocode_wanted
= nocode_wanted
;
7548 res
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
7550 nocode_wanted
= saved_nocode_wanted
;
7570 goto tok_identifier
;
7572 /* allow to take the address of a label */
7573 if (tok
< TOK_UIDENT
)
7574 expect("label identifier");
7575 s
= label_find(tok
);
7577 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7579 if (s
->r
== LABEL_DECLARED
)
7580 s
->r
= LABEL_FORWARD
;
7583 s
->type
.t
= VT_VOID
;
7584 mk_pointer(&s
->type
);
7585 s
->type
.t
|= VT_STATIC
;
7587 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
7596 expect("identifier");
7600 error("'%s' undeclared", get_tok_str(t
, NULL
));
7601 /* for simple function calls, we tolerate undeclared
7602 external reference to int() function */
7603 if (tcc_state
->warn_implicit_function_declaration
)
7604 warning("implicit declaration of function '%s'",
7605 get_tok_str(t
, NULL
));
7606 s
= external_global_sym(t
, &func_old_type
, 0);
7608 if ((s
->type
.t
& (VT_STATIC
| VT_INLINE
| VT_BTYPE
)) ==
7609 (VT_STATIC
| VT_INLINE
| VT_FUNC
)) {
7610 /* if referencing an inline function, then we generate a
7611 symbol to it if not already done. It will have the
7612 effect to generate code for it at the end of the
7613 compilation unit. Inline function as always
7614 generated in the text section. */
7616 put_extern_sym(s
, text_section
, 0, 0);
7617 r
= VT_SYM
| VT_CONST
;
7621 vset(&s
->type
, r
, s
->c
);
7622 /* if forward reference, we must point to s */
7623 if (vtop
->r
& VT_SYM
) {
7630 /* post operations */
7632 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
7635 } else if (tok
== '.' || tok
== TOK_ARROW
) {
7637 if (tok
== TOK_ARROW
)
7642 /* expect pointer on structure */
7643 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
7644 expect("struct or union");
7648 while ((s
= s
->next
) != NULL
) {
7653 error("field not found");
7654 /* add field offset to pointer */
7655 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
7658 /* change type to field type, and set to lvalue */
7659 vtop
->type
= s
->type
;
7660 /* an array is never an lvalue */
7661 if (!(vtop
->type
.t
& VT_ARRAY
)) {
7662 vtop
->r
|= lvalue_type(vtop
->type
.t
);
7663 /* if bound checking, the referenced pointer must be checked */
7664 if (do_bounds_check
)
7665 vtop
->r
|= VT_MUSTBOUND
;
7668 } else if (tok
== '[') {
7674 } else if (tok
== '(') {
7680 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
7681 /* pointer test (no array accepted) */
7682 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
7683 vtop
->type
= *pointed_type(&vtop
->type
);
7684 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
7688 expect("function pointer");
7691 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
7693 /* get return type */
7696 sa
= s
->next
; /* first parameter */
7699 /* compute first implicit argument if a structure is returned */
7700 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
7701 /* get some space for the returned structure */
7702 size
= type_size(&s
->type
, &align
);
7703 loc
= (loc
- size
) & -align
;
7705 ret
.r
= VT_LOCAL
| VT_LVAL
;
7706 /* pass it as 'int' to avoid structure arg passing
7708 vseti(VT_LOCAL
, loc
);
7713 /* return in register */
7714 if (is_float(ret
.type
.t
)) {
7717 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
7726 gfunc_param_typed(s
, sa
);
7736 error("too few arguments to function");
7738 if (!nocode_wanted
) {
7739 gfunc_call(nb_args
);
7741 vtop
-= (nb_args
+ 1);
7744 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
7752 static void uneq(void)
7758 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
7759 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
7760 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
7775 static void expr_prod(void)
7780 while (tok
== '*' || tok
== '/' || tok
== '%') {
7788 static void expr_sum(void)
7793 while (tok
== '+' || tok
== '-') {
7801 static void expr_shift(void)
7806 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
7814 static void expr_cmp(void)
7819 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
7820 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
7828 static void expr_cmpeq(void)
7833 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
7841 static void expr_and(void)
7844 while (tok
== '&') {
7851 static void expr_xor(void)
7854 while (tok
== '^') {
7861 static void expr_or(void)
7864 while (tok
== '|') {
7871 /* XXX: fix this mess */
7872 static void expr_land_const(void)
7875 while (tok
== TOK_LAND
) {
7882 /* XXX: fix this mess */
7883 static void expr_lor_const(void)
7886 while (tok
== TOK_LOR
) {
7893 /* only used if non constant */
7894 static void expr_land(void)
7899 if (tok
== TOK_LAND
) {
7904 if (tok
!= TOK_LAND
) {
7914 static void expr_lor(void)
7919 if (tok
== TOK_LOR
) {
7924 if (tok
!= TOK_LOR
) {
7934 /* XXX: better constant handling */
7935 static void expr_eq(void)
7937 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
7939 CType type
, type1
, type2
;
7948 if (tok
== ':' && gnu_ext
) {
7964 if (vtop
!= vstack
) {
7965 /* needed to avoid having different registers saved in
7967 if (is_float(vtop
->type
.t
))
7974 if (tok
== ':' && gnu_ext
) {
7982 sv
= *vtop
; /* save value to handle it later */
7983 vtop
--; /* no vpop so that FP stack is not flushed */
7991 bt1
= t1
& VT_BTYPE
;
7993 bt2
= t2
& VT_BTYPE
;
7994 /* cast operands to correct type according to ISOC rules */
7995 if (is_float(bt1
) || is_float(bt2
)) {
7996 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
7997 type
.t
= VT_LDOUBLE
;
7998 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
8003 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
8004 /* cast to biggest op */
8006 /* convert to unsigned if it does not fit in a long long */
8007 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
8008 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
8009 type
.t
|= VT_UNSIGNED
;
8010 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
8011 /* XXX: test pointer compatibility */
8013 } else if (bt1
== VT_FUNC
|| bt2
== VT_FUNC
) {
8014 /* XXX: test function pointer compatibility */
8016 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
8017 /* XXX: test structure compatibility */
8019 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
8020 /* NOTE: as an extension, we accept void on only one side */
8023 /* integer operations */
8025 /* convert to unsigned if it does not fit in an integer */
8026 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
8027 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
8028 type
.t
|= VT_UNSIGNED
;
8031 /* now we convert second operand */
8033 if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
8036 if (is_float(type
.t
)) {
8038 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
8039 /* for long longs, we use fixed registers to avoid having
8040 to handle a complicated move */
8045 /* this is horrible, but we must also convert first
8049 /* put again first value and cast it */
8052 if (VT_STRUCT
== (vtop
->type
.t
& VT_BTYPE
))
8062 static void gexpr(void)
8073 /* parse an expression and return its type without any side effect. */
8074 static void expr_type(CType
*type
)
8076 int saved_nocode_wanted
;
8078 saved_nocode_wanted
= nocode_wanted
;
8083 nocode_wanted
= saved_nocode_wanted
;
8086 /* parse a unary expression and return its type without any side
8088 static void unary_type(CType
*type
)
8100 /* parse a constant expression and return value in vtop. */
8101 static void expr_const1(void)
8110 /* parse an integer constant and return its value. */
8111 static int expr_const(void)
8115 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
8116 expect("constant expression");
8122 /* return the label token if current token is a label, otherwise
8124 static int is_label(void)
8128 /* fast test first */
8129 if (tok
< TOK_UIDENT
)
8131 /* no need to save tokc because tok is an identifier */
8138 unget_tok(last_tok
);
8143 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
8144 int case_reg
, int is_expr
)
8149 /* generate line number info */
8151 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
8152 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
8154 last_line_num
= file
->line_num
;
8158 /* default return value is (void) */
8160 vtop
->type
.t
= VT_VOID
;
8163 if (tok
== TOK_IF
) {
8170 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
8172 if (c
== TOK_ELSE
) {
8176 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
8177 gsym(d
); /* patch else jmp */
8180 } else if (tok
== TOK_WHILE
) {
8188 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
8192 } else if (tok
== '{') {
8196 /* record local declaration stack position */
8198 llabel
= local_label_stack
;
8199 /* handle local labels declarations */
8200 if (tok
== TOK_LABEL
) {
8203 if (tok
< TOK_UIDENT
)
8204 expect("label identifier");
8205 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
8215 while (tok
!= '}') {
8220 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
8223 /* pop locally defined labels */
8224 label_pop(&local_label_stack
, llabel
);
8225 /* pop locally defined symbols */
8226 sym_pop(&local_stack
, s
);
8228 } else if (tok
== TOK_RETURN
) {
8232 gen_assign_cast(&func_vt
);
8233 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
8235 /* if returning structure, must copy it to implicit
8236 first pointer arg location */
8239 size
= type_size(&func_vt
,&align
);
8242 if((vtop
->r
!= (VT_LOCAL
| VT_LVAL
) || (vtop
->c
.i
& 3))
8246 loc
= (loc
- size
) & -4;
8249 vset(&type
, VT_LOCAL
| VT_LVAL
, addr
);
8252 vset(&int_type
, VT_LOCAL
| VT_LVAL
, addr
);
8254 vtop
->type
= int_type
;
8260 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
8263 /* copy structure value to pointer */
8268 } else if (is_float(func_vt
.t
)) {
8273 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
8276 rsym
= gjmp(rsym
); /* jmp */
8277 } else if (tok
== TOK_BREAK
) {
8280 error("cannot break");
8281 *bsym
= gjmp(*bsym
);
8284 } else if (tok
== TOK_CONTINUE
) {
8287 error("cannot continue");
8288 *csym
= gjmp(*csym
);
8291 } else if (tok
== TOK_FOR
) {
8318 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
8323 if (tok
== TOK_DO
) {
8328 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
8339 if (tok
== TOK_SWITCH
) {
8343 /* XXX: other types than integer */
8344 case_reg
= gv(RC_INT
);
8348 b
= gjmp(0); /* jump to first case */
8350 block(&a
, csym
, &b
, &c
, case_reg
, 0);
8351 /* if no default, jmp after switch */
8359 if (tok
== TOK_CASE
) {
8366 if (gnu_ext
&& tok
== TOK_DOTS
) {
8370 warning("empty case range");
8372 /* since a case is like a label, we must skip it with a jmp */
8379 *case_sym
= gtst(1, 0);
8382 *case_sym
= gtst(1, 0);
8386 *case_sym
= gtst(1, *case_sym
);
8391 goto block_after_label
;
8393 if (tok
== TOK_DEFAULT
) {
8399 error("too many 'default'");
8402 goto block_after_label
;
8404 if (tok
== TOK_GOTO
) {
8406 if (tok
== '*' && gnu_ext
) {
8410 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
8413 } else if (tok
>= TOK_UIDENT
) {
8414 s
= label_find(tok
);
8415 /* put forward definition if needed */
8417 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
8419 if (s
->r
== LABEL_DECLARED
)
8420 s
->r
= LABEL_FORWARD
;
8422 /* label already defined */
8423 if (s
->r
& LABEL_FORWARD
)
8424 s
->next
= (void *)gjmp((long)s
->next
);
8426 gjmp_addr((long)s
->next
);
8429 expect("label identifier");
8432 } else if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
8440 if (s
->r
== LABEL_DEFINED
)
8441 error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
8442 gsym((long)s
->next
);
8443 s
->r
= LABEL_DEFINED
;
8445 s
= label_push(&global_label_stack
, b
, LABEL_DEFINED
);
8447 s
->next
= (void *)ind
;
8448 /* we accept this, but it is a mistake */
8451 warning("deprecated use of label at end of compound statement");
8455 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
8458 /* expression case */
8473 /* t is the array or struct type. c is the array or struct
8474 address. cur_index/cur_field is the pointer to the current
8475 value. 'size_only' is true if only size info is needed (only used
8477 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
8478 int *cur_index
, Sym
**cur_field
,
8482 int notfirst
, index
, index_last
, align
, l
, nb_elems
, elem_size
;
8488 if (gnu_ext
&& (l
= is_label()) != 0)
8490 while (tok
== '[' || tok
== '.') {
8492 if (!(type
->t
& VT_ARRAY
))
8493 expect("array type");
8496 index
= expr_const();
8497 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
8498 expect("invalid index");
8499 if (tok
== TOK_DOTS
&& gnu_ext
) {
8501 index_last
= expr_const();
8502 if (index_last
< 0 ||
8503 (s
->c
>= 0 && index_last
>= s
->c
) ||
8505 expect("invalid index");
8511 *cur_index
= index_last
;
8512 type
= pointed_type(type
);
8513 elem_size
= type_size(type
, &align
);
8514 c
+= index
* elem_size
;
8515 /* NOTE: we only support ranges for last designator */
8516 nb_elems
= index_last
- index
+ 1;
8517 if (nb_elems
!= 1) {
8526 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
8527 expect("struct/union type");
8540 /* XXX: fix this mess by using explicit storage field */
8542 type1
.t
|= (type
->t
& ~VT_TYPE
);
8556 if (type
->t
& VT_ARRAY
) {
8558 type
= pointed_type(type
);
8559 c
+= index
* type_size(type
, &align
);
8563 error("too many field init");
8564 /* XXX: fix this mess by using explicit storage field */
8566 type1
.t
|= (type
->t
& ~VT_TYPE
);
8571 decl_initializer(type
, sec
, c
, 0, size_only
);
8573 /* XXX: make it more general */
8574 if (!size_only
&& nb_elems
> 1) {
8575 unsigned long c_end
;
8580 error("range init not supported yet for dynamic storage");
8581 c_end
= c
+ nb_elems
* elem_size
;
8582 if (c_end
> sec
->data_allocated
)
8583 section_realloc(sec
, c_end
);
8584 src
= sec
->data
+ c
;
8586 for(i
= 1; i
< nb_elems
; i
++) {
8588 memcpy(dst
, src
, elem_size
);
8594 #define EXPR_CONST 1
8597 /* store a value or an expression directly in global data or in local array */
8598 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
8599 int v
, int expr_type
)
8601 int saved_global_expr
, bt
, bit_pos
, bit_size
;
8603 unsigned long long bit_mask
;
8611 /* compound literals must be allocated globally in this case */
8612 saved_global_expr
= global_expr
;
8615 global_expr
= saved_global_expr
;
8616 /* NOTE: symbols are accepted */
8617 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
8618 error("initializer element is not constant");
8626 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
8629 /* XXX: not portable */
8630 /* XXX: generate error if incorrect relocation */
8631 gen_assign_cast(&dtype
);
8632 bt
= type
->t
& VT_BTYPE
;
8633 ptr
= sec
->data
+ c
;
8634 /* XXX: make code faster ? */
8635 if (!(type
->t
& VT_BITFIELD
)) {
8640 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
8641 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
8642 bit_mask
= (1LL << bit_size
) - 1;
8644 if ((vtop
->r
& VT_SYM
) &&
8650 (bt
== VT_INT
&& bit_size
!= 32)))
8651 error("initializer element is not computable at load time");
8654 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8657 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8660 *(double *)ptr
= vtop
->c
.d
;
8663 *(long double *)ptr
= vtop
->c
.ld
;
8666 *(long long *)ptr
|= (vtop
->c
.ll
& bit_mask
) << bit_pos
;
8669 if (vtop
->r
& VT_SYM
) {
8670 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
8672 *(int *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8677 vset(&dtype
, VT_LOCAL
|VT_LVAL
, c
);
8684 /* put zeros for variable based init */
8685 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
8688 /* nothing to do because globals are already set to zero */
8690 vpush_global_sym(&func_old_type
, TOK_memset
);
8698 /* 't' contains the type and storage info. 'c' is the offset of the
8699 object in section 'sec'. If 'sec' is NULL, it means stack based
8700 allocation. 'first' is true if array '{' must be read (multi
8701 dimension implicit array init handling). 'size_only' is true if
8702 size only evaluation is wanted (only for arrays). */
8703 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
8704 int first
, int size_only
)
8706 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
8707 int size1
, align1
, expr_type
;
8711 if (type
->t
& VT_ARRAY
) {
8715 t1
= pointed_type(type
);
8716 size1
= type_size(t1
, &align1
);
8719 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
8725 /* only parse strings here if correct type (otherwise: handle
8726 them as ((w)char *) expressions */
8727 if ((tok
== TOK_LSTR
&&
8728 #ifdef TCC_TARGET_PE
8729 (t1
->t
& VT_BTYPE
) == VT_SHORT
&& (t1
->t
& VT_UNSIGNED
)
8731 (t1
->t
& VT_BTYPE
) == VT_INT
8733 ) || (tok
== TOK_STR
&& (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
8734 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8739 /* compute maximum number of chars wanted */
8741 cstr_len
= cstr
->size
;
8743 cstr_len
= cstr
->size
/ sizeof(nwchar_t
);
8746 if (n
>= 0 && nb
> (n
- array_length
))
8747 nb
= n
- array_length
;
8750 warning("initializer-string for array is too long");
8751 /* in order to go faster for common case (char
8752 string in global variable, we handle it
8754 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
8755 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
8759 ch
= ((unsigned char *)cstr
->data
)[i
];
8761 ch
= ((nwchar_t
*)cstr
->data
)[i
];
8762 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
8770 /* only add trailing zero if enough storage (no
8771 warning in this case since it is standard) */
8772 if (n
< 0 || array_length
< n
) {
8774 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
8780 while (tok
!= '}') {
8781 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
8782 if (n
>= 0 && index
>= n
)
8783 error("index too large");
8784 /* must put zero in holes (note that doing it that way
8785 ensures that it even works with designators) */
8786 if (!size_only
&& array_length
< index
) {
8787 init_putz(t1
, sec
, c
+ array_length
* size1
,
8788 (index
- array_length
) * size1
);
8791 if (index
> array_length
)
8792 array_length
= index
;
8793 /* special test for multi dimensional arrays (may not
8794 be strictly correct if designators are used at the
8796 if (index
>= n
&& no_oblock
)
8805 /* put zeros at the end */
8806 if (!size_only
&& n
>= 0 && array_length
< n
) {
8807 init_putz(t1
, sec
, c
+ array_length
* size1
,
8808 (n
- array_length
) * size1
);
8810 /* patch type size if needed */
8812 s
->c
= array_length
;
8813 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
8814 (sec
|| !first
|| tok
== '{')) {
8817 /* NOTE: the previous test is a specific case for automatic
8818 struct/union init */
8819 /* XXX: union needs only one init */
8821 /* XXX: this test is incorrect for local initializers
8822 beginning with ( without {. It would be much more difficult
8823 to do it correctly (ideally, the expression parser should
8824 be used in all cases) */
8830 while (tok
== '(') {
8834 if (!parse_btype(&type1
, &ad1
))
8836 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
8838 if (!is_assignable_types(type
, &type1
))
8839 error("invalid type for cast");
8844 if (first
|| tok
== '{') {
8853 while (tok
!= '}') {
8854 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
8856 if (!size_only
&& array_length
< index
) {
8857 init_putz(type
, sec
, c
+ array_length
,
8858 index
- array_length
);
8860 index
= index
+ type_size(&f
->type
, &align1
);
8861 if (index
> array_length
)
8862 array_length
= index
;
8864 if (no_oblock
&& f
== NULL
)
8870 /* put zeros at the end */
8871 if (!size_only
&& array_length
< n
) {
8872 init_putz(type
, sec
, c
+ array_length
,
8881 } else if (tok
== '{') {
8883 decl_initializer(type
, sec
, c
, first
, size_only
);
8885 } else if (size_only
) {
8886 /* just skip expression */
8888 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
8892 else if (tok
== ')')
8897 /* currently, we always use constant expression for globals
8898 (may change for scripting case) */
8899 expr_type
= EXPR_CONST
;
8901 expr_type
= EXPR_ANY
;
8902 init_putv(type
, sec
, c
, 0, expr_type
);
8906 /* parse an initializer for type 't' if 'has_init' is non zero, and
8907 allocate space in local or global data space ('r' is either
8908 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8909 variable 'v' of scope 'scope' is declared before initializers are
8910 parsed. If 'v' is zero, then a reference to the new object is put
8911 in the value stack. If 'has_init' is 2, a special parsing is done
8912 to handle string constants. */
8913 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
8914 int has_init
, int v
, int scope
)
8916 int size
, align
, addr
, data_offset
;
8918 ParseState saved_parse_state
;
8919 TokenString init_str
;
8922 size
= type_size(type
, &align
);
8923 /* If unknown size, we must evaluate it before
8924 evaluating initializers because
8925 initializers can generate global data too
8926 (e.g. string pointers or ISOC99 compound
8927 literals). It also simplifies local
8928 initializers handling */
8929 tok_str_new(&init_str
);
8932 error("unknown type size");
8933 /* get all init string */
8934 if (has_init
== 2) {
8935 /* only get strings */
8936 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8937 tok_str_add_tok(&init_str
);
8942 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
8944 error("unexpected end of file in initializer");
8945 tok_str_add_tok(&init_str
);
8948 else if (tok
== '}') {
8956 tok_str_add(&init_str
, -1);
8957 tok_str_add(&init_str
, 0);
8960 save_parse_state(&saved_parse_state
);
8962 macro_ptr
= init_str
.str
;
8964 decl_initializer(type
, NULL
, 0, 1, 1);
8965 /* prepare second initializer parsing */
8966 macro_ptr
= init_str
.str
;
8969 /* if still unknown size, error */
8970 size
= type_size(type
, &align
);
8972 error("unknown type size");
8974 /* take into account specified alignment if bigger */
8976 if (ad
->aligned
> align
)
8977 align
= ad
->aligned
;
8978 } else if (ad
->packed
) {
8981 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
8983 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
8985 loc
= (loc
- size
) & -align
;
8987 /* handles bounds */
8988 /* XXX: currently, since we do only one pass, we cannot track
8989 '&' operators, so we add only arrays */
8990 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
8991 unsigned long *bounds_ptr
;
8992 /* add padding between regions */
8994 /* then add local bound info */
8995 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
8996 bounds_ptr
[0] = addr
;
8997 bounds_ptr
[1] = size
;
9000 /* local variable */
9001 sym_push(v
, type
, r
, addr
);
9003 /* push local reference */
9004 vset(type
, r
, addr
);
9010 if (v
&& scope
== VT_CONST
) {
9011 /* see if the symbol was already defined */
9014 if (!is_compatible_types(&sym
->type
, type
))
9015 error("incompatible types for redefinition of '%s'",
9016 get_tok_str(v
, NULL
));
9017 if (sym
->type
.t
& VT_EXTERN
) {
9018 /* if the variable is extern, it was not allocated */
9019 sym
->type
.t
&= ~VT_EXTERN
;
9020 /* set array size if it was ommited in extern
9022 if ((sym
->type
.t
& VT_ARRAY
) &&
9023 sym
->type
.ref
->c
< 0 &&
9025 sym
->type
.ref
->c
= type
->ref
->c
;
9027 /* we accept several definitions of the same
9028 global variable. this is tricky, because we
9029 must play with the SHN_COMMON type of the symbol */
9030 /* XXX: should check if the variable was already
9031 initialized. It is incorrect to initialized it
9033 /* no init data, we won't add more to the symbol */
9040 /* allocate symbol in corresponding section */
9045 else if (tcc_state
->nocommon
)
9049 data_offset
= sec
->data_offset
;
9050 data_offset
= (data_offset
+ align
- 1) & -align
;
9052 /* very important to increment global pointer at this time
9053 because initializers themselves can create new initializers */
9054 data_offset
+= size
;
9055 /* add padding if bound check */
9056 if (do_bounds_check
)
9058 sec
->data_offset
= data_offset
;
9059 /* allocate section space to put the data */
9060 if (sec
->sh_type
!= SHT_NOBITS
&&
9061 data_offset
> sec
->data_allocated
)
9062 section_realloc(sec
, data_offset
);
9063 /* align section if needed */
9064 if (align
> sec
->sh_addralign
)
9065 sec
->sh_addralign
= align
;
9067 addr
= 0; /* avoid warning */
9071 if (scope
!= VT_CONST
|| !sym
) {
9072 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
9074 /* update symbol definition */
9076 put_extern_sym(sym
, sec
, addr
, size
);
9079 /* put a common area */
9080 put_extern_sym(sym
, NULL
, align
, size
);
9081 /* XXX: find a nicer way */
9082 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
9083 esym
->st_shndx
= SHN_COMMON
;
9088 /* push global reference */
9089 sym
= get_sym_ref(type
, sec
, addr
, size
);
9091 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
9095 /* handles bounds now because the symbol must be defined
9096 before for the relocation */
9097 if (do_bounds_check
) {
9098 unsigned long *bounds_ptr
;
9100 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
9101 /* then add global bound info */
9102 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
9103 bounds_ptr
[0] = 0; /* relocated */
9104 bounds_ptr
[1] = size
;
9108 decl_initializer(type
, sec
, addr
, 1, 0);
9109 /* restore parse state if needed */
9111 tok_str_free(init_str
.str
);
9112 restore_parse_state(&saved_parse_state
);
9118 void put_func_debug(Sym
*sym
)
9123 /* XXX: we put here a dummy type */
9124 snprintf(buf
, sizeof(buf
), "%s:%c1",
9125 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
9126 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
9127 cur_text_section
, sym
->c
);
9132 /* parse an old style function declaration list */
9133 /* XXX: check multiple parameter */
9134 static void func_decl_list(Sym
*func_sym
)
9141 /* parse each declaration */
9142 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
) {
9143 if (!parse_btype(&btype
, &ad
))
9144 expect("declaration list");
9145 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
9146 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
9148 /* we accept no variable after */
9152 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
9153 /* find parameter in function parameter list */
9156 if ((s
->v
& ~SYM_FIELD
) == v
)
9160 error("declaration for parameter '%s' but no such parameter",
9161 get_tok_str(v
, NULL
));
9163 /* check that no storage specifier except 'register' was given */
9164 if (type
.t
& VT_STORAGE
)
9165 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
9166 convert_parameter_type(&type
);
9167 /* we can add the type (NOTE: it could be local to the function) */
9169 /* accept other parameters */
9180 /* parse a function defined by symbol 'sym' and generate its code in
9181 'cur_text_section' */
9182 static void gen_function(Sym
*sym
)
9184 int saved_nocode_wanted
= nocode_wanted
;
9186 ind
= cur_text_section
->data_offset
;
9187 /* NOTE: we patch the symbol size later */
9188 put_extern_sym(sym
, cur_text_section
, ind
, 0);
9189 funcname
= get_tok_str(sym
->v
, NULL
);
9191 /* put debug symbol */
9193 put_func_debug(sym
);
9194 /* push a dummy symbol to enable local sym storage */
9195 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
9196 gfunc_prolog(&sym
->type
);
9198 block(NULL
, NULL
, NULL
, NULL
, 0, 0);
9201 cur_text_section
->data_offset
= ind
;
9202 label_pop(&global_label_stack
, NULL
);
9203 sym_pop(&local_stack
, NULL
); /* reset local stack */
9204 /* end of function */
9205 /* patch symbol size */
9206 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
9209 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
9211 funcname
= ""; /* for safety */
9212 func_vt
.t
= VT_VOID
; /* for safety */
9213 ind
= 0; /* for safety */
9214 nocode_wanted
= saved_nocode_wanted
;
9217 static void gen_inline_functions(void)
9221 int *str
, inline_generated
;
9223 /* iterate while inline function are referenced */
9225 inline_generated
= 0;
9226 for(sym
= global_stack
; sym
!= NULL
; sym
= sym
->prev
) {
9228 if (((type
->t
& VT_BTYPE
) == VT_FUNC
) &&
9229 (type
->t
& (VT_STATIC
| VT_INLINE
)) ==
9230 (VT_STATIC
| VT_INLINE
) &&
9232 /* the function was used: generate its code and
9233 convert it to a normal function */
9234 str
= INLINE_DEF(sym
->r
);
9235 sym
->r
= VT_SYM
| VT_CONST
;
9236 sym
->type
.t
&= ~VT_INLINE
;
9240 cur_text_section
= text_section
;
9242 macro_ptr
= NULL
; /* fail safe */
9245 inline_generated
= 1;
9248 if (!inline_generated
)
9252 /* free all remaining inline function tokens */
9253 for(sym
= global_stack
; sym
!= NULL
; sym
= sym
->prev
) {
9255 if (((type
->t
& VT_BTYPE
) == VT_FUNC
) &&
9256 (type
->t
& (VT_STATIC
| VT_INLINE
)) ==
9257 (VT_STATIC
| VT_INLINE
)) {
9258 //gr printf("sym %d %s\n", sym->r, get_tok_str(sym->v, NULL));
9259 if (sym
->r
== (VT_SYM
| VT_CONST
)) //gr beware!
9261 str
= INLINE_DEF(sym
->r
);
9263 sym
->r
= 0; /* fail safe */
9268 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
9269 static void decl(int l
)
9277 if (!parse_btype(&btype
, &ad
)) {
9278 /* skip redundant ';' */
9279 /* XXX: find more elegant solution */
9284 if (l
== VT_CONST
&&
9285 (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
9286 /* global asm block */
9290 /* special test for old K&R protos without explicit int
9291 type. Only accepted when defining global data */
9292 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
9296 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
9297 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
9299 /* we accept no variable after */
9303 while (1) { /* iterate thru each declaration */
9305 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
9309 type_to_str(buf
, sizeof(buf
), &type
, get_tok_str(v
, NULL
));
9310 printf("type = '%s'\n", buf
);
9313 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
9314 /* if old style function prototype, we accept a
9317 if (sym
->c
== FUNC_OLD
)
9318 func_decl_list(sym
);
9323 error("cannot use local functions");
9324 if ((type
.t
& VT_BTYPE
) != VT_FUNC
)
9325 expect("function definition");
9327 /* reject abstract declarators in function definition */
9329 while ((sym
= sym
->next
) != NULL
)
9330 if (!(sym
->v
& ~SYM_FIELD
))
9331 expect("identifier");
9333 /* XXX: cannot do better now: convert extern line to static inline */
9334 if ((type
.t
& (VT_EXTERN
| VT_INLINE
)) == (VT_EXTERN
| VT_INLINE
))
9335 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
9339 if ((sym
->type
.t
& VT_BTYPE
) != VT_FUNC
)
9341 /* specific case: if not func_call defined, we put
9342 the one of the prototype */
9343 /* XXX: should have default value */
9344 r
= sym
->type
.ref
->r
;
9345 if (FUNC_CALL(r
) != FUNC_CDECL
9346 && FUNC_CALL(type
.ref
->r
) == FUNC_CDECL
)
9347 FUNC_CALL(type
.ref
->r
) = FUNC_CALL(r
);
9349 FUNC_EXPORT(type
.ref
->r
) = 1;
9351 if (!is_compatible_types(&sym
->type
, &type
)) {
9353 error("incompatible types for redefinition of '%s'",
9354 get_tok_str(v
, NULL
));
9356 /* if symbol is already defined, then put complete type */
9359 /* put function symbol */
9360 sym
= global_identifier_push(v
, type
.t
, 0);
9361 sym
->type
.ref
= type
.ref
;
9364 /* static inline functions are just recorded as a kind
9365 of macro. Their code will be emitted at the end of
9366 the compilation unit only if they are used */
9367 if ((type
.t
& (VT_INLINE
| VT_STATIC
)) ==
9368 (VT_INLINE
| VT_STATIC
)) {
9369 TokenString func_str
;
9372 tok_str_new(&func_str
);
9378 error("unexpected end of file");
9379 tok_str_add_tok(&func_str
);
9384 } else if (t
== '}') {
9386 if (block_level
== 0)
9390 tok_str_add(&func_str
, -1);
9391 tok_str_add(&func_str
, 0);
9392 INLINE_DEF(sym
->r
) = func_str
.str
;
9394 /* compute text section */
9395 cur_text_section
= ad
.section
;
9396 if (!cur_text_section
)
9397 cur_text_section
= text_section
;
9398 sym
->r
= VT_SYM
| VT_CONST
;
9403 if (btype
.t
& VT_TYPEDEF
) {
9404 /* save typedefed type */
9405 /* XXX: test storage specifiers ? */
9406 sym
= sym_push(v
, &type
, 0, 0);
9407 sym
->type
.t
|= VT_TYPEDEF
;
9408 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
9409 /* external function definition */
9410 /* specific case for func_call attribute */
9412 type
.ref
->r
= ad
.func_attr
;
9413 external_sym(v
, &type
, 0);
9415 /* not lvalue if array */
9417 if (!(type
.t
& VT_ARRAY
))
9418 r
|= lvalue_type(type
.t
);
9419 has_init
= (tok
== '=');
9420 if ((btype
.t
& VT_EXTERN
) ||
9421 ((type
.t
& VT_ARRAY
) && (type
.t
& VT_STATIC
) &&
9422 !has_init
&& l
== VT_CONST
&& type
.ref
->c
< 0)) {
9423 /* external variable */
9424 /* NOTE: as GCC, uninitialized global static
9425 arrays of null size are considered as
9427 external_sym(v
, &type
, r
);
9429 type
.t
|= (btype
.t
& VT_STATIC
); /* Retain "static". */
9430 if (type
.t
& VT_STATIC
)
9436 decl_initializer_alloc(&type
, &ad
, r
,
9450 /* better than nothing, but needs extension to handle '-E' option
9452 static void preprocess_init(TCCState
*s1
)
9454 s1
->include_stack_ptr
= s1
->include_stack
;
9455 /* XXX: move that before to avoid having to initialize
9456 file->ifdef_stack_ptr ? */
9457 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
9458 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
9460 /* XXX: not ANSI compliant: bound checking says error */
9462 s1
->pack_stack
[0] = 0;
9463 s1
->pack_stack_ptr
= s1
->pack_stack
;
9466 /* compile the C file opened in 'file'. Return non zero if errors. */
9467 static int tcc_compile(TCCState
*s1
)
9471 volatile int section_sym
;
9474 printf("%s: **** new file\n", file
->filename
);
9476 preprocess_init(s1
);
9479 anon_sym
= SYM_FIRST_ANOM
;
9481 /* file info: full path + filename */
9482 section_sym
= 0; /* avoid warning */
9484 section_sym
= put_elf_sym(symtab_section
, 0, 0,
9485 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
9486 text_section
->sh_num
, NULL
);
9487 getcwd(buf
, sizeof(buf
));
9489 normalize_slashes(buf
);
9491 pstrcat(buf
, sizeof(buf
), "/");
9492 put_stabs_r(buf
, N_SO
, 0, 0,
9493 text_section
->data_offset
, text_section
, section_sym
);
9494 put_stabs_r(file
->filename
, N_SO
, 0, 0,
9495 text_section
->data_offset
, text_section
, section_sym
);
9497 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
9498 symbols can be safely used */
9499 put_elf_sym(symtab_section
, 0, 0,
9500 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
9501 SHN_ABS
, file
->filename
);
9503 /* define some often used types */
9504 int_type
.t
= VT_INT
;
9506 char_pointer_type
.t
= VT_BYTE
;
9507 mk_pointer(&char_pointer_type
);
9509 func_old_type
.t
= VT_FUNC
;
9510 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
9512 #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
9513 float_type
.t
= VT_FLOAT
;
9514 double_type
.t
= VT_DOUBLE
;
9516 func_float_type
.t
= VT_FUNC
;
9517 func_float_type
.ref
= sym_push(SYM_FIELD
, &float_type
, FUNC_CDECL
, FUNC_OLD
);
9518 func_double_type
.t
= VT_FUNC
;
9519 func_double_type
.ref
= sym_push(SYM_FIELD
, &double_type
, FUNC_CDECL
, FUNC_OLD
);
9523 /* define 'void *alloca(unsigned int)' builtin function */
9528 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
9529 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
9532 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
9536 define_start
= define_stack
;
9539 if (setjmp(s1
->error_jmp_buf
) == 0) {
9541 s1
->error_set_jmp_enabled
= 1;
9543 ch
= file
->buf_ptr
[0];
9544 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
9545 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
;
9549 expect("declaration");
9551 /* end of translation unit info */
9553 put_stabs_r(NULL
, N_SO
, 0, 0,
9554 text_section
->data_offset
, text_section
, section_sym
);
9557 s1
->error_set_jmp_enabled
= 0;
9559 /* reset define stack, but leave -Dsymbols (may be incorrect if
9560 they are undefined) */
9561 free_defines(define_start
);
9563 gen_inline_functions();
9565 sym_pop(&global_stack
, NULL
);
9567 return s1
->nb_errors
!= 0 ? -1 : 0;
9570 /* Preprocess the current file */
9571 /* XXX: add line and file infos, add options to preserve spaces */
9572 static int tcc_preprocess(TCCState
*s1
)
9577 preprocess_init(s1
);
9579 define_start
= define_stack
;
9581 ch
= file
->buf_ptr
[0];
9582 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
9583 parse_flags
= PARSE_FLAG_ASM_COMMENTS
| PARSE_FLAG_PREPROCESS
|
9584 PARSE_FLAG_LINEFEED
;
9588 if (tok
== TOK_EOF
) {
9590 } else if (tok
== TOK_LINEFEED
) {
9594 fputc(' ', s1
->outfile
);
9597 fputs(get_tok_str(tok
, &tokc
), s1
->outfile
);
9600 free_defines(define_start
);
9605 int tcc_compile_string(TCCState
*s
, const char *str
)
9607 BufferedFile bf1
, *bf
= &bf1
;
9611 /* init file structure */
9613 /* XXX: avoid copying */
9615 buf
= tcc_malloc(len
+ 1);
9618 memcpy(buf
, str
, len
);
9621 bf
->buf_end
= buf
+ len
;
9622 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
9626 ret
= tcc_compile(s
);
9630 /* currently, no need to close */
9635 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
9636 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
9638 BufferedFile bf1
, *bf
= &bf1
;
9640 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
9641 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
9645 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
9647 /* init file structure */
9649 bf
->buf_ptr
= bf
->buffer
;
9650 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
9651 *bf
->buf_end
= CH_EOB
;
9652 bf
->filename
[0] = '\0';
9656 s1
->include_stack_ptr
= s1
->include_stack
;
9658 /* parse with define parser */
9659 ch
= file
->buf_ptr
[0];
9665 /* undefine a preprocessor symbol */
9666 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
9670 ts
= tok_alloc(sym
, strlen(sym
));
9671 s
= define_find(ts
->tok
);
9672 /* undefine symbol by putting an invalid name */
9677 #ifdef CONFIG_TCC_ASM
9679 #ifdef TCC_TARGET_I386
9680 #include "i386-asm.c"
9685 static void asm_instr(void)
9687 error("inline asm() not supported");
9689 static void asm_global_instr(void)
9691 error("inline asm() not supported");
9697 #ifdef TCC_TARGET_COFF
9698 #include "tcccoff.c"
9701 #ifdef TCC_TARGET_PE
9705 /* print the position in the source file of PC value 'pc' by reading
9706 the stabs debug information */
9707 static void rt_printline(unsigned long wanted_pc
)
9709 Stab_Sym
*sym
, *sym_end
;
9710 char func_name
[128], last_func_name
[128];
9711 unsigned long func_addr
, last_pc
, pc
;
9712 const char *incl_files
[INCLUDE_STACK_SIZE
];
9713 int incl_index
, len
, last_line_num
, i
;
9714 const char *str
, *p
;
9716 fprintf(stderr
, "0x%08lx:", wanted_pc
);
9718 func_name
[0] = '\0';
9721 last_func_name
[0] = '\0';
9722 last_pc
= 0xffffffff;
9724 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
9725 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
9726 while (sym
< sym_end
) {
9727 switch(sym
->n_type
) {
9728 /* function start or end */
9730 if (sym
->n_strx
== 0) {
9731 /* we test if between last line and end of function */
9732 pc
= sym
->n_value
+ func_addr
;
9733 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9735 func_name
[0] = '\0';
9738 str
= stabstr_section
->data
+ sym
->n_strx
;
9739 p
= strchr(str
, ':');
9741 pstrcpy(func_name
, sizeof(func_name
), str
);
9744 if (len
> sizeof(func_name
) - 1)
9745 len
= sizeof(func_name
) - 1;
9746 memcpy(func_name
, str
, len
);
9747 func_name
[len
] = '\0';
9749 func_addr
= sym
->n_value
;
9752 /* line number info */
9754 pc
= sym
->n_value
+ func_addr
;
9755 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9758 last_line_num
= sym
->n_desc
;
9760 strcpy(last_func_name
, func_name
);
9764 str
= stabstr_section
->data
+ sym
->n_strx
;
9766 if (incl_index
< INCLUDE_STACK_SIZE
) {
9767 incl_files
[incl_index
++] = str
;
9775 if (sym
->n_strx
== 0) {
9776 incl_index
= 0; /* end of translation unit */
9778 str
= stabstr_section
->data
+ sym
->n_strx
;
9779 /* do not add path */
9781 if (len
> 0 && str
[len
- 1] != '/')
9789 /* second pass: we try symtab symbols (no line number info) */
9792 Elf32_Sym
*sym
, *sym_end
;
9795 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
9796 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
9799 type
= ELF32_ST_TYPE(sym
->st_info
);
9800 if (type
== STT_FUNC
) {
9801 if (wanted_pc
>= sym
->st_value
&&
9802 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
9803 pstrcpy(last_func_name
, sizeof(last_func_name
),
9804 strtab_section
->data
+ sym
->st_name
);
9810 /* did not find any info: */
9811 fprintf(stderr
, " ???\n");
9814 if (last_func_name
[0] != '\0') {
9815 fprintf(stderr
, " %s()", last_func_name
);
9817 if (incl_index
> 0) {
9818 fprintf(stderr
, " (%s:%d",
9819 incl_files
[incl_index
- 1], last_line_num
);
9820 for(i
= incl_index
- 2; i
>= 0; i
--)
9821 fprintf(stderr
, ", included from %s", incl_files
[i
]);
9822 fprintf(stderr
, ")");
9824 fprintf(stderr
, "\n");
9827 #if !defined(_WIN32) && !defined(CONFIG_TCCBOOT)
9831 /* fix for glibc 2.1 */
9837 /* return the PC at frame level 'level'. Return non zero if not found */
9838 static int rt_get_caller_pc(unsigned long *paddr
,
9839 ucontext_t
*uc
, int level
)
9845 #if defined(__FreeBSD__)
9846 *paddr
= uc
->uc_mcontext
.mc_eip
;
9847 #elif defined(__dietlibc__)
9848 *paddr
= uc
->uc_mcontext
.eip
;
9850 *paddr
= uc
->uc_mcontext
.gregs
[REG_EIP
];
9854 #if defined(__FreeBSD__)
9855 fp
= uc
->uc_mcontext
.mc_ebp
;
9856 #elif defined(__dietlibc__)
9857 fp
= uc
->uc_mcontext
.ebp
;
9859 fp
= uc
->uc_mcontext
.gregs
[REG_EBP
];
9861 for(i
=1;i
<level
;i
++) {
9862 /* XXX: check address validity with program info */
9863 if (fp
<= 0x1000 || fp
>= 0xc0000000)
9865 fp
= ((unsigned long *)fp
)[0];
9867 *paddr
= ((unsigned long *)fp
)[1];
9873 #warning add arch specific rt_get_caller_pc()
9875 static int rt_get_caller_pc(unsigned long *paddr
,
9876 ucontext_t
*uc
, int level
)
9882 /* emit a run time error at position 'pc' */
9883 void rt_error(ucontext_t
*uc
, const char *fmt
, ...)
9890 fprintf(stderr
, "Runtime error: ");
9891 vfprintf(stderr
, fmt
, ap
);
9892 fprintf(stderr
, "\n");
9893 for(i
=0;i
<num_callers
;i
++) {
9894 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
9897 fprintf(stderr
, "at ");
9899 fprintf(stderr
, "by ");
9906 /* signal handler for fatal errors */
9907 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
9909 ucontext_t
*uc
= puc
;
9913 switch(siginf
->si_code
) {
9916 rt_error(uc
, "division by zero");
9919 rt_error(uc
, "floating point exception");
9925 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
9926 rt_error(uc
, *rt_bound_error_msg
);
9928 rt_error(uc
, "dereferencing invalid pointer");
9931 rt_error(uc
, "illegal instruction");
9934 rt_error(uc
, "abort() called");
9937 rt_error(uc
, "caught signal %d", signum
);
9944 /* do all relocations (needed before using tcc_get_symbol()) */
9945 int tcc_relocate(TCCState
*s1
)
9952 #ifdef TCC_TARGET_PE
9955 tcc_add_runtime(s1
);
9958 relocate_common_syms();
9960 tcc_add_linker_symbols(s1
);
9961 #ifndef TCC_TARGET_PE
9962 build_got_entries(s1
);
9964 /* compute relocation address : section are relocated in place. We
9965 also alloc the bss space */
9966 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9967 s
= s1
->sections
[i
];
9968 if (s
->sh_flags
& SHF_ALLOC
) {
9969 if (s
->sh_type
== SHT_NOBITS
)
9970 s
->data
= tcc_mallocz(s
->data_offset
);
9971 s
->sh_addr
= (unsigned long)s
->data
;
9975 relocate_syms(s1
, 1);
9977 if (s1
->nb_errors
!= 0)
9980 /* relocate each section */
9981 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9982 s
= s1
->sections
[i
];
9984 relocate_section(s1
, s
);
9987 /* mark executable sections as executable in memory */
9988 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9989 s
= s1
->sections
[i
];
9990 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_EXECINSTR
)) ==
9991 (SHF_ALLOC
| SHF_EXECINSTR
))
9992 set_pages_executable(s
->data
, s
->data_offset
);
9997 /* launch the compiled program with the given arguments */
9998 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
10000 int (*prog_main
)(int, char **);
10002 if (tcc_relocate(s1
) < 0)
10005 prog_main
= tcc_get_symbol_err(s1
, "main");
10008 #if defined(_WIN32) || defined(CONFIG_TCCBOOT)
10009 error("debug mode currently not available for Windows");
10011 struct sigaction sigact
;
10012 /* install TCC signal handlers to print debug info on fatal
10014 sigact
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
10015 sigact
.sa_sigaction
= sig_error
;
10016 sigemptyset(&sigact
.sa_mask
);
10017 sigaction(SIGFPE
, &sigact
, NULL
);
10018 sigaction(SIGILL
, &sigact
, NULL
);
10019 sigaction(SIGSEGV
, &sigact
, NULL
);
10020 sigaction(SIGBUS
, &sigact
, NULL
);
10021 sigaction(SIGABRT
, &sigact
, NULL
);
10025 #ifdef CONFIG_TCC_BCHECK
10026 if (do_bounds_check
) {
10027 void (*bound_init
)(void);
10029 /* set error function */
10030 rt_bound_error_msg
= (void *)tcc_get_symbol_err(s1
,
10031 "__bound_error_msg");
10033 /* XXX: use .init section so that it also work in binary ? */
10034 bound_init
= (void *)tcc_get_symbol_err(s1
, "__bound_init");
10038 return (*prog_main
)(argc
, argv
);
10041 TCCState
*tcc_new(void)
10048 s
= tcc_mallocz(sizeof(TCCState
));
10052 s
->output_type
= TCC_OUTPUT_MEMORY
;
10054 /* init isid table */
10056 isidnum_table
[i
] = isid(i
) || isnum(i
);
10058 /* add all tokens */
10059 table_ident
= NULL
;
10060 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
10062 tok_ident
= TOK_IDENT
;
10071 ts
= tok_alloc(p
, r
- p
- 1);
10075 /* we add dummy defines for some special macros to speed up tests
10076 and to have working defined() */
10077 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
10078 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
10079 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
10080 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
10082 /* standard defines */
10083 tcc_define_symbol(s
, "__STDC__", NULL
);
10084 #if defined(TCC_TARGET_I386)
10085 tcc_define_symbol(s
, "__i386__", NULL
);
10087 #if defined(TCC_TARGET_ARM)
10088 tcc_define_symbol(s
, "__ARM_ARCH_4__", NULL
);
10089 tcc_define_symbol(s
, "__arm_elf__", NULL
);
10090 tcc_define_symbol(s
, "__arm_elf", NULL
);
10091 tcc_define_symbol(s
, "arm_elf", NULL
);
10092 tcc_define_symbol(s
, "__arm__", NULL
);
10093 tcc_define_symbol(s
, "__arm", NULL
);
10094 tcc_define_symbol(s
, "arm", NULL
);
10095 tcc_define_symbol(s
, "__APCS_32__", NULL
);
10097 #ifdef TCC_TARGET_PE
10098 tcc_define_symbol(s
, "_WIN32", NULL
);
10100 tcc_define_symbol(s
, "__unix__", NULL
);
10101 tcc_define_symbol(s
, "__unix", NULL
);
10102 #if defined(__linux)
10103 tcc_define_symbol(s
, "__linux__", NULL
);
10104 tcc_define_symbol(s
, "__linux", NULL
);
10107 /* tiny C specific defines */
10108 tcc_define_symbol(s
, "__TINYC__", NULL
);
10110 /* tiny C & gcc defines */
10111 tcc_define_symbol(s
, "__SIZE_TYPE__", "unsigned int");
10112 tcc_define_symbol(s
, "__PTRDIFF_TYPE__", "int");
10113 #ifdef TCC_TARGET_PE
10114 tcc_define_symbol(s
, "__WCHAR_TYPE__", "unsigned short");
10116 tcc_define_symbol(s
, "__WCHAR_TYPE__", "int");
10119 /* default library paths */
10120 #ifdef TCC_TARGET_PE
10123 snprintf(buf
, sizeof(buf
), "%s/lib", tcc_lib_path
);
10124 tcc_add_library_path(s
, buf
);
10127 tcc_add_library_path(s
, "/usr/local/lib");
10128 tcc_add_library_path(s
, "/usr/lib");
10129 tcc_add_library_path(s
, "/lib");
10132 /* no section zero */
10133 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
10135 /* create standard sections */
10136 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
10137 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
10138 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
10140 /* symbols are always generated for linking stage */
10141 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
10143 ".hashtab", SHF_PRIVATE
);
10144 strtab_section
= symtab_section
->link
;
10146 /* private symbol table for dynamic symbols */
10147 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
10149 ".dynhashtab", SHF_PRIVATE
);
10150 s
->alacarte_link
= 1;
10152 #ifdef CHAR_IS_UNSIGNED
10153 s
->char_is_unsigned
= 1;
10155 #if defined(TCC_TARGET_PE) && 0
10156 /* XXX: currently the PE linker is not ready to support that */
10157 s
->leading_underscore
= 1;
10162 void tcc_delete(TCCState
*s1
)
10166 /* free -D defines */
10167 free_defines(NULL
);
10170 n
= tok_ident
- TOK_IDENT
;
10171 for(i
= 0; i
< n
; i
++)
10172 tcc_free(table_ident
[i
]);
10173 tcc_free(table_ident
);
10175 /* free all sections */
10177 free_section(symtab_section
->hash
);
10179 free_section(s1
->dynsymtab_section
->hash
);
10180 free_section(s1
->dynsymtab_section
->link
);
10181 free_section(s1
->dynsymtab_section
);
10183 for(i
= 1; i
< s1
->nb_sections
; i
++)
10184 free_section(s1
->sections
[i
]);
10185 tcc_free(s1
->sections
);
10187 /* free loaded dlls array */
10188 dynarray_reset(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
);
10190 /* free library paths */
10191 dynarray_reset(&s1
->library_paths
, &s1
->nb_library_paths
);
10193 /* free include paths */
10194 dynarray_reset(&s1
->cached_includes
, &s1
->nb_cached_includes
);
10195 dynarray_reset(&s1
->include_paths
, &s1
->nb_include_paths
);
10196 dynarray_reset(&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
);
10201 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
10205 pathname1
= tcc_strdup(pathname
);
10206 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
10210 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
10214 pathname1
= tcc_strdup(pathname
);
10215 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
10219 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
10224 BufferedFile
*saved_file
;
10226 /* find source file type with extension */
10227 ext
= tcc_fileextension(filename
);
10231 /* open the file */
10233 file
= tcc_open(s1
, filename
);
10235 if (flags
& AFF_PRINT_ERROR
) {
10236 error_noabort("file '%s' not found", filename
);
10242 if (flags
& AFF_PREPROCESS
) {
10243 ret
= tcc_preprocess(s1
);
10244 } else if (!ext
[0] || !strcmp(ext
, "c")) {
10245 /* C file assumed */
10246 ret
= tcc_compile(s1
);
10248 #ifdef CONFIG_TCC_ASM
10249 if (!strcmp(ext
, "S")) {
10250 /* preprocessed assembler */
10251 ret
= tcc_assemble(s1
, 1);
10252 } else if (!strcmp(ext
, "s")) {
10253 /* non preprocessed assembler */
10254 ret
= tcc_assemble(s1
, 0);
10257 #ifdef TCC_TARGET_PE
10258 if (!strcmp(ext
, "def")) {
10259 ret
= pe_load_def_file(s1
, file
->fd
);
10264 /* assume executable format: auto guess file type */
10265 ret
= read(fd
, &ehdr
, sizeof(ehdr
));
10266 lseek(fd
, 0, SEEK_SET
);
10268 error_noabort("could not read header");
10270 } else if (ret
!= sizeof(ehdr
)) {
10271 goto try_load_script
;
10274 if (ehdr
.e_ident
[0] == ELFMAG0
&&
10275 ehdr
.e_ident
[1] == ELFMAG1
&&
10276 ehdr
.e_ident
[2] == ELFMAG2
&&
10277 ehdr
.e_ident
[3] == ELFMAG3
) {
10278 file
->line_num
= 0; /* do not display line number if error */
10279 if (ehdr
.e_type
== ET_REL
) {
10280 ret
= tcc_load_object_file(s1
, fd
, 0);
10281 } else if (ehdr
.e_type
== ET_DYN
) {
10282 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
10283 #ifdef TCC_TARGET_PE
10287 h
= dlopen(filename
, RTLD_GLOBAL
| RTLD_LAZY
);
10294 ret
= tcc_load_dll(s1
, fd
, filename
,
10295 (flags
& AFF_REFERENCED_DLL
) != 0);
10298 error_noabort("unrecognized ELF file");
10301 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
10302 file
->line_num
= 0; /* do not display line number if error */
10303 ret
= tcc_load_archive(s1
, fd
);
10305 #ifdef TCC_TARGET_COFF
10306 if (*(uint16_t *)(&ehdr
) == COFF_C67_MAGIC
) {
10307 ret
= tcc_load_coff(s1
, fd
);
10310 #ifdef TCC_TARGET_PE
10311 if (pe_test_res_file(&ehdr
, ret
)) {
10312 ret
= pe_load_res_file(s1
, fd
);
10316 /* as GNU ld, consider it is an ld script if not recognized */
10318 ret
= tcc_load_ldscript(s1
);
10320 error_noabort("unrecognized file type");
10335 int tcc_add_file(TCCState
*s
, const char *filename
)
10337 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
10340 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
10344 pathname1
= tcc_strdup(pathname
);
10345 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
10349 /* find and load a dll. Return non zero if not found */
10350 /* XXX: add '-rpath' option support ? */
10351 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
10356 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
10357 snprintf(buf
, sizeof(buf
), "%s/%s",
10358 s
->library_paths
[i
], filename
);
10359 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
10365 /* the library name is the same as the argument of the '-l' option */
10366 int tcc_add_library(TCCState
*s
, const char *libraryname
)
10371 /* first we look for the dynamic library if not static linking */
10372 if (!s
->static_link
) {
10373 #ifdef TCC_TARGET_PE
10374 snprintf(buf
, sizeof(buf
), "%s.def", libraryname
);
10376 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
10378 if (tcc_add_dll(s
, buf
, 0) == 0)
10382 /* then we look for the static library */
10383 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
10384 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
10385 s
->library_paths
[i
], libraryname
);
10386 if (tcc_add_file_internal(s
, buf
, 0) == 0)
10392 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
10394 add_elf_sym(symtab_section
, val
, 0,
10395 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
), 0,
10400 int tcc_set_output_type(TCCState
*s
, int output_type
)
10402 s
->output_type
= output_type
;
10404 if (!s
->nostdinc
) {
10407 /* default include paths */
10408 /* XXX: reverse order needed if -isystem support */
10409 #ifndef TCC_TARGET_PE
10410 tcc_add_sysinclude_path(s
, "/usr/local/include");
10411 tcc_add_sysinclude_path(s
, "/usr/include");
10413 snprintf(buf
, sizeof(buf
), "%s/include", tcc_lib_path
);
10414 tcc_add_sysinclude_path(s
, buf
);
10415 #ifdef TCC_TARGET_PE
10416 snprintf(buf
, sizeof(buf
), "%s/include/winapi", tcc_lib_path
);
10417 tcc_add_sysinclude_path(s
, buf
);
10421 /* if bound checking, then add corresponding sections */
10422 #ifdef CONFIG_TCC_BCHECK
10423 if (do_bounds_check
) {
10424 /* define symbol */
10425 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
10426 /* create bounds sections */
10427 bounds_section
= new_section(s
, ".bounds",
10428 SHT_PROGBITS
, SHF_ALLOC
);
10429 lbounds_section
= new_section(s
, ".lbounds",
10430 SHT_PROGBITS
, SHF_ALLOC
);
10434 if (s
->char_is_unsigned
) {
10435 tcc_define_symbol(s
, "__CHAR_UNSIGNED__", NULL
);
10438 /* add debug sections */
10441 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
10442 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
10443 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
10444 put_elf_str(stabstr_section
, "");
10445 stab_section
->link
= stabstr_section
;
10446 /* put first entry */
10447 put_stabs("", 0, 0, 0, 0);
10450 /* add libc crt1/crti objects */
10451 #ifndef TCC_TARGET_PE
10452 if ((output_type
== TCC_OUTPUT_EXE
|| output_type
== TCC_OUTPUT_DLL
) &&
10454 if (output_type
!= TCC_OUTPUT_DLL
)
10455 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
10456 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
10462 #define WD_ALL 0x0001 /* warning is activated when using -Wall */
10463 #define FD_INVERT 0x0002 /* invert value before storing */
10465 typedef struct FlagDef
{
10471 static const FlagDef warning_defs
[] = {
10472 { offsetof(TCCState
, warn_unsupported
), 0, "unsupported" },
10473 { offsetof(TCCState
, warn_write_strings
), 0, "write-strings" },
10474 { offsetof(TCCState
, warn_error
), 0, "error" },
10475 { offsetof(TCCState
, warn_implicit_function_declaration
), WD_ALL
,
10476 "implicit-function-declaration" },
10479 static int set_flag(TCCState
*s
, const FlagDef
*flags
, int nb_flags
,
10480 const char *name
, int value
)
10487 if (r
[0] == 'n' && r
[1] == 'o' && r
[2] == '-') {
10491 for(i
= 0, p
= flags
; i
< nb_flags
; i
++, p
++) {
10492 if (!strcmp(r
, p
->name
))
10497 if (p
->flags
& FD_INVERT
)
10499 *(int *)((uint8_t *)s
+ p
->offset
) = value
;
10504 /* set/reset a warning */
10505 int tcc_set_warning(TCCState
*s
, const char *warning_name
, int value
)
10510 if (!strcmp(warning_name
, "all")) {
10511 for(i
= 0, p
= warning_defs
; i
< countof(warning_defs
); i
++, p
++) {
10512 if (p
->flags
& WD_ALL
)
10513 *(int *)((uint8_t *)s
+ p
->offset
) = 1;
10517 return set_flag(s
, warning_defs
, countof(warning_defs
),
10518 warning_name
, value
);
10522 static const FlagDef flag_defs
[] = {
10523 { offsetof(TCCState
, char_is_unsigned
), 0, "unsigned-char" },
10524 { offsetof(TCCState
, char_is_unsigned
), FD_INVERT
, "signed-char" },
10525 { offsetof(TCCState
, nocommon
), FD_INVERT
, "common" },
10526 { offsetof(TCCState
, leading_underscore
), 0, "leading-underscore" },
10529 /* set/reset a flag */
10530 int tcc_set_flag(TCCState
*s
, const char *flag_name
, int value
)
10532 return set_flag(s
, flag_defs
, countof(flag_defs
),
10536 #if !defined(LIBTCC)
10538 static int64_t getclock_us(void)
10543 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
10546 gettimeofday(&tv
, NULL
);
10547 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
10553 printf("tcc version " TCC_VERSION
" - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n"
10554 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
10555 " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
10556 " [infile1 infile2...] [-run infile args...]\n"
10558 "General options:\n"
10559 " -v display current version\n"
10560 " -c compile only - generate an object file\n"
10561 " -o outfile set output filename\n"
10562 " -Bdir set tcc internal library path\n"
10563 " -bench output compilation statistics\n"
10564 " -run run compiled source\n"
10565 " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
10566 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
10567 " -w disable all warnings\n"
10568 "Preprocessor options:\n"
10569 " -E preprocess only\n"
10570 " -Idir add include path 'dir'\n"
10571 " -Dsym[=val] define 'sym' with value 'val'\n"
10572 " -Usym undefine 'sym'\n"
10573 "Linker options:\n"
10574 " -Ldir add library path 'dir'\n"
10575 " -llib link with dynamic or static library 'lib'\n"
10576 " -shared generate a shared library\n"
10577 " -static static linking\n"
10578 " -rdynamic export all global symbols to dynamic linker\n"
10579 " -r generate (relocatable) object file\n"
10580 "Debugger options:\n"
10581 " -g generate runtime debug info\n"
10582 #ifdef CONFIG_TCC_BCHECK
10583 " -b compile with built-in memory and bounds checker (implies -g)\n"
10585 " -bt N show N callers in stack traces\n"
10589 #define TCC_OPTION_HAS_ARG 0x0001
10590 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
10592 typedef struct TCCOption
{
10620 TCC_OPTION_nostdinc
,
10621 TCC_OPTION_nostdlib
,
10622 TCC_OPTION_print_search_dirs
,
10623 TCC_OPTION_rdynamic
,
10631 static const TCCOption tcc_options
[] = {
10632 { "h", TCC_OPTION_HELP
, 0 },
10633 { "?", TCC_OPTION_HELP
, 0 },
10634 { "I", TCC_OPTION_I
, TCC_OPTION_HAS_ARG
},
10635 { "D", TCC_OPTION_D
, TCC_OPTION_HAS_ARG
},
10636 { "U", TCC_OPTION_U
, TCC_OPTION_HAS_ARG
},
10637 { "L", TCC_OPTION_L
, TCC_OPTION_HAS_ARG
},
10638 { "B", TCC_OPTION_B
, TCC_OPTION_HAS_ARG
},
10639 { "l", TCC_OPTION_l
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10640 { "bench", TCC_OPTION_bench
, 0 },
10641 { "bt", TCC_OPTION_bt
, TCC_OPTION_HAS_ARG
},
10642 #ifdef CONFIG_TCC_BCHECK
10643 { "b", TCC_OPTION_b
, 0 },
10645 { "g", TCC_OPTION_g
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10646 { "c", TCC_OPTION_c
, 0 },
10647 { "static", TCC_OPTION_static
, 0 },
10648 { "shared", TCC_OPTION_shared
, 0 },
10649 { "o", TCC_OPTION_o
, TCC_OPTION_HAS_ARG
},
10650 { "run", TCC_OPTION_run
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10651 { "rdynamic", TCC_OPTION_rdynamic
, 0 },
10652 { "r", TCC_OPTION_r
, 0 },
10653 { "Wl,", TCC_OPTION_Wl
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10654 { "W", TCC_OPTION_W
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10655 { "O", TCC_OPTION_O
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10656 { "m", TCC_OPTION_m
, TCC_OPTION_HAS_ARG
},
10657 { "f", TCC_OPTION_f
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10658 { "nostdinc", TCC_OPTION_nostdinc
, 0 },
10659 { "nostdlib", TCC_OPTION_nostdlib
, 0 },
10660 { "print-search-dirs", TCC_OPTION_print_search_dirs
, 0 },
10661 { "v", TCC_OPTION_v
, 0 },
10662 { "w", TCC_OPTION_w
, 0 },
10663 { "pipe", TCC_OPTION_pipe
, 0},
10664 { "E", TCC_OPTION_E
, 0},
10668 /* convert 'str' into an array of space separated strings */
10669 static int expand_args(char ***pargv
, const char *str
)
10678 while (is_space(*str
))
10683 while (*str
!= '\0' && !is_space(*str
))
10686 arg
= tcc_malloc(len
+ 1);
10687 memcpy(arg
, s1
, len
);
10689 dynarray_add((void ***)&argv
, &argc
, arg
);
10695 static char **files
;
10696 static int nb_files
, nb_libraries
;
10697 static int multiple_files
;
10698 static int print_search_dirs
;
10699 static int output_type
;
10700 static int reloc_output
;
10701 static const char *outfile
;
10703 int parse_args(TCCState
*s
, int argc
, char **argv
)
10706 const TCCOption
*popt
;
10707 const char *optarg
, *p1
, *r1
;
10712 if (optind
>= argc
) {
10713 if (nb_files
== 0 && !print_search_dirs
)
10718 r
= argv
[optind
++];
10720 /* add a new file */
10721 dynarray_add((void ***)&files
, &nb_files
, r
);
10722 if (!multiple_files
) {
10724 /* argv[0] will be this file */
10728 /* find option in table (match only the first chars */
10729 popt
= tcc_options
;
10733 error("invalid option -- '%s'", r
);
10746 if (popt
->flags
& TCC_OPTION_HAS_ARG
) {
10747 if (*r1
!= '\0' || (popt
->flags
& TCC_OPTION_NOSEP
)) {
10750 if (optind
>= argc
)
10751 error("argument to '%s' is missing", r
);
10752 optarg
= argv
[optind
++];
10760 switch(popt
->index
) {
10761 case TCC_OPTION_HELP
:
10766 if (tcc_add_include_path(s
, optarg
) < 0)
10767 error("too many include paths");
10772 sym
= (char *)optarg
;
10773 value
= strchr(sym
, '=');
10778 tcc_define_symbol(s
, sym
, value
);
10782 tcc_undefine_symbol(s
, optarg
);
10785 tcc_add_library_path(s
, optarg
);
10788 /* set tcc utilities path (mainly for tcc development) */
10789 tcc_lib_path
= optarg
;
10792 dynarray_add((void ***)&files
, &nb_files
, r
);
10795 case TCC_OPTION_bench
:
10798 case TCC_OPTION_bt
:
10799 num_callers
= atoi(optarg
);
10801 #ifdef CONFIG_TCC_BCHECK
10803 do_bounds_check
= 1;
10811 multiple_files
= 1;
10812 output_type
= TCC_OUTPUT_OBJ
;
10814 case TCC_OPTION_static
:
10815 s
->static_link
= 1;
10817 case TCC_OPTION_shared
:
10818 output_type
= TCC_OUTPUT_DLL
;
10821 multiple_files
= 1;
10825 /* generate a .o merging several output files */
10827 output_type
= TCC_OUTPUT_OBJ
;
10829 case TCC_OPTION_nostdinc
:
10832 case TCC_OPTION_nostdlib
:
10835 case TCC_OPTION_print_search_dirs
:
10836 print_search_dirs
= 1;
10838 case TCC_OPTION_run
:
10842 argc1
= expand_args(&argv1
, optarg
);
10844 parse_args(s
, argc1
, argv1
);
10846 multiple_files
= 0;
10847 output_type
= TCC_OUTPUT_MEMORY
;
10851 printf("tcc version %s\n", TCC_VERSION
);
10854 if (tcc_set_flag(s
, optarg
, 1) < 0 && s
->warn_unsupported
)
10855 goto unsupported_option
;
10858 if (tcc_set_warning(s
, optarg
, 1) < 0 &&
10859 s
->warn_unsupported
)
10860 goto unsupported_option
;
10865 case TCC_OPTION_rdynamic
:
10868 case TCC_OPTION_Wl
:
10871 if (strstart(optarg
, "-Ttext,", &p
)) {
10872 s
->text_addr
= strtoul(p
, NULL
, 16);
10873 s
->has_text_addr
= 1;
10874 } else if (strstart(optarg
, "--oformat,", &p
)) {
10875 if (strstart(p
, "elf32-", NULL
)) {
10876 s
->output_format
= TCC_OUTPUT_FORMAT_ELF
;
10877 } else if (!strcmp(p
, "binary")) {
10878 s
->output_format
= TCC_OUTPUT_FORMAT_BINARY
;
10880 #ifdef TCC_TARGET_COFF
10881 if (!strcmp(p
, "coff")) {
10882 s
->output_format
= TCC_OUTPUT_FORMAT_COFF
;
10886 error("target %s not found", p
);
10889 error("unsupported linker option '%s'", optarg
);
10894 output_type
= TCC_OUTPUT_PREPROCESS
;
10897 if (s
->warn_unsupported
) {
10898 unsupported_option
:
10899 warning("unsupported option '%s'", r
);
10908 int main(int argc
, char **argv
)
10912 int nb_objfiles
, ret
, optind
;
10913 char objfilename
[1024];
10914 int64_t start_time
= 0;
10917 tcc_lib_path
= w32_tcc_lib_path();
10921 output_type
= TCC_OUTPUT_EXE
;
10923 multiple_files
= 1;
10928 print_search_dirs
= 0;
10931 optind
= parse_args(s
, argc
- 1, argv
+ 1) + 1;
10933 if (print_search_dirs
) {
10934 /* enough for Linux kernel */
10935 printf("install: %s/\n", tcc_lib_path
);
10939 nb_objfiles
= nb_files
- nb_libraries
;
10941 /* if outfile provided without other options, we output an
10943 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
10944 output_type
= TCC_OUTPUT_EXE
;
10946 /* check -c consistency : only single file handled. XXX: checks file type */
10947 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
10948 /* accepts only a single input file */
10949 if (nb_objfiles
!= 1)
10950 error("cannot specify multiple files with -c");
10951 if (nb_libraries
!= 0)
10952 error("cannot specify libraries with -c");
10956 if (output_type
== TCC_OUTPUT_PREPROCESS
) {
10958 s
->outfile
= stdout
;
10960 s
->outfile
= fopen(outfile
, "w");
10962 error("could not open '%s", outfile
);
10964 } else if (output_type
!= TCC_OUTPUT_MEMORY
) {
10966 /* compute default outfile name */
10968 pstrcpy(objfilename
, sizeof(objfilename
), tcc_basename(files
[0]));
10969 ext
= tcc_fileextension(objfilename
);
10970 #ifdef TCC_TARGET_PE
10971 if (output_type
== TCC_OUTPUT_DLL
)
10972 strcpy(ext
, ".dll");
10974 if (output_type
== TCC_OUTPUT_EXE
)
10975 strcpy(ext
, ".exe");
10978 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
&& *ext
)
10981 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
10982 outfile
= objfilename
;
10987 start_time
= getclock_us();
10990 tcc_set_output_type(s
, output_type
);
10992 /* compile or add each files or library */
10993 for(i
= 0; i
< nb_files
&& ret
== 0; i
++) {
10994 const char *filename
;
10996 filename
= files
[i
];
10997 if (output_type
== TCC_OUTPUT_PREPROCESS
) {
10998 if (tcc_add_file_internal(s
, filename
,
10999 AFF_PRINT_ERROR
| AFF_PREPROCESS
) < 0)
11001 } else if (filename
[0] == '-') {
11002 if (tcc_add_library(s
, filename
+ 2) < 0)
11003 error("cannot find %s", filename
);
11005 if (tcc_add_file(s
, filename
) < 0)
11010 /* free all files */
11018 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
11019 if (total_time
< 0.001)
11020 total_time
= 0.001;
11021 if (total_bytes
< 1)
11023 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
11024 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
11025 total_time
, (int)(total_lines
/ total_time
),
11026 total_bytes
/ total_time
/ 1000000.0);
11029 if (s
->output_type
== TCC_OUTPUT_PREPROCESS
) {
11031 fclose(s
->outfile
);
11032 } else if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
11033 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
11035 #ifdef TCC_TARGET_PE
11036 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
11037 ret
= pe_output_file(s
, outfile
);
11041 ret
= tcc_output_file(s
, outfile
) ? 1 : 0;
11044 /* XXX: cannot do it with bound checking because of the malloc hooks */
11045 if (!do_bounds_check
)
11050 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);