2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program 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
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 #include <sys/timeb.h>
36 #include <sys/ucontext.h>
40 #ifndef CONFIG_TCC_STATIC
48 /* preprocessor debug */
50 /* include file debug */
55 /* target selection */
56 //#define TCC_TARGET_I386 /* i386 code generator */
57 //#define TCC_TARGET_IL /* .NET CLI generator */
59 /* default target is I386 */
60 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
61 #define TCC_TARGET_I386
64 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
65 #define CONFIG_TCC_BCHECK /* enable bound checking code */
68 #ifndef CONFIG_TCC_PREFIX
69 #define CONFIG_TCC_PREFIX "/usr/local"
72 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
73 executables or dlls */
74 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
76 #define INCLUDE_STACK_SIZE 32
77 #define IFDEF_STACK_SIZE 64
78 #define VSTACK_SIZE 64
79 #define STRING_MAX_SIZE 1024
81 #define TOK_HASH_SIZE 2048 /* must be a power of two */
82 #define TOK_ALLOC_INCR 512 /* must be a power of two */
84 /* token symbol management */
85 typedef struct TokenSym
{
86 struct TokenSym
*hash_next
;
87 struct Sym
*sym_define
; /* direct pointer to define */
88 struct Sym
*sym_label
; /* direct pointer to label */
89 struct Sym
*sym_struct
; /* direct pointer to structure */
90 struct Sym
*sym_identifier
; /* direct pointer to identifier */
91 int tok
; /* token number */
96 typedef struct CString
{
97 int size
; /* size in bytes */
98 void *data
; /* either 'char *' or 'int *' */
100 void *data_allocated
; /* if non NULL, data has been malloced */
103 /* type definition */
104 typedef struct CType
{
110 typedef union CValue
{
116 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
118 unsigned long long ull
;
119 struct CString
*cstr
;
125 typedef struct SValue
{
126 CType type
; /* type */
127 unsigned short r
; /* register + flags */
128 unsigned short r2
; /* second register, used for 'long long'
129 type. If not used, set to VT_CONST */
130 CValue c
; /* constant, if VT_CONST */
131 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
134 /* symbol management */
136 int v
; /* symbol token */
137 int r
; /* associated register */
138 int c
; /* associated number */
139 CType type
; /* associated type */
140 struct Sym
*next
; /* next related symbol */
141 struct Sym
*prev
; /* prev symbol in stack */
142 struct Sym
*prev_tok
; /* previous symbol for this token */
145 /* section definition */
146 /* XXX: use directly ELF structure for parameters ? */
147 /* special flag to indicate that the section should not be linked to
149 #define SHF_PRIVATE 0x80000000
151 typedef struct Section
{
152 unsigned long data_offset
; /* current data offset */
153 unsigned char *data
; /* section data */
154 unsigned long data_allocated
; /* used for realloc() handling */
155 int sh_name
; /* elf section name (only used during output) */
156 int sh_num
; /* elf section number */
157 int sh_type
; /* elf section type */
158 int sh_flags
; /* elf section flags */
159 int sh_info
; /* elf section info */
160 int sh_addralign
; /* elf section alignment */
161 int sh_entsize
; /* elf entry size */
162 unsigned long sh_size
; /* section size (only used during output) */
163 unsigned long sh_addr
; /* address at which the section is relocated */
164 unsigned long sh_offset
; /* address at which the section is relocated */
165 int nb_hashed_syms
; /* used to resize the hash table */
166 struct Section
*link
; /* link to another section */
167 struct Section
*reloc
; /* corresponding section for relocation, if any */
168 struct Section
*hash
; /* hash table for symbols */
169 struct Section
*next
;
170 char name
[64]; /* section name */
173 typedef struct DLLReference
{
178 /* GNUC attribute definition */
179 typedef struct AttributeDef
{
182 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
185 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
186 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
187 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
189 /* stored in 'Sym.c' field */
190 #define FUNC_NEW 1 /* ansi function prototype */
191 #define FUNC_OLD 2 /* old function prototype */
192 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
194 /* stored in 'Sym.r' field */
195 #define FUNC_CDECL 0 /* standard c call */
196 #define FUNC_STDCALL 1 /* pascal c call */
198 /* field 'Sym.t' for macros */
199 #define MACRO_OBJ 0 /* object like macro */
200 #define MACRO_FUNC 1 /* function like macro */
202 /* field 'Sym.r' for labels */
203 #define LABEL_FORWARD 1 /* label is forward defined */
205 /* type_decl() types */
206 #define TYPE_ABSTRACT 1 /* type without variable */
207 #define TYPE_DIRECT 2 /* type with variable */
209 #define IO_BUF_SIZE 8192
211 typedef struct BufferedFile
{
212 unsigned char *buf_ptr
;
213 unsigned char *buf_end
;
215 int line_num
; /* current line number - here to simply code */
216 int ifndef_macro
; /* #ifndef macro / #endif search */
217 int ifndef_macro_saved
; /* saved ifndef_macro */
218 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
219 char inc_type
; /* type of include */
220 char inc_filename
[512]; /* filename specified by the user */
221 char filename
[1024]; /* current filename - here to simplify code */
222 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
225 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
226 #define CH_EOF (-1) /* end of file */
228 /* parsing state (used to save parser state to reparse part of the
229 source several times) */
230 typedef struct ParseState
{
237 /* used to record tokens */
238 typedef struct TokenString
{
244 /* include file cache, used to find files faster and also to eliminate
245 inclusion if the include file is protected by #ifndef ... #endif */
246 typedef struct CachedInclude
{
248 char type
; /* '"' or '>' to give include type */
249 char filename
[1]; /* path specified in #include */
253 static struct BufferedFile
*file
;
254 static int ch
, tok
, tok1
;
255 static CValue tokc
, tok1c
;
256 static CString tokcstr
; /* current parsed string, if any */
257 /* additionnal informations about token */
258 static int tok_flags
;
259 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */
260 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */
261 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
263 /* if true, line feed is returned as a token. line feed is also
265 static int return_linefeed
;
266 static Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
267 static Section
*cur_text_section
; /* current section where function code is
269 /* bound check related sections */
270 static Section
*bounds_section
; /* contains global data bound description */
271 static Section
*lbounds_section
; /* contains local data bound description */
272 /* symbol sections */
273 static Section
*symtab_section
, *strtab_section
;
276 static Section
*stab_section
, *stabstr_section
;
278 /* loc : local variable index
279 ind : output code index
281 anon_sym: anonymous symbol index
283 static int rsym
, anon_sym
, ind
, loc
;
284 /* expression generation modifiers */
285 static int const_wanted
; /* true if constant wanted */
286 static int nocode_wanted
; /* true if no code generation wanted for an expression */
287 static int global_expr
; /* true if compound literals must be allocated
288 globally (used during initializers parsing */
289 static CType func_vt
; /* current function return type (used by return
292 static int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
293 static int tok_ident
;
294 static TokenSym
**table_ident
;
295 static TokenSym
*hash_ident
[TOK_HASH_SIZE
];
296 static char token_buf
[STRING_MAX_SIZE
+ 1];
297 static char *funcname
;
298 static Sym
*global_stack
, *local_stack
;
299 static Sym
*define_stack
;
300 static Sym
*label_stack
;
302 static SValue vstack
[VSTACK_SIZE
], *vtop
;
303 static int *macro_ptr
, *macro_ptr_allocated
;
304 /* some predefined types */
305 static CType char_pointer_type
, func_old_type
, int_type
;
307 /* compile with debug symbol (and use them if error during execution) */
308 static int do_debug
= 0;
310 /* compile with built-in memory and bounds checker */
311 static int do_bounds_check
= 0;
313 /* display benchmark infos */
314 static int do_bench
= 0;
315 static int total_lines
;
316 static int total_bytes
;
318 /* use GNU C extensions */
319 static int gnu_ext
= 1;
321 /* use Tiny C extensions */
322 static int tcc_ext
= 1;
324 /* max number of callers shown if error */
325 static int num_callers
= 6;
326 static const char **rt_bound_error_msg
;
328 /* XXX: suppress that ASAP */
329 static struct TCCState
*tcc_state
;
331 /* give the path of the tcc libraries */
332 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
337 BufferedFile
**include_stack_ptr
;
338 int *ifdef_stack_ptr
;
340 /* include file handling */
341 char **include_paths
;
342 int nb_include_paths
;
343 char **sysinclude_paths
;
344 int nb_sysinclude_paths
;
345 CachedInclude
**cached_includes
;
346 int nb_cached_includes
;
348 char **library_paths
;
349 int nb_library_paths
;
351 /* array of all loaded dlls (including those referenced by loaded
353 DLLReference
**loaded_dlls
;
358 int nb_sections
; /* number of sections, including first dummy section */
362 unsigned long *got_offsets
;
365 /* give the correspondance from symtab indexes to dynsym indexes */
366 int *symtab_to_dynsym
;
368 /* temporary dynamic symbol sections (for dll loading) */
369 Section
*dynsymtab_section
;
370 /* exported dynamic symbol section */
373 /* if true, static linking is performed */
378 void (*error_func
)(void *opaque
, const char *msg
);
379 int error_set_jmp_enabled
;
380 jmp_buf error_jmp_buf
;
383 /* see include_stack_ptr */
384 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
386 /* see ifdef_stack_ptr */
387 int ifdef_stack
[IFDEF_STACK_SIZE
];
390 /* The current value can be: */
391 #define VT_VALMASK 0x00ff
392 #define VT_CONST 0x00f0 /* constant in vc
393 (must be first non register value) */
394 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
395 #define VT_LOCAL 0x00f2 /* offset on stack */
396 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
397 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
398 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
399 #define VT_LVAL 0x0100 /* var is an lvalue */
400 #define VT_SYM 0x0200 /* a symbol value is added */
401 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
402 char/short stored in integer registers) */
403 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
404 dereferencing value */
405 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
406 bounding function call point is in vc */
407 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
408 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
409 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
410 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
413 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
415 #define VT_INT 0 /* integer type */
416 #define VT_BYTE 1 /* signed byte type */
417 #define VT_SHORT 2 /* short type */
418 #define VT_VOID 3 /* void type */
419 #define VT_PTR 4 /* pointer */
420 #define VT_ENUM 5 /* enum definition */
421 #define VT_FUNC 6 /* function type */
422 #define VT_STRUCT 7 /* struct/union definition */
423 #define VT_FLOAT 8 /* IEEE float */
424 #define VT_DOUBLE 9 /* IEEE double */
425 #define VT_LDOUBLE 10 /* IEEE long double */
426 #define VT_BOOL 11 /* ISOC99 boolean type */
427 #define VT_LLONG 12 /* 64 bit integer */
428 #define VT_LONG 13 /* long integer (NEVER USED as type, only
430 #define VT_BTYPE 0x000f /* mask for basic type */
431 #define VT_UNSIGNED 0x0010 /* unsigned type */
432 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
433 #define VT_BITFIELD 0x0040 /* bitfield modifier */
436 #define VT_EXTERN 0x00000080 /* extern definition */
437 #define VT_STATIC 0x00000100 /* static variable */
438 #define VT_TYPEDEF 0x00000200 /* typedef definition */
440 /* type mask (except storage) */
441 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
445 /* warning: the following compare tokens depend on i386 asm code */
457 #define TOK_LAND 0xa0
461 #define TOK_MID 0xa3 /* inc/dec, to void constant */
463 #define TOK_UDIV 0xb0 /* unsigned division */
464 #define TOK_UMOD 0xb1 /* unsigned modulo */
465 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
466 #define TOK_CINT 0xb3 /* number in tokc */
467 #define TOK_CCHAR 0xb4 /* char constant in tokc */
468 #define TOK_STR 0xb5 /* pointer to string in tokc */
469 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
470 #define TOK_LCHAR 0xb7
471 #define TOK_LSTR 0xb8
472 #define TOK_CFLOAT 0xb9 /* float constant */
473 #define TOK_LINENUM 0xba /* line number info */
474 #define TOK_CDOUBLE 0xc0 /* double constant */
475 #define TOK_CLDOUBLE 0xc1 /* long double constant */
476 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
477 #define TOK_ADDC1 0xc3 /* add with carry generation */
478 #define TOK_ADDC2 0xc4 /* add with carry use */
479 #define TOK_SUBC1 0xc5 /* add with carry generation */
480 #define TOK_SUBC2 0xc6 /* add with carry use */
481 #define TOK_CUINT 0xc8 /* unsigned int constant */
482 #define TOK_CLLONG 0xc9 /* long long constant */
483 #define TOK_CULLONG 0xca /* unsigned long long constant */
484 #define TOK_ARROW 0xcb
485 #define TOK_DOTS 0xcc /* three dots */
486 #define TOK_SHR 0xcd /* unsigned shift right */
487 #define TOK_PPNUM 0xce /* preprocessor number */
489 #define TOK_SHL 0x01 /* shift left */
490 #define TOK_SAR 0x02 /* signed shift right */
492 /* assignement operators : normal operator or 0x80 */
493 #define TOK_A_MOD 0xa5
494 #define TOK_A_AND 0xa6
495 #define TOK_A_MUL 0xaa
496 #define TOK_A_ADD 0xab
497 #define TOK_A_SUB 0xad
498 #define TOK_A_DIV 0xaf
499 #define TOK_A_XOR 0xde
500 #define TOK_A_OR 0xfc
501 #define TOK_A_SHL 0x81
502 #define TOK_A_SAR 0x82
504 /* WARNING: the content of this string encodes token numbers */
505 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";
507 #define TOK_EOF (-1) /* end of file */
508 #define TOK_LINEFEED 10 /* line feed */
510 /* all identificators and strings have token above that */
511 #define TOK_IDENT 256
514 TOK_LAST
= TOK_IDENT
- 1,
515 #define DEF(id, str) id,
520 static const char *tcc_keywords
=
521 #define DEF(id, str) str "\0"
526 #define TOK_UIDENT TOK_DEFINE
529 #define snprintf _snprintf
530 #define vsnprintf _vsnprintf
533 #if defined(WIN32) || defined(TCC_UCLIBC)
534 /* currently incorrect */
535 long double strtold(const char *nptr
, char **endptr
)
537 return (long double)strtod(nptr
, endptr
);
539 float strtof(const char *nptr
, char **endptr
)
541 return (float)strtod(nptr
, endptr
);
544 /* XXX: need to define this to use them in non ISOC99 context */
545 extern float strtof (const char *__nptr
, char **__endptr
);
546 extern long double strtold (const char *__nptr
, char **__endptr
);
549 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
550 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
552 static void sum(int l
);
553 static void next(void);
554 static void next_nomacro(void);
555 static void parse_expr_type(CType
*type
);
556 static void expr_type(CType
*type
);
557 static void unary_type(CType
*type
);
558 static int expr_const(void);
559 static void expr_eq(void);
560 static void gexpr(void);
561 static void decl(int l
);
562 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
563 int first
, int size_only
);
564 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
565 int has_init
, int v
, int scope
);
567 void gv2(int rc1
, int rc2
);
568 void move_reg(int r
, int s
);
569 void save_regs(int n
);
570 void save_reg(int r
);
576 static void macro_subst(TokenString
*tok_str
,
577 Sym
**nested_list
, int *macro_str
);
578 int save_reg_forced(int r
);
580 void force_charshort_cast(int t
);
581 static void gen_cast(CType
*type
);
583 static Sym
*sym_find(int v
);
584 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
587 int type_size(CType
*type
, int *a
);
588 static inline CType
*pointed_type(CType
*type
);
589 static int pointed_size(CType
*type
);
590 static int lvalue_type(int t
);
591 static int is_compatible_types(CType
*type1
, CType
*type2
);
592 static int parse_btype(CType
*type
, AttributeDef
*ad
);
593 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
595 void error(const char *fmt
, ...);
597 void vset(CType
*type
, int r
, int v
);
598 void type_to_str(char *buf
, int buf_size
,
599 CType
*type
, const char *varstr
);
600 char *get_tok_str(int v
, CValue
*cv
);
601 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
602 unsigned long offset
, unsigned long size
);
603 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
605 /* section generation */
606 static void section_realloc(Section
*sec
, unsigned long new_size
);
607 static void *section_ptr_add(Section
*sec
, unsigned long size
);
608 static void put_extern_sym(Sym
*sym
, Section
*section
,
609 unsigned long value
, unsigned long size
);
610 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
611 static int put_elf_str(Section
*s
, const char *sym
);
612 static int put_elf_sym(Section
*s
,
613 unsigned long value
, unsigned long size
,
614 int info
, int other
, int shndx
, const char *name
);
615 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
616 int info
, int sh_num
, const char *name
);
617 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
618 int type
, int symbol
);
619 static void put_stabs(const char *str
, int type
, int other
, int desc
,
620 unsigned long value
);
621 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
622 unsigned long value
, Section
*sec
, int sym_index
);
623 static void put_stabn(int type
, int other
, int desc
, int value
);
624 static void put_stabd(int type
, int other
, int desc
);
625 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
627 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
628 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
629 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
631 /* true if float/double/long double type */
632 static inline int is_float(int t
)
636 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
639 #ifdef TCC_TARGET_I386
640 #include "i386-gen.c"
646 #ifdef CONFIG_TCC_STATIC
648 #define RTLD_LAZY 0x001
649 #define RTLD_NOW 0x002
650 #define RTLD_GLOBAL 0x100
651 #define RTLD_DEFAULT NULL
653 /* dummy function for profiling */
654 void *dlopen(const char *filename
, int flag
)
659 const char *dlerror(void)
664 typedef struct TCCSyms
{
669 #define TCCSYM(a) { #a, &a, },
671 /* add the symbol you want here if no dynamic linking is done */
672 static TCCSyms tcc_syms
[] = {
680 void *dlsym(void *handle
, const char *symbol
)
684 while (p
->str
!= NULL
) {
685 if (!strcmp(p
->str
, symbol
))
694 /********************************************************/
696 /* we use our own 'finite' function to avoid potential problems with
697 non standard math libs */
698 /* XXX: endianness dependant */
699 int ieee_finite(double d
)
702 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
705 /* copy a string and truncate it. */
706 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
713 q_end
= buf
+ buf_size
- 1;
725 /* strcat and truncate. */
726 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
731 pstrcpy(buf
+ len
, buf_size
- len
, s
);
735 /* memory management */
741 static inline void tcc_free(void *ptr
)
744 mem_cur_size
-= malloc_usable_size(ptr
);
749 static void *tcc_malloc(unsigned long size
)
754 error("memory full");
756 mem_cur_size
+= malloc_usable_size(ptr
);
757 if (mem_cur_size
> mem_max_size
)
758 mem_max_size
= mem_cur_size
;
763 static void *tcc_mallocz(unsigned long size
)
766 ptr
= tcc_malloc(size
);
767 memset(ptr
, 0, size
);
771 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
775 mem_cur_size
-= malloc_usable_size(ptr
);
777 ptr1
= realloc(ptr
, size
);
779 /* NOTE: count not correct if alloc error, but not critical */
780 mem_cur_size
+= malloc_usable_size(ptr1
);
781 if (mem_cur_size
> mem_max_size
)
782 mem_max_size
= mem_cur_size
;
787 static char *tcc_strdup(const char *str
)
790 ptr
= tcc_malloc(strlen(str
) + 1);
795 #define free(p) use_tcc_free(p)
796 #define malloc(s) use_tcc_malloc(s)
797 #define realloc(p, s) use_tcc_realloc(p, s)
799 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
806 /* every power of two we double array size */
807 if ((nb
& (nb
- 1)) == 0) {
812 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
814 error("memory full");
821 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
825 sec
= tcc_mallocz(sizeof(Section
));
826 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
827 sec
->sh_type
= sh_type
;
828 sec
->sh_flags
= sh_flags
;
835 sec
->sh_addralign
= 4;
838 sec
->sh_addralign
= 1;
841 sec
->sh_addralign
= 32; /* default conservative alignment */
845 /* only add section if not private */
846 if (!(sh_flags
& SHF_PRIVATE
)) {
847 sec
->sh_num
= s1
->nb_sections
;
848 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
853 static void free_section(Section
*s
)
859 /* realloc section and set its content to zero */
860 static void section_realloc(Section
*sec
, unsigned long new_size
)
865 size
= sec
->data_allocated
;
868 while (size
< new_size
)
870 data
= tcc_realloc(sec
->data
, size
);
872 error("memory full");
873 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
875 sec
->data_allocated
= size
;
878 /* reserve at least 'size' bytes in section 'sec' from
880 static void *section_ptr_add(Section
*sec
, unsigned long size
)
882 unsigned long offset
, offset1
;
884 offset
= sec
->data_offset
;
885 offset1
= offset
+ size
;
886 if (offset1
> sec
->data_allocated
)
887 section_realloc(sec
, offset1
);
888 sec
->data_offset
= offset1
;
889 return sec
->data
+ offset
;
892 /* return a reference to a section, and create it if it does not
894 Section
*find_section(TCCState
*s1
, const char *name
)
898 for(i
= 1; i
< s1
->nb_sections
; i
++) {
899 sec
= s1
->sections
[i
];
900 if (!strcmp(name
, sec
->name
))
903 /* sections are created as PROGBITS */
904 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
907 /* update sym->c so that it points to an external symbol in section
908 'section' with value 'value' */
909 static void put_extern_sym(Sym
*sym
, Section
*section
,
910 unsigned long value
, unsigned long size
)
912 int sym_type
, sym_bind
, sh_num
, info
;
917 sh_num
= section
->sh_num
;
921 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
)
924 sym_type
= STT_OBJECT
;
925 if (sym
->type
.t
& VT_STATIC
)
926 sym_bind
= STB_LOCAL
;
928 sym_bind
= STB_GLOBAL
;
930 name
= get_tok_str(sym
->v
, NULL
);
931 #ifdef CONFIG_TCC_BCHECK
932 if (do_bounds_check
) {
935 /* XXX: avoid doing that for statics ? */
936 /* if bound checking is activated, we change some function
937 names by adding the "__bound" prefix */
940 /* XXX: we rely only on malloc hooks */
952 strcpy(buf
, "__bound_");
959 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
960 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
962 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
963 esym
->st_value
= value
;
964 esym
->st_size
= size
;
965 esym
->st_shndx
= sh_num
;
969 /* add a new relocation entry to symbol 'sym' in section 's' */
970 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
973 put_extern_sym(sym
, NULL
, 0, 0);
974 /* now we can add ELF relocation info */
975 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
978 static inline int isid(int c
)
980 return (c
>= 'a' && c
<= 'z') ||
981 (c
>= 'A' && c
<= 'Z') ||
985 static inline int isnum(int c
)
987 return c
>= '0' && c
<= '9';
990 static inline int isoct(int c
)
992 return c
>= '0' && c
<= '7';
995 static inline int toup(int c
)
997 if (c
>= 'a' && c
<= 'z')
998 return c
- 'a' + 'A';
1003 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1007 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1010 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1014 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1018 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1025 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1026 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1027 (*f
)->filename
, (*f
)->line_num
);
1028 if (file
->line_num
> 0) {
1029 strcat_printf(buf
, sizeof(buf
),
1030 "%s:%d: ", file
->filename
, file
->line_num
);
1032 strcat_printf(buf
, sizeof(buf
),
1033 "%s: ", file
->filename
);
1036 strcat_printf(buf
, sizeof(buf
),
1040 strcat_printf(buf
, sizeof(buf
), "warning: ");
1041 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1043 if (!s1
->error_func
) {
1044 /* default case: stderr */
1045 fprintf(stderr
, "%s\n", buf
);
1047 s1
->error_func(s1
->error_opaque
, buf
);
1054 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1055 void (*error_func
)(void *opaque
, const char *msg
))
1057 s
->error_opaque
= error_opaque
;
1058 s
->error_func
= error_func
;
1062 /* error without aborting current compilation */
1063 void error_noabort(const char *fmt
, ...)
1065 TCCState
*s1
= tcc_state
;
1069 error1(s1
, 0, fmt
, ap
);
1073 void error(const char *fmt
, ...)
1075 TCCState
*s1
= tcc_state
;
1079 error1(s1
, 0, fmt
, ap
);
1081 /* better than nothing: in some cases, we accept to handle errors */
1082 if (s1
->error_set_jmp_enabled
) {
1083 longjmp(s1
->error_jmp_buf
, 1);
1085 /* XXX: suppress it someday */
1090 void expect(const char *msg
)
1092 error("%s expected", msg
);
1095 void warning(const char *fmt
, ...)
1097 TCCState
*s1
= tcc_state
;
1101 error1(s1
, 1, fmt
, ap
);
1108 error("'%c' expected", c
);
1112 void test_lvalue(void)
1114 if (!(vtop
->r
& VT_LVAL
))
1118 TokenSym
*tok_alloc(const char *str
, int len
)
1120 TokenSym
*ts
, **pts
, **ptable
;
1125 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
1127 pts
= &hash_ident
[h
];
1132 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1134 pts
= &(ts
->hash_next
);
1137 if (tok_ident
>= SYM_FIRST_ANOM
)
1138 error("memory full");
1140 /* expand token table if needed */
1141 i
= tok_ident
- TOK_IDENT
;
1142 if ((i
% TOK_ALLOC_INCR
) == 0) {
1143 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1145 error("memory full");
1146 table_ident
= ptable
;
1149 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1150 table_ident
[i
] = ts
;
1151 ts
->tok
= tok_ident
++;
1152 ts
->sym_define
= NULL
;
1153 ts
->sym_label
= NULL
;
1154 ts
->sym_struct
= NULL
;
1155 ts
->sym_identifier
= NULL
;
1157 ts
->hash_next
= NULL
;
1158 memcpy(ts
->str
, str
, len
);
1159 ts
->str
[len
] = '\0';
1164 /* CString handling */
1166 static void cstr_realloc(CString
*cstr
, int new_size
)
1171 size
= cstr
->size_allocated
;
1173 size
= 8; /* no need to allocate a too small first string */
1174 while (size
< new_size
)
1176 data
= tcc_realloc(cstr
->data_allocated
, size
);
1178 error("memory full");
1179 cstr
->data_allocated
= data
;
1180 cstr
->size_allocated
= size
;
1185 static void cstr_ccat(CString
*cstr
, int ch
)
1188 size
= cstr
->size
+ 1;
1189 if (size
> cstr
->size_allocated
)
1190 cstr_realloc(cstr
, size
);
1191 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1195 static void cstr_cat(CString
*cstr
, const char *str
)
1207 /* add a wide char */
1208 static void cstr_wccat(CString
*cstr
, int ch
)
1211 size
= cstr
->size
+ sizeof(int);
1212 if (size
> cstr
->size_allocated
)
1213 cstr_realloc(cstr
, size
);
1214 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1218 static void cstr_new(CString
*cstr
)
1220 memset(cstr
, 0, sizeof(CString
));
1223 /* free string and reset it to NULL */
1224 static void cstr_free(CString
*cstr
)
1226 tcc_free(cstr
->data_allocated
);
1230 #define cstr_reset(cstr) cstr_free(cstr)
1232 static CString
*cstr_dup(CString
*cstr1
)
1237 cstr
= tcc_malloc(sizeof(CString
));
1240 cstr
->size_allocated
= size
;
1241 cstr
->data_allocated
= tcc_malloc(size
);
1242 cstr
->data
= cstr
->data_allocated
;
1243 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1247 /* XXX: unicode ? */
1248 static void add_char(CString
*cstr
, int c
)
1250 if (c
== '\'' || c
== '\"' || c
== '\\') {
1251 /* XXX: could be more precise if char or string */
1252 cstr_ccat(cstr
, '\\');
1254 if (c
>= 32 && c
<= 126) {
1257 cstr_ccat(cstr
, '\\');
1259 cstr_ccat(cstr
, 'n');
1261 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1262 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1263 cstr_ccat(cstr
, '0' + (c
& 7));
1268 /* XXX: buffer overflow */
1269 /* XXX: float tokens */
1270 char *get_tok_str(int v
, CValue
*cv
)
1272 static char buf
[STRING_MAX_SIZE
+ 1];
1273 static CString cstr_buf
;
1279 /* NOTE: to go faster, we give a fixed buffer for small strings */
1280 cstr_reset(&cstr_buf
);
1281 cstr_buf
.data
= buf
;
1282 cstr_buf
.size_allocated
= sizeof(buf
);
1288 /* XXX: not quite exact, but only useful for testing */
1289 sprintf(p
, "%u", cv
->ui
);
1293 /* XXX: not quite exact, but only useful for testing */
1294 sprintf(p
, "%Lu", cv
->ull
);
1298 cstr_ccat(&cstr_buf
, '\'');
1299 add_char(&cstr_buf
, cv
->i
);
1300 cstr_ccat(&cstr_buf
, '\'');
1301 cstr_ccat(&cstr_buf
, '\0');
1305 len
= cstr
->size
- 1;
1307 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1308 cstr_ccat(&cstr_buf
, '\0');
1313 cstr_ccat(&cstr_buf
, '\"');
1315 len
= cstr
->size
- 1;
1317 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1319 len
= (cstr
->size
/ sizeof(int)) - 1;
1321 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1323 cstr_ccat(&cstr_buf
, '\"');
1324 cstr_ccat(&cstr_buf
, '\0');
1333 return strcpy(p
, "<<=");
1335 return strcpy(p
, ">>=");
1337 if (v
< TOK_IDENT
) {
1338 /* search in two bytes table */
1352 } else if (v
< tok_ident
) {
1353 return table_ident
[v
- TOK_IDENT
]->str
;
1354 } else if (v
>= SYM_FIRST_ANOM
) {
1355 /* special name for anonymous symbol */
1356 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1358 /* should never happen */
1363 return cstr_buf
.data
;
1366 /* push, without hashing */
1367 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1370 s
= tcc_malloc(sizeof(Sym
));
1381 /* find a symbol and return its associated structure. 's' is the top
1382 of the symbol stack */
1383 static Sym
*sym_find2(Sym
*s
, int v
)
1393 /* structure lookup */
1394 static Sym
*struct_find(int v
)
1397 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1399 return table_ident
[v
]->sym_struct
;
1402 /* find an identifier */
1403 static inline Sym
*sym_find(int v
)
1406 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1408 return table_ident
[v
]->sym_identifier
;
1411 /* push a given symbol on the symbol stack */
1412 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1421 s
= sym_push2(ps
, v
, type
->t
, c
);
1422 s
->type
.ref
= type
->ref
;
1424 /* don't record fields or anonymous symbols */
1426 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1427 /* record symbol in token array */
1428 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1430 ps
= &ts
->sym_struct
;
1432 ps
= &ts
->sym_identifier
;
1439 /* push a global identifier */
1440 static Sym
*global_identifier_push(int v
, int t
, int c
)
1443 s
= sym_push2(&global_stack
, v
, t
, c
);
1444 /* don't record anonymous symbol */
1445 if (v
< SYM_FIRST_ANOM
) {
1446 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1447 /* modify the top most local identifier, so that
1448 sym_identifier will point to 's' when popped */
1450 ps
= &(*ps
)->prev_tok
;
1457 /* pop symbols until top reaches 'b' */
1458 static void sym_pop(Sym
**ptop
, Sym
*b
)
1468 /* remove symbol in token array */
1470 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1471 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1473 ps
= &ts
->sym_struct
;
1475 ps
= &ts
->sym_identifier
;
1486 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1491 fd
= open(filename
, O_RDONLY
);
1494 bf
= tcc_malloc(sizeof(BufferedFile
));
1500 bf
->buf_ptr
= bf
->buffer
;
1501 bf
->buf_end
= bf
->buffer
;
1502 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1503 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1505 bf
->ifndef_macro
= 0;
1506 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1507 // printf("opening '%s'\n", filename);
1511 void tcc_close(BufferedFile
*bf
)
1513 total_lines
+= bf
->line_num
;
1518 /* fill input buffer and return next char */
1519 int tcc_getc_slow(BufferedFile
*bf
)
1522 /* only tries to read if really end of buffer */
1523 if (bf
->buf_ptr
>= bf
->buf_end
) {
1525 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1532 bf
->buf_ptr
= bf
->buffer
;
1533 bf
->buf_end
= bf
->buffer
+ len
;
1534 *bf
->buf_end
= CH_EOB
;
1536 if (bf
->buf_ptr
< bf
->buf_end
) {
1537 return *bf
->buf_ptr
++;
1539 bf
->buf_ptr
= bf
->buf_end
;
1544 /* no need to put that inline */
1545 void handle_eob(void)
1547 /* no need to do anything if not at EOB */
1548 if (file
->buf_ptr
<= file
->buf_end
)
1550 ch
= tcc_getc_slow(file
);
1553 /* read next char from current input file and handle end of input buffer */
1554 static inline void inp(void)
1556 ch
= *(file
->buf_ptr
++);
1557 /* end of buffer/file handling */
1562 /* handle '\[\r]\n' */
1563 static void handle_stray(void)
1565 while (ch
== '\\') {
1570 } else if (ch
== '\r') {
1578 error("stray '\\' in program");
1583 /* input with '\[\r]\n' handling. Note that this function cannot
1584 handle other characters after '\', so you cannot call it inside
1585 strings or comments */
1586 static void minp(void)
1594 static void parse_line_comment(void)
1596 /* single line C++ comments */
1597 /* XXX: accept '\\\n' ? */
1599 while (ch
!= '\n' && ch
!= TOK_EOF
)
1603 static void parse_comment(void)
1608 /* fast skip loop */
1609 while (ch
!= '\n' && ch
!= '*' && ch
!= TOK_EOF
)
1611 /* now we can handle all the cases */
1615 } else if (ch
== '*') {
1619 goto end_of_comment
;
1620 } else if (ch
== '\\') {
1625 } else if (ch
== '\r') {
1634 } else if (ch
!= '*') {
1639 error("unexpected end of file in comment");
1648 /* space exlcuding newline */
1649 static inline int is_space(int ch
)
1651 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1654 static inline void skip_spaces(void)
1656 while (is_space(ch
))
1660 /* skip block of text until #else, #elif or #endif. skip also pairs of
1662 void preprocess_skip(void)
1664 int a
, start_of_line
, sep
;
1692 /* XXX: better error message */
1693 if (ch
== TOK_EOF
) {
1694 error("unterminated string");
1695 } else if (ch
== '\n') {
1697 } else if (ch
== '\\') {
1698 /* ignore next char */
1712 } else if (ch
== '/') {
1713 parse_line_comment();
1719 if (start_of_line
) {
1722 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1724 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1726 else if (tok
== TOK_ENDIF
)
1742 /* ParseState handling */
1744 /* XXX: currently, no include file info is stored. Thus, we cannot display
1745 accurate messages if the function or data definition spans multiple
1748 /* save current parse state in 's' */
1749 void save_parse_state(ParseState
*s
)
1751 s
->line_num
= file
->line_num
;
1752 s
->macro_ptr
= macro_ptr
;
1757 /* restore parse state from 's' */
1758 void restore_parse_state(ParseState
*s
)
1760 file
->line_num
= s
->line_num
;
1761 macro_ptr
= s
->macro_ptr
;
1766 /* return the number of additionnal 'ints' necessary to store the
1768 static inline int tok_ext_size(int t
)
1787 return LDOUBLE_SIZE
/ 4;
1793 /* token string handling */
1795 static inline void tok_str_new(TokenString
*s
)
1799 s
->last_line_num
= -1;
1802 static void tok_str_free(int *str
)
1813 if (t
== TOK_STR
|| t
== TOK_LSTR
|| t
== TOK_PPNUM
) {
1814 /* XXX: use a macro to be portable on 64 bit ? */
1815 cstr
= (CString
*)(*p
++);
1819 p
+= tok_ext_size(t
);
1825 static void tok_str_add(TokenString
*s
, int t
)
1831 if ((len
& 63) == 0) {
1832 str
= tcc_realloc(str
, (len
+ 64) * sizeof(int));
1841 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1847 if (t
== TOK_STR
|| t
== TOK_LSTR
|| t
== TOK_PPNUM
) {
1848 /* special case: need to duplicate string */
1849 cv1
.cstr
= cstr_dup(cv
->cstr
);
1850 tok_str_add(s
, cv1
.tab
[0]);
1852 n
= tok_ext_size(t
);
1854 tok_str_add(s
, cv
->tab
[i
]);
1858 /* add the current parse token in token string 's' */
1859 static void tok_str_add_tok(TokenString
*s
)
1863 /* save line number info */
1864 if (file
->line_num
!= s
->last_line_num
) {
1865 s
->last_line_num
= file
->line_num
;
1866 cval
.i
= s
->last_line_num
;
1867 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1869 tok_str_add2(s
, tok
, &tokc
);
1872 /* get a token from an integer array and increment pointer accordingly */
1873 static int tok_get(int **tok_str
, CValue
*cv
)
1879 n
= tok_ext_size(t
);
1886 /* defines handling */
1887 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
1891 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
1892 s
->next
= first_arg
;
1893 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
1896 /* undefined a define symbol. Its name is just set to zero */
1897 static void define_undef(Sym
*s
)
1901 if (v
>= TOK_IDENT
&& v
< tok_ident
)
1902 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
1906 static inline Sym
*define_find(int v
)
1909 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1911 return table_ident
[v
]->sym_define
;
1914 /* free define stack until top reaches 'b' */
1915 static void free_defines(Sym
*b
)
1923 /* do not free args or predefined defines */
1925 tok_str_free((int *)top
->c
);
1927 if (v
>= TOK_IDENT
&& v
< tok_ident
)
1928 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
1936 static Sym
*label_find(int v
)
1939 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1941 return table_ident
[v
]->sym_label
;
1944 static Sym
*label_push(int v
, int flags
)
1947 s
= sym_push2(&label_stack
, v
, 0, 0);
1949 table_ident
[v
- TOK_IDENT
]->sym_label
= s
;
1953 /* eval an expression for #if/#elif */
1954 int expr_preprocess(void)
1960 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1961 next(); /* do macro subst */
1962 if (tok
== TOK_DEFINED
) {
1967 c
= define_find(tok
) != 0;
1972 } else if (tok
>= TOK_IDENT
) {
1973 /* if undefined macro */
1977 tok_str_add_tok(&str
);
1979 tok_str_add(&str
, -1); /* simulate end of file */
1980 tok_str_add(&str
, 0);
1981 /* now evaluate C constant expression */
1982 macro_ptr
= str
.str
;
1986 tok_str_free(str
.str
);
1990 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
1991 void tok_print(int *str
)
1997 t
= tok_get(&str
, &cval
);
2000 printf(" %s", get_tok_str(t
, &cval
));
2006 /* parse after #define */
2007 void parse_define(void)
2009 Sym
*s
, *first
, **ps
;
2010 int v
, t
, varg
, is_vaargs
;
2015 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2016 /* XXX: should check if same macro (ANSI) */
2019 /* '(' must be just after macro definition for MACRO_FUNC */
2024 while (tok
!= ')') {
2028 if (varg
== TOK_DOTS
) {
2029 varg
= TOK___VA_ARGS__
;
2031 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2035 if (varg
< TOK_IDENT
)
2036 error("badly punctuated parameter list");
2037 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2048 /* EOF testing necessary for '-D' handling */
2049 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2050 tok_str_add2(&str
, tok
, &tokc
);
2053 tok_str_add(&str
, 0);
2055 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2058 define_push(v
, t
, str
.str
, first
);
2061 /* XXX: use a token or a hash table to accelerate matching ? */
2062 static CachedInclude
*search_cached_include(TCCState
*s1
,
2063 int type
, const char *filename
)
2068 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
2069 e
= s1
->cached_includes
[i
];
2070 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2076 static inline void add_cached_include(TCCState
*s1
, int type
,
2077 const char *filename
, int ifndef_macro
)
2081 if (search_cached_include(s1
, type
, filename
))
2084 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2086 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2090 strcpy(e
->filename
, filename
);
2091 e
->ifndef_macro
= ifndef_macro
;
2092 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2095 /* is_bof is true if first non space token at beginning of file */
2096 static void preprocess(int is_bof
)
2098 TCCState
*s1
= tcc_state
;
2099 int size
, i
, c
, n
, line_num
;
2100 char buf
[1024], *q
, *p
;
2106 return_linefeed
= 1; /* linefeed will be returned as a
2107 token. EOF is also returned as line feed */
2117 s
= define_find(tok
);
2118 /* undefine symbol by putting an invalid name */
2127 } else if (ch
== '\"') {
2132 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2133 if ((q
- buf
) < sizeof(buf
) - 1)
2139 /* eat all spaces and comments after include */
2140 /* XXX: slightly incorrect */
2141 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2145 /* computed #include : either we have only strings or
2146 we have anything enclosed in '<>' */
2149 if (tok
== TOK_STR
) {
2150 while (tok
!= TOK_LINEFEED
) {
2151 if (tok
!= TOK_STR
) {
2153 error("'#include' expects \"FILENAME\" or <FILENAME>");
2155 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2161 while (tok
!= TOK_LINEFEED
) {
2162 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2166 /* check syntax and remove '<>' */
2167 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2168 goto include_syntax
;
2169 memmove(buf
, buf
+ 1, len
- 2);
2170 buf
[len
- 2] = '\0';
2176 e
= search_cached_include(s1
, c
, buf
);
2177 if (e
&& define_find(e
->ifndef_macro
)) {
2178 /* no need to parse the include because the 'ifndef macro'
2181 printf("%s: skipping %s\n", file
->filename
, buf
);
2185 /* first search in current dir if "header.h" */
2187 p
= strrchr(file
->filename
, '/');
2189 size
= p
+ 1 - file
->filename
;
2190 if (size
> sizeof(buf1
) - 1)
2191 size
= sizeof(buf1
) - 1;
2192 memcpy(buf1
, file
->filename
, size
);
2194 pstrcat(buf1
, sizeof(buf1
), buf
);
2195 f
= tcc_open(s1
, buf1
);
2199 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2200 error("#include recursion too deep");
2201 /* now search in all the include paths */
2202 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2203 for(i
= 0; i
< n
; i
++) {
2205 if (i
< s1
->nb_include_paths
)
2206 path
= s1
->include_paths
[i
];
2208 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2209 pstrcpy(buf1
, sizeof(buf1
), path
);
2210 pstrcat(buf1
, sizeof(buf1
), "/");
2211 pstrcat(buf1
, sizeof(buf1
), buf
);
2212 f
= tcc_open(s1
, buf1
);
2216 error("include file '%s' not found", buf
);
2220 printf("%s: including %s\n", file
->filename
, buf1
);
2223 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2224 /* push current file in stack */
2225 /* XXX: fix current line init */
2226 *s1
->include_stack_ptr
++ = file
;
2228 /* add include file debug info */
2230 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2232 tok_flags
|= TOK_FLAG_BOF
;
2240 c
= expr_preprocess();
2246 if (tok
< TOK_IDENT
)
2247 error("invalid argument for '#if%sdef'", c
? "n" : "");
2251 printf("#ifndef %s\n", get_tok_str(tok
, NULL
));
2253 file
->ifndef_macro
= tok
;
2256 c
= (define_find(tok
) != 0) ^ c
;
2258 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2259 error("memory full");
2260 *s1
->ifdef_stack_ptr
++ = c
;
2263 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2264 error("#else without matching #if");
2265 if (s1
->ifdef_stack_ptr
[-1] & 2)
2266 error("#else after #else");
2267 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2270 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2271 error("#elif without matching #if");
2272 c
= s1
->ifdef_stack_ptr
[-1];
2274 error("#elif after #else");
2275 /* last #if/#elif expression was true: we skip */
2278 c
= expr_preprocess();
2279 s1
->ifdef_stack_ptr
[-1] = c
;
2289 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2290 error("#endif without matching #if");
2291 s1
->ifdef_stack_ptr
--;
2292 /* '#ifndef macro' was at the start of file. Now we check if
2293 an '#endif' is exactly at the end of file */
2294 if (file
->ifndef_macro
&&
2295 s1
->ifdef_stack_ptr
== file
->ifdef_stack_ptr
) {
2296 file
->ifndef_macro_saved
= file
->ifndef_macro
;
2297 /* need to set to zero to avoid false matches if another
2298 #ifndef at middle of file */
2299 file
->ifndef_macro
= 0;
2300 while (tok
!= TOK_LINEFEED
)
2302 tok_flags
|= TOK_FLAG_ENDIF
;
2308 if (tok
!= TOK_CINT
)
2312 if (tok
!= TOK_LINEFEED
) {
2315 pstrcpy(file
->filename
, sizeof(file
->filename
),
2316 (char *)tokc
.cstr
->data
);
2318 /* NOTE: we do it there to avoid problems with linefeed */
2319 file
->line_num
= line_num
;
2326 while (ch
!= '\n' && ch
!= CH_EOF
) {
2327 if ((q
- buf
) < sizeof(buf
) - 1)
2333 error("#error %s", buf
);
2335 warning("#warning %s", buf
);
2338 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
2339 /* '!' is ignored to allow C scripts. numbers are ignored
2340 to emulate cpp behaviour */
2342 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
2346 /* ignore other preprocess commands or #! for C scripts */
2347 while (tok
!= TOK_LINEFEED
)
2350 return_linefeed
= 0;
2353 /* read a number in base b */
2354 static int getn(int b
)
2359 if (ch
>= 'a' && ch
<= 'f')
2361 else if (ch
>= 'A' && ch
<= 'F')
2367 if (t
< 0 || t
>= b
)
2375 /* read a character for string or char constant and eval escape codes */
2376 static int getq(void)
2385 case '0': case '1': case '2': case '3':
2386 case '4': case '5': case '6': case '7':
2387 /* at most three octal digits */
2391 c
= c
* 8 + ch
- '0';
2394 c
= c
* 8 + ch
- '0';
2425 goto invalid_escape
;
2440 goto invalid_escape
;
2445 error("invalid escaped char");
2448 } else if (c
== '\r' && ch
== '\n') {
2455 /* we use 64 bit numbers */
2458 /* bn = (bn << shift) | or_val */
2459 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2463 for(i
=0;i
<BN_SIZE
;i
++) {
2465 bn
[i
] = (v
<< shift
) | or_val
;
2466 or_val
= v
>> (32 - shift
);
2470 void bn_zero(unsigned int *bn
)
2473 for(i
=0;i
<BN_SIZE
;i
++) {
2478 /* parse number in null terminated string 'p' and return it in the
2480 void parse_number(const char *p
)
2482 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
2484 unsigned int bn
[BN_SIZE
];
2495 goto float_frac_parse
;
2496 } else if (t
== '0') {
2497 if (ch
== 'x' || ch
== 'X') {
2501 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2507 /* parse all digits. cannot check octal numbers at this stage
2508 because of floating point constants */
2510 if (ch
>= 'a' && ch
<= 'f')
2512 else if (ch
>= 'A' && ch
<= 'F')
2520 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2522 error("number too long");
2528 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2529 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2531 /* NOTE: strtox should support that for hexa numbers, but
2532 non ISOC99 libcs do not support it, so we prefer to do
2534 /* hexadecimal or binary floats */
2535 /* XXX: handle overflows */
2547 } else if (t
>= 'a') {
2549 } else if (t
>= 'A') {
2554 bn_lshift(bn
, shift
, t
);
2561 if (t
>= 'a' && t
<= 'f') {
2563 } else if (t
>= 'A' && t
<= 'F') {
2565 } else if (t
>= '0' && t
<= '9') {
2571 error("invalid digit");
2572 bn_lshift(bn
, shift
, t
);
2577 if (ch
!= 'p' && ch
!= 'P')
2584 } else if (ch
== '-') {
2588 if (ch
< '0' || ch
> '9')
2589 expect("exponent digits");
2590 while (ch
>= '0' && ch
<= '9') {
2591 exp_val
= exp_val
* 10 + ch
- '0';
2594 exp_val
= exp_val
* s
;
2596 /* now we can generate the number */
2597 /* XXX: should patch directly float number */
2598 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
2599 d
= ldexp(d
, exp_val
- frac_bits
);
2604 /* float : should handle overflow */
2606 } else if (t
== 'L') {
2609 /* XXX: not large enough */
2610 tokc
.ld
= (long double)d
;
2616 /* decimal floats */
2618 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2623 while (ch
>= '0' && ch
<= '9') {
2624 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2630 if (ch
== 'e' || ch
== 'E') {
2631 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2635 if (ch
== '-' || ch
== '+') {
2636 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2641 if (ch
< '0' || ch
> '9')
2642 expect("exponent digits");
2643 while (ch
>= '0' && ch
<= '9') {
2644 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2656 tokc
.f
= strtof(token_buf
, NULL
);
2657 } else if (t
== 'L') {
2660 tokc
.ld
= strtold(token_buf
, NULL
);
2663 tokc
.d
= strtod(token_buf
, NULL
);
2667 unsigned long long n
, n1
;
2670 /* integer number */
2673 if (b
== 10 && *q
== '0') {
2680 /* no need for checks except for base 10 / 8 errors */
2683 } else if (t
>= 'a') {
2685 } else if (t
>= 'A') {
2690 error("invalid digit");
2694 /* detect overflow */
2695 /* XXX: this test is not reliable */
2697 error("integer constant overflow");
2700 /* XXX: not exactly ANSI compliant */
2701 if ((n
& 0xffffffff00000000LL
) != 0) {
2706 } else if (n
> 0x7fffffff) {
2717 error("three 'l's in integer constant");
2720 if (tok
== TOK_CINT
)
2722 else if (tok
== TOK_CUINT
)
2726 } else if (t
== 'U') {
2728 error("two 'u's in integer constant");
2730 if (tok
== TOK_CINT
)
2732 else if (tok
== TOK_CLLONG
)
2739 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2746 /* return next token without macro substitution */
2747 static inline void next_nomacro1(void)
2769 TCCState
*s1
= tcc_state
;
2771 if (return_linefeed
) {
2773 } else if (s1
->include_stack_ptr
== s1
->include_stack
) {
2774 /* no include left : end of file */
2777 /* pop include file */
2779 /* test if previous '#endif' was after a #ifdef at
2781 if (tok_flags
& TOK_FLAG_ENDIF
) {
2783 printf("#endif %s\n", get_tok_str(file
->ifndef_macro_saved
, NULL
));
2785 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
2786 file
->ifndef_macro_saved
);
2789 /* add end of include file debug info */
2791 put_stabd(N_EINCL
, 0, 0);
2793 /* pop include stack */
2795 s1
->include_stack_ptr
--;
2796 file
= *s1
->include_stack_ptr
;
2805 if (return_linefeed
) {
2808 tok_flags
|= TOK_FLAG_BOL
;
2816 if (tok_flags
& TOK_FLAG_BOL
) {
2817 preprocess(tok_flags
& TOK_FLAG_BOF
);
2822 tok
= TOK_TWOSHARPS
;
2829 case 'a': case 'b': case 'c': case 'd':
2830 case 'e': case 'f': case 'g': case 'h':
2831 case 'i': case 'j': case 'k': case 'l':
2832 case 'm': case 'n': case 'o': case 'p':
2833 case 'q': case 'r': case 's': case 't':
2834 case 'u': case 'v': case 'w': case 'x':
2836 case 'A': case 'B': case 'C': case 'D':
2837 case 'E': case 'F': case 'G': case 'H':
2838 case 'I': case 'J': case 'K':
2839 case 'M': case 'N': case 'O': case 'P':
2840 case 'Q': case 'R': case 'S': case 'T':
2841 case 'U': case 'V': case 'W': case 'X':
2848 while (isid(ch
) || isnum(ch
)) {
2849 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2850 error("ident too long");
2855 ts
= tok_alloc(token_buf
, q
- token_buf
);
2872 case '0': case '1': case '2': case '3':
2873 case '4': case '5': case '6': case '7':
2876 cstr_reset(&tokcstr
);
2877 /* after the first digit, accept digits, alpha, '.' or sign if
2878 prefixed by 'eEpP' */
2882 cstr_ccat(&tokcstr
, ch
);
2884 if (!(isnum(ch
) || isid(ch
) || ch
== '.' ||
2885 ((ch
== '+' || ch
== '-') &&
2886 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
2889 /* We add a trailing '\0' to ease parsing */
2890 cstr_ccat(&tokcstr
, '\0');
2891 tokc
.cstr
= &tokcstr
;
2895 /* special dot handling because it can also start a number */
2898 cstr_reset(&tokcstr
);
2899 cstr_ccat(&tokcstr
, '.');
2917 /* this cast is needed if >= 128 */
2918 if (tok
== TOK_CCHAR
)
2922 error("unterminated character constant");
2929 cstr_reset(&tokcstr
);
2930 while (ch
!= '\"') {
2933 error("unterminated string");
2935 cstr_ccat(&tokcstr
, b
);
2937 cstr_wccat(&tokcstr
, b
);
2940 cstr_ccat(&tokcstr
, '\0');
2942 cstr_wccat(&tokcstr
, '\0');
2943 tokc
.cstr
= &tokcstr
;
2952 } else if (ch
== '<') {
2970 } else if (ch
== '>') {
3007 } else if (ch
== '=') {
3019 } else if (ch
== '=') {
3031 } else if (ch
== '=') {
3043 } else if (ch
== '=') {
3046 } else if (ch
== '>') {
3079 /* comments or operator */
3085 } else if (ch
== '/') {
3086 parse_line_comment();
3088 } else if (ch
== '=') {
3112 error("unrecognized character \\x%02x", ch
);
3116 #if defined(PARSE_DEBUG)
3117 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3121 /* return next token without macro substitution. Can read input from
3123 static void next_nomacro(void)
3129 tok
= tok_get(¯o_ptr
, &tokc
);
3130 if (tok
== TOK_LINENUM
) {
3131 file
->line_num
= tokc
.i
;
3140 /* substitute args in macro_str and return allocated string */
3141 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
3143 int *st
, last_tok
, t
, notfirst
;
3152 t
= tok_get(¯o_str
, &cval
);
3157 t
= tok_get(¯o_str
, &cval
);
3160 s
= sym_find2(args
, t
);
3167 cstr_ccat(&cstr
, ' ');
3168 t
= tok_get(&st
, &cval
);
3169 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
3172 cstr_ccat(&cstr
, '\0');
3174 printf("stringize: %s\n", (char *)cstr
.data
);
3178 tok_str_add2(&str
, TOK_STR
, &cval
);
3181 tok_str_add2(&str
, t
, &cval
);
3183 } else if (t
>= TOK_IDENT
) {
3184 s
= sym_find2(args
, t
);
3187 /* if '##' is present before or after, no arg substitution */
3188 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
3189 /* special case for var arg macros : ## eats the
3190 ',' if empty VA_ARGS variable. */
3191 /* XXX: test of the ',' is not 100%
3192 reliable. should fix it to avoid security
3194 if (gnu_ext
&& s
->type
.t
&&
3195 last_tok
== TOK_TWOSHARPS
&&
3196 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
3198 /* suppress ',' '##' */
3201 /* suppress '##' and add variable */
3209 t1
= tok_get(&st
, &cval
);
3212 tok_str_add2(&str
, t1
, &cval
);
3216 macro_subst(&str
, nested_list
, st
);
3219 tok_str_add(&str
, t
);
3222 tok_str_add2(&str
, t
, &cval
);
3226 tok_str_add(&str
, 0);
3230 /* handle the '##' operator */
3231 static int *macro_twosharps(void)
3236 const char *p1
, *p2
;
3238 TokenString macro_str1
;
3242 tok_str_new(¯o_str1
);
3248 while (*macro_ptr
== TOK_TWOSHARPS
) {
3250 macro_ptr1
= macro_ptr
;
3253 t
= tok_get(¯o_ptr
, &cval
);
3255 /* We concatenate the two tokens if we have an
3256 identifier or a preprocessing number */
3258 p1
= get_tok_str(tok
, &tokc
);
3259 cstr_cat(&cstr
, p1
);
3260 p2
= get_tok_str(t
, &cval
);
3261 cstr_cat(&cstr
, p2
);
3262 cstr_ccat(&cstr
, '\0');
3264 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
3265 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
3266 if (tok
== TOK_PPNUM
) {
3267 /* if number, then create a number token */
3268 /* NOTE: no need to allocate because
3269 tok_str_add2() does it */
3272 /* if identifier, we must do a test to
3273 validate we have a correct identifier */
3274 if (t
== TOK_PPNUM
) {
3284 if (!isnum(c
) && !isid(c
))
3288 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
3289 tok
= ts
->tok
; /* modify current token */
3292 const char *str
= cstr
.data
;
3293 const unsigned char *q
;
3295 /* we look for a valid token */
3296 /* XXX: do more extensive checks */
3297 if (!strcmp(str
, ">>=")) {
3299 } else if (!strcmp(str
, "<<=")) {
3301 } else if (strlen(str
) == 2) {
3302 /* search in two bytes table */
3307 if (q
[0] == str
[0] && q
[1] == str
[1])
3314 /* NOTE: because get_tok_str use a static buffer,
3317 p1
= get_tok_str(tok
, &tokc
);
3318 cstr_cat(&cstr
, p1
);
3319 cstr_ccat(&cstr
, '\0');
3320 p2
= get_tok_str(t
, &cval
);
3321 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
3322 /* cannot merge tokens: just add them separately */
3323 tok_str_add2(¯o_str1
, tok
, &tokc
);
3324 /* XXX: free associated memory ? */
3331 tok_str_add2(¯o_str1
, tok
, &tokc
);
3334 tok_str_add(¯o_str1
, 0);
3335 return macro_str1
.str
;
3339 /* do macro substitution of current token with macro 's' and add
3340 result to (tok_str,tok_len). 'nested_list' is the list of all
3341 macros we got inside to avoid recursing. Return non zero if no
3342 substitution needs to be done */
3343 static int macro_subst_tok(TokenString
*tok_str
,
3344 Sym
**nested_list
, Sym
*s
)
3346 Sym
*args
, *sa
, *sa1
;
3347 int mstr_allocated
, parlevel
, *mstr
, t
;
3353 /* if symbol is a macro, prepare substitution */
3354 /* if nested substitution, do nothing */
3355 if (sym_find2(*nested_list
, tok
))
3358 /* special macros */
3359 if (tok
== TOK___LINE__
) {
3360 cval
.i
= file
->line_num
;
3361 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
3362 } else if (tok
== TOK___FILE__
) {
3363 cstrval
= file
->filename
;
3365 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3366 } else if (tok
== TOK___DATE__
) {
3367 cstrval
= "Jan 1 2002";
3369 } else if (tok
== TOK___TIME__
) {
3370 cstrval
= "00:00:00";
3373 cstr_cat(&cstr
, cstrval
);
3374 cstr_ccat(&cstr
, '\0');
3376 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3381 if (s
->type
.t
== MACRO_FUNC
) {
3382 /* NOTE: we do not use next_nomacro to avoid eating the
3383 next token. XXX: find better solution */
3387 /* XXX: incorrect with comments */
3388 while (is_space(ch
) || ch
== '\n')
3392 if (t
!= '(') /* no macro subst */
3395 /* argument macro */
3400 /* NOTE: empty args are allowed, except if no args */
3402 /* handle '()' case */
3403 if (!args
&& tok
== ')')
3406 error("macro '%s' used with too many args",
3407 get_tok_str(s
->v
, 0));
3410 /* NOTE: non zero sa->t indicates VA_ARGS */
3411 while ((parlevel
> 0 ||
3413 (tok
!= ',' || sa
->type
.t
))) &&
3417 else if (tok
== ')')
3419 tok_str_add2(&str
, tok
, &tokc
);
3422 tok_str_add(&str
, 0);
3423 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
3426 /* special case for gcc var args: add an empty
3427 var arg argument if it is omitted */
3428 if (sa
&& sa
->type
.t
&& gnu_ext
)
3438 error("macro '%s' used with too few args",
3439 get_tok_str(s
->v
, 0));
3442 /* now subst each arg */
3443 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3448 tok_str_free((int *)sa
->c
);
3454 sym_push2(nested_list
, s
->v
, 0, 0);
3455 macro_subst(tok_str
, nested_list
, mstr
);
3456 /* pop nested defined symbol */
3458 *nested_list
= sa1
->prev
;
3466 /* do macro substitution of macro_str and add result to
3467 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3468 inside to avoid recursing. */
3469 static void macro_subst(TokenString
*tok_str
,
3470 Sym
**nested_list
, int *macro_str
)
3473 int *saved_macro_ptr
;
3476 saved_macro_ptr
= macro_ptr
;
3477 macro_ptr
= macro_str
;
3478 /* first scan for '##' operator handling */
3479 macro_str1
= macro_twosharps();
3480 macro_ptr
= macro_str1
;
3486 s
= define_find(tok
);
3488 if (macro_subst_tok(tok_str
, nested_list
, s
) != 0)
3492 tok_str_add2(tok_str
, tok
, &tokc
);
3495 macro_ptr
= saved_macro_ptr
;
3496 tok_str_free(macro_str1
);
3499 /* return next token with macro substitution */
3500 static void next(void)
3502 Sym
*nested_list
, *s
;
3505 /* special 'ungettok' case for label parsing */
3514 /* if not reading from macro substituted string, then try
3515 to substitute macros */
3516 if (tok
>= TOK_IDENT
) {
3517 s
= define_find(tok
);
3519 /* we have a macro: we try to substitute */
3522 if (macro_subst_tok(&str
, &nested_list
, s
) == 0) {
3523 /* substitution done, NOTE: maybe empty */
3524 tok_str_add(&str
, 0);
3525 macro_ptr
= str
.str
;
3526 macro_ptr_allocated
= str
.str
;
3533 /* end of macro string: free it */
3534 tok_str_free(macro_ptr_allocated
);
3540 /* convert preprocessor tokens into C tokens */
3541 if (tok
== TOK_PPNUM
) {
3542 parse_number((char *)tokc
.cstr
->data
);
3547 void swap(int *p
, int *q
)
3555 void vsetc(CType
*type
, int r
, CValue
*vc
)
3559 if (vtop
>= vstack
+ VSTACK_SIZE
)
3560 error("memory full");
3561 /* cannot let cpu flags if other instruction are generated. Also
3562 avoid leaving VT_JMP anywhere except on the top of the stack
3563 because it would complicate the code generator. */
3564 if (vtop
>= vstack
) {
3565 v
= vtop
->r
& VT_VALMASK
;
3566 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
3572 vtop
->r2
= VT_CONST
;
3576 /* push integer constant */
3581 vsetc(&int_type
, VT_CONST
, &cval
);
3584 /* Return a static symbol pointing to a section */
3585 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
3586 unsigned long offset
, unsigned long size
)
3592 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
3593 sym
->type
.ref
= type
->ref
;
3594 sym
->r
= VT_CONST
| VT_SYM
;
3595 put_extern_sym(sym
, sec
, offset
, size
);
3599 /* push a reference to a section offset by adding a dummy symbol */
3600 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
3605 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
3606 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
3609 /* define a new external reference to a symbol 'v' of type 'u' */
3610 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
3616 /* push forward reference */
3617 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
3618 s
->type
.ref
= type
->ref
;
3619 s
->r
= r
| VT_CONST
| VT_SYM
;
3624 /* define a new external reference to a symbol 'v' of type 'u' */
3625 static Sym
*external_sym(int v
, CType
*type
, int r
)
3631 /* push forward reference */
3632 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
3633 s
->type
.t
|= VT_EXTERN
;
3638 /* push a reference to global symbol v */
3639 static void vpush_global_sym(CType
*type
, int v
)
3644 sym
= external_global_sym(v
, type
, 0);
3646 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
3650 void vset(CType
*type
, int r
, int v
)
3655 vsetc(type
, r
, &cval
);
3658 void vseti(int r
, int v
)
3674 void vpushv(SValue
*v
)
3676 if (vtop
>= vstack
+ VSTACK_SIZE
)
3677 error("memory full");
3687 /* save r to the memory stack, and mark it as being free */
3688 void save_reg(int r
)
3690 int l
, saved
, size
, align
;
3694 /* modify all stack values */
3697 for(p
=vstack
;p
<=vtop
;p
++) {
3698 if ((p
->r
& VT_VALMASK
) == r
||
3699 (p
->r2
& VT_VALMASK
) == r
) {
3700 /* must save value on stack if not already done */
3702 /* NOTE: must reload 'r' because r might be equal to r2 */
3703 r
= p
->r
& VT_VALMASK
;
3704 /* store register in the stack */
3706 if ((p
->r
& VT_LVAL
) ||
3707 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
3709 size
= type_size(type
, &align
);
3710 loc
= (loc
- size
) & -align
;
3711 sv
.type
.t
= type
->t
;
3712 sv
.r
= VT_LOCAL
| VT_LVAL
;
3715 #ifdef TCC_TARGET_I386
3716 /* x86 specific: need to pop fp register ST0 if saved */
3718 o(0xd9dd); /* fstp %st(1) */
3721 /* special long long case */
3722 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
3729 /* mark that stack entry as being saved on the stack */
3730 if (p
->r
& VT_LVAL
) {
3731 /* also suppress the bounded flag because the
3732 relocation address of the function was stored in
3734 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
3736 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
3744 /* find a free register of class 'rc'. If none, save one register */
3750 /* find a free register */
3751 for(r
=0;r
<NB_REGS
;r
++) {
3752 if (reg_classes
[r
] & rc
) {
3753 for(p
=vstack
;p
<=vtop
;p
++) {
3754 if ((p
->r
& VT_VALMASK
) == r
||
3755 (p
->r2
& VT_VALMASK
) == r
)
3763 /* no register left : free the first one on the stack (VERY
3764 IMPORTANT to start from the bottom to ensure that we don't
3765 spill registers used in gen_opi()) */
3766 for(p
=vstack
;p
<=vtop
;p
++) {
3767 r
= p
->r
& VT_VALMASK
;
3768 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
3770 /* also look at second register (if long long) */
3771 r
= p
->r2
& VT_VALMASK
;
3772 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
3778 /* Should never comes here */
3782 /* save registers up to (vtop - n) stack entry */
3783 void save_regs(int n
)
3788 for(p
= vstack
;p
<= p1
; p
++) {
3789 r
= p
->r
& VT_VALMASK
;
3796 /* move register 's' to 'r', and flush previous value of r to memory
3798 void move_reg(int r
, int s
)
3811 /* get address of vtop (vtop MUST BE an lvalue) */
3814 vtop
->r
&= ~VT_LVAL
;
3815 /* tricky: if saved lvalue, then we can go back to lvalue */
3816 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
3817 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
3820 #ifdef CONFIG_TCC_BCHECK
3821 /* generate lvalue bound code */
3827 vtop
->r
&= ~VT_MUSTBOUND
;
3828 /* if lvalue, then use checking code before dereferencing */
3829 if (vtop
->r
& VT_LVAL
) {
3830 /* if not VT_BOUNDED value, then make one */
3831 if (!(vtop
->r
& VT_BOUNDED
)) {
3832 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
3833 /* must save type because we must set it to int to get pointer */
3835 vtop
->type
.t
= VT_INT
;
3838 gen_bounded_ptr_add();
3839 vtop
->r
|= lval_type
;
3842 /* then check for dereferencing */
3843 gen_bounded_ptr_deref();
3848 /* store vtop a register belonging to class 'rc'. lvalues are
3849 converted to values. Cannot be used if cannot be converted to
3850 register value (such as structures). */
3853 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
3854 unsigned long long ll
;
3856 /* NOTE: get_reg can modify vstack[] */
3857 if (vtop
->type
.t
& VT_BITFIELD
) {
3858 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
3859 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3860 /* remove bit field info to avoid loops */
3861 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3862 /* generate shifts */
3863 vpushi(32 - (bit_pos
+ bit_size
));
3865 vpushi(32 - bit_size
);
3866 /* NOTE: transformed to SHR if unsigned */
3870 if (is_float(vtop
->type
.t
) &&
3871 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3874 unsigned long offset
;
3876 /* XXX: unify with initializers handling ? */
3877 /* CPUs usually cannot use float constants, so we store them
3878 generically in data segment */
3879 size
= type_size(&vtop
->type
, &align
);
3880 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
3881 data_section
->data_offset
= offset
;
3882 /* XXX: not portable yet */
3883 ptr
= section_ptr_add(data_section
, size
);
3886 ptr
[i
] = vtop
->c
.tab
[i
];
3887 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
3888 vtop
->r
|= VT_LVAL
| VT_SYM
;
3892 #ifdef CONFIG_TCC_BCHECK
3893 if (vtop
->r
& VT_MUSTBOUND
)
3897 r
= vtop
->r
& VT_VALMASK
;
3898 /* need to reload if:
3900 - lvalue (need to dereference pointer)
3901 - already a register, but not in the right class */
3902 if (r
>= VT_CONST
||
3903 (vtop
->r
& VT_LVAL
) ||
3904 !(reg_classes
[r
] & rc
) ||
3905 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
3906 !(reg_classes
[vtop
->r2
] & rc
))) {
3908 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
3909 /* two register type load : expand to two words
3911 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3914 vtop
->c
.ui
= ll
; /* first word */
3916 vtop
->r
= r
; /* save register value */
3917 vpushi(ll
>> 32); /* second word */
3918 } else if (r
>= VT_CONST
||
3919 (vtop
->r
& VT_LVAL
)) {
3920 /* load from memory */
3923 vtop
[-1].r
= r
; /* save register value */
3924 /* increment pointer to get second word */
3925 vtop
->type
.t
= VT_INT
;
3931 /* move registers */
3934 vtop
[-1].r
= r
; /* save register value */
3935 vtop
->r
= vtop
[-1].r2
;
3937 /* allocate second register */
3944 /* write second register */
3946 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
3948 /* lvalue of scalar type : need to use lvalue type
3949 because of possible cast */
3952 /* compute memory access type */
3953 if (vtop
->r
& VT_LVAL_BYTE
)
3955 else if (vtop
->r
& VT_LVAL_SHORT
)
3957 if (vtop
->r
& VT_LVAL_UNSIGNED
)
3961 /* restore wanted type */
3964 /* one register type load */
3973 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3974 void gv2(int rc1
, int rc2
)
3978 /* generate more generic register first. But VT_JMP or VT_CMP
3979 values must be generated first in all cases to avoid possible
3981 v
= vtop
[0].r
& VT_VALMASK
;
3982 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
3987 /* test if reload is needed for first register */
3988 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
3998 /* test if reload is needed for first register */
3999 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
4005 /* expand long long on stack in two int registers */
4010 u
= vtop
->type
.t
& VT_UNSIGNED
;
4013 vtop
[0].r
= vtop
[-1].r2
;
4014 vtop
[0].r2
= VT_CONST
;
4015 vtop
[-1].r2
= VT_CONST
;
4016 vtop
[0].type
.t
= VT_INT
| u
;
4017 vtop
[-1].type
.t
= VT_INT
| u
;
4020 /* build a long long from two ints */
4023 gv2(RC_INT
, RC_INT
);
4024 vtop
[-1].r2
= vtop
[0].r
;
4025 vtop
[-1].type
.t
= t
;
4029 /* rotate n first stack elements to the bottom */
4036 for(i
=-n
+1;i
!=0;i
++)
4037 vtop
[i
] = vtop
[i
+1];
4041 /* pop stack value */
4045 v
= vtop
->r
& VT_VALMASK
;
4046 #ifdef TCC_TARGET_I386
4047 /* for x86, we need to pop the FP stack */
4048 if (v
== REG_ST0
&& !nocode_wanted
) {
4049 o(0xd9dd); /* fstp %st(1) */
4052 if (v
== VT_JMP
|| v
== VT_JMPI
) {
4053 /* need to put correct jump if && or || without test */
4059 /* convert stack entry to register and duplicate its value in another
4067 if ((t
& VT_BTYPE
) == VT_LLONG
) {
4074 /* stack: H L L1 H1 */
4082 /* duplicate value */
4093 load(r1
, &sv
); /* move r to r1 */
4095 /* duplicates value */
4100 /* generate CPU independent (unsigned) long long operations */
4101 void gen_opl(int op
)
4103 int t
, a
, b
, op1
, c
, i
;
4111 func
= TOK___divdi3
;
4114 func
= TOK___udivdi3
;
4117 func
= TOK___moddi3
;
4120 func
= TOK___umoddi3
;
4122 /* call generic long long function */
4123 gfunc_start(&gf
, FUNC_CDECL
);
4126 vpush_global_sym(&func_old_type
, func
);
4130 vtop
->r2
= REG_LRET
;
4143 /* stack: L1 H1 L2 H2 */
4148 vtop
[-2] = vtop
[-3];
4151 /* stack: H1 H2 L1 L2 */
4157 /* stack: H1 H2 L1 L2 ML MH */
4160 /* stack: ML MH H1 H2 L1 L2 */
4164 /* stack: ML MH H1 L2 H2 L1 */
4169 /* stack: ML MH M1 M2 */
4172 } else if (op
== '+' || op
== '-') {
4173 /* XXX: add non carry method too (for MIPS or alpha) */
4179 /* stack: H1 H2 (L1 op L2) */
4182 gen_op(op1
+ 1); /* TOK_xxxC2 */
4185 /* stack: H1 H2 (L1 op L2) */
4188 /* stack: (L1 op L2) H1 H2 */
4190 /* stack: (L1 op L2) (H1 op H2) */
4198 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4199 t
= vtop
[-1].type
.t
;
4203 /* stack: L H shift */
4205 /* constant: simpler */
4206 /* NOTE: all comments are for SHL. the other cases are
4207 done by swaping words */
4218 if (op
!= TOK_SAR
) {
4251 /* XXX: should provide a faster fallback on x86 ? */
4254 func
= TOK___sardi3
;
4257 func
= TOK___shrdi3
;
4260 func
= TOK___shldi3
;
4266 /* compare operations */
4272 /* stack: L1 H1 L2 H2 */
4274 vtop
[-1] = vtop
[-2];
4276 /* stack: L1 L2 H1 H2 */
4279 /* when values are equal, we need to compare low words. since
4280 the jump is inverted, we invert the test too. */
4283 else if (op1
== TOK_GT
)
4285 else if (op1
== TOK_ULT
)
4287 else if (op1
== TOK_UGT
)
4292 if (op1
!= TOK_NE
) {
4296 /* generate non equal test */
4297 /* XXX: NOT PORTABLE yet */
4301 #ifdef TCC_TARGET_I386
4302 b
= psym(0x850f, 0);
4304 error("not implemented");
4317 /* handle integer constant optimizations and various machine
4319 void gen_opic(int op
)
4326 /* currently, we cannot do computations with forward symbols */
4327 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4328 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4332 case '+': v1
->c
.i
+= fc
; break;
4333 case '-': v1
->c
.i
-= fc
; break;
4334 case '&': v1
->c
.i
&= fc
; break;
4335 case '^': v1
->c
.i
^= fc
; break;
4336 case '|': v1
->c
.i
|= fc
; break;
4337 case '*': v1
->c
.i
*= fc
; break;
4344 /* if division by zero, generate explicit division */
4347 error("division by zero in constant");
4351 default: v1
->c
.i
/= fc
; break;
4352 case '%': v1
->c
.i
%= fc
; break;
4353 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
4354 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
4357 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
4358 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
4359 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
4361 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
4362 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
4363 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
4364 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
4365 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
4366 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
4367 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
4368 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
4369 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
4370 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
4372 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
4373 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
4379 /* if commutative ops, put c2 as constant */
4380 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
4381 op
== '|' || op
== '*')) {
4386 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
4389 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
4390 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
4396 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
4397 /* try to use shifts instead of muls or divs */
4398 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
4407 else if (op
== TOK_PDIV
)
4413 } else if (c2
&& (op
== '+' || op
== '-') &&
4414 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
4415 (VT_CONST
| VT_SYM
)) {
4416 /* symbol + constant case */
4423 if (!nocode_wanted
) {
4424 /* call low level op generator */
4433 /* generate a floating point operation with constant propagation */
4434 void gen_opif(int op
)
4442 /* currently, we cannot do computations with forward symbols */
4443 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4444 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4446 if (v1
->type
.t
== VT_FLOAT
) {
4449 } else if (v1
->type
.t
== VT_DOUBLE
) {
4457 /* NOTE: we only do constant propagation if finite number (not
4458 NaN or infinity) (ANSI spec) */
4459 if (!ieee_finite(f1
) || !ieee_finite(f2
))
4463 case '+': f1
+= f2
; break;
4464 case '-': f1
-= f2
; break;
4465 case '*': f1
*= f2
; break;
4469 error("division by zero in constant");
4474 /* XXX: also handles tests ? */
4478 /* XXX: overflow test ? */
4479 if (v1
->type
.t
== VT_FLOAT
) {
4481 } else if (v1
->type
.t
== VT_DOUBLE
) {
4489 if (!nocode_wanted
) {
4497 static int pointed_size(CType
*type
)
4500 return type_size(pointed_type(type
), &align
);
4504 void check_pointer_types(SValue
*p1
, SValue
*p2
)
4506 char buf1
[256], buf2
[256];
4510 if (!is_compatible_types(t1
, t2
)) {
4511 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
4512 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
4513 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
4518 /* generic gen_op: handles types problems */
4521 int u
, t1
, t2
, bt1
, bt2
, t
;
4524 t1
= vtop
[-1].type
.t
;
4525 t2
= vtop
[0].type
.t
;
4526 bt1
= t1
& VT_BTYPE
;
4527 bt2
= t2
& VT_BTYPE
;
4529 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
4530 /* at least one operand is a pointer */
4531 /* relationnal op: must be both pointers */
4532 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4533 // check_pointer_types(vtop, vtop - 1);
4534 /* pointers are handled are unsigned */
4535 t
= VT_INT
| VT_UNSIGNED
;
4538 /* if both pointers, then it must be the '-' op */
4539 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
4541 error("cannot use pointers here");
4542 // check_pointer_types(vtop - 1, vtop);
4543 /* XXX: check that types are compatible */
4544 u
= pointed_size(&vtop
[-1].type
);
4546 /* set to integer type */
4547 vtop
->type
.t
= VT_INT
;
4551 /* exactly one pointer : must be '+' or '-'. */
4552 if (op
!= '-' && op
!= '+')
4553 error("cannot use pointers here");
4554 /* Put pointer as first operand */
4555 if (bt2
== VT_PTR
) {
4559 type1
= vtop
[-1].type
;
4560 /* XXX: cast to int ? (long long case) */
4561 vpushi(pointed_size(&vtop
[-1].type
));
4563 #ifdef CONFIG_TCC_BCHECK
4564 /* if evaluating constant expression, no code should be
4565 generated, so no bound check */
4566 if (do_bounds_check
&& !const_wanted
) {
4567 /* if bounded pointers, we generate a special code to
4574 gen_bounded_ptr_add();
4580 /* put again type if gen_opic() swaped operands */
4583 } else if (is_float(bt1
) || is_float(bt2
)) {
4584 /* compute bigger type and do implicit casts */
4585 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
4587 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
4592 /* floats can only be used for a few operations */
4593 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
4594 (op
< TOK_ULT
|| op
> TOK_GT
))
4595 error("invalid operands for binary operation");
4597 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
4598 /* cast to biggest op */
4600 /* convert to unsigned if it does not fit in a long long */
4601 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4602 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4606 /* integer operations */
4608 /* convert to unsigned if it does not fit in an integer */
4609 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4610 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4613 /* XXX: currently, some unsigned operations are explicit, so
4614 we modify them here */
4615 if (t
& VT_UNSIGNED
) {
4622 else if (op
== TOK_LT
)
4624 else if (op
== TOK_GT
)
4626 else if (op
== TOK_LE
)
4628 else if (op
== TOK_GE
)
4635 /* special case for shifts and long long: we keep the shift as
4637 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
4642 else if ((t
& VT_BTYPE
) == VT_LLONG
)
4646 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4647 /* relationnal op: the result is an int */
4648 vtop
->type
.t
= VT_INT
;
4655 /* generic itof for unsigned long long case */
4656 void gen_cvt_itof1(int t
)
4660 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
4661 (VT_LLONG
| VT_UNSIGNED
)) {
4663 gfunc_start(&gf
, FUNC_CDECL
);
4666 vpush_global_sym(&func_old_type
, TOK___ulltof
);
4667 else if (t
== VT_DOUBLE
)
4668 vpush_global_sym(&func_old_type
, TOK___ulltod
);
4670 vpush_global_sym(&func_old_type
, TOK___ulltold
);
4679 /* generic ftoi for unsigned long long case */
4680 void gen_cvt_ftoi1(int t
)
4685 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
4686 /* not handled natively */
4687 gfunc_start(&gf
, FUNC_CDECL
);
4688 st
= vtop
->type
.t
& VT_BTYPE
;
4691 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
4692 else if (st
== VT_DOUBLE
)
4693 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
4695 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
4699 vtop
->r2
= REG_LRET
;
4705 /* force char or short cast */
4706 void force_charshort_cast(int t
)
4710 /* XXX: add optimization if lvalue : just change type and offset */
4715 if (t
& VT_UNSIGNED
) {
4716 vpushi((1 << bits
) - 1);
4727 /* cast 'vtop' to 'type' */
4728 static void gen_cast(CType
*type
)
4730 int sbt
, dbt
, sf
, df
, c
;
4732 /* special delayed cast for char/short */
4733 /* XXX: in some cases (multiple cascaded casts), it may still
4735 if (vtop
->r
& VT_MUSTCAST
) {
4736 vtop
->r
&= ~VT_MUSTCAST
;
4737 force_charshort_cast(vtop
->type
.t
);
4740 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
4741 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
4743 if (sbt
!= dbt
&& !nocode_wanted
) {
4746 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4748 /* convert from fp to fp */
4750 /* constant case: we can do it now */
4751 /* XXX: in ISOC, cannot do it if error in convert */
4752 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
4753 vtop
->c
.f
= (float)vtop
->c
.d
;
4754 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
4755 vtop
->c
.f
= (float)vtop
->c
.ld
;
4756 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
4757 vtop
->c
.d
= (double)vtop
->c
.f
;
4758 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
4759 vtop
->c
.d
= (double)vtop
->c
.ld
;
4760 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
4761 vtop
->c
.ld
= (long double)vtop
->c
.f
;
4762 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
4763 vtop
->c
.ld
= (long double)vtop
->c
.d
;
4765 /* non constant case: generate code */
4769 /* convert int to fp */
4772 case VT_LLONG
| VT_UNSIGNED
:
4774 /* XXX: add const cases for long long */
4776 case VT_INT
| VT_UNSIGNED
:
4778 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
4779 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
4780 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
4785 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
4786 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
4787 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
4796 /* convert fp to int */
4797 /* we handle char/short/etc... with generic code */
4798 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
4799 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
4804 case VT_LLONG
| VT_UNSIGNED
:
4806 /* XXX: add const cases for long long */
4808 case VT_INT
| VT_UNSIGNED
:
4810 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4811 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4812 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4818 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4819 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4820 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4828 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
4829 /* additionnal cast for char/short/bool... */
4833 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
4834 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
4835 /* scalar to long long */
4837 if (sbt
== (VT_INT
| VT_UNSIGNED
))
4838 vtop
->c
.ll
= vtop
->c
.ui
;
4840 vtop
->c
.ll
= vtop
->c
.i
;
4842 /* machine independant conversion */
4844 /* generate high word */
4845 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
4853 /* patch second register */
4854 vtop
[-1].r2
= vtop
->r
;
4858 } else if (dbt
== VT_BOOL
) {
4859 /* scalar to bool */
4862 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
4863 (dbt
& VT_BTYPE
) == VT_SHORT
) {
4864 force_charshort_cast(dbt
);
4865 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
4867 if (sbt
== VT_LLONG
) {
4868 /* from long long: just take low order word */
4872 /* if lvalue and single word type, nothing to do because
4873 the lvalue already contains the real type size (see
4874 VT_LVAL_xxx constants) */
4880 /* return type size. Put alignment at 'a' */
4881 int type_size(CType
*type
, int *a
)
4886 bt
= type
->t
& VT_BTYPE
;
4887 if (bt
== VT_STRUCT
) {
4890 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
4892 } else if (bt
== VT_PTR
) {
4893 if (type
->t
& VT_ARRAY
) {
4895 return type_size(&s
->type
, a
) * s
->c
;
4900 } else if (bt
== VT_LDOUBLE
) {
4902 return LDOUBLE_SIZE
;
4903 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
4906 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
4909 } else if (bt
== VT_SHORT
) {
4913 /* char, void, function, _Bool */
4919 /* return the pointed type of t */
4920 static inline CType
*pointed_type(CType
*type
)
4922 return &type
->ref
->type
;
4925 /* modify type so that its it is a pointer to type. */
4926 static void mk_pointer(CType
*type
)
4929 s
= sym_push(SYM_FIELD
, type
, 0, -1);
4930 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
4934 static int is_compatible_types(CType
*type1
, CType
*type2
)
4937 int bt1
, bt2
, t1
, t2
;
4939 t1
= type1
->t
& VT_TYPE
;
4940 t2
= type2
->t
& VT_TYPE
;
4941 bt1
= t1
& VT_BTYPE
;
4942 bt2
= t2
& VT_BTYPE
;
4943 if (bt1
== VT_PTR
) {
4944 type1
= pointed_type(type1
);
4945 /* if function, then convert implicitely to function pointer */
4946 if (bt2
!= VT_FUNC
) {
4949 type2
= pointed_type(type2
);
4951 /* void matches everything */
4952 /* XXX: not fully compliant */
4953 if ((type1
->t
& VT_TYPE
) == VT_VOID
|| (type2
->t
& VT_TYPE
) == VT_VOID
)
4955 return is_compatible_types(type1
, type2
);
4956 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4958 } else if (bt1
== VT_FUNC
) {
4963 if (!is_compatible_types(&s1
->type
, &s2
->type
))
4965 /* XXX: not complete */
4966 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
4970 while (s1
!= NULL
) {
4973 if (!is_compatible_types(&s1
->type
, &s2
->type
))
4982 /* XXX: not complete */
4987 /* print a type. If 'varstr' is not NULL, then the variable is also
4988 printed in the type */
4990 /* XXX: add array and function pointers */
4991 void type_to_str(char *buf
, int buf_size
,
4992 CType
*type
, const char *varstr
)
4999 t
= type
->t
& VT_TYPE
;
5002 if (t
& VT_UNSIGNED
)
5003 pstrcat(buf
, buf_size
, "unsigned ");
5033 tstr
= "long double";
5035 pstrcat(buf
, buf_size
, tstr
);
5039 if (bt
== VT_STRUCT
)
5043 pstrcat(buf
, buf_size
, tstr
);
5045 if (v
>= SYM_FIRST_ANOM
)
5046 pstrcat(buf
, buf_size
, "<anonymous>");
5048 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
5052 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
5053 pstrcat(buf
, buf_size
, "(");
5055 while (sa
!= NULL
) {
5056 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
5057 pstrcat(buf
, buf_size
, buf1
);
5060 pstrcat(buf
, buf_size
, ", ");
5062 pstrcat(buf
, buf_size
, ")");
5066 pstrcpy(buf1
, sizeof(buf1
), "*");
5068 pstrcat(buf1
, sizeof(buf1
), varstr
);
5069 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
5073 pstrcat(buf
, buf_size
, " ");
5074 pstrcat(buf
, buf_size
, varstr
);
5079 /* verify type compatibility to store vtop in 'dt' type, and generate
5081 void gen_assign_cast(CType
*dt
)
5084 char buf1
[256], buf2
[256];
5086 st
= &vtop
->type
; /* source type */
5087 if ((dt
->t
& VT_BTYPE
) == VT_PTR
) {
5088 /* special cases for pointers */
5089 /* a function is implicitely a function pointer */
5090 if ((st
->t
& VT_BTYPE
) == VT_FUNC
) {
5091 if (!is_compatible_types(pointed_type(dt
), st
))
5096 /* '0' can also be a pointer */
5097 if ((st
->t
& VT_BTYPE
) == VT_INT
&&
5098 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
5102 if (!is_compatible_types(dt
, st
)) {
5104 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
5105 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
5106 error("cannot cast '%s' to '%s'", buf1
, buf2
);
5112 /* store vtop in lvalue pushed on stack */
5115 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
5118 ft
= vtop
[-1].type
.t
;
5119 sbt
= vtop
->type
.t
& VT_BTYPE
;
5120 dbt
= ft
& VT_BTYPE
;
5121 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
5122 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
5123 /* optimize char/short casts */
5124 delayed_cast
= VT_MUSTCAST
;
5125 vtop
->type
.t
= ft
& VT_TYPE
;
5128 gen_assign_cast(&vtop
[-1].type
);
5131 if (sbt
== VT_STRUCT
) {
5132 /* if structure, only generate pointer */
5133 /* structure assignment : generate memcpy */
5134 /* XXX: optimize if small size */
5135 if (!nocode_wanted
) {
5137 gfunc_start(&gf
, FUNC_CDECL
);
5139 size
= type_size(&vtop
->type
, &align
);
5143 vtop
->type
.t
= VT_INT
;
5148 vtop
->type
.t
= VT_INT
;
5153 vpush_global_sym(&func_old_type
, TOK_memcpy
);
5159 /* leave source on stack */
5160 } else if (ft
& VT_BITFIELD
) {
5161 /* bitfield store handling */
5162 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
5163 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
5164 /* remove bit field info to avoid loops */
5165 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
5167 /* duplicate destination */
5169 vtop
[-1] = vtop
[-2];
5171 /* mask and shift source */
5172 vpushi((1 << bit_size
) - 1);
5176 /* load destination, mask and or with source */
5178 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
5184 #ifdef CONFIG_TCC_BCHECK
5185 /* bound check case */
5186 if (vtop
[-1].r
& VT_MUSTBOUND
) {
5192 if (!nocode_wanted
) {
5196 r
= gv(rc
); /* generate value */
5197 /* if lvalue was saved on stack, must read it */
5198 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
5200 t
= get_reg(RC_INT
);
5202 sv
.r
= VT_LOCAL
| VT_LVAL
;
5203 sv
.c
.ul
= vtop
[-1].c
.ul
;
5205 vtop
[-1].r
= t
| VT_LVAL
;
5208 /* two word case handling : store second register at word + 4 */
5209 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
5211 /* convert to int to increment easily */
5212 vtop
->type
.t
= VT_INT
;
5218 /* XXX: it works because r2 is spilled last ! */
5219 store(vtop
->r2
, vtop
- 1);
5223 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5224 vtop
->r
|= delayed_cast
;
5228 /* post defines POST/PRE add. c is the token ++ or -- */
5229 void inc(int post
, int c
)
5232 vdup(); /* save lvalue */
5234 gv_dup(); /* duplicate value */
5239 vpushi(c
- TOK_MID
);
5241 vstore(); /* store value */
5243 vpop(); /* if post op, return saved value */
5246 /* Parse GNUC __attribute__ extension. Currently, the following
5247 extensions are recognized:
5248 - aligned(n) : set data/function alignment.
5249 - section(x) : generate data/code in this section.
5250 - unused : currently ignored, but may be used someday.
5252 void parse_attribute(AttributeDef
*ad
)
5259 while (tok
!= ')') {
5260 if (tok
< TOK_IDENT
)
5261 expect("attribute name");
5266 case TOK___SECTION__
:
5269 expect("section name");
5270 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
5275 case TOK___ALIGNED__
:
5278 if (n
<= 0 || (n
& (n
- 1)) != 0)
5279 error("alignment must be a positive power of two");
5284 case TOK___UNUSED__
:
5285 /* currently, no need to handle it because tcc does not
5286 track unused objects */
5289 case TOK___NORETURN__
:
5290 /* currently, no need to handle it because tcc does not
5291 track unused objects */
5296 ad
->func_call
= FUNC_CDECL
;
5300 case TOK___STDCALL__
:
5301 ad
->func_call
= FUNC_STDCALL
;
5304 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
5305 /* skip parameters */
5306 /* XXX: skip parenthesis too */
5309 while (tok
!= ')' && tok
!= -1)
5323 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5324 static void struct_decl(CType
*type
, int u
)
5326 int a
, v
, size
, align
, maxalign
, c
, offset
;
5327 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
5332 a
= tok
; /* save decl type */
5337 /* struct already defined ? return it */
5338 /* XXX: check consistency */
5342 error("invalid type");
5349 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, 0);
5350 /* put struct/union/enum name in type */
5358 error("struct/union/enum already defined");
5359 /* cannot be empty */
5366 if (a
== TOK_ENUM
) {
5373 /* enum symbols have static storage */
5374 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
5375 ss
->type
.t
|= VT_STATIC
;
5380 parse_btype(&btype
, &ad
);
5386 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
);
5387 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
5388 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
5389 error("invalid type for '%s'",
5390 get_tok_str(v
, NULL
));
5394 bit_size
= expr_const();
5395 /* XXX: handle v = 0 case for messages */
5397 error("negative width in bit-field '%s'",
5398 get_tok_str(v
, NULL
));
5399 if (v
&& bit_size
== 0)
5400 error("zero width for bit-field '%s'",
5401 get_tok_str(v
, NULL
));
5403 size
= type_size(&type1
, &align
);
5405 if (bit_size
>= 0) {
5406 bt
= type1
.t
& VT_BTYPE
;
5410 error("bitfields must have scalar type");
5412 if (bit_size
> bsize
) {
5413 error("width of '%s' exceeds its type",
5414 get_tok_str(v
, NULL
));
5415 } else if (bit_size
== bsize
) {
5416 /* no need for bit fields */
5418 } else if (bit_size
== 0) {
5419 /* XXX: what to do if only padding in a
5421 /* zero size: means to pad */
5425 /* we do not have enough room ? */
5426 if ((bit_pos
+ bit_size
) > bsize
)
5429 /* XXX: handle LSB first */
5430 type1
.t
|= VT_BITFIELD
|
5431 (bit_pos
<< VT_STRUCT_SHIFT
) |
5432 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
5433 bit_pos
+= bit_size
;
5439 /* add new memory data only if starting
5441 if (lbit_pos
== 0) {
5442 if (a
== TOK_STRUCT
) {
5443 c
= (c
+ align
- 1) & -align
;
5451 if (align
> maxalign
)
5455 printf("add field %s offset=%d",
5456 get_tok_str(v
, NULL
), offset
);
5457 if (type1
.t
& VT_BITFIELD
) {
5458 printf(" pos=%d size=%d",
5459 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
5460 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
5464 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
5468 if (tok
== ';' || tok
== -1)
5478 /* size for struct/union, dummy for enum */
5479 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
5483 /* return 0 if no type declaration. otherwise, return the basic type
5486 static int parse_btype(CType
*type
, AttributeDef
*ad
)
5488 int t
, u
, type_found
;
5492 memset(ad
, 0, sizeof(AttributeDef
));
5503 if ((t
& VT_BTYPE
) != 0)
5504 error("too many basic types");
5518 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
5519 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5520 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
5521 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
5535 if ((t
& VT_BTYPE
) == VT_LONG
) {
5536 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5543 struct_decl(&type1
, VT_ENUM
);
5546 type
->ref
= type1
.ref
;
5550 struct_decl(&type1
, VT_STRUCT
);
5553 /* type modifiers */
5558 case TOK___SIGNED__
:
5561 case TOK___INLINE__
:
5583 /* GNUC attribute */
5584 case TOK___ATTRIBUTE__
:
5585 parse_attribute(ad
);
5590 parse_expr_type(&type1
);
5594 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
5596 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
5597 type
->ref
= s
->type
.ref
;
5604 /* long is never used as type */
5605 if ((t
& VT_BTYPE
) == VT_LONG
)
5606 t
= (t
& ~VT_BTYPE
) | VT_INT
;
5611 static void post_type(CType
*type
, AttributeDef
*ad
)
5614 Sym
**plast
, *s
, *first
;
5619 /* function declaration */
5624 while (tok
!= ')') {
5625 /* read param name and compute offset */
5626 if (l
!= FUNC_OLD
) {
5627 if (!parse_btype(&pt
, &ad1
)) {
5629 error("invalid type");
5636 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5638 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
5639 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
5640 error("parameter declared as void");
5647 /* array must be transformed to pointer according to ANSI C */
5649 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
5654 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5661 /* if no parameters, then old type prototype */
5665 t1
= type
->t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5666 type
->t
&= ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5667 post_type(type
, ad
);
5668 /* we push a anonymous symbol which will contain the function prototype */
5669 s
= sym_push(SYM_FIELD
, type
, ad
->func_call
, l
);
5671 type
->t
= t1
| VT_FUNC
;
5673 } else if (tok
== '[') {
5674 /* array definition */
5680 error("invalid array size");
5683 /* parse next post type */
5684 t1
= type
->t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5685 type
->t
&= ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5686 post_type(type
, ad
);
5688 /* we push a anonymous symbol which will contain the array
5690 s
= sym_push(SYM_FIELD
, type
, 0, n
);
5691 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
5696 /* Parse a type declaration (except basic type), and return the type
5697 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5698 expected. 'type' should contain the basic type. 'ad' is the
5699 attribute definition of the basic type. It can be modified by
5702 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
5705 CType type1
, *type2
;
5707 while (tok
== '*') {
5709 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
5714 /* recursive type */
5715 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5716 type1
.t
= 0; /* XXX: same as int */
5719 /* XXX: this is not correct to modify 'ad' at this point, but
5720 the syntax is not clear */
5721 if (tok
== TOK___ATTRIBUTE__
)
5722 parse_attribute(ad
);
5723 type_decl(&type1
, ad
, v
, td
);
5726 /* type identifier */
5727 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
5731 if (!(td
& TYPE_ABSTRACT
))
5732 expect("identifier");
5736 post_type(type
, ad
);
5737 if (tok
== TOK___ATTRIBUTE__
)
5738 parse_attribute(ad
);
5741 /* append type at the end of type1 */
5754 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5755 static int lvalue_type(int t
)
5762 else if (bt
== VT_SHORT
)
5766 if (t
& VT_UNSIGNED
)
5767 r
|= VT_LVAL_UNSIGNED
;
5771 /* indirection with full error checking and bound check */
5772 static void indir(void)
5774 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
5776 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
5778 vtop
->type
= *pointed_type(&vtop
->type
);
5779 /* an array is never an lvalue */
5780 if (!(vtop
->type
.t
& VT_ARRAY
)) {
5781 vtop
->r
|= lvalue_type(vtop
->type
.t
);
5782 /* if bound checking, the referenced pointer must be checked */
5783 if (do_bounds_check
)
5784 vtop
->r
|= VT_MUSTBOUND
;
5788 /* pass a parameter to a function and do type checking and casting */
5789 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
5794 func_type
= func
->c
;
5795 if (func_type
== FUNC_OLD
||
5796 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5797 /* default casting : only need to convert float to double */
5798 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
5802 } else if (arg
== NULL
) {
5803 error("too many arguments to function");
5805 gen_assign_cast(&arg
->type
);
5807 if (!nocode_wanted
) {
5814 /* parse an expression of the form '(type)' or '(expr)' and return its
5816 static void parse_expr_type(CType
*type
)
5822 if (parse_btype(type
, &ad
)) {
5823 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
5830 static void vpush_tokc(int t
)
5834 vsetc(&type
, VT_CONST
, &tokc
);
5837 static void unary(void)
5839 int n
, t
, align
, size
, r
;
5845 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
5848 } else if (tok
== TOK_CUINT
) {
5849 vpush_tokc(VT_INT
| VT_UNSIGNED
);
5851 } else if (tok
== TOK_CLLONG
) {
5852 vpush_tokc(VT_LLONG
);
5854 } else if (tok
== TOK_CULLONG
) {
5855 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
5857 } else if (tok
== TOK_CFLOAT
) {
5858 vpush_tokc(VT_FLOAT
);
5860 } else if (tok
== TOK_CDOUBLE
) {
5861 vpush_tokc(VT_DOUBLE
);
5863 } else if (tok
== TOK_CLDOUBLE
) {
5864 vpush_tokc(VT_LDOUBLE
);
5866 } else if (tok
== TOK___FUNC__
|| (tok
== TOK___FUNCTION__
&& gnu_ext
)) {
5869 /* special function name identifier */
5871 len
= strlen(funcname
) + 1;
5872 /* generate char[len] type */
5877 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
5878 ptr
= section_ptr_add(data_section
, len
);
5879 memcpy(ptr
, funcname
, len
);
5881 } else if (tok
== TOK_LSTR
) {
5884 } else if (tok
== TOK_STR
) {
5885 /* string parsing */
5891 memset(&ad
, 0, sizeof(AttributeDef
));
5892 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
5898 if (parse_btype(&type
, &ad
)) {
5899 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
5901 /* check ISOC99 compound literal */
5903 /* data is allocated locally by default */
5908 /* all except arrays are lvalues */
5909 if (!(type
.t
& VT_ARRAY
))
5910 r
|= lvalue_type(type
.t
);
5911 memset(&ad
, 0, sizeof(AttributeDef
));
5912 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
5921 } else if (t
== '*') {
5924 } else if (t
== '&') {
5926 /* functions names must be treated as function pointers,
5927 except for unary '&' and sizeof. Since we consider that
5928 functions are not lvalues, we only have to handle it
5929 there and in function calls. */
5930 /* arrays can also be used although they are not lvalues */
5931 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
5932 !(vtop
->type
.t
& VT_ARRAY
))
5934 mk_pointer(&vtop
->type
);
5936 } else if (t
== '!') {
5938 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
5939 vtop
->c
.i
= !vtop
->c
.i
;
5940 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
5941 vtop
->c
.i
= vtop
->c
.i
^ 1;
5943 vseti(VT_JMP
, gtst(1, 0));
5944 } else if (t
== '~') {
5948 } else if (t
== '+') {
5949 /* in order to force cast, we add zero */
5951 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
5952 error("pointer not accepted for unary plus");
5955 } else if (t
== TOK_SIZEOF
|| t
== TOK_ALIGNOF
) {
5957 parse_expr_type(&type
);
5961 size
= type_size(&type
, &align
);
5962 if (t
== TOK_SIZEOF
)
5966 } else if (t
== TOK_INC
|| t
== TOK_DEC
) {
5969 } else if (t
== '-') {
5973 } else if (t
== TOK_LAND
&& gnu_ext
) {
5974 /* allow to take the address of a label */
5975 if (tok
< TOK_UIDENT
)
5976 expect("label identifier");
5977 s
= label_find(tok
);
5979 s
= label_push(tok
, LABEL_FORWARD
);
5982 s
->type
.t
= VT_VOID
;
5983 mk_pointer(&s
->type
);
5984 s
->type
.t
|= VT_STATIC
;
5986 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
5991 expect("identifier");
5995 error("'%s' undeclared", get_tok_str(t
, NULL
));
5996 /* for simple function calls, we tolerate undeclared
5997 external reference to int() function */
5998 s
= external_global_sym(t
, &func_old_type
, 0);
6000 vset(&s
->type
, s
->r
, s
->c
);
6001 /* if forward reference, we must point to s */
6002 if (vtop
->r
& VT_SYM
) {
6009 /* post operations */
6011 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
6014 } else if (tok
== '.' || tok
== TOK_ARROW
) {
6016 if (tok
== TOK_ARROW
)
6021 /* expect pointer on structure */
6022 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
6023 expect("struct or union");
6027 while ((s
= s
->next
) != NULL
) {
6032 error("field not found");
6033 /* add field offset to pointer */
6034 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
6037 /* change type to field type, and set to lvalue */
6038 vtop
->type
= s
->type
;
6039 /* an array is never an lvalue */
6040 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6041 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6042 /* if bound checking, the referenced pointer must be checked */
6043 if (do_bounds_check
)
6044 vtop
->r
|= VT_MUSTBOUND
;
6047 } else if (tok
== '[') {
6053 } else if (tok
== '(') {
6058 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
6059 /* pointer test (no array accepted) */
6060 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
6061 vtop
->type
= *pointed_type(&vtop
->type
);
6062 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
6066 expect("function pointer");
6069 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
6071 /* get return type */
6073 if (!nocode_wanted
) {
6074 save_regs(0); /* save used temporary registers */
6075 gfunc_start(&gf
, s
->r
);
6078 sa
= s
->next
; /* first parameter */
6079 #ifdef INVERT_FUNC_PARAMS
6083 ParseState saved_parse_state
;
6086 /* read each argument and store it on a stack */
6092 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
6096 else if (tok
== ')')
6098 tok_str_add_tok(&str
);
6101 tok_str_add(&str
, -1); /* end of file added */
6102 tok_str_add(&str
, 0);
6103 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
6104 s1
->next
= sa
; /* add reference to argument */
6113 /* now generate code in reverse order by reading the stack */
6114 save_parse_state(&saved_parse_state
);
6116 macro_ptr
= (int *)args
->c
;
6120 expect("',' or ')'");
6121 gfunc_param_typed(&gf
, s
, args
->next
);
6123 tok_str_free((int *)args
->c
);
6127 restore_parse_state(&saved_parse_state
);
6130 /* compute first implicit argument if a structure is returned */
6131 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
6132 /* get some space for the returned structure */
6133 size
= type_size(&s
->type
, &align
);
6134 loc
= (loc
- size
) & -align
;
6136 ret
.r
= VT_LOCAL
| VT_LVAL
;
6137 /* pass it as 'int' to avoid structure arg passing
6139 vseti(VT_LOCAL
, loc
);
6148 /* return in register */
6149 if (is_float(ret
.type
.t
)) {
6152 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
6158 #ifndef INVERT_FUNC_PARAMS
6162 gfunc_param_typed(&gf
, s
, sa
);
6172 error("too few arguments to function");
6179 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
6187 static void uneq(void)
6193 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
6194 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
6195 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
6210 static void sum(int l
)
6218 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
6219 (l
== 1 && (tok
== '+' || tok
== '-')) ||
6220 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
6221 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
6222 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
6223 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
6224 (l
== 5 && tok
== '&') ||
6225 (l
== 6 && tok
== '^') ||
6226 (l
== 7 && tok
== '|') ||
6227 (l
== 8 && tok
== TOK_LAND
) ||
6228 (l
== 9 && tok
== TOK_LOR
)) {
6237 /* only used if non constant */
6238 static void eand(void)
6245 if (tok
!= TOK_LAND
) {
6258 static void eor(void)
6265 if (tok
!= TOK_LOR
) {
6278 /* XXX: better constant handling */
6279 static void expr_eq(void)
6281 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
6283 CType type
, type1
, type2
;
6304 save_regs(1); /* we need to save all registers here except
6305 at the top because it is a branch point */
6309 sv
= *vtop
; /* save value to handle it later */
6310 vtop
--; /* no vpop so that FP stack is not flushed */
6319 bt1
= t1
& VT_BTYPE
;
6321 bt2
= t2
& VT_BTYPE
;
6322 /* cast operands to correct type according to ISOC rules */
6323 if (is_float(bt1
) || is_float(bt2
)) {
6324 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
6325 type
.t
= VT_LDOUBLE
;
6326 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
6331 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
6332 /* cast to biggest op */
6334 /* convert to unsigned if it does not fit in a long long */
6335 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
6336 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
6337 type
.t
|= VT_UNSIGNED
;
6338 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
6339 /* XXX: test pointer compatibility */
6341 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
6342 /* XXX: test structure compatibility */
6344 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
6345 /* NOTE: as an extension, we accept void on only one side */
6348 /* integer operations */
6350 /* convert to unsigned if it does not fit in an integer */
6351 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
6352 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
6353 type
.t
|= VT_UNSIGNED
;
6356 /* now we convert second operand */
6359 if (is_float(type
.t
)) {
6361 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
6362 /* for long longs, we use fixed registers to avoid having
6363 to handle a complicated move */
6367 /* this is horrible, but we must also convert first
6371 /* put again first value and cast it */
6382 static void gexpr(void)
6393 /* parse an expression and return its type without any side effect. */
6394 static void expr_type(CType
*type
)
6406 /* parse a unary expression and return its type without any side
6408 static void unary_type(CType
*type
)
6420 /* parse a constant expression and return value in vtop. */
6421 static void expr_const1(void)
6430 /* parse an integer constant and return its value. */
6431 static int expr_const(void)
6435 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
6436 expect("constant expression");
6442 /* return the label token if current token is a label, otherwise
6444 static int is_label(void)
6449 /* fast test first */
6450 if (tok
< TOK_UIDENT
)
6452 /* no need to save tokc since we expect an identifier */
6460 /* XXX: may not work in all cases (macros ?) */
6469 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
6474 /* generate line number info */
6476 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
6477 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
6479 last_line_num
= file
->line_num
;
6482 if (tok
== TOK_IF
) {
6489 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6491 if (c
== TOK_ELSE
) {
6495 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6496 gsym(d
); /* patch else jmp */
6499 } else if (tok
== TOK_WHILE
) {
6507 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6511 } else if (tok
== '{') {
6515 while (tok
!= '}') {
6518 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6520 /* pop locally defined symbols */
6521 sym_pop(&local_stack
, s
);
6523 } else if (tok
== TOK_RETURN
) {
6527 gen_assign_cast(&func_vt
);
6528 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
6530 /* if returning structure, must copy it to implicit
6531 first pointer arg location */
6534 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
6537 /* copy structure value to pointer */
6539 } else if (is_float(func_vt
.t
)) {
6544 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6547 rsym
= gjmp(rsym
); /* jmp */
6548 } else if (tok
== TOK_BREAK
) {
6551 error("cannot break");
6552 *bsym
= gjmp(*bsym
);
6555 } else if (tok
== TOK_CONTINUE
) {
6558 error("cannot continue");
6559 *csym
= gjmp(*csym
);
6562 } else if (tok
== TOK_FOR
) {
6589 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6594 if (tok
== TOK_DO
) {
6599 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6610 if (tok
== TOK_SWITCH
) {
6614 /* XXX: other types than integer */
6615 case_reg
= gv(RC_INT
);
6619 b
= gjmp(0); /* jump to first case */
6621 block(&a
, csym
, &b
, &c
, case_reg
);
6622 /* if no default, jmp after switch */
6630 if (tok
== TOK_CASE
) {
6637 if (gnu_ext
&& tok
== TOK_DOTS
) {
6641 warning("empty case range");
6643 /* since a case is like a label, we must skip it with a jmp */
6650 *case_sym
= gtst(1, 0);
6653 *case_sym
= gtst(1, 0);
6657 *case_sym
= gtst(1, *case_sym
);
6661 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6663 if (tok
== TOK_DEFAULT
) {
6669 error("too many 'default'");
6671 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6673 if (tok
== TOK_GOTO
) {
6675 if (tok
== '*' && gnu_ext
) {
6679 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
6682 } else if (tok
>= TOK_UIDENT
) {
6683 s
= label_find(tok
);
6684 /* put forward definition if needed */
6686 s
= label_push(tok
, LABEL_FORWARD
);
6688 /* label already defined */
6689 if (s
->r
& LABEL_FORWARD
)
6690 s
->next
= (void *)gjmp((long)s
->next
);
6692 gjmp_addr((long)s
->next
);
6695 expect("label identifier");
6704 if (!(s
->r
& LABEL_FORWARD
))
6705 error("multiple defined label");
6706 gsym((long)s
->next
);
6708 s
= label_push(b
, 0);
6710 s
->next
= (void *)ind
;
6712 /* we accept this, but it is a mistake */
6714 warning("deprecated use of label at end of compound statement");
6716 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6718 /* expression case */
6728 /* t is the array or struct type. c is the array or struct
6729 address. cur_index/cur_field is the pointer to the current
6730 value. 'size_only' is true if only size info is needed (only used
6732 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
6733 int *cur_index
, Sym
**cur_field
,
6737 int notfirst
, index
, align
, l
;
6741 if (gnu_ext
&& (l
= is_label()) != 0)
6744 while (tok
== '[' || tok
== '.') {
6746 if (!(type
->t
& VT_ARRAY
))
6747 expect("array type");
6750 index
= expr_const();
6751 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
6752 expect("invalid index");
6756 type
= pointed_type(type
);
6757 c
+= index
* type_size(type
, &align
);
6763 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
6764 expect("struct/union type");
6777 /* XXX: suppress this mess by using explicit storage field */
6779 type1
.t
|= (type
->t
& ~VT_TYPE
);
6793 if (type
->t
& VT_ARRAY
) {
6795 type
= pointed_type(type
);
6796 c
+= index
* type_size(type
, &align
);
6800 error("too many field init");
6801 /* XXX: suppress this mess by using explicit storage field */
6803 type1
.t
|= (type
->t
& ~VT_TYPE
);
6808 decl_initializer(type
, sec
, c
, 0, size_only
);
6812 #define EXPR_CONST 1
6815 /* store a value or an expression directly in global data or in local array */
6816 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
6817 int v
, int expr_type
)
6819 int saved_global_expr
, bt
;
6827 /* compound literals must be allocated globally in this case */
6828 saved_global_expr
= global_expr
;
6831 global_expr
= saved_global_expr
;
6832 /* NOTE: symbols are accepted */
6833 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
6834 error("initializer element is not constant");
6842 /* XXX: not portable */
6843 /* XXX: generate error if incorrect relocation */
6844 gen_assign_cast(type
);
6845 bt
= type
->t
& VT_BTYPE
;
6846 ptr
= sec
->data
+ c
;
6847 if ((vtop
->r
& VT_SYM
) &&
6853 error("initializer element is not computable at load time");
6856 *(char *)ptr
= vtop
->c
.i
;
6859 *(short *)ptr
= vtop
->c
.i
;
6862 *(double *)ptr
= vtop
->c
.d
;
6865 *(long double *)ptr
= vtop
->c
.ld
;
6868 *(long long *)ptr
= vtop
->c
.ll
;
6871 if (vtop
->r
& VT_SYM
) {
6872 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
6874 *(int *)ptr
= vtop
->c
.i
;
6879 vset(type
, VT_LOCAL
, c
);
6886 /* put zeros for variable based init */
6887 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
6892 /* nothing to do because globals are already set to zero */
6894 gfunc_start(&gf
, FUNC_CDECL
);
6901 vpush_global_sym(&func_old_type
, TOK_memset
);
6906 /* 't' contains the type and storage info. 'c' is the offset of the
6907 object in section 'sec'. If 'sec' is NULL, it means stack based
6908 allocation. 'first' is true if array '{' must be read (multi
6909 dimension implicit array init handling). 'size_only' is true if
6910 size only evaluation is wanted (only for arrays). */
6911 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
6912 int first
, int size_only
)
6914 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
6915 int size1
, align1
, expr_type
;
6919 if (type
->t
& VT_ARRAY
) {
6923 t1
= pointed_type(type
);
6924 size1
= type_size(t1
, &align1
);
6927 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
6933 /* only parse strings here if correct type (otherwise: handle
6934 them as ((w)char *) expressions */
6935 if ((tok
== TOK_LSTR
&&
6936 (t1
->t
& VT_BTYPE
) == VT_INT
) ||
6938 (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
6939 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6944 /* compute maximum number of chars wanted */
6946 cstr_len
= cstr
->size
;
6948 cstr_len
= cstr
->size
/ sizeof(int);
6951 if (n
>= 0 && nb
> (n
- array_length
))
6952 nb
= n
- array_length
;
6955 warning("initializer-string for array is too long");
6956 /* in order to go faster for common case (char
6957 string in global variable, we handle it
6959 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
6960 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
6964 ch
= ((unsigned char *)cstr
->data
)[i
];
6966 ch
= ((int *)cstr
->data
)[i
];
6967 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
6975 /* only add trailing zero if enough storage (no
6976 warning in this case since it is standard) */
6977 if (n
< 0 || array_length
< n
) {
6979 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
6985 while (tok
!= '}') {
6986 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
6987 if (n
>= 0 && index
>= n
)
6988 error("index too large");
6989 /* must put zero in holes (note that doing it that way
6990 ensures that it even works with designators) */
6991 if (!size_only
&& array_length
< index
) {
6992 init_putz(t1
, sec
, c
+ array_length
* size1
,
6993 (index
- array_length
) * size1
);
6996 if (index
> array_length
)
6997 array_length
= index
;
6998 /* special test for multi dimensional arrays (may not
6999 be strictly correct if designators are used at the
7001 if (index
>= n
&& no_oblock
)
7010 /* put zeros at the end */
7011 if (!size_only
&& n
>= 0 && array_length
< n
) {
7012 init_putz(t1
, sec
, c
+ array_length
* size1
,
7013 (n
- array_length
) * size1
);
7015 /* patch type size if needed */
7017 s
->c
= array_length
;
7018 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
7019 /* XXX: union needs only one init */
7026 while (tok
!= '}') {
7027 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
7028 /* fill with zero between fields */
7030 if (!size_only
&& array_length
< index
) {
7031 init_putz(type
, sec
, c
+ array_length
,
7032 index
- array_length
);
7034 index
= index
+ type_size(&f
->type
, &align1
);
7035 if (index
> array_length
)
7036 array_length
= index
;
7042 /* put zeros at the end */
7043 if (!size_only
&& array_length
< n
) {
7044 init_putz(type
, sec
, c
+ array_length
,
7048 } else if (tok
== '{') {
7050 decl_initializer(type
, sec
, c
, first
, size_only
);
7052 } else if (size_only
) {
7053 /* just skip expression */
7055 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
7059 else if (tok
== ')')
7064 /* currently, we always use constant expression for globals
7065 (may change for scripting case) */
7066 expr_type
= EXPR_CONST
;
7068 expr_type
= EXPR_ANY
;
7069 init_putv(type
, sec
, c
, 0, expr_type
);
7073 /* parse an initializer for type 't' if 'has_init' is non zero, and
7074 allocate space in local or global data space ('r' is either
7075 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7076 variable 'v' of scope 'scope' is declared before initializers are
7077 parsed. If 'v' is zero, then a reference to the new object is put
7078 in the value stack. If 'has_init' is 2, a special parsing is done
7079 to handle string constants. */
7080 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
7081 int has_init
, int v
, int scope
)
7083 int size
, align
, addr
, data_offset
;
7085 ParseState saved_parse_state
;
7086 TokenString init_str
;
7089 size
= type_size(type
, &align
);
7090 /* If unknown size, we must evaluate it before
7091 evaluating initializers because
7092 initializers can generate global data too
7093 (e.g. string pointers or ISOC99 compound
7094 literals). It also simplifies local
7095 initializers handling */
7096 tok_str_new(&init_str
);
7099 error("unknown type size");
7100 /* get all init string */
7101 if (has_init
== 2) {
7102 /* only get strings */
7103 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
7104 tok_str_add_tok(&init_str
);
7109 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
7111 error("unexpected end of file in initializer");
7112 tok_str_add_tok(&init_str
);
7115 else if (tok
== '}') {
7123 tok_str_add(&init_str
, -1);
7124 tok_str_add(&init_str
, 0);
7127 save_parse_state(&saved_parse_state
);
7129 macro_ptr
= init_str
.str
;
7131 decl_initializer(type
, NULL
, 0, 1, 1);
7132 /* prepare second initializer parsing */
7133 macro_ptr
= init_str
.str
;
7136 /* if still unknown size, error */
7137 size
= type_size(type
, &align
);
7139 error("unknown type size");
7141 /* take into account specified alignment if bigger */
7142 if (ad
->aligned
> align
)
7143 align
= ad
->aligned
;
7144 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
7146 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
7148 #ifdef TCC_TARGET_IL
7149 /* XXX: ugly patch to allocate local variables for IL, just
7154 loc
= (loc
- size
) & -align
;
7157 /* handles bounds */
7158 /* XXX: currently, since we do only one pass, we cannot track
7159 '&' operators, so we add only arrays */
7160 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
7161 unsigned long *bounds_ptr
;
7162 /* add padding between regions */
7164 /* then add local bound info */
7165 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
7166 bounds_ptr
[0] = addr
;
7167 bounds_ptr
[1] = size
;
7170 /* compute section */
7178 data_offset
= sec
->data_offset
;
7179 data_offset
= (data_offset
+ align
- 1) & -align
;
7181 /* very important to increment global pointer at this time
7182 because initializers themselves can create new initializers */
7183 data_offset
+= size
;
7184 /* add padding if bound check */
7185 if (do_bounds_check
)
7187 sec
->data_offset
= data_offset
;
7188 /* allocate section space to put the data */
7189 if (sec
->sh_type
!= SHT_NOBITS
&&
7190 data_offset
> sec
->data_allocated
)
7191 section_realloc(sec
, data_offset
);
7195 /* local variable */
7196 sym_push(v
, type
, r
, addr
);
7198 /* push local reference */
7199 vset(type
, r
, addr
);
7205 if (scope
== VT_CONST
) {
7206 /* global scope: see if already defined */
7210 if (!is_compatible_types(&sym
->type
, type
))
7211 error("incompatible types for redefinition of '%s'",
7212 get_tok_str(v
, NULL
));
7213 if (!(sym
->type
.t
& VT_EXTERN
))
7214 error("redefinition of '%s'", get_tok_str(v
, NULL
));
7215 sym
->type
.t
&= ~VT_EXTERN
;
7218 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
7220 put_extern_sym(sym
, sec
, addr
, size
);
7224 /* push global reference */
7225 sym
= get_sym_ref(type
, sec
, addr
, size
);
7227 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
7231 /* handles bounds now because the symbol must be defined
7232 before for the relocation */
7233 if (do_bounds_check
) {
7234 unsigned long *bounds_ptr
;
7236 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
7237 /* then add global bound info */
7238 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
7239 bounds_ptr
[0] = 0; /* relocated */
7240 bounds_ptr
[1] = size
;
7244 decl_initializer(type
, sec
, addr
, 1, 0);
7245 /* restore parse state if needed */
7247 tok_str_free(init_str
.str
);
7248 restore_parse_state(&saved_parse_state
);
7253 void put_func_debug(Sym
*sym
)
7258 /* XXX: we put here a dummy type */
7259 snprintf(buf
, sizeof(buf
), "%s:%c1",
7260 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
7261 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
7262 cur_text_section
, sym
->c
);
7267 /* not finished : try to put some local vars in registers */
7268 //#define CONFIG_REG_VARS
7270 #ifdef CONFIG_REG_VARS
7271 void add_var_ref(int t
)
7273 printf("%s:%d: &%s\n",
7274 file
->filename
, file
->line_num
,
7275 get_tok_str(t
, NULL
));
7278 /* first pass on a function with heuristic to extract variable usage
7279 and pointer references to local variables for register allocation */
7280 void analyse_function(void)
7287 /* any symbol coming after '&' is considered as being a
7288 variable whose reference is taken. It is highly unaccurate
7289 but it is difficult to do better without a complete parse */
7292 /* if '& number', then no need to examine next tokens */
7293 if (tok
== TOK_CINT
||
7295 tok
== TOK_CLLONG
||
7296 tok
== TOK_CULLONG
) {
7298 } else if (tok
>= TOK_UIDENT
) {
7299 /* if '& ident [' or '& ident ->', then ident address
7303 if (tok
!= '[' && tok
!= TOK_ARROW
)
7307 while (tok
!= '}' && tok
!= ';' &&
7308 !((tok
== ',' || tok
== ')') && level
== 0)) {
7309 if (tok
>= TOK_UIDENT
) {
7311 } else if (tok
== '(') {
7313 } else if (tok
== ')') {
7326 /* parse an old style function declaration list */
7327 /* XXX: check multiple parameter */
7328 static void func_decl_list(Sym
*func_sym
)
7335 /* parse each declaration */
7336 while (tok
!= '{' && tok
!= ';' && tok
!= TOK_EOF
) {
7337 if (!parse_btype(&btype
, &ad
))
7338 expect("declaration list");
7339 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
7340 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
7342 /* we accept no variable after */
7346 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
7347 /* find parameter in function parameter list */
7350 if ((s
->v
& ~SYM_FIELD
) == v
)
7354 error("declaration for parameter '%s' but no such parameter",
7355 get_tok_str(v
, NULL
));
7357 /* check that no storage specifier except 'register' was given */
7358 if (type
.t
& (VT_EXTERN
| VT_STATIC
| VT_TYPEDEF
))
7359 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
7360 /* we can add the type (NOTE: it could be local to the function) */
7362 /* accept other parameters */
7373 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
7374 static void decl(int l
)
7382 if (!parse_btype(&btype
, &ad
)) {
7383 /* skip redundant ';' */
7384 /* XXX: find more elegant solution */
7389 /* special test for old K&R protos without explicit int
7390 type. Only accepted when defining global data */
7391 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
7395 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
7396 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
7398 /* we accept no variable after */
7402 while (1) { /* iterate thru each declaration */
7404 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
7408 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
7409 printf("type = '%s'\n", buf
);
7412 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
7413 /* if old style function prototype, we accept a
7416 if (sym
->c
== FUNC_OLD
)
7417 func_decl_list(sym
);
7421 #ifdef CONFIG_REG_VARS
7422 TokenString func_str
;
7423 ParseState saved_parse_state
;
7428 error("cannot use local functions");
7429 if (!(type
.t
& VT_FUNC
))
7430 expect("function definition");
7432 #ifdef CONFIG_REG_VARS
7433 /* parse all function code and record it */
7435 tok_str_new(&func_str
);
7441 error("unexpected end of file");
7442 tok_str_add_tok(&func_str
);
7447 } else if (t
== '}') {
7449 if (block_level
== 0)
7453 tok_str_add(&func_str
, -1);
7454 tok_str_add(&func_str
, 0);
7456 save_parse_state(&saved_parse_state
);
7458 macro_ptr
= func_str
.str
;
7463 /* compute text section */
7464 cur_text_section
= ad
.section
;
7465 if (!cur_text_section
)
7466 cur_text_section
= text_section
;
7467 ind
= cur_text_section
->data_offset
;
7468 funcname
= get_tok_str(v
, NULL
);
7471 /* if symbol is already defined, then put complete type */
7474 /* put function symbol */
7475 sym
= global_identifier_push(v
, type
.t
, 0);
7476 sym
->type
.ref
= type
.ref
;
7478 /* NOTE: we patch the symbol size later */
7479 put_extern_sym(sym
, cur_text_section
, ind
, 0);
7481 sym
->r
= VT_SYM
| VT_CONST
;
7482 /* put debug symbol */
7484 put_func_debug(sym
);
7485 /* push a dummy symbol to enable local sym storage */
7486 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
7487 gfunc_prolog(&type
);
7490 #ifdef CONFIG_REG_VARS
7491 macro_ptr
= func_str
.str
;
7494 block(NULL
, NULL
, NULL
, NULL
, 0);
7497 cur_text_section
->data_offset
= ind
;
7498 /* look if any labels are undefined. Define symbols if
7499 '&&label' was used. */
7502 for(s
= label_stack
; s
!= NULL
; s
= s1
) {
7504 if (s
->r
& LABEL_FORWARD
) {
7505 error("label '%s' used but not defined",
7506 get_tok_str(s
->v
, NULL
));
7509 /* define corresponding symbol. A size of
7511 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
7514 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= NULL
;
7519 sym_pop(&local_stack
, NULL
); /* reset local stack */
7520 /* end of function */
7521 /* patch symbol size */
7522 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
7525 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
7527 funcname
= ""; /* for safety */
7528 func_vt
.t
= VT_VOID
; /* for safety */
7529 ind
= 0; /* for safety */
7531 #ifdef CONFIG_REG_VARS
7532 tok_str_free(func_str
.str
);
7533 restore_parse_state(&saved_parse_state
);
7537 if (btype
.t
& VT_TYPEDEF
) {
7538 /* save typedefed type */
7539 /* XXX: test storage specifiers ? */
7540 sym
= sym_push(v
, &type
, 0, 0);
7541 sym
->type
.t
|= VT_TYPEDEF
;
7542 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
7543 /* external function definition */
7544 external_sym(v
, &type
, 0);
7546 /* not lvalue if array */
7548 if (!(type
.t
& VT_ARRAY
))
7549 r
|= lvalue_type(type
.t
);
7550 if (btype
.t
& VT_EXTERN
) {
7551 /* external variable */
7552 external_sym(v
, &type
, r
);
7554 if (type
.t
& VT_STATIC
)
7558 has_init
= (tok
== '=');
7561 decl_initializer_alloc(&type
, &ad
, r
,
7575 /* compile the C file opened in 'file'. Return non zero if errors. */
7576 static int tcc_compile(TCCState
*s1
)
7580 volatile int section_sym
;
7583 printf("%s: **** new file\n", file
->filename
);
7586 s1
->include_stack_ptr
= s1
->include_stack
;
7587 /* XXX: move that before to avoid having to initialize
7588 file->ifdef_stack_ptr ? */
7589 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
7590 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
7592 /* XXX: not ANSI compliant: bound checking says error */
7594 anon_sym
= SYM_FIRST_ANOM
;
7596 /* file info: full path + filename */
7597 section_sym
= 0; /* avoid warning */
7599 section_sym
= put_elf_sym(symtab_section
, 0, 0,
7600 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
7601 text_section
->sh_num
, NULL
);
7602 getcwd(buf
, sizeof(buf
));
7603 pstrcat(buf
, sizeof(buf
), "/");
7604 put_stabs_r(buf
, N_SO
, 0, 0,
7605 text_section
->data_offset
, text_section
, section_sym
);
7606 put_stabs_r(file
->filename
, N_SO
, 0, 0,
7607 text_section
->data_offset
, text_section
, section_sym
);
7609 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
7610 symbols can be safely used */
7611 put_elf_sym(symtab_section
, 0, 0,
7612 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
7613 SHN_ABS
, file
->filename
);
7615 /* define some often used types */
7616 int_type
.t
= VT_INT
;
7618 char_pointer_type
.t
= VT_BYTE
;
7619 mk_pointer(&char_pointer_type
);
7621 func_old_type
.t
= VT_FUNC
;
7622 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
7625 /* define 'void *alloca(unsigned int)' builtin function */
7630 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
7631 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
7634 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
7638 define_start
= define_stack
;
7640 if (setjmp(s1
->error_jmp_buf
) == 0) {
7642 s1
->error_set_jmp_enabled
= 1;
7644 ch
= '\n'; /* XXX: suppress that*/
7645 tok_flags
= TOK_FLAG_BOL
| TOK_FLAG_BOF
;
7649 expect("declaration");
7651 /* end of translation unit info */
7653 put_stabs_r(NULL
, N_SO
, 0, 0,
7654 text_section
->data_offset
, text_section
, section_sym
);
7657 s1
->error_set_jmp_enabled
= 0;
7659 /* reset define stack, but leave -Dsymbols (may be incorrect if
7660 they are undefined) */
7661 free_defines(define_start
);
7663 sym_pop(&global_stack
, NULL
);
7665 return s1
->nb_errors
!= 0 ? -1 : 0;
7669 int tcc_compile_string(TCCState
*s
, const char *str
)
7671 BufferedFile bf1
, *bf
= &bf1
;
7675 /* init file structure */
7677 /* XXX: avoid copying */
7679 buf
= tcc_malloc(len
+ 1);
7684 bf
->buf_end
= buf
+ len
;
7685 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
7689 ret
= tcc_compile(s
);
7693 /* currently, no need to close */
7698 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
7699 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
7701 BufferedFile bf1
, *bf
= &bf1
;
7703 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
7704 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
7708 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
7710 /* init file structure */
7712 bf
->buf_ptr
= bf
->buffer
;
7713 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
7714 *bf
->buf_end
= CH_EOB
;
7715 bf
->filename
[0] = '\0';
7719 s1
->include_stack_ptr
= s1
->include_stack
;
7721 /* parse with define parser */
7722 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7728 /* undefine a preprocessor symbol */
7729 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
7733 ts
= tok_alloc(sym
, strlen(sym
));
7734 s
= define_find(ts
->tok
);
7735 /* undefine symbol by putting an invalid name */
7742 /* print the position in the source file of PC value 'pc' by reading
7743 the stabs debug information */
7744 static void rt_printline(unsigned long wanted_pc
)
7746 Stab_Sym
*sym
, *sym_end
;
7747 char func_name
[128], last_func_name
[128];
7748 unsigned long func_addr
, last_pc
, pc
;
7749 const char *incl_files
[INCLUDE_STACK_SIZE
];
7750 int incl_index
, len
, last_line_num
, i
;
7751 const char *str
, *p
;
7753 fprintf(stderr
, "0x%08lx:", wanted_pc
);
7755 func_name
[0] = '\0';
7758 last_func_name
[0] = '\0';
7759 last_pc
= 0xffffffff;
7761 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
7762 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
7763 while (sym
< sym_end
) {
7764 switch(sym
->n_type
) {
7765 /* function start or end */
7767 if (sym
->n_strx
== 0) {
7768 /* we test if between last line and end of function */
7769 pc
= sym
->n_value
+ func_addr
;
7770 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7772 func_name
[0] = '\0';
7775 str
= stabstr_section
->data
+ sym
->n_strx
;
7776 p
= strchr(str
, ':');
7778 pstrcpy(func_name
, sizeof(func_name
), str
);
7781 if (len
> sizeof(func_name
) - 1)
7782 len
= sizeof(func_name
) - 1;
7783 memcpy(func_name
, str
, len
);
7784 func_name
[len
] = '\0';
7786 func_addr
= sym
->n_value
;
7789 /* line number info */
7791 pc
= sym
->n_value
+ func_addr
;
7792 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7795 last_line_num
= sym
->n_desc
;
7797 strcpy(last_func_name
, func_name
);
7801 str
= stabstr_section
->data
+ sym
->n_strx
;
7803 if (incl_index
< INCLUDE_STACK_SIZE
) {
7804 incl_files
[incl_index
++] = str
;
7812 if (sym
->n_strx
== 0) {
7813 incl_index
= 0; /* end of translation unit */
7815 str
= stabstr_section
->data
+ sym
->n_strx
;
7816 /* do not add path */
7818 if (len
> 0 && str
[len
- 1] != '/')
7826 /* second pass: we try symtab symbols (no line number info) */
7829 Elf32_Sym
*sym
, *sym_end
;
7832 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
7833 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
7836 type
= ELF32_ST_TYPE(sym
->st_info
);
7837 if (type
== STT_FUNC
) {
7838 if (wanted_pc
>= sym
->st_value
&&
7839 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
7840 pstrcpy(last_func_name
, sizeof(last_func_name
),
7841 strtab_section
->data
+ sym
->st_name
);
7847 /* did not find any info: */
7848 fprintf(stderr
, " ???\n");
7851 if (last_func_name
[0] != '\0') {
7852 fprintf(stderr
, " %s()", last_func_name
);
7854 if (incl_index
> 0) {
7855 fprintf(stderr
, " (%s:%d",
7856 incl_files
[incl_index
- 1], last_line_num
);
7857 for(i
= incl_index
- 2; i
>= 0; i
--)
7858 fprintf(stderr
, ", included from %s", incl_files
[i
]);
7859 fprintf(stderr
, ")");
7861 fprintf(stderr
, "\n");
7873 /* return the PC at frame level 'level'. Return non zero if not found */
7874 static int rt_get_caller_pc(unsigned long *paddr
,
7875 struct ucontext
*uc
, int level
)
7881 *paddr
= uc
->uc_mcontext
.gregs
[EIP
];
7884 fp
= uc
->uc_mcontext
.gregs
[EBP
];
7885 for(i
=1;i
<level
;i
++) {
7886 /* XXX: check address validity with program info */
7887 if (fp
<= 0x1000 || fp
>= 0xc0000000)
7889 fp
= ((unsigned long *)fp
)[0];
7891 *paddr
= ((unsigned long *)fp
)[1];
7896 #error add arch specific rt_get_caller_pc()
7899 /* emit a run time error at position 'pc' */
7900 void rt_error(struct ucontext
*uc
, const char *fmt
, ...)
7907 fprintf(stderr
, "Runtime error: ");
7908 vfprintf(stderr
, fmt
, ap
);
7909 fprintf(stderr
, "\n");
7910 for(i
=0;i
<num_callers
;i
++) {
7911 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
7914 fprintf(stderr
, "at ");
7916 fprintf(stderr
, "by ");
7923 /* signal handler for fatal errors */
7924 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
7926 struct ucontext
*uc
= puc
;
7930 switch(siginf
->si_code
) {
7933 rt_error(uc
, "division by zero");
7936 rt_error(uc
, "floating point exception");
7942 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
7943 rt_error(uc
, *rt_bound_error_msg
);
7945 rt_error(uc
, "dereferencing invalid pointer");
7948 rt_error(uc
, "illegal instruction");
7951 rt_error(uc
, "abort() called");
7954 rt_error(uc
, "caught signal %d", signum
);
7961 /* do all relocations (needed before using tcc_get_symbol()) */
7962 int tcc_relocate(TCCState
*s1
)
7969 tcc_add_runtime(s1
);
7971 relocate_common_syms();
7973 /* compute relocation address : section are relocated in place. We
7974 also alloc the bss space */
7975 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7976 s
= s1
->sections
[i
];
7977 if (s
->sh_flags
& SHF_ALLOC
) {
7978 if (s
->sh_type
== SHT_NOBITS
)
7979 s
->data
= tcc_mallocz(s
->data_offset
);
7980 s
->sh_addr
= (unsigned long)s
->data
;
7984 relocate_syms(s1
, 1);
7986 if (s1
->nb_errors
!= 0)
7989 /* relocate each section */
7990 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7991 s
= s1
->sections
[i
];
7993 relocate_section(s1
, s
);
7998 /* launch the compiled program with the given arguments */
7999 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
8001 int (*prog_main
)(int, char **);
8003 if (tcc_relocate(s1
) < 0)
8006 prog_main
= tcc_get_symbol(s1
, "main");
8010 error("debug mode currently not available for Windows");
8012 struct sigaction sigact
;
8013 /* install TCC signal handlers to print debug info on fatal
8015 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
8016 sigact
.sa_sigaction
= sig_error
;
8017 sigemptyset(&sigact
.sa_mask
);
8018 sigaction(SIGFPE
, &sigact
, NULL
);
8019 sigaction(SIGILL
, &sigact
, NULL
);
8020 sigaction(SIGSEGV
, &sigact
, NULL
);
8021 sigaction(SIGBUS
, &sigact
, NULL
);
8022 sigaction(SIGABRT
, &sigact
, NULL
);
8026 #ifdef CONFIG_TCC_BCHECK
8027 if (do_bounds_check
) {
8028 void (*bound_init
)(void);
8030 /* set error function */
8031 rt_bound_error_msg
= (void *)tcc_get_symbol(s1
, "__bound_error_msg");
8033 /* XXX: use .init section so that it also work in binary ? */
8034 bound_init
= (void *)tcc_get_symbol(s1
, "__bound_init");
8038 return (*prog_main
)(argc
, argv
);
8041 TCCState
*tcc_new(void)
8046 s
= tcc_mallocz(sizeof(TCCState
));
8050 s
->output_type
= TCC_OUTPUT_MEMORY
;
8052 /* default include paths */
8053 tcc_add_sysinclude_path(s
, "/usr/local/include");
8054 tcc_add_sysinclude_path(s
, "/usr/include");
8055 tcc_add_sysinclude_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
8057 /* add all tokens */
8059 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
8061 tok_ident
= TOK_IDENT
;
8066 tok_alloc(p
, r
- p
- 1);
8070 /* we add dummy defines for some special macros to speed up tests
8071 and to have working defined() */
8072 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
8073 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
8074 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
8075 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
8077 /* standard defines */
8078 tcc_define_symbol(s
, "__STDC__", NULL
);
8079 #if defined(TCC_TARGET_I386)
8080 tcc_define_symbol(s
, "__i386__", NULL
);
8083 tcc_define_symbol(s
, "linux", NULL
);
8085 /* tiny C specific defines */
8086 tcc_define_symbol(s
, "__TINYC__", NULL
);
8088 /* default library paths */
8089 tcc_add_library_path(s
, "/usr/local/lib");
8090 tcc_add_library_path(s
, "/usr/lib");
8091 tcc_add_library_path(s
, "/lib");
8093 /* no section zero */
8094 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
8096 /* create standard sections */
8097 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
8098 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
8099 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
8101 /* symbols are always generated for linking stage */
8102 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
8104 ".hashtab", SHF_PRIVATE
);
8105 strtab_section
= symtab_section
->link
;
8107 /* private symbol table for dynamic symbols */
8108 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
8110 ".dynhashtab", SHF_PRIVATE
);
8114 void tcc_delete(TCCState
*s1
)
8118 /* free -D defines */
8122 n
= tok_ident
- TOK_IDENT
;
8123 for(i
= 0; i
< n
; i
++)
8124 tcc_free(table_ident
[i
]);
8125 tcc_free(table_ident
);
8127 /* free all sections */
8129 free_section(symtab_section
->hash
);
8131 free_section(s1
->dynsymtab_section
->hash
);
8132 free_section(s1
->dynsymtab_section
->link
);
8133 free_section(s1
->dynsymtab_section
);
8135 for(i
= 1; i
< s1
->nb_sections
; i
++)
8136 free_section(s1
->sections
[i
]);
8137 tcc_free(s1
->sections
);
8139 /* free loaded dlls array */
8140 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
8141 tcc_free(s1
->loaded_dlls
[i
]);
8142 tcc_free(s1
->loaded_dlls
);
8145 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
8146 tcc_free(s1
->library_paths
[i
]);
8147 tcc_free(s1
->library_paths
);
8149 /* cached includes */
8150 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
8151 tcc_free(s1
->cached_includes
[i
]);
8152 tcc_free(s1
->cached_includes
);
8154 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
8155 tcc_free(s1
->include_paths
[i
]);
8156 tcc_free(s1
->include_paths
);
8158 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
8159 tcc_free(s1
->sysinclude_paths
[i
]);
8160 tcc_free(s1
->sysinclude_paths
);
8165 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
8169 pathname1
= tcc_strdup(pathname
);
8170 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
8174 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
8178 pathname1
= tcc_strdup(pathname
);
8179 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
8183 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
8188 BufferedFile
*saved_file
;
8190 /* find source file type with extension */
8191 ext
= strrchr(filename
, '.');
8197 file
= tcc_open(s1
, filename
);
8199 if (flags
& AFF_PRINT_ERROR
) {
8200 error_noabort("file '%s' not found", filename
);
8206 if (!ext
|| !strcmp(ext
, "c")) {
8207 /* C file assumed */
8208 ret
= tcc_compile(s1
);
8211 /* assume executable format: auto guess file type */
8212 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
)) {
8213 error_noabort("could not read header");
8216 lseek(fd
, 0, SEEK_SET
);
8218 if (ehdr
.e_ident
[0] == ELFMAG0
&&
8219 ehdr
.e_ident
[1] == ELFMAG1
&&
8220 ehdr
.e_ident
[2] == ELFMAG2
&&
8221 ehdr
.e_ident
[3] == ELFMAG3
) {
8222 file
->line_num
= 0; /* do not display line number if error */
8223 if (ehdr
.e_type
== ET_REL
) {
8224 ret
= tcc_load_object_file(s1
, fd
, 0);
8225 } else if (ehdr
.e_type
== ET_DYN
) {
8226 ret
= tcc_load_dll(s1
, fd
, filename
,
8227 (flags
& AFF_REFERENCED_DLL
) != 0);
8229 error_noabort("unrecognized ELF file");
8232 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
8233 file
->line_num
= 0; /* do not display line number if error */
8234 ret
= tcc_load_archive(s1
, fd
);
8236 /* as GNU ld, consider it is an ld script if not recognized */
8237 ret
= tcc_load_ldscript(s1
);
8239 error_noabort("unrecognized file type");
8254 int tcc_add_file(TCCState
*s
, const char *filename
)
8256 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
8259 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
8263 pathname1
= tcc_strdup(pathname
);
8264 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
8268 /* find and load a dll. Return non zero if not found */
8269 /* XXX: add '-rpath' option support ? */
8270 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
8275 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
8276 snprintf(buf
, sizeof(buf
), "%s/%s",
8277 s
->library_paths
[i
], filename
);
8278 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
8284 /* the library name is the same as the argument of the '-l' option */
8285 int tcc_add_library(TCCState
*s
, const char *libraryname
)
8291 /* first we look for the dynamic library if not static linking */
8292 if (!s
->static_link
) {
8293 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8294 /* if we output to memory, then we simply we dlopen(). */
8295 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
8296 /* Since the libc is already loaded, we don't need to load it again */
8297 if (!strcmp(libraryname
, "c"))
8299 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
8303 if (tcc_add_dll(s
, buf
, 0) == 0)
8308 /* then we look for the static library */
8309 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
8310 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
8311 s
->library_paths
[i
], libraryname
);
8312 if (tcc_add_file_internal(s
, buf
, 0) == 0)
8318 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
8320 add_elf_sym(symtab_section
, val
, 0,
8321 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
8326 int tcc_set_output_type(TCCState
*s
, int output_type
)
8328 s
->output_type
= output_type
;
8330 /* if bound checking, then add corresponding sections */
8331 #ifdef CONFIG_TCC_BCHECK
8332 if (do_bounds_check
) {
8334 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
8335 /* create bounds sections */
8336 bounds_section
= new_section(s
, ".bounds",
8337 SHT_PROGBITS
, SHF_ALLOC
);
8338 lbounds_section
= new_section(s
, ".lbounds",
8339 SHT_PROGBITS
, SHF_ALLOC
);
8343 /* add debug sections */
8346 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
8347 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
8348 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
8349 put_elf_str(stabstr_section
, "");
8350 stab_section
->link
= stabstr_section
;
8351 /* put first entry */
8352 put_stabs("", 0, 0, 0, 0);
8355 /* add libc crt1/crti objects */
8356 if (output_type
== TCC_OUTPUT_EXE
||
8357 output_type
== TCC_OUTPUT_DLL
) {
8358 if (output_type
!= TCC_OUTPUT_DLL
)
8359 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
8360 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
8365 #if !defined(LIBTCC)
8367 static int64_t getclock_us(void)
8372 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
8375 gettimeofday(&tv
, NULL
);
8376 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
8382 printf("tcc version 0.9.13 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8383 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8384 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
8385 " [--] infile1 [infile2... --] [infile_args...]\n"
8387 "General options:\n"
8388 " -c compile only - generate an object file\n"
8389 " -o outfile set output filename\n"
8390 " -- allows multiples input files if no -o option given. Also\n"
8391 " separate input files from runtime arguments\n"
8392 " -Bdir set tcc internal library path\n"
8393 " -bench output compilation statistics\n"
8394 "Preprocessor options:\n"
8395 " -Idir add include path 'dir'\n"
8396 " -Dsym[=val] define 'sym' with value 'val'\n"
8397 " -Usym undefine 'sym'\n"
8399 " -Ldir add library path 'dir'\n"
8400 " -llib link with dynamic or static library 'lib'\n"
8401 " -shared generate a shared library\n"
8402 " -static static linking\n"
8403 " -r relocatable output\n"
8404 "Debugger options:\n"
8405 " -g generate runtime debug info\n"
8406 #ifdef CONFIG_TCC_BCHECK
8407 " -b compile with built-in memory and bounds checker (implies -g)\n"
8409 " -bt N show N callers in stack traces\n"
8413 int main(int argc
, char **argv
)
8416 int optind
, output_type
, multiple_files
, i
, reloc_output
;
8419 int nb_files
, nb_libraries
, nb_objfiles
, dminus
, ret
;
8420 char objfilename
[1024];
8421 int64_t start_time
= 0;
8424 output_type
= TCC_OUTPUT_MEMORY
;
8435 if (optind
>= argc
) {
8443 /* add a new file */
8444 dynarray_add((void ***)&files
, &nb_files
, r
);
8445 if (!multiple_files
) {
8447 /* argv[0] will be this file */
8450 } else if (r
[1] == '-') {
8451 /* '--' enables multiple files input and also ends several file input */
8452 if (dminus
&& multiple_files
) {
8453 optind
--; /* argv[0] will be '--' */
8458 } else if (r
[1] == 'h' || r
[1] == '?') {
8462 } else if (r
[1] == 'I') {
8463 if (tcc_add_include_path(s
, r
+ 2) < 0)
8464 error("too many include paths");
8465 } else if (r
[1] == 'D') {
8468 value
= strchr(sym
, '=');
8473 tcc_define_symbol(s
, sym
, value
);
8474 } else if (r
[1] == 'U') {
8475 tcc_undefine_symbol(s
, r
+ 2);
8476 } else if (r
[1] == 'L') {
8477 tcc_add_library_path(s
, r
+ 2);
8478 } else if (r
[1] == 'B') {
8479 /* set tcc utilities path (mainly for tcc development) */
8480 tcc_lib_path
= r
+ 2;
8481 } else if (r
[1] == 'l') {
8482 dynarray_add((void ***)&files
, &nb_files
, r
);
8484 } else if (!strcmp(r
+ 1, "bench")) {
8486 } else if (!strcmp(r
+ 1, "bt")) {
8487 num_callers
= atoi(argv
[optind
++]);
8489 #ifdef CONFIG_TCC_BCHECK
8491 do_bounds_check
= 1;
8497 } else if (r
[1] == 'c') {
8499 output_type
= TCC_OUTPUT_OBJ
;
8500 } else if (!strcmp(r
+ 1, "static")) {
8502 } else if (!strcmp(r
+ 1, "shared")) {
8503 output_type
= TCC_OUTPUT_DLL
;
8504 } else if (r
[1] == 'o') {
8508 outfile
= argv
[optind
++];
8509 } else if (r
[1] == 'r') {
8510 /* generate a .o merging several output files */
8512 output_type
= TCC_OUTPUT_OBJ
;
8513 } else if (r
[1] == 'W' || r
[1] == 'O' || r
[1] == 'm' || r
[1] == 'f') {
8514 /* ignore those options to be a drop-in replacement for gcc */
8516 error("invalid option -- '%s'", r
);
8520 nb_objfiles
= nb_files
- nb_libraries
;
8522 /* if outfile provided without other options, we output an
8524 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
8525 output_type
= TCC_OUTPUT_EXE
;
8527 /* check -c consistency : only single file handled. XXX: checks file type */
8528 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
8529 /* accepts only a single input file */
8530 if (nb_objfiles
!= 1)
8531 error("cannot specify multiple files with -c");
8532 if (nb_libraries
!= 0)
8533 error("cannot specify libraries with -c");
8536 /* compute default outfile name */
8537 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
8538 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
8540 /* add .o extension */
8541 pstrcpy(objfilename
, sizeof(objfilename
) - 1, files
[0]);
8542 ext
= strrchr(objfilename
, '.');
8544 goto default_outfile
;
8545 strcpy(ext
+ 1, "o");
8548 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
8550 outfile
= objfilename
;
8554 start_time
= getclock_us();
8557 tcc_set_output_type(s
, output_type
);
8559 /* compile or add each files or library */
8560 for(i
= 0;i
< nb_files
; i
++) {
8561 const char *filename
;
8563 filename
= files
[i
];
8564 if (filename
[0] == '-') {
8565 if (tcc_add_library(s
, filename
+ 2) < 0)
8566 error("cannot find %s", filename
);
8568 if (tcc_add_file(s
, filename
) < 0) {
8575 /* free all files */
8580 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
8581 if (total_time
< 0.001)
8583 if (total_bytes
< 1)
8585 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
8586 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
8587 total_time
, (int)(total_lines
/ total_time
),
8588 total_bytes
/ total_time
/ 1000000.0);
8591 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
8592 tcc_output_file(s
, outfile
);
8595 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
8598 /* XXX: cannot do it with bound checking because of the malloc hooks */
8599 if (!do_bounds_check
)
8604 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);