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>
40 #include <sys/ucontext.h>
44 #ifndef CONFIG_TCC_STATIC
52 /* preprocessor debug */
54 /* include file debug */
62 /* target selection */
63 //#define TCC_TARGET_I386 /* i386 code generator */
64 //#define TCC_TARGET_ARM /* ARMv4 code generator */
65 //#define TCC_TARGET_C67 /* TMS320C67xx code generator */
67 /* default target is I386 */
68 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
69 !defined(TCC_TARGET_C67)
70 #define TCC_TARGET_I386
73 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
74 !defined(TCC_TARGET_C67)
75 #define CONFIG_TCC_BCHECK /* enable bound checking code */
78 /* define it to include assembler support */
79 #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
80 #define CONFIG_TCC_ASM
91 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
92 executables or dlls */
93 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
95 #define INCLUDE_STACK_SIZE 32
96 #define IFDEF_STACK_SIZE 64
97 #define VSTACK_SIZE 64
98 #define STRING_MAX_SIZE 1024
100 #define TOK_HASH_SIZE 2048 /* must be a power of two */
101 #define TOK_ALLOC_INCR 512 /* must be a power of two */
102 #define TOK_STR_ALLOC_INCR_BITS 6
103 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
104 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
106 /* token symbol management */
107 typedef struct TokenSym
{
108 struct TokenSym
*hash_next
;
109 struct Sym
*sym_define
; /* direct pointer to define */
110 struct Sym
*sym_label
; /* direct pointer to label */
111 struct Sym
*sym_struct
; /* direct pointer to structure */
112 struct Sym
*sym_identifier
; /* direct pointer to identifier */
113 int tok
; /* token number */
118 typedef struct CString
{
119 int size
; /* size in bytes */
120 void *data
; /* either 'char *' or 'int *' */
122 void *data_allocated
; /* if non NULL, data has been malloced */
125 /* type definition */
126 typedef struct CType
{
132 typedef union CValue
{
138 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
140 unsigned long long ull
;
141 struct CString
*cstr
;
147 typedef struct SValue
{
148 CType type
; /* type */
149 unsigned short r
; /* register + flags */
150 unsigned short r2
; /* second register, used for 'long long'
151 type. If not used, set to VT_CONST */
152 CValue c
; /* constant, if VT_CONST */
153 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
156 /* symbol management */
158 int v
; /* symbol token */
159 int r
; /* associated register */
160 int c
; /* associated number */
161 CType type
; /* associated type */
162 struct Sym
*next
; /* next related symbol */
163 struct Sym
*prev
; /* prev symbol in stack */
164 struct Sym
*prev_tok
; /* previous symbol for this token */
167 /* section definition */
168 /* XXX: use directly ELF structure for parameters ? */
169 /* special flag to indicate that the section should not be linked to
171 #define SHF_PRIVATE 0x80000000
173 typedef struct Section
{
174 unsigned long data_offset
; /* current data offset */
175 unsigned char *data
; /* section data */
176 unsigned long data_allocated
; /* used for realloc() handling */
177 int sh_name
; /* elf section name (only used during output) */
178 int sh_num
; /* elf section number */
179 int sh_type
; /* elf section type */
180 int sh_flags
; /* elf section flags */
181 int sh_info
; /* elf section info */
182 int sh_addralign
; /* elf section alignment */
183 int sh_entsize
; /* elf entry size */
184 unsigned long sh_size
; /* section size (only used during output) */
185 unsigned long sh_addr
; /* address at which the section is relocated */
186 unsigned long sh_offset
; /* address at which the section is relocated */
187 int nb_hashed_syms
; /* used to resize the hash table */
188 struct Section
*link
; /* link to another section */
189 struct Section
*reloc
; /* corresponding section for relocation, if any */
190 struct Section
*hash
; /* hash table for symbols */
191 struct Section
*next
;
192 char name
[1]; /* section name */
195 typedef struct DLLReference
{
200 /* GNUC attribute definition */
201 typedef struct AttributeDef
{
204 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
207 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
208 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
209 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
211 /* stored in 'Sym.c' field */
212 #define FUNC_NEW 1 /* ansi function prototype */
213 #define FUNC_OLD 2 /* old function prototype */
214 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
216 /* stored in 'Sym.r' field */
217 #define FUNC_CDECL 0 /* standard c call */
218 #define FUNC_STDCALL 1 /* pascal c call */
220 /* field 'Sym.t' for macros */
221 #define MACRO_OBJ 0 /* object like macro */
222 #define MACRO_FUNC 1 /* function like macro */
224 /* field 'Sym.r' for C labels */
225 #define LABEL_DEFINED 0 /* label is defined */
226 #define LABEL_FORWARD 1 /* label is forward defined */
227 #define LABEL_DECLARED 2 /* label is declared but never used */
229 /* type_decl() types */
230 #define TYPE_ABSTRACT 1 /* type without variable */
231 #define TYPE_DIRECT 2 /* type with variable */
233 #define IO_BUF_SIZE 8192
235 typedef struct BufferedFile
{
239 int line_num
; /* current line number - here to simplify code */
240 int ifndef_macro
; /* #ifndef macro / #endif search */
241 int ifndef_macro_saved
; /* saved ifndef_macro */
242 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
243 char inc_type
; /* type of include */
244 char inc_filename
[512]; /* filename specified by the user */
245 char filename
[1024]; /* current filename - here to simplify code */
246 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
249 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
250 #define CH_EOF (-1) /* end of file */
252 /* parsing state (used to save parser state to reparse part of the
253 source several times) */
254 typedef struct ParseState
{
261 /* used to record tokens */
262 typedef struct TokenString
{
269 /* include file cache, used to find files faster and also to eliminate
270 inclusion if the include file is protected by #ifndef ... #endif */
271 typedef struct CachedInclude
{
273 char type
; /* '"' or '>' to give include type */
274 char filename
[1]; /* path specified in #include */
278 static struct BufferedFile
*file
;
281 static CString tokcstr
; /* current parsed string, if any */
282 /* additional informations about token */
283 static int tok_flags
;
284 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
285 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
286 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
288 static int *macro_ptr
, *macro_ptr_allocated
;
289 static int *unget_saved_macro_ptr
;
290 static int unget_saved_buffer
[TOK_MAX_SIZE
+ 1];
291 static int unget_buffer_enabled
;
292 static int parse_flags
;
293 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
294 #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
295 #define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
296 token. line feed is also
299 static Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
300 static Section
*cur_text_section
; /* current section where function code is
302 /* bound check related sections */
303 static Section
*bounds_section
; /* contains global data bound description */
304 static Section
*lbounds_section
; /* contains local data bound description */
305 /* symbol sections */
306 static Section
*symtab_section
, *strtab_section
;
309 static Section
*stab_section
, *stabstr_section
;
311 /* loc : local variable index
312 ind : output code index
314 anon_sym: anonymous symbol index
316 static int rsym
, anon_sym
, ind
, loc
;
317 /* expression generation modifiers */
318 static int const_wanted
; /* true if constant wanted */
319 static int nocode_wanted
; /* true if no code generation wanted for an expression */
320 static int global_expr
; /* true if compound literals must be allocated
321 globally (used during initializers parsing */
322 static CType func_vt
; /* current function return type (used by return
325 static int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
326 static int tok_ident
;
327 static TokenSym
**table_ident
;
328 static TokenSym
*hash_ident
[TOK_HASH_SIZE
];
329 static char token_buf
[STRING_MAX_SIZE
+ 1];
330 static char *funcname
;
331 static Sym
*global_stack
, *local_stack
;
332 static Sym
*define_stack
;
333 static Sym
*global_label_stack
, *local_label_stack
;
335 static SValue vstack
[VSTACK_SIZE
], *vtop
;
336 /* some predefined types */
337 static CType char_pointer_type
, func_old_type
, int_type
;
338 /* true if isid(c) || isnum(c) */
339 static unsigned char isidnum_table
[256];
341 /* compile with debug symbol (and use them if error during execution) */
342 static int do_debug
= 0;
344 /* compile with built-in memory and bounds checker */
345 static int do_bounds_check
= 0;
347 /* display benchmark infos */
349 static int do_bench
= 0;
351 static int total_lines
;
352 static int total_bytes
;
354 /* use GNU C extensions */
355 static int gnu_ext
= 1;
357 /* use Tiny C extensions */
358 static int tcc_ext
= 1;
360 /* max number of callers shown if error */
361 static int num_callers
= 6;
362 static const char **rt_bound_error_msg
;
364 /* XXX: get rid of this ASAP */
365 static struct TCCState
*tcc_state
;
367 /* give the path of the tcc libraries */
368 static const char *tcc_lib_path
= CONFIG_TCC_LIBDIR
"/tcc";
373 BufferedFile
**include_stack_ptr
;
374 int *ifdef_stack_ptr
;
376 /* include file handling */
377 char **include_paths
;
378 int nb_include_paths
;
379 char **sysinclude_paths
;
380 int nb_sysinclude_paths
;
381 CachedInclude
**cached_includes
;
382 int nb_cached_includes
;
384 char **library_paths
;
385 int nb_library_paths
;
387 /* array of all loaded dlls (including those referenced by loaded
389 DLLReference
**loaded_dlls
;
394 int nb_sections
; /* number of sections, including first dummy section */
399 unsigned long *got_offsets
;
401 /* give the correspondance from symtab indexes to dynsym indexes */
402 int *symtab_to_dynsym
;
404 /* temporary dynamic symbol sections (for dll loading) */
405 Section
*dynsymtab_section
;
406 /* exported dynamic symbol section */
409 int nostdinc
; /* if true, no standard headers are added */
410 int nostdlib
; /* if true, no standard libraries are added */
412 /* if true, static linking is performed */
415 /* if true, all symbols are exported */
418 /* if true, only link in referenced objects from archive */
421 /* C language options */
422 int char_is_unsigned
;
424 /* warning switches */
425 int warn_write_strings
;
426 int warn_unsupported
;
429 int warn_implicit_function_declaration
;
433 void (*error_func
)(void *opaque
, const char *msg
);
434 int error_set_jmp_enabled
;
435 jmp_buf error_jmp_buf
;
438 /* tiny assembler state */
441 /* see include_stack_ptr */
442 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
444 /* see ifdef_stack_ptr */
445 int ifdef_stack
[IFDEF_STACK_SIZE
];
448 /* The current value can be: */
449 #define VT_VALMASK 0x00ff
450 #define VT_CONST 0x00f0 /* constant in vc
451 (must be first non register value) */
452 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
453 #define VT_LOCAL 0x00f2 /* offset on stack */
454 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
455 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
456 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
457 #define VT_LVAL 0x0100 /* var is an lvalue */
458 #define VT_SYM 0x0200 /* a symbol value is added */
459 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
460 char/short stored in integer registers) */
461 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
462 dereferencing value */
463 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
464 bounding function call point is in vc */
465 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
466 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
467 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
468 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
471 #define VT_INT 0 /* integer type */
472 #define VT_BYTE 1 /* signed byte type */
473 #define VT_SHORT 2 /* short type */
474 #define VT_VOID 3 /* void type */
475 #define VT_PTR 4 /* pointer */
476 #define VT_ENUM 5 /* enum definition */
477 #define VT_FUNC 6 /* function type */
478 #define VT_STRUCT 7 /* struct/union definition */
479 #define VT_FLOAT 8 /* IEEE float */
480 #define VT_DOUBLE 9 /* IEEE double */
481 #define VT_LDOUBLE 10 /* IEEE long double */
482 #define VT_BOOL 11 /* ISOC99 boolean type */
483 #define VT_LLONG 12 /* 64 bit integer */
484 #define VT_LONG 13 /* long integer (NEVER USED as type, only
486 #define VT_BTYPE 0x000f /* mask for basic type */
487 #define VT_UNSIGNED 0x0010 /* unsigned type */
488 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
489 #define VT_BITFIELD 0x0040 /* bitfield modifier */
490 #define VT_CONSTANT 0x0800 /* const modifier */
491 #define VT_VOLATILE 0x1000 /* volatile modifier */
492 #define VT_SIGNED 0x2000 /* signed type */
495 #define VT_EXTERN 0x00000080 /* extern definition */
496 #define VT_STATIC 0x00000100 /* static variable */
497 #define VT_TYPEDEF 0x00000200 /* typedef definition */
498 #define VT_INLINE 0x00000400 /* inline definition */
500 #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */
502 /* type mask (except storage) */
503 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
504 #define VT_TYPE (~(VT_STORAGE))
508 /* warning: the following compare tokens depend on i386 asm code */
520 #define TOK_LAND 0xa0
524 #define TOK_MID 0xa3 /* inc/dec, to void constant */
526 #define TOK_UDIV 0xb0 /* unsigned division */
527 #define TOK_UMOD 0xb1 /* unsigned modulo */
528 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
529 #define TOK_CINT 0xb3 /* number in tokc */
530 #define TOK_CCHAR 0xb4 /* char constant in tokc */
531 #define TOK_STR 0xb5 /* pointer to string in tokc */
532 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
533 #define TOK_LCHAR 0xb7
534 #define TOK_LSTR 0xb8
535 #define TOK_CFLOAT 0xb9 /* float constant */
536 #define TOK_LINENUM 0xba /* line number info */
537 #define TOK_CDOUBLE 0xc0 /* double constant */
538 #define TOK_CLDOUBLE 0xc1 /* long double constant */
539 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
540 #define TOK_ADDC1 0xc3 /* add with carry generation */
541 #define TOK_ADDC2 0xc4 /* add with carry use */
542 #define TOK_SUBC1 0xc5 /* add with carry generation */
543 #define TOK_SUBC2 0xc6 /* add with carry use */
544 #define TOK_CUINT 0xc8 /* unsigned int constant */
545 #define TOK_CLLONG 0xc9 /* long long constant */
546 #define TOK_CULLONG 0xca /* unsigned long long constant */
547 #define TOK_ARROW 0xcb
548 #define TOK_DOTS 0xcc /* three dots */
549 #define TOK_SHR 0xcd /* unsigned shift right */
550 #define TOK_PPNUM 0xce /* preprocessor number */
552 #define TOK_SHL 0x01 /* shift left */
553 #define TOK_SAR 0x02 /* signed shift right */
555 /* assignement operators : normal operator or 0x80 */
556 #define TOK_A_MOD 0xa5
557 #define TOK_A_AND 0xa6
558 #define TOK_A_MUL 0xaa
559 #define TOK_A_ADD 0xab
560 #define TOK_A_SUB 0xad
561 #define TOK_A_DIV 0xaf
562 #define TOK_A_XOR 0xde
563 #define TOK_A_OR 0xfc
564 #define TOK_A_SHL 0x81
565 #define TOK_A_SAR 0x82
568 #define offsetof(type, field) ((size_t) &((type *)0)->field)
572 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
575 /* WARNING: the content of this string encodes token numbers */
576 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";
578 #define TOK_EOF (-1) /* end of file */
579 #define TOK_LINEFEED 10 /* line feed */
581 /* all identificators and strings have token above that */
582 #define TOK_IDENT 256
584 /* only used for i386 asm opcodes definitions */
585 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
588 DEF(TOK_ASM_ ## x ## b, #x "b") \
589 DEF(TOK_ASM_ ## x ## w, #x "w") \
590 DEF(TOK_ASM_ ## x ## l, #x "l") \
591 DEF(TOK_ASM_ ## x, #x)
594 DEF(TOK_ASM_ ## x ## w, #x "w") \
595 DEF(TOK_ASM_ ## x ## l, #x "l") \
596 DEF(TOK_ASM_ ## x, #x)
599 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
600 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
601 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
602 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
605 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
606 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
609 #define DEF_ASMTEST(x) \
641 #define TOK_ASM_int TOK_INT
644 TOK_LAST
= TOK_IDENT
- 1,
645 #define DEF(id, str) id,
650 static const char tcc_keywords
[] =
651 #define DEF(id, str) str "\0"
656 #define TOK_UIDENT TOK_DEFINE
659 #define snprintf _snprintf
660 #define vsnprintf _vsnprintf
663 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
664 /* currently incorrect */
665 long double strtold(const char *nptr
, char **endptr
)
667 return (long double)strtod(nptr
, endptr
);
669 float strtof(const char *nptr
, char **endptr
)
671 return (float)strtod(nptr
, endptr
);
674 /* XXX: need to define this to use them in non ISOC99 context */
675 extern float strtof (const char *__nptr
, char **__endptr
);
676 extern long double strtold (const char *__nptr
, char **__endptr
);
679 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
680 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
682 static void next(void);
683 static void next_nomacro(void);
684 static void parse_expr_type(CType
*type
);
685 static void expr_type(CType
*type
);
686 static void unary_type(CType
*type
);
687 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
688 int case_reg
, int is_expr
);
689 static int expr_const(void);
690 static void expr_eq(void);
691 static void gexpr(void);
692 static void decl(int l
);
693 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
694 int first
, int size_only
);
695 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
696 int has_init
, int v
, int scope
);
698 void gv2(int rc1
, int rc2
);
699 void move_reg(int r
, int s
);
700 void save_regs(int n
);
701 void save_reg(int r
);
706 int get_reg_ex(int rc
,int rc2
);
708 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
709 const int *macro_str
, int can_read_stream
);
710 int save_reg_forced(int r
);
712 void force_charshort_cast(int t
);
713 static void gen_cast(CType
*type
);
715 static Sym
*sym_find(int v
);
716 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
719 static int type_size(CType
*type
, int *a
);
720 static inline CType
*pointed_type(CType
*type
);
721 static int pointed_size(CType
*type
);
722 static int lvalue_type(int t
);
723 static int parse_btype(CType
*type
, AttributeDef
*ad
);
724 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
725 static int is_compatible_types(CType
*type1
, CType
*type2
);
727 int ieee_finite(double d
);
728 void error(const char *fmt
, ...);
731 static void vpush_global_sym(CType
*type
, int v
);
732 void vset(CType
*type
, int r
, int v
);
733 void type_to_str(char *buf
, int buf_size
,
734 CType
*type
, const char *varstr
);
735 char *get_tok_str(int v
, CValue
*cv
);
736 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
737 unsigned long offset
, unsigned long size
);
738 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
740 /* section generation */
741 static void section_realloc(Section
*sec
, unsigned long new_size
);
742 static void *section_ptr_add(Section
*sec
, unsigned long size
);
743 static void put_extern_sym(Sym
*sym
, Section
*section
,
744 unsigned long value
, unsigned long size
);
745 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
746 static int put_elf_str(Section
*s
, const char *sym
);
747 static int put_elf_sym(Section
*s
,
748 unsigned long value
, unsigned long size
,
749 int info
, int other
, int shndx
, const char *name
);
750 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
751 int info
, int sh_num
, const char *name
);
752 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
753 int type
, int symbol
);
754 static void put_stabs(const char *str
, int type
, int other
, int desc
,
755 unsigned long value
);
756 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
757 unsigned long value
, Section
*sec
, int sym_index
);
758 static void put_stabn(int type
, int other
, int desc
, int value
);
759 static void put_stabd(int type
, int other
, int desc
);
760 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
762 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
763 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
764 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
768 #ifdef CONFIG_TCC_ASM
770 typedef struct ExprValue
{
775 #define MAX_ASM_OPERANDS 30
777 typedef struct ASMOperand
{
778 int id
; /* GCC 3 optionnal identifier (0 if number only supported */
780 char asm_str
[16]; /* computed asm string for operand */
781 SValue
*vt
; /* C value of the expression */
782 int ref_index
; /* if >= 0, gives reference to a output constraint */
783 int priority
; /* priority, used to assign registers */
784 int reg
; /* if >= 0, register number used for this operand */
785 int is_llong
; /* true if double register value */
788 static void asm_expr(TCCState
*s1
, ExprValue
*pe
);
789 static int asm_int_expr(TCCState
*s1
);
790 static int find_constraint(ASMOperand
*operands
, int nb_operands
,
791 const char *name
, const char **pp
);
793 static int tcc_assemble(TCCState
*s1
, int do_preprocess
);
797 static void asm_instr(void);
799 /* true if float/double/long double type */
800 static inline int is_float(int t
)
804 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
807 #ifdef TCC_TARGET_I386
808 #include "i386-gen.c"
811 #ifdef TCC_TARGET_ARM
815 #ifdef TCC_TARGET_C67
819 #ifdef CONFIG_TCC_STATIC
821 #define RTLD_LAZY 0x001
822 #define RTLD_NOW 0x002
823 #define RTLD_GLOBAL 0x100
824 #define RTLD_DEFAULT NULL
826 /* dummy function for profiling */
827 void *dlopen(const char *filename
, int flag
)
832 const char *dlerror(void)
837 typedef struct TCCSyms
{
842 #define TCCSYM(a) { #a, &a, },
844 /* add the symbol you want here if no dynamic linking is done */
845 static TCCSyms tcc_syms
[] = {
853 void *dlsym(void *handle
, const char *symbol
)
857 while (p
->str
!= NULL
) {
858 if (!strcmp(p
->str
, symbol
))
867 /********************************************************/
869 /* we use our own 'finite' function to avoid potential problems with
870 non standard math libs */
871 /* XXX: endianness dependent */
872 int ieee_finite(double d
)
875 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
878 /* copy a string and truncate it. */
879 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
886 q_end
= buf
+ buf_size
- 1;
898 /* strcat and truncate. */
899 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
904 pstrcpy(buf
+ len
, buf_size
- len
, s
);
908 /* memory management */
914 static inline void tcc_free(void *ptr
)
917 mem_cur_size
-= malloc_usable_size(ptr
);
922 static void *tcc_malloc(unsigned long size
)
927 error("memory full");
929 mem_cur_size
+= malloc_usable_size(ptr
);
930 if (mem_cur_size
> mem_max_size
)
931 mem_max_size
= mem_cur_size
;
936 static void *tcc_mallocz(unsigned long size
)
939 ptr
= tcc_malloc(size
);
940 memset(ptr
, 0, size
);
944 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
948 mem_cur_size
-= malloc_usable_size(ptr
);
950 ptr1
= realloc(ptr
, size
);
952 /* NOTE: count not correct if alloc error, but not critical */
953 mem_cur_size
+= malloc_usable_size(ptr1
);
954 if (mem_cur_size
> mem_max_size
)
955 mem_max_size
= mem_cur_size
;
960 static char *tcc_strdup(const char *str
)
963 ptr
= tcc_malloc(strlen(str
) + 1);
968 #define free(p) use_tcc_free(p)
969 #define malloc(s) use_tcc_malloc(s)
970 #define realloc(p, s) use_tcc_realloc(p, s)
972 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
979 /* every power of two we double array size */
980 if ((nb
& (nb
- 1)) == 0) {
985 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
987 error("memory full");
994 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
998 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
999 strcpy(sec
->name
, name
);
1000 sec
->sh_type
= sh_type
;
1001 sec
->sh_flags
= sh_flags
;
1008 sec
->sh_addralign
= 4;
1011 sec
->sh_addralign
= 1;
1014 sec
->sh_addralign
= 32; /* default conservative alignment */
1018 /* only add section if not private */
1019 if (!(sh_flags
& SHF_PRIVATE
)) {
1020 sec
->sh_num
= s1
->nb_sections
;
1021 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
1026 static void free_section(Section
*s
)
1032 /* realloc section and set its content to zero */
1033 static void section_realloc(Section
*sec
, unsigned long new_size
)
1036 unsigned char *data
;
1038 size
= sec
->data_allocated
;
1041 while (size
< new_size
)
1043 data
= tcc_realloc(sec
->data
, size
);
1045 error("memory full");
1046 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
1048 sec
->data_allocated
= size
;
1051 /* reserve at least 'size' bytes in section 'sec' from
1052 sec->data_offset. */
1053 static void *section_ptr_add(Section
*sec
, unsigned long size
)
1055 unsigned long offset
, offset1
;
1057 offset
= sec
->data_offset
;
1058 offset1
= offset
+ size
;
1059 if (offset1
> sec
->data_allocated
)
1060 section_realloc(sec
, offset1
);
1061 sec
->data_offset
= offset1
;
1062 return sec
->data
+ offset
;
1065 /* return a reference to a section, and create it if it does not
1067 Section
*find_section(TCCState
*s1
, const char *name
)
1071 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1072 sec
= s1
->sections
[i
];
1073 if (!strcmp(name
, sec
->name
))
1076 /* sections are created as PROGBITS */
1077 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
1080 /* update sym->c so that it points to an external symbol in section
1081 'section' with value 'value' */
1082 static void put_extern_sym(Sym
*sym
, Section
*section
,
1083 unsigned long value
, unsigned long size
)
1085 int sym_type
, sym_bind
, sh_num
, info
;
1090 sh_num
= section
->sh_num
;
1094 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
)
1095 sym_type
= STT_FUNC
;
1097 sym_type
= STT_OBJECT
;
1098 if (sym
->type
.t
& VT_STATIC
)
1099 sym_bind
= STB_LOCAL
;
1101 sym_bind
= STB_GLOBAL
;
1103 name
= get_tok_str(sym
->v
, NULL
);
1104 #ifdef CONFIG_TCC_BCHECK
1105 if (do_bounds_check
) {
1108 /* XXX: avoid doing that for statics ? */
1109 /* if bound checking is activated, we change some function
1110 names by adding the "__bound" prefix */
1113 /* XXX: we rely only on malloc hooks */
1125 strcpy(buf
, "__bound_");
1132 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
1133 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
1135 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
1136 esym
->st_value
= value
;
1137 esym
->st_size
= size
;
1138 esym
->st_shndx
= sh_num
;
1142 /* add a new relocation entry to symbol 'sym' in section 's' */
1143 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
1146 put_extern_sym(sym
, NULL
, 0, 0);
1147 /* now we can add ELF relocation info */
1148 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
1151 static inline int isid(int c
)
1153 return (c
>= 'a' && c
<= 'z') ||
1154 (c
>= 'A' && c
<= 'Z') ||
1158 static inline int isnum(int c
)
1160 return c
>= '0' && c
<= '9';
1163 static inline int isoct(int c
)
1165 return c
>= '0' && c
<= '7';
1168 static inline int toup(int c
)
1170 if (c
>= 'a' && c
<= 'z')
1171 return c
- 'a' + 'A';
1176 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1180 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1183 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1187 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1191 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1198 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1199 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1200 (*f
)->filename
, (*f
)->line_num
);
1201 if (file
->line_num
> 0) {
1202 strcat_printf(buf
, sizeof(buf
),
1203 "%s:%d: ", file
->filename
, file
->line_num
);
1205 strcat_printf(buf
, sizeof(buf
),
1206 "%s: ", file
->filename
);
1209 strcat_printf(buf
, sizeof(buf
),
1213 strcat_printf(buf
, sizeof(buf
), "warning: ");
1214 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1216 if (!s1
->error_func
) {
1217 /* default case: stderr */
1218 fprintf(stderr
, "%s\n", buf
);
1220 s1
->error_func(s1
->error_opaque
, buf
);
1222 if (!is_warning
|| s1
->warn_error
)
1227 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1228 void (*error_func
)(void *opaque
, const char *msg
))
1230 s
->error_opaque
= error_opaque
;
1231 s
->error_func
= error_func
;
1235 /* error without aborting current compilation */
1236 void error_noabort(const char *fmt
, ...)
1238 TCCState
*s1
= tcc_state
;
1242 error1(s1
, 0, fmt
, ap
);
1246 void error(const char *fmt
, ...)
1248 TCCState
*s1
= tcc_state
;
1252 error1(s1
, 0, fmt
, ap
);
1254 /* better than nothing: in some cases, we accept to handle errors */
1255 if (s1
->error_set_jmp_enabled
) {
1256 longjmp(s1
->error_jmp_buf
, 1);
1258 /* XXX: eliminate this someday */
1263 void expect(const char *msg
)
1265 error("%s expected", msg
);
1268 void warning(const char *fmt
, ...)
1270 TCCState
*s1
= tcc_state
;
1277 error1(s1
, 1, fmt
, ap
);
1284 error("'%c' expected", c
);
1288 static void test_lvalue(void)
1290 if (!(vtop
->r
& VT_LVAL
))
1294 /* allocate a new token */
1295 static TokenSym
*tok_alloc_new(TokenSym
**pts
, const char *str
, int len
)
1297 TokenSym
*ts
, **ptable
;
1300 if (tok_ident
>= SYM_FIRST_ANOM
)
1301 error("memory full");
1303 /* expand token table if needed */
1304 i
= tok_ident
- TOK_IDENT
;
1305 if ((i
% TOK_ALLOC_INCR
) == 0) {
1306 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1308 error("memory full");
1309 table_ident
= ptable
;
1312 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1313 table_ident
[i
] = ts
;
1314 ts
->tok
= tok_ident
++;
1315 ts
->sym_define
= NULL
;
1316 ts
->sym_label
= NULL
;
1317 ts
->sym_struct
= NULL
;
1318 ts
->sym_identifier
= NULL
;
1320 ts
->hash_next
= NULL
;
1321 memcpy(ts
->str
, str
, len
);
1322 ts
->str
[len
] = '\0';
1327 #define TOK_HASH_INIT 1
1328 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1330 /* find a token and add it if not found */
1331 static TokenSym
*tok_alloc(const char *str
, int len
)
1333 TokenSym
*ts
, **pts
;
1339 h
= TOK_HASH_FUNC(h
, ((unsigned char *)str
)[i
]);
1340 h
&= (TOK_HASH_SIZE
- 1);
1342 pts
= &hash_ident
[h
];
1347 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1349 pts
= &(ts
->hash_next
);
1351 return tok_alloc_new(pts
, str
, len
);
1354 /* CString handling */
1356 static void cstr_realloc(CString
*cstr
, int new_size
)
1361 size
= cstr
->size_allocated
;
1363 size
= 8; /* no need to allocate a too small first string */
1364 while (size
< new_size
)
1366 data
= tcc_realloc(cstr
->data_allocated
, size
);
1368 error("memory full");
1369 cstr
->data_allocated
= data
;
1370 cstr
->size_allocated
= size
;
1375 static void cstr_ccat(CString
*cstr
, int ch
)
1378 size
= cstr
->size
+ 1;
1379 if (size
> cstr
->size_allocated
)
1380 cstr_realloc(cstr
, size
);
1381 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1385 static void cstr_cat(CString
*cstr
, const char *str
)
1397 /* add a wide char */
1398 static void cstr_wccat(CString
*cstr
, int ch
)
1401 size
= cstr
->size
+ sizeof(int);
1402 if (size
> cstr
->size_allocated
)
1403 cstr_realloc(cstr
, size
);
1404 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1408 static void cstr_new(CString
*cstr
)
1410 memset(cstr
, 0, sizeof(CString
));
1413 /* free string and reset it to NULL */
1414 static void cstr_free(CString
*cstr
)
1416 tcc_free(cstr
->data_allocated
);
1420 #define cstr_reset(cstr) cstr_free(cstr)
1422 static CString
*cstr_dup(CString
*cstr1
)
1427 cstr
= tcc_malloc(sizeof(CString
));
1430 cstr
->size_allocated
= size
;
1431 cstr
->data_allocated
= tcc_malloc(size
);
1432 cstr
->data
= cstr
->data_allocated
;
1433 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1437 /* XXX: unicode ? */
1438 static void add_char(CString
*cstr
, int c
)
1440 if (c
== '\'' || c
== '\"' || c
== '\\') {
1441 /* XXX: could be more precise if char or string */
1442 cstr_ccat(cstr
, '\\');
1444 if (c
>= 32 && c
<= 126) {
1447 cstr_ccat(cstr
, '\\');
1449 cstr_ccat(cstr
, 'n');
1451 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1452 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1453 cstr_ccat(cstr
, '0' + (c
& 7));
1458 /* XXX: buffer overflow */
1459 /* XXX: float tokens */
1460 char *get_tok_str(int v
, CValue
*cv
)
1462 static char buf
[STRING_MAX_SIZE
+ 1];
1463 static CString cstr_buf
;
1469 /* NOTE: to go faster, we give a fixed buffer for small strings */
1470 cstr_reset(&cstr_buf
);
1471 cstr_buf
.data
= buf
;
1472 cstr_buf
.size_allocated
= sizeof(buf
);
1478 /* XXX: not quite exact, but only useful for testing */
1479 sprintf(p
, "%u", cv
->ui
);
1483 /* XXX: not quite exact, but only useful for testing */
1484 sprintf(p
, "%Lu", cv
->ull
);
1488 cstr_ccat(&cstr_buf
, '\'');
1489 add_char(&cstr_buf
, cv
->i
);
1490 cstr_ccat(&cstr_buf
, '\'');
1491 cstr_ccat(&cstr_buf
, '\0');
1495 len
= cstr
->size
- 1;
1497 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1498 cstr_ccat(&cstr_buf
, '\0');
1503 cstr_ccat(&cstr_buf
, '\"');
1505 len
= cstr
->size
- 1;
1507 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1509 len
= (cstr
->size
/ sizeof(int)) - 1;
1511 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1513 cstr_ccat(&cstr_buf
, '\"');
1514 cstr_ccat(&cstr_buf
, '\0');
1523 return strcpy(p
, "<<=");
1525 return strcpy(p
, ">>=");
1527 if (v
< TOK_IDENT
) {
1528 /* search in two bytes table */
1542 } else if (v
< tok_ident
) {
1543 return table_ident
[v
- TOK_IDENT
]->str
;
1544 } else if (v
>= SYM_FIRST_ANOM
) {
1545 /* special name for anonymous symbol */
1546 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1548 /* should never happen */
1553 return cstr_buf
.data
;
1556 /* push, without hashing */
1557 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1560 s
= tcc_malloc(sizeof(Sym
));
1571 /* find a symbol and return its associated structure. 's' is the top
1572 of the symbol stack */
1573 static Sym
*sym_find2(Sym
*s
, int v
)
1583 /* structure lookup */
1584 static inline Sym
*struct_find(int v
)
1587 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1589 return table_ident
[v
]->sym_struct
;
1592 /* find an identifier */
1593 static inline Sym
*sym_find(int v
)
1596 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1598 return table_ident
[v
]->sym_identifier
;
1601 /* push a given symbol on the symbol stack */
1602 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1611 s
= sym_push2(ps
, v
, type
->t
, c
);
1612 s
->type
.ref
= type
->ref
;
1614 /* don't record fields or anonymous symbols */
1616 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1617 /* record symbol in token array */
1618 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1620 ps
= &ts
->sym_struct
;
1622 ps
= &ts
->sym_identifier
;
1629 /* push a global identifier */
1630 static Sym
*global_identifier_push(int v
, int t
, int c
)
1633 s
= sym_push2(&global_stack
, v
, t
, c
);
1634 /* don't record anonymous symbol */
1635 if (v
< SYM_FIRST_ANOM
) {
1636 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1637 /* modify the top most local identifier, so that
1638 sym_identifier will point to 's' when popped */
1640 ps
= &(*ps
)->prev_tok
;
1647 /* pop symbols until top reaches 'b' */
1648 static void sym_pop(Sym
**ptop
, Sym
*b
)
1658 /* remove symbol in token array */
1660 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1661 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1663 ps
= &ts
->sym_struct
;
1665 ps
= &ts
->sym_identifier
;
1676 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1681 fd
= open(filename
, O_RDONLY
);
1684 bf
= tcc_malloc(sizeof(BufferedFile
));
1690 bf
->buf_ptr
= bf
->buffer
;
1691 bf
->buf_end
= bf
->buffer
;
1692 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1693 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1695 bf
->ifndef_macro
= 0;
1696 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1697 // printf("opening '%s'\n", filename);
1701 void tcc_close(BufferedFile
*bf
)
1703 total_lines
+= bf
->line_num
;
1708 /* fill input buffer and peek next char */
1709 static int tcc_peekc_slow(BufferedFile
*bf
)
1712 /* only tries to read if really end of buffer */
1713 if (bf
->buf_ptr
>= bf
->buf_end
) {
1715 #if defined(PARSE_DEBUG)
1720 len
= read(bf
->fd
, bf
->buffer
, len
);
1727 bf
->buf_ptr
= bf
->buffer
;
1728 bf
->buf_end
= bf
->buffer
+ len
;
1729 *bf
->buf_end
= CH_EOB
;
1731 if (bf
->buf_ptr
< bf
->buf_end
) {
1732 return bf
->buf_ptr
[0];
1734 bf
->buf_ptr
= bf
->buf_end
;
1739 /* return the current character, handling end of block if necessary
1741 static int handle_eob(void)
1743 return tcc_peekc_slow(file
);
1746 /* read next char from current input file and handle end of input buffer */
1747 static inline void inp(void)
1749 ch
= *(++(file
->buf_ptr
));
1750 /* end of buffer/file handling */
1755 /* handle '\[\r]\n' */
1756 static void handle_stray(void)
1758 while (ch
== '\\') {
1763 } else if (ch
== '\r') {
1771 error("stray '\\' in program");
1776 /* skip the stray and handle the \\n case. Output an error if
1777 incorrect char after the stray */
1778 static int handle_stray1(uint8_t *p
)
1782 if (p
>= file
->buf_end
) {
1799 /* handle just the EOB case, but not stray */
1800 #define PEEKC_EOB(c, p)\
1811 /* handle the complicated stray case */
1812 #define PEEKC(c, p)\
1817 c = handle_stray1(p);\
1822 /* input with '\[\r]\n' handling. Note that this function cannot
1823 handle other characters after '\', so you cannot call it inside
1824 strings or comments */
1825 static void minp(void)
1833 /* single line C++ comments */
1834 static uint8_t *parse_line_comment(uint8_t *p
)
1842 if (c
== '\n' || c
== CH_EOF
) {
1844 } else if (c
== '\\') {
1853 } else if (c
== '\r') {
1871 static uint8_t *parse_comment(uint8_t *p
)
1877 /* fast skip loop */
1880 if (c
== '\n' || c
== '*' || c
== '\\')
1884 if (c
== '\n' || c
== '*' || c
== '\\')
1888 /* now we can handle all the cases */
1892 } else if (c
== '*') {
1898 } else if (c
== '/') {
1899 goto end_of_comment
;
1900 } else if (c
== '\\') {
1905 /* skip '\[\r]\n', otherwise just skip the stray */
1911 } else if (c
== '\r') {
1928 /* stray, eob or eof */
1933 error("unexpected end of file in comment");
1934 } else if (c
== '\\') {
1946 /* space exlcuding newline */
1947 static inline int is_space(int ch
)
1949 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1952 static inline void skip_spaces(void)
1954 while (is_space(ch
))
1958 /* parse a string without interpreting escapes */
1959 static uint8_t *parse_pp_string(uint8_t *p
,
1960 int sep
, CString
*str
)
1968 } else if (c
== '\\') {
1973 unterminated_string
:
1974 /* XXX: indicate line number of start of string */
1975 error("missing terminating %c character", sep
);
1976 } else if (c
== '\\') {
1977 /* escape : just skip \[\r]\n */
1982 } else if (c
== '\r') {
1985 expect("'\n' after '\r'");
1988 } else if (c
== CH_EOF
) {
1989 goto unterminated_string
;
1992 cstr_ccat(str
, '\\');
1998 } else if (c
== '\n') {
2001 } else if (c
== '\r') {
2004 cstr_ccat(str
, '\r');
2020 /* skip block of text until #else, #elif or #endif. skip also pairs of
2022 void preprocess_skip(void)
2024 int a
, start_of_line
, c
;
2051 } else if (c
== '\\') {
2052 /* XXX: incorrect: should not give an error */
2053 ch
= file
->buf_ptr
[0];
2061 p
= parse_pp_string(p
, c
, NULL
);
2070 p
= parse_comment(p
);
2071 } else if (ch
== '/') {
2072 p
= parse_line_comment(p
);
2078 if (start_of_line
) {
2083 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
2085 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
2087 else if (tok
== TOK_ENDIF
)
2101 /* ParseState handling */
2103 /* XXX: currently, no include file info is stored. Thus, we cannot display
2104 accurate messages if the function or data definition spans multiple
2107 /* save current parse state in 's' */
2108 void save_parse_state(ParseState
*s
)
2110 s
->line_num
= file
->line_num
;
2111 s
->macro_ptr
= macro_ptr
;
2116 /* restore parse state from 's' */
2117 void restore_parse_state(ParseState
*s
)
2119 file
->line_num
= s
->line_num
;
2120 macro_ptr
= s
->macro_ptr
;
2125 /* return the number of additional 'ints' necessary to store the
2127 static inline int tok_ext_size(int t
)
2146 return LDOUBLE_SIZE
/ 4;
2152 /* token string handling */
2154 static inline void tok_str_new(TokenString
*s
)
2158 s
->allocated_len
= 0;
2159 s
->last_line_num
= -1;
2162 static void tok_str_free(int *str
)
2171 /* NOTE: we test zero separately so that GCC can generate a
2172 table for the following switch */
2187 /* XXX: use a macro to be portable on 64 bit ? */
2188 cstr
= (CString
*)p
[1];
2199 p
+= 1 + (LDOUBLE_SIZE
/ 4);
2209 static int *tok_str_realloc(TokenString
*s
)
2213 len
= s
->allocated_len
+ TOK_STR_ALLOC_INCR
;
2214 str
= tcc_realloc(s
->str
, len
* sizeof(int));
2216 error("memory full");
2217 s
->allocated_len
= len
;
2222 static void tok_str_add(TokenString
*s
, int t
)
2228 if (len
>= s
->allocated_len
)
2229 str
= tok_str_realloc(s
);
2234 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
2241 /* allocate space for worst case */
2242 if (len
+ TOK_MAX_SIZE
> s
->allocated_len
)
2243 str
= tok_str_realloc(s
);
2252 str
[len
++] = cv
->tab
[0];
2257 str
[len
++] = (int)cstr_dup(cv
->cstr
);
2262 #if LDOUBLE_SIZE == 8
2265 str
[len
++] = cv
->tab
[0];
2266 str
[len
++] = cv
->tab
[1];
2268 #if LDOUBLE_SIZE == 12
2270 str
[len
++] = cv
->tab
[0];
2271 str
[len
++] = cv
->tab
[1];
2272 str
[len
++] = cv
->tab
[2];
2273 #elif LDOUBLE_SIZE != 8
2274 #error add long double size support
2283 /* add the current parse token in token string 's' */
2284 static void tok_str_add_tok(TokenString
*s
)
2288 /* save line number info */
2289 if (file
->line_num
!= s
->last_line_num
) {
2290 s
->last_line_num
= file
->line_num
;
2291 cval
.i
= s
->last_line_num
;
2292 tok_str_add2(s
, TOK_LINENUM
, &cval
);
2294 tok_str_add2(s
, tok
, &tokc
);
2297 #if LDOUBLE_SIZE == 12
2298 #define LDOUBLE_GET(p, cv) \
2302 #elif LDOUBLE_SIZE == 8
2303 #define LDOUBLE_GET(p, cv) \
2307 #error add long double size support
2311 /* get a token from an integer array and increment pointer
2312 accordingly. we code it as a macro to avoid pointer aliasing. */
2313 #define TOK_GET(t, p, cv) \
2335 case TOK_CLDOUBLE: \
2336 LDOUBLE_GET(p, cv); \
2337 p += LDOUBLE_SIZE / 4; \
2344 /* defines handling */
2345 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
2349 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
2350 s
->next
= first_arg
;
2351 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
2354 /* undefined a define symbol. Its name is just set to zero */
2355 static void define_undef(Sym
*s
)
2359 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2360 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2364 static inline Sym
*define_find(int v
)
2367 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2369 return table_ident
[v
]->sym_define
;
2372 /* free define stack until top reaches 'b' */
2373 static void free_defines(Sym
*b
)
2381 /* do not free args or predefined defines */
2383 tok_str_free((int *)top
->c
);
2385 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2386 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2394 static Sym
*label_find(int v
)
2397 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2399 return table_ident
[v
]->sym_label
;
2402 static Sym
*label_push(Sym
**ptop
, int v
, int flags
)
2405 s
= sym_push2(ptop
, v
, 0, 0);
2407 ps
= &table_ident
[v
- TOK_IDENT
]->sym_label
;
2408 if (ptop
== &global_label_stack
) {
2409 /* modify the top most local identifier, so that
2410 sym_identifier will point to 's' when popped */
2412 ps
= &(*ps
)->prev_tok
;
2419 /* pop labels until element last is reached. Look if any labels are
2420 undefined. Define symbols if '&&label' was used. */
2421 static void label_pop(Sym
**ptop
, Sym
*slast
)
2424 for(s
= *ptop
; s
!= slast
; s
= s1
) {
2426 if (s
->r
== LABEL_DECLARED
) {
2427 warning("label '%s' declared but not used", get_tok_str(s
->v
, NULL
));
2428 } else if (s
->r
== LABEL_FORWARD
) {
2429 error("label '%s' used but not defined",
2430 get_tok_str(s
->v
, NULL
));
2433 /* define corresponding symbol. A size of
2435 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
2439 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= s
->prev_tok
;
2445 /* eval an expression for #if/#elif */
2446 static int expr_preprocess(void)
2452 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2453 next(); /* do macro subst */
2454 if (tok
== TOK_DEFINED
) {
2459 c
= define_find(tok
) != 0;
2464 } else if (tok
>= TOK_IDENT
) {
2465 /* if undefined macro */
2469 tok_str_add_tok(&str
);
2471 tok_str_add(&str
, -1); /* simulate end of file */
2472 tok_str_add(&str
, 0);
2473 /* now evaluate C constant expression */
2474 macro_ptr
= str
.str
;
2478 tok_str_free(str
.str
);
2482 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2483 static void tok_print(int *str
)
2489 TOK_GET(t
, str
, cval
);
2492 printf(" %s", get_tok_str(t
, &cval
));
2498 /* parse after #define */
2499 static void parse_define(void)
2501 Sym
*s
, *first
, **ps
;
2502 int v
, t
, varg
, is_vaargs
, c
;
2507 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2508 /* XXX: should check if same macro (ANSI) */
2511 /* '(' must be just after macro definition for MACRO_FUNC */
2512 c
= file
->buf_ptr
[0];
2514 c
= handle_stray1(file
->buf_ptr
);
2519 while (tok
!= ')') {
2523 if (varg
== TOK_DOTS
) {
2524 varg
= TOK___VA_ARGS__
;
2526 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2530 if (varg
< TOK_IDENT
)
2531 error("badly punctuated parameter list");
2532 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2543 /* EOF testing necessary for '-D' handling */
2544 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2545 tok_str_add2(&str
, tok
, &tokc
);
2548 tok_str_add(&str
, 0);
2550 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2553 define_push(v
, t
, str
.str
, first
);
2556 /* XXX: use a token or a hash table to accelerate matching ? */
2557 static CachedInclude
*search_cached_include(TCCState
*s1
,
2558 int type
, const char *filename
)
2563 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
2564 e
= s1
->cached_includes
[i
];
2565 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2571 static inline void add_cached_include(TCCState
*s1
, int type
,
2572 const char *filename
, int ifndef_macro
)
2576 if (search_cached_include(s1
, type
, filename
))
2579 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2581 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2585 strcpy(e
->filename
, filename
);
2586 e
->ifndef_macro
= ifndef_macro
;
2587 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2590 /* is_bof is true if first non space token at beginning of file */
2591 static void preprocess(int is_bof
)
2593 TCCState
*s1
= tcc_state
;
2594 int size
, i
, c
, n
, saved_parse_flags
;
2595 char buf
[1024], *q
, *p
;
2601 saved_parse_flags
= parse_flags
;
2602 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
|
2603 PARSE_FLAG_LINEFEED
;
2613 s
= define_find(tok
);
2614 /* undefine symbol by putting an invalid name */
2619 ch
= file
->buf_ptr
[0];
2620 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2625 } else if (ch
== '\"') {
2628 /* XXX: better stray handling */
2631 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2632 if ((q
- buf
) < sizeof(buf
) - 1)
2639 /* eat all spaces and comments after include */
2640 /* XXX: slightly incorrect */
2641 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2645 /* computed #include : either we have only strings or
2646 we have anything enclosed in '<>' */
2649 if (tok
== TOK_STR
) {
2650 while (tok
!= TOK_LINEFEED
) {
2651 if (tok
!= TOK_STR
) {
2653 error("'#include' expects \"FILENAME\" or <FILENAME>");
2655 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2661 while (tok
!= TOK_LINEFEED
) {
2662 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2666 /* check syntax and remove '<>' */
2667 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2668 goto include_syntax
;
2669 memmove(buf
, buf
+ 1, len
- 2);
2670 buf
[len
- 2] = '\0';
2675 e
= search_cached_include(s1
, c
, buf
);
2676 if (e
&& define_find(e
->ifndef_macro
)) {
2677 /* no need to parse the include because the 'ifndef macro'
2680 printf("%s: skipping %s\n", file
->filename
, buf
);
2684 /* first search in current dir if "header.h" */
2686 p
= strrchr(file
->filename
, '/');
2688 size
= p
+ 1 - file
->filename
;
2689 if (size
> sizeof(buf1
) - 1)
2690 size
= sizeof(buf1
) - 1;
2691 memcpy(buf1
, file
->filename
, size
);
2693 pstrcat(buf1
, sizeof(buf1
), buf
);
2694 f
= tcc_open(s1
, buf1
);
2698 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2699 error("#include recursion too deep");
2700 /* now search in all the include paths */
2701 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2702 for(i
= 0; i
< n
; i
++) {
2704 if (i
< s1
->nb_include_paths
)
2705 path
= s1
->include_paths
[i
];
2707 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2708 pstrcpy(buf1
, sizeof(buf1
), path
);
2709 pstrcat(buf1
, sizeof(buf1
), "/");
2710 pstrcat(buf1
, sizeof(buf1
), buf
);
2711 f
= tcc_open(s1
, buf1
);
2715 error("include file '%s' not found", buf
);
2719 printf("%s: including %s\n", file
->filename
, buf1
);
2722 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2723 /* push current file in stack */
2724 /* XXX: fix current line init */
2725 *s1
->include_stack_ptr
++ = file
;
2727 /* add include file debug info */
2729 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2731 tok_flags
|= TOK_FLAG_BOF
| TOK_FLAG_BOL
;
2732 ch
= file
->buf_ptr
[0];
2740 c
= expr_preprocess();
2746 if (tok
< TOK_IDENT
)
2747 error("invalid argument for '#if%sdef'", c
? "n" : "");
2751 printf("#ifndef %s\n", get_tok_str(tok
, NULL
));
2753 file
->ifndef_macro
= tok
;
2756 c
= (define_find(tok
) != 0) ^ c
;
2758 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2759 error("memory full");
2760 *s1
->ifdef_stack_ptr
++ = c
;
2763 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2764 error("#else without matching #if");
2765 if (s1
->ifdef_stack_ptr
[-1] & 2)
2766 error("#else after #else");
2767 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2770 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2771 error("#elif without matching #if");
2772 c
= s1
->ifdef_stack_ptr
[-1];
2774 error("#elif after #else");
2775 /* last #if/#elif expression was true: we skip */
2778 c
= expr_preprocess();
2779 s1
->ifdef_stack_ptr
[-1] = c
;
2789 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2790 error("#endif without matching #if");
2791 s1
->ifdef_stack_ptr
--;
2792 /* '#ifndef macro' was at the start of file. Now we check if
2793 an '#endif' is exactly at the end of file */
2794 if (file
->ifndef_macro
&&
2795 s1
->ifdef_stack_ptr
== file
->ifdef_stack_ptr
) {
2796 file
->ifndef_macro_saved
= file
->ifndef_macro
;
2797 /* need to set to zero to avoid false matches if another
2798 #ifndef at middle of file */
2799 file
->ifndef_macro
= 0;
2800 while (tok
!= TOK_LINEFEED
)
2802 tok_flags
|= TOK_FLAG_ENDIF
;
2808 if (tok
!= TOK_CINT
)
2810 file
->line_num
= tokc
.i
- 1; /* the line number will be incremented after */
2812 if (tok
!= TOK_LINEFEED
) {
2815 pstrcpy(file
->filename
, sizeof(file
->filename
),
2816 (char *)tokc
.cstr
->data
);
2822 ch
= file
->buf_ptr
[0];
2825 while (ch
!= '\n' && ch
!= CH_EOF
) {
2826 if ((q
- buf
) < sizeof(buf
) - 1)
2832 error("#error %s", buf
);
2834 warning("#warning %s", buf
);
2840 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
2841 /* '!' is ignored to allow C scripts. numbers are ignored
2842 to emulate cpp behaviour */
2844 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
2848 /* ignore other preprocess commands or #! for C scripts */
2849 while (tok
!= TOK_LINEFEED
)
2852 parse_flags
= saved_parse_flags
;
2855 /* evaluate escape codes in a string. */
2856 static void parse_escape_string(CString
*outstr
, const uint8_t *buf
, int is_long
)
2871 case '0': case '1': case '2': case '3':
2872 case '4': case '5': case '6': case '7':
2873 /* at most three octal digits */
2878 n
= n
* 8 + c
- '0';
2882 n
= n
* 8 + c
- '0';
2887 goto add_char_nonext
;
2893 if (c
>= 'a' && c
<= 'f')
2895 else if (c
>= 'A' && c
<= 'F')
2905 goto add_char_nonext
;
2929 goto invalid_escape
;
2939 if (c
>= '!' && c
<= '~')
2940 warning("unknown escape sequence: \'\\%c\'", c
);
2942 warning("unknown escape sequence: \'\\x%x\'", c
);
2949 cstr_ccat(outstr
, c
);
2951 cstr_wccat(outstr
, c
);
2953 /* add a trailing '\0' */
2955 cstr_ccat(outstr
, '\0');
2957 cstr_wccat(outstr
, '\0');
2960 /* we use 64 bit numbers */
2963 /* bn = (bn << shift) | or_val */
2964 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2968 for(i
=0;i
<BN_SIZE
;i
++) {
2970 bn
[i
] = (v
<< shift
) | or_val
;
2971 or_val
= v
>> (32 - shift
);
2975 void bn_zero(unsigned int *bn
)
2978 for(i
=0;i
<BN_SIZE
;i
++) {
2983 /* parse number in null terminated string 'p' and return it in the
2985 void parse_number(const char *p
)
2987 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
2989 unsigned int bn
[BN_SIZE
];
3000 goto float_frac_parse
;
3001 } else if (t
== '0') {
3002 if (ch
== 'x' || ch
== 'X') {
3006 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
3012 /* parse all digits. cannot check octal numbers at this stage
3013 because of floating point constants */
3015 if (ch
>= 'a' && ch
<= 'f')
3017 else if (ch
>= 'A' && ch
<= 'F')
3025 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
3027 error("number too long");
3033 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
3034 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
3036 /* NOTE: strtox should support that for hexa numbers, but
3037 non ISOC99 libcs do not support it, so we prefer to do
3039 /* hexadecimal or binary floats */
3040 /* XXX: handle overflows */
3052 } else if (t
>= 'a') {
3054 } else if (t
>= 'A') {
3059 bn_lshift(bn
, shift
, t
);
3066 if (t
>= 'a' && t
<= 'f') {
3068 } else if (t
>= 'A' && t
<= 'F') {
3070 } else if (t
>= '0' && t
<= '9') {
3076 error("invalid digit");
3077 bn_lshift(bn
, shift
, t
);
3082 if (ch
!= 'p' && ch
!= 'P')
3089 } else if (ch
== '-') {
3093 if (ch
< '0' || ch
> '9')
3094 expect("exponent digits");
3095 while (ch
>= '0' && ch
<= '9') {
3096 exp_val
= exp_val
* 10 + ch
- '0';
3099 exp_val
= exp_val
* s
;
3101 /* now we can generate the number */
3102 /* XXX: should patch directly float number */
3103 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
3104 d
= ldexp(d
, exp_val
- frac_bits
);
3109 /* float : should handle overflow */
3111 } else if (t
== 'L') {
3114 /* XXX: not large enough */
3115 tokc
.ld
= (long double)d
;
3121 /* decimal floats */
3123 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3128 while (ch
>= '0' && ch
<= '9') {
3129 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3135 if (ch
== 'e' || ch
== 'E') {
3136 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3140 if (ch
== '-' || ch
== '+') {
3141 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3146 if (ch
< '0' || ch
> '9')
3147 expect("exponent digits");
3148 while (ch
>= '0' && ch
<= '9') {
3149 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3161 tokc
.f
= strtof(token_buf
, NULL
);
3162 } else if (t
== 'L') {
3165 tokc
.ld
= strtold(token_buf
, NULL
);
3168 tokc
.d
= strtod(token_buf
, NULL
);
3172 unsigned long long n
, n1
;
3175 /* integer number */
3178 if (b
== 10 && *q
== '0') {
3185 /* no need for checks except for base 10 / 8 errors */
3188 } else if (t
>= 'a') {
3190 } else if (t
>= 'A') {
3195 error("invalid digit");
3199 /* detect overflow */
3200 /* XXX: this test is not reliable */
3202 error("integer constant overflow");
3205 /* XXX: not exactly ANSI compliant */
3206 if ((n
& 0xffffffff00000000LL
) != 0) {
3211 } else if (n
> 0x7fffffff) {
3222 error("three 'l's in integer constant");
3225 if (tok
== TOK_CINT
)
3227 else if (tok
== TOK_CUINT
)
3231 } else if (t
== 'U') {
3233 error("two 'u's in integer constant");
3235 if (tok
== TOK_CINT
)
3237 else if (tok
== TOK_CLLONG
)
3244 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
3252 #define PARSE2(c1, tok1, c2, tok2) \
3263 /* return next token without macro substitution */
3264 static inline void next_nomacro1(void)
3284 /* first look if it is in fact an end of buffer */
3285 if (p
>= file
->buf_end
) {
3289 if (p
>= file
->buf_end
)
3302 TCCState
*s1
= tcc_state
;
3303 if (parse_flags
& PARSE_FLAG_LINEFEED
) {
3305 } else if (s1
->include_stack_ptr
== s1
->include_stack
||
3306 !(parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3307 /* no include left : end of file. */
3310 /* pop include file */
3312 /* test if previous '#endif' was after a #ifdef at
3314 if (tok_flags
& TOK_FLAG_ENDIF
) {
3316 printf("#endif %s\n", get_tok_str(file
->ifndef_macro_saved
, NULL
));
3318 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
3319 file
->ifndef_macro_saved
);
3322 /* add end of include file debug info */
3324 put_stabd(N_EINCL
, 0, 0);
3326 /* pop include stack */
3328 s1
->include_stack_ptr
--;
3329 file
= *s1
->include_stack_ptr
;
3337 if (parse_flags
& PARSE_FLAG_LINEFEED
) {
3341 tok_flags
|= TOK_FLAG_BOL
;
3350 if ((tok_flags
& TOK_FLAG_BOL
) &&
3351 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3353 preprocess(tok_flags
& TOK_FLAG_BOF
);
3359 tok
= TOK_TWOSHARPS
;
3366 case 'a': case 'b': case 'c': case 'd':
3367 case 'e': case 'f': case 'g': case 'h':
3368 case 'i': case 'j': case 'k': case 'l':
3369 case 'm': case 'n': case 'o': case 'p':
3370 case 'q': case 'r': case 's': case 't':
3371 case 'u': case 'v': case 'w': case 'x':
3373 case 'A': case 'B': case 'C': case 'D':
3374 case 'E': case 'F': case 'G': case 'H':
3375 case 'I': case 'J': case 'K':
3376 case 'M': case 'N': case 'O': case 'P':
3377 case 'Q': case 'R': case 'S': case 'T':
3378 case 'U': case 'V': case 'W': case 'X':
3384 h
= TOK_HASH_FUNC(h
, c
);
3388 if (!isidnum_table
[c
])
3390 h
= TOK_HASH_FUNC(h
, c
);
3397 /* fast case : no stray found, so we have the full token
3398 and we have already hashed it */
3400 h
&= (TOK_HASH_SIZE
- 1);
3401 pts
= &hash_ident
[h
];
3406 if (ts
->len
== len
&& !memcmp(ts
->str
, p1
, len
))
3408 pts
= &(ts
->hash_next
);
3410 ts
= tok_alloc_new(pts
, p1
, len
);
3414 cstr_reset(&tokcstr
);
3417 cstr_ccat(&tokcstr
, *p1
);
3423 while (isidnum_table
[c
]) {
3424 cstr_ccat(&tokcstr
, c
);
3427 ts
= tok_alloc(tokcstr
.data
, tokcstr
.size
);
3433 if (t
!= '\\' && t
!= '\'' && t
!= '\"') {
3435 goto parse_ident_fast
;
3438 if (c
== '\'' || c
== '\"') {
3442 cstr_reset(&tokcstr
);
3443 cstr_ccat(&tokcstr
, 'L');
3444 goto parse_ident_slow
;
3448 case '0': case '1': case '2': case '3':
3449 case '4': case '5': case '6': case '7':
3452 cstr_reset(&tokcstr
);
3453 /* after the first digit, accept digits, alpha, '.' or sign if
3454 prefixed by 'eEpP' */
3458 cstr_ccat(&tokcstr
, c
);
3460 if (!(isnum(c
) || isid(c
) || c
== '.' ||
3461 ((c
== '+' || c
== '-') &&
3462 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
3465 /* We add a trailing '\0' to ease parsing */
3466 cstr_ccat(&tokcstr
, '\0');
3467 tokc
.cstr
= &tokcstr
;
3471 /* special dot handling because it can also start a number */
3474 cstr_reset(&tokcstr
);
3475 cstr_ccat(&tokcstr
, '.');
3477 } else if (c
== '.') {
3497 /* parse the string */
3499 p
= parse_pp_string(p
, sep
, &str
);
3500 cstr_ccat(&str
, '\0');
3502 /* eval the escape (should be done as TOK_PPNUM) */
3503 cstr_reset(&tokcstr
);
3504 parse_escape_string(&tokcstr
, str
.data
, is_long
);
3509 /* XXX: make it portable */
3513 char_size
= sizeof(int);
3514 if (tokcstr
.size
<= char_size
)
3515 error("empty character constant");
3516 if (tokcstr
.size
> 2 * char_size
)
3517 warning("multi-character character constant");
3519 tokc
.i
= *(int8_t *)tokcstr
.data
;
3522 tokc
.i
= *(int *)tokcstr
.data
;
3526 tokc
.cstr
= &tokcstr
;
3540 } else if (c
== '<') {
3558 } else if (c
== '>') {
3576 } else if (c
== '=') {
3589 } else if (c
== '=') {
3602 } else if (c
== '=') {
3615 } else if (c
== '=') {
3618 } else if (c
== '>') {
3626 PARSE2('!', '!', '=', TOK_NE
)
3627 PARSE2('=', '=', '=', TOK_EQ
)
3628 PARSE2('*', '*', '=', TOK_A_MUL
)
3629 PARSE2('%', '%', '=', TOK_A_MOD
)
3630 PARSE2('^', '^', '=', TOK_A_XOR
)
3632 /* comments or operator */
3636 p
= parse_comment(p
);
3638 } else if (c
== '/') {
3639 p
= parse_line_comment(p
);
3641 } else if (c
== '=') {
3661 case '$': /* only used in assembler */
3666 error("unrecognized character \\x%02x", c
);
3671 #if defined(PARSE_DEBUG)
3672 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3676 /* return next token without macro substitution. Can read input from
3678 static void next_nomacro(void)
3684 TOK_GET(tok
, macro_ptr
, tokc
);
3685 if (tok
== TOK_LINENUM
) {
3686 file
->line_num
= tokc
.i
;
3695 /* substitute args in macro_str and return allocated string */
3696 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
3698 int *st
, last_tok
, t
, notfirst
;
3707 TOK_GET(t
, macro_str
, cval
);
3712 TOK_GET(t
, macro_str
, cval
);
3715 s
= sym_find2(args
, t
);
3722 cstr_ccat(&cstr
, ' ');
3723 TOK_GET(t
, st
, cval
);
3724 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
3727 cstr_ccat(&cstr
, '\0');
3729 printf("stringize: %s\n", (char *)cstr
.data
);
3733 tok_str_add2(&str
, TOK_STR
, &cval
);
3736 tok_str_add2(&str
, t
, &cval
);
3738 } else if (t
>= TOK_IDENT
) {
3739 s
= sym_find2(args
, t
);
3742 /* if '##' is present before or after, no arg substitution */
3743 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
3744 /* special case for var arg macros : ## eats the
3745 ',' if empty VA_ARGS variable. */
3746 /* XXX: test of the ',' is not 100%
3747 reliable. should fix it to avoid security
3749 if (gnu_ext
&& s
->type
.t
&&
3750 last_tok
== TOK_TWOSHARPS
&&
3751 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
3753 /* suppress ',' '##' */
3756 /* suppress '##' and add variable */
3764 TOK_GET(t1
, st
, cval
);
3767 tok_str_add2(&str
, t1
, &cval
);
3771 /* NOTE: the stream cannot be read when macro
3772 substituing an argument */
3773 macro_subst(&str
, nested_list
, st
, 0);
3776 tok_str_add(&str
, t
);
3779 tok_str_add2(&str
, t
, &cval
);
3783 tok_str_add(&str
, 0);
3787 static char const ab_month_name
[12][4] =
3789 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
3790 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
3793 /* do macro substitution of current token with macro 's' and add
3794 result to (tok_str,tok_len). 'nested_list' is the list of all
3795 macros we got inside to avoid recursing. Return non zero if no
3796 substitution needs to be done */
3797 static int macro_subst_tok(TokenString
*tok_str
,
3798 Sym
**nested_list
, Sym
*s
, int can_read_stream
)
3800 Sym
*args
, *sa
, *sa1
;
3801 int mstr_allocated
, parlevel
, *mstr
, t
;
3807 /* if symbol is a macro, prepare substitution */
3809 /* special macros */
3810 if (tok
== TOK___LINE__
) {
3811 cval
.i
= file
->line_num
;
3812 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
3813 } else if (tok
== TOK___FILE__
) {
3814 cstrval
= file
->filename
;
3816 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3817 } else if (tok
== TOK___DATE__
|| tok
== TOK___TIME__
) {
3823 tm
= localtime(&ti
);
3824 if (tok
== TOK___DATE__
) {
3825 snprintf(buf
, sizeof(buf
), "%s %2d %d",
3826 ab_month_name
[tm
->tm_mon
], tm
->tm_mday
, tm
->tm_year
+ 1900);
3828 snprintf(buf
, sizeof(buf
), "%02d:%02d:%02d",
3829 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
3834 cstr_cat(&cstr
, cstrval
);
3835 cstr_ccat(&cstr
, '\0');
3837 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3842 if (s
->type
.t
== MACRO_FUNC
) {
3843 /* NOTE: we do not use next_nomacro to avoid eating the
3844 next token. XXX: find better solution */
3847 if (t
== 0 && can_read_stream
) {
3848 /* end of macro stream: we must look at the token
3849 after in the file */
3855 /* XXX: incorrect with comments */
3856 ch
= file
->buf_ptr
[0];
3857 while (is_space(ch
) || ch
== '\n')
3861 if (t
!= '(') /* no macro subst */
3864 /* argument macro */
3869 /* NOTE: empty args are allowed, except if no args */
3871 /* handle '()' case */
3872 if (!args
&& !sa
&& tok
== ')')
3875 error("macro '%s' used with too many args",
3876 get_tok_str(s
->v
, 0));
3879 /* NOTE: non zero sa->t indicates VA_ARGS */
3880 while ((parlevel
> 0 ||
3882 (tok
!= ',' || sa
->type
.t
))) &&
3886 else if (tok
== ')')
3888 tok_str_add2(&str
, tok
, &tokc
);
3891 tok_str_add(&str
, 0);
3892 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
3895 /* special case for gcc var args: add an empty
3896 var arg argument if it is omitted */
3897 if (sa
&& sa
->type
.t
&& gnu_ext
)
3907 error("macro '%s' used with too few args",
3908 get_tok_str(s
->v
, 0));
3911 /* now subst each arg */
3912 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3917 tok_str_free((int *)sa
->c
);
3923 sym_push2(nested_list
, s
->v
, 0, 0);
3924 macro_subst(tok_str
, nested_list
, mstr
, 1);
3925 /* pop nested defined symbol */
3927 *nested_list
= sa1
->prev
;
3935 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
3936 return the resulting string (which must be freed). */
3937 static inline int *macro_twosharps(const int *macro_str
)
3940 const int *macro_ptr1
, *start_macro_ptr
, *ptr
, *saved_macro_ptr
;
3942 const char *p1
, *p2
;
3944 TokenString macro_str1
;
3947 start_macro_ptr
= macro_str
;
3948 /* we search the first '##' */
3950 macro_ptr1
= macro_str
;
3951 TOK_GET(t
, macro_str
, cval
);
3952 /* nothing more to do if end of string */
3955 if (*macro_str
== TOK_TWOSHARPS
)
3959 /* we saw '##', so we need more processing to handle it */
3961 tok_str_new(¯o_str1
);
3965 /* add all tokens seen so far */
3966 for(ptr
= start_macro_ptr
; ptr
< macro_ptr1
;) {
3967 TOK_GET(t
, ptr
, cval
);
3968 tok_str_add2(¯o_str1
, t
, &cval
);
3970 saved_macro_ptr
= macro_ptr
;
3971 /* XXX: get rid of the use of macro_ptr here */
3972 macro_ptr
= (int *)macro_str
;
3974 while (*macro_ptr
== TOK_TWOSHARPS
) {
3976 macro_ptr1
= macro_ptr
;
3979 TOK_GET(t
, macro_ptr
, cval
);
3980 /* We concatenate the two tokens if we have an
3981 identifier or a preprocessing number */
3983 p1
= get_tok_str(tok
, &tokc
);
3984 cstr_cat(&cstr
, p1
);
3985 p2
= get_tok_str(t
, &cval
);
3986 cstr_cat(&cstr
, p2
);
3987 cstr_ccat(&cstr
, '\0');
3989 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
3990 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
3991 if (tok
== TOK_PPNUM
) {
3992 /* if number, then create a number token */
3993 /* NOTE: no need to allocate because
3994 tok_str_add2() does it */
3997 /* if identifier, we must do a test to
3998 validate we have a correct identifier */
3999 if (t
== TOK_PPNUM
) {
4009 if (!isnum(c
) && !isid(c
))
4013 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
4014 tok
= ts
->tok
; /* modify current token */
4017 const char *str
= cstr
.data
;
4018 const unsigned char *q
;
4020 /* we look for a valid token */
4021 /* XXX: do more extensive checks */
4022 if (!strcmp(str
, ">>=")) {
4024 } else if (!strcmp(str
, "<<=")) {
4026 } else if (strlen(str
) == 2) {
4027 /* search in two bytes table */
4032 if (q
[0] == str
[0] && q
[1] == str
[1])
4039 /* NOTE: because get_tok_str use a static buffer,
4042 p1
= get_tok_str(tok
, &tokc
);
4043 cstr_cat(&cstr
, p1
);
4044 cstr_ccat(&cstr
, '\0');
4045 p2
= get_tok_str(t
, &cval
);
4046 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
4047 /* cannot merge tokens: just add them separately */
4048 tok_str_add2(¯o_str1
, tok
, &tokc
);
4049 /* XXX: free associated memory ? */
4056 tok_str_add2(¯o_str1
, tok
, &tokc
);
4061 macro_ptr
= (int *)saved_macro_ptr
;
4063 tok_str_add(¯o_str1
, 0);
4064 return macro_str1
.str
;
4068 /* do macro substitution of macro_str and add result to
4069 (tok_str,tok_len). 'nested_list' is the list of all macros we got
4070 inside to avoid recursing. */
4071 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
4072 const int *macro_str
, int can_read_stream
)
4075 int *saved_macro_ptr
, *macro_str1
;
4080 /* first scan for '##' operator handling */
4082 macro_str1
= macro_twosharps(ptr
);
4086 /* NOTE: ptr == NULL can only happen if tokens are read from
4087 file stream due to a macro function call */
4090 TOK_GET(t
, ptr
, cval
);
4095 /* if nested substitution, do nothing */
4096 if (sym_find2(*nested_list
, t
))
4098 saved_macro_ptr
= macro_ptr
;
4099 macro_ptr
= (int *)ptr
;
4101 ret
= macro_subst_tok(tok_str
, nested_list
, s
, can_read_stream
);
4102 ptr
= (int *)macro_ptr
;
4103 macro_ptr
= saved_macro_ptr
;
4108 tok_str_add2(tok_str
, t
, &cval
);
4112 tok_str_free(macro_str1
);
4115 /* return next token with macro substitution */
4116 static void next(void)
4118 Sym
*nested_list
, *s
;
4124 /* if not reading from macro substituted string, then try
4125 to substitute macros */
4126 if (tok
>= TOK_IDENT
&&
4127 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
4128 s
= define_find(tok
);
4130 /* we have a macro: we try to substitute */
4133 if (macro_subst_tok(&str
, &nested_list
, s
, 1) == 0) {
4134 /* substitution done, NOTE: maybe empty */
4135 tok_str_add(&str
, 0);
4136 macro_ptr
= str
.str
;
4137 macro_ptr_allocated
= str
.str
;
4144 /* end of macro or end of unget buffer */
4145 if (unget_buffer_enabled
) {
4146 macro_ptr
= unget_saved_macro_ptr
;
4147 unget_buffer_enabled
= 0;
4149 /* end of macro string: free it */
4150 tok_str_free(macro_ptr_allocated
);
4157 /* convert preprocessor tokens into C tokens */
4158 if (tok
== TOK_PPNUM
&&
4159 (parse_flags
& PARSE_FLAG_TOK_NUM
)) {
4160 parse_number((char *)tokc
.cstr
->data
);
4164 /* push back current token and set current token to 'last_tok'. Only
4165 identifier case handled for labels. */
4166 static inline void unget_tok(int last_tok
)
4170 unget_saved_macro_ptr
= macro_ptr
;
4171 unget_buffer_enabled
= 1;
4172 q
= unget_saved_buffer
;
4175 n
= tok_ext_size(tok
) - 1;
4178 *q
= 0; /* end of token string */
4183 void swap(int *p
, int *q
)
4191 void vsetc(CType
*type
, int r
, CValue
*vc
)
4195 if (vtop
>= vstack
+ VSTACK_SIZE
)
4196 error("memory full");
4197 /* cannot let cpu flags if other instruction are generated. Also
4198 avoid leaving VT_JMP anywhere except on the top of the stack
4199 because it would complicate the code generator. */
4200 if (vtop
>= vstack
) {
4201 v
= vtop
->r
& VT_VALMASK
;
4202 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
4208 vtop
->r2
= VT_CONST
;
4212 /* push integer constant */
4217 vsetc(&int_type
, VT_CONST
, &cval
);
4220 /* Return a static symbol pointing to a section */
4221 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
4222 unsigned long offset
, unsigned long size
)
4228 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
4229 sym
->type
.ref
= type
->ref
;
4230 sym
->r
= VT_CONST
| VT_SYM
;
4231 put_extern_sym(sym
, sec
, offset
, size
);
4235 /* push a reference to a section offset by adding a dummy symbol */
4236 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
4241 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4242 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
4245 /* define a new external reference to a symbol 'v' of type 'u' */
4246 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
4252 /* push forward reference */
4253 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
4254 s
->type
.ref
= type
->ref
;
4255 s
->r
= r
| VT_CONST
| VT_SYM
;
4260 /* define a new external reference to a symbol 'v' of type 'u' */
4261 static Sym
*external_sym(int v
, CType
*type
, int r
)
4267 /* push forward reference */
4268 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
4269 s
->type
.t
|= VT_EXTERN
;
4271 if (!is_compatible_types(&s
->type
, type
))
4272 error("incompatible types for redefinition of '%s'",
4273 get_tok_str(v
, NULL
));
4278 /* push a reference to global symbol v */
4279 static void vpush_global_sym(CType
*type
, int v
)
4284 sym
= external_global_sym(v
, type
, 0);
4286 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4290 void vset(CType
*type
, int r
, int v
)
4295 vsetc(type
, r
, &cval
);
4298 void vseti(int r
, int v
)
4314 void vpushv(SValue
*v
)
4316 if (vtop
>= vstack
+ VSTACK_SIZE
)
4317 error("memory full");
4327 /* save r to the memory stack, and mark it as being free */
4328 void save_reg(int r
)
4330 int l
, saved
, size
, align
;
4334 /* modify all stack values */
4337 for(p
=vstack
;p
<=vtop
;p
++) {
4338 if ((p
->r
& VT_VALMASK
) == r
||
4339 (p
->r2
& VT_VALMASK
) == r
) {
4340 /* must save value on stack if not already done */
4342 /* NOTE: must reload 'r' because r might be equal to r2 */
4343 r
= p
->r
& VT_VALMASK
;
4344 /* store register in the stack */
4346 if ((p
->r
& VT_LVAL
) ||
4347 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
4349 size
= type_size(type
, &align
);
4350 loc
= (loc
- size
) & -align
;
4351 sv
.type
.t
= type
->t
;
4352 sv
.r
= VT_LOCAL
| VT_LVAL
;
4355 #ifdef TCC_TARGET_I386
4356 /* x86 specific: need to pop fp register ST0 if saved */
4357 if (r
== TREG_ST0
) {
4358 o(0xd9dd); /* fstp %st(1) */
4361 /* special long long case */
4362 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
4369 /* mark that stack entry as being saved on the stack */
4370 if (p
->r
& VT_LVAL
) {
4371 /* also clear the bounded flag because the
4372 relocation address of the function was stored in
4374 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
4376 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
4384 /* find a register of class 'rc2' with at most one reference on stack.
4385 * If none, call get_reg(rc) */
4386 int get_reg_ex(int rc
, int rc2
)
4391 for(r
=0;r
<NB_REGS
;r
++) {
4392 if (reg_classes
[r
] & rc2
) {
4395 for(p
= vstack
; p
<= vtop
; p
++) {
4396 if ((p
->r
& VT_VALMASK
) == r
||
4397 (p
->r2
& VT_VALMASK
) == r
)
4407 /* find a free register of class 'rc'. If none, save one register */
4413 /* find a free register */
4414 for(r
=0;r
<NB_REGS
;r
++) {
4415 if (reg_classes
[r
] & rc
) {
4416 for(p
=vstack
;p
<=vtop
;p
++) {
4417 if ((p
->r
& VT_VALMASK
) == r
||
4418 (p
->r2
& VT_VALMASK
) == r
)
4426 /* no register left : free the first one on the stack (VERY
4427 IMPORTANT to start from the bottom to ensure that we don't
4428 spill registers used in gen_opi()) */
4429 for(p
=vstack
;p
<=vtop
;p
++) {
4430 r
= p
->r
& VT_VALMASK
;
4431 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
4433 /* also look at second register (if long long) */
4434 r
= p
->r2
& VT_VALMASK
;
4435 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
4441 /* Should never comes here */
4445 /* save registers up to (vtop - n) stack entry */
4446 void save_regs(int n
)
4451 for(p
= vstack
;p
<= p1
; p
++) {
4452 r
= p
->r
& VT_VALMASK
;
4459 /* move register 's' to 'r', and flush previous value of r to memory
4461 void move_reg(int r
, int s
)
4474 /* get address of vtop (vtop MUST BE an lvalue) */
4477 vtop
->r
&= ~VT_LVAL
;
4478 /* tricky: if saved lvalue, then we can go back to lvalue */
4479 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
4480 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
4483 #ifdef CONFIG_TCC_BCHECK
4484 /* generate lvalue bound code */
4490 vtop
->r
&= ~VT_MUSTBOUND
;
4491 /* if lvalue, then use checking code before dereferencing */
4492 if (vtop
->r
& VT_LVAL
) {
4493 /* if not VT_BOUNDED value, then make one */
4494 if (!(vtop
->r
& VT_BOUNDED
)) {
4495 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
4496 /* must save type because we must set it to int to get pointer */
4498 vtop
->type
.t
= VT_INT
;
4501 gen_bounded_ptr_add();
4502 vtop
->r
|= lval_type
;
4505 /* then check for dereferencing */
4506 gen_bounded_ptr_deref();
4511 /* store vtop a register belonging to class 'rc'. lvalues are
4512 converted to values. Cannot be used if cannot be converted to
4513 register value (such as structures). */
4516 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
4517 unsigned long long ll
;
4519 /* NOTE: get_reg can modify vstack[] */
4520 if (vtop
->type
.t
& VT_BITFIELD
) {
4521 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
4522 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4523 /* remove bit field info to avoid loops */
4524 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4525 /* generate shifts */
4526 vpushi(32 - (bit_pos
+ bit_size
));
4528 vpushi(32 - bit_size
);
4529 /* NOTE: transformed to SHR if unsigned */
4533 if (is_float(vtop
->type
.t
) &&
4534 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4537 unsigned long offset
;
4539 /* XXX: unify with initializers handling ? */
4540 /* CPUs usually cannot use float constants, so we store them
4541 generically in data segment */
4542 size
= type_size(&vtop
->type
, &align
);
4543 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
4544 data_section
->data_offset
= offset
;
4545 /* XXX: not portable yet */
4546 ptr
= section_ptr_add(data_section
, size
);
4549 ptr
[i
] = vtop
->c
.tab
[i
];
4550 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
4551 vtop
->r
|= VT_LVAL
| VT_SYM
;
4555 #ifdef CONFIG_TCC_BCHECK
4556 if (vtop
->r
& VT_MUSTBOUND
)
4560 r
= vtop
->r
& VT_VALMASK
;
4561 /* need to reload if:
4563 - lvalue (need to dereference pointer)
4564 - already a register, but not in the right class */
4565 if (r
>= VT_CONST
||
4566 (vtop
->r
& VT_LVAL
) ||
4567 !(reg_classes
[r
] & rc
) ||
4568 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
4569 !(reg_classes
[vtop
->r2
] & rc
))) {
4571 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
4572 /* two register type load : expand to two words
4574 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4577 vtop
->c
.ui
= ll
; /* first word */
4579 vtop
->r
= r
; /* save register value */
4580 vpushi(ll
>> 32); /* second word */
4581 } else if (r
>= VT_CONST
||
4582 (vtop
->r
& VT_LVAL
)) {
4583 /* load from memory */
4586 vtop
[-1].r
= r
; /* save register value */
4587 /* increment pointer to get second word */
4588 vtop
->type
.t
= VT_INT
;
4594 /* move registers */
4597 vtop
[-1].r
= r
; /* save register value */
4598 vtop
->r
= vtop
[-1].r2
;
4600 /* allocate second register */
4607 /* write second register */
4609 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
4611 /* lvalue of scalar type : need to use lvalue type
4612 because of possible cast */
4615 /* compute memory access type */
4616 if (vtop
->r
& VT_LVAL_BYTE
)
4618 else if (vtop
->r
& VT_LVAL_SHORT
)
4620 if (vtop
->r
& VT_LVAL_UNSIGNED
)
4624 /* restore wanted type */
4627 /* one register type load */
4632 #ifdef TCC_TARGET_C67
4633 /* uses register pairs for doubles */
4634 if ((vtop
->type
.t
& VT_BTYPE
) == VT_DOUBLE
)
4641 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4642 void gv2(int rc1
, int rc2
)
4646 /* generate more generic register first. But VT_JMP or VT_CMP
4647 values must be generated first in all cases to avoid possible
4649 v
= vtop
[0].r
& VT_VALMASK
;
4650 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
4655 /* test if reload is needed for first register */
4656 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
4666 /* test if reload is needed for first register */
4667 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
4673 /* expand long long on stack in two int registers */
4678 u
= vtop
->type
.t
& VT_UNSIGNED
;
4681 vtop
[0].r
= vtop
[-1].r2
;
4682 vtop
[0].r2
= VT_CONST
;
4683 vtop
[-1].r2
= VT_CONST
;
4684 vtop
[0].type
.t
= VT_INT
| u
;
4685 vtop
[-1].type
.t
= VT_INT
| u
;
4688 /* build a long long from two ints */
4691 gv2(RC_INT
, RC_INT
);
4692 vtop
[-1].r2
= vtop
[0].r
;
4693 vtop
[-1].type
.t
= t
;
4697 /* rotate n first stack elements to the bottom
4698 I1 ... In -> I2 ... In I1 [top is right]
4706 for(i
=-n
+1;i
!=0;i
++)
4707 vtop
[i
] = vtop
[i
+1];
4711 /* rotate n first stack elements to the top
4712 I1 ... In -> In I1 ... I(n-1) [top is right]
4720 for(i
= 0;i
< n
- 1; i
++)
4721 vtop
[-i
] = vtop
[-i
- 1];
4725 /* pop stack value */
4729 v
= vtop
->r
& VT_VALMASK
;
4730 #ifdef TCC_TARGET_I386
4731 /* for x86, we need to pop the FP stack */
4732 if (v
== TREG_ST0
&& !nocode_wanted
) {
4733 o(0xd9dd); /* fstp %st(1) */
4736 if (v
== VT_JMP
|| v
== VT_JMPI
) {
4737 /* need to put correct jump if && or || without test */
4743 /* convert stack entry to register and duplicate its value in another
4751 if ((t
& VT_BTYPE
) == VT_LLONG
) {
4758 /* stack: H L L1 H1 */
4766 /* duplicate value */
4777 load(r1
, &sv
); /* move r to r1 */
4779 /* duplicates value */
4784 /* generate CPU independent (unsigned) long long operations */
4785 void gen_opl(int op
)
4787 int t
, a
, b
, op1
, c
, i
;
4794 func
= TOK___divdi3
;
4797 func
= TOK___udivdi3
;
4800 func
= TOK___moddi3
;
4803 func
= TOK___umoddi3
;
4805 /* call generic long long function */
4806 vpush_global_sym(&func_old_type
, func
);
4811 vtop
->r2
= REG_LRET
;
4824 /* stack: L1 H1 L2 H2 */
4829 vtop
[-2] = vtop
[-3];
4832 /* stack: H1 H2 L1 L2 */
4838 /* stack: H1 H2 L1 L2 ML MH */
4841 /* stack: ML MH H1 H2 L1 L2 */
4845 /* stack: ML MH H1 L2 H2 L1 */
4850 /* stack: ML MH M1 M2 */
4853 } else if (op
== '+' || op
== '-') {
4854 /* XXX: add non carry method too (for MIPS or alpha) */
4860 /* stack: H1 H2 (L1 op L2) */
4863 gen_op(op1
+ 1); /* TOK_xxxC2 */
4866 /* stack: H1 H2 (L1 op L2) */
4869 /* stack: (L1 op L2) H1 H2 */
4871 /* stack: (L1 op L2) (H1 op H2) */
4879 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4880 t
= vtop
[-1].type
.t
;
4884 /* stack: L H shift */
4886 /* constant: simpler */
4887 /* NOTE: all comments are for SHL. the other cases are
4888 done by swaping words */
4899 if (op
!= TOK_SAR
) {
4932 /* XXX: should provide a faster fallback on x86 ? */
4935 func
= TOK___sardi3
;
4938 func
= TOK___shrdi3
;
4941 func
= TOK___shldi3
;
4947 /* compare operations */
4953 /* stack: L1 H1 L2 H2 */
4955 vtop
[-1] = vtop
[-2];
4957 /* stack: L1 L2 H1 H2 */
4960 /* when values are equal, we need to compare low words. since
4961 the jump is inverted, we invert the test too. */
4964 else if (op1
== TOK_GT
)
4966 else if (op1
== TOK_ULT
)
4968 else if (op1
== TOK_UGT
)
4973 if (op1
!= TOK_NE
) {
4977 /* generate non equal test */
4978 /* XXX: NOT PORTABLE yet */
4982 #if defined(TCC_TARGET_I386)
4983 b
= psym(0x850f, 0);
4984 #elif defined(TCC_TARGET_ARM)
4986 o(0x1A000000 | encbranch(ind
, 0, 1));
4987 #elif defined(TCC_TARGET_C67)
4988 error("not implemented");
4990 #error not supported
4994 /* compare low. Always unsigned */
4998 else if (op1
== TOK_LE
)
5000 else if (op1
== TOK_GT
)
5002 else if (op1
== TOK_GE
)
5012 /* handle integer constant optimizations and various machine
5014 void gen_opic(int op
)
5021 /* currently, we cannot do computations with forward symbols */
5022 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5023 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5027 case '+': v1
->c
.i
+= fc
; break;
5028 case '-': v1
->c
.i
-= fc
; break;
5029 case '&': v1
->c
.i
&= fc
; break;
5030 case '^': v1
->c
.i
^= fc
; break;
5031 case '|': v1
->c
.i
|= fc
; break;
5032 case '*': v1
->c
.i
*= fc
; break;
5039 /* if division by zero, generate explicit division */
5042 error("division by zero in constant");
5046 default: v1
->c
.i
/= fc
; break;
5047 case '%': v1
->c
.i
%= fc
; break;
5048 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
5049 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
5052 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
5053 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
5054 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
5056 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
5057 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
5058 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
5059 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
5060 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
5061 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
5062 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
5063 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
5064 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
5065 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
5067 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
5068 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
5074 /* if commutative ops, put c2 as constant */
5075 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
5076 op
== '|' || op
== '*')) {
5081 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
5084 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
5085 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
5091 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
5092 /* try to use shifts instead of muls or divs */
5093 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
5102 else if (op
== TOK_PDIV
)
5108 } else if (c2
&& (op
== '+' || op
== '-') &&
5109 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
5110 (VT_CONST
| VT_SYM
)) {
5111 /* symbol + constant case */
5118 if (!nocode_wanted
) {
5119 /* call low level op generator */
5128 /* generate a floating point operation with constant propagation */
5129 void gen_opif(int op
)
5137 /* currently, we cannot do computations with forward symbols */
5138 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5139 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5141 if (v1
->type
.t
== VT_FLOAT
) {
5144 } else if (v1
->type
.t
== VT_DOUBLE
) {
5152 /* NOTE: we only do constant propagation if finite number (not
5153 NaN or infinity) (ANSI spec) */
5154 if (!ieee_finite(f1
) || !ieee_finite(f2
))
5158 case '+': f1
+= f2
; break;
5159 case '-': f1
-= f2
; break;
5160 case '*': f1
*= f2
; break;
5164 error("division by zero in constant");
5169 /* XXX: also handles tests ? */
5173 /* XXX: overflow test ? */
5174 if (v1
->type
.t
== VT_FLOAT
) {
5176 } else if (v1
->type
.t
== VT_DOUBLE
) {
5184 if (!nocode_wanted
) {
5192 static int pointed_size(CType
*type
)
5195 return type_size(pointed_type(type
), &align
);
5198 static inline int is_null_pointer(SValue
*p
)
5200 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
5202 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& p
->c
.i
== 0) ||
5203 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.ll
== 0);
5206 static inline int is_integer_btype(int bt
)
5208 return (bt
== VT_BYTE
|| bt
== VT_SHORT
||
5209 bt
== VT_INT
|| bt
== VT_LLONG
);
5212 /* check types for comparison or substraction of pointers */
5213 static void check_comparison_pointer_types(SValue
*p1
, SValue
*p2
, int op
)
5215 CType
*type1
, *type2
, tmp_type1
, tmp_type2
;
5218 /* null pointers are accepted for all comparisons as gcc */
5219 if (is_null_pointer(p1
) || is_null_pointer(p2
))
5223 bt1
= type1
->t
& VT_BTYPE
;
5224 bt2
= type2
->t
& VT_BTYPE
;
5225 /* accept comparison between pointer and integer with a warning */
5226 if ((is_integer_btype(bt1
) || is_integer_btype(bt2
)) && op
!= '-') {
5227 warning("comparison between pointer and integer");
5231 /* both must be pointers or implicit function pointers */
5232 if (bt1
== VT_PTR
) {
5233 type1
= pointed_type(type1
);
5234 } else if (bt1
!= VT_FUNC
)
5235 goto invalid_operands
;
5237 if (bt2
== VT_PTR
) {
5238 type2
= pointed_type(type2
);
5239 } else if (bt2
!= VT_FUNC
) {
5241 error("invalid operands to binary %s", get_tok_str(op
, NULL
));
5243 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
5244 (type2
->t
& VT_BTYPE
) == VT_VOID
)
5248 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5249 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5250 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
5251 /* gcc-like error if '-' is used */
5253 goto invalid_operands
;
5255 warning("comparison of distinct pointer types lacks a cast");
5259 /* generic gen_op: handles types problems */
5262 int u
, t1
, t2
, bt1
, bt2
, t
;
5265 t1
= vtop
[-1].type
.t
;
5266 t2
= vtop
[0].type
.t
;
5267 bt1
= t1
& VT_BTYPE
;
5268 bt2
= t2
& VT_BTYPE
;
5270 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5271 /* at least one operand is a pointer */
5272 /* relationnal op: must be both pointers */
5273 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5274 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5275 /* pointers are handled are unsigned */
5276 t
= VT_INT
| VT_UNSIGNED
;
5279 /* if both pointers, then it must be the '-' op */
5280 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
5282 error("cannot use pointers here");
5283 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5284 /* XXX: check that types are compatible */
5285 u
= pointed_size(&vtop
[-1].type
);
5287 /* set to integer type */
5288 vtop
->type
.t
= VT_INT
;
5292 /* exactly one pointer : must be '+' or '-'. */
5293 if (op
!= '-' && op
!= '+')
5294 error("cannot use pointers here");
5295 /* Put pointer as first operand */
5296 if (bt2
== VT_PTR
) {
5300 type1
= vtop
[-1].type
;
5301 /* XXX: cast to int ? (long long case) */
5302 vpushi(pointed_size(&vtop
[-1].type
));
5304 #ifdef CONFIG_TCC_BCHECK
5305 /* if evaluating constant expression, no code should be
5306 generated, so no bound check */
5307 if (do_bounds_check
&& !const_wanted
) {
5308 /* if bounded pointers, we generate a special code to
5315 gen_bounded_ptr_add();
5321 /* put again type if gen_opic() swaped operands */
5324 } else if (is_float(bt1
) || is_float(bt2
)) {
5325 /* compute bigger type and do implicit casts */
5326 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5328 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5333 /* floats can only be used for a few operations */
5334 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
5335 (op
< TOK_ULT
|| op
> TOK_GT
))
5336 error("invalid operands for binary operation");
5338 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5339 /* cast to biggest op */
5341 /* convert to unsigned if it does not fit in a long long */
5342 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5343 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5347 /* integer operations */
5349 /* convert to unsigned if it does not fit in an integer */
5350 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5351 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5354 /* XXX: currently, some unsigned operations are explicit, so
5355 we modify them here */
5356 if (t
& VT_UNSIGNED
) {
5363 else if (op
== TOK_LT
)
5365 else if (op
== TOK_GT
)
5367 else if (op
== TOK_LE
)
5369 else if (op
== TOK_GE
)
5376 /* special case for shifts and long long: we keep the shift as
5378 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
5383 else if ((t
& VT_BTYPE
) == VT_LLONG
)
5387 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5388 /* relationnal op: the result is an int */
5389 vtop
->type
.t
= VT_INT
;
5396 /* generic itof for unsigned long long case */
5397 void gen_cvt_itof1(int t
)
5399 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
5400 (VT_LLONG
| VT_UNSIGNED
)) {
5403 vpush_global_sym(&func_old_type
, TOK___ulltof
);
5404 else if (t
== VT_DOUBLE
)
5405 vpush_global_sym(&func_old_type
, TOK___ulltod
);
5407 vpush_global_sym(&func_old_type
, TOK___ulltold
);
5417 /* generic ftoi for unsigned long long case */
5418 void gen_cvt_ftoi1(int t
)
5422 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
5423 /* not handled natively */
5424 st
= vtop
->type
.t
& VT_BTYPE
;
5426 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
5427 else if (st
== VT_DOUBLE
)
5428 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
5430 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
5435 vtop
->r2
= REG_LRET
;
5441 /* force char or short cast */
5442 void force_charshort_cast(int t
)
5446 /* XXX: add optimization if lvalue : just change type and offset */
5451 if (t
& VT_UNSIGNED
) {
5452 vpushi((1 << bits
) - 1);
5463 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
5464 static void gen_cast(CType
*type
)
5466 int sbt
, dbt
, sf
, df
, c
;
5468 /* special delayed cast for char/short */
5469 /* XXX: in some cases (multiple cascaded casts), it may still
5471 if (vtop
->r
& VT_MUSTCAST
) {
5472 vtop
->r
&= ~VT_MUSTCAST
;
5473 force_charshort_cast(vtop
->type
.t
);
5476 /* bitfields first get cast to ints */
5477 if (vtop
->type
.t
& VT_BITFIELD
) {
5481 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
5482 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5484 if (sbt
!= dbt
&& !nocode_wanted
) {
5487 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5489 /* convert from fp to fp */
5491 /* constant case: we can do it now */
5492 /* XXX: in ISOC, cannot do it if error in convert */
5493 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
5494 vtop
->c
.f
= (float)vtop
->c
.d
;
5495 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
5496 vtop
->c
.f
= (float)vtop
->c
.ld
;
5497 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
5498 vtop
->c
.d
= (double)vtop
->c
.f
;
5499 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
5500 vtop
->c
.d
= (double)vtop
->c
.ld
;
5501 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
5502 vtop
->c
.ld
= (long double)vtop
->c
.f
;
5503 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
5504 vtop
->c
.ld
= (long double)vtop
->c
.d
;
5506 /* non constant case: generate code */
5510 /* convert int to fp */
5513 case VT_LLONG
| VT_UNSIGNED
:
5515 /* XXX: add const cases for long long */
5517 case VT_INT
| VT_UNSIGNED
:
5519 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
5520 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
5521 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
5526 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
5527 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
5528 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
5534 #if !defined(TCC_TARGET_ARM)
5541 /* convert fp to int */
5542 /* we handle char/short/etc... with generic code */
5543 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
5544 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
5549 case VT_LLONG
| VT_UNSIGNED
:
5551 /* XXX: add const cases for long long */
5553 case VT_INT
| VT_UNSIGNED
:
5555 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5556 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5557 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5563 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5564 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5565 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5573 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
5574 /* additional cast for char/short/bool... */
5578 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
5579 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
5580 /* scalar to long long */
5582 if (sbt
== (VT_INT
| VT_UNSIGNED
))
5583 vtop
->c
.ll
= vtop
->c
.ui
;
5585 vtop
->c
.ll
= vtop
->c
.i
;
5587 /* machine independent conversion */
5589 /* generate high word */
5590 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
5598 /* patch second register */
5599 vtop
[-1].r2
= vtop
->r
;
5603 } else if (dbt
== VT_BOOL
) {
5604 /* scalar to bool */
5607 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
5608 (dbt
& VT_BTYPE
) == VT_SHORT
) {
5609 force_charshort_cast(dbt
);
5610 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
5612 if (sbt
== VT_LLONG
) {
5613 /* from long long: just take low order word */
5617 /* if lvalue and single word type, nothing to do because
5618 the lvalue already contains the real type size (see
5619 VT_LVAL_xxx constants) */
5625 /* return type size. Put alignment at 'a' */
5626 static int type_size(CType
*type
, int *a
)
5631 bt
= type
->t
& VT_BTYPE
;
5632 if (bt
== VT_STRUCT
) {
5637 } else if (bt
== VT_PTR
) {
5638 if (type
->t
& VT_ARRAY
) {
5640 return type_size(&s
->type
, a
) * s
->c
;
5645 } else if (bt
== VT_LDOUBLE
) {
5647 return LDOUBLE_SIZE
;
5648 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
5649 #ifdef TCC_TARGET_I386
5655 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
5658 } else if (bt
== VT_SHORT
) {
5662 /* char, void, function, _Bool */
5668 /* return the pointed type of t */
5669 static inline CType
*pointed_type(CType
*type
)
5671 return &type
->ref
->type
;
5674 /* modify type so that its it is a pointer to type. */
5675 static void mk_pointer(CType
*type
)
5678 s
= sym_push(SYM_FIELD
, type
, 0, -1);
5679 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
5683 /* compare function types. OLD functions match any new functions */
5684 static int is_compatible_func(CType
*type1
, CType
*type2
)
5690 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5692 /* XXX: not complete */
5693 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
5697 while (s1
!= NULL
) {
5700 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5710 /* return true if type1 and type2 are exactly the same (including
5713 - enums are not checked as gcc __builtin_types_compatible_p ()
5715 static int is_compatible_types(CType
*type1
, CType
*type2
)
5719 t1
= type1
->t
& VT_TYPE
;
5720 t2
= type2
->t
& VT_TYPE
;
5721 /* XXX: bitfields ? */
5724 /* test more complicated cases */
5725 bt1
= t1
& VT_BTYPE
;
5726 if (bt1
== VT_PTR
) {
5727 type1
= pointed_type(type1
);
5728 type2
= pointed_type(type2
);
5729 return is_compatible_types(type1
, type2
);
5730 } else if (bt1
== VT_STRUCT
) {
5731 return (type1
->ref
== type2
->ref
);
5732 } else if (bt1
== VT_FUNC
) {
5733 return is_compatible_func(type1
, type2
);
5739 /* print a type. If 'varstr' is not NULL, then the variable is also
5740 printed in the type */
5742 /* XXX: add array and function pointers */
5743 void type_to_str(char *buf
, int buf_size
,
5744 CType
*type
, const char *varstr
)
5751 t
= type
->t
& VT_TYPE
;
5754 if (t
& VT_CONSTANT
)
5755 pstrcat(buf
, buf_size
, "const ");
5756 if (t
& VT_VOLATILE
)
5757 pstrcat(buf
, buf_size
, "volatile ");
5758 if (t
& VT_UNSIGNED
)
5759 pstrcat(buf
, buf_size
, "unsigned ");
5789 tstr
= "long double";
5791 pstrcat(buf
, buf_size
, tstr
);
5795 if (bt
== VT_STRUCT
)
5799 pstrcat(buf
, buf_size
, tstr
);
5800 v
= type
->ref
->v
& ~SYM_STRUCT
;
5801 if (v
>= SYM_FIRST_ANOM
)
5802 pstrcat(buf
, buf_size
, "<anonymous>");
5804 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
5808 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
5809 pstrcat(buf
, buf_size
, "(");
5811 while (sa
!= NULL
) {
5812 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
5813 pstrcat(buf
, buf_size
, buf1
);
5816 pstrcat(buf
, buf_size
, ", ");
5818 pstrcat(buf
, buf_size
, ")");
5822 pstrcpy(buf1
, sizeof(buf1
), "*");
5824 pstrcat(buf1
, sizeof(buf1
), varstr
);
5825 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
5829 pstrcat(buf
, buf_size
, " ");
5830 pstrcat(buf
, buf_size
, varstr
);
5835 /* verify type compatibility to store vtop in 'dt' type, and generate
5837 static void gen_assign_cast(CType
*dt
)
5839 CType
*st
, *type1
, *type2
, tmp_type1
, tmp_type2
;
5840 char buf1
[256], buf2
[256];
5843 st
= &vtop
->type
; /* source type */
5844 dbt
= dt
->t
& VT_BTYPE
;
5845 sbt
= st
->t
& VT_BTYPE
;
5846 if (dt
->t
& VT_CONSTANT
)
5847 warning("assignment of read-only location");
5850 /* special cases for pointers */
5851 /* '0' can also be a pointer */
5852 if (is_null_pointer(vtop
))
5854 /* accept implicit pointer to integer cast with warning */
5855 if (is_integer_btype(sbt
)) {
5856 warning("assignment makes pointer from integer without a cast");
5859 type1
= pointed_type(dt
);
5860 /* a function is implicitely a function pointer */
5861 if (sbt
== VT_FUNC
) {
5862 if ((type1
->t
& VT_BTYPE
) != VT_VOID
&&
5863 !is_compatible_types(pointed_type(dt
), st
))
5870 type2
= pointed_type(st
);
5871 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
5872 (type2
->t
& VT_BTYPE
) == VT_VOID
) {
5873 /* void * can match anything */
5875 /* exact type match, except for unsigned */
5878 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5879 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5880 if (!is_compatible_types(&tmp_type1
, &tmp_type2
))
5883 /* check const and volatile */
5884 if ((!(type1
->t
& VT_CONSTANT
) && (type2
->t
& VT_CONSTANT
)) ||
5885 (!(type1
->t
& VT_VOLATILE
) && (type2
->t
& VT_VOLATILE
)))
5886 warning("assignment discards qualifiers from pointer target type");
5892 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
5893 warning("assignment makes integer from pointer without a cast");
5895 /* XXX: more tests */
5900 tmp_type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
5901 tmp_type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
5902 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
5904 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
5905 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
5906 error("cannot cast '%s' to '%s'", buf1
, buf2
);
5914 /* store vtop in lvalue pushed on stack */
5917 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
5919 ft
= vtop
[-1].type
.t
;
5920 sbt
= vtop
->type
.t
& VT_BTYPE
;
5921 dbt
= ft
& VT_BTYPE
;
5922 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
5923 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
5924 /* optimize char/short casts */
5925 delayed_cast
= VT_MUSTCAST
;
5926 vtop
->type
.t
= ft
& VT_TYPE
;
5927 /* XXX: factorize */
5928 if (ft
& VT_CONSTANT
)
5929 warning("assignment of read-only location");
5932 gen_assign_cast(&vtop
[-1].type
);
5935 if (sbt
== VT_STRUCT
) {
5936 /* if structure, only generate pointer */
5937 /* structure assignment : generate memcpy */
5938 /* XXX: optimize if small size */
5939 if (!nocode_wanted
) {
5940 size
= type_size(&vtop
->type
, &align
);
5942 vpush_global_sym(&func_old_type
, TOK_memcpy
);
5946 vtop
->type
.t
= VT_INT
;
5950 vtop
->type
.t
= VT_INT
;
5962 /* leave source on stack */
5963 } else if (ft
& VT_BITFIELD
) {
5964 /* bitfield store handling */
5965 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
5966 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
5967 /* remove bit field info to avoid loops */
5968 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
5970 /* duplicate destination */
5972 vtop
[-1] = vtop
[-2];
5974 /* mask and shift source */
5975 vpushi((1 << bit_size
) - 1);
5979 /* load destination, mask and or with source */
5981 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
5987 #ifdef CONFIG_TCC_BCHECK
5988 /* bound check case */
5989 if (vtop
[-1].r
& VT_MUSTBOUND
) {
5995 if (!nocode_wanted
) {
5999 r
= gv(rc
); /* generate value */
6000 /* if lvalue was saved on stack, must read it */
6001 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
6003 t
= get_reg(RC_INT
);
6005 sv
.r
= VT_LOCAL
| VT_LVAL
;
6006 sv
.c
.ul
= vtop
[-1].c
.ul
;
6008 vtop
[-1].r
= t
| VT_LVAL
;
6011 /* two word case handling : store second register at word + 4 */
6012 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
6014 /* convert to int to increment easily */
6015 vtop
->type
.t
= VT_INT
;
6021 /* XXX: it works because r2 is spilled last ! */
6022 store(vtop
->r2
, vtop
- 1);
6026 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6027 vtop
->r
|= delayed_cast
;
6031 /* post defines POST/PRE add. c is the token ++ or -- */
6032 void inc(int post
, int c
)
6035 vdup(); /* save lvalue */
6037 gv_dup(); /* duplicate value */
6042 vpushi(c
- TOK_MID
);
6044 vstore(); /* store value */
6046 vpop(); /* if post op, return saved value */
6049 /* Parse GNUC __attribute__ extension. Currently, the following
6050 extensions are recognized:
6051 - aligned(n) : set data/function alignment.
6052 - section(x) : generate data/code in this section.
6053 - unused : currently ignored, but may be used someday.
6055 static void parse_attribute(AttributeDef
*ad
)
6059 while (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
6063 while (tok
!= ')') {
6064 if (tok
< TOK_IDENT
)
6065 expect("attribute name");
6073 expect("section name");
6074 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
6083 if (n
<= 0 || (n
& (n
- 1)) != 0)
6084 error("alignment must be a positive power of two");
6093 /* currently, no need to handle it because tcc does not
6094 track unused objects */
6098 /* currently, no need to handle it because tcc does not
6099 track unused objects */
6104 ad
->func_call
= FUNC_CDECL
;
6109 ad
->func_call
= FUNC_STDCALL
;
6112 if (tcc_state
->warn_unsupported
)
6113 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
6114 /* skip parameters */
6115 /* XXX: skip parenthesis too */
6118 while (tok
!= ')' && tok
!= -1)
6133 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
6134 static void struct_decl(CType
*type
, int u
)
6136 int a
, v
, size
, align
, maxalign
, c
, offset
;
6137 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
6142 a
= tok
; /* save decl type */
6147 /* struct already defined ? return it */
6149 expect("struct/union/enum name");
6153 error("invalid type");
6160 /* we put an undefined size for struct/union */
6161 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
6162 s
->r
= 0; /* default alignment is zero as gcc */
6163 /* put struct/union/enum name in type */
6171 error("struct/union/enum already defined");
6172 /* cannot be empty */
6174 /* non empty enums are not allowed */
6175 if (a
== TOK_ENUM
) {
6179 expect("identifier");
6185 /* enum symbols have static storage */
6186 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
6187 ss
->type
.t
|= VT_STATIC
;
6192 /* NOTE: we accept a trailing comma */
6202 while (tok
!= '}') {
6203 parse_btype(&btype
, &ad
);
6209 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
);
6210 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
6211 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
| VT_INLINE
)))
6212 error("invalid type for '%s'",
6213 get_tok_str(v
, NULL
));
6217 bit_size
= expr_const();
6218 /* XXX: handle v = 0 case for messages */
6220 error("negative width in bit-field '%s'",
6221 get_tok_str(v
, NULL
));
6222 if (v
&& bit_size
== 0)
6223 error("zero width for bit-field '%s'",
6224 get_tok_str(v
, NULL
));
6226 size
= type_size(&type1
, &align
);
6228 if (bit_size
>= 0) {
6229 bt
= type1
.t
& VT_BTYPE
;
6234 error("bitfields must have scalar type");
6236 if (bit_size
> bsize
) {
6237 error("width of '%s' exceeds its type",
6238 get_tok_str(v
, NULL
));
6239 } else if (bit_size
== bsize
) {
6240 /* no need for bit fields */
6242 } else if (bit_size
== 0) {
6243 /* XXX: what to do if only padding in a
6245 /* zero size: means to pad */
6249 /* we do not have enough room ? */
6250 if ((bit_pos
+ bit_size
) > bsize
)
6253 /* XXX: handle LSB first */
6254 type1
.t
|= VT_BITFIELD
|
6255 (bit_pos
<< VT_STRUCT_SHIFT
) |
6256 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
6257 bit_pos
+= bit_size
;
6263 /* add new memory data only if starting
6265 if (lbit_pos
== 0) {
6266 if (a
== TOK_STRUCT
) {
6267 c
= (c
+ align
- 1) & -align
;
6275 if (align
> maxalign
)
6279 printf("add field %s offset=%d",
6280 get_tok_str(v
, NULL
), offset
);
6281 if (type1
.t
& VT_BITFIELD
) {
6282 printf(" pos=%d size=%d",
6283 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
6284 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
6288 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
6292 if (tok
== ';' || tok
== TOK_EOF
)
6299 /* store size and alignment */
6300 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
6306 /* return 0 if no type declaration. otherwise, return the basic type
6309 static int parse_btype(CType
*type
, AttributeDef
*ad
)
6311 int t
, u
, type_found
, typespec_found
;
6315 memset(ad
, 0, sizeof(AttributeDef
));
6322 /* currently, we really ignore extension */
6332 if ((t
& VT_BTYPE
) != 0)
6333 error("too many basic types");
6349 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
6350 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6351 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
6352 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
6366 if ((t
& VT_BTYPE
) == VT_LONG
) {
6367 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6374 struct_decl(&type1
, VT_ENUM
);
6377 type
->ref
= type1
.ref
;
6381 struct_decl(&type1
, VT_STRUCT
);
6384 /* type modifiers */
6437 /* GNUC attribute */
6438 case TOK_ATTRIBUTE1
:
6439 case TOK_ATTRIBUTE2
:
6440 parse_attribute(ad
);
6447 parse_expr_type(&type1
);
6453 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
6455 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
6456 type
->ref
= s
->type
.ref
;
6463 if ((t
& (VT_SIGNED
|VT_UNSIGNED
)) == (VT_SIGNED
|VT_UNSIGNED
))
6464 error("signed and unsigned modifier");
6465 if (tcc_state
->char_is_unsigned
) {
6466 if ((t
& (VT_SIGNED
|VT_UNSIGNED
|VT_BTYPE
)) == VT_BYTE
)
6471 /* long is never used as type */
6472 if ((t
& VT_BTYPE
) == VT_LONG
)
6473 t
= (t
& ~VT_BTYPE
) | VT_INT
;
6478 /* convert a function parameter type (array to pointer and function to
6479 function pointer) */
6480 static inline void convert_parameter_type(CType
*pt
)
6482 /* array must be transformed to pointer according to ANSI C */
6484 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
6489 static void post_type(CType
*type
, AttributeDef
*ad
)
6492 Sym
**plast
, *s
, *first
;
6497 /* function declaration */
6502 while (tok
!= ')') {
6503 /* read param name and compute offset */
6504 if (l
!= FUNC_OLD
) {
6505 if (!parse_btype(&pt
, &ad1
)) {
6507 error("invalid type");
6514 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
6516 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
6517 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
6518 error("parameter declared as void");
6525 convert_parameter_type(&pt
);
6526 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
6531 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
6538 /* if no parameters, then old type prototype */
6542 t1
= type
->t
& VT_STORAGE
;
6543 /* NOTE: const is ignored in returned type as it has a special
6544 meaning in gcc / C++ */
6545 type
->t
&= ~(VT_STORAGE
| VT_CONSTANT
);
6546 post_type(type
, ad
);
6547 /* we push a anonymous symbol which will contain the function prototype */
6548 s
= sym_push(SYM_FIELD
, type
, ad
->func_call
, l
);
6550 type
->t
= t1
| VT_FUNC
;
6552 } else if (tok
== '[') {
6553 /* array definition */
6559 error("invalid array size");
6562 /* parse next post type */
6563 t1
= type
->t
& VT_STORAGE
;
6564 type
->t
&= ~VT_STORAGE
;
6565 post_type(type
, ad
);
6567 /* we push a anonymous symbol which will contain the array
6569 s
= sym_push(SYM_FIELD
, type
, 0, n
);
6570 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
6575 /* Parse a type declaration (except basic type), and return the type
6576 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6577 expected. 'type' should contain the basic type. 'ad' is the
6578 attribute definition of the basic type. It can be modified by
6581 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
6584 CType type1
, *type2
;
6587 while (tok
== '*') {
6595 qualifiers
|= VT_CONSTANT
;
6600 qualifiers
|= VT_VOLATILE
;
6608 type
->t
|= qualifiers
;
6611 /* XXX: clarify attribute handling */
6612 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6613 parse_attribute(ad
);
6615 /* recursive type */
6616 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6617 type1
.t
= 0; /* XXX: same as int */
6620 /* XXX: this is not correct to modify 'ad' at this point, but
6621 the syntax is not clear */
6622 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6623 parse_attribute(ad
);
6624 type_decl(&type1
, ad
, v
, td
);
6627 /* type identifier */
6628 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
6632 if (!(td
& TYPE_ABSTRACT
))
6633 expect("identifier");
6637 post_type(type
, ad
);
6638 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6639 parse_attribute(ad
);
6642 /* append type at the end of type1 */
6655 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6656 static int lvalue_type(int t
)
6661 if (bt
== VT_BYTE
|| bt
== VT_BOOL
)
6663 else if (bt
== VT_SHORT
)
6667 if (t
& VT_UNSIGNED
)
6668 r
|= VT_LVAL_UNSIGNED
;
6672 /* indirection with full error checking and bound check */
6673 static void indir(void)
6675 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
6677 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
6679 vtop
->type
= *pointed_type(&vtop
->type
);
6680 /* an array is never an lvalue */
6681 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6682 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6683 /* if bound checking, the referenced pointer must be checked */
6684 if (do_bounds_check
)
6685 vtop
->r
|= VT_MUSTBOUND
;
6689 /* pass a parameter to a function and do type checking and casting */
6690 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
6695 func_type
= func
->c
;
6696 if (func_type
== FUNC_OLD
||
6697 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
6698 /* default casting : only need to convert float to double */
6699 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
6703 } else if (arg
== NULL
) {
6704 error("too many arguments to function");
6707 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
6708 gen_assign_cast(&type
);
6712 /* parse an expression of the form '(type)' or '(expr)' and return its
6714 static void parse_expr_type(CType
*type
)
6720 if (parse_btype(type
, &ad
)) {
6721 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
6728 static void parse_type(CType
*type
)
6733 if (!parse_btype(type
, &ad
)) {
6736 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
6739 static void vpush_tokc(int t
)
6743 vsetc(&type
, VT_CONST
, &tokc
);
6746 static void unary(void)
6748 int n
, t
, align
, size
, r
;
6753 /* XXX: GCC 2.95.3 does not generate a table although it should be
6767 vpush_tokc(VT_INT
| VT_UNSIGNED
);
6771 vpush_tokc(VT_LLONG
);
6775 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
6779 vpush_tokc(VT_FLOAT
);
6783 vpush_tokc(VT_DOUBLE
);
6787 vpush_tokc(VT_LDOUBLE
);
6790 case TOK___FUNCTION__
:
6792 goto tok_identifier
;
6798 /* special function name identifier */
6799 len
= strlen(funcname
) + 1;
6800 /* generate char[len] type */
6805 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
6806 ptr
= section_ptr_add(data_section
, len
);
6807 memcpy(ptr
, funcname
, len
);
6815 /* string parsing */
6818 if (tcc_state
->warn_write_strings
)
6823 memset(&ad
, 0, sizeof(AttributeDef
));
6824 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
6829 if (parse_btype(&type
, &ad
)) {
6830 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
6832 /* check ISOC99 compound literal */
6834 /* data is allocated locally by default */
6839 /* all except arrays are lvalues */
6840 if (!(type
.t
& VT_ARRAY
))
6841 r
|= lvalue_type(type
.t
);
6842 memset(&ad
, 0, sizeof(AttributeDef
));
6843 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
6848 } else if (tok
== '{') {
6849 /* save all registers */
6851 /* statement expression : we do not accept break/continue
6852 inside as GCC does */
6853 block(NULL
, NULL
, NULL
, NULL
, 0, 1);
6868 /* functions names must be treated as function pointers,
6869 except for unary '&' and sizeof. Since we consider that
6870 functions are not lvalues, we only have to handle it
6871 there and in function calls. */
6872 /* arrays can also be used although they are not lvalues */
6873 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
6874 !(vtop
->type
.t
& VT_ARRAY
))
6876 mk_pointer(&vtop
->type
);
6882 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
6883 vtop
->c
.i
= !vtop
->c
.i
;
6884 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
6885 vtop
->c
.i
= vtop
->c
.i
^ 1;
6887 vseti(VT_JMP
, gtst(1, 0));
6897 /* in order to force cast, we add zero */
6899 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
6900 error("pointer not accepted for unary plus");
6910 parse_expr_type(&type
);
6914 size
= type_size(&type
, &align
);
6915 if (t
== TOK_SIZEOF
) {
6917 error("sizeof applied to an incomplete type");
6924 case TOK_builtin_types_compatible_p
:
6933 type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6934 type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6935 vpushi(is_compatible_types(&type1
, &type2
));
6938 case TOK_builtin_constant_p
:
6940 int saved_nocode_wanted
, res
;
6943 saved_nocode_wanted
= nocode_wanted
;
6946 res
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
6948 nocode_wanted
= saved_nocode_wanted
;
6968 goto tok_identifier
;
6970 /* allow to take the address of a label */
6971 if (tok
< TOK_UIDENT
)
6972 expect("label identifier");
6973 s
= label_find(tok
);
6975 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
6977 if (s
->r
== LABEL_DECLARED
)
6978 s
->r
= LABEL_FORWARD
;
6981 s
->type
.t
= VT_VOID
;
6982 mk_pointer(&s
->type
);
6983 s
->type
.t
|= VT_STATIC
;
6985 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
6994 expect("identifier");
6998 error("'%s' undeclared", get_tok_str(t
, NULL
));
6999 /* for simple function calls, we tolerate undeclared
7000 external reference to int() function */
7001 if (tcc_state
->warn_implicit_function_declaration
)
7002 warning("implicit declaration of function '%s'",
7003 get_tok_str(t
, NULL
));
7004 s
= external_global_sym(t
, &func_old_type
, 0);
7006 vset(&s
->type
, s
->r
, s
->c
);
7007 /* if forward reference, we must point to s */
7008 if (vtop
->r
& VT_SYM
) {
7015 /* post operations */
7017 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
7020 } else if (tok
== '.' || tok
== TOK_ARROW
) {
7022 if (tok
== TOK_ARROW
)
7027 /* expect pointer on structure */
7028 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
7029 expect("struct or union");
7033 while ((s
= s
->next
) != NULL
) {
7038 error("field not found");
7039 /* add field offset to pointer */
7040 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
7043 /* change type to field type, and set to lvalue */
7044 vtop
->type
= s
->type
;
7045 /* an array is never an lvalue */
7046 if (!(vtop
->type
.t
& VT_ARRAY
)) {
7047 vtop
->r
|= lvalue_type(vtop
->type
.t
);
7048 /* if bound checking, the referenced pointer must be checked */
7049 if (do_bounds_check
)
7050 vtop
->r
|= VT_MUSTBOUND
;
7053 } else if (tok
== '[') {
7059 } else if (tok
== '(') {
7065 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
7066 /* pointer test (no array accepted) */
7067 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
7068 vtop
->type
= *pointed_type(&vtop
->type
);
7069 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
7073 expect("function pointer");
7076 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
7078 /* get return type */
7081 sa
= s
->next
; /* first parameter */
7083 /* compute first implicit argument if a structure is returned */
7084 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
7085 /* get some space for the returned structure */
7086 size
= type_size(&s
->type
, &align
);
7087 loc
= (loc
- size
) & -align
;
7089 ret
.r
= VT_LOCAL
| VT_LVAL
;
7090 /* pass it as 'int' to avoid structure arg passing
7092 vseti(VT_LOCAL
, loc
);
7098 /* return in register */
7099 if (is_float(ret
.type
.t
)) {
7102 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
7111 gfunc_param_typed(s
, sa
);
7121 error("too few arguments to function");
7123 if (!nocode_wanted
) {
7124 gfunc_call(nb_args
);
7126 vtop
-= (nb_args
+ 1);
7129 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
7137 static void uneq(void)
7143 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
7144 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
7145 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
7160 static void expr_prod(void)
7165 while (tok
== '*' || tok
== '/' || tok
== '%') {
7173 static void expr_sum(void)
7178 while (tok
== '+' || tok
== '-') {
7186 static void expr_shift(void)
7191 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
7199 static void expr_cmp(void)
7204 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
7205 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
7213 static void expr_cmpeq(void)
7218 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
7226 static void expr_and(void)
7229 while (tok
== '&') {
7236 static void expr_xor(void)
7239 while (tok
== '^') {
7246 static void expr_or(void)
7249 while (tok
== '|') {
7256 /* XXX: fix this mess */
7257 static void expr_land_const(void)
7260 while (tok
== TOK_LAND
) {
7267 /* XXX: fix this mess */
7268 static void expr_lor_const(void)
7271 while (tok
== TOK_LOR
) {
7278 /* only used if non constant */
7279 static void expr_land(void)
7284 if (tok
== TOK_LAND
) {
7288 if (tok
!= TOK_LAND
) {
7298 static void expr_lor(void)
7303 if (tok
== TOK_LOR
) {
7307 if (tok
!= TOK_LOR
) {
7317 /* XXX: better constant handling */
7318 static void expr_eq(void)
7320 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
7322 CType type
, type1
, type2
;
7331 if (tok
== ':' && gnu_ext
) {
7347 if (vtop
!= vstack
) {
7348 /* needed to avoid having different registers saved in
7350 if (is_float(vtop
->type
.t
))
7357 if (tok
== ':' && gnu_ext
) {
7365 sv
= *vtop
; /* save value to handle it later */
7366 vtop
--; /* no vpop so that FP stack is not flushed */
7374 bt1
= t1
& VT_BTYPE
;
7376 bt2
= t2
& VT_BTYPE
;
7377 /* cast operands to correct type according to ISOC rules */
7378 if (is_float(bt1
) || is_float(bt2
)) {
7379 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
7380 type
.t
= VT_LDOUBLE
;
7381 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
7386 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
7387 /* cast to biggest op */
7389 /* convert to unsigned if it does not fit in a long long */
7390 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
7391 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
7392 type
.t
|= VT_UNSIGNED
;
7393 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
7394 /* XXX: test pointer compatibility */
7396 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
7397 /* XXX: test structure compatibility */
7399 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
7400 /* NOTE: as an extension, we accept void on only one side */
7403 /* integer operations */
7405 /* convert to unsigned if it does not fit in an integer */
7406 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
7407 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
7408 type
.t
|= VT_UNSIGNED
;
7411 /* now we convert second operand */
7414 if (is_float(type
.t
)) {
7416 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
7417 /* for long longs, we use fixed registers to avoid having
7418 to handle a complicated move */
7423 /* this is horrible, but we must also convert first
7427 /* put again first value and cast it */
7438 static void gexpr(void)
7449 /* parse an expression and return its type without any side effect. */
7450 static void expr_type(CType
*type
)
7452 int saved_nocode_wanted
;
7454 saved_nocode_wanted
= nocode_wanted
;
7459 nocode_wanted
= saved_nocode_wanted
;
7462 /* parse a unary expression and return its type without any side
7464 static void unary_type(CType
*type
)
7476 /* parse a constant expression and return value in vtop. */
7477 static void expr_const1(void)
7486 /* parse an integer constant and return its value. */
7487 static int expr_const(void)
7491 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
7492 expect("constant expression");
7498 /* return the label token if current token is a label, otherwise
7500 static int is_label(void)
7504 /* fast test first */
7505 if (tok
< TOK_UIDENT
)
7507 /* no need to save tokc because tok is an identifier */
7514 unget_tok(last_tok
);
7519 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
7520 int case_reg
, int is_expr
)
7525 /* generate line number info */
7527 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
7528 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
7530 last_line_num
= file
->line_num
;
7534 /* default return value is (void) */
7536 vtop
->type
.t
= VT_VOID
;
7539 if (tok
== TOK_IF
) {
7546 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7548 if (c
== TOK_ELSE
) {
7552 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7553 gsym(d
); /* patch else jmp */
7556 } else if (tok
== TOK_WHILE
) {
7564 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7568 } else if (tok
== '{') {
7572 /* record local declaration stack position */
7574 llabel
= local_label_stack
;
7575 /* handle local labels declarations */
7576 if (tok
== TOK_LABEL
) {
7579 if (tok
< TOK_UIDENT
)
7580 expect("label identifier");
7581 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
7591 while (tok
!= '}') {
7596 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
7599 /* pop locally defined labels */
7600 label_pop(&local_label_stack
, llabel
);
7601 /* pop locally defined symbols */
7602 sym_pop(&local_stack
, s
);
7604 } else if (tok
== TOK_RETURN
) {
7608 gen_assign_cast(&func_vt
);
7609 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
7611 /* if returning structure, must copy it to implicit
7612 first pointer arg location */
7615 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
7618 /* copy structure value to pointer */
7620 } else if (is_float(func_vt
.t
)) {
7625 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
7628 rsym
= gjmp(rsym
); /* jmp */
7629 } else if (tok
== TOK_BREAK
) {
7632 error("cannot break");
7633 *bsym
= gjmp(*bsym
);
7636 } else if (tok
== TOK_CONTINUE
) {
7639 error("cannot continue");
7640 *csym
= gjmp(*csym
);
7643 } else if (tok
== TOK_FOR
) {
7670 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7675 if (tok
== TOK_DO
) {
7680 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7691 if (tok
== TOK_SWITCH
) {
7695 /* XXX: other types than integer */
7696 case_reg
= gv(RC_INT
);
7700 b
= gjmp(0); /* jump to first case */
7702 block(&a
, csym
, &b
, &c
, case_reg
, 0);
7703 /* if no default, jmp after switch */
7711 if (tok
== TOK_CASE
) {
7718 if (gnu_ext
&& tok
== TOK_DOTS
) {
7722 warning("empty case range");
7724 /* since a case is like a label, we must skip it with a jmp */
7731 *case_sym
= gtst(1, 0);
7734 *case_sym
= gtst(1, 0);
7738 *case_sym
= gtst(1, *case_sym
);
7743 goto block_after_label
;
7745 if (tok
== TOK_DEFAULT
) {
7751 error("too many 'default'");
7754 goto block_after_label
;
7756 if (tok
== TOK_GOTO
) {
7758 if (tok
== '*' && gnu_ext
) {
7762 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
7765 } else if (tok
>= TOK_UIDENT
) {
7766 s
= label_find(tok
);
7767 /* put forward definition if needed */
7769 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7771 if (s
->r
== LABEL_DECLARED
)
7772 s
->r
= LABEL_FORWARD
;
7774 /* label already defined */
7775 if (s
->r
& LABEL_FORWARD
)
7776 s
->next
= (void *)gjmp((long)s
->next
);
7778 gjmp_addr((long)s
->next
);
7781 expect("label identifier");
7784 } else if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
7792 if (s
->r
== LABEL_DEFINED
)
7793 error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
7794 gsym((long)s
->next
);
7795 s
->r
= LABEL_DEFINED
;
7797 s
= label_push(&global_label_stack
, b
, LABEL_DEFINED
);
7799 s
->next
= (void *)ind
;
7800 /* we accept this, but it is a mistake */
7803 warning("deprecated use of label at end of compound statement");
7807 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
7810 /* expression case */
7825 /* t is the array or struct type. c is the array or struct
7826 address. cur_index/cur_field is the pointer to the current
7827 value. 'size_only' is true if only size info is needed (only used
7829 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
7830 int *cur_index
, Sym
**cur_field
,
7834 int notfirst
, index
, index_last
, align
, l
, nb_elems
, elem_size
;
7840 if (gnu_ext
&& (l
= is_label()) != 0)
7842 while (tok
== '[' || tok
== '.') {
7844 if (!(type
->t
& VT_ARRAY
))
7845 expect("array type");
7848 index
= expr_const();
7849 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
7850 expect("invalid index");
7851 if (tok
== TOK_DOTS
&& gnu_ext
) {
7853 index_last
= expr_const();
7854 if (index_last
< 0 ||
7855 (s
->c
>= 0 && index_last
>= s
->c
) ||
7857 expect("invalid index");
7863 *cur_index
= index_last
;
7864 type
= pointed_type(type
);
7865 elem_size
= type_size(type
, &align
);
7866 c
+= index
* elem_size
;
7867 /* NOTE: we only support ranges for last designator */
7868 nb_elems
= index_last
- index
+ 1;
7869 if (nb_elems
!= 1) {
7878 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
7879 expect("struct/union type");
7892 /* XXX: fix this mess by using explicit storage field */
7894 type1
.t
|= (type
->t
& ~VT_TYPE
);
7908 if (type
->t
& VT_ARRAY
) {
7910 type
= pointed_type(type
);
7911 c
+= index
* type_size(type
, &align
);
7915 error("too many field init");
7916 /* XXX: fix this mess by using explicit storage field */
7918 type1
.t
|= (type
->t
& ~VT_TYPE
);
7923 decl_initializer(type
, sec
, c
, 0, size_only
);
7925 /* XXX: make it more general */
7926 if (!size_only
&& nb_elems
> 1) {
7927 unsigned long c_end
;
7932 error("range init not supported yet for dynamic storage");
7933 c_end
= c
+ nb_elems
* elem_size
;
7934 if (c_end
> sec
->data_allocated
)
7935 section_realloc(sec
, c_end
);
7936 src
= sec
->data
+ c
;
7938 for(i
= 1; i
< nb_elems
; i
++) {
7940 memcpy(dst
, src
, elem_size
);
7946 #define EXPR_CONST 1
7949 /* store a value or an expression directly in global data or in local array */
7950 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
7951 int v
, int expr_type
)
7953 int saved_global_expr
, bt
, bit_pos
, bit_size
;
7955 unsigned long long bit_mask
;
7963 /* compound literals must be allocated globally in this case */
7964 saved_global_expr
= global_expr
;
7967 global_expr
= saved_global_expr
;
7968 /* NOTE: symbols are accepted */
7969 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
7970 error("initializer element is not constant");
7978 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
7981 /* XXX: not portable */
7982 /* XXX: generate error if incorrect relocation */
7983 gen_assign_cast(&dtype
);
7984 bt
= type
->t
& VT_BTYPE
;
7985 ptr
= sec
->data
+ c
;
7986 /* XXX: make code faster ? */
7987 if (!(type
->t
& VT_BITFIELD
)) {
7992 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
7993 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
7994 bit_mask
= (1LL << bit_size
) - 1;
7996 if ((vtop
->r
& VT_SYM
) &&
8002 (bt
== VT_INT
&& bit_size
!= 32)))
8003 error("initializer element is not computable at load time");
8006 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8009 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8012 *(double *)ptr
= vtop
->c
.d
;
8015 *(long double *)ptr
= vtop
->c
.ld
;
8018 *(long long *)ptr
|= (vtop
->c
.ll
& bit_mask
) << bit_pos
;
8021 if (vtop
->r
& VT_SYM
) {
8022 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
8024 *(int *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8029 vset(&dtype
, VT_LOCAL
, c
);
8036 /* put zeros for variable based init */
8037 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
8040 /* nothing to do because globals are already set to zero */
8042 vpush_global_sym(&func_old_type
, TOK_memset
);
8050 /* 't' contains the type and storage info. 'c' is the offset of the
8051 object in section 'sec'. If 'sec' is NULL, it means stack based
8052 allocation. 'first' is true if array '{' must be read (multi
8053 dimension implicit array init handling). 'size_only' is true if
8054 size only evaluation is wanted (only for arrays). */
8055 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
8056 int first
, int size_only
)
8058 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
8059 int size1
, align1
, expr_type
;
8063 if (type
->t
& VT_ARRAY
) {
8067 t1
= pointed_type(type
);
8068 size1
= type_size(t1
, &align1
);
8071 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
8077 /* only parse strings here if correct type (otherwise: handle
8078 them as ((w)char *) expressions */
8079 if ((tok
== TOK_LSTR
&&
8080 (t1
->t
& VT_BTYPE
) == VT_INT
) ||
8082 (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
8083 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8088 /* compute maximum number of chars wanted */
8090 cstr_len
= cstr
->size
;
8092 cstr_len
= cstr
->size
/ sizeof(int);
8095 if (n
>= 0 && nb
> (n
- array_length
))
8096 nb
= n
- array_length
;
8099 warning("initializer-string for array is too long");
8100 /* in order to go faster for common case (char
8101 string in global variable, we handle it
8103 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
8104 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
8108 ch
= ((unsigned char *)cstr
->data
)[i
];
8110 ch
= ((int *)cstr
->data
)[i
];
8111 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
8119 /* only add trailing zero if enough storage (no
8120 warning in this case since it is standard) */
8121 if (n
< 0 || array_length
< n
) {
8123 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
8129 while (tok
!= '}') {
8130 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
8131 if (n
>= 0 && index
>= n
)
8132 error("index too large");
8133 /* must put zero in holes (note that doing it that way
8134 ensures that it even works with designators) */
8135 if (!size_only
&& array_length
< index
) {
8136 init_putz(t1
, sec
, c
+ array_length
* size1
,
8137 (index
- array_length
) * size1
);
8140 if (index
> array_length
)
8141 array_length
= index
;
8142 /* special test for multi dimensional arrays (may not
8143 be strictly correct if designators are used at the
8145 if (index
>= n
&& no_oblock
)
8154 /* put zeros at the end */
8155 if (!size_only
&& n
>= 0 && array_length
< n
) {
8156 init_putz(t1
, sec
, c
+ array_length
* size1
,
8157 (n
- array_length
) * size1
);
8159 /* patch type size if needed */
8161 s
->c
= array_length
;
8162 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
8163 (sec
|| !first
|| tok
== '{')) {
8166 /* NOTE: the previous test is a specific case for automatic
8167 struct/union init */
8168 /* XXX: union needs only one init */
8170 /* XXX: this test is incorrect for local initializers
8171 beginning with ( without {. It would be much more difficult
8172 to do it correctly (ideally, the expression parser should
8173 be used in all cases) */
8179 while (tok
== '(') {
8183 if (!parse_btype(&type1
, &ad1
))
8185 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
8187 if (!is_assignable_types(type
, &type1
))
8188 error("invalid type for cast");
8193 if (first
|| tok
== '{') {
8202 while (tok
!= '}') {
8203 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
8205 if (!size_only
&& array_length
< index
) {
8206 init_putz(type
, sec
, c
+ array_length
,
8207 index
- array_length
);
8209 index
= index
+ type_size(&f
->type
, &align1
);
8210 if (index
> array_length
)
8211 array_length
= index
;
8213 if (no_oblock
&& f
== NULL
)
8219 /* put zeros at the end */
8220 if (!size_only
&& array_length
< n
) {
8221 init_putz(type
, sec
, c
+ array_length
,
8230 } else if (tok
== '{') {
8232 decl_initializer(type
, sec
, c
, first
, size_only
);
8234 } else if (size_only
) {
8235 /* just skip expression */
8237 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
8241 else if (tok
== ')')
8246 /* currently, we always use constant expression for globals
8247 (may change for scripting case) */
8248 expr_type
= EXPR_CONST
;
8250 expr_type
= EXPR_ANY
;
8251 init_putv(type
, sec
, c
, 0, expr_type
);
8255 /* parse an initializer for type 't' if 'has_init' is non zero, and
8256 allocate space in local or global data space ('r' is either
8257 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8258 variable 'v' of scope 'scope' is declared before initializers are
8259 parsed. If 'v' is zero, then a reference to the new object is put
8260 in the value stack. If 'has_init' is 2, a special parsing is done
8261 to handle string constants. */
8262 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
8263 int has_init
, int v
, int scope
)
8265 int size
, align
, addr
, data_offset
;
8267 ParseState saved_parse_state
;
8268 TokenString init_str
;
8271 size
= type_size(type
, &align
);
8272 /* If unknown size, we must evaluate it before
8273 evaluating initializers because
8274 initializers can generate global data too
8275 (e.g. string pointers or ISOC99 compound
8276 literals). It also simplifies local
8277 initializers handling */
8278 tok_str_new(&init_str
);
8281 error("unknown type size");
8282 /* get all init string */
8283 if (has_init
== 2) {
8284 /* only get strings */
8285 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8286 tok_str_add_tok(&init_str
);
8291 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
8293 error("unexpected end of file in initializer");
8294 tok_str_add_tok(&init_str
);
8297 else if (tok
== '}') {
8305 tok_str_add(&init_str
, -1);
8306 tok_str_add(&init_str
, 0);
8309 save_parse_state(&saved_parse_state
);
8311 macro_ptr
= init_str
.str
;
8313 decl_initializer(type
, NULL
, 0, 1, 1);
8314 /* prepare second initializer parsing */
8315 macro_ptr
= init_str
.str
;
8318 /* if still unknown size, error */
8319 size
= type_size(type
, &align
);
8321 error("unknown type size");
8323 /* take into account specified alignment if bigger */
8324 if (ad
->aligned
> align
)
8325 align
= ad
->aligned
;
8326 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
8328 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
8330 loc
= (loc
- size
) & -align
;
8332 /* handles bounds */
8333 /* XXX: currently, since we do only one pass, we cannot track
8334 '&' operators, so we add only arrays */
8335 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
8336 unsigned long *bounds_ptr
;
8337 /* add padding between regions */
8339 /* then add local bound info */
8340 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
8341 bounds_ptr
[0] = addr
;
8342 bounds_ptr
[1] = size
;
8345 /* local variable */
8346 sym_push(v
, type
, r
, addr
);
8348 /* push local reference */
8349 vset(type
, r
, addr
);
8355 if (v
&& scope
== VT_CONST
) {
8356 /* see if the symbol was already defined */
8359 if (!is_compatible_types(&sym
->type
, type
))
8360 error("incompatible types for redefinition of '%s'",
8361 get_tok_str(v
, NULL
));
8362 if (sym
->type
.t
& VT_EXTERN
) {
8363 /* if the variable is extern, it was not allocated */
8364 sym
->type
.t
&= ~VT_EXTERN
;
8366 /* we accept several definitions of the same
8367 global variable. this is tricky, because we
8368 must play with the SHN_COMMON type of the symbol */
8369 /* XXX: should check if the variable was already
8370 initialized. It is incorrect to initialized it
8372 /* no init data, we won't add more to the symbol */
8379 /* allocate symbol in corresponding section */
8386 data_offset
= sec
->data_offset
;
8387 data_offset
= (data_offset
+ align
- 1) & -align
;
8389 /* very important to increment global pointer at this time
8390 because initializers themselves can create new initializers */
8391 data_offset
+= size
;
8392 /* add padding if bound check */
8393 if (do_bounds_check
)
8395 sec
->data_offset
= data_offset
;
8396 /* allocate section space to put the data */
8397 if (sec
->sh_type
!= SHT_NOBITS
&&
8398 data_offset
> sec
->data_allocated
)
8399 section_realloc(sec
, data_offset
);
8401 addr
= 0; /* avoid warning */
8405 if (scope
== VT_CONST
) {
8410 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
8412 /* update symbol definition */
8414 put_extern_sym(sym
, sec
, addr
, size
);
8417 /* put a common area */
8418 put_extern_sym(sym
, NULL
, align
, size
);
8419 /* XXX: find a nicer way */
8420 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
8421 esym
->st_shndx
= SHN_COMMON
;
8426 /* push global reference */
8427 sym
= get_sym_ref(type
, sec
, addr
, size
);
8429 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
8433 /* handles bounds now because the symbol must be defined
8434 before for the relocation */
8435 if (do_bounds_check
) {
8436 unsigned long *bounds_ptr
;
8438 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
8439 /* then add global bound info */
8440 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
8441 bounds_ptr
[0] = 0; /* relocated */
8442 bounds_ptr
[1] = size
;
8446 decl_initializer(type
, sec
, addr
, 1, 0);
8447 /* restore parse state if needed */
8449 tok_str_free(init_str
.str
);
8450 restore_parse_state(&saved_parse_state
);
8456 void put_func_debug(Sym
*sym
)
8461 /* XXX: we put here a dummy type */
8462 snprintf(buf
, sizeof(buf
), "%s:%c1",
8463 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
8464 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
8465 cur_text_section
, sym
->c
);
8470 /* not finished : try to put some local vars in registers */
8471 //#define CONFIG_REG_VARS
8473 #ifdef CONFIG_REG_VARS
8474 void add_var_ref(int t
)
8476 printf("%s:%d: &%s\n",
8477 file
->filename
, file
->line_num
,
8478 get_tok_str(t
, NULL
));
8481 /* first pass on a function with heuristic to extract variable usage
8482 and pointer references to local variables for register allocation */
8483 void analyse_function(void)
8490 /* any symbol coming after '&' is considered as being a
8491 variable whose reference is taken. It is highly unaccurate
8492 but it is difficult to do better without a complete parse */
8495 /* if '& number', then no need to examine next tokens */
8496 if (tok
== TOK_CINT
||
8498 tok
== TOK_CLLONG
||
8499 tok
== TOK_CULLONG
) {
8501 } else if (tok
>= TOK_UIDENT
) {
8502 /* if '& ident [' or '& ident ->', then ident address
8506 if (tok
!= '[' && tok
!= TOK_ARROW
)
8510 while (tok
!= '}' && tok
!= ';' &&
8511 !((tok
== ',' || tok
== ')') && level
== 0)) {
8512 if (tok
>= TOK_UIDENT
) {
8514 } else if (tok
== '(') {
8516 } else if (tok
== ')') {
8529 /* parse an old style function declaration list */
8530 /* XXX: check multiple parameter */
8531 static void func_decl_list(Sym
*func_sym
)
8538 /* parse each declaration */
8539 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
) {
8540 if (!parse_btype(&btype
, &ad
))
8541 expect("declaration list");
8542 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
8543 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
8545 /* we accept no variable after */
8549 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8550 /* find parameter in function parameter list */
8553 if ((s
->v
& ~SYM_FIELD
) == v
)
8557 error("declaration for parameter '%s' but no such parameter",
8558 get_tok_str(v
, NULL
));
8560 /* check that no storage specifier except 'register' was given */
8561 if (type
.t
& VT_STORAGE
)
8562 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
8563 convert_parameter_type(&type
);
8564 /* we can add the type (NOTE: it could be local to the function) */
8566 /* accept other parameters */
8577 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
8578 static void decl(int l
)
8586 if (!parse_btype(&btype
, &ad
)) {
8587 /* skip redundant ';' */
8588 /* XXX: find more elegant solution */
8593 /* special test for old K&R protos without explicit int
8594 type. Only accepted when defining global data */
8595 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
8599 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
8600 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
8602 /* we accept no variable after */
8606 while (1) { /* iterate thru each declaration */
8608 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8612 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
8613 printf("type = '%s'\n", buf
);
8616 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8617 /* if old style function prototype, we accept a
8620 if (sym
->c
== FUNC_OLD
)
8621 func_decl_list(sym
);
8625 #ifdef CONFIG_REG_VARS
8626 TokenString func_str
;
8627 ParseState saved_parse_state
;
8632 error("cannot use local functions");
8633 if (!(type
.t
& VT_FUNC
))
8634 expect("function definition");
8636 /* reject abstract declarators in function definition */
8638 while ((sym
= sym
->next
) != NULL
)
8639 if (!(sym
->v
& ~SYM_FIELD
))
8640 expect("identifier");
8642 /* XXX: cannot do better now: convert extern line to static inline */
8643 if ((type
.t
& (VT_EXTERN
| VT_INLINE
)) == (VT_EXTERN
| VT_INLINE
))
8644 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
8646 #ifdef CONFIG_REG_VARS
8647 /* parse all function code and record it */
8649 tok_str_new(&func_str
);
8655 error("unexpected end of file");
8656 tok_str_add_tok(&func_str
);
8661 } else if (t
== '}') {
8663 if (block_level
== 0)
8667 tok_str_add(&func_str
, -1);
8668 tok_str_add(&func_str
, 0);
8670 save_parse_state(&saved_parse_state
);
8672 macro_ptr
= func_str
.str
;
8677 /* compute text section */
8678 cur_text_section
= ad
.section
;
8679 if (!cur_text_section
)
8680 cur_text_section
= text_section
;
8681 ind
= cur_text_section
->data_offset
;
8682 funcname
= get_tok_str(v
, NULL
);
8685 /* if symbol is already defined, then put complete type */
8688 /* put function symbol */
8689 sym
= global_identifier_push(v
, type
.t
, 0);
8690 sym
->type
.ref
= type
.ref
;
8692 /* NOTE: we patch the symbol size later */
8693 put_extern_sym(sym
, cur_text_section
, ind
, 0);
8695 sym
->r
= VT_SYM
| VT_CONST
;
8696 /* put debug symbol */
8698 put_func_debug(sym
);
8699 /* push a dummy symbol to enable local sym storage */
8700 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
8701 gfunc_prolog(&type
);
8703 #ifdef CONFIG_REG_VARS
8704 macro_ptr
= func_str
.str
;
8707 block(NULL
, NULL
, NULL
, NULL
, 0, 0);
8710 cur_text_section
->data_offset
= ind
;
8711 label_pop(&global_label_stack
, NULL
);
8712 sym_pop(&local_stack
, NULL
); /* reset local stack */
8713 /* end of function */
8714 /* patch symbol size */
8715 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
8718 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
8720 funcname
= ""; /* for safety */
8721 func_vt
.t
= VT_VOID
; /* for safety */
8722 ind
= 0; /* for safety */
8724 #ifdef CONFIG_REG_VARS
8725 tok_str_free(func_str
.str
);
8726 restore_parse_state(&saved_parse_state
);
8730 if (btype
.t
& VT_TYPEDEF
) {
8731 /* save typedefed type */
8732 /* XXX: test storage specifiers ? */
8733 sym
= sym_push(v
, &type
, 0, 0);
8734 sym
->type
.t
|= VT_TYPEDEF
;
8735 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8736 /* external function definition */
8737 external_sym(v
, &type
, 0);
8739 /* not lvalue if array */
8741 if (!(type
.t
& VT_ARRAY
))
8742 r
|= lvalue_type(type
.t
);
8743 has_init
= (tok
== '=');
8744 if ((btype
.t
& VT_EXTERN
) ||
8745 ((type
.t
& VT_ARRAY
) && (type
.t
& VT_STATIC
) &&
8746 !has_init
&& l
== VT_CONST
&& type
.ref
->c
< 0)) {
8747 /* external variable */
8748 /* NOTE: as GCC, uninitialized global static
8749 arrays of null size are considered as
8751 external_sym(v
, &type
, r
);
8753 if (type
.t
& VT_STATIC
)
8759 decl_initializer_alloc(&type
, &ad
, r
,
8773 /* better than nothing, but needs extension to handle '-E' option
8775 static void preprocess_init(TCCState
*s1
)
8777 s1
->include_stack_ptr
= s1
->include_stack
;
8778 /* XXX: move that before to avoid having to initialize
8779 file->ifdef_stack_ptr ? */
8780 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
8781 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
8783 /* XXX: not ANSI compliant: bound checking says error */
8787 /* compile the C file opened in 'file'. Return non zero if errors. */
8788 static int tcc_compile(TCCState
*s1
)
8792 volatile int section_sym
;
8795 printf("%s: **** new file\n", file
->filename
);
8797 preprocess_init(s1
);
8800 anon_sym
= SYM_FIRST_ANOM
;
8802 /* file info: full path + filename */
8803 section_sym
= 0; /* avoid warning */
8805 section_sym
= put_elf_sym(symtab_section
, 0, 0,
8806 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
8807 text_section
->sh_num
, NULL
);
8808 getcwd(buf
, sizeof(buf
));
8809 pstrcat(buf
, sizeof(buf
), "/");
8810 put_stabs_r(buf
, N_SO
, 0, 0,
8811 text_section
->data_offset
, text_section
, section_sym
);
8812 put_stabs_r(file
->filename
, N_SO
, 0, 0,
8813 text_section
->data_offset
, text_section
, section_sym
);
8815 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8816 symbols can be safely used */
8817 put_elf_sym(symtab_section
, 0, 0,
8818 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
8819 SHN_ABS
, file
->filename
);
8821 /* define some often used types */
8822 int_type
.t
= VT_INT
;
8824 char_pointer_type
.t
= VT_BYTE
;
8825 mk_pointer(&char_pointer_type
);
8827 func_old_type
.t
= VT_FUNC
;
8828 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
8831 /* define 'void *alloca(unsigned int)' builtin function */
8836 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
8837 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
8840 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
8844 define_start
= define_stack
;
8846 if (setjmp(s1
->error_jmp_buf
) == 0) {
8848 s1
->error_set_jmp_enabled
= 1;
8850 ch
= file
->buf_ptr
[0];
8851 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
8852 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
;
8856 expect("declaration");
8858 /* end of translation unit info */
8860 put_stabs_r(NULL
, N_SO
, 0, 0,
8861 text_section
->data_offset
, text_section
, section_sym
);
8864 s1
->error_set_jmp_enabled
= 0;
8866 /* reset define stack, but leave -Dsymbols (may be incorrect if
8867 they are undefined) */
8868 free_defines(define_start
);
8870 sym_pop(&global_stack
, NULL
);
8872 return s1
->nb_errors
!= 0 ? -1 : 0;
8876 int tcc_compile_string(TCCState
*s
, const char *str
)
8878 BufferedFile bf1
, *bf
= &bf1
;
8882 /* init file structure */
8884 /* XXX: avoid copying */
8886 buf
= tcc_malloc(len
+ 1);
8889 memcpy(buf
, str
, len
);
8892 bf
->buf_end
= buf
+ len
;
8893 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
8897 ret
= tcc_compile(s
);
8901 /* currently, no need to close */
8906 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
8907 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
8909 BufferedFile bf1
, *bf
= &bf1
;
8911 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
8912 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
8916 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
8918 /* init file structure */
8920 bf
->buf_ptr
= bf
->buffer
;
8921 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
8922 *bf
->buf_end
= CH_EOB
;
8923 bf
->filename
[0] = '\0';
8927 s1
->include_stack_ptr
= s1
->include_stack
;
8929 /* parse with define parser */
8930 ch
= file
->buf_ptr
[0];
8936 /* undefine a preprocessor symbol */
8937 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
8941 ts
= tok_alloc(sym
, strlen(sym
));
8942 s
= define_find(ts
->tok
);
8943 /* undefine symbol by putting an invalid name */
8948 #ifdef CONFIG_TCC_ASM
8950 #ifdef TCC_TARGET_I386
8951 #include "i386-asm.c"
8956 static void asm_instr(void)
8958 error("inline asm() not supported");
8964 /* print the position in the source file of PC value 'pc' by reading
8965 the stabs debug information */
8966 static void rt_printline(unsigned long wanted_pc
)
8968 Stab_Sym
*sym
, *sym_end
;
8969 char func_name
[128], last_func_name
[128];
8970 unsigned long func_addr
, last_pc
, pc
;
8971 const char *incl_files
[INCLUDE_STACK_SIZE
];
8972 int incl_index
, len
, last_line_num
, i
;
8973 const char *str
, *p
;
8975 fprintf(stderr
, "0x%08lx:", wanted_pc
);
8977 func_name
[0] = '\0';
8980 last_func_name
[0] = '\0';
8981 last_pc
= 0xffffffff;
8983 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
8984 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
8985 while (sym
< sym_end
) {
8986 switch(sym
->n_type
) {
8987 /* function start or end */
8989 if (sym
->n_strx
== 0) {
8990 /* we test if between last line and end of function */
8991 pc
= sym
->n_value
+ func_addr
;
8992 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
8994 func_name
[0] = '\0';
8997 str
= stabstr_section
->data
+ sym
->n_strx
;
8998 p
= strchr(str
, ':');
9000 pstrcpy(func_name
, sizeof(func_name
), str
);
9003 if (len
> sizeof(func_name
) - 1)
9004 len
= sizeof(func_name
) - 1;
9005 memcpy(func_name
, str
, len
);
9006 func_name
[len
] = '\0';
9008 func_addr
= sym
->n_value
;
9011 /* line number info */
9013 pc
= sym
->n_value
+ func_addr
;
9014 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9017 last_line_num
= sym
->n_desc
;
9019 strcpy(last_func_name
, func_name
);
9023 str
= stabstr_section
->data
+ sym
->n_strx
;
9025 if (incl_index
< INCLUDE_STACK_SIZE
) {
9026 incl_files
[incl_index
++] = str
;
9034 if (sym
->n_strx
== 0) {
9035 incl_index
= 0; /* end of translation unit */
9037 str
= stabstr_section
->data
+ sym
->n_strx
;
9038 /* do not add path */
9040 if (len
> 0 && str
[len
- 1] != '/')
9048 /* second pass: we try symtab symbols (no line number info) */
9051 Elf32_Sym
*sym
, *sym_end
;
9054 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
9055 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
9058 type
= ELF32_ST_TYPE(sym
->st_info
);
9059 if (type
== STT_FUNC
) {
9060 if (wanted_pc
>= sym
->st_value
&&
9061 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
9062 pstrcpy(last_func_name
, sizeof(last_func_name
),
9063 strtab_section
->data
+ sym
->st_name
);
9069 /* did not find any info: */
9070 fprintf(stderr
, " ???\n");
9073 if (last_func_name
[0] != '\0') {
9074 fprintf(stderr
, " %s()", last_func_name
);
9076 if (incl_index
> 0) {
9077 fprintf(stderr
, " (%s:%d",
9078 incl_files
[incl_index
- 1], last_line_num
);
9079 for(i
= incl_index
- 2; i
>= 0; i
--)
9080 fprintf(stderr
, ", included from %s", incl_files
[i
]);
9081 fprintf(stderr
, ")");
9083 fprintf(stderr
, "\n");
9090 /* fix for glibc 2.1 */
9096 /* return the PC at frame level 'level'. Return non zero if not found */
9097 static int rt_get_caller_pc(unsigned long *paddr
,
9098 ucontext_t
*uc
, int level
)
9104 #if defined(__FreeBSD__)
9105 *paddr
= uc
->uc_mcontext
.mc_eip
;
9106 #elif defined(__dietlibc__)
9107 *paddr
= uc
->uc_mcontext
.eip
;
9109 *paddr
= uc
->uc_mcontext
.gregs
[REG_EIP
];
9113 #if defined(__FreeBSD__)
9114 fp
= uc
->uc_mcontext
.mc_ebp
;
9115 #elif defined(__dietlibc__)
9116 fp
= uc
->uc_mcontext
.ebp
;
9118 fp
= uc
->uc_mcontext
.gregs
[REG_EBP
];
9120 for(i
=1;i
<level
;i
++) {
9121 /* XXX: check address validity with program info */
9122 if (fp
<= 0x1000 || fp
>= 0xc0000000)
9124 fp
= ((unsigned long *)fp
)[0];
9126 *paddr
= ((unsigned long *)fp
)[1];
9132 #warning add arch specific rt_get_caller_pc()
9134 static int rt_get_caller_pc(unsigned long *paddr
,
9135 ucontext_t
*uc
, int level
)
9141 /* emit a run time error at position 'pc' */
9142 void rt_error(ucontext_t
*uc
, const char *fmt
, ...)
9149 fprintf(stderr
, "Runtime error: ");
9150 vfprintf(stderr
, fmt
, ap
);
9151 fprintf(stderr
, "\n");
9152 for(i
=0;i
<num_callers
;i
++) {
9153 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
9156 fprintf(stderr
, "at ");
9158 fprintf(stderr
, "by ");
9165 /* signal handler for fatal errors */
9166 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
9168 ucontext_t
*uc
= puc
;
9172 switch(siginf
->si_code
) {
9175 rt_error(uc
, "division by zero");
9178 rt_error(uc
, "floating point exception");
9184 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
9185 rt_error(uc
, *rt_bound_error_msg
);
9187 rt_error(uc
, "dereferencing invalid pointer");
9190 rt_error(uc
, "illegal instruction");
9193 rt_error(uc
, "abort() called");
9196 rt_error(uc
, "caught signal %d", signum
);
9203 /* do all relocations (needed before using tcc_get_symbol()) */
9204 int tcc_relocate(TCCState
*s1
)
9211 tcc_add_runtime(s1
);
9213 build_got_entries(s1
);
9215 relocate_common_syms();
9217 /* compute relocation address : section are relocated in place. We
9218 also alloc the bss space */
9219 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9220 s
= s1
->sections
[i
];
9221 if (s
->sh_flags
& SHF_ALLOC
) {
9222 if (s
->sh_type
== SHT_NOBITS
)
9223 s
->data
= tcc_mallocz(s
->data_offset
);
9224 s
->sh_addr
= (unsigned long)s
->data
;
9228 relocate_syms(s1
, 1);
9230 if (s1
->nb_errors
!= 0)
9233 /* relocate each section */
9234 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9235 s
= s1
->sections
[i
];
9237 relocate_section(s1
, s
);
9242 /* launch the compiled program with the given arguments */
9243 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
9245 int (*prog_main
)(int, char **);
9247 if (tcc_relocate(s1
) < 0)
9250 prog_main
= tcc_get_symbol_err(s1
, "main");
9254 error("debug mode currently not available for Windows");
9256 struct sigaction sigact
;
9257 /* install TCC signal handlers to print debug info on fatal
9259 sigact
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
9260 sigact
.sa_sigaction
= sig_error
;
9261 sigemptyset(&sigact
.sa_mask
);
9262 sigaction(SIGFPE
, &sigact
, NULL
);
9263 sigaction(SIGILL
, &sigact
, NULL
);
9264 sigaction(SIGSEGV
, &sigact
, NULL
);
9265 sigaction(SIGBUS
, &sigact
, NULL
);
9266 sigaction(SIGABRT
, &sigact
, NULL
);
9270 #ifdef CONFIG_TCC_BCHECK
9271 if (do_bounds_check
) {
9272 void (*bound_init
)(void);
9274 /* set error function */
9275 rt_bound_error_msg
= (void *)tcc_get_symbol_err(s1
,
9276 "__bound_error_msg");
9278 /* XXX: use .init section so that it also work in binary ? */
9279 bound_init
= (void *)tcc_get_symbol_err(s1
, "__bound_init");
9283 return (*prog_main
)(argc
, argv
);
9286 TCCState
*tcc_new(void)
9293 s
= tcc_mallocz(sizeof(TCCState
));
9297 s
->output_type
= TCC_OUTPUT_MEMORY
;
9299 /* init isid table */
9301 isidnum_table
[i
] = isid(i
) || isnum(i
);
9303 /* add all tokens */
9305 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
9307 tok_ident
= TOK_IDENT
;
9316 ts
= tok_alloc(p
, r
- p
- 1);
9320 /* we add dummy defines for some special macros to speed up tests
9321 and to have working defined() */
9322 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
9323 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
9324 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
9325 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
9327 /* standard defines */
9328 tcc_define_symbol(s
, "__STDC__", NULL
);
9329 #if defined(TCC_TARGET_I386)
9330 tcc_define_symbol(s
, "__i386__", NULL
);
9332 #if defined(TCC_TARGET_ARM)
9333 tcc_define_symbol(s
, "__ARM_ARCH_4__", NULL
);
9334 tcc_define_symbol(s
, "__arm_elf__", NULL
);
9335 tcc_define_symbol(s
, "__arm_elf", NULL
);
9336 tcc_define_symbol(s
, "arm_elf", NULL
);
9337 tcc_define_symbol(s
, "__arm__", NULL
);
9338 tcc_define_symbol(s
, "__arm", NULL
);
9339 tcc_define_symbol(s
, "arm", NULL
);
9340 tcc_define_symbol(s
, "__APCS_32__", NULL
);
9343 tcc_define_symbol(s
, "__linux__", NULL
);
9344 tcc_define_symbol(s
, "linux", NULL
);
9346 /* tiny C specific defines */
9347 tcc_define_symbol(s
, "__TINYC__", NULL
);
9349 /* tiny C & gcc defines */
9350 tcc_define_symbol(s
, "__SIZE_TYPE__", "unsigned int");
9351 tcc_define_symbol(s
, "__PTRDIFF_TYPE__", "int");
9352 tcc_define_symbol(s
, "__WCHAR_TYPE__", "int");
9354 /* default library paths */
9355 tcc_add_library_path(s
, "/usr/local/lib");
9356 tcc_add_library_path(s
, "/usr/lib");
9357 tcc_add_library_path(s
, "/lib");
9359 /* no section zero */
9360 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
9362 /* create standard sections */
9363 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
9364 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
9365 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
9367 /* symbols are always generated for linking stage */
9368 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
9370 ".hashtab", SHF_PRIVATE
);
9371 strtab_section
= symtab_section
->link
;
9373 /* private symbol table for dynamic symbols */
9374 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
9376 ".dynhashtab", SHF_PRIVATE
);
9377 s
->alacarte_link
= 1;
9379 #ifdef CHAR_IS_UNSIGNED
9380 s
->char_is_unsigned
= 1;
9385 void tcc_delete(TCCState
*s1
)
9389 /* free -D defines */
9393 n
= tok_ident
- TOK_IDENT
;
9394 for(i
= 0; i
< n
; i
++)
9395 tcc_free(table_ident
[i
]);
9396 tcc_free(table_ident
);
9398 /* free all sections */
9400 free_section(symtab_section
->hash
);
9402 free_section(s1
->dynsymtab_section
->hash
);
9403 free_section(s1
->dynsymtab_section
->link
);
9404 free_section(s1
->dynsymtab_section
);
9406 for(i
= 1; i
< s1
->nb_sections
; i
++)
9407 free_section(s1
->sections
[i
]);
9408 tcc_free(s1
->sections
);
9410 /* free loaded dlls array */
9411 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
9412 tcc_free(s1
->loaded_dlls
[i
]);
9413 tcc_free(s1
->loaded_dlls
);
9416 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
9417 tcc_free(s1
->library_paths
[i
]);
9418 tcc_free(s1
->library_paths
);
9420 /* cached includes */
9421 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
9422 tcc_free(s1
->cached_includes
[i
]);
9423 tcc_free(s1
->cached_includes
);
9425 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
9426 tcc_free(s1
->include_paths
[i
]);
9427 tcc_free(s1
->include_paths
);
9429 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
9430 tcc_free(s1
->sysinclude_paths
[i
]);
9431 tcc_free(s1
->sysinclude_paths
);
9436 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
9440 pathname1
= tcc_strdup(pathname
);
9441 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
9445 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
9449 pathname1
= tcc_strdup(pathname
);
9450 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
9454 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
9456 const char *ext
, *filename1
;
9459 BufferedFile
*saved_file
;
9461 /* find source file type with extension */
9462 filename1
= strrchr(filename
, '/');
9466 filename1
= filename
;
9467 ext
= strrchr(filename1
, '.');
9473 file
= tcc_open(s1
, filename
);
9475 if (flags
& AFF_PRINT_ERROR
) {
9476 error_noabort("file '%s' not found", filename
);
9482 if (!ext
|| !strcmp(ext
, "c")) {
9483 /* C file assumed */
9484 ret
= tcc_compile(s1
);
9486 #ifdef CONFIG_TCC_ASM
9487 if (!strcmp(ext
, "S")) {
9488 /* preprocessed assembler */
9489 ret
= tcc_assemble(s1
, 1);
9490 } else if (!strcmp(ext
, "s")) {
9491 /* non preprocessed assembler */
9492 ret
= tcc_assemble(s1
, 0);
9497 /* assume executable format: auto guess file type */
9498 ret
= read(fd
, &ehdr
, sizeof(ehdr
));
9499 lseek(fd
, 0, SEEK_SET
);
9501 error_noabort("could not read header");
9503 } else if (ret
!= sizeof(ehdr
)) {
9504 goto try_load_script
;
9507 if (ehdr
.e_ident
[0] == ELFMAG0
&&
9508 ehdr
.e_ident
[1] == ELFMAG1
&&
9509 ehdr
.e_ident
[2] == ELFMAG2
&&
9510 ehdr
.e_ident
[3] == ELFMAG3
) {
9511 file
->line_num
= 0; /* do not display line number if error */
9512 if (ehdr
.e_type
== ET_REL
) {
9513 ret
= tcc_load_object_file(s1
, fd
, 0);
9514 } else if (ehdr
.e_type
== ET_DYN
) {
9515 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
9517 h
= dlopen(filename
, RTLD_GLOBAL
| RTLD_LAZY
);
9523 ret
= tcc_load_dll(s1
, fd
, filename
,
9524 (flags
& AFF_REFERENCED_DLL
) != 0);
9527 error_noabort("unrecognized ELF file");
9530 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
9531 file
->line_num
= 0; /* do not display line number if error */
9532 ret
= tcc_load_archive(s1
, fd
);
9534 /* as GNU ld, consider it is an ld script if not recognized */
9536 ret
= tcc_load_ldscript(s1
);
9538 error_noabort("unrecognized file type");
9553 int tcc_add_file(TCCState
*s
, const char *filename
)
9555 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
9558 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
9562 pathname1
= tcc_strdup(pathname
);
9563 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
9567 /* find and load a dll. Return non zero if not found */
9568 /* XXX: add '-rpath' option support ? */
9569 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
9574 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
9575 snprintf(buf
, sizeof(buf
), "%s/%s",
9576 s
->library_paths
[i
], filename
);
9577 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
9583 /* the library name is the same as the argument of the '-l' option */
9584 int tcc_add_library(TCCState
*s
, const char *libraryname
)
9589 /* first we look for the dynamic library if not static linking */
9590 if (!s
->static_link
) {
9591 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
9592 if (tcc_add_dll(s
, buf
, 0) == 0)
9596 /* then we look for the static library */
9597 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
9598 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
9599 s
->library_paths
[i
], libraryname
);
9600 if (tcc_add_file_internal(s
, buf
, 0) == 0)
9606 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
9608 add_elf_sym(symtab_section
, val
, 0,
9609 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
9614 int tcc_set_output_type(TCCState
*s
, int output_type
)
9618 s
->output_type
= output_type
;
9621 /* default include paths */
9622 /* XXX: reverse order needed if -isystem support */
9623 tcc_add_sysinclude_path(s
, "/usr/local/include");
9624 tcc_add_sysinclude_path(s
, "/usr/include");
9625 snprintf(buf
, sizeof(buf
), "%s/include", tcc_lib_path
);
9626 tcc_add_sysinclude_path(s
, buf
);
9629 /* if bound checking, then add corresponding sections */
9630 #ifdef CONFIG_TCC_BCHECK
9631 if (do_bounds_check
) {
9633 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
9634 /* create bounds sections */
9635 bounds_section
= new_section(s
, ".bounds",
9636 SHT_PROGBITS
, SHF_ALLOC
);
9637 lbounds_section
= new_section(s
, ".lbounds",
9638 SHT_PROGBITS
, SHF_ALLOC
);
9642 if (s
->char_is_unsigned
) {
9643 tcc_define_symbol(s
, "__CHAR_UNSIGNED__", NULL
);
9646 /* add debug sections */
9649 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
9650 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
9651 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
9652 put_elf_str(stabstr_section
, "");
9653 stab_section
->link
= stabstr_section
;
9654 /* put first entry */
9655 put_stabs("", 0, 0, 0, 0);
9658 /* add libc crt1/crti objects */
9659 if ((output_type
== TCC_OUTPUT_EXE
|| output_type
== TCC_OUTPUT_DLL
) &&
9661 if (output_type
!= TCC_OUTPUT_DLL
)
9662 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
9663 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
9668 #define WD_ALL 0x0001 /* warning is activated when using -Wall */
9669 #define FD_INVERT 0x0002 /* invert value before storing */
9671 typedef struct FlagDef
{
9677 static const FlagDef warning_defs
[] = {
9678 { offsetof(TCCState
, warn_unsupported
), 0, "unsupported" },
9679 { offsetof(TCCState
, warn_write_strings
), 0, "write-strings" },
9680 { offsetof(TCCState
, warn_error
), 0, "error" },
9681 { offsetof(TCCState
, warn_implicit_function_declaration
), WD_ALL
,
9682 "implicit-function-declaration" },
9685 static int set_flag(TCCState
*s
, const FlagDef
*flags
, int nb_flags
,
9686 const char *name
, int value
)
9693 if (r
[0] == 'n' && r
[1] == 'o' && r
[2] == '-') {
9697 for(i
= 0, p
= flags
; i
< nb_flags
; i
++, p
++) {
9698 if (!strcmp(r
, p
->name
))
9703 if (p
->flags
& FD_INVERT
)
9705 *(int *)((uint8_t *)s
+ p
->offset
) = value
;
9710 /* set/reset a warning */
9711 int tcc_set_warning(TCCState
*s
, const char *warning_name
, int value
)
9716 if (!strcmp(warning_name
, "all")) {
9717 for(i
= 0, p
= warning_defs
; i
< countof(warning_defs
); i
++, p
++) {
9718 if (p
->flags
& WD_ALL
)
9719 *(int *)((uint8_t *)s
+ p
->offset
) = 1;
9723 return set_flag(s
, warning_defs
, countof(warning_defs
),
9724 warning_name
, value
);
9728 static const FlagDef flag_defs
[] = {
9729 { offsetof(TCCState
, char_is_unsigned
), 0, "unsigned-char" },
9730 { offsetof(TCCState
, char_is_unsigned
), FD_INVERT
, "signed-char" },
9733 /* set/reset a flag */
9734 int tcc_set_flag(TCCState
*s
, const char *flag_name
, int value
)
9736 return set_flag(s
, flag_defs
, countof(flag_defs
),
9740 #if !defined(LIBTCC)
9742 /* extract the basename of a file */
9743 static const char *tcc_basename(const char *name
)
9746 p
= strrchr(name
, '/');
9749 p
= strrchr(name
, '\\');
9758 static int64_t getclock_us(void)
9763 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
9766 gettimeofday(&tv
, NULL
);
9767 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
9773 printf("tcc version " TCC_VERSION
" - Tiny C Compiler - Copyright (C) 2001-2003 Fabrice Bellard\n"
9774 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
9775 " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
9776 " [infile1 infile2...] [-run infile args...]\n"
9778 "General options:\n"
9779 " -v display current version\n"
9780 " -c compile only - generate an object file\n"
9781 " -o outfile set output filename\n"
9782 " -Bdir set tcc internal library path\n"
9783 " -bench output compilation statistics\n"
9784 " -run run compiled source\n"
9785 " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
9786 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
9787 " -w disable all warnings\n"
9788 "Preprocessor options:\n"
9789 " -Idir add include path 'dir'\n"
9790 " -Dsym[=val] define 'sym' with value 'val'\n"
9791 " -Usym undefine 'sym'\n"
9793 " -Ldir add library path 'dir'\n"
9794 " -llib link with dynamic or static library 'lib'\n"
9795 " -shared generate a shared library\n"
9796 " -static static linking\n"
9797 " -rdynamic export all global symbols to dynamic linker\n"
9798 " -r relocatable output\n"
9799 "Debugger options:\n"
9800 " -g generate runtime debug info\n"
9801 #ifdef CONFIG_TCC_BCHECK
9802 " -b compile with built-in memory and bounds checker (implies -g)\n"
9804 " -bt N show N callers in stack traces\n"
9808 #define TCC_OPTION_HAS_ARG 0x0001
9809 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
9811 typedef struct TCCOption
{
9838 TCC_OPTION_nostdinc
,
9839 TCC_OPTION_nostdlib
,
9840 TCC_OPTION_print_search_dirs
,
9841 TCC_OPTION_rdynamic
,
9847 static const TCCOption tcc_options
[] = {
9848 { "h", TCC_OPTION_HELP
, 0 },
9849 { "?", TCC_OPTION_HELP
, 0 },
9850 { "I", TCC_OPTION_I
, TCC_OPTION_HAS_ARG
},
9851 { "D", TCC_OPTION_D
, TCC_OPTION_HAS_ARG
},
9852 { "U", TCC_OPTION_U
, TCC_OPTION_HAS_ARG
},
9853 { "L", TCC_OPTION_L
, TCC_OPTION_HAS_ARG
},
9854 { "B", TCC_OPTION_B
, TCC_OPTION_HAS_ARG
},
9855 { "l", TCC_OPTION_l
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9856 { "bench", TCC_OPTION_bench
, 0 },
9857 { "bt", TCC_OPTION_bt
, TCC_OPTION_HAS_ARG
},
9858 #ifdef CONFIG_TCC_BCHECK
9859 { "b", TCC_OPTION_b
, 0 },
9861 { "g", TCC_OPTION_g
, 0 },
9862 { "c", TCC_OPTION_c
, 0 },
9863 { "static", TCC_OPTION_static
, 0 },
9864 { "shared", TCC_OPTION_shared
, 0 },
9865 { "o", TCC_OPTION_o
, TCC_OPTION_HAS_ARG
},
9866 { "run", TCC_OPTION_run
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9867 { "rdynamic", TCC_OPTION_rdynamic
, 0 },
9868 { "r", TCC_OPTION_r
, 0 },
9869 { "W", TCC_OPTION_W
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9870 { "O", TCC_OPTION_O
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9871 { "m", TCC_OPTION_m
, TCC_OPTION_HAS_ARG
},
9872 { "f", TCC_OPTION_f
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
9873 { "nostdinc", TCC_OPTION_nostdinc
, 0 },
9874 { "nostdlib", TCC_OPTION_nostdlib
, 0 },
9875 { "print-search-dirs", TCC_OPTION_print_search_dirs
, 0 },
9876 { "v", TCC_OPTION_v
, 0 },
9877 { "w", TCC_OPTION_w
, 0 },
9881 /* convert 'str' into an array of space separated strings */
9882 static int expand_args(char ***pargv
, const char *str
)
9891 while (is_space(*str
))
9896 while (*str
!= '\0' && !is_space(*str
))
9899 arg
= tcc_malloc(len
+ 1);
9900 memcpy(arg
, s1
, len
);
9902 dynarray_add((void ***)&argv
, &argc
, arg
);
9908 static char **files
;
9909 static int nb_files
, nb_libraries
;
9910 static int multiple_files
;
9911 static int print_search_dirs
;
9912 static int output_type
;
9913 static int reloc_output
;
9914 static const char *outfile
;
9916 int parse_args(TCCState
*s
, int argc
, char **argv
)
9919 const TCCOption
*popt
;
9920 const char *optarg
, *p1
, *r1
;
9925 if (optind
>= argc
) {
9926 if (nb_files
== 0 && !print_search_dirs
)
9933 /* add a new file */
9934 dynarray_add((void ***)&files
, &nb_files
, r
);
9935 if (!multiple_files
) {
9937 /* argv[0] will be this file */
9941 /* find option in table (match only the first chars */
9946 error("invalid option -- '%s'", r
);
9959 if (popt
->flags
& TCC_OPTION_HAS_ARG
) {
9960 if (*r1
!= '\0' || (popt
->flags
& TCC_OPTION_NOSEP
)) {
9964 error("argument to '%s' is missing", r
);
9965 optarg
= argv
[optind
++];
9973 switch(popt
->index
) {
9974 case TCC_OPTION_HELP
:
9979 if (tcc_add_include_path(s
, optarg
) < 0)
9980 error("too many include paths");
9985 sym
= (char *)optarg
;
9986 value
= strchr(sym
, '=');
9991 tcc_define_symbol(s
, sym
, value
);
9995 tcc_undefine_symbol(s
, optarg
);
9998 tcc_add_library_path(s
, optarg
);
10001 /* set tcc utilities path (mainly for tcc development) */
10002 tcc_lib_path
= optarg
;
10005 dynarray_add((void ***)&files
, &nb_files
, r
);
10008 case TCC_OPTION_bench
:
10011 case TCC_OPTION_bt
:
10012 num_callers
= atoi(optarg
);
10014 #ifdef CONFIG_TCC_BCHECK
10016 do_bounds_check
= 1;
10024 multiple_files
= 1;
10025 output_type
= TCC_OUTPUT_OBJ
;
10027 case TCC_OPTION_static
:
10028 s
->static_link
= 1;
10030 case TCC_OPTION_shared
:
10031 output_type
= TCC_OUTPUT_DLL
;
10034 multiple_files
= 1;
10038 /* generate a .o merging several output files */
10040 output_type
= TCC_OUTPUT_OBJ
;
10042 case TCC_OPTION_nostdinc
:
10045 case TCC_OPTION_nostdlib
:
10048 case TCC_OPTION_print_search_dirs
:
10049 print_search_dirs
= 1;
10051 case TCC_OPTION_run
:
10055 argc1
= expand_args(&argv1
, optarg
);
10057 parse_args(s
, argc1
, argv1
);
10059 multiple_files
= 0;
10060 output_type
= TCC_OUTPUT_MEMORY
;
10064 printf("tcc version %s\n", TCC_VERSION
);
10067 if (tcc_set_flag(s
, optarg
, 1) < 0 && s
->warn_unsupported
)
10068 goto unsupported_option
;
10071 if (tcc_set_warning(s
, optarg
, 1) < 0 &&
10072 s
->warn_unsupported
)
10073 goto unsupported_option
;
10078 case TCC_OPTION_rdynamic
:
10082 if (s
->warn_unsupported
) {
10083 unsupported_option
:
10084 warning("unsupported option '%s'", r
);
10093 int main(int argc
, char **argv
)
10097 int nb_objfiles
, ret
, optind
;
10098 char objfilename
[1024];
10099 int64_t start_time
= 0;
10102 output_type
= TCC_OUTPUT_EXE
;
10104 multiple_files
= 1;
10109 print_search_dirs
= 0;
10111 optind
= parse_args(s
, argc
- 1, argv
+ 1) + 1;
10113 if (print_search_dirs
) {
10114 /* enough for Linux kernel */
10115 printf("install: %s/\n", tcc_lib_path
);
10119 nb_objfiles
= nb_files
- nb_libraries
;
10121 /* if outfile provided without other options, we output an
10123 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
10124 output_type
= TCC_OUTPUT_EXE
;
10126 /* check -c consistency : only single file handled. XXX: checks file type */
10127 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
10128 /* accepts only a single input file */
10129 if (nb_objfiles
!= 1)
10130 error("cannot specify multiple files with -c");
10131 if (nb_libraries
!= 0)
10132 error("cannot specify libraries with -c");
10135 /* compute default outfile name */
10136 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
10137 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
10140 pstrcpy(objfilename
, sizeof(objfilename
) - 1,
10141 tcc_basename(files
[0]));
10142 /* add .o extension */
10143 ext
= strrchr(objfilename
, '.');
10145 goto default_outfile
;
10146 strcpy(ext
+ 1, "o");
10149 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
10151 outfile
= objfilename
;
10155 start_time
= getclock_us();
10158 tcc_set_output_type(s
, output_type
);
10160 /* compile or add each files or library */
10161 for(i
= 0;i
< nb_files
; i
++) {
10162 const char *filename
;
10164 filename
= files
[i
];
10165 if (filename
[0] == '-') {
10166 if (tcc_add_library(s
, filename
+ 2) < 0)
10167 error("cannot find %s", filename
);
10169 if (tcc_add_file(s
, filename
) < 0) {
10176 /* free all files */
10181 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
10182 if (total_time
< 0.001)
10183 total_time
= 0.001;
10184 if (total_bytes
< 1)
10186 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
10187 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
10188 total_time
, (int)(total_lines
/ total_time
),
10189 total_bytes
/ total_time
/ 1000000.0);
10192 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
10193 tcc_output_file(s
, outfile
);
10196 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
10199 /* XXX: cannot do it with bound checking because of the malloc hooks */
10200 if (!do_bounds_check
)
10205 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);