2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001, 2002, 2003 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
36 #include <sys/timeb.h>
37 #define CONFIG_TCC_STATIC
41 #include <sys/ucontext.h>
45 #ifndef CONFIG_TCC_STATIC
53 /* preprocessor debug */
55 /* include file debug */
63 /* target selection */
64 //#define TCC_TARGET_I386 /* i386 code generator */
65 //#define TCC_TARGET_ARM /* ARMv4 code generator */
66 //#define TCC_TARGET_C67 /* TMS320C67xx code generator */
68 /* default target is I386 */
69 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
70 !defined(TCC_TARGET_C67)
71 #define TCC_TARGET_I386
74 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
75 !defined(TCC_TARGET_C67)
76 #define CONFIG_TCC_BCHECK /* enable bound checking code */
79 /* define it to include assembler support */
80 #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
81 #define CONFIG_TCC_ASM
84 /* object format selection */
85 #if defined(TCC_TARGET_C67)
86 #define TCC_TARGET_COFF
95 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
96 executables or dlls */
97 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
99 #define INCLUDE_STACK_SIZE 32
100 #define IFDEF_STACK_SIZE 64
101 #define VSTACK_SIZE 64
102 #define STRING_MAX_SIZE 1024
104 #define TOK_HASH_SIZE 2048 /* must be a power of two */
105 #define TOK_ALLOC_INCR 512 /* must be a power of two */
106 #define TOK_STR_ALLOC_INCR_BITS 6
107 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
108 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
110 /* token symbol management */
111 typedef struct TokenSym
{
112 struct TokenSym
*hash_next
;
113 struct Sym
*sym_define
; /* direct pointer to define */
114 struct Sym
*sym_label
; /* direct pointer to label */
115 struct Sym
*sym_struct
; /* direct pointer to structure */
116 struct Sym
*sym_identifier
; /* direct pointer to identifier */
117 int tok
; /* token number */
122 typedef struct CString
{
123 int size
; /* size in bytes */
124 void *data
; /* either 'char *' or 'int *' */
126 void *data_allocated
; /* if non NULL, data has been malloced */
129 /* type definition */
130 typedef struct CType
{
136 typedef union CValue
{
142 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
144 unsigned long long ull
;
145 struct CString
*cstr
;
151 typedef struct SValue
{
152 CType type
; /* type */
153 unsigned short r
; /* register + flags */
154 unsigned short r2
; /* second register, used for 'long long'
155 type. If not used, set to VT_CONST */
156 CValue c
; /* constant, if VT_CONST */
157 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
160 /* symbol management */
162 int v
; /* symbol token */
163 int r
; /* associated register */
164 int c
; /* associated number */
165 CType type
; /* associated type */
166 struct Sym
*next
; /* next related symbol */
167 struct Sym
*prev
; /* prev symbol in stack */
168 struct Sym
*prev_tok
; /* previous symbol for this token */
171 /* section definition */
172 /* XXX: use directly ELF structure for parameters ? */
173 /* special flag to indicate that the section should not be linked to
175 #define SHF_PRIVATE 0x80000000
177 typedef struct Section
{
178 unsigned long data_offset
; /* current data offset */
179 unsigned char *data
; /* section data */
180 unsigned long data_allocated
; /* used for realloc() handling */
181 int sh_name
; /* elf section name (only used during output) */
182 int sh_num
; /* elf section number */
183 int sh_type
; /* elf section type */
184 int sh_flags
; /* elf section flags */
185 int sh_info
; /* elf section info */
186 int sh_addralign
; /* elf section alignment */
187 int sh_entsize
; /* elf entry size */
188 unsigned long sh_size
; /* section size (only used during output) */
189 unsigned long sh_addr
; /* address at which the section is relocated */
190 unsigned long sh_offset
; /* address at which the section is relocated */
191 int nb_hashed_syms
; /* used to resize the hash table */
192 struct Section
*link
; /* link to another section */
193 struct Section
*reloc
; /* corresponding section for relocation, if any */
194 struct Section
*hash
; /* hash table for symbols */
195 struct Section
*next
;
196 char name
[1]; /* section name */
199 typedef struct DLLReference
{
204 /* GNUC attribute definition */
205 typedef struct AttributeDef
{
208 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
211 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
212 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
213 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
215 /* stored in 'Sym.c' field */
216 #define FUNC_NEW 1 /* ansi function prototype */
217 #define FUNC_OLD 2 /* old function prototype */
218 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
220 /* stored in 'Sym.r' field */
221 #define FUNC_CDECL 0 /* standard c call */
222 #define FUNC_STDCALL 1 /* pascal c call */
224 /* field 'Sym.t' for macros */
225 #define MACRO_OBJ 0 /* object like macro */
226 #define MACRO_FUNC 1 /* function like macro */
228 /* field 'Sym.r' for C labels */
229 #define LABEL_DEFINED 0 /* label is defined */
230 #define LABEL_FORWARD 1 /* label is forward defined */
231 #define LABEL_DECLARED 2 /* label is declared but never used */
233 /* type_decl() types */
234 #define TYPE_ABSTRACT 1 /* type without variable */
235 #define TYPE_DIRECT 2 /* type with variable */
237 #define IO_BUF_SIZE 8192
239 typedef struct BufferedFile
{
243 int line_num
; /* current line number - here to simplify code */
244 int ifndef_macro
; /* #ifndef macro / #endif search */
245 int ifndef_macro_saved
; /* saved ifndef_macro */
246 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
247 char inc_type
; /* type of include */
248 char inc_filename
[512]; /* filename specified by the user */
249 char filename
[1024]; /* current filename - here to simplify code */
250 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
253 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
254 #define CH_EOF (-1) /* end of file */
256 /* parsing state (used to save parser state to reparse part of the
257 source several times) */
258 typedef struct ParseState
{
265 /* used to record tokens */
266 typedef struct TokenString
{
273 /* include file cache, used to find files faster and also to eliminate
274 inclusion if the include file is protected by #ifndef ... #endif */
275 typedef struct CachedInclude
{
277 char type
; /* '"' or '>' to give include type */
278 char filename
[1]; /* path specified in #include */
282 static struct BufferedFile
*file
;
285 static CString tokcstr
; /* current parsed string, if any */
286 /* additional informations about token */
287 static int tok_flags
;
288 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
289 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
290 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
292 static int *macro_ptr
, *macro_ptr_allocated
;
293 static int *unget_saved_macro_ptr
;
294 static int unget_saved_buffer
[TOK_MAX_SIZE
+ 1];
295 static int unget_buffer_enabled
;
296 static int parse_flags
;
297 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
298 #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
299 #define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
300 token. line feed is also
303 static Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
304 static Section
*cur_text_section
; /* current section where function code is
306 /* bound check related sections */
307 static Section
*bounds_section
; /* contains global data bound description */
308 static Section
*lbounds_section
; /* contains local data bound description */
309 /* symbol sections */
310 static Section
*symtab_section
, *strtab_section
;
313 static Section
*stab_section
, *stabstr_section
;
315 /* loc : local variable index
316 ind : output code index
318 anon_sym: anonymous symbol index
320 static int rsym
, anon_sym
, ind
, loc
;
321 /* expression generation modifiers */
322 static int const_wanted
; /* true if constant wanted */
323 static int nocode_wanted
; /* true if no code generation wanted for an expression */
324 static int global_expr
; /* true if compound literals must be allocated
325 globally (used during initializers parsing */
326 static CType func_vt
; /* current function return type (used by return
329 static int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
330 static int tok_ident
;
331 static TokenSym
**table_ident
;
332 static TokenSym
*hash_ident
[TOK_HASH_SIZE
];
333 static char token_buf
[STRING_MAX_SIZE
+ 1];
334 static char *funcname
;
335 static Sym
*global_stack
, *local_stack
;
336 static Sym
*define_stack
;
337 static Sym
*global_label_stack
, *local_label_stack
;
339 static SValue vstack
[VSTACK_SIZE
], *vtop
;
340 /* some predefined types */
341 static CType char_pointer_type
, func_old_type
, int_type
;
342 /* true if isid(c) || isnum(c) */
343 static unsigned char isidnum_table
[256];
345 /* compile with debug symbol (and use them if error during execution) */
346 static int do_debug
= 0;
348 /* compile with built-in memory and bounds checker */
349 static int do_bounds_check
= 0;
351 /* display benchmark infos */
353 static int do_bench
= 0;
355 static int total_lines
;
356 static int total_bytes
;
358 /* use GNU C extensions */
359 static int gnu_ext
= 1;
361 /* use Tiny C extensions */
362 static int tcc_ext
= 1;
364 /* max number of callers shown if error */
365 static int num_callers
= 6;
366 static const char **rt_bound_error_msg
;
368 /* XXX: get rid of this ASAP */
369 static struct TCCState
*tcc_state
;
371 /* give the path of the tcc libraries */
372 static const char *tcc_lib_path
= CONFIG_TCC_LIBDIR
"/tcc";
377 BufferedFile
**include_stack_ptr
;
378 int *ifdef_stack_ptr
;
380 /* include file handling */
381 char **include_paths
;
382 int nb_include_paths
;
383 char **sysinclude_paths
;
384 int nb_sysinclude_paths
;
385 CachedInclude
**cached_includes
;
386 int nb_cached_includes
;
388 char **library_paths
;
389 int nb_library_paths
;
391 /* array of all loaded dlls (including those referenced by loaded
393 DLLReference
**loaded_dlls
;
398 int nb_sections
; /* number of sections, including first dummy section */
403 unsigned long *got_offsets
;
405 /* give the correspondance from symtab indexes to dynsym indexes */
406 int *symtab_to_dynsym
;
408 /* temporary dynamic symbol sections (for dll loading) */
409 Section
*dynsymtab_section
;
410 /* exported dynamic symbol section */
413 int nostdinc
; /* if true, no standard headers are added */
414 int nostdlib
; /* if true, no standard libraries are added */
416 /* if true, static linking is performed */
419 /* if true, all symbols are exported */
422 /* if true, only link in referenced objects from archive */
425 /* C language options */
426 int char_is_unsigned
;
428 /* warning switches */
429 int warn_write_strings
;
430 int warn_unsupported
;
433 int warn_implicit_function_declaration
;
437 void (*error_func
)(void *opaque
, const char *msg
);
438 int error_set_jmp_enabled
;
439 jmp_buf error_jmp_buf
;
442 /* tiny assembler state */
445 /* see include_stack_ptr */
446 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
448 /* see ifdef_stack_ptr */
449 int ifdef_stack
[IFDEF_STACK_SIZE
];
452 /* The current value can be: */
453 #define VT_VALMASK 0x00ff
454 #define VT_CONST 0x00f0 /* constant in vc
455 (must be first non register value) */
456 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
457 #define VT_LOCAL 0x00f2 /* offset on stack */
458 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
459 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
460 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
461 #define VT_LVAL 0x0100 /* var is an lvalue */
462 #define VT_SYM 0x0200 /* a symbol value is added */
463 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
464 char/short stored in integer registers) */
465 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
466 dereferencing value */
467 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
468 bounding function call point is in vc */
469 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
470 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
471 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
472 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
475 #define VT_INT 0 /* integer type */
476 #define VT_BYTE 1 /* signed byte type */
477 #define VT_SHORT 2 /* short type */
478 #define VT_VOID 3 /* void type */
479 #define VT_PTR 4 /* pointer */
480 #define VT_ENUM 5 /* enum definition */
481 #define VT_FUNC 6 /* function type */
482 #define VT_STRUCT 7 /* struct/union definition */
483 #define VT_FLOAT 8 /* IEEE float */
484 #define VT_DOUBLE 9 /* IEEE double */
485 #define VT_LDOUBLE 10 /* IEEE long double */
486 #define VT_BOOL 11 /* ISOC99 boolean type */
487 #define VT_LLONG 12 /* 64 bit integer */
488 #define VT_LONG 13 /* long integer (NEVER USED as type, only
490 #define VT_BTYPE 0x000f /* mask for basic type */
491 #define VT_UNSIGNED 0x0010 /* unsigned type */
492 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
493 #define VT_BITFIELD 0x0040 /* bitfield modifier */
494 #define VT_CONSTANT 0x0800 /* const modifier */
495 #define VT_VOLATILE 0x1000 /* volatile modifier */
496 #define VT_SIGNED 0x2000 /* signed type */
499 #define VT_EXTERN 0x00000080 /* extern definition */
500 #define VT_STATIC 0x00000100 /* static variable */
501 #define VT_TYPEDEF 0x00000200 /* typedef definition */
502 #define VT_INLINE 0x00000400 /* inline definition */
504 #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */
506 /* type mask (except storage) */
507 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
508 #define VT_TYPE (~(VT_STORAGE))
512 /* warning: the following compare tokens depend on i386 asm code */
524 #define TOK_LAND 0xa0
528 #define TOK_MID 0xa3 /* inc/dec, to void constant */
530 #define TOK_UDIV 0xb0 /* unsigned division */
531 #define TOK_UMOD 0xb1 /* unsigned modulo */
532 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
533 #define TOK_CINT 0xb3 /* number in tokc */
534 #define TOK_CCHAR 0xb4 /* char constant in tokc */
535 #define TOK_STR 0xb5 /* pointer to string in tokc */
536 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
537 #define TOK_LCHAR 0xb7
538 #define TOK_LSTR 0xb8
539 #define TOK_CFLOAT 0xb9 /* float constant */
540 #define TOK_LINENUM 0xba /* line number info */
541 #define TOK_CDOUBLE 0xc0 /* double constant */
542 #define TOK_CLDOUBLE 0xc1 /* long double constant */
543 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
544 #define TOK_ADDC1 0xc3 /* add with carry generation */
545 #define TOK_ADDC2 0xc4 /* add with carry use */
546 #define TOK_SUBC1 0xc5 /* add with carry generation */
547 #define TOK_SUBC2 0xc6 /* add with carry use */
548 #define TOK_CUINT 0xc8 /* unsigned int constant */
549 #define TOK_CLLONG 0xc9 /* long long constant */
550 #define TOK_CULLONG 0xca /* unsigned long long constant */
551 #define TOK_ARROW 0xcb
552 #define TOK_DOTS 0xcc /* three dots */
553 #define TOK_SHR 0xcd /* unsigned shift right */
554 #define TOK_PPNUM 0xce /* preprocessor number */
556 #define TOK_SHL 0x01 /* shift left */
557 #define TOK_SAR 0x02 /* signed shift right */
559 /* assignement operators : normal operator or 0x80 */
560 #define TOK_A_MOD 0xa5
561 #define TOK_A_AND 0xa6
562 #define TOK_A_MUL 0xaa
563 #define TOK_A_ADD 0xab
564 #define TOK_A_SUB 0xad
565 #define TOK_A_DIV 0xaf
566 #define TOK_A_XOR 0xde
567 #define TOK_A_OR 0xfc
568 #define TOK_A_SHL 0x81
569 #define TOK_A_SAR 0x82
572 #define offsetof(type, field) ((size_t) &((type *)0)->field)
576 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
579 /* WARNING: the content of this string encodes token numbers */
580 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";
582 #define TOK_EOF (-1) /* end of file */
583 #define TOK_LINEFEED 10 /* line feed */
585 /* all identificators and strings have token above that */
586 #define TOK_IDENT 256
588 /* only used for i386 asm opcodes definitions */
589 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
592 DEF(TOK_ASM_ ## x ## b, #x "b") \
593 DEF(TOK_ASM_ ## x ## w, #x "w") \
594 DEF(TOK_ASM_ ## x ## l, #x "l") \
595 DEF(TOK_ASM_ ## x, #x)
598 DEF(TOK_ASM_ ## x ## w, #x "w") \
599 DEF(TOK_ASM_ ## x ## l, #x "l") \
600 DEF(TOK_ASM_ ## x, #x)
603 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
604 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
605 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
606 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
609 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
610 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
613 #define DEF_ASMTEST(x) \
645 #define TOK_ASM_int TOK_INT
648 TOK_LAST
= TOK_IDENT
- 1,
649 #define DEF(id, str) id,
654 static const char tcc_keywords
[] =
655 #define DEF(id, str) str "\0"
660 #define TOK_UIDENT TOK_DEFINE
663 #define snprintf _snprintf
664 #define vsnprintf _vsnprintf
667 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
668 /* currently incorrect */
669 long double strtold(const char *nptr
, char **endptr
)
671 return (long double)strtod(nptr
, endptr
);
673 float strtof(const char *nptr
, char **endptr
)
675 return (float)strtod(nptr
, endptr
);
678 /* XXX: need to define this to use them in non ISOC99 context */
679 extern float strtof (const char *__nptr
, char **__endptr
);
680 extern long double strtold (const char *__nptr
, char **__endptr
);
683 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
684 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
686 static void next(void);
687 static void next_nomacro(void);
688 static void parse_expr_type(CType
*type
);
689 static void expr_type(CType
*type
);
690 static void unary_type(CType
*type
);
691 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
692 int case_reg
, int is_expr
);
693 static int expr_const(void);
694 static void expr_eq(void);
695 static void gexpr(void);
696 static void decl(int l
);
697 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
698 int first
, int size_only
);
699 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
700 int has_init
, int v
, int scope
);
702 void gv2(int rc1
, int rc2
);
703 void move_reg(int r
, int s
);
704 void save_regs(int n
);
705 void save_reg(int r
);
710 int get_reg_ex(int rc
,int rc2
);
712 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
713 const int *macro_str
, int can_read_stream
);
714 int save_reg_forced(int r
);
716 void force_charshort_cast(int t
);
717 static void gen_cast(CType
*type
);
719 static Sym
*sym_find(int v
);
720 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
723 static int type_size(CType
*type
, int *a
);
724 static inline CType
*pointed_type(CType
*type
);
725 static int pointed_size(CType
*type
);
726 static int lvalue_type(int t
);
727 static int parse_btype(CType
*type
, AttributeDef
*ad
);
728 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
729 static int is_compatible_types(CType
*type1
, CType
*type2
);
731 int ieee_finite(double d
);
732 void error(const char *fmt
, ...);
736 void lexpand_nr(void);
737 static void vpush_global_sym(CType
*type
, int v
);
738 void vset(CType
*type
, int r
, int v
);
739 void type_to_str(char *buf
, int buf_size
,
740 CType
*type
, const char *varstr
);
741 char *get_tok_str(int v
, CValue
*cv
);
742 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
743 unsigned long offset
, unsigned long size
);
744 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
746 /* section generation */
747 static void section_realloc(Section
*sec
, unsigned long new_size
);
748 static void *section_ptr_add(Section
*sec
, unsigned long size
);
749 static void put_extern_sym(Sym
*sym
, Section
*section
,
750 unsigned long value
, unsigned long size
);
751 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
752 static int put_elf_str(Section
*s
, const char *sym
);
753 static int put_elf_sym(Section
*s
,
754 unsigned long value
, unsigned long size
,
755 int info
, int other
, int shndx
, const char *name
);
756 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
757 int info
, int sh_num
, const char *name
);
758 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
759 int type
, int symbol
);
760 static void put_stabs(const char *str
, int type
, int other
, int desc
,
761 unsigned long value
);
762 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
763 unsigned long value
, Section
*sec
, int sym_index
);
764 static void put_stabn(int type
, int other
, int desc
, int value
);
765 static void put_stabd(int type
, int other
, int desc
);
766 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
768 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
769 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
770 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
773 int tcc_output_coff(TCCState
*s1
, const char *OutFile
);
777 #ifdef CONFIG_TCC_ASM
779 typedef struct ExprValue
{
784 #define MAX_ASM_OPERANDS 30
786 typedef struct ASMOperand
{
787 int id
; /* GCC 3 optionnal identifier (0 if number only supported */
789 char asm_str
[16]; /* computed asm string for operand */
790 SValue
*vt
; /* C value of the expression */
791 int ref_index
; /* if >= 0, gives reference to a output constraint */
792 int priority
; /* priority, used to assign registers */
793 int reg
; /* if >= 0, register number used for this operand */
794 int is_llong
; /* true if double register value */
797 static void asm_expr(TCCState
*s1
, ExprValue
*pe
);
798 static int asm_int_expr(TCCState
*s1
);
799 static int find_constraint(ASMOperand
*operands
, int nb_operands
,
800 const char *name
, const char **pp
);
802 static int tcc_assemble(TCCState
*s1
, int do_preprocess
);
806 static void asm_instr(void);
808 /* true if float/double/long double type */
809 static inline int is_float(int t
)
813 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
816 #ifdef TCC_TARGET_I386
817 #include "i386-gen.c"
820 #ifdef TCC_TARGET_ARM
824 #ifdef TCC_TARGET_C67
828 #ifdef CONFIG_TCC_STATIC
830 #define RTLD_LAZY 0x001
831 #define RTLD_NOW 0x002
832 #define RTLD_GLOBAL 0x100
833 #define RTLD_DEFAULT NULL
835 /* dummy function for profiling */
836 void *dlopen(const char *filename
, int flag
)
841 const char *dlerror(void)
846 typedef struct TCCSyms
{
851 #define TCCSYM(a) { #a, &a, },
853 /* add the symbol you want here if no dynamic linking is done */
854 static TCCSyms tcc_syms
[] = {
862 void *dlsym(void *handle
, const char *symbol
)
866 while (p
->str
!= NULL
) {
867 if (!strcmp(p
->str
, symbol
))
876 /********************************************************/
878 /* we use our own 'finite' function to avoid potential problems with
879 non standard math libs */
880 /* XXX: endianness dependent */
881 int ieee_finite(double d
)
884 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
887 /* copy a string and truncate it. */
888 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
895 q_end
= buf
+ buf_size
- 1;
907 /* strcat and truncate. */
908 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
913 pstrcpy(buf
+ len
, buf_size
- len
, s
);
917 /* memory management */
923 static inline void tcc_free(void *ptr
)
926 mem_cur_size
-= malloc_usable_size(ptr
);
931 static void *tcc_malloc(unsigned long size
)
936 error("memory full");
938 mem_cur_size
+= malloc_usable_size(ptr
);
939 if (mem_cur_size
> mem_max_size
)
940 mem_max_size
= mem_cur_size
;
945 static void *tcc_mallocz(unsigned long size
)
948 ptr
= tcc_malloc(size
);
949 memset(ptr
, 0, size
);
953 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
957 mem_cur_size
-= malloc_usable_size(ptr
);
959 ptr1
= realloc(ptr
, size
);
961 /* NOTE: count not correct if alloc error, but not critical */
962 mem_cur_size
+= malloc_usable_size(ptr1
);
963 if (mem_cur_size
> mem_max_size
)
964 mem_max_size
= mem_cur_size
;
969 static char *tcc_strdup(const char *str
)
972 ptr
= tcc_malloc(strlen(str
) + 1);
977 #define free(p) use_tcc_free(p)
978 #define malloc(s) use_tcc_malloc(s)
979 #define realloc(p, s) use_tcc_realloc(p, s)
981 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
988 /* every power of two we double array size */
989 if ((nb
& (nb
- 1)) == 0) {
994 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
996 error("memory full");
1003 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
1007 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
1008 strcpy(sec
->name
, name
);
1009 sec
->sh_type
= sh_type
;
1010 sec
->sh_flags
= sh_flags
;
1017 sec
->sh_addralign
= 4;
1020 sec
->sh_addralign
= 1;
1023 sec
->sh_addralign
= 32; /* default conservative alignment */
1027 /* only add section if not private */
1028 if (!(sh_flags
& SHF_PRIVATE
)) {
1029 sec
->sh_num
= s1
->nb_sections
;
1030 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
1035 static void free_section(Section
*s
)
1041 /* realloc section and set its content to zero */
1042 static void section_realloc(Section
*sec
, unsigned long new_size
)
1045 unsigned char *data
;
1047 size
= sec
->data_allocated
;
1050 while (size
< new_size
)
1052 data
= tcc_realloc(sec
->data
, size
);
1054 error("memory full");
1055 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
1057 sec
->data_allocated
= size
;
1060 /* reserve at least 'size' bytes in section 'sec' from
1061 sec->data_offset. */
1062 static void *section_ptr_add(Section
*sec
, unsigned long size
)
1064 unsigned long offset
, offset1
;
1066 offset
= sec
->data_offset
;
1067 offset1
= offset
+ size
;
1068 if (offset1
> sec
->data_allocated
)
1069 section_realloc(sec
, offset1
);
1070 sec
->data_offset
= offset1
;
1071 return sec
->data
+ offset
;
1074 /* return a reference to a section, and create it if it does not
1076 Section
*find_section(TCCState
*s1
, const char *name
)
1080 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1081 sec
= s1
->sections
[i
];
1082 if (!strcmp(name
, sec
->name
))
1085 /* sections are created as PROGBITS */
1086 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
1089 /* update sym->c so that it points to an external symbol in section
1090 'section' with value 'value' */
1091 static void put_extern_sym(Sym
*sym
, Section
*section
,
1092 unsigned long value
, unsigned long size
)
1094 int sym_type
, sym_bind
, sh_num
, info
;
1099 sh_num
= section
->sh_num
;
1103 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
)
1104 sym_type
= STT_FUNC
;
1106 sym_type
= STT_OBJECT
;
1107 if (sym
->type
.t
& VT_STATIC
)
1108 sym_bind
= STB_LOCAL
;
1110 sym_bind
= STB_GLOBAL
;
1112 name
= get_tok_str(sym
->v
, NULL
);
1113 #ifdef CONFIG_TCC_BCHECK
1114 if (do_bounds_check
) {
1117 /* XXX: avoid doing that for statics ? */
1118 /* if bound checking is activated, we change some function
1119 names by adding the "__bound" prefix */
1122 /* XXX: we rely only on malloc hooks */
1134 strcpy(buf
, "__bound_");
1141 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
1142 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
1144 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
1145 esym
->st_value
= value
;
1146 esym
->st_size
= size
;
1147 esym
->st_shndx
= sh_num
;
1151 /* add a new relocation entry to symbol 'sym' in section 's' */
1152 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
1155 put_extern_sym(sym
, NULL
, 0, 0);
1156 /* now we can add ELF relocation info */
1157 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
1160 static inline int isid(int c
)
1162 return (c
>= 'a' && c
<= 'z') ||
1163 (c
>= 'A' && c
<= 'Z') ||
1167 static inline int isnum(int c
)
1169 return c
>= '0' && c
<= '9';
1172 static inline int isoct(int c
)
1174 return c
>= '0' && c
<= '7';
1177 static inline int toup(int c
)
1179 if (c
>= 'a' && c
<= 'z')
1180 return c
- 'a' + 'A';
1185 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1189 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1192 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1196 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1200 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1207 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1208 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1209 (*f
)->filename
, (*f
)->line_num
);
1210 if (file
->line_num
> 0) {
1211 strcat_printf(buf
, sizeof(buf
),
1212 "%s:%d: ", file
->filename
, file
->line_num
);
1214 strcat_printf(buf
, sizeof(buf
),
1215 "%s: ", file
->filename
);
1218 strcat_printf(buf
, sizeof(buf
),
1222 strcat_printf(buf
, sizeof(buf
), "warning: ");
1223 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1225 if (!s1
->error_func
) {
1226 /* default case: stderr */
1227 fprintf(stderr
, "%s\n", buf
);
1229 s1
->error_func(s1
->error_opaque
, buf
);
1231 if (!is_warning
|| s1
->warn_error
)
1236 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1237 void (*error_func
)(void *opaque
, const char *msg
))
1239 s
->error_opaque
= error_opaque
;
1240 s
->error_func
= error_func
;
1244 /* error without aborting current compilation */
1245 void error_noabort(const char *fmt
, ...)
1247 TCCState
*s1
= tcc_state
;
1251 error1(s1
, 0, fmt
, ap
);
1255 void error(const char *fmt
, ...)
1257 TCCState
*s1
= tcc_state
;
1261 error1(s1
, 0, fmt
, ap
);
1263 /* better than nothing: in some cases, we accept to handle errors */
1264 if (s1
->error_set_jmp_enabled
) {
1265 longjmp(s1
->error_jmp_buf
, 1);
1267 /* XXX: eliminate this someday */
1272 void expect(const char *msg
)
1274 error("%s expected", msg
);
1277 void warning(const char *fmt
, ...)
1279 TCCState
*s1
= tcc_state
;
1286 error1(s1
, 1, fmt
, ap
);
1293 error("'%c' expected", c
);
1297 static void test_lvalue(void)
1299 if (!(vtop
->r
& VT_LVAL
))
1303 /* allocate a new token */
1304 static TokenSym
*tok_alloc_new(TokenSym
**pts
, const char *str
, int len
)
1306 TokenSym
*ts
, **ptable
;
1309 if (tok_ident
>= SYM_FIRST_ANOM
)
1310 error("memory full");
1312 /* expand token table if needed */
1313 i
= tok_ident
- TOK_IDENT
;
1314 if ((i
% TOK_ALLOC_INCR
) == 0) {
1315 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1317 error("memory full");
1318 table_ident
= ptable
;
1321 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1322 table_ident
[i
] = ts
;
1323 ts
->tok
= tok_ident
++;
1324 ts
->sym_define
= NULL
;
1325 ts
->sym_label
= NULL
;
1326 ts
->sym_struct
= NULL
;
1327 ts
->sym_identifier
= NULL
;
1329 ts
->hash_next
= NULL
;
1330 memcpy(ts
->str
, str
, len
);
1331 ts
->str
[len
] = '\0';
1336 #define TOK_HASH_INIT 1
1337 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1339 /* find a token and add it if not found */
1340 static TokenSym
*tok_alloc(const char *str
, int len
)
1342 TokenSym
*ts
, **pts
;
1348 h
= TOK_HASH_FUNC(h
, ((unsigned char *)str
)[i
]);
1349 h
&= (TOK_HASH_SIZE
- 1);
1351 pts
= &hash_ident
[h
];
1356 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1358 pts
= &(ts
->hash_next
);
1360 return tok_alloc_new(pts
, str
, len
);
1363 /* CString handling */
1365 static void cstr_realloc(CString
*cstr
, int new_size
)
1370 size
= cstr
->size_allocated
;
1372 size
= 8; /* no need to allocate a too small first string */
1373 while (size
< new_size
)
1375 data
= tcc_realloc(cstr
->data_allocated
, size
);
1377 error("memory full");
1378 cstr
->data_allocated
= data
;
1379 cstr
->size_allocated
= size
;
1384 static void cstr_ccat(CString
*cstr
, int ch
)
1387 size
= cstr
->size
+ 1;
1388 if (size
> cstr
->size_allocated
)
1389 cstr_realloc(cstr
, size
);
1390 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1394 static void cstr_cat(CString
*cstr
, const char *str
)
1406 /* add a wide char */
1407 static void cstr_wccat(CString
*cstr
, int ch
)
1410 size
= cstr
->size
+ sizeof(int);
1411 if (size
> cstr
->size_allocated
)
1412 cstr_realloc(cstr
, size
);
1413 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1417 static void cstr_new(CString
*cstr
)
1419 memset(cstr
, 0, sizeof(CString
));
1422 /* free string and reset it to NULL */
1423 static void cstr_free(CString
*cstr
)
1425 tcc_free(cstr
->data_allocated
);
1429 #define cstr_reset(cstr) cstr_free(cstr)
1431 static CString
*cstr_dup(CString
*cstr1
)
1436 cstr
= tcc_malloc(sizeof(CString
));
1439 cstr
->size_allocated
= size
;
1440 cstr
->data_allocated
= tcc_malloc(size
);
1441 cstr
->data
= cstr
->data_allocated
;
1442 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1446 /* XXX: unicode ? */
1447 static void add_char(CString
*cstr
, int c
)
1449 if (c
== '\'' || c
== '\"' || c
== '\\') {
1450 /* XXX: could be more precise if char or string */
1451 cstr_ccat(cstr
, '\\');
1453 if (c
>= 32 && c
<= 126) {
1456 cstr_ccat(cstr
, '\\');
1458 cstr_ccat(cstr
, 'n');
1460 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1461 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1462 cstr_ccat(cstr
, '0' + (c
& 7));
1467 /* XXX: buffer overflow */
1468 /* XXX: float tokens */
1469 char *get_tok_str(int v
, CValue
*cv
)
1471 static char buf
[STRING_MAX_SIZE
+ 1];
1472 static CString cstr_buf
;
1478 /* NOTE: to go faster, we give a fixed buffer for small strings */
1479 cstr_reset(&cstr_buf
);
1480 cstr_buf
.data
= buf
;
1481 cstr_buf
.size_allocated
= sizeof(buf
);
1487 /* XXX: not quite exact, but only useful for testing */
1488 sprintf(p
, "%u", cv
->ui
);
1492 /* XXX: not quite exact, but only useful for testing */
1493 sprintf(p
, "%Lu", cv
->ull
);
1497 cstr_ccat(&cstr_buf
, '\'');
1498 add_char(&cstr_buf
, cv
->i
);
1499 cstr_ccat(&cstr_buf
, '\'');
1500 cstr_ccat(&cstr_buf
, '\0');
1504 len
= cstr
->size
- 1;
1506 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1507 cstr_ccat(&cstr_buf
, '\0');
1512 cstr_ccat(&cstr_buf
, '\"');
1514 len
= cstr
->size
- 1;
1516 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1518 len
= (cstr
->size
/ sizeof(int)) - 1;
1520 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1522 cstr_ccat(&cstr_buf
, '\"');
1523 cstr_ccat(&cstr_buf
, '\0');
1532 return strcpy(p
, "<<=");
1534 return strcpy(p
, ">>=");
1536 if (v
< TOK_IDENT
) {
1537 /* search in two bytes table */
1551 } else if (v
< tok_ident
) {
1552 return table_ident
[v
- TOK_IDENT
]->str
;
1553 } else if (v
>= SYM_FIRST_ANOM
) {
1554 /* special name for anonymous symbol */
1555 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1557 /* should never happen */
1562 return cstr_buf
.data
;
1565 /* push, without hashing */
1566 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1569 s
= tcc_malloc(sizeof(Sym
));
1580 /* find a symbol and return its associated structure. 's' is the top
1581 of the symbol stack */
1582 static Sym
*sym_find2(Sym
*s
, int v
)
1592 /* structure lookup */
1593 static inline Sym
*struct_find(int v
)
1596 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1598 return table_ident
[v
]->sym_struct
;
1601 /* find an identifier */
1602 static inline Sym
*sym_find(int v
)
1605 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1607 return table_ident
[v
]->sym_identifier
;
1610 /* push a given symbol on the symbol stack */
1611 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1620 s
= sym_push2(ps
, v
, type
->t
, c
);
1621 s
->type
.ref
= type
->ref
;
1623 /* don't record fields or anonymous symbols */
1625 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1626 /* record symbol in token array */
1627 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1629 ps
= &ts
->sym_struct
;
1631 ps
= &ts
->sym_identifier
;
1638 /* push a global identifier */
1639 static Sym
*global_identifier_push(int v
, int t
, int c
)
1642 s
= sym_push2(&global_stack
, v
, t
, c
);
1643 /* don't record anonymous symbol */
1644 if (v
< SYM_FIRST_ANOM
) {
1645 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1646 /* modify the top most local identifier, so that
1647 sym_identifier will point to 's' when popped */
1649 ps
= &(*ps
)->prev_tok
;
1656 /* pop symbols until top reaches 'b' */
1657 static void sym_pop(Sym
**ptop
, Sym
*b
)
1667 /* remove symbol in token array */
1669 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1670 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1672 ps
= &ts
->sym_struct
;
1674 ps
= &ts
->sym_identifier
;
1685 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1690 fd
= open(filename
, O_RDONLY
);
1693 bf
= tcc_malloc(sizeof(BufferedFile
));
1699 bf
->buf_ptr
= bf
->buffer
;
1700 bf
->buf_end
= bf
->buffer
;
1701 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1702 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1704 bf
->ifndef_macro
= 0;
1705 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1706 // printf("opening '%s'\n", filename);
1710 void tcc_close(BufferedFile
*bf
)
1712 total_lines
+= bf
->line_num
;
1717 /* fill input buffer and peek next char */
1718 static int tcc_peekc_slow(BufferedFile
*bf
)
1721 /* only tries to read if really end of buffer */
1722 if (bf
->buf_ptr
>= bf
->buf_end
) {
1724 #if defined(PARSE_DEBUG)
1729 len
= read(bf
->fd
, bf
->buffer
, len
);
1736 bf
->buf_ptr
= bf
->buffer
;
1737 bf
->buf_end
= bf
->buffer
+ len
;
1738 *bf
->buf_end
= CH_EOB
;
1740 if (bf
->buf_ptr
< bf
->buf_end
) {
1741 return bf
->buf_ptr
[0];
1743 bf
->buf_ptr
= bf
->buf_end
;
1748 /* return the current character, handling end of block if necessary
1750 static int handle_eob(void)
1752 return tcc_peekc_slow(file
);
1755 /* read next char from current input file and handle end of input buffer */
1756 static inline void inp(void)
1758 ch
= *(++(file
->buf_ptr
));
1759 /* end of buffer/file handling */
1764 /* handle '\[\r]\n' */
1765 static void handle_stray(void)
1767 while (ch
== '\\') {
1772 } else if (ch
== '\r') {
1780 error("stray '\\' in program");
1785 /* skip the stray and handle the \\n case. Output an error if
1786 incorrect char after the stray */
1787 static int handle_stray1(uint8_t *p
)
1791 if (p
>= file
->buf_end
) {
1808 /* handle just the EOB case, but not stray */
1809 #define PEEKC_EOB(c, p)\
1820 /* handle the complicated stray case */
1821 #define PEEKC(c, p)\
1826 c = handle_stray1(p);\
1831 /* input with '\[\r]\n' handling. Note that this function cannot
1832 handle other characters after '\', so you cannot call it inside
1833 strings or comments */
1834 static void minp(void)
1842 /* single line C++ comments */
1843 static uint8_t *parse_line_comment(uint8_t *p
)
1851 if (c
== '\n' || c
== CH_EOF
) {
1853 } else if (c
== '\\') {
1862 } else if (c
== '\r') {
1880 static uint8_t *parse_comment(uint8_t *p
)
1886 /* fast skip loop */
1889 if (c
== '\n' || c
== '*' || c
== '\\')
1893 if (c
== '\n' || c
== '*' || c
== '\\')
1897 /* now we can handle all the cases */
1901 } else if (c
== '*') {
1907 } else if (c
== '/') {
1908 goto end_of_comment
;
1909 } else if (c
== '\\') {
1914 /* skip '\[\r]\n', otherwise just skip the stray */
1920 } else if (c
== '\r') {
1937 /* stray, eob or eof */
1942 error("unexpected end of file in comment");
1943 } else if (c
== '\\') {
1955 /* space exlcuding newline */
1956 static inline int is_space(int ch
)
1958 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1961 static inline void skip_spaces(void)
1963 while (is_space(ch
))
1967 /* parse a string without interpreting escapes */
1968 static uint8_t *parse_pp_string(uint8_t *p
,
1969 int sep
, CString
*str
)
1977 } else if (c
== '\\') {
1982 unterminated_string
:
1983 /* XXX: indicate line number of start of string */
1984 error("missing terminating %c character", sep
);
1985 } else if (c
== '\\') {
1986 /* escape : just skip \[\r]\n */
1991 } else if (c
== '\r') {
1994 expect("'\n' after '\r'");
1997 } else if (c
== CH_EOF
) {
1998 goto unterminated_string
;
2001 cstr_ccat(str
, '\\');
2007 } else if (c
== '\n') {
2010 } else if (c
== '\r') {
2013 cstr_ccat(str
, '\r');
2029 /* skip block of text until #else, #elif or #endif. skip also pairs of
2031 void preprocess_skip(void)
2033 int a
, start_of_line
, c
;
2060 } else if (c
== '\\') {
2061 /* XXX: incorrect: should not give an error */
2062 ch
= file
->buf_ptr
[0];
2070 p
= parse_pp_string(p
, c
, NULL
);
2079 p
= parse_comment(p
);
2080 } else if (ch
== '/') {
2081 p
= parse_line_comment(p
);
2087 if (start_of_line
) {
2092 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
2094 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
2096 else if (tok
== TOK_ENDIF
)
2110 /* ParseState handling */
2112 /* XXX: currently, no include file info is stored. Thus, we cannot display
2113 accurate messages if the function or data definition spans multiple
2116 /* save current parse state in 's' */
2117 void save_parse_state(ParseState
*s
)
2119 s
->line_num
= file
->line_num
;
2120 s
->macro_ptr
= macro_ptr
;
2125 /* restore parse state from 's' */
2126 void restore_parse_state(ParseState
*s
)
2128 file
->line_num
= s
->line_num
;
2129 macro_ptr
= s
->macro_ptr
;
2134 /* return the number of additional 'ints' necessary to store the
2136 static inline int tok_ext_size(int t
)
2155 return LDOUBLE_SIZE
/ 4;
2161 /* token string handling */
2163 static inline void tok_str_new(TokenString
*s
)
2167 s
->allocated_len
= 0;
2168 s
->last_line_num
= -1;
2171 static void tok_str_free(int *str
)
2180 /* NOTE: we test zero separately so that GCC can generate a
2181 table for the following switch */
2196 /* XXX: use a macro to be portable on 64 bit ? */
2197 cstr
= (CString
*)p
[1];
2208 p
+= 1 + (LDOUBLE_SIZE
/ 4);
2218 static int *tok_str_realloc(TokenString
*s
)
2222 len
= s
->allocated_len
+ TOK_STR_ALLOC_INCR
;
2223 str
= tcc_realloc(s
->str
, len
* sizeof(int));
2225 error("memory full");
2226 s
->allocated_len
= len
;
2231 static void tok_str_add(TokenString
*s
, int t
)
2237 if (len
>= s
->allocated_len
)
2238 str
= tok_str_realloc(s
);
2243 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
2250 /* allocate space for worst case */
2251 if (len
+ TOK_MAX_SIZE
> s
->allocated_len
)
2252 str
= tok_str_realloc(s
);
2261 str
[len
++] = cv
->tab
[0];
2266 str
[len
++] = (int)cstr_dup(cv
->cstr
);
2271 #if LDOUBLE_SIZE == 8
2274 str
[len
++] = cv
->tab
[0];
2275 str
[len
++] = cv
->tab
[1];
2277 #if LDOUBLE_SIZE == 12
2279 str
[len
++] = cv
->tab
[0];
2280 str
[len
++] = cv
->tab
[1];
2281 str
[len
++] = cv
->tab
[2];
2282 #elif LDOUBLE_SIZE != 8
2283 #error add long double size support
2292 /* add the current parse token in token string 's' */
2293 static void tok_str_add_tok(TokenString
*s
)
2297 /* save line number info */
2298 if (file
->line_num
!= s
->last_line_num
) {
2299 s
->last_line_num
= file
->line_num
;
2300 cval
.i
= s
->last_line_num
;
2301 tok_str_add2(s
, TOK_LINENUM
, &cval
);
2303 tok_str_add2(s
, tok
, &tokc
);
2306 #if LDOUBLE_SIZE == 12
2307 #define LDOUBLE_GET(p, cv) \
2311 #elif LDOUBLE_SIZE == 8
2312 #define LDOUBLE_GET(p, cv) \
2316 #error add long double size support
2320 /* get a token from an integer array and increment pointer
2321 accordingly. we code it as a macro to avoid pointer aliasing. */
2322 #define TOK_GET(t, p, cv) \
2344 case TOK_CLDOUBLE: \
2345 LDOUBLE_GET(p, cv); \
2346 p += LDOUBLE_SIZE / 4; \
2353 /* defines handling */
2354 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
2358 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
2359 s
->next
= first_arg
;
2360 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
2363 /* undefined a define symbol. Its name is just set to zero */
2364 static void define_undef(Sym
*s
)
2368 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2369 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2373 static inline Sym
*define_find(int v
)
2376 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2378 return table_ident
[v
]->sym_define
;
2381 /* free define stack until top reaches 'b' */
2382 static void free_defines(Sym
*b
)
2390 /* do not free args or predefined defines */
2392 tok_str_free((int *)top
->c
);
2394 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2395 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2403 static Sym
*label_find(int v
)
2406 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2408 return table_ident
[v
]->sym_label
;
2411 static Sym
*label_push(Sym
**ptop
, int v
, int flags
)
2414 s
= sym_push2(ptop
, v
, 0, 0);
2416 ps
= &table_ident
[v
- TOK_IDENT
]->sym_label
;
2417 if (ptop
== &global_label_stack
) {
2418 /* modify the top most local identifier, so that
2419 sym_identifier will point to 's' when popped */
2421 ps
= &(*ps
)->prev_tok
;
2428 /* pop labels until element last is reached. Look if any labels are
2429 undefined. Define symbols if '&&label' was used. */
2430 static void label_pop(Sym
**ptop
, Sym
*slast
)
2433 for(s
= *ptop
; s
!= slast
; s
= s1
) {
2435 if (s
->r
== LABEL_DECLARED
) {
2436 warning("label '%s' declared but not used", get_tok_str(s
->v
, NULL
));
2437 } else if (s
->r
== LABEL_FORWARD
) {
2438 error("label '%s' used but not defined",
2439 get_tok_str(s
->v
, NULL
));
2442 /* define corresponding symbol. A size of
2444 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
2448 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= s
->prev_tok
;
2454 /* eval an expression for #if/#elif */
2455 static int expr_preprocess(void)
2461 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2462 next(); /* do macro subst */
2463 if (tok
== TOK_DEFINED
) {
2468 c
= define_find(tok
) != 0;
2473 } else if (tok
>= TOK_IDENT
) {
2474 /* if undefined macro */
2478 tok_str_add_tok(&str
);
2480 tok_str_add(&str
, -1); /* simulate end of file */
2481 tok_str_add(&str
, 0);
2482 /* now evaluate C constant expression */
2483 macro_ptr
= str
.str
;
2487 tok_str_free(str
.str
);
2491 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2492 static void tok_print(int *str
)
2498 TOK_GET(t
, str
, cval
);
2501 printf(" %s", get_tok_str(t
, &cval
));
2507 /* parse after #define */
2508 static void parse_define(void)
2510 Sym
*s
, *first
, **ps
;
2511 int v
, t
, varg
, is_vaargs
, c
;
2516 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2517 /* XXX: should check if same macro (ANSI) */
2520 /* '(' must be just after macro definition for MACRO_FUNC */
2521 c
= file
->buf_ptr
[0];
2523 c
= handle_stray1(file
->buf_ptr
);
2528 while (tok
!= ')') {
2532 if (varg
== TOK_DOTS
) {
2533 varg
= TOK___VA_ARGS__
;
2535 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2539 if (varg
< TOK_IDENT
)
2540 error("badly punctuated parameter list");
2541 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2552 /* EOF testing necessary for '-D' handling */
2553 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2554 tok_str_add2(&str
, tok
, &tokc
);
2557 tok_str_add(&str
, 0);
2559 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2562 define_push(v
, t
, str
.str
, first
);
2565 /* XXX: use a token or a hash table to accelerate matching ? */
2566 static CachedInclude
*search_cached_include(TCCState
*s1
,
2567 int type
, const char *filename
)
2572 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
2573 e
= s1
->cached_includes
[i
];
2574 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2580 static inline void add_cached_include(TCCState
*s1
, int type
,
2581 const char *filename
, int ifndef_macro
)
2585 if (search_cached_include(s1
, type
, filename
))
2588 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2590 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2594 strcpy(e
->filename
, filename
);
2595 e
->ifndef_macro
= ifndef_macro
;
2596 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2599 /* is_bof is true if first non space token at beginning of file */
2600 static void preprocess(int is_bof
)
2602 TCCState
*s1
= tcc_state
;
2603 int size
, i
, c
, n
, saved_parse_flags
;
2604 char buf
[1024], *q
, *p
;
2610 saved_parse_flags
= parse_flags
;
2611 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
|
2612 PARSE_FLAG_LINEFEED
;
2622 s
= define_find(tok
);
2623 /* undefine symbol by putting an invalid name */
2628 ch
= file
->buf_ptr
[0];
2629 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2634 } else if (ch
== '\"') {
2637 /* XXX: better stray handling */
2640 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2641 if ((q
- buf
) < sizeof(buf
) - 1)
2648 /* eat all spaces and comments after include */
2649 /* XXX: slightly incorrect */
2650 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2654 /* computed #include : either we have only strings or
2655 we have anything enclosed in '<>' */
2658 if (tok
== TOK_STR
) {
2659 while (tok
!= TOK_LINEFEED
) {
2660 if (tok
!= TOK_STR
) {
2662 error("'#include' expects \"FILENAME\" or <FILENAME>");
2664 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2670 while (tok
!= TOK_LINEFEED
) {
2671 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2675 /* check syntax and remove '<>' */
2676 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2677 goto include_syntax
;
2678 memmove(buf
, buf
+ 1, len
- 2);
2679 buf
[len
- 2] = '\0';
2684 e
= search_cached_include(s1
, c
, buf
);
2685 if (e
&& define_find(e
->ifndef_macro
)) {
2686 /* no need to parse the include because the 'ifndef macro'
2689 printf("%s: skipping %s\n", file
->filename
, buf
);
2693 /* first search in current dir if "header.h" */
2695 p
= strrchr(file
->filename
, '/');
2697 size
= p
+ 1 - file
->filename
;
2698 if (size
> sizeof(buf1
) - 1)
2699 size
= sizeof(buf1
) - 1;
2700 memcpy(buf1
, file
->filename
, size
);
2702 pstrcat(buf1
, sizeof(buf1
), buf
);
2703 f
= tcc_open(s1
, buf1
);
2707 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2708 error("#include recursion too deep");
2709 /* now search in all the include paths */
2710 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2711 for(i
= 0; i
< n
; i
++) {
2713 if (i
< s1
->nb_include_paths
)
2714 path
= s1
->include_paths
[i
];
2716 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2717 pstrcpy(buf1
, sizeof(buf1
), path
);
2718 pstrcat(buf1
, sizeof(buf1
), "/");
2719 pstrcat(buf1
, sizeof(buf1
), buf
);
2720 f
= tcc_open(s1
, buf1
);
2724 error("include file '%s' not found", buf
);
2728 printf("%s: including %s\n", file
->filename
, buf1
);
2731 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2732 /* push current file in stack */
2733 /* XXX: fix current line init */
2734 *s1
->include_stack_ptr
++ = file
;
2736 /* add include file debug info */
2738 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2740 tok_flags
|= TOK_FLAG_BOF
| TOK_FLAG_BOL
;
2741 ch
= file
->buf_ptr
[0];
2749 c
= expr_preprocess();
2755 if (tok
< TOK_IDENT
)
2756 error("invalid argument for '#if%sdef'", c
? "n" : "");
2760 printf("#ifndef %s\n", get_tok_str(tok
, NULL
));
2762 file
->ifndef_macro
= tok
;
2765 c
= (define_find(tok
) != 0) ^ c
;
2767 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2768 error("memory full");
2769 *s1
->ifdef_stack_ptr
++ = c
;
2772 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2773 error("#else without matching #if");
2774 if (s1
->ifdef_stack_ptr
[-1] & 2)
2775 error("#else after #else");
2776 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2779 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2780 error("#elif without matching #if");
2781 c
= s1
->ifdef_stack_ptr
[-1];
2783 error("#elif after #else");
2784 /* last #if/#elif expression was true: we skip */
2787 c
= expr_preprocess();
2788 s1
->ifdef_stack_ptr
[-1] = c
;
2798 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2799 error("#endif without matching #if");
2800 s1
->ifdef_stack_ptr
--;
2801 /* '#ifndef macro' was at the start of file. Now we check if
2802 an '#endif' is exactly at the end of file */
2803 if (file
->ifndef_macro
&&
2804 s1
->ifdef_stack_ptr
== file
->ifdef_stack_ptr
) {
2805 file
->ifndef_macro_saved
= file
->ifndef_macro
;
2806 /* need to set to zero to avoid false matches if another
2807 #ifndef at middle of file */
2808 file
->ifndef_macro
= 0;
2809 while (tok
!= TOK_LINEFEED
)
2811 tok_flags
|= TOK_FLAG_ENDIF
;
2817 if (tok
!= TOK_CINT
)
2819 file
->line_num
= tokc
.i
- 1; /* the line number will be incremented after */
2821 if (tok
!= TOK_LINEFEED
) {
2824 pstrcpy(file
->filename
, sizeof(file
->filename
),
2825 (char *)tokc
.cstr
->data
);
2831 ch
= file
->buf_ptr
[0];
2834 while (ch
!= '\n' && ch
!= CH_EOF
) {
2835 if ((q
- buf
) < sizeof(buf
) - 1)
2841 error("#error %s", buf
);
2843 warning("#warning %s", buf
);
2849 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
2850 /* '!' is ignored to allow C scripts. numbers are ignored
2851 to emulate cpp behaviour */
2853 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
2857 /* ignore other preprocess commands or #! for C scripts */
2858 while (tok
!= TOK_LINEFEED
)
2861 parse_flags
= saved_parse_flags
;
2864 /* evaluate escape codes in a string. */
2865 static void parse_escape_string(CString
*outstr
, const uint8_t *buf
, int is_long
)
2880 case '0': case '1': case '2': case '3':
2881 case '4': case '5': case '6': case '7':
2882 /* at most three octal digits */
2887 n
= n
* 8 + c
- '0';
2891 n
= n
* 8 + c
- '0';
2896 goto add_char_nonext
;
2902 if (c
>= 'a' && c
<= 'f')
2904 else if (c
>= 'A' && c
<= 'F')
2914 goto add_char_nonext
;
2938 goto invalid_escape
;
2948 if (c
>= '!' && c
<= '~')
2949 warning("unknown escape sequence: \'\\%c\'", c
);
2951 warning("unknown escape sequence: \'\\x%x\'", c
);
2958 cstr_ccat(outstr
, c
);
2960 cstr_wccat(outstr
, c
);
2962 /* add a trailing '\0' */
2964 cstr_ccat(outstr
, '\0');
2966 cstr_wccat(outstr
, '\0');
2969 /* we use 64 bit numbers */
2972 /* bn = (bn << shift) | or_val */
2973 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2977 for(i
=0;i
<BN_SIZE
;i
++) {
2979 bn
[i
] = (v
<< shift
) | or_val
;
2980 or_val
= v
>> (32 - shift
);
2984 void bn_zero(unsigned int *bn
)
2987 for(i
=0;i
<BN_SIZE
;i
++) {
2992 /* parse number in null terminated string 'p' and return it in the
2994 void parse_number(const char *p
)
2996 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
2998 unsigned int bn
[BN_SIZE
];
3009 goto float_frac_parse
;
3010 } else if (t
== '0') {
3011 if (ch
== 'x' || ch
== 'X') {
3015 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
3021 /* parse all digits. cannot check octal numbers at this stage
3022 because of floating point constants */
3024 if (ch
>= 'a' && ch
<= 'f')
3026 else if (ch
>= 'A' && ch
<= 'F')
3034 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
3036 error("number too long");
3042 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
3043 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
3045 /* NOTE: strtox should support that for hexa numbers, but
3046 non ISOC99 libcs do not support it, so we prefer to do
3048 /* hexadecimal or binary floats */
3049 /* XXX: handle overflows */
3061 } else if (t
>= 'a') {
3063 } else if (t
>= 'A') {
3068 bn_lshift(bn
, shift
, t
);
3075 if (t
>= 'a' && t
<= 'f') {
3077 } else if (t
>= 'A' && t
<= 'F') {
3079 } else if (t
>= '0' && t
<= '9') {
3085 error("invalid digit");
3086 bn_lshift(bn
, shift
, t
);
3091 if (ch
!= 'p' && ch
!= 'P')
3098 } else if (ch
== '-') {
3102 if (ch
< '0' || ch
> '9')
3103 expect("exponent digits");
3104 while (ch
>= '0' && ch
<= '9') {
3105 exp_val
= exp_val
* 10 + ch
- '0';
3108 exp_val
= exp_val
* s
;
3110 /* now we can generate the number */
3111 /* XXX: should patch directly float number */
3112 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
3113 d
= ldexp(d
, exp_val
- frac_bits
);
3118 /* float : should handle overflow */
3120 } else if (t
== 'L') {
3123 /* XXX: not large enough */
3124 tokc
.ld
= (long double)d
;
3130 /* decimal floats */
3132 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3137 while (ch
>= '0' && ch
<= '9') {
3138 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3144 if (ch
== 'e' || ch
== 'E') {
3145 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3149 if (ch
== '-' || ch
== '+') {
3150 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3155 if (ch
< '0' || ch
> '9')
3156 expect("exponent digits");
3157 while (ch
>= '0' && ch
<= '9') {
3158 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3170 tokc
.f
= strtof(token_buf
, NULL
);
3171 } else if (t
== 'L') {
3174 tokc
.ld
= strtold(token_buf
, NULL
);
3177 tokc
.d
= strtod(token_buf
, NULL
);
3181 unsigned long long n
, n1
;
3184 /* integer number */
3187 if (b
== 10 && *q
== '0') {
3194 /* no need for checks except for base 10 / 8 errors */
3197 } else if (t
>= 'a') {
3199 } else if (t
>= 'A') {
3204 error("invalid digit");
3208 /* detect overflow */
3209 /* XXX: this test is not reliable */
3211 error("integer constant overflow");
3214 /* XXX: not exactly ANSI compliant */
3215 if ((n
& 0xffffffff00000000LL
) != 0) {
3220 } else if (n
> 0x7fffffff) {
3231 error("three 'l's in integer constant");
3234 if (tok
== TOK_CINT
)
3236 else if (tok
== TOK_CUINT
)
3240 } else if (t
== 'U') {
3242 error("two 'u's in integer constant");
3244 if (tok
== TOK_CINT
)
3246 else if (tok
== TOK_CLLONG
)
3253 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
3261 #define PARSE2(c1, tok1, c2, tok2) \
3272 /* return next token without macro substitution */
3273 static inline void next_nomacro1(void)
3293 /* first look if it is in fact an end of buffer */
3294 if (p
>= file
->buf_end
) {
3298 if (p
>= file
->buf_end
)
3311 TCCState
*s1
= tcc_state
;
3312 if (parse_flags
& PARSE_FLAG_LINEFEED
) {
3314 } else if (s1
->include_stack_ptr
== s1
->include_stack
||
3315 !(parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3316 /* no include left : end of file. */
3319 /* pop include file */
3321 /* test if previous '#endif' was after a #ifdef at
3323 if (tok_flags
& TOK_FLAG_ENDIF
) {
3325 printf("#endif %s\n", get_tok_str(file
->ifndef_macro_saved
, NULL
));
3327 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
3328 file
->ifndef_macro_saved
);
3331 /* add end of include file debug info */
3333 put_stabd(N_EINCL
, 0, 0);
3335 /* pop include stack */
3337 s1
->include_stack_ptr
--;
3338 file
= *s1
->include_stack_ptr
;
3346 if (parse_flags
& PARSE_FLAG_LINEFEED
) {
3350 tok_flags
|= TOK_FLAG_BOL
;
3359 if ((tok_flags
& TOK_FLAG_BOL
) &&
3360 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3362 preprocess(tok_flags
& TOK_FLAG_BOF
);
3368 tok
= TOK_TWOSHARPS
;
3375 case 'a': case 'b': case 'c': case 'd':
3376 case 'e': case 'f': case 'g': case 'h':
3377 case 'i': case 'j': case 'k': case 'l':
3378 case 'm': case 'n': case 'o': case 'p':
3379 case 'q': case 'r': case 's': case 't':
3380 case 'u': case 'v': case 'w': case 'x':
3382 case 'A': case 'B': case 'C': case 'D':
3383 case 'E': case 'F': case 'G': case 'H':
3384 case 'I': case 'J': case 'K':
3385 case 'M': case 'N': case 'O': case 'P':
3386 case 'Q': case 'R': case 'S': case 'T':
3387 case 'U': case 'V': case 'W': case 'X':
3393 h
= TOK_HASH_FUNC(h
, c
);
3397 if (!isidnum_table
[c
])
3399 h
= TOK_HASH_FUNC(h
, c
);
3406 /* fast case : no stray found, so we have the full token
3407 and we have already hashed it */
3409 h
&= (TOK_HASH_SIZE
- 1);
3410 pts
= &hash_ident
[h
];
3415 if (ts
->len
== len
&& !memcmp(ts
->str
, p1
, len
))
3417 pts
= &(ts
->hash_next
);
3419 ts
= tok_alloc_new(pts
, p1
, len
);
3423 cstr_reset(&tokcstr
);
3426 cstr_ccat(&tokcstr
, *p1
);
3432 while (isidnum_table
[c
]) {
3433 cstr_ccat(&tokcstr
, c
);
3436 ts
= tok_alloc(tokcstr
.data
, tokcstr
.size
);
3442 if (t
!= '\\' && t
!= '\'' && t
!= '\"') {
3444 goto parse_ident_fast
;
3447 if (c
== '\'' || c
== '\"') {
3451 cstr_reset(&tokcstr
);
3452 cstr_ccat(&tokcstr
, 'L');
3453 goto parse_ident_slow
;
3457 case '0': case '1': case '2': case '3':
3458 case '4': case '5': case '6': case '7':
3461 cstr_reset(&tokcstr
);
3462 /* after the first digit, accept digits, alpha, '.' or sign if
3463 prefixed by 'eEpP' */
3467 cstr_ccat(&tokcstr
, c
);
3469 if (!(isnum(c
) || isid(c
) || c
== '.' ||
3470 ((c
== '+' || c
== '-') &&
3471 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
3474 /* We add a trailing '\0' to ease parsing */
3475 cstr_ccat(&tokcstr
, '\0');
3476 tokc
.cstr
= &tokcstr
;
3480 /* special dot handling because it can also start a number */
3483 cstr_reset(&tokcstr
);
3484 cstr_ccat(&tokcstr
, '.');
3486 } else if (c
== '.') {
3506 /* parse the string */
3508 p
= parse_pp_string(p
, sep
, &str
);
3509 cstr_ccat(&str
, '\0');
3511 /* eval the escape (should be done as TOK_PPNUM) */
3512 cstr_reset(&tokcstr
);
3513 parse_escape_string(&tokcstr
, str
.data
, is_long
);
3518 /* XXX: make it portable */
3522 char_size
= sizeof(int);
3523 if (tokcstr
.size
<= char_size
)
3524 error("empty character constant");
3525 if (tokcstr
.size
> 2 * char_size
)
3526 warning("multi-character character constant");
3528 tokc
.i
= *(int8_t *)tokcstr
.data
;
3531 tokc
.i
= *(int *)tokcstr
.data
;
3535 tokc
.cstr
= &tokcstr
;
3549 } else if (c
== '<') {
3567 } else if (c
== '>') {
3585 } else if (c
== '=') {
3598 } else if (c
== '=') {
3611 } else if (c
== '=') {
3624 } else if (c
== '=') {
3627 } else if (c
== '>') {
3635 PARSE2('!', '!', '=', TOK_NE
)
3636 PARSE2('=', '=', '=', TOK_EQ
)
3637 PARSE2('*', '*', '=', TOK_A_MUL
)
3638 PARSE2('%', '%', '=', TOK_A_MOD
)
3639 PARSE2('^', '^', '=', TOK_A_XOR
)
3641 /* comments or operator */
3645 p
= parse_comment(p
);
3647 } else if (c
== '/') {
3648 p
= parse_line_comment(p
);
3650 } else if (c
== '=') {
3670 case '$': /* only used in assembler */
3675 error("unrecognized character \\x%02x", c
);
3680 #if defined(PARSE_DEBUG)
3681 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3685 /* return next token without macro substitution. Can read input from
3687 static void next_nomacro(void)
3693 TOK_GET(tok
, macro_ptr
, tokc
);
3694 if (tok
== TOK_LINENUM
) {
3695 file
->line_num
= tokc
.i
;
3704 /* substitute args in macro_str and return allocated string */
3705 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
3707 int *st
, last_tok
, t
, notfirst
;
3716 TOK_GET(t
, macro_str
, cval
);
3721 TOK_GET(t
, macro_str
, cval
);
3724 s
= sym_find2(args
, t
);
3731 cstr_ccat(&cstr
, ' ');
3732 TOK_GET(t
, st
, cval
);
3733 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
3736 cstr_ccat(&cstr
, '\0');
3738 printf("stringize: %s\n", (char *)cstr
.data
);
3742 tok_str_add2(&str
, TOK_STR
, &cval
);
3745 tok_str_add2(&str
, t
, &cval
);
3747 } else if (t
>= TOK_IDENT
) {
3748 s
= sym_find2(args
, t
);
3751 /* if '##' is present before or after, no arg substitution */
3752 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
3753 /* special case for var arg macros : ## eats the
3754 ',' if empty VA_ARGS variable. */
3755 /* XXX: test of the ',' is not 100%
3756 reliable. should fix it to avoid security
3758 if (gnu_ext
&& s
->type
.t
&&
3759 last_tok
== TOK_TWOSHARPS
&&
3760 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
3762 /* suppress ',' '##' */
3765 /* suppress '##' and add variable */
3773 TOK_GET(t1
, st
, cval
);
3776 tok_str_add2(&str
, t1
, &cval
);
3780 /* NOTE: the stream cannot be read when macro
3781 substituing an argument */
3782 macro_subst(&str
, nested_list
, st
, 0);
3785 tok_str_add(&str
, t
);
3788 tok_str_add2(&str
, t
, &cval
);
3792 tok_str_add(&str
, 0);
3796 static char const ab_month_name
[12][4] =
3798 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
3799 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
3802 /* do macro substitution of current token with macro 's' and add
3803 result to (tok_str,tok_len). 'nested_list' is the list of all
3804 macros we got inside to avoid recursing. Return non zero if no
3805 substitution needs to be done */
3806 static int macro_subst_tok(TokenString
*tok_str
,
3807 Sym
**nested_list
, Sym
*s
, int can_read_stream
)
3809 Sym
*args
, *sa
, *sa1
;
3810 int mstr_allocated
, parlevel
, *mstr
, t
, t1
;
3817 /* if symbol is a macro, prepare substitution */
3819 /* special macros */
3820 if (tok
== TOK___LINE__
) {
3821 snprintf(buf
, sizeof(buf
), "%d", file
->line_num
);
3825 } else if (tok
== TOK___FILE__
) {
3826 cstrval
= file
->filename
;
3828 } else if (tok
== TOK___DATE__
|| tok
== TOK___TIME__
) {
3833 tm
= localtime(&ti
);
3834 if (tok
== TOK___DATE__
) {
3835 snprintf(buf
, sizeof(buf
), "%s %2d %d",
3836 ab_month_name
[tm
->tm_mon
], tm
->tm_mday
, tm
->tm_year
+ 1900);
3838 snprintf(buf
, sizeof(buf
), "%02d:%02d:%02d",
3839 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
3846 cstr_cat(&cstr
, cstrval
);
3847 cstr_ccat(&cstr
, '\0');
3849 tok_str_add2(tok_str
, t1
, &cval
);
3854 if (s
->type
.t
== MACRO_FUNC
) {
3855 /* NOTE: we do not use next_nomacro to avoid eating the
3856 next token. XXX: find better solution */
3859 if (t
== 0 && can_read_stream
) {
3860 /* end of macro stream: we must look at the token
3861 after in the file */
3867 /* XXX: incorrect with comments */
3868 ch
= file
->buf_ptr
[0];
3869 while (is_space(ch
) || ch
== '\n')
3873 if (t
!= '(') /* no macro subst */
3876 /* argument macro */
3881 /* NOTE: empty args are allowed, except if no args */
3883 /* handle '()' case */
3884 if (!args
&& !sa
&& tok
== ')')
3887 error("macro '%s' used with too many args",
3888 get_tok_str(s
->v
, 0));
3891 /* NOTE: non zero sa->t indicates VA_ARGS */
3892 while ((parlevel
> 0 ||
3894 (tok
!= ',' || sa
->type
.t
))) &&
3898 else if (tok
== ')')
3900 tok_str_add2(&str
, tok
, &tokc
);
3903 tok_str_add(&str
, 0);
3904 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
3907 /* special case for gcc var args: add an empty
3908 var arg argument if it is omitted */
3909 if (sa
&& sa
->type
.t
&& gnu_ext
)
3919 error("macro '%s' used with too few args",
3920 get_tok_str(s
->v
, 0));
3923 /* now subst each arg */
3924 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3929 tok_str_free((int *)sa
->c
);
3935 sym_push2(nested_list
, s
->v
, 0, 0);
3936 macro_subst(tok_str
, nested_list
, mstr
, 1);
3937 /* pop nested defined symbol */
3939 *nested_list
= sa1
->prev
;
3947 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
3948 return the resulting string (which must be freed). */
3949 static inline int *macro_twosharps(const int *macro_str
)
3952 const int *macro_ptr1
, *start_macro_ptr
, *ptr
, *saved_macro_ptr
;
3954 const char *p1
, *p2
;
3956 TokenString macro_str1
;
3959 start_macro_ptr
= macro_str
;
3960 /* we search the first '##' */
3962 macro_ptr1
= macro_str
;
3963 TOK_GET(t
, macro_str
, cval
);
3964 /* nothing more to do if end of string */
3967 if (*macro_str
== TOK_TWOSHARPS
)
3971 /* we saw '##', so we need more processing to handle it */
3973 tok_str_new(¯o_str1
);
3977 /* add all tokens seen so far */
3978 for(ptr
= start_macro_ptr
; ptr
< macro_ptr1
;) {
3979 TOK_GET(t
, ptr
, cval
);
3980 tok_str_add2(¯o_str1
, t
, &cval
);
3982 saved_macro_ptr
= macro_ptr
;
3983 /* XXX: get rid of the use of macro_ptr here */
3984 macro_ptr
= (int *)macro_str
;
3986 while (*macro_ptr
== TOK_TWOSHARPS
) {
3988 macro_ptr1
= macro_ptr
;
3991 TOK_GET(t
, macro_ptr
, cval
);
3992 /* We concatenate the two tokens if we have an
3993 identifier or a preprocessing number */
3995 p1
= get_tok_str(tok
, &tokc
);
3996 cstr_cat(&cstr
, p1
);
3997 p2
= get_tok_str(t
, &cval
);
3998 cstr_cat(&cstr
, p2
);
3999 cstr_ccat(&cstr
, '\0');
4001 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
4002 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
4003 if (tok
== TOK_PPNUM
) {
4004 /* if number, then create a number token */
4005 /* NOTE: no need to allocate because
4006 tok_str_add2() does it */
4009 /* if identifier, we must do a test to
4010 validate we have a correct identifier */
4011 if (t
== TOK_PPNUM
) {
4021 if (!isnum(c
) && !isid(c
))
4025 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
4026 tok
= ts
->tok
; /* modify current token */
4029 const char *str
= cstr
.data
;
4030 const unsigned char *q
;
4032 /* we look for a valid token */
4033 /* XXX: do more extensive checks */
4034 if (!strcmp(str
, ">>=")) {
4036 } else if (!strcmp(str
, "<<=")) {
4038 } else if (strlen(str
) == 2) {
4039 /* search in two bytes table */
4044 if (q
[0] == str
[0] && q
[1] == str
[1])
4051 /* NOTE: because get_tok_str use a static buffer,
4054 p1
= get_tok_str(tok
, &tokc
);
4055 cstr_cat(&cstr
, p1
);
4056 cstr_ccat(&cstr
, '\0');
4057 p2
= get_tok_str(t
, &cval
);
4058 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
4059 /* cannot merge tokens: just add them separately */
4060 tok_str_add2(¯o_str1
, tok
, &tokc
);
4061 /* XXX: free associated memory ? */
4068 tok_str_add2(¯o_str1
, tok
, &tokc
);
4073 macro_ptr
= (int *)saved_macro_ptr
;
4075 tok_str_add(¯o_str1
, 0);
4076 return macro_str1
.str
;
4080 /* do macro substitution of macro_str and add result to
4081 (tok_str,tok_len). 'nested_list' is the list of all macros we got
4082 inside to avoid recursing. */
4083 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
4084 const int *macro_str
, int can_read_stream
)
4087 int *saved_macro_ptr
, *macro_str1
;
4092 /* first scan for '##' operator handling */
4094 macro_str1
= macro_twosharps(ptr
);
4098 /* NOTE: ptr == NULL can only happen if tokens are read from
4099 file stream due to a macro function call */
4102 TOK_GET(t
, ptr
, cval
);
4107 /* if nested substitution, do nothing */
4108 if (sym_find2(*nested_list
, t
))
4110 saved_macro_ptr
= macro_ptr
;
4111 macro_ptr
= (int *)ptr
;
4113 ret
= macro_subst_tok(tok_str
, nested_list
, s
, can_read_stream
);
4114 ptr
= (int *)macro_ptr
;
4115 macro_ptr
= saved_macro_ptr
;
4120 tok_str_add2(tok_str
, t
, &cval
);
4124 tok_str_free(macro_str1
);
4127 /* return next token with macro substitution */
4128 static void next(void)
4130 Sym
*nested_list
, *s
;
4136 /* if not reading from macro substituted string, then try
4137 to substitute macros */
4138 if (tok
>= TOK_IDENT
&&
4139 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
4140 s
= define_find(tok
);
4142 /* we have a macro: we try to substitute */
4145 if (macro_subst_tok(&str
, &nested_list
, s
, 1) == 0) {
4146 /* substitution done, NOTE: maybe empty */
4147 tok_str_add(&str
, 0);
4148 macro_ptr
= str
.str
;
4149 macro_ptr_allocated
= str
.str
;
4156 /* end of macro or end of unget buffer */
4157 if (unget_buffer_enabled
) {
4158 macro_ptr
= unget_saved_macro_ptr
;
4159 unget_buffer_enabled
= 0;
4161 /* end of macro string: free it */
4162 tok_str_free(macro_ptr_allocated
);
4169 /* convert preprocessor tokens into C tokens */
4170 if (tok
== TOK_PPNUM
&&
4171 (parse_flags
& PARSE_FLAG_TOK_NUM
)) {
4172 parse_number((char *)tokc
.cstr
->data
);
4176 /* push back current token and set current token to 'last_tok'. Only
4177 identifier case handled for labels. */
4178 static inline void unget_tok(int last_tok
)
4182 unget_saved_macro_ptr
= macro_ptr
;
4183 unget_buffer_enabled
= 1;
4184 q
= unget_saved_buffer
;
4187 n
= tok_ext_size(tok
) - 1;
4190 *q
= 0; /* end of token string */
4195 void swap(int *p
, int *q
)
4203 void vsetc(CType
*type
, int r
, CValue
*vc
)
4207 if (vtop
>= vstack
+ VSTACK_SIZE
)
4208 error("memory full");
4209 /* cannot let cpu flags if other instruction are generated. Also
4210 avoid leaving VT_JMP anywhere except on the top of the stack
4211 because it would complicate the code generator. */
4212 if (vtop
>= vstack
) {
4213 v
= vtop
->r
& VT_VALMASK
;
4214 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
4220 vtop
->r2
= VT_CONST
;
4224 /* push integer constant */
4229 vsetc(&int_type
, VT_CONST
, &cval
);
4232 /* Return a static symbol pointing to a section */
4233 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
4234 unsigned long offset
, unsigned long size
)
4240 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
4241 sym
->type
.ref
= type
->ref
;
4242 sym
->r
= VT_CONST
| VT_SYM
;
4243 put_extern_sym(sym
, sec
, offset
, size
);
4247 /* push a reference to a section offset by adding a dummy symbol */
4248 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
4253 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4254 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
4257 /* define a new external reference to a symbol 'v' of type 'u' */
4258 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
4264 /* push forward reference */
4265 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
4266 s
->type
.ref
= type
->ref
;
4267 s
->r
= r
| VT_CONST
| VT_SYM
;
4272 /* define a new external reference to a symbol 'v' of type 'u' */
4273 static Sym
*external_sym(int v
, CType
*type
, int r
)
4279 /* push forward reference */
4280 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
4281 s
->type
.t
|= VT_EXTERN
;
4283 if (!is_compatible_types(&s
->type
, type
))
4284 error("incompatible types for redefinition of '%s'",
4285 get_tok_str(v
, NULL
));
4290 /* push a reference to global symbol v */
4291 static void vpush_global_sym(CType
*type
, int v
)
4296 sym
= external_global_sym(v
, type
, 0);
4298 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4302 void vset(CType
*type
, int r
, int v
)
4307 vsetc(type
, r
, &cval
);
4310 void vseti(int r
, int v
)
4326 void vpushv(SValue
*v
)
4328 if (vtop
>= vstack
+ VSTACK_SIZE
)
4329 error("memory full");
4339 /* save r to the memory stack, and mark it as being free */
4340 void save_reg(int r
)
4342 int l
, saved
, size
, align
;
4346 /* modify all stack values */
4349 for(p
=vstack
;p
<=vtop
;p
++) {
4350 if ((p
->r
& VT_VALMASK
) == r
||
4351 (p
->r2
& VT_VALMASK
) == r
) {
4352 /* must save value on stack if not already done */
4354 /* NOTE: must reload 'r' because r might be equal to r2 */
4355 r
= p
->r
& VT_VALMASK
;
4356 /* store register in the stack */
4358 if ((p
->r
& VT_LVAL
) ||
4359 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
4361 size
= type_size(type
, &align
);
4362 loc
= (loc
- size
) & -align
;
4363 sv
.type
.t
= type
->t
;
4364 sv
.r
= VT_LOCAL
| VT_LVAL
;
4367 #ifdef TCC_TARGET_I386
4368 /* x86 specific: need to pop fp register ST0 if saved */
4369 if (r
== TREG_ST0
) {
4370 o(0xd9dd); /* fstp %st(1) */
4373 /* special long long case */
4374 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
4381 /* mark that stack entry as being saved on the stack */
4382 if (p
->r
& VT_LVAL
) {
4383 /* also clear the bounded flag because the
4384 relocation address of the function was stored in
4386 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
4388 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
4396 /* find a register of class 'rc2' with at most one reference on stack.
4397 * If none, call get_reg(rc) */
4398 int get_reg_ex(int rc
, int rc2
)
4403 for(r
=0;r
<NB_REGS
;r
++) {
4404 if (reg_classes
[r
] & rc2
) {
4407 for(p
= vstack
; p
<= vtop
; p
++) {
4408 if ((p
->r
& VT_VALMASK
) == r
||
4409 (p
->r2
& VT_VALMASK
) == r
)
4419 /* find a free register of class 'rc'. If none, save one register */
4425 /* find a free register */
4426 for(r
=0;r
<NB_REGS
;r
++) {
4427 if (reg_classes
[r
] & rc
) {
4428 for(p
=vstack
;p
<=vtop
;p
++) {
4429 if ((p
->r
& VT_VALMASK
) == r
||
4430 (p
->r2
& VT_VALMASK
) == r
)
4438 /* no register left : free the first one on the stack (VERY
4439 IMPORTANT to start from the bottom to ensure that we don't
4440 spill registers used in gen_opi()) */
4441 for(p
=vstack
;p
<=vtop
;p
++) {
4442 r
= p
->r
& VT_VALMASK
;
4443 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
4445 /* also look at second register (if long long) */
4446 r
= p
->r2
& VT_VALMASK
;
4447 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
4453 /* Should never comes here */
4457 /* save registers up to (vtop - n) stack entry */
4458 void save_regs(int n
)
4463 for(p
= vstack
;p
<= p1
; p
++) {
4464 r
= p
->r
& VT_VALMASK
;
4471 /* move register 's' to 'r', and flush previous value of r to memory
4473 void move_reg(int r
, int s
)
4486 /* get address of vtop (vtop MUST BE an lvalue) */
4489 vtop
->r
&= ~VT_LVAL
;
4490 /* tricky: if saved lvalue, then we can go back to lvalue */
4491 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
4492 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
4495 #ifdef CONFIG_TCC_BCHECK
4496 /* generate lvalue bound code */
4502 vtop
->r
&= ~VT_MUSTBOUND
;
4503 /* if lvalue, then use checking code before dereferencing */
4504 if (vtop
->r
& VT_LVAL
) {
4505 /* if not VT_BOUNDED value, then make one */
4506 if (!(vtop
->r
& VT_BOUNDED
)) {
4507 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
4508 /* must save type because we must set it to int to get pointer */
4510 vtop
->type
.t
= VT_INT
;
4513 gen_bounded_ptr_add();
4514 vtop
->r
|= lval_type
;
4517 /* then check for dereferencing */
4518 gen_bounded_ptr_deref();
4523 /* store vtop a register belonging to class 'rc'. lvalues are
4524 converted to values. Cannot be used if cannot be converted to
4525 register value (such as structures). */
4528 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
4529 unsigned long long ll
;
4531 /* NOTE: get_reg can modify vstack[] */
4532 if (vtop
->type
.t
& VT_BITFIELD
) {
4533 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
4534 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4535 /* remove bit field info to avoid loops */
4536 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4537 /* generate shifts */
4538 vpushi(32 - (bit_pos
+ bit_size
));
4540 vpushi(32 - bit_size
);
4541 /* NOTE: transformed to SHR if unsigned */
4545 if (is_float(vtop
->type
.t
) &&
4546 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4549 unsigned long offset
;
4551 /* XXX: unify with initializers handling ? */
4552 /* CPUs usually cannot use float constants, so we store them
4553 generically in data segment */
4554 size
= type_size(&vtop
->type
, &align
);
4555 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
4556 data_section
->data_offset
= offset
;
4557 /* XXX: not portable yet */
4558 ptr
= section_ptr_add(data_section
, size
);
4561 ptr
[i
] = vtop
->c
.tab
[i
];
4562 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
4563 vtop
->r
|= VT_LVAL
| VT_SYM
;
4567 #ifdef CONFIG_TCC_BCHECK
4568 if (vtop
->r
& VT_MUSTBOUND
)
4572 r
= vtop
->r
& VT_VALMASK
;
4573 /* need to reload if:
4575 - lvalue (need to dereference pointer)
4576 - already a register, but not in the right class */
4577 if (r
>= VT_CONST
||
4578 (vtop
->r
& VT_LVAL
) ||
4579 !(reg_classes
[r
] & rc
) ||
4580 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
4581 !(reg_classes
[vtop
->r2
] & rc
))) {
4583 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
4584 /* two register type load : expand to two words
4586 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4589 vtop
->c
.ui
= ll
; /* first word */
4591 vtop
->r
= r
; /* save register value */
4592 vpushi(ll
>> 32); /* second word */
4593 } else if (r
>= VT_CONST
||
4594 (vtop
->r
& VT_LVAL
)) {
4595 /* load from memory */
4598 vtop
[-1].r
= r
; /* save register value */
4599 /* increment pointer to get second word */
4600 vtop
->type
.t
= VT_INT
;
4606 /* move registers */
4609 vtop
[-1].r
= r
; /* save register value */
4610 vtop
->r
= vtop
[-1].r2
;
4612 /* allocate second register */
4619 /* write second register */
4621 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
4623 /* lvalue of scalar type : need to use lvalue type
4624 because of possible cast */
4627 /* compute memory access type */
4628 if (vtop
->r
& VT_LVAL_BYTE
)
4630 else if (vtop
->r
& VT_LVAL_SHORT
)
4632 if (vtop
->r
& VT_LVAL_UNSIGNED
)
4636 /* restore wanted type */
4639 /* one register type load */
4644 #ifdef TCC_TARGET_C67
4645 /* uses register pairs for doubles */
4646 if ((vtop
->type
.t
& VT_BTYPE
) == VT_DOUBLE
)
4653 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4654 void gv2(int rc1
, int rc2
)
4658 /* generate more generic register first. But VT_JMP or VT_CMP
4659 values must be generated first in all cases to avoid possible
4661 v
= vtop
[0].r
& VT_VALMASK
;
4662 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
4667 /* test if reload is needed for first register */
4668 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
4678 /* test if reload is needed for first register */
4679 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
4685 /* expand long long on stack in two int registers */
4690 u
= vtop
->type
.t
& VT_UNSIGNED
;
4693 vtop
[0].r
= vtop
[-1].r2
;
4694 vtop
[0].r2
= VT_CONST
;
4695 vtop
[-1].r2
= VT_CONST
;
4696 vtop
[0].type
.t
= VT_INT
| u
;
4697 vtop
[-1].type
.t
= VT_INT
| u
;
4700 #ifdef TCC_TARGET_ARM
4701 /* expand long long on stack */
4702 void lexpand_nr(void)
4706 u
= vtop
->type
.t
& VT_UNSIGNED
;
4708 vtop
->r2
= VT_CONST
;
4709 vtop
->type
.t
= VT_INT
| u
;
4710 v
=vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
);
4711 if (v
== VT_CONST
) {
4712 vtop
[-1].c
.ui
= vtop
->c
.ull
;
4713 vtop
->c
.ui
= vtop
->c
.ull
>> 32;
4715 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
4717 vtop
->r
= vtop
[-1].r
;
4718 } else if (v
> VT_CONST
) {
4722 vtop
->r
= vtop
[-1].r2
;
4723 vtop
[-1].r2
= VT_CONST
;
4724 vtop
[-1].type
.t
= VT_INT
| u
;
4728 /* build a long long from two ints */
4731 gv2(RC_INT
, RC_INT
);
4732 vtop
[-1].r2
= vtop
[0].r
;
4733 vtop
[-1].type
.t
= t
;
4737 /* rotate n first stack elements to the bottom
4738 I1 ... In -> I2 ... In I1 [top is right]
4746 for(i
=-n
+1;i
!=0;i
++)
4747 vtop
[i
] = vtop
[i
+1];
4751 /* rotate n first stack elements to the top
4752 I1 ... In -> In I1 ... I(n-1) [top is right]
4760 for(i
= 0;i
< n
- 1; i
++)
4761 vtop
[-i
] = vtop
[-i
- 1];
4765 #ifdef TCC_TARGET_ARM
4766 /* like vrott but in other direction
4767 In ... I1 -> I(n-1) ... I1 In [top is right]
4775 for(i
= n
- 1; i
> 0; i
--)
4776 vtop
[-i
] = vtop
[-i
+ 1];
4781 /* pop stack value */
4785 v
= vtop
->r
& VT_VALMASK
;
4786 #ifdef TCC_TARGET_I386
4787 /* for x86, we need to pop the FP stack */
4788 if (v
== TREG_ST0
&& !nocode_wanted
) {
4789 o(0xd9dd); /* fstp %st(1) */
4792 if (v
== VT_JMP
|| v
== VT_JMPI
) {
4793 /* need to put correct jump if && or || without test */
4799 /* convert stack entry to register and duplicate its value in another
4807 if ((t
& VT_BTYPE
) == VT_LLONG
) {
4814 /* stack: H L L1 H1 */
4822 /* duplicate value */
4833 load(r1
, &sv
); /* move r to r1 */
4835 /* duplicates value */
4840 /* generate CPU independent (unsigned) long long operations */
4841 void gen_opl(int op
)
4843 int t
, a
, b
, op1
, c
, i
;
4850 func
= TOK___divdi3
;
4853 func
= TOK___udivdi3
;
4856 func
= TOK___moddi3
;
4859 func
= TOK___umoddi3
;
4861 /* call generic long long function */
4862 vpush_global_sym(&func_old_type
, func
);
4867 vtop
->r2
= REG_LRET
;
4880 /* stack: L1 H1 L2 H2 */
4885 vtop
[-2] = vtop
[-3];
4888 /* stack: H1 H2 L1 L2 */
4894 /* stack: H1 H2 L1 L2 ML MH */
4897 /* stack: ML MH H1 H2 L1 L2 */
4901 /* stack: ML MH H1 L2 H2 L1 */
4906 /* stack: ML MH M1 M2 */
4909 } else if (op
== '+' || op
== '-') {
4910 /* XXX: add non carry method too (for MIPS or alpha) */
4916 /* stack: H1 H2 (L1 op L2) */
4919 gen_op(op1
+ 1); /* TOK_xxxC2 */
4922 /* stack: H1 H2 (L1 op L2) */
4925 /* stack: (L1 op L2) H1 H2 */
4927 /* stack: (L1 op L2) (H1 op H2) */
4935 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4936 t
= vtop
[-1].type
.t
;
4940 /* stack: L H shift */
4942 /* constant: simpler */
4943 /* NOTE: all comments are for SHL. the other cases are
4944 done by swaping words */
4955 if (op
!= TOK_SAR
) {
4988 /* XXX: should provide a faster fallback on x86 ? */
4991 func
= TOK___sardi3
;
4994 func
= TOK___shrdi3
;
4997 func
= TOK___shldi3
;
5003 /* compare operations */
5009 /* stack: L1 H1 L2 H2 */
5011 vtop
[-1] = vtop
[-2];
5013 /* stack: L1 L2 H1 H2 */
5016 /* when values are equal, we need to compare low words. since
5017 the jump is inverted, we invert the test too. */
5020 else if (op1
== TOK_GT
)
5022 else if (op1
== TOK_ULT
)
5024 else if (op1
== TOK_UGT
)
5029 if (op1
!= TOK_NE
) {
5033 /* generate non equal test */
5034 /* XXX: NOT PORTABLE yet */
5038 #if defined(TCC_TARGET_I386)
5039 b
= psym(0x850f, 0);
5040 #elif defined(TCC_TARGET_ARM)
5042 o(0x1A000000 | encbranch(ind
, 0, 1));
5043 #elif defined(TCC_TARGET_C67)
5044 error("not implemented");
5046 #error not supported
5050 /* compare low. Always unsigned */
5054 else if (op1
== TOK_LE
)
5056 else if (op1
== TOK_GT
)
5058 else if (op1
== TOK_GE
)
5068 /* handle integer constant optimizations and various machine
5070 void gen_opic(int op
)
5077 /* currently, we cannot do computations with forward symbols */
5078 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5079 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5083 case '+': v1
->c
.i
+= fc
; break;
5084 case '-': v1
->c
.i
-= fc
; break;
5085 case '&': v1
->c
.i
&= fc
; break;
5086 case '^': v1
->c
.i
^= fc
; break;
5087 case '|': v1
->c
.i
|= fc
; break;
5088 case '*': v1
->c
.i
*= fc
; break;
5095 /* if division by zero, generate explicit division */
5098 error("division by zero in constant");
5102 default: v1
->c
.i
/= fc
; break;
5103 case '%': v1
->c
.i
%= fc
; break;
5104 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
5105 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
5108 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
5109 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
5110 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
5112 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
5113 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
5114 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
5115 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
5116 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
5117 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
5118 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
5119 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
5120 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
5121 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
5123 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
5124 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
5130 /* if commutative ops, put c2 as constant */
5131 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
5132 op
== '|' || op
== '*')) {
5137 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
5140 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
5141 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
5147 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
5148 /* try to use shifts instead of muls or divs */
5149 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
5158 else if (op
== TOK_PDIV
)
5164 } else if (c2
&& (op
== '+' || op
== '-') &&
5165 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
5166 (VT_CONST
| VT_SYM
)) {
5167 /* symbol + constant case */
5174 if (!nocode_wanted
) {
5175 /* call low level op generator */
5184 /* generate a floating point operation with constant propagation */
5185 void gen_opif(int op
)
5193 /* currently, we cannot do computations with forward symbols */
5194 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5195 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5197 if (v1
->type
.t
== VT_FLOAT
) {
5200 } else if (v1
->type
.t
== VT_DOUBLE
) {
5208 /* NOTE: we only do constant propagation if finite number (not
5209 NaN or infinity) (ANSI spec) */
5210 if (!ieee_finite(f1
) || !ieee_finite(f2
))
5214 case '+': f1
+= f2
; break;
5215 case '-': f1
-= f2
; break;
5216 case '*': f1
*= f2
; break;
5220 error("division by zero in constant");
5225 /* XXX: also handles tests ? */
5229 /* XXX: overflow test ? */
5230 if (v1
->type
.t
== VT_FLOAT
) {
5232 } else if (v1
->type
.t
== VT_DOUBLE
) {
5240 if (!nocode_wanted
) {
5248 static int pointed_size(CType
*type
)
5251 return type_size(pointed_type(type
), &align
);
5254 static inline int is_null_pointer(SValue
*p
)
5256 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
5258 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& p
->c
.i
== 0) ||
5259 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.ll
== 0);
5262 static inline int is_integer_btype(int bt
)
5264 return (bt
== VT_BYTE
|| bt
== VT_SHORT
||
5265 bt
== VT_INT
|| bt
== VT_LLONG
);
5268 /* check types for comparison or substraction of pointers */
5269 static void check_comparison_pointer_types(SValue
*p1
, SValue
*p2
, int op
)
5271 CType
*type1
, *type2
, tmp_type1
, tmp_type2
;
5274 /* null pointers are accepted for all comparisons as gcc */
5275 if (is_null_pointer(p1
) || is_null_pointer(p2
))
5279 bt1
= type1
->t
& VT_BTYPE
;
5280 bt2
= type2
->t
& VT_BTYPE
;
5281 /* accept comparison between pointer and integer with a warning */
5282 if ((is_integer_btype(bt1
) || is_integer_btype(bt2
)) && op
!= '-') {
5283 warning("comparison between pointer and integer");
5287 /* both must be pointers or implicit function pointers */
5288 if (bt1
== VT_PTR
) {
5289 type1
= pointed_type(type1
);
5290 } else if (bt1
!= VT_FUNC
)
5291 goto invalid_operands
;
5293 if (bt2
== VT_PTR
) {
5294 type2
= pointed_type(type2
);
5295 } else if (bt2
!= VT_FUNC
) {
5297 error("invalid operands to binary %s", get_tok_str(op
, NULL
));
5299 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
5300 (type2
->t
& VT_BTYPE
) == VT_VOID
)
5304 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5305 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5306 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
5307 /* gcc-like error if '-' is used */
5309 goto invalid_operands
;
5311 warning("comparison of distinct pointer types lacks a cast");
5315 /* generic gen_op: handles types problems */
5318 int u
, t1
, t2
, bt1
, bt2
, t
;
5321 t1
= vtop
[-1].type
.t
;
5322 t2
= vtop
[0].type
.t
;
5323 bt1
= t1
& VT_BTYPE
;
5324 bt2
= t2
& VT_BTYPE
;
5326 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5327 /* at least one operand is a pointer */
5328 /* relationnal op: must be both pointers */
5329 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5330 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5331 /* pointers are handled are unsigned */
5332 t
= VT_INT
| VT_UNSIGNED
;
5335 /* if both pointers, then it must be the '-' op */
5336 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
5338 error("cannot use pointers here");
5339 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5340 /* XXX: check that types are compatible */
5341 u
= pointed_size(&vtop
[-1].type
);
5343 /* set to integer type */
5344 vtop
->type
.t
= VT_INT
;
5348 /* exactly one pointer : must be '+' or '-'. */
5349 if (op
!= '-' && op
!= '+')
5350 error("cannot use pointers here");
5351 /* Put pointer as first operand */
5352 if (bt2
== VT_PTR
) {
5356 type1
= vtop
[-1].type
;
5357 /* XXX: cast to int ? (long long case) */
5358 vpushi(pointed_size(&vtop
[-1].type
));
5360 #ifdef CONFIG_TCC_BCHECK
5361 /* if evaluating constant expression, no code should be
5362 generated, so no bound check */
5363 if (do_bounds_check
&& !const_wanted
) {
5364 /* if bounded pointers, we generate a special code to
5371 gen_bounded_ptr_add();
5377 /* put again type if gen_opic() swaped operands */
5380 } else if (is_float(bt1
) || is_float(bt2
)) {
5381 /* compute bigger type and do implicit casts */
5382 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5384 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5389 /* floats can only be used for a few operations */
5390 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
5391 (op
< TOK_ULT
|| op
> TOK_GT
))
5392 error("invalid operands for binary operation");
5394 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5395 /* cast to biggest op */
5397 /* convert to unsigned if it does not fit in a long long */
5398 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5399 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5403 /* integer operations */
5405 /* convert to unsigned if it does not fit in an integer */
5406 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5407 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5410 /* XXX: currently, some unsigned operations are explicit, so
5411 we modify them here */
5412 if (t
& VT_UNSIGNED
) {
5419 else if (op
== TOK_LT
)
5421 else if (op
== TOK_GT
)
5423 else if (op
== TOK_LE
)
5425 else if (op
== TOK_GE
)
5432 /* special case for shifts and long long: we keep the shift as
5434 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
5439 else if ((t
& VT_BTYPE
) == VT_LLONG
)
5443 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5444 /* relationnal op: the result is an int */
5445 vtop
->type
.t
= VT_INT
;
5452 /* generic itof for unsigned long long case */
5453 void gen_cvt_itof1(int t
)
5455 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
5456 (VT_LLONG
| VT_UNSIGNED
)) {
5459 vpush_global_sym(&func_old_type
, TOK___ulltof
);
5460 else if (t
== VT_DOUBLE
)
5461 vpush_global_sym(&func_old_type
, TOK___ulltod
);
5463 vpush_global_sym(&func_old_type
, TOK___ulltold
);
5473 /* generic ftoi for unsigned long long case */
5474 void gen_cvt_ftoi1(int t
)
5478 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
5479 /* not handled natively */
5480 st
= vtop
->type
.t
& VT_BTYPE
;
5482 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
5483 else if (st
== VT_DOUBLE
)
5484 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
5486 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
5491 vtop
->r2
= REG_LRET
;
5497 /* force char or short cast */
5498 void force_charshort_cast(int t
)
5502 /* XXX: add optimization if lvalue : just change type and offset */
5507 if (t
& VT_UNSIGNED
) {
5508 vpushi((1 << bits
) - 1);
5519 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
5520 static void gen_cast(CType
*type
)
5522 int sbt
, dbt
, sf
, df
, c
;
5524 /* special delayed cast for char/short */
5525 /* XXX: in some cases (multiple cascaded casts), it may still
5527 if (vtop
->r
& VT_MUSTCAST
) {
5528 vtop
->r
&= ~VT_MUSTCAST
;
5529 force_charshort_cast(vtop
->type
.t
);
5532 /* bitfields first get cast to ints */
5533 if (vtop
->type
.t
& VT_BITFIELD
) {
5537 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
5538 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5540 if (sbt
!= dbt
&& !nocode_wanted
) {
5543 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5545 /* convert from fp to fp */
5547 /* constant case: we can do it now */
5548 /* XXX: in ISOC, cannot do it if error in convert */
5549 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
5550 vtop
->c
.f
= (float)vtop
->c
.d
;
5551 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
5552 vtop
->c
.f
= (float)vtop
->c
.ld
;
5553 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
5554 vtop
->c
.d
= (double)vtop
->c
.f
;
5555 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
5556 vtop
->c
.d
= (double)vtop
->c
.ld
;
5557 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
5558 vtop
->c
.ld
= (long double)vtop
->c
.f
;
5559 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
5560 vtop
->c
.ld
= (long double)vtop
->c
.d
;
5562 /* non constant case: generate code */
5566 /* convert int to fp */
5569 case VT_LLONG
| VT_UNSIGNED
:
5571 /* XXX: add const cases for long long */
5573 case VT_INT
| VT_UNSIGNED
:
5575 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
5576 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
5577 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
5582 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
5583 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
5584 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
5590 #if !defined(TCC_TARGET_ARM)
5597 /* convert fp to int */
5598 /* we handle char/short/etc... with generic code */
5599 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
5600 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
5605 case VT_LLONG
| VT_UNSIGNED
:
5607 /* XXX: add const cases for long long */
5609 case VT_INT
| VT_UNSIGNED
:
5611 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5612 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5613 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5619 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5620 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5621 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5629 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
5630 /* additional cast for char/short/bool... */
5634 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
5635 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
5636 /* scalar to long long */
5638 if (sbt
== (VT_INT
| VT_UNSIGNED
))
5639 vtop
->c
.ll
= vtop
->c
.ui
;
5641 vtop
->c
.ll
= vtop
->c
.i
;
5643 /* machine independent conversion */
5645 /* generate high word */
5646 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
5654 /* patch second register */
5655 vtop
[-1].r2
= vtop
->r
;
5659 } else if (dbt
== VT_BOOL
) {
5660 /* scalar to bool */
5663 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
5664 (dbt
& VT_BTYPE
) == VT_SHORT
) {
5665 force_charshort_cast(dbt
);
5666 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
5668 if (sbt
== VT_LLONG
) {
5669 /* from long long: just take low order word */
5673 /* if lvalue and single word type, nothing to do because
5674 the lvalue already contains the real type size (see
5675 VT_LVAL_xxx constants) */
5681 /* return type size. Put alignment at 'a' */
5682 static int type_size(CType
*type
, int *a
)
5687 bt
= type
->t
& VT_BTYPE
;
5688 if (bt
== VT_STRUCT
) {
5693 } else if (bt
== VT_PTR
) {
5694 if (type
->t
& VT_ARRAY
) {
5696 return type_size(&s
->type
, a
) * s
->c
;
5701 } else if (bt
== VT_LDOUBLE
) {
5703 return LDOUBLE_SIZE
;
5704 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
5705 #ifdef TCC_TARGET_I386
5711 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
5714 } else if (bt
== VT_SHORT
) {
5718 /* char, void, function, _Bool */
5724 /* return the pointed type of t */
5725 static inline CType
*pointed_type(CType
*type
)
5727 return &type
->ref
->type
;
5730 /* modify type so that its it is a pointer to type. */
5731 static void mk_pointer(CType
*type
)
5734 s
= sym_push(SYM_FIELD
, type
, 0, -1);
5735 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
5739 /* compare function types. OLD functions match any new functions */
5740 static int is_compatible_func(CType
*type1
, CType
*type2
)
5746 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5748 /* XXX: not complete */
5749 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
5753 while (s1
!= NULL
) {
5756 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5766 /* return true if type1 and type2 are exactly the same (including
5769 - enums are not checked as gcc __builtin_types_compatible_p ()
5771 static int is_compatible_types(CType
*type1
, CType
*type2
)
5775 t1
= type1
->t
& VT_TYPE
;
5776 t2
= type2
->t
& VT_TYPE
;
5777 /* XXX: bitfields ? */
5780 /* test more complicated cases */
5781 bt1
= t1
& VT_BTYPE
;
5782 if (bt1
== VT_PTR
) {
5783 type1
= pointed_type(type1
);
5784 type2
= pointed_type(type2
);
5785 return is_compatible_types(type1
, type2
);
5786 } else if (bt1
== VT_STRUCT
) {
5787 return (type1
->ref
== type2
->ref
);
5788 } else if (bt1
== VT_FUNC
) {
5789 return is_compatible_func(type1
, type2
);
5795 /* print a type. If 'varstr' is not NULL, then the variable is also
5796 printed in the type */
5798 /* XXX: add array and function pointers */
5799 void type_to_str(char *buf
, int buf_size
,
5800 CType
*type
, const char *varstr
)
5807 t
= type
->t
& VT_TYPE
;
5810 if (t
& VT_CONSTANT
)
5811 pstrcat(buf
, buf_size
, "const ");
5812 if (t
& VT_VOLATILE
)
5813 pstrcat(buf
, buf_size
, "volatile ");
5814 if (t
& VT_UNSIGNED
)
5815 pstrcat(buf
, buf_size
, "unsigned ");
5845 tstr
= "long double";
5847 pstrcat(buf
, buf_size
, tstr
);
5851 if (bt
== VT_STRUCT
)
5855 pstrcat(buf
, buf_size
, tstr
);
5856 v
= type
->ref
->v
& ~SYM_STRUCT
;
5857 if (v
>= SYM_FIRST_ANOM
)
5858 pstrcat(buf
, buf_size
, "<anonymous>");
5860 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
5864 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
5865 pstrcat(buf
, buf_size
, "(");
5867 while (sa
!= NULL
) {
5868 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
5869 pstrcat(buf
, buf_size
, buf1
);
5872 pstrcat(buf
, buf_size
, ", ");
5874 pstrcat(buf
, buf_size
, ")");
5878 pstrcpy(buf1
, sizeof(buf1
), "*");
5880 pstrcat(buf1
, sizeof(buf1
), varstr
);
5881 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
5885 pstrcat(buf
, buf_size
, " ");
5886 pstrcat(buf
, buf_size
, varstr
);
5891 /* verify type compatibility to store vtop in 'dt' type, and generate
5893 static void gen_assign_cast(CType
*dt
)
5895 CType
*st
, *type1
, *type2
, tmp_type1
, tmp_type2
;
5896 char buf1
[256], buf2
[256];
5899 st
= &vtop
->type
; /* source type */
5900 dbt
= dt
->t
& VT_BTYPE
;
5901 sbt
= st
->t
& VT_BTYPE
;
5902 if (dt
->t
& VT_CONSTANT
)
5903 warning("assignment of read-only location");
5906 /* special cases for pointers */
5907 /* '0' can also be a pointer */
5908 if (is_null_pointer(vtop
))
5910 /* accept implicit pointer to integer cast with warning */
5911 if (is_integer_btype(sbt
)) {
5912 warning("assignment makes pointer from integer without a cast");
5915 type1
= pointed_type(dt
);
5916 /* a function is implicitely a function pointer */
5917 if (sbt
== VT_FUNC
) {
5918 if ((type1
->t
& VT_BTYPE
) != VT_VOID
&&
5919 !is_compatible_types(pointed_type(dt
), st
))
5926 type2
= pointed_type(st
);
5927 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
5928 (type2
->t
& VT_BTYPE
) == VT_VOID
) {
5929 /* void * can match anything */
5931 /* exact type match, except for unsigned */
5934 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5935 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5936 if (!is_compatible_types(&tmp_type1
, &tmp_type2
))
5939 /* check const and volatile */
5940 if ((!(type1
->t
& VT_CONSTANT
) && (type2
->t
& VT_CONSTANT
)) ||
5941 (!(type1
->t
& VT_VOLATILE
) && (type2
->t
& VT_VOLATILE
)))
5942 warning("assignment discards qualifiers from pointer target type");
5948 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
5949 warning("assignment makes integer from pointer without a cast");
5951 /* XXX: more tests */
5956 tmp_type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
5957 tmp_type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
5958 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
5960 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
5961 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
5962 error("cannot cast '%s' to '%s'", buf1
, buf2
);
5970 /* store vtop in lvalue pushed on stack */
5973 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
5975 ft
= vtop
[-1].type
.t
;
5976 sbt
= vtop
->type
.t
& VT_BTYPE
;
5977 dbt
= ft
& VT_BTYPE
;
5978 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
5979 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
5980 /* optimize char/short casts */
5981 delayed_cast
= VT_MUSTCAST
;
5982 vtop
->type
.t
= ft
& VT_TYPE
;
5983 /* XXX: factorize */
5984 if (ft
& VT_CONSTANT
)
5985 warning("assignment of read-only location");
5988 gen_assign_cast(&vtop
[-1].type
);
5991 if (sbt
== VT_STRUCT
) {
5992 /* if structure, only generate pointer */
5993 /* structure assignment : generate memcpy */
5994 /* XXX: optimize if small size */
5995 if (!nocode_wanted
) {
5996 size
= type_size(&vtop
->type
, &align
);
5998 vpush_global_sym(&func_old_type
, TOK_memcpy
);
6002 vtop
->type
.t
= VT_INT
;
6006 vtop
->type
.t
= VT_INT
;
6018 /* leave source on stack */
6019 } else if (ft
& VT_BITFIELD
) {
6020 /* bitfield store handling */
6021 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
6022 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
6023 /* remove bit field info to avoid loops */
6024 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
6026 /* duplicate destination */
6028 vtop
[-1] = vtop
[-2];
6030 /* mask and shift source */
6031 vpushi((1 << bit_size
) - 1);
6035 /* load destination, mask and or with source */
6037 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
6043 #ifdef CONFIG_TCC_BCHECK
6044 /* bound check case */
6045 if (vtop
[-1].r
& VT_MUSTBOUND
) {
6051 if (!nocode_wanted
) {
6055 r
= gv(rc
); /* generate value */
6056 /* if lvalue was saved on stack, must read it */
6057 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
6059 t
= get_reg(RC_INT
);
6061 sv
.r
= VT_LOCAL
| VT_LVAL
;
6062 sv
.c
.ul
= vtop
[-1].c
.ul
;
6064 vtop
[-1].r
= t
| VT_LVAL
;
6067 /* two word case handling : store second register at word + 4 */
6068 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
6070 /* convert to int to increment easily */
6071 vtop
->type
.t
= VT_INT
;
6077 /* XXX: it works because r2 is spilled last ! */
6078 store(vtop
->r2
, vtop
- 1);
6082 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6083 vtop
->r
|= delayed_cast
;
6087 /* post defines POST/PRE add. c is the token ++ or -- */
6088 void inc(int post
, int c
)
6091 vdup(); /* save lvalue */
6093 gv_dup(); /* duplicate value */
6098 vpushi(c
- TOK_MID
);
6100 vstore(); /* store value */
6102 vpop(); /* if post op, return saved value */
6105 /* Parse GNUC __attribute__ extension. Currently, the following
6106 extensions are recognized:
6107 - aligned(n) : set data/function alignment.
6108 - section(x) : generate data/code in this section.
6109 - unused : currently ignored, but may be used someday.
6111 static void parse_attribute(AttributeDef
*ad
)
6115 while (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
6119 while (tok
!= ')') {
6120 if (tok
< TOK_IDENT
)
6121 expect("attribute name");
6129 expect("section name");
6130 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
6139 if (n
<= 0 || (n
& (n
- 1)) != 0)
6140 error("alignment must be a positive power of two");
6149 /* currently, no need to handle it because tcc does not
6150 track unused objects */
6154 /* currently, no need to handle it because tcc does not
6155 track unused objects */
6160 ad
->func_call
= FUNC_CDECL
;
6165 ad
->func_call
= FUNC_STDCALL
;
6168 if (tcc_state
->warn_unsupported
)
6169 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
6170 /* skip parameters */
6171 /* XXX: skip parenthesis too */
6174 while (tok
!= ')' && tok
!= -1)
6189 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
6190 static void struct_decl(CType
*type
, int u
)
6192 int a
, v
, size
, align
, maxalign
, c
, offset
;
6193 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
6198 a
= tok
; /* save decl type */
6203 /* struct already defined ? return it */
6205 expect("struct/union/enum name");
6209 error("invalid type");
6216 /* we put an undefined size for struct/union */
6217 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
6218 s
->r
= 0; /* default alignment is zero as gcc */
6219 /* put struct/union/enum name in type */
6227 error("struct/union/enum already defined");
6228 /* cannot be empty */
6230 /* non empty enums are not allowed */
6231 if (a
== TOK_ENUM
) {
6235 expect("identifier");
6241 /* enum symbols have static storage */
6242 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
6243 ss
->type
.t
|= VT_STATIC
;
6248 /* NOTE: we accept a trailing comma */
6258 while (tok
!= '}') {
6259 parse_btype(&btype
, &ad
);
6265 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
);
6266 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
6267 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
| VT_INLINE
)))
6268 error("invalid type for '%s'",
6269 get_tok_str(v
, NULL
));
6273 bit_size
= expr_const();
6274 /* XXX: handle v = 0 case for messages */
6276 error("negative width in bit-field '%s'",
6277 get_tok_str(v
, NULL
));
6278 if (v
&& bit_size
== 0)
6279 error("zero width for bit-field '%s'",
6280 get_tok_str(v
, NULL
));
6282 size
= type_size(&type1
, &align
);
6284 if (bit_size
>= 0) {
6285 bt
= type1
.t
& VT_BTYPE
;
6290 error("bitfields must have scalar type");
6292 if (bit_size
> bsize
) {
6293 error("width of '%s' exceeds its type",
6294 get_tok_str(v
, NULL
));
6295 } else if (bit_size
== bsize
) {
6296 /* no need for bit fields */
6298 } else if (bit_size
== 0) {
6299 /* XXX: what to do if only padding in a
6301 /* zero size: means to pad */
6305 /* we do not have enough room ? */
6306 if ((bit_pos
+ bit_size
) > bsize
)
6309 /* XXX: handle LSB first */
6310 type1
.t
|= VT_BITFIELD
|
6311 (bit_pos
<< VT_STRUCT_SHIFT
) |
6312 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
6313 bit_pos
+= bit_size
;
6319 /* add new memory data only if starting
6321 if (lbit_pos
== 0) {
6322 if (a
== TOK_STRUCT
) {
6323 c
= (c
+ align
- 1) & -align
;
6331 if (align
> maxalign
)
6335 printf("add field %s offset=%d",
6336 get_tok_str(v
, NULL
), offset
);
6337 if (type1
.t
& VT_BITFIELD
) {
6338 printf(" pos=%d size=%d",
6339 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
6340 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
6344 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
6348 if (tok
== ';' || tok
== TOK_EOF
)
6355 /* store size and alignment */
6356 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
6362 /* return 0 if no type declaration. otherwise, return the basic type
6365 static int parse_btype(CType
*type
, AttributeDef
*ad
)
6367 int t
, u
, type_found
, typespec_found
;
6371 memset(ad
, 0, sizeof(AttributeDef
));
6378 /* currently, we really ignore extension */
6388 if ((t
& VT_BTYPE
) != 0)
6389 error("too many basic types");
6405 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
6406 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6407 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
6408 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
6422 if ((t
& VT_BTYPE
) == VT_LONG
) {
6423 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6430 struct_decl(&type1
, VT_ENUM
);
6433 type
->ref
= type1
.ref
;
6437 struct_decl(&type1
, VT_STRUCT
);
6440 /* type modifiers */
6493 /* GNUC attribute */
6494 case TOK_ATTRIBUTE1
:
6495 case TOK_ATTRIBUTE2
:
6496 parse_attribute(ad
);
6503 parse_expr_type(&type1
);
6509 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
6511 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
6512 type
->ref
= s
->type
.ref
;
6519 if ((t
& (VT_SIGNED
|VT_UNSIGNED
)) == (VT_SIGNED
|VT_UNSIGNED
))
6520 error("signed and unsigned modifier");
6521 if (tcc_state
->char_is_unsigned
) {
6522 if ((t
& (VT_SIGNED
|VT_UNSIGNED
|VT_BTYPE
)) == VT_BYTE
)
6527 /* long is never used as type */
6528 if ((t
& VT_BTYPE
) == VT_LONG
)
6529 t
= (t
& ~VT_BTYPE
) | VT_INT
;
6534 /* convert a function parameter type (array to pointer and function to
6535 function pointer) */
6536 static inline void convert_parameter_type(CType
*pt
)
6538 /* array must be transformed to pointer according to ANSI C */
6540 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
6545 static void post_type(CType
*type
, AttributeDef
*ad
)
6548 Sym
**plast
, *s
, *first
;
6553 /* function declaration */
6558 while (tok
!= ')') {
6559 /* read param name and compute offset */
6560 if (l
!= FUNC_OLD
) {
6561 if (!parse_btype(&pt
, &ad1
)) {
6563 error("invalid type");
6570 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
6572 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
6573 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
6574 error("parameter declared as void");
6581 convert_parameter_type(&pt
);
6582 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
6587 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
6594 /* if no parameters, then old type prototype */
6598 t1
= type
->t
& VT_STORAGE
;
6599 /* NOTE: const is ignored in returned type as it has a special
6600 meaning in gcc / C++ */
6601 type
->t
&= ~(VT_STORAGE
| VT_CONSTANT
);
6602 post_type(type
, ad
);
6603 /* we push a anonymous symbol which will contain the function prototype */
6604 s
= sym_push(SYM_FIELD
, type
, ad
->func_call
, l
);
6606 type
->t
= t1
| VT_FUNC
;
6608 } else if (tok
== '[') {
6609 /* array definition */
6615 error("invalid array size");
6618 /* parse next post type */
6619 t1
= type
->t
& VT_STORAGE
;
6620 type
->t
&= ~VT_STORAGE
;
6621 post_type(type
, ad
);
6623 /* we push a anonymous symbol which will contain the array
6625 s
= sym_push(SYM_FIELD
, type
, 0, n
);
6626 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
6631 /* Parse a type declaration (except basic type), and return the type
6632 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6633 expected. 'type' should contain the basic type. 'ad' is the
6634 attribute definition of the basic type. It can be modified by
6637 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
6640 CType type1
, *type2
;
6643 while (tok
== '*') {
6651 qualifiers
|= VT_CONSTANT
;
6656 qualifiers
|= VT_VOLATILE
;
6664 type
->t
|= qualifiers
;
6667 /* XXX: clarify attribute handling */
6668 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6669 parse_attribute(ad
);
6671 /* recursive type */
6672 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6673 type1
.t
= 0; /* XXX: same as int */
6676 /* XXX: this is not correct to modify 'ad' at this point, but
6677 the syntax is not clear */
6678 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6679 parse_attribute(ad
);
6680 type_decl(&type1
, ad
, v
, td
);
6683 /* type identifier */
6684 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
6688 if (!(td
& TYPE_ABSTRACT
))
6689 expect("identifier");
6693 post_type(type
, ad
);
6694 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6695 parse_attribute(ad
);
6698 /* append type at the end of type1 */
6711 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6712 static int lvalue_type(int t
)
6717 if (bt
== VT_BYTE
|| bt
== VT_BOOL
)
6719 else if (bt
== VT_SHORT
)
6723 if (t
& VT_UNSIGNED
)
6724 r
|= VT_LVAL_UNSIGNED
;
6728 /* indirection with full error checking and bound check */
6729 static void indir(void)
6731 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
6733 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
6735 vtop
->type
= *pointed_type(&vtop
->type
);
6736 /* an array is never an lvalue */
6737 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6738 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6739 /* if bound checking, the referenced pointer must be checked */
6740 if (do_bounds_check
)
6741 vtop
->r
|= VT_MUSTBOUND
;
6745 /* pass a parameter to a function and do type checking and casting */
6746 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
6751 func_type
= func
->c
;
6752 if (func_type
== FUNC_OLD
||
6753 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
6754 /* default casting : only need to convert float to double */
6755 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
6759 } else if (arg
== NULL
) {
6760 error("too many arguments to function");
6763 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
6764 gen_assign_cast(&type
);
6768 /* parse an expression of the form '(type)' or '(expr)' and return its
6770 static void parse_expr_type(CType
*type
)
6776 if (parse_btype(type
, &ad
)) {
6777 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
6784 static void parse_type(CType
*type
)
6789 if (!parse_btype(type
, &ad
)) {
6792 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
6795 static void vpush_tokc(int t
)
6799 vsetc(&type
, VT_CONST
, &tokc
);
6802 static void unary(void)
6804 int n
, t
, align
, size
, r
;
6809 /* XXX: GCC 2.95.3 does not generate a table although it should be
6823 vpush_tokc(VT_INT
| VT_UNSIGNED
);
6827 vpush_tokc(VT_LLONG
);
6831 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
6835 vpush_tokc(VT_FLOAT
);
6839 vpush_tokc(VT_DOUBLE
);
6843 vpush_tokc(VT_LDOUBLE
);
6846 case TOK___FUNCTION__
:
6848 goto tok_identifier
;
6854 /* special function name identifier */
6855 len
= strlen(funcname
) + 1;
6856 /* generate char[len] type */
6861 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
6862 ptr
= section_ptr_add(data_section
, len
);
6863 memcpy(ptr
, funcname
, len
);
6871 /* string parsing */
6874 if (tcc_state
->warn_write_strings
)
6879 memset(&ad
, 0, sizeof(AttributeDef
));
6880 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
6885 if (parse_btype(&type
, &ad
)) {
6886 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
6888 /* check ISOC99 compound literal */
6890 /* data is allocated locally by default */
6895 /* all except arrays are lvalues */
6896 if (!(type
.t
& VT_ARRAY
))
6897 r
|= lvalue_type(type
.t
);
6898 memset(&ad
, 0, sizeof(AttributeDef
));
6899 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
6904 } else if (tok
== '{') {
6905 /* save all registers */
6907 /* statement expression : we do not accept break/continue
6908 inside as GCC does */
6909 block(NULL
, NULL
, NULL
, NULL
, 0, 1);
6924 /* functions names must be treated as function pointers,
6925 except for unary '&' and sizeof. Since we consider that
6926 functions are not lvalues, we only have to handle it
6927 there and in function calls. */
6928 /* arrays can also be used although they are not lvalues */
6929 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
6930 !(vtop
->type
.t
& VT_ARRAY
))
6932 mk_pointer(&vtop
->type
);
6938 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
6939 vtop
->c
.i
= !vtop
->c
.i
;
6940 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
6941 vtop
->c
.i
= vtop
->c
.i
^ 1;
6943 vseti(VT_JMP
, gtst(1, 0));
6953 /* in order to force cast, we add zero */
6955 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
6956 error("pointer not accepted for unary plus");
6966 parse_expr_type(&type
);
6970 size
= type_size(&type
, &align
);
6971 if (t
== TOK_SIZEOF
) {
6973 error("sizeof applied to an incomplete type");
6980 case TOK_builtin_types_compatible_p
:
6989 type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6990 type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6991 vpushi(is_compatible_types(&type1
, &type2
));
6994 case TOK_builtin_constant_p
:
6996 int saved_nocode_wanted
, res
;
6999 saved_nocode_wanted
= nocode_wanted
;
7002 res
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
7004 nocode_wanted
= saved_nocode_wanted
;
7024 goto tok_identifier
;
7026 /* allow to take the address of a label */
7027 if (tok
< TOK_UIDENT
)
7028 expect("label identifier");
7029 s
= label_find(tok
);
7031 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7033 if (s
->r
== LABEL_DECLARED
)
7034 s
->r
= LABEL_FORWARD
;
7037 s
->type
.t
= VT_VOID
;
7038 mk_pointer(&s
->type
);
7039 s
->type
.t
|= VT_STATIC
;
7041 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
7050 expect("identifier");
7054 error("'%s' undeclared", get_tok_str(t
, NULL
));
7055 /* for simple function calls, we tolerate undeclared
7056 external reference to int() function */
7057 if (tcc_state
->warn_implicit_function_declaration
)
7058 warning("implicit declaration of function '%s'",
7059 get_tok_str(t
, NULL
));
7060 s
= external_global_sym(t
, &func_old_type
, 0);
7062 vset(&s
->type
, s
->r
, s
->c
);
7063 /* if forward reference, we must point to s */
7064 if (vtop
->r
& VT_SYM
) {
7071 /* post operations */
7073 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
7076 } else if (tok
== '.' || tok
== TOK_ARROW
) {
7078 if (tok
== TOK_ARROW
)
7083 /* expect pointer on structure */
7084 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
7085 expect("struct or union");
7089 while ((s
= s
->next
) != NULL
) {
7094 error("field not found");
7095 /* add field offset to pointer */
7096 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
7099 /* change type to field type, and set to lvalue */
7100 vtop
->type
= s
->type
;
7101 /* an array is never an lvalue */
7102 if (!(vtop
->type
.t
& VT_ARRAY
)) {
7103 vtop
->r
|= lvalue_type(vtop
->type
.t
);
7104 /* if bound checking, the referenced pointer must be checked */
7105 if (do_bounds_check
)
7106 vtop
->r
|= VT_MUSTBOUND
;
7109 } else if (tok
== '[') {
7115 } else if (tok
== '(') {
7121 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
7122 /* pointer test (no array accepted) */
7123 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
7124 vtop
->type
= *pointed_type(&vtop
->type
);
7125 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
7129 expect("function pointer");
7132 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
7134 /* get return type */
7137 sa
= s
->next
; /* first parameter */
7139 /* compute first implicit argument if a structure is returned */
7140 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
7141 /* get some space for the returned structure */
7142 size
= type_size(&s
->type
, &align
);
7143 loc
= (loc
- size
) & -align
;
7145 ret
.r
= VT_LOCAL
| VT_LVAL
;
7146 /* pass it as 'int' to avoid structure arg passing
7148 vseti(VT_LOCAL
, loc
);
7154 /* return in register */
7155 if (is_float(ret
.type
.t
)) {
7158 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
7167 gfunc_param_typed(s
, sa
);
7177 error("too few arguments to function");
7179 if (!nocode_wanted
) {
7180 gfunc_call(nb_args
);
7182 vtop
-= (nb_args
+ 1);
7185 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
7193 static void uneq(void)
7199 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
7200 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
7201 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
7216 static void expr_prod(void)
7221 while (tok
== '*' || tok
== '/' || tok
== '%') {
7229 static void expr_sum(void)
7234 while (tok
== '+' || tok
== '-') {
7242 static void expr_shift(void)
7247 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
7255 static void expr_cmp(void)
7260 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
7261 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
7269 static void expr_cmpeq(void)
7274 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
7282 static void expr_and(void)
7285 while (tok
== '&') {
7292 static void expr_xor(void)
7295 while (tok
== '^') {
7302 static void expr_or(void)
7305 while (tok
== '|') {
7312 /* XXX: fix this mess */
7313 static void expr_land_const(void)
7316 while (tok
== TOK_LAND
) {
7323 /* XXX: fix this mess */
7324 static void expr_lor_const(void)
7327 while (tok
== TOK_LOR
) {
7334 /* only used if non constant */
7335 static void expr_land(void)
7340 if (tok
== TOK_LAND
) {
7344 if (tok
!= TOK_LAND
) {
7354 static void expr_lor(void)
7359 if (tok
== TOK_LOR
) {
7363 if (tok
!= TOK_LOR
) {
7373 /* XXX: better constant handling */
7374 static void expr_eq(void)
7376 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
7378 CType type
, type1
, type2
;
7387 if (tok
== ':' && gnu_ext
) {
7403 if (vtop
!= vstack
) {
7404 /* needed to avoid having different registers saved in
7406 if (is_float(vtop
->type
.t
))
7413 if (tok
== ':' && gnu_ext
) {
7421 sv
= *vtop
; /* save value to handle it later */
7422 vtop
--; /* no vpop so that FP stack is not flushed */
7430 bt1
= t1
& VT_BTYPE
;
7432 bt2
= t2
& VT_BTYPE
;
7433 /* cast operands to correct type according to ISOC rules */
7434 if (is_float(bt1
) || is_float(bt2
)) {
7435 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
7436 type
.t
= VT_LDOUBLE
;
7437 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
7442 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
7443 /* cast to biggest op */
7445 /* convert to unsigned if it does not fit in a long long */
7446 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
7447 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
7448 type
.t
|= VT_UNSIGNED
;
7449 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
7450 /* XXX: test pointer compatibility */
7452 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
7453 /* XXX: test structure compatibility */
7455 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
7456 /* NOTE: as an extension, we accept void on only one side */
7459 /* integer operations */
7461 /* convert to unsigned if it does not fit in an integer */
7462 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
7463 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
7464 type
.t
|= VT_UNSIGNED
;
7467 /* now we convert second operand */
7470 if (is_float(type
.t
)) {
7472 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
7473 /* for long longs, we use fixed registers to avoid having
7474 to handle a complicated move */
7479 /* this is horrible, but we must also convert first
7483 /* put again first value and cast it */
7494 static void gexpr(void)
7505 /* parse an expression and return its type without any side effect. */
7506 static void expr_type(CType
*type
)
7508 int saved_nocode_wanted
;
7510 saved_nocode_wanted
= nocode_wanted
;
7515 nocode_wanted
= saved_nocode_wanted
;
7518 /* parse a unary expression and return its type without any side
7520 static void unary_type(CType
*type
)
7532 /* parse a constant expression and return value in vtop. */
7533 static void expr_const1(void)
7542 /* parse an integer constant and return its value. */
7543 static int expr_const(void)
7547 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
7548 expect("constant expression");
7554 /* return the label token if current token is a label, otherwise
7556 static int is_label(void)
7560 /* fast test first */
7561 if (tok
< TOK_UIDENT
)
7563 /* no need to save tokc because tok is an identifier */
7570 unget_tok(last_tok
);
7575 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
7576 int case_reg
, int is_expr
)
7581 /* generate line number info */
7583 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
7584 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
7586 last_line_num
= file
->line_num
;
7590 /* default return value is (void) */
7592 vtop
->type
.t
= VT_VOID
;
7595 if (tok
== TOK_IF
) {
7602 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7604 if (c
== TOK_ELSE
) {
7608 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7609 gsym(d
); /* patch else jmp */
7612 } else if (tok
== TOK_WHILE
) {
7620 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7624 } else if (tok
== '{') {
7628 /* record local declaration stack position */
7630 llabel
= local_label_stack
;
7631 /* handle local labels declarations */
7632 if (tok
== TOK_LABEL
) {
7635 if (tok
< TOK_UIDENT
)
7636 expect("label identifier");
7637 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
7647 while (tok
!= '}') {
7652 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
7655 /* pop locally defined labels */
7656 label_pop(&local_label_stack
, llabel
);
7657 /* pop locally defined symbols */
7658 sym_pop(&local_stack
, s
);
7660 } else if (tok
== TOK_RETURN
) {
7664 gen_assign_cast(&func_vt
);
7665 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
7667 /* if returning structure, must copy it to implicit
7668 first pointer arg location */
7671 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
7674 /* copy structure value to pointer */
7676 } else if (is_float(func_vt
.t
)) {
7681 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
7684 rsym
= gjmp(rsym
); /* jmp */
7685 } else if (tok
== TOK_BREAK
) {
7688 error("cannot break");
7689 *bsym
= gjmp(*bsym
);
7692 } else if (tok
== TOK_CONTINUE
) {
7695 error("cannot continue");
7696 *csym
= gjmp(*csym
);
7699 } else if (tok
== TOK_FOR
) {
7726 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7731 if (tok
== TOK_DO
) {
7736 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7747 if (tok
== TOK_SWITCH
) {
7751 /* XXX: other types than integer */
7752 case_reg
= gv(RC_INT
);
7756 b
= gjmp(0); /* jump to first case */
7758 block(&a
, csym
, &b
, &c
, case_reg
, 0);
7759 /* if no default, jmp after switch */
7767 if (tok
== TOK_CASE
) {
7774 if (gnu_ext
&& tok
== TOK_DOTS
) {
7778 warning("empty case range");
7780 /* since a case is like a label, we must skip it with a jmp */
7787 *case_sym
= gtst(1, 0);
7790 *case_sym
= gtst(1, 0);
7794 *case_sym
= gtst(1, *case_sym
);
7799 goto block_after_label
;
7801 if (tok
== TOK_DEFAULT
) {
7807 error("too many 'default'");
7810 goto block_after_label
;
7812 if (tok
== TOK_GOTO
) {
7814 if (tok
== '*' && gnu_ext
) {
7818 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
7821 } else if (tok
>= TOK_UIDENT
) {
7822 s
= label_find(tok
);
7823 /* put forward definition if needed */
7825 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7827 if (s
->r
== LABEL_DECLARED
)
7828 s
->r
= LABEL_FORWARD
;
7830 /* label already defined */
7831 if (s
->r
& LABEL_FORWARD
)
7832 s
->next
= (void *)gjmp((long)s
->next
);
7834 gjmp_addr((long)s
->next
);
7837 expect("label identifier");
7840 } else if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
7848 if (s
->r
== LABEL_DEFINED
)
7849 error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
7850 gsym((long)s
->next
);
7851 s
->r
= LABEL_DEFINED
;
7853 s
= label_push(&global_label_stack
, b
, LABEL_DEFINED
);
7855 s
->next
= (void *)ind
;
7856 /* we accept this, but it is a mistake */
7859 warning("deprecated use of label at end of compound statement");
7863 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
7866 /* expression case */
7881 /* t is the array or struct type. c is the array or struct
7882 address. cur_index/cur_field is the pointer to the current
7883 value. 'size_only' is true if only size info is needed (only used
7885 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
7886 int *cur_index
, Sym
**cur_field
,
7890 int notfirst
, index
, index_last
, align
, l
, nb_elems
, elem_size
;
7896 if (gnu_ext
&& (l
= is_label()) != 0)
7898 while (tok
== '[' || tok
== '.') {
7900 if (!(type
->t
& VT_ARRAY
))
7901 expect("array type");
7904 index
= expr_const();
7905 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
7906 expect("invalid index");
7907 if (tok
== TOK_DOTS
&& gnu_ext
) {
7909 index_last
= expr_const();
7910 if (index_last
< 0 ||
7911 (s
->c
>= 0 && index_last
>= s
->c
) ||
7913 expect("invalid index");
7919 *cur_index
= index_last
;
7920 type
= pointed_type(type
);
7921 elem_size
= type_size(type
, &align
);
7922 c
+= index
* elem_size
;
7923 /* NOTE: we only support ranges for last designator */
7924 nb_elems
= index_last
- index
+ 1;
7925 if (nb_elems
!= 1) {
7934 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
7935 expect("struct/union type");
7948 /* XXX: fix this mess by using explicit storage field */
7950 type1
.t
|= (type
->t
& ~VT_TYPE
);
7964 if (type
->t
& VT_ARRAY
) {
7966 type
= pointed_type(type
);
7967 c
+= index
* type_size(type
, &align
);
7971 error("too many field init");
7972 /* XXX: fix this mess by using explicit storage field */
7974 type1
.t
|= (type
->t
& ~VT_TYPE
);
7979 decl_initializer(type
, sec
, c
, 0, size_only
);
7981 /* XXX: make it more general */
7982 if (!size_only
&& nb_elems
> 1) {
7983 unsigned long c_end
;
7988 error("range init not supported yet for dynamic storage");
7989 c_end
= c
+ nb_elems
* elem_size
;
7990 if (c_end
> sec
->data_allocated
)
7991 section_realloc(sec
, c_end
);
7992 src
= sec
->data
+ c
;
7994 for(i
= 1; i
< nb_elems
; i
++) {
7996 memcpy(dst
, src
, elem_size
);
8002 #define EXPR_CONST 1
8005 /* store a value or an expression directly in global data or in local array */
8006 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
8007 int v
, int expr_type
)
8009 int saved_global_expr
, bt
, bit_pos
, bit_size
;
8011 unsigned long long bit_mask
;
8019 /* compound literals must be allocated globally in this case */
8020 saved_global_expr
= global_expr
;
8023 global_expr
= saved_global_expr
;
8024 /* NOTE: symbols are accepted */
8025 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
8026 error("initializer element is not constant");
8034 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
8037 /* XXX: not portable */
8038 /* XXX: generate error if incorrect relocation */
8039 gen_assign_cast(&dtype
);
8040 bt
= type
->t
& VT_BTYPE
;
8041 ptr
= sec
->data
+ c
;
8042 /* XXX: make code faster ? */
8043 if (!(type
->t
& VT_BITFIELD
)) {
8048 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
8049 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
8050 bit_mask
= (1LL << bit_size
) - 1;
8052 if ((vtop
->r
& VT_SYM
) &&
8058 (bt
== VT_INT
&& bit_size
!= 32)))
8059 error("initializer element is not computable at load time");
8062 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8065 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8068 *(double *)ptr
= vtop
->c
.d
;
8071 *(long double *)ptr
= vtop
->c
.ld
;
8074 *(long long *)ptr
|= (vtop
->c
.ll
& bit_mask
) << bit_pos
;
8077 if (vtop
->r
& VT_SYM
) {
8078 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
8080 *(int *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8085 vset(&dtype
, VT_LOCAL
, c
);
8092 /* put zeros for variable based init */
8093 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
8096 /* nothing to do because globals are already set to zero */
8098 vpush_global_sym(&func_old_type
, TOK_memset
);
8106 /* 't' contains the type and storage info. 'c' is the offset of the
8107 object in section 'sec'. If 'sec' is NULL, it means stack based
8108 allocation. 'first' is true if array '{' must be read (multi
8109 dimension implicit array init handling). 'size_only' is true if
8110 size only evaluation is wanted (only for arrays). */
8111 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
8112 int first
, int size_only
)
8114 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
8115 int size1
, align1
, expr_type
;
8119 if (type
->t
& VT_ARRAY
) {
8123 t1
= pointed_type(type
);
8124 size1
= type_size(t1
, &align1
);
8127 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
8133 /* only parse strings here if correct type (otherwise: handle
8134 them as ((w)char *) expressions */
8135 if ((tok
== TOK_LSTR
&&
8136 (t1
->t
& VT_BTYPE
) == VT_INT
) ||
8138 (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
8139 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8144 /* compute maximum number of chars wanted */
8146 cstr_len
= cstr
->size
;
8148 cstr_len
= cstr
->size
/ sizeof(int);
8151 if (n
>= 0 && nb
> (n
- array_length
))
8152 nb
= n
- array_length
;
8155 warning("initializer-string for array is too long");
8156 /* in order to go faster for common case (char
8157 string in global variable, we handle it
8159 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
8160 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
8164 ch
= ((unsigned char *)cstr
->data
)[i
];
8166 ch
= ((int *)cstr
->data
)[i
];
8167 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
8175 /* only add trailing zero if enough storage (no
8176 warning in this case since it is standard) */
8177 if (n
< 0 || array_length
< n
) {
8179 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
8185 while (tok
!= '}') {
8186 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
8187 if (n
>= 0 && index
>= n
)
8188 error("index too large");
8189 /* must put zero in holes (note that doing it that way
8190 ensures that it even works with designators) */
8191 if (!size_only
&& array_length
< index
) {
8192 init_putz(t1
, sec
, c
+ array_length
* size1
,
8193 (index
- array_length
) * size1
);
8196 if (index
> array_length
)
8197 array_length
= index
;
8198 /* special test for multi dimensional arrays (may not
8199 be strictly correct if designators are used at the
8201 if (index
>= n
&& no_oblock
)
8210 /* put zeros at the end */
8211 if (!size_only
&& n
>= 0 && array_length
< n
) {
8212 init_putz(t1
, sec
, c
+ array_length
* size1
,
8213 (n
- array_length
) * size1
);
8215 /* patch type size if needed */
8217 s
->c
= array_length
;
8218 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
8219 (sec
|| !first
|| tok
== '{')) {
8222 /* NOTE: the previous test is a specific case for automatic
8223 struct/union init */
8224 /* XXX: union needs only one init */
8226 /* XXX: this test is incorrect for local initializers
8227 beginning with ( without {. It would be much more difficult
8228 to do it correctly (ideally, the expression parser should
8229 be used in all cases) */
8235 while (tok
== '(') {
8239 if (!parse_btype(&type1
, &ad1
))
8241 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
8243 if (!is_assignable_types(type
, &type1
))
8244 error("invalid type for cast");
8249 if (first
|| tok
== '{') {
8258 while (tok
!= '}') {
8259 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
8261 if (!size_only
&& array_length
< index
) {
8262 init_putz(type
, sec
, c
+ array_length
,
8263 index
- array_length
);
8265 index
= index
+ type_size(&f
->type
, &align1
);
8266 if (index
> array_length
)
8267 array_length
= index
;
8269 if (no_oblock
&& f
== NULL
)
8275 /* put zeros at the end */
8276 if (!size_only
&& array_length
< n
) {
8277 init_putz(type
, sec
, c
+ array_length
,
8286 } else if (tok
== '{') {
8288 decl_initializer(type
, sec
, c
, first
, size_only
);
8290 } else if (size_only
) {
8291 /* just skip expression */
8293 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
8297 else if (tok
== ')')
8302 /* currently, we always use constant expression for globals
8303 (may change for scripting case) */
8304 expr_type
= EXPR_CONST
;
8306 expr_type
= EXPR_ANY
;
8307 init_putv(type
, sec
, c
, 0, expr_type
);
8311 /* parse an initializer for type 't' if 'has_init' is non zero, and
8312 allocate space in local or global data space ('r' is either
8313 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8314 variable 'v' of scope 'scope' is declared before initializers are
8315 parsed. If 'v' is zero, then a reference to the new object is put
8316 in the value stack. If 'has_init' is 2, a special parsing is done
8317 to handle string constants. */
8318 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
8319 int has_init
, int v
, int scope
)
8321 int size
, align
, addr
, data_offset
;
8323 ParseState saved_parse_state
;
8324 TokenString init_str
;
8327 size
= type_size(type
, &align
);
8328 /* If unknown size, we must evaluate it before
8329 evaluating initializers because
8330 initializers can generate global data too
8331 (e.g. string pointers or ISOC99 compound
8332 literals). It also simplifies local
8333 initializers handling */
8334 tok_str_new(&init_str
);
8337 error("unknown type size");
8338 /* get all init string */
8339 if (has_init
== 2) {
8340 /* only get strings */
8341 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8342 tok_str_add_tok(&init_str
);
8347 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
8349 error("unexpected end of file in initializer");
8350 tok_str_add_tok(&init_str
);
8353 else if (tok
== '}') {
8361 tok_str_add(&init_str
, -1);
8362 tok_str_add(&init_str
, 0);
8365 save_parse_state(&saved_parse_state
);
8367 macro_ptr
= init_str
.str
;
8369 decl_initializer(type
, NULL
, 0, 1, 1);
8370 /* prepare second initializer parsing */
8371 macro_ptr
= init_str
.str
;
8374 /* if still unknown size, error */
8375 size
= type_size(type
, &align
);
8377 error("unknown type size");
8379 /* take into account specified alignment if bigger */
8380 if (ad
->aligned
> align
)
8381 align
= ad
->aligned
;
8382 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
8384 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
8386 loc
= (loc
- size
) & -align
;
8388 /* handles bounds */
8389 /* XXX: currently, since we do only one pass, we cannot track
8390 '&' operators, so we add only arrays */
8391 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
8392 unsigned long *bounds_ptr
;
8393 /* add padding between regions */
8395 /* then add local bound info */
8396 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
8397 bounds_ptr
[0] = addr
;
8398 bounds_ptr
[1] = size
;
8401 /* local variable */
8402 sym_push(v
, type
, r
, addr
);
8404 /* push local reference */
8405 vset(type
, r
, addr
);
8411 if (v
&& scope
== VT_CONST
) {
8412 /* see if the symbol was already defined */
8415 if (!is_compatible_types(&sym
->type
, type
))
8416 error("incompatible types for redefinition of '%s'",
8417 get_tok_str(v
, NULL
));
8418 if (sym
->type
.t
& VT_EXTERN
) {
8419 /* if the variable is extern, it was not allocated */
8420 sym
->type
.t
&= ~VT_EXTERN
;
8422 /* we accept several definitions of the same
8423 global variable. this is tricky, because we
8424 must play with the SHN_COMMON type of the symbol */
8425 /* XXX: should check if the variable was already
8426 initialized. It is incorrect to initialized it
8428 /* no init data, we won't add more to the symbol */
8435 /* allocate symbol in corresponding section */
8442 data_offset
= sec
->data_offset
;
8443 data_offset
= (data_offset
+ align
- 1) & -align
;
8445 /* very important to increment global pointer at this time
8446 because initializers themselves can create new initializers */
8447 data_offset
+= size
;
8448 /* add padding if bound check */
8449 if (do_bounds_check
)
8451 sec
->data_offset
= data_offset
;
8452 /* allocate section space to put the data */
8453 if (sec
->sh_type
!= SHT_NOBITS
&&
8454 data_offset
> sec
->data_allocated
)
8455 section_realloc(sec
, data_offset
);
8457 addr
= 0; /* avoid warning */
8461 if (scope
== VT_CONST
) {
8466 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
8468 /* update symbol definition */
8470 put_extern_sym(sym
, sec
, addr
, size
);
8473 /* put a common area */
8474 put_extern_sym(sym
, NULL
, align
, size
);
8475 /* XXX: find a nicer way */
8476 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
8477 esym
->st_shndx
= SHN_COMMON
;
8482 /* push global reference */
8483 sym
= get_sym_ref(type
, sec
, addr
, size
);
8485 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
8489 /* handles bounds now because the symbol must be defined
8490 before for the relocation */
8491 if (do_bounds_check
) {
8492 unsigned long *bounds_ptr
;
8494 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
8495 /* then add global bound info */
8496 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
8497 bounds_ptr
[0] = 0; /* relocated */
8498 bounds_ptr
[1] = size
;
8502 decl_initializer(type
, sec
, addr
, 1, 0);
8503 /* restore parse state if needed */
8505 tok_str_free(init_str
.str
);
8506 restore_parse_state(&saved_parse_state
);
8512 void put_func_debug(Sym
*sym
)
8517 /* XXX: we put here a dummy type */
8518 snprintf(buf
, sizeof(buf
), "%s:%c1",
8519 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
8520 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
8521 cur_text_section
, sym
->c
);
8526 /* not finished : try to put some local vars in registers */
8527 //#define CONFIG_REG_VARS
8529 #ifdef CONFIG_REG_VARS
8530 void add_var_ref(int t
)
8532 printf("%s:%d: &%s\n",
8533 file
->filename
, file
->line_num
,
8534 get_tok_str(t
, NULL
));
8537 /* first pass on a function with heuristic to extract variable usage
8538 and pointer references to local variables for register allocation */
8539 void analyse_function(void)
8546 /* any symbol coming after '&' is considered as being a
8547 variable whose reference is taken. It is highly unaccurate
8548 but it is difficult to do better without a complete parse */
8551 /* if '& number', then no need to examine next tokens */
8552 if (tok
== TOK_CINT
||
8554 tok
== TOK_CLLONG
||
8555 tok
== TOK_CULLONG
) {
8557 } else if (tok
>= TOK_UIDENT
) {
8558 /* if '& ident [' or '& ident ->', then ident address
8562 if (tok
!= '[' && tok
!= TOK_ARROW
)
8566 while (tok
!= '}' && tok
!= ';' &&
8567 !((tok
== ',' || tok
== ')') && level
== 0)) {
8568 if (tok
>= TOK_UIDENT
) {
8570 } else if (tok
== '(') {
8572 } else if (tok
== ')') {
8585 /* parse an old style function declaration list */
8586 /* XXX: check multiple parameter */
8587 static void func_decl_list(Sym
*func_sym
)
8594 /* parse each declaration */
8595 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
) {
8596 if (!parse_btype(&btype
, &ad
))
8597 expect("declaration list");
8598 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
8599 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
8601 /* we accept no variable after */
8605 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8606 /* find parameter in function parameter list */
8609 if ((s
->v
& ~SYM_FIELD
) == v
)
8613 error("declaration for parameter '%s' but no such parameter",
8614 get_tok_str(v
, NULL
));
8616 /* check that no storage specifier except 'register' was given */
8617 if (type
.t
& VT_STORAGE
)
8618 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
8619 convert_parameter_type(&type
);
8620 /* we can add the type (NOTE: it could be local to the function) */
8622 /* accept other parameters */
8633 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
8634 static void decl(int l
)
8642 if (!parse_btype(&btype
, &ad
)) {
8643 /* skip redundant ';' */
8644 /* XXX: find more elegant solution */
8649 /* special test for old K&R protos without explicit int
8650 type. Only accepted when defining global data */
8651 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
8655 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
8656 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
8658 /* we accept no variable after */
8662 while (1) { /* iterate thru each declaration */
8664 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8668 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
8669 printf("type = '%s'\n", buf
);
8672 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8673 /* if old style function prototype, we accept a
8676 if (sym
->c
== FUNC_OLD
)
8677 func_decl_list(sym
);
8681 #ifdef CONFIG_REG_VARS
8682 TokenString func_str
;
8683 ParseState saved_parse_state
;
8688 error("cannot use local functions");
8689 if (!(type
.t
& VT_FUNC
))
8690 expect("function definition");
8692 /* reject abstract declarators in function definition */
8694 while ((sym
= sym
->next
) != NULL
)
8695 if (!(sym
->v
& ~SYM_FIELD
))
8696 expect("identifier");
8698 /* XXX: cannot do better now: convert extern line to static inline */
8699 if ((type
.t
& (VT_EXTERN
| VT_INLINE
)) == (VT_EXTERN
| VT_INLINE
))
8700 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
8702 #ifdef CONFIG_REG_VARS
8703 /* parse all function code and record it */
8705 tok_str_new(&func_str
);
8711 error("unexpected end of file");
8712 tok_str_add_tok(&func_str
);
8717 } else if (t
== '}') {
8719 if (block_level
== 0)
8723 tok_str_add(&func_str
, -1);
8724 tok_str_add(&func_str
, 0);
8726 save_parse_state(&saved_parse_state
);
8728 macro_ptr
= func_str
.str
;
8733 /* compute text section */
8734 cur_text_section
= ad
.section
;
8735 if (!cur_text_section
)
8736 cur_text_section
= text_section
;
8737 ind
= cur_text_section
->data_offset
;
8738 funcname
= get_tok_str(v
, NULL
);
8741 /* if symbol is already defined, then put complete type */
8744 /* put function symbol */
8745 sym
= global_identifier_push(v
, type
.t
, 0);
8746 sym
->type
.ref
= type
.ref
;
8748 /* NOTE: we patch the symbol size later */
8749 put_extern_sym(sym
, cur_text_section
, ind
, 0);
8751 sym
->r
= VT_SYM
| VT_CONST
;
8752 /* put debug symbol */
8754 put_func_debug(sym
);
8755 /* push a dummy symbol to enable local sym storage */
8756 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
8757 gfunc_prolog(&type
);
8759 #ifdef CONFIG_REG_VARS
8760 macro_ptr
= func_str
.str
;
8763 block(NULL
, NULL
, NULL
, NULL
, 0, 0);
8766 cur_text_section
->data_offset
= ind
;
8767 label_pop(&global_label_stack
, NULL
);
8768 sym_pop(&local_stack
, NULL
); /* reset local stack */
8769 /* end of function */
8770 /* patch symbol size */
8771 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
8774 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
8776 funcname
= ""; /* for safety */
8777 func_vt
.t
= VT_VOID
; /* for safety */
8778 ind
= 0; /* for safety */
8780 #ifdef CONFIG_REG_VARS
8781 tok_str_free(func_str
.str
);
8782 restore_parse_state(&saved_parse_state
);
8786 if (btype
.t
& VT_TYPEDEF
) {
8787 /* save typedefed type */
8788 /* XXX: test storage specifiers ? */
8789 sym
= sym_push(v
, &type
, 0, 0);
8790 sym
->type
.t
|= VT_TYPEDEF
;
8791 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8792 /* external function definition */
8793 external_sym(v
, &type
, 0);
8795 /* not lvalue if array */
8797 if (!(type
.t
& VT_ARRAY
))
8798 r
|= lvalue_type(type
.t
);
8799 has_init
= (tok
== '=');
8800 if ((btype
.t
& VT_EXTERN
) ||
8801 ((type
.t
& VT_ARRAY
) && (type
.t
& VT_STATIC
) &&
8802 !has_init
&& l
== VT_CONST
&& type
.ref
->c
< 0)) {
8803 /* external variable */
8804 /* NOTE: as GCC, uninitialized global static
8805 arrays of null size are considered as
8807 external_sym(v
, &type
, r
);
8809 if (type
.t
& VT_STATIC
)
8815 decl_initializer_alloc(&type
, &ad
, r
,
8829 /* better than nothing, but needs extension to handle '-E' option
8831 static void preprocess_init(TCCState
*s1
)
8833 s1
->include_stack_ptr
= s1
->include_stack
;
8834 /* XXX: move that before to avoid having to initialize
8835 file->ifdef_stack_ptr ? */
8836 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
8837 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
8839 /* XXX: not ANSI compliant: bound checking says error */
8843 /* compile the C file opened in 'file'. Return non zero if errors. */
8844 static int tcc_compile(TCCState
*s1
)
8848 volatile int section_sym
;
8851 printf("%s: **** new file\n", file
->filename
);
8853 preprocess_init(s1
);
8856 anon_sym
= SYM_FIRST_ANOM
;
8858 /* file info: full path + filename */
8859 section_sym
= 0; /* avoid warning */
8861 section_sym
= put_elf_sym(symtab_section
, 0, 0,
8862 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
8863 text_section
->sh_num
, NULL
);
8864 getcwd(buf
, sizeof(buf
));
8865 pstrcat(buf
, sizeof(buf
), "/");
8866 put_stabs_r(buf
, N_SO
, 0, 0,
8867 text_section
->data_offset
, text_section
, section_sym
);
8868 put_stabs_r(file
->filename
, N_SO
, 0, 0,
8869 text_section
->data_offset
, text_section
, section_sym
);
8871 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8872 symbols can be safely used */
8873 put_elf_sym(symtab_section
, 0, 0,
8874 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
8875 SHN_ABS
, file
->filename
);
8877 /* define some often used types */
8878 int_type
.t
= VT_INT
;
8880 char_pointer_type
.t
= VT_BYTE
;
8881 mk_pointer(&char_pointer_type
);
8883 func_old_type
.t
= VT_FUNC
;
8884 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
8887 /* define 'void *alloca(unsigned int)' builtin function */
8892 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
8893 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
8896 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
8900 define_start
= define_stack
;
8902 if (setjmp(s1
->error_jmp_buf
) == 0) {
8904 s1
->error_set_jmp_enabled
= 1;
8906 ch
= file
->buf_ptr
[0];
8907 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
8908 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
;
8912 expect("declaration");
8914 /* end of translation unit info */
8916 put_stabs_r(NULL
, N_SO
, 0, 0,
8917 text_section
->data_offset
, text_section
, section_sym
);
8920 s1
->error_set_jmp_enabled
= 0;
8922 /* reset define stack, but leave -Dsymbols (may be incorrect if
8923 they are undefined) */
8924 free_defines(define_start
);
8926 sym_pop(&global_stack
, NULL
);
8928 return s1
->nb_errors
!= 0 ? -1 : 0;
8932 int tcc_compile_string(TCCState
*s
, const char *str
)
8934 BufferedFile bf1
, *bf
= &bf1
;
8938 /* init file structure */
8940 /* XXX: avoid copying */
8942 buf
= tcc_malloc(len
+ 1);
8945 memcpy(buf
, str
, len
);
8948 bf
->buf_end
= buf
+ len
;
8949 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
8953 ret
= tcc_compile(s
);
8957 /* currently, no need to close */
8962 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8963 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
8965 BufferedFile bf1
, *bf
= &bf1
;
8967 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
8968 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
8972 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
8974 /* init file structure */
8976 bf
->buf_ptr
= bf
->buffer
;
8977 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
8978 *bf
->buf_end
= CH_EOB
;
8979 bf
->filename
[0] = '\0';
8983 s1
->include_stack_ptr
= s1
->include_stack
;
8985 /* parse with define parser */
8986 ch
= file
->buf_ptr
[0];
8992 /* undefine a preprocessor symbol */
8993 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
8997 ts
= tok_alloc(sym
, strlen(sym
));
8998 s
= define_find(ts
->tok
);
8999 /* undefine symbol by putting an invalid name */
9004 #ifdef CONFIG_TCC_ASM
9006 #ifdef TCC_TARGET_I386
9007 #include "i386-asm.c"
9012 static void asm_instr(void)
9014 error("inline asm() not supported");
9020 #ifdef TCC_TARGET_COFF
9021 #include "tcccoff.c"
9024 /* print the position in the source file of PC value 'pc' by reading
9025 the stabs debug information */
9026 static void rt_printline(unsigned long wanted_pc
)
9028 Stab_Sym
*sym
, *sym_end
;
9029 char func_name
[128], last_func_name
[128];
9030 unsigned long func_addr
, last_pc
, pc
;
9031 const char *incl_files
[INCLUDE_STACK_SIZE
];
9032 int incl_index
, len
, last_line_num
, i
;
9033 const char *str
, *p
;
9035 fprintf(stderr
, "0x%08lx:", wanted_pc
);
9037 func_name
[0] = '\0';
9040 last_func_name
[0] = '\0';
9041 last_pc
= 0xffffffff;
9043 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
9044 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
9045 while (sym
< sym_end
) {
9046 switch(sym
->n_type
) {
9047 /* function start or end */
9049 if (sym
->n_strx
== 0) {
9050 /* we test if between last line and end of function */
9051 pc
= sym
->n_value
+ func_addr
;
9052 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9054 func_name
[0] = '\0';
9057 str
= stabstr_section
->data
+ sym
->n_strx
;
9058 p
= strchr(str
, ':');
9060 pstrcpy(func_name
, sizeof(func_name
), str
);
9063 if (len
> sizeof(func_name
) - 1)
9064 len
= sizeof(func_name
) - 1;
9065 memcpy(func_name
, str
, len
);
9066 func_name
[len
] = '\0';
9068 func_addr
= sym
->n_value
;
9071 /* line number info */
9073 pc
= sym
->n_value
+ func_addr
;
9074 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9077 last_line_num
= sym
->n_desc
;
9079 strcpy(last_func_name
, func_name
);
9083 str
= stabstr_section
->data
+ sym
->n_strx
;
9085 if (incl_index
< INCLUDE_STACK_SIZE
) {
9086 incl_files
[incl_index
++] = str
;
9094 if (sym
->n_strx
== 0) {
9095 incl_index
= 0; /* end of translation unit */
9097 str
= stabstr_section
->data
+ sym
->n_strx
;
9098 /* do not add path */
9100 if (len
> 0 && str
[len
- 1] != '/')
9108 /* second pass: we try symtab symbols (no line number info) */
9111 Elf32_Sym
*sym
, *sym_end
;
9114 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
9115 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
9118 type
= ELF32_ST_TYPE(sym
->st_info
);
9119 if (type
== STT_FUNC
) {
9120 if (wanted_pc
>= sym
->st_value
&&
9121 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
9122 pstrcpy(last_func_name
, sizeof(last_func_name
),
9123 strtab_section
->data
+ sym
->st_name
);
9129 /* did not find any info: */
9130 fprintf(stderr
, " ???\n");
9133 if (last_func_name
[0] != '\0') {
9134 fprintf(stderr
, " %s()", last_func_name
);
9136 if (incl_index
> 0) {
9137 fprintf(stderr
, " (%s:%d",
9138 incl_files
[incl_index
- 1], last_line_num
);
9139 for(i
= incl_index
- 2; i
>= 0; i
--)
9140 fprintf(stderr
, ", included from %s", incl_files
[i
]);
9141 fprintf(stderr
, ")");
9143 fprintf(stderr
, "\n");
9150 /* fix for glibc 2.1 */
9156 /* return the PC at frame level 'level'. Return non zero if not found */
9157 static int rt_get_caller_pc(unsigned long *paddr
,
9158 ucontext_t
*uc
, int level
)
9164 #if defined(__FreeBSD__)
9165 *paddr
= uc
->uc_mcontext
.mc_eip
;
9166 #elif defined(__dietlibc__)
9167 *paddr
= uc
->uc_mcontext
.eip
;
9169 *paddr
= uc
->uc_mcontext
.gregs
[REG_EIP
];
9173 #if defined(__FreeBSD__)
9174 fp
= uc
->uc_mcontext
.mc_ebp
;
9175 #elif defined(__dietlibc__)
9176 fp
= uc
->uc_mcontext
.ebp
;
9178 fp
= uc
->uc_mcontext
.gregs
[REG_EBP
];
9180 for(i
=1;i
<level
;i
++) {
9181 /* XXX: check address validity with program info */
9182 if (fp
<= 0x1000 || fp
>= 0xc0000000)
9184 fp
= ((unsigned long *)fp
)[0];
9186 *paddr
= ((unsigned long *)fp
)[1];
9192 #warning add arch specific rt_get_caller_pc()
9194 static int rt_get_caller_pc(unsigned long *paddr
,
9195 ucontext_t
*uc
, int level
)
9201 /* emit a run time error at position 'pc' */
9202 void rt_error(ucontext_t
*uc
, const char *fmt
, ...)
9209 fprintf(stderr
, "Runtime error: ");
9210 vfprintf(stderr
, fmt
, ap
);
9211 fprintf(stderr
, "\n");
9212 for(i
=0;i
<num_callers
;i
++) {
9213 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
9216 fprintf(stderr
, "at ");
9218 fprintf(stderr
, "by ");
9225 /* signal handler for fatal errors */
9226 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
9228 ucontext_t
*uc
= puc
;
9232 switch(siginf
->si_code
) {
9235 rt_error(uc
, "division by zero");
9238 rt_error(uc
, "floating point exception");
9244 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
9245 rt_error(uc
, *rt_bound_error_msg
);
9247 rt_error(uc
, "dereferencing invalid pointer");
9250 rt_error(uc
, "illegal instruction");
9253 rt_error(uc
, "abort() called");
9256 rt_error(uc
, "caught signal %d", signum
);
9263 /* do all relocations (needed before using tcc_get_symbol()) */
9264 int tcc_relocate(TCCState
*s1
)
9271 tcc_add_runtime(s1
);
9273 build_got_entries(s1
);
9275 relocate_common_syms();
9277 /* compute relocation address : section are relocated in place. We
9278 also alloc the bss space */
9279 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9280 s
= s1
->sections
[i
];
9281 if (s
->sh_flags
& SHF_ALLOC
) {
9282 if (s
->sh_type
== SHT_NOBITS
)
9283 s
->data
= tcc_mallocz(s
->data_offset
);
9284 s
->sh_addr
= (unsigned long)s
->data
;
9288 relocate_syms(s1
, 1);
9290 if (s1
->nb_errors
!= 0)
9293 /* relocate each section */
9294 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9295 s
= s1
->sections
[i
];
9297 relocate_section(s1
, s
);
9302 /* launch the compiled program with the given arguments */
9303 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
9305 int (*prog_main
)(int, char **);
9307 if (tcc_relocate(s1
) < 0)
9310 prog_main
= tcc_get_symbol_err(s1
, "main");
9314 error("debug mode currently not available for Windows");
9316 struct sigaction sigact
;
9317 /* install TCC signal handlers to print debug info on fatal
9319 sigact
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
9320 sigact
.sa_sigaction
= sig_error
;
9321 sigemptyset(&sigact
.sa_mask
);
9322 sigaction(SIGFPE
, &sigact
, NULL
);
9323 sigaction(SIGILL
, &sigact
, NULL
);
9324 sigaction(SIGSEGV
, &sigact
, NULL
);
9325 sigaction(SIGBUS
, &sigact
, NULL
);
9326 sigaction(SIGABRT
, &sigact
, NULL
);
9330 #ifdef CONFIG_TCC_BCHECK
9331 if (do_bounds_check
) {
9332 void (*bound_init
)(void);
9334 /* set error function */
9335 rt_bound_error_msg
= (void *)tcc_get_symbol_err(s1
,
9336 "__bound_error_msg");
9338 /* XXX: use .init section so that it also work in binary ? */
9339 bound_init
= (void *)tcc_get_symbol_err(s1
, "__bound_init");
9343 return (*prog_main
)(argc
, argv
);
9346 TCCState
*tcc_new(void)
9353 s
= tcc_mallocz(sizeof(TCCState
));
9357 s
->output_type
= TCC_OUTPUT_MEMORY
;
9359 /* init isid table */
9361 isidnum_table
[i
] = isid(i
) || isnum(i
);
9363 /* add all tokens */
9365 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
9367 tok_ident
= TOK_IDENT
;
9376 ts
= tok_alloc(p
, r
- p
- 1);
9380 /* we add dummy defines for some special macros to speed up tests
9381 and to have working defined() */
9382 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
9383 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
9384 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
9385 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
9387 /* standard defines */
9388 tcc_define_symbol(s
, "__STDC__", NULL
);
9389 #if defined(TCC_TARGET_I386)
9390 tcc_define_symbol(s
, "__i386__", NULL
);
9392 #if defined(TCC_TARGET_ARM)
9393 tcc_define_symbol(s
, "__ARM_ARCH_4__", NULL
);
9394 tcc_define_symbol(s
, "__arm_elf__", NULL
);
9395 tcc_define_symbol(s
, "__arm_elf", NULL
);
9396 tcc_define_symbol(s
, "arm_elf", NULL
);
9397 tcc_define_symbol(s
, "__arm__", NULL
);
9398 tcc_define_symbol(s
, "__arm", NULL
);
9399 tcc_define_symbol(s
, "arm", NULL
);
9400 tcc_define_symbol(s
, "__APCS_32__", NULL
);
9403 tcc_define_symbol(s
, "__linux__", NULL
);
9404 tcc_define_symbol(s
, "linux", NULL
);
9406 /* tiny C specific defines */
9407 tcc_define_symbol(s
, "__TINYC__", NULL
);
9409 /* tiny C & gcc defines */
9410 tcc_define_symbol(s
, "__SIZE_TYPE__", "unsigned int");
9411 tcc_define_symbol(s
, "__PTRDIFF_TYPE__", "int");
9412 tcc_define_symbol(s
, "__WCHAR_TYPE__", "int");
9414 /* default library paths */
9415 tcc_add_library_path(s
, "/usr/local/lib");
9416 tcc_add_library_path(s
, "/usr/lib");
9417 tcc_add_library_path(s
, "/lib");
9419 /* no section zero */
9420 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
9422 /* create standard sections */
9423 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
9424 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
9425 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
9427 /* symbols are always generated for linking stage */
9428 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
9430 ".hashtab", SHF_PRIVATE
);
9431 strtab_section
= symtab_section
->link
;
9433 /* private symbol table for dynamic symbols */
9434 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
9436 ".dynhashtab", SHF_PRIVATE
);
9437 s
->alacarte_link
= 1;
9439 #ifdef CHAR_IS_UNSIGNED
9440 s
->char_is_unsigned
= 1;
9445 void tcc_delete(TCCState
*s1
)
9449 /* free -D defines */
9453 n
= tok_ident
- TOK_IDENT
;
9454 for(i
= 0; i
< n
; i
++)
9455 tcc_free(table_ident
[i
]);
9456 tcc_free(table_ident
);
9458 /* free all sections */
9460 free_section(symtab_section
->hash
);
9462 free_section(s1
->dynsymtab_section
->hash
);
9463 free_section(s1
->dynsymtab_section
->link
);
9464 free_section(s1
->dynsymtab_section
);
9466 for(i
= 1; i
< s1
->nb_sections
; i
++)
9467 free_section(s1
->sections
[i
]);
9468 tcc_free(s1
->sections
);
9470 /* free loaded dlls array */
9471 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
9472 tcc_free(s1
->loaded_dlls
[i
]);
9473 tcc_free(s1
->loaded_dlls
);
9476 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
9477 tcc_free(s1
->library_paths
[i
]);
9478 tcc_free(s1
->library_paths
);
9480 /* cached includes */
9481 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
9482 tcc_free(s1
->cached_includes
[i
]);
9483 tcc_free(s1
->cached_includes
);
9485 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
9486 tcc_free(s1
->include_paths
[i
]);
9487 tcc_free(s1
->include_paths
);
9489 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
9490 tcc_free(s1
->sysinclude_paths
[i
]);
9491 tcc_free(s1
->sysinclude_paths
);
9496 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
9500 pathname1
= tcc_strdup(pathname
);
9501 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
9505 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
9509 pathname1
= tcc_strdup(pathname
);
9510 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
9514 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
9516 const char *ext
, *filename1
;
9519 BufferedFile
*saved_file
;
9521 /* find source file type with extension */
9522 filename1
= strrchr(filename
, '/');
9526 filename1
= filename
;
9527 ext
= strrchr(filename1
, '.');
9533 file
= tcc_open(s1
, filename
);
9535 if (flags
& AFF_PRINT_ERROR
) {
9536 error_noabort("file '%s' not found", filename
);
9542 if (!ext
|| !strcmp(ext
, "c")) {
9543 /* C file assumed */
9544 ret
= tcc_compile(s1
);
9546 #ifdef CONFIG_TCC_ASM
9547 if (!strcmp(ext
, "S")) {
9548 /* preprocessed assembler */
9549 ret
= tcc_assemble(s1
, 1);
9550 } else if (!strcmp(ext
, "s")) {
9551 /* non preprocessed assembler */
9552 ret
= tcc_assemble(s1
, 0);
9557 /* assume executable format: auto guess file type */
9558 ret
= read(fd
, &ehdr
, sizeof(ehdr
));
9559 lseek(fd
, 0, SEEK_SET
);
9561 error_noabort("could not read header");
9563 } else if (ret
!= sizeof(ehdr
)) {
9564 goto try_load_script
;
9567 if (ehdr
.e_ident
[0] == ELFMAG0
&&
9568 ehdr
.e_ident
[1] == ELFMAG1
&&
9569 ehdr
.e_ident
[2] == ELFMAG2
&&
9570 ehdr
.e_ident
[3] == ELFMAG3
) {
9571 file
->line_num
= 0; /* do not display line number if error */
9572 if (ehdr
.e_type
== ET_REL
) {
9573 ret
= tcc_load_object_file(s1
, fd
, 0);
9574 } else if (ehdr
.e_type
== ET_DYN
) {
9575 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
9577 h
= dlopen(filename
, RTLD_GLOBAL
| RTLD_LAZY
);
9583 ret
= tcc_load_dll(s1
, fd
, filename
,
9584 (flags
& AFF_REFERENCED_DLL
) != 0);
9587 error_noabort("unrecognized ELF file");
9590 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
9591 file
->line_num
= 0; /* do not display line number if error */
9592 ret
= tcc_load_archive(s1
, fd
);
9594 #ifdef TCC_TARGET_COFF
9595 if (*(uint16_t *)(&ehdr
) == COFF_C67_MAGIC
) {
9596 ret
= tcc_load_coff(s1
, fd
);
9600 /* as GNU ld, consider it is an ld script if not recognized */
9602 ret
= tcc_load_ldscript(s1
);
9604 error_noabort("unrecognized file type");
9619 int tcc_add_file(TCCState
*s
, const char *filename
)
9621 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
9624 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
9628 pathname1
= tcc_strdup(pathname
);
9629 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
9633 /* find and load a dll. Return non zero if not found */
9634 /* XXX: add '-rpath' option support ? */
9635 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
9640 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
9641 snprintf(buf
, sizeof(buf
), "%s/%s",
9642 s
->library_paths
[i
], filename
);
9643 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
9649 /* the library name is the same as the argument of the '-l' option */
9650 int tcc_add_library(TCCState
*s
, const char *libraryname
)
9655 /* first we look for the dynamic library if not static linking */
9656 if (!s
->static_link
) {
9657 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
9658 if (tcc_add_dll(s
, buf
, 0) == 0)
9662 /* then we look for the static library */
9663 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
9664 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
9665 s
->library_paths
[i
], libraryname
);
9666 if (tcc_add_file_internal(s
, buf
, 0) == 0)
9672 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
9674 add_elf_sym(symtab_section
, val
, 0,
9675 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
9680 int tcc_set_output_type(TCCState
*s
, int output_type
)
9684 s
->output_type
= output_type
;
9687 /* default include paths */
9688 /* XXX: reverse order needed if -isystem support */
9689 tcc_add_sysinclude_path(s
, "/usr/local/include");
9690 tcc_add_sysinclude_path(s
, "/usr/include");
9691 snprintf(buf
, sizeof(buf
), "%s/include", tcc_lib_path
);
9692 tcc_add_sysinclude_path(s
, buf
);
9695 /* if bound checking, then add corresponding sections */
9696 #ifdef CONFIG_TCC_BCHECK
9697 if (do_bounds_check
) {
9699 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
9700 /* create bounds sections */
9701 bounds_section
= new_section(s
, ".bounds",
9702 SHT_PROGBITS
, SHF_ALLOC
);
9703 lbounds_section
= new_section(s
, ".lbounds",
9704 SHT_PROGBITS
, SHF_ALLOC
);
9708 if (s
->char_is_unsigned
) {
9709 tcc_define_symbol(s
, "__CHAR_UNSIGNED__", NULL
);
9712 /* add debug sections */
9715 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
9716 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
9717 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
9718 put_elf_str(stabstr_section
, "");
9719 stab_section
->link
= stabstr_section
;
9720 /* put first entry */
9721 put_stabs("", 0, 0, 0, 0);
9724 /* add libc crt1/crti objects */
9725 if ((output_type
== TCC_OUTPUT_EXE
|| output_type
== TCC_OUTPUT_DLL
) &&
9727 if (output_type
!= TCC_OUTPUT_DLL
)
9728 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
9729 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
9734 #define WD_ALL 0x0001 /* warning is activated when using -Wall */
9735 #define FD_INVERT 0x0002 /* invert value before storing */
9737 typedef struct FlagDef
{
9743 static const FlagDef warning_defs
[] = {
9744 { offsetof(TCCState
, warn_unsupported
), 0, "unsupported" },
9745 { offsetof(TCCState
, warn_write_strings
), 0, "write-strings" },
9746 { offsetof(TCCState
, warn_error
), 0, "error" },
9747 { offsetof(TCCState
, warn_implicit_function_declaration
), WD_ALL
,
9748 "implicit-function-declaration" },
9751 static int set_flag(TCCState
*s
, const FlagDef
*flags
, int nb_flags
,
9752 const char *name
, int value
)
9759 if (r
[0] == 'n' && r
[1] == 'o' && r
[2] == '-') {
9763 for(i
= 0, p
= flags
; i
< nb_flags
; i
++, p
++) {
9764 if (!strcmp(r
, p
->name
))
9769 if (p
->flags
& FD_INVERT
)
9771 *(int *)((uint8_t *)s
+ p
->offset
) = value
;
9776 /* set/reset a warning */
9777 int tcc_set_warning(TCCState
*s
, const char *warning_name
, int value
)
9782 if (!strcmp(warning_name
, "all")) {
9783 for(i
= 0, p
= warning_defs
; i
< countof(warning_defs
); i
++, p
++) {
9784 if (p
->flags
& WD_ALL
)
9785 *(int *)((uint8_t *)s
+ p
->offset
) = 1;
9789 return set_flag(s
, warning_defs
, countof(warning_defs
),
9790 warning_name
, value
);
9794 static const FlagDef flag_defs
[] = {
9795 { offsetof(TCCState
, char_is_unsigned
), 0, "unsigned-char" },
9796 { offsetof(TCCState
, char_is_unsigned
), FD_INVERT
, "signed-char" },
9799 /* set/reset a flag */
9800 int tcc_set_flag(TCCState
*s
, const char *flag_name
, int value
)
9802 return set_flag(s
, flag_defs
, countof(flag_defs
),
9806 #if !defined(LIBTCC)
9808 /* extract the basename of a file */
9809 static const char *tcc_basename(const char *name
)
9812 p
= strrchr(name
, '/');
9815 p
= strrchr(name
, '\\');
9824 static int64_t getclock_us(void)
9829 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
9832 gettimeofday(&tv
, NULL
);
9833 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
9839 printf("tcc version " TCC_VERSION
" - Tiny C Compiler - Copyright (C) 2001-2003 Fabrice Bellard\n"
9840 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
9841 " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
9842 " [infile1 infile2...] [-run infile args...]\n"
9844 "General options:\n"
9845 " -v display current version\n"
9846 " -c compile only - generate an object file\n"
9847 " -o outfile set output filename\n"
9848 " -Bdir set tcc internal library path\n"
9849 " -bench output compilation statistics\n"
9850 " -run run compiled source\n"
9851 " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
9852 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
9853 " -w disable all warnings\n"
9854 "Preprocessor options:\n"
9855 " -Idir add include path 'dir'\n"
9856 " -Dsym[=val] define 'sym' with value 'val'\n"
9857 " -Usym undefine 'sym'\n"
9859 " -Ldir add library path 'dir'\n"
9860 " -llib link with dynamic or static library 'lib'\n"
9861 " -shared generate a shared library\n"
9862 " -static static linking\n"
9863 " -rdynamic export all global symbols to dynamic linker\n"
9864 " -r relocatable output\n"
9865 "Debugger options:\n"
9866 " -g generate runtime debug info\n"
9867 #ifdef CONFIG_TCC_BCHECK
9868 " -b compile with built-in memory and bounds checker (implies -g)\n"
9870 " -bt N show N callers in stack traces\n"
9874 #define TCC_OPTION_HAS_ARG 0x0001
9875 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
9877 typedef struct TCCOption
{
9904 TCC_OPTION_nostdinc
,
9905 TCC_OPTION_nostdlib
,
9906 TCC_OPTION_print_search_dirs
,
9907 TCC_OPTION_rdynamic
,
9913 static const TCCOption tcc_options
[] = {
9914 { "h", TCC_OPTION_HELP
, 0 },
9915 { "?", TCC_OPTION_HELP
, 0 },
9916 { "I", TCC_OPTION_I
, TCC_OPTION_HAS_ARG
},
9917 { "D", TCC_OPTION_D
, TCC_OPTION_HAS_ARG
},
9918 { "U", TCC_OPTION_U
, TCC_OPTION_HAS_ARG
},
9919 { "L", TCC_OPTION_L
, TCC_OPTION_HAS_ARG
},
9920 { "B", TCC_OPTION_B
, TCC_OPTION_HAS_ARG
},
9921 { "l", TCC_OPTION_l
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9922 { "bench", TCC_OPTION_bench
, 0 },
9923 { "bt", TCC_OPTION_bt
, TCC_OPTION_HAS_ARG
},
9924 #ifdef CONFIG_TCC_BCHECK
9925 { "b", TCC_OPTION_b
, 0 },
9927 { "g", TCC_OPTION_g
, 0 },
9928 { "c", TCC_OPTION_c
, 0 },
9929 { "static", TCC_OPTION_static
, 0 },
9930 { "shared", TCC_OPTION_shared
, 0 },
9931 { "o", TCC_OPTION_o
, TCC_OPTION_HAS_ARG
},
9932 { "run", TCC_OPTION_run
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9933 { "rdynamic", TCC_OPTION_rdynamic
, 0 },
9934 { "r", TCC_OPTION_r
, 0 },
9935 { "W", TCC_OPTION_W
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9936 { "O", TCC_OPTION_O
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9937 { "m", TCC_OPTION_m
, TCC_OPTION_HAS_ARG
},
9938 { "f", TCC_OPTION_f
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9939 { "nostdinc", TCC_OPTION_nostdinc
, 0 },
9940 { "nostdlib", TCC_OPTION_nostdlib
, 0 },
9941 { "print-search-dirs", TCC_OPTION_print_search_dirs
, 0 },
9942 { "v", TCC_OPTION_v
, 0 },
9943 { "w", TCC_OPTION_w
, 0 },
9947 /* convert 'str' into an array of space separated strings */
9948 static int expand_args(char ***pargv
, const char *str
)
9957 while (is_space(*str
))
9962 while (*str
!= '\0' && !is_space(*str
))
9965 arg
= tcc_malloc(len
+ 1);
9966 memcpy(arg
, s1
, len
);
9968 dynarray_add((void ***)&argv
, &argc
, arg
);
9974 static char **files
;
9975 static int nb_files
, nb_libraries
;
9976 static int multiple_files
;
9977 static int print_search_dirs
;
9978 static int output_type
;
9979 static int reloc_output
;
9980 static const char *outfile
;
9982 int parse_args(TCCState
*s
, int argc
, char **argv
)
9985 const TCCOption
*popt
;
9986 const char *optarg
, *p1
, *r1
;
9991 if (optind
>= argc
) {
9992 if (nb_files
== 0 && !print_search_dirs
)
9999 /* add a new file */
10000 dynarray_add((void ***)&files
, &nb_files
, r
);
10001 if (!multiple_files
) {
10003 /* argv[0] will be this file */
10007 /* find option in table (match only the first chars */
10008 popt
= tcc_options
;
10012 error("invalid option -- '%s'", r
);
10025 if (popt
->flags
& TCC_OPTION_HAS_ARG
) {
10026 if (*r1
!= '\0' || (popt
->flags
& TCC_OPTION_NOSEP
)) {
10029 if (optind
>= argc
)
10030 error("argument to '%s' is missing", r
);
10031 optarg
= argv
[optind
++];
10039 switch(popt
->index
) {
10040 case TCC_OPTION_HELP
:
10045 if (tcc_add_include_path(s
, optarg
) < 0)
10046 error("too many include paths");
10051 sym
= (char *)optarg
;
10052 value
= strchr(sym
, '=');
10057 tcc_define_symbol(s
, sym
, value
);
10061 tcc_undefine_symbol(s
, optarg
);
10064 tcc_add_library_path(s
, optarg
);
10067 /* set tcc utilities path (mainly for tcc development) */
10068 tcc_lib_path
= optarg
;
10071 dynarray_add((void ***)&files
, &nb_files
, r
);
10074 case TCC_OPTION_bench
:
10077 case TCC_OPTION_bt
:
10078 num_callers
= atoi(optarg
);
10080 #ifdef CONFIG_TCC_BCHECK
10082 do_bounds_check
= 1;
10090 multiple_files
= 1;
10091 output_type
= TCC_OUTPUT_OBJ
;
10093 case TCC_OPTION_static
:
10094 s
->static_link
= 1;
10096 case TCC_OPTION_shared
:
10097 output_type
= TCC_OUTPUT_DLL
;
10100 multiple_files
= 1;
10104 /* generate a .o merging several output files */
10106 output_type
= TCC_OUTPUT_OBJ
;
10108 case TCC_OPTION_nostdinc
:
10111 case TCC_OPTION_nostdlib
:
10114 case TCC_OPTION_print_search_dirs
:
10115 print_search_dirs
= 1;
10117 case TCC_OPTION_run
:
10121 argc1
= expand_args(&argv1
, optarg
);
10123 parse_args(s
, argc1
, argv1
);
10125 multiple_files
= 0;
10126 output_type
= TCC_OUTPUT_MEMORY
;
10130 printf("tcc version %s\n", TCC_VERSION
);
10133 if (tcc_set_flag(s
, optarg
, 1) < 0 && s
->warn_unsupported
)
10134 goto unsupported_option
;
10137 if (tcc_set_warning(s
, optarg
, 1) < 0 &&
10138 s
->warn_unsupported
)
10139 goto unsupported_option
;
10144 case TCC_OPTION_rdynamic
:
10148 if (s
->warn_unsupported
) {
10149 unsupported_option
:
10150 warning("unsupported option '%s'", r
);
10159 int main(int argc
, char **argv
)
10163 int nb_objfiles
, ret
, optind
;
10164 char objfilename
[1024];
10165 int64_t start_time
= 0;
10168 output_type
= TCC_OUTPUT_EXE
;
10170 multiple_files
= 1;
10175 print_search_dirs
= 0;
10177 optind
= parse_args(s
, argc
- 1, argv
+ 1) + 1;
10179 if (print_search_dirs
) {
10180 /* enough for Linux kernel */
10181 printf("install: %s/\n", tcc_lib_path
);
10185 nb_objfiles
= nb_files
- nb_libraries
;
10187 /* if outfile provided without other options, we output an
10189 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
10190 output_type
= TCC_OUTPUT_EXE
;
10192 /* check -c consistency : only single file handled. XXX: checks file type */
10193 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
10194 /* accepts only a single input file */
10195 if (nb_objfiles
!= 1)
10196 error("cannot specify multiple files with -c");
10197 if (nb_libraries
!= 0)
10198 error("cannot specify libraries with -c");
10201 /* compute default outfile name */
10202 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
10203 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
10206 pstrcpy(objfilename
, sizeof(objfilename
) - 1,
10207 tcc_basename(files
[0]));
10208 /* add .o extension */
10209 ext
= strrchr(objfilename
, '.');
10211 goto default_outfile
;
10212 strcpy(ext
+ 1, "o");
10215 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
10217 outfile
= objfilename
;
10221 start_time
= getclock_us();
10224 tcc_set_output_type(s
, output_type
);
10226 /* compile or add each files or library */
10227 for(i
= 0;i
< nb_files
; i
++) {
10228 const char *filename
;
10230 filename
= files
[i
];
10231 if (filename
[0] == '-') {
10232 if (tcc_add_library(s
, filename
+ 2) < 0)
10233 error("cannot find %s", filename
);
10235 if (tcc_add_file(s
, filename
) < 0) {
10242 /* free all files */
10247 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
10248 if (total_time
< 0.001)
10249 total_time
= 0.001;
10250 if (total_bytes
< 1)
10252 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
10253 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
10254 total_time
, (int)(total_lines
/ total_time
),
10255 total_bytes
/ total_time
/ 1000000.0);
10258 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
10259 tcc_output_file(s
, outfile
);
10262 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
10265 /* XXX: cannot do it with bound checking because of the malloc hooks */
10266 if (!do_bounds_check
)
10271 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);