2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #define CONFIG_TCC_STATIC
43 #include <sys/timeb.h>
44 #define CONFIG_TCC_STATIC
48 #include <sys/ucontext.h>
51 #endif /* !CONFIG_TCCBOOT */
55 #ifndef CONFIG_TCC_STATIC
66 /* preprocessor debug */
68 /* include file debug */
76 /* target selection */
77 //#define TCC_TARGET_I386 /* i386 code generator */
78 //#define TCC_TARGET_ARM /* ARMv4 code generator */
79 //#define TCC_TARGET_C67 /* TMS320C67xx code generator */
81 /* default target is I386 */
82 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
83 !defined(TCC_TARGET_C67)
84 #define TCC_TARGET_I386
87 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
88 !defined(TCC_TARGET_C67)
89 #define CONFIG_TCC_BCHECK /* enable bound checking code */
92 /* define it to include assembler support */
93 #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
94 #define CONFIG_TCC_ASM
97 /* object format selection */
98 #if defined(TCC_TARGET_C67)
99 #define TCC_TARGET_COFF
108 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
109 executables or dlls */
110 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
112 #define INCLUDE_STACK_SIZE 32
113 #define IFDEF_STACK_SIZE 64
114 #define VSTACK_SIZE 64
115 #define STRING_MAX_SIZE 1024
117 #define TOK_HASH_SIZE 8192 /* must be a power of two */
118 #define TOK_ALLOC_INCR 512 /* must be a power of two */
119 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
121 /* token symbol management */
122 typedef struct TokenSym
{
123 struct TokenSym
*hash_next
;
124 struct Sym
*sym_define
; /* direct pointer to define */
125 struct Sym
*sym_label
; /* direct pointer to label */
126 struct Sym
*sym_struct
; /* direct pointer to structure */
127 struct Sym
*sym_identifier
; /* direct pointer to identifier */
128 int tok
; /* token number */
133 typedef struct CString
{
134 int size
; /* size in bytes */
135 void *data
; /* either 'char *' or 'int *' */
137 void *data_allocated
; /* if non NULL, data has been malloced */
140 /* type definition */
141 typedef struct CType
{
147 typedef union CValue
{
153 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
155 unsigned long long ull
;
156 struct CString
*cstr
;
162 typedef struct SValue
{
163 CType type
; /* type */
164 unsigned short r
; /* register + flags */
165 unsigned short r2
; /* second register, used for 'long long'
166 type. If not used, set to VT_CONST */
167 CValue c
; /* constant, if VT_CONST */
168 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
171 /* symbol management */
173 int v
; /* symbol token */
174 int r
; /* associated register */
175 int c
; /* associated number */
176 CType type
; /* associated type */
177 struct Sym
*next
; /* next related symbol */
178 struct Sym
*prev
; /* prev symbol in stack */
179 struct Sym
*prev_tok
; /* previous symbol for this token */
182 /* section definition */
183 /* XXX: use directly ELF structure for parameters ? */
184 /* special flag to indicate that the section should not be linked to
186 #define SHF_PRIVATE 0x80000000
188 typedef struct Section
{
189 unsigned long data_offset
; /* current data offset */
190 unsigned char *data
; /* section data */
191 unsigned long data_allocated
; /* used for realloc() handling */
192 int sh_name
; /* elf section name (only used during output) */
193 int sh_num
; /* elf section number */
194 int sh_type
; /* elf section type */
195 int sh_flags
; /* elf section flags */
196 int sh_info
; /* elf section info */
197 int sh_addralign
; /* elf section alignment */
198 int sh_entsize
; /* elf entry size */
199 unsigned long sh_size
; /* section size (only used during output) */
200 unsigned long sh_addr
; /* address at which the section is relocated */
201 unsigned long sh_offset
; /* address at which the section is relocated */
202 int nb_hashed_syms
; /* used to resize the hash table */
203 struct Section
*link
; /* link to another section */
204 struct Section
*reloc
; /* corresponding section for relocation, if any */
205 struct Section
*hash
; /* hash table for symbols */
206 struct Section
*next
;
207 char name
[1]; /* section name */
210 typedef struct DLLReference
{
215 /* GNUC attribute definition */
216 typedef struct AttributeDef
{
220 unsigned char func_call
; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */
223 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
224 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
225 #define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
227 /* stored in 'Sym.c' field */
228 #define FUNC_NEW 1 /* ansi function prototype */
229 #define FUNC_OLD 2 /* old function prototype */
230 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
232 /* stored in 'Sym.r' field */
233 #define FUNC_CDECL 0 /* standard c call */
234 #define FUNC_STDCALL 1 /* pascal c call */
235 #define FUNC_FASTCALL1 2 /* first param in %eax */
236 #define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
237 #define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
239 /* field 'Sym.t' for macros */
240 #define MACRO_OBJ 0 /* object like macro */
241 #define MACRO_FUNC 1 /* function like macro */
243 /* field 'Sym.r' for C labels */
244 #define LABEL_DEFINED 0 /* label is defined */
245 #define LABEL_FORWARD 1 /* label is forward defined */
246 #define LABEL_DECLARED 2 /* label is declared but never used */
248 /* type_decl() types */
249 #define TYPE_ABSTRACT 1 /* type without variable */
250 #define TYPE_DIRECT 2 /* type with variable */
252 #define IO_BUF_SIZE 8192
254 typedef struct BufferedFile
{
258 int line_num
; /* current line number - here to simplify code */
259 int ifndef_macro
; /* #ifndef macro / #endif search */
260 int ifndef_macro_saved
; /* saved ifndef_macro */
261 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
262 char inc_type
; /* type of include */
263 char inc_filename
[512]; /* filename specified by the user */
264 char filename
[1024]; /* current filename - here to simplify code */
265 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
268 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
269 #define CH_EOF (-1) /* end of file */
271 /* parsing state (used to save parser state to reparse part of the
272 source several times) */
273 typedef struct ParseState
{
280 /* used to record tokens */
281 typedef struct TokenString
{
288 /* include file cache, used to find files faster and also to eliminate
289 inclusion if the include file is protected by #ifndef ... #endif */
290 typedef struct CachedInclude
{
292 char type
; /* '"' or '>' to give include type */
293 char filename
[1]; /* path specified in #include */
297 static struct BufferedFile
*file
;
300 static CString tokcstr
; /* current parsed string, if any */
301 /* additional informations about token */
302 static int tok_flags
;
303 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
304 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
305 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
307 static int *macro_ptr
, *macro_ptr_allocated
;
308 static int *unget_saved_macro_ptr
;
309 static int unget_saved_buffer
[TOK_MAX_SIZE
+ 1];
310 static int unget_buffer_enabled
;
311 static int parse_flags
;
312 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
313 #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
314 #define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
315 token. line feed is also
317 #define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
319 static Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
320 static Section
*cur_text_section
; /* current section where function code is
322 static Section
*last_text_section
; /* to handle .previous asm directive */
323 /* bound check related sections */
324 static Section
*bounds_section
; /* contains global data bound description */
325 static Section
*lbounds_section
; /* contains local data bound description */
326 /* symbol sections */
327 static Section
*symtab_section
, *strtab_section
;
330 static Section
*stab_section
, *stabstr_section
;
332 /* loc : local variable index
333 ind : output code index
335 anon_sym: anonymous symbol index
337 static int rsym
, anon_sym
, ind
, loc
;
338 /* expression generation modifiers */
339 static int const_wanted
; /* true if constant wanted */
340 static int nocode_wanted
; /* true if no code generation wanted for an expression */
341 static int global_expr
; /* true if compound literals must be allocated
342 globally (used during initializers parsing */
343 static CType func_vt
; /* current function return type (used by return
346 static int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
347 static int tok_ident
;
348 static TokenSym
**table_ident
;
349 static TokenSym
*hash_ident
[TOK_HASH_SIZE
];
350 static char token_buf
[STRING_MAX_SIZE
+ 1];
351 static char *funcname
;
352 static Sym
*global_stack
, *local_stack
;
353 static Sym
*define_stack
;
354 static Sym
*global_label_stack
, *local_label_stack
;
356 static SValue vstack
[VSTACK_SIZE
], *vtop
;
357 /* some predefined types */
358 static CType char_pointer_type
, func_old_type
, int_type
;
359 /* true if isid(c) || isnum(c) */
360 static unsigned char isidnum_table
[256];
362 /* compile with debug symbol (and use them if error during execution) */
363 static int do_debug
= 0;
365 /* compile with built-in memory and bounds checker */
366 static int do_bounds_check
= 0;
368 /* display benchmark infos */
370 static int do_bench
= 0;
372 static int total_lines
;
373 static int total_bytes
;
375 /* use GNU C extensions */
376 static int gnu_ext
= 1;
378 /* use Tiny C extensions */
379 static int tcc_ext
= 1;
381 /* max number of callers shown if error */
382 static int num_callers
= 6;
383 static const char **rt_bound_error_msg
;
385 /* XXX: get rid of this ASAP */
386 static struct TCCState
*tcc_state
;
388 /* give the path of the tcc libraries */
389 static const char *tcc_lib_path
= CONFIG_TCC_LIBDIR
"/tcc";
394 BufferedFile
**include_stack_ptr
;
395 int *ifdef_stack_ptr
;
397 /* include file handling */
398 char **include_paths
;
399 int nb_include_paths
;
400 char **sysinclude_paths
;
401 int nb_sysinclude_paths
;
402 CachedInclude
**cached_includes
;
403 int nb_cached_includes
;
405 char **library_paths
;
406 int nb_library_paths
;
408 /* array of all loaded dlls (including those referenced by loaded
410 DLLReference
**loaded_dlls
;
415 int nb_sections
; /* number of sections, including first dummy section */
420 unsigned long *got_offsets
;
422 /* give the correspondance from symtab indexes to dynsym indexes */
423 int *symtab_to_dynsym
;
425 /* temporary dynamic symbol sections (for dll loading) */
426 Section
*dynsymtab_section
;
427 /* exported dynamic symbol section */
430 int nostdinc
; /* if true, no standard headers are added */
431 int nostdlib
; /* if true, no standard libraries are added */
433 int nocommon
; /* if true, do not use common symbols for .bss data */
435 /* if true, static linking is performed */
438 /* if true, all symbols are exported */
441 /* if true, only link in referenced objects from archive */
444 /* address of text section */
445 unsigned long text_addr
;
448 /* output format, see TCC_OUTPUT_FORMAT_xxx */
451 /* C language options */
452 int char_is_unsigned
;
454 /* warning switches */
455 int warn_write_strings
;
456 int warn_unsupported
;
459 int warn_implicit_function_declaration
;
463 void (*error_func
)(void *opaque
, const char *msg
);
464 int error_set_jmp_enabled
;
465 jmp_buf error_jmp_buf
;
468 /* tiny assembler state */
471 /* see include_stack_ptr */
472 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
474 /* see ifdef_stack_ptr */
475 int ifdef_stack
[IFDEF_STACK_SIZE
];
478 /* The current value can be: */
479 #define VT_VALMASK 0x00ff
480 #define VT_CONST 0x00f0 /* constant in vc
481 (must be first non register value) */
482 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
483 #define VT_LOCAL 0x00f2 /* offset on stack */
484 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
485 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
486 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
487 #define VT_LVAL 0x0100 /* var is an lvalue */
488 #define VT_SYM 0x0200 /* a symbol value is added */
489 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
490 char/short stored in integer registers) */
491 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
492 dereferencing value */
493 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
494 bounding function call point is in vc */
495 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
496 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
497 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
498 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
501 #define VT_INT 0 /* integer type */
502 #define VT_BYTE 1 /* signed byte type */
503 #define VT_SHORT 2 /* short type */
504 #define VT_VOID 3 /* void type */
505 #define VT_PTR 4 /* pointer */
506 #define VT_ENUM 5 /* enum definition */
507 #define VT_FUNC 6 /* function type */
508 #define VT_STRUCT 7 /* struct/union definition */
509 #define VT_FLOAT 8 /* IEEE float */
510 #define VT_DOUBLE 9 /* IEEE double */
511 #define VT_LDOUBLE 10 /* IEEE long double */
512 #define VT_BOOL 11 /* ISOC99 boolean type */
513 #define VT_LLONG 12 /* 64 bit integer */
514 #define VT_LONG 13 /* long integer (NEVER USED as type, only
516 #define VT_BTYPE 0x000f /* mask for basic type */
517 #define VT_UNSIGNED 0x0010 /* unsigned type */
518 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
519 #define VT_BITFIELD 0x0040 /* bitfield modifier */
520 #define VT_CONSTANT 0x0800 /* const modifier */
521 #define VT_VOLATILE 0x1000 /* volatile modifier */
522 #define VT_SIGNED 0x2000 /* signed type */
525 #define VT_EXTERN 0x00000080 /* extern definition */
526 #define VT_STATIC 0x00000100 /* static variable */
527 #define VT_TYPEDEF 0x00000200 /* typedef definition */
528 #define VT_INLINE 0x00000400 /* inline definition */
530 #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */
532 /* type mask (except storage) */
533 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
534 #define VT_TYPE (~(VT_STORAGE))
538 /* warning: the following compare tokens depend on i386 asm code */
550 #define TOK_LAND 0xa0
554 #define TOK_MID 0xa3 /* inc/dec, to void constant */
556 #define TOK_UDIV 0xb0 /* unsigned division */
557 #define TOK_UMOD 0xb1 /* unsigned modulo */
558 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
559 #define TOK_CINT 0xb3 /* number in tokc */
560 #define TOK_CCHAR 0xb4 /* char constant in tokc */
561 #define TOK_STR 0xb5 /* pointer to string in tokc */
562 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
563 #define TOK_LCHAR 0xb7
564 #define TOK_LSTR 0xb8
565 #define TOK_CFLOAT 0xb9 /* float constant */
566 #define TOK_LINENUM 0xba /* line number info */
567 #define TOK_CDOUBLE 0xc0 /* double constant */
568 #define TOK_CLDOUBLE 0xc1 /* long double constant */
569 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
570 #define TOK_ADDC1 0xc3 /* add with carry generation */
571 #define TOK_ADDC2 0xc4 /* add with carry use */
572 #define TOK_SUBC1 0xc5 /* add with carry generation */
573 #define TOK_SUBC2 0xc6 /* add with carry use */
574 #define TOK_CUINT 0xc8 /* unsigned int constant */
575 #define TOK_CLLONG 0xc9 /* long long constant */
576 #define TOK_CULLONG 0xca /* unsigned long long constant */
577 #define TOK_ARROW 0xcb
578 #define TOK_DOTS 0xcc /* three dots */
579 #define TOK_SHR 0xcd /* unsigned shift right */
580 #define TOK_PPNUM 0xce /* preprocessor number */
582 #define TOK_SHL 0x01 /* shift left */
583 #define TOK_SAR 0x02 /* signed shift right */
585 /* assignement operators : normal operator or 0x80 */
586 #define TOK_A_MOD 0xa5
587 #define TOK_A_AND 0xa6
588 #define TOK_A_MUL 0xaa
589 #define TOK_A_ADD 0xab
590 #define TOK_A_SUB 0xad
591 #define TOK_A_DIV 0xaf
592 #define TOK_A_XOR 0xde
593 #define TOK_A_OR 0xfc
594 #define TOK_A_SHL 0x81
595 #define TOK_A_SAR 0x82
598 #define offsetof(type, field) ((size_t) &((type *)0)->field)
602 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
605 /* WARNING: the content of this string encodes token numbers */
606 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";
608 #define TOK_EOF (-1) /* end of file */
609 #define TOK_LINEFEED 10 /* line feed */
611 /* all identificators and strings have token above that */
612 #define TOK_IDENT 256
614 /* only used for i386 asm opcodes definitions */
615 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
618 DEF(TOK_ASM_ ## x ## b, #x "b") \
619 DEF(TOK_ASM_ ## x ## w, #x "w") \
620 DEF(TOK_ASM_ ## x ## l, #x "l") \
621 DEF(TOK_ASM_ ## x, #x)
624 DEF(TOK_ASM_ ## x ## w, #x "w") \
625 DEF(TOK_ASM_ ## x ## l, #x "l") \
626 DEF(TOK_ASM_ ## x, #x)
629 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
630 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
631 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
632 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
635 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
636 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
639 #define DEF_ASMTEST(x) \
671 #define TOK_ASM_int TOK_INT
674 TOK_LAST
= TOK_IDENT
- 1,
675 #define DEF(id, str) id,
680 static const char tcc_keywords
[] =
681 #define DEF(id, str) str "\0"
686 #define TOK_UIDENT TOK_DEFINE
689 #define snprintf _snprintf
690 #define vsnprintf _vsnprintf
693 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
694 /* currently incorrect */
695 long double strtold(const char *nptr
, char **endptr
)
697 return (long double)strtod(nptr
, endptr
);
699 float strtof(const char *nptr
, char **endptr
)
701 return (float)strtod(nptr
, endptr
);
704 /* XXX: need to define this to use them in non ISOC99 context */
705 extern float strtof (const char *__nptr
, char **__endptr
);
706 extern long double strtold (const char *__nptr
, char **__endptr
);
709 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
710 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
712 static void next(void);
713 static void next_nomacro(void);
714 static void parse_expr_type(CType
*type
);
715 static void expr_type(CType
*type
);
716 static void unary_type(CType
*type
);
717 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
718 int case_reg
, int is_expr
);
719 static int expr_const(void);
720 static void expr_eq(void);
721 static void gexpr(void);
722 static void gen_inline_functions(void);
723 static void decl(int l
);
724 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
725 int first
, int size_only
);
726 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
727 int has_init
, int v
, int scope
);
729 void gv2(int rc1
, int rc2
);
730 void move_reg(int r
, int s
);
731 void save_regs(int n
);
732 void save_reg(int r
);
737 int get_reg_ex(int rc
,int rc2
);
739 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
740 const int *macro_str
, int can_read_stream
);
742 void force_charshort_cast(int t
);
743 static void gen_cast(CType
*type
);
745 static Sym
*sym_find(int v
);
746 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
749 static int type_size(CType
*type
, int *a
);
750 static inline CType
*pointed_type(CType
*type
);
751 static int pointed_size(CType
*type
);
752 static int lvalue_type(int t
);
753 static int parse_btype(CType
*type
, AttributeDef
*ad
);
754 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
755 static int is_compatible_types(CType
*type1
, CType
*type2
);
757 int ieee_finite(double d
);
758 void error(const char *fmt
, ...);
762 void lexpand_nr(void);
763 static void vpush_global_sym(CType
*type
, int v
);
764 void vset(CType
*type
, int r
, int v
);
765 void type_to_str(char *buf
, int buf_size
,
766 CType
*type
, const char *varstr
);
767 char *get_tok_str(int v
, CValue
*cv
);
768 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
769 unsigned long offset
, unsigned long size
);
770 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
772 /* section generation */
773 static void section_realloc(Section
*sec
, unsigned long new_size
);
774 static void *section_ptr_add(Section
*sec
, unsigned long size
);
775 static void put_extern_sym(Sym
*sym
, Section
*section
,
776 unsigned long value
, unsigned long size
);
777 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
778 static int put_elf_str(Section
*s
, const char *sym
);
779 static int put_elf_sym(Section
*s
,
780 unsigned long value
, unsigned long size
,
781 int info
, int other
, int shndx
, const char *name
);
782 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
783 int info
, int sh_num
, const char *name
);
784 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
785 int type
, int symbol
);
786 static void put_stabs(const char *str
, int type
, int other
, int desc
,
787 unsigned long value
);
788 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
789 unsigned long value
, Section
*sec
, int sym_index
);
790 static void put_stabn(int type
, int other
, int desc
, int value
);
791 static void put_stabd(int type
, int other
, int desc
);
792 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
794 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
795 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
796 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
799 int tcc_output_coff(TCCState
*s1
, FILE *f
);
803 #ifdef CONFIG_TCC_ASM
805 typedef struct ExprValue
{
810 #define MAX_ASM_OPERANDS 30
812 typedef struct ASMOperand
{
813 int id
; /* GCC 3 optionnal identifier (0 if number only supported */
815 char asm_str
[16]; /* computed asm string for operand */
816 SValue
*vt
; /* C value of the expression */
817 int ref_index
; /* if >= 0, gives reference to a output constraint */
818 int input_index
; /* if >= 0, gives reference to an input constraint */
819 int priority
; /* priority, used to assign registers */
820 int reg
; /* if >= 0, register number used for this operand */
821 int is_llong
; /* true if double register value */
822 int is_memory
; /* true if memory operand */
823 int is_rw
; /* for '+' modifier */
826 static void asm_expr(TCCState
*s1
, ExprValue
*pe
);
827 static int asm_int_expr(TCCState
*s1
);
828 static int find_constraint(ASMOperand
*operands
, int nb_operands
,
829 const char *name
, const char **pp
);
831 static int tcc_assemble(TCCState
*s1
, int do_preprocess
);
835 static void asm_instr(void);
836 static void asm_global_instr(void);
838 /* true if float/double/long double type */
839 static inline int is_float(int t
)
843 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
846 #ifdef TCC_TARGET_I386
847 #include "i386-gen.c"
850 #ifdef TCC_TARGET_ARM
854 #ifdef TCC_TARGET_C67
858 #ifdef CONFIG_TCC_STATIC
860 #define RTLD_LAZY 0x001
861 #define RTLD_NOW 0x002
862 #define RTLD_GLOBAL 0x100
863 #define RTLD_DEFAULT NULL
865 /* dummy function for profiling */
866 void *dlopen(const char *filename
, int flag
)
871 const char *dlerror(void)
876 typedef struct TCCSyms
{
881 #define TCCSYM(a) { #a, &a, },
883 /* add the symbol you want here if no dynamic linking is done */
884 static TCCSyms tcc_syms
[] = {
885 #if !defined(CONFIG_TCCBOOT)
894 void *dlsym(void *handle
, const char *symbol
)
898 while (p
->str
!= NULL
) {
899 if (!strcmp(p
->str
, symbol
))
908 /********************************************************/
910 /* we use our own 'finite' function to avoid potential problems with
911 non standard math libs */
912 /* XXX: endianness dependent */
913 int ieee_finite(double d
)
916 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
919 /* copy a string and truncate it. */
920 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
927 q_end
= buf
+ buf_size
- 1;
939 /* strcat and truncate. */
940 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
945 pstrcpy(buf
+ len
, buf_size
- len
, s
);
949 static int strstart(const char *str
, const char *val
, const char **ptr
)
965 /* memory management */
971 static inline void tcc_free(void *ptr
)
974 mem_cur_size
-= malloc_usable_size(ptr
);
979 static void *tcc_malloc(unsigned long size
)
984 error("memory full");
986 mem_cur_size
+= malloc_usable_size(ptr
);
987 if (mem_cur_size
> mem_max_size
)
988 mem_max_size
= mem_cur_size
;
993 static void *tcc_mallocz(unsigned long size
)
996 ptr
= tcc_malloc(size
);
997 memset(ptr
, 0, size
);
1001 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
1005 mem_cur_size
-= malloc_usable_size(ptr
);
1007 ptr1
= realloc(ptr
, size
);
1009 /* NOTE: count not correct if alloc error, but not critical */
1010 mem_cur_size
+= malloc_usable_size(ptr1
);
1011 if (mem_cur_size
> mem_max_size
)
1012 mem_max_size
= mem_cur_size
;
1017 static char *tcc_strdup(const char *str
)
1020 ptr
= tcc_malloc(strlen(str
) + 1);
1025 #define free(p) use_tcc_free(p)
1026 #define malloc(s) use_tcc_malloc(s)
1027 #define realloc(p, s) use_tcc_realloc(p, s)
1029 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
1036 /* every power of two we double array size */
1037 if ((nb
& (nb
- 1)) == 0) {
1042 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
1044 error("memory full");
1051 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
1055 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
1056 strcpy(sec
->name
, name
);
1057 sec
->sh_type
= sh_type
;
1058 sec
->sh_flags
= sh_flags
;
1065 sec
->sh_addralign
= 4;
1068 sec
->sh_addralign
= 1;
1071 sec
->sh_addralign
= 32; /* default conservative alignment */
1075 /* only add section if not private */
1076 if (!(sh_flags
& SHF_PRIVATE
)) {
1077 sec
->sh_num
= s1
->nb_sections
;
1078 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
1083 static void free_section(Section
*s
)
1089 /* realloc section and set its content to zero */
1090 static void section_realloc(Section
*sec
, unsigned long new_size
)
1093 unsigned char *data
;
1095 size
= sec
->data_allocated
;
1098 while (size
< new_size
)
1100 data
= tcc_realloc(sec
->data
, size
);
1102 error("memory full");
1103 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
1105 sec
->data_allocated
= size
;
1108 /* reserve at least 'size' bytes in section 'sec' from
1109 sec->data_offset. */
1110 static void *section_ptr_add(Section
*sec
, unsigned long size
)
1112 unsigned long offset
, offset1
;
1114 offset
= sec
->data_offset
;
1115 offset1
= offset
+ size
;
1116 if (offset1
> sec
->data_allocated
)
1117 section_realloc(sec
, offset1
);
1118 sec
->data_offset
= offset1
;
1119 return sec
->data
+ offset
;
1122 /* return a reference to a section, and create it if it does not
1124 Section
*find_section(TCCState
*s1
, const char *name
)
1128 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1129 sec
= s1
->sections
[i
];
1130 if (!strcmp(name
, sec
->name
))
1133 /* sections are created as PROGBITS */
1134 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
1137 #define SECTION_ABS ((void *)1)
1139 /* update sym->c so that it points to an external symbol in section
1140 'section' with value 'value' */
1141 static void put_extern_sym(Sym
*sym
, Section
*section
,
1142 unsigned long value
, unsigned long size
)
1144 int sym_type
, sym_bind
, sh_num
, info
;
1148 if (section
== NULL
)
1150 else if (section
== SECTION_ABS
)
1153 sh_num
= section
->sh_num
;
1155 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
)
1156 sym_type
= STT_FUNC
;
1158 sym_type
= STT_OBJECT
;
1159 if (sym
->type
.t
& VT_STATIC
)
1160 sym_bind
= STB_LOCAL
;
1162 sym_bind
= STB_GLOBAL
;
1164 name
= get_tok_str(sym
->v
, NULL
);
1165 #ifdef CONFIG_TCC_BCHECK
1166 if (do_bounds_check
) {
1169 /* XXX: avoid doing that for statics ? */
1170 /* if bound checking is activated, we change some function
1171 names by adding the "__bound" prefix */
1174 /* XXX: we rely only on malloc hooks */
1186 strcpy(buf
, "__bound_");
1193 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
1194 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
1196 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
1197 esym
->st_value
= value
;
1198 esym
->st_size
= size
;
1199 esym
->st_shndx
= sh_num
;
1203 /* add a new relocation entry to symbol 'sym' in section 's' */
1204 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
1207 put_extern_sym(sym
, NULL
, 0, 0);
1208 /* now we can add ELF relocation info */
1209 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
1212 static inline int isid(int c
)
1214 return (c
>= 'a' && c
<= 'z') ||
1215 (c
>= 'A' && c
<= 'Z') ||
1219 static inline int isnum(int c
)
1221 return c
>= '0' && c
<= '9';
1224 static inline int isoct(int c
)
1226 return c
>= '0' && c
<= '7';
1229 static inline int toup(int c
)
1231 if (c
>= 'a' && c
<= 'z')
1232 return c
- 'a' + 'A';
1237 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1241 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1244 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1248 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1252 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1259 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1260 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1261 (*f
)->filename
, (*f
)->line_num
);
1262 if (file
->line_num
> 0) {
1263 strcat_printf(buf
, sizeof(buf
),
1264 "%s:%d: ", file
->filename
, file
->line_num
);
1266 strcat_printf(buf
, sizeof(buf
),
1267 "%s: ", file
->filename
);
1270 strcat_printf(buf
, sizeof(buf
),
1274 strcat_printf(buf
, sizeof(buf
), "warning: ");
1275 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1277 if (!s1
->error_func
) {
1278 /* default case: stderr */
1279 fprintf(stderr
, "%s\n", buf
);
1281 s1
->error_func(s1
->error_opaque
, buf
);
1283 if (!is_warning
|| s1
->warn_error
)
1288 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1289 void (*error_func
)(void *opaque
, const char *msg
))
1291 s
->error_opaque
= error_opaque
;
1292 s
->error_func
= error_func
;
1296 /* error without aborting current compilation */
1297 void error_noabort(const char *fmt
, ...)
1299 TCCState
*s1
= tcc_state
;
1303 error1(s1
, 0, fmt
, ap
);
1307 void error(const char *fmt
, ...)
1309 TCCState
*s1
= tcc_state
;
1313 error1(s1
, 0, fmt
, ap
);
1315 /* better than nothing: in some cases, we accept to handle errors */
1316 if (s1
->error_set_jmp_enabled
) {
1317 longjmp(s1
->error_jmp_buf
, 1);
1319 /* XXX: eliminate this someday */
1324 void expect(const char *msg
)
1326 error("%s expected", msg
);
1329 void warning(const char *fmt
, ...)
1331 TCCState
*s1
= tcc_state
;
1338 error1(s1
, 1, fmt
, ap
);
1345 error("'%c' expected", c
);
1349 static void test_lvalue(void)
1351 if (!(vtop
->r
& VT_LVAL
))
1355 /* allocate a new token */
1356 static TokenSym
*tok_alloc_new(TokenSym
**pts
, const char *str
, int len
)
1358 TokenSym
*ts
, **ptable
;
1361 if (tok_ident
>= SYM_FIRST_ANOM
)
1362 error("memory full");
1364 /* expand token table if needed */
1365 i
= tok_ident
- TOK_IDENT
;
1366 if ((i
% TOK_ALLOC_INCR
) == 0) {
1367 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1369 error("memory full");
1370 table_ident
= ptable
;
1373 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1374 table_ident
[i
] = ts
;
1375 ts
->tok
= tok_ident
++;
1376 ts
->sym_define
= NULL
;
1377 ts
->sym_label
= NULL
;
1378 ts
->sym_struct
= NULL
;
1379 ts
->sym_identifier
= NULL
;
1381 ts
->hash_next
= NULL
;
1382 memcpy(ts
->str
, str
, len
);
1383 ts
->str
[len
] = '\0';
1388 #define TOK_HASH_INIT 1
1389 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1391 /* find a token and add it if not found */
1392 static TokenSym
*tok_alloc(const char *str
, int len
)
1394 TokenSym
*ts
, **pts
;
1400 h
= TOK_HASH_FUNC(h
, ((unsigned char *)str
)[i
]);
1401 h
&= (TOK_HASH_SIZE
- 1);
1403 pts
= &hash_ident
[h
];
1408 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1410 pts
= &(ts
->hash_next
);
1412 return tok_alloc_new(pts
, str
, len
);
1415 /* CString handling */
1417 static void cstr_realloc(CString
*cstr
, int new_size
)
1422 size
= cstr
->size_allocated
;
1424 size
= 8; /* no need to allocate a too small first string */
1425 while (size
< new_size
)
1427 data
= tcc_realloc(cstr
->data_allocated
, size
);
1429 error("memory full");
1430 cstr
->data_allocated
= data
;
1431 cstr
->size_allocated
= size
;
1436 static void cstr_ccat(CString
*cstr
, int ch
)
1439 size
= cstr
->size
+ 1;
1440 if (size
> cstr
->size_allocated
)
1441 cstr_realloc(cstr
, size
);
1442 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1446 static void cstr_cat(CString
*cstr
, const char *str
)
1458 /* add a wide char */
1459 static void cstr_wccat(CString
*cstr
, int ch
)
1462 size
= cstr
->size
+ sizeof(int);
1463 if (size
> cstr
->size_allocated
)
1464 cstr_realloc(cstr
, size
);
1465 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1469 static void cstr_new(CString
*cstr
)
1471 memset(cstr
, 0, sizeof(CString
));
1474 /* free string and reset it to NULL */
1475 static void cstr_free(CString
*cstr
)
1477 tcc_free(cstr
->data_allocated
);
1481 #define cstr_reset(cstr) cstr_free(cstr)
1483 static CString
*cstr_dup(CString
*cstr1
)
1488 cstr
= tcc_malloc(sizeof(CString
));
1491 cstr
->size_allocated
= size
;
1492 cstr
->data_allocated
= tcc_malloc(size
);
1493 cstr
->data
= cstr
->data_allocated
;
1494 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1498 /* XXX: unicode ? */
1499 static void add_char(CString
*cstr
, int c
)
1501 if (c
== '\'' || c
== '\"' || c
== '\\') {
1502 /* XXX: could be more precise if char or string */
1503 cstr_ccat(cstr
, '\\');
1505 if (c
>= 32 && c
<= 126) {
1508 cstr_ccat(cstr
, '\\');
1510 cstr_ccat(cstr
, 'n');
1512 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1513 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1514 cstr_ccat(cstr
, '0' + (c
& 7));
1519 /* XXX: buffer overflow */
1520 /* XXX: float tokens */
1521 char *get_tok_str(int v
, CValue
*cv
)
1523 static char buf
[STRING_MAX_SIZE
+ 1];
1524 static CString cstr_buf
;
1530 /* NOTE: to go faster, we give a fixed buffer for small strings */
1531 cstr_reset(&cstr_buf
);
1532 cstr_buf
.data
= buf
;
1533 cstr_buf
.size_allocated
= sizeof(buf
);
1539 /* XXX: not quite exact, but only useful for testing */
1540 sprintf(p
, "%u", cv
->ui
);
1544 /* XXX: not quite exact, but only useful for testing */
1545 sprintf(p
, "%Lu", cv
->ull
);
1549 cstr_ccat(&cstr_buf
, '\'');
1550 add_char(&cstr_buf
, cv
->i
);
1551 cstr_ccat(&cstr_buf
, '\'');
1552 cstr_ccat(&cstr_buf
, '\0');
1556 len
= cstr
->size
- 1;
1558 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1559 cstr_ccat(&cstr_buf
, '\0');
1564 cstr_ccat(&cstr_buf
, '\"');
1566 len
= cstr
->size
- 1;
1568 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1570 len
= (cstr
->size
/ sizeof(int)) - 1;
1572 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1574 cstr_ccat(&cstr_buf
, '\"');
1575 cstr_ccat(&cstr_buf
, '\0');
1584 return strcpy(p
, "<<=");
1586 return strcpy(p
, ">>=");
1588 if (v
< TOK_IDENT
) {
1589 /* search in two bytes table */
1603 } else if (v
< tok_ident
) {
1604 return table_ident
[v
- TOK_IDENT
]->str
;
1605 } else if (v
>= SYM_FIRST_ANOM
) {
1606 /* special name for anonymous symbol */
1607 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1609 /* should never happen */
1614 return cstr_buf
.data
;
1617 /* push, without hashing */
1618 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1621 s
= tcc_malloc(sizeof(Sym
));
1632 /* find a symbol and return its associated structure. 's' is the top
1633 of the symbol stack */
1634 static Sym
*sym_find2(Sym
*s
, int v
)
1644 /* structure lookup */
1645 static inline Sym
*struct_find(int v
)
1648 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1650 return table_ident
[v
]->sym_struct
;
1653 /* find an identifier */
1654 static inline Sym
*sym_find(int v
)
1657 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1659 return table_ident
[v
]->sym_identifier
;
1662 /* push a given symbol on the symbol stack */
1663 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1672 s
= sym_push2(ps
, v
, type
->t
, c
);
1673 s
->type
.ref
= type
->ref
;
1675 /* don't record fields or anonymous symbols */
1677 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1678 /* record symbol in token array */
1679 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1681 ps
= &ts
->sym_struct
;
1683 ps
= &ts
->sym_identifier
;
1690 /* push a global identifier */
1691 static Sym
*global_identifier_push(int v
, int t
, int c
)
1694 s
= sym_push2(&global_stack
, v
, t
, c
);
1695 /* don't record anonymous symbol */
1696 if (v
< SYM_FIRST_ANOM
) {
1697 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1698 /* modify the top most local identifier, so that
1699 sym_identifier will point to 's' when popped */
1701 ps
= &(*ps
)->prev_tok
;
1708 /* pop symbols until top reaches 'b' */
1709 static void sym_pop(Sym
**ptop
, Sym
*b
)
1719 /* remove symbol in token array */
1721 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1722 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1724 ps
= &ts
->sym_struct
;
1726 ps
= &ts
->sym_identifier
;
1737 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1742 fd
= open(filename
, O_RDONLY
| O_BINARY
);
1745 bf
= tcc_malloc(sizeof(BufferedFile
));
1751 bf
->buf_ptr
= bf
->buffer
;
1752 bf
->buf_end
= bf
->buffer
;
1753 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1754 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1756 bf
->ifndef_macro
= 0;
1757 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1758 // printf("opening '%s'\n", filename);
1762 void tcc_close(BufferedFile
*bf
)
1764 total_lines
+= bf
->line_num
;
1769 /* fill input buffer and peek next char */
1770 static int tcc_peekc_slow(BufferedFile
*bf
)
1773 /* only tries to read if really end of buffer */
1774 if (bf
->buf_ptr
>= bf
->buf_end
) {
1776 #if defined(PARSE_DEBUG)
1781 len
= read(bf
->fd
, bf
->buffer
, len
);
1788 bf
->buf_ptr
= bf
->buffer
;
1789 bf
->buf_end
= bf
->buffer
+ len
;
1790 *bf
->buf_end
= CH_EOB
;
1792 if (bf
->buf_ptr
< bf
->buf_end
) {
1793 return bf
->buf_ptr
[0];
1795 bf
->buf_ptr
= bf
->buf_end
;
1800 /* return the current character, handling end of block if necessary
1802 static int handle_eob(void)
1804 return tcc_peekc_slow(file
);
1807 /* read next char from current input file and handle end of input buffer */
1808 static inline void inp(void)
1810 ch
= *(++(file
->buf_ptr
));
1811 /* end of buffer/file handling */
1816 /* handle '\[\r]\n' */
1817 static void handle_stray(void)
1819 while (ch
== '\\') {
1824 } else if (ch
== '\r') {
1832 error("stray '\\' in program");
1837 /* skip the stray and handle the \\n case. Output an error if
1838 incorrect char after the stray */
1839 static int handle_stray1(uint8_t *p
)
1843 if (p
>= file
->buf_end
) {
1860 /* handle just the EOB case, but not stray */
1861 #define PEEKC_EOB(c, p)\
1872 /* handle the complicated stray case */
1873 #define PEEKC(c, p)\
1878 c = handle_stray1(p);\
1883 /* input with '\[\r]\n' handling. Note that this function cannot
1884 handle other characters after '\', so you cannot call it inside
1885 strings or comments */
1886 static void minp(void)
1894 /* single line C++ comments */
1895 static uint8_t *parse_line_comment(uint8_t *p
)
1903 if (c
== '\n' || c
== CH_EOF
) {
1905 } else if (c
== '\\') {
1914 } else if (c
== '\r') {
1932 static uint8_t *parse_comment(uint8_t *p
)
1938 /* fast skip loop */
1941 if (c
== '\n' || c
== '*' || c
== '\\')
1945 if (c
== '\n' || c
== '*' || c
== '\\')
1949 /* now we can handle all the cases */
1953 } else if (c
== '*') {
1959 } else if (c
== '/') {
1960 goto end_of_comment
;
1961 } else if (c
== '\\') {
1966 /* skip '\[\r]\n', otherwise just skip the stray */
1972 } else if (c
== '\r') {
1989 /* stray, eob or eof */
1994 error("unexpected end of file in comment");
1995 } else if (c
== '\\') {
2007 /* space exlcuding newline */
2008 static inline int is_space(int ch
)
2010 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
2013 static inline void skip_spaces(void)
2015 while (is_space(ch
))
2019 /* parse a string without interpreting escapes */
2020 static uint8_t *parse_pp_string(uint8_t *p
,
2021 int sep
, CString
*str
)
2029 } else if (c
== '\\') {
2034 unterminated_string
:
2035 /* XXX: indicate line number of start of string */
2036 error("missing terminating %c character", sep
);
2037 } else if (c
== '\\') {
2038 /* escape : just skip \[\r]\n */
2043 } else if (c
== '\r') {
2046 expect("'\n' after '\r'");
2049 } else if (c
== CH_EOF
) {
2050 goto unterminated_string
;
2053 cstr_ccat(str
, '\\');
2059 } else if (c
== '\n') {
2062 } else if (c
== '\r') {
2066 cstr_ccat(str
, '\r');
2082 /* skip block of text until #else, #elif or #endif. skip also pairs of
2084 void preprocess_skip(void)
2086 int a
, start_of_line
, c
;
2113 } else if (c
== '\\') {
2114 /* XXX: incorrect: should not give an error */
2115 ch
= file
->buf_ptr
[0];
2123 p
= parse_pp_string(p
, c
, NULL
);
2132 p
= parse_comment(p
);
2133 } else if (ch
== '/') {
2134 p
= parse_line_comment(p
);
2140 if (start_of_line
) {
2145 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
2147 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
2149 else if (tok
== TOK_ENDIF
)
2163 /* ParseState handling */
2165 /* XXX: currently, no include file info is stored. Thus, we cannot display
2166 accurate messages if the function or data definition spans multiple
2169 /* save current parse state in 's' */
2170 void save_parse_state(ParseState
*s
)
2172 s
->line_num
= file
->line_num
;
2173 s
->macro_ptr
= macro_ptr
;
2178 /* restore parse state from 's' */
2179 void restore_parse_state(ParseState
*s
)
2181 file
->line_num
= s
->line_num
;
2182 macro_ptr
= s
->macro_ptr
;
2187 /* return the number of additional 'ints' necessary to store the
2189 static inline int tok_ext_size(int t
)
2208 return LDOUBLE_SIZE
/ 4;
2214 /* token string handling */
2216 static inline void tok_str_new(TokenString
*s
)
2220 s
->allocated_len
= 0;
2221 s
->last_line_num
= -1;
2224 static void tok_str_free(int *str
)
2233 /* NOTE: we test zero separately so that GCC can generate a
2234 table for the following switch */
2249 /* XXX: use a macro to be portable on 64 bit ? */
2250 cstr
= (CString
*)p
[1];
2261 p
+= 1 + (LDOUBLE_SIZE
/ 4);
2271 static int *tok_str_realloc(TokenString
*s
)
2275 if (s
->allocated_len
== 0) {
2278 len
= s
->allocated_len
* 2;
2280 str
= tcc_realloc(s
->str
, len
* sizeof(int));
2282 error("memory full");
2283 s
->allocated_len
= len
;
2288 static void tok_str_add(TokenString
*s
, int t
)
2294 if (len
>= s
->allocated_len
)
2295 str
= tok_str_realloc(s
);
2300 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
2307 /* allocate space for worst case */
2308 if (len
+ TOK_MAX_SIZE
> s
->allocated_len
)
2309 str
= tok_str_realloc(s
);
2318 str
[len
++] = cv
->tab
[0];
2323 str
[len
++] = (int)cstr_dup(cv
->cstr
);
2328 #if LDOUBLE_SIZE == 8
2331 str
[len
++] = cv
->tab
[0];
2332 str
[len
++] = cv
->tab
[1];
2334 #if LDOUBLE_SIZE == 12
2336 str
[len
++] = cv
->tab
[0];
2337 str
[len
++] = cv
->tab
[1];
2338 str
[len
++] = cv
->tab
[2];
2339 #elif LDOUBLE_SIZE != 8
2340 #error add long double size support
2349 /* add the current parse token in token string 's' */
2350 static void tok_str_add_tok(TokenString
*s
)
2354 /* save line number info */
2355 if (file
->line_num
!= s
->last_line_num
) {
2356 s
->last_line_num
= file
->line_num
;
2357 cval
.i
= s
->last_line_num
;
2358 tok_str_add2(s
, TOK_LINENUM
, &cval
);
2360 tok_str_add2(s
, tok
, &tokc
);
2363 #if LDOUBLE_SIZE == 12
2364 #define LDOUBLE_GET(p, cv) \
2368 #elif LDOUBLE_SIZE == 8
2369 #define LDOUBLE_GET(p, cv) \
2373 #error add long double size support
2377 /* get a token from an integer array and increment pointer
2378 accordingly. we code it as a macro to avoid pointer aliasing. */
2379 #define TOK_GET(t, p, cv) \
2401 case TOK_CLDOUBLE: \
2402 LDOUBLE_GET(p, cv); \
2403 p += LDOUBLE_SIZE / 4; \
2410 /* defines handling */
2411 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
2415 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
2416 s
->next
= first_arg
;
2417 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
2420 /* undefined a define symbol. Its name is just set to zero */
2421 static void define_undef(Sym
*s
)
2425 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2426 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2430 static inline Sym
*define_find(int v
)
2433 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2435 return table_ident
[v
]->sym_define
;
2438 /* free define stack until top reaches 'b' */
2439 static void free_defines(Sym
*b
)
2447 /* do not free args or predefined defines */
2449 tok_str_free((int *)top
->c
);
2451 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2452 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2460 static Sym
*label_find(int v
)
2463 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2465 return table_ident
[v
]->sym_label
;
2468 static Sym
*label_push(Sym
**ptop
, int v
, int flags
)
2471 s
= sym_push2(ptop
, v
, 0, 0);
2473 ps
= &table_ident
[v
- TOK_IDENT
]->sym_label
;
2474 if (ptop
== &global_label_stack
) {
2475 /* modify the top most local identifier, so that
2476 sym_identifier will point to 's' when popped */
2478 ps
= &(*ps
)->prev_tok
;
2485 /* pop labels until element last is reached. Look if any labels are
2486 undefined. Define symbols if '&&label' was used. */
2487 static void label_pop(Sym
**ptop
, Sym
*slast
)
2490 for(s
= *ptop
; s
!= slast
; s
= s1
) {
2492 if (s
->r
== LABEL_DECLARED
) {
2493 warning("label '%s' declared but not used", get_tok_str(s
->v
, NULL
));
2494 } else if (s
->r
== LABEL_FORWARD
) {
2495 error("label '%s' used but not defined",
2496 get_tok_str(s
->v
, NULL
));
2499 /* define corresponding symbol. A size of
2501 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
2505 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= s
->prev_tok
;
2511 /* eval an expression for #if/#elif */
2512 static int expr_preprocess(void)
2518 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2519 next(); /* do macro subst */
2520 if (tok
== TOK_DEFINED
) {
2525 c
= define_find(tok
) != 0;
2530 } else if (tok
>= TOK_IDENT
) {
2531 /* if undefined macro */
2535 tok_str_add_tok(&str
);
2537 tok_str_add(&str
, -1); /* simulate end of file */
2538 tok_str_add(&str
, 0);
2539 /* now evaluate C constant expression */
2540 macro_ptr
= str
.str
;
2544 tok_str_free(str
.str
);
2548 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2549 static void tok_print(int *str
)
2555 TOK_GET(t
, str
, cval
);
2558 printf(" %s", get_tok_str(t
, &cval
));
2564 /* parse after #define */
2565 static void parse_define(void)
2567 Sym
*s
, *first
, **ps
;
2568 int v
, t
, varg
, is_vaargs
, c
;
2573 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2574 /* XXX: should check if same macro (ANSI) */
2577 /* '(' must be just after macro definition for MACRO_FUNC */
2578 c
= file
->buf_ptr
[0];
2580 c
= handle_stray1(file
->buf_ptr
);
2585 while (tok
!= ')') {
2589 if (varg
== TOK_DOTS
) {
2590 varg
= TOK___VA_ARGS__
;
2592 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2596 if (varg
< TOK_IDENT
)
2597 error("badly punctuated parameter list");
2598 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2609 /* EOF testing necessary for '-D' handling */
2610 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2611 tok_str_add2(&str
, tok
, &tokc
);
2614 tok_str_add(&str
, 0);
2616 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2619 define_push(v
, t
, str
.str
, first
);
2622 /* XXX: use a token or a hash table to accelerate matching ? */
2623 static CachedInclude
*search_cached_include(TCCState
*s1
,
2624 int type
, const char *filename
)
2629 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
2630 e
= s1
->cached_includes
[i
];
2631 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2637 static inline void add_cached_include(TCCState
*s1
, int type
,
2638 const char *filename
, int ifndef_macro
)
2642 if (search_cached_include(s1
, type
, filename
))
2645 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2647 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2651 strcpy(e
->filename
, filename
);
2652 e
->ifndef_macro
= ifndef_macro
;
2653 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2656 /* is_bof is true if first non space token at beginning of file */
2657 static void preprocess(int is_bof
)
2659 TCCState
*s1
= tcc_state
;
2660 int size
, i
, c
, n
, saved_parse_flags
;
2661 char buf
[1024], *q
, *p
;
2667 saved_parse_flags
= parse_flags
;
2668 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
|
2669 PARSE_FLAG_LINEFEED
;
2679 s
= define_find(tok
);
2680 /* undefine symbol by putting an invalid name */
2685 ch
= file
->buf_ptr
[0];
2686 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2691 } else if (ch
== '\"') {
2694 /* XXX: better stray handling */
2697 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2698 if ((q
- buf
) < sizeof(buf
) - 1)
2705 /* eat all spaces and comments after include */
2706 /* XXX: slightly incorrect */
2707 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2711 /* computed #include : either we have only strings or
2712 we have anything enclosed in '<>' */
2715 if (tok
== TOK_STR
) {
2716 while (tok
!= TOK_LINEFEED
) {
2717 if (tok
!= TOK_STR
) {
2719 error("'#include' expects \"FILENAME\" or <FILENAME>");
2721 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2727 while (tok
!= TOK_LINEFEED
) {
2728 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2732 /* check syntax and remove '<>' */
2733 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2734 goto include_syntax
;
2735 memmove(buf
, buf
+ 1, len
- 2);
2736 buf
[len
- 2] = '\0';
2741 e
= search_cached_include(s1
, c
, buf
);
2742 if (e
&& define_find(e
->ifndef_macro
)) {
2743 /* no need to parse the include because the 'ifndef macro'
2746 printf("%s: skipping %s\n", file
->filename
, buf
);
2750 /* first search in current dir if "header.h" */
2752 p
= strrchr(file
->filename
, '/');
2754 size
= p
+ 1 - file
->filename
;
2755 if (size
> sizeof(buf1
) - 1)
2756 size
= sizeof(buf1
) - 1;
2757 memcpy(buf1
, file
->filename
, size
);
2759 pstrcat(buf1
, sizeof(buf1
), buf
);
2760 f
= tcc_open(s1
, buf1
);
2764 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2765 error("#include recursion too deep");
2766 /* now search in all the include paths */
2767 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2768 for(i
= 0; i
< n
; i
++) {
2770 if (i
< s1
->nb_include_paths
)
2771 path
= s1
->include_paths
[i
];
2773 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2774 pstrcpy(buf1
, sizeof(buf1
), path
);
2775 pstrcat(buf1
, sizeof(buf1
), "/");
2776 pstrcat(buf1
, sizeof(buf1
), buf
);
2777 f
= tcc_open(s1
, buf1
);
2781 error("include file '%s' not found", buf
);
2785 printf("%s: including %s\n", file
->filename
, buf1
);
2788 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2789 /* push current file in stack */
2790 /* XXX: fix current line init */
2791 *s1
->include_stack_ptr
++ = file
;
2793 /* add include file debug info */
2795 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2797 tok_flags
|= TOK_FLAG_BOF
| TOK_FLAG_BOL
;
2798 ch
= file
->buf_ptr
[0];
2806 c
= expr_preprocess();
2812 if (tok
< TOK_IDENT
)
2813 error("invalid argument for '#if%sdef'", c
? "n" : "");
2817 printf("#ifndef %s\n", get_tok_str(tok
, NULL
));
2819 file
->ifndef_macro
= tok
;
2822 c
= (define_find(tok
) != 0) ^ c
;
2824 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2825 error("memory full");
2826 *s1
->ifdef_stack_ptr
++ = c
;
2829 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2830 error("#else without matching #if");
2831 if (s1
->ifdef_stack_ptr
[-1] & 2)
2832 error("#else after #else");
2833 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2836 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2837 error("#elif without matching #if");
2838 c
= s1
->ifdef_stack_ptr
[-1];
2840 error("#elif after #else");
2841 /* last #if/#elif expression was true: we skip */
2844 c
= expr_preprocess();
2845 s1
->ifdef_stack_ptr
[-1] = c
;
2855 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2856 error("#endif without matching #if");
2857 s1
->ifdef_stack_ptr
--;
2858 /* '#ifndef macro' was at the start of file. Now we check if
2859 an '#endif' is exactly at the end of file */
2860 if (file
->ifndef_macro
&&
2861 s1
->ifdef_stack_ptr
== file
->ifdef_stack_ptr
) {
2862 file
->ifndef_macro_saved
= file
->ifndef_macro
;
2863 /* need to set to zero to avoid false matches if another
2864 #ifndef at middle of file */
2865 file
->ifndef_macro
= 0;
2866 while (tok
!= TOK_LINEFEED
)
2868 tok_flags
|= TOK_FLAG_ENDIF
;
2874 if (tok
!= TOK_CINT
)
2876 file
->line_num
= tokc
.i
- 1; /* the line number will be incremented after */
2878 if (tok
!= TOK_LINEFEED
) {
2881 pstrcpy(file
->filename
, sizeof(file
->filename
),
2882 (char *)tokc
.cstr
->data
);
2888 ch
= file
->buf_ptr
[0];
2891 while (ch
!= '\n' && ch
!= CH_EOF
) {
2892 if ((q
- buf
) < sizeof(buf
) - 1)
2898 error("#error %s", buf
);
2900 warning("#warning %s", buf
);
2906 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
2907 /* '!' is ignored to allow C scripts. numbers are ignored
2908 to emulate cpp behaviour */
2910 if (!(saved_parse_flags
& PARSE_FLAG_ASM_COMMENTS
))
2911 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
2915 /* ignore other preprocess commands or #! for C scripts */
2916 while (tok
!= TOK_LINEFEED
)
2919 parse_flags
= saved_parse_flags
;
2922 /* evaluate escape codes in a string. */
2923 static void parse_escape_string(CString
*outstr
, const uint8_t *buf
, int is_long
)
2938 case '0': case '1': case '2': case '3':
2939 case '4': case '5': case '6': case '7':
2940 /* at most three octal digits */
2945 n
= n
* 8 + c
- '0';
2949 n
= n
* 8 + c
- '0';
2954 goto add_char_nonext
;
2960 if (c
>= 'a' && c
<= 'f')
2962 else if (c
>= 'A' && c
<= 'F')
2972 goto add_char_nonext
;
2996 goto invalid_escape
;
3006 if (c
>= '!' && c
<= '~')
3007 warning("unknown escape sequence: \'\\%c\'", c
);
3009 warning("unknown escape sequence: \'\\x%x\'", c
);
3016 cstr_ccat(outstr
, c
);
3018 cstr_wccat(outstr
, c
);
3020 /* add a trailing '\0' */
3022 cstr_ccat(outstr
, '\0');
3024 cstr_wccat(outstr
, '\0');
3027 /* we use 64 bit numbers */
3030 /* bn = (bn << shift) | or_val */
3031 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
3035 for(i
=0;i
<BN_SIZE
;i
++) {
3037 bn
[i
] = (v
<< shift
) | or_val
;
3038 or_val
= v
>> (32 - shift
);
3042 void bn_zero(unsigned int *bn
)
3045 for(i
=0;i
<BN_SIZE
;i
++) {
3050 /* parse number in null terminated string 'p' and return it in the
3052 void parse_number(const char *p
)
3054 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
3056 unsigned int bn
[BN_SIZE
];
3067 goto float_frac_parse
;
3068 } else if (t
== '0') {
3069 if (ch
== 'x' || ch
== 'X') {
3073 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
3079 /* parse all digits. cannot check octal numbers at this stage
3080 because of floating point constants */
3082 if (ch
>= 'a' && ch
<= 'f')
3084 else if (ch
>= 'A' && ch
<= 'F')
3092 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
3094 error("number too long");
3100 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
3101 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
3103 /* NOTE: strtox should support that for hexa numbers, but
3104 non ISOC99 libcs do not support it, so we prefer to do
3106 /* hexadecimal or binary floats */
3107 /* XXX: handle overflows */
3119 } else if (t
>= 'a') {
3121 } else if (t
>= 'A') {
3126 bn_lshift(bn
, shift
, t
);
3133 if (t
>= 'a' && t
<= 'f') {
3135 } else if (t
>= 'A' && t
<= 'F') {
3137 } else if (t
>= '0' && t
<= '9') {
3143 error("invalid digit");
3144 bn_lshift(bn
, shift
, t
);
3149 if (ch
!= 'p' && ch
!= 'P')
3156 } else if (ch
== '-') {
3160 if (ch
< '0' || ch
> '9')
3161 expect("exponent digits");
3162 while (ch
>= '0' && ch
<= '9') {
3163 exp_val
= exp_val
* 10 + ch
- '0';
3166 exp_val
= exp_val
* s
;
3168 /* now we can generate the number */
3169 /* XXX: should patch directly float number */
3170 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
3171 d
= ldexp(d
, exp_val
- frac_bits
);
3176 /* float : should handle overflow */
3178 } else if (t
== 'L') {
3181 /* XXX: not large enough */
3182 tokc
.ld
= (long double)d
;
3188 /* decimal floats */
3190 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3195 while (ch
>= '0' && ch
<= '9') {
3196 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3202 if (ch
== 'e' || ch
== 'E') {
3203 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3207 if (ch
== '-' || ch
== '+') {
3208 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3213 if (ch
< '0' || ch
> '9')
3214 expect("exponent digits");
3215 while (ch
>= '0' && ch
<= '9') {
3216 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3228 tokc
.f
= strtof(token_buf
, NULL
);
3229 } else if (t
== 'L') {
3232 tokc
.ld
= strtold(token_buf
, NULL
);
3235 tokc
.d
= strtod(token_buf
, NULL
);
3239 unsigned long long n
, n1
;
3242 /* integer number */
3245 if (b
== 10 && *q
== '0') {
3252 /* no need for checks except for base 10 / 8 errors */
3255 } else if (t
>= 'a') {
3257 } else if (t
>= 'A') {
3262 error("invalid digit");
3266 /* detect overflow */
3267 /* XXX: this test is not reliable */
3269 error("integer constant overflow");
3272 /* XXX: not exactly ANSI compliant */
3273 if ((n
& 0xffffffff00000000LL
) != 0) {
3278 } else if (n
> 0x7fffffff) {
3289 error("three 'l's in integer constant");
3292 if (tok
== TOK_CINT
)
3294 else if (tok
== TOK_CUINT
)
3298 } else if (t
== 'U') {
3300 error("two 'u's in integer constant");
3302 if (tok
== TOK_CINT
)
3304 else if (tok
== TOK_CLLONG
)
3311 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
3319 #define PARSE2(c1, tok1, c2, tok2) \
3330 /* return next token without macro substitution */
3331 static inline void next_nomacro1(void)
3351 /* first look if it is in fact an end of buffer */
3352 if (p
>= file
->buf_end
) {
3356 if (p
>= file
->buf_end
)
3369 TCCState
*s1
= tcc_state
;
3370 if (parse_flags
& PARSE_FLAG_LINEFEED
) {
3372 } else if (s1
->include_stack_ptr
== s1
->include_stack
||
3373 !(parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3374 /* no include left : end of file. */
3377 /* pop include file */
3379 /* test if previous '#endif' was after a #ifdef at
3381 if (tok_flags
& TOK_FLAG_ENDIF
) {
3383 printf("#endif %s\n", get_tok_str(file
->ifndef_macro_saved
, NULL
));
3385 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
3386 file
->ifndef_macro_saved
);
3389 /* add end of include file debug info */
3391 put_stabd(N_EINCL
, 0, 0);
3393 /* pop include stack */
3395 s1
->include_stack_ptr
--;
3396 file
= *s1
->include_stack_ptr
;
3404 if (parse_flags
& PARSE_FLAG_LINEFEED
) {
3408 tok_flags
|= TOK_FLAG_BOL
;
3417 if ((tok_flags
& TOK_FLAG_BOL
) &&
3418 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3420 preprocess(tok_flags
& TOK_FLAG_BOF
);
3426 tok
= TOK_TWOSHARPS
;
3428 if (parse_flags
& PARSE_FLAG_ASM_COMMENTS
) {
3429 p
= parse_line_comment(p
- 1);
3438 case 'a': case 'b': case 'c': case 'd':
3439 case 'e': case 'f': case 'g': case 'h':
3440 case 'i': case 'j': case 'k': case 'l':
3441 case 'm': case 'n': case 'o': case 'p':
3442 case 'q': case 'r': case 's': case 't':
3443 case 'u': case 'v': case 'w': case 'x':
3445 case 'A': case 'B': case 'C': case 'D':
3446 case 'E': case 'F': case 'G': case 'H':
3447 case 'I': case 'J': case 'K':
3448 case 'M': case 'N': case 'O': case 'P':
3449 case 'Q': case 'R': case 'S': case 'T':
3450 case 'U': case 'V': case 'W': case 'X':
3456 h
= TOK_HASH_FUNC(h
, c
);
3460 if (!isidnum_table
[c
])
3462 h
= TOK_HASH_FUNC(h
, c
);
3469 /* fast case : no stray found, so we have the full token
3470 and we have already hashed it */
3472 h
&= (TOK_HASH_SIZE
- 1);
3473 pts
= &hash_ident
[h
];
3478 if (ts
->len
== len
&& !memcmp(ts
->str
, p1
, len
))
3480 pts
= &(ts
->hash_next
);
3482 ts
= tok_alloc_new(pts
, p1
, len
);
3486 cstr_reset(&tokcstr
);
3489 cstr_ccat(&tokcstr
, *p1
);
3495 while (isidnum_table
[c
]) {
3496 cstr_ccat(&tokcstr
, c
);
3499 ts
= tok_alloc(tokcstr
.data
, tokcstr
.size
);
3505 if (t
!= '\\' && t
!= '\'' && t
!= '\"') {
3507 goto parse_ident_fast
;
3510 if (c
== '\'' || c
== '\"') {
3514 cstr_reset(&tokcstr
);
3515 cstr_ccat(&tokcstr
, 'L');
3516 goto parse_ident_slow
;
3520 case '0': case '1': case '2': case '3':
3521 case '4': case '5': case '6': case '7':
3524 cstr_reset(&tokcstr
);
3525 /* after the first digit, accept digits, alpha, '.' or sign if
3526 prefixed by 'eEpP' */
3530 cstr_ccat(&tokcstr
, c
);
3532 if (!(isnum(c
) || isid(c
) || c
== '.' ||
3533 ((c
== '+' || c
== '-') &&
3534 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
3537 /* We add a trailing '\0' to ease parsing */
3538 cstr_ccat(&tokcstr
, '\0');
3539 tokc
.cstr
= &tokcstr
;
3543 /* special dot handling because it can also start a number */
3546 cstr_reset(&tokcstr
);
3547 cstr_ccat(&tokcstr
, '.');
3549 } else if (c
== '.') {
3569 /* parse the string */
3571 p
= parse_pp_string(p
, sep
, &str
);
3572 cstr_ccat(&str
, '\0');
3574 /* eval the escape (should be done as TOK_PPNUM) */
3575 cstr_reset(&tokcstr
);
3576 parse_escape_string(&tokcstr
, str
.data
, is_long
);
3581 /* XXX: make it portable */
3585 char_size
= sizeof(int);
3586 if (tokcstr
.size
<= char_size
)
3587 error("empty character constant");
3588 if (tokcstr
.size
> 2 * char_size
)
3589 warning("multi-character character constant");
3591 tokc
.i
= *(int8_t *)tokcstr
.data
;
3594 tokc
.i
= *(int *)tokcstr
.data
;
3598 tokc
.cstr
= &tokcstr
;
3612 } else if (c
== '<') {
3630 } else if (c
== '>') {
3648 } else if (c
== '=') {
3661 } else if (c
== '=') {
3674 } else if (c
== '=') {
3687 } else if (c
== '=') {
3690 } else if (c
== '>') {
3698 PARSE2('!', '!', '=', TOK_NE
)
3699 PARSE2('=', '=', '=', TOK_EQ
)
3700 PARSE2('*', '*', '=', TOK_A_MUL
)
3701 PARSE2('%', '%', '=', TOK_A_MOD
)
3702 PARSE2('^', '^', '=', TOK_A_XOR
)
3704 /* comments or operator */
3708 p
= parse_comment(p
);
3710 } else if (c
== '/') {
3711 p
= parse_line_comment(p
);
3713 } else if (c
== '=') {
3733 case '$': /* only used in assembler */
3738 error("unrecognized character \\x%02x", c
);
3743 #if defined(PARSE_DEBUG)
3744 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3748 /* return next token without macro substitution. Can read input from
3750 static void next_nomacro(void)
3756 TOK_GET(tok
, macro_ptr
, tokc
);
3757 if (tok
== TOK_LINENUM
) {
3758 file
->line_num
= tokc
.i
;
3767 /* substitute args in macro_str and return allocated string */
3768 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
3770 int *st
, last_tok
, t
, notfirst
;
3779 TOK_GET(t
, macro_str
, cval
);
3784 TOK_GET(t
, macro_str
, cval
);
3787 s
= sym_find2(args
, t
);
3794 cstr_ccat(&cstr
, ' ');
3795 TOK_GET(t
, st
, cval
);
3796 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
3799 cstr_ccat(&cstr
, '\0');
3801 printf("stringize: %s\n", (char *)cstr
.data
);
3805 tok_str_add2(&str
, TOK_STR
, &cval
);
3808 tok_str_add2(&str
, t
, &cval
);
3810 } else if (t
>= TOK_IDENT
) {
3811 s
= sym_find2(args
, t
);
3814 /* if '##' is present before or after, no arg substitution */
3815 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
3816 /* special case for var arg macros : ## eats the
3817 ',' if empty VA_ARGS variable. */
3818 /* XXX: test of the ',' is not 100%
3819 reliable. should fix it to avoid security
3821 if (gnu_ext
&& s
->type
.t
&&
3822 last_tok
== TOK_TWOSHARPS
&&
3823 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
3825 /* suppress ',' '##' */
3828 /* suppress '##' and add variable */
3836 TOK_GET(t1
, st
, cval
);
3839 tok_str_add2(&str
, t1
, &cval
);
3843 /* NOTE: the stream cannot be read when macro
3844 substituing an argument */
3845 macro_subst(&str
, nested_list
, st
, 0);
3848 tok_str_add(&str
, t
);
3851 tok_str_add2(&str
, t
, &cval
);
3855 tok_str_add(&str
, 0);
3859 static char const ab_month_name
[12][4] =
3861 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
3862 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
3865 /* do macro substitution of current token with macro 's' and add
3866 result to (tok_str,tok_len). 'nested_list' is the list of all
3867 macros we got inside to avoid recursing. Return non zero if no
3868 substitution needs to be done */
3869 static int macro_subst_tok(TokenString
*tok_str
,
3870 Sym
**nested_list
, Sym
*s
, int can_read_stream
)
3872 Sym
*args
, *sa
, *sa1
;
3873 int mstr_allocated
, parlevel
, *mstr
, t
, t1
;
3880 /* if symbol is a macro, prepare substitution */
3881 /* special macros */
3882 if (tok
== TOK___LINE__
) {
3883 snprintf(buf
, sizeof(buf
), "%d", file
->line_num
);
3887 } else if (tok
== TOK___FILE__
) {
3888 cstrval
= file
->filename
;
3890 } else if (tok
== TOK___DATE__
|| tok
== TOK___TIME__
) {
3895 tm
= localtime(&ti
);
3896 if (tok
== TOK___DATE__
) {
3897 snprintf(buf
, sizeof(buf
), "%s %2d %d",
3898 ab_month_name
[tm
->tm_mon
], tm
->tm_mday
, tm
->tm_year
+ 1900);
3900 snprintf(buf
, sizeof(buf
), "%02d:%02d:%02d",
3901 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
3908 cstr_cat(&cstr
, cstrval
);
3909 cstr_ccat(&cstr
, '\0');
3911 tok_str_add2(tok_str
, t1
, &cval
);
3916 if (s
->type
.t
== MACRO_FUNC
) {
3917 /* NOTE: we do not use next_nomacro to avoid eating the
3918 next token. XXX: find better solution */
3921 if (t
== 0 && can_read_stream
) {
3922 /* end of macro stream: we must look at the token
3923 after in the file */
3929 /* XXX: incorrect with comments */
3930 ch
= file
->buf_ptr
[0];
3931 while (is_space(ch
) || ch
== '\n')
3935 if (t
!= '(') /* no macro subst */
3938 /* argument macro */
3943 /* NOTE: empty args are allowed, except if no args */
3945 /* handle '()' case */
3946 if (!args
&& !sa
&& tok
== ')')
3949 error("macro '%s' used with too many args",
3950 get_tok_str(s
->v
, 0));
3953 /* NOTE: non zero sa->t indicates VA_ARGS */
3954 while ((parlevel
> 0 ||
3956 (tok
!= ',' || sa
->type
.t
))) &&
3960 else if (tok
== ')')
3962 tok_str_add2(&str
, tok
, &tokc
);
3965 tok_str_add(&str
, 0);
3966 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
3969 /* special case for gcc var args: add an empty
3970 var arg argument if it is omitted */
3971 if (sa
&& sa
->type
.t
&& gnu_ext
)
3981 error("macro '%s' used with too few args",
3982 get_tok_str(s
->v
, 0));
3985 /* now subst each arg */
3986 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3991 tok_str_free((int *)sa
->c
);
3997 sym_push2(nested_list
, s
->v
, 0, 0);
3998 macro_subst(tok_str
, nested_list
, mstr
, 1);
3999 /* pop nested defined symbol */
4001 *nested_list
= sa1
->prev
;
4009 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
4010 return the resulting string (which must be freed). */
4011 static inline int *macro_twosharps(const int *macro_str
)
4014 const int *macro_ptr1
, *start_macro_ptr
, *ptr
, *saved_macro_ptr
;
4016 const char *p1
, *p2
;
4018 TokenString macro_str1
;
4021 start_macro_ptr
= macro_str
;
4022 /* we search the first '##' */
4024 macro_ptr1
= macro_str
;
4025 TOK_GET(t
, macro_str
, cval
);
4026 /* nothing more to do if end of string */
4029 if (*macro_str
== TOK_TWOSHARPS
)
4033 /* we saw '##', so we need more processing to handle it */
4035 tok_str_new(¯o_str1
);
4039 /* add all tokens seen so far */
4040 for(ptr
= start_macro_ptr
; ptr
< macro_ptr1
;) {
4041 TOK_GET(t
, ptr
, cval
);
4042 tok_str_add2(¯o_str1
, t
, &cval
);
4044 saved_macro_ptr
= macro_ptr
;
4045 /* XXX: get rid of the use of macro_ptr here */
4046 macro_ptr
= (int *)macro_str
;
4048 while (*macro_ptr
== TOK_TWOSHARPS
) {
4050 macro_ptr1
= macro_ptr
;
4053 TOK_GET(t
, macro_ptr
, cval
);
4054 /* We concatenate the two tokens if we have an
4055 identifier or a preprocessing number */
4057 p1
= get_tok_str(tok
, &tokc
);
4058 cstr_cat(&cstr
, p1
);
4059 p2
= get_tok_str(t
, &cval
);
4060 cstr_cat(&cstr
, p2
);
4061 cstr_ccat(&cstr
, '\0');
4063 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
4064 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
4065 if (tok
== TOK_PPNUM
) {
4066 /* if number, then create a number token */
4067 /* NOTE: no need to allocate because
4068 tok_str_add2() does it */
4071 /* if identifier, we must do a test to
4072 validate we have a correct identifier */
4073 if (t
== TOK_PPNUM
) {
4083 if (!isnum(c
) && !isid(c
))
4087 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
4088 tok
= ts
->tok
; /* modify current token */
4091 const char *str
= cstr
.data
;
4092 const unsigned char *q
;
4094 /* we look for a valid token */
4095 /* XXX: do more extensive checks */
4096 if (!strcmp(str
, ">>=")) {
4098 } else if (!strcmp(str
, "<<=")) {
4100 } else if (strlen(str
) == 2) {
4101 /* search in two bytes table */
4106 if (q
[0] == str
[0] && q
[1] == str
[1])
4113 /* NOTE: because get_tok_str use a static buffer,
4116 p1
= get_tok_str(tok
, &tokc
);
4117 cstr_cat(&cstr
, p1
);
4118 cstr_ccat(&cstr
, '\0');
4119 p2
= get_tok_str(t
, &cval
);
4120 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
4121 /* cannot merge tokens: just add them separately */
4122 tok_str_add2(¯o_str1
, tok
, &tokc
);
4123 /* XXX: free associated memory ? */
4130 tok_str_add2(¯o_str1
, tok
, &tokc
);
4135 macro_ptr
= (int *)saved_macro_ptr
;
4137 tok_str_add(¯o_str1
, 0);
4138 return macro_str1
.str
;
4142 /* do macro substitution of macro_str and add result to
4143 (tok_str,tok_len). 'nested_list' is the list of all macros we got
4144 inside to avoid recursing. */
4145 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
4146 const int *macro_str
, int can_read_stream
)
4149 int *saved_macro_ptr
, *macro_str1
;
4154 /* first scan for '##' operator handling */
4156 macro_str1
= macro_twosharps(ptr
);
4160 /* NOTE: ptr == NULL can only happen if tokens are read from
4161 file stream due to a macro function call */
4164 TOK_GET(t
, ptr
, cval
);
4169 /* if nested substitution, do nothing */
4170 if (sym_find2(*nested_list
, t
))
4172 saved_macro_ptr
= macro_ptr
;
4173 macro_ptr
= (int *)ptr
;
4175 ret
= macro_subst_tok(tok_str
, nested_list
, s
, can_read_stream
);
4176 ptr
= (int *)macro_ptr
;
4177 macro_ptr
= saved_macro_ptr
;
4182 tok_str_add2(tok_str
, t
, &cval
);
4186 tok_str_free(macro_str1
);
4189 /* return next token with macro substitution */
4190 static void next(void)
4192 Sym
*nested_list
, *s
;
4198 /* if not reading from macro substituted string, then try
4199 to substitute macros */
4200 if (tok
>= TOK_IDENT
&&
4201 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
4202 s
= define_find(tok
);
4204 /* we have a macro: we try to substitute */
4207 if (macro_subst_tok(&str
, &nested_list
, s
, 1) == 0) {
4208 /* substitution done, NOTE: maybe empty */
4209 tok_str_add(&str
, 0);
4210 macro_ptr
= str
.str
;
4211 macro_ptr_allocated
= str
.str
;
4218 /* end of macro or end of unget buffer */
4219 if (unget_buffer_enabled
) {
4220 macro_ptr
= unget_saved_macro_ptr
;
4221 unget_buffer_enabled
= 0;
4223 /* end of macro string: free it */
4224 tok_str_free(macro_ptr_allocated
);
4231 /* convert preprocessor tokens into C tokens */
4232 if (tok
== TOK_PPNUM
&&
4233 (parse_flags
& PARSE_FLAG_TOK_NUM
)) {
4234 parse_number((char *)tokc
.cstr
->data
);
4238 /* push back current token and set current token to 'last_tok'. Only
4239 identifier case handled for labels. */
4240 static inline void unget_tok(int last_tok
)
4244 unget_saved_macro_ptr
= macro_ptr
;
4245 unget_buffer_enabled
= 1;
4246 q
= unget_saved_buffer
;
4249 n
= tok_ext_size(tok
) - 1;
4252 *q
= 0; /* end of token string */
4257 void swap(int *p
, int *q
)
4265 void vsetc(CType
*type
, int r
, CValue
*vc
)
4269 if (vtop
>= vstack
+ VSTACK_SIZE
)
4270 error("memory full");
4271 /* cannot let cpu flags if other instruction are generated. Also
4272 avoid leaving VT_JMP anywhere except on the top of the stack
4273 because it would complicate the code generator. */
4274 if (vtop
>= vstack
) {
4275 v
= vtop
->r
& VT_VALMASK
;
4276 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
4282 vtop
->r2
= VT_CONST
;
4286 /* push integer constant */
4291 vsetc(&int_type
, VT_CONST
, &cval
);
4294 /* Return a static symbol pointing to a section */
4295 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
4296 unsigned long offset
, unsigned long size
)
4302 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
4303 sym
->type
.ref
= type
->ref
;
4304 sym
->r
= VT_CONST
| VT_SYM
;
4305 put_extern_sym(sym
, sec
, offset
, size
);
4309 /* push a reference to a section offset by adding a dummy symbol */
4310 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
4315 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4316 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
4319 /* define a new external reference to a symbol 'v' of type 'u' */
4320 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
4326 /* push forward reference */
4327 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
4328 s
->type
.ref
= type
->ref
;
4329 s
->r
= r
| VT_CONST
| VT_SYM
;
4334 /* define a new external reference to a symbol 'v' of type 'u' */
4335 static Sym
*external_sym(int v
, CType
*type
, int r
)
4341 /* push forward reference */
4342 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
4343 s
->type
.t
|= VT_EXTERN
;
4345 if (!is_compatible_types(&s
->type
, type
))
4346 error("incompatible types for redefinition of '%s'",
4347 get_tok_str(v
, NULL
));
4352 /* push a reference to global symbol v */
4353 static void vpush_global_sym(CType
*type
, int v
)
4358 sym
= external_global_sym(v
, type
, 0);
4360 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4364 void vset(CType
*type
, int r
, int v
)
4369 vsetc(type
, r
, &cval
);
4372 void vseti(int r
, int v
)
4388 void vpushv(SValue
*v
)
4390 if (vtop
>= vstack
+ VSTACK_SIZE
)
4391 error("memory full");
4401 /* save r to the memory stack, and mark it as being free */
4402 void save_reg(int r
)
4404 int l
, saved
, size
, align
;
4408 /* modify all stack values */
4411 for(p
=vstack
;p
<=vtop
;p
++) {
4412 if ((p
->r
& VT_VALMASK
) == r
||
4413 (p
->r2
& VT_VALMASK
) == r
) {
4414 /* must save value on stack if not already done */
4416 /* NOTE: must reload 'r' because r might be equal to r2 */
4417 r
= p
->r
& VT_VALMASK
;
4418 /* store register in the stack */
4420 if ((p
->r
& VT_LVAL
) ||
4421 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
4423 size
= type_size(type
, &align
);
4424 loc
= (loc
- size
) & -align
;
4425 sv
.type
.t
= type
->t
;
4426 sv
.r
= VT_LOCAL
| VT_LVAL
;
4429 #ifdef TCC_TARGET_I386
4430 /* x86 specific: need to pop fp register ST0 if saved */
4431 if (r
== TREG_ST0
) {
4432 o(0xd9dd); /* fstp %st(1) */
4435 /* special long long case */
4436 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
4443 /* mark that stack entry as being saved on the stack */
4444 if (p
->r
& VT_LVAL
) {
4445 /* also clear the bounded flag because the
4446 relocation address of the function was stored in
4448 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
4450 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
4458 /* find a register of class 'rc2' with at most one reference on stack.
4459 * If none, call get_reg(rc) */
4460 int get_reg_ex(int rc
, int rc2
)
4465 for(r
=0;r
<NB_REGS
;r
++) {
4466 if (reg_classes
[r
] & rc2
) {
4469 for(p
= vstack
; p
<= vtop
; p
++) {
4470 if ((p
->r
& VT_VALMASK
) == r
||
4471 (p
->r2
& VT_VALMASK
) == r
)
4481 /* find a free register of class 'rc'. If none, save one register */
4487 /* find a free register */
4488 for(r
=0;r
<NB_REGS
;r
++) {
4489 if (reg_classes
[r
] & rc
) {
4490 for(p
=vstack
;p
<=vtop
;p
++) {
4491 if ((p
->r
& VT_VALMASK
) == r
||
4492 (p
->r2
& VT_VALMASK
) == r
)
4500 /* no register left : free the first one on the stack (VERY
4501 IMPORTANT to start from the bottom to ensure that we don't
4502 spill registers used in gen_opi()) */
4503 for(p
=vstack
;p
<=vtop
;p
++) {
4504 r
= p
->r
& VT_VALMASK
;
4505 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
4507 /* also look at second register (if long long) */
4508 r
= p
->r2
& VT_VALMASK
;
4509 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
4515 /* Should never comes here */
4519 /* save registers up to (vtop - n) stack entry */
4520 void save_regs(int n
)
4525 for(p
= vstack
;p
<= p1
; p
++) {
4526 r
= p
->r
& VT_VALMASK
;
4533 /* move register 's' to 'r', and flush previous value of r to memory
4535 void move_reg(int r
, int s
)
4548 /* get address of vtop (vtop MUST BE an lvalue) */
4551 vtop
->r
&= ~VT_LVAL
;
4552 /* tricky: if saved lvalue, then we can go back to lvalue */
4553 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
4554 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
4557 #ifdef CONFIG_TCC_BCHECK
4558 /* generate lvalue bound code */
4564 vtop
->r
&= ~VT_MUSTBOUND
;
4565 /* if lvalue, then use checking code before dereferencing */
4566 if (vtop
->r
& VT_LVAL
) {
4567 /* if not VT_BOUNDED value, then make one */
4568 if (!(vtop
->r
& VT_BOUNDED
)) {
4569 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
4570 /* must save type because we must set it to int to get pointer */
4572 vtop
->type
.t
= VT_INT
;
4575 gen_bounded_ptr_add();
4576 vtop
->r
|= lval_type
;
4579 /* then check for dereferencing */
4580 gen_bounded_ptr_deref();
4585 /* store vtop a register belonging to class 'rc'. lvalues are
4586 converted to values. Cannot be used if cannot be converted to
4587 register value (such as structures). */
4590 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
4591 unsigned long long ll
;
4593 /* NOTE: get_reg can modify vstack[] */
4594 if (vtop
->type
.t
& VT_BITFIELD
) {
4595 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
4596 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4597 /* remove bit field info to avoid loops */
4598 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4599 /* generate shifts */
4600 vpushi(32 - (bit_pos
+ bit_size
));
4602 vpushi(32 - bit_size
);
4603 /* NOTE: transformed to SHR if unsigned */
4607 if (is_float(vtop
->type
.t
) &&
4608 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4611 unsigned long offset
;
4613 /* XXX: unify with initializers handling ? */
4614 /* CPUs usually cannot use float constants, so we store them
4615 generically in data segment */
4616 size
= type_size(&vtop
->type
, &align
);
4617 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
4618 data_section
->data_offset
= offset
;
4619 /* XXX: not portable yet */
4620 ptr
= section_ptr_add(data_section
, size
);
4623 ptr
[i
] = vtop
->c
.tab
[i
];
4624 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
4625 vtop
->r
|= VT_LVAL
| VT_SYM
;
4629 #ifdef CONFIG_TCC_BCHECK
4630 if (vtop
->r
& VT_MUSTBOUND
)
4634 r
= vtop
->r
& VT_VALMASK
;
4635 /* need to reload if:
4637 - lvalue (need to dereference pointer)
4638 - already a register, but not in the right class */
4639 if (r
>= VT_CONST
||
4640 (vtop
->r
& VT_LVAL
) ||
4641 !(reg_classes
[r
] & rc
) ||
4642 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
4643 !(reg_classes
[vtop
->r2
] & rc
))) {
4645 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
4646 /* two register type load : expand to two words
4648 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4651 vtop
->c
.ui
= ll
; /* first word */
4653 vtop
->r
= r
; /* save register value */
4654 vpushi(ll
>> 32); /* second word */
4655 } else if (r
>= VT_CONST
|| /* XXX: test to VT_CONST incorrect ? */
4656 (vtop
->r
& VT_LVAL
)) {
4657 /* We do not want to modifier the long long
4658 pointer here, so the safest (and less
4659 efficient) is to save all the other registers
4660 in the stack. XXX: totally inefficient. */
4662 /* load from memory */
4665 vtop
[-1].r
= r
; /* save register value */
4666 /* increment pointer to get second word */
4667 vtop
->type
.t
= VT_INT
;
4673 /* move registers */
4676 vtop
[-1].r
= r
; /* save register value */
4677 vtop
->r
= vtop
[-1].r2
;
4679 /* allocate second register */
4686 /* write second register */
4688 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
4690 /* lvalue of scalar type : need to use lvalue type
4691 because of possible cast */
4694 /* compute memory access type */
4695 if (vtop
->r
& VT_LVAL_BYTE
)
4697 else if (vtop
->r
& VT_LVAL_SHORT
)
4699 if (vtop
->r
& VT_LVAL_UNSIGNED
)
4703 /* restore wanted type */
4706 /* one register type load */
4711 #ifdef TCC_TARGET_C67
4712 /* uses register pairs for doubles */
4713 if ((vtop
->type
.t
& VT_BTYPE
) == VT_DOUBLE
)
4720 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4721 void gv2(int rc1
, int rc2
)
4725 /* generate more generic register first. But VT_JMP or VT_CMP
4726 values must be generated first in all cases to avoid possible
4728 v
= vtop
[0].r
& VT_VALMASK
;
4729 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
4734 /* test if reload is needed for first register */
4735 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
4745 /* test if reload is needed for first register */
4746 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
4752 /* expand long long on stack in two int registers */
4757 u
= vtop
->type
.t
& VT_UNSIGNED
;
4760 vtop
[0].r
= vtop
[-1].r2
;
4761 vtop
[0].r2
= VT_CONST
;
4762 vtop
[-1].r2
= VT_CONST
;
4763 vtop
[0].type
.t
= VT_INT
| u
;
4764 vtop
[-1].type
.t
= VT_INT
| u
;
4767 #ifdef TCC_TARGET_ARM
4768 /* expand long long on stack */
4769 void lexpand_nr(void)
4773 u
= vtop
->type
.t
& VT_UNSIGNED
;
4775 vtop
->r2
= VT_CONST
;
4776 vtop
->type
.t
= VT_INT
| u
;
4777 v
=vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
);
4778 if (v
== VT_CONST
) {
4779 vtop
[-1].c
.ui
= vtop
->c
.ull
;
4780 vtop
->c
.ui
= vtop
->c
.ull
>> 32;
4782 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
4784 vtop
->r
= vtop
[-1].r
;
4785 } else if (v
> VT_CONST
) {
4789 vtop
->r
= vtop
[-1].r2
;
4790 vtop
[-1].r2
= VT_CONST
;
4791 vtop
[-1].type
.t
= VT_INT
| u
;
4795 /* build a long long from two ints */
4798 gv2(RC_INT
, RC_INT
);
4799 vtop
[-1].r2
= vtop
[0].r
;
4800 vtop
[-1].type
.t
= t
;
4804 /* rotate n first stack elements to the bottom
4805 I1 ... In -> I2 ... In I1 [top is right]
4813 for(i
=-n
+1;i
!=0;i
++)
4814 vtop
[i
] = vtop
[i
+1];
4818 /* rotate n first stack elements to the top
4819 I1 ... In -> In I1 ... I(n-1) [top is right]
4827 for(i
= 0;i
< n
- 1; i
++)
4828 vtop
[-i
] = vtop
[-i
- 1];
4832 #ifdef TCC_TARGET_ARM
4833 /* like vrott but in other direction
4834 In ... I1 -> I(n-1) ... I1 In [top is right]
4842 for(i
= n
- 1; i
> 0; i
--)
4843 vtop
[-i
] = vtop
[-i
+ 1];
4848 /* pop stack value */
4852 v
= vtop
->r
& VT_VALMASK
;
4853 #ifdef TCC_TARGET_I386
4854 /* for x86, we need to pop the FP stack */
4855 if (v
== TREG_ST0
&& !nocode_wanted
) {
4856 o(0xd9dd); /* fstp %st(1) */
4859 if (v
== VT_JMP
|| v
== VT_JMPI
) {
4860 /* need to put correct jump if && or || without test */
4866 /* convert stack entry to register and duplicate its value in another
4874 if ((t
& VT_BTYPE
) == VT_LLONG
) {
4881 /* stack: H L L1 H1 */
4889 /* duplicate value */
4900 load(r1
, &sv
); /* move r to r1 */
4902 /* duplicates value */
4907 /* generate CPU independent (unsigned) long long operations */
4908 void gen_opl(int op
)
4910 int t
, a
, b
, op1
, c
, i
;
4917 func
= TOK___divdi3
;
4920 func
= TOK___udivdi3
;
4923 func
= TOK___moddi3
;
4926 func
= TOK___umoddi3
;
4928 /* call generic long long function */
4929 vpush_global_sym(&func_old_type
, func
);
4934 vtop
->r2
= REG_LRET
;
4947 /* stack: L1 H1 L2 H2 */
4952 vtop
[-2] = vtop
[-3];
4955 /* stack: H1 H2 L1 L2 */
4961 /* stack: H1 H2 L1 L2 ML MH */
4964 /* stack: ML MH H1 H2 L1 L2 */
4968 /* stack: ML MH H1 L2 H2 L1 */
4973 /* stack: ML MH M1 M2 */
4976 } else if (op
== '+' || op
== '-') {
4977 /* XXX: add non carry method too (for MIPS or alpha) */
4983 /* stack: H1 H2 (L1 op L2) */
4986 gen_op(op1
+ 1); /* TOK_xxxC2 */
4989 /* stack: H1 H2 (L1 op L2) */
4992 /* stack: (L1 op L2) H1 H2 */
4994 /* stack: (L1 op L2) (H1 op H2) */
5002 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
5003 t
= vtop
[-1].type
.t
;
5007 /* stack: L H shift */
5009 /* constant: simpler */
5010 /* NOTE: all comments are for SHL. the other cases are
5011 done by swaping words */
5022 if (op
!= TOK_SAR
) {
5055 /* XXX: should provide a faster fallback on x86 ? */
5058 func
= TOK___sardi3
;
5061 func
= TOK___shrdi3
;
5064 func
= TOK___shldi3
;
5070 /* compare operations */
5076 /* stack: L1 H1 L2 H2 */
5078 vtop
[-1] = vtop
[-2];
5080 /* stack: L1 L2 H1 H2 */
5083 /* when values are equal, we need to compare low words. since
5084 the jump is inverted, we invert the test too. */
5087 else if (op1
== TOK_GT
)
5089 else if (op1
== TOK_ULT
)
5091 else if (op1
== TOK_UGT
)
5096 if (op1
!= TOK_NE
) {
5100 /* generate non equal test */
5101 /* XXX: NOT PORTABLE yet */
5105 #if defined(TCC_TARGET_I386)
5106 b
= psym(0x850f, 0);
5107 #elif defined(TCC_TARGET_ARM)
5109 o(0x1A000000 | encbranch(ind
, 0, 1));
5110 #elif defined(TCC_TARGET_C67)
5111 error("not implemented");
5113 #error not supported
5117 /* compare low. Always unsigned */
5121 else if (op1
== TOK_LE
)
5123 else if (op1
== TOK_GT
)
5125 else if (op1
== TOK_GE
)
5135 /* handle integer constant optimizations and various machine
5137 void gen_opic(int op
)
5144 /* currently, we cannot do computations with forward symbols */
5145 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5146 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5150 case '+': v1
->c
.i
+= fc
; break;
5151 case '-': v1
->c
.i
-= fc
; break;
5152 case '&': v1
->c
.i
&= fc
; break;
5153 case '^': v1
->c
.i
^= fc
; break;
5154 case '|': v1
->c
.i
|= fc
; break;
5155 case '*': v1
->c
.i
*= fc
; break;
5162 /* if division by zero, generate explicit division */
5165 error("division by zero in constant");
5169 default: v1
->c
.i
/= fc
; break;
5170 case '%': v1
->c
.i
%= fc
; break;
5171 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
5172 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
5175 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
5176 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
5177 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
5179 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
5180 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
5181 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
5182 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
5183 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
5184 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
5185 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
5186 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
5187 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
5188 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
5190 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
5191 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
5197 /* if commutative ops, put c2 as constant */
5198 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
5199 op
== '|' || op
== '*')) {
5204 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
5207 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
5208 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
5214 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
5215 /* try to use shifts instead of muls or divs */
5216 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
5225 else if (op
== TOK_PDIV
)
5231 } else if (c2
&& (op
== '+' || op
== '-') &&
5232 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
5233 (VT_CONST
| VT_SYM
)) {
5234 /* symbol + constant case */
5241 if (!nocode_wanted
) {
5242 /* call low level op generator */
5251 /* generate a floating point operation with constant propagation */
5252 void gen_opif(int op
)
5260 /* currently, we cannot do computations with forward symbols */
5261 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5262 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5264 if (v1
->type
.t
== VT_FLOAT
) {
5267 } else if (v1
->type
.t
== VT_DOUBLE
) {
5275 /* NOTE: we only do constant propagation if finite number (not
5276 NaN or infinity) (ANSI spec) */
5277 if (!ieee_finite(f1
) || !ieee_finite(f2
))
5281 case '+': f1
+= f2
; break;
5282 case '-': f1
-= f2
; break;
5283 case '*': f1
*= f2
; break;
5287 error("division by zero in constant");
5292 /* XXX: also handles tests ? */
5296 /* XXX: overflow test ? */
5297 if (v1
->type
.t
== VT_FLOAT
) {
5299 } else if (v1
->type
.t
== VT_DOUBLE
) {
5307 if (!nocode_wanted
) {
5315 static int pointed_size(CType
*type
)
5318 return type_size(pointed_type(type
), &align
);
5321 static inline int is_null_pointer(SValue
*p
)
5323 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
5325 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& p
->c
.i
== 0) ||
5326 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.ll
== 0);
5329 static inline int is_integer_btype(int bt
)
5331 return (bt
== VT_BYTE
|| bt
== VT_SHORT
||
5332 bt
== VT_INT
|| bt
== VT_LLONG
);
5335 /* check types for comparison or substraction of pointers */
5336 static void check_comparison_pointer_types(SValue
*p1
, SValue
*p2
, int op
)
5338 CType
*type1
, *type2
, tmp_type1
, tmp_type2
;
5341 /* null pointers are accepted for all comparisons as gcc */
5342 if (is_null_pointer(p1
) || is_null_pointer(p2
))
5346 bt1
= type1
->t
& VT_BTYPE
;
5347 bt2
= type2
->t
& VT_BTYPE
;
5348 /* accept comparison between pointer and integer with a warning */
5349 if ((is_integer_btype(bt1
) || is_integer_btype(bt2
)) && op
!= '-') {
5350 warning("comparison between pointer and integer");
5354 /* both must be pointers or implicit function pointers */
5355 if (bt1
== VT_PTR
) {
5356 type1
= pointed_type(type1
);
5357 } else if (bt1
!= VT_FUNC
)
5358 goto invalid_operands
;
5360 if (bt2
== VT_PTR
) {
5361 type2
= pointed_type(type2
);
5362 } else if (bt2
!= VT_FUNC
) {
5364 error("invalid operands to binary %s", get_tok_str(op
, NULL
));
5366 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
5367 (type2
->t
& VT_BTYPE
) == VT_VOID
)
5371 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5372 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5373 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
5374 /* gcc-like error if '-' is used */
5376 goto invalid_operands
;
5378 warning("comparison of distinct pointer types lacks a cast");
5382 /* generic gen_op: handles types problems */
5385 int u
, t1
, t2
, bt1
, bt2
, t
;
5388 t1
= vtop
[-1].type
.t
;
5389 t2
= vtop
[0].type
.t
;
5390 bt1
= t1
& VT_BTYPE
;
5391 bt2
= t2
& VT_BTYPE
;
5393 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5394 /* at least one operand is a pointer */
5395 /* relationnal op: must be both pointers */
5396 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5397 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5398 /* pointers are handled are unsigned */
5399 t
= VT_INT
| VT_UNSIGNED
;
5402 /* if both pointers, then it must be the '-' op */
5403 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
5405 error("cannot use pointers here");
5406 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5407 /* XXX: check that types are compatible */
5408 u
= pointed_size(&vtop
[-1].type
);
5410 /* set to integer type */
5411 vtop
->type
.t
= VT_INT
;
5415 /* exactly one pointer : must be '+' or '-'. */
5416 if (op
!= '-' && op
!= '+')
5417 error("cannot use pointers here");
5418 /* Put pointer as first operand */
5419 if (bt2
== VT_PTR
) {
5423 type1
= vtop
[-1].type
;
5424 /* XXX: cast to int ? (long long case) */
5425 vpushi(pointed_size(&vtop
[-1].type
));
5427 #ifdef CONFIG_TCC_BCHECK
5428 /* if evaluating constant expression, no code should be
5429 generated, so no bound check */
5430 if (do_bounds_check
&& !const_wanted
) {
5431 /* if bounded pointers, we generate a special code to
5438 gen_bounded_ptr_add();
5444 /* put again type if gen_opic() swaped operands */
5447 } else if (is_float(bt1
) || is_float(bt2
)) {
5448 /* compute bigger type and do implicit casts */
5449 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5451 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5456 /* floats can only be used for a few operations */
5457 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
5458 (op
< TOK_ULT
|| op
> TOK_GT
))
5459 error("invalid operands for binary operation");
5461 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5462 /* cast to biggest op */
5464 /* convert to unsigned if it does not fit in a long long */
5465 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5466 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5470 /* integer operations */
5472 /* convert to unsigned if it does not fit in an integer */
5473 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5474 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5477 /* XXX: currently, some unsigned operations are explicit, so
5478 we modify them here */
5479 if (t
& VT_UNSIGNED
) {
5486 else if (op
== TOK_LT
)
5488 else if (op
== TOK_GT
)
5490 else if (op
== TOK_LE
)
5492 else if (op
== TOK_GE
)
5499 /* special case for shifts and long long: we keep the shift as
5501 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
5506 else if ((t
& VT_BTYPE
) == VT_LLONG
)
5510 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5511 /* relationnal op: the result is an int */
5512 vtop
->type
.t
= VT_INT
;
5519 /* generic itof for unsigned long long case */
5520 void gen_cvt_itof1(int t
)
5522 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
5523 (VT_LLONG
| VT_UNSIGNED
)) {
5526 vpush_global_sym(&func_old_type
, TOK___ulltof
);
5527 else if (t
== VT_DOUBLE
)
5528 vpush_global_sym(&func_old_type
, TOK___ulltod
);
5530 vpush_global_sym(&func_old_type
, TOK___ulltold
);
5540 /* generic ftoi for unsigned long long case */
5541 void gen_cvt_ftoi1(int t
)
5545 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
5546 /* not handled natively */
5547 st
= vtop
->type
.t
& VT_BTYPE
;
5549 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
5550 else if (st
== VT_DOUBLE
)
5551 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
5553 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
5558 vtop
->r2
= REG_LRET
;
5564 /* force char or short cast */
5565 void force_charshort_cast(int t
)
5569 /* XXX: add optimization if lvalue : just change type and offset */
5574 if (t
& VT_UNSIGNED
) {
5575 vpushi((1 << bits
) - 1);
5586 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
5587 static void gen_cast(CType
*type
)
5589 int sbt
, dbt
, sf
, df
, c
;
5591 /* special delayed cast for char/short */
5592 /* XXX: in some cases (multiple cascaded casts), it may still
5594 if (vtop
->r
& VT_MUSTCAST
) {
5595 vtop
->r
&= ~VT_MUSTCAST
;
5596 force_charshort_cast(vtop
->type
.t
);
5599 /* bitfields first get cast to ints */
5600 if (vtop
->type
.t
& VT_BITFIELD
) {
5604 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
5605 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5607 if (sbt
!= dbt
&& !nocode_wanted
) {
5610 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5612 /* convert from fp to fp */
5614 /* constant case: we can do it now */
5615 /* XXX: in ISOC, cannot do it if error in convert */
5616 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
5617 vtop
->c
.f
= (float)vtop
->c
.d
;
5618 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
5619 vtop
->c
.f
= (float)vtop
->c
.ld
;
5620 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
5621 vtop
->c
.d
= (double)vtop
->c
.f
;
5622 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
5623 vtop
->c
.d
= (double)vtop
->c
.ld
;
5624 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
5625 vtop
->c
.ld
= (long double)vtop
->c
.f
;
5626 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
5627 vtop
->c
.ld
= (long double)vtop
->c
.d
;
5629 /* non constant case: generate code */
5633 /* convert int to fp */
5636 case VT_LLONG
| VT_UNSIGNED
:
5638 /* XXX: add const cases for long long */
5640 case VT_INT
| VT_UNSIGNED
:
5642 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
5643 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
5644 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
5649 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
5650 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
5651 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
5657 #if !defined(TCC_TARGET_ARM)
5664 /* convert fp to int */
5665 /* we handle char/short/etc... with generic code */
5666 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
5667 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
5672 case VT_LLONG
| VT_UNSIGNED
:
5674 /* XXX: add const cases for long long */
5676 case VT_INT
| VT_UNSIGNED
:
5678 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5679 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5680 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5686 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5687 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5688 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5696 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
5697 /* additional cast for char/short/bool... */
5701 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
5702 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
5703 /* scalar to long long */
5705 if (sbt
== (VT_INT
| VT_UNSIGNED
))
5706 vtop
->c
.ll
= vtop
->c
.ui
;
5708 vtop
->c
.ll
= vtop
->c
.i
;
5710 /* machine independent conversion */
5712 /* generate high word */
5713 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
5721 /* patch second register */
5722 vtop
[-1].r2
= vtop
->r
;
5726 } else if (dbt
== VT_BOOL
) {
5727 /* scalar to bool */
5730 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
5731 (dbt
& VT_BTYPE
) == VT_SHORT
) {
5732 force_charshort_cast(dbt
);
5733 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
5735 if (sbt
== VT_LLONG
) {
5736 /* from long long: just take low order word */
5740 /* if lvalue and single word type, nothing to do because
5741 the lvalue already contains the real type size (see
5742 VT_LVAL_xxx constants) */
5748 /* return type size. Put alignment at 'a' */
5749 static int type_size(CType
*type
, int *a
)
5754 bt
= type
->t
& VT_BTYPE
;
5755 if (bt
== VT_STRUCT
) {
5760 } else if (bt
== VT_PTR
) {
5761 if (type
->t
& VT_ARRAY
) {
5763 return type_size(&s
->type
, a
) * s
->c
;
5768 } else if (bt
== VT_LDOUBLE
) {
5770 return LDOUBLE_SIZE
;
5771 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
5772 #ifdef TCC_TARGET_I386
5778 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
5781 } else if (bt
== VT_SHORT
) {
5785 /* char, void, function, _Bool */
5791 /* return the pointed type of t */
5792 static inline CType
*pointed_type(CType
*type
)
5794 return &type
->ref
->type
;
5797 /* modify type so that its it is a pointer to type. */
5798 static void mk_pointer(CType
*type
)
5801 s
= sym_push(SYM_FIELD
, type
, 0, -1);
5802 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
5806 /* compare function types. OLD functions match any new functions */
5807 static int is_compatible_func(CType
*type1
, CType
*type2
)
5813 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5815 /* check func_call */
5818 /* XXX: not complete */
5819 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
5823 while (s1
!= NULL
) {
5826 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5836 /* return true if type1 and type2 are exactly the same (including
5839 - enums are not checked as gcc __builtin_types_compatible_p ()
5841 static int is_compatible_types(CType
*type1
, CType
*type2
)
5845 t1
= type1
->t
& VT_TYPE
;
5846 t2
= type2
->t
& VT_TYPE
;
5847 /* XXX: bitfields ? */
5850 /* test more complicated cases */
5851 bt1
= t1
& VT_BTYPE
;
5852 if (bt1
== VT_PTR
) {
5853 type1
= pointed_type(type1
);
5854 type2
= pointed_type(type2
);
5855 return is_compatible_types(type1
, type2
);
5856 } else if (bt1
== VT_STRUCT
) {
5857 return (type1
->ref
== type2
->ref
);
5858 } else if (bt1
== VT_FUNC
) {
5859 return is_compatible_func(type1
, type2
);
5865 /* print a type. If 'varstr' is not NULL, then the variable is also
5866 printed in the type */
5868 /* XXX: add array and function pointers */
5869 void type_to_str(char *buf
, int buf_size
,
5870 CType
*type
, const char *varstr
)
5877 t
= type
->t
& VT_TYPE
;
5880 if (t
& VT_CONSTANT
)
5881 pstrcat(buf
, buf_size
, "const ");
5882 if (t
& VT_VOLATILE
)
5883 pstrcat(buf
, buf_size
, "volatile ");
5884 if (t
& VT_UNSIGNED
)
5885 pstrcat(buf
, buf_size
, "unsigned ");
5915 tstr
= "long double";
5917 pstrcat(buf
, buf_size
, tstr
);
5921 if (bt
== VT_STRUCT
)
5925 pstrcat(buf
, buf_size
, tstr
);
5926 v
= type
->ref
->v
& ~SYM_STRUCT
;
5927 if (v
>= SYM_FIRST_ANOM
)
5928 pstrcat(buf
, buf_size
, "<anonymous>");
5930 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
5934 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
5935 pstrcat(buf
, buf_size
, "(");
5937 while (sa
!= NULL
) {
5938 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
5939 pstrcat(buf
, buf_size
, buf1
);
5942 pstrcat(buf
, buf_size
, ", ");
5944 pstrcat(buf
, buf_size
, ")");
5948 pstrcpy(buf1
, sizeof(buf1
), "*");
5950 pstrcat(buf1
, sizeof(buf1
), varstr
);
5951 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
5955 pstrcat(buf
, buf_size
, " ");
5956 pstrcat(buf
, buf_size
, varstr
);
5961 /* verify type compatibility to store vtop in 'dt' type, and generate
5963 static void gen_assign_cast(CType
*dt
)
5965 CType
*st
, *type1
, *type2
, tmp_type1
, tmp_type2
;
5966 char buf1
[256], buf2
[256];
5969 st
= &vtop
->type
; /* source type */
5970 dbt
= dt
->t
& VT_BTYPE
;
5971 sbt
= st
->t
& VT_BTYPE
;
5972 if (dt
->t
& VT_CONSTANT
)
5973 warning("assignment of read-only location");
5976 /* special cases for pointers */
5977 /* '0' can also be a pointer */
5978 if (is_null_pointer(vtop
))
5980 /* accept implicit pointer to integer cast with warning */
5981 if (is_integer_btype(sbt
)) {
5982 warning("assignment makes pointer from integer without a cast");
5985 type1
= pointed_type(dt
);
5986 /* a function is implicitely a function pointer */
5987 if (sbt
== VT_FUNC
) {
5988 if ((type1
->t
& VT_BTYPE
) != VT_VOID
&&
5989 !is_compatible_types(pointed_type(dt
), st
))
5996 type2
= pointed_type(st
);
5997 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
5998 (type2
->t
& VT_BTYPE
) == VT_VOID
) {
5999 /* void * can match anything */
6001 /* exact type match, except for unsigned */
6004 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
6005 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
6006 if (!is_compatible_types(&tmp_type1
, &tmp_type2
))
6009 /* check const and volatile */
6010 if ((!(type1
->t
& VT_CONSTANT
) && (type2
->t
& VT_CONSTANT
)) ||
6011 (!(type1
->t
& VT_VOLATILE
) && (type2
->t
& VT_VOLATILE
)))
6012 warning("assignment discards qualifiers from pointer target type");
6018 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
6019 warning("assignment makes integer from pointer without a cast");
6021 /* XXX: more tests */
6026 tmp_type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6027 tmp_type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6028 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
6030 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
6031 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
6032 error("cannot cast '%s' to '%s'", buf1
, buf2
);
6040 /* store vtop in lvalue pushed on stack */
6043 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
6045 ft
= vtop
[-1].type
.t
;
6046 sbt
= vtop
->type
.t
& VT_BTYPE
;
6047 dbt
= ft
& VT_BTYPE
;
6048 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
6049 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
6050 /* optimize char/short casts */
6051 delayed_cast
= VT_MUSTCAST
;
6052 vtop
->type
.t
= ft
& VT_TYPE
;
6053 /* XXX: factorize */
6054 if (ft
& VT_CONSTANT
)
6055 warning("assignment of read-only location");
6058 if (!(ft
& VT_BITFIELD
))
6059 gen_assign_cast(&vtop
[-1].type
);
6062 if (sbt
== VT_STRUCT
) {
6063 /* if structure, only generate pointer */
6064 /* structure assignment : generate memcpy */
6065 /* XXX: optimize if small size */
6066 if (!nocode_wanted
) {
6067 size
= type_size(&vtop
->type
, &align
);
6069 vpush_global_sym(&func_old_type
, TOK_memcpy
);
6073 vtop
->type
.t
= VT_INT
;
6077 vtop
->type
.t
= VT_INT
;
6089 /* leave source on stack */
6090 } else if (ft
& VT_BITFIELD
) {
6091 /* bitfield store handling */
6092 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
6093 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
6094 /* remove bit field info to avoid loops */
6095 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
6097 /* duplicate destination */
6099 vtop
[-1] = vtop
[-2];
6101 /* mask and shift source */
6102 vpushi((1 << bit_size
) - 1);
6106 /* load destination, mask and or with source */
6108 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
6114 #ifdef CONFIG_TCC_BCHECK
6115 /* bound check case */
6116 if (vtop
[-1].r
& VT_MUSTBOUND
) {
6122 if (!nocode_wanted
) {
6126 r
= gv(rc
); /* generate value */
6127 /* if lvalue was saved on stack, must read it */
6128 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
6130 t
= get_reg(RC_INT
);
6132 sv
.r
= VT_LOCAL
| VT_LVAL
;
6133 sv
.c
.ul
= vtop
[-1].c
.ul
;
6135 vtop
[-1].r
= t
| VT_LVAL
;
6138 /* two word case handling : store second register at word + 4 */
6139 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
6141 /* convert to int to increment easily */
6142 vtop
->type
.t
= VT_INT
;
6148 /* XXX: it works because r2 is spilled last ! */
6149 store(vtop
->r2
, vtop
- 1);
6153 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6154 vtop
->r
|= delayed_cast
;
6158 /* post defines POST/PRE add. c is the token ++ or -- */
6159 void inc(int post
, int c
)
6162 vdup(); /* save lvalue */
6164 gv_dup(); /* duplicate value */
6169 vpushi(c
- TOK_MID
);
6171 vstore(); /* store value */
6173 vpop(); /* if post op, return saved value */
6176 /* Parse GNUC __attribute__ extension. Currently, the following
6177 extensions are recognized:
6178 - aligned(n) : set data/function alignment.
6179 - packed : force data alignment to 1
6180 - section(x) : generate data/code in this section.
6181 - unused : currently ignored, but may be used someday.
6182 - regparm(n) : pass function parameters in registers (i386 only)
6184 static void parse_attribute(AttributeDef
*ad
)
6188 while (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
6192 while (tok
!= ')') {
6193 if (tok
< TOK_IDENT
)
6194 expect("attribute name");
6202 expect("section name");
6203 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
6212 if (n
<= 0 || (n
& (n
- 1)) != 0)
6213 error("alignment must be a positive power of two");
6226 /* currently, no need to handle it because tcc does not
6227 track unused objects */
6231 /* currently, no need to handle it because tcc does not
6232 track unused objects */
6237 ad
->func_call
= FUNC_CDECL
;
6242 ad
->func_call
= FUNC_STDCALL
;
6244 #ifdef TCC_TARGET_I386
6254 ad
->func_call
= FUNC_FASTCALL1
+ n
- 1;
6259 if (tcc_state
->warn_unsupported
)
6260 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
6261 /* skip parameters */
6262 /* XXX: skip parenthesis too */
6265 while (tok
!= ')' && tok
!= -1)
6280 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
6281 static void struct_decl(CType
*type
, int u
)
6283 int a
, v
, size
, align
, maxalign
, c
, offset
;
6284 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
6289 a
= tok
; /* save decl type */
6294 /* struct already defined ? return it */
6296 expect("struct/union/enum name");
6300 error("invalid type");
6307 /* we put an undefined size for struct/union */
6308 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
6309 s
->r
= 0; /* default alignment is zero as gcc */
6310 /* put struct/union/enum name in type */
6318 error("struct/union/enum already defined");
6319 /* cannot be empty */
6321 /* non empty enums are not allowed */
6322 if (a
== TOK_ENUM
) {
6326 expect("identifier");
6332 /* enum symbols have static storage */
6333 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
6334 ss
->type
.t
|= VT_STATIC
;
6339 /* NOTE: we accept a trailing comma */
6349 while (tok
!= '}') {
6350 parse_btype(&btype
, &ad
);
6356 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
);
6357 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
6358 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
| VT_INLINE
)))
6359 error("invalid type for '%s'",
6360 get_tok_str(v
, NULL
));
6364 bit_size
= expr_const();
6365 /* XXX: handle v = 0 case for messages */
6367 error("negative width in bit-field '%s'",
6368 get_tok_str(v
, NULL
));
6369 if (v
&& bit_size
== 0)
6370 error("zero width for bit-field '%s'",
6371 get_tok_str(v
, NULL
));
6373 size
= type_size(&type1
, &align
);
6375 if (align
< ad
.aligned
)
6377 } else if (ad
.packed
) {
6381 if (bit_size
>= 0) {
6382 bt
= type1
.t
& VT_BTYPE
;
6388 error("bitfields must have scalar type");
6390 if (bit_size
> bsize
) {
6391 error("width of '%s' exceeds its type",
6392 get_tok_str(v
, NULL
));
6393 } else if (bit_size
== bsize
) {
6394 /* no need for bit fields */
6396 } else if (bit_size
== 0) {
6397 /* XXX: what to do if only padding in a
6399 /* zero size: means to pad */
6403 /* we do not have enough room ? */
6404 if ((bit_pos
+ bit_size
) > bsize
)
6407 /* XXX: handle LSB first */
6408 type1
.t
|= VT_BITFIELD
|
6409 (bit_pos
<< VT_STRUCT_SHIFT
) |
6410 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
6411 bit_pos
+= bit_size
;
6417 /* add new memory data only if starting
6419 if (lbit_pos
== 0) {
6420 if (a
== TOK_STRUCT
) {
6421 c
= (c
+ align
- 1) & -align
;
6429 if (align
> maxalign
)
6433 printf("add field %s offset=%d",
6434 get_tok_str(v
, NULL
), offset
);
6435 if (type1
.t
& VT_BITFIELD
) {
6436 printf(" pos=%d size=%d",
6437 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
6438 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
6442 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
6446 if (tok
== ';' || tok
== TOK_EOF
)
6453 /* store size and alignment */
6454 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
6460 /* return 0 if no type declaration. otherwise, return the basic type
6463 static int parse_btype(CType
*type
, AttributeDef
*ad
)
6465 int t
, u
, type_found
, typespec_found
;
6469 memset(ad
, 0, sizeof(AttributeDef
));
6476 /* currently, we really ignore extension */
6486 if ((t
& VT_BTYPE
) != 0)
6487 error("too many basic types");
6503 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
6504 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6505 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
6506 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
6520 if ((t
& VT_BTYPE
) == VT_LONG
) {
6521 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6528 struct_decl(&type1
, VT_ENUM
);
6531 type
->ref
= type1
.ref
;
6535 struct_decl(&type1
, VT_STRUCT
);
6538 /* type modifiers */
6591 /* GNUC attribute */
6592 case TOK_ATTRIBUTE1
:
6593 case TOK_ATTRIBUTE2
:
6594 parse_attribute(ad
);
6601 parse_expr_type(&type1
);
6607 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
6609 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
6610 type
->ref
= s
->type
.ref
;
6617 if ((t
& (VT_SIGNED
|VT_UNSIGNED
)) == (VT_SIGNED
|VT_UNSIGNED
))
6618 error("signed and unsigned modifier");
6619 if (tcc_state
->char_is_unsigned
) {
6620 if ((t
& (VT_SIGNED
|VT_UNSIGNED
|VT_BTYPE
)) == VT_BYTE
)
6625 /* long is never used as type */
6626 if ((t
& VT_BTYPE
) == VT_LONG
)
6627 t
= (t
& ~VT_BTYPE
) | VT_INT
;
6632 /* convert a function parameter type (array to pointer and function to
6633 function pointer) */
6634 static inline void convert_parameter_type(CType
*pt
)
6636 /* remove const and volatile qualifiers (XXX: const could be used
6637 to indicate a const function parameter */
6638 pt
->t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6639 /* array must be transformed to pointer according to ANSI C */
6641 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
6646 static void post_type(CType
*type
, AttributeDef
*ad
)
6649 Sym
**plast
, *s
, *first
;
6654 /* function declaration */
6659 while (tok
!= ')') {
6660 /* read param name and compute offset */
6661 if (l
!= FUNC_OLD
) {
6662 if (!parse_btype(&pt
, &ad1
)) {
6664 error("invalid type");
6671 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
6673 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
6674 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
6675 error("parameter declared as void");
6682 convert_parameter_type(&pt
);
6683 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
6688 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
6695 /* if no parameters, then old type prototype */
6699 t1
= type
->t
& VT_STORAGE
;
6700 /* NOTE: const is ignored in returned type as it has a special
6701 meaning in gcc / C++ */
6702 type
->t
&= ~(VT_STORAGE
| VT_CONSTANT
);
6703 post_type(type
, ad
);
6704 /* we push a anonymous symbol which will contain the function prototype */
6705 s
= sym_push(SYM_FIELD
, type
, ad
->func_call
, l
);
6707 type
->t
= t1
| VT_FUNC
;
6709 } else if (tok
== '[') {
6710 /* array definition */
6716 error("invalid array size");
6719 /* parse next post type */
6720 t1
= type
->t
& VT_STORAGE
;
6721 type
->t
&= ~VT_STORAGE
;
6722 post_type(type
, ad
);
6724 /* we push a anonymous symbol which will contain the array
6726 s
= sym_push(SYM_FIELD
, type
, 0, n
);
6727 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
6732 /* Parse a type declaration (except basic type), and return the type
6733 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6734 expected. 'type' should contain the basic type. 'ad' is the
6735 attribute definition of the basic type. It can be modified by
6738 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
6741 CType type1
, *type2
;
6744 while (tok
== '*') {
6752 qualifiers
|= VT_CONSTANT
;
6757 qualifiers
|= VT_VOLATILE
;
6765 type
->t
|= qualifiers
;
6768 /* XXX: clarify attribute handling */
6769 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6770 parse_attribute(ad
);
6772 /* recursive type */
6773 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6774 type1
.t
= 0; /* XXX: same as int */
6777 /* XXX: this is not correct to modify 'ad' at this point, but
6778 the syntax is not clear */
6779 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6780 parse_attribute(ad
);
6781 type_decl(&type1
, ad
, v
, td
);
6784 /* type identifier */
6785 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
6789 if (!(td
& TYPE_ABSTRACT
))
6790 expect("identifier");
6794 post_type(type
, ad
);
6795 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6796 parse_attribute(ad
);
6799 /* append type at the end of type1 */
6812 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6813 static int lvalue_type(int t
)
6818 if (bt
== VT_BYTE
|| bt
== VT_BOOL
)
6820 else if (bt
== VT_SHORT
)
6824 if (t
& VT_UNSIGNED
)
6825 r
|= VT_LVAL_UNSIGNED
;
6829 /* indirection with full error checking and bound check */
6830 static void indir(void)
6832 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
6834 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
6836 vtop
->type
= *pointed_type(&vtop
->type
);
6837 /* an array is never an lvalue */
6838 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6839 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6840 /* if bound checking, the referenced pointer must be checked */
6841 if (do_bounds_check
)
6842 vtop
->r
|= VT_MUSTBOUND
;
6846 /* pass a parameter to a function and do type checking and casting */
6847 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
6852 func_type
= func
->c
;
6853 if (func_type
== FUNC_OLD
||
6854 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
6855 /* default casting : only need to convert float to double */
6856 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
6860 } else if (arg
== NULL
) {
6861 error("too many arguments to function");
6864 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
6865 gen_assign_cast(&type
);
6869 /* parse an expression of the form '(type)' or '(expr)' and return its
6871 static void parse_expr_type(CType
*type
)
6877 if (parse_btype(type
, &ad
)) {
6878 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
6885 static void parse_type(CType
*type
)
6890 if (!parse_btype(type
, &ad
)) {
6893 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
6896 static void vpush_tokc(int t
)
6900 vsetc(&type
, VT_CONST
, &tokc
);
6903 static void unary(void)
6905 int n
, t
, align
, size
, r
;
6910 /* XXX: GCC 2.95.3 does not generate a table although it should be
6924 vpush_tokc(VT_INT
| VT_UNSIGNED
);
6928 vpush_tokc(VT_LLONG
);
6932 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
6936 vpush_tokc(VT_FLOAT
);
6940 vpush_tokc(VT_DOUBLE
);
6944 vpush_tokc(VT_LDOUBLE
);
6947 case TOK___FUNCTION__
:
6949 goto tok_identifier
;
6955 /* special function name identifier */
6956 len
= strlen(funcname
) + 1;
6957 /* generate char[len] type */
6962 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
6963 ptr
= section_ptr_add(data_section
, len
);
6964 memcpy(ptr
, funcname
, len
);
6972 /* string parsing */
6975 if (tcc_state
->warn_write_strings
)
6980 memset(&ad
, 0, sizeof(AttributeDef
));
6981 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
6986 if (parse_btype(&type
, &ad
)) {
6987 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
6989 /* check ISOC99 compound literal */
6991 /* data is allocated locally by default */
6996 /* all except arrays are lvalues */
6997 if (!(type
.t
& VT_ARRAY
))
6998 r
|= lvalue_type(type
.t
);
6999 memset(&ad
, 0, sizeof(AttributeDef
));
7000 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
7005 } else if (tok
== '{') {
7006 /* save all registers */
7008 /* statement expression : we do not accept break/continue
7009 inside as GCC does */
7010 block(NULL
, NULL
, NULL
, NULL
, 0, 1);
7025 /* functions names must be treated as function pointers,
7026 except for unary '&' and sizeof. Since we consider that
7027 functions are not lvalues, we only have to handle it
7028 there and in function calls. */
7029 /* arrays can also be used although they are not lvalues */
7030 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
7031 !(vtop
->type
.t
& VT_ARRAY
))
7033 mk_pointer(&vtop
->type
);
7039 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
7040 vtop
->c
.i
= !vtop
->c
.i
;
7041 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
7042 vtop
->c
.i
= vtop
->c
.i
^ 1;
7044 vseti(VT_JMP
, gtst(1, 0));
7054 /* in order to force cast, we add zero */
7056 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
7057 error("pointer not accepted for unary plus");
7067 parse_expr_type(&type
);
7071 size
= type_size(&type
, &align
);
7072 if (t
== TOK_SIZEOF
) {
7074 error("sizeof applied to an incomplete type");
7081 case TOK_builtin_types_compatible_p
:
7090 type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7091 type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7092 vpushi(is_compatible_types(&type1
, &type2
));
7095 case TOK_builtin_constant_p
:
7097 int saved_nocode_wanted
, res
;
7100 saved_nocode_wanted
= nocode_wanted
;
7103 res
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
7105 nocode_wanted
= saved_nocode_wanted
;
7125 goto tok_identifier
;
7127 /* allow to take the address of a label */
7128 if (tok
< TOK_UIDENT
)
7129 expect("label identifier");
7130 s
= label_find(tok
);
7132 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7134 if (s
->r
== LABEL_DECLARED
)
7135 s
->r
= LABEL_FORWARD
;
7138 s
->type
.t
= VT_VOID
;
7139 mk_pointer(&s
->type
);
7140 s
->type
.t
|= VT_STATIC
;
7142 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
7151 expect("identifier");
7155 error("'%s' undeclared", get_tok_str(t
, NULL
));
7156 /* for simple function calls, we tolerate undeclared
7157 external reference to int() function */
7158 if (tcc_state
->warn_implicit_function_declaration
)
7159 warning("implicit declaration of function '%s'",
7160 get_tok_str(t
, NULL
));
7161 s
= external_global_sym(t
, &func_old_type
, 0);
7163 if ((s
->type
.t
& (VT_STATIC
| VT_INLINE
| VT_BTYPE
)) ==
7164 (VT_STATIC
| VT_INLINE
| VT_FUNC
)) {
7165 /* if referencing an inline function, then we generate a
7166 symbol to it if not already done. It will have the
7167 effect to generate code for it at the end of the
7168 compilation unit. Inline function as always
7169 generated in the text section. */
7171 put_extern_sym(s
, text_section
, 0, 0);
7172 r
= VT_SYM
| VT_CONST
;
7176 vset(&s
->type
, r
, s
->c
);
7177 /* if forward reference, we must point to s */
7178 if (vtop
->r
& VT_SYM
) {
7185 /* post operations */
7187 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
7190 } else if (tok
== '.' || tok
== TOK_ARROW
) {
7192 if (tok
== TOK_ARROW
)
7197 /* expect pointer on structure */
7198 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
7199 expect("struct or union");
7203 while ((s
= s
->next
) != NULL
) {
7208 error("field not found");
7209 /* add field offset to pointer */
7210 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
7213 /* change type to field type, and set to lvalue */
7214 vtop
->type
= s
->type
;
7215 /* an array is never an lvalue */
7216 if (!(vtop
->type
.t
& VT_ARRAY
)) {
7217 vtop
->r
|= lvalue_type(vtop
->type
.t
);
7218 /* if bound checking, the referenced pointer must be checked */
7219 if (do_bounds_check
)
7220 vtop
->r
|= VT_MUSTBOUND
;
7223 } else if (tok
== '[') {
7229 } else if (tok
== '(') {
7235 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
7236 /* pointer test (no array accepted) */
7237 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
7238 vtop
->type
= *pointed_type(&vtop
->type
);
7239 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
7243 expect("function pointer");
7246 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
7248 /* get return type */
7251 sa
= s
->next
; /* first parameter */
7253 /* compute first implicit argument if a structure is returned */
7254 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
7255 /* get some space for the returned structure */
7256 size
= type_size(&s
->type
, &align
);
7257 loc
= (loc
- size
) & -align
;
7259 ret
.r
= VT_LOCAL
| VT_LVAL
;
7260 /* pass it as 'int' to avoid structure arg passing
7262 vseti(VT_LOCAL
, loc
);
7268 /* return in register */
7269 if (is_float(ret
.type
.t
)) {
7272 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
7281 gfunc_param_typed(s
, sa
);
7291 error("too few arguments to function");
7293 if (!nocode_wanted
) {
7294 gfunc_call(nb_args
);
7296 vtop
-= (nb_args
+ 1);
7299 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
7307 static void uneq(void)
7313 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
7314 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
7315 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
7330 static void expr_prod(void)
7335 while (tok
== '*' || tok
== '/' || tok
== '%') {
7343 static void expr_sum(void)
7348 while (tok
== '+' || tok
== '-') {
7356 static void expr_shift(void)
7361 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
7369 static void expr_cmp(void)
7374 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
7375 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
7383 static void expr_cmpeq(void)
7388 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
7396 static void expr_and(void)
7399 while (tok
== '&') {
7406 static void expr_xor(void)
7409 while (tok
== '^') {
7416 static void expr_or(void)
7419 while (tok
== '|') {
7426 /* XXX: fix this mess */
7427 static void expr_land_const(void)
7430 while (tok
== TOK_LAND
) {
7437 /* XXX: fix this mess */
7438 static void expr_lor_const(void)
7441 while (tok
== TOK_LOR
) {
7448 /* only used if non constant */
7449 static void expr_land(void)
7454 if (tok
== TOK_LAND
) {
7458 if (tok
!= TOK_LAND
) {
7468 static void expr_lor(void)
7473 if (tok
== TOK_LOR
) {
7477 if (tok
!= TOK_LOR
) {
7487 /* XXX: better constant handling */
7488 static void expr_eq(void)
7490 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
7492 CType type
, type1
, type2
;
7501 if (tok
== ':' && gnu_ext
) {
7517 if (vtop
!= vstack
) {
7518 /* needed to avoid having different registers saved in
7520 if (is_float(vtop
->type
.t
))
7527 if (tok
== ':' && gnu_ext
) {
7535 sv
= *vtop
; /* save value to handle it later */
7536 vtop
--; /* no vpop so that FP stack is not flushed */
7544 bt1
= t1
& VT_BTYPE
;
7546 bt2
= t2
& VT_BTYPE
;
7547 /* cast operands to correct type according to ISOC rules */
7548 if (is_float(bt1
) || is_float(bt2
)) {
7549 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
7550 type
.t
= VT_LDOUBLE
;
7551 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
7556 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
7557 /* cast to biggest op */
7559 /* convert to unsigned if it does not fit in a long long */
7560 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
7561 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
7562 type
.t
|= VT_UNSIGNED
;
7563 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
7564 /* XXX: test pointer compatibility */
7566 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
7567 /* XXX: test structure compatibility */
7569 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
7570 /* NOTE: as an extension, we accept void on only one side */
7573 /* integer operations */
7575 /* convert to unsigned if it does not fit in an integer */
7576 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
7577 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
7578 type
.t
|= VT_UNSIGNED
;
7581 /* now we convert second operand */
7584 if (is_float(type
.t
)) {
7586 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
7587 /* for long longs, we use fixed registers to avoid having
7588 to handle a complicated move */
7593 /* this is horrible, but we must also convert first
7597 /* put again first value and cast it */
7608 static void gexpr(void)
7619 /* parse an expression and return its type without any side effect. */
7620 static void expr_type(CType
*type
)
7622 int saved_nocode_wanted
;
7624 saved_nocode_wanted
= nocode_wanted
;
7629 nocode_wanted
= saved_nocode_wanted
;
7632 /* parse a unary expression and return its type without any side
7634 static void unary_type(CType
*type
)
7646 /* parse a constant expression and return value in vtop. */
7647 static void expr_const1(void)
7656 /* parse an integer constant and return its value. */
7657 static int expr_const(void)
7661 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
7662 expect("constant expression");
7668 /* return the label token if current token is a label, otherwise
7670 static int is_label(void)
7674 /* fast test first */
7675 if (tok
< TOK_UIDENT
)
7677 /* no need to save tokc because tok is an identifier */
7684 unget_tok(last_tok
);
7689 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
7690 int case_reg
, int is_expr
)
7695 /* generate line number info */
7697 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
7698 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
7700 last_line_num
= file
->line_num
;
7704 /* default return value is (void) */
7706 vtop
->type
.t
= VT_VOID
;
7709 if (tok
== TOK_IF
) {
7716 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7718 if (c
== TOK_ELSE
) {
7722 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7723 gsym(d
); /* patch else jmp */
7726 } else if (tok
== TOK_WHILE
) {
7734 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7738 } else if (tok
== '{') {
7742 /* record local declaration stack position */
7744 llabel
= local_label_stack
;
7745 /* handle local labels declarations */
7746 if (tok
== TOK_LABEL
) {
7749 if (tok
< TOK_UIDENT
)
7750 expect("label identifier");
7751 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
7761 while (tok
!= '}') {
7766 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
7769 /* pop locally defined labels */
7770 label_pop(&local_label_stack
, llabel
);
7771 /* pop locally defined symbols */
7772 sym_pop(&local_stack
, s
);
7774 } else if (tok
== TOK_RETURN
) {
7778 gen_assign_cast(&func_vt
);
7779 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
7781 /* if returning structure, must copy it to implicit
7782 first pointer arg location */
7785 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
7788 /* copy structure value to pointer */
7790 } else if (is_float(func_vt
.t
)) {
7795 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
7798 rsym
= gjmp(rsym
); /* jmp */
7799 } else if (tok
== TOK_BREAK
) {
7802 error("cannot break");
7803 *bsym
= gjmp(*bsym
);
7806 } else if (tok
== TOK_CONTINUE
) {
7809 error("cannot continue");
7810 *csym
= gjmp(*csym
);
7813 } else if (tok
== TOK_FOR
) {
7840 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7845 if (tok
== TOK_DO
) {
7850 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7861 if (tok
== TOK_SWITCH
) {
7865 /* XXX: other types than integer */
7866 case_reg
= gv(RC_INT
);
7870 b
= gjmp(0); /* jump to first case */
7872 block(&a
, csym
, &b
, &c
, case_reg
, 0);
7873 /* if no default, jmp after switch */
7881 if (tok
== TOK_CASE
) {
7888 if (gnu_ext
&& tok
== TOK_DOTS
) {
7892 warning("empty case range");
7894 /* since a case is like a label, we must skip it with a jmp */
7901 *case_sym
= gtst(1, 0);
7904 *case_sym
= gtst(1, 0);
7908 *case_sym
= gtst(1, *case_sym
);
7913 goto block_after_label
;
7915 if (tok
== TOK_DEFAULT
) {
7921 error("too many 'default'");
7924 goto block_after_label
;
7926 if (tok
== TOK_GOTO
) {
7928 if (tok
== '*' && gnu_ext
) {
7932 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
7935 } else if (tok
>= TOK_UIDENT
) {
7936 s
= label_find(tok
);
7937 /* put forward definition if needed */
7939 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7941 if (s
->r
== LABEL_DECLARED
)
7942 s
->r
= LABEL_FORWARD
;
7944 /* label already defined */
7945 if (s
->r
& LABEL_FORWARD
)
7946 s
->next
= (void *)gjmp((long)s
->next
);
7948 gjmp_addr((long)s
->next
);
7951 expect("label identifier");
7954 } else if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
7962 if (s
->r
== LABEL_DEFINED
)
7963 error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
7964 gsym((long)s
->next
);
7965 s
->r
= LABEL_DEFINED
;
7967 s
= label_push(&global_label_stack
, b
, LABEL_DEFINED
);
7969 s
->next
= (void *)ind
;
7970 /* we accept this, but it is a mistake */
7973 warning("deprecated use of label at end of compound statement");
7977 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
7980 /* expression case */
7995 /* t is the array or struct type. c is the array or struct
7996 address. cur_index/cur_field is the pointer to the current
7997 value. 'size_only' is true if only size info is needed (only used
7999 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
8000 int *cur_index
, Sym
**cur_field
,
8004 int notfirst
, index
, index_last
, align
, l
, nb_elems
, elem_size
;
8010 if (gnu_ext
&& (l
= is_label()) != 0)
8012 while (tok
== '[' || tok
== '.') {
8014 if (!(type
->t
& VT_ARRAY
))
8015 expect("array type");
8018 index
= expr_const();
8019 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
8020 expect("invalid index");
8021 if (tok
== TOK_DOTS
&& gnu_ext
) {
8023 index_last
= expr_const();
8024 if (index_last
< 0 ||
8025 (s
->c
>= 0 && index_last
>= s
->c
) ||
8027 expect("invalid index");
8033 *cur_index
= index_last
;
8034 type
= pointed_type(type
);
8035 elem_size
= type_size(type
, &align
);
8036 c
+= index
* elem_size
;
8037 /* NOTE: we only support ranges for last designator */
8038 nb_elems
= index_last
- index
+ 1;
8039 if (nb_elems
!= 1) {
8048 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
8049 expect("struct/union type");
8062 /* XXX: fix this mess by using explicit storage field */
8064 type1
.t
|= (type
->t
& ~VT_TYPE
);
8078 if (type
->t
& VT_ARRAY
) {
8080 type
= pointed_type(type
);
8081 c
+= index
* type_size(type
, &align
);
8085 error("too many field init");
8086 /* XXX: fix this mess by using explicit storage field */
8088 type1
.t
|= (type
->t
& ~VT_TYPE
);
8093 decl_initializer(type
, sec
, c
, 0, size_only
);
8095 /* XXX: make it more general */
8096 if (!size_only
&& nb_elems
> 1) {
8097 unsigned long c_end
;
8102 error("range init not supported yet for dynamic storage");
8103 c_end
= c
+ nb_elems
* elem_size
;
8104 if (c_end
> sec
->data_allocated
)
8105 section_realloc(sec
, c_end
);
8106 src
= sec
->data
+ c
;
8108 for(i
= 1; i
< nb_elems
; i
++) {
8110 memcpy(dst
, src
, elem_size
);
8116 #define EXPR_CONST 1
8119 /* store a value or an expression directly in global data or in local array */
8120 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
8121 int v
, int expr_type
)
8123 int saved_global_expr
, bt
, bit_pos
, bit_size
;
8125 unsigned long long bit_mask
;
8133 /* compound literals must be allocated globally in this case */
8134 saved_global_expr
= global_expr
;
8137 global_expr
= saved_global_expr
;
8138 /* NOTE: symbols are accepted */
8139 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
8140 error("initializer element is not constant");
8148 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
8151 /* XXX: not portable */
8152 /* XXX: generate error if incorrect relocation */
8153 gen_assign_cast(&dtype
);
8154 bt
= type
->t
& VT_BTYPE
;
8155 ptr
= sec
->data
+ c
;
8156 /* XXX: make code faster ? */
8157 if (!(type
->t
& VT_BITFIELD
)) {
8162 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
8163 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
8164 bit_mask
= (1LL << bit_size
) - 1;
8166 if ((vtop
->r
& VT_SYM
) &&
8172 (bt
== VT_INT
&& bit_size
!= 32)))
8173 error("initializer element is not computable at load time");
8176 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8179 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8182 *(double *)ptr
= vtop
->c
.d
;
8185 *(long double *)ptr
= vtop
->c
.ld
;
8188 *(long long *)ptr
|= (vtop
->c
.ll
& bit_mask
) << bit_pos
;
8191 if (vtop
->r
& VT_SYM
) {
8192 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
8194 *(int *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8199 vset(&dtype
, VT_LOCAL
, c
);
8206 /* put zeros for variable based init */
8207 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
8210 /* nothing to do because globals are already set to zero */
8212 vpush_global_sym(&func_old_type
, TOK_memset
);
8220 /* 't' contains the type and storage info. 'c' is the offset of the
8221 object in section 'sec'. If 'sec' is NULL, it means stack based
8222 allocation. 'first' is true if array '{' must be read (multi
8223 dimension implicit array init handling). 'size_only' is true if
8224 size only evaluation is wanted (only for arrays). */
8225 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
8226 int first
, int size_only
)
8228 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
8229 int size1
, align1
, expr_type
;
8233 if (type
->t
& VT_ARRAY
) {
8237 t1
= pointed_type(type
);
8238 size1
= type_size(t1
, &align1
);
8241 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
8247 /* only parse strings here if correct type (otherwise: handle
8248 them as ((w)char *) expressions */
8249 if ((tok
== TOK_LSTR
&&
8250 (t1
->t
& VT_BTYPE
) == VT_INT
) ||
8252 (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
8253 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8258 /* compute maximum number of chars wanted */
8260 cstr_len
= cstr
->size
;
8262 cstr_len
= cstr
->size
/ sizeof(int);
8265 if (n
>= 0 && nb
> (n
- array_length
))
8266 nb
= n
- array_length
;
8269 warning("initializer-string for array is too long");
8270 /* in order to go faster for common case (char
8271 string in global variable, we handle it
8273 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
8274 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
8278 ch
= ((unsigned char *)cstr
->data
)[i
];
8280 ch
= ((int *)cstr
->data
)[i
];
8281 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
8289 /* only add trailing zero if enough storage (no
8290 warning in this case since it is standard) */
8291 if (n
< 0 || array_length
< n
) {
8293 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
8299 while (tok
!= '}') {
8300 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
8301 if (n
>= 0 && index
>= n
)
8302 error("index too large");
8303 /* must put zero in holes (note that doing it that way
8304 ensures that it even works with designators) */
8305 if (!size_only
&& array_length
< index
) {
8306 init_putz(t1
, sec
, c
+ array_length
* size1
,
8307 (index
- array_length
) * size1
);
8310 if (index
> array_length
)
8311 array_length
= index
;
8312 /* special test for multi dimensional arrays (may not
8313 be strictly correct if designators are used at the
8315 if (index
>= n
&& no_oblock
)
8324 /* put zeros at the end */
8325 if (!size_only
&& n
>= 0 && array_length
< n
) {
8326 init_putz(t1
, sec
, c
+ array_length
* size1
,
8327 (n
- array_length
) * size1
);
8329 /* patch type size if needed */
8331 s
->c
= array_length
;
8332 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
8333 (sec
|| !first
|| tok
== '{')) {
8336 /* NOTE: the previous test is a specific case for automatic
8337 struct/union init */
8338 /* XXX: union needs only one init */
8340 /* XXX: this test is incorrect for local initializers
8341 beginning with ( without {. It would be much more difficult
8342 to do it correctly (ideally, the expression parser should
8343 be used in all cases) */
8349 while (tok
== '(') {
8353 if (!parse_btype(&type1
, &ad1
))
8355 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
8357 if (!is_assignable_types(type
, &type1
))
8358 error("invalid type for cast");
8363 if (first
|| tok
== '{') {
8372 while (tok
!= '}') {
8373 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
8375 if (!size_only
&& array_length
< index
) {
8376 init_putz(type
, sec
, c
+ array_length
,
8377 index
- array_length
);
8379 index
= index
+ type_size(&f
->type
, &align1
);
8380 if (index
> array_length
)
8381 array_length
= index
;
8383 if (no_oblock
&& f
== NULL
)
8389 /* put zeros at the end */
8390 if (!size_only
&& array_length
< n
) {
8391 init_putz(type
, sec
, c
+ array_length
,
8400 } else if (tok
== '{') {
8402 decl_initializer(type
, sec
, c
, first
, size_only
);
8404 } else if (size_only
) {
8405 /* just skip expression */
8407 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
8411 else if (tok
== ')')
8416 /* currently, we always use constant expression for globals
8417 (may change for scripting case) */
8418 expr_type
= EXPR_CONST
;
8420 expr_type
= EXPR_ANY
;
8421 init_putv(type
, sec
, c
, 0, expr_type
);
8425 /* parse an initializer for type 't' if 'has_init' is non zero, and
8426 allocate space in local or global data space ('r' is either
8427 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8428 variable 'v' of scope 'scope' is declared before initializers are
8429 parsed. If 'v' is zero, then a reference to the new object is put
8430 in the value stack. If 'has_init' is 2, a special parsing is done
8431 to handle string constants. */
8432 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
8433 int has_init
, int v
, int scope
)
8435 int size
, align
, addr
, data_offset
;
8437 ParseState saved_parse_state
;
8438 TokenString init_str
;
8441 size
= type_size(type
, &align
);
8442 /* If unknown size, we must evaluate it before
8443 evaluating initializers because
8444 initializers can generate global data too
8445 (e.g. string pointers or ISOC99 compound
8446 literals). It also simplifies local
8447 initializers handling */
8448 tok_str_new(&init_str
);
8451 error("unknown type size");
8452 /* get all init string */
8453 if (has_init
== 2) {
8454 /* only get strings */
8455 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8456 tok_str_add_tok(&init_str
);
8461 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
8463 error("unexpected end of file in initializer");
8464 tok_str_add_tok(&init_str
);
8467 else if (tok
== '}') {
8475 tok_str_add(&init_str
, -1);
8476 tok_str_add(&init_str
, 0);
8479 save_parse_state(&saved_parse_state
);
8481 macro_ptr
= init_str
.str
;
8483 decl_initializer(type
, NULL
, 0, 1, 1);
8484 /* prepare second initializer parsing */
8485 macro_ptr
= init_str
.str
;
8488 /* if still unknown size, error */
8489 size
= type_size(type
, &align
);
8491 error("unknown type size");
8493 /* take into account specified alignment if bigger */
8495 if (ad
->aligned
> align
)
8496 align
= ad
->aligned
;
8497 } else if (ad
->packed
) {
8500 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
8502 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
8504 loc
= (loc
- size
) & -align
;
8506 /* handles bounds */
8507 /* XXX: currently, since we do only one pass, we cannot track
8508 '&' operators, so we add only arrays */
8509 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
8510 unsigned long *bounds_ptr
;
8511 /* add padding between regions */
8513 /* then add local bound info */
8514 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
8515 bounds_ptr
[0] = addr
;
8516 bounds_ptr
[1] = size
;
8519 /* local variable */
8520 sym_push(v
, type
, r
, addr
);
8522 /* push local reference */
8523 vset(type
, r
, addr
);
8529 if (v
&& scope
== VT_CONST
) {
8530 /* see if the symbol was already defined */
8533 if (!is_compatible_types(&sym
->type
, type
))
8534 error("incompatible types for redefinition of '%s'",
8535 get_tok_str(v
, NULL
));
8536 if (sym
->type
.t
& VT_EXTERN
) {
8537 /* if the variable is extern, it was not allocated */
8538 sym
->type
.t
&= ~VT_EXTERN
;
8539 /* set array size if it was ommited in extern
8541 if ((sym
->type
.t
& VT_ARRAY
) &&
8542 sym
->type
.ref
->c
< 0 &&
8544 sym
->type
.ref
->c
= type
->ref
->c
;
8546 /* we accept several definitions of the same
8547 global variable. this is tricky, because we
8548 must play with the SHN_COMMON type of the symbol */
8549 /* XXX: should check if the variable was already
8550 initialized. It is incorrect to initialized it
8552 /* no init data, we won't add more to the symbol */
8559 /* allocate symbol in corresponding section */
8564 else if (tcc_state
->nocommon
)
8568 data_offset
= sec
->data_offset
;
8569 data_offset
= (data_offset
+ align
- 1) & -align
;
8571 /* very important to increment global pointer at this time
8572 because initializers themselves can create new initializers */
8573 data_offset
+= size
;
8574 /* add padding if bound check */
8575 if (do_bounds_check
)
8577 sec
->data_offset
= data_offset
;
8578 /* allocate section space to put the data */
8579 if (sec
->sh_type
!= SHT_NOBITS
&&
8580 data_offset
> sec
->data_allocated
)
8581 section_realloc(sec
, data_offset
);
8582 /* align section if needed */
8583 if (align
> sec
->sh_addralign
)
8584 sec
->sh_addralign
= align
;
8586 addr
= 0; /* avoid warning */
8590 if (scope
== VT_CONST
) {
8595 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
8597 /* update symbol definition */
8599 put_extern_sym(sym
, sec
, addr
, size
);
8602 /* put a common area */
8603 put_extern_sym(sym
, NULL
, align
, size
);
8604 /* XXX: find a nicer way */
8605 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
8606 esym
->st_shndx
= SHN_COMMON
;
8611 /* push global reference */
8612 sym
= get_sym_ref(type
, sec
, addr
, size
);
8614 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
8618 /* handles bounds now because the symbol must be defined
8619 before for the relocation */
8620 if (do_bounds_check
) {
8621 unsigned long *bounds_ptr
;
8623 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
8624 /* then add global bound info */
8625 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
8626 bounds_ptr
[0] = 0; /* relocated */
8627 bounds_ptr
[1] = size
;
8631 decl_initializer(type
, sec
, addr
, 1, 0);
8632 /* restore parse state if needed */
8634 tok_str_free(init_str
.str
);
8635 restore_parse_state(&saved_parse_state
);
8641 void put_func_debug(Sym
*sym
)
8646 /* XXX: we put here a dummy type */
8647 snprintf(buf
, sizeof(buf
), "%s:%c1",
8648 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
8649 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
8650 cur_text_section
, sym
->c
);
8655 /* parse an old style function declaration list */
8656 /* XXX: check multiple parameter */
8657 static void func_decl_list(Sym
*func_sym
)
8664 /* parse each declaration */
8665 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
) {
8666 if (!parse_btype(&btype
, &ad
))
8667 expect("declaration list");
8668 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
8669 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
8671 /* we accept no variable after */
8675 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8676 /* find parameter in function parameter list */
8679 if ((s
->v
& ~SYM_FIELD
) == v
)
8683 error("declaration for parameter '%s' but no such parameter",
8684 get_tok_str(v
, NULL
));
8686 /* check that no storage specifier except 'register' was given */
8687 if (type
.t
& VT_STORAGE
)
8688 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
8689 convert_parameter_type(&type
);
8690 /* we can add the type (NOTE: it could be local to the function) */
8692 /* accept other parameters */
8703 /* parse a function defined by symbol 'sym' and generate its code in
8704 'cur_text_section' */
8705 static void gen_function(Sym
*sym
)
8707 ind
= cur_text_section
->data_offset
;
8708 /* NOTE: we patch the symbol size later */
8709 put_extern_sym(sym
, cur_text_section
, ind
, 0);
8710 funcname
= get_tok_str(sym
->v
, NULL
);
8712 /* put debug symbol */
8714 put_func_debug(sym
);
8715 /* push a dummy symbol to enable local sym storage */
8716 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
8717 gfunc_prolog(&sym
->type
);
8719 block(NULL
, NULL
, NULL
, NULL
, 0, 0);
8722 cur_text_section
->data_offset
= ind
;
8723 label_pop(&global_label_stack
, NULL
);
8724 sym_pop(&local_stack
, NULL
); /* reset local stack */
8725 /* end of function */
8726 /* patch symbol size */
8727 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
8730 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
8732 funcname
= ""; /* for safety */
8733 func_vt
.t
= VT_VOID
; /* for safety */
8734 ind
= 0; /* for safety */
8737 static void gen_inline_functions(void)
8741 int *str
, inline_generated
;
8743 /* iterate while inline function are referenced */
8745 inline_generated
= 0;
8746 for(sym
= global_stack
; sym
!= NULL
; sym
= sym
->prev
) {
8748 if (((type
->t
& VT_BTYPE
) == VT_FUNC
) &&
8749 (type
->t
& (VT_STATIC
| VT_INLINE
)) ==
8750 (VT_STATIC
| VT_INLINE
) &&
8752 /* the function was used: generate its code and
8753 convert it to a normal function */
8754 str
= (int *)sym
->r
;
8755 sym
->r
= VT_SYM
| VT_CONST
;
8756 type
->t
&= ~VT_INLINE
;
8760 cur_text_section
= text_section
;
8762 macro_ptr
= NULL
; /* fail safe */
8765 inline_generated
= 1;
8768 if (!inline_generated
)
8772 /* free all remaining inline function tokens */
8773 for(sym
= global_stack
; sym
!= NULL
; sym
= sym
->prev
) {
8775 if (((type
->t
& VT_BTYPE
) == VT_FUNC
) &&
8776 (type
->t
& (VT_STATIC
| VT_INLINE
)) ==
8777 (VT_STATIC
| VT_INLINE
)) {
8778 str
= (int *)sym
->r
;
8780 sym
->r
= 0; /* fail safe */
8785 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
8786 static void decl(int l
)
8794 if (!parse_btype(&btype
, &ad
)) {
8795 /* skip redundant ';' */
8796 /* XXX: find more elegant solution */
8801 if (l
== VT_CONST
&&
8802 (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
8803 /* global asm block */
8807 /* special test for old K&R protos without explicit int
8808 type. Only accepted when defining global data */
8809 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
8813 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
8814 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
8816 /* we accept no variable after */
8820 while (1) { /* iterate thru each declaration */
8822 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8826 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
8827 printf("type = '%s'\n", buf
);
8830 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8831 /* if old style function prototype, we accept a
8834 if (sym
->c
== FUNC_OLD
)
8835 func_decl_list(sym
);
8840 error("cannot use local functions");
8841 if (!(type
.t
& VT_FUNC
))
8842 expect("function definition");
8844 /* reject abstract declarators in function definition */
8846 while ((sym
= sym
->next
) != NULL
)
8847 if (!(sym
->v
& ~SYM_FIELD
))
8848 expect("identifier");
8850 /* XXX: cannot do better now: convert extern line to static inline */
8851 if ((type
.t
& (VT_EXTERN
| VT_INLINE
)) == (VT_EXTERN
| VT_INLINE
))
8852 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
8856 if ((sym
->type
.t
& VT_BTYPE
) != VT_FUNC
)
8858 /* specific case: if not func_call defined, we put
8859 the one of the prototype */
8860 /* XXX: should have default value */
8861 if (sym
->type
.ref
->r
!= FUNC_CDECL
&&
8862 type
.ref
->r
== FUNC_CDECL
)
8863 type
.ref
->r
= sym
->type
.ref
->r
;
8864 if (!is_compatible_types(&sym
->type
, &type
)) {
8866 error("incompatible types for redefinition of '%s'",
8867 get_tok_str(v
, NULL
));
8869 /* if symbol is already defined, then put complete type */
8872 /* put function symbol */
8873 sym
= global_identifier_push(v
, type
.t
, 0);
8874 sym
->type
.ref
= type
.ref
;
8877 /* static inline functions are just recorded as a kind
8878 of macro. Their code will be emitted at the end of
8879 the compilation unit only if they are used */
8880 if ((type
.t
& (VT_INLINE
| VT_STATIC
)) ==
8881 (VT_INLINE
| VT_STATIC
)) {
8882 TokenString func_str
;
8885 tok_str_new(&func_str
);
8891 error("unexpected end of file");
8892 tok_str_add_tok(&func_str
);
8897 } else if (t
== '}') {
8899 if (block_level
== 0)
8903 tok_str_add(&func_str
, -1);
8904 tok_str_add(&func_str
, 0);
8905 sym
->r
= (int)func_str
.str
;
8907 /* compute text section */
8908 cur_text_section
= ad
.section
;
8909 if (!cur_text_section
)
8910 cur_text_section
= text_section
;
8911 sym
->r
= VT_SYM
| VT_CONST
;
8916 if (btype
.t
& VT_TYPEDEF
) {
8917 /* save typedefed type */
8918 /* XXX: test storage specifiers ? */
8919 sym
= sym_push(v
, &type
, 0, 0);
8920 sym
->type
.t
|= VT_TYPEDEF
;
8921 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8922 /* external function definition */
8923 /* specific case for func_call attribute */
8925 type
.ref
->r
= ad
.func_call
;
8926 external_sym(v
, &type
, 0);
8928 /* not lvalue if array */
8930 if (!(type
.t
& VT_ARRAY
))
8931 r
|= lvalue_type(type
.t
);
8932 has_init
= (tok
== '=');
8933 if ((btype
.t
& VT_EXTERN
) ||
8934 ((type
.t
& VT_ARRAY
) && (type
.t
& VT_STATIC
) &&
8935 !has_init
&& l
== VT_CONST
&& type
.ref
->c
< 0)) {
8936 /* external variable */
8937 /* NOTE: as GCC, uninitialized global static
8938 arrays of null size are considered as
8940 external_sym(v
, &type
, r
);
8942 if (type
.t
& VT_STATIC
)
8948 decl_initializer_alloc(&type
, &ad
, r
,
8962 /* better than nothing, but needs extension to handle '-E' option
8964 static void preprocess_init(TCCState
*s1
)
8966 s1
->include_stack_ptr
= s1
->include_stack
;
8967 /* XXX: move that before to avoid having to initialize
8968 file->ifdef_stack_ptr ? */
8969 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
8970 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
8972 /* XXX: not ANSI compliant: bound checking says error */
8976 /* compile the C file opened in 'file'. Return non zero if errors. */
8977 static int tcc_compile(TCCState
*s1
)
8981 volatile int section_sym
;
8984 printf("%s: **** new file\n", file
->filename
);
8986 preprocess_init(s1
);
8989 anon_sym
= SYM_FIRST_ANOM
;
8991 /* file info: full path + filename */
8992 section_sym
= 0; /* avoid warning */
8994 section_sym
= put_elf_sym(symtab_section
, 0, 0,
8995 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
8996 text_section
->sh_num
, NULL
);
8997 getcwd(buf
, sizeof(buf
));
8998 pstrcat(buf
, sizeof(buf
), "/");
8999 put_stabs_r(buf
, N_SO
, 0, 0,
9000 text_section
->data_offset
, text_section
, section_sym
);
9001 put_stabs_r(file
->filename
, N_SO
, 0, 0,
9002 text_section
->data_offset
, text_section
, section_sym
);
9004 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
9005 symbols can be safely used */
9006 put_elf_sym(symtab_section
, 0, 0,
9007 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
9008 SHN_ABS
, file
->filename
);
9010 /* define some often used types */
9011 int_type
.t
= VT_INT
;
9013 char_pointer_type
.t
= VT_BYTE
;
9014 mk_pointer(&char_pointer_type
);
9016 func_old_type
.t
= VT_FUNC
;
9017 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
9020 /* define 'void *alloca(unsigned int)' builtin function */
9025 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
9026 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
9029 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
9033 define_start
= define_stack
;
9035 if (setjmp(s1
->error_jmp_buf
) == 0) {
9037 s1
->error_set_jmp_enabled
= 1;
9039 ch
= file
->buf_ptr
[0];
9040 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
9041 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
;
9045 expect("declaration");
9047 /* end of translation unit info */
9049 put_stabs_r(NULL
, N_SO
, 0, 0,
9050 text_section
->data_offset
, text_section
, section_sym
);
9053 s1
->error_set_jmp_enabled
= 0;
9055 /* reset define stack, but leave -Dsymbols (may be incorrect if
9056 they are undefined) */
9057 free_defines(define_start
);
9059 gen_inline_functions();
9061 sym_pop(&global_stack
, NULL
);
9063 return s1
->nb_errors
!= 0 ? -1 : 0;
9067 int tcc_compile_string(TCCState
*s
, const char *str
)
9069 BufferedFile bf1
, *bf
= &bf1
;
9073 /* init file structure */
9075 /* XXX: avoid copying */
9077 buf
= tcc_malloc(len
+ 1);
9080 memcpy(buf
, str
, len
);
9083 bf
->buf_end
= buf
+ len
;
9084 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
9088 ret
= tcc_compile(s
);
9092 /* currently, no need to close */
9097 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
9098 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
9100 BufferedFile bf1
, *bf
= &bf1
;
9102 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
9103 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
9107 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
9109 /* init file structure */
9111 bf
->buf_ptr
= bf
->buffer
;
9112 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
9113 *bf
->buf_end
= CH_EOB
;
9114 bf
->filename
[0] = '\0';
9118 s1
->include_stack_ptr
= s1
->include_stack
;
9120 /* parse with define parser */
9121 ch
= file
->buf_ptr
[0];
9127 /* undefine a preprocessor symbol */
9128 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
9132 ts
= tok_alloc(sym
, strlen(sym
));
9133 s
= define_find(ts
->tok
);
9134 /* undefine symbol by putting an invalid name */
9139 #ifdef CONFIG_TCC_ASM
9141 #ifdef TCC_TARGET_I386
9142 #include "i386-asm.c"
9147 static void asm_instr(void)
9149 error("inline asm() not supported");
9151 static void asm_global_instr(void)
9153 error("inline asm() not supported");
9159 #ifdef TCC_TARGET_COFF
9160 #include "tcccoff.c"
9163 /* print the position in the source file of PC value 'pc' by reading
9164 the stabs debug information */
9165 static void rt_printline(unsigned long wanted_pc
)
9167 Stab_Sym
*sym
, *sym_end
;
9168 char func_name
[128], last_func_name
[128];
9169 unsigned long func_addr
, last_pc
, pc
;
9170 const char *incl_files
[INCLUDE_STACK_SIZE
];
9171 int incl_index
, len
, last_line_num
, i
;
9172 const char *str
, *p
;
9174 fprintf(stderr
, "0x%08lx:", wanted_pc
);
9176 func_name
[0] = '\0';
9179 last_func_name
[0] = '\0';
9180 last_pc
= 0xffffffff;
9182 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
9183 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
9184 while (sym
< sym_end
) {
9185 switch(sym
->n_type
) {
9186 /* function start or end */
9188 if (sym
->n_strx
== 0) {
9189 /* we test if between last line and end of function */
9190 pc
= sym
->n_value
+ func_addr
;
9191 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9193 func_name
[0] = '\0';
9196 str
= stabstr_section
->data
+ sym
->n_strx
;
9197 p
= strchr(str
, ':');
9199 pstrcpy(func_name
, sizeof(func_name
), str
);
9202 if (len
> sizeof(func_name
) - 1)
9203 len
= sizeof(func_name
) - 1;
9204 memcpy(func_name
, str
, len
);
9205 func_name
[len
] = '\0';
9207 func_addr
= sym
->n_value
;
9210 /* line number info */
9212 pc
= sym
->n_value
+ func_addr
;
9213 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9216 last_line_num
= sym
->n_desc
;
9218 strcpy(last_func_name
, func_name
);
9222 str
= stabstr_section
->data
+ sym
->n_strx
;
9224 if (incl_index
< INCLUDE_STACK_SIZE
) {
9225 incl_files
[incl_index
++] = str
;
9233 if (sym
->n_strx
== 0) {
9234 incl_index
= 0; /* end of translation unit */
9236 str
= stabstr_section
->data
+ sym
->n_strx
;
9237 /* do not add path */
9239 if (len
> 0 && str
[len
- 1] != '/')
9247 /* second pass: we try symtab symbols (no line number info) */
9250 Elf32_Sym
*sym
, *sym_end
;
9253 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
9254 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
9257 type
= ELF32_ST_TYPE(sym
->st_info
);
9258 if (type
== STT_FUNC
) {
9259 if (wanted_pc
>= sym
->st_value
&&
9260 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
9261 pstrcpy(last_func_name
, sizeof(last_func_name
),
9262 strtab_section
->data
+ sym
->st_name
);
9268 /* did not find any info: */
9269 fprintf(stderr
, " ???\n");
9272 if (last_func_name
[0] != '\0') {
9273 fprintf(stderr
, " %s()", last_func_name
);
9275 if (incl_index
> 0) {
9276 fprintf(stderr
, " (%s:%d",
9277 incl_files
[incl_index
- 1], last_line_num
);
9278 for(i
= incl_index
- 2; i
>= 0; i
--)
9279 fprintf(stderr
, ", included from %s", incl_files
[i
]);
9280 fprintf(stderr
, ")");
9282 fprintf(stderr
, "\n");
9285 #if !defined(WIN32) && !defined(CONFIG_TCCBOOT)
9289 /* fix for glibc 2.1 */
9295 /* return the PC at frame level 'level'. Return non zero if not found */
9296 static int rt_get_caller_pc(unsigned long *paddr
,
9297 ucontext_t
*uc
, int level
)
9303 #if defined(__FreeBSD__)
9304 *paddr
= uc
->uc_mcontext
.mc_eip
;
9305 #elif defined(__dietlibc__)
9306 *paddr
= uc
->uc_mcontext
.eip
;
9308 *paddr
= uc
->uc_mcontext
.gregs
[REG_EIP
];
9312 #if defined(__FreeBSD__)
9313 fp
= uc
->uc_mcontext
.mc_ebp
;
9314 #elif defined(__dietlibc__)
9315 fp
= uc
->uc_mcontext
.ebp
;
9317 fp
= uc
->uc_mcontext
.gregs
[REG_EBP
];
9319 for(i
=1;i
<level
;i
++) {
9320 /* XXX: check address validity with program info */
9321 if (fp
<= 0x1000 || fp
>= 0xc0000000)
9323 fp
= ((unsigned long *)fp
)[0];
9325 *paddr
= ((unsigned long *)fp
)[1];
9331 #warning add arch specific rt_get_caller_pc()
9333 static int rt_get_caller_pc(unsigned long *paddr
,
9334 ucontext_t
*uc
, int level
)
9340 /* emit a run time error at position 'pc' */
9341 void rt_error(ucontext_t
*uc
, const char *fmt
, ...)
9348 fprintf(stderr
, "Runtime error: ");
9349 vfprintf(stderr
, fmt
, ap
);
9350 fprintf(stderr
, "\n");
9351 for(i
=0;i
<num_callers
;i
++) {
9352 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
9355 fprintf(stderr
, "at ");
9357 fprintf(stderr
, "by ");
9364 /* signal handler for fatal errors */
9365 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
9367 ucontext_t
*uc
= puc
;
9371 switch(siginf
->si_code
) {
9374 rt_error(uc
, "division by zero");
9377 rt_error(uc
, "floating point exception");
9383 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
9384 rt_error(uc
, *rt_bound_error_msg
);
9386 rt_error(uc
, "dereferencing invalid pointer");
9389 rt_error(uc
, "illegal instruction");
9392 rt_error(uc
, "abort() called");
9395 rt_error(uc
, "caught signal %d", signum
);
9402 /* do all relocations (needed before using tcc_get_symbol()) */
9403 int tcc_relocate(TCCState
*s1
)
9410 tcc_add_runtime(s1
);
9412 build_got_entries(s1
);
9414 relocate_common_syms();
9416 /* compute relocation address : section are relocated in place. We
9417 also alloc the bss space */
9418 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9419 s
= s1
->sections
[i
];
9420 if (s
->sh_flags
& SHF_ALLOC
) {
9421 if (s
->sh_type
== SHT_NOBITS
)
9422 s
->data
= tcc_mallocz(s
->data_offset
);
9423 s
->sh_addr
= (unsigned long)s
->data
;
9427 relocate_syms(s1
, 1);
9429 if (s1
->nb_errors
!= 0)
9432 /* relocate each section */
9433 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9434 s
= s1
->sections
[i
];
9436 relocate_section(s1
, s
);
9441 /* launch the compiled program with the given arguments */
9442 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
9444 int (*prog_main
)(int, char **);
9446 if (tcc_relocate(s1
) < 0)
9449 prog_main
= tcc_get_symbol_err(s1
, "main");
9452 #if defined(WIN32) || defined(CONFIG_TCCBOOT)
9453 error("debug mode currently not available for Windows");
9455 struct sigaction sigact
;
9456 /* install TCC signal handlers to print debug info on fatal
9458 sigact
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
9459 sigact
.sa_sigaction
= sig_error
;
9460 sigemptyset(&sigact
.sa_mask
);
9461 sigaction(SIGFPE
, &sigact
, NULL
);
9462 sigaction(SIGILL
, &sigact
, NULL
);
9463 sigaction(SIGSEGV
, &sigact
, NULL
);
9464 sigaction(SIGBUS
, &sigact
, NULL
);
9465 sigaction(SIGABRT
, &sigact
, NULL
);
9469 #ifdef CONFIG_TCC_BCHECK
9470 if (do_bounds_check
) {
9471 void (*bound_init
)(void);
9473 /* set error function */
9474 rt_bound_error_msg
= (void *)tcc_get_symbol_err(s1
,
9475 "__bound_error_msg");
9477 /* XXX: use .init section so that it also work in binary ? */
9478 bound_init
= (void *)tcc_get_symbol_err(s1
, "__bound_init");
9482 return (*prog_main
)(argc
, argv
);
9485 TCCState
*tcc_new(void)
9492 s
= tcc_mallocz(sizeof(TCCState
));
9496 s
->output_type
= TCC_OUTPUT_MEMORY
;
9498 /* init isid table */
9500 isidnum_table
[i
] = isid(i
) || isnum(i
);
9502 /* add all tokens */
9504 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
9506 tok_ident
= TOK_IDENT
;
9515 ts
= tok_alloc(p
, r
- p
- 1);
9519 /* we add dummy defines for some special macros to speed up tests
9520 and to have working defined() */
9521 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
9522 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
9523 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
9524 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
9526 /* standard defines */
9527 tcc_define_symbol(s
, "__STDC__", NULL
);
9528 #if defined(TCC_TARGET_I386)
9529 tcc_define_symbol(s
, "__i386__", NULL
);
9531 #if defined(TCC_TARGET_ARM)
9532 tcc_define_symbol(s
, "__ARM_ARCH_4__", NULL
);
9533 tcc_define_symbol(s
, "__arm_elf__", NULL
);
9534 tcc_define_symbol(s
, "__arm_elf", NULL
);
9535 tcc_define_symbol(s
, "arm_elf", NULL
);
9536 tcc_define_symbol(s
, "__arm__", NULL
);
9537 tcc_define_symbol(s
, "__arm", NULL
);
9538 tcc_define_symbol(s
, "arm", NULL
);
9539 tcc_define_symbol(s
, "__APCS_32__", NULL
);
9542 tcc_define_symbol(s
, "__linux__", NULL
);
9543 tcc_define_symbol(s
, "linux", NULL
);
9545 /* tiny C specific defines */
9546 tcc_define_symbol(s
, "__TINYC__", NULL
);
9548 /* tiny C & gcc defines */
9549 tcc_define_symbol(s
, "__SIZE_TYPE__", "unsigned int");
9550 tcc_define_symbol(s
, "__PTRDIFF_TYPE__", "int");
9551 tcc_define_symbol(s
, "__WCHAR_TYPE__", "int");
9553 /* default library paths */
9554 tcc_add_library_path(s
, "/usr/local/lib");
9555 tcc_add_library_path(s
, "/usr/lib");
9556 tcc_add_library_path(s
, "/lib");
9558 /* no section zero */
9559 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
9561 /* create standard sections */
9562 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
9563 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
9564 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
9566 /* symbols are always generated for linking stage */
9567 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
9569 ".hashtab", SHF_PRIVATE
);
9570 strtab_section
= symtab_section
->link
;
9572 /* private symbol table for dynamic symbols */
9573 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
9575 ".dynhashtab", SHF_PRIVATE
);
9576 s
->alacarte_link
= 1;
9578 #ifdef CHAR_IS_UNSIGNED
9579 s
->char_is_unsigned
= 1;
9584 void tcc_delete(TCCState
*s1
)
9588 /* free -D defines */
9592 n
= tok_ident
- TOK_IDENT
;
9593 for(i
= 0; i
< n
; i
++)
9594 tcc_free(table_ident
[i
]);
9595 tcc_free(table_ident
);
9597 /* free all sections */
9599 free_section(symtab_section
->hash
);
9601 free_section(s1
->dynsymtab_section
->hash
);
9602 free_section(s1
->dynsymtab_section
->link
);
9603 free_section(s1
->dynsymtab_section
);
9605 for(i
= 1; i
< s1
->nb_sections
; i
++)
9606 free_section(s1
->sections
[i
]);
9607 tcc_free(s1
->sections
);
9609 /* free loaded dlls array */
9610 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
9611 tcc_free(s1
->loaded_dlls
[i
]);
9612 tcc_free(s1
->loaded_dlls
);
9615 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
9616 tcc_free(s1
->library_paths
[i
]);
9617 tcc_free(s1
->library_paths
);
9619 /* cached includes */
9620 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
9621 tcc_free(s1
->cached_includes
[i
]);
9622 tcc_free(s1
->cached_includes
);
9624 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
9625 tcc_free(s1
->include_paths
[i
]);
9626 tcc_free(s1
->include_paths
);
9628 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
9629 tcc_free(s1
->sysinclude_paths
[i
]);
9630 tcc_free(s1
->sysinclude_paths
);
9635 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
9639 pathname1
= tcc_strdup(pathname
);
9640 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
9644 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
9648 pathname1
= tcc_strdup(pathname
);
9649 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
9653 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
9655 const char *ext
, *filename1
;
9658 BufferedFile
*saved_file
;
9660 /* find source file type with extension */
9661 filename1
= strrchr(filename
, '/');
9665 filename1
= filename
;
9666 ext
= strrchr(filename1
, '.');
9672 file
= tcc_open(s1
, filename
);
9674 if (flags
& AFF_PRINT_ERROR
) {
9675 error_noabort("file '%s' not found", filename
);
9681 if (!ext
|| !strcmp(ext
, "c")) {
9682 /* C file assumed */
9683 ret
= tcc_compile(s1
);
9685 #ifdef CONFIG_TCC_ASM
9686 if (!strcmp(ext
, "S")) {
9687 /* preprocessed assembler */
9688 ret
= tcc_assemble(s1
, 1);
9689 } else if (!strcmp(ext
, "s")) {
9690 /* non preprocessed assembler */
9691 ret
= tcc_assemble(s1
, 0);
9696 /* assume executable format: auto guess file type */
9697 ret
= read(fd
, &ehdr
, sizeof(ehdr
));
9698 lseek(fd
, 0, SEEK_SET
);
9700 error_noabort("could not read header");
9702 } else if (ret
!= sizeof(ehdr
)) {
9703 goto try_load_script
;
9706 if (ehdr
.e_ident
[0] == ELFMAG0
&&
9707 ehdr
.e_ident
[1] == ELFMAG1
&&
9708 ehdr
.e_ident
[2] == ELFMAG2
&&
9709 ehdr
.e_ident
[3] == ELFMAG3
) {
9710 file
->line_num
= 0; /* do not display line number if error */
9711 if (ehdr
.e_type
== ET_REL
) {
9712 ret
= tcc_load_object_file(s1
, fd
, 0);
9713 } else if (ehdr
.e_type
== ET_DYN
) {
9714 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
9716 h
= dlopen(filename
, RTLD_GLOBAL
| RTLD_LAZY
);
9722 ret
= tcc_load_dll(s1
, fd
, filename
,
9723 (flags
& AFF_REFERENCED_DLL
) != 0);
9726 error_noabort("unrecognized ELF file");
9729 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
9730 file
->line_num
= 0; /* do not display line number if error */
9731 ret
= tcc_load_archive(s1
, fd
);
9733 #ifdef TCC_TARGET_COFF
9734 if (*(uint16_t *)(&ehdr
) == COFF_C67_MAGIC
) {
9735 ret
= tcc_load_coff(s1
, fd
);
9739 /* as GNU ld, consider it is an ld script if not recognized */
9741 ret
= tcc_load_ldscript(s1
);
9743 error_noabort("unrecognized file type");
9758 int tcc_add_file(TCCState
*s
, const char *filename
)
9760 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
9763 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
9767 pathname1
= tcc_strdup(pathname
);
9768 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
9772 /* find and load a dll. Return non zero if not found */
9773 /* XXX: add '-rpath' option support ? */
9774 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
9779 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
9780 snprintf(buf
, sizeof(buf
), "%s/%s",
9781 s
->library_paths
[i
], filename
);
9782 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
9788 /* the library name is the same as the argument of the '-l' option */
9789 int tcc_add_library(TCCState
*s
, const char *libraryname
)
9794 /* first we look for the dynamic library if not static linking */
9795 if (!s
->static_link
) {
9796 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
9797 if (tcc_add_dll(s
, buf
, 0) == 0)
9801 /* then we look for the static library */
9802 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
9803 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
9804 s
->library_paths
[i
], libraryname
);
9805 if (tcc_add_file_internal(s
, buf
, 0) == 0)
9811 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
9813 add_elf_sym(symtab_section
, val
, 0,
9814 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
9819 int tcc_set_output_type(TCCState
*s
, int output_type
)
9823 s
->output_type
= output_type
;
9826 /* default include paths */
9827 /* XXX: reverse order needed if -isystem support */
9828 tcc_add_sysinclude_path(s
, "/usr/local/include");
9829 tcc_add_sysinclude_path(s
, "/usr/include");
9830 snprintf(buf
, sizeof(buf
), "%s/include", tcc_lib_path
);
9831 tcc_add_sysinclude_path(s
, buf
);
9834 /* if bound checking, then add corresponding sections */
9835 #ifdef CONFIG_TCC_BCHECK
9836 if (do_bounds_check
) {
9838 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
9839 /* create bounds sections */
9840 bounds_section
= new_section(s
, ".bounds",
9841 SHT_PROGBITS
, SHF_ALLOC
);
9842 lbounds_section
= new_section(s
, ".lbounds",
9843 SHT_PROGBITS
, SHF_ALLOC
);
9847 if (s
->char_is_unsigned
) {
9848 tcc_define_symbol(s
, "__CHAR_UNSIGNED__", NULL
);
9851 /* add debug sections */
9854 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
9855 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
9856 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
9857 put_elf_str(stabstr_section
, "");
9858 stab_section
->link
= stabstr_section
;
9859 /* put first entry */
9860 put_stabs("", 0, 0, 0, 0);
9863 /* add libc crt1/crti objects */
9864 if ((output_type
== TCC_OUTPUT_EXE
|| output_type
== TCC_OUTPUT_DLL
) &&
9866 if (output_type
!= TCC_OUTPUT_DLL
)
9867 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
9868 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
9873 #define WD_ALL 0x0001 /* warning is activated when using -Wall */
9874 #define FD_INVERT 0x0002 /* invert value before storing */
9876 typedef struct FlagDef
{
9882 static const FlagDef warning_defs
[] = {
9883 { offsetof(TCCState
, warn_unsupported
), 0, "unsupported" },
9884 { offsetof(TCCState
, warn_write_strings
), 0, "write-strings" },
9885 { offsetof(TCCState
, warn_error
), 0, "error" },
9886 { offsetof(TCCState
, warn_implicit_function_declaration
), WD_ALL
,
9887 "implicit-function-declaration" },
9890 static int set_flag(TCCState
*s
, const FlagDef
*flags
, int nb_flags
,
9891 const char *name
, int value
)
9898 if (r
[0] == 'n' && r
[1] == 'o' && r
[2] == '-') {
9902 for(i
= 0, p
= flags
; i
< nb_flags
; i
++, p
++) {
9903 if (!strcmp(r
, p
->name
))
9908 if (p
->flags
& FD_INVERT
)
9910 *(int *)((uint8_t *)s
+ p
->offset
) = value
;
9915 /* set/reset a warning */
9916 int tcc_set_warning(TCCState
*s
, const char *warning_name
, int value
)
9921 if (!strcmp(warning_name
, "all")) {
9922 for(i
= 0, p
= warning_defs
; i
< countof(warning_defs
); i
++, p
++) {
9923 if (p
->flags
& WD_ALL
)
9924 *(int *)((uint8_t *)s
+ p
->offset
) = 1;
9928 return set_flag(s
, warning_defs
, countof(warning_defs
),
9929 warning_name
, value
);
9933 static const FlagDef flag_defs
[] = {
9934 { offsetof(TCCState
, char_is_unsigned
), 0, "unsigned-char" },
9935 { offsetof(TCCState
, char_is_unsigned
), FD_INVERT
, "signed-char" },
9936 { offsetof(TCCState
, nocommon
), FD_INVERT
, "common" },
9939 /* set/reset a flag */
9940 int tcc_set_flag(TCCState
*s
, const char *flag_name
, int value
)
9942 return set_flag(s
, flag_defs
, countof(flag_defs
),
9946 #if !defined(LIBTCC)
9948 /* extract the basename of a file */
9949 static const char *tcc_basename(const char *name
)
9952 p
= strrchr(name
, '/');
9955 p
= strrchr(name
, '\\');
9964 static int64_t getclock_us(void)
9969 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
9972 gettimeofday(&tv
, NULL
);
9973 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
9979 printf("tcc version " TCC_VERSION
" - Tiny C Compiler - Copyright (C) 2001-2004 Fabrice Bellard\n"
9980 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
9981 " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
9982 " [infile1 infile2...] [-run infile args...]\n"
9984 "General options:\n"
9985 " -v display current version\n"
9986 " -c compile only - generate an object file\n"
9987 " -o outfile set output filename\n"
9988 " -Bdir set tcc internal library path\n"
9989 " -bench output compilation statistics\n"
9990 " -run run compiled source\n"
9991 " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
9992 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
9993 " -w disable all warnings\n"
9994 "Preprocessor options:\n"
9995 " -Idir add include path 'dir'\n"
9996 " -Dsym[=val] define 'sym' with value 'val'\n"
9997 " -Usym undefine 'sym'\n"
9999 " -Ldir add library path 'dir'\n"
10000 " -llib link with dynamic or static library 'lib'\n"
10001 " -shared generate a shared library\n"
10002 " -static static linking\n"
10003 " -rdynamic export all global symbols to dynamic linker\n"
10004 " -r relocatable output\n"
10005 "Debugger options:\n"
10006 " -g generate runtime debug info\n"
10007 #ifdef CONFIG_TCC_BCHECK
10008 " -b compile with built-in memory and bounds checker (implies -g)\n"
10010 " -bt N show N callers in stack traces\n"
10014 #define TCC_OPTION_HAS_ARG 0x0001
10015 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
10017 typedef struct TCCOption
{
10045 TCC_OPTION_nostdinc
,
10046 TCC_OPTION_nostdlib
,
10047 TCC_OPTION_print_search_dirs
,
10048 TCC_OPTION_rdynamic
,
10054 static const TCCOption tcc_options
[] = {
10055 { "h", TCC_OPTION_HELP
, 0 },
10056 { "?", TCC_OPTION_HELP
, 0 },
10057 { "I", TCC_OPTION_I
, TCC_OPTION_HAS_ARG
},
10058 { "D", TCC_OPTION_D
, TCC_OPTION_HAS_ARG
},
10059 { "U", TCC_OPTION_U
, TCC_OPTION_HAS_ARG
},
10060 { "L", TCC_OPTION_L
, TCC_OPTION_HAS_ARG
},
10061 { "B", TCC_OPTION_B
, TCC_OPTION_HAS_ARG
},
10062 { "l", TCC_OPTION_l
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10063 { "bench", TCC_OPTION_bench
, 0 },
10064 { "bt", TCC_OPTION_bt
, TCC_OPTION_HAS_ARG
},
10065 #ifdef CONFIG_TCC_BCHECK
10066 { "b", TCC_OPTION_b
, 0 },
10068 { "g", TCC_OPTION_g
, 0 },
10069 { "c", TCC_OPTION_c
, 0 },
10070 { "static", TCC_OPTION_static
, 0 },
10071 { "shared", TCC_OPTION_shared
, 0 },
10072 { "o", TCC_OPTION_o
, TCC_OPTION_HAS_ARG
},
10073 { "run", TCC_OPTION_run
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10074 { "rdynamic", TCC_OPTION_rdynamic
, 0 },
10075 { "r", TCC_OPTION_r
, 0 },
10076 { "Wl,", TCC_OPTION_Wl
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10077 { "W", TCC_OPTION_W
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10078 { "O", TCC_OPTION_O
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10079 { "m", TCC_OPTION_m
, TCC_OPTION_HAS_ARG
},
10080 { "f", TCC_OPTION_f
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10081 { "nostdinc", TCC_OPTION_nostdinc
, 0 },
10082 { "nostdlib", TCC_OPTION_nostdlib
, 0 },
10083 { "print-search-dirs", TCC_OPTION_print_search_dirs
, 0 },
10084 { "v", TCC_OPTION_v
, 0 },
10085 { "w", TCC_OPTION_w
, 0 },
10089 /* convert 'str' into an array of space separated strings */
10090 static int expand_args(char ***pargv
, const char *str
)
10099 while (is_space(*str
))
10104 while (*str
!= '\0' && !is_space(*str
))
10107 arg
= tcc_malloc(len
+ 1);
10108 memcpy(arg
, s1
, len
);
10110 dynarray_add((void ***)&argv
, &argc
, arg
);
10116 static char **files
;
10117 static int nb_files
, nb_libraries
;
10118 static int multiple_files
;
10119 static int print_search_dirs
;
10120 static int output_type
;
10121 static int reloc_output
;
10122 static const char *outfile
;
10124 int parse_args(TCCState
*s
, int argc
, char **argv
)
10127 const TCCOption
*popt
;
10128 const char *optarg
, *p1
, *r1
;
10133 if (optind
>= argc
) {
10134 if (nb_files
== 0 && !print_search_dirs
)
10139 r
= argv
[optind
++];
10141 /* add a new file */
10142 dynarray_add((void ***)&files
, &nb_files
, r
);
10143 if (!multiple_files
) {
10145 /* argv[0] will be this file */
10149 /* find option in table (match only the first chars */
10150 popt
= tcc_options
;
10154 error("invalid option -- '%s'", r
);
10167 if (popt
->flags
& TCC_OPTION_HAS_ARG
) {
10168 if (*r1
!= '\0' || (popt
->flags
& TCC_OPTION_NOSEP
)) {
10171 if (optind
>= argc
)
10172 error("argument to '%s' is missing", r
);
10173 optarg
= argv
[optind
++];
10181 switch(popt
->index
) {
10182 case TCC_OPTION_HELP
:
10187 if (tcc_add_include_path(s
, optarg
) < 0)
10188 error("too many include paths");
10193 sym
= (char *)optarg
;
10194 value
= strchr(sym
, '=');
10199 tcc_define_symbol(s
, sym
, value
);
10203 tcc_undefine_symbol(s
, optarg
);
10206 tcc_add_library_path(s
, optarg
);
10209 /* set tcc utilities path (mainly for tcc development) */
10210 tcc_lib_path
= optarg
;
10213 dynarray_add((void ***)&files
, &nb_files
, r
);
10216 case TCC_OPTION_bench
:
10219 case TCC_OPTION_bt
:
10220 num_callers
= atoi(optarg
);
10222 #ifdef CONFIG_TCC_BCHECK
10224 do_bounds_check
= 1;
10232 multiple_files
= 1;
10233 output_type
= TCC_OUTPUT_OBJ
;
10235 case TCC_OPTION_static
:
10236 s
->static_link
= 1;
10238 case TCC_OPTION_shared
:
10239 output_type
= TCC_OUTPUT_DLL
;
10242 multiple_files
= 1;
10246 /* generate a .o merging several output files */
10248 output_type
= TCC_OUTPUT_OBJ
;
10250 case TCC_OPTION_nostdinc
:
10253 case TCC_OPTION_nostdlib
:
10256 case TCC_OPTION_print_search_dirs
:
10257 print_search_dirs
= 1;
10259 case TCC_OPTION_run
:
10263 argc1
= expand_args(&argv1
, optarg
);
10265 parse_args(s
, argc1
, argv1
);
10267 multiple_files
= 0;
10268 output_type
= TCC_OUTPUT_MEMORY
;
10272 printf("tcc version %s\n", TCC_VERSION
);
10275 if (tcc_set_flag(s
, optarg
, 1) < 0 && s
->warn_unsupported
)
10276 goto unsupported_option
;
10279 if (tcc_set_warning(s
, optarg
, 1) < 0 &&
10280 s
->warn_unsupported
)
10281 goto unsupported_option
;
10286 case TCC_OPTION_rdynamic
:
10289 case TCC_OPTION_Wl
:
10292 if (strstart(optarg
, "-Ttext,", &p
)) {
10293 s
->text_addr
= strtoul(p
, NULL
, 16);
10294 s
->has_text_addr
= 1;
10295 } else if (strstart(optarg
, "--oformat,", &p
)) {
10296 if (strstart(p
, "elf32-", NULL
)) {
10297 s
->output_format
= TCC_OUTPUT_FORMAT_ELF
;
10298 } else if (!strcmp(p
, "binary")) {
10299 s
->output_format
= TCC_OUTPUT_FORMAT_BINARY
;
10301 #ifdef TCC_TARGET_COFF
10302 if (!strcmp(p
, "coff")) {
10303 s
->output_format
= TCC_OUTPUT_FORMAT_COFF
;
10307 error("target %s not found", p
);
10310 error("unsupported linker option '%s'", optarg
);
10315 if (s
->warn_unsupported
) {
10316 unsupported_option
:
10317 warning("unsupported option '%s'", r
);
10326 int main(int argc
, char **argv
)
10330 int nb_objfiles
, ret
, optind
;
10331 char objfilename
[1024];
10332 int64_t start_time
= 0;
10335 output_type
= TCC_OUTPUT_EXE
;
10337 multiple_files
= 1;
10342 print_search_dirs
= 0;
10344 optind
= parse_args(s
, argc
- 1, argv
+ 1) + 1;
10346 if (print_search_dirs
) {
10347 /* enough for Linux kernel */
10348 printf("install: %s/\n", tcc_lib_path
);
10352 nb_objfiles
= nb_files
- nb_libraries
;
10354 /* if outfile provided without other options, we output an
10356 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
10357 output_type
= TCC_OUTPUT_EXE
;
10359 /* check -c consistency : only single file handled. XXX: checks file type */
10360 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
10361 /* accepts only a single input file */
10362 if (nb_objfiles
!= 1)
10363 error("cannot specify multiple files with -c");
10364 if (nb_libraries
!= 0)
10365 error("cannot specify libraries with -c");
10368 /* compute default outfile name */
10369 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
10370 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
10373 pstrcpy(objfilename
, sizeof(objfilename
) - 1,
10374 tcc_basename(files
[0]));
10375 /* add .o extension */
10376 ext
= strrchr(objfilename
, '.');
10378 goto default_outfile
;
10379 strcpy(ext
+ 1, "o");
10382 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
10384 outfile
= objfilename
;
10388 start_time
= getclock_us();
10391 tcc_set_output_type(s
, output_type
);
10393 /* compile or add each files or library */
10394 for(i
= 0;i
< nb_files
; i
++) {
10395 const char *filename
;
10397 filename
= files
[i
];
10398 if (filename
[0] == '-') {
10399 if (tcc_add_library(s
, filename
+ 2) < 0)
10400 error("cannot find %s", filename
);
10402 if (tcc_add_file(s
, filename
) < 0) {
10409 /* free all files */
10414 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
10415 if (total_time
< 0.001)
10416 total_time
= 0.001;
10417 if (total_bytes
< 1)
10419 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
10420 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
10421 total_time
, (int)(total_lines
/ total_time
),
10422 total_bytes
/ total_time
/ 1000000.0);
10425 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
10426 tcc_output_file(s
, outfile
);
10429 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
10432 /* XXX: cannot do it with bound checking because of the malloc hooks */
10433 if (!do_bounds_check
)
10438 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);