2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #define CONFIG_TCC_STATIC
42 #include <sys/timeb.h>
46 #include <sys/ucontext.h>
49 #endif /* !CONFIG_TCCBOOT */
62 /* preprocessor debug */
64 /* include file debug */
72 /* target selection */
73 //#define TCC_TARGET_I386 /* i386 code generator */
74 //#define TCC_TARGET_ARM /* ARMv4 code generator */
75 //#define TCC_TARGET_C67 /* TMS320C67xx code generator */
77 /* default target is I386 */
78 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
79 !defined(TCC_TARGET_C67)
80 #define TCC_TARGET_I386
83 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
84 !defined(TCC_TARGET_C67)
85 #define CONFIG_TCC_BCHECK /* enable bound checking code */
88 #if defined(WIN32) && !defined(TCC_TARGET_PE)
89 #define CONFIG_TCC_STATIC
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 256
115 #define STRING_MAX_SIZE 1024
116 #define PACK_STACK_SIZE 8
118 #define TOK_HASH_SIZE 8192 /* must be a power of two */
119 #define TOK_ALLOC_INCR 512 /* must be a power of two */
120 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
122 /* token symbol management */
123 typedef struct TokenSym
{
124 struct TokenSym
*hash_next
;
125 struct Sym
*sym_define
; /* direct pointer to define */
126 struct Sym
*sym_label
; /* direct pointer to label */
127 struct Sym
*sym_struct
; /* direct pointer to structure */
128 struct Sym
*sym_identifier
; /* direct pointer to identifier */
129 int tok
; /* token number */
134 typedef struct CString
{
135 int size
; /* size in bytes */
136 void *data
; /* either 'char *' or 'int *' */
138 void *data_allocated
; /* if non NULL, data has been malloced */
141 /* type definition */
142 typedef struct CType
{
148 typedef union CValue
{
154 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
156 unsigned long long ull
;
157 struct CString
*cstr
;
163 typedef struct SValue
{
164 CType type
; /* type */
165 unsigned short r
; /* register + flags */
166 unsigned short r2
; /* second register, used for 'long long'
167 type. If not used, set to VT_CONST */
168 CValue c
; /* constant, if VT_CONST */
169 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
172 /* symbol management */
174 int v
; /* symbol token */
175 int r
; /* associated register */
176 int c
; /* associated number */
177 CType type
; /* associated type */
178 struct Sym
*next
; /* next related symbol */
179 struct Sym
*prev
; /* prev symbol in stack */
180 struct Sym
*prev_tok
; /* previous symbol for this token */
183 /* section definition */
184 /* XXX: use directly ELF structure for parameters ? */
185 /* special flag to indicate that the section should not be linked to
187 #define SHF_PRIVATE 0x80000000
189 typedef struct Section
{
190 unsigned long data_offset
; /* current data offset */
191 unsigned char *data
; /* section data */
192 unsigned long data_allocated
; /* used for realloc() handling */
193 int sh_name
; /* elf section name (only used during output) */
194 int sh_num
; /* elf section number */
195 int sh_type
; /* elf section type */
196 int sh_flags
; /* elf section flags */
197 int sh_info
; /* elf section info */
198 int sh_addralign
; /* elf section alignment */
199 int sh_entsize
; /* elf entry size */
200 unsigned long sh_size
; /* section size (only used during output) */
201 unsigned long sh_addr
; /* address at which the section is relocated */
202 unsigned long sh_offset
; /* address at which the section is relocated */
203 int nb_hashed_syms
; /* used to resize the hash table */
204 struct Section
*link
; /* link to another section */
205 struct Section
*reloc
; /* corresponding section for relocation, if any */
206 struct Section
*hash
; /* hash table for symbols */
207 struct Section
*next
;
208 char name
[1]; /* section name */
211 typedef struct DLLReference
{
216 /* GNUC attribute definition */
217 typedef struct AttributeDef
{
221 unsigned char func_call
; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */
222 unsigned char dllexport
;
225 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
226 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
227 #define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
229 /* stored in 'Sym.c' field */
230 #define FUNC_NEW 1 /* ansi function prototype */
231 #define FUNC_OLD 2 /* old function prototype */
232 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
234 /* stored in 'Sym.r' field */
235 #define FUNC_CDECL 0 /* standard c call */
236 #define FUNC_STDCALL 1 /* pascal c call */
237 #define FUNC_FASTCALL1 2 /* first param in %eax */
238 #define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
239 #define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
241 /* field 'Sym.t' for macros */
242 #define MACRO_OBJ 0 /* object like macro */
243 #define MACRO_FUNC 1 /* function like macro */
245 /* field 'Sym.r' for C labels */
246 #define LABEL_DEFINED 0 /* label is defined */
247 #define LABEL_FORWARD 1 /* label is forward defined */
248 #define LABEL_DECLARED 2 /* label is declared but never used */
250 /* type_decl() types */
251 #define TYPE_ABSTRACT 1 /* type without variable */
252 #define TYPE_DIRECT 2 /* type with variable */
254 #define IO_BUF_SIZE 8192
256 typedef struct BufferedFile
{
260 int line_num
; /* current line number - here to simplify code */
261 int ifndef_macro
; /* #ifndef macro / #endif search */
262 int ifndef_macro_saved
; /* saved ifndef_macro */
263 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
264 char inc_type
; /* type of include */
265 char inc_filename
[512]; /* filename specified by the user */
266 char filename
[1024]; /* current filename - here to simplify code */
267 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
270 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
271 #define CH_EOF (-1) /* end of file */
273 /* parsing state (used to save parser state to reparse part of the
274 source several times) */
275 typedef struct ParseState
{
282 /* used to record tokens */
283 typedef struct TokenString
{
290 /* include file cache, used to find files faster and also to eliminate
291 inclusion if the include file is protected by #ifndef ... #endif */
292 typedef struct CachedInclude
{
294 int hash_next
; /* -1 if none */
295 char type
; /* '"' or '>' to give include type */
296 char filename
[1]; /* path specified in #include */
299 #define CACHED_INCLUDES_HASH_SIZE 512
302 static struct BufferedFile
*file
;
305 static CString tokcstr
; /* current parsed string, if any */
306 /* additional informations about token */
307 static int tok_flags
;
308 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
309 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
310 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
312 static int *macro_ptr
, *macro_ptr_allocated
;
313 static int *unget_saved_macro_ptr
;
314 static int unget_saved_buffer
[TOK_MAX_SIZE
+ 1];
315 static int unget_buffer_enabled
;
316 static int parse_flags
;
317 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
318 #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */
319 #define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a
320 token. line feed is also
322 #define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
324 static Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
325 static Section
*cur_text_section
; /* current section where function code is
327 #ifdef CONFIG_TCC_ASM
328 static Section
*last_text_section
; /* to handle .previous asm directive */
330 /* bound check related sections */
331 static Section
*bounds_section
; /* contains global data bound description */
332 static Section
*lbounds_section
; /* contains local data bound description */
333 /* symbol sections */
334 static Section
*symtab_section
, *strtab_section
;
337 static Section
*stab_section
, *stabstr_section
;
339 /* loc : local variable index
340 ind : output code index
342 anon_sym: anonymous symbol index
344 static int rsym
, anon_sym
, ind
, loc
;
345 /* expression generation modifiers */
346 static int const_wanted
; /* true if constant wanted */
347 static int nocode_wanted
; /* true if no code generation wanted for an expression */
348 static int global_expr
; /* true if compound literals must be allocated
349 globally (used during initializers parsing */
350 static CType func_vt
; /* current function return type (used by return
353 static int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
354 static int tok_ident
;
355 static TokenSym
**table_ident
;
356 static TokenSym
*hash_ident
[TOK_HASH_SIZE
];
357 static char token_buf
[STRING_MAX_SIZE
+ 1];
358 static char *funcname
;
359 static Sym
*global_stack
, *local_stack
;
360 static Sym
*define_stack
;
361 static Sym
*global_label_stack
, *local_label_stack
;
362 /* symbol allocator */
363 #define SYM_POOL_NB (8192 / sizeof(Sym))
364 static Sym
*sym_free_first
;
366 static SValue vstack
[VSTACK_SIZE
], *vtop
;
367 /* some predefined types */
368 static CType char_pointer_type
, func_old_type
, int_type
;
369 /* true if isid(c) || isnum(c) */
370 static unsigned char isidnum_table
[256];
372 /* compile with debug symbol (and use them if error during execution) */
373 static int do_debug
= 0;
375 /* compile with built-in memory and bounds checker */
376 static int do_bounds_check
= 0;
378 /* display benchmark infos */
380 static int do_bench
= 0;
382 static int total_lines
;
383 static int total_bytes
;
385 /* use GNU C extensions */
386 static int gnu_ext
= 1;
388 /* use Tiny C extensions */
389 static int tcc_ext
= 1;
391 /* max number of callers shown if error */
392 static int num_callers
= 6;
393 static const char **rt_bound_error_msg
;
395 /* XXX: get rid of this ASAP */
396 static struct TCCState
*tcc_state
;
398 /* give the path of the tcc libraries */
399 static const char *tcc_lib_path
= CONFIG_TCCDIR
;
404 BufferedFile
**include_stack_ptr
;
405 int *ifdef_stack_ptr
;
407 /* include file handling */
408 char **include_paths
;
409 int nb_include_paths
;
410 char **sysinclude_paths
;
411 int nb_sysinclude_paths
;
412 CachedInclude
**cached_includes
;
413 int nb_cached_includes
;
415 char **library_paths
;
416 int nb_library_paths
;
418 /* array of all loaded dlls (including those referenced by loaded
420 DLLReference
**loaded_dlls
;
425 int nb_sections
; /* number of sections, including first dummy section */
430 unsigned long *got_offsets
;
432 /* give the correspondance from symtab indexes to dynsym indexes */
433 int *symtab_to_dynsym
;
435 /* temporary dynamic symbol sections (for dll loading) */
436 Section
*dynsymtab_section
;
437 /* exported dynamic symbol section */
440 int nostdinc
; /* if true, no standard headers are added */
441 int nostdlib
; /* if true, no standard libraries are added */
443 int nocommon
; /* if true, do not use common symbols for .bss data */
445 /* if true, static linking is performed */
448 /* if true, all symbols are exported */
451 /* if true, only link in referenced objects from archive */
454 /* address of text section */
455 unsigned long text_addr
;
458 /* output format, see TCC_OUTPUT_FORMAT_xxx */
461 /* C language options */
462 int char_is_unsigned
;
464 /* warning switches */
465 int warn_write_strings
;
466 int warn_unsupported
;
469 int warn_implicit_function_declaration
;
473 void (*error_func
)(void *opaque
, const char *msg
);
474 int error_set_jmp_enabled
;
475 jmp_buf error_jmp_buf
;
478 /* tiny assembler state */
481 /* see include_stack_ptr */
482 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
484 /* see ifdef_stack_ptr */
485 int ifdef_stack
[IFDEF_STACK_SIZE
];
487 /* see cached_includes */
488 int cached_includes_hash
[CACHED_INCLUDES_HASH_SIZE
];
491 int pack_stack
[PACK_STACK_SIZE
];
495 /* The current value can be: */
496 #define VT_VALMASK 0x00ff
497 #define VT_CONST 0x00f0 /* constant in vc
498 (must be first non register value) */
499 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
500 #define VT_LOCAL 0x00f2 /* offset on stack */
501 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
502 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
503 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
504 #define VT_LVAL 0x0100 /* var is an lvalue */
505 #define VT_SYM 0x0200 /* a symbol value is added */
506 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
507 char/short stored in integer registers) */
508 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
509 dereferencing value */
510 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
511 bounding function call point is in vc */
512 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
513 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
514 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
515 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
518 #define VT_INT 0 /* integer type */
519 #define VT_BYTE 1 /* signed byte type */
520 #define VT_SHORT 2 /* short type */
521 #define VT_VOID 3 /* void type */
522 #define VT_PTR 4 /* pointer */
523 #define VT_ENUM 5 /* enum definition */
524 #define VT_FUNC 6 /* function type */
525 #define VT_STRUCT 7 /* struct/union definition */
526 #define VT_FLOAT 8 /* IEEE float */
527 #define VT_DOUBLE 9 /* IEEE double */
528 #define VT_LDOUBLE 10 /* IEEE long double */
529 #define VT_BOOL 11 /* ISOC99 boolean type */
530 #define VT_LLONG 12 /* 64 bit integer */
531 #define VT_LONG 13 /* long integer (NEVER USED as type, only
533 #define VT_BTYPE 0x000f /* mask for basic type */
534 #define VT_UNSIGNED 0x0010 /* unsigned type */
535 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
536 #define VT_BITFIELD 0x0040 /* bitfield modifier */
537 #define VT_CONSTANT 0x0800 /* const modifier */
538 #define VT_VOLATILE 0x1000 /* volatile modifier */
539 #define VT_SIGNED 0x2000 /* signed type */
542 #define VT_EXTERN 0x00000080 /* extern definition */
543 #define VT_STATIC 0x00000100 /* static variable */
544 #define VT_TYPEDEF 0x00000200 /* typedef definition */
545 #define VT_INLINE 0x00000400 /* inline definition */
547 #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */
549 /* type mask (except storage) */
550 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
551 #define VT_TYPE (~(VT_STORAGE))
555 /* warning: the following compare tokens depend on i386 asm code */
567 #define TOK_LAND 0xa0
571 #define TOK_MID 0xa3 /* inc/dec, to void constant */
573 #define TOK_UDIV 0xb0 /* unsigned division */
574 #define TOK_UMOD 0xb1 /* unsigned modulo */
575 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
576 #define TOK_CINT 0xb3 /* number in tokc */
577 #define TOK_CCHAR 0xb4 /* char constant in tokc */
578 #define TOK_STR 0xb5 /* pointer to string in tokc */
579 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
580 #define TOK_LCHAR 0xb7
581 #define TOK_LSTR 0xb8
582 #define TOK_CFLOAT 0xb9 /* float constant */
583 #define TOK_LINENUM 0xba /* line number info */
584 #define TOK_CDOUBLE 0xc0 /* double constant */
585 #define TOK_CLDOUBLE 0xc1 /* long double constant */
586 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
587 #define TOK_ADDC1 0xc3 /* add with carry generation */
588 #define TOK_ADDC2 0xc4 /* add with carry use */
589 #define TOK_SUBC1 0xc5 /* add with carry generation */
590 #define TOK_SUBC2 0xc6 /* add with carry use */
591 #define TOK_CUINT 0xc8 /* unsigned int constant */
592 #define TOK_CLLONG 0xc9 /* long long constant */
593 #define TOK_CULLONG 0xca /* unsigned long long constant */
594 #define TOK_ARROW 0xcb
595 #define TOK_DOTS 0xcc /* three dots */
596 #define TOK_SHR 0xcd /* unsigned shift right */
597 #define TOK_PPNUM 0xce /* preprocessor number */
599 #define TOK_SHL 0x01 /* shift left */
600 #define TOK_SAR 0x02 /* signed shift right */
602 /* assignement operators : normal operator or 0x80 */
603 #define TOK_A_MOD 0xa5
604 #define TOK_A_AND 0xa6
605 #define TOK_A_MUL 0xaa
606 #define TOK_A_ADD 0xab
607 #define TOK_A_SUB 0xad
608 #define TOK_A_DIV 0xaf
609 #define TOK_A_XOR 0xde
610 #define TOK_A_OR 0xfc
611 #define TOK_A_SHL 0x81
612 #define TOK_A_SAR 0x82
615 #define offsetof(type, field) ((size_t) &((type *)0)->field)
619 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
622 /* WARNING: the content of this string encodes token numbers */
623 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";
625 #define TOK_EOF (-1) /* end of file */
626 #define TOK_LINEFEED 10 /* line feed */
628 /* all identificators and strings have token above that */
629 #define TOK_IDENT 256
631 /* only used for i386 asm opcodes definitions */
632 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
635 DEF(TOK_ASM_ ## x ## b, #x "b") \
636 DEF(TOK_ASM_ ## x ## w, #x "w") \
637 DEF(TOK_ASM_ ## x ## l, #x "l") \
638 DEF(TOK_ASM_ ## x, #x)
641 DEF(TOK_ASM_ ## x ## w, #x "w") \
642 DEF(TOK_ASM_ ## x ## l, #x "l") \
643 DEF(TOK_ASM_ ## x, #x)
646 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
647 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
648 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
649 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
652 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
653 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
656 #define DEF_ASMTEST(x) \
688 #define TOK_ASM_int TOK_INT
691 TOK_LAST
= TOK_IDENT
- 1,
692 #define DEF(id, str) id,
697 static const char tcc_keywords
[] =
698 #define DEF(id, str) str "\0"
703 #define TOK_UIDENT TOK_DEFINE
706 int __stdcall
GetModuleFileNameA(void *, char *, int);
707 void *__stdcall
GetProcAddress(void *, const char *);
708 void *__stdcall
GetModuleHandleA(const char *);
709 void *__stdcall
LoadLibraryA(const char *);
710 int __stdcall
FreeConsole(void);
712 #define snprintf _snprintf
713 #define vsnprintf _vsnprintf
716 #if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)
717 /* currently incorrect */
718 long double strtold(const char *nptr
, char **endptr
)
720 return (long double)strtod(nptr
, endptr
);
722 float strtof(const char *nptr
, char **endptr
)
724 return (float)strtod(nptr
, endptr
);
727 /* XXX: need to define this to use them in non ISOC99 context */
728 extern float strtof (const char *__nptr
, char **__endptr
);
729 extern long double strtold (const char *__nptr
, char **__endptr
);
732 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
733 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
734 static const char *tcc_basename(const char *name
);
736 static void next(void);
737 static void next_nomacro(void);
738 static void parse_expr_type(CType
*type
);
739 static void expr_type(CType
*type
);
740 static void unary_type(CType
*type
);
741 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
742 int case_reg
, int is_expr
);
743 static int expr_const(void);
744 static void expr_eq(void);
745 static void gexpr(void);
746 static void gen_inline_functions(void);
747 static void decl(int l
);
748 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
749 int first
, int size_only
);
750 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
751 int has_init
, int v
, int scope
);
753 void gv2(int rc1
, int rc2
);
754 void move_reg(int r
, int s
);
755 void save_regs(int n
);
756 void save_reg(int r
);
761 int get_reg_ex(int rc
,int rc2
);
763 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
764 const int *macro_str
, int can_read_stream
);
766 void force_charshort_cast(int t
);
767 static void gen_cast(CType
*type
);
769 static Sym
*sym_find(int v
);
770 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
773 static int type_size(CType
*type
, int *a
);
774 static inline CType
*pointed_type(CType
*type
);
775 static int pointed_size(CType
*type
);
776 static int lvalue_type(int t
);
777 static int parse_btype(CType
*type
, AttributeDef
*ad
);
778 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
779 static int is_compatible_types(CType
*type1
, CType
*type2
);
781 int ieee_finite(double d
);
782 void error(const char *fmt
, ...);
786 void lexpand_nr(void);
787 static void vpush_global_sym(CType
*type
, int v
);
788 void vset(CType
*type
, int r
, int v
);
789 void type_to_str(char *buf
, int buf_size
,
790 CType
*type
, const char *varstr
);
791 char *get_tok_str(int v
, CValue
*cv
);
792 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
793 unsigned long offset
, unsigned long size
);
794 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
796 /* section generation */
797 static void section_realloc(Section
*sec
, unsigned long new_size
);
798 static void *section_ptr_add(Section
*sec
, unsigned long size
);
799 static void put_extern_sym(Sym
*sym
, Section
*section
,
800 unsigned long value
, unsigned long size
);
801 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
802 static int put_elf_str(Section
*s
, const char *sym
);
803 static int put_elf_sym(Section
*s
,
804 unsigned long value
, unsigned long size
,
805 int info
, int other
, int shndx
, const char *name
);
806 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
807 int info
, int other
, int sh_num
, const char *name
);
808 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
809 int type
, int symbol
);
810 static void put_stabs(const char *str
, int type
, int other
, int desc
,
811 unsigned long value
);
812 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
813 unsigned long value
, Section
*sec
, int sym_index
);
814 static void put_stabn(int type
, int other
, int desc
, int value
);
815 static void put_stabd(int type
, int other
, int desc
);
816 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
818 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
819 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
820 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
823 int tcc_output_coff(TCCState
*s1
, FILE *f
);
826 void *resolve_sym(TCCState
*s1
, const char *sym
, int type
);
827 int pe_load_def_file(struct TCCState
*s1
, FILE *fp
);
828 void pe_setup_paths(struct TCCState
*s1
, int *p_output_type
, const char **p_outfile
, char *first_file
);
829 unsigned long pe_add_runtime(struct TCCState
*s1
);
830 int tcc_output_pe(struct TCCState
*s1
, const char *filename
);
834 #ifdef CONFIG_TCC_ASM
836 typedef struct ExprValue
{
841 #define MAX_ASM_OPERANDS 30
843 typedef struct ASMOperand
{
844 int id
; /* GCC 3 optionnal identifier (0 if number only supported */
846 char asm_str
[16]; /* computed asm string for operand */
847 SValue
*vt
; /* C value of the expression */
848 int ref_index
; /* if >= 0, gives reference to a output constraint */
849 int input_index
; /* if >= 0, gives reference to an input constraint */
850 int priority
; /* priority, used to assign registers */
851 int reg
; /* if >= 0, register number used for this operand */
852 int is_llong
; /* true if double register value */
853 int is_memory
; /* true if memory operand */
854 int is_rw
; /* for '+' modifier */
857 static void asm_expr(TCCState
*s1
, ExprValue
*pe
);
858 static int asm_int_expr(TCCState
*s1
);
859 static int find_constraint(ASMOperand
*operands
, int nb_operands
,
860 const char *name
, const char **pp
);
862 static int tcc_assemble(TCCState
*s1
, int do_preprocess
);
866 static void asm_instr(void);
867 static void asm_global_instr(void);
869 /* true if float/double/long double type */
870 static inline int is_float(int t
)
874 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
877 #ifdef TCC_TARGET_I386
878 #include "i386-gen.c"
881 #ifdef TCC_TARGET_ARM
885 #ifdef TCC_TARGET_C67
889 #ifdef CONFIG_TCC_STATIC
891 #define RTLD_LAZY 0x001
892 #define RTLD_NOW 0x002
893 #define RTLD_GLOBAL 0x100
894 #define RTLD_DEFAULT NULL
896 /* dummy function for profiling */
897 void *dlopen(const char *filename
, int flag
)
902 const char *dlerror(void)
907 typedef struct TCCSyms
{
912 #define TCCSYM(a) { #a, &a, },
914 /* add the symbol you want here if no dynamic linking is done */
915 static TCCSyms tcc_syms
[] = {
916 #if !defined(CONFIG_TCCBOOT)
925 void *resolve_sym(TCCState
*s1
, const char *symbol
, int type
)
929 while (p
->str
!= NULL
) {
930 if (!strcmp(p
->str
, symbol
))
937 #elif !defined(WIN32)
941 void *resolve_sym(TCCState
*s1
, const char *sym
, int type
)
943 return dlsym(RTLD_DEFAULT
, sym
);
948 /********************************************************/
950 /* we use our own 'finite' function to avoid potential problems with
951 non standard math libs */
952 /* XXX: endianness dependent */
953 int ieee_finite(double d
)
956 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
959 /* copy a string and truncate it. */
960 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
967 q_end
= buf
+ buf_size
- 1;
979 /* strcat and truncate. */
980 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
985 pstrcpy(buf
+ len
, buf_size
- len
, s
);
989 static int strstart(const char *str
, const char *val
, const char **ptr
)
1005 /* memory management */
1011 static inline void tcc_free(void *ptr
)
1014 mem_cur_size
-= malloc_usable_size(ptr
);
1019 static void *tcc_malloc(unsigned long size
)
1024 error("memory full");
1026 mem_cur_size
+= malloc_usable_size(ptr
);
1027 if (mem_cur_size
> mem_max_size
)
1028 mem_max_size
= mem_cur_size
;
1033 static void *tcc_mallocz(unsigned long size
)
1036 ptr
= tcc_malloc(size
);
1037 memset(ptr
, 0, size
);
1041 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
1045 mem_cur_size
-= malloc_usable_size(ptr
);
1047 ptr1
= realloc(ptr
, size
);
1049 /* NOTE: count not correct if alloc error, but not critical */
1050 mem_cur_size
+= malloc_usable_size(ptr1
);
1051 if (mem_cur_size
> mem_max_size
)
1052 mem_max_size
= mem_cur_size
;
1057 static char *tcc_strdup(const char *str
)
1060 ptr
= tcc_malloc(strlen(str
) + 1);
1065 #define free(p) use_tcc_free(p)
1066 #define malloc(s) use_tcc_malloc(s)
1067 #define realloc(p, s) use_tcc_realloc(p, s)
1069 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
1076 /* every power of two we double array size */
1077 if ((nb
& (nb
- 1)) == 0) {
1082 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
1084 error("memory full");
1091 /* symbol allocator */
1092 static Sym
*__sym_malloc(void)
1094 Sym
*sym_pool
, *sym
, *last_sym
;
1097 sym_pool
= tcc_malloc(SYM_POOL_NB
* sizeof(Sym
));
1099 last_sym
= sym_free_first
;
1101 for(i
= 0; i
< SYM_POOL_NB
; i
++) {
1102 sym
->next
= last_sym
;
1106 sym_free_first
= last_sym
;
1110 static inline Sym
*sym_malloc(void)
1113 sym
= sym_free_first
;
1115 sym
= __sym_malloc();
1116 sym_free_first
= sym
->next
;
1120 static inline void sym_free(Sym
*sym
)
1122 sym
->next
= sym_free_first
;
1123 sym_free_first
= sym
;
1126 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
1130 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
1131 strcpy(sec
->name
, name
);
1132 sec
->sh_type
= sh_type
;
1133 sec
->sh_flags
= sh_flags
;
1140 sec
->sh_addralign
= 4;
1143 sec
->sh_addralign
= 1;
1146 sec
->sh_addralign
= 32; /* default conservative alignment */
1150 /* only add section if not private */
1151 if (!(sh_flags
& SHF_PRIVATE
)) {
1152 sec
->sh_num
= s1
->nb_sections
;
1153 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
1158 static void free_section(Section
*s
)
1164 /* realloc section and set its content to zero */
1165 static void section_realloc(Section
*sec
, unsigned long new_size
)
1168 unsigned char *data
;
1170 size
= sec
->data_allocated
;
1173 while (size
< new_size
)
1175 data
= tcc_realloc(sec
->data
, size
);
1177 error("memory full");
1178 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
1180 sec
->data_allocated
= size
;
1183 /* reserve at least 'size' bytes in section 'sec' from
1184 sec->data_offset. */
1185 static void *section_ptr_add(Section
*sec
, unsigned long size
)
1187 unsigned long offset
, offset1
;
1189 offset
= sec
->data_offset
;
1190 offset1
= offset
+ size
;
1191 if (offset1
> sec
->data_allocated
)
1192 section_realloc(sec
, offset1
);
1193 sec
->data_offset
= offset1
;
1194 return sec
->data
+ offset
;
1197 /* return a reference to a section, and create it if it does not
1199 Section
*find_section(TCCState
*s1
, const char *name
)
1203 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1204 sec
= s1
->sections
[i
];
1205 if (!strcmp(name
, sec
->name
))
1208 /* sections are created as PROGBITS */
1209 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
1212 #define SECTION_ABS ((void *)1)
1214 /* update sym->c so that it points to an external symbol in section
1215 'section' with value 'value' */
1216 static void put_extern_sym(Sym
*sym
, Section
*section
,
1217 unsigned long value
, unsigned long size
)
1219 int sym_type
, sym_bind
, sh_num
, info
;
1223 if (section
== NULL
)
1225 else if (section
== SECTION_ABS
)
1228 sh_num
= section
->sh_num
;
1230 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
)
1231 sym_type
= STT_FUNC
;
1233 sym_type
= STT_OBJECT
;
1234 if (sym
->type
.t
& VT_STATIC
)
1235 sym_bind
= STB_LOCAL
;
1237 sym_bind
= STB_GLOBAL
;
1239 name
= get_tok_str(sym
->v
, NULL
);
1240 #ifdef CONFIG_TCC_BCHECK
1241 if (do_bounds_check
) {
1244 /* XXX: avoid doing that for statics ? */
1245 /* if bound checking is activated, we change some function
1246 names by adding the "__bound" prefix */
1249 /* XXX: we rely only on malloc hooks */
1261 strcpy(buf
, "__bound_");
1268 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
1269 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, 0, sh_num
, name
);
1271 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
1272 esym
->st_value
= value
;
1273 esym
->st_size
= size
;
1274 esym
->st_shndx
= sh_num
;
1278 /* add a new relocation entry to symbol 'sym' in section 's' */
1279 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
1282 put_extern_sym(sym
, NULL
, 0, 0);
1283 /* now we can add ELF relocation info */
1284 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
1287 static inline int isid(int c
)
1289 return (c
>= 'a' && c
<= 'z') ||
1290 (c
>= 'A' && c
<= 'Z') ||
1294 static inline int isnum(int c
)
1296 return c
>= '0' && c
<= '9';
1299 static inline int isoct(int c
)
1301 return c
>= '0' && c
<= '7';
1304 static inline int toup(int c
)
1306 if (c
>= 'a' && c
<= 'z')
1307 return c
- 'a' + 'A';
1312 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1316 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1319 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1323 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1327 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1334 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1335 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1336 (*f
)->filename
, (*f
)->line_num
);
1337 if (file
->line_num
> 0) {
1338 strcat_printf(buf
, sizeof(buf
),
1339 "%s:%d: ", file
->filename
, file
->line_num
);
1341 strcat_printf(buf
, sizeof(buf
),
1342 "%s: ", file
->filename
);
1345 strcat_printf(buf
, sizeof(buf
),
1349 strcat_printf(buf
, sizeof(buf
), "warning: ");
1350 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1352 if (!s1
->error_func
) {
1353 /* default case: stderr */
1354 fprintf(stderr
, "%s\n", buf
);
1356 s1
->error_func(s1
->error_opaque
, buf
);
1358 if (!is_warning
|| s1
->warn_error
)
1363 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1364 void (*error_func
)(void *opaque
, const char *msg
))
1366 s
->error_opaque
= error_opaque
;
1367 s
->error_func
= error_func
;
1371 /* error without aborting current compilation */
1372 void error_noabort(const char *fmt
, ...)
1374 TCCState
*s1
= tcc_state
;
1378 error1(s1
, 0, fmt
, ap
);
1382 void error(const char *fmt
, ...)
1384 TCCState
*s1
= tcc_state
;
1388 error1(s1
, 0, fmt
, ap
);
1390 /* better than nothing: in some cases, we accept to handle errors */
1391 if (s1
->error_set_jmp_enabled
) {
1392 longjmp(s1
->error_jmp_buf
, 1);
1394 /* XXX: eliminate this someday */
1399 void expect(const char *msg
)
1401 error("%s expected", msg
);
1404 void warning(const char *fmt
, ...)
1406 TCCState
*s1
= tcc_state
;
1413 error1(s1
, 1, fmt
, ap
);
1420 error("'%c' expected", c
);
1424 static void test_lvalue(void)
1426 if (!(vtop
->r
& VT_LVAL
))
1430 /* allocate a new token */
1431 static TokenSym
*tok_alloc_new(TokenSym
**pts
, const char *str
, int len
)
1433 TokenSym
*ts
, **ptable
;
1436 if (tok_ident
>= SYM_FIRST_ANOM
)
1437 error("memory full");
1439 /* expand token table if needed */
1440 i
= tok_ident
- TOK_IDENT
;
1441 if ((i
% TOK_ALLOC_INCR
) == 0) {
1442 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1444 error("memory full");
1445 table_ident
= ptable
;
1448 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1449 table_ident
[i
] = ts
;
1450 ts
->tok
= tok_ident
++;
1451 ts
->sym_define
= NULL
;
1452 ts
->sym_label
= NULL
;
1453 ts
->sym_struct
= NULL
;
1454 ts
->sym_identifier
= NULL
;
1456 ts
->hash_next
= NULL
;
1457 memcpy(ts
->str
, str
, len
);
1458 ts
->str
[len
] = '\0';
1463 #define TOK_HASH_INIT 1
1464 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1466 /* find a token and add it if not found */
1467 static TokenSym
*tok_alloc(const char *str
, int len
)
1469 TokenSym
*ts
, **pts
;
1475 h
= TOK_HASH_FUNC(h
, ((unsigned char *)str
)[i
]);
1476 h
&= (TOK_HASH_SIZE
- 1);
1478 pts
= &hash_ident
[h
];
1483 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1485 pts
= &(ts
->hash_next
);
1487 return tok_alloc_new(pts
, str
, len
);
1490 /* CString handling */
1492 static void cstr_realloc(CString
*cstr
, int new_size
)
1497 size
= cstr
->size_allocated
;
1499 size
= 8; /* no need to allocate a too small first string */
1500 while (size
< new_size
)
1502 data
= tcc_realloc(cstr
->data_allocated
, size
);
1504 error("memory full");
1505 cstr
->data_allocated
= data
;
1506 cstr
->size_allocated
= size
;
1511 static inline void cstr_ccat(CString
*cstr
, int ch
)
1514 size
= cstr
->size
+ 1;
1515 if (size
> cstr
->size_allocated
)
1516 cstr_realloc(cstr
, size
);
1517 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1521 static void cstr_cat(CString
*cstr
, const char *str
)
1533 /* add a wide char */
1534 static void cstr_wccat(CString
*cstr
, int ch
)
1537 size
= cstr
->size
+ sizeof(int);
1538 if (size
> cstr
->size_allocated
)
1539 cstr_realloc(cstr
, size
);
1540 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1544 static void cstr_new(CString
*cstr
)
1546 memset(cstr
, 0, sizeof(CString
));
1549 /* free string and reset it to NULL */
1550 static void cstr_free(CString
*cstr
)
1552 tcc_free(cstr
->data_allocated
);
1556 #define cstr_reset(cstr) cstr_free(cstr)
1558 /* XXX: unicode ? */
1559 static void add_char(CString
*cstr
, int c
)
1561 if (c
== '\'' || c
== '\"' || c
== '\\') {
1562 /* XXX: could be more precise if char or string */
1563 cstr_ccat(cstr
, '\\');
1565 if (c
>= 32 && c
<= 126) {
1568 cstr_ccat(cstr
, '\\');
1570 cstr_ccat(cstr
, 'n');
1572 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1573 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1574 cstr_ccat(cstr
, '0' + (c
& 7));
1579 /* XXX: buffer overflow */
1580 /* XXX: float tokens */
1581 char *get_tok_str(int v
, CValue
*cv
)
1583 static char buf
[STRING_MAX_SIZE
+ 1];
1584 static CString cstr_buf
;
1590 /* NOTE: to go faster, we give a fixed buffer for small strings */
1591 cstr_reset(&cstr_buf
);
1592 cstr_buf
.data
= buf
;
1593 cstr_buf
.size_allocated
= sizeof(buf
);
1599 /* XXX: not quite exact, but only useful for testing */
1600 sprintf(p
, "%u", cv
->ui
);
1604 /* XXX: not quite exact, but only useful for testing */
1605 sprintf(p
, "%Lu", cv
->ull
);
1609 cstr_ccat(&cstr_buf
, '\'');
1610 add_char(&cstr_buf
, cv
->i
);
1611 cstr_ccat(&cstr_buf
, '\'');
1612 cstr_ccat(&cstr_buf
, '\0');
1616 len
= cstr
->size
- 1;
1618 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1619 cstr_ccat(&cstr_buf
, '\0');
1624 cstr_ccat(&cstr_buf
, '\"');
1626 len
= cstr
->size
- 1;
1628 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1630 len
= (cstr
->size
/ sizeof(int)) - 1;
1632 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1634 cstr_ccat(&cstr_buf
, '\"');
1635 cstr_ccat(&cstr_buf
, '\0');
1644 return strcpy(p
, "<<=");
1646 return strcpy(p
, ">>=");
1648 if (v
< TOK_IDENT
) {
1649 /* search in two bytes table */
1663 } else if (v
< tok_ident
) {
1664 return table_ident
[v
- TOK_IDENT
]->str
;
1665 } else if (v
>= SYM_FIRST_ANOM
) {
1666 /* special name for anonymous symbol */
1667 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1669 /* should never happen */
1674 return cstr_buf
.data
;
1677 /* push, without hashing */
1678 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1692 /* find a symbol and return its associated structure. 's' is the top
1693 of the symbol stack */
1694 static Sym
*sym_find2(Sym
*s
, int v
)
1704 /* structure lookup */
1705 static inline Sym
*struct_find(int v
)
1708 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1710 return table_ident
[v
]->sym_struct
;
1713 /* find an identifier */
1714 static inline Sym
*sym_find(int v
)
1717 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1719 return table_ident
[v
]->sym_identifier
;
1722 /* push a given symbol on the symbol stack */
1723 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1732 s
= sym_push2(ps
, v
, type
->t
, c
);
1733 s
->type
.ref
= type
->ref
;
1735 /* don't record fields or anonymous symbols */
1737 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1738 /* record symbol in token array */
1739 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1741 ps
= &ts
->sym_struct
;
1743 ps
= &ts
->sym_identifier
;
1750 /* push a global identifier */
1751 static Sym
*global_identifier_push(int v
, int t
, int c
)
1754 s
= sym_push2(&global_stack
, v
, t
, c
);
1755 /* don't record anonymous symbol */
1756 if (v
< SYM_FIRST_ANOM
) {
1757 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1758 /* modify the top most local identifier, so that
1759 sym_identifier will point to 's' when popped */
1761 ps
= &(*ps
)->prev_tok
;
1768 /* pop symbols until top reaches 'b' */
1769 static void sym_pop(Sym
**ptop
, Sym
*b
)
1779 /* remove symbol in token array */
1781 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1782 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1784 ps
= &ts
->sym_struct
;
1786 ps
= &ts
->sym_identifier
;
1797 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1802 fd
= open(filename
, O_RDONLY
| O_BINARY
);
1805 bf
= tcc_malloc(sizeof(BufferedFile
));
1811 bf
->buf_ptr
= bf
->buffer
;
1812 bf
->buf_end
= bf
->buffer
;
1813 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1814 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1816 bf
->ifndef_macro
= 0;
1817 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1818 // printf("opening '%s'\n", filename);
1822 void tcc_close(BufferedFile
*bf
)
1824 total_lines
+= bf
->line_num
;
1829 /* fill input buffer and peek next char */
1830 static int tcc_peekc_slow(BufferedFile
*bf
)
1833 /* only tries to read if really end of buffer */
1834 if (bf
->buf_ptr
>= bf
->buf_end
) {
1836 #if defined(PARSE_DEBUG)
1841 len
= read(bf
->fd
, bf
->buffer
, len
);
1848 bf
->buf_ptr
= bf
->buffer
;
1849 bf
->buf_end
= bf
->buffer
+ len
;
1850 *bf
->buf_end
= CH_EOB
;
1852 if (bf
->buf_ptr
< bf
->buf_end
) {
1853 return bf
->buf_ptr
[0];
1855 bf
->buf_ptr
= bf
->buf_end
;
1860 /* return the current character, handling end of block if necessary
1862 static int handle_eob(void)
1864 return tcc_peekc_slow(file
);
1867 /* read next char from current input file and handle end of input buffer */
1868 static inline void inp(void)
1870 ch
= *(++(file
->buf_ptr
));
1871 /* end of buffer/file handling */
1876 /* handle '\[\r]\n' */
1877 static void handle_stray(void)
1879 while (ch
== '\\') {
1884 } else if (ch
== '\r') {
1892 error("stray '\\' in program");
1897 /* skip the stray and handle the \\n case. Output an error if
1898 incorrect char after the stray */
1899 static int handle_stray1(uint8_t *p
)
1903 if (p
>= file
->buf_end
) {
1920 /* handle just the EOB case, but not stray */
1921 #define PEEKC_EOB(c, p)\
1932 /* handle the complicated stray case */
1933 #define PEEKC(c, p)\
1938 c = handle_stray1(p);\
1943 /* input with '\[\r]\n' handling. Note that this function cannot
1944 handle other characters after '\', so you cannot call it inside
1945 strings or comments */
1946 static void minp(void)
1954 /* single line C++ comments */
1955 static uint8_t *parse_line_comment(uint8_t *p
)
1963 if (c
== '\n' || c
== CH_EOF
) {
1965 } else if (c
== '\\') {
1974 } else if (c
== '\r') {
1992 static uint8_t *parse_comment(uint8_t *p
)
1998 /* fast skip loop */
2001 if (c
== '\n' || c
== '*' || c
== '\\')
2005 if (c
== '\n' || c
== '*' || c
== '\\')
2009 /* now we can handle all the cases */
2013 } else if (c
== '*') {
2019 } else if (c
== '/') {
2020 goto end_of_comment
;
2021 } else if (c
== '\\') {
2026 /* skip '\[\r]\n', otherwise just skip the stray */
2032 } else if (c
== '\r') {
2049 /* stray, eob or eof */
2054 error("unexpected end of file in comment");
2055 } else if (c
== '\\') {
2067 /* space exlcuding newline */
2068 static inline int is_space(int ch
)
2070 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
2073 static inline void skip_spaces(void)
2075 while (is_space(ch
))
2079 /* parse a string without interpreting escapes */
2080 static uint8_t *parse_pp_string(uint8_t *p
,
2081 int sep
, CString
*str
)
2089 } else if (c
== '\\') {
2094 unterminated_string
:
2095 /* XXX: indicate line number of start of string */
2096 error("missing terminating %c character", sep
);
2097 } else if (c
== '\\') {
2098 /* escape : just skip \[\r]\n */
2103 } else if (c
== '\r') {
2106 expect("'\n' after '\r'");
2109 } else if (c
== CH_EOF
) {
2110 goto unterminated_string
;
2113 cstr_ccat(str
, '\\');
2119 } else if (c
== '\n') {
2122 } else if (c
== '\r') {
2126 cstr_ccat(str
, '\r');
2142 /* skip block of text until #else, #elif or #endif. skip also pairs of
2144 void preprocess_skip(void)
2146 int a
, start_of_line
, c
;
2173 } else if (c
== '\\') {
2174 /* XXX: incorrect: should not give an error */
2175 ch
= file
->buf_ptr
[0];
2183 p
= parse_pp_string(p
, c
, NULL
);
2192 p
= parse_comment(p
);
2193 } else if (ch
== '/') {
2194 p
= parse_line_comment(p
);
2200 if (start_of_line
) {
2205 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
2207 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
2209 else if (tok
== TOK_ENDIF
)
2223 /* ParseState handling */
2225 /* XXX: currently, no include file info is stored. Thus, we cannot display
2226 accurate messages if the function or data definition spans multiple
2229 /* save current parse state in 's' */
2230 void save_parse_state(ParseState
*s
)
2232 s
->line_num
= file
->line_num
;
2233 s
->macro_ptr
= macro_ptr
;
2238 /* restore parse state from 's' */
2239 void restore_parse_state(ParseState
*s
)
2241 file
->line_num
= s
->line_num
;
2242 macro_ptr
= s
->macro_ptr
;
2247 /* return the number of additional 'ints' necessary to store the
2249 static inline int tok_ext_size(int t
)
2263 error("unsupported token");
2270 return LDOUBLE_SIZE
/ 4;
2276 /* token string handling */
2278 static inline void tok_str_new(TokenString
*s
)
2282 s
->allocated_len
= 0;
2283 s
->last_line_num
= -1;
2286 static void tok_str_free(int *str
)
2291 static int *tok_str_realloc(TokenString
*s
)
2295 if (s
->allocated_len
== 0) {
2298 len
= s
->allocated_len
* 2;
2300 str
= tcc_realloc(s
->str
, len
* sizeof(int));
2302 error("memory full");
2303 s
->allocated_len
= len
;
2308 static void tok_str_add(TokenString
*s
, int t
)
2314 if (len
>= s
->allocated_len
)
2315 str
= tok_str_realloc(s
);
2320 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
2327 /* allocate space for worst case */
2328 if (len
+ TOK_MAX_SIZE
> s
->allocated_len
)
2329 str
= tok_str_realloc(s
);
2338 str
[len
++] = cv
->tab
[0];
2347 nb_words
= (sizeof(CString
) + cv
->cstr
->size
+ 3) >> 2;
2348 while ((len
+ nb_words
) > s
->allocated_len
)
2349 str
= tok_str_realloc(s
);
2350 cstr
= (CString
*)(str
+ len
);
2352 cstr
->size
= cv
->cstr
->size
;
2353 cstr
->data_allocated
= NULL
;
2354 cstr
->size_allocated
= cstr
->size
;
2355 memcpy((char *)cstr
+ sizeof(CString
),
2356 cv
->cstr
->data
, cstr
->size
);
2363 #if LDOUBLE_SIZE == 8
2366 str
[len
++] = cv
->tab
[0];
2367 str
[len
++] = cv
->tab
[1];
2369 #if LDOUBLE_SIZE == 12
2371 str
[len
++] = cv
->tab
[0];
2372 str
[len
++] = cv
->tab
[1];
2373 str
[len
++] = cv
->tab
[2];
2374 #elif LDOUBLE_SIZE != 8
2375 #error add long double size support
2384 /* add the current parse token in token string 's' */
2385 static void tok_str_add_tok(TokenString
*s
)
2389 /* save line number info */
2390 if (file
->line_num
!= s
->last_line_num
) {
2391 s
->last_line_num
= file
->line_num
;
2392 cval
.i
= s
->last_line_num
;
2393 tok_str_add2(s
, TOK_LINENUM
, &cval
);
2395 tok_str_add2(s
, tok
, &tokc
);
2398 #if LDOUBLE_SIZE == 12
2399 #define LDOUBLE_GET(p, cv) \
2403 #elif LDOUBLE_SIZE == 8
2404 #define LDOUBLE_GET(p, cv) \
2408 #error add long double size support
2412 /* get a token from an integer array and increment pointer
2413 accordingly. we code it as a macro to avoid pointer aliasing. */
2414 #define TOK_GET(t, p, cv) \
2429 cv.cstr = (CString *)p; \
2430 cv.cstr->data = (char *)p + sizeof(CString);\
2431 p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\
2440 case TOK_CLDOUBLE: \
2441 LDOUBLE_GET(p, cv); \
2442 p += LDOUBLE_SIZE / 4; \
2449 /* defines handling */
2450 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
2454 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
2455 s
->next
= first_arg
;
2456 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
2459 /* undefined a define symbol. Its name is just set to zero */
2460 static void define_undef(Sym
*s
)
2464 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2465 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2469 static inline Sym
*define_find(int v
)
2472 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2474 return table_ident
[v
]->sym_define
;
2477 /* free define stack until top reaches 'b' */
2478 static void free_defines(Sym
*b
)
2486 /* do not free args or predefined defines */
2488 tok_str_free((int *)top
->c
);
2490 if (v
>= TOK_IDENT
&& v
< tok_ident
)
2491 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
2499 static Sym
*label_find(int v
)
2502 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
2504 return table_ident
[v
]->sym_label
;
2507 static Sym
*label_push(Sym
**ptop
, int v
, int flags
)
2510 s
= sym_push2(ptop
, v
, 0, 0);
2512 ps
= &table_ident
[v
- TOK_IDENT
]->sym_label
;
2513 if (ptop
== &global_label_stack
) {
2514 /* modify the top most local identifier, so that
2515 sym_identifier will point to 's' when popped */
2517 ps
= &(*ps
)->prev_tok
;
2524 /* pop labels until element last is reached. Look if any labels are
2525 undefined. Define symbols if '&&label' was used. */
2526 static void label_pop(Sym
**ptop
, Sym
*slast
)
2529 for(s
= *ptop
; s
!= slast
; s
= s1
) {
2531 if (s
->r
== LABEL_DECLARED
) {
2532 warning("label '%s' declared but not used", get_tok_str(s
->v
, NULL
));
2533 } else if (s
->r
== LABEL_FORWARD
) {
2534 error("label '%s' used but not defined",
2535 get_tok_str(s
->v
, NULL
));
2538 /* define corresponding symbol. A size of
2540 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
2544 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= s
->prev_tok
;
2550 /* eval an expression for #if/#elif */
2551 static int expr_preprocess(void)
2557 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2558 next(); /* do macro subst */
2559 if (tok
== TOK_DEFINED
) {
2564 c
= define_find(tok
) != 0;
2569 } else if (tok
>= TOK_IDENT
) {
2570 /* if undefined macro */
2574 tok_str_add_tok(&str
);
2576 tok_str_add(&str
, -1); /* simulate end of file */
2577 tok_str_add(&str
, 0);
2578 /* now evaluate C constant expression */
2579 macro_ptr
= str
.str
;
2583 tok_str_free(str
.str
);
2587 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2588 static void tok_print(int *str
)
2594 TOK_GET(t
, str
, cval
);
2597 printf(" %s", get_tok_str(t
, &cval
));
2603 /* parse after #define */
2604 static void parse_define(void)
2606 Sym
*s
, *first
, **ps
;
2607 int v
, t
, varg
, is_vaargs
, c
;
2612 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2613 /* XXX: should check if same macro (ANSI) */
2616 /* '(' must be just after macro definition for MACRO_FUNC */
2617 c
= file
->buf_ptr
[0];
2619 c
= handle_stray1(file
->buf_ptr
);
2624 while (tok
!= ')') {
2628 if (varg
== TOK_DOTS
) {
2629 varg
= TOK___VA_ARGS__
;
2631 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2635 if (varg
< TOK_IDENT
)
2636 error("badly punctuated parameter list");
2637 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2648 /* EOF testing necessary for '-D' handling */
2649 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2650 tok_str_add2(&str
, tok
, &tokc
);
2653 tok_str_add(&str
, 0);
2655 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2658 define_push(v
, t
, str
.str
, first
);
2661 static inline int hash_cached_include(int type
, const char *filename
)
2663 const unsigned char *s
;
2667 h
= TOK_HASH_FUNC(h
, type
);
2670 h
= TOK_HASH_FUNC(h
, *s
);
2673 h
&= (CACHED_INCLUDES_HASH_SIZE
- 1);
2677 /* XXX: use a token or a hash table to accelerate matching ? */
2678 static CachedInclude
*search_cached_include(TCCState
*s1
,
2679 int type
, const char *filename
)
2683 h
= hash_cached_include(type
, filename
);
2684 i
= s1
->cached_includes_hash
[h
];
2688 e
= s1
->cached_includes
[i
- 1];
2689 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2696 static inline void add_cached_include(TCCState
*s1
, int type
,
2697 const char *filename
, int ifndef_macro
)
2702 if (search_cached_include(s1
, type
, filename
))
2705 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2707 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2711 strcpy(e
->filename
, filename
);
2712 e
->ifndef_macro
= ifndef_macro
;
2713 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2714 /* add in hash table */
2715 h
= hash_cached_include(type
, filename
);
2716 e
->hash_next
= s1
->cached_includes_hash
[h
];
2717 s1
->cached_includes_hash
[h
] = s1
->nb_cached_includes
;
2720 static void pragma_parse(TCCState
*s1
)
2725 if (tok
== TOK_pack
) {
2728 #pragma pack(1) // set
2729 #pragma pack() // reset to default
2730 #pragma pack(push,1) // push & set
2731 #pragma pack(pop) // restore previous
2734 if (tok
== TOK_ASM_pop
) {
2736 if (s1
->pack_stack_ptr
<= s1
->pack_stack
) {
2738 error("out of pack stack");
2740 s1
->pack_stack_ptr
--;
2744 if (tok
== TOK_ASM_push
) {
2746 if (s1
->pack_stack_ptr
>= s1
->pack_stack
+ PACK_STACK_SIZE
- 1)
2748 s1
->pack_stack_ptr
++;
2751 if (tok
!= TOK_CINT
) {
2753 error("invalid pack pragma");
2756 if (val
< 1 || val
> 16 || (val
& (val
- 1)) != 0)
2760 *s1
->pack_stack_ptr
= val
;
2766 /* is_bof is true if first non space token at beginning of file */
2767 static void preprocess(int is_bof
)
2769 TCCState
*s1
= tcc_state
;
2770 int size
, i
, c
, n
, saved_parse_flags
;
2771 char buf
[1024], *q
, *p
;
2777 saved_parse_flags
= parse_flags
;
2778 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
|
2779 PARSE_FLAG_LINEFEED
;
2789 s
= define_find(tok
);
2790 /* undefine symbol by putting an invalid name */
2795 case TOK_INCLUDE_NEXT
:
2796 ch
= file
->buf_ptr
[0];
2797 /* XXX: incorrect if comments : use next_nomacro with a special mode */
2802 } else if (ch
== '\"') {
2805 /* XXX: better stray handling */
2808 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2809 if ((q
- buf
) < sizeof(buf
) - 1)
2816 /* eat all spaces and comments after include */
2817 /* XXX: slightly incorrect */
2818 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2822 /* computed #include : either we have only strings or
2823 we have anything enclosed in '<>' */
2826 if (tok
== TOK_STR
) {
2827 while (tok
!= TOK_LINEFEED
) {
2828 if (tok
!= TOK_STR
) {
2830 error("'#include' expects \"FILENAME\" or <FILENAME>");
2832 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2838 while (tok
!= TOK_LINEFEED
) {
2839 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2843 /* check syntax and remove '<>' */
2844 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2845 goto include_syntax
;
2846 memmove(buf
, buf
+ 1, len
- 2);
2847 buf
[len
- 2] = '\0';
2852 e
= search_cached_include(s1
, c
, buf
);
2853 if (e
&& define_find(e
->ifndef_macro
)) {
2854 /* no need to parse the include because the 'ifndef macro'
2857 printf("%s: skipping %s\n", file
->filename
, buf
);
2861 /* first search in current dir if "header.h" */
2863 p
= strrchr(file
->filename
, '/');
2865 size
= p
+ 1 - file
->filename
;
2866 if (size
> sizeof(buf1
) - 1)
2867 size
= sizeof(buf1
) - 1;
2868 memcpy(buf1
, file
->filename
, size
);
2870 pstrcat(buf1
, sizeof(buf1
), buf
);
2871 f
= tcc_open(s1
, buf1
);
2873 if (tok
== TOK_INCLUDE_NEXT
)
2879 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2880 error("#include recursion too deep");
2881 /* now search in all the include paths */
2882 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2883 for(i
= 0; i
< n
; i
++) {
2885 if (i
< s1
->nb_include_paths
)
2886 path
= s1
->include_paths
[i
];
2888 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2889 pstrcpy(buf1
, sizeof(buf1
), path
);
2890 pstrcat(buf1
, sizeof(buf1
), "/");
2891 pstrcat(buf1
, sizeof(buf1
), buf
);
2892 f
= tcc_open(s1
, buf1
);
2894 if (tok
== TOK_INCLUDE_NEXT
)
2900 error("include file '%s' not found", buf
);
2904 printf("%s: including %s\n", file
->filename
, buf1
);
2907 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2908 /* push current file in stack */
2909 /* XXX: fix current line init */
2910 *s1
->include_stack_ptr
++ = file
;
2912 /* add include file debug info */
2914 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2916 tok_flags
|= TOK_FLAG_BOF
| TOK_FLAG_BOL
;
2917 ch
= file
->buf_ptr
[0];
2925 c
= expr_preprocess();
2931 if (tok
< TOK_IDENT
)
2932 error("invalid argument for '#if%sdef'", c
? "n" : "");
2936 printf("#ifndef %s\n", get_tok_str(tok
, NULL
));
2938 file
->ifndef_macro
= tok
;
2941 c
= (define_find(tok
) != 0) ^ c
;
2943 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2944 error("memory full");
2945 *s1
->ifdef_stack_ptr
++ = c
;
2948 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2949 error("#else without matching #if");
2950 if (s1
->ifdef_stack_ptr
[-1] & 2)
2951 error("#else after #else");
2952 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2955 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2956 error("#elif without matching #if");
2957 c
= s1
->ifdef_stack_ptr
[-1];
2959 error("#elif after #else");
2960 /* last #if/#elif expression was true: we skip */
2963 c
= expr_preprocess();
2964 s1
->ifdef_stack_ptr
[-1] = c
;
2974 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2975 error("#endif without matching #if");
2976 s1
->ifdef_stack_ptr
--;
2977 /* '#ifndef macro' was at the start of file. Now we check if
2978 an '#endif' is exactly at the end of file */
2979 if (file
->ifndef_macro
&&
2980 s1
->ifdef_stack_ptr
== file
->ifdef_stack_ptr
) {
2981 file
->ifndef_macro_saved
= file
->ifndef_macro
;
2982 /* need to set to zero to avoid false matches if another
2983 #ifndef at middle of file */
2984 file
->ifndef_macro
= 0;
2985 while (tok
!= TOK_LINEFEED
)
2987 tok_flags
|= TOK_FLAG_ENDIF
;
2993 if (tok
!= TOK_CINT
)
2995 file
->line_num
= tokc
.i
- 1; /* the line number will be incremented after */
2997 if (tok
!= TOK_LINEFEED
) {
3000 pstrcpy(file
->filename
, sizeof(file
->filename
),
3001 (char *)tokc
.cstr
->data
);
3007 ch
= file
->buf_ptr
[0];
3010 while (ch
!= '\n' && ch
!= CH_EOF
) {
3011 if ((q
- buf
) < sizeof(buf
) - 1)
3017 error("#error %s", buf
);
3019 warning("#warning %s", buf
);
3025 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
3026 /* '!' is ignored to allow C scripts. numbers are ignored
3027 to emulate cpp behaviour */
3029 if (!(saved_parse_flags
& PARSE_FLAG_ASM_COMMENTS
))
3030 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
3034 /* ignore other preprocess commands or #! for C scripts */
3035 while (tok
!= TOK_LINEFEED
)
3038 parse_flags
= saved_parse_flags
;
3041 /* evaluate escape codes in a string. */
3042 static void parse_escape_string(CString
*outstr
, const uint8_t *buf
, int is_long
)
3057 case '0': case '1': case '2': case '3':
3058 case '4': case '5': case '6': case '7':
3059 /* at most three octal digits */
3064 n
= n
* 8 + c
- '0';
3068 n
= n
* 8 + c
- '0';
3073 goto add_char_nonext
;
3079 if (c
>= 'a' && c
<= 'f')
3081 else if (c
>= 'A' && c
<= 'F')
3091 goto add_char_nonext
;
3115 goto invalid_escape
;
3125 if (c
>= '!' && c
<= '~')
3126 warning("unknown escape sequence: \'\\%c\'", c
);
3128 warning("unknown escape sequence: \'\\x%x\'", c
);
3135 cstr_ccat(outstr
, c
);
3137 cstr_wccat(outstr
, c
);
3139 /* add a trailing '\0' */
3141 cstr_ccat(outstr
, '\0');
3143 cstr_wccat(outstr
, '\0');
3146 /* we use 64 bit numbers */
3149 /* bn = (bn << shift) | or_val */
3150 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
3154 for(i
=0;i
<BN_SIZE
;i
++) {
3156 bn
[i
] = (v
<< shift
) | or_val
;
3157 or_val
= v
>> (32 - shift
);
3161 void bn_zero(unsigned int *bn
)
3164 for(i
=0;i
<BN_SIZE
;i
++) {
3169 /* parse number in null terminated string 'p' and return it in the
3171 void parse_number(const char *p
)
3173 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
3175 unsigned int bn
[BN_SIZE
];
3186 goto float_frac_parse
;
3187 } else if (t
== '0') {
3188 if (ch
== 'x' || ch
== 'X') {
3192 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
3198 /* parse all digits. cannot check octal numbers at this stage
3199 because of floating point constants */
3201 if (ch
>= 'a' && ch
<= 'f')
3203 else if (ch
>= 'A' && ch
<= 'F')
3211 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
3213 error("number too long");
3219 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
3220 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
3222 /* NOTE: strtox should support that for hexa numbers, but
3223 non ISOC99 libcs do not support it, so we prefer to do
3225 /* hexadecimal or binary floats */
3226 /* XXX: handle overflows */
3238 } else if (t
>= 'a') {
3240 } else if (t
>= 'A') {
3245 bn_lshift(bn
, shift
, t
);
3252 if (t
>= 'a' && t
<= 'f') {
3254 } else if (t
>= 'A' && t
<= 'F') {
3256 } else if (t
>= '0' && t
<= '9') {
3262 error("invalid digit");
3263 bn_lshift(bn
, shift
, t
);
3268 if (ch
!= 'p' && ch
!= 'P')
3275 } else if (ch
== '-') {
3279 if (ch
< '0' || ch
> '9')
3280 expect("exponent digits");
3281 while (ch
>= '0' && ch
<= '9') {
3282 exp_val
= exp_val
* 10 + ch
- '0';
3285 exp_val
= exp_val
* s
;
3287 /* now we can generate the number */
3288 /* XXX: should patch directly float number */
3289 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
3290 d
= ldexp(d
, exp_val
- frac_bits
);
3295 /* float : should handle overflow */
3297 } else if (t
== 'L') {
3300 /* XXX: not large enough */
3301 tokc
.ld
= (long double)d
;
3307 /* decimal floats */
3309 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3314 while (ch
>= '0' && ch
<= '9') {
3315 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3321 if (ch
== 'e' || ch
== 'E') {
3322 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3326 if (ch
== '-' || ch
== '+') {
3327 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3332 if (ch
< '0' || ch
> '9')
3333 expect("exponent digits");
3334 while (ch
>= '0' && ch
<= '9') {
3335 if (q
>= token_buf
+ STRING_MAX_SIZE
)
3347 tokc
.f
= strtof(token_buf
, NULL
);
3348 } else if (t
== 'L') {
3351 tokc
.ld
= strtold(token_buf
, NULL
);
3354 tokc
.d
= strtod(token_buf
, NULL
);
3358 unsigned long long n
, n1
;
3361 /* integer number */
3364 if (b
== 10 && *q
== '0') {
3371 /* no need for checks except for base 10 / 8 errors */
3374 } else if (t
>= 'a') {
3376 } else if (t
>= 'A') {
3381 error("invalid digit");
3385 /* detect overflow */
3386 /* XXX: this test is not reliable */
3388 error("integer constant overflow");
3391 /* XXX: not exactly ANSI compliant */
3392 if ((n
& 0xffffffff00000000LL
) != 0) {
3397 } else if (n
> 0x7fffffff) {
3408 error("three 'l's in integer constant");
3411 if (tok
== TOK_CINT
)
3413 else if (tok
== TOK_CUINT
)
3417 } else if (t
== 'U') {
3419 error("two 'u's in integer constant");
3421 if (tok
== TOK_CINT
)
3423 else if (tok
== TOK_CLLONG
)
3430 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
3438 #define PARSE2(c1, tok1, c2, tok2) \
3449 /* return next token without macro substitution */
3450 static inline void next_nomacro1(void)
3470 /* first look if it is in fact an end of buffer */
3471 if (p
>= file
->buf_end
) {
3475 if (p
>= file
->buf_end
)
3488 TCCState
*s1
= tcc_state
;
3489 if (parse_flags
& PARSE_FLAG_LINEFEED
) {
3491 } else if (s1
->include_stack_ptr
== s1
->include_stack
||
3492 !(parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3493 /* no include left : end of file. */
3496 /* pop include file */
3498 /* test if previous '#endif' was after a #ifdef at
3500 if (tok_flags
& TOK_FLAG_ENDIF
) {
3502 printf("#endif %s\n", get_tok_str(file
->ifndef_macro_saved
, NULL
));
3504 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
3505 file
->ifndef_macro_saved
);
3508 /* add end of include file debug info */
3510 put_stabd(N_EINCL
, 0, 0);
3512 /* pop include stack */
3514 s1
->include_stack_ptr
--;
3515 file
= *s1
->include_stack_ptr
;
3523 if (parse_flags
& PARSE_FLAG_LINEFEED
) {
3527 tok_flags
|= TOK_FLAG_BOL
;
3536 if ((tok_flags
& TOK_FLAG_BOL
) &&
3537 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
3539 preprocess(tok_flags
& TOK_FLAG_BOF
);
3545 tok
= TOK_TWOSHARPS
;
3547 if (parse_flags
& PARSE_FLAG_ASM_COMMENTS
) {
3548 p
= parse_line_comment(p
- 1);
3557 case 'a': case 'b': case 'c': case 'd':
3558 case 'e': case 'f': case 'g': case 'h':
3559 case 'i': case 'j': case 'k': case 'l':
3560 case 'm': case 'n': case 'o': case 'p':
3561 case 'q': case 'r': case 's': case 't':
3562 case 'u': case 'v': case 'w': case 'x':
3564 case 'A': case 'B': case 'C': case 'D':
3565 case 'E': case 'F': case 'G': case 'H':
3566 case 'I': case 'J': case 'K':
3567 case 'M': case 'N': case 'O': case 'P':
3568 case 'Q': case 'R': case 'S': case 'T':
3569 case 'U': case 'V': case 'W': case 'X':
3575 h
= TOK_HASH_FUNC(h
, c
);
3579 if (!isidnum_table
[c
])
3581 h
= TOK_HASH_FUNC(h
, c
);
3588 /* fast case : no stray found, so we have the full token
3589 and we have already hashed it */
3591 h
&= (TOK_HASH_SIZE
- 1);
3592 pts
= &hash_ident
[h
];
3597 if (ts
->len
== len
&& !memcmp(ts
->str
, p1
, len
))
3599 pts
= &(ts
->hash_next
);
3601 ts
= tok_alloc_new(pts
, p1
, len
);
3605 cstr_reset(&tokcstr
);
3608 cstr_ccat(&tokcstr
, *p1
);
3614 while (isidnum_table
[c
]) {
3615 cstr_ccat(&tokcstr
, c
);
3618 ts
= tok_alloc(tokcstr
.data
, tokcstr
.size
);
3624 if (t
!= '\\' && t
!= '\'' && t
!= '\"') {
3626 goto parse_ident_fast
;
3629 if (c
== '\'' || c
== '\"') {
3633 cstr_reset(&tokcstr
);
3634 cstr_ccat(&tokcstr
, 'L');
3635 goto parse_ident_slow
;
3639 case '0': case '1': case '2': case '3':
3640 case '4': case '5': case '6': case '7':
3643 cstr_reset(&tokcstr
);
3644 /* after the first digit, accept digits, alpha, '.' or sign if
3645 prefixed by 'eEpP' */
3649 cstr_ccat(&tokcstr
, c
);
3651 if (!(isnum(c
) || isid(c
) || c
== '.' ||
3652 ((c
== '+' || c
== '-') &&
3653 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
3656 /* We add a trailing '\0' to ease parsing */
3657 cstr_ccat(&tokcstr
, '\0');
3658 tokc
.cstr
= &tokcstr
;
3662 /* special dot handling because it can also start a number */
3665 cstr_reset(&tokcstr
);
3666 cstr_ccat(&tokcstr
, '.');
3668 } else if (c
== '.') {
3688 /* parse the string */
3690 p
= parse_pp_string(p
, sep
, &str
);
3691 cstr_ccat(&str
, '\0');
3693 /* eval the escape (should be done as TOK_PPNUM) */
3694 cstr_reset(&tokcstr
);
3695 parse_escape_string(&tokcstr
, str
.data
, is_long
);
3700 /* XXX: make it portable */
3704 char_size
= sizeof(int);
3705 if (tokcstr
.size
<= char_size
)
3706 error("empty character constant");
3707 if (tokcstr
.size
> 2 * char_size
)
3708 warning("multi-character character constant");
3710 tokc
.i
= *(int8_t *)tokcstr
.data
;
3713 tokc
.i
= *(int *)tokcstr
.data
;
3717 tokc
.cstr
= &tokcstr
;
3731 } else if (c
== '<') {
3749 } else if (c
== '>') {
3767 } else if (c
== '=') {
3780 } else if (c
== '=') {
3793 } else if (c
== '=') {
3806 } else if (c
== '=') {
3809 } else if (c
== '>') {
3817 PARSE2('!', '!', '=', TOK_NE
)
3818 PARSE2('=', '=', '=', TOK_EQ
)
3819 PARSE2('*', '*', '=', TOK_A_MUL
)
3820 PARSE2('%', '%', '=', TOK_A_MOD
)
3821 PARSE2('^', '^', '=', TOK_A_XOR
)
3823 /* comments or operator */
3827 p
= parse_comment(p
);
3829 } else if (c
== '/') {
3830 p
= parse_line_comment(p
);
3832 } else if (c
== '=') {
3852 case '$': /* only used in assembler */
3857 error("unrecognized character \\x%02x", c
);
3862 #if defined(PARSE_DEBUG)
3863 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3867 /* return next token without macro substitution. Can read input from
3869 static void next_nomacro(void)
3875 TOK_GET(tok
, macro_ptr
, tokc
);
3876 if (tok
== TOK_LINENUM
) {
3877 file
->line_num
= tokc
.i
;
3886 /* substitute args in macro_str and return allocated string */
3887 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
3889 int *st
, last_tok
, t
, notfirst
;
3898 TOK_GET(t
, macro_str
, cval
);
3903 TOK_GET(t
, macro_str
, cval
);
3906 s
= sym_find2(args
, t
);
3913 cstr_ccat(&cstr
, ' ');
3914 TOK_GET(t
, st
, cval
);
3915 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
3918 cstr_ccat(&cstr
, '\0');
3920 printf("stringize: %s\n", (char *)cstr
.data
);
3924 tok_str_add2(&str
, TOK_STR
, &cval
);
3927 tok_str_add2(&str
, t
, &cval
);
3929 } else if (t
>= TOK_IDENT
) {
3930 s
= sym_find2(args
, t
);
3933 /* if '##' is present before or after, no arg substitution */
3934 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
3935 /* special case for var arg macros : ## eats the
3936 ',' if empty VA_ARGS variable. */
3937 /* XXX: test of the ',' is not 100%
3938 reliable. should fix it to avoid security
3940 if (gnu_ext
&& s
->type
.t
&&
3941 last_tok
== TOK_TWOSHARPS
&&
3942 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
3944 /* suppress ',' '##' */
3947 /* suppress '##' and add variable */
3955 TOK_GET(t1
, st
, cval
);
3958 tok_str_add2(&str
, t1
, &cval
);
3962 /* NOTE: the stream cannot be read when macro
3963 substituing an argument */
3964 macro_subst(&str
, nested_list
, st
, 0);
3967 tok_str_add(&str
, t
);
3970 tok_str_add2(&str
, t
, &cval
);
3974 tok_str_add(&str
, 0);
3978 static char const ab_month_name
[12][4] =
3980 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
3981 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
3984 /* do macro substitution of current token with macro 's' and add
3985 result to (tok_str,tok_len). 'nested_list' is the list of all
3986 macros we got inside to avoid recursing. Return non zero if no
3987 substitution needs to be done */
3988 static int macro_subst_tok(TokenString
*tok_str
,
3989 Sym
**nested_list
, Sym
*s
, int can_read_stream
)
3991 Sym
*args
, *sa
, *sa1
;
3992 int mstr_allocated
, parlevel
, *mstr
, t
, t1
;
3999 /* if symbol is a macro, prepare substitution */
4000 /* special macros */
4001 if (tok
== TOK___LINE__
) {
4002 snprintf(buf
, sizeof(buf
), "%d", file
->line_num
);
4006 } else if (tok
== TOK___FILE__
) {
4007 cstrval
= file
->filename
;
4009 } else if (tok
== TOK___DATE__
|| tok
== TOK___TIME__
) {
4014 tm
= localtime(&ti
);
4015 if (tok
== TOK___DATE__
) {
4016 snprintf(buf
, sizeof(buf
), "%s %2d %d",
4017 ab_month_name
[tm
->tm_mon
], tm
->tm_mday
, tm
->tm_year
+ 1900);
4019 snprintf(buf
, sizeof(buf
), "%02d:%02d:%02d",
4020 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
4027 cstr_cat(&cstr
, cstrval
);
4028 cstr_ccat(&cstr
, '\0');
4030 tok_str_add2(tok_str
, t1
, &cval
);
4035 if (s
->type
.t
== MACRO_FUNC
) {
4036 /* NOTE: we do not use next_nomacro to avoid eating the
4037 next token. XXX: find better solution */
4040 if (t
== 0 && can_read_stream
) {
4041 /* end of macro stream: we must look at the token
4042 after in the file */
4048 /* XXX: incorrect with comments */
4049 ch
= file
->buf_ptr
[0];
4050 while (is_space(ch
) || ch
== '\n')
4054 if (t
!= '(') /* no macro subst */
4057 /* argument macro */
4062 /* NOTE: empty args are allowed, except if no args */
4064 /* handle '()' case */
4065 if (!args
&& !sa
&& tok
== ')')
4068 error("macro '%s' used with too many args",
4069 get_tok_str(s
->v
, 0));
4072 /* NOTE: non zero sa->t indicates VA_ARGS */
4073 while ((parlevel
> 0 ||
4075 (tok
!= ',' || sa
->type
.t
))) &&
4079 else if (tok
== ')')
4081 tok_str_add2(&str
, tok
, &tokc
);
4084 tok_str_add(&str
, 0);
4085 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
4088 /* special case for gcc var args: add an empty
4089 var arg argument if it is omitted */
4090 if (sa
&& sa
->type
.t
&& gnu_ext
)
4100 error("macro '%s' used with too few args",
4101 get_tok_str(s
->v
, 0));
4104 /* now subst each arg */
4105 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
4110 tok_str_free((int *)sa
->c
);
4116 sym_push2(nested_list
, s
->v
, 0, 0);
4117 macro_subst(tok_str
, nested_list
, mstr
, 1);
4118 /* pop nested defined symbol */
4120 *nested_list
= sa1
->prev
;
4128 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
4129 return the resulting string (which must be freed). */
4130 static inline int *macro_twosharps(const int *macro_str
)
4133 const int *macro_ptr1
, *start_macro_ptr
, *ptr
, *saved_macro_ptr
;
4135 const char *p1
, *p2
;
4137 TokenString macro_str1
;
4140 start_macro_ptr
= macro_str
;
4141 /* we search the first '##' */
4143 macro_ptr1
= macro_str
;
4144 TOK_GET(t
, macro_str
, cval
);
4145 /* nothing more to do if end of string */
4148 if (*macro_str
== TOK_TWOSHARPS
)
4152 /* we saw '##', so we need more processing to handle it */
4154 tok_str_new(¯o_str1
);
4158 /* add all tokens seen so far */
4159 for(ptr
= start_macro_ptr
; ptr
< macro_ptr1
;) {
4160 TOK_GET(t
, ptr
, cval
);
4161 tok_str_add2(¯o_str1
, t
, &cval
);
4163 saved_macro_ptr
= macro_ptr
;
4164 /* XXX: get rid of the use of macro_ptr here */
4165 macro_ptr
= (int *)macro_str
;
4167 while (*macro_ptr
== TOK_TWOSHARPS
) {
4169 macro_ptr1
= macro_ptr
;
4172 TOK_GET(t
, macro_ptr
, cval
);
4173 /* We concatenate the two tokens if we have an
4174 identifier or a preprocessing number */
4176 p1
= get_tok_str(tok
, &tokc
);
4177 cstr_cat(&cstr
, p1
);
4178 p2
= get_tok_str(t
, &cval
);
4179 cstr_cat(&cstr
, p2
);
4180 cstr_ccat(&cstr
, '\0');
4182 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
4183 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
4184 if (tok
== TOK_PPNUM
) {
4185 /* if number, then create a number token */
4186 /* NOTE: no need to allocate because
4187 tok_str_add2() does it */
4190 /* if identifier, we must do a test to
4191 validate we have a correct identifier */
4192 if (t
== TOK_PPNUM
) {
4202 if (!isnum(c
) && !isid(c
))
4206 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
4207 tok
= ts
->tok
; /* modify current token */
4210 const char *str
= cstr
.data
;
4211 const unsigned char *q
;
4213 /* we look for a valid token */
4214 /* XXX: do more extensive checks */
4215 if (!strcmp(str
, ">>=")) {
4217 } else if (!strcmp(str
, "<<=")) {
4219 } else if (strlen(str
) == 2) {
4220 /* search in two bytes table */
4225 if (q
[0] == str
[0] && q
[1] == str
[1])
4232 /* NOTE: because get_tok_str use a static buffer,
4235 p1
= get_tok_str(tok
, &tokc
);
4236 cstr_cat(&cstr
, p1
);
4237 cstr_ccat(&cstr
, '\0');
4238 p2
= get_tok_str(t
, &cval
);
4239 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
4240 /* cannot merge tokens: just add them separately */
4241 tok_str_add2(¯o_str1
, tok
, &tokc
);
4242 /* XXX: free associated memory ? */
4249 tok_str_add2(¯o_str1
, tok
, &tokc
);
4254 macro_ptr
= (int *)saved_macro_ptr
;
4256 tok_str_add(¯o_str1
, 0);
4257 return macro_str1
.str
;
4261 /* do macro substitution of macro_str and add result to
4262 (tok_str,tok_len). 'nested_list' is the list of all macros we got
4263 inside to avoid recursing. */
4264 static void macro_subst(TokenString
*tok_str
, Sym
**nested_list
,
4265 const int *macro_str
, int can_read_stream
)
4268 int *saved_macro_ptr
, *macro_str1
;
4273 /* first scan for '##' operator handling */
4275 macro_str1
= macro_twosharps(ptr
);
4279 /* NOTE: ptr == NULL can only happen if tokens are read from
4280 file stream due to a macro function call */
4283 TOK_GET(t
, ptr
, cval
);
4288 /* if nested substitution, do nothing */
4289 if (sym_find2(*nested_list
, t
))
4291 saved_macro_ptr
= macro_ptr
;
4292 macro_ptr
= (int *)ptr
;
4294 ret
= macro_subst_tok(tok_str
, nested_list
, s
, can_read_stream
);
4295 ptr
= (int *)macro_ptr
;
4296 macro_ptr
= saved_macro_ptr
;
4301 tok_str_add2(tok_str
, t
, &cval
);
4305 tok_str_free(macro_str1
);
4308 /* return next token with macro substitution */
4309 static void next(void)
4311 Sym
*nested_list
, *s
;
4317 /* if not reading from macro substituted string, then try
4318 to substitute macros */
4319 if (tok
>= TOK_IDENT
&&
4320 (parse_flags
& PARSE_FLAG_PREPROCESS
)) {
4321 s
= define_find(tok
);
4323 /* we have a macro: we try to substitute */
4326 if (macro_subst_tok(&str
, &nested_list
, s
, 1) == 0) {
4327 /* substitution done, NOTE: maybe empty */
4328 tok_str_add(&str
, 0);
4329 macro_ptr
= str
.str
;
4330 macro_ptr_allocated
= str
.str
;
4337 /* end of macro or end of unget buffer */
4338 if (unget_buffer_enabled
) {
4339 macro_ptr
= unget_saved_macro_ptr
;
4340 unget_buffer_enabled
= 0;
4342 /* end of macro string: free it */
4343 tok_str_free(macro_ptr_allocated
);
4350 /* convert preprocessor tokens into C tokens */
4351 if (tok
== TOK_PPNUM
&&
4352 (parse_flags
& PARSE_FLAG_TOK_NUM
)) {
4353 parse_number((char *)tokc
.cstr
->data
);
4357 /* push back current token and set current token to 'last_tok'. Only
4358 identifier case handled for labels. */
4359 static inline void unget_tok(int last_tok
)
4363 unget_saved_macro_ptr
= macro_ptr
;
4364 unget_buffer_enabled
= 1;
4365 q
= unget_saved_buffer
;
4368 n
= tok_ext_size(tok
) - 1;
4371 *q
= 0; /* end of token string */
4376 void swap(int *p
, int *q
)
4384 void vsetc(CType
*type
, int r
, CValue
*vc
)
4388 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
4389 error("memory full");
4390 /* cannot let cpu flags if other instruction are generated. Also
4391 avoid leaving VT_JMP anywhere except on the top of the stack
4392 because it would complicate the code generator. */
4393 if (vtop
>= vstack
) {
4394 v
= vtop
->r
& VT_VALMASK
;
4395 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
4401 vtop
->r2
= VT_CONST
;
4405 /* push integer constant */
4410 vsetc(&int_type
, VT_CONST
, &cval
);
4413 /* Return a static symbol pointing to a section */
4414 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
4415 unsigned long offset
, unsigned long size
)
4421 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
4422 sym
->type
.ref
= type
->ref
;
4423 sym
->r
= VT_CONST
| VT_SYM
;
4424 put_extern_sym(sym
, sec
, offset
, size
);
4428 /* push a reference to a section offset by adding a dummy symbol */
4429 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
4434 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4435 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
4438 /* define a new external reference to a symbol 'v' of type 'u' */
4439 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
4445 /* push forward reference */
4446 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
4447 s
->type
.ref
= type
->ref
;
4448 s
->r
= r
| VT_CONST
| VT_SYM
;
4453 /* define a new external reference to a symbol 'v' of type 'u' */
4454 static Sym
*external_sym(int v
, CType
*type
, int r
)
4460 /* push forward reference */
4461 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
4462 s
->type
.t
|= VT_EXTERN
;
4464 if (!is_compatible_types(&s
->type
, type
))
4465 error("incompatible types for redefinition of '%s'",
4466 get_tok_str(v
, NULL
));
4471 /* push a reference to global symbol v */
4472 static void vpush_global_sym(CType
*type
, int v
)
4477 sym
= external_global_sym(v
, type
, 0);
4479 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
4483 void vset(CType
*type
, int r
, int v
)
4488 vsetc(type
, r
, &cval
);
4491 void vseti(int r
, int v
)
4507 void vpushv(SValue
*v
)
4509 if (vtop
>= vstack
+ (VSTACK_SIZE
- 1))
4510 error("memory full");
4520 /* save r to the memory stack, and mark it as being free */
4521 void save_reg(int r
)
4523 int l
, saved
, size
, align
;
4527 /* modify all stack values */
4530 for(p
=vstack
;p
<=vtop
;p
++) {
4531 if ((p
->r
& VT_VALMASK
) == r
||
4532 (p
->r2
& VT_VALMASK
) == r
) {
4533 /* must save value on stack if not already done */
4535 /* NOTE: must reload 'r' because r might be equal to r2 */
4536 r
= p
->r
& VT_VALMASK
;
4537 /* store register in the stack */
4539 if ((p
->r
& VT_LVAL
) ||
4540 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
4542 size
= type_size(type
, &align
);
4543 loc
= (loc
- size
) & -align
;
4544 sv
.type
.t
= type
->t
;
4545 sv
.r
= VT_LOCAL
| VT_LVAL
;
4548 #ifdef TCC_TARGET_I386
4549 /* x86 specific: need to pop fp register ST0 if saved */
4550 if (r
== TREG_ST0
) {
4551 o(0xd9dd); /* fstp %st(1) */
4554 /* special long long case */
4555 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
4562 /* mark that stack entry as being saved on the stack */
4563 if (p
->r
& VT_LVAL
) {
4564 /* also clear the bounded flag because the
4565 relocation address of the function was stored in
4567 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
4569 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
4577 /* find a register of class 'rc2' with at most one reference on stack.
4578 * If none, call get_reg(rc) */
4579 int get_reg_ex(int rc
, int rc2
)
4584 for(r
=0;r
<NB_REGS
;r
++) {
4585 if (reg_classes
[r
] & rc2
) {
4588 for(p
= vstack
; p
<= vtop
; p
++) {
4589 if ((p
->r
& VT_VALMASK
) == r
||
4590 (p
->r2
& VT_VALMASK
) == r
)
4600 /* find a free register of class 'rc'. If none, save one register */
4606 /* find a free register */
4607 for(r
=0;r
<NB_REGS
;r
++) {
4608 if (reg_classes
[r
] & rc
) {
4609 for(p
=vstack
;p
<=vtop
;p
++) {
4610 if ((p
->r
& VT_VALMASK
) == r
||
4611 (p
->r2
& VT_VALMASK
) == r
)
4619 /* no register left : free the first one on the stack (VERY
4620 IMPORTANT to start from the bottom to ensure that we don't
4621 spill registers used in gen_opi()) */
4622 for(p
=vstack
;p
<=vtop
;p
++) {
4623 r
= p
->r
& VT_VALMASK
;
4624 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
4626 /* also look at second register (if long long) */
4627 r
= p
->r2
& VT_VALMASK
;
4628 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
4634 /* Should never comes here */
4638 /* save registers up to (vtop - n) stack entry */
4639 void save_regs(int n
)
4644 for(p
= vstack
;p
<= p1
; p
++) {
4645 r
= p
->r
& VT_VALMASK
;
4652 /* move register 's' to 'r', and flush previous value of r to memory
4654 void move_reg(int r
, int s
)
4667 /* get address of vtop (vtop MUST BE an lvalue) */
4670 vtop
->r
&= ~VT_LVAL
;
4671 /* tricky: if saved lvalue, then we can go back to lvalue */
4672 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
4673 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
4676 #ifdef CONFIG_TCC_BCHECK
4677 /* generate lvalue bound code */
4683 vtop
->r
&= ~VT_MUSTBOUND
;
4684 /* if lvalue, then use checking code before dereferencing */
4685 if (vtop
->r
& VT_LVAL
) {
4686 /* if not VT_BOUNDED value, then make one */
4687 if (!(vtop
->r
& VT_BOUNDED
)) {
4688 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
4689 /* must save type because we must set it to int to get pointer */
4691 vtop
->type
.t
= VT_INT
;
4694 gen_bounded_ptr_add();
4695 vtop
->r
|= lval_type
;
4698 /* then check for dereferencing */
4699 gen_bounded_ptr_deref();
4704 /* store vtop a register belonging to class 'rc'. lvalues are
4705 converted to values. Cannot be used if cannot be converted to
4706 register value (such as structures). */
4709 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
4710 unsigned long long ll
;
4712 /* NOTE: get_reg can modify vstack[] */
4713 if (vtop
->type
.t
& VT_BITFIELD
) {
4714 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
4715 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4716 /* remove bit field info to avoid loops */
4717 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4718 /* generate shifts */
4719 vpushi(32 - (bit_pos
+ bit_size
));
4721 vpushi(32 - bit_size
);
4722 /* NOTE: transformed to SHR if unsigned */
4726 if (is_float(vtop
->type
.t
) &&
4727 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4730 unsigned long offset
;
4732 /* XXX: unify with initializers handling ? */
4733 /* CPUs usually cannot use float constants, so we store them
4734 generically in data segment */
4735 size
= type_size(&vtop
->type
, &align
);
4736 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
4737 data_section
->data_offset
= offset
;
4738 /* XXX: not portable yet */
4739 ptr
= section_ptr_add(data_section
, size
);
4742 ptr
[i
] = vtop
->c
.tab
[i
];
4743 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
4744 vtop
->r
|= VT_LVAL
| VT_SYM
;
4748 #ifdef CONFIG_TCC_BCHECK
4749 if (vtop
->r
& VT_MUSTBOUND
)
4753 r
= vtop
->r
& VT_VALMASK
;
4754 /* need to reload if:
4756 - lvalue (need to dereference pointer)
4757 - already a register, but not in the right class */
4758 if (r
>= VT_CONST
||
4759 (vtop
->r
& VT_LVAL
) ||
4760 !(reg_classes
[r
] & rc
) ||
4761 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
4762 !(reg_classes
[vtop
->r2
] & rc
))) {
4764 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
4765 /* two register type load : expand to two words
4767 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
4770 vtop
->c
.ui
= ll
; /* first word */
4772 vtop
->r
= r
; /* save register value */
4773 vpushi(ll
>> 32); /* second word */
4774 } else if (r
>= VT_CONST
|| /* XXX: test to VT_CONST incorrect ? */
4775 (vtop
->r
& VT_LVAL
)) {
4776 /* We do not want to modifier the long long
4777 pointer here, so the safest (and less
4778 efficient) is to save all the other registers
4779 in the stack. XXX: totally inefficient. */
4781 /* load from memory */
4784 vtop
[-1].r
= r
; /* save register value */
4785 /* increment pointer to get second word */
4786 vtop
->type
.t
= VT_INT
;
4792 /* move registers */
4795 vtop
[-1].r
= r
; /* save register value */
4796 vtop
->r
= vtop
[-1].r2
;
4798 /* allocate second register */
4805 /* write second register */
4807 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
4809 /* lvalue of scalar type : need to use lvalue type
4810 because of possible cast */
4813 /* compute memory access type */
4814 if (vtop
->r
& VT_LVAL_BYTE
)
4816 else if (vtop
->r
& VT_LVAL_SHORT
)
4818 if (vtop
->r
& VT_LVAL_UNSIGNED
)
4822 /* restore wanted type */
4825 /* one register type load */
4830 #ifdef TCC_TARGET_C67
4831 /* uses register pairs for doubles */
4832 if ((vtop
->type
.t
& VT_BTYPE
) == VT_DOUBLE
)
4839 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4840 void gv2(int rc1
, int rc2
)
4844 /* generate more generic register first. But VT_JMP or VT_CMP
4845 values must be generated first in all cases to avoid possible
4847 v
= vtop
[0].r
& VT_VALMASK
;
4848 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
4853 /* test if reload is needed for first register */
4854 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
4864 /* test if reload is needed for first register */
4865 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
4871 /* expand long long on stack in two int registers */
4876 u
= vtop
->type
.t
& VT_UNSIGNED
;
4879 vtop
[0].r
= vtop
[-1].r2
;
4880 vtop
[0].r2
= VT_CONST
;
4881 vtop
[-1].r2
= VT_CONST
;
4882 vtop
[0].type
.t
= VT_INT
| u
;
4883 vtop
[-1].type
.t
= VT_INT
| u
;
4886 #ifdef TCC_TARGET_ARM
4887 /* expand long long on stack */
4888 void lexpand_nr(void)
4892 u
= vtop
->type
.t
& VT_UNSIGNED
;
4894 vtop
->r2
= VT_CONST
;
4895 vtop
->type
.t
= VT_INT
| u
;
4896 v
=vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
);
4897 if (v
== VT_CONST
) {
4898 vtop
[-1].c
.ui
= vtop
->c
.ull
;
4899 vtop
->c
.ui
= vtop
->c
.ull
>> 32;
4901 } else if (v
== (VT_LVAL
|VT_CONST
) || v
== (VT_LVAL
|VT_LOCAL
)) {
4903 vtop
->r
= vtop
[-1].r
;
4904 } else if (v
> VT_CONST
) {
4908 vtop
->r
= vtop
[-1].r2
;
4909 vtop
[-1].r2
= VT_CONST
;
4910 vtop
[-1].type
.t
= VT_INT
| u
;
4914 /* build a long long from two ints */
4917 gv2(RC_INT
, RC_INT
);
4918 vtop
[-1].r2
= vtop
[0].r
;
4919 vtop
[-1].type
.t
= t
;
4923 /* rotate n first stack elements to the bottom
4924 I1 ... In -> I2 ... In I1 [top is right]
4932 for(i
=-n
+1;i
!=0;i
++)
4933 vtop
[i
] = vtop
[i
+1];
4937 /* rotate n first stack elements to the top
4938 I1 ... In -> In I1 ... I(n-1) [top is right]
4946 for(i
= 0;i
< n
- 1; i
++)
4947 vtop
[-i
] = vtop
[-i
- 1];
4951 #ifdef TCC_TARGET_ARM
4952 /* like vrott but in other direction
4953 In ... I1 -> I(n-1) ... I1 In [top is right]
4961 for(i
= n
- 1; i
> 0; i
--)
4962 vtop
[-i
] = vtop
[-i
+ 1];
4967 /* pop stack value */
4971 v
= vtop
->r
& VT_VALMASK
;
4972 #ifdef TCC_TARGET_I386
4973 /* for x86, we need to pop the FP stack */
4974 if (v
== TREG_ST0
&& !nocode_wanted
) {
4975 o(0xd9dd); /* fstp %st(1) */
4978 if (v
== VT_JMP
|| v
== VT_JMPI
) {
4979 /* need to put correct jump if && or || without test */
4985 /* convert stack entry to register and duplicate its value in another
4993 if ((t
& VT_BTYPE
) == VT_LLONG
) {
5000 /* stack: H L L1 H1 */
5008 /* duplicate value */
5019 load(r1
, &sv
); /* move r to r1 */
5021 /* duplicates value */
5026 /* generate CPU independent (unsigned) long long operations */
5027 void gen_opl(int op
)
5029 int t
, a
, b
, op1
, c
, i
;
5036 func
= TOK___divdi3
;
5039 func
= TOK___udivdi3
;
5042 func
= TOK___moddi3
;
5045 func
= TOK___umoddi3
;
5047 /* call generic long long function */
5048 vpush_global_sym(&func_old_type
, func
);
5053 vtop
->r2
= REG_LRET
;
5066 /* stack: L1 H1 L2 H2 */
5071 vtop
[-2] = vtop
[-3];
5074 /* stack: H1 H2 L1 L2 */
5080 /* stack: H1 H2 L1 L2 ML MH */
5083 /* stack: ML MH H1 H2 L1 L2 */
5087 /* stack: ML MH H1 L2 H2 L1 */
5092 /* stack: ML MH M1 M2 */
5095 } else if (op
== '+' || op
== '-') {
5096 /* XXX: add non carry method too (for MIPS or alpha) */
5102 /* stack: H1 H2 (L1 op L2) */
5105 gen_op(op1
+ 1); /* TOK_xxxC2 */
5108 /* stack: H1 H2 (L1 op L2) */
5111 /* stack: (L1 op L2) H1 H2 */
5113 /* stack: (L1 op L2) (H1 op H2) */
5121 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
5122 t
= vtop
[-1].type
.t
;
5126 /* stack: L H shift */
5128 /* constant: simpler */
5129 /* NOTE: all comments are for SHL. the other cases are
5130 done by swaping words */
5141 if (op
!= TOK_SAR
) {
5174 /* XXX: should provide a faster fallback on x86 ? */
5177 func
= TOK___sardi3
;
5180 func
= TOK___shrdi3
;
5183 func
= TOK___shldi3
;
5189 /* compare operations */
5195 /* stack: L1 H1 L2 H2 */
5197 vtop
[-1] = vtop
[-2];
5199 /* stack: L1 L2 H1 H2 */
5202 /* when values are equal, we need to compare low words. since
5203 the jump is inverted, we invert the test too. */
5206 else if (op1
== TOK_GT
)
5208 else if (op1
== TOK_ULT
)
5210 else if (op1
== TOK_UGT
)
5215 if (op1
!= TOK_NE
) {
5219 /* generate non equal test */
5220 /* XXX: NOT PORTABLE yet */
5224 #if defined(TCC_TARGET_I386)
5225 b
= psym(0x850f, 0);
5226 #elif defined(TCC_TARGET_ARM)
5228 o(0x1A000000 | encbranch(ind
, 0, 1));
5229 #elif defined(TCC_TARGET_C67)
5230 error("not implemented");
5232 #error not supported
5236 /* compare low. Always unsigned */
5240 else if (op1
== TOK_LE
)
5242 else if (op1
== TOK_GT
)
5244 else if (op1
== TOK_GE
)
5254 /* handle integer constant optimizations and various machine
5256 void gen_opic(int op
)
5263 /* currently, we cannot do computations with forward symbols */
5264 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5265 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5269 case '+': v1
->c
.i
+= fc
; break;
5270 case '-': v1
->c
.i
-= fc
; break;
5271 case '&': v1
->c
.i
&= fc
; break;
5272 case '^': v1
->c
.i
^= fc
; break;
5273 case '|': v1
->c
.i
|= fc
; break;
5274 case '*': v1
->c
.i
*= fc
; break;
5281 /* if division by zero, generate explicit division */
5284 error("division by zero in constant");
5288 default: v1
->c
.i
/= fc
; break;
5289 case '%': v1
->c
.i
%= fc
; break;
5290 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
5291 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
5294 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
5295 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
5296 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
5298 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
5299 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
5300 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
5301 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
5302 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
5303 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
5304 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
5305 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
5306 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
5307 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
5309 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
5310 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
5316 /* if commutative ops, put c2 as constant */
5317 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
5318 op
== '|' || op
== '*')) {
5323 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
5326 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
5327 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
5333 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
5334 /* try to use shifts instead of muls or divs */
5335 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
5344 else if (op
== TOK_PDIV
)
5350 } else if (c2
&& (op
== '+' || op
== '-') &&
5351 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
5352 (VT_CONST
| VT_SYM
)) {
5353 /* symbol + constant case */
5360 if (!nocode_wanted
) {
5361 /* call low level op generator */
5370 /* generate a floating point operation with constant propagation */
5371 void gen_opif(int op
)
5379 /* currently, we cannot do computations with forward symbols */
5380 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5381 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5383 if (v1
->type
.t
== VT_FLOAT
) {
5386 } else if (v1
->type
.t
== VT_DOUBLE
) {
5394 /* NOTE: we only do constant propagation if finite number (not
5395 NaN or infinity) (ANSI spec) */
5396 if (!ieee_finite(f1
) || !ieee_finite(f2
))
5400 case '+': f1
+= f2
; break;
5401 case '-': f1
-= f2
; break;
5402 case '*': f1
*= f2
; break;
5406 error("division by zero in constant");
5411 /* XXX: also handles tests ? */
5415 /* XXX: overflow test ? */
5416 if (v1
->type
.t
== VT_FLOAT
) {
5418 } else if (v1
->type
.t
== VT_DOUBLE
) {
5426 if (!nocode_wanted
) {
5434 static int pointed_size(CType
*type
)
5437 return type_size(pointed_type(type
), &align
);
5440 static inline int is_null_pointer(SValue
*p
)
5442 if ((p
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
5444 return ((p
->type
.t
& VT_BTYPE
) == VT_INT
&& p
->c
.i
== 0) ||
5445 ((p
->type
.t
& VT_BTYPE
) == VT_LLONG
&& p
->c
.ll
== 0);
5448 static inline int is_integer_btype(int bt
)
5450 return (bt
== VT_BYTE
|| bt
== VT_SHORT
||
5451 bt
== VT_INT
|| bt
== VT_LLONG
);
5454 /* check types for comparison or substraction of pointers */
5455 static void check_comparison_pointer_types(SValue
*p1
, SValue
*p2
, int op
)
5457 CType
*type1
, *type2
, tmp_type1
, tmp_type2
;
5460 /* null pointers are accepted for all comparisons as gcc */
5461 if (is_null_pointer(p1
) || is_null_pointer(p2
))
5465 bt1
= type1
->t
& VT_BTYPE
;
5466 bt2
= type2
->t
& VT_BTYPE
;
5467 /* accept comparison between pointer and integer with a warning */
5468 if ((is_integer_btype(bt1
) || is_integer_btype(bt2
)) && op
!= '-') {
5469 warning("comparison between pointer and integer");
5473 /* both must be pointers or implicit function pointers */
5474 if (bt1
== VT_PTR
) {
5475 type1
= pointed_type(type1
);
5476 } else if (bt1
!= VT_FUNC
)
5477 goto invalid_operands
;
5479 if (bt2
== VT_PTR
) {
5480 type2
= pointed_type(type2
);
5481 } else if (bt2
!= VT_FUNC
) {
5483 error("invalid operands to binary %s", get_tok_str(op
, NULL
));
5485 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
5486 (type2
->t
& VT_BTYPE
) == VT_VOID
)
5490 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5491 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
5492 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
5493 /* gcc-like error if '-' is used */
5495 goto invalid_operands
;
5497 warning("comparison of distinct pointer types lacks a cast");
5501 /* generic gen_op: handles types problems */
5504 int u
, t1
, t2
, bt1
, bt2
, t
;
5507 t1
= vtop
[-1].type
.t
;
5508 t2
= vtop
[0].type
.t
;
5509 bt1
= t1
& VT_BTYPE
;
5510 bt2
= t2
& VT_BTYPE
;
5512 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5513 /* at least one operand is a pointer */
5514 /* relationnal op: must be both pointers */
5515 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5516 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5517 /* pointers are handled are unsigned */
5518 t
= VT_INT
| VT_UNSIGNED
;
5521 /* if both pointers, then it must be the '-' op */
5522 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
5524 error("cannot use pointers here");
5525 check_comparison_pointer_types(vtop
- 1, vtop
, op
);
5526 /* XXX: check that types are compatible */
5527 u
= pointed_size(&vtop
[-1].type
);
5529 /* set to integer type */
5530 vtop
->type
.t
= VT_INT
;
5534 /* exactly one pointer : must be '+' or '-'. */
5535 if (op
!= '-' && op
!= '+')
5536 error("cannot use pointers here");
5537 /* Put pointer as first operand */
5538 if (bt2
== VT_PTR
) {
5542 type1
= vtop
[-1].type
;
5543 /* XXX: cast to int ? (long long case) */
5544 vpushi(pointed_size(&vtop
[-1].type
));
5546 #ifdef CONFIG_TCC_BCHECK
5547 /* if evaluating constant expression, no code should be
5548 generated, so no bound check */
5549 if (do_bounds_check
&& !const_wanted
) {
5550 /* if bounded pointers, we generate a special code to
5557 gen_bounded_ptr_add();
5563 /* put again type if gen_opic() swaped operands */
5566 } else if (is_float(bt1
) || is_float(bt2
)) {
5567 /* compute bigger type and do implicit casts */
5568 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5570 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5575 /* floats can only be used for a few operations */
5576 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
5577 (op
< TOK_ULT
|| op
> TOK_GT
))
5578 error("invalid operands for binary operation");
5580 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5581 /* cast to biggest op */
5583 /* convert to unsigned if it does not fit in a long long */
5584 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5585 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5589 /* integer operations */
5591 /* convert to unsigned if it does not fit in an integer */
5592 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5593 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5596 /* XXX: currently, some unsigned operations are explicit, so
5597 we modify them here */
5598 if (t
& VT_UNSIGNED
) {
5605 else if (op
== TOK_LT
)
5607 else if (op
== TOK_GT
)
5609 else if (op
== TOK_LE
)
5611 else if (op
== TOK_GE
)
5618 /* special case for shifts and long long: we keep the shift as
5620 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
5625 else if ((t
& VT_BTYPE
) == VT_LLONG
)
5629 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
5630 /* relationnal op: the result is an int */
5631 vtop
->type
.t
= VT_INT
;
5638 /* generic itof for unsigned long long case */
5639 void gen_cvt_itof1(int t
)
5641 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
5642 (VT_LLONG
| VT_UNSIGNED
)) {
5645 vpush_global_sym(&func_old_type
, TOK___ulltof
);
5646 else if (t
== VT_DOUBLE
)
5647 vpush_global_sym(&func_old_type
, TOK___ulltod
);
5649 vpush_global_sym(&func_old_type
, TOK___ulltold
);
5659 /* generic ftoi for unsigned long long case */
5660 void gen_cvt_ftoi1(int t
)
5664 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
5665 /* not handled natively */
5666 st
= vtop
->type
.t
& VT_BTYPE
;
5668 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
5669 else if (st
== VT_DOUBLE
)
5670 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
5672 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
5677 vtop
->r2
= REG_LRET
;
5683 /* force char or short cast */
5684 void force_charshort_cast(int t
)
5688 /* XXX: add optimization if lvalue : just change type and offset */
5693 if (t
& VT_UNSIGNED
) {
5694 vpushi((1 << bits
) - 1);
5705 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
5706 static void gen_cast(CType
*type
)
5708 int sbt
, dbt
, sf
, df
, c
;
5710 /* special delayed cast for char/short */
5711 /* XXX: in some cases (multiple cascaded casts), it may still
5713 if (vtop
->r
& VT_MUSTCAST
) {
5714 vtop
->r
&= ~VT_MUSTCAST
;
5715 force_charshort_cast(vtop
->type
.t
);
5718 /* bitfields first get cast to ints */
5719 if (vtop
->type
.t
& VT_BITFIELD
) {
5723 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
5724 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
5726 if (sbt
!= dbt
&& !nocode_wanted
) {
5729 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
5731 /* convert from fp to fp */
5733 /* constant case: we can do it now */
5734 /* XXX: in ISOC, cannot do it if error in convert */
5735 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
5736 vtop
->c
.f
= (float)vtop
->c
.d
;
5737 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
5738 vtop
->c
.f
= (float)vtop
->c
.ld
;
5739 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
5740 vtop
->c
.d
= (double)vtop
->c
.f
;
5741 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
5742 vtop
->c
.d
= (double)vtop
->c
.ld
;
5743 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
5744 vtop
->c
.ld
= (long double)vtop
->c
.f
;
5745 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
5746 vtop
->c
.ld
= (long double)vtop
->c
.d
;
5748 /* non constant case: generate code */
5752 /* convert int to fp */
5755 case VT_LLONG
| VT_UNSIGNED
:
5757 /* XXX: add const cases for long long */
5759 case VT_INT
| VT_UNSIGNED
:
5761 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
5762 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
5763 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
5768 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
5769 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
5770 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
5776 #if !defined(TCC_TARGET_ARM)
5783 /* convert fp to int */
5784 /* we handle char/short/etc... with generic code */
5785 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
5786 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
5791 case VT_LLONG
| VT_UNSIGNED
:
5793 /* XXX: add const cases for long long */
5795 case VT_INT
| VT_UNSIGNED
:
5797 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5798 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5799 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
5805 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5806 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5807 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
5815 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
5816 /* additional cast for char/short/bool... */
5820 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
5821 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
5822 /* scalar to long long */
5824 if (sbt
== (VT_INT
| VT_UNSIGNED
))
5825 vtop
->c
.ll
= vtop
->c
.ui
;
5827 vtop
->c
.ll
= vtop
->c
.i
;
5829 /* machine independent conversion */
5831 /* generate high word */
5832 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
5840 /* patch second register */
5841 vtop
[-1].r2
= vtop
->r
;
5845 } else if (dbt
== VT_BOOL
) {
5846 /* scalar to bool */
5849 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
5850 (dbt
& VT_BTYPE
) == VT_SHORT
) {
5851 force_charshort_cast(dbt
);
5852 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
5854 if (sbt
== VT_LLONG
) {
5855 /* from long long: just take low order word */
5859 /* if lvalue and single word type, nothing to do because
5860 the lvalue already contains the real type size (see
5861 VT_LVAL_xxx constants) */
5867 /* return type size. Put alignment at 'a' */
5868 static int type_size(CType
*type
, int *a
)
5873 bt
= type
->t
& VT_BTYPE
;
5874 if (bt
== VT_STRUCT
) {
5879 } else if (bt
== VT_PTR
) {
5880 if (type
->t
& VT_ARRAY
) {
5882 return type_size(&s
->type
, a
) * s
->c
;
5887 } else if (bt
== VT_LDOUBLE
) {
5889 return LDOUBLE_SIZE
;
5890 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
5891 #ifdef TCC_TARGET_I386
5897 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
5900 } else if (bt
== VT_SHORT
) {
5904 /* char, void, function, _Bool */
5910 /* return the pointed type of t */
5911 static inline CType
*pointed_type(CType
*type
)
5913 return &type
->ref
->type
;
5916 /* modify type so that its it is a pointer to type. */
5917 static void mk_pointer(CType
*type
)
5920 s
= sym_push(SYM_FIELD
, type
, 0, -1);
5921 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
5925 /* compare function types. OLD functions match any new functions */
5926 static int is_compatible_func(CType
*type1
, CType
*type2
)
5932 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5934 /* check func_call */
5937 /* XXX: not complete */
5938 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
5942 while (s1
!= NULL
) {
5945 if (!is_compatible_types(&s1
->type
, &s2
->type
))
5955 /* return true if type1 and type2 are exactly the same (including
5958 - enums are not checked as gcc __builtin_types_compatible_p ()
5960 static int is_compatible_types(CType
*type1
, CType
*type2
)
5964 t1
= type1
->t
& VT_TYPE
;
5965 t2
= type2
->t
& VT_TYPE
;
5966 /* XXX: bitfields ? */
5969 /* test more complicated cases */
5970 bt1
= t1
& VT_BTYPE
;
5971 if (bt1
== VT_PTR
) {
5972 type1
= pointed_type(type1
);
5973 type2
= pointed_type(type2
);
5974 return is_compatible_types(type1
, type2
);
5975 } else if (bt1
== VT_STRUCT
) {
5976 return (type1
->ref
== type2
->ref
);
5977 } else if (bt1
== VT_FUNC
) {
5978 return is_compatible_func(type1
, type2
);
5984 /* print a type. If 'varstr' is not NULL, then the variable is also
5985 printed in the type */
5987 /* XXX: add array and function pointers */
5988 void type_to_str(char *buf
, int buf_size
,
5989 CType
*type
, const char *varstr
)
5996 t
= type
->t
& VT_TYPE
;
5999 if (t
& VT_CONSTANT
)
6000 pstrcat(buf
, buf_size
, "const ");
6001 if (t
& VT_VOLATILE
)
6002 pstrcat(buf
, buf_size
, "volatile ");
6003 if (t
& VT_UNSIGNED
)
6004 pstrcat(buf
, buf_size
, "unsigned ");
6034 tstr
= "long double";
6036 pstrcat(buf
, buf_size
, tstr
);
6040 if (bt
== VT_STRUCT
)
6044 pstrcat(buf
, buf_size
, tstr
);
6045 v
= type
->ref
->v
& ~SYM_STRUCT
;
6046 if (v
>= SYM_FIRST_ANOM
)
6047 pstrcat(buf
, buf_size
, "<anonymous>");
6049 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
6053 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
6054 pstrcat(buf
, buf_size
, "(");
6056 while (sa
!= NULL
) {
6057 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
6058 pstrcat(buf
, buf_size
, buf1
);
6061 pstrcat(buf
, buf_size
, ", ");
6063 pstrcat(buf
, buf_size
, ")");
6067 pstrcpy(buf1
, sizeof(buf1
), "*");
6069 pstrcat(buf1
, sizeof(buf1
), varstr
);
6070 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
6074 pstrcat(buf
, buf_size
, " ");
6075 pstrcat(buf
, buf_size
, varstr
);
6080 /* verify type compatibility to store vtop in 'dt' type, and generate
6082 static void gen_assign_cast(CType
*dt
)
6084 CType
*st
, *type1
, *type2
, tmp_type1
, tmp_type2
;
6085 char buf1
[256], buf2
[256];
6088 st
= &vtop
->type
; /* source type */
6089 dbt
= dt
->t
& VT_BTYPE
;
6090 sbt
= st
->t
& VT_BTYPE
;
6091 if (dt
->t
& VT_CONSTANT
)
6092 warning("assignment of read-only location");
6095 /* special cases for pointers */
6096 /* '0' can also be a pointer */
6097 if (is_null_pointer(vtop
))
6099 /* accept implicit pointer to integer cast with warning */
6100 if (is_integer_btype(sbt
)) {
6101 warning("assignment makes pointer from integer without a cast");
6104 type1
= pointed_type(dt
);
6105 /* a function is implicitely a function pointer */
6106 if (sbt
== VT_FUNC
) {
6107 if ((type1
->t
& VT_BTYPE
) != VT_VOID
&&
6108 !is_compatible_types(pointed_type(dt
), st
))
6115 type2
= pointed_type(st
);
6116 if ((type1
->t
& VT_BTYPE
) == VT_VOID
||
6117 (type2
->t
& VT_BTYPE
) == VT_VOID
) {
6118 /* void * can match anything */
6120 /* exact type match, except for unsigned */
6123 tmp_type1
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
6124 tmp_type2
.t
&= ~(VT_UNSIGNED
| VT_CONSTANT
| VT_VOLATILE
);
6125 if (!is_compatible_types(&tmp_type1
, &tmp_type2
))
6128 /* check const and volatile */
6129 if ((!(type1
->t
& VT_CONSTANT
) && (type2
->t
& VT_CONSTANT
)) ||
6130 (!(type1
->t
& VT_VOLATILE
) && (type2
->t
& VT_VOLATILE
)))
6131 warning("assignment discards qualifiers from pointer target type");
6137 if (sbt
== VT_PTR
|| sbt
== VT_FUNC
) {
6138 warning("assignment makes integer from pointer without a cast");
6140 /* XXX: more tests */
6145 tmp_type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6146 tmp_type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6147 if (!is_compatible_types(&tmp_type1
, &tmp_type2
)) {
6149 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
6150 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
6151 error("cannot cast '%s' to '%s'", buf1
, buf2
);
6159 /* store vtop in lvalue pushed on stack */
6162 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
6164 ft
= vtop
[-1].type
.t
;
6165 sbt
= vtop
->type
.t
& VT_BTYPE
;
6166 dbt
= ft
& VT_BTYPE
;
6167 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
6168 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
6169 /* optimize char/short casts */
6170 delayed_cast
= VT_MUSTCAST
;
6171 vtop
->type
.t
= ft
& VT_TYPE
;
6172 /* XXX: factorize */
6173 if (ft
& VT_CONSTANT
)
6174 warning("assignment of read-only location");
6177 if (!(ft
& VT_BITFIELD
))
6178 gen_assign_cast(&vtop
[-1].type
);
6181 if (sbt
== VT_STRUCT
) {
6182 /* if structure, only generate pointer */
6183 /* structure assignment : generate memcpy */
6184 /* XXX: optimize if small size */
6185 if (!nocode_wanted
) {
6186 size
= type_size(&vtop
->type
, &align
);
6188 vpush_global_sym(&func_old_type
, TOK_memcpy
);
6192 vtop
->type
.t
= VT_INT
;
6196 vtop
->type
.t
= VT_INT
;
6208 /* leave source on stack */
6209 } else if (ft
& VT_BITFIELD
) {
6210 /* bitfield store handling */
6211 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
6212 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
6213 /* remove bit field info to avoid loops */
6214 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
6216 /* duplicate destination */
6218 vtop
[-1] = vtop
[-2];
6220 /* mask and shift source */
6221 vpushi((1 << bit_size
) - 1);
6225 /* load destination, mask and or with source */
6227 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
6233 #ifdef CONFIG_TCC_BCHECK
6234 /* bound check case */
6235 if (vtop
[-1].r
& VT_MUSTBOUND
) {
6241 if (!nocode_wanted
) {
6245 r
= gv(rc
); /* generate value */
6246 /* if lvalue was saved on stack, must read it */
6247 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
6249 t
= get_reg(RC_INT
);
6251 sv
.r
= VT_LOCAL
| VT_LVAL
;
6252 sv
.c
.ul
= vtop
[-1].c
.ul
;
6254 vtop
[-1].r
= t
| VT_LVAL
;
6257 /* two word case handling : store second register at word + 4 */
6258 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
6260 /* convert to int to increment easily */
6261 vtop
->type
.t
= VT_INT
;
6267 /* XXX: it works because r2 is spilled last ! */
6268 store(vtop
->r2
, vtop
- 1);
6272 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6273 vtop
->r
|= delayed_cast
;
6277 /* post defines POST/PRE add. c is the token ++ or -- */
6278 void inc(int post
, int c
)
6281 vdup(); /* save lvalue */
6283 gv_dup(); /* duplicate value */
6288 vpushi(c
- TOK_MID
);
6290 vstore(); /* store value */
6292 vpop(); /* if post op, return saved value */
6295 /* Parse GNUC __attribute__ extension. Currently, the following
6296 extensions are recognized:
6297 - aligned(n) : set data/function alignment.
6298 - packed : force data alignment to 1
6299 - section(x) : generate data/code in this section.
6300 - unused : currently ignored, but may be used someday.
6301 - regparm(n) : pass function parameters in registers (i386 only)
6303 static void parse_attribute(AttributeDef
*ad
)
6307 while (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
) {
6311 while (tok
!= ')') {
6312 if (tok
< TOK_IDENT
)
6313 expect("attribute name");
6321 expect("section name");
6322 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
6331 if (n
<= 0 || (n
& (n
- 1)) != 0)
6332 error("alignment must be a positive power of two");
6345 /* currently, no need to handle it because tcc does not
6346 track unused objects */
6350 /* currently, no need to handle it because tcc does not
6351 track unused objects */
6356 ad
->func_call
= FUNC_CDECL
;
6361 ad
->func_call
= FUNC_STDCALL
;
6363 #ifdef TCC_TARGET_I386
6373 ad
->func_call
= FUNC_FASTCALL1
+ n
- 1;
6381 if (tcc_state
->warn_unsupported
)
6382 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
6383 /* skip parameters */
6384 /* XXX: skip parenthesis too */
6387 while (tok
!= ')' && tok
!= -1)
6402 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
6403 static void struct_decl(CType
*type
, int u
)
6405 int a
, v
, size
, align
, maxalign
, c
, offset
;
6406 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
6411 a
= tok
; /* save decl type */
6416 /* struct already defined ? return it */
6418 expect("struct/union/enum name");
6422 error("invalid type");
6429 /* we put an undefined size for struct/union */
6430 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, -1);
6431 s
->r
= 0; /* default alignment is zero as gcc */
6432 /* put struct/union/enum name in type */
6440 error("struct/union/enum already defined");
6441 /* cannot be empty */
6443 /* non empty enums are not allowed */
6444 if (a
== TOK_ENUM
) {
6448 expect("identifier");
6454 /* enum symbols have static storage */
6455 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
6456 ss
->type
.t
|= VT_STATIC
;
6461 /* NOTE: we accept a trailing comma */
6471 while (tok
!= '}') {
6472 parse_btype(&btype
, &ad
);
6478 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
);
6479 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
6480 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
| VT_INLINE
)))
6481 error("invalid type for '%s'",
6482 get_tok_str(v
, NULL
));
6486 bit_size
= expr_const();
6487 /* XXX: handle v = 0 case for messages */
6489 error("negative width in bit-field '%s'",
6490 get_tok_str(v
, NULL
));
6491 if (v
&& bit_size
== 0)
6492 error("zero width for bit-field '%s'",
6493 get_tok_str(v
, NULL
));
6495 size
= type_size(&type1
, &align
);
6497 if (align
< ad
.aligned
)
6499 } else if (ad
.packed
) {
6501 } else if (*tcc_state
->pack_stack_ptr
) {
6502 if (align
> *tcc_state
->pack_stack_ptr
)
6503 align
= *tcc_state
->pack_stack_ptr
;
6506 if (bit_size
>= 0) {
6507 bt
= type1
.t
& VT_BTYPE
;
6513 error("bitfields must have scalar type");
6515 if (bit_size
> bsize
) {
6516 error("width of '%s' exceeds its type",
6517 get_tok_str(v
, NULL
));
6518 } else if (bit_size
== bsize
) {
6519 /* no need for bit fields */
6521 } else if (bit_size
== 0) {
6522 /* XXX: what to do if only padding in a
6524 /* zero size: means to pad */
6528 /* we do not have enough room ? */
6529 if ((bit_pos
+ bit_size
) > bsize
)
6532 /* XXX: handle LSB first */
6533 type1
.t
|= VT_BITFIELD
|
6534 (bit_pos
<< VT_STRUCT_SHIFT
) |
6535 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
6536 bit_pos
+= bit_size
;
6542 /* add new memory data only if starting
6544 if (lbit_pos
== 0) {
6545 if (a
== TOK_STRUCT
) {
6546 c
= (c
+ align
- 1) & -align
;
6554 if (align
> maxalign
)
6558 printf("add field %s offset=%d",
6559 get_tok_str(v
, NULL
), offset
);
6560 if (type1
.t
& VT_BITFIELD
) {
6561 printf(" pos=%d size=%d",
6562 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
6563 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
6567 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
6571 if (tok
== ';' || tok
== TOK_EOF
)
6578 /* store size and alignment */
6579 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
6585 /* return 0 if no type declaration. otherwise, return the basic type
6588 static int parse_btype(CType
*type
, AttributeDef
*ad
)
6590 int t
, u
, type_found
, typespec_found
;
6594 memset(ad
, 0, sizeof(AttributeDef
));
6601 /* currently, we really ignore extension */
6611 if ((t
& VT_BTYPE
) != 0)
6612 error("too many basic types");
6628 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
6629 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6630 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
6631 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
6645 if ((t
& VT_BTYPE
) == VT_LONG
) {
6646 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
6653 struct_decl(&type1
, VT_ENUM
);
6656 type
->ref
= type1
.ref
;
6660 struct_decl(&type1
, VT_STRUCT
);
6663 /* type modifiers */
6716 /* GNUC attribute */
6717 case TOK_ATTRIBUTE1
:
6718 case TOK_ATTRIBUTE2
:
6719 parse_attribute(ad
);
6726 parse_expr_type(&type1
);
6732 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
6734 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
6735 type
->ref
= s
->type
.ref
;
6742 if ((t
& (VT_SIGNED
|VT_UNSIGNED
)) == (VT_SIGNED
|VT_UNSIGNED
))
6743 error("signed and unsigned modifier");
6744 if (tcc_state
->char_is_unsigned
) {
6745 if ((t
& (VT_SIGNED
|VT_UNSIGNED
|VT_BTYPE
)) == VT_BYTE
)
6750 /* long is never used as type */
6751 if ((t
& VT_BTYPE
) == VT_LONG
)
6752 t
= (t
& ~VT_BTYPE
) | VT_INT
;
6757 /* convert a function parameter type (array to pointer and function to
6758 function pointer) */
6759 static inline void convert_parameter_type(CType
*pt
)
6761 /* remove const and volatile qualifiers (XXX: const could be used
6762 to indicate a const function parameter */
6763 pt
->t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
6764 /* array must be transformed to pointer according to ANSI C */
6766 if ((pt
->t
& VT_BTYPE
) == VT_FUNC
) {
6771 static void post_type(CType
*type
, AttributeDef
*ad
)
6774 Sym
**plast
, *s
, *first
;
6779 /* function declaration */
6784 while (tok
!= ')') {
6785 /* read param name and compute offset */
6786 if (l
!= FUNC_OLD
) {
6787 if (!parse_btype(&pt
, &ad1
)) {
6789 error("invalid type");
6796 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
6798 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
6799 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
6800 error("parameter declared as void");
6807 convert_parameter_type(&pt
);
6808 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
6813 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
6820 /* if no parameters, then old type prototype */
6824 t1
= type
->t
& VT_STORAGE
;
6825 /* NOTE: const is ignored in returned type as it has a special
6826 meaning in gcc / C++ */
6827 type
->t
&= ~(VT_STORAGE
| VT_CONSTANT
);
6828 post_type(type
, ad
);
6829 /* we push a anonymous symbol which will contain the function prototype */
6830 s
= sym_push(SYM_FIELD
, type
, ad
->func_call
, l
);
6832 type
->t
= t1
| VT_FUNC
;
6834 } else if (tok
== '[') {
6835 /* array definition */
6841 error("invalid array size");
6844 /* parse next post type */
6845 t1
= type
->t
& VT_STORAGE
;
6846 type
->t
&= ~VT_STORAGE
;
6847 post_type(type
, ad
);
6849 /* we push a anonymous symbol which will contain the array
6851 s
= sym_push(SYM_FIELD
, type
, 0, n
);
6852 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
6857 /* Parse a type declaration (except basic type), and return the type
6858 in 'type'. 'td' is a bitmask indicating which kind of type decl is
6859 expected. 'type' should contain the basic type. 'ad' is the
6860 attribute definition of the basic type. It can be modified by
6863 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
6866 CType type1
, *type2
;
6869 while (tok
== '*') {
6877 qualifiers
|= VT_CONSTANT
;
6882 qualifiers
|= VT_VOLATILE
;
6890 type
->t
|= qualifiers
;
6893 /* XXX: clarify attribute handling */
6894 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6895 parse_attribute(ad
);
6897 /* recursive type */
6898 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6899 type1
.t
= 0; /* XXX: same as int */
6902 /* XXX: this is not correct to modify 'ad' at this point, but
6903 the syntax is not clear */
6904 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6905 parse_attribute(ad
);
6906 type_decl(&type1
, ad
, v
, td
);
6909 /* type identifier */
6910 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
6914 if (!(td
& TYPE_ABSTRACT
))
6915 expect("identifier");
6919 post_type(type
, ad
);
6920 if (tok
== TOK_ATTRIBUTE1
|| tok
== TOK_ATTRIBUTE2
)
6921 parse_attribute(ad
);
6924 /* append type at the end of type1 */
6937 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
6938 static int lvalue_type(int t
)
6943 if (bt
== VT_BYTE
|| bt
== VT_BOOL
)
6945 else if (bt
== VT_SHORT
)
6949 if (t
& VT_UNSIGNED
)
6950 r
|= VT_LVAL_UNSIGNED
;
6954 /* indirection with full error checking and bound check */
6955 static void indir(void)
6957 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
6959 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
6961 vtop
->type
= *pointed_type(&vtop
->type
);
6962 /* an array is never an lvalue */
6963 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6964 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6965 /* if bound checking, the referenced pointer must be checked */
6966 if (do_bounds_check
)
6967 vtop
->r
|= VT_MUSTBOUND
;
6971 /* pass a parameter to a function and do type checking and casting */
6972 static void gfunc_param_typed(Sym
*func
, Sym
*arg
)
6977 func_type
= func
->c
;
6978 if (func_type
== FUNC_OLD
||
6979 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
6980 /* default casting : only need to convert float to double */
6981 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
6985 } else if (arg
== NULL
) {
6986 error("too many arguments to function");
6989 type
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
6990 gen_assign_cast(&type
);
6994 /* parse an expression of the form '(type)' or '(expr)' and return its
6996 static void parse_expr_type(CType
*type
)
7002 if (parse_btype(type
, &ad
)) {
7003 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
7010 static void parse_type(CType
*type
)
7015 if (!parse_btype(type
, &ad
)) {
7018 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
7021 static void vpush_tokc(int t
)
7025 vsetc(&type
, VT_CONST
, &tokc
);
7028 static void unary(void)
7030 int n
, t
, align
, size
, r
;
7035 /* XXX: GCC 2.95.3 does not generate a table although it should be
7049 vpush_tokc(VT_INT
| VT_UNSIGNED
);
7053 vpush_tokc(VT_LLONG
);
7057 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
7061 vpush_tokc(VT_FLOAT
);
7065 vpush_tokc(VT_DOUBLE
);
7069 vpush_tokc(VT_LDOUBLE
);
7072 case TOK___FUNCTION__
:
7074 goto tok_identifier
;
7080 /* special function name identifier */
7081 len
= strlen(funcname
) + 1;
7082 /* generate char[len] type */
7087 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
7088 ptr
= section_ptr_add(data_section
, len
);
7089 memcpy(ptr
, funcname
, len
);
7097 /* string parsing */
7100 if (tcc_state
->warn_write_strings
)
7105 memset(&ad
, 0, sizeof(AttributeDef
));
7106 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
7111 if (parse_btype(&type
, &ad
)) {
7112 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
7114 /* check ISOC99 compound literal */
7116 /* data is allocated locally by default */
7121 /* all except arrays are lvalues */
7122 if (!(type
.t
& VT_ARRAY
))
7123 r
|= lvalue_type(type
.t
);
7124 memset(&ad
, 0, sizeof(AttributeDef
));
7125 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
7130 } else if (tok
== '{') {
7131 /* save all registers */
7133 /* statement expression : we do not accept break/continue
7134 inside as GCC does */
7135 block(NULL
, NULL
, NULL
, NULL
, 0, 1);
7150 /* functions names must be treated as function pointers,
7151 except for unary '&' and sizeof. Since we consider that
7152 functions are not lvalues, we only have to handle it
7153 there and in function calls. */
7154 /* arrays can also be used although they are not lvalues */
7155 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
7156 !(vtop
->type
.t
& VT_ARRAY
))
7158 mk_pointer(&vtop
->type
);
7164 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
7165 vtop
->c
.i
= !vtop
->c
.i
;
7166 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
7167 vtop
->c
.i
= vtop
->c
.i
^ 1;
7169 vseti(VT_JMP
, gtst(1, 0));
7179 /* in order to force cast, we add zero */
7181 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
7182 error("pointer not accepted for unary plus");
7192 parse_expr_type(&type
);
7196 size
= type_size(&type
, &align
);
7197 if (t
== TOK_SIZEOF
) {
7199 error("sizeof applied to an incomplete type");
7206 case TOK_builtin_types_compatible_p
:
7215 type1
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7216 type2
.t
&= ~(VT_CONSTANT
| VT_VOLATILE
);
7217 vpushi(is_compatible_types(&type1
, &type2
));
7220 case TOK_builtin_constant_p
:
7222 int saved_nocode_wanted
, res
;
7225 saved_nocode_wanted
= nocode_wanted
;
7228 res
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
7230 nocode_wanted
= saved_nocode_wanted
;
7250 goto tok_identifier
;
7252 /* allow to take the address of a label */
7253 if (tok
< TOK_UIDENT
)
7254 expect("label identifier");
7255 s
= label_find(tok
);
7257 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
7259 if (s
->r
== LABEL_DECLARED
)
7260 s
->r
= LABEL_FORWARD
;
7263 s
->type
.t
= VT_VOID
;
7264 mk_pointer(&s
->type
);
7265 s
->type
.t
|= VT_STATIC
;
7267 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
7276 expect("identifier");
7280 error("'%s' undeclared", get_tok_str(t
, NULL
));
7281 /* for simple function calls, we tolerate undeclared
7282 external reference to int() function */
7283 if (tcc_state
->warn_implicit_function_declaration
)
7284 warning("implicit declaration of function '%s'",
7285 get_tok_str(t
, NULL
));
7286 s
= external_global_sym(t
, &func_old_type
, 0);
7288 if ((s
->type
.t
& (VT_STATIC
| VT_INLINE
| VT_BTYPE
)) ==
7289 (VT_STATIC
| VT_INLINE
| VT_FUNC
)) {
7290 /* if referencing an inline function, then we generate a
7291 symbol to it if not already done. It will have the
7292 effect to generate code for it at the end of the
7293 compilation unit. Inline function as always
7294 generated in the text section. */
7296 put_extern_sym(s
, text_section
, 0, 0);
7297 r
= VT_SYM
| VT_CONST
;
7301 vset(&s
->type
, r
, s
->c
);
7302 /* if forward reference, we must point to s */
7303 if (vtop
->r
& VT_SYM
) {
7310 /* post operations */
7312 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
7315 } else if (tok
== '.' || tok
== TOK_ARROW
) {
7317 if (tok
== TOK_ARROW
)
7322 /* expect pointer on structure */
7323 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
7324 expect("struct or union");
7328 while ((s
= s
->next
) != NULL
) {
7333 error("field not found");
7334 /* add field offset to pointer */
7335 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
7338 /* change type to field type, and set to lvalue */
7339 vtop
->type
= s
->type
;
7340 /* an array is never an lvalue */
7341 if (!(vtop
->type
.t
& VT_ARRAY
)) {
7342 vtop
->r
|= lvalue_type(vtop
->type
.t
);
7343 /* if bound checking, the referenced pointer must be checked */
7344 if (do_bounds_check
)
7345 vtop
->r
|= VT_MUSTBOUND
;
7348 } else if (tok
== '[') {
7354 } else if (tok
== '(') {
7360 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
7361 /* pointer test (no array accepted) */
7362 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
7363 vtop
->type
= *pointed_type(&vtop
->type
);
7364 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
7368 expect("function pointer");
7371 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
7373 /* get return type */
7376 sa
= s
->next
; /* first parameter */
7378 /* compute first implicit argument if a structure is returned */
7379 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
7380 /* get some space for the returned structure */
7381 size
= type_size(&s
->type
, &align
);
7382 loc
= (loc
- size
) & -align
;
7384 ret
.r
= VT_LOCAL
| VT_LVAL
;
7385 /* pass it as 'int' to avoid structure arg passing
7387 vseti(VT_LOCAL
, loc
);
7393 /* return in register */
7394 if (is_float(ret
.type
.t
)) {
7397 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
7406 gfunc_param_typed(s
, sa
);
7416 error("too few arguments to function");
7418 if (!nocode_wanted
) {
7419 gfunc_call(nb_args
);
7421 vtop
-= (nb_args
+ 1);
7424 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
7432 static void uneq(void)
7438 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
7439 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
7440 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
7455 static void expr_prod(void)
7460 while (tok
== '*' || tok
== '/' || tok
== '%') {
7468 static void expr_sum(void)
7473 while (tok
== '+' || tok
== '-') {
7481 static void expr_shift(void)
7486 while (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
7494 static void expr_cmp(void)
7499 while ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
7500 tok
== TOK_ULT
|| tok
== TOK_UGE
) {
7508 static void expr_cmpeq(void)
7513 while (tok
== TOK_EQ
|| tok
== TOK_NE
) {
7521 static void expr_and(void)
7524 while (tok
== '&') {
7531 static void expr_xor(void)
7534 while (tok
== '^') {
7541 static void expr_or(void)
7544 while (tok
== '|') {
7551 /* XXX: fix this mess */
7552 static void expr_land_const(void)
7555 while (tok
== TOK_LAND
) {
7562 /* XXX: fix this mess */
7563 static void expr_lor_const(void)
7566 while (tok
== TOK_LOR
) {
7573 /* only used if non constant */
7574 static void expr_land(void)
7579 if (tok
== TOK_LAND
) {
7583 if (tok
!= TOK_LAND
) {
7593 static void expr_lor(void)
7598 if (tok
== TOK_LOR
) {
7602 if (tok
!= TOK_LOR
) {
7612 /* XXX: better constant handling */
7613 static void expr_eq(void)
7615 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
7617 CType type
, type1
, type2
;
7626 if (tok
== ':' && gnu_ext
) {
7642 if (vtop
!= vstack
) {
7643 /* needed to avoid having different registers saved in
7645 if (is_float(vtop
->type
.t
))
7652 if (tok
== ':' && gnu_ext
) {
7660 sv
= *vtop
; /* save value to handle it later */
7661 vtop
--; /* no vpop so that FP stack is not flushed */
7669 bt1
= t1
& VT_BTYPE
;
7671 bt2
= t2
& VT_BTYPE
;
7672 /* cast operands to correct type according to ISOC rules */
7673 if (is_float(bt1
) || is_float(bt2
)) {
7674 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
7675 type
.t
= VT_LDOUBLE
;
7676 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
7681 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
7682 /* cast to biggest op */
7684 /* convert to unsigned if it does not fit in a long long */
7685 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
7686 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
7687 type
.t
|= VT_UNSIGNED
;
7688 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
7689 /* XXX: test pointer compatibility */
7691 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
7692 /* XXX: test structure compatibility */
7694 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
7695 /* NOTE: as an extension, we accept void on only one side */
7698 /* integer operations */
7700 /* convert to unsigned if it does not fit in an integer */
7701 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
7702 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
7703 type
.t
|= VT_UNSIGNED
;
7706 /* now we convert second operand */
7709 if (is_float(type
.t
)) {
7711 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
7712 /* for long longs, we use fixed registers to avoid having
7713 to handle a complicated move */
7718 /* this is horrible, but we must also convert first
7722 /* put again first value and cast it */
7733 static void gexpr(void)
7744 /* parse an expression and return its type without any side effect. */
7745 static void expr_type(CType
*type
)
7747 int saved_nocode_wanted
;
7749 saved_nocode_wanted
= nocode_wanted
;
7754 nocode_wanted
= saved_nocode_wanted
;
7757 /* parse a unary expression and return its type without any side
7759 static void unary_type(CType
*type
)
7771 /* parse a constant expression and return value in vtop. */
7772 static void expr_const1(void)
7781 /* parse an integer constant and return its value. */
7782 static int expr_const(void)
7786 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
7787 expect("constant expression");
7793 /* return the label token if current token is a label, otherwise
7795 static int is_label(void)
7799 /* fast test first */
7800 if (tok
< TOK_UIDENT
)
7802 /* no need to save tokc because tok is an identifier */
7809 unget_tok(last_tok
);
7814 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
,
7815 int case_reg
, int is_expr
)
7820 /* generate line number info */
7822 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
7823 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
7825 last_line_num
= file
->line_num
;
7829 /* default return value is (void) */
7831 vtop
->type
.t
= VT_VOID
;
7834 if (tok
== TOK_IF
) {
7841 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7843 if (c
== TOK_ELSE
) {
7847 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, 0);
7848 gsym(d
); /* patch else jmp */
7851 } else if (tok
== TOK_WHILE
) {
7859 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7863 } else if (tok
== '{') {
7867 /* record local declaration stack position */
7869 llabel
= local_label_stack
;
7870 /* handle local labels declarations */
7871 if (tok
== TOK_LABEL
) {
7874 if (tok
< TOK_UIDENT
)
7875 expect("label identifier");
7876 label_push(&local_label_stack
, tok
, LABEL_DECLARED
);
7886 while (tok
!= '}') {
7891 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
7894 /* pop locally defined labels */
7895 label_pop(&local_label_stack
, llabel
);
7896 /* pop locally defined symbols */
7897 sym_pop(&local_stack
, s
);
7899 } else if (tok
== TOK_RETURN
) {
7903 gen_assign_cast(&func_vt
);
7904 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
7906 /* if returning structure, must copy it to implicit
7907 first pointer arg location */
7910 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
7913 /* copy structure value to pointer */
7915 } else if (is_float(func_vt
.t
)) {
7920 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
7923 rsym
= gjmp(rsym
); /* jmp */
7924 } else if (tok
== TOK_BREAK
) {
7927 error("cannot break");
7928 *bsym
= gjmp(*bsym
);
7931 } else if (tok
== TOK_CONTINUE
) {
7934 error("cannot continue");
7935 *csym
= gjmp(*csym
);
7938 } else if (tok
== TOK_FOR
) {
7965 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7970 if (tok
== TOK_DO
) {
7975 block(&a
, &b
, case_sym
, def_sym
, case_reg
, 0);
7986 if (tok
== TOK_SWITCH
) {
7990 /* XXX: other types than integer */
7991 case_reg
= gv(RC_INT
);
7995 b
= gjmp(0); /* jump to first case */
7997 block(&a
, csym
, &b
, &c
, case_reg
, 0);
7998 /* if no default, jmp after switch */
8006 if (tok
== TOK_CASE
) {
8013 if (gnu_ext
&& tok
== TOK_DOTS
) {
8017 warning("empty case range");
8019 /* since a case is like a label, we must skip it with a jmp */
8026 *case_sym
= gtst(1, 0);
8029 *case_sym
= gtst(1, 0);
8033 *case_sym
= gtst(1, *case_sym
);
8038 goto block_after_label
;
8040 if (tok
== TOK_DEFAULT
) {
8046 error("too many 'default'");
8049 goto block_after_label
;
8051 if (tok
== TOK_GOTO
) {
8053 if (tok
== '*' && gnu_ext
) {
8057 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
8060 } else if (tok
>= TOK_UIDENT
) {
8061 s
= label_find(tok
);
8062 /* put forward definition if needed */
8064 s
= label_push(&global_label_stack
, tok
, LABEL_FORWARD
);
8066 if (s
->r
== LABEL_DECLARED
)
8067 s
->r
= LABEL_FORWARD
;
8069 /* label already defined */
8070 if (s
->r
& LABEL_FORWARD
)
8071 s
->next
= (void *)gjmp((long)s
->next
);
8073 gjmp_addr((long)s
->next
);
8076 expect("label identifier");
8079 } else if (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
) {
8087 if (s
->r
== LABEL_DEFINED
)
8088 error("duplicate label '%s'", get_tok_str(s
->v
, NULL
));
8089 gsym((long)s
->next
);
8090 s
->r
= LABEL_DEFINED
;
8092 s
= label_push(&global_label_stack
, b
, LABEL_DEFINED
);
8094 s
->next
= (void *)ind
;
8095 /* we accept this, but it is a mistake */
8098 warning("deprecated use of label at end of compound statement");
8102 block(bsym
, csym
, case_sym
, def_sym
, case_reg
, is_expr
);
8105 /* expression case */
8120 /* t is the array or struct type. c is the array or struct
8121 address. cur_index/cur_field is the pointer to the current
8122 value. 'size_only' is true if only size info is needed (only used
8124 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
8125 int *cur_index
, Sym
**cur_field
,
8129 int notfirst
, index
, index_last
, align
, l
, nb_elems
, elem_size
;
8135 if (gnu_ext
&& (l
= is_label()) != 0)
8137 while (tok
== '[' || tok
== '.') {
8139 if (!(type
->t
& VT_ARRAY
))
8140 expect("array type");
8143 index
= expr_const();
8144 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
8145 expect("invalid index");
8146 if (tok
== TOK_DOTS
&& gnu_ext
) {
8148 index_last
= expr_const();
8149 if (index_last
< 0 ||
8150 (s
->c
>= 0 && index_last
>= s
->c
) ||
8152 expect("invalid index");
8158 *cur_index
= index_last
;
8159 type
= pointed_type(type
);
8160 elem_size
= type_size(type
, &align
);
8161 c
+= index
* elem_size
;
8162 /* NOTE: we only support ranges for last designator */
8163 nb_elems
= index_last
- index
+ 1;
8164 if (nb_elems
!= 1) {
8173 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
8174 expect("struct/union type");
8187 /* XXX: fix this mess by using explicit storage field */
8189 type1
.t
|= (type
->t
& ~VT_TYPE
);
8203 if (type
->t
& VT_ARRAY
) {
8205 type
= pointed_type(type
);
8206 c
+= index
* type_size(type
, &align
);
8210 error("too many field init");
8211 /* XXX: fix this mess by using explicit storage field */
8213 type1
.t
|= (type
->t
& ~VT_TYPE
);
8218 decl_initializer(type
, sec
, c
, 0, size_only
);
8220 /* XXX: make it more general */
8221 if (!size_only
&& nb_elems
> 1) {
8222 unsigned long c_end
;
8227 error("range init not supported yet for dynamic storage");
8228 c_end
= c
+ nb_elems
* elem_size
;
8229 if (c_end
> sec
->data_allocated
)
8230 section_realloc(sec
, c_end
);
8231 src
= sec
->data
+ c
;
8233 for(i
= 1; i
< nb_elems
; i
++) {
8235 memcpy(dst
, src
, elem_size
);
8241 #define EXPR_CONST 1
8244 /* store a value or an expression directly in global data or in local array */
8245 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
8246 int v
, int expr_type
)
8248 int saved_global_expr
, bt
, bit_pos
, bit_size
;
8250 unsigned long long bit_mask
;
8258 /* compound literals must be allocated globally in this case */
8259 saved_global_expr
= global_expr
;
8262 global_expr
= saved_global_expr
;
8263 /* NOTE: symbols are accepted */
8264 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
8265 error("initializer element is not constant");
8273 dtype
.t
&= ~VT_CONSTANT
; /* need to do that to avoid false warning */
8276 /* XXX: not portable */
8277 /* XXX: generate error if incorrect relocation */
8278 gen_assign_cast(&dtype
);
8279 bt
= type
->t
& VT_BTYPE
;
8280 ptr
= sec
->data
+ c
;
8281 /* XXX: make code faster ? */
8282 if (!(type
->t
& VT_BITFIELD
)) {
8287 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
8288 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
8289 bit_mask
= (1LL << bit_size
) - 1;
8291 if ((vtop
->r
& VT_SYM
) &&
8297 (bt
== VT_INT
&& bit_size
!= 32)))
8298 error("initializer element is not computable at load time");
8301 *(char *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8304 *(short *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8307 *(double *)ptr
= vtop
->c
.d
;
8310 *(long double *)ptr
= vtop
->c
.ld
;
8313 *(long long *)ptr
|= (vtop
->c
.ll
& bit_mask
) << bit_pos
;
8316 if (vtop
->r
& VT_SYM
) {
8317 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
8319 *(int *)ptr
|= (vtop
->c
.i
& bit_mask
) << bit_pos
;
8324 vset(&dtype
, VT_LOCAL
, c
);
8331 /* put zeros for variable based init */
8332 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
8335 /* nothing to do because globals are already set to zero */
8337 vpush_global_sym(&func_old_type
, TOK_memset
);
8345 /* 't' contains the type and storage info. 'c' is the offset of the
8346 object in section 'sec'. If 'sec' is NULL, it means stack based
8347 allocation. 'first' is true if array '{' must be read (multi
8348 dimension implicit array init handling). 'size_only' is true if
8349 size only evaluation is wanted (only for arrays). */
8350 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
8351 int first
, int size_only
)
8353 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
8354 int size1
, align1
, expr_type
;
8358 if (type
->t
& VT_ARRAY
) {
8362 t1
= pointed_type(type
);
8363 size1
= type_size(t1
, &align1
);
8366 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
8372 /* only parse strings here if correct type (otherwise: handle
8373 them as ((w)char *) expressions */
8374 if ((tok
== TOK_LSTR
&&
8375 (t1
->t
& VT_BTYPE
) == VT_INT
) ||
8377 (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
8378 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8383 /* compute maximum number of chars wanted */
8385 cstr_len
= cstr
->size
;
8387 cstr_len
= cstr
->size
/ sizeof(int);
8390 if (n
>= 0 && nb
> (n
- array_length
))
8391 nb
= n
- array_length
;
8394 warning("initializer-string for array is too long");
8395 /* in order to go faster for common case (char
8396 string in global variable, we handle it
8398 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
8399 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
8403 ch
= ((unsigned char *)cstr
->data
)[i
];
8405 ch
= ((int *)cstr
->data
)[i
];
8406 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
8414 /* only add trailing zero if enough storage (no
8415 warning in this case since it is standard) */
8416 if (n
< 0 || array_length
< n
) {
8418 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
8424 while (tok
!= '}') {
8425 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
8426 if (n
>= 0 && index
>= n
)
8427 error("index too large");
8428 /* must put zero in holes (note that doing it that way
8429 ensures that it even works with designators) */
8430 if (!size_only
&& array_length
< index
) {
8431 init_putz(t1
, sec
, c
+ array_length
* size1
,
8432 (index
- array_length
) * size1
);
8435 if (index
> array_length
)
8436 array_length
= index
;
8437 /* special test for multi dimensional arrays (may not
8438 be strictly correct if designators are used at the
8440 if (index
>= n
&& no_oblock
)
8449 /* put zeros at the end */
8450 if (!size_only
&& n
>= 0 && array_length
< n
) {
8451 init_putz(t1
, sec
, c
+ array_length
* size1
,
8452 (n
- array_length
) * size1
);
8454 /* patch type size if needed */
8456 s
->c
= array_length
;
8457 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&&
8458 (sec
|| !first
|| tok
== '{')) {
8461 /* NOTE: the previous test is a specific case for automatic
8462 struct/union init */
8463 /* XXX: union needs only one init */
8465 /* XXX: this test is incorrect for local initializers
8466 beginning with ( without {. It would be much more difficult
8467 to do it correctly (ideally, the expression parser should
8468 be used in all cases) */
8474 while (tok
== '(') {
8478 if (!parse_btype(&type1
, &ad1
))
8480 type_decl(&type1
, &ad1
, &n
, TYPE_ABSTRACT
);
8482 if (!is_assignable_types(type
, &type1
))
8483 error("invalid type for cast");
8488 if (first
|| tok
== '{') {
8497 while (tok
!= '}') {
8498 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
8500 if (!size_only
&& array_length
< index
) {
8501 init_putz(type
, sec
, c
+ array_length
,
8502 index
- array_length
);
8504 index
= index
+ type_size(&f
->type
, &align1
);
8505 if (index
> array_length
)
8506 array_length
= index
;
8508 if (no_oblock
&& f
== NULL
)
8514 /* put zeros at the end */
8515 if (!size_only
&& array_length
< n
) {
8516 init_putz(type
, sec
, c
+ array_length
,
8525 } else if (tok
== '{') {
8527 decl_initializer(type
, sec
, c
, first
, size_only
);
8529 } else if (size_only
) {
8530 /* just skip expression */
8532 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
8536 else if (tok
== ')')
8541 /* currently, we always use constant expression for globals
8542 (may change for scripting case) */
8543 expr_type
= EXPR_CONST
;
8545 expr_type
= EXPR_ANY
;
8546 init_putv(type
, sec
, c
, 0, expr_type
);
8550 /* parse an initializer for type 't' if 'has_init' is non zero, and
8551 allocate space in local or global data space ('r' is either
8552 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8553 variable 'v' of scope 'scope' is declared before initializers are
8554 parsed. If 'v' is zero, then a reference to the new object is put
8555 in the value stack. If 'has_init' is 2, a special parsing is done
8556 to handle string constants. */
8557 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
8558 int has_init
, int v
, int scope
)
8560 int size
, align
, addr
, data_offset
;
8562 ParseState saved_parse_state
;
8563 TokenString init_str
;
8566 size
= type_size(type
, &align
);
8567 /* If unknown size, we must evaluate it before
8568 evaluating initializers because
8569 initializers can generate global data too
8570 (e.g. string pointers or ISOC99 compound
8571 literals). It also simplifies local
8572 initializers handling */
8573 tok_str_new(&init_str
);
8576 error("unknown type size");
8577 /* get all init string */
8578 if (has_init
== 2) {
8579 /* only get strings */
8580 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
8581 tok_str_add_tok(&init_str
);
8586 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
8588 error("unexpected end of file in initializer");
8589 tok_str_add_tok(&init_str
);
8592 else if (tok
== '}') {
8600 tok_str_add(&init_str
, -1);
8601 tok_str_add(&init_str
, 0);
8604 save_parse_state(&saved_parse_state
);
8606 macro_ptr
= init_str
.str
;
8608 decl_initializer(type
, NULL
, 0, 1, 1);
8609 /* prepare second initializer parsing */
8610 macro_ptr
= init_str
.str
;
8613 /* if still unknown size, error */
8614 size
= type_size(type
, &align
);
8616 error("unknown type size");
8618 /* take into account specified alignment if bigger */
8620 if (ad
->aligned
> align
)
8621 align
= ad
->aligned
;
8622 } else if (ad
->packed
) {
8625 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
8627 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
8629 loc
= (loc
- size
) & -align
;
8631 /* handles bounds */
8632 /* XXX: currently, since we do only one pass, we cannot track
8633 '&' operators, so we add only arrays */
8634 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
8635 unsigned long *bounds_ptr
;
8636 /* add padding between regions */
8638 /* then add local bound info */
8639 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
8640 bounds_ptr
[0] = addr
;
8641 bounds_ptr
[1] = size
;
8644 /* local variable */
8645 sym_push(v
, type
, r
, addr
);
8647 /* push local reference */
8648 vset(type
, r
, addr
);
8654 if (v
&& scope
== VT_CONST
) {
8655 /* see if the symbol was already defined */
8658 if (!is_compatible_types(&sym
->type
, type
))
8659 error("incompatible types for redefinition of '%s'",
8660 get_tok_str(v
, NULL
));
8661 if (sym
->type
.t
& VT_EXTERN
) {
8662 /* if the variable is extern, it was not allocated */
8663 sym
->type
.t
&= ~VT_EXTERN
;
8664 /* set array size if it was ommited in extern
8666 if ((sym
->type
.t
& VT_ARRAY
) &&
8667 sym
->type
.ref
->c
< 0 &&
8669 sym
->type
.ref
->c
= type
->ref
->c
;
8671 /* we accept several definitions of the same
8672 global variable. this is tricky, because we
8673 must play with the SHN_COMMON type of the symbol */
8674 /* XXX: should check if the variable was already
8675 initialized. It is incorrect to initialized it
8677 /* no init data, we won't add more to the symbol */
8684 /* allocate symbol in corresponding section */
8689 else if (tcc_state
->nocommon
)
8693 data_offset
= sec
->data_offset
;
8694 data_offset
= (data_offset
+ align
- 1) & -align
;
8696 /* very important to increment global pointer at this time
8697 because initializers themselves can create new initializers */
8698 data_offset
+= size
;
8699 /* add padding if bound check */
8700 if (do_bounds_check
)
8702 sec
->data_offset
= data_offset
;
8703 /* allocate section space to put the data */
8704 if (sec
->sh_type
!= SHT_NOBITS
&&
8705 data_offset
> sec
->data_allocated
)
8706 section_realloc(sec
, data_offset
);
8707 /* align section if needed */
8708 if (align
> sec
->sh_addralign
)
8709 sec
->sh_addralign
= align
;
8711 addr
= 0; /* avoid warning */
8715 if (scope
== VT_CONST
) {
8720 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
8722 /* update symbol definition */
8724 put_extern_sym(sym
, sec
, addr
, size
);
8727 /* put a common area */
8728 put_extern_sym(sym
, NULL
, align
, size
);
8729 /* XXX: find a nicer way */
8730 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
8731 esym
->st_shndx
= SHN_COMMON
;
8736 /* push global reference */
8737 sym
= get_sym_ref(type
, sec
, addr
, size
);
8739 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
8743 /* handles bounds now because the symbol must be defined
8744 before for the relocation */
8745 if (do_bounds_check
) {
8746 unsigned long *bounds_ptr
;
8748 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
8749 /* then add global bound info */
8750 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
8751 bounds_ptr
[0] = 0; /* relocated */
8752 bounds_ptr
[1] = size
;
8756 decl_initializer(type
, sec
, addr
, 1, 0);
8757 /* restore parse state if needed */
8759 tok_str_free(init_str
.str
);
8760 restore_parse_state(&saved_parse_state
);
8766 void put_func_debug(Sym
*sym
)
8771 /* XXX: we put here a dummy type */
8772 snprintf(buf
, sizeof(buf
), "%s:%c1",
8773 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
8774 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
8775 cur_text_section
, sym
->c
);
8780 /* parse an old style function declaration list */
8781 /* XXX: check multiple parameter */
8782 static void func_decl_list(Sym
*func_sym
)
8789 /* parse each declaration */
8790 while (tok
!= '{' && tok
!= ';' && tok
!= ',' && tok
!= TOK_EOF
) {
8791 if (!parse_btype(&btype
, &ad
))
8792 expect("declaration list");
8793 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
8794 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
8796 /* we accept no variable after */
8800 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8801 /* find parameter in function parameter list */
8804 if ((s
->v
& ~SYM_FIELD
) == v
)
8808 error("declaration for parameter '%s' but no such parameter",
8809 get_tok_str(v
, NULL
));
8811 /* check that no storage specifier except 'register' was given */
8812 if (type
.t
& VT_STORAGE
)
8813 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
8814 convert_parameter_type(&type
);
8815 /* we can add the type (NOTE: it could be local to the function) */
8817 /* accept other parameters */
8828 /* parse a function defined by symbol 'sym' and generate its code in
8829 'cur_text_section' */
8830 static void gen_function(Sym
*sym
)
8832 ind
= cur_text_section
->data_offset
;
8833 /* NOTE: we patch the symbol size later */
8834 put_extern_sym(sym
, cur_text_section
, ind
, 0);
8835 funcname
= get_tok_str(sym
->v
, NULL
);
8837 /* put debug symbol */
8839 put_func_debug(sym
);
8840 /* push a dummy symbol to enable local sym storage */
8841 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
8842 gfunc_prolog(&sym
->type
);
8844 block(NULL
, NULL
, NULL
, NULL
, 0, 0);
8847 cur_text_section
->data_offset
= ind
;
8848 label_pop(&global_label_stack
, NULL
);
8849 sym_pop(&local_stack
, NULL
); /* reset local stack */
8850 /* end of function */
8851 /* patch symbol size */
8852 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
8855 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
8857 funcname
= ""; /* for safety */
8858 func_vt
.t
= VT_VOID
; /* for safety */
8859 ind
= 0; /* for safety */
8862 static void gen_inline_functions(void)
8866 int *str
, inline_generated
;
8868 /* iterate while inline function are referenced */
8870 inline_generated
= 0;
8871 for(sym
= global_stack
; sym
!= NULL
; sym
= sym
->prev
) {
8873 if (((type
->t
& VT_BTYPE
) == VT_FUNC
) &&
8874 (type
->t
& (VT_STATIC
| VT_INLINE
)) ==
8875 (VT_STATIC
| VT_INLINE
) &&
8877 /* the function was used: generate its code and
8878 convert it to a normal function */
8879 str
= (int *)sym
->r
;
8880 sym
->r
= VT_SYM
| VT_CONST
;
8881 type
->t
&= ~VT_INLINE
;
8885 cur_text_section
= text_section
;
8887 macro_ptr
= NULL
; /* fail safe */
8890 inline_generated
= 1;
8893 if (!inline_generated
)
8897 /* free all remaining inline function tokens */
8898 for(sym
= global_stack
; sym
!= NULL
; sym
= sym
->prev
) {
8900 if (((type
->t
& VT_BTYPE
) == VT_FUNC
) &&
8901 (type
->t
& (VT_STATIC
| VT_INLINE
)) ==
8902 (VT_STATIC
| VT_INLINE
)) {
8903 str
= (int *)sym
->r
;
8905 sym
->r
= 0; /* fail safe */
8910 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
8911 static void decl(int l
)
8919 if (!parse_btype(&btype
, &ad
)) {
8920 /* skip redundant ';' */
8921 /* XXX: find more elegant solution */
8926 if (l
== VT_CONST
&&
8927 (tok
== TOK_ASM1
|| tok
== TOK_ASM2
|| tok
== TOK_ASM3
)) {
8928 /* global asm block */
8932 /* special test for old K&R protos without explicit int
8933 type. Only accepted when defining global data */
8934 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
8938 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
8939 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
8941 /* we accept no variable after */
8945 while (1) { /* iterate thru each declaration */
8947 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
8951 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
8952 printf("type = '%s'\n", buf
);
8955 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
8956 /* if old style function prototype, we accept a
8959 if (sym
->c
== FUNC_OLD
)
8960 func_decl_list(sym
);
8965 error("cannot use local functions");
8966 if (!(type
.t
& VT_FUNC
))
8967 expect("function definition");
8969 /* reject abstract declarators in function definition */
8971 while ((sym
= sym
->next
) != NULL
)
8972 if (!(sym
->v
& ~SYM_FIELD
))
8973 expect("identifier");
8975 /* XXX: cannot do better now: convert extern line to static inline */
8976 if ((type
.t
& (VT_EXTERN
| VT_INLINE
)) == (VT_EXTERN
| VT_INLINE
))
8977 type
.t
= (type
.t
& ~VT_EXTERN
) | VT_STATIC
;
8981 if ((sym
->type
.t
& VT_BTYPE
) != VT_FUNC
)
8983 /* specific case: if not func_call defined, we put
8984 the one of the prototype */
8985 /* XXX: should have default value */
8986 if (sym
->type
.ref
->r
!= FUNC_CDECL
&&
8987 type
.ref
->r
== FUNC_CDECL
)
8988 type
.ref
->r
= sym
->type
.ref
->r
;
8989 if (!is_compatible_types(&sym
->type
, &type
)) {
8991 error("incompatible types for redefinition of '%s'",
8992 get_tok_str(v
, NULL
));
8994 /* if symbol is already defined, then put complete type */
8997 /* put function symbol */
8998 sym
= global_identifier_push(v
, type
.t
, 0);
8999 sym
->type
.ref
= type
.ref
;
9002 /* static inline functions are just recorded as a kind
9003 of macro. Their code will be emitted at the end of
9004 the compilation unit only if they are used */
9005 if ((type
.t
& (VT_INLINE
| VT_STATIC
)) ==
9006 (VT_INLINE
| VT_STATIC
)) {
9007 TokenString func_str
;
9010 tok_str_new(&func_str
);
9016 error("unexpected end of file");
9017 tok_str_add_tok(&func_str
);
9022 } else if (t
== '}') {
9024 if (block_level
== 0)
9028 tok_str_add(&func_str
, -1);
9029 tok_str_add(&func_str
, 0);
9030 sym
->r
= (int)func_str
.str
;
9032 /* compute text section */
9033 cur_text_section
= ad
.section
;
9034 if (!cur_text_section
)
9035 cur_text_section
= text_section
;
9036 sym
->r
= VT_SYM
| VT_CONST
;
9038 #ifdef TCC_TARGET_PE
9040 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_other
|= 1;
9046 if (btype
.t
& VT_TYPEDEF
) {
9047 /* save typedefed type */
9048 /* XXX: test storage specifiers ? */
9049 sym
= sym_push(v
, &type
, 0, 0);
9050 sym
->type
.t
|= VT_TYPEDEF
;
9051 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
9052 /* external function definition */
9053 /* specific case for func_call attribute */
9055 type
.ref
->r
= ad
.func_call
;
9056 external_sym(v
, &type
, 0);
9058 /* not lvalue if array */
9060 if (!(type
.t
& VT_ARRAY
))
9061 r
|= lvalue_type(type
.t
);
9062 has_init
= (tok
== '=');
9063 if ((btype
.t
& VT_EXTERN
) ||
9064 ((type
.t
& VT_ARRAY
) && (type
.t
& VT_STATIC
) &&
9065 !has_init
&& l
== VT_CONST
&& type
.ref
->c
< 0)) {
9066 /* external variable */
9067 /* NOTE: as GCC, uninitialized global static
9068 arrays of null size are considered as
9070 external_sym(v
, &type
, r
);
9072 if (type
.t
& VT_STATIC
)
9078 decl_initializer_alloc(&type
, &ad
, r
,
9092 /* better than nothing, but needs extension to handle '-E' option
9094 static void preprocess_init(TCCState
*s1
)
9096 s1
->include_stack_ptr
= s1
->include_stack
;
9097 /* XXX: move that before to avoid having to initialize
9098 file->ifdef_stack_ptr ? */
9099 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
9100 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
9102 /* XXX: not ANSI compliant: bound checking says error */
9104 s1
->pack_stack
[0] = 0;
9105 s1
->pack_stack_ptr
= s1
->pack_stack
;
9108 /* compile the C file opened in 'file'. Return non zero if errors. */
9109 static int tcc_compile(TCCState
*s1
)
9113 volatile int section_sym
;
9116 printf("%s: **** new file\n", file
->filename
);
9118 preprocess_init(s1
);
9121 anon_sym
= SYM_FIRST_ANOM
;
9123 /* file info: full path + filename */
9124 section_sym
= 0; /* avoid warning */
9126 section_sym
= put_elf_sym(symtab_section
, 0, 0,
9127 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
9128 text_section
->sh_num
, NULL
);
9129 getcwd(buf
, sizeof(buf
));
9130 pstrcat(buf
, sizeof(buf
), "/");
9131 put_stabs_r(buf
, N_SO
, 0, 0,
9132 text_section
->data_offset
, text_section
, section_sym
);
9133 put_stabs_r(file
->filename
, N_SO
, 0, 0,
9134 text_section
->data_offset
, text_section
, section_sym
);
9136 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
9137 symbols can be safely used */
9138 put_elf_sym(symtab_section
, 0, 0,
9139 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
9140 SHN_ABS
, file
->filename
);
9142 /* define some often used types */
9143 int_type
.t
= VT_INT
;
9145 char_pointer_type
.t
= VT_BYTE
;
9146 mk_pointer(&char_pointer_type
);
9148 func_old_type
.t
= VT_FUNC
;
9149 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
9152 /* define 'void *alloca(unsigned int)' builtin function */
9157 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
9158 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
9161 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
9165 define_start
= define_stack
;
9167 if (setjmp(s1
->error_jmp_buf
) == 0) {
9169 s1
->error_set_jmp_enabled
= 1;
9171 ch
= file
->buf_ptr
[0];
9172 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
9173 parse_flags
= PARSE_FLAG_PREPROCESS
| PARSE_FLAG_TOK_NUM
;
9177 expect("declaration");
9179 /* end of translation unit info */
9181 put_stabs_r(NULL
, N_SO
, 0, 0,
9182 text_section
->data_offset
, text_section
, section_sym
);
9185 s1
->error_set_jmp_enabled
= 0;
9187 /* reset define stack, but leave -Dsymbols (may be incorrect if
9188 they are undefined) */
9189 free_defines(define_start
);
9191 gen_inline_functions();
9193 sym_pop(&global_stack
, NULL
);
9195 return s1
->nb_errors
!= 0 ? -1 : 0;
9199 int tcc_compile_string(TCCState
*s
, const char *str
)
9201 BufferedFile bf1
, *bf
= &bf1
;
9205 /* init file structure */
9207 /* XXX: avoid copying */
9209 buf
= tcc_malloc(len
+ 1);
9212 memcpy(buf
, str
, len
);
9215 bf
->buf_end
= buf
+ len
;
9216 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
9220 ret
= tcc_compile(s
);
9224 /* currently, no need to close */
9229 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
9230 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
9232 BufferedFile bf1
, *bf
= &bf1
;
9234 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
9235 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
9239 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
9241 /* init file structure */
9243 bf
->buf_ptr
= bf
->buffer
;
9244 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
9245 *bf
->buf_end
= CH_EOB
;
9246 bf
->filename
[0] = '\0';
9250 s1
->include_stack_ptr
= s1
->include_stack
;
9252 /* parse with define parser */
9253 ch
= file
->buf_ptr
[0];
9259 /* undefine a preprocessor symbol */
9260 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
9264 ts
= tok_alloc(sym
, strlen(sym
));
9265 s
= define_find(ts
->tok
);
9266 /* undefine symbol by putting an invalid name */
9271 #ifdef CONFIG_TCC_ASM
9273 #ifdef TCC_TARGET_I386
9274 #include "i386-asm.c"
9279 static void asm_instr(void)
9281 error("inline asm() not supported");
9283 static void asm_global_instr(void)
9285 error("inline asm() not supported");
9291 #ifdef TCC_TARGET_COFF
9292 #include "tcccoff.c"
9295 #ifdef TCC_TARGET_PE
9299 /* print the position in the source file of PC value 'pc' by reading
9300 the stabs debug information */
9301 static void rt_printline(unsigned long wanted_pc
)
9303 Stab_Sym
*sym
, *sym_end
;
9304 char func_name
[128], last_func_name
[128];
9305 unsigned long func_addr
, last_pc
, pc
;
9306 const char *incl_files
[INCLUDE_STACK_SIZE
];
9307 int incl_index
, len
, last_line_num
, i
;
9308 const char *str
, *p
;
9310 fprintf(stderr
, "0x%08lx:", wanted_pc
);
9312 func_name
[0] = '\0';
9315 last_func_name
[0] = '\0';
9316 last_pc
= 0xffffffff;
9318 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
9319 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
9320 while (sym
< sym_end
) {
9321 switch(sym
->n_type
) {
9322 /* function start or end */
9324 if (sym
->n_strx
== 0) {
9325 /* we test if between last line and end of function */
9326 pc
= sym
->n_value
+ func_addr
;
9327 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9329 func_name
[0] = '\0';
9332 str
= stabstr_section
->data
+ sym
->n_strx
;
9333 p
= strchr(str
, ':');
9335 pstrcpy(func_name
, sizeof(func_name
), str
);
9338 if (len
> sizeof(func_name
) - 1)
9339 len
= sizeof(func_name
) - 1;
9340 memcpy(func_name
, str
, len
);
9341 func_name
[len
] = '\0';
9343 func_addr
= sym
->n_value
;
9346 /* line number info */
9348 pc
= sym
->n_value
+ func_addr
;
9349 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
9352 last_line_num
= sym
->n_desc
;
9354 strcpy(last_func_name
, func_name
);
9358 str
= stabstr_section
->data
+ sym
->n_strx
;
9360 if (incl_index
< INCLUDE_STACK_SIZE
) {
9361 incl_files
[incl_index
++] = str
;
9369 if (sym
->n_strx
== 0) {
9370 incl_index
= 0; /* end of translation unit */
9372 str
= stabstr_section
->data
+ sym
->n_strx
;
9373 /* do not add path */
9375 if (len
> 0 && str
[len
- 1] != '/')
9383 /* second pass: we try symtab symbols (no line number info) */
9386 Elf32_Sym
*sym
, *sym_end
;
9389 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
9390 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
9393 type
= ELF32_ST_TYPE(sym
->st_info
);
9394 if (type
== STT_FUNC
) {
9395 if (wanted_pc
>= sym
->st_value
&&
9396 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
9397 pstrcpy(last_func_name
, sizeof(last_func_name
),
9398 strtab_section
->data
+ sym
->st_name
);
9404 /* did not find any info: */
9405 fprintf(stderr
, " ???\n");
9408 if (last_func_name
[0] != '\0') {
9409 fprintf(stderr
, " %s()", last_func_name
);
9411 if (incl_index
> 0) {
9412 fprintf(stderr
, " (%s:%d",
9413 incl_files
[incl_index
- 1], last_line_num
);
9414 for(i
= incl_index
- 2; i
>= 0; i
--)
9415 fprintf(stderr
, ", included from %s", incl_files
[i
]);
9416 fprintf(stderr
, ")");
9418 fprintf(stderr
, "\n");
9421 #if !defined(WIN32) && !defined(CONFIG_TCCBOOT)
9425 /* fix for glibc 2.1 */
9431 /* return the PC at frame level 'level'. Return non zero if not found */
9432 static int rt_get_caller_pc(unsigned long *paddr
,
9433 ucontext_t
*uc
, int level
)
9439 #if defined(__FreeBSD__)
9440 *paddr
= uc
->uc_mcontext
.mc_eip
;
9441 #elif defined(__dietlibc__)
9442 *paddr
= uc
->uc_mcontext
.eip
;
9444 *paddr
= uc
->uc_mcontext
.gregs
[REG_EIP
];
9448 #if defined(__FreeBSD__)
9449 fp
= uc
->uc_mcontext
.mc_ebp
;
9450 #elif defined(__dietlibc__)
9451 fp
= uc
->uc_mcontext
.ebp
;
9453 fp
= uc
->uc_mcontext
.gregs
[REG_EBP
];
9455 for(i
=1;i
<level
;i
++) {
9456 /* XXX: check address validity with program info */
9457 if (fp
<= 0x1000 || fp
>= 0xc0000000)
9459 fp
= ((unsigned long *)fp
)[0];
9461 *paddr
= ((unsigned long *)fp
)[1];
9467 #warning add arch specific rt_get_caller_pc()
9469 static int rt_get_caller_pc(unsigned long *paddr
,
9470 ucontext_t
*uc
, int level
)
9476 /* emit a run time error at position 'pc' */
9477 void rt_error(ucontext_t
*uc
, const char *fmt
, ...)
9484 fprintf(stderr
, "Runtime error: ");
9485 vfprintf(stderr
, fmt
, ap
);
9486 fprintf(stderr
, "\n");
9487 for(i
=0;i
<num_callers
;i
++) {
9488 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
9491 fprintf(stderr
, "at ");
9493 fprintf(stderr
, "by ");
9500 /* signal handler for fatal errors */
9501 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
9503 ucontext_t
*uc
= puc
;
9507 switch(siginf
->si_code
) {
9510 rt_error(uc
, "division by zero");
9513 rt_error(uc
, "floating point exception");
9519 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
9520 rt_error(uc
, *rt_bound_error_msg
);
9522 rt_error(uc
, "dereferencing invalid pointer");
9525 rt_error(uc
, "illegal instruction");
9528 rt_error(uc
, "abort() called");
9531 rt_error(uc
, "caught signal %d", signum
);
9538 /* do all relocations (needed before using tcc_get_symbol()) */
9539 int tcc_relocate(TCCState
*s1
)
9546 #ifdef TCC_TARGET_PE
9549 tcc_add_runtime(s1
);
9552 relocate_common_syms();
9554 tcc_add_linker_symbols(s1
);
9556 build_got_entries(s1
);
9558 /* compute relocation address : section are relocated in place. We
9559 also alloc the bss space */
9560 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9561 s
= s1
->sections
[i
];
9562 if (s
->sh_flags
& SHF_ALLOC
) {
9563 if (s
->sh_type
== SHT_NOBITS
)
9564 s
->data
= tcc_mallocz(s
->data_offset
);
9565 s
->sh_addr
= (unsigned long)s
->data
;
9569 relocate_syms(s1
, 1);
9571 if (s1
->nb_errors
!= 0)
9574 /* relocate each section */
9575 for(i
= 1; i
< s1
->nb_sections
; i
++) {
9576 s
= s1
->sections
[i
];
9578 relocate_section(s1
, s
);
9583 /* launch the compiled program with the given arguments */
9584 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
9586 int (*prog_main
)(int, char **);
9588 if (tcc_relocate(s1
) < 0)
9591 prog_main
= tcc_get_symbol_err(s1
, "main");
9594 #if defined(WIN32) || defined(CONFIG_TCCBOOT)
9595 error("debug mode currently not available for Windows");
9597 struct sigaction sigact
;
9598 /* install TCC signal handlers to print debug info on fatal
9600 sigact
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
9601 sigact
.sa_sigaction
= sig_error
;
9602 sigemptyset(&sigact
.sa_mask
);
9603 sigaction(SIGFPE
, &sigact
, NULL
);
9604 sigaction(SIGILL
, &sigact
, NULL
);
9605 sigaction(SIGSEGV
, &sigact
, NULL
);
9606 sigaction(SIGBUS
, &sigact
, NULL
);
9607 sigaction(SIGABRT
, &sigact
, NULL
);
9611 #ifdef CONFIG_TCC_BCHECK
9612 if (do_bounds_check
) {
9613 void (*bound_init
)(void);
9615 /* set error function */
9616 rt_bound_error_msg
= (void *)tcc_get_symbol_err(s1
,
9617 "__bound_error_msg");
9619 /* XXX: use .init section so that it also work in binary ? */
9620 bound_init
= (void *)tcc_get_symbol_err(s1
, "__bound_init");
9624 return (*prog_main
)(argc
, argv
);
9627 TCCState
*tcc_new(void)
9634 s
= tcc_mallocz(sizeof(TCCState
));
9638 s
->output_type
= TCC_OUTPUT_MEMORY
;
9640 /* init isid table */
9642 isidnum_table
[i
] = isid(i
) || isnum(i
);
9644 /* add all tokens */
9646 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
9648 tok_ident
= TOK_IDENT
;
9657 ts
= tok_alloc(p
, r
- p
- 1);
9661 /* we add dummy defines for some special macros to speed up tests
9662 and to have working defined() */
9663 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
9664 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
9665 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
9666 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
9668 /* standard defines */
9669 tcc_define_symbol(s
, "__STDC__", NULL
);
9670 #if defined(TCC_TARGET_I386)
9671 tcc_define_symbol(s
, "__i386__", NULL
);
9673 #if defined(TCC_TARGET_ARM)
9674 tcc_define_symbol(s
, "__ARM_ARCH_4__", NULL
);
9675 tcc_define_symbol(s
, "__arm_elf__", NULL
);
9676 tcc_define_symbol(s
, "__arm_elf", NULL
);
9677 tcc_define_symbol(s
, "arm_elf", NULL
);
9678 tcc_define_symbol(s
, "__arm__", NULL
);
9679 tcc_define_symbol(s
, "__arm", NULL
);
9680 tcc_define_symbol(s
, "arm", NULL
);
9681 tcc_define_symbol(s
, "__APCS_32__", NULL
);
9684 tcc_define_symbol(s
, "__linux__", NULL
);
9685 tcc_define_symbol(s
, "linux", NULL
);
9687 /* tiny C specific defines */
9688 tcc_define_symbol(s
, "__TINYC__", NULL
);
9690 /* tiny C & gcc defines */
9691 tcc_define_symbol(s
, "__SIZE_TYPE__", "unsigned int");
9692 tcc_define_symbol(s
, "__PTRDIFF_TYPE__", "int");
9693 tcc_define_symbol(s
, "__WCHAR_TYPE__", "int");
9695 /* default library paths */
9696 #ifdef TCC_TARGET_PE
9699 snprintf(buf
, sizeof(buf
), "%s/lib", tcc_lib_path
);
9700 tcc_add_library_path(s
, buf
);
9703 tcc_add_library_path(s
, "/usr/local/lib");
9704 tcc_add_library_path(s
, "/usr/lib");
9705 tcc_add_library_path(s
, "/lib");
9708 /* no section zero */
9709 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
9711 /* create standard sections */
9712 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
9713 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
9714 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
9716 /* symbols are always generated for linking stage */
9717 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
9719 ".hashtab", SHF_PRIVATE
);
9720 strtab_section
= symtab_section
->link
;
9722 /* private symbol table for dynamic symbols */
9723 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
9725 ".dynhashtab", SHF_PRIVATE
);
9726 s
->alacarte_link
= 1;
9728 #ifdef CHAR_IS_UNSIGNED
9729 s
->char_is_unsigned
= 1;
9734 void tcc_delete(TCCState
*s1
)
9738 /* free -D defines */
9742 n
= tok_ident
- TOK_IDENT
;
9743 for(i
= 0; i
< n
; i
++)
9744 tcc_free(table_ident
[i
]);
9745 tcc_free(table_ident
);
9747 /* free all sections */
9749 free_section(symtab_section
->hash
);
9751 free_section(s1
->dynsymtab_section
->hash
);
9752 free_section(s1
->dynsymtab_section
->link
);
9753 free_section(s1
->dynsymtab_section
);
9755 for(i
= 1; i
< s1
->nb_sections
; i
++)
9756 free_section(s1
->sections
[i
]);
9757 tcc_free(s1
->sections
);
9759 /* free loaded dlls array */
9760 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
9761 tcc_free(s1
->loaded_dlls
[i
]);
9762 tcc_free(s1
->loaded_dlls
);
9765 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
9766 tcc_free(s1
->library_paths
[i
]);
9767 tcc_free(s1
->library_paths
);
9769 /* cached includes */
9770 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
9771 tcc_free(s1
->cached_includes
[i
]);
9772 tcc_free(s1
->cached_includes
);
9774 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
9775 tcc_free(s1
->include_paths
[i
]);
9776 tcc_free(s1
->include_paths
);
9778 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
9779 tcc_free(s1
->sysinclude_paths
[i
]);
9780 tcc_free(s1
->sysinclude_paths
);
9785 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
9789 pathname1
= tcc_strdup(pathname
);
9790 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
9794 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
9798 pathname1
= tcc_strdup(pathname
);
9799 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
9803 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
9805 const char *ext
, *filename1
;
9808 BufferedFile
*saved_file
;
9810 /* find source file type with extension */
9811 filename1
= strrchr(filename
, '/');
9815 filename1
= filename
;
9816 ext
= strrchr(filename1
, '.');
9822 file
= tcc_open(s1
, filename
);
9824 if (flags
& AFF_PRINT_ERROR
) {
9825 error_noabort("file '%s' not found", filename
);
9831 if (!ext
|| !strcmp(ext
, "c")) {
9832 /* C file assumed */
9833 ret
= tcc_compile(s1
);
9835 #ifdef CONFIG_TCC_ASM
9836 if (!strcmp(ext
, "S")) {
9837 /* preprocessed assembler */
9838 ret
= tcc_assemble(s1
, 1);
9839 } else if (!strcmp(ext
, "s")) {
9840 /* non preprocessed assembler */
9841 ret
= tcc_assemble(s1
, 0);
9844 #ifdef TCC_TARGET_PE
9845 if (!strcmp(ext
, "def")) {
9846 ret
= pe_load_def_file(s1
, fdopen(file
->fd
, "rb"));
9851 /* assume executable format: auto guess file type */
9852 ret
= read(fd
, &ehdr
, sizeof(ehdr
));
9853 lseek(fd
, 0, SEEK_SET
);
9855 error_noabort("could not read header");
9857 } else if (ret
!= sizeof(ehdr
)) {
9858 goto try_load_script
;
9861 if (ehdr
.e_ident
[0] == ELFMAG0
&&
9862 ehdr
.e_ident
[1] == ELFMAG1
&&
9863 ehdr
.e_ident
[2] == ELFMAG2
&&
9864 ehdr
.e_ident
[3] == ELFMAG3
) {
9865 file
->line_num
= 0; /* do not display line number if error */
9866 if (ehdr
.e_type
== ET_REL
) {
9867 ret
= tcc_load_object_file(s1
, fd
, 0);
9868 } else if (ehdr
.e_type
== ET_DYN
) {
9869 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
9870 #ifdef TCC_TARGET_PE
9874 h
= dlopen(filename
, RTLD_GLOBAL
| RTLD_LAZY
);
9881 ret
= tcc_load_dll(s1
, fd
, filename
,
9882 (flags
& AFF_REFERENCED_DLL
) != 0);
9885 error_noabort("unrecognized ELF file");
9888 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
9889 file
->line_num
= 0; /* do not display line number if error */
9890 ret
= tcc_load_archive(s1
, fd
);
9892 #ifdef TCC_TARGET_COFF
9893 if (*(uint16_t *)(&ehdr
) == COFF_C67_MAGIC
) {
9894 ret
= tcc_load_coff(s1
, fd
);
9898 /* as GNU ld, consider it is an ld script if not recognized */
9900 ret
= tcc_load_ldscript(s1
);
9902 error_noabort("unrecognized file type");
9917 int tcc_add_file(TCCState
*s
, const char *filename
)
9919 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
9922 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
9926 pathname1
= tcc_strdup(pathname
);
9927 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
9931 /* find and load a dll. Return non zero if not found */
9932 /* XXX: add '-rpath' option support ? */
9933 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
9938 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
9939 snprintf(buf
, sizeof(buf
), "%s/%s",
9940 s
->library_paths
[i
], filename
);
9941 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
9947 /* the library name is the same as the argument of the '-l' option */
9948 int tcc_add_library(TCCState
*s
, const char *libraryname
)
9953 /* first we look for the dynamic library if not static linking */
9954 if (!s
->static_link
) {
9955 #ifdef TCC_TARGET_PE
9956 snprintf(buf
, sizeof(buf
), "%s.def", libraryname
);
9958 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
9960 if (tcc_add_dll(s
, buf
, 0) == 0)
9964 /* then we look for the static library */
9965 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
9966 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
9967 s
->library_paths
[i
], libraryname
);
9968 if (tcc_add_file_internal(s
, buf
, 0) == 0)
9974 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
9976 add_elf_sym(symtab_section
, val
, 0,
9977 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
), 0,
9982 int tcc_set_output_type(TCCState
*s
, int output_type
)
9984 s
->output_type
= output_type
;
9989 /* default include paths */
9990 /* XXX: reverse order needed if -isystem support */
9991 #ifndef TCC_TARGET_PE
9992 tcc_add_sysinclude_path(s
, "/usr/local/include");
9993 tcc_add_sysinclude_path(s
, "/usr/include");
9995 snprintf(buf
, sizeof(buf
), "%s/include", tcc_lib_path
);
9996 tcc_add_sysinclude_path(s
, buf
);
9997 #ifdef TCC_TARGET_PE
9998 snprintf(buf
, sizeof(buf
), "%s/include/winapi", tcc_lib_path
);
9999 tcc_add_sysinclude_path(s
, buf
);
10003 /* if bound checking, then add corresponding sections */
10004 #ifdef CONFIG_TCC_BCHECK
10005 if (do_bounds_check
) {
10006 /* define symbol */
10007 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
10008 /* create bounds sections */
10009 bounds_section
= new_section(s
, ".bounds",
10010 SHT_PROGBITS
, SHF_ALLOC
);
10011 lbounds_section
= new_section(s
, ".lbounds",
10012 SHT_PROGBITS
, SHF_ALLOC
);
10016 if (s
->char_is_unsigned
) {
10017 tcc_define_symbol(s
, "__CHAR_UNSIGNED__", NULL
);
10020 /* add debug sections */
10023 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
10024 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
10025 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
10026 put_elf_str(stabstr_section
, "");
10027 stab_section
->link
= stabstr_section
;
10028 /* put first entry */
10029 put_stabs("", 0, 0, 0, 0);
10032 /* add libc crt1/crti objects */
10033 #ifndef TCC_TARGET_PE
10034 if ((output_type
== TCC_OUTPUT_EXE
|| output_type
== TCC_OUTPUT_DLL
) &&
10036 if (output_type
!= TCC_OUTPUT_DLL
)
10037 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
10038 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
10044 #define WD_ALL 0x0001 /* warning is activated when using -Wall */
10045 #define FD_INVERT 0x0002 /* invert value before storing */
10047 typedef struct FlagDef
{
10053 static const FlagDef warning_defs
[] = {
10054 { offsetof(TCCState
, warn_unsupported
), 0, "unsupported" },
10055 { offsetof(TCCState
, warn_write_strings
), 0, "write-strings" },
10056 { offsetof(TCCState
, warn_error
), 0, "error" },
10057 { offsetof(TCCState
, warn_implicit_function_declaration
), WD_ALL
,
10058 "implicit-function-declaration" },
10061 static int set_flag(TCCState
*s
, const FlagDef
*flags
, int nb_flags
,
10062 const char *name
, int value
)
10069 if (r
[0] == 'n' && r
[1] == 'o' && r
[2] == '-') {
10073 for(i
= 0, p
= flags
; i
< nb_flags
; i
++, p
++) {
10074 if (!strcmp(r
, p
->name
))
10079 if (p
->flags
& FD_INVERT
)
10081 *(int *)((uint8_t *)s
+ p
->offset
) = value
;
10086 /* set/reset a warning */
10087 int tcc_set_warning(TCCState
*s
, const char *warning_name
, int value
)
10092 if (!strcmp(warning_name
, "all")) {
10093 for(i
= 0, p
= warning_defs
; i
< countof(warning_defs
); i
++, p
++) {
10094 if (p
->flags
& WD_ALL
)
10095 *(int *)((uint8_t *)s
+ p
->offset
) = 1;
10099 return set_flag(s
, warning_defs
, countof(warning_defs
),
10100 warning_name
, value
);
10104 static const FlagDef flag_defs
[] = {
10105 { offsetof(TCCState
, char_is_unsigned
), 0, "unsigned-char" },
10106 { offsetof(TCCState
, char_is_unsigned
), FD_INVERT
, "signed-char" },
10107 { offsetof(TCCState
, nocommon
), FD_INVERT
, "common" },
10110 /* set/reset a flag */
10111 int tcc_set_flag(TCCState
*s
, const char *flag_name
, int value
)
10113 return set_flag(s
, flag_defs
, countof(flag_defs
),
10117 #if !defined(LIBTCC)
10119 /* extract the basename of a file */
10120 static const char *tcc_basename(const char *name
)
10123 p
= strrchr(name
, '/');
10126 p
= strrchr(name
, '\\');
10135 static int64_t getclock_us(void)
10140 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
10143 gettimeofday(&tv
, NULL
);
10144 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
10150 printf("tcc version " TCC_VERSION
" - Tiny C Compiler - Copyright (C) 2001-2005 Fabrice Bellard\n"
10151 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
10152 " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
10153 " [infile1 infile2...] [-run infile args...]\n"
10155 "General options:\n"
10156 " -v display current version\n"
10157 " -c compile only - generate an object file\n"
10158 " -o outfile set output filename\n"
10159 " -Bdir set tcc internal library path\n"
10160 " -bench output compilation statistics\n"
10161 " -run run compiled source\n"
10162 " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n"
10163 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n"
10164 " -w disable all warnings\n"
10165 "Preprocessor options:\n"
10166 " -Idir add include path 'dir'\n"
10167 " -Dsym[=val] define 'sym' with value 'val'\n"
10168 " -Usym undefine 'sym'\n"
10169 "Linker options:\n"
10170 " -Ldir add library path 'dir'\n"
10171 " -llib link with dynamic or static library 'lib'\n"
10172 " -shared generate a shared library\n"
10173 " -static static linking\n"
10174 " -rdynamic export all global symbols to dynamic linker\n"
10175 " -r relocatable output\n"
10176 "Debugger options:\n"
10177 " -g generate runtime debug info\n"
10178 #ifdef CONFIG_TCC_BCHECK
10179 " -b compile with built-in memory and bounds checker (implies -g)\n"
10181 " -bt N show N callers in stack traces\n"
10185 #define TCC_OPTION_HAS_ARG 0x0001
10186 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
10188 typedef struct TCCOption
{
10216 TCC_OPTION_nostdinc
,
10217 TCC_OPTION_nostdlib
,
10218 TCC_OPTION_print_search_dirs
,
10219 TCC_OPTION_rdynamic
,
10226 static const TCCOption tcc_options
[] = {
10227 { "h", TCC_OPTION_HELP
, 0 },
10228 { "?", TCC_OPTION_HELP
, 0 },
10229 { "I", TCC_OPTION_I
, TCC_OPTION_HAS_ARG
},
10230 { "D", TCC_OPTION_D
, TCC_OPTION_HAS_ARG
},
10231 { "U", TCC_OPTION_U
, TCC_OPTION_HAS_ARG
},
10232 { "L", TCC_OPTION_L
, TCC_OPTION_HAS_ARG
},
10233 { "B", TCC_OPTION_B
, TCC_OPTION_HAS_ARG
},
10234 { "l", TCC_OPTION_l
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10235 { "bench", TCC_OPTION_bench
, 0 },
10236 { "bt", TCC_OPTION_bt
, TCC_OPTION_HAS_ARG
},
10237 #ifdef CONFIG_TCC_BCHECK
10238 { "b", TCC_OPTION_b
, 0 },
10240 { "g", TCC_OPTION_g
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10241 { "c", TCC_OPTION_c
, 0 },
10242 { "static", TCC_OPTION_static
, 0 },
10243 { "shared", TCC_OPTION_shared
, 0 },
10244 { "o", TCC_OPTION_o
, TCC_OPTION_HAS_ARG
},
10245 { "run", TCC_OPTION_run
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10246 { "rdynamic", TCC_OPTION_rdynamic
, 0 },
10247 { "r", TCC_OPTION_r
, 0 },
10248 { "Wl,", TCC_OPTION_Wl
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10249 { "W", TCC_OPTION_W
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10250 { "O", TCC_OPTION_O
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10251 { "m", TCC_OPTION_m
, TCC_OPTION_HAS_ARG
},
10252 { "f", TCC_OPTION_f
, TCC_OPTION_HAS_ARG
| TCC_OPTION_NOSEP
},
10253 { "nostdinc", TCC_OPTION_nostdinc
, 0 },
10254 { "nostdlib", TCC_OPTION_nostdlib
, 0 },
10255 { "print-search-dirs", TCC_OPTION_print_search_dirs
, 0 },
10256 { "v", TCC_OPTION_v
, 0 },
10257 { "w", TCC_OPTION_w
, 0 },
10258 { "pipe", TCC_OPTION_pipe
, 0},
10262 /* convert 'str' into an array of space separated strings */
10263 static int expand_args(char ***pargv
, const char *str
)
10272 while (is_space(*str
))
10277 while (*str
!= '\0' && !is_space(*str
))
10280 arg
= tcc_malloc(len
+ 1);
10281 memcpy(arg
, s1
, len
);
10283 dynarray_add((void ***)&argv
, &argc
, arg
);
10289 static char **files
;
10290 static int nb_files
, nb_libraries
;
10291 static int multiple_files
;
10292 static int print_search_dirs
;
10293 static int output_type
;
10294 static int reloc_output
;
10295 static const char *outfile
;
10297 int parse_args(TCCState
*s
, int argc
, char **argv
)
10300 const TCCOption
*popt
;
10301 const char *optarg
, *p1
, *r1
;
10306 if (optind
>= argc
) {
10307 if (nb_files
== 0 && !print_search_dirs
)
10312 r
= argv
[optind
++];
10314 /* add a new file */
10315 dynarray_add((void ***)&files
, &nb_files
, r
);
10316 if (!multiple_files
) {
10318 /* argv[0] will be this file */
10322 /* find option in table (match only the first chars */
10323 popt
= tcc_options
;
10327 error("invalid option -- '%s'", r
);
10340 if (popt
->flags
& TCC_OPTION_HAS_ARG
) {
10341 if (*r1
!= '\0' || (popt
->flags
& TCC_OPTION_NOSEP
)) {
10344 if (optind
>= argc
)
10345 error("argument to '%s' is missing", r
);
10346 optarg
= argv
[optind
++];
10354 switch(popt
->index
) {
10355 case TCC_OPTION_HELP
:
10360 if (tcc_add_include_path(s
, optarg
) < 0)
10361 error("too many include paths");
10366 sym
= (char *)optarg
;
10367 value
= strchr(sym
, '=');
10372 tcc_define_symbol(s
, sym
, value
);
10376 tcc_undefine_symbol(s
, optarg
);
10379 tcc_add_library_path(s
, optarg
);
10382 /* set tcc utilities path (mainly for tcc development) */
10383 tcc_lib_path
= optarg
;
10386 dynarray_add((void ***)&files
, &nb_files
, r
);
10389 case TCC_OPTION_bench
:
10392 case TCC_OPTION_bt
:
10393 num_callers
= atoi(optarg
);
10395 #ifdef CONFIG_TCC_BCHECK
10397 do_bounds_check
= 1;
10405 multiple_files
= 1;
10406 output_type
= TCC_OUTPUT_OBJ
;
10408 case TCC_OPTION_static
:
10409 s
->static_link
= 1;
10411 case TCC_OPTION_shared
:
10412 output_type
= TCC_OUTPUT_DLL
;
10415 multiple_files
= 1;
10419 /* generate a .o merging several output files */
10421 output_type
= TCC_OUTPUT_OBJ
;
10423 case TCC_OPTION_nostdinc
:
10426 case TCC_OPTION_nostdlib
:
10429 case TCC_OPTION_print_search_dirs
:
10430 print_search_dirs
= 1;
10432 case TCC_OPTION_run
:
10436 argc1
= expand_args(&argv1
, optarg
);
10438 parse_args(s
, argc1
, argv1
);
10440 multiple_files
= 0;
10441 output_type
= TCC_OUTPUT_MEMORY
;
10445 printf("tcc version %s\n", TCC_VERSION
);
10448 if (tcc_set_flag(s
, optarg
, 1) < 0 && s
->warn_unsupported
)
10449 goto unsupported_option
;
10452 if (tcc_set_warning(s
, optarg
, 1) < 0 &&
10453 s
->warn_unsupported
)
10454 goto unsupported_option
;
10459 case TCC_OPTION_rdynamic
:
10462 case TCC_OPTION_Wl
:
10465 if (strstart(optarg
, "-Ttext,", &p
)) {
10466 s
->text_addr
= strtoul(p
, NULL
, 16);
10467 s
->has_text_addr
= 1;
10468 } else if (strstart(optarg
, "--oformat,", &p
)) {
10469 if (strstart(p
, "elf32-", NULL
)) {
10470 s
->output_format
= TCC_OUTPUT_FORMAT_ELF
;
10471 } else if (!strcmp(p
, "binary")) {
10472 s
->output_format
= TCC_OUTPUT_FORMAT_BINARY
;
10474 #ifdef TCC_TARGET_COFF
10475 if (!strcmp(p
, "coff")) {
10476 s
->output_format
= TCC_OUTPUT_FORMAT_COFF
;
10480 error("target %s not found", p
);
10483 error("unsupported linker option '%s'", optarg
);
10488 if (s
->warn_unsupported
) {
10489 unsupported_option
:
10490 warning("unsupported option '%s'", r
);
10499 int main(int argc
, char **argv
)
10503 int nb_objfiles
, ret
, optind
;
10504 char objfilename
[1024];
10505 int64_t start_time
= 0;
10508 /* on win32, we suppose the lib and includes are at the location
10511 static char path
[1024];
10514 GetModuleFileNameA(NULL
, path
, sizeof path
);
10515 p
= d
= strlwr(path
);
10520 tcc_lib_path
= path
;
10525 output_type
= TCC_OUTPUT_EXE
;
10527 multiple_files
= 1;
10532 print_search_dirs
= 0;
10534 optind
= parse_args(s
, argc
- 1, argv
+ 1) + 1;
10536 if (print_search_dirs
) {
10537 /* enough for Linux kernel */
10538 printf("install: %s/\n", tcc_lib_path
);
10542 nb_objfiles
= nb_files
- nb_libraries
;
10544 /* if outfile provided without other options, we output an
10546 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
10547 output_type
= TCC_OUTPUT_EXE
;
10549 /* check -c consistency : only single file handled. XXX: checks file type */
10550 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
10551 /* accepts only a single input file */
10552 if (nb_objfiles
!= 1)
10553 error("cannot specify multiple files with -c");
10554 if (nb_libraries
!= 0)
10555 error("cannot specify libraries with -c");
10558 /* compute default outfile name */
10559 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
10560 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
10563 pstrcpy(objfilename
, sizeof(objfilename
) - 1,
10564 tcc_basename(files
[0]));
10565 /* add .o extension */
10566 ext
= strrchr(objfilename
, '.');
10568 goto default_outfile
;
10569 strcpy(ext
+ 1, "o");
10572 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
10574 outfile
= objfilename
;
10578 start_time
= getclock_us();
10581 tcc_set_output_type(s
, output_type
);
10583 /* compile or add each files or library */
10584 for(i
= 0;i
< nb_files
; i
++) {
10585 const char *filename
;
10587 filename
= files
[i
];
10588 if (filename
[0] == '-') {
10589 if (tcc_add_library(s
, filename
+ 2) < 0)
10590 error("cannot find %s", filename
);
10592 if (tcc_add_file(s
, filename
) < 0) {
10599 /* free all files */
10604 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
10605 if (total_time
< 0.001)
10606 total_time
= 0.001;
10607 if (total_bytes
< 1)
10609 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
10610 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
10611 total_time
, (int)(total_lines
/ total_time
),
10612 total_bytes
/ total_time
/ 1000000.0);
10615 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
10616 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
10618 #ifdef TCC_TARGET_PE
10619 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
10620 ret
= tcc_output_pe(s
, outfile
);
10624 tcc_output_file(s
, outfile
);
10628 /* XXX: cannot do it with bound checking because of the malloc hooks */
10629 if (!do_bounds_check
)
10634 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);