2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 #include <sys/timeb.h>
37 #define CONFIG_TCC_STATIC
41 #include <sys/ucontext.h>
45 #ifndef CONFIG_TCC_STATIC
53 /* preprocessor debug */
55 /* include file debug */
63 /* target selection */
64 //#define TCC_TARGET_I386 /* i386 code generator */
65 //#define TCC_TARGET_ARM /* ARMv4 code generator */
66 //#define TCC_TARGET_C67 /* TMS320C67xx code generator */
68 /* default target is I386 */
69 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
70 !defined(TCC_TARGET_C67)
71 #define TCC_TARGET_I386
74 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
75 !defined(TCC_TARGET_C67)
76 #define CONFIG_TCC_BCHECK /* enable bound checking code */
79 /* define it to include assembler support */
80 #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
81 #define CONFIG_TCC_ASM
84 /* object format selection */
85 #if defined(TCC_TARGET_C67)
86 #define TCC_TARGET_COFF
95 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
96 executables or dlls */
97 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
99 #define INCLUDE_STACK_SIZE 32
100 #define IFDEF_STACK_SIZE 64
101 #define VSTACK_SIZE 64
102 #define STRING_MAX_SIZE 1024
104 #define TOK_HASH_SIZE 2048 /* must be a power of two */
105 #define TOK_ALLOC_INCR 512 /* must be a power of two */
106 #define TOK_STR_ALLOC_INCR_BITS 6
107 #define TOK_STR_ALLOC_INCR (1 << TOK_STR_ALLOC_INCR_BITS)
108 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
110 /* token symbol management */
111 typedef struct TokenSym
{
112 struct TokenSym
*hash_next
;
113 struct Sym
*sym_define
; /* direct pointer to define */
114 struct Sym
*sym_label
; /* direct pointer to label */
115 struct Sym
*sym_struct
; /* direct pointer to structure */
116 struct Sym
*sym_identifier
; /* direct pointer to identifier */
117 int tok
; /* token number */
122 typedef struct CString
{
123 int size
; /* size in bytes */
124 void *data
; /* either 'char *' or 'int *' */
126 void *data_allocated
; /* if non NULL, data has been malloced */
129 /* type definition */
130 typedef struct CType
{
136 typedef union CValue
{
142 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
144 unsigned long long ull
;
145 struct CString
*cstr
;
151 typedef struct SValue
{
152 CType type
; /* type */
153 unsigned short r
; /* register + flags */
154 unsigned short r2
; /* second register, used for 'long long'
155 type. If not used, set to VT_CONST */
156 CValue c
; /* constant, if VT_CONST */
157 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
160 /* symbol management */
162 int v
; /* symbol token */
163 int r
; /* associated register */
164 int c
; /* associated number */
165 CType type
; /* associated type */
166 struct Sym
*next
; /* next related symbol */
167 struct Sym
*prev
; /* prev symbol in stack */
168 struct Sym
*prev_tok
; /* previous symbol for this token */
171 /* section definition */
172 /* XXX: use directly ELF structure for parameters ? */
173 /* special flag to indicate that the section should not be linked to
175 #define SHF_PRIVATE 0x80000000
177 typedef struct Section
{
178 unsigned long data_offset
; /* current data offset */
179 unsigned char *data
; /* section data */
180 unsigned long data_allocated
; /* used for realloc() handling */
181 int sh_name
; /* elf section name (only used during output) */
182 int sh_num
; /* elf section number */
183 int sh_type
; /* elf section type */
184 int sh_flags
; /* elf section flags */
185 int sh_info
; /* elf section info */
186 int sh_addralign
; /* elf section alignment */
187 int sh_entsize
; /* elf entry size */
188 unsigned long sh_size
; /* section size (only used during output) */
189 unsigned long sh_addr
; /* address at which the section is relocated */
190 unsigned long sh_offset
; /* address at which the section is relocated */
191 int nb_hashed_syms
; /* used to resize the hash table */
192 struct Section
*link
; /* link to another section */
193 struct Section
*reloc
; /* corresponding section for relocation, if any */
194 struct Section
*hash
; /* hash table for symbols */
195 struct Section
*next
;
196 char name
[1]; /* section name */
199 typedef struct DLLReference
{
204 /* GNUC attribute definition */
205 typedef struct AttributeDef
{
208 unsigned char func_call
; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */
211 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
212 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
213 #define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
215 /* stored in 'Sym.c' field */
216 #define FUNC_NEW 1 /* ansi function prototype */
217 #define FUNC_OLD 2 /* old function prototype */
218 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
220 /* stored in 'Sym.r' field */
221 #define FUNC_CDECL 0 /* standard c call */
222 #define FUNC_STDCALL 1 /* pascal c call */
223 #define FUNC_FASTCALL1 2 /* first param in %eax */
224 #define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
225 #define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
227 /* field 'Sym.t' for macros */
228 #define MACRO_OBJ 0 /* object like macro */
229 #define MACRO_FUNC 1 /* function like macro */
231 /* field 'Sym.r' for C labels */
232 #define LABEL_DEFINED 0 /* label is defined */
233 #define LABEL_FORWARD 1 /* label is forward defined */
234 #define LABEL_DECLARED 2 /* label is declared but never used */
236 /* type_decl() types */
237 #define TYPE_ABSTRACT 1 /* type without variable */
238 #define TYPE_DIRECT 2 /* type with variable */
240 #define IO_BUF_SIZE 8192
242 typedef struct BufferedFile
{
246 int line_num
; /* current line number - here to simplify code */
247 int ifndef_macro
; /* #ifndef macro / #endif search */
248 int ifndef_macro_saved
; /* saved ifndef_macro */
249 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
250 char inc_type
; /* type of include */
251 char inc_filename
[512]; /* filename specified by the user */
252 char filename
[1024]; /* current filename - here to simplify code */
253 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
256 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
257 #define CH_EOF (-1) /* end of file */
259 /* parsing state (used to save parser state to reparse part of the
260 source several times) */
261 typedef struct ParseState
{
268 /* used to record tokens */
269 typedef struct TokenString
{
276 /* include file cache, used to find files faster and also to eliminate
277 inclusion if the include file is protected by #ifndef ... #endif */
278 typedef struct CachedInclude
{
280 char type
; /* '"' or '>' to give include type */
281 char filename
[1]; /* path specified in #include */
285 static struct BufferedFile
*file
;
288 static CString tokcstr
; /* current parsed string, if any */
289 /* additional informations about token */
290 static int tok_flags
;
291 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
292 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
293 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
295 static int *macro_ptr
, *macro_ptr_allocated
;
296 static int *unget_saved_macro_ptr
;
297 static int unget_saved_buffer
[TOK_MAX_SIZE
+ 1];
298 static int unget_buffer_enabled
;
299 static int parse_flags
;
300 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
301 #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
302 #define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
303 token. line feed is also
305 #define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
307 static Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
308 static Section
*cur_text_section
; /* current section where function code is
310 static Section
*last_text_section
; /* to handle .previous asm directive */
311 /* bound check related sections */
312 static Section
*bounds_section
; /* contains global data bound description */
313 static Section
*lbounds_section
; /* contains local data bound description */
314 /* symbol sections */
315 static Section
*symtab_section
, *strtab_section
;
318 static Section
*stab_section
, *stabstr_section
;
320 /* loc : local variable index
321 ind : output code index
323 anon_sym: anonymous symbol index
325 static int rsym
, anon_sym
, ind
, loc
;
326 /* expression generation modifiers */
327 static int const_wanted
; /* true if constant wanted */
328 static int nocode_wanted
; /* true if no code generation wanted for an expression */
329 static int global_expr
; /* true if compound literals must be allocated
330 globally (used during initializers parsing */
331 static CType func_vt
; /* current function return type (used by return
334 static int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
335 static int tok_ident
;
336 static TokenSym
**table_ident
;
337 static TokenSym
*hash_ident
[TOK_HASH_SIZE
];
338 static char token_buf
[STRING_MAX_SIZE
+ 1];
339 static char *funcname
;
340 static Sym
*global_stack
, *local_stack
;
341 static Sym
*define_stack
;
342 static Sym
*global_label_stack
, *local_label_stack
;
344 static SValue vstack
[VSTACK_SIZE
], *vtop
;
345 /* some predefined types */
346 static CType char_pointer_type
, func_old_type
, int_type
;
347 /* true if isid(c) || isnum(c) */
348 static unsigned char isidnum_table
[256];
350 /* compile with debug symbol (and use them if error during execution) */
351 static int do_debug
= 0;
353 /* compile with built-in memory and bounds checker */
354 static int do_bounds_check
= 0;
356 /* display benchmark infos */
358 static int do_bench
= 0;
360 static int total_lines
;
361 static int total_bytes
;
363 /* use GNU C extensions */
364 static int gnu_ext
= 1;
366 /* use Tiny C extensions */
367 static int tcc_ext
= 1;
369 /* max number of callers shown if error */
370 static int num_callers
= 6;
371 static const char **rt_bound_error_msg
;
373 /* XXX: get rid of this ASAP */
374 static struct TCCState
*tcc_state
;
376 /* give the path of the tcc libraries */
377 static const char *tcc_lib_path
= CONFIG_TCC_LIBDIR
"/tcc";
382 BufferedFile
**include_stack_ptr
;
383 int *ifdef_stack_ptr
;
385 /* include file handling */
386 char **include_paths
;
387 int nb_include_paths
;
388 char **sysinclude_paths
;
389 int nb_sysinclude_paths
;
390 CachedInclude
**cached_includes
;
391 int nb_cached_includes
;
393 char **library_paths
;
394 int nb_library_paths
;
396 /* array of all loaded dlls (including those referenced by loaded
398 DLLReference
**loaded_dlls
;
403 int nb_sections
; /* number of sections, including first dummy section */
408 unsigned long *got_offsets
;
410 /* give the correspondance from symtab indexes to dynsym indexes */
411 int *symtab_to_dynsym
;
413 /* temporary dynamic symbol sections (for dll loading) */
414 Section
*dynsymtab_section
;
415 /* exported dynamic symbol section */
418 int nostdinc
; /* if true, no standard headers are added */
419 int nostdlib
; /* if true, no standard libraries are added */
421 int nocommon
; /* if true, do not use common symbols for .bss data */
423 /* if true, static linking is performed */
426 /* if true, all symbols are exported */
429 /* if true, only link in referenced objects from archive */
432 /* address of text section */
433 unsigned long text_addr
;
436 /* C language options */
437 int char_is_unsigned
;
439 /* warning switches */
440 int warn_write_strings
;
441 int warn_unsupported
;
444 int warn_implicit_function_declaration
;
448 void (*error_func
)(void *opaque
, const char *msg
);
449 int error_set_jmp_enabled
;
450 jmp_buf error_jmp_buf
;
453 /* tiny assembler state */
456 /* see include_stack_ptr */
457 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
459 /* see ifdef_stack_ptr */
460 int ifdef_stack
[IFDEF_STACK_SIZE
];
463 /* The current value can be: */
464 #define VT_VALMASK 0x00ff
465 #define VT_CONST 0x00f0 /* constant in vc
466 (must be first non register value) */
467 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
468 #define VT_LOCAL 0x00f2 /* offset on stack */
469 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
470 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
471 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
472 #define VT_LVAL 0x0100 /* var is an lvalue */
473 #define VT_SYM 0x0200 /* a symbol value is added */
474 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
475 char/short stored in integer registers) */
476 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
477 dereferencing value */
478 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
479 bounding function call point is in vc */
480 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
481 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
482 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
483 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
486 #define VT_INT 0 /* integer type */
487 #define VT_BYTE 1 /* signed byte type */
488 #define VT_SHORT 2 /* short type */
489 #define VT_VOID 3 /* void type */
490 #define VT_PTR 4 /* pointer */
491 #define VT_ENUM 5 /* enum definition */
492 #define VT_FUNC 6 /* function type */
493 #define VT_STRUCT 7 /* struct/union definition */
494 #define VT_FLOAT 8 /* IEEE float */
495 #define VT_DOUBLE 9 /* IEEE double */
496 #define VT_LDOUBLE 10 /* IEEE long double */
497 #define VT_BOOL 11 /* ISOC99 boolean type */
498 #define VT_LLONG 12 /* 64 bit integer */
499 #define VT_LONG 13 /* long integer (NEVER USED as type, only
501 #define VT_BTYPE 0x000f /* mask for basic type */
502 #define VT_UNSIGNED 0x0010 /* unsigned type */
503 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
504 #define VT_BITFIELD 0x0040 /* bitfield modifier */
505 #define VT_CONSTANT 0x0800 /* const modifier */
506 #define VT_VOLATILE 0x1000 /* volatile modifier */
507 #define VT_SIGNED 0x2000 /* signed type */
510 #define VT_EXTERN 0x00000080 /* extern definition */
511 #define VT_STATIC 0x00000100 /* static variable */
512 #define VT_TYPEDEF 0x00000200 /* typedef definition */
513 #define VT_INLINE 0x00000400 /* inline definition */
515 #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */
517 /* type mask (except storage) */
518 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
519 #define VT_TYPE (~(VT_STORAGE))
523 /* warning: the following compare tokens depend on i386 asm code */
535 #define TOK_LAND 0xa0
539 #define TOK_MID 0xa3 /* inc/dec, to void constant */
541 #define TOK_UDIV 0xb0 /* unsigned division */
542 #define TOK_UMOD 0xb1 /* unsigned modulo */
543 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
544 #define TOK_CINT 0xb3 /* number in tokc */
545 #define TOK_CCHAR 0xb4 /* char constant in tokc */
546 #define TOK_STR 0xb5 /* pointer to string in tokc */
547 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
548 #define TOK_LCHAR 0xb7
549 #define TOK_LSTR 0xb8
550 #define TOK_CFLOAT 0xb9 /* float constant */
551 #define TOK_LINENUM 0xba /* line number info */
552 #define TOK_CDOUBLE 0xc0 /* double constant */
553 #define TOK_CLDOUBLE 0xc1 /* long double constant */
554 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
555 #define TOK_ADDC1 0xc3 /* add with carry generation */
556 #define TOK_ADDC2 0xc4 /* add with carry use */
557 #define TOK_SUBC1 0xc5 /* add with carry generation */
558 #define TOK_SUBC2 0xc6 /* add with carry use */
559 #define TOK_CUINT 0xc8 /* unsigned int constant */
560 #define TOK_CLLONG 0xc9 /* long long constant */
561 #define TOK_CULLONG 0xca /* unsigned long long constant */
562 #define TOK_ARROW 0xcb
563 #define TOK_DOTS 0xcc /* three dots */
564 #define TOK_SHR 0xcd /* unsigned shift right */
565 #define TOK_PPNUM 0xce /* preprocessor number */
567 #define TOK_SHL 0x01 /* shift left */
568 #define TOK_SAR 0x02 /* signed shift right */
570 /* assignement operators : normal operator or 0x80 */
571 #define TOK_A_MOD 0xa5
572 #define TOK_A_AND 0xa6
573 #define TOK_A_MUL 0xaa
574 #define TOK_A_ADD 0xab
575 #define TOK_A_SUB 0xad
576 #define TOK_A_DIV 0xaf
577 #define TOK_A_XOR 0xde
578 #define TOK_A_OR 0xfc
579 #define TOK_A_SHL 0x81
580 #define TOK_A_SAR 0x82
583 #define offsetof(type, field) ((size_t) &((type *)0)->field)
587 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
590 /* WARNING: the content of this string encodes token numbers */
591 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";
593 #define TOK_EOF (-1) /* end of file */
594 #define TOK_LINEFEED 10 /* line feed */
596 /* all identificators and strings have token above that */
597 #define TOK_IDENT 256
599 /* only used for i386 asm opcodes definitions */
600 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
603 DEF(TOK_ASM_ ## x ## b, #x "b") \
604 DEF(TOK_ASM_ ## x ## w, #x "w") \
605 DEF(TOK_ASM_ ## x ## l, #x "l") \
606 DEF(TOK_ASM_ ## x, #x)
609 DEF(TOK_ASM_ ## x ## w, #x "w") \
610 DEF(TOK_ASM_ ## x ## l, #x "l") \
611 DEF(TOK_ASM_ ## x, #x)
614 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
615 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
616 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
617 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
620 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
621 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
624 #define DEF_ASMTEST(x) \
656 #define TOK_ASM_int TOK_INT
659 TOK_LAST
= TOK_IDENT
- 1,
660 #define DEF(id, str) id,
665 static const char tcc_keywords
[] =
666 #define DEF(id, str) str "\0"
671 #define TOK_UIDENT TOK_DEFINE
674 #define snprintf _snprintf
675 #define vsnprintf _vsnprintf
678 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
679 /* currently incorrect */
680 long double strtold(const char *nptr
, char **endptr
)
682 return (long double)strtod(nptr
, endptr
);
684 float strtof(const char *nptr
, char **endptr
)
686 return (float)strtod(nptr
, endptr
);
689 /* XXX: need to define this to use them in non ISOC99 context */
690 extern float strtof (const char *__nptr
, char **__endptr
);
691 extern long double strtold (const char *__nptr
, char **__endptr
);
694 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
695 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
697 static void next(void);
698 static void next_nomacro(void);
699 static void parse_expr_type(CType
*type
);
700 static void expr_type(CType
*type
);
701 static void unary_type(CType
*type
);
702 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
703 int case_reg
, int is_expr
);
704 static int expr_const(void);
705 static void expr_eq(void);
706 static void gexpr(void);
707 static void decl(int l
);
708 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
709 int first
, int size_only
);
710 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
711 int has_init
, int v
, int scope
);
713 void gv2(int rc1
, int rc2
);
714 void move_reg(int r
, int s
);
715 void save_regs(int n
);
716 void save_reg(int r
);
721 int get_reg_ex(int rc
,int rc2
);
723 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
724 const int *macro_str
, int can_read_stream
);
725 int save_reg_forced(int r
);
727 void force_charshort_cast(int t
);
728 static void gen_cast(CType
*type
);
730 static Sym
*sym_find(int v
);
731 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
734 static int type_size(CType
*type
, int *a
);
735 static inline CType
*pointed_type(CType
*type
);
736 static int pointed_size(CType
*type
);
737 static int lvalue_type(int t
);
738 static int parse_btype(CType
*type
, AttributeDef
*ad
);
739 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
740 static int is_compatible_types(CType
*type1
, CType
*type2
);
742 int ieee_finite(double d
);
743 void error(const char *fmt
, ...);
747 void lexpand_nr(void);
748 static void vpush_global_sym(CType
*type
, int v
);
749 void vset(CType
*type
, int r
, int v
);
750 void type_to_str(char *buf
, int buf_size
,
751 CType
*type
, const char *varstr
);
752 char *get_tok_str(int v
, CValue
*cv
);
753 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
754 unsigned long offset
, unsigned long size
);
755 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
757 /* section generation */
758 static void section_realloc(Section
*sec
, unsigned long new_size
);
759 static void *section_ptr_add(Section
*sec
, unsigned long size
);
760 static void put_extern_sym(Sym
*sym
, Section
*section
,
761 unsigned long value
, unsigned long size
);
762 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
763 static int put_elf_str(Section
*s
, const char *sym
);
764 static int put_elf_sym(Section
*s
,
765 unsigned long value
, unsigned long size
,
766 int info
, int other
, int shndx
, const char *name
);
767 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
768 int info
, int sh_num
, const char *name
);
769 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
770 int type
, int symbol
);
771 static void put_stabs(const char *str
, int type
, int other
, int desc
,
772 unsigned long value
);
773 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
774 unsigned long value
, Section
*sec
, int sym_index
);
775 static void put_stabn(int type
, int other
, int desc
, int value
);
776 static void put_stabd(int type
, int other
, int desc
);
777 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
779 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
780 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
781 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
784 int tcc_output_coff(TCCState
*s1
, const char *OutFile
);
788 #ifdef CONFIG_TCC_ASM
790 typedef struct ExprValue
{
795 #define MAX_ASM_OPERANDS 30
797 typedef struct ASMOperand
{
798 int id
; /* GCC 3 optionnal identifier (0 if number only supported */
800 char asm_str
[16]; /* computed asm string for operand */
801 SValue
*vt
; /* C value of the expression */
802 int ref_index
; /* if >= 0, gives reference to a output constraint */
803 int input_index
; /* if >= 0, gives reference to an input constraint */
804 int priority
; /* priority, used to assign registers */
805 int reg
; /* if >= 0, register number used for this operand */
806 int is_llong
; /* true if double register value */
807 int is_memory
; /* true if memory operand */
808 int is_rw
; /* for '+' modifier */
811 static void asm_expr(TCCState
*s1
, ExprValue
*pe
);
812 static int asm_int_expr(TCCState
*s1
);
813 static int find_constraint(ASMOperand
*operands
, int nb_operands
,
814 const char *name
, const char **pp
);
816 static int tcc_assemble(TCCState
*s1
, int do_preprocess
);
820 static void asm_instr(void);
821 static void asm_global_instr(void);
823 /* true if float/double/long double type */
824 static inline int is_float(int t
)
828 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
831 #ifdef TCC_TARGET_I386
832 #include "i386-gen.c"
835 #ifdef TCC_TARGET_ARM
839 #ifdef TCC_TARGET_C67
843 #ifdef CONFIG_TCC_STATIC
845 #define RTLD_LAZY 0x001
846 #define RTLD_NOW 0x002
847 #define RTLD_GLOBAL 0x100
848 #define RTLD_DEFAULT NULL
850 /* dummy function for profiling */
851 void *dlopen(const char *filename
, int flag
)
856 const char *dlerror(void)
861 typedef struct TCCSyms
{
866 #define TCCSYM(a) { #a, &a, },
868 /* add the symbol you want here if no dynamic linking is done */
869 static TCCSyms tcc_syms
[] = {
877 void *dlsym(void *handle
, const char *symbol
)
881 while (p
->str
!= NULL
) {
882 if (!strcmp(p
->str
, symbol
))
891 /********************************************************/
893 /* we use our own 'finite' function to avoid potential problems with
894 non standard math libs */
895 /* XXX: endianness dependent */
896 int ieee_finite(double d
)
899 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
902 /* copy a string and truncate it. */
903 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
910 q_end
= buf
+ buf_size
- 1;
922 /* strcat and truncate. */
923 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
928 pstrcpy(buf
+ len
, buf_size
- len
, s
);
932 static int strstart(const char *str
, const char *val
, const char **ptr
)
948 /* memory management */
954 static inline void tcc_free(void *ptr
)
957 mem_cur_size
-= malloc_usable_size(ptr
);
962 static void *tcc_malloc(unsigned long size
)
967 error("memory full");
969 mem_cur_size
+= malloc_usable_size(ptr
);
970 if (mem_cur_size
> mem_max_size
)
971 mem_max_size
= mem_cur_size
;
976 static void *tcc_mallocz(unsigned long size
)
979 ptr
= tcc_malloc(size
);
980 memset(ptr
, 0, size
);
984 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
988 mem_cur_size
-= malloc_usable_size(ptr
);
990 ptr1
= realloc(ptr
, size
);
992 /* NOTE: count not correct if alloc error, but not critical */
993 mem_cur_size
+= malloc_usable_size(ptr1
);
994 if (mem_cur_size
> mem_max_size
)
995 mem_max_size
= mem_cur_size
;
1000 static char *tcc_strdup(const char *str
)
1003 ptr
= tcc_malloc(strlen(str
) + 1);
1008 #define free(p) use_tcc_free(p)
1009 #define malloc(s) use_tcc_malloc(s)
1010 #define realloc(p, s) use_tcc_realloc(p, s)
1012 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
1019 /* every power of two we double array size */
1020 if ((nb
& (nb
- 1)) == 0) {
1025 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
1027 error("memory full");
1034 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
1038 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
1039 strcpy(sec
->name
, name
);
1040 sec
->sh_type
= sh_type
;
1041 sec
->sh_flags
= sh_flags
;
1048 sec
->sh_addralign
= 4;
1051 sec
->sh_addralign
= 1;
1054 sec
->sh_addralign
= 32; /* default conservative alignment */
1058 /* only add section if not private */
1059 if (!(sh_flags
& SHF_PRIVATE
)) {
1060 sec
->sh_num
= s1
->nb_sections
;
1061 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
1066 static void free_section(Section
*s
)
1072 /* realloc section and set its content to zero */
1073 static void section_realloc(Section
*sec
, unsigned long new_size
)
1076 unsigned char *data
;
1078 size
= sec
->data_allocated
;
1081 while (size
< new_size
)
1083 data
= tcc_realloc(sec
->data
, size
);
1085 error("memory full");
1086 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
1088 sec
->data_allocated
= size
;
1091 /* reserve at least 'size' bytes in section 'sec' from
1092 sec->data_offset. */
1093 static void *section_ptr_add(Section
*sec
, unsigned long size
)
1095 unsigned long offset
, offset1
;
1097 offset
= sec
->data_offset
;
1098 offset1
= offset
+ size
;
1099 if (offset1
> sec
->data_allocated
)
1100 section_realloc(sec
, offset1
);
1101 sec
->data_offset
= offset1
;
1102 return sec
->data
+ offset
;
1105 /* return a reference to a section, and create it if it does not
1107 Section
*find_section(TCCState
*s1
, const char *name
)
1111 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1112 sec
= s1
->sections
[i
];
1113 if (!strcmp(name
, sec
->name
))
1116 /* sections are created as PROGBITS */
1117 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
1120 #define SECTION_ABS ((void *)1)
1122 /* update sym->c so that it points to an external symbol in section
1123 'section' with value 'value' */
1124 static void put_extern_sym(Sym
*sym
, Section
*section
,
1125 unsigned long value
, unsigned long size
)
1127 int sym_type
, sym_bind
, sh_num
, info
;
1131 if (section
== NULL
)
1133 else if (section
== SECTION_ABS
)
1136 sh_num
= section
->sh_num
;
1138 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
)
1139 sym_type
= STT_FUNC
;
1141 sym_type
= STT_OBJECT
;
1142 if (sym
->type
.t
& VT_STATIC
)
1143 sym_bind
= STB_LOCAL
;
1145 sym_bind
= STB_GLOBAL
;
1147 name
= get_tok_str(sym
->v
, NULL
);
1148 #ifdef CONFIG_TCC_BCHECK
1149 if (do_bounds_check
) {
1152 /* XXX: avoid doing that for statics ? */
1153 /* if bound checking is activated, we change some function
1154 names by adding the "__bound" prefix */
1157 /* XXX: we rely only on malloc hooks */
1169 strcpy(buf
, "__bound_");
1176 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
1177 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
1179 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
1180 esym
->st_value
= value
;
1181 esym
->st_size
= size
;
1182 esym
->st_shndx
= sh_num
;
1186 /* add a new relocation entry to symbol 'sym' in section 's' */
1187 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
1190 put_extern_sym(sym
, NULL
, 0, 0);
1191 /* now we can add ELF relocation info */
1192 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
1195 static inline int isid(int c
)
1197 return (c
>= 'a' && c
<= 'z') ||
1198 (c
>= 'A' && c
<= 'Z') ||
1202 static inline int isnum(int c
)
1204 return c
>= '0' && c
<= '9';
1207 static inline int isoct(int c
)
1209 return c
>= '0' && c
<= '7';
1212 static inline int toup(int c
)
1214 if (c
>= 'a' && c
<= 'z')
1215 return c
- 'a' + 'A';
1220 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1224 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1227 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1231 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1235 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1242 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1243 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1244 (*f
)->filename
, (*f
)->line_num
);
1245 if (file
->line_num
> 0) {
1246 strcat_printf(buf
, sizeof(buf
),
1247 "%s:%d: ", file
->filename
, file
->line_num
);
1249 strcat_printf(buf
, sizeof(buf
),
1250 "%s: ", file
->filename
);
1253 strcat_printf(buf
, sizeof(buf
),
1257 strcat_printf(buf
, sizeof(buf
), "warning: ");
1258 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1260 if (!s1
->error_func
) {
1261 /* default case: stderr */
1262 fprintf(stderr
, "%s\n", buf
);
1264 s1
->error_func(s1
->error_opaque
, buf
);
1266 if (!is_warning
|| s1
->warn_error
)
1271 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1272 void (*error_func
)(void *opaque
, const char *msg
))
1274 s
->error_opaque
= error_opaque
;
1275 s
->error_func
= error_func
;
1279 /* error without aborting current compilation */
1280 void error_noabort(const char *fmt
, ...)
1282 TCCState
*s1
= tcc_state
;
1286 error1(s1
, 0, fmt
, ap
);
1290 void error(const char *fmt
, ...)
1292 TCCState
*s1
= tcc_state
;
1296 error1(s1
, 0, fmt
, ap
);
1298 /* better than nothing: in some cases, we accept to handle errors */
1299 if (s1
->error_set_jmp_enabled
) {
1300 longjmp(s1
->error_jmp_buf
, 1);
1302 /* XXX: eliminate this someday */
1307 void expect(const char *msg
)
1309 error("%s expected", msg
);
1312 void warning(const char *fmt
, ...)
1314 TCCState
*s1
= tcc_state
;
1321 error1(s1
, 1, fmt
, ap
);
1328 error("'%c' expected", c
);
1332 static void test_lvalue(void)
1334 if (!(vtop
->r
& VT_LVAL
))
1338 /* allocate a new token */
1339 static TokenSym
*tok_alloc_new(TokenSym
**pts
, const char *str
, int len
)
1341 TokenSym
*ts
, **ptable
;
1344 if (tok_ident
>= SYM_FIRST_ANOM
)
1345 error("memory full");
1347 /* expand token table if needed */
1348 i
= tok_ident
- TOK_IDENT
;
1349 if ((i
% TOK_ALLOC_INCR
) == 0) {
1350 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1352 error("memory full");
1353 table_ident
= ptable
;
1356 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1357 table_ident
[i
] = ts
;
1358 ts
->tok
= tok_ident
++;
1359 ts
->sym_define
= NULL
;
1360 ts
->sym_label
= NULL
;
1361 ts
->sym_struct
= NULL
;
1362 ts
->sym_identifier
= NULL
;
1364 ts
->hash_next
= NULL
;
1365 memcpy(ts
->str
, str
, len
);
1366 ts
->str
[len
] = '\0';
1371 #define TOK_HASH_INIT 1
1372 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1374 /* find a token and add it if not found */
1375 static TokenSym
*tok_alloc(const char *str
, int len
)
1377 TokenSym
*ts
, **pts
;
1383 h
= TOK_HASH_FUNC(h
, ((unsigned char *)str
)[i
]);
1384 h
&= (TOK_HASH_SIZE
- 1);
1386 pts
= &hash_ident
[h
];
1391 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1393 pts
= &(ts
->hash_next
);
1395 return tok_alloc_new(pts
, str
, len
);
1398 /* CString handling */
1400 static void cstr_realloc(CString
*cstr
, int new_size
)
1405 size
= cstr
->size_allocated
;
1407 size
= 8; /* no need to allocate a too small first string */
1408 while (size
< new_size
)
1410 data
= tcc_realloc(cstr
->data_allocated
, size
);
1412 error("memory full");
1413 cstr
->data_allocated
= data
;
1414 cstr
->size_allocated
= size
;
1419 static void cstr_ccat(CString
*cstr
, int ch
)
1422 size
= cstr
->size
+ 1;
1423 if (size
> cstr
->size_allocated
)
1424 cstr_realloc(cstr
, size
);
1425 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1429 static void cstr_cat(CString
*cstr
, const char *str
)
1441 /* add a wide char */
1442 static void cstr_wccat(CString
*cstr
, int ch
)
1445 size
= cstr
->size
+ sizeof(int);
1446 if (size
> cstr
->size_allocated
)
1447 cstr_realloc(cstr
, size
);
1448 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1452 static void cstr_new(CString
*cstr
)
1454 memset(cstr
, 0, sizeof(CString
));
1457 /* free string and reset it to NULL */
1458 static void cstr_free(CString
*cstr
)
1460 tcc_free(cstr
->data_allocated
);
1464 #define cstr_reset(cstr) cstr_free(cstr)
1466 static CString
*cstr_dup(CString
*cstr1
)
1471 cstr
= tcc_malloc(sizeof(CString
));
1474 cstr
->size_allocated
= size
;
1475 cstr
->data_allocated
= tcc_malloc(size
);
1476 cstr
->data
= cstr
->data_allocated
;
1477 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1481 /* XXX: unicode ? */
1482 static void add_char(CString
*cstr
, int c
)
1484 if (c
== '\'' || c
== '\"' || c
== '\\') {
1485 /* XXX: could be more precise if char or string */
1486 cstr_ccat(cstr
, '\\');
1488 if (c
>= 32 && c
<= 126) {
1491 cstr_ccat(cstr
, '\\');
1493 cstr_ccat(cstr
, 'n');
1495 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1496 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1497 cstr_ccat(cstr
, '0' + (c
& 7));
1502 /* XXX: buffer overflow */
1503 /* XXX: float tokens */
1504 char *get_tok_str(int v
, CValue
*cv
)
1506 static char buf
[STRING_MAX_SIZE
+ 1];
1507 static CString cstr_buf
;
1513 /* NOTE: to go faster, we give a fixed buffer for small strings */
1514 cstr_reset(&cstr_buf
);
1515 cstr_buf
.data
= buf
;
1516 cstr_buf
.size_allocated
= sizeof(buf
);
1522 /* XXX: not quite exact, but only useful for testing */
1523 sprintf(p
, "%u", cv
->ui
);
1527 /* XXX: not quite exact, but only useful for testing */
1528 sprintf(p
, "%Lu", cv
->ull
);
1532 cstr_ccat(&cstr_buf
, '\'');
1533 add_char(&cstr_buf
, cv
->i
);
1534 cstr_ccat(&cstr_buf
, '\'');
1535 cstr_ccat(&cstr_buf
, '\0');
1539 len
= cstr
->size
- 1;
1541 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1542 cstr_ccat(&cstr_buf
, '\0');
1547 cstr_ccat(&cstr_buf
, '\"');
1549 len
= cstr
->size
- 1;
1551 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1553 len
= (cstr
->size
/ sizeof(int)) - 1;
1555 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1557 cstr_ccat(&cstr_buf
, '\"');
1558 cstr_ccat(&cstr_buf
, '\0');
1567 return strcpy(p
, "<<=");
1569 return strcpy(p
, ">>=");
1571 if (v
< TOK_IDENT
) {
1572 /* search in two bytes table */
1586 } else if (v
< tok_ident
) {
1587 return table_ident
[v
- TOK_IDENT
]->str
;
1588 } else if (v
>= SYM_FIRST_ANOM
) {
1589 /* special name for anonymous symbol */
1590 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1592 /* should never happen */
1597 return cstr_buf
.data
;
1600 /* push, without hashing */
1601 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1604 s
= tcc_malloc(sizeof(Sym
));
1615 /* find a symbol and return its associated structure. 's' is the top
1616 of the symbol stack */
1617 static Sym
*sym_find2(Sym
*s
, int v
)
1627 /* structure lookup */
1628 static inline Sym
*struct_find(int v
)
1631 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1633 return table_ident
[v
]->sym_struct
;
1636 /* find an identifier */
1637 static inline Sym
*sym_find(int v
)
1640 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1642 return table_ident
[v
]->sym_identifier
;
1645 /* push a given symbol on the symbol stack */
1646 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1655 s
= sym_push2(ps
, v
, type
->t
, c
);
1656 s
->type
.ref
= type
->ref
;
1658 /* don't record fields or anonymous symbols */
1660 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1661 /* record symbol in token array */
1662 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1664 ps
= &ts
->sym_struct
;
1666 ps
= &ts
->sym_identifier
;
1673 /* push a global identifier */
1674 static Sym
*global_identifier_push(int v
, int t
, int c
)
1677 s
= sym_push2(&global_stack
, v
, t
, c
);
1678 /* don't record anonymous symbol */
1679 if (v
< SYM_FIRST_ANOM
) {
1680 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1681 /* modify the top most local identifier, so that
1682 sym_identifier will point to 's' when popped */
1684 ps
= &(*ps
)->prev_tok
;
1691 /* pop symbols until top reaches 'b' */
1692 static void sym_pop(Sym
**ptop
, Sym
*b
)
1702 /* remove symbol in token array */
1704 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1705 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1707 ps
= &ts
->sym_struct
;
1709 ps
= &ts
->sym_identifier
;
1720 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1725 fd
= open(filename
, O_RDONLY
);
1728 bf
= tcc_malloc(sizeof(BufferedFile
));
1734 bf
->buf_ptr
= bf
->buffer
;
1735 bf
->buf_end
= bf
->buffer
;
1736 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1737 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1739 bf
->ifndef_macro
= 0;
1740 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1741 // printf("opening '%s'\n", filename);
1745 void tcc_close(BufferedFile
*bf
)
1747 total_lines
+= bf
->line_num
;
1752 /* fill input buffer and peek next char */
1753 static int tcc_peekc_slow(BufferedFile
*bf
)
1756 /* only tries to read if really end of buffer */
1757 if (bf
->buf_ptr
>= bf
->buf_end
) {
1759 #if defined(PARSE_DEBUG)
1764 len
= read(bf
->fd
, bf
->buffer
, len
);
1771 bf
->buf_ptr
= bf
->buffer
;
1772 bf
->buf_end
= bf
->buffer
+ len
;
1773 *bf
->buf_end
= CH_EOB
;
1775 if (bf
->buf_ptr
< bf
->buf_end
) {
1776 return bf
->buf_ptr
[0];
1778 bf
->buf_ptr
= bf
->buf_end
;
1783 /* return the current character, handling end of block if necessary
1785 static int handle_eob(void)
1787 return tcc_peekc_slow(file
);
1790 /* read next char from current input file and handle end of input buffer */
1791 static inline void inp(void)
1793 ch
= *(++(file
->buf_ptr
));
1794 /* end of buffer/file handling */
1799 /* handle '\[\r]\n' */
1800 static void handle_stray(void)
1802 while (ch
== '\\') {
1807 } else if (ch
== '\r') {
1815 error("stray '\\' in program");
1820 /* skip the stray and handle the \\n case. Output an error if
1821 incorrect char after the stray */
1822 static int handle_stray1(uint8_t *p
)
1826 if (p
>= file
->buf_end
) {
1843 /* handle just the EOB case, but not stray */
1844 #define PEEKC_EOB(c, p)\
1855 /* handle the complicated stray case */
1856 #define PEEKC(c, p)\
1861 c = handle_stray1(p);\
1866 /* input with '\[\r]\n' handling. Note that this function cannot
1867 handle other characters after '\', so you cannot call it inside
1868 strings or comments */
1869 static void minp(void)
1877 /* single line C++ comments */
1878 static uint8_t *parse_line_comment(uint8_t *p
)
1886 if (c
== '\n' || c
== CH_EOF
) {
1888 } else if (c
== '\\') {
1897 } else if (c
== '\r') {
1915 static uint8_t *parse_comment(uint8_t *p
)
1921 /* fast skip loop */
1924 if (c
== '\n' || c
== '*' || c
== '\\')
1928 if (c
== '\n' || c
== '*' || c
== '\\')
1932 /* now we can handle all the cases */
1936 } else if (c
== '*') {
1942 } else if (c
== '/') {
1943 goto end_of_comment
;
1944 } else if (c
== '\\') {
1949 /* skip '\[\r]\n', otherwise just skip the stray */
1955 } else if (c
== '\r') {
1972 /* stray, eob or eof */
1977 error("unexpected end of file in comment");
1978 } else if (c
== '\\') {
1990 /* space exlcuding newline */
1991 static inline int is_space(int ch
)
1993 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1996 static inline void skip_spaces(void)
1998 while (is_space(ch
))
2002 /* parse a string without interpreting escapes */
2003 static uint8_t *parse_pp_string(uint8_t *p
,
2004 int sep
, CString
*str
)
2012 } else if (c
== '\\') {
2017 unterminated_string
:
2018 /* XXX: indicate line number of start of string */
2019 error("missing terminating %c character", sep
);
2020 } else if (c
== '\\') {
2021 /* escape : just skip \[\r]\n */
2026 } else if (c
== '\r') {
2029 expect("'\n' after '\r'");
2032 } else if (c
== CH_EOF
) {
2033 goto unterminated_string
;
2036 cstr_ccat(str
, '\\');
2042 } else if (c
== '\n') {
2045 } else if (c
== '\r') {
2048 cstr_ccat(str
, '\r');
2064 /* skip block of text until #else, #elif or #endif. skip also pairs of
2066 void preprocess_skip(void)
2068 int a
, start_of_line
, c
;
2095 } else if (c
== '\\') {
2096 /* XXX: incorrect: should not give an error */
2097 ch
= file
->buf_ptr
[0];
2105 p
= parse_pp_string(p
, c
, NULL
);
2114 p
= parse_comment(p
);
2115 } else if (ch
== '/') {
2116 p
= parse_line_comment(p
);
2122 if (start_of_line
) {
2127 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
2129 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
2131 else if (tok
== TOK_ENDIF
)
2145 /* ParseState handling */
2147 /* XXX: currently, no include file info is stored. Thus, we cannot display
2148 accurate messages if the function or data definition spans multiple
2151 /* save current parse state in 's' */
2152 void save_parse_state(ParseState
*s
)
2154 s
->line_num
= file
->line_num
;
2155 s
->macro_ptr
= macro_ptr
;
2160 /* restore parse state from 's' */
2161 void restore_parse_state(ParseState
*s
)
2163 file
->line_num
= s
->line_num
;
2164 macro_ptr
= s
->macro_ptr
;
2169 /* return the number of additional 'ints' necessary to store the
2171 static inline int tok_ext_size(int t
)
2190 return LDOUBLE_SIZE
/ 4;
2196 /* token string handling */
2198 static inline void tok_str_new(TokenString
*s
)
2202 s
->allocated_len
= 0;
2203 s
->last_line_num
= -1;
2206 static void tok_str_free(int *str
)
2215 /* NOTE: we test zero separately so that GCC can generate a
2216 table for the following switch */
2231 /* XXX: use a macro to be portable on 64 bit ? */
2232 cstr
= (CString
*)p
[1];
2243 p
+= 1 + (LDOUBLE_SIZE
/ 4);
2253 static int *tok_str_realloc(TokenString
*s
)
2257 len
= s
->allocated_len
+ TOK_STR_ALLOC_INCR
;
2258 str
= tcc_realloc(s
->str
, len
* sizeof(int));
2260 error("memory full");
2261 s
->allocated_len
= len
;
2266 static void tok_str_add(TokenString
*s
, int t
)
2272 if (len
>= s
->allocated_len
)
2273 str
= tok_str_realloc(s
);
2278 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
2285 /* allocate space for worst case */
2286 if (len
+ TOK_MAX_SIZE
> s
->allocated_len
)
2287 str
= tok_str_realloc(s
);
2296 str
[len
++] = cv
->tab
[0];
2301 str
[len
++] = (int)cstr_dup(cv
->cstr
);
2306 #if LDOUBLE_SIZE == 8
2309 str
[len
++] = cv
->tab
[0];
2310 str
[len
++] = cv
->tab
[1];
2312 #if LDOUBLE_SIZE == 12
2314 str
[len
++] = cv
->tab
[0];
2315 str
[len
++] = cv
->tab
[1];
2316 str
[len
++] = cv
->tab
[2];
2317 #elif LDOUBLE_SIZE != 8
2318 #error add long double size support
2327 /* add the current parse token in token string 's' */
2328 static void tok_str_add_tok(TokenString
*s
)
2332 /* save line number info */
2333 if (file
->line_num
!= s
->last_line_num
) {
2334 s
->last_line_num
= file
->line_num
;
2335 cval
.i
= s
->last_line_num
;
2336 tok_str_add2(s
, TOK_LINENUM
, &cval
);
2338 tok_str_add2(s
, tok
, &tokc
);
2341 #if LDOUBLE_SIZE == 12
2342 #define LDOUBLE_GET(p, cv) \
2346 #elif LDOUBLE_SIZE == 8
2347 #define LDOUBLE_GET(p, cv) \
2351 #error add long double size support
2355 /* get a token from an integer array and increment pointer
2356 accordingly. we code it as a macro to avoid pointer aliasing. */
2357 #define TOK_GET(t, p, cv) \
2379 case TOK_CLDOUBLE: \
2380 LDOUBLE_GET(p, cv); \
2381 p += LDOUBLE_SIZE / 4; \
2388 /* defines handling */
2389 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
2393 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
2394 s
->next
= first_arg
;
2395 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
2398 /* undefined a define symbol. Its name is just set to zero */
2399 static void define_undef(Sym
*s
)
2403 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2404 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2408 static inline Sym
*define_find(int v
)
2411 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2413 return table_ident
[v
]->sym_define
;
2416 /* free define stack until top reaches 'b' */
2417 static void free_defines(Sym
*b
)
2425 /* do not free args or predefined defines */
2427 tok_str_free((int *)top
->c
);
2429 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2430 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2438 static Sym
*label_find(int v
)
2441 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2443 return table_ident
[v
]->sym_label
;
2446 static Sym
*label_push(Sym
**ptop
, int v
, int flags
)
2449 s
= sym_push2(ptop
, v
, 0, 0);
2451 ps
= &table_ident
[v
- TOK_IDENT
]->sym_label
;
2452 if (ptop
== &global_label_stack
) {
2453 /* modify the top most local identifier, so that
2454 sym_identifier will point to 's' when popped */
2456 ps
= &(*ps
)->prev_tok
;
2463 /* pop labels until element last is reached. Look if any labels are
2464 undefined. Define symbols if '&&label' was used. */
2465 static void label_pop(Sym
**ptop
, Sym
*slast
)
2468 for(s
= *ptop
; s
!= slast
; s
= s1
) {
2470 if (s
->r
== LABEL_DECLARED
) {
2471 warning("label '%s' declared but not used", get_tok_str(s
->v
, NULL
));
2472 } else if (s
->r
== LABEL_FORWARD
) {
2473 error("label '%s' used but not defined",
2474 get_tok_str(s
->v
, NULL
));
2477 /* define corresponding symbol. A size of
2479 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
2483 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= s
->prev_tok
;
2489 /* eval an expression for #if/#elif */
2490 static int expr_preprocess(void)
2496 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2497 next(); /* do macro subst */
2498 if (tok
== TOK_DEFINED
) {
2503 c
= define_find(tok
) != 0;
2508 } else if (tok
>= TOK_IDENT
) {
2509 /* if undefined macro */
2513 tok_str_add_tok(&str
);
2515 tok_str_add(&str
, -1); /* simulate end of file */
2516 tok_str_add(&str
, 0);
2517 /* now evaluate C constant expression */
2518 macro_ptr
= str
.str
;
2522 tok_str_free(str
.str
);
2526 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2527 static void tok_print(int *str
)
2533 TOK_GET(t
, str
, cval
);
2536 printf(" %s", get_tok_str(t
, &cval
));
2542 /* parse after #define */
2543 static void parse_define(void)
2545 Sym
*s
, *first
, **ps
;
2546 int v
, t
, varg
, is_vaargs
, c
;
2551 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2552 /* XXX: should check if same macro (ANSI) */
2555 /* '(' must be just after macro definition for MACRO_FUNC */
2556 c
= file
->buf_ptr
[0];
2558 c
= handle_stray1(file
->buf_ptr
);
2563 while (tok
!= ')') {
2567 if (varg
== TOK_DOTS
) {
2568 varg
= TOK___VA_ARGS__
;
2570 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2574 if (varg
< TOK_IDENT
)
2575 error("badly punctuated parameter list");
2576 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2587 /* EOF testing necessary for '-D' handling */
2588 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2589 tok_str_add2(&str
, tok
, &tokc
);
2592 tok_str_add(&str
, 0);
2594 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2597 define_push(v
, t
, str
.str
, first
);
2600 /* XXX: use a token or a hash table to accelerate matching ? */
2601 static CachedInclude
*search_cached_include(TCCState
*s1
,
2602 int type
, const char *filename
)
2607 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
2608 e
= s1
->cached_includes
[i
];
2609 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2615 static inline void add_cached_include(TCCState
*s1
, int type
,
2616 const char *filename
, int ifndef_macro
)
2620 if (search_cached_include(s1
, type
, filename
))
2623 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2625 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2629 strcpy(e
->filename
, filename
);
2630 e
->ifndef_macro
= ifndef_macro
;
2631 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2634 /* is_bof is true if first non space token at beginning of file */
2635 static void preprocess(int is_bof
)
2637 TCCState
*s1
= tcc_state
;
2638 int size
, i
, c
, n
, saved_parse_flags
;
2639 char buf
[1024], *q
, *p
;
2645 saved_parse_flags
= parse_flags
;
2646 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
|
2647 PARSE_FLAG_LINEFEED
;
2657 s
= define_find(tok
);
2658 /* undefine symbol by putting an invalid name */
2663 ch
= file
->buf_ptr
[0];
2664 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2669 } else if (ch
== '\"') {
2672 /* XXX: better stray handling */
2675 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2676 if ((q
- buf
) < sizeof(buf
) - 1)
2683 /* eat all spaces and comments after include */
2684 /* XXX: slightly incorrect */
2685 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2689 /* computed #include : either we have only strings or
2690 we have anything enclosed in '<>' */
2693 if (tok
== TOK_STR
) {
2694 while (tok
!= TOK_LINEFEED
) {
2695 if (tok
!= TOK_STR
) {
2697 error("'#include' expects \"FILENAME\" or <FILENAME>");
2699 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2705 while (tok
!= TOK_LINEFEED
) {
2706 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2710 /* check syntax and remove '<>' */
2711 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2712 goto include_syntax
;
2713 memmove(buf
, buf
+ 1, len
- 2);
2714 buf
[len
- 2] = '\0';
2719 e
= search_cached_include(s1
, c
, buf
);
2720 if (e
&& define_find(e
->ifndef_macro
)) {
2721 /* no need to parse the include because the 'ifndef macro'
2724 printf("%s: skipping %s\n", file
->filename
, buf
);
2728 /* first search in current dir if "header.h" */
2730 p
= strrchr(file
->filename
, '/');
2732 size
= p
+ 1 - file
->filename
;
2733 if (size
> sizeof(buf1
) - 1)
2734 size
= sizeof(buf1
) - 1;
2735 memcpy(buf1
, file
->filename
, size
);
2737 pstrcat(buf1
, sizeof(buf1
), buf
);
2738 f
= tcc_open(s1
, buf1
);
2742 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2743 error("#include recursion too deep");
2744 /* now search in all the include paths */
2745 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2746 for(i
= 0; i
< n
; i
++) {
2748 if (i
< s1
->nb_include_paths
)
2749 path
= s1
->include_paths
[i
];
2751 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2752 pstrcpy(buf1
, sizeof(buf1
), path
);
2753 pstrcat(buf1
, sizeof(buf1
), "/");
2754 pstrcat(buf1
, sizeof(buf1
), buf
);
2755 f
= tcc_open(s1
, buf1
);
2759 error("include file '%s' not found", buf
);
2763 printf("%s: including %s\n", file
->filename
, buf1
);
2766 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2767 /* push current file in stack */
2768 /* XXX: fix current line init */
2769 *s1
->include_stack_ptr
++ = file
;
2771 /* add include file debug info */
2773 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2775 tok_flags
|= TOK_FLAG_BOF
| TOK_FLAG_BOL
;
2776 ch
= file
->buf_ptr
[0];
2784 c
= expr_preprocess();
2790 if (tok
< TOK_IDENT
)
2791 error("invalid argument for '#if%sdef'", c
? "n" : "");
2795 printf("#ifndef %s\n", get_tok_str(tok
, NULL
));
2797 file
->ifndef_macro
= tok
;
2800 c
= (define_find(tok
) != 0) ^ c
;
2802 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2803 error("memory full");
2804 *s1
->ifdef_stack_ptr
++ = c
;
2807 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2808 error("#else without matching #if");
2809 if (s1
->ifdef_stack_ptr
[-1] & 2)
2810 error("#else after #else");
2811 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2814 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2815 error("#elif without matching #if");
2816 c
= s1
->ifdef_stack_ptr
[-1];
2818 error("#elif after #else");
2819 /* last #if/#elif expression was true: we skip */
2822 c
= expr_preprocess();
2823 s1
->ifdef_stack_ptr
[-1] = c
;
2833 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2834 error("#endif without matching #if");
2835 s1
->ifdef_stack_ptr
--;
2836 /* '#ifndef macro' was at the start of file. Now we check if
2837 an '#endif' is exactly at the end of file */
2838 if (file
->ifndef_macro
&&
2839 s1
->ifdef_stack_ptr
== file
->ifdef_stack_ptr
) {
2840 file
->ifndef_macro_saved
= file
->ifndef_macro
;
2841 /* need to set to zero to avoid false matches if another
2842 #ifndef at middle of file */
2843 file
->ifndef_macro
= 0;
2844 while (tok
!= TOK_LINEFEED
)
2846 tok_flags
|= TOK_FLAG_ENDIF
;
2852 if (tok
!= TOK_CINT
)
2854 file
->line_num
= tokc
.i
- 1; /* the line number will be incremented after */
2856 if (tok
!= TOK_LINEFEED
) {
2859 pstrcpy(file
->filename
, sizeof(file
->filename
),
2860 (char *)tokc
.cstr
->data
);
2866 ch
= file
->buf_ptr
[0];
2869 while (ch
!= '\n' && ch
!= CH_EOF
) {
2870 if ((q
- buf
) < sizeof(buf
) - 1)
2876 error("#error %s", buf
);
2878 warning("#warning %s", buf
);
2884 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
2885 /* '!' is ignored to allow C scripts. numbers are ignored
2886 to emulate cpp behaviour */
2888 if (!(saved_parse_flags
& PARSE_FLAG_ASM_COMMENTS
))
2889 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
2893 /* ignore other preprocess commands or #! for C scripts */
2894 while (tok
!= TOK_LINEFEED
)
2897 parse_flags
= saved_parse_flags
;
2900 /* evaluate escape codes in a string. */
2901 static void parse_escape_string(CString
*outstr
, const uint8_t *buf
, int is_long
)
2916 case '0': case '1': case '2': case '3':
2917 case '4': case '5': case '6': case '7':
2918 /* at most three octal digits */
2923 n
= n
* 8 + c
- '0';
2927 n
= n
* 8 + c
- '0';
2932 goto add_char_nonext
;
2938 if (c
>= 'a' && c
<= 'f')
2940 else if (c
>= 'A' && c
<= 'F')
2950 goto add_char_nonext
;
2974 goto invalid_escape
;
2984 if (c
>= '!' && c
<= '~')
2985 warning("unknown escape sequence: \'\\%c\'", c
);
2987 warning("unknown escape sequence: \'\\x%x\'", c
);
2994 cstr_ccat(outstr
, c
);
2996 cstr_wccat(outstr
, c
);
2998 /* add a trailing '\0' */
3000 cstr_ccat(outstr
, '\0');
3002 cstr_wccat(outstr
, '\0');
3005 /* we use 64 bit numbers */
3008 /* bn = (bn << shift) | or_val */
3009 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
3013 for(i
=0;i
<BN_SIZE
;i
++) {
3015 bn
[i
] = (v
<< shift
) | or_val
;
3016 or_val
= v
>> (32 - shift
);
3020 void bn_zero(unsigned int *bn
)
3023 for(i
=0;i
<BN_SIZE
;i
++) {
3028 /* parse number in null terminated string 'p' and return it in the
3030 void parse_number(const char *p
)
3032 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
3034 unsigned int bn
[BN_SIZE
];
3045 goto float_frac_parse
;
3046 } else if (t
== '0') {
3047 if (ch
== 'x' || ch
== 'X') {
3051 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
3057 /* parse all digits. cannot check octal numbers at this stage
3058 because of floating point constants */
3060 if (ch
>= 'a' && ch
<= 'f')
3062 else if (ch
>= 'A' && ch
<= 'F')
3070 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
3072 error("number too long");
3078 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
3079 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
3081 /* NOTE: strtox should support that for hexa numbers, but
3082 non ISOC99 libcs do not support it, so we prefer to do
3084 /* hexadecimal or binary floats */
3085 /* XXX: handle overflows */
3097 } else if (t
>= 'a') {
3099 } else if (t
>= 'A') {
3104 bn_lshift(bn
, shift
, t
);
3111 if (t
>= 'a' && t
<= 'f') {
3113 } else if (t
>= 'A' && t
<= 'F') {
3115 } else if (t
>= '0' && t
<= '9') {
3121 error("invalid digit");
3122 bn_lshift(bn
, shift
, t
);
3127 if (ch
!= 'p' && ch
!= 'P')
3134 } else if (ch
== '-') {
3138 if (ch
< '0' || ch
> '9')
3139 expect("exponent digits");
3140 while (ch
>= '0' && ch
<= '9') {
3141 exp_val
= exp_val
* 10 + ch
- '0';
3144 exp_val
= exp_val
* s
;
3146 /* now we can generate the number */
3147 /* XXX: should patch directly float number */
3148 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
3149 d
= ldexp(d
, exp_val
- frac_bits
);
3154 /* float : should handle overflow */
3156 } else if (t
== 'L') {
3159 /* XXX: not large enough */
3160 tokc
.ld
= (long double)d
;
3166 /* decimal floats */
3168 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3173 while (ch
>= '0' && ch
<= '9') {
3174 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3180 if (ch
== 'e' || ch
== 'E') {
3181 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3185 if (ch
== '-' || ch
== '+') {
3186 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3191 if (ch
< '0' || ch
> '9')
3192 expect("exponent digits");
3193 while (ch
>= '0' && ch
<= '9') {
3194 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3206 tokc
.f
= strtof(token_buf
, NULL
);
3207 } else if (t
== 'L') {
3210 tokc
.ld
= strtold(token_buf
, NULL
);
3213 tokc
.d
= strtod(token_buf
, NULL
);
3217 unsigned long long n
, n1
;
3220 /* integer number */
3223 if (b
== 10 && *q
== '0') {
3230 /* no need for checks except for base 10 / 8 errors */
3233 } else if (t
>= 'a') {
3235 } else if (t
>= 'A') {
3240 error("invalid digit");
3244 /* detect overflow */
3245 /* XXX: this test is not reliable */
3247 error("integer constant overflow");
3250 /* XXX: not exactly ANSI compliant */
3251 if ((n
& 0xffffffff00000000LL
) != 0) {
3256 } else if (n
> 0x7fffffff) {
3267 error("three 'l's in integer constant");
3270 if (tok
== TOK_CINT
)
3272 else if (tok
== TOK_CUINT
)
3276 } else if (t
== 'U') {
3278 error("two 'u's in integer constant");
3280 if (tok
== TOK_CINT
)
3282 else if (tok
== TOK_CLLONG
)
3289 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
3297 #define PARSE2(c1, tok1, c2, tok2) \
3308 /* return next token without macro substitution */
3309 static inline void next_nomacro1(void)
3329 /* first look if it is in fact an end of buffer */
3330 if (p
>= file
->buf_end
) {
3334 if (p
>= file
->buf_end
)
3347 TCCState
*s1
= tcc_state
;
3348 if (parse_flags
& PARSE_FLAG_LINEFEED
) {
3350 } else if (s1
->include_stack_ptr
== s1
->include_stack
||
3351 !(parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3352 /* no include left : end of file. */
3355 /* pop include file */
3357 /* test if previous '#endif' was after a #ifdef at
3359 if (tok_flags
& TOK_FLAG_ENDIF
) {
3361 printf("#endif %s\n", get_tok_str(file
->ifndef_macro_saved
, NULL
));
3363 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
3364 file
->ifndef_macro_saved
);
3367 /* add end of include file debug info */
3369 put_stabd(N_EINCL
, 0, 0);
3371 /* pop include stack */
3373 s1
->include_stack_ptr
--;
3374 file
= *s1
->include_stack_ptr
;
3382 if (parse_flags
& PARSE_FLAG_LINEFEED
) {
3386 tok_flags
|= TOK_FLAG_BOL
;
3395 if ((tok_flags
& TOK_FLAG_BOL
) &&
3396 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3398 preprocess(tok_flags
& TOK_FLAG_BOF
);
3404 tok
= TOK_TWOSHARPS
;
3406 if (parse_flags
& PARSE_FLAG_ASM_COMMENTS
) {
3407 p
= parse_line_comment(p
- 1);
3416 case 'a': case 'b': case 'c': case 'd':
3417 case 'e': case 'f': case 'g': case 'h':
3418 case 'i': case 'j': case 'k': case 'l':
3419 case 'm': case 'n': case 'o': case 'p':
3420 case 'q': case 'r': case 's': case 't':
3421 case 'u': case 'v': case 'w': case 'x':
3423 case 'A': case 'B': case 'C': case 'D':
3424 case 'E': case 'F': case 'G': case 'H':
3425 case 'I': case 'J': case 'K':
3426 case 'M': case 'N': case 'O': case 'P':
3427 case 'Q': case 'R': case 'S': case 'T':
3428 case 'U': case 'V': case 'W': case 'X':
3434 h
= TOK_HASH_FUNC(h
, c
);
3438 if (!isidnum_table
[c
])
3440 h
= TOK_HASH_FUNC(h
, c
);
3447 /* fast case : no stray found, so we have the full token
3448 and we have already hashed it */
3450 h
&= (TOK_HASH_SIZE
- 1);
3451 pts
= &hash_ident
[h
];
3456 if (ts
->len
== len
&& !memcmp(ts
->str
, p1
, len
))
3458 pts
= &(ts
->hash_next
);
3460 ts
= tok_alloc_new(pts
, p1
, len
);
3464 cstr_reset(&tokcstr
);
3467 cstr_ccat(&tokcstr
, *p1
);
3473 while (isidnum_table
[c
]) {
3474 cstr_ccat(&tokcstr
, c
);
3477 ts
= tok_alloc(tokcstr
.data
, tokcstr
.size
);
3483 if (t
!= '\\' && t
!= '\'' && t
!= '\"') {
3485 goto parse_ident_fast
;
3488 if (c
== '\'' || c
== '\"') {
3492 cstr_reset(&tokcstr
);
3493 cstr_ccat(&tokcstr
, 'L');
3494 goto parse_ident_slow
;
3498 case '0': case '1': case '2': case '3':
3499 case '4': case '5': case '6': case '7':
3502 cstr_reset(&tokcstr
);
3503 /* after the first digit, accept digits, alpha, '.' or sign if
3504 prefixed by 'eEpP' */
3508 cstr_ccat(&tokcstr
, c
);
3510 if (!(isnum(c
) || isid(c
) || c
== '.' ||
3511 ((c
== '+' || c
== '-') &&
3512 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
3515 /* We add a trailing '\0' to ease parsing */
3516 cstr_ccat(&tokcstr
, '\0');
3517 tokc
.cstr
= &tokcstr
;
3521 /* special dot handling because it can also start a number */
3524 cstr_reset(&tokcstr
);
3525 cstr_ccat(&tokcstr
, '.');
3527 } else if (c
== '.') {
3547 /* parse the string */
3549 p
= parse_pp_string(p
, sep
, &str
);
3550 cstr_ccat(&str
, '\0');
3552 /* eval the escape (should be done as TOK_PPNUM) */
3553 cstr_reset(&tokcstr
);
3554 parse_escape_string(&tokcstr
, str
.data
, is_long
);
3559 /* XXX: make it portable */
3563 char_size
= sizeof(int);
3564 if (tokcstr
.size
<= char_size
)
3565 error("empty character constant");
3566 if (tokcstr
.size
> 2 * char_size
)
3567 warning("multi-character character constant");
3569 tokc
.i
= *(int8_t *)tokcstr
.data
;
3572 tokc
.i
= *(int *)tokcstr
.data
;
3576 tokc
.cstr
= &tokcstr
;
3590 } else if (c
== '<') {
3608 } else if (c
== '>') {
3626 } else if (c
== '=') {
3639 } else if (c
== '=') {
3652 } else if (c
== '=') {
3665 } else if (c
== '=') {
3668 } else if (c
== '>') {
3676 PARSE2('!', '!', '=', TOK_NE
)
3677 PARSE2('=', '=', '=', TOK_EQ
)
3678 PARSE2('*', '*', '=', TOK_A_MUL
)
3679 PARSE2('%', '%', '=', TOK_A_MOD
)
3680 PARSE2('^', '^', '=', TOK_A_XOR
)
3682 /* comments or operator */
3686 p
= parse_comment(p
);
3688 } else if (c
== '/') {
3689 p
= parse_line_comment(p
);
3691 } else if (c
== '=') {
3711 case '$': /* only used in assembler */
3716 error("unrecognized character \\x%02x", c
);
3721 #if defined(PARSE_DEBUG)
3722 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3726 /* return next token without macro substitution. Can read input from
3728 static void next_nomacro(void)
3734 TOK_GET(tok
, macro_ptr
, tokc
);
3735 if (tok
== TOK_LINENUM
) {
3736 file
->line_num
= tokc
.i
;
3745 /* substitute args in macro_str and return allocated string */
3746 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
3748 int *st
, last_tok
, t
, notfirst
;
3757 TOK_GET(t
, macro_str
, cval
);
3762 TOK_GET(t
, macro_str
, cval
);
3765 s
= sym_find2(args
, t
);
3772 cstr_ccat(&cstr
, ' ');
3773 TOK_GET(t
, st
, cval
);
3774 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
3777 cstr_ccat(&cstr
, '\0');
3779 printf("stringize: %s\n", (char *)cstr
.data
);
3783 tok_str_add2(&str
, TOK_STR
, &cval
);
3786 tok_str_add2(&str
, t
, &cval
);
3788 } else if (t
>= TOK_IDENT
) {
3789 s
= sym_find2(args
, t
);
3792 /* if '##' is present before or after, no arg substitution */
3793 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
3794 /* special case for var arg macros : ## eats the
3795 ',' if empty VA_ARGS variable. */
3796 /* XXX: test of the ',' is not 100%
3797 reliable. should fix it to avoid security
3799 if (gnu_ext
&& s
->type
.t
&&
3800 last_tok
== TOK_TWOSHARPS
&&
3801 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
3803 /* suppress ',' '##' */
3806 /* suppress '##' and add variable */
3814 TOK_GET(t1
, st
, cval
);
3817 tok_str_add2(&str
, t1
, &cval
);
3821 /* NOTE: the stream cannot be read when macro
3822 substituing an argument */
3823 macro_subst(&str
, nested_list
, st
, 0);
3826 tok_str_add(&str
, t
);
3829 tok_str_add2(&str
, t
, &cval
);
3833 tok_str_add(&str
, 0);
3837 static char const ab_month_name
[12][4] =
3839 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
3840 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
3843 /* do macro substitution of current token with macro 's' and add
3844 result to (tok_str,tok_len). 'nested_list' is the list of all
3845 macros we got inside to avoid recursing. Return non zero if no
3846 substitution needs to be done */
3847 static int macro_subst_tok(TokenString
*tok_str
,
3848 Sym
**nested_list
, Sym
*s
, int can_read_stream
)
3850 Sym
*args
, *sa
, *sa1
;
3851 int mstr_allocated
, parlevel
, *mstr
, t
, t1
;
3858 /* if symbol is a macro, prepare substitution */
3859 /* special macros */
3860 if (tok
== TOK___LINE__
) {
3861 snprintf(buf
, sizeof(buf
), "%d", file
->line_num
);
3865 } else if (tok
== TOK___FILE__
) {
3866 cstrval
= file
->filename
;
3868 } else if (tok
== TOK___DATE__
|| tok
== TOK___TIME__
) {
3873 tm
= localtime(&ti
);
3874 if (tok
== TOK___DATE__
) {
3875 snprintf(buf
, sizeof(buf
), "%s %2d %d",
3876 ab_month_name
[tm
->tm_mon
], tm
->tm_mday
, tm
->tm_year
+ 1900);
3878 snprintf(buf
, sizeof(buf
), "%02d:%02d:%02d",
3879 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
3886 cstr_cat(&cstr
, cstrval
);
3887 cstr_ccat(&cstr
, '\0');
3889 tok_str_add2(tok_str
, t1
, &cval
);
3894 if (s
->type
.t
== MACRO_FUNC
) {
3895 /* NOTE: we do not use next_nomacro to avoid eating the
3896 next token. XXX: find better solution */
3899 if (t
== 0 && can_read_stream
) {
3900 /* end of macro stream: we must look at the token
3901 after in the file */
3907 /* XXX: incorrect with comments */
3908 ch
= file
->buf_ptr
[0];
3909 while (is_space(ch
) || ch
== '\n')
3913 if (t
!= '(') /* no macro subst */
3916 /* argument macro */
3921 /* NOTE: empty args are allowed, except if no args */
3923 /* handle '()' case */
3924 if (!args
&& !sa
&& tok
== ')')
3927 error("macro '%s' used with too many args",
3928 get_tok_str(s
->v
, 0));
3931 /* NOTE: non zero sa->t indicates VA_ARGS */
3932 while ((parlevel
> 0 ||
3934 (tok
!= ',' || sa
->type
.t
))) &&
3938 else if (tok
== ')')
3940 tok_str_add2(&str
, tok
, &tokc
);
3943 tok_str_add(&str
, 0);
3944 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
3947 /* special case for gcc var args: add an empty
3948 var arg argument if it is omitted */
3949 if (sa
&& sa
->type
.t
&& gnu_ext
)
3959 error("macro '%s' used with too few args",
3960 get_tok_str(s
->v
, 0));
3963 /* now subst each arg */
3964 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3969 tok_str_free((int *)sa
->c
);
3975 sym_push2(nested_list
, s
->v
, 0, 0);
3976 macro_subst(tok_str
, nested_list
, mstr
, 1);
3977 /* pop nested defined symbol */
3979 *nested_list
= sa1
->prev
;
3987 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
3988 return the resulting string (which must be freed). */
3989 static inline int *macro_twosharps(const int *macro_str
)
3992 const int *macro_ptr1
, *start_macro_ptr
, *ptr
, *saved_macro_ptr
;
3994 const char *p1
, *p2
;
3996 TokenString macro_str1
;
3999 start_macro_ptr
= macro_str
;
4000 /* we search the first '##' */
4002 macro_ptr1
= macro_str
;
4003 TOK_GET(t
, macro_str
, cval
);
4004 /* nothing more to do if end of string */
4007 if (*macro_str
== TOK_TWOSHARPS
)
4011 /* we saw '##', so we need more processing to handle it */
4013 tok_str_new(¯o_str1
);
4017 /* add all tokens seen so far */
4018 for(ptr
= start_macro_ptr
; ptr
< macro_ptr1
;) {
4019 TOK_GET(t
, ptr
, cval
);
4020 tok_str_add2(¯o_str1
, t
, &cval
);
4022 saved_macro_ptr
= macro_ptr
;
4023 /* XXX: get rid of the use of macro_ptr here */
4024 macro_ptr
= (int *)macro_str
;
4026 while (*macro_ptr
== TOK_TWOSHARPS
) {
4028 macro_ptr1
= macro_ptr
;
4031 TOK_GET(t
, macro_ptr
, cval
);
4032 /* We concatenate the two tokens if we have an
4033 identifier or a preprocessing number */
4035 p1
= get_tok_str(tok
, &tokc
);
4036 cstr_cat(&cstr
, p1
);
4037 p2
= get_tok_str(t
, &cval
);
4038 cstr_cat(&cstr
, p2
);
4039 cstr_ccat(&cstr
, '\0');
4041 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
4042 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
4043 if (tok
== TOK_PPNUM
) {
4044 /* if number, then create a number token */
4045 /* NOTE: no need to allocate because
4046 tok_str_add2() does it */
4049 /* if identifier, we must do a test to
4050 validate we have a correct identifier */
4051 if (t
== TOK_PPNUM
) {
4061 if (!isnum(c
) && !isid(c
))
4065 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
4066 tok
= ts
->tok
; /* modify current token */
4069 const char *str
= cstr
.data
;
4070 const unsigned char *q
;
4072 /* we look for a valid token */
4073 /* XXX: do more extensive checks */
4074 if (!strcmp(str
, ">>=")) {
4076 } else if (!strcmp(str
, "<<=")) {
4078 } else if (strlen(str
) == 2) {
4079 /* search in two bytes table */
4084 if (q
[0] == str
[0] && q
[1] == str
[1])
4091 /* NOTE: because get_tok_str use a static buffer,
4094 p1
= get_tok_str(tok
, &tokc
);
4095 cstr_cat(&cstr
, p1
);
4096 cstr_ccat(&cstr
, '\0');
4097 p2
= get_tok_str(t
, &cval
);
4098 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
4099 /* cannot merge tokens: just add them separately */
4100 tok_str_add2(¯o_str1
, tok
, &tokc
);
4101 /* XXX: free associated memory ? */
4108 tok_str_add2(¯o_str1
, tok
, &tokc
);
4113 macro_ptr
= (int *)saved_macro_ptr
;
4115 tok_str_add(¯o_str1
, 0);
4116 return macro_str1
.str
;
4120 /* do macro substitution of macro_str and add result to
4121 (tok_str,tok_len). 'nested_list' is the list of all macros we got
4122 inside to avoid recursing. */
4123 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
4124 const int *macro_str
, int can_read_stream
)
4127 int *saved_macro_ptr
, *macro_str1
;
4132 /* first scan for '##' operator handling */
4134 macro_str1
= macro_twosharps(ptr
);
4138 /* NOTE: ptr == NULL can only happen if tokens are read from
4139 file stream due to a macro function call */
4142 TOK_GET(t
, ptr
, cval
);
4147 /* if nested substitution, do nothing */
4148 if (sym_find2(*nested_list
, t
))
4150 saved_macro_ptr
= macro_ptr
;
4151 macro_ptr
= (int *)ptr
;
4153 ret
= macro_subst_tok(tok_str
, nested_list
, s
, can_read_stream
);
4154 ptr
= (int *)macro_ptr
;
4155 macro_ptr
= saved_macro_ptr
;
4160 tok_str_add2(tok_str
, t
, &cval
);
4164 tok_str_free(macro_str1
);
4167 /* return next token with macro substitution */
4168 static void next(void)
4170 Sym
*nested_list
, *s
;
4176 /* if not reading from macro substituted string, then try
4177 to substitute macros */
4178 if (tok
>= TOK_IDENT
&&
4179 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
4180 s
= define_find(tok
);
4182 /* we have a macro: we try to substitute */
4185 if (macro_subst_tok(&str
, &nested_list
, s
, 1) == 0) {
4186 /* substitution done, NOTE: maybe empty */
4187 tok_str_add(&str
, 0);
4188 macro_ptr
= str
.str
;
4189 macro_ptr_allocated
= str
.str
;
4196 /* end of macro or end of unget buffer */
4197 if (unget_buffer_enabled
) {
4198 macro_ptr
= unget_saved_macro_ptr
;
4199 unget_buffer_enabled
= 0;
4201 /* end of macro string: free it */
4202 tok_str_free(macro_ptr_allocated
);
4209 /* convert preprocessor tokens into C tokens */
4210 if (tok
== TOK_PPNUM
&&
4211 (parse_flags
& PARSE_FLAG_TOK_NUM
)) {
4212 parse_number((char *)tokc
.cstr
->data
);
4216 /* push back current token and set current token to 'last_tok'. Only
4217 identifier case handled for labels. */
4218 static inline void unget_tok(int last_tok
)
4222 unget_saved_macro_ptr
= macro_ptr
;
4223 unget_buffer_enabled
= 1;
4224 q
= unget_saved_buffer
;
4227 n
= tok_ext_size(tok
) - 1;
4230 *q
= 0; /* end of token string */
4235 void swap(int *p
, int *q
)
4243 void vsetc(CType
*type
, int r
, CValue
*vc
)
4247 if (vtop
>= vstack
+ VSTACK_SIZE
)
4248 error("memory full");
4249 /* cannot let cpu flags if other instruction are generated. Also
4250 avoid leaving VT_JMP anywhere except on the top of the stack
4251 because it would complicate the code generator. */
4252 if (vtop
>= vstack
) {
4253 v
= vtop
->r
& VT_VALMASK
;
4254 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
4260 vtop
->r2
= VT_CONST
;
4264 /* push integer constant */
4269 vsetc(&int_type
, VT_CONST
, &cval
);
4272 /* Return a static symbol pointing to a section */
4273 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
4274 unsigned long offset
, unsigned long size
)
4280 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
4281 sym
->type
.ref
= type
->ref
;
4282 sym
->r
= VT_CONST
| VT_SYM
;
4283 put_extern_sym(sym
, sec
, offset
, size
);
4287 /* push a reference to a section offset by adding a dummy symbol */
4288 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
4293 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4294 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
4297 /* define a new external reference to a symbol 'v' of type 'u' */
4298 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
4304 /* push forward reference */
4305 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
4306 s
->type
.ref
= type
->ref
;
4307 s
->r
= r
| VT_CONST
| VT_SYM
;
4312 /* define a new external reference to a symbol 'v' of type 'u' */
4313 static Sym
*external_sym(int v
, CType
*type
, int r
)
4319 /* push forward reference */
4320 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
4321 s
->type
.t
|= VT_EXTERN
;
4323 if (!is_compatible_types(&s
->type
, type
))
4324 error("incompatible types for redefinition of '%s'",
4325 get_tok_str(v
, NULL
));
4330 /* push a reference to global symbol v */
4331 static void vpush_global_sym(CType
*type
, int v
)
4336 sym
= external_global_sym(v
, type
, 0);
4338 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4342 void vset(CType
*type
, int r
, int v
)
4347 vsetc(type
, r
, &cval
);
4350 void vseti(int r
, int v
)
4366 void vpushv(SValue
*v
)
4368 if (vtop
>= vstack
+ VSTACK_SIZE
)
4369 error("memory full");
4379 /* save r to the memory stack, and mark it as being free */
4380 void save_reg(int r
)
4382 int l
, saved
, size
, align
;
4386 /* modify all stack values */
4389 for(p
=vstack
;p
<=vtop
;p
++) {
4390 if ((p
->r
& VT_VALMASK
) == r
||
4391 (p
->r2
& VT_VALMASK
) == r
) {
4392 /* must save value on stack if not already done */
4394 /* NOTE: must reload 'r' because r might be equal to r2 */
4395 r
= p
->r
& VT_VALMASK
;
4396 /* store register in the stack */
4398 if ((p
->r
& VT_LVAL
) ||
4399 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
4401 size
= type_size(type
, &align
);
4402 loc
= (loc
- size
) & -align
;
4403 sv
.type
.t
= type
->t
;
4404 sv
.r
= VT_LOCAL
| VT_LVAL
;
4407 #ifdef TCC_TARGET_I386
4408 /* x86 specific: need to pop fp register ST0 if saved */
4409 if (r
== TREG_ST0
) {
4410 o(0xd9dd); /* fstp %st(1) */
4413 /* special long long case */
4414 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
4421 /* mark that stack entry as being saved on the stack */
4422 if (p
->r
& VT_LVAL
) {
4423 /* also clear the bounded flag because the
4424 relocation address of the function was stored in
4426 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
4428 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
4436 /* find a register of class 'rc2' with at most one reference on stack.
4437 * If none, call get_reg(rc) */
4438 int get_reg_ex(int rc
, int rc2
)
4443 for(r
=0;r
<NB_REGS
;r
++) {
4444 if (reg_classes
[r
] & rc2
) {
4447 for(p
= vstack
; p
<= vtop
; p
++) {
4448 if ((p
->r
& VT_VALMASK
) == r
||
4449 (p
->r2
& VT_VALMASK
) == r
)
4459 /* find a free register of class 'rc'. If none, save one register */
4465 /* find a free register */
4466 for(r
=0;r
<NB_REGS
;r
++) {
4467 if (reg_classes
[r
] & rc
) {
4468 for(p
=vstack
;p
<=vtop
;p
++) {
4469 if ((p
->r
& VT_VALMASK
) == r
||
4470 (p
->r2
& VT_VALMASK
) == r
)
4478 /* no register left : free the first one on the stack (VERY
4479 IMPORTANT to start from the bottom to ensure that we don't
4480 spill registers used in gen_opi()) */
4481 for(p
=vstack
;p
<=vtop
;p
++) {
4482 r
= p
->r
& VT_VALMASK
;
4483 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
4485 /* also look at second register (if long long) */
4486 r
= p
->r2
& VT_VALMASK
;
4487 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
4493 /* Should never comes here */
4497 /* save registers up to (vtop - n) stack entry */
4498 void save_regs(int n
)
4503 for(p
= vstack
;p
<= p1
; p
++) {
4504 r
= p
->r
& VT_VALMASK
;
4511 /* move register 's' to 'r', and flush previous value of r to memory
4513 void move_reg(int r
, int s
)
4526 /* get address of vtop (vtop MUST BE an lvalue) */
4529 vtop
->r
&= ~VT_LVAL
;
4530 /* tricky: if saved lvalue, then we can go back to lvalue */
4531 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
4532 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
4535 #ifdef CONFIG_TCC_BCHECK
4536 /* generate lvalue bound code */
4542 vtop
->r
&= ~VT_MUSTBOUND
;
4543 /* if lvalue, then use checking code before dereferencing */
4544 if (vtop
->r
& VT_LVAL
) {
4545 /* if not VT_BOUNDED value, then make one */
4546 if (!(vtop
->r
& VT_BOUNDED
)) {
4547 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
4548 /* must save type because we must set it to int to get pointer */
4550 vtop
->type
.t
= VT_INT
;
4553 gen_bounded_ptr_add();
4554 vtop
->r
|= lval_type
;
4557 /* then check for dereferencing */
4558 gen_bounded_ptr_deref();
4563 /* store vtop a register belonging to class 'rc'. lvalues are
4564 converted to values. Cannot be used if cannot be converted to
4565 register value (such as structures). */
4568 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
4569 unsigned long long ll
;
4571 /* NOTE: get_reg can modify vstack[] */
4572 if (vtop
->type
.t
& VT_BITFIELD
) {
4573 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
4574 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4575 /* remove bit field info to avoid loops */
4576 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4577 /* generate shifts */
4578 vpushi(32 - (bit_pos
+ bit_size
));
4580 vpushi(32 - bit_size
);
4581 /* NOTE: transformed to SHR if unsigned */
4585 if (is_float(vtop
->type
.t
) &&
4586 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4589 unsigned long offset
;
4591 /* XXX: unify with initializers handling ? */
4592 /* CPUs usually cannot use float constants, so we store them
4593 generically in data segment */
4594 size
= type_size(&vtop
->type
, &align
);
4595 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
4596 data_section
->data_offset
= offset
;
4597 /* XXX: not portable yet */
4598 ptr
= section_ptr_add(data_section
, size
);
4601 ptr
[i
] = vtop
->c
.tab
[i
];
4602 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
4603 vtop
->r
|= VT_LVAL
| VT_SYM
;
4607 #ifdef CONFIG_TCC_BCHECK
4608 if (vtop
->r
& VT_MUSTBOUND
)
4612 r
= vtop
->r
& VT_VALMASK
;
4613 /* need to reload if:
4615 - lvalue (need to dereference pointer)
4616 - already a register, but not in the right class */
4617 if (r
>= VT_CONST
||
4618 (vtop
->r
& VT_LVAL
) ||
4619 !(reg_classes
[r
] & rc
) ||
4620 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
4621 !(reg_classes
[vtop
->r2
] & rc
))) {
4623 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
4624 /* two register type load : expand to two words
4626 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4629 vtop
->c
.ui
= ll
; /* first word */
4631 vtop
->r
= r
; /* save register value */
4632 vpushi(ll
>> 32); /* second word */
4633 } else if (r
>= VT_CONST
||
4634 (vtop
->r
& VT_LVAL
)) {
4635 /* load from memory */
4638 vtop
[-1].r
= r
; /* save register value */
4639 /* increment pointer to get second word */
4640 vtop
->type
.t
= VT_INT
;
4646 /* move registers */
4649 vtop
[-1].r
= r
; /* save register value */
4650 vtop
->r
= vtop
[-1].r2
;
4652 /* allocate second register */
4659 /* write second register */
4661 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
4663 /* lvalue of scalar type : need to use lvalue type
4664 because of possible cast */
4667 /* compute memory access type */
4668 if (vtop
->r
& VT_LVAL_BYTE
)
4670 else if (vtop
->r
& VT_LVAL_SHORT
)
4672 if (vtop
->r
& VT_LVAL_UNSIGNED
)
4676 /* restore wanted type */
4679 /* one register type load */
4684 #ifdef TCC_TARGET_C67
4685 /* uses register pairs for doubles */
4686 if ((vtop
->type
.t
& VT_BTYPE
) == VT_DOUBLE
)
4693 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4694 void gv2(int rc1
, int rc2
)
4698 /* generate more generic register first. But VT_JMP or VT_CMP
4699 values must be generated first in all cases to avoid possible
4701 v
= vtop
[0].r
& VT_VALMASK
;
4702 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
4707 /* test if reload is needed for first register */
4708 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
4718 /* test if reload is needed for first register */
4719 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
4725 /* expand long long on stack in two int registers */
4730 u
= vtop
->type
.t
& VT_UNSIGNED
;
4733 vtop
[0].r
= vtop
[-1].r2
;
4734 vtop
[0].r2
= VT_CONST
;
4735 vtop
[-1].r2
= VT_CONST
;
4736 vtop
[0].type
.t
= VT_INT
| u
;
4737 vtop
[-1].type
.t
= VT_INT
| u
;
4740 #ifdef TCC_TARGET_ARM
4741 /* expand long long on stack */
4742 void lexpand_nr(void)
4746 u
= vtop
->type
.t
& VT_UNSIGNED
;
4748 vtop
->r2
= VT_CONST
;
4749 vtop
->type
.t
= VT_INT
| u
;
4750 v
=vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
);
4751 if (v
== VT_CONST
) {
4752 vtop
[-1].c
.ui
= vtop
->c
.ull
;
4753 vtop
->c
.ui
= vtop
->c
.ull
>> 32;
4755 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
4757 vtop
->r
= vtop
[-1].r
;
4758 } else if (v
> VT_CONST
) {
4762 vtop
->r
= vtop
[-1].r2
;
4763 vtop
[-1].r2
= VT_CONST
;
4764 vtop
[-1].type
.t
= VT_INT
| u
;
4768 /* build a long long from two ints */
4771 gv2(RC_INT
, RC_INT
);
4772 vtop
[-1].r2
= vtop
[0].r
;
4773 vtop
[-1].type
.t
= t
;
4777 /* rotate n first stack elements to the bottom
4778 I1 ... In -> I2 ... In I1 [top is right]
4786 for(i
=-n
+1;i
!=0;i
++)
4787 vtop
[i
] = vtop
[i
+1];
4791 /* rotate n first stack elements to the top
4792 I1 ... In -> In I1 ... I(n-1) [top is right]
4800 for(i
= 0;i
< n
- 1; i
++)
4801 vtop
[-i
] = vtop
[-i
- 1];
4805 #ifdef TCC_TARGET_ARM
4806 /* like vrott but in other direction
4807 In ... I1 -> I(n-1) ... I1 In [top is right]
4815 for(i
= n
- 1; i
> 0; i
--)
4816 vtop
[-i
] = vtop
[-i
+ 1];
4821 /* pop stack value */
4825 v
= vtop
->r
& VT_VALMASK
;
4826 #ifdef TCC_TARGET_I386
4827 /* for x86, we need to pop the FP stack */
4828 if (v
== TREG_ST0
&& !nocode_wanted
) {
4829 o(0xd9dd); /* fstp %st(1) */
4832 if (v
== VT_JMP
|| v
== VT_JMPI
) {
4833 /* need to put correct jump if && or || without test */
4839 /* convert stack entry to register and duplicate its value in another
4847 if ((t
& VT_BTYPE
) == VT_LLONG
) {
4854 /* stack: H L L1 H1 */
4862 /* duplicate value */
4873 load(r1
, &sv
); /* move r to r1 */
4875 /* duplicates value */
4880 /* generate CPU independent (unsigned) long long operations */
4881 void gen_opl(int op
)
4883 int t
, a
, b
, op1
, c
, i
;
4890 func
= TOK___divdi3
;
4893 func
= TOK___udivdi3
;
4896 func
= TOK___moddi3
;
4899 func
= TOK___umoddi3
;
4901 /* call generic long long function */
4902 vpush_global_sym(&func_old_type
, func
);
4907 vtop
->r2
= REG_LRET
;
4920 /* stack: L1 H1 L2 H2 */
4925 vtop
[-2] = vtop
[-3];
4928 /* stack: H1 H2 L1 L2 */
4934 /* stack: H1 H2 L1 L2 ML MH */
4937 /* stack: ML MH H1 H2 L1 L2 */
4941 /* stack: ML MH H1 L2 H2 L1 */
4946 /* stack: ML MH M1 M2 */
4949 } else if (op
== '+' || op
== '-') {
4950 /* XXX: add non carry method too (for MIPS or alpha) */
4956 /* stack: H1 H2 (L1 op L2) */
4959 gen_op(op1
+ 1); /* TOK_xxxC2 */
4962 /* stack: H1 H2 (L1 op L2) */
4965 /* stack: (L1 op L2) H1 H2 */
4967 /* stack: (L1 op L2) (H1 op H2) */
4975 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4976 t
= vtop
[-1].type
.t
;
4980 /* stack: L H shift */
4982 /* constant: simpler */
4983 /* NOTE: all comments are for SHL. the other cases are
4984 done by swaping words */
4995 if (op
!= TOK_SAR
) {
5028 /* XXX: should provide a faster fallback on x86 ? */
5031 func
= TOK___sardi3
;
5034 func
= TOK___shrdi3
;
5037 func
= TOK___shldi3
;
5043 /* compare operations */
5049 /* stack: L1 H1 L2 H2 */
5051 vtop
[-1] = vtop
[-2];
5053 /* stack: L1 L2 H1 H2 */
5056 /* when values are equal, we need to compare low words. since
5057 the jump is inverted, we invert the test too. */
5060 else if (op1
== TOK_GT
)
5062 else if (op1
== TOK_ULT
)
5064 else if (op1
== TOK_UGT
)
5069 if (op1
!= TOK_NE
) {
5073 /* generate non equal test */
5074 /* XXX: NOT PORTABLE yet */
5078 #if defined(TCC_TARGET_I386)
5079 b
= psym(0x850f, 0);
5080 #elif defined(TCC_TARGET_ARM)
5082 o(0x1A000000 | encbranch(ind
, 0, 1));
5083 #elif defined(TCC_TARGET_C67)
5084 error("not implemented");
5086 #error not supported
5090 /* compare low. Always unsigned */
5094 else if (op1
== TOK_LE
)
5096 else if (op1
== TOK_GT
)
5098 else if (op1
== TOK_GE
)
5108 /* handle integer constant optimizations and various machine
5110 void gen_opic(int op
)
5117 /* currently, we cannot do computations with forward symbols */
5118 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5119 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5123 case '+': v1
->c
.i
+= fc
; break;
5124 case '-': v1
->c
.i
-= fc
; break;
5125 case '&': v1
->c
.i
&= fc
; break;
5126 case '^': v1
->c
.i
^= fc
; break;
5127 case '|': v1
->c
.i
|= fc
; break;
5128 case '*': v1
->c
.i
*= fc
; break;
5135 /* if division by zero, generate explicit division */
5138 error("division by zero in constant");
5142 default: v1
->c
.i
/= fc
; break;
5143 case '%': v1
->c
.i
%= fc
; break;
5144 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
5145 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
5148 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
5149 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
5150 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
5152 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
5153 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
5154 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
5155 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
5156 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
5157 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
5158 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
5159 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
5160 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
5161 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
5163 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
5164 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
5170 /* if commutative ops, put c2 as constant */
5171 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
5172 op
== '|' || op
== '*')) {
5177 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
5180 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
5181 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
5187 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
5188 /* try to use shifts instead of muls or divs */
5189 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
5198 else if (op
== TOK_PDIV
)
5204 } else if (c2
&& (op
== '+' || op
== '-') &&
5205 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
5206 (VT_CONST
| VT_SYM
)) {
5207 /* symbol + constant case */
5214 if (!nocode_wanted
) {
5215 /* call low level op generator */
5224 /* generate a floating point operation with constant propagation */
5225 void gen_opif(int op
)
5233 /* currently, we cannot do computations with forward symbols */
5234 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5235 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5237 if (v1
->type
.t
== VT_FLOAT
) {
5240 } else if (v1
->type
.t
== VT_DOUBLE
) {
5248 /* NOTE: we only do constant propagation if finite number (not
5249 NaN or infinity) (ANSI spec) */
5250 if (!ieee_finite(f1
) || !ieee_finite(f2
))
5254 case '+': f1
+= f2
; break;
5255 case '-': f1
-= f2
; break;
5256 case '*': f1
*= f2
; break;
5260 error("division by zero in constant");
5265 /* XXX: also handles tests ? */
5269 /* XXX: overflow test ? */
5270 if (v1
->type
.t
== VT_FLOAT
) {
5272 } else if (v1
->type
.t
== VT_DOUBLE
) {
5280 if (!nocode_wanted
) {
5288 static int pointed_size(CType
*type
)
5291 return type_size(pointed_type(type
), &align
);
5294 static inline int is_null_pointer(SValue
*p
)
5296 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
5298 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& p
->c
.i
== 0) ||
5299 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.ll
== 0);
5302 static inline int is_integer_btype(int bt
)
5304 return (bt
== VT_BYTE
|| bt
== VT_SHORT
||
5305 bt
== VT_INT
|| bt
== VT_LLONG
);
5308 /* check types for comparison or substraction of pointers */
5309 static void check_comparison_pointer_types(SValue
*p1
, SValue
*p2
, int op
)
5311 CType
*type1
, *type2
, tmp_type1
, tmp_type2
;
5314 /* null pointers are accepted for all comparisons as gcc */
5315 if (is_null_pointer(p1
) || is_null_pointer(p2
))
5319 bt1
= type1
->t
& VT_BTYPE
;
5320 bt2
= type2
->t
& VT_BTYPE
;
5321 /* accept comparison between pointer and integer with a warning */
5322 if ((is_integer_btype(bt1
) || is_integer_btype(bt2
)) && op
!= '-') {
5323 warning("comparison between pointer and integer");
5327 /* both must be pointers or implicit function pointers */
5328 if (bt1
== VT_PTR
) {
5329 type1
= pointed_type(type1
);
5330 } else if (bt1
!= VT_FUNC
)
5331 goto invalid_operands
;
5333 if (bt2
== VT_PTR
) {
5334 type2
= pointed_type(type2
);
5335 } else if (bt2
!= VT_FUNC
) {
5337 error("invalid operands to binary %s", get_tok_str(op
, NULL
));
5339 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
5340 (type2
->t
& VT_BTYPE
) == VT_VOID
)
5344 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5345 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5346 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
5347 /* gcc-like error if '-' is used */
5349 goto invalid_operands
;
5351 warning("comparison of distinct pointer types lacks a cast");
5355 /* generic gen_op: handles types problems */
5358 int u
, t1
, t2
, bt1
, bt2
, t
;
5361 t1
= vtop
[-1].type
.t
;
5362 t2
= vtop
[0].type
.t
;
5363 bt1
= t1
& VT_BTYPE
;
5364 bt2
= t2
& VT_BTYPE
;
5366 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5367 /* at least one operand is a pointer */
5368 /* relationnal op: must be both pointers */
5369 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5370 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5371 /* pointers are handled are unsigned */
5372 t
= VT_INT
| VT_UNSIGNED
;
5375 /* if both pointers, then it must be the '-' op */
5376 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
5378 error("cannot use pointers here");
5379 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5380 /* XXX: check that types are compatible */
5381 u
= pointed_size(&vtop
[-1].type
);
5383 /* set to integer type */
5384 vtop
->type
.t
= VT_INT
;
5388 /* exactly one pointer : must be '+' or '-'. */
5389 if (op
!= '-' && op
!= '+')
5390 error("cannot use pointers here");
5391 /* Put pointer as first operand */
5392 if (bt2
== VT_PTR
) {
5396 type1
= vtop
[-1].type
;
5397 /* XXX: cast to int ? (long long case) */
5398 vpushi(pointed_size(&vtop
[-1].type
));
5400 #ifdef CONFIG_TCC_BCHECK
5401 /* if evaluating constant expression, no code should be
5402 generated, so no bound check */
5403 if (do_bounds_check
&& !const_wanted
) {
5404 /* if bounded pointers, we generate a special code to
5411 gen_bounded_ptr_add();
5417 /* put again type if gen_opic() swaped operands */
5420 } else if (is_float(bt1
) || is_float(bt2
)) {
5421 /* compute bigger type and do implicit casts */
5422 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5424 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5429 /* floats can only be used for a few operations */
5430 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
5431 (op
< TOK_ULT
|| op
> TOK_GT
))
5432 error("invalid operands for binary operation");
5434 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5435 /* cast to biggest op */
5437 /* convert to unsigned if it does not fit in a long long */
5438 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5439 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5443 /* integer operations */
5445 /* convert to unsigned if it does not fit in an integer */
5446 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5447 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5450 /* XXX: currently, some unsigned operations are explicit, so
5451 we modify them here */
5452 if (t
& VT_UNSIGNED
) {
5459 else if (op
== TOK_LT
)
5461 else if (op
== TOK_GT
)
5463 else if (op
== TOK_LE
)
5465 else if (op
== TOK_GE
)
5472 /* special case for shifts and long long: we keep the shift as
5474 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
5479 else if ((t
& VT_BTYPE
) == VT_LLONG
)
5483 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5484 /* relationnal op: the result is an int */
5485 vtop
->type
.t
= VT_INT
;
5492 /* generic itof for unsigned long long case */
5493 void gen_cvt_itof1(int t
)
5495 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
5496 (VT_LLONG
| VT_UNSIGNED
)) {
5499 vpush_global_sym(&func_old_type
, TOK___ulltof
);
5500 else if (t
== VT_DOUBLE
)
5501 vpush_global_sym(&func_old_type
, TOK___ulltod
);
5503 vpush_global_sym(&func_old_type
, TOK___ulltold
);
5513 /* generic ftoi for unsigned long long case */
5514 void gen_cvt_ftoi1(int t
)
5518 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
5519 /* not handled natively */
5520 st
= vtop
->type
.t
& VT_BTYPE
;
5522 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
5523 else if (st
== VT_DOUBLE
)
5524 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
5526 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
5531 vtop
->r2
= REG_LRET
;
5537 /* force char or short cast */
5538 void force_charshort_cast(int t
)
5542 /* XXX: add optimization if lvalue : just change type and offset */
5547 if (t
& VT_UNSIGNED
) {
5548 vpushi((1 << bits
) - 1);
5559 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
5560 static void gen_cast(CType
*type
)
5562 int sbt
, dbt
, sf
, df
, c
;
5564 /* special delayed cast for char/short */
5565 /* XXX: in some cases (multiple cascaded casts), it may still
5567 if (vtop
->r
& VT_MUSTCAST
) {
5568 vtop
->r
&= ~VT_MUSTCAST
;
5569 force_charshort_cast(vtop
->type
.t
);
5572 /* bitfields first get cast to ints */
5573 if (vtop
->type
.t
& VT_BITFIELD
) {
5577 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
5578 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5580 if (sbt
!= dbt
&& !nocode_wanted
) {
5583 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5585 /* convert from fp to fp */
5587 /* constant case: we can do it now */
5588 /* XXX: in ISOC, cannot do it if error in convert */
5589 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
5590 vtop
->c
.f
= (float)vtop
->c
.d
;
5591 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
5592 vtop
->c
.f
= (float)vtop
->c
.ld
;
5593 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
5594 vtop
->c
.d
= (double)vtop
->c
.f
;
5595 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
5596 vtop
->c
.d
= (double)vtop
->c
.ld
;
5597 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
5598 vtop
->c
.ld
= (long double)vtop
->c
.f
;
5599 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
5600 vtop
->c
.ld
= (long double)vtop
->c
.d
;
5602 /* non constant case: generate code */
5606 /* convert int to fp */
5609 case VT_LLONG
| VT_UNSIGNED
:
5611 /* XXX: add const cases for long long */
5613 case VT_INT
| VT_UNSIGNED
:
5615 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
5616 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
5617 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
5622 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
5623 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
5624 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
5630 #if !defined(TCC_TARGET_ARM)
5637 /* convert fp to int */
5638 /* we handle char/short/etc... with generic code */
5639 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
5640 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
5645 case VT_LLONG
| VT_UNSIGNED
:
5647 /* XXX: add const cases for long long */
5649 case VT_INT
| VT_UNSIGNED
:
5651 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5652 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5653 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5659 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5660 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5661 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5669 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
5670 /* additional cast for char/short/bool... */
5674 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
5675 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
5676 /* scalar to long long */
5678 if (sbt
== (VT_INT
| VT_UNSIGNED
))
5679 vtop
->c
.ll
= vtop
->c
.ui
;
5681 vtop
->c
.ll
= vtop
->c
.i
;
5683 /* machine independent conversion */
5685 /* generate high word */
5686 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
5694 /* patch second register */
5695 vtop
[-1].r2
= vtop
->r
;
5699 } else if (dbt
== VT_BOOL
) {
5700 /* scalar to bool */
5703 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
5704 (dbt
& VT_BTYPE
) == VT_SHORT
) {
5705 force_charshort_cast(dbt
);
5706 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
5708 if (sbt
== VT_LLONG
) {
5709 /* from long long: just take low order word */
5713 /* if lvalue and single word type, nothing to do because
5714 the lvalue already contains the real type size (see
5715 VT_LVAL_xxx constants) */
5721 /* return type size. Put alignment at 'a' */
5722 static int type_size(CType
*type
, int *a
)
5727 bt
= type
->t
& VT_BTYPE
;
5728 if (bt
== VT_STRUCT
) {
5733 } else if (bt
== VT_PTR
) {
5734 if (type
->t
& VT_ARRAY
) {
5736 return type_size(&s
->type
, a
) * s
->c
;
5741 } else if (bt
== VT_LDOUBLE
) {
5743 return LDOUBLE_SIZE
;
5744 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
5745 #ifdef TCC_TARGET_I386
5751 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
5754 } else if (bt
== VT_SHORT
) {
5758 /* char, void, function, _Bool */
5764 /* return the pointed type of t */
5765 static inline CType
*pointed_type(CType
*type
)
5767 return &type
->ref
->type
;
5770 /* modify type so that its it is a pointer to type. */
5771 static void mk_pointer(CType
*type
)
5774 s
= sym_push(SYM_FIELD
, type
, 0, -1);
5775 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
5779 /* compare function types. OLD functions match any new functions */
5780 static int is_compatible_func(CType
*type1
, CType
*type2
)
5786 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5788 /* check func_call */
5791 /* XXX: not complete */
5792 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
5796 while (s1
!= NULL
) {
5799 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5809 /* return true if type1 and type2 are exactly the same (including
5812 - enums are not checked as gcc __builtin_types_compatible_p ()
5814 static int is_compatible_types(CType
*type1
, CType
*type2
)
5818 t1
= type1
->t
& VT_TYPE
;
5819 t2
= type2
->t
& VT_TYPE
;
5820 /* XXX: bitfields ? */
5823 /* test more complicated cases */
5824 bt1
= t1
& VT_BTYPE
;
5825 if (bt1
== VT_PTR
) {
5826 type1
= pointed_type(type1
);
5827 type2
= pointed_type(type2
);
5828 return is_compatible_types(type1
, type2
);
5829 } else if (bt1
== VT_STRUCT
) {
5830 return (type1
->ref
== type2
->ref
);
5831 } else if (bt1
== VT_FUNC
) {
5832 return is_compatible_func(type1
, type2
);
5838 /* print a type. If 'varstr' is not NULL, then the variable is also
5839 printed in the type */
5841 /* XXX: add array and function pointers */
5842 void type_to_str(char *buf
, int buf_size
,
5843 CType
*type
, const char *varstr
)
5850 t
= type
->t
& VT_TYPE
;
5853 if (t
& VT_CONSTANT
)
5854 pstrcat(buf
, buf_size
, "const ");
5855 if (t
& VT_VOLATILE
)
5856 pstrcat(buf
, buf_size
, "volatile ");
5857 if (t
& VT_UNSIGNED
)
5858 pstrcat(buf
, buf_size
, "unsigned ");
5888 tstr
= "long double";
5890 pstrcat(buf
, buf_size
, tstr
);
5894 if (bt
== VT_STRUCT
)
5898 pstrcat(buf
, buf_size
, tstr
);
5899 v
= type
->ref
->v
& ~SYM_STRUCT
;
5900 if (v
>= SYM_FIRST_ANOM
)
5901 pstrcat(buf
, buf_size
, "<anonymous>");
5903 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
5907 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
5908 pstrcat(buf
, buf_size
, "(");
5910 while (sa
!= NULL
) {
5911 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
5912 pstrcat(buf
, buf_size
, buf1
);
5915 pstrcat(buf
, buf_size
, ", ");
5917 pstrcat(buf
, buf_size
, ")");
5921 pstrcpy(buf1
, sizeof(buf1
), "*");
5923 pstrcat(buf1
, sizeof(buf1
), varstr
);
5924 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
5928 pstrcat(buf
, buf_size
, " ");
5929 pstrcat(buf
, buf_size
, varstr
);
5934 /* verify type compatibility to store vtop in 'dt' type, and generate
5936 static void gen_assign_cast(CType
*dt
)
5938 CType
*st
, *type1
, *type2
, tmp_type1
, tmp_type2
;
5939 char buf1
[256], buf2
[256];
5942 st
= &vtop
->type
; /* source type */
5943 dbt
= dt
->t
& VT_BTYPE
;
5944 sbt
= st
->t
& VT_BTYPE
;
5945 if (dt
->t
& VT_CONSTANT
)
5946 warning("assignment of read-only location");
5949 /* special cases for pointers */
5950 /* '0' can also be a pointer */
5951 if (is_null_pointer(vtop
))
5953 /* accept implicit pointer to integer cast with warning */
5954 if (is_integer_btype(sbt
)) {
5955 warning("assignment makes pointer from integer without a cast");
5958 type1
= pointed_type(dt
);
5959 /* a function is implicitely a function pointer */
5960 if (sbt
== VT_FUNC
) {
5961 if ((type1
->t
& VT_BTYPE
) != VT_VOID
&&
5962 !is_compatible_types(pointed_type(dt
), st
))
5969 type2
= pointed_type(st
);
5970 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
5971 (type2
->t
& VT_BTYPE
) == VT_VOID
) {
5972 /* void * can match anything */
5974 /* exact type match, except for unsigned */
5977 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5978 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5979 if (!is_compatible_types(&tmp_type1
, &tmp_type2
))
5982 /* check const and volatile */
5983 if ((!(type1
->t
& VT_CONSTANT
) && (type2
->t
& VT_CONSTANT
)) ||
5984 (!(type1
->t
& VT_VOLATILE
) && (type2
->t
& VT_VOLATILE
)))
5985 warning("assignment discards qualifiers from pointer target type");
5991 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
5992 warning("assignment makes integer from pointer without a cast");
5994 /* XXX: more tests */
5999 tmp_type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6000 tmp_type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6001 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
6003 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
6004 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
6005 error("cannot cast '%s' to '%s'", buf1
, buf2
);
6013 /* store vtop in lvalue pushed on stack */
6016 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
6018 ft
= vtop
[-1].type
.t
;
6019 sbt
= vtop
->type
.t
& VT_BTYPE
;
6020 dbt
= ft
& VT_BTYPE
;
6021 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
6022 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
6023 /* optimize char/short casts */
6024 delayed_cast
= VT_MUSTCAST
;
6025 vtop
->type
.t
= ft
& VT_TYPE
;
6026 /* XXX: factorize */
6027 if (ft
& VT_CONSTANT
)
6028 warning("assignment of read-only location");
6031 if (!(ft
& VT_BITFIELD
))
6032 gen_assign_cast(&vtop
[-1].type
);
6035 if (sbt
== VT_STRUCT
) {
6036 /* if structure, only generate pointer */
6037 /* structure assignment : generate memcpy */
6038 /* XXX: optimize if small size */
6039 if (!nocode_wanted
) {
6040 size
= type_size(&vtop
->type
, &align
);
6042 vpush_global_sym(&func_old_type
, TOK_memcpy
);
6046 vtop
->type
.t
= VT_INT
;
6050 vtop
->type
.t
= VT_INT
;
6062 /* leave source on stack */
6063 } else if (ft
& VT_BITFIELD
) {
6064 /* bitfield store handling */
6065 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
6066 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
6067 /* remove bit field info to avoid loops */
6068 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
6070 /* duplicate destination */
6072 vtop
[-1] = vtop
[-2];
6074 /* mask and shift source */
6075 vpushi((1 << bit_size
) - 1);
6079 /* load destination, mask and or with source */
6081 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
6087 #ifdef CONFIG_TCC_BCHECK
6088 /* bound check case */
6089 if (vtop
[-1].r
& VT_MUSTBOUND
) {
6095 if (!nocode_wanted
) {
6099 r
= gv(rc
); /* generate value */
6100 /* if lvalue was saved on stack, must read it */
6101 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
6103 t
= get_reg(RC_INT
);
6105 sv
.r
= VT_LOCAL
| VT_LVAL
;
6106 sv
.c
.ul
= vtop
[-1].c
.ul
;
6108 vtop
[-1].r
= t
| VT_LVAL
;
6111 /* two word case handling : store second register at word + 4 */
6112 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
6114 /* convert to int to increment easily */
6115 vtop
->type
.t
= VT_INT
;
6121 /* XXX: it works because r2 is spilled last ! */
6122 store(vtop
->r2
, vtop
- 1);
6126 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6127 vtop
->r
|= delayed_cast
;
6131 /* post defines POST/PRE add. c is the token ++ or -- */
6132 void inc(int post
, int c
)
6135 vdup(); /* save lvalue */
6137 gv_dup(); /* duplicate value */
6142 vpushi(c
- TOK_MID
);
6144 vstore(); /* store value */
6146 vpop(); /* if post op, return saved value */
6149 /* Parse GNUC __attribute__ extension. Currently, the following
6150 extensions are recognized:
6151 - aligned(n) : set data/function alignment.
6152 - section(x) : generate data/code in this section.
6153 - unused : currently ignored, but may be used someday.
6155 static void parse_attribute(AttributeDef
*ad
)
6159 while (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
6163 while (tok
!= ')') {
6164 if (tok
< TOK_IDENT
)
6165 expect("attribute name");
6173 expect("section name");
6174 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
6183 if (n
<= 0 || (n
& (n
- 1)) != 0)
6184 error("alignment must be a positive power of two");
6193 /* currently, no need to handle it because tcc does not
6194 track unused objects */
6198 /* currently, no need to handle it because tcc does not
6199 track unused objects */
6204 ad
->func_call
= FUNC_CDECL
;
6209 ad
->func_call
= FUNC_STDCALL
;
6211 #ifdef TCC_TARGET_I386
6221 ad
->func_call
= FUNC_FASTCALL1
+ n
- 1;
6226 if (tcc_state
->warn_unsupported
)
6227 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
6228 /* skip parameters */
6229 /* XXX: skip parenthesis too */
6232 while (tok
!= ')' && tok
!= -1)
6247 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
6248 static void struct_decl(CType
*type
, int u
)
6250 int a
, v
, size
, align
, maxalign
, c
, offset
;
6251 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
6256 a
= tok
; /* save decl type */
6261 /* struct already defined ? return it */
6263 expect("struct/union/enum name");
6267 error("invalid type");
6274 /* we put an undefined size for struct/union */
6275 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
6276 s
->r
= 0; /* default alignment is zero as gcc */
6277 /* put struct/union/enum name in type */
6285 error("struct/union/enum already defined");
6286 /* cannot be empty */
6288 /* non empty enums are not allowed */
6289 if (a
== TOK_ENUM
) {
6293 expect("identifier");
6299 /* enum symbols have static storage */
6300 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
6301 ss
->type
.t
|= VT_STATIC
;
6306 /* NOTE: we accept a trailing comma */
6316 while (tok
!= '}') {
6317 parse_btype(&btype
, &ad
);
6323 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
);
6324 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
6325 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
| VT_INLINE
)))
6326 error("invalid type for '%s'",
6327 get_tok_str(v
, NULL
));
6331 bit_size
= expr_const();
6332 /* XXX: handle v = 0 case for messages */
6334 error("negative width in bit-field '%s'",
6335 get_tok_str(v
, NULL
));
6336 if (v
&& bit_size
== 0)
6337 error("zero width for bit-field '%s'",
6338 get_tok_str(v
, NULL
));
6340 size
= type_size(&type1
, &align
);
6341 if (align
< ad
.aligned
)
6344 if (bit_size
>= 0) {
6345 bt
= type1
.t
& VT_BTYPE
;
6350 error("bitfields must have scalar type");
6352 if (bit_size
> bsize
) {
6353 error("width of '%s' exceeds its type",
6354 get_tok_str(v
, NULL
));
6355 } else if (bit_size
== bsize
) {
6356 /* no need for bit fields */
6358 } else if (bit_size
== 0) {
6359 /* XXX: what to do if only padding in a
6361 /* zero size: means to pad */
6365 /* we do not have enough room ? */
6366 if ((bit_pos
+ bit_size
) > bsize
)
6369 /* XXX: handle LSB first */
6370 type1
.t
|= VT_BITFIELD
|
6371 (bit_pos
<< VT_STRUCT_SHIFT
) |
6372 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
6373 bit_pos
+= bit_size
;
6379 /* add new memory data only if starting
6381 if (lbit_pos
== 0) {
6382 if (a
== TOK_STRUCT
) {
6383 c
= (c
+ align
- 1) & -align
;
6391 if (align
> maxalign
)
6395 printf("add field %s offset=%d",
6396 get_tok_str(v
, NULL
), offset
);
6397 if (type1
.t
& VT_BITFIELD
) {
6398 printf(" pos=%d size=%d",
6399 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
6400 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
6404 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
6408 if (tok
== ';' || tok
== TOK_EOF
)
6415 /* store size and alignment */
6416 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
6422 /* return 0 if no type declaration. otherwise, return the basic type
6425 static int parse_btype(CType
*type
, AttributeDef
*ad
)
6427 int t
, u
, type_found
, typespec_found
;
6431 memset(ad
, 0, sizeof(AttributeDef
));
6438 /* currently, we really ignore extension */
6448 if ((t
& VT_BTYPE
) != 0)
6449 error("too many basic types");
6465 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
6466 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6467 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
6468 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
6482 if ((t
& VT_BTYPE
) == VT_LONG
) {
6483 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6490 struct_decl(&type1
, VT_ENUM
);
6493 type
->ref
= type1
.ref
;
6497 struct_decl(&type1
, VT_STRUCT
);
6500 /* type modifiers */
6553 /* GNUC attribute */
6554 case TOK_ATTRIBUTE1
:
6555 case TOK_ATTRIBUTE2
:
6556 parse_attribute(ad
);
6563 parse_expr_type(&type1
);
6569 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
6571 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
6572 type
->ref
= s
->type
.ref
;
6579 if ((t
& (VT_SIGNED
|VT_UNSIGNED
)) == (VT_SIGNED
|VT_UNSIGNED
))
6580 error("signed and unsigned modifier");
6581 if (tcc_state
->char_is_unsigned
) {
6582 if ((t
& (VT_SIGNED
|VT_UNSIGNED
|VT_BTYPE
)) == VT_BYTE
)
6587 /* long is never used as type */
6588 if ((t
& VT_BTYPE
) == VT_LONG
)
6589 t
= (t
& ~VT_BTYPE
) | VT_INT
;
6594 /* convert a function parameter type (array to pointer and function to
6595 function pointer) */
6596 static inline void convert_parameter_type(CType
*pt
)
6598 /* array must be transformed to pointer according to ANSI C */
6600 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
6605 static void post_type(CType
*type
, AttributeDef
*ad
)
6608 Sym
**plast
, *s
, *first
;
6613 /* function declaration */
6618 while (tok
!= ')') {
6619 /* read param name and compute offset */
6620 if (l
!= FUNC_OLD
) {
6621 if (!parse_btype(&pt
, &ad1
)) {
6623 error("invalid type");
6630 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
6632 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
6633 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
6634 error("parameter declared as void");
6641 convert_parameter_type(&pt
);
6642 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
6647 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
6654 /* if no parameters, then old type prototype */
6658 t1
= type
->t
& VT_STORAGE
;
6659 /* NOTE: const is ignored in returned type as it has a special
6660 meaning in gcc / C++ */
6661 type
->t
&= ~(VT_STORAGE
| VT_CONSTANT
);
6662 post_type(type
, ad
);
6663 /* we push a anonymous symbol which will contain the function prototype */
6664 s
= sym_push(SYM_FIELD
, type
, ad
->func_call
, l
);
6666 type
->t
= t1
| VT_FUNC
;
6668 } else if (tok
== '[') {
6669 /* array definition */
6675 error("invalid array size");
6678 /* parse next post type */
6679 t1
= type
->t
& VT_STORAGE
;
6680 type
->t
&= ~VT_STORAGE
;
6681 post_type(type
, ad
);
6683 /* we push a anonymous symbol which will contain the array
6685 s
= sym_push(SYM_FIELD
, type
, 0, n
);
6686 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
6691 /* Parse a type declaration (except basic type), and return the type
6692 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6693 expected. 'type' should contain the basic type. 'ad' is the
6694 attribute definition of the basic type. It can be modified by
6697 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
6700 CType type1
, *type2
;
6703 while (tok
== '*') {
6711 qualifiers
|= VT_CONSTANT
;
6716 qualifiers
|= VT_VOLATILE
;
6724 type
->t
|= qualifiers
;
6727 /* XXX: clarify attribute handling */
6728 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6729 parse_attribute(ad
);
6731 /* recursive type */
6732 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6733 type1
.t
= 0; /* XXX: same as int */
6736 /* XXX: this is not correct to modify 'ad' at this point, but
6737 the syntax is not clear */
6738 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6739 parse_attribute(ad
);
6740 type_decl(&type1
, ad
, v
, td
);
6743 /* type identifier */
6744 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
6748 if (!(td
& TYPE_ABSTRACT
))
6749 expect("identifier");
6753 post_type(type
, ad
);
6754 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6755 parse_attribute(ad
);
6758 /* append type at the end of type1 */
6771 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6772 static int lvalue_type(int t
)
6777 if (bt
== VT_BYTE
|| bt
== VT_BOOL
)
6779 else if (bt
== VT_SHORT
)
6783 if (t
& VT_UNSIGNED
)
6784 r
|= VT_LVAL_UNSIGNED
;
6788 /* indirection with full error checking and bound check */
6789 static void indir(void)
6791 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
6793 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
6795 vtop
->type
= *pointed_type(&vtop
->type
);
6796 /* an array is never an lvalue */
6797 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6798 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6799 /* if bound checking, the referenced pointer must be checked */
6800 if (do_bounds_check
)
6801 vtop
->r
|= VT_MUSTBOUND
;
6805 /* pass a parameter to a function and do type checking and casting */
6806 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
6811 func_type
= func
->c
;
6812 if (func_type
== FUNC_OLD
||
6813 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
6814 /* default casting : only need to convert float to double */
6815 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
6819 } else if (arg
== NULL
) {
6820 error("too many arguments to function");
6823 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
6824 gen_assign_cast(&type
);
6828 /* parse an expression of the form '(type)' or '(expr)' and return its
6830 static void parse_expr_type(CType
*type
)
6836 if (parse_btype(type
, &ad
)) {
6837 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
6844 static void parse_type(CType
*type
)
6849 if (!parse_btype(type
, &ad
)) {
6852 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
6855 static void vpush_tokc(int t
)
6859 vsetc(&type
, VT_CONST
, &tokc
);
6862 static void unary(void)
6864 int n
, t
, align
, size
, r
;
6869 /* XXX: GCC 2.95.3 does not generate a table although it should be
6883 vpush_tokc(VT_INT
| VT_UNSIGNED
);
6887 vpush_tokc(VT_LLONG
);
6891 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
6895 vpush_tokc(VT_FLOAT
);
6899 vpush_tokc(VT_DOUBLE
);
6903 vpush_tokc(VT_LDOUBLE
);
6906 case TOK___FUNCTION__
:
6908 goto tok_identifier
;
6914 /* special function name identifier */
6915 len
= strlen(funcname
) + 1;
6916 /* generate char[len] type */
6921 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
6922 ptr
= section_ptr_add(data_section
, len
);
6923 memcpy(ptr
, funcname
, len
);
6931 /* string parsing */
6934 if (tcc_state
->warn_write_strings
)
6939 memset(&ad
, 0, sizeof(AttributeDef
));
6940 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
6945 if (parse_btype(&type
, &ad
)) {
6946 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
6948 /* check ISOC99 compound literal */
6950 /* data is allocated locally by default */
6955 /* all except arrays are lvalues */
6956 if (!(type
.t
& VT_ARRAY
))
6957 r
|= lvalue_type(type
.t
);
6958 memset(&ad
, 0, sizeof(AttributeDef
));
6959 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
6964 } else if (tok
== '{') {
6965 /* save all registers */
6967 /* statement expression : we do not accept break/continue
6968 inside as GCC does */
6969 block(NULL
, NULL
, NULL
, NULL
, 0, 1);
6984 /* functions names must be treated as function pointers,
6985 except for unary '&' and sizeof. Since we consider that
6986 functions are not lvalues, we only have to handle it
6987 there and in function calls. */
6988 /* arrays can also be used although they are not lvalues */
6989 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
6990 !(vtop
->type
.t
& VT_ARRAY
))
6992 mk_pointer(&vtop
->type
);
6998 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
6999 vtop
->c
.i
= !vtop
->c
.i
;
7000 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
7001 vtop
->c
.i
= vtop
->c
.i
^ 1;
7003 vseti(VT_JMP
, gtst(1, 0));
7013 /* in order to force cast, we add zero */
7015 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
7016 error("pointer not accepted for unary plus");
7026 parse_expr_type(&type
);
7030 size
= type_size(&type
, &align
);
7031 if (t
== TOK_SIZEOF
) {
7033 error("sizeof applied to an incomplete type");
7040 case TOK_builtin_types_compatible_p
:
7049 type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7050 type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7051 vpushi(is_compatible_types(&type1
, &type2
));
7054 case TOK_builtin_constant_p
:
7056 int saved_nocode_wanted
, res
;
7059 saved_nocode_wanted
= nocode_wanted
;
7062 res
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
7064 nocode_wanted
= saved_nocode_wanted
;
7084 goto tok_identifier
;
7086 /* allow to take the address of a label */
7087 if (tok
< TOK_UIDENT
)
7088 expect("label identifier");
7089 s
= label_find(tok
);
7091 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7093 if (s
->r
== LABEL_DECLARED
)
7094 s
->r
= LABEL_FORWARD
;
7097 s
->type
.t
= VT_VOID
;
7098 mk_pointer(&s
->type
);
7099 s
->type
.t
|= VT_STATIC
;
7101 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
7110 expect("identifier");
7114 error("'%s' undeclared", get_tok_str(t
, NULL
));
7115 /* for simple function calls, we tolerate undeclared
7116 external reference to int() function */
7117 if (tcc_state
->warn_implicit_function_declaration
)
7118 warning("implicit declaration of function '%s'",
7119 get_tok_str(t
, NULL
));
7120 s
= external_global_sym(t
, &func_old_type
, 0);
7122 vset(&s
->type
, s
->r
, s
->c
);
7123 /* if forward reference, we must point to s */
7124 if (vtop
->r
& VT_SYM
) {
7131 /* post operations */
7133 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
7136 } else if (tok
== '.' || tok
== TOK_ARROW
) {
7138 if (tok
== TOK_ARROW
)
7143 /* expect pointer on structure */
7144 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
7145 expect("struct or union");
7149 while ((s
= s
->next
) != NULL
) {
7154 error("field not found");
7155 /* add field offset to pointer */
7156 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
7159 /* change type to field type, and set to lvalue */
7160 vtop
->type
= s
->type
;
7161 /* an array is never an lvalue */
7162 if (!(vtop
->type
.t
& VT_ARRAY
)) {
7163 vtop
->r
|= lvalue_type(vtop
->type
.t
);
7164 /* if bound checking, the referenced pointer must be checked */
7165 if (do_bounds_check
)
7166 vtop
->r
|= VT_MUSTBOUND
;
7169 } else if (tok
== '[') {
7175 } else if (tok
== '(') {
7181 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
7182 /* pointer test (no array accepted) */
7183 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
7184 vtop
->type
= *pointed_type(&vtop
->type
);
7185 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
7189 expect("function pointer");
7192 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
7194 /* get return type */
7197 sa
= s
->next
; /* first parameter */
7199 /* compute first implicit argument if a structure is returned */
7200 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
7201 /* get some space for the returned structure */
7202 size
= type_size(&s
->type
, &align
);
7203 loc
= (loc
- size
) & -align
;
7205 ret
.r
= VT_LOCAL
| VT_LVAL
;
7206 /* pass it as 'int' to avoid structure arg passing
7208 vseti(VT_LOCAL
, loc
);
7214 /* return in register */
7215 if (is_float(ret
.type
.t
)) {
7218 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
7227 gfunc_param_typed(s
, sa
);
7237 error("too few arguments to function");
7239 if (!nocode_wanted
) {
7240 gfunc_call(nb_args
);
7242 vtop
-= (nb_args
+ 1);
7245 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
7253 static void uneq(void)
7259 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
7260 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
7261 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
7276 static void expr_prod(void)
7281 while (tok
== '*' || tok
== '/' || tok
== '%') {
7289 static void expr_sum(void)
7294 while (tok
== '+' || tok
== '-') {
7302 static void expr_shift(void)
7307 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
7315 static void expr_cmp(void)
7320 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
7321 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
7329 static void expr_cmpeq(void)
7334 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
7342 static void expr_and(void)
7345 while (tok
== '&') {
7352 static void expr_xor(void)
7355 while (tok
== '^') {
7362 static void expr_or(void)
7365 while (tok
== '|') {
7372 /* XXX: fix this mess */
7373 static void expr_land_const(void)
7376 while (tok
== TOK_LAND
) {
7383 /* XXX: fix this mess */
7384 static void expr_lor_const(void)
7387 while (tok
== TOK_LOR
) {
7394 /* only used if non constant */
7395 static void expr_land(void)
7400 if (tok
== TOK_LAND
) {
7404 if (tok
!= TOK_LAND
) {
7414 static void expr_lor(void)
7419 if (tok
== TOK_LOR
) {
7423 if (tok
!= TOK_LOR
) {
7433 /* XXX: better constant handling */
7434 static void expr_eq(void)
7436 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
7438 CType type
, type1
, type2
;
7447 if (tok
== ':' && gnu_ext
) {
7463 if (vtop
!= vstack
) {
7464 /* needed to avoid having different registers saved in
7466 if (is_float(vtop
->type
.t
))
7473 if (tok
== ':' && gnu_ext
) {
7481 sv
= *vtop
; /* save value to handle it later */
7482 vtop
--; /* no vpop so that FP stack is not flushed */
7490 bt1
= t1
& VT_BTYPE
;
7492 bt2
= t2
& VT_BTYPE
;
7493 /* cast operands to correct type according to ISOC rules */
7494 if (is_float(bt1
) || is_float(bt2
)) {
7495 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
7496 type
.t
= VT_LDOUBLE
;
7497 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
7502 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
7503 /* cast to biggest op */
7505 /* convert to unsigned if it does not fit in a long long */
7506 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
7507 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
7508 type
.t
|= VT_UNSIGNED
;
7509 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
7510 /* XXX: test pointer compatibility */
7512 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
7513 /* XXX: test structure compatibility */
7515 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
7516 /* NOTE: as an extension, we accept void on only one side */
7519 /* integer operations */
7521 /* convert to unsigned if it does not fit in an integer */
7522 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
7523 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
7524 type
.t
|= VT_UNSIGNED
;
7527 /* now we convert second operand */
7530 if (is_float(type
.t
)) {
7532 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
7533 /* for long longs, we use fixed registers to avoid having
7534 to handle a complicated move */
7539 /* this is horrible, but we must also convert first
7543 /* put again first value and cast it */
7554 static void gexpr(void)
7565 /* parse an expression and return its type without any side effect. */
7566 static void expr_type(CType
*type
)
7568 int saved_nocode_wanted
;
7570 saved_nocode_wanted
= nocode_wanted
;
7575 nocode_wanted
= saved_nocode_wanted
;
7578 /* parse a unary expression and return its type without any side
7580 static void unary_type(CType
*type
)
7592 /* parse a constant expression and return value in vtop. */
7593 static void expr_const1(void)
7602 /* parse an integer constant and return its value. */
7603 static int expr_const(void)
7607 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
7608 expect("constant expression");
7614 /* return the label token if current token is a label, otherwise
7616 static int is_label(void)
7620 /* fast test first */
7621 if (tok
< TOK_UIDENT
)
7623 /* no need to save tokc because tok is an identifier */
7630 unget_tok(last_tok
);
7635 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
7636 int case_reg
, int is_expr
)
7641 /* generate line number info */
7643 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
7644 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
7646 last_line_num
= file
->line_num
;
7650 /* default return value is (void) */
7652 vtop
->type
.t
= VT_VOID
;
7655 if (tok
== TOK_IF
) {
7662 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7664 if (c
== TOK_ELSE
) {
7668 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7669 gsym(d
); /* patch else jmp */
7672 } else if (tok
== TOK_WHILE
) {
7680 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7684 } else if (tok
== '{') {
7688 /* record local declaration stack position */
7690 llabel
= local_label_stack
;
7691 /* handle local labels declarations */
7692 if (tok
== TOK_LABEL
) {
7695 if (tok
< TOK_UIDENT
)
7696 expect("label identifier");
7697 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
7707 while (tok
!= '}') {
7712 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
7715 /* pop locally defined labels */
7716 label_pop(&local_label_stack
, llabel
);
7717 /* pop locally defined symbols */
7718 sym_pop(&local_stack
, s
);
7720 } else if (tok
== TOK_RETURN
) {
7724 gen_assign_cast(&func_vt
);
7725 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
7727 /* if returning structure, must copy it to implicit
7728 first pointer arg location */
7731 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
7734 /* copy structure value to pointer */
7736 } else if (is_float(func_vt
.t
)) {
7741 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
7744 rsym
= gjmp(rsym
); /* jmp */
7745 } else if (tok
== TOK_BREAK
) {
7748 error("cannot break");
7749 *bsym
= gjmp(*bsym
);
7752 } else if (tok
== TOK_CONTINUE
) {
7755 error("cannot continue");
7756 *csym
= gjmp(*csym
);
7759 } else if (tok
== TOK_FOR
) {
7786 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7791 if (tok
== TOK_DO
) {
7796 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7807 if (tok
== TOK_SWITCH
) {
7811 /* XXX: other types than integer */
7812 case_reg
= gv(RC_INT
);
7816 b
= gjmp(0); /* jump to first case */
7818 block(&a
, csym
, &b
, &c
, case_reg
, 0);
7819 /* if no default, jmp after switch */
7827 if (tok
== TOK_CASE
) {
7834 if (gnu_ext
&& tok
== TOK_DOTS
) {
7838 warning("empty case range");
7840 /* since a case is like a label, we must skip it with a jmp */
7847 *case_sym
= gtst(1, 0);
7850 *case_sym
= gtst(1, 0);
7854 *case_sym
= gtst(1, *case_sym
);
7859 goto block_after_label
;
7861 if (tok
== TOK_DEFAULT
) {
7867 error("too many 'default'");
7870 goto block_after_label
;
7872 if (tok
== TOK_GOTO
) {
7874 if (tok
== '*' && gnu_ext
) {
7878 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
7881 } else if (tok
>= TOK_UIDENT
) {
7882 s
= label_find(tok
);
7883 /* put forward definition if needed */
7885 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7887 if (s
->r
== LABEL_DECLARED
)
7888 s
->r
= LABEL_FORWARD
;
7890 /* label already defined */
7891 if (s
->r
& LABEL_FORWARD
)
7892 s
->next
= (void *)gjmp((long)s
->next
);
7894 gjmp_addr((long)s
->next
);
7897 expect("label identifier");
7900 } else if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
7908 if (s
->r
== LABEL_DEFINED
)
7909 error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
7910 gsym((long)s
->next
);
7911 s
->r
= LABEL_DEFINED
;
7913 s
= label_push(&global_label_stack
, b
, LABEL_DEFINED
);
7915 s
->next
= (void *)ind
;
7916 /* we accept this, but it is a mistake */
7919 warning("deprecated use of label at end of compound statement");
7923 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
7926 /* expression case */
7941 /* t is the array or struct type. c is the array or struct
7942 address. cur_index/cur_field is the pointer to the current
7943 value. 'size_only' is true if only size info is needed (only used
7945 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
7946 int *cur_index
, Sym
**cur_field
,
7950 int notfirst
, index
, index_last
, align
, l
, nb_elems
, elem_size
;
7956 if (gnu_ext
&& (l
= is_label()) != 0)
7958 while (tok
== '[' || tok
== '.') {
7960 if (!(type
->t
& VT_ARRAY
))
7961 expect("array type");
7964 index
= expr_const();
7965 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
7966 expect("invalid index");
7967 if (tok
== TOK_DOTS
&& gnu_ext
) {
7969 index_last
= expr_const();
7970 if (index_last
< 0 ||
7971 (s
->c
>= 0 && index_last
>= s
->c
) ||
7973 expect("invalid index");
7979 *cur_index
= index_last
;
7980 type
= pointed_type(type
);
7981 elem_size
= type_size(type
, &align
);
7982 c
+= index
* elem_size
;
7983 /* NOTE: we only support ranges for last designator */
7984 nb_elems
= index_last
- index
+ 1;
7985 if (nb_elems
!= 1) {
7994 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
7995 expect("struct/union type");
8008 /* XXX: fix this mess by using explicit storage field */
8010 type1
.t
|= (type
->t
& ~VT_TYPE
);
8024 if (type
->t
& VT_ARRAY
) {
8026 type
= pointed_type(type
);
8027 c
+= index
* type_size(type
, &align
);
8031 error("too many field init");
8032 /* XXX: fix this mess by using explicit storage field */
8034 type1
.t
|= (type
->t
& ~VT_TYPE
);
8039 decl_initializer(type
, sec
, c
, 0, size_only
);
8041 /* XXX: make it more general */
8042 if (!size_only
&& nb_elems
> 1) {
8043 unsigned long c_end
;
8048 error("range init not supported yet for dynamic storage");
8049 c_end
= c
+ nb_elems
* elem_size
;
8050 if (c_end
> sec
->data_allocated
)
8051 section_realloc(sec
, c_end
);
8052 src
= sec
->data
+ c
;
8054 for(i
= 1; i
< nb_elems
; i
++) {
8056 memcpy(dst
, src
, elem_size
);
8062 #define EXPR_CONST 1
8065 /* store a value or an expression directly in global data or in local array */
8066 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
8067 int v
, int expr_type
)
8069 int saved_global_expr
, bt
, bit_pos
, bit_size
;
8071 unsigned long long bit_mask
;
8079 /* compound literals must be allocated globally in this case */
8080 saved_global_expr
= global_expr
;
8083 global_expr
= saved_global_expr
;
8084 /* NOTE: symbols are accepted */
8085 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
8086 error("initializer element is not constant");
8094 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
8097 /* XXX: not portable */
8098 /* XXX: generate error if incorrect relocation */
8099 gen_assign_cast(&dtype
);
8100 bt
= type
->t
& VT_BTYPE
;
8101 ptr
= sec
->data
+ c
;
8102 /* XXX: make code faster ? */
8103 if (!(type
->t
& VT_BITFIELD
)) {
8108 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
8109 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
8110 bit_mask
= (1LL << bit_size
) - 1;
8112 if ((vtop
->r
& VT_SYM
) &&
8118 (bt
== VT_INT
&& bit_size
!= 32)))
8119 error("initializer element is not computable at load time");
8122 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8125 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8128 *(double *)ptr
= vtop
->c
.d
;
8131 *(long double *)ptr
= vtop
->c
.ld
;
8134 *(long long *)ptr
|= (vtop
->c
.ll
& bit_mask
) << bit_pos
;
8137 if (vtop
->r
& VT_SYM
) {
8138 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
8140 *(int *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8145 vset(&dtype
, VT_LOCAL
, c
);
8152 /* put zeros for variable based init */
8153 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
8156 /* nothing to do because globals are already set to zero */
8158 vpush_global_sym(&func_old_type
, TOK_memset
);
8166 /* 't' contains the type and storage info. 'c' is the offset of the
8167 object in section 'sec'. If 'sec' is NULL, it means stack based
8168 allocation. 'first' is true if array '{' must be read (multi
8169 dimension implicit array init handling). 'size_only' is true if
8170 size only evaluation is wanted (only for arrays). */
8171 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
8172 int first
, int size_only
)
8174 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
8175 int size1
, align1
, expr_type
;
8179 if (type
->t
& VT_ARRAY
) {
8183 t1
= pointed_type(type
);
8184 size1
= type_size(t1
, &align1
);
8187 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
8193 /* only parse strings here if correct type (otherwise: handle
8194 them as ((w)char *) expressions */
8195 if ((tok
== TOK_LSTR
&&
8196 (t1
->t
& VT_BTYPE
) == VT_INT
) ||
8198 (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
8199 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8204 /* compute maximum number of chars wanted */
8206 cstr_len
= cstr
->size
;
8208 cstr_len
= cstr
->size
/ sizeof(int);
8211 if (n
>= 0 && nb
> (n
- array_length
))
8212 nb
= n
- array_length
;
8215 warning("initializer-string for array is too long");
8216 /* in order to go faster for common case (char
8217 string in global variable, we handle it
8219 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
8220 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
8224 ch
= ((unsigned char *)cstr
->data
)[i
];
8226 ch
= ((int *)cstr
->data
)[i
];
8227 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
8235 /* only add trailing zero if enough storage (no
8236 warning in this case since it is standard) */
8237 if (n
< 0 || array_length
< n
) {
8239 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
8245 while (tok
!= '}') {
8246 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
8247 if (n
>= 0 && index
>= n
)
8248 error("index too large");
8249 /* must put zero in holes (note that doing it that way
8250 ensures that it even works with designators) */
8251 if (!size_only
&& array_length
< index
) {
8252 init_putz(t1
, sec
, c
+ array_length
* size1
,
8253 (index
- array_length
) * size1
);
8256 if (index
> array_length
)
8257 array_length
= index
;
8258 /* special test for multi dimensional arrays (may not
8259 be strictly correct if designators are used at the
8261 if (index
>= n
&& no_oblock
)
8270 /* put zeros at the end */
8271 if (!size_only
&& n
>= 0 && array_length
< n
) {
8272 init_putz(t1
, sec
, c
+ array_length
* size1
,
8273 (n
- array_length
) * size1
);
8275 /* patch type size if needed */
8277 s
->c
= array_length
;
8278 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
8279 (sec
|| !first
|| tok
== '{')) {
8282 /* NOTE: the previous test is a specific case for automatic
8283 struct/union init */
8284 /* XXX: union needs only one init */
8286 /* XXX: this test is incorrect for local initializers
8287 beginning with ( without {. It would be much more difficult
8288 to do it correctly (ideally, the expression parser should
8289 be used in all cases) */
8295 while (tok
== '(') {
8299 if (!parse_btype(&type1
, &ad1
))
8301 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
8303 if (!is_assignable_types(type
, &type1
))
8304 error("invalid type for cast");
8309 if (first
|| tok
== '{') {
8318 while (tok
!= '}') {
8319 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
8321 if (!size_only
&& array_length
< index
) {
8322 init_putz(type
, sec
, c
+ array_length
,
8323 index
- array_length
);
8325 index
= index
+ type_size(&f
->type
, &align1
);
8326 if (index
> array_length
)
8327 array_length
= index
;
8329 if (no_oblock
&& f
== NULL
)
8335 /* put zeros at the end */
8336 if (!size_only
&& array_length
< n
) {
8337 init_putz(type
, sec
, c
+ array_length
,
8346 } else if (tok
== '{') {
8348 decl_initializer(type
, sec
, c
, first
, size_only
);
8350 } else if (size_only
) {
8351 /* just skip expression */
8353 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
8357 else if (tok
== ')')
8362 /* currently, we always use constant expression for globals
8363 (may change for scripting case) */
8364 expr_type
= EXPR_CONST
;
8366 expr_type
= EXPR_ANY
;
8367 init_putv(type
, sec
, c
, 0, expr_type
);
8371 /* parse an initializer for type 't' if 'has_init' is non zero, and
8372 allocate space in local or global data space ('r' is either
8373 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8374 variable 'v' of scope 'scope' is declared before initializers are
8375 parsed. If 'v' is zero, then a reference to the new object is put
8376 in the value stack. If 'has_init' is 2, a special parsing is done
8377 to handle string constants. */
8378 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
8379 int has_init
, int v
, int scope
)
8381 int size
, align
, addr
, data_offset
;
8383 ParseState saved_parse_state
;
8384 TokenString init_str
;
8387 size
= type_size(type
, &align
);
8388 /* If unknown size, we must evaluate it before
8389 evaluating initializers because
8390 initializers can generate global data too
8391 (e.g. string pointers or ISOC99 compound
8392 literals). It also simplifies local
8393 initializers handling */
8394 tok_str_new(&init_str
);
8397 error("unknown type size");
8398 /* get all init string */
8399 if (has_init
== 2) {
8400 /* only get strings */
8401 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8402 tok_str_add_tok(&init_str
);
8407 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
8409 error("unexpected end of file in initializer");
8410 tok_str_add_tok(&init_str
);
8413 else if (tok
== '}') {
8421 tok_str_add(&init_str
, -1);
8422 tok_str_add(&init_str
, 0);
8425 save_parse_state(&saved_parse_state
);
8427 macro_ptr
= init_str
.str
;
8429 decl_initializer(type
, NULL
, 0, 1, 1);
8430 /* prepare second initializer parsing */
8431 macro_ptr
= init_str
.str
;
8434 /* if still unknown size, error */
8435 size
= type_size(type
, &align
);
8437 error("unknown type size");
8439 /* take into account specified alignment if bigger */
8440 if (ad
->aligned
> align
)
8441 align
= ad
->aligned
;
8442 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
8444 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
8446 loc
= (loc
- size
) & -align
;
8448 /* handles bounds */
8449 /* XXX: currently, since we do only one pass, we cannot track
8450 '&' operators, so we add only arrays */
8451 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
8452 unsigned long *bounds_ptr
;
8453 /* add padding between regions */
8455 /* then add local bound info */
8456 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
8457 bounds_ptr
[0] = addr
;
8458 bounds_ptr
[1] = size
;
8461 /* local variable */
8462 sym_push(v
, type
, r
, addr
);
8464 /* push local reference */
8465 vset(type
, r
, addr
);
8471 if (v
&& scope
== VT_CONST
) {
8472 /* see if the symbol was already defined */
8475 if (!is_compatible_types(&sym
->type
, type
))
8476 error("incompatible types for redefinition of '%s'",
8477 get_tok_str(v
, NULL
));
8478 if (sym
->type
.t
& VT_EXTERN
) {
8479 /* if the variable is extern, it was not allocated */
8480 sym
->type
.t
&= ~VT_EXTERN
;
8481 /* set array size if it was ommited in extern
8483 if ((sym
->type
.t
& VT_ARRAY
) &&
8484 sym
->type
.ref
->c
< 0 &&
8486 sym
->type
.ref
->c
= type
->ref
->c
;
8488 /* we accept several definitions of the same
8489 global variable. this is tricky, because we
8490 must play with the SHN_COMMON type of the symbol */
8491 /* XXX: should check if the variable was already
8492 initialized. It is incorrect to initialized it
8494 /* no init data, we won't add more to the symbol */
8501 /* allocate symbol in corresponding section */
8506 else if (tcc_state
->nocommon
)
8510 data_offset
= sec
->data_offset
;
8511 data_offset
= (data_offset
+ align
- 1) & -align
;
8513 /* very important to increment global pointer at this time
8514 because initializers themselves can create new initializers */
8515 data_offset
+= size
;
8516 /* add padding if bound check */
8517 if (do_bounds_check
)
8519 sec
->data_offset
= data_offset
;
8520 /* allocate section space to put the data */
8521 if (sec
->sh_type
!= SHT_NOBITS
&&
8522 data_offset
> sec
->data_allocated
)
8523 section_realloc(sec
, data_offset
);
8524 /* align section if needed */
8525 if (align
> sec
->sh_addralign
)
8526 sec
->sh_addralign
= align
;
8528 addr
= 0; /* avoid warning */
8532 if (scope
== VT_CONST
) {
8537 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
8539 /* update symbol definition */
8541 put_extern_sym(sym
, sec
, addr
, size
);
8544 /* put a common area */
8545 put_extern_sym(sym
, NULL
, align
, size
);
8546 /* XXX: find a nicer way */
8547 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
8548 esym
->st_shndx
= SHN_COMMON
;
8553 /* push global reference */
8554 sym
= get_sym_ref(type
, sec
, addr
, size
);
8556 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
8560 /* handles bounds now because the symbol must be defined
8561 before for the relocation */
8562 if (do_bounds_check
) {
8563 unsigned long *bounds_ptr
;
8565 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
8566 /* then add global bound info */
8567 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
8568 bounds_ptr
[0] = 0; /* relocated */
8569 bounds_ptr
[1] = size
;
8573 decl_initializer(type
, sec
, addr
, 1, 0);
8574 /* restore parse state if needed */
8576 tok_str_free(init_str
.str
);
8577 restore_parse_state(&saved_parse_state
);
8583 void put_func_debug(Sym
*sym
)
8588 /* XXX: we put here a dummy type */
8589 snprintf(buf
, sizeof(buf
), "%s:%c1",
8590 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
8591 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
8592 cur_text_section
, sym
->c
);
8597 /* not finished : try to put some local vars in registers */
8598 //#define CONFIG_REG_VARS
8600 #ifdef CONFIG_REG_VARS
8601 void add_var_ref(int t
)
8603 printf("%s:%d: &%s\n",
8604 file
->filename
, file
->line_num
,
8605 get_tok_str(t
, NULL
));
8608 /* first pass on a function with heuristic to extract variable usage
8609 and pointer references to local variables for register allocation */
8610 void analyse_function(void)
8617 /* any symbol coming after '&' is considered as being a
8618 variable whose reference is taken. It is highly unaccurate
8619 but it is difficult to do better without a complete parse */
8622 /* if '& number', then no need to examine next tokens */
8623 if (tok
== TOK_CINT
||
8625 tok
== TOK_CLLONG
||
8626 tok
== TOK_CULLONG
) {
8628 } else if (tok
>= TOK_UIDENT
) {
8629 /* if '& ident [' or '& ident ->', then ident address
8633 if (tok
!= '[' && tok
!= TOK_ARROW
)
8637 while (tok
!= '}' && tok
!= ';' &&
8638 !((tok
== ',' || tok
== ')') && level
== 0)) {
8639 if (tok
>= TOK_UIDENT
) {
8641 } else if (tok
== '(') {
8643 } else if (tok
== ')') {
8656 /* parse an old style function declaration list */
8657 /* XXX: check multiple parameter */
8658 static void func_decl_list(Sym
*func_sym
)
8665 /* parse each declaration */
8666 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
) {
8667 if (!parse_btype(&btype
, &ad
))
8668 expect("declaration list");
8669 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
8670 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
8672 /* we accept no variable after */
8676 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8677 /* find parameter in function parameter list */
8680 if ((s
->v
& ~SYM_FIELD
) == v
)
8684 error("declaration for parameter '%s' but no such parameter",
8685 get_tok_str(v
, NULL
));
8687 /* check that no storage specifier except 'register' was given */
8688 if (type
.t
& VT_STORAGE
)
8689 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
8690 convert_parameter_type(&type
);
8691 /* we can add the type (NOTE: it could be local to the function) */
8693 /* accept other parameters */
8704 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
8705 static void decl(int l
)
8713 if (!parse_btype(&btype
, &ad
)) {
8714 /* skip redundant ';' */
8715 /* XXX: find more elegant solution */
8720 if (l
== VT_CONST
&&
8721 (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
8722 /* global asm block */
8726 /* special test for old K&R protos without explicit int
8727 type. Only accepted when defining global data */
8728 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
8732 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
8733 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
8735 /* we accept no variable after */
8739 while (1) { /* iterate thru each declaration */
8741 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8745 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
8746 printf("type = '%s'\n", buf
);
8749 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8750 /* if old style function prototype, we accept a
8753 if (sym
->c
== FUNC_OLD
)
8754 func_decl_list(sym
);
8758 #ifdef CONFIG_REG_VARS
8759 TokenString func_str
;
8760 ParseState saved_parse_state
;
8764 error("cannot use local functions");
8765 if (!(type
.t
& VT_FUNC
))
8766 expect("function definition");
8768 /* reject abstract declarators in function definition */
8770 while ((sym
= sym
->next
) != NULL
)
8771 if (!(sym
->v
& ~SYM_FIELD
))
8772 expect("identifier");
8774 /* XXX: cannot do better now: convert extern line to static inline */
8775 if ((type
.t
& (VT_EXTERN
| VT_INLINE
)) == (VT_EXTERN
| VT_INLINE
))
8776 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
8778 #ifdef CONFIG_REG_VARS
8779 /* parse all function code and record it */
8781 tok_str_new(&func_str
);
8787 error("unexpected end of file");
8788 tok_str_add_tok(&func_str
);
8793 } else if (t
== '}') {
8795 if (block_level
== 0)
8799 tok_str_add(&func_str
, -1);
8800 tok_str_add(&func_str
, 0);
8802 save_parse_state(&saved_parse_state
);
8804 macro_ptr
= func_str
.str
;
8809 /* compute text section */
8810 cur_text_section
= ad
.section
;
8811 if (!cur_text_section
)
8812 cur_text_section
= text_section
;
8813 ind
= cur_text_section
->data_offset
;
8814 funcname
= get_tok_str(v
, NULL
);
8817 if ((sym
->type
.t
& VT_BTYPE
) != VT_FUNC
)
8819 /* specific case: if not func_call defined, we put
8820 the one of the prototype */
8821 /* XXX: should have default value */
8822 if (sym
->type
.ref
->r
!= FUNC_CDECL
&&
8823 type
.ref
->r
== FUNC_CDECL
)
8824 type
.ref
->r
= sym
->type
.ref
->r
;
8825 if (!is_compatible_types(&sym
->type
, &type
)) {
8827 error("incompatible types for redefinition of '%s'",
8828 get_tok_str(v
, NULL
));
8830 /* if symbol is already defined, then put complete type */
8833 /* put function symbol */
8834 sym
= global_identifier_push(v
, type
.t
, 0);
8835 sym
->type
.ref
= type
.ref
;
8837 /* NOTE: we patch the symbol size later */
8838 put_extern_sym(sym
, cur_text_section
, ind
, 0);
8840 sym
->r
= VT_SYM
| VT_CONST
;
8841 /* put debug symbol */
8843 put_func_debug(sym
);
8844 /* push a dummy symbol to enable local sym storage */
8845 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
8846 gfunc_prolog(&type
);
8848 #ifdef CONFIG_REG_VARS
8849 macro_ptr
= func_str
.str
;
8852 block(NULL
, NULL
, NULL
, NULL
, 0, 0);
8855 cur_text_section
->data_offset
= ind
;
8856 label_pop(&global_label_stack
, NULL
);
8857 sym_pop(&local_stack
, NULL
); /* reset local stack */
8858 /* end of function */
8859 /* patch symbol size */
8860 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
8863 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
8865 funcname
= ""; /* for safety */
8866 func_vt
.t
= VT_VOID
; /* for safety */
8867 ind
= 0; /* for safety */
8869 #ifdef CONFIG_REG_VARS
8870 tok_str_free(func_str
.str
);
8871 restore_parse_state(&saved_parse_state
);
8875 if (btype
.t
& VT_TYPEDEF
) {
8876 /* save typedefed type */
8877 /* XXX: test storage specifiers ? */
8878 sym
= sym_push(v
, &type
, 0, 0);
8879 sym
->type
.t
|= VT_TYPEDEF
;
8880 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8881 /* external function definition */
8882 /* specific case for func_call attribute */
8884 type
.ref
->r
= ad
.func_call
;
8885 external_sym(v
, &type
, 0);
8887 /* not lvalue if array */
8889 if (!(type
.t
& VT_ARRAY
))
8890 r
|= lvalue_type(type
.t
);
8891 has_init
= (tok
== '=');
8892 if ((btype
.t
& VT_EXTERN
) ||
8893 ((type
.t
& VT_ARRAY
) && (type
.t
& VT_STATIC
) &&
8894 !has_init
&& l
== VT_CONST
&& type
.ref
->c
< 0)) {
8895 /* external variable */
8896 /* NOTE: as GCC, uninitialized global static
8897 arrays of null size are considered as
8899 external_sym(v
, &type
, r
);
8901 if (type
.t
& VT_STATIC
)
8907 decl_initializer_alloc(&type
, &ad
, r
,
8921 /* better than nothing, but needs extension to handle '-E' option
8923 static void preprocess_init(TCCState
*s1
)
8925 s1
->include_stack_ptr
= s1
->include_stack
;
8926 /* XXX: move that before to avoid having to initialize
8927 file->ifdef_stack_ptr ? */
8928 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
8929 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
8931 /* XXX: not ANSI compliant: bound checking says error */
8935 /* compile the C file opened in 'file'. Return non zero if errors. */
8936 static int tcc_compile(TCCState
*s1
)
8940 volatile int section_sym
;
8943 printf("%s: **** new file\n", file
->filename
);
8945 preprocess_init(s1
);
8948 anon_sym
= SYM_FIRST_ANOM
;
8950 /* file info: full path + filename */
8951 section_sym
= 0; /* avoid warning */
8953 section_sym
= put_elf_sym(symtab_section
, 0, 0,
8954 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
8955 text_section
->sh_num
, NULL
);
8956 getcwd(buf
, sizeof(buf
));
8957 pstrcat(buf
, sizeof(buf
), "/");
8958 put_stabs_r(buf
, N_SO
, 0, 0,
8959 text_section
->data_offset
, text_section
, section_sym
);
8960 put_stabs_r(file
->filename
, N_SO
, 0, 0,
8961 text_section
->data_offset
, text_section
, section_sym
);
8963 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
8964 symbols can be safely used */
8965 put_elf_sym(symtab_section
, 0, 0,
8966 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
8967 SHN_ABS
, file
->filename
);
8969 /* define some often used types */
8970 int_type
.t
= VT_INT
;
8972 char_pointer_type
.t
= VT_BYTE
;
8973 mk_pointer(&char_pointer_type
);
8975 func_old_type
.t
= VT_FUNC
;
8976 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
8979 /* define 'void *alloca(unsigned int)' builtin function */
8984 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
8985 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
8988 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
8992 define_start
= define_stack
;
8994 if (setjmp(s1
->error_jmp_buf
) == 0) {
8996 s1
->error_set_jmp_enabled
= 1;
8998 ch
= file
->buf_ptr
[0];
8999 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
9000 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
;
9004 expect("declaration");
9006 /* end of translation unit info */
9008 put_stabs_r(NULL
, N_SO
, 0, 0,
9009 text_section
->data_offset
, text_section
, section_sym
);
9012 s1
->error_set_jmp_enabled
= 0;
9014 /* reset define stack, but leave -Dsymbols (may be incorrect if
9015 they are undefined) */
9016 free_defines(define_start
);
9018 sym_pop(&global_stack
, NULL
);
9020 return s1
->nb_errors
!= 0 ? -1 : 0;
9024 int tcc_compile_string(TCCState
*s
, const char *str
)
9026 BufferedFile bf1
, *bf
= &bf1
;
9030 /* init file structure */
9032 /* XXX: avoid copying */
9034 buf
= tcc_malloc(len
+ 1);
9037 memcpy(buf
, str
, len
);
9040 bf
->buf_end
= buf
+ len
;
9041 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
9045 ret
= tcc_compile(s
);
9049 /* currently, no need to close */
9054 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
9055 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
9057 BufferedFile bf1
, *bf
= &bf1
;
9059 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
9060 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
9064 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
9066 /* init file structure */
9068 bf
->buf_ptr
= bf
->buffer
;
9069 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
9070 *bf
->buf_end
= CH_EOB
;
9071 bf
->filename
[0] = '\0';
9075 s1
->include_stack_ptr
= s1
->include_stack
;
9077 /* parse with define parser */
9078 ch
= file
->buf_ptr
[0];
9084 /* undefine a preprocessor symbol */
9085 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
9089 ts
= tok_alloc(sym
, strlen(sym
));
9090 s
= define_find(ts
->tok
);
9091 /* undefine symbol by putting an invalid name */
9096 #ifdef CONFIG_TCC_ASM
9098 #ifdef TCC_TARGET_I386
9099 #include "i386-asm.c"
9104 static void asm_instr(void)
9106 error("inline asm() not supported");
9108 static void asm_global_instr(void)
9110 error("inline asm() not supported");
9116 #ifdef TCC_TARGET_COFF
9117 #include "tcccoff.c"
9120 /* print the position in the source file of PC value 'pc' by reading
9121 the stabs debug information */
9122 static void rt_printline(unsigned long wanted_pc
)
9124 Stab_Sym
*sym
, *sym_end
;
9125 char func_name
[128], last_func_name
[128];
9126 unsigned long func_addr
, last_pc
, pc
;
9127 const char *incl_files
[INCLUDE_STACK_SIZE
];
9128 int incl_index
, len
, last_line_num
, i
;
9129 const char *str
, *p
;
9131 fprintf(stderr
, "0x%08lx:", wanted_pc
);
9133 func_name
[0] = '\0';
9136 last_func_name
[0] = '\0';
9137 last_pc
= 0xffffffff;
9139 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
9140 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
9141 while (sym
< sym_end
) {
9142 switch(sym
->n_type
) {
9143 /* function start or end */
9145 if (sym
->n_strx
== 0) {
9146 /* we test if between last line and end of function */
9147 pc
= sym
->n_value
+ func_addr
;
9148 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9150 func_name
[0] = '\0';
9153 str
= stabstr_section
->data
+ sym
->n_strx
;
9154 p
= strchr(str
, ':');
9156 pstrcpy(func_name
, sizeof(func_name
), str
);
9159 if (len
> sizeof(func_name
) - 1)
9160 len
= sizeof(func_name
) - 1;
9161 memcpy(func_name
, str
, len
);
9162 func_name
[len
] = '\0';
9164 func_addr
= sym
->n_value
;
9167 /* line number info */
9169 pc
= sym
->n_value
+ func_addr
;
9170 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9173 last_line_num
= sym
->n_desc
;
9175 strcpy(last_func_name
, func_name
);
9179 str
= stabstr_section
->data
+ sym
->n_strx
;
9181 if (incl_index
< INCLUDE_STACK_SIZE
) {
9182 incl_files
[incl_index
++] = str
;
9190 if (sym
->n_strx
== 0) {
9191 incl_index
= 0; /* end of translation unit */
9193 str
= stabstr_section
->data
+ sym
->n_strx
;
9194 /* do not add path */
9196 if (len
> 0 && str
[len
- 1] != '/')
9204 /* second pass: we try symtab symbols (no line number info) */
9207 Elf32_Sym
*sym
, *sym_end
;
9210 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
9211 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
9214 type
= ELF32_ST_TYPE(sym
->st_info
);
9215 if (type
== STT_FUNC
) {
9216 if (wanted_pc
>= sym
->st_value
&&
9217 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
9218 pstrcpy(last_func_name
, sizeof(last_func_name
),
9219 strtab_section
->data
+ sym
->st_name
);
9225 /* did not find any info: */
9226 fprintf(stderr
, " ???\n");
9229 if (last_func_name
[0] != '\0') {
9230 fprintf(stderr
, " %s()", last_func_name
);
9232 if (incl_index
> 0) {
9233 fprintf(stderr
, " (%s:%d",
9234 incl_files
[incl_index
- 1], last_line_num
);
9235 for(i
= incl_index
- 2; i
>= 0; i
--)
9236 fprintf(stderr
, ", included from %s", incl_files
[i
]);
9237 fprintf(stderr
, ")");
9239 fprintf(stderr
, "\n");
9246 /* fix for glibc 2.1 */
9252 /* return the PC at frame level 'level'. Return non zero if not found */
9253 static int rt_get_caller_pc(unsigned long *paddr
,
9254 ucontext_t
*uc
, int level
)
9260 #if defined(__FreeBSD__)
9261 *paddr
= uc
->uc_mcontext
.mc_eip
;
9262 #elif defined(__dietlibc__)
9263 *paddr
= uc
->uc_mcontext
.eip
;
9265 *paddr
= uc
->uc_mcontext
.gregs
[REG_EIP
];
9269 #if defined(__FreeBSD__)
9270 fp
= uc
->uc_mcontext
.mc_ebp
;
9271 #elif defined(__dietlibc__)
9272 fp
= uc
->uc_mcontext
.ebp
;
9274 fp
= uc
->uc_mcontext
.gregs
[REG_EBP
];
9276 for(i
=1;i
<level
;i
++) {
9277 /* XXX: check address validity with program info */
9278 if (fp
<= 0x1000 || fp
>= 0xc0000000)
9280 fp
= ((unsigned long *)fp
)[0];
9282 *paddr
= ((unsigned long *)fp
)[1];
9288 #warning add arch specific rt_get_caller_pc()
9290 static int rt_get_caller_pc(unsigned long *paddr
,
9291 ucontext_t
*uc
, int level
)
9297 /* emit a run time error at position 'pc' */
9298 void rt_error(ucontext_t
*uc
, const char *fmt
, ...)
9305 fprintf(stderr
, "Runtime error: ");
9306 vfprintf(stderr
, fmt
, ap
);
9307 fprintf(stderr
, "\n");
9308 for(i
=0;i
<num_callers
;i
++) {
9309 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
9312 fprintf(stderr
, "at ");
9314 fprintf(stderr
, "by ");
9321 /* signal handler for fatal errors */
9322 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
9324 ucontext_t
*uc
= puc
;
9328 switch(siginf
->si_code
) {
9331 rt_error(uc
, "division by zero");
9334 rt_error(uc
, "floating point exception");
9340 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
9341 rt_error(uc
, *rt_bound_error_msg
);
9343 rt_error(uc
, "dereferencing invalid pointer");
9346 rt_error(uc
, "illegal instruction");
9349 rt_error(uc
, "abort() called");
9352 rt_error(uc
, "caught signal %d", signum
);
9359 /* do all relocations (needed before using tcc_get_symbol()) */
9360 int tcc_relocate(TCCState
*s1
)
9367 tcc_add_runtime(s1
);
9369 build_got_entries(s1
);
9371 relocate_common_syms();
9373 /* compute relocation address : section are relocated in place. We
9374 also alloc the bss space */
9375 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9376 s
= s1
->sections
[i
];
9377 if (s
->sh_flags
& SHF_ALLOC
) {
9378 if (s
->sh_type
== SHT_NOBITS
)
9379 s
->data
= tcc_mallocz(s
->data_offset
);
9380 s
->sh_addr
= (unsigned long)s
->data
;
9384 relocate_syms(s1
, 1);
9386 if (s1
->nb_errors
!= 0)
9389 /* relocate each section */
9390 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9391 s
= s1
->sections
[i
];
9393 relocate_section(s1
, s
);
9398 /* launch the compiled program with the given arguments */
9399 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
9401 int (*prog_main
)(int, char **);
9403 if (tcc_relocate(s1
) < 0)
9406 prog_main
= tcc_get_symbol_err(s1
, "main");
9410 error("debug mode currently not available for Windows");
9412 struct sigaction sigact
;
9413 /* install TCC signal handlers to print debug info on fatal
9415 sigact
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
9416 sigact
.sa_sigaction
= sig_error
;
9417 sigemptyset(&sigact
.sa_mask
);
9418 sigaction(SIGFPE
, &sigact
, NULL
);
9419 sigaction(SIGILL
, &sigact
, NULL
);
9420 sigaction(SIGSEGV
, &sigact
, NULL
);
9421 sigaction(SIGBUS
, &sigact
, NULL
);
9422 sigaction(SIGABRT
, &sigact
, NULL
);
9426 #ifdef CONFIG_TCC_BCHECK
9427 if (do_bounds_check
) {
9428 void (*bound_init
)(void);
9430 /* set error function */
9431 rt_bound_error_msg
= (void *)tcc_get_symbol_err(s1
,
9432 "__bound_error_msg");
9434 /* XXX: use .init section so that it also work in binary ? */
9435 bound_init
= (void *)tcc_get_symbol_err(s1
, "__bound_init");
9439 return (*prog_main
)(argc
, argv
);
9442 TCCState
*tcc_new(void)
9449 s
= tcc_mallocz(sizeof(TCCState
));
9453 s
->output_type
= TCC_OUTPUT_MEMORY
;
9455 /* init isid table */
9457 isidnum_table
[i
] = isid(i
) || isnum(i
);
9459 /* add all tokens */
9461 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
9463 tok_ident
= TOK_IDENT
;
9472 ts
= tok_alloc(p
, r
- p
- 1);
9476 /* we add dummy defines for some special macros to speed up tests
9477 and to have working defined() */
9478 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
9479 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
9480 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
9481 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
9483 /* standard defines */
9484 tcc_define_symbol(s
, "__STDC__", NULL
);
9485 #if defined(TCC_TARGET_I386)
9486 tcc_define_symbol(s
, "__i386__", NULL
);
9488 #if defined(TCC_TARGET_ARM)
9489 tcc_define_symbol(s
, "__ARM_ARCH_4__", NULL
);
9490 tcc_define_symbol(s
, "__arm_elf__", NULL
);
9491 tcc_define_symbol(s
, "__arm_elf", NULL
);
9492 tcc_define_symbol(s
, "arm_elf", NULL
);
9493 tcc_define_symbol(s
, "__arm__", NULL
);
9494 tcc_define_symbol(s
, "__arm", NULL
);
9495 tcc_define_symbol(s
, "arm", NULL
);
9496 tcc_define_symbol(s
, "__APCS_32__", NULL
);
9499 tcc_define_symbol(s
, "__linux__", NULL
);
9500 tcc_define_symbol(s
, "linux", NULL
);
9502 /* tiny C specific defines */
9503 tcc_define_symbol(s
, "__TINYC__", NULL
);
9505 /* tiny C & gcc defines */
9506 tcc_define_symbol(s
, "__SIZE_TYPE__", "unsigned int");
9507 tcc_define_symbol(s
, "__PTRDIFF_TYPE__", "int");
9508 tcc_define_symbol(s
, "__WCHAR_TYPE__", "int");
9510 /* default library paths */
9511 tcc_add_library_path(s
, "/usr/local/lib");
9512 tcc_add_library_path(s
, "/usr/lib");
9513 tcc_add_library_path(s
, "/lib");
9515 /* no section zero */
9516 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
9518 /* create standard sections */
9519 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
9520 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
9521 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
9523 /* symbols are always generated for linking stage */
9524 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
9526 ".hashtab", SHF_PRIVATE
);
9527 strtab_section
= symtab_section
->link
;
9529 /* private symbol table for dynamic symbols */
9530 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
9532 ".dynhashtab", SHF_PRIVATE
);
9533 s
->alacarte_link
= 1;
9535 #ifdef CHAR_IS_UNSIGNED
9536 s
->char_is_unsigned
= 1;
9541 void tcc_delete(TCCState
*s1
)
9545 /* free -D defines */
9549 n
= tok_ident
- TOK_IDENT
;
9550 for(i
= 0; i
< n
; i
++)
9551 tcc_free(table_ident
[i
]);
9552 tcc_free(table_ident
);
9554 /* free all sections */
9556 free_section(symtab_section
->hash
);
9558 free_section(s1
->dynsymtab_section
->hash
);
9559 free_section(s1
->dynsymtab_section
->link
);
9560 free_section(s1
->dynsymtab_section
);
9562 for(i
= 1; i
< s1
->nb_sections
; i
++)
9563 free_section(s1
->sections
[i
]);
9564 tcc_free(s1
->sections
);
9566 /* free loaded dlls array */
9567 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
9568 tcc_free(s1
->loaded_dlls
[i
]);
9569 tcc_free(s1
->loaded_dlls
);
9572 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
9573 tcc_free(s1
->library_paths
[i
]);
9574 tcc_free(s1
->library_paths
);
9576 /* cached includes */
9577 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
9578 tcc_free(s1
->cached_includes
[i
]);
9579 tcc_free(s1
->cached_includes
);
9581 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
9582 tcc_free(s1
->include_paths
[i
]);
9583 tcc_free(s1
->include_paths
);
9585 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
9586 tcc_free(s1
->sysinclude_paths
[i
]);
9587 tcc_free(s1
->sysinclude_paths
);
9592 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
9596 pathname1
= tcc_strdup(pathname
);
9597 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
9601 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
9605 pathname1
= tcc_strdup(pathname
);
9606 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
9610 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
9612 const char *ext
, *filename1
;
9615 BufferedFile
*saved_file
;
9617 /* find source file type with extension */
9618 filename1
= strrchr(filename
, '/');
9622 filename1
= filename
;
9623 ext
= strrchr(filename1
, '.');
9629 file
= tcc_open(s1
, filename
);
9631 if (flags
& AFF_PRINT_ERROR
) {
9632 error_noabort("file '%s' not found", filename
);
9638 if (!ext
|| !strcmp(ext
, "c")) {
9639 /* C file assumed */
9640 ret
= tcc_compile(s1
);
9642 #ifdef CONFIG_TCC_ASM
9643 if (!strcmp(ext
, "S")) {
9644 /* preprocessed assembler */
9645 ret
= tcc_assemble(s1
, 1);
9646 } else if (!strcmp(ext
, "s")) {
9647 /* non preprocessed assembler */
9648 ret
= tcc_assemble(s1
, 0);
9653 /* assume executable format: auto guess file type */
9654 ret
= read(fd
, &ehdr
, sizeof(ehdr
));
9655 lseek(fd
, 0, SEEK_SET
);
9657 error_noabort("could not read header");
9659 } else if (ret
!= sizeof(ehdr
)) {
9660 goto try_load_script
;
9663 if (ehdr
.e_ident
[0] == ELFMAG0
&&
9664 ehdr
.e_ident
[1] == ELFMAG1
&&
9665 ehdr
.e_ident
[2] == ELFMAG2
&&
9666 ehdr
.e_ident
[3] == ELFMAG3
) {
9667 file
->line_num
= 0; /* do not display line number if error */
9668 if (ehdr
.e_type
== ET_REL
) {
9669 ret
= tcc_load_object_file(s1
, fd
, 0);
9670 } else if (ehdr
.e_type
== ET_DYN
) {
9671 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
9673 h
= dlopen(filename
, RTLD_GLOBAL
| RTLD_LAZY
);
9679 ret
= tcc_load_dll(s1
, fd
, filename
,
9680 (flags
& AFF_REFERENCED_DLL
) != 0);
9683 error_noabort("unrecognized ELF file");
9686 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
9687 file
->line_num
= 0; /* do not display line number if error */
9688 ret
= tcc_load_archive(s1
, fd
);
9690 #ifdef TCC_TARGET_COFF
9691 if (*(uint16_t *)(&ehdr
) == COFF_C67_MAGIC
) {
9692 ret
= tcc_load_coff(s1
, fd
);
9696 /* as GNU ld, consider it is an ld script if not recognized */
9698 ret
= tcc_load_ldscript(s1
);
9700 error_noabort("unrecognized file type");
9715 int tcc_add_file(TCCState
*s
, const char *filename
)
9717 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
9720 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
9724 pathname1
= tcc_strdup(pathname
);
9725 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
9729 /* find and load a dll. Return non zero if not found */
9730 /* XXX: add '-rpath' option support ? */
9731 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
9736 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
9737 snprintf(buf
, sizeof(buf
), "%s/%s",
9738 s
->library_paths
[i
], filename
);
9739 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
9745 /* the library name is the same as the argument of the '-l' option */
9746 int tcc_add_library(TCCState
*s
, const char *libraryname
)
9751 /* first we look for the dynamic library if not static linking */
9752 if (!s
->static_link
) {
9753 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
9754 if (tcc_add_dll(s
, buf
, 0) == 0)
9758 /* then we look for the static library */
9759 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
9760 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
9761 s
->library_paths
[i
], libraryname
);
9762 if (tcc_add_file_internal(s
, buf
, 0) == 0)
9768 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
9770 add_elf_sym(symtab_section
, val
, 0,
9771 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
9776 int tcc_set_output_type(TCCState
*s
, int output_type
)
9780 s
->output_type
= output_type
;
9783 /* default include paths */
9784 /* XXX: reverse order needed if -isystem support */
9785 tcc_add_sysinclude_path(s
, "/usr/local/include");
9786 tcc_add_sysinclude_path(s
, "/usr/include");
9787 snprintf(buf
, sizeof(buf
), "%s/include", tcc_lib_path
);
9788 tcc_add_sysinclude_path(s
, buf
);
9791 /* if bound checking, then add corresponding sections */
9792 #ifdef CONFIG_TCC_BCHECK
9793 if (do_bounds_check
) {
9795 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
9796 /* create bounds sections */
9797 bounds_section
= new_section(s
, ".bounds",
9798 SHT_PROGBITS
, SHF_ALLOC
);
9799 lbounds_section
= new_section(s
, ".lbounds",
9800 SHT_PROGBITS
, SHF_ALLOC
);
9804 if (s
->char_is_unsigned
) {
9805 tcc_define_symbol(s
, "__CHAR_UNSIGNED__", NULL
);
9808 /* add debug sections */
9811 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
9812 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
9813 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
9814 put_elf_str(stabstr_section
, "");
9815 stab_section
->link
= stabstr_section
;
9816 /* put first entry */
9817 put_stabs("", 0, 0, 0, 0);
9820 /* add libc crt1/crti objects */
9821 if ((output_type
== TCC_OUTPUT_EXE
|| output_type
== TCC_OUTPUT_DLL
) &&
9823 if (output_type
!= TCC_OUTPUT_DLL
)
9824 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
9825 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
9830 #define WD_ALL 0x0001 /* warning is activated when using -Wall */
9831 #define FD_INVERT 0x0002 /* invert value before storing */
9833 typedef struct FlagDef
{
9839 static const FlagDef warning_defs
[] = {
9840 { offsetof(TCCState
, warn_unsupported
), 0, "unsupported" },
9841 { offsetof(TCCState
, warn_write_strings
), 0, "write-strings" },
9842 { offsetof(TCCState
, warn_error
), 0, "error" },
9843 { offsetof(TCCState
, warn_implicit_function_declaration
), WD_ALL
,
9844 "implicit-function-declaration" },
9847 static int set_flag(TCCState
*s
, const FlagDef
*flags
, int nb_flags
,
9848 const char *name
, int value
)
9855 if (r
[0] == 'n' && r
[1] == 'o' && r
[2] == '-') {
9859 for(i
= 0, p
= flags
; i
< nb_flags
; i
++, p
++) {
9860 if (!strcmp(r
, p
->name
))
9865 if (p
->flags
& FD_INVERT
)
9867 *(int *)((uint8_t *)s
+ p
->offset
) = value
;
9872 /* set/reset a warning */
9873 int tcc_set_warning(TCCState
*s
, const char *warning_name
, int value
)
9878 if (!strcmp(warning_name
, "all")) {
9879 for(i
= 0, p
= warning_defs
; i
< countof(warning_defs
); i
++, p
++) {
9880 if (p
->flags
& WD_ALL
)
9881 *(int *)((uint8_t *)s
+ p
->offset
) = 1;
9885 return set_flag(s
, warning_defs
, countof(warning_defs
),
9886 warning_name
, value
);
9890 static const FlagDef flag_defs
[] = {
9891 { offsetof(TCCState
, char_is_unsigned
), 0, "unsigned-char" },
9892 { offsetof(TCCState
, char_is_unsigned
), FD_INVERT
, "signed-char" },
9893 { offsetof(TCCState
, nocommon
), FD_INVERT
, "common" },
9896 /* set/reset a flag */
9897 int tcc_set_flag(TCCState
*s
, const char *flag_name
, int value
)
9899 return set_flag(s
, flag_defs
, countof(flag_defs
),
9903 #if !defined(LIBTCC)
9905 /* extract the basename of a file */
9906 static const char *tcc_basename(const char *name
)
9909 p
= strrchr(name
, '/');
9912 p
= strrchr(name
, '\\');
9921 static int64_t getclock_us(void)
9926 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
9929 gettimeofday(&tv
, NULL
);
9930 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
9936 printf("tcc version " TCC_VERSION
" - Tiny C Compiler - Copyright (C) 2001-2003 Fabrice Bellard\n"
9937 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
9938 " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
9939 " [infile1 infile2...] [-run infile args...]\n"
9941 "General options:\n"
9942 " -v display current version\n"
9943 " -c compile only - generate an object file\n"
9944 " -o outfile set output filename\n"
9945 " -Bdir set tcc internal library path\n"
9946 " -bench output compilation statistics\n"
9947 " -run run compiled source\n"
9948 " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
9949 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
9950 " -w disable all warnings\n"
9951 "Preprocessor options:\n"
9952 " -Idir add include path 'dir'\n"
9953 " -Dsym[=val] define 'sym' with value 'val'\n"
9954 " -Usym undefine 'sym'\n"
9956 " -Ldir add library path 'dir'\n"
9957 " -llib link with dynamic or static library 'lib'\n"
9958 " -shared generate a shared library\n"
9959 " -static static linking\n"
9960 " -rdynamic export all global symbols to dynamic linker\n"
9961 " -r relocatable output\n"
9962 "Debugger options:\n"
9963 " -g generate runtime debug info\n"
9964 #ifdef CONFIG_TCC_BCHECK
9965 " -b compile with built-in memory and bounds checker (implies -g)\n"
9967 " -bt N show N callers in stack traces\n"
9971 #define TCC_OPTION_HAS_ARG 0x0001
9972 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
9974 typedef struct TCCOption
{
10002 TCC_OPTION_nostdinc
,
10003 TCC_OPTION_nostdlib
,
10004 TCC_OPTION_print_search_dirs
,
10005 TCC_OPTION_rdynamic
,
10011 static const TCCOption tcc_options
[] = {
10012 { "h", TCC_OPTION_HELP
, 0 },
10013 { "?", TCC_OPTION_HELP
, 0 },
10014 { "I", TCC_OPTION_I
, TCC_OPTION_HAS_ARG
},
10015 { "D", TCC_OPTION_D
, TCC_OPTION_HAS_ARG
},
10016 { "U", TCC_OPTION_U
, TCC_OPTION_HAS_ARG
},
10017 { "L", TCC_OPTION_L
, TCC_OPTION_HAS_ARG
},
10018 { "B", TCC_OPTION_B
, TCC_OPTION_HAS_ARG
},
10019 { "l", TCC_OPTION_l
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10020 { "bench", TCC_OPTION_bench
, 0 },
10021 { "bt", TCC_OPTION_bt
, TCC_OPTION_HAS_ARG
},
10022 #ifdef CONFIG_TCC_BCHECK
10023 { "b", TCC_OPTION_b
, 0 },
10025 { "g", TCC_OPTION_g
, 0 },
10026 { "c", TCC_OPTION_c
, 0 },
10027 { "static", TCC_OPTION_static
, 0 },
10028 { "shared", TCC_OPTION_shared
, 0 },
10029 { "o", TCC_OPTION_o
, TCC_OPTION_HAS_ARG
},
10030 { "run", TCC_OPTION_run
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10031 { "rdynamic", TCC_OPTION_rdynamic
, 0 },
10032 { "r", TCC_OPTION_r
, 0 },
10033 { "Wl,", TCC_OPTION_Wl
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10034 { "W", TCC_OPTION_W
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10035 { "O", TCC_OPTION_O
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10036 { "m", TCC_OPTION_m
, TCC_OPTION_HAS_ARG
},
10037 { "f", TCC_OPTION_f
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10038 { "nostdinc", TCC_OPTION_nostdinc
, 0 },
10039 { "nostdlib", TCC_OPTION_nostdlib
, 0 },
10040 { "print-search-dirs", TCC_OPTION_print_search_dirs
, 0 },
10041 { "v", TCC_OPTION_v
, 0 },
10042 { "w", TCC_OPTION_w
, 0 },
10046 /* convert 'str' into an array of space separated strings */
10047 static int expand_args(char ***pargv
, const char *str
)
10056 while (is_space(*str
))
10061 while (*str
!= '\0' && !is_space(*str
))
10064 arg
= tcc_malloc(len
+ 1);
10065 memcpy(arg
, s1
, len
);
10067 dynarray_add((void ***)&argv
, &argc
, arg
);
10073 static char **files
;
10074 static int nb_files
, nb_libraries
;
10075 static int multiple_files
;
10076 static int print_search_dirs
;
10077 static int output_type
;
10078 static int reloc_output
;
10079 static const char *outfile
;
10081 int parse_args(TCCState
*s
, int argc
, char **argv
)
10084 const TCCOption
*popt
;
10085 const char *optarg
, *p1
, *r1
;
10090 if (optind
>= argc
) {
10091 if (nb_files
== 0 && !print_search_dirs
)
10096 r
= argv
[optind
++];
10098 /* add a new file */
10099 dynarray_add((void ***)&files
, &nb_files
, r
);
10100 if (!multiple_files
) {
10102 /* argv[0] will be this file */
10106 /* find option in table (match only the first chars */
10107 popt
= tcc_options
;
10111 error("invalid option -- '%s'", r
);
10124 if (popt
->flags
& TCC_OPTION_HAS_ARG
) {
10125 if (*r1
!= '\0' || (popt
->flags
& TCC_OPTION_NOSEP
)) {
10128 if (optind
>= argc
)
10129 error("argument to '%s' is missing", r
);
10130 optarg
= argv
[optind
++];
10138 switch(popt
->index
) {
10139 case TCC_OPTION_HELP
:
10144 if (tcc_add_include_path(s
, optarg
) < 0)
10145 error("too many include paths");
10150 sym
= (char *)optarg
;
10151 value
= strchr(sym
, '=');
10156 tcc_define_symbol(s
, sym
, value
);
10160 tcc_undefine_symbol(s
, optarg
);
10163 tcc_add_library_path(s
, optarg
);
10166 /* set tcc utilities path (mainly for tcc development) */
10167 tcc_lib_path
= optarg
;
10170 dynarray_add((void ***)&files
, &nb_files
, r
);
10173 case TCC_OPTION_bench
:
10176 case TCC_OPTION_bt
:
10177 num_callers
= atoi(optarg
);
10179 #ifdef CONFIG_TCC_BCHECK
10181 do_bounds_check
= 1;
10189 multiple_files
= 1;
10190 output_type
= TCC_OUTPUT_OBJ
;
10192 case TCC_OPTION_static
:
10193 s
->static_link
= 1;
10195 case TCC_OPTION_shared
:
10196 output_type
= TCC_OUTPUT_DLL
;
10199 multiple_files
= 1;
10203 /* generate a .o merging several output files */
10205 output_type
= TCC_OUTPUT_OBJ
;
10207 case TCC_OPTION_nostdinc
:
10210 case TCC_OPTION_nostdlib
:
10213 case TCC_OPTION_print_search_dirs
:
10214 print_search_dirs
= 1;
10216 case TCC_OPTION_run
:
10220 argc1
= expand_args(&argv1
, optarg
);
10222 parse_args(s
, argc1
, argv1
);
10224 multiple_files
= 0;
10225 output_type
= TCC_OUTPUT_MEMORY
;
10229 printf("tcc version %s\n", TCC_VERSION
);
10232 if (tcc_set_flag(s
, optarg
, 1) < 0 && s
->warn_unsupported
)
10233 goto unsupported_option
;
10236 if (tcc_set_warning(s
, optarg
, 1) < 0 &&
10237 s
->warn_unsupported
)
10238 goto unsupported_option
;
10243 case TCC_OPTION_rdynamic
:
10246 case TCC_OPTION_Wl
:
10249 if (strstart(optarg
, "-Ttext,", &p
)) {
10250 s
->text_addr
= strtoul(p
, NULL
, 16);
10251 s
->has_text_addr
= 1;
10253 error("unsupported ld option '%s'", optarg
);
10258 if (s
->warn_unsupported
) {
10259 unsupported_option
:
10260 warning("unsupported option '%s'", r
);
10269 int main(int argc
, char **argv
)
10273 int nb_objfiles
, ret
, optind
;
10274 char objfilename
[1024];
10275 int64_t start_time
= 0;
10278 output_type
= TCC_OUTPUT_EXE
;
10280 multiple_files
= 1;
10285 print_search_dirs
= 0;
10287 optind
= parse_args(s
, argc
- 1, argv
+ 1) + 1;
10289 if (print_search_dirs
) {
10290 /* enough for Linux kernel */
10291 printf("install: %s/\n", tcc_lib_path
);
10295 nb_objfiles
= nb_files
- nb_libraries
;
10297 /* if outfile provided without other options, we output an
10299 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
10300 output_type
= TCC_OUTPUT_EXE
;
10302 /* check -c consistency : only single file handled. XXX: checks file type */
10303 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
10304 /* accepts only a single input file */
10305 if (nb_objfiles
!= 1)
10306 error("cannot specify multiple files with -c");
10307 if (nb_libraries
!= 0)
10308 error("cannot specify libraries with -c");
10311 /* compute default outfile name */
10312 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
10313 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
10316 pstrcpy(objfilename
, sizeof(objfilename
) - 1,
10317 tcc_basename(files
[0]));
10318 /* add .o extension */
10319 ext
= strrchr(objfilename
, '.');
10321 goto default_outfile
;
10322 strcpy(ext
+ 1, "o");
10325 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
10327 outfile
= objfilename
;
10331 start_time
= getclock_us();
10334 tcc_set_output_type(s
, output_type
);
10336 /* compile or add each files or library */
10337 for(i
= 0;i
< nb_files
; i
++) {
10338 const char *filename
;
10340 filename
= files
[i
];
10341 if (filename
[0] == '-') {
10342 if (tcc_add_library(s
, filename
+ 2) < 0)
10343 error("cannot find %s", filename
);
10345 if (tcc_add_file(s
, filename
) < 0) {
10352 /* free all files */
10357 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
10358 if (total_time
< 0.001)
10359 total_time
= 0.001;
10360 if (total_bytes
< 1)
10362 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
10363 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
10364 total_time
, (int)(total_lines
/ total_time
),
10365 total_bytes
/ total_time
/ 1000000.0);
10368 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
10369 tcc_output_file(s
, outfile
);
10372 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
10375 /* XXX: cannot do it with bound checking because of the malloc hooks */
10376 if (!do_bounds_check
)
10381 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);