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/ucontext.h>
36 #ifndef CONFIG_TCC_STATIC
43 /* preprocessor debug */
45 /* include file debug */
50 /* target selection */
51 //#define TCC_TARGET_I386 /* i386 code generator */
52 //#define TCC_TARGET_IL /* .NET CLI generator */
54 /* default target is I386 */
55 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
56 #define TCC_TARGET_I386
59 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
60 #define CONFIG_TCC_BCHECK /* enable bound checking code */
63 #ifndef CONFIG_TCC_PREFIX
64 #define CONFIG_TCC_PREFIX "/usr/local"
67 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
68 executables or dlls */
69 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
71 #define INCLUDE_STACK_SIZE 32
72 #define IFDEF_STACK_SIZE 64
73 #define VSTACK_SIZE 64
74 #define STRING_MAX_SIZE 1024
76 #define TOK_HASH_SIZE 2048 /* must be a power of two */
77 #define TOK_ALLOC_INCR 512 /* must be a power of two */
78 #define SYM_HASH_SIZE 1031
80 /* token symbol management */
81 typedef struct TokenSym
{
82 struct TokenSym
*hash_next
;
83 int tok
; /* token number */
88 typedef struct CString
{
89 int size
; /* size in bytes */
90 void *data
; /* either 'char *' or 'int *' */
92 void *data_allocated
; /* if non NULL, data has been malloced */
96 typedef union CValue
{
102 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
104 unsigned long long ull
;
105 struct CString
*cstr
;
111 typedef struct SValue
{
113 unsigned short r
; /* register + flags */
114 unsigned short r2
; /* second register, used for 'long long'
115 type. If not used, set to VT_CONST */
116 CValue c
; /* constant, if VT_CONST */
117 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
120 /* symbol management */
122 int v
; /* symbol token */
123 int t
; /* associated type */
124 int r
; /* associated register */
125 int c
; /* associated number */
126 struct Sym
*next
; /* next related symbol */
127 struct Sym
*prev
; /* prev symbol in stack */
128 struct Sym
*hash_next
; /* next symbol in hash table */
131 typedef struct SymStack
{
133 struct Sym
*hash
[SYM_HASH_SIZE
];
136 /* section definition */
137 /* XXX: use directly ELF structure for parameters ? */
138 /* special flag to indicate that the section should not be linked to
140 #define SHF_PRIVATE 0x80000000
142 typedef struct Section
{
143 unsigned long data_offset
; /* current data offset */
144 unsigned char *data
; /* section data */
145 unsigned long data_allocated
; /* used for realloc() handling */
146 int sh_name
; /* elf section name (only used during output) */
147 int sh_num
; /* elf section number */
148 int sh_type
; /* elf section type */
149 int sh_flags
; /* elf section flags */
150 int sh_info
; /* elf section info */
151 int sh_addralign
; /* elf section alignment */
152 int sh_entsize
; /* elf entry size */
153 unsigned long sh_size
; /* section size (only used during output) */
154 unsigned long sh_addr
; /* address at which the section is relocated */
155 unsigned long sh_offset
; /* address at which the section is relocated */
156 int nb_hashed_syms
; /* used to resize the hash table */
157 struct Section
*link
; /* link to another section */
158 struct Section
*reloc
; /* corresponding section for relocation, if any */
159 struct Section
*hash
; /* hash table for symbols */
160 struct Section
*next
;
161 char name
[64]; /* section name */
164 typedef struct DLLReference
{
169 /* GNUC attribute definition */
170 typedef struct AttributeDef
{
173 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
176 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
177 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
178 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
180 /* stored in 'Sym.c' field */
181 #define FUNC_NEW 1 /* ansi function prototype */
182 #define FUNC_OLD 2 /* old function prototype */
183 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
185 /* stored in 'Sym.r' field */
186 #define FUNC_CDECL 0 /* standard c call */
187 #define FUNC_STDCALL 1 /* pascal c call */
189 /* field 'Sym.t' for macros */
190 #define MACRO_OBJ 0 /* object like macro */
191 #define MACRO_FUNC 1 /* function like macro */
193 /* field 'Sym.r' for labels */
194 #define LABEL_FORWARD 1 /* label is forward defined */
196 /* type_decl() types */
197 #define TYPE_ABSTRACT 1 /* type without variable */
198 #define TYPE_DIRECT 2 /* type with variable */
200 #define IO_BUF_SIZE 8192
202 typedef struct BufferedFile
{
203 unsigned char *buf_ptr
;
204 unsigned char *buf_end
;
206 int line_num
; /* current line number - here to simply code */
207 int ifndef_macro
; /*'#ifndef macro \n #define macro' search */
208 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
209 char inc_type
; /* type of include */
210 char inc_filename
[512]; /* filename specified by the user */
211 char filename
[1024]; /* current filename - here to simplify code */
212 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
215 #define CH_EOB 0 /* end of buffer or '\0' char in file */
216 #define CH_EOF (-1) /* end of file */
218 /* parsing state (used to save parser state to reparse part of the
219 source several times) */
220 typedef struct ParseState
{
227 /* used to record tokens */
228 typedef struct TokenString
{
234 /* include file cache, used to find files faster and also to eliminate
235 inclusion if the include file is protected by #ifndef ... #endif */
236 typedef struct CachedInclude
{
238 char type
; /* '"' or '>' to give include type */
239 char filename
[1]; /* path specified in #include */
243 struct BufferedFile
*file
;
244 int ch
, ch1
, tok
, tok1
;
246 CString tokcstr
; /* current parsed string, if any */
247 /* if true, line feed is returned as a token. line feed is also
250 /* set to TRUE if eof was reached */
252 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
253 Section
*cur_text_section
; /* current section where function code is
255 /* bound check related sections */
256 Section
*bounds_section
; /* contains global data bound description */
257 Section
*lbounds_section
; /* contains local data bound description */
258 /* symbol sections */
259 Section
*symtab_section
, *strtab_section
;
262 Section
*stab_section
, *stabstr_section
;
264 /* loc : local variable index
265 ind : output code index
267 anon_sym: anonymous symbol index
271 /* expression generation modifiers */
272 int const_wanted
; /* true if constant wanted */
273 int nocode_wanted
; /* true if no code generation wanted for an expression */
274 int global_expr
; /* true if compound literals must be allocated
275 globally (used during initializers parsing */
276 int func_vt
, func_vc
; /* current function return type (used by
277 return instruction) */
278 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
280 TokenSym
**table_ident
;
281 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
282 char token_buf
[STRING_MAX_SIZE
+ 1];
284 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
286 SValue vstack
[VSTACK_SIZE
], *vtop
;
287 int *macro_ptr
, *macro_ptr_allocated
;
288 int char_pointer_type
;
291 /* compile with debug symbol (and use them if error during execution) */
294 /* compile with built-in memory and bounds checker */
295 int do_bounds_check
= 0;
297 /* display benchmark infos */
302 /* use GNU C extensions */
305 /* use Tiny C extensions */
308 /* max number of callers shown if error */
309 static int num_callers
= 6;
310 static const char **rt_bound_error_msg
;
312 /* XXX: suppress that ASAP */
313 static struct TCCState
*tcc_state
;
315 /* give the path of the tcc libraries */
316 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
321 BufferedFile
**include_stack_ptr
;
322 int *ifdef_stack_ptr
;
324 /* include file handling */
325 char **include_paths
;
326 int nb_include_paths
;
327 char **sysinclude_paths
;
328 int nb_sysinclude_paths
;
329 CachedInclude
**cached_includes
;
330 int nb_cached_includes
;
332 char **library_paths
;
333 int nb_library_paths
;
335 /* array of all loaded dlls (including those referenced by loaded
337 DLLReference
**loaded_dlls
;
342 int nb_sections
; /* number of sections, including first dummy section */
346 unsigned long *got_offsets
;
349 /* give the correspondance from symtab indexes to dynsym indexes */
350 int *symtab_to_dynsym
;
352 /* temporary dynamic symbol sections (for dll loading) */
353 Section
*dynsymtab_section
;
354 /* exported dynamic symbol section */
357 /* if true, static linking is performed */
362 void (*error_func
)(void *opaque
, const char *msg
);
363 int error_set_jmp_enabled
;
364 jmp_buf error_jmp_buf
;
367 /* see include_stack_ptr */
368 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
370 /* see ifdef_stack_ptr */
371 int ifdef_stack
[IFDEF_STACK_SIZE
];
374 /* The current value can be: */
375 #define VT_VALMASK 0x00ff
376 #define VT_CONST 0x00f0 /* constant in vc
377 (must be first non register value) */
378 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
379 #define VT_LOCAL 0x00f2 /* offset on stack */
380 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
381 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
382 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
383 #define VT_LVAL 0x0100 /* var is an lvalue */
384 #define VT_SYM 0x0200 /* a symbol value is added */
385 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
386 char/short stored in integer registers) */
387 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
388 dereferencing value */
389 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
390 bounding function call point is in vc */
391 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
392 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
393 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
394 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
397 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
399 #define VT_INT 0 /* integer type */
400 #define VT_BYTE 1 /* signed byte type */
401 #define VT_SHORT 2 /* short type */
402 #define VT_VOID 3 /* void type */
403 #define VT_PTR 4 /* pointer */
404 #define VT_ENUM 5 /* enum definition */
405 #define VT_FUNC 6 /* function type */
406 #define VT_STRUCT 7 /* struct/union definition */
407 #define VT_FLOAT 8 /* IEEE float */
408 #define VT_DOUBLE 9 /* IEEE double */
409 #define VT_LDOUBLE 10 /* IEEE long double */
410 #define VT_BOOL 11 /* ISOC99 boolean type */
411 #define VT_LLONG 12 /* 64 bit integer */
412 #define VT_LONG 13 /* long integer (NEVER USED as type, only
414 #define VT_BTYPE 0x000f /* mask for basic type */
415 #define VT_UNSIGNED 0x0010 /* unsigned type */
416 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
417 #define VT_BITFIELD 0x0040 /* bitfield modifier */
420 #define VT_EXTERN 0x00000080 /* extern definition */
421 #define VT_STATIC 0x00000100 /* static variable */
422 #define VT_TYPEDEF 0x00000200 /* typedef definition */
424 /* type mask (except storage) */
425 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
429 /* warning: the following compare tokens depend on i386 asm code */
441 #define TOK_LAND 0xa0
445 #define TOK_MID 0xa3 /* inc/dec, to void constant */
447 #define TOK_UDIV 0xb0 /* unsigned division */
448 #define TOK_UMOD 0xb1 /* unsigned modulo */
449 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
450 #define TOK_CINT 0xb3 /* number in tokc */
451 #define TOK_CCHAR 0xb4 /* char constant in tokc */
452 #define TOK_STR 0xb5 /* pointer to string in tokc */
453 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
454 #define TOK_LCHAR 0xb7
455 #define TOK_LSTR 0xb8
456 #define TOK_CFLOAT 0xb9 /* float constant */
457 #define TOK_LINENUM 0xba /* line number info */
458 #define TOK_CDOUBLE 0xc0 /* double constant */
459 #define TOK_CLDOUBLE 0xc1 /* long double constant */
460 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
461 #define TOK_ADDC1 0xc3 /* add with carry generation */
462 #define TOK_ADDC2 0xc4 /* add with carry use */
463 #define TOK_SUBC1 0xc5 /* add with carry generation */
464 #define TOK_SUBC2 0xc6 /* add with carry use */
465 #define TOK_CUINT 0xc8 /* unsigned int constant */
466 #define TOK_CLLONG 0xc9 /* long long constant */
467 #define TOK_CULLONG 0xca /* unsigned long long constant */
468 #define TOK_ARROW 0xcb
469 #define TOK_DOTS 0xcc /* three dots */
470 #define TOK_SHR 0xcd /* unsigned shift right */
471 #define TOK_PPNUM 0xce /* preprocessor number */
473 #define TOK_SHL 0x01 /* shift left */
474 #define TOK_SAR 0x02 /* signed shift right */
476 /* assignement operators : normal operator or 0x80 */
477 #define TOK_A_MOD 0xa5
478 #define TOK_A_AND 0xa6
479 #define TOK_A_MUL 0xaa
480 #define TOK_A_ADD 0xab
481 #define TOK_A_SUB 0xad
482 #define TOK_A_DIV 0xaf
483 #define TOK_A_XOR 0xde
484 #define TOK_A_OR 0xfc
485 #define TOK_A_SHL 0x81
486 #define TOK_A_SAR 0x82
488 /* WARNING: the content of this string encodes token numbers */
489 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";
491 #define TOK_EOF (-1) /* end of file */
492 #define TOK_LINEFEED 10 /* line feed */
494 /* all identificators and strings have token above that */
495 #define TOK_IDENT 256
498 TOK_LAST
= TOK_IDENT
- 1,
499 #define DEF(id, str) id,
504 static const char *tcc_keywords
=
505 #define DEF(id, str) str "\0"
510 #define TOK_UIDENT TOK_DEFINE
513 #define snprintf _snprintf
516 #if defined(WIN32) || defined(TCC_UCLIBC)
517 /* currently incorrect */
518 long double strtold(const char *nptr
, char **endptr
)
520 return (long double)strtod(nptr
, endptr
);
522 float strtof(const char *nptr
, char **endptr
)
524 return (float)strtod(nptr
, endptr
);
527 /* XXX: need to define this to use them in non ISOC99 context */
528 extern float strtof (const char *__nptr
, char **__endptr
);
529 extern long double strtold (const char *__nptr
, char **__endptr
);
532 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
533 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
535 static void sum(int l
);
536 static void next(void);
537 static void next_nomacro(void);
538 static int parse_expr_type(void);
539 static int expr_type(void);
540 static int unary_type(void);
541 static int expr_const(void);
542 static void expr_eq(void);
543 static void gexpr(void);
544 static void decl(int l
);
545 static void decl_initializer(int t
, Section
*sec
, unsigned long c
,
546 int first
, int size_only
);
547 static void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
,
548 int has_init
, int v
, int scope
);
550 void gv2(int rc1
, int rc2
);
551 void move_reg(int r
, int s
);
552 void save_regs(int n
);
553 void save_reg(int r
);
559 static void macro_subst(TokenString
*tok_str
,
560 Sym
**nested_list
, int *macro_str
);
561 int save_reg_forced(int r
);
563 void force_charshort_cast(int t
);
564 void gen_cast(int t
);
566 Sym
*sym_find(int v
);
567 Sym
*sym_push(int v
, int t
, int r
, int c
);
570 int type_size(int t
, int *a
);
571 int pointed_type(int t
);
572 int pointed_size(int t
);
573 static int lvalue_type(int t
);
574 int is_compatible_types(int t1
, int t2
);
575 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
576 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
578 void error(const char *fmt
, ...);
579 void rt_error(struct ucontext
*uc
, const char *fmt
, ...);
581 void vset(int t
, int r
, int v
);
582 void type_to_str(char *buf
, int buf_size
,
583 int t
, const char *varstr
);
584 char *get_tok_str(int v
, CValue
*cv
);
585 static Sym
*get_sym_ref(int t
, Section
*sec
,
586 unsigned long offset
, unsigned long size
);
587 static Sym
*external_global_sym(int v
, int u
, int r
);
589 /* section generation */
590 static void section_realloc(Section
*sec
, unsigned long new_size
);
591 static void *section_ptr_add(Section
*sec
, unsigned long size
);
592 static void put_extern_sym(Sym
*sym
, Section
*section
,
593 unsigned long value
, unsigned long size
);
594 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
595 static int put_elf_str(Section
*s
, const char *sym
);
596 static int put_elf_sym(Section
*s
,
597 unsigned long value
, unsigned long size
,
598 int info
, int other
, int shndx
, const char *name
);
599 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
600 int info
, int sh_num
, const char *name
);
601 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
602 int type
, int symbol
);
603 static void put_stabs(const char *str
, int type
, int other
, int desc
,
604 unsigned long value
);
605 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
606 unsigned long value
, Section
*sec
, int sym_index
);
607 static void put_stabn(int type
, int other
, int desc
, int value
);
608 static void put_stabd(int type
, int other
, int desc
);
609 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
611 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
612 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
613 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
615 /* true if float/double/long double type */
616 static inline int is_float(int t
)
620 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
623 #ifdef TCC_TARGET_I386
624 #include "i386-gen.c"
630 #ifdef CONFIG_TCC_STATIC
632 #define RTLD_LAZY 0x001
633 #define RTLD_NOW 0x002
634 #define RTLD_GLOBAL 0x100
636 /* dummy function for profiling */
637 void *dlopen(const char *filename
, int flag
)
642 const char *dlerror(void)
647 typedef struct TCCSyms
{
652 #define TCCSYM(a) { #a, &a, },
654 /* add the symbol you want here if no dynamic linking is done */
655 static TCCSyms tcc_syms
[] = {
663 void *dlsym(void *handle
, const char *symbol
)
667 while (p
->str
!= NULL
) {
668 if (!strcmp(p
->str
, symbol
))
677 /********************************************************/
679 /* we use our own 'finite' function to avoid potential problems with
680 non standard math libs */
681 /* XXX: endianness dependant */
682 int ieee_finite(double d
)
685 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
688 /* copy a string and truncate it. */
689 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
696 q_end
= buf
+ buf_size
- 1;
708 /* strcat and truncate. */
709 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
714 pstrcpy(buf
+ len
, buf_size
- len
, s
);
718 /* memory management */
724 static inline void tcc_free(void *ptr
)
727 mem_cur_size
-= malloc_usable_size(ptr
);
732 static void *tcc_malloc(unsigned long size
)
737 error("memory full");
739 mem_cur_size
+= malloc_usable_size(ptr
);
740 if (mem_cur_size
> mem_max_size
)
741 mem_max_size
= mem_cur_size
;
746 static void *tcc_mallocz(unsigned long size
)
749 ptr
= tcc_malloc(size
);
750 memset(ptr
, 0, size
);
754 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
758 mem_cur_size
-= malloc_usable_size(ptr
);
760 ptr1
= realloc(ptr
, size
);
762 /* NOTE: count not correct if alloc error, but not critical */
763 mem_cur_size
+= malloc_usable_size(ptr1
);
764 if (mem_cur_size
> mem_max_size
)
765 mem_max_size
= mem_cur_size
;
770 static char *tcc_strdup(const char *str
)
773 ptr
= tcc_malloc(strlen(str
) + 1);
778 #define free(p) use_tcc_free(p)
779 #define malloc(s) use_tcc_malloc(s)
780 #define realloc(p, s) use_tcc_realloc(p, s)
782 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
789 /* every power of two we double array size */
790 if ((nb
& (nb
- 1)) == 0) {
795 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
797 error("memory full");
804 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
808 sec
= tcc_mallocz(sizeof(Section
));
809 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
810 sec
->sh_type
= sh_type
;
811 sec
->sh_flags
= sh_flags
;
818 sec
->sh_addralign
= 4;
821 sec
->sh_addralign
= 1;
824 sec
->sh_addralign
= 32; /* default conservative alignment */
828 /* only add section if not private */
829 if (!(sh_flags
& SHF_PRIVATE
)) {
830 sec
->sh_num
= s1
->nb_sections
;
831 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
836 static void free_section(Section
*s
)
842 /* realloc section and set its content to zero */
843 static void section_realloc(Section
*sec
, unsigned long new_size
)
848 size
= sec
->data_allocated
;
851 while (size
< new_size
)
853 data
= tcc_realloc(sec
->data
, size
);
855 error("memory full");
856 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
858 sec
->data_allocated
= size
;
861 /* reserve at least 'size' bytes in section 'sec' from
863 static void *section_ptr_add(Section
*sec
, unsigned long size
)
865 unsigned long offset
, offset1
;
867 offset
= sec
->data_offset
;
868 offset1
= offset
+ size
;
869 if (offset1
> sec
->data_allocated
)
870 section_realloc(sec
, offset1
);
871 sec
->data_offset
= offset1
;
872 return sec
->data
+ offset
;
875 /* return a reference to a section, and create it if it does not
877 Section
*find_section(TCCState
*s1
, const char *name
)
881 for(i
= 1; i
< s1
->nb_sections
; i
++) {
882 sec
= s1
->sections
[i
];
883 if (!strcmp(name
, sec
->name
))
886 /* sections are created as PROGBITS */
887 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
890 /* update sym->c so that it points to an external symbol in section
891 'section' with value 'value' */
892 static void put_extern_sym(Sym
*sym
, Section
*section
,
893 unsigned long value
, unsigned long size
)
895 int sym_type
, sym_bind
, sh_num
, info
;
901 sh_num
= section
->sh_num
;
905 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
908 sym_type
= STT_OBJECT
;
909 if (sym
->t
& VT_STATIC
)
910 sym_bind
= STB_LOCAL
;
912 sym_bind
= STB_GLOBAL
;
914 name
= get_tok_str(sym
->v
, NULL
);
915 #ifdef CONFIG_TCC_BCHECK
916 if (do_bounds_check
) {
917 /* XXX: avoid doing that for statics ? */
918 /* if bound checking is activated, we change some function
919 names by adding the "__bound" prefix */
922 /* XXX: we rely only on malloc hooks */
934 strcpy(buf
, "__bound_");
941 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
942 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
944 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
945 esym
->st_value
= value
;
946 esym
->st_size
= size
;
947 esym
->st_shndx
= sh_num
;
951 /* add a new relocation entry to symbol 'sym' in section 's' */
952 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
955 put_extern_sym(sym
, NULL
, 0, 0);
956 /* now we can add ELF relocation info */
957 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
960 static inline int isid(int c
)
962 return (c
>= 'a' && c
<= 'z') ||
963 (c
>= 'A' && c
<= 'Z') ||
967 static inline int isnum(int c
)
969 return c
>= '0' && c
<= '9';
972 static inline int isoct(int c
)
974 return c
>= '0' && c
<= '7';
977 static inline int toup(int c
)
979 if (c
>= 'a' && c
<= 'z')
980 return c
- 'a' + 'A';
985 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
989 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
992 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
996 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1000 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1007 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1008 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1009 (*f
)->filename
, (*f
)->line_num
);
1010 if (file
->line_num
> 0) {
1011 strcat_printf(buf
, sizeof(buf
),
1012 "%s:%d: ", file
->filename
, file
->line_num
);
1014 strcat_printf(buf
, sizeof(buf
),
1015 "%s: ", file
->filename
);
1018 strcat_printf(buf
, sizeof(buf
),
1022 strcat_printf(buf
, sizeof(buf
), "warning: ");
1023 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1025 if (!s1
->error_func
) {
1026 /* default case: stderr */
1027 fprintf(stderr
, "%s\n", buf
);
1029 s1
->error_func(s1
->error_opaque
, buf
);
1036 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1037 void (*error_func
)(void *opaque
, const char *msg
))
1039 s
->error_opaque
= error_opaque
;
1040 s
->error_func
= error_func
;
1044 /* error without aborting current compilation */
1045 void error_noabort(const char *fmt
, ...)
1047 TCCState
*s1
= tcc_state
;
1051 error1(s1
, 0, fmt
, ap
);
1055 void error(const char *fmt
, ...)
1057 TCCState
*s1
= tcc_state
;
1061 error1(s1
, 0, fmt
, ap
);
1063 /* better than nothing: in some cases, we accept to handle errors */
1064 if (s1
->error_set_jmp_enabled
) {
1065 longjmp(s1
->error_jmp_buf
, 1);
1067 /* XXX: suppress it someday */
1072 void expect(const char *msg
)
1074 error("%s expected", msg
);
1077 void warning(const char *fmt
, ...)
1079 TCCState
*s1
= tcc_state
;
1083 error1(s1
, 1, fmt
, ap
);
1090 error("'%c' expected", c
);
1094 void test_lvalue(void)
1096 if (!(vtop
->r
& VT_LVAL
))
1100 TokenSym
*tok_alloc(const char *str
, int len
)
1102 TokenSym
*ts
, **pts
, **ptable
;
1107 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
1109 pts
= &hash_ident
[h
];
1114 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1116 pts
= &(ts
->hash_next
);
1119 if (tok_ident
>= SYM_FIRST_ANOM
)
1120 error("memory full");
1122 /* expand token table if needed */
1123 i
= tok_ident
- TOK_IDENT
;
1124 if ((i
% TOK_ALLOC_INCR
) == 0) {
1125 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1127 error("memory full");
1128 table_ident
= ptable
;
1131 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1132 table_ident
[i
] = ts
;
1133 ts
->tok
= tok_ident
++;
1135 ts
->hash_next
= NULL
;
1136 memcpy(ts
->str
, str
, len
+ 1);
1141 /* CString handling */
1143 static void cstr_realloc(CString
*cstr
, int new_size
)
1148 size
= cstr
->size_allocated
;
1150 size
= 8; /* no need to allocate a too small first string */
1151 while (size
< new_size
)
1153 data
= tcc_realloc(cstr
->data_allocated
, size
);
1155 error("memory full");
1156 cstr
->data_allocated
= data
;
1157 cstr
->size_allocated
= size
;
1162 static void cstr_ccat(CString
*cstr
, int ch
)
1165 size
= cstr
->size
+ 1;
1166 if (size
> cstr
->size_allocated
)
1167 cstr_realloc(cstr
, size
);
1168 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1172 static void cstr_cat(CString
*cstr
, const char *str
)
1184 /* add a wide char */
1185 static void cstr_wccat(CString
*cstr
, int ch
)
1188 size
= cstr
->size
+ sizeof(int);
1189 if (size
> cstr
->size_allocated
)
1190 cstr_realloc(cstr
, size
);
1191 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1195 static void cstr_new(CString
*cstr
)
1197 memset(cstr
, 0, sizeof(CString
));
1200 /* free string and reset it to NULL */
1201 static void cstr_free(CString
*cstr
)
1203 tcc_free(cstr
->data_allocated
);
1207 #define cstr_reset(cstr) cstr_free(cstr)
1209 /* XXX: unicode ? */
1210 static void add_char(CString
*cstr
, int c
)
1212 if (c
== '\'' || c
== '\"' || c
== '\\') {
1213 /* XXX: could be more precise if char or string */
1214 cstr_ccat(cstr
, '\\');
1216 if (c
>= 32 && c
<= 126) {
1219 cstr_ccat(cstr
, '\\');
1221 cstr_ccat(cstr
, 'n');
1223 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1224 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1225 cstr_ccat(cstr
, '0' + (c
& 7));
1230 /* XXX: buffer overflow */
1231 /* XXX: float tokens */
1232 char *get_tok_str(int v
, CValue
*cv
)
1234 static char buf
[STRING_MAX_SIZE
+ 1];
1235 static CString cstr_buf
;
1241 /* NOTE: to go faster, we give a fixed buffer for small strings */
1242 cstr_reset(&cstr_buf
);
1243 cstr_buf
.data
= buf
;
1244 cstr_buf
.size_allocated
= sizeof(buf
);
1250 /* XXX: not quite exact, but only useful for testing */
1251 sprintf(p
, "%u", cv
->ui
);
1255 /* XXX: not quite exact, but only useful for testing */
1256 sprintf(p
, "%Lu", cv
->ull
);
1260 cstr_ccat(&cstr_buf
, '\'');
1261 add_char(&cstr_buf
, cv
->i
);
1262 cstr_ccat(&cstr_buf
, '\'');
1263 cstr_ccat(&cstr_buf
, '\0');
1267 len
= cstr
->size
- 1;
1269 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1270 cstr_ccat(&cstr_buf
, '\0');
1275 cstr_ccat(&cstr_buf
, '\"');
1277 len
= cstr
->size
- 1;
1279 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1281 len
= (cstr
->size
/ sizeof(int)) - 1;
1283 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1285 cstr_ccat(&cstr_buf
, '\"');
1286 cstr_ccat(&cstr_buf
, '\0');
1295 return strcpy(p
, "<<=");
1297 return strcpy(p
, ">>=");
1299 if (v
< TOK_IDENT
) {
1300 /* search in two bytes table */
1314 } else if (v
< tok_ident
) {
1315 return table_ident
[v
- TOK_IDENT
]->str
;
1316 } else if (v
>= SYM_FIRST_ANOM
) {
1317 /* special name for anonymous symbol */
1318 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1320 /* should never happen */
1325 return cstr_buf
.data
;
1328 /* push, without hashing */
1329 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1332 s
= tcc_malloc(sizeof(Sym
));
1343 /* find a symbol and return its associated structure. 's' is the top
1344 of the symbol stack */
1345 Sym
*sym_find2(Sym
*s
, int v
)
1355 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1357 /* find a symbol and return its associated structure. 'st' is the
1359 Sym
*sym_find1(SymStack
*st
, int v
)
1363 s
= st
->hash
[HASH_SYM(v
)];
1372 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1375 s
= sym_push2(&st
->top
, v
, t
, c
);
1376 /* add in hash table */
1378 ps
= &st
->hash
[HASH_SYM(v
)];
1385 /* find a symbol in the right symbol space */
1386 Sym
*sym_find(int v
)
1389 s
= sym_find1(&local_stack
, v
);
1391 s
= sym_find1(&global_stack
, v
);
1395 /* push a given symbol on the symbol stack */
1396 Sym
*sym_push(int v
, int t
, int r
, int c
)
1399 if (local_stack
.top
)
1400 s
= sym_push1(&local_stack
, v
, t
, c
);
1402 s
= sym_push1(&global_stack
, v
, t
, c
);
1407 /* pop symbols until top reaches 'b' */
1408 void sym_pop(SymStack
*st
, Sym
*b
)
1415 /* free hash table entry, except if symbol was freed (only
1416 used for #undef symbols) */
1418 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1425 /* undefined a hashed symbol (used for #undef). Its name is set to
1427 void sym_undef(SymStack
*st
, Sym
*s
)
1430 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1431 while (*ss
!= NULL
) {
1434 ss
= &(*ss
)->hash_next
;
1442 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1447 fd
= open(filename
, O_RDONLY
);
1450 bf
= tcc_malloc(sizeof(BufferedFile
));
1456 bf
->buf_ptr
= bf
->buffer
;
1457 bf
->buf_end
= bf
->buffer
;
1458 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1459 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1461 bf
->ifndef_macro
= 0;
1462 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1463 // printf("opening '%s'\n", filename);
1467 void tcc_close(BufferedFile
*bf
)
1469 total_lines
+= bf
->line_num
;
1474 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1475 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1477 /* fill input buffer and return next char */
1478 int tcc_getc_slow(BufferedFile
*bf
)
1481 /* only tries to read if really end of buffer */
1482 if (bf
->buf_ptr
>= bf
->buf_end
) {
1484 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1491 bf
->buf_ptr
= bf
->buffer
;
1492 bf
->buf_end
= bf
->buffer
+ len
;
1493 *bf
->buf_end
= CH_EOB
;
1495 if (bf
->buf_ptr
< bf
->buf_end
) {
1496 return *bf
->buf_ptr
++;
1498 bf
->buf_ptr
= bf
->buf_end
;
1503 /* no need to put that inline */
1504 void handle_eob(void)
1506 TCCState
*s1
= tcc_state
;
1508 ch1
= tcc_getc_slow(file
);
1512 if (return_linefeed
) {
1516 if (s1
->include_stack_ptr
== s1
->include_stack
)
1518 /* add end of include file debug info */
1520 put_stabd(N_EINCL
, 0, 0);
1522 /* pop include stack */
1524 s1
->include_stack_ptr
--;
1525 file
= *s1
->include_stack_ptr
;
1529 /* read next char from current input file */
1530 static inline void inp(void)
1532 ch1
= TCC_GETC(file
);
1533 /* end of buffer/file handling */
1538 // printf("ch1=%c 0x%x\n", ch1, ch1);
1541 /* handle '\\n' and '\\r\n' */
1542 static void handle_stray(void)
1547 } else if (ch1
== '\r') {
1550 error("invalid character after '\\'");
1557 } while (ch
== '\\');
1560 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1562 static inline void minp(void)
1571 /* same as minp, but also skip comments */
1572 static void cinp(void)
1579 /* single line C++ comments */
1581 while (ch1
!= '\n' && ch1
!= CH_EOF
)
1583 ch
= ' '; /* return space */
1584 } else if (ch1
== '*') {
1587 while (ch1
!= CH_EOF
) {
1590 if (c
== '*' && ch1
== '/') {
1592 ch
= ' '; /* return space */
1604 /* space exlcuding newline */
1605 static inline int is_space(int ch
)
1607 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1610 static inline void skip_spaces(void)
1612 while (is_space(ch
))
1616 /* skip block of text until #else, #elif or #endif. skip also pairs of
1618 void preprocess_skip(void)
1623 while (ch
!= '\n') {
1634 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1636 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1638 else if (tok
== TOK_ENDIF
)
1644 /* ParseState handling */
1646 /* XXX: currently, no include file info is stored. Thus, we cannot display
1647 accurate messages if the function or data definition spans multiple
1650 /* save current parse state in 's' */
1651 void save_parse_state(ParseState
*s
)
1653 s
->line_num
= file
->line_num
;
1654 s
->macro_ptr
= macro_ptr
;
1659 /* restore parse state from 's' */
1660 void restore_parse_state(ParseState
*s
)
1662 file
->line_num
= s
->line_num
;
1663 macro_ptr
= s
->macro_ptr
;
1668 /* return the number of additionnal 'ints' necessary to store the
1670 static inline int tok_ext_size(int t
)
1689 return LDOUBLE_SIZE
/ 4;
1695 /* token string handling */
1697 static inline void tok_str_new(TokenString
*s
)
1701 s
->last_line_num
= -1;
1704 static void tok_str_free(int *str
)
1715 if (t
== TOK_STR
|| t
== TOK_LSTR
|| t
== TOK_PPNUM
) {
1716 /* XXX: use a macro to be portable on 64 bit ? */
1717 cstr
= (CString
*)(*p
++);
1721 p
+= tok_ext_size(t
);
1727 static void tok_str_add(TokenString
*s
, int t
)
1733 if ((len
& 63) == 0) {
1734 str
= tcc_realloc(str
, (len
+ 64) * sizeof(int));
1743 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1746 CString
*cstr
, *cstr1
;
1750 if (t
== TOK_STR
|| t
== TOK_LSTR
|| t
== TOK_PPNUM
) {
1751 /* special case: need to duplicate string */
1753 cstr
= tcc_malloc(sizeof(CString
));
1756 cstr
->size_allocated
= size
;
1757 cstr
->data_allocated
= tcc_malloc(size
);
1758 cstr
->data
= cstr
->data_allocated
;
1759 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1761 tok_str_add(s
, cv1
.tab
[0]);
1763 n
= tok_ext_size(t
);
1765 tok_str_add(s
, cv
->tab
[i
]);
1769 /* add the current parse token in token string 's' */
1770 static void tok_str_add_tok(TokenString
*s
)
1774 /* save line number info */
1775 if (file
->line_num
!= s
->last_line_num
) {
1776 s
->last_line_num
= file
->line_num
;
1777 cval
.i
= s
->last_line_num
;
1778 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1780 tok_str_add2(s
, tok
, &tokc
);
1783 /* get a token from an integer array and increment pointer accordingly */
1784 static int tok_get(int **tok_str
, CValue
*cv
)
1790 n
= tok_ext_size(t
);
1797 /* eval an expression for #if/#elif */
1798 int expr_preprocess(void)
1804 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1805 next(); /* do macro subst */
1806 if (tok
== TOK_DEFINED
) {
1811 c
= sym_find1(&define_stack
, tok
) != 0;
1816 } else if (tok
>= TOK_IDENT
) {
1817 /* if undefined macro */
1821 tok_str_add_tok(&str
);
1823 tok_str_add(&str
, -1); /* simulate end of file */
1824 tok_str_add(&str
, 0);
1825 /* now evaluate C constant expression */
1826 macro_ptr
= str
.str
;
1830 tok_str_free(str
.str
);
1834 #if defined(DEBUG) || defined(PP_DEBUG)
1835 void tok_print(int *str
)
1841 t
= tok_get(&str
, &cval
);
1844 printf(" %s", get_tok_str(t
, &cval
));
1850 /* parse after #define */
1851 void parse_define(void)
1853 Sym
*s
, *first
, **ps
;
1854 int v
, t
, varg
, is_vaargs
;
1858 /* XXX: should check if same macro (ANSI) */
1861 /* '(' must be just after macro definition for MACRO_FUNC */
1866 while (tok
!= ')') {
1870 if (varg
== TOK_DOTS
) {
1871 varg
= TOK___VA_ARGS__
;
1873 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1877 if (varg
< TOK_IDENT
)
1878 error("badly punctuated parameter list");
1879 s
= sym_push1(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1890 /* EOF testing necessary for '-D' handling */
1891 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1892 tok_str_add2(&str
, tok
, &tokc
);
1895 tok_str_add(&str
, 0);
1897 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1900 s
= sym_push1(&define_stack
, v
, t
, (int)str
.str
);
1904 /* XXX: use a token or a hash table to accelerate matching ? */
1905 static CachedInclude
*search_cached_include(TCCState
*s1
,
1906 int type
, const char *filename
)
1911 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
1912 e
= s1
->cached_includes
[i
];
1913 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
1919 static inline void add_cached_include(TCCState
*s1
, int type
,
1920 const char *filename
, int ifndef_macro
)
1924 if (search_cached_include(s1
, type
, filename
))
1927 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
1929 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
1933 strcpy(e
->filename
, filename
);
1934 e
->ifndef_macro
= ifndef_macro
;
1935 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
1940 INCLUDE_STATE_NONE
= 0,
1941 INCLUDE_STATE_SEEK_IFNDEF
,
1944 void preprocess(void)
1946 TCCState
*s1
= tcc_state
;
1948 enum IncludeState state
;
1949 char buf
[1024], *q
, *p
;
1955 return_linefeed
= 1; /* linefeed will be returned as a
1956 token. EOF is also returned as line feed */
1957 state
= INCLUDE_STATE_NONE
;
1963 if (tok
== TOK_DEFINE
) {
1966 } else if (tok
== TOK_UNDEF
) {
1968 s
= sym_find1(&define_stack
, tok
);
1969 /* undefine symbol by putting an invalid name */
1971 sym_undef(&define_stack
, s
);
1972 } else if (tok
== TOK_INCLUDE
) {
1977 } else if (ch
== '\"') {
1982 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
1983 if ((q
- buf
) < sizeof(buf
) - 1)
1988 /* eat all spaces and comments after include */
1989 /* XXX: slightly incorrect */
1990 while (ch1
!= '\n' && ch1
!= CH_EOF
)
1993 /* computed #include : either we have only strings or
1994 we have anything enclosed in '<>' */
1997 if (tok
== TOK_STR
) {
1998 while (tok
!= TOK_LINEFEED
) {
1999 if (tok
!= TOK_STR
) {
2001 error("'#include' expects \"FILENAME\" or <FILENAME>");
2003 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2009 while (tok
!= TOK_LINEFEED
) {
2010 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2014 /* check syntax and remove '<>' */
2015 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2016 goto include_syntax
;
2017 memmove(buf
, buf
+ 1, len
- 2);
2018 buf
[len
- 2] = '\0';
2024 e
= search_cached_include(s1
, c
, buf
);
2025 if (e
&& sym_find1(&define_stack
, e
->ifndef_macro
)) {
2026 /* no need to parse the include because the 'ifndef macro'
2029 printf("%s: skipping %s\n", file
->filename
, buf
);
2033 /* first search in current dir if "header.h" */
2035 p
= strrchr(file
->filename
, '/');
2037 size
= p
+ 1 - file
->filename
;
2038 if (size
> sizeof(buf1
) - 1)
2039 size
= sizeof(buf1
) - 1;
2040 memcpy(buf1
, file
->filename
, size
);
2042 pstrcat(buf1
, sizeof(buf1
), buf
);
2043 f
= tcc_open(s1
, buf1
);
2047 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2048 error("#include recursion too deep");
2049 /* now search in all the include paths */
2050 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2051 for(i
= 0; i
< n
; i
++) {
2053 if (i
< s1
->nb_include_paths
)
2054 path
= s1
->include_paths
[i
];
2056 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2057 pstrcpy(buf1
, sizeof(buf1
), path
);
2058 pstrcat(buf1
, sizeof(buf1
), "/");
2059 pstrcat(buf1
, sizeof(buf1
), buf
);
2060 f
= tcc_open(s1
, buf1
);
2064 error("include file '%s' not found", buf
);
2068 printf("%s: including %s\n", file
->filename
, buf1
);
2071 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2072 /* push current file in stack */
2073 /* XXX: fix current line init */
2074 *s1
->include_stack_ptr
++ = file
;
2076 /* add include file debug info */
2078 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2080 /* we check for the construct: #ifndef IDENT \n #define IDENT */
2082 /* get first non space char */
2083 while (is_space(ch
) || ch
== '\n')
2087 state
= INCLUDE_STATE_SEEK_IFNDEF
;
2090 } else if (tok
== TOK_IFNDEF
) {
2093 } else if (tok
== TOK_IF
) {
2094 c
= expr_preprocess();
2096 } else if (tok
== TOK_IFDEF
) {
2100 if (tok
< TOK_IDENT
)
2101 error("invalid argument for '#if%sdef'", c
? "n" : "");
2102 if (state
== INCLUDE_STATE_SEEK_IFNDEF
) {
2104 file
->ifndef_macro
= tok
;
2106 state
= INCLUDE_STATE_NONE
;
2108 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
2110 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2111 error("memory full");
2112 *s1
->ifdef_stack_ptr
++ = c
;
2114 } else if (tok
== TOK_ELSE
) {
2115 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2116 error("#else without matching #if");
2117 if (s1
->ifdef_stack_ptr
[-1] & 2)
2118 error("#else after #else");
2119 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2121 } else if (tok
== TOK_ELIF
) {
2122 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2123 error("#elif without matching #if");
2124 c
= s1
->ifdef_stack_ptr
[-1];
2126 error("#elif after #else");
2127 /* last #if/#elif expression was true: we skip */
2130 c
= expr_preprocess();
2131 s1
->ifdef_stack_ptr
[-1] = c
;
2136 state
= INCLUDE_STATE_NONE
;
2139 } else if (tok
== TOK_ENDIF
) {
2140 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2141 error("#endif without matching #if");
2142 if (file
->ifndef_macro
&&
2143 s1
->ifdef_stack_ptr
== (file
->ifdef_stack_ptr
+ 1)) {
2144 /* '#ifndef macro \n #define macro' was at the start of
2145 file. Now we check if an '#endif' is exactly at the end
2147 while (tok
!= TOK_LINEFEED
)
2149 /* XXX: should also skip comments, but it is more complicated */
2151 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
2152 file
->ifndef_macro
);
2154 /* if not end of file, we must desactivate the ifndef
2156 file
->ifndef_macro
= 0;
2159 s1
->ifdef_stack_ptr
--;
2160 } else if (tok
== TOK_LINE
) {
2163 if (tok
!= TOK_CINT
)
2167 if (tok
!= TOK_LINEFEED
) {
2170 pstrcpy(file
->filename
, sizeof(file
->filename
),
2171 (char *)tokc
.cstr
->data
);
2173 /* NOTE: we do it there to avoid problems with linefeed */
2174 file
->line_num
= line_num
;
2175 } else if (tok
== TOK_ERROR
) {
2178 /* ignore other preprocess commands or #! for C scripts */
2179 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
)
2182 return_linefeed
= 0;
2185 /* read a number in base b */
2186 static int getn(int b
)
2191 if (ch
>= 'a' && ch
<= 'f')
2193 else if (ch
>= 'A' && ch
<= 'F')
2199 if (t
< 0 || t
>= b
)
2207 /* read a character for string or char constant and eval escape codes */
2208 static int getq(void)
2216 /* at most three octal digits */
2220 c
= c
* 8 + ch
- '0';
2223 c
= c
* 8 + ch
- '0';
2228 } else if (ch
== 'x') {
2246 else if (ch
== 'e' && gnu_ext
)
2248 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
2251 error("invalid escaped char");
2254 } else if (c
== '\r' && ch
== '\n') {
2261 /* we use 64 bit numbers */
2264 /* bn = (bn << shift) | or_val */
2265 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2269 for(i
=0;i
<BN_SIZE
;i
++) {
2271 bn
[i
] = (v
<< shift
) | or_val
;
2272 or_val
= v
>> (32 - shift
);
2276 void bn_zero(unsigned int *bn
)
2279 for(i
=0;i
<BN_SIZE
;i
++) {
2284 /* parse number in null terminated string 'p' and return it in the
2286 void parse_number(const char *p
)
2288 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
2290 unsigned int bn
[BN_SIZE
];
2301 goto float_frac_parse
;
2302 } else if (t
== '0') {
2303 if (ch
== 'x' || ch
== 'X') {
2307 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2313 /* parse all digits. cannot check octal numbers at this stage
2314 because of floating point constants */
2316 if (ch
>= 'a' && ch
<= 'f')
2318 else if (ch
>= 'A' && ch
<= 'F')
2326 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2328 error("number too long");
2334 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2335 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2337 /* NOTE: strtox should support that for hexa numbers, but
2338 non ISOC99 libcs do not support it, so we prefer to do
2340 /* hexadecimal or binary floats */
2341 /* XXX: handle overflows */
2353 } else if (t
>= 'a') {
2355 } else if (t
>= 'A') {
2360 bn_lshift(bn
, shift
, t
);
2367 if (t
>= 'a' && t
<= 'f') {
2369 } else if (t
>= 'A' && t
<= 'F') {
2371 } else if (t
>= '0' && t
<= '9') {
2377 error("invalid digit");
2378 bn_lshift(bn
, shift
, t
);
2383 if (ch
!= 'p' && ch
!= 'P')
2384 error("exponent expected");
2390 } else if (ch
== '-') {
2394 if (ch
< '0' || ch
> '9')
2395 error("exponent digits expected");
2396 while (ch
>= '0' && ch
<= '9') {
2397 exp_val
= exp_val
* 10 + ch
- '0';
2400 exp_val
= exp_val
* s
;
2402 /* now we can generate the number */
2403 /* XXX: should patch directly float number */
2404 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
2405 d
= ldexp(d
, exp_val
- frac_bits
);
2410 /* float : should handle overflow */
2412 } else if (t
== 'L') {
2415 /* XXX: not large enough */
2416 tokc
.ld
= (long double)d
;
2422 /* decimal floats */
2424 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2429 while (ch
>= '0' && ch
<= '9') {
2430 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2436 if (ch
== 'e' || ch
== 'E') {
2437 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2441 if (ch
== '-' || ch
== '+') {
2442 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2447 if (ch
< '0' || ch
> '9')
2448 error("exponent digits expected");
2449 while (ch
>= '0' && ch
<= '9') {
2450 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2462 tokc
.f
= strtof(token_buf
, NULL
);
2463 } else if (t
== 'L') {
2466 tokc
.ld
= strtold(token_buf
, NULL
);
2469 tokc
.d
= strtod(token_buf
, NULL
);
2473 unsigned long long n
, n1
;
2476 /* integer number */
2479 if (b
== 10 && *q
== '0') {
2486 /* no need for checks except for base 10 / 8 errors */
2489 } else if (t
>= 'a') {
2491 } else if (t
>= 'A') {
2496 error("invalid digit");
2500 /* detect overflow */
2501 /* XXX: this test is not reliable */
2503 error("integer constant overflow");
2506 /* XXX: not exactly ANSI compliant */
2507 if ((n
& 0xffffffff00000000LL
) != 0) {
2512 } else if (n
> 0x7fffffff) {
2523 error("three 'l's in integer constant");
2526 if (tok
== TOK_CINT
)
2528 else if (tok
== TOK_CUINT
)
2532 } else if (t
== 'U') {
2534 error("two 'u's in integer constant");
2536 if (tok
== TOK_CINT
)
2538 else if (tok
== TOK_CLLONG
)
2545 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2552 /* return next token without macro substitution */
2553 static inline void next_nomacro1(void)
2561 while (ch
== '\n') {
2562 /* during preprocessor parsing, '\n' is a token */
2563 if (return_linefeed
) {
2570 /* preprocessor command if # at start of line after
2593 while (isid(ch
) || isnum(ch
)) {
2594 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2595 error("ident too long");
2600 ts
= tok_alloc(token_buf
, q
- token_buf
);
2602 } else if (isnum(ch
)) {
2604 cstr_reset(&tokcstr
);
2605 /* after the first digit, accept digits, alpha, '.' or sign if
2606 prefixed by 'eEpP' */
2610 cstr_ccat(&tokcstr
, ch
);
2612 if (!(isnum(ch
) || isid(ch
) || ch
== '.' ||
2613 ((ch
== '+' || ch
== '-') &&
2614 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
2617 /* We add a trailing '\0' to ease parsing */
2618 cstr_ccat(&tokcstr
, '\0');
2619 tokc
.cstr
= &tokcstr
;
2621 } else if (ch
== '.') {
2622 /* special dot handling because it can also start a number */
2625 cstr_reset(&tokcstr
);
2626 cstr_ccat(&tokcstr
, '.');
2638 } else if (ch
== '\'') {
2643 /* this cast is needed if >= 128 */
2644 if (tok
== TOK_CCHAR
)
2650 } else if (ch
== '\"') {
2654 cstr_reset(&tokcstr
);
2655 while (ch
!= '\"') {
2658 error("unterminated string");
2660 cstr_ccat(&tokcstr
, b
);
2662 cstr_wccat(&tokcstr
, b
);
2665 cstr_ccat(&tokcstr
, '\0');
2667 cstr_wccat(&tokcstr
, '\0');
2668 tokc
.cstr
= &tokcstr
;
2676 if (*q
== tok
&& q
[1] == ch
) {
2679 /* three chars tests */
2680 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2685 } else if (tok
== TOK_DOTS
) {
2687 error("parse error");
2694 /* single char substitutions */
2697 else if (tok
== '>')
2702 /* return next token without macro substitution. Can read input from
2704 static void next_nomacro(void)
2710 tok
= tok_get(¯o_ptr
, &tokc
);
2711 if (tok
== TOK_LINENUM
) {
2712 file
->line_num
= tokc
.i
;
2721 /* substitute args in macro_str and return allocated string */
2722 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2724 int *st
, last_tok
, t
, notfirst
;
2733 t
= tok_get(¯o_str
, &cval
);
2738 t
= tok_get(¯o_str
, &cval
);
2741 s
= sym_find2(args
, t
);
2748 cstr_ccat(&cstr
, ' ');
2749 t
= tok_get(&st
, &cval
);
2750 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
2753 cstr_ccat(&cstr
, '\0');
2755 printf("stringize: %s\n", (char *)cstr
.data
);
2759 tok_str_add2(&str
, TOK_STR
, &cval
);
2762 tok_str_add2(&str
, t
, &cval
);
2764 } else if (t
>= TOK_IDENT
) {
2765 s
= sym_find2(args
, t
);
2768 /* if '##' is present before or after, no arg substitution */
2769 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2770 /* special case for var arg macros : ## eats the
2771 ',' if empty VA_ARGS variable. */
2772 /* XXX: test of the ',' is not 100%
2773 reliable. should fix it to avoid security
2775 if (gnu_ext
&& s
->t
&&
2776 last_tok
== TOK_TWOSHARPS
&&
2777 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
2779 /* suppress ',' '##' */
2782 /* suppress '##' and add variable */
2790 t1
= tok_get(&st
, &cval
);
2793 tok_str_add2(&str
, t1
, &cval
);
2797 macro_subst(&str
, nested_list
, st
);
2800 tok_str_add(&str
, t
);
2803 tok_str_add2(&str
, t
, &cval
);
2807 tok_str_add(&str
, 0);
2811 /* handle the '##' operator */
2812 static int *macro_twosharps(void)
2817 const char *p1
, *p2
;
2819 TokenString macro_str1
;
2823 tok_str_new(¯o_str1
);
2829 while (*macro_ptr
== TOK_TWOSHARPS
) {
2831 macro_ptr1
= macro_ptr
;
2834 t
= tok_get(¯o_ptr
, &cval
);
2836 /* We concatenate the two tokens if we have an
2837 identifier or a preprocessing number */
2839 p1
= get_tok_str(tok
, &tokc
);
2840 cstr_cat(&cstr
, p1
);
2841 p2
= get_tok_str(t
, &cval
);
2842 cstr_cat(&cstr
, p2
);
2843 cstr_ccat(&cstr
, '\0');
2845 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
2846 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
2847 if (tok
== TOK_PPNUM
) {
2848 /* if number, then create a number token */
2849 /* NOTE: no need to allocate because
2850 tok_str_add2() does it */
2853 /* if identifier, we must do a test to
2854 validate we have a correct identifier */
2855 if (t
== TOK_PPNUM
) {
2865 if (!isnum(c
) && !isid(c
))
2869 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
2870 tok
= ts
->tok
; /* modify current token */
2873 const char *str
= cstr
.data
;
2874 const unsigned char *q
;
2876 /* we look for a valid token */
2877 /* XXX: do more extensive checks */
2878 if (!strcmp(str
, ">>=")) {
2880 } else if (!strcmp(str
, "<<=")) {
2882 } else if (strlen(str
) == 2) {
2883 /* search in two bytes table */
2888 if (q
[0] == str
[0] && q
[1] == str
[1])
2895 /* NOTE: because get_tok_str use a static buffer,
2898 p1
= get_tok_str(tok
, &tokc
);
2899 cstr_cat(&cstr
, p1
);
2900 cstr_ccat(&cstr
, '\0');
2901 p2
= get_tok_str(t
, &cval
);
2902 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
2903 /* cannot merge tokens: just add them separately */
2904 tok_str_add2(¯o_str1
, tok
, &tokc
);
2905 /* XXX: free associated memory ? */
2912 tok_str_add2(¯o_str1
, tok
, &tokc
);
2915 tok_str_add(¯o_str1
, 0);
2916 return macro_str1
.str
;
2920 /* do macro substitution of current token with macro 's' and add
2921 result to (tok_str,tok_len). 'nested_list' is the list of all
2922 macros we got inside to avoid recursing. Return non zero if no
2923 substitution needs to be done */
2924 static int macro_subst_tok(TokenString
*tok_str
,
2925 Sym
**nested_list
, Sym
*s
)
2927 Sym
*args
, *sa
, *sa1
;
2928 int mstr_allocated
, parlevel
, *mstr
, t
;
2934 /* if symbol is a macro, prepare substitution */
2935 /* if nested substitution, do nothing */
2936 if (sym_find2(*nested_list
, tok
))
2939 /* special macros */
2940 if (tok
== TOK___LINE__
) {
2941 cval
.i
= file
->line_num
;
2942 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
2943 } else if (tok
== TOK___FILE__
) {
2944 cstrval
= file
->filename
;
2946 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2947 } else if (tok
== TOK___DATE__
) {
2948 cstrval
= "Jan 1 2002";
2950 } else if (tok
== TOK___TIME__
) {
2951 cstrval
= "00:00:00";
2954 cstr_cat(&cstr
, cstrval
);
2955 cstr_ccat(&cstr
, '\0');
2957 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2962 if (s
->t
== MACRO_FUNC
) {
2963 /* NOTE: we do not use next_nomacro to avoid eating the
2964 next token. XXX: find better solution */
2968 while (is_space(ch
) || ch
== '\n')
2972 if (t
!= '(') /* no macro subst */
2975 /* argument macro */
2980 /* NOTE: empty args are allowed, except if no args */
2982 /* handle '()' case */
2983 if (!args
&& tok
== ')')
2986 error("macro '%s' used with too many args",
2987 get_tok_str(s
->v
, 0));
2990 /* NOTE: non zero sa->t indicates VA_ARGS */
2991 while ((parlevel
> 0 ||
2993 (tok
!= ',' || sa
->t
))) &&
2997 else if (tok
== ')')
2999 tok_str_add2(&str
, tok
, &tokc
);
3002 tok_str_add(&str
, 0);
3003 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->t
, (int)str
.str
);
3006 /* special case for gcc var args: add an empty
3007 var arg argument if it is omitted */
3008 if (sa
&& sa
->t
&& gnu_ext
)
3018 error("macro '%s' used with too few args",
3019 get_tok_str(s
->v
, 0));
3022 /* now subst each arg */
3023 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3028 tok_str_free((int *)sa
->c
);
3034 sym_push2(nested_list
, s
->v
, 0, 0);
3035 macro_subst(tok_str
, nested_list
, mstr
);
3036 /* pop nested defined symbol */
3038 *nested_list
= sa1
->prev
;
3046 /* do macro substitution of macro_str and add result to
3047 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3048 inside to avoid recursing. */
3049 static void macro_subst(TokenString
*tok_str
,
3050 Sym
**nested_list
, int *macro_str
)
3053 int *saved_macro_ptr
;
3056 saved_macro_ptr
= macro_ptr
;
3057 macro_ptr
= macro_str
;
3058 /* first scan for '##' operator handling */
3059 macro_str1
= macro_twosharps();
3060 macro_ptr
= macro_str1
;
3066 s
= sym_find1(&define_stack
, tok
);
3068 if (macro_subst_tok(tok_str
, nested_list
, s
) != 0)
3072 tok_str_add2(tok_str
, tok
, &tokc
);
3075 macro_ptr
= saved_macro_ptr
;
3076 tok_str_free(macro_str1
);
3079 /* return next token with macro substitution */
3080 static void next(void)
3082 Sym
*nested_list
, *s
;
3085 /* special 'ungettok' case for label parsing */
3094 /* if not reading from macro substituted string, then try
3095 to substitute macros */
3096 if (tok
>= TOK_IDENT
) {
3097 s
= sym_find1(&define_stack
, tok
);
3099 /* we have a macro: we try to substitute */
3102 if (macro_subst_tok(&str
, &nested_list
, s
) == 0) {
3103 /* substitution done, NOTE: maybe empty */
3104 tok_str_add(&str
, 0);
3105 macro_ptr
= str
.str
;
3106 macro_ptr_allocated
= str
.str
;
3113 /* end of macro string: free it */
3114 tok_str_free(macro_ptr_allocated
);
3120 /* convert preprocessor tokens into C tokens */
3121 if (tok
== TOK_PPNUM
) {
3122 parse_number((char *)tokc
.cstr
->data
);
3126 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3130 void swap(int *p
, int *q
)
3138 void vsetc(int t
, int r
, CValue
*vc
)
3142 if (vtop
>= vstack
+ VSTACK_SIZE
)
3143 error("memory full");
3144 /* cannot let cpu flags if other instruction are generated. Also
3145 avoid leaving VT_JMP anywhere except on the top of the stack
3146 because it would complicate the code generator. */
3147 if (vtop
>= vstack
) {
3148 v
= vtop
->r
& VT_VALMASK
;
3149 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
3155 vtop
->r2
= VT_CONST
;
3159 /* push integer constant */
3164 vsetc(VT_INT
, VT_CONST
, &cval
);
3167 /* Return a static symbol pointing to a section */
3168 static Sym
*get_sym_ref(int t
, Section
*sec
,
3169 unsigned long offset
, unsigned long size
)
3175 sym
= sym_push1(&global_stack
, v
, t
| VT_STATIC
, 0);
3176 sym
->r
= VT_CONST
| VT_SYM
;
3177 put_extern_sym(sym
, sec
, offset
, size
);
3181 /* push a reference to a section offset by adding a dummy symbol */
3182 static void vpush_ref(int t
, Section
*sec
, unsigned long offset
, unsigned long size
)
3187 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
3188 vtop
->sym
= get_sym_ref(t
, sec
, offset
, size
);
3191 /* define a new external reference to a symbol 'v' of type 'u' */
3192 static Sym
*external_global_sym(int v
, int u
, int r
)
3198 /* push forward reference */
3199 s
= sym_push1(&global_stack
,
3200 v
, u
| VT_EXTERN
, 0);
3201 s
->r
= r
| VT_CONST
| VT_SYM
;
3206 /* define a new external reference to a symbol 'v' of type 'u' */
3207 static Sym
*external_sym(int v
, int u
, int r
)
3213 /* push forward reference */
3214 s
= sym_push(v
, u
| VT_EXTERN
, r
| VT_CONST
| VT_SYM
, 0);
3219 /* push a reference to global symbol v */
3220 static void vpush_global_sym(int t
, int v
)
3225 sym
= external_global_sym(v
, t
, 0);
3227 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
3231 void vset(int t
, int r
, int v
)
3248 void vpushv(SValue
*v
)
3250 if (vtop
>= vstack
+ VSTACK_SIZE
)
3251 error("memory full");
3261 /* save r to the memory stack, and mark it as being free */
3262 void save_reg(int r
)
3264 int l
, saved
, t
, size
, align
;
3267 /* modify all stack values */
3270 for(p
=vstack
;p
<=vtop
;p
++) {
3271 if ((p
->r
& VT_VALMASK
) == r
||
3272 (p
->r2
& VT_VALMASK
) == r
) {
3273 /* must save value on stack if not already done */
3275 /* NOTE: must reload 'r' because r might be equal to r2 */
3276 r
= p
->r
& VT_VALMASK
;
3277 /* store register in the stack */
3279 if ((p
->r
& VT_LVAL
) ||
3280 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
3282 size
= type_size(t
, &align
);
3283 loc
= (loc
- size
) & -align
;
3285 sv
.r
= VT_LOCAL
| VT_LVAL
;
3288 #ifdef TCC_TARGET_I386
3289 /* x86 specific: need to pop fp register ST0 if saved */
3291 o(0xd9dd); /* fstp %st(1) */
3294 /* special long long case */
3295 if ((t
& VT_BTYPE
) == VT_LLONG
) {
3302 /* mark that stack entry as being saved on the stack */
3303 if (p
->r
& VT_LVAL
) {
3304 /* also suppress the bounded flag because the
3305 relocation address of the function was stored in
3307 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
3309 p
->r
= lvalue_type(p
->t
) | VT_LOCAL
;
3317 /* find a free register of class 'rc'. If none, save one register */
3323 /* find a free register */
3324 for(r
=0;r
<NB_REGS
;r
++) {
3325 if (reg_classes
[r
] & rc
) {
3326 for(p
=vstack
;p
<=vtop
;p
++) {
3327 if ((p
->r
& VT_VALMASK
) == r
||
3328 (p
->r2
& VT_VALMASK
) == r
)
3336 /* no register left : free the first one on the stack (VERY
3337 IMPORTANT to start from the bottom to ensure that we don't
3338 spill registers used in gen_opi()) */
3339 for(p
=vstack
;p
<=vtop
;p
++) {
3340 r
= p
->r
& VT_VALMASK
;
3341 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
3343 /* also look at second register (if long long) */
3344 r
= p
->r2
& VT_VALMASK
;
3345 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
3351 /* Should never comes here */
3355 /* save registers up to (vtop - n) stack entry */
3356 void save_regs(int n
)
3361 for(p
= vstack
;p
<= p1
; p
++) {
3362 r
= p
->r
& VT_VALMASK
;
3369 /* move register 's' to 'r', and flush previous value of r to memory
3371 void move_reg(int r
, int s
)
3384 /* get address of vtop (vtop MUST BE an lvalue) */
3387 vtop
->r
&= ~VT_LVAL
;
3388 /* tricky: if saved lvalue, then we can go back to lvalue */
3389 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
3390 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
3393 #ifdef CONFIG_TCC_BCHECK
3394 /* generate lvalue bound code */
3399 vtop
->r
&= ~VT_MUSTBOUND
;
3400 /* if lvalue, then use checking code before dereferencing */
3401 if (vtop
->r
& VT_LVAL
) {
3402 /* if not VT_BOUNDED value, then make one */
3403 if (!(vtop
->r
& VT_BOUNDED
)) {
3404 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
3405 /* must save type because we must set it to int to get pointer */
3410 gen_bounded_ptr_add();
3411 vtop
->r
|= lval_type
;
3414 /* then check for dereferencing */
3415 gen_bounded_ptr_deref();
3420 /* store vtop a register belonging to class 'rc'. lvalues are
3421 converted to values. Cannot be used if cannot be converted to
3422 register value (such as structures). */
3425 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
3426 unsigned long long ll
;
3428 /* NOTE: get_reg can modify vstack[] */
3429 if (vtop
->t
& VT_BITFIELD
) {
3430 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
3431 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3432 /* remove bit field info to avoid loops */
3433 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3434 /* generate shifts */
3435 vpushi(32 - (bit_pos
+ bit_size
));
3437 vpushi(32 - bit_size
);
3438 /* NOTE: transformed to SHR if unsigned */
3442 if (is_float(vtop
->t
) &&
3443 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3446 unsigned long offset
;
3448 /* XXX: unify with initializers handling ? */
3449 /* CPUs usually cannot use float constants, so we store them
3450 generically in data segment */
3451 size
= type_size(vtop
->t
, &align
);
3452 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
3453 data_section
->data_offset
= offset
;
3454 /* XXX: not portable yet */
3455 ptr
= section_ptr_add(data_section
, size
);
3458 ptr
[i
] = vtop
->c
.tab
[i
];
3459 sym
= get_sym_ref(vtop
->t
, data_section
, offset
, size
<< 2);
3460 vtop
->r
|= VT_LVAL
| VT_SYM
;
3464 #ifdef CONFIG_TCC_BCHECK
3465 if (vtop
->r
& VT_MUSTBOUND
)
3469 r
= vtop
->r
& VT_VALMASK
;
3470 /* need to reload if:
3472 - lvalue (need to dereference pointer)
3473 - already a register, but not in the right class */
3474 if (r
>= VT_CONST
||
3475 (vtop
->r
& VT_LVAL
) ||
3476 !(reg_classes
[r
] & rc
) ||
3477 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
3478 !(reg_classes
[vtop
->r2
] & rc
))) {
3480 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
3481 /* two register type load : expand to two words
3483 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3486 vtop
->c
.ui
= ll
; /* first word */
3488 vtop
->r
= r
; /* save register value */
3489 vpushi(ll
>> 32); /* second word */
3490 } else if (r
>= VT_CONST
||
3491 (vtop
->r
& VT_LVAL
)) {
3492 /* load from memory */
3495 vtop
[-1].r
= r
; /* save register value */
3496 /* increment pointer to get second word */
3503 /* move registers */
3506 vtop
[-1].r
= r
; /* save register value */
3507 vtop
->r
= vtop
[-1].r2
;
3509 /* allocate second register */
3516 /* write second register */
3518 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
3520 /* lvalue of scalar type : need to use lvalue type
3521 because of possible cast */
3524 /* compute memory access type */
3525 if (vtop
->r
& VT_LVAL_BYTE
)
3527 else if (vtop
->r
& VT_LVAL_SHORT
)
3529 if (vtop
->r
& VT_LVAL_UNSIGNED
)
3533 /* restore wanted type */
3536 /* one register type load */
3545 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3546 void gv2(int rc1
, int rc2
)
3550 /* generate more generic register first. But VT_JMP or VT_CMP
3551 values must be generated first in all cases to avoid possible
3553 v
= vtop
[0].r
& VT_VALMASK
;
3554 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
3559 /* test if reload is needed for first register */
3560 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
3570 /* test if reload is needed for first register */
3571 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
3577 /* expand long long on stack in two int registers */
3582 u
= vtop
->t
& VT_UNSIGNED
;
3585 vtop
[0].r
= vtop
[-1].r2
;
3586 vtop
[0].r2
= VT_CONST
;
3587 vtop
[-1].r2
= VT_CONST
;
3588 vtop
[0].t
= VT_INT
| u
;
3589 vtop
[-1].t
= VT_INT
| u
;
3592 /* build a long long from two ints */
3595 gv2(RC_INT
, RC_INT
);
3596 vtop
[-1].r2
= vtop
[0].r
;
3601 /* rotate n first stack elements to the bottom */
3608 for(i
=-n
+1;i
!=0;i
++)
3609 vtop
[i
] = vtop
[i
+1];
3613 /* pop stack value */
3617 v
= vtop
->r
& VT_VALMASK
;
3618 #ifdef TCC_TARGET_I386
3619 /* for x86, we need to pop the FP stack */
3620 if (v
== REG_ST0
&& !nocode_wanted
) {
3621 o(0xd9dd); /* fstp %st(1) */
3624 if (v
== VT_JMP
|| v
== VT_JMPI
) {
3625 /* need to put correct jump if && or || without test */
3631 /* convert stack entry to register and duplicate its value in another
3639 if ((t
& VT_BTYPE
) == VT_LLONG
) {
3646 /* stack: H L L1 H1 */
3654 /* duplicate value */
3665 load(r1
, &sv
); /* move r to r1 */
3667 /* duplicates value */
3672 /* generate CPU independent (unsigned) long long operations */
3673 void gen_opl(int op
)
3675 int t
, a
, b
, op1
, c
, i
;
3683 func
= TOK___divdi3
;
3686 func
= TOK___udivdi3
;
3689 func
= TOK___moddi3
;
3692 func
= TOK___umoddi3
;
3694 /* call generic long long function */
3695 gfunc_start(&gf
, FUNC_CDECL
);
3698 vpush_global_sym(func_old_type
, func
);
3702 vtop
->r2
= REG_LRET
;
3715 /* stack: L1 H1 L2 H2 */
3720 vtop
[-2] = vtop
[-3];
3723 /* stack: H1 H2 L1 L2 */
3729 /* stack: H1 H2 L1 L2 ML MH */
3732 /* stack: ML MH H1 H2 L1 L2 */
3736 /* stack: ML MH H1 L2 H2 L1 */
3741 /* stack: ML MH M1 M2 */
3744 } else if (op
== '+' || op
== '-') {
3745 /* XXX: add non carry method too (for MIPS or alpha) */
3751 /* stack: H1 H2 (L1 op L2) */
3754 gen_op(op1
+ 1); /* TOK_xxxC2 */
3757 /* stack: H1 H2 (L1 op L2) */
3760 /* stack: (L1 op L2) H1 H2 */
3762 /* stack: (L1 op L2) (H1 op H2) */
3770 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3775 /* stack: L H shift */
3777 /* constant: simpler */
3778 /* NOTE: all comments are for SHL. the other cases are
3779 done by swaping words */
3790 if (op
!= TOK_SAR
) {
3823 /* XXX: should provide a faster fallback on x86 ? */
3826 func
= TOK___sardi3
;
3829 func
= TOK___shrdi3
;
3832 func
= TOK___shldi3
;
3838 /* compare operations */
3844 /* stack: L1 H1 L2 H2 */
3846 vtop
[-1] = vtop
[-2];
3848 /* stack: L1 L2 H1 H2 */
3851 /* when values are equal, we need to compare low words. since
3852 the jump is inverted, we invert the test too. */
3855 else if (op1
== TOK_GT
)
3857 else if (op1
== TOK_ULT
)
3859 else if (op1
== TOK_UGT
)
3864 if (op1
!= TOK_NE
) {
3868 /* generate non equal test */
3869 /* XXX: NOT PORTABLE yet */
3873 #ifdef TCC_TARGET_I386
3874 b
= psym(0x850f, 0);
3876 error("not implemented");
3884 vset(VT_INT
, VT_JMPI
, a
);
3889 /* handle integer constant optimizations and various machine
3891 void gen_opic(int op
)
3898 /* currently, we cannot do computations with forward symbols */
3899 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3900 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3904 case '+': v1
->c
.i
+= fc
; break;
3905 case '-': v1
->c
.i
-= fc
; break;
3906 case '&': v1
->c
.i
&= fc
; break;
3907 case '^': v1
->c
.i
^= fc
; break;
3908 case '|': v1
->c
.i
|= fc
; break;
3909 case '*': v1
->c
.i
*= fc
; break;
3916 /* if division by zero, generate explicit division */
3919 error("division by zero in constant");
3923 default: v1
->c
.i
/= fc
; break;
3924 case '%': v1
->c
.i
%= fc
; break;
3925 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3926 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3929 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3930 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3931 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3933 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3934 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3935 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3936 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3937 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3938 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3939 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3940 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3941 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3942 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3944 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3945 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3951 /* if commutative ops, put c2 as constant */
3952 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3953 op
== '|' || op
== '*')) {
3958 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3961 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3962 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3968 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3969 /* try to use shifts instead of muls or divs */
3970 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3979 else if (op
== TOK_PDIV
)
3985 } else if (c2
&& (op
== '+' || op
== '-') &&
3986 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
3987 (VT_CONST
| VT_SYM
)) {
3988 /* symbol + constant case */
3995 if (!nocode_wanted
) {
3996 /* call low level op generator */
4005 /* generate a floating point operation with constant propagation */
4006 void gen_opif(int op
)
4014 /* currently, we cannot do computations with forward symbols */
4015 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4016 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4018 if (v1
->t
== VT_FLOAT
) {
4021 } else if (v1
->t
== VT_DOUBLE
) {
4029 /* NOTE: we only do constant propagation if finite number (not
4030 NaN or infinity) (ANSI spec) */
4031 if (!ieee_finite(f1
) || !ieee_finite(f2
))
4035 case '+': f1
+= f2
; break;
4036 case '-': f1
-= f2
; break;
4037 case '*': f1
*= f2
; break;
4041 error("division by zero in constant");
4046 /* XXX: also handles tests ? */
4050 /* XXX: overflow test ? */
4051 if (v1
->t
== VT_FLOAT
) {
4053 } else if (v1
->t
== VT_DOUBLE
) {
4061 if (!nocode_wanted
) {
4069 int pointed_size(int t
)
4071 return type_size(pointed_type(t
), &t
);
4075 void check_pointer_types(SValue
*p1
, SValue
*p2
)
4077 char buf1
[256], buf2
[256];
4081 if (!is_compatible_types(t1
, t2
)) {
4082 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
4083 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
4084 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
4089 /* generic gen_op: handles types problems */
4092 int u
, t1
, t2
, bt1
, bt2
, t
;
4096 bt1
= t1
& VT_BTYPE
;
4097 bt2
= t2
& VT_BTYPE
;
4099 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
4100 /* at least one operand is a pointer */
4101 /* relationnal op: must be both pointers */
4102 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4103 // check_pointer_types(vtop, vtop - 1);
4104 /* pointers are handled are unsigned */
4105 t
= VT_INT
| VT_UNSIGNED
;
4108 /* if both pointers, then it must be the '-' op */
4109 if ((t1
& VT_BTYPE
) == VT_PTR
&&
4110 (t2
& VT_BTYPE
) == VT_PTR
) {
4112 error("cannot use pointers here");
4113 // check_pointer_types(vtop - 1, vtop);
4114 /* XXX: check that types are compatible */
4115 u
= pointed_size(t1
);
4117 /* set to integer type */
4122 /* exactly one pointer : must be '+' or '-'. */
4123 if (op
!= '-' && op
!= '+')
4124 error("cannot use pointers here");
4125 /* Put pointer as first operand */
4126 if ((t2
& VT_BTYPE
) == VT_PTR
) {
4130 /* XXX: cast to int ? (long long case) */
4131 vpushi(pointed_size(vtop
[-1].t
));
4133 #ifdef CONFIG_TCC_BCHECK
4134 /* if evaluating constant expression, no code should be
4135 generated, so no bound check */
4136 if (do_bounds_check
&& !const_wanted
) {
4137 /* if bounded pointers, we generate a special code to
4144 gen_bounded_ptr_add();
4150 /* put again type if gen_opic() swaped operands */
4153 } else if (is_float(bt1
) || is_float(bt2
)) {
4154 /* compute bigger type and do implicit casts */
4155 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
4157 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
4162 /* floats can only be used for a few operations */
4163 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
4164 (op
< TOK_ULT
|| op
> TOK_GT
))
4165 error("invalid operands for binary operation");
4167 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
4168 /* cast to biggest op */
4170 /* convert to unsigned if it does not fit in a long long */
4171 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4172 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4176 /* integer operations */
4178 /* convert to unsigned if it does not fit in an integer */
4179 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4180 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4183 /* XXX: currently, some unsigned operations are explicit, so
4184 we modify them here */
4185 if (t
& VT_UNSIGNED
) {
4192 else if (op
== TOK_LT
)
4194 else if (op
== TOK_GT
)
4196 else if (op
== TOK_LE
)
4198 else if (op
== TOK_GE
)
4204 /* special case for shifts and long long: we keep the shift as
4206 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
4212 else if ((t
& VT_BTYPE
) == VT_LLONG
)
4216 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4217 /* relationnal op: the result is an int */
4225 /* generic itof for unsigned long long case */
4226 void gen_cvt_itof1(int t
)
4230 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
4231 (VT_LLONG
| VT_UNSIGNED
)) {
4233 gfunc_start(&gf
, FUNC_CDECL
);
4236 vpush_global_sym(func_old_type
, TOK___ulltof
);
4237 else if (t
== VT_DOUBLE
)
4238 vpush_global_sym(func_old_type
, TOK___ulltod
);
4240 vpush_global_sym(func_old_type
, TOK___ulltold
);
4249 /* generic ftoi for unsigned long long case */
4250 void gen_cvt_ftoi1(int t
)
4255 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
4256 /* not handled natively */
4257 gfunc_start(&gf
, FUNC_CDECL
);
4258 st
= vtop
->t
& VT_BTYPE
;
4261 vpush_global_sym(func_old_type
, TOK___fixunssfdi
);
4262 else if (st
== VT_DOUBLE
)
4263 vpush_global_sym(func_old_type
, TOK___fixunsdfdi
);
4265 vpush_global_sym(func_old_type
, TOK___fixunsxfdi
);
4269 vtop
->r2
= REG_LRET
;
4275 /* force char or short cast */
4276 void force_charshort_cast(int t
)
4280 /* XXX: add optimization if lvalue : just change type and offset */
4285 if (t
& VT_UNSIGNED
) {
4286 vpushi((1 << bits
) - 1);
4297 /* cast 'vtop' to 't' type */
4298 void gen_cast(int t
)
4300 int sbt
, dbt
, sf
, df
, c
;
4302 /* special delayed cast for char/short */
4303 /* XXX: in some cases (multiple cascaded casts), it may still
4305 if (vtop
->r
& VT_MUSTCAST
) {
4306 vtop
->r
&= ~VT_MUSTCAST
;
4307 force_charshort_cast(vtop
->t
);
4310 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
4311 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
4313 if (sbt
!= dbt
&& !nocode_wanted
) {
4316 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4318 /* convert from fp to fp */
4320 /* constant case: we can do it now */
4321 /* XXX: in ISOC, cannot do it if error in convert */
4322 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
4323 vtop
->c
.f
= (float)vtop
->c
.d
;
4324 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
4325 vtop
->c
.f
= (float)vtop
->c
.ld
;
4326 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
4327 vtop
->c
.d
= (double)vtop
->c
.f
;
4328 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
4329 vtop
->c
.d
= (double)vtop
->c
.ld
;
4330 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
4331 vtop
->c
.ld
= (long double)vtop
->c
.f
;
4332 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
4333 vtop
->c
.ld
= (long double)vtop
->c
.d
;
4335 /* non constant case: generate code */
4339 /* convert int to fp */
4342 case VT_LLONG
| VT_UNSIGNED
:
4344 /* XXX: add const cases for long long */
4346 case VT_INT
| VT_UNSIGNED
:
4348 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
4349 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
4350 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
4355 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
4356 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
4357 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
4366 /* convert fp to int */
4367 /* we handle char/short/etc... with generic code */
4368 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
4369 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
4374 case VT_LLONG
| VT_UNSIGNED
:
4376 /* XXX: add const cases for long long */
4378 case VT_INT
| VT_UNSIGNED
:
4380 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4381 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4382 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4388 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4389 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4390 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4398 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
4399 /* additionnal cast for char/short/bool... */
4403 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
4404 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
4405 /* scalar to long long */
4407 if (sbt
== (VT_INT
| VT_UNSIGNED
))
4408 vtop
->c
.ll
= vtop
->c
.ui
;
4410 vtop
->c
.ll
= vtop
->c
.i
;
4412 /* machine independant conversion */
4414 /* generate high word */
4415 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
4423 /* patch second register */
4424 vtop
[-1].r2
= vtop
->r
;
4428 } else if (dbt
== VT_BOOL
) {
4429 /* scalar to bool */
4432 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
4433 (dbt
& VT_BTYPE
) == VT_SHORT
) {
4434 force_charshort_cast(t
);
4435 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
4437 if (sbt
== VT_LLONG
) {
4438 /* from long long: just take low order word */
4442 /* if lvalue and single word type, nothing to do because
4443 the lvalue already contains the real type size (see
4444 VT_LVAL_xxx constants) */
4450 /* return type size. Put alignment at 'a' */
4451 int type_size(int t
, int *a
)
4457 if (bt
== VT_STRUCT
) {
4459 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4460 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
4462 } else if (bt
== VT_PTR
) {
4464 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4465 return type_size(s
->t
, a
) * s
->c
;
4470 } else if (bt
== VT_LDOUBLE
) {
4472 return LDOUBLE_SIZE
;
4473 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
4476 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
4479 } else if (bt
== VT_SHORT
) {
4483 /* char, void, function, _Bool */
4489 /* return the pointed type of t */
4490 int pointed_type(int t
)
4493 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4494 return s
->t
| (t
& ~VT_TYPE
);
4497 int mk_pointer(int t
)
4501 sym_push(p
, t
, 0, -1);
4502 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
4505 int is_compatible_types(int t1
, int t2
)
4512 bt1
= t1
& VT_BTYPE
;
4513 bt2
= t2
& VT_BTYPE
;
4514 if (bt1
== VT_PTR
) {
4515 t1
= pointed_type(t1
);
4516 /* if function, then convert implicitely to function pointer */
4517 if (bt2
!= VT_FUNC
) {
4520 t2
= pointed_type(t2
);
4522 /* void matches everything */
4525 if (t1
== VT_VOID
|| t2
== VT_VOID
)
4527 return is_compatible_types(t1
, t2
);
4528 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4530 } else if (bt1
== VT_FUNC
) {
4533 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
4534 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
4535 if (!is_compatible_types(s1
->t
, s2
->t
))
4537 /* XXX: not complete */
4538 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
4542 while (s1
!= NULL
) {
4545 if (!is_compatible_types(s1
->t
, s2
->t
))
4554 /* XXX: not complete */
4559 /* print a type. If 'varstr' is not NULL, then the variable is also
4560 printed in the type */
4562 /* XXX: add array and function pointers */
4563 void type_to_str(char *buf
, int buf_size
,
4564 int t
, const char *varstr
)
4574 if (t
& VT_UNSIGNED
)
4575 pstrcat(buf
, buf_size
, "unsigned ");
4605 tstr
= "long double";
4607 pstrcat(buf
, buf_size
, tstr
);
4611 if (bt
== VT_STRUCT
)
4615 pstrcat(buf
, buf_size
, tstr
);
4616 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
4617 if (v
>= SYM_FIRST_ANOM
)
4618 pstrcat(buf
, buf_size
, "<anonymous>");
4620 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
4623 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4624 type_to_str(buf
, buf_size
, s
->t
, varstr
);
4625 pstrcat(buf
, buf_size
, "(");
4627 while (sa
!= NULL
) {
4628 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
4629 pstrcat(buf
, buf_size
, buf1
);
4632 pstrcat(buf
, buf_size
, ", ");
4634 pstrcat(buf
, buf_size
, ")");
4637 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4638 pstrcpy(buf1
, sizeof(buf1
), "*");
4640 pstrcat(buf1
, sizeof(buf1
), varstr
);
4641 type_to_str(buf
, buf_size
, s
->t
, buf1
);
4645 pstrcat(buf
, buf_size
, " ");
4646 pstrcat(buf
, buf_size
, varstr
);
4651 /* verify type compatibility to store vtop in 'dt' type, and generate
4653 void gen_assign_cast(int dt
)
4656 char buf1
[256], buf2
[256];
4658 st
= vtop
->t
; /* source type */
4659 if ((dt
& VT_BTYPE
) == VT_PTR
) {
4660 /* special cases for pointers */
4661 /* a function is implicitely a function pointer */
4662 if ((st
& VT_BTYPE
) == VT_FUNC
) {
4663 if (!is_compatible_types(pointed_type(dt
), st
))
4668 /* '0' can also be a pointer */
4669 if ((st
& VT_BTYPE
) == VT_INT
&&
4670 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
4674 if (!is_compatible_types(dt
, st
)) {
4676 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
4677 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
4678 error("cannot cast '%s' to '%s'", buf1
, buf2
);
4684 /* store vtop in lvalue pushed on stack */
4687 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
4691 sbt
= vtop
->t
& VT_BTYPE
;
4692 dbt
= ft
& VT_BTYPE
;
4693 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
4694 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
4695 /* optimize char/short casts */
4696 delayed_cast
= VT_MUSTCAST
;
4697 vtop
->t
= ft
& VT_TYPE
;
4700 gen_assign_cast(ft
& VT_TYPE
);
4703 if (sbt
== VT_STRUCT
) {
4704 /* if structure, only generate pointer */
4705 /* structure assignment : generate memcpy */
4706 /* XXX: optimize if small size */
4707 if (!nocode_wanted
) {
4709 gfunc_start(&gf
, FUNC_CDECL
);
4711 size
= type_size(vtop
->t
, &align
);
4725 vpush_global_sym(func_old_type
, TOK_memcpy
);
4731 /* leave source on stack */
4732 } else if (ft
& VT_BITFIELD
) {
4733 /* bitfield store handling */
4734 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
4735 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4736 /* remove bit field info to avoid loops */
4737 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4739 /* duplicate destination */
4741 vtop
[-1] = vtop
[-2];
4743 /* mask and shift source */
4744 vpushi((1 << bit_size
) - 1);
4748 /* load destination, mask and or with source */
4750 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4756 #ifdef CONFIG_TCC_BCHECK
4757 /* bound check case */
4758 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4764 if (!nocode_wanted
) {
4768 r
= gv(rc
); /* generate value */
4769 /* if lvalue was saved on stack, must read it */
4770 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4772 t
= get_reg(RC_INT
);
4774 sv
.r
= VT_LOCAL
| VT_LVAL
;
4775 sv
.c
.ul
= vtop
[-1].c
.ul
;
4777 vtop
[-1].r
= t
| VT_LVAL
;
4780 /* two word case handling : store second register at word + 4 */
4781 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4783 /* convert to int to increment easily */
4790 /* XXX: it works because r2 is spilled last ! */
4791 store(vtop
->r2
, vtop
- 1);
4795 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4796 vtop
->r
|= delayed_cast
;
4800 /* post defines POST/PRE add. c is the token ++ or -- */
4801 void inc(int post
, int c
)
4804 vdup(); /* save lvalue */
4806 gv_dup(); /* duplicate value */
4811 vpushi(c
- TOK_MID
);
4813 vstore(); /* store value */
4815 vpop(); /* if post op, return saved value */
4818 /* Parse GNUC __attribute__ extension. Currently, the following
4819 extensions are recognized:
4820 - aligned(n) : set data/function alignment.
4821 - section(x) : generate data/code in this section.
4822 - unused : currently ignored, but may be used someday.
4824 void parse_attribute(AttributeDef
*ad
)
4831 while (tok
!= ')') {
4832 if (tok
< TOK_IDENT
)
4833 expect("attribute name");
4838 case TOK___SECTION__
:
4841 expect("section name");
4842 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
4847 case TOK___ALIGNED__
:
4850 if (n
<= 0 || (n
& (n
- 1)) != 0)
4851 error("alignment must be a positive power of two");
4856 case TOK___UNUSED__
:
4857 /* currently, no need to handle it because tcc does not
4858 track unused objects */
4861 case TOK___NORETURN__
:
4862 /* currently, no need to handle it because tcc does not
4863 track unused objects */
4868 ad
->func_call
= FUNC_CDECL
;
4872 case TOK___STDCALL__
:
4873 ad
->func_call
= FUNC_STDCALL
;
4876 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4877 /* skip parameters */
4878 /* XXX: skip parenthesis too */
4881 while (tok
!= ')' && tok
!= -1)
4895 /* enum/struct/union declaration */
4896 int struct_decl(int u
)
4898 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4899 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4903 a
= tok
; /* save decl type */
4908 /* struct already defined ? return it */
4909 /* XXX: check consistency */
4910 s
= sym_find(v
| SYM_STRUCT
);
4913 error("invalid type");
4919 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4920 /* put struct/union/enum name in type */
4922 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4927 error("struct/union/enum already defined");
4928 /* cannot be empty */
4935 if (a
== TOK_ENUM
) {
4942 /* enum symbols have static storage */
4943 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4948 parse_btype(&b
, &ad
);
4953 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4954 if ((t
& VT_BTYPE
) == VT_FUNC
||
4955 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4956 error("invalid type for '%s'",
4957 get_tok_str(v
, NULL
));
4963 bit_size
= expr_const();
4964 /* XXX: handle v = 0 case for messages */
4966 error("negative width in bit-field '%s'",
4967 get_tok_str(v
, NULL
));
4968 if (v
&& bit_size
== 0)
4969 error("zero width for bit-field '%s'",
4970 get_tok_str(v
, NULL
));
4972 size
= type_size(t
, &align
);
4974 if (bit_size
>= 0) {
4979 error("bitfields must have scalar type");
4981 if (bit_size
> bsize
) {
4982 error("width of '%s' exceeds its type",
4983 get_tok_str(v
, NULL
));
4984 } else if (bit_size
== bsize
) {
4985 /* no need for bit fields */
4987 } else if (bit_size
== 0) {
4988 /* XXX: what to do if only padding in a
4990 /* zero size: means to pad */
4994 /* we do not have enough room ? */
4995 if ((bit_pos
+ bit_size
) > bsize
)
4998 /* XXX: handle LSB first */
5000 (bit_pos
<< VT_STRUCT_SHIFT
) |
5001 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
5002 bit_pos
+= bit_size
;
5008 /* add new memory data only if starting
5010 if (lbit_pos
== 0) {
5011 if (a
== TOK_STRUCT
) {
5012 c
= (c
+ align
- 1) & -align
;
5020 if (align
> maxalign
)
5024 printf("add field %s offset=%d",
5025 get_tok_str(v
, NULL
), offset
);
5026 if (t
& VT_BITFIELD
) {
5027 printf(" pos=%d size=%d",
5028 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
5029 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
5033 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
5037 if (tok
== ';' || tok
== -1)
5047 /* size for struct/union, dummy for enum */
5048 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
5053 /* return 0 if no type declaration. otherwise, return the basic type
5056 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
5058 int t
, u
, type_found
;
5061 memset(ad
, 0, sizeof(AttributeDef
));
5072 if ((t
& VT_BTYPE
) != 0)
5073 error("too many basic types");
5087 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
5088 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5089 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
5090 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
5104 if ((t
& VT_BTYPE
) == VT_LONG
) {
5105 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5112 u
= struct_decl(VT_ENUM
);
5116 u
= struct_decl(VT_STRUCT
);
5119 /* type modifiers */
5124 case TOK___SIGNED__
:
5127 case TOK___INLINE__
:
5149 /* GNUC attribute */
5150 case TOK___ATTRIBUTE__
:
5151 parse_attribute(ad
);
5156 u
= parse_expr_type();
5160 if (!s
|| !(s
->t
& VT_TYPEDEF
))
5162 t
|= (s
->t
& ~VT_TYPEDEF
);
5169 /* long is never used as type */
5170 if ((t
& VT_BTYPE
) == VT_LONG
)
5171 t
= (t
& ~VT_BTYPE
) | VT_INT
;
5176 int post_type(int t
, AttributeDef
*ad
)
5178 int p
, n
, pt
, l
, t1
;
5179 Sym
**plast
, *s
, *first
;
5183 /* function declaration */
5188 while (tok
!= ')') {
5189 /* read param name and compute offset */
5190 if (l
!= FUNC_OLD
) {
5191 if (!parse_btype(&pt
, &ad1
)) {
5193 error("invalid type");
5200 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5202 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
5203 if ((pt
& VT_BTYPE
) == VT_VOID
)
5204 error("parameter declared as void");
5211 /* array must be transformed to pointer according to ANSI C */
5213 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
5218 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5225 /* if no parameters, then old type prototype */
5229 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5230 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
5231 /* we push a anonymous symbol which will contain the function prototype */
5233 s
= sym_push(p
, t
, ad
->func_call
, l
);
5235 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
5236 } else if (tok
== '[') {
5237 /* array definition */
5243 error("invalid array size");
5246 /* parse next post type */
5247 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5248 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
5250 /* we push a anonymous symbol which will contain the array
5253 sym_push(p
, t
, 0, n
);
5254 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
5259 /* Read a type declaration (except basic type), and return the
5260 type. 'td' is a bitmask indicating which kind of type decl is
5261 expected. 't' should contain the basic type. 'ad' is the attribute
5262 definition of the basic type. It can be modified by type_decl(). */
5263 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
5268 while (tok
== '*') {
5270 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
5275 /* recursive type */
5276 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5279 /* XXX: this is not correct to modify 'ad' at this point, but
5280 the syntax is not clear */
5281 if (tok
== TOK___ATTRIBUTE__
)
5282 parse_attribute(ad
);
5283 u
= type_decl(ad
, v
, 0, td
);
5287 /* type identifier */
5288 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
5292 if (!(td
& TYPE_ABSTRACT
))
5293 expect("identifier");
5297 /* append t at the end of u */
5298 t
= post_type(t
, ad
);
5299 if (tok
== TOK___ATTRIBUTE__
)
5300 parse_attribute(ad
);
5305 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
5315 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5316 static int lvalue_type(int t
)
5323 else if (bt
== VT_SHORT
)
5327 if (t
& VT_UNSIGNED
)
5328 r
|= VT_LVAL_UNSIGNED
;
5332 /* indirection with full error checking and bound check */
5333 static void indir(void)
5335 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
5337 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
5339 vtop
->t
= pointed_type(vtop
->t
);
5340 /* an array is never an lvalue */
5341 if (!(vtop
->t
& VT_ARRAY
)) {
5342 vtop
->r
|= lvalue_type(vtop
->t
);
5343 /* if bound checking, the referenced pointer must be checked */
5344 if (do_bounds_check
)
5345 vtop
->r
|= VT_MUSTBOUND
;
5349 /* pass a parameter to a function and do type checking and casting */
5350 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
5353 func_type
= func
->c
;
5354 if (func_type
== FUNC_OLD
||
5355 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5356 /* default casting : only need to convert float to double */
5357 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
5358 gen_cast(VT_DOUBLE
);
5359 } else if (arg
== NULL
) {
5360 error("too many arguments to function");
5362 gen_assign_cast(arg
->t
);
5364 if (!nocode_wanted
) {
5371 /* parse an expression of the form '(type)' or '(expr)' and return its
5373 static int parse_expr_type(void)
5379 if (parse_btype(&ft
, &ad
)) {
5380 ft
= type_decl(&ad
, &n
, ft
, TYPE_ABSTRACT
);
5388 static void unary(void)
5390 int n
, t
, ft
, align
, size
, r
;
5395 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
5398 } else if (tok
== TOK_CUINT
) {
5399 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
5401 } else if (tok
== TOK_CLLONG
) {
5402 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
5404 } else if (tok
== TOK_CULLONG
) {
5405 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
5407 } else if (tok
== TOK_CFLOAT
) {
5408 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
5410 } else if (tok
== TOK_CDOUBLE
) {
5411 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
5413 } else if (tok
== TOK_CLDOUBLE
) {
5414 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
5416 } else if (tok
== TOK___FUNC__
|| (tok
== TOK___FUNCTION__
&& gnu_ext
)) {
5419 /* special function name identifier */
5421 len
= strlen(funcname
) + 1;
5422 /* generate char[len] type */
5423 t
= VT_ARRAY
| mk_pointer(VT_BYTE
);
5424 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5426 vpush_ref(t
, data_section
, data_section
->data_offset
, len
);
5427 ptr
= section_ptr_add(data_section
, len
);
5428 memcpy(ptr
, funcname
, len
);
5430 } else if (tok
== TOK_LSTR
) {
5433 } else if (tok
== TOK_STR
) {
5434 /* string parsing */
5437 t
= VT_ARRAY
| mk_pointer(t
);
5438 memset(&ad
, 0, sizeof(AttributeDef
));
5439 decl_initializer_alloc(t
, &ad
, VT_CONST
, 2, 0, 0);
5445 if (parse_btype(&t
, &ad
)) {
5446 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
5448 /* check ISOC99 compound literal */
5450 /* data is allocated locally by default */
5455 /* all except arrays are lvalues */
5456 if (!(ft
& VT_ARRAY
))
5457 r
|= lvalue_type(ft
);
5458 memset(&ad
, 0, sizeof(AttributeDef
));
5459 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
5468 } else if (t
== '*') {
5471 } else if (t
== '&') {
5473 /* functions names must be treated as function pointers,
5474 except for unary '&' and sizeof. Since we consider that
5475 functions are not lvalues, we only have to handle it
5476 there and in function calls. */
5477 /* arrays can also be used although they are not lvalues */
5478 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
5479 !(vtop
->t
& VT_ARRAY
))
5481 vtop
->t
= mk_pointer(vtop
->t
);
5483 } else if (t
== '!') {
5485 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
5486 vtop
->c
.i
= !vtop
->c
.i
;
5487 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
5488 vtop
->c
.i
= vtop
->c
.i
^ 1;
5490 vset(VT_INT
, VT_JMP
, gtst(1, 0));
5491 } else if (t
== '~') {
5495 } else if (t
== '+') {
5496 /* in order to force cast, we add zero */
5498 if ((vtop
->t
& VT_BTYPE
) == VT_PTR
)
5499 error("pointer not accepted for unary plus");
5502 } else if (t
== TOK_SIZEOF
|| t
== TOK_ALIGNOF
) {
5504 ft
= parse_expr_type();
5508 size
= type_size(ft
, &align
);
5509 if (t
== TOK_SIZEOF
)
5513 } else if (t
== TOK_INC
|| t
== TOK_DEC
) {
5516 } else if (t
== '-') {
5520 } else if (t
== TOK_LAND
&& gnu_ext
) {
5521 /* allow to take the address of a label */
5522 if (tok
< TOK_UIDENT
)
5523 expect("label identifier");
5524 s
= sym_find1(&label_stack
, tok
);
5526 s
= sym_push1(&label_stack
, tok
, 0, 0);
5527 s
->r
= LABEL_FORWARD
;
5530 s
->t
= mk_pointer(VT_VOID
) | VT_STATIC
;
5531 vset(s
->t
, VT_CONST
| VT_SYM
, 0);
5536 expect("identifier");
5540 error("'%s' undeclared", get_tok_str(t
, NULL
));
5541 /* for simple function calls, we tolerate undeclared
5542 external reference to int() function */
5543 s
= external_global_sym(t
, func_old_type
, 0);
5545 vset(s
->t
, s
->r
, s
->c
);
5546 /* if forward reference, we must point to s */
5547 if (vtop
->r
& VT_SYM
) {
5554 /* post operations */
5556 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
5559 } else if (tok
== '.' || tok
== TOK_ARROW
) {
5561 if (tok
== TOK_ARROW
)
5566 /* expect pointer on structure */
5567 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
5568 expect("struct or union");
5569 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5572 while ((s
= s
->next
) != NULL
) {
5577 error("field not found");
5578 /* add field offset to pointer */
5579 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
5582 /* change type to field type, and set to lvalue */
5584 /* an array is never an lvalue */
5585 if (!(vtop
->t
& VT_ARRAY
)) {
5586 vtop
->r
|= lvalue_type(vtop
->t
);
5587 /* if bound checking, the referenced pointer must be checked */
5588 if (do_bounds_check
)
5589 vtop
->r
|= VT_MUSTBOUND
;
5592 } else if (tok
== '[') {
5598 } else if (tok
== '(') {
5603 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
5604 /* pointer test (no array accepted) */
5605 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
5606 vtop
->t
= pointed_type(vtop
->t
);
5607 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
5611 expect("function pointer");
5614 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
5616 /* get return type */
5617 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
5618 if (!nocode_wanted
) {
5619 save_regs(0); /* save used temporary registers */
5620 gfunc_start(&gf
, s
->r
);
5623 sa
= s
->next
; /* first parameter */
5624 #ifdef INVERT_FUNC_PARAMS
5628 ParseState saved_parse_state
;
5631 /* read each argument and store it on a stack */
5637 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
5641 else if (tok
== ')')
5643 tok_str_add_tok(&str
);
5646 tok_str_add(&str
, -1); /* end of file added */
5647 tok_str_add(&str
, 0);
5648 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
5649 s1
->next
= sa
; /* add reference to argument */
5658 /* now generate code in reverse order by reading the stack */
5659 save_parse_state(&saved_parse_state
);
5661 macro_ptr
= (int *)args
->c
;
5665 expect("',' or ')'");
5666 gfunc_param_typed(&gf
, s
, args
->next
);
5668 tok_str_free((int *)args
->c
);
5672 restore_parse_state(&saved_parse_state
);
5675 /* compute first implicit argument if a structure is returned */
5676 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
5677 /* get some space for the returned structure */
5678 size
= type_size(s
->t
, &align
);
5679 loc
= (loc
- size
) & -align
;
5681 ret
.r
= VT_LOCAL
| VT_LVAL
;
5682 /* pass it as 'int' to avoid structure arg passing
5684 vset(VT_INT
, VT_LOCAL
, loc
);
5693 /* return in register */
5694 if (is_float(ret
.t
)) {
5697 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
5703 #ifndef INVERT_FUNC_PARAMS
5707 gfunc_param_typed(&gf
, s
, sa
);
5717 error("too few arguments to function");
5724 vsetc(ret
.t
, ret
.r
, &ret
.c
);
5732 static void uneq(void)
5738 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
5739 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
5740 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
5755 static void sum(int l
)
5763 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
5764 (l
== 1 && (tok
== '+' || tok
== '-')) ||
5765 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
5766 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
5767 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
5768 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
5769 (l
== 5 && tok
== '&') ||
5770 (l
== 6 && tok
== '^') ||
5771 (l
== 7 && tok
== '|') ||
5772 (l
== 8 && tok
== TOK_LAND
) ||
5773 (l
== 9 && tok
== TOK_LOR
)) {
5782 /* only used if non constant */
5783 static void eand(void)
5790 if (tok
!= TOK_LAND
) {
5793 vset(VT_INT
, VT_JMPI
, t
);
5803 static void eor(void)
5810 if (tok
!= TOK_LOR
) {
5813 vset(VT_INT
, VT_JMP
, t
);
5823 /* XXX: better constant handling */
5824 static void expr_eq(void)
5826 int tt
, u
, r1
, r2
, rc
, t1
, t2
, t
, bt1
, bt2
;
5848 save_regs(1); /* we need to save all registers here except
5849 at the top because it is a branch point */
5853 bt1
= t1
& VT_BTYPE
;
5854 sv
= *vtop
; /* save value to handle it later */
5855 vtop
--; /* no vpop so that FP stack is not flushed */
5863 bt2
= t2
& VT_BTYPE
;
5864 /* cast operands to correct type according to ISOC rules */
5865 if (is_float(bt1
) || is_float(bt2
)) {
5866 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5868 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5873 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5874 /* cast to biggest op */
5876 /* convert to unsigned if it does not fit in a long long */
5877 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5878 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5880 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5881 /* XXX: test pointer compatibility */
5883 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
5884 /* XXX: test structure compatibility */
5886 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
5887 /* NOTE: as an extension, we accept void on only one side */
5890 /* integer operations */
5892 /* convert to unsigned if it does not fit in an integer */
5893 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5894 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5898 /* now we convert second operand */
5903 } else if ((t
& VT_BTYPE
) == VT_LLONG
) {
5904 /* for long longs, we use fixed registers to avoid having
5905 to handle a complicated move */
5909 /* this is horrible, but we must also convert first
5913 /* put again first value and cast it */
5924 static void gexpr(void)
5935 /* parse an expression and return its type without any side effect. */
5936 static int expr_type(void)
5949 /* parse a unary expression and return its type without any side
5951 static int unary_type(void)
5964 /* parse a constant expression and return value in vtop. */
5965 static void expr_const1(void)
5974 /* parse an integer constant and return its value. */
5975 static int expr_const(void)
5979 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
5980 expect("constant expression");
5986 /* return the label token if current token is a label, otherwise
5988 static int is_label(void)
5993 /* fast test first */
5994 if (tok
< TOK_UIDENT
)
5996 /* no need to save tokc since we expect an identifier */
6004 /* XXX: may not work in all cases (macros ?) */
6013 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
6018 /* generate line number info */
6020 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
6021 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
6023 last_line_num
= file
->line_num
;
6026 if (tok
== TOK_IF
) {
6033 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6035 if (c
== TOK_ELSE
) {
6039 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6040 gsym(d
); /* patch else jmp */
6043 } else if (tok
== TOK_WHILE
) {
6051 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6055 } else if (tok
== '{') {
6058 s
= local_stack
.top
;
6059 while (tok
!= '}') {
6062 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6064 /* pop locally defined symbols */
6065 sym_pop(&local_stack
, s
);
6067 } else if (tok
== TOK_RETURN
) {
6071 gen_assign_cast(func_vt
);
6072 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
6073 /* if returning structure, must copy it to implicit
6074 first pointer arg location */
6075 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
6078 /* copy structure value to pointer */
6080 } else if (is_float(func_vt
)) {
6085 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6088 rsym
= gjmp(rsym
); /* jmp */
6089 } else if (tok
== TOK_BREAK
) {
6092 error("cannot break");
6093 *bsym
= gjmp(*bsym
);
6096 } else if (tok
== TOK_CONTINUE
) {
6099 error("cannot continue");
6100 *csym
= gjmp(*csym
);
6103 } else if (tok
== TOK_FOR
) {
6130 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6135 if (tok
== TOK_DO
) {
6140 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6151 if (tok
== TOK_SWITCH
) {
6155 /* XXX: other types than integer */
6156 case_reg
= gv(RC_INT
);
6160 b
= gjmp(0); /* jump to first case */
6162 block(&a
, csym
, &b
, &c
, case_reg
);
6163 /* if no default, jmp after switch */
6171 if (tok
== TOK_CASE
) {
6178 if (gnu_ext
&& tok
== TOK_DOTS
) {
6182 warning("empty case range");
6184 /* since a case is like a label, we must skip it with a jmp */
6187 vset(VT_INT
, case_reg
, 0);
6191 *case_sym
= gtst(1, 0);
6194 *case_sym
= gtst(1, 0);
6195 vset(VT_INT
, case_reg
, 0);
6198 *case_sym
= gtst(1, *case_sym
);
6202 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6204 if (tok
== TOK_DEFAULT
) {
6210 error("too many 'default'");
6212 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6214 if (tok
== TOK_GOTO
) {
6216 if (tok
== '*' && gnu_ext
) {
6220 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
6223 } else if (tok
>= TOK_UIDENT
) {
6224 s
= sym_find1(&label_stack
, tok
);
6225 /* put forward definition if needed */
6227 s
= sym_push1(&label_stack
, tok
, 0, 0);
6228 s
->r
= LABEL_FORWARD
;
6230 /* label already defined */
6231 if (s
->r
& LABEL_FORWARD
)
6232 s
->next
= (void *)gjmp((long)s
->next
);
6234 gjmp_addr((long)s
->next
);
6237 expect("label identifier");
6244 s
= sym_find1(&label_stack
, b
);
6246 if (!(s
->r
& LABEL_FORWARD
))
6247 error("multiple defined label");
6248 gsym((long)s
->next
);
6250 s
= sym_push1(&label_stack
, b
, 0, 0);
6252 s
->next
= (void *)ind
;
6254 /* we accept this, but it is a mistake */
6256 warning("deprecated use of label at end of compound statement");
6258 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6260 /* expression case */
6270 /* t is the array or struct type. c is the array or struct
6271 address. cur_index/cur_field is the pointer to the current
6272 value. 'size_only' is true if only size info is needed (only used
6274 static void decl_designator(int t
, Section
*sec
, unsigned long c
,
6275 int *cur_index
, Sym
**cur_field
,
6279 int notfirst
, index
, align
, l
;
6282 if (gnu_ext
&& (l
= is_label()) != 0)
6285 while (tok
== '[' || tok
== '.') {
6287 if (!(t
& VT_ARRAY
))
6288 expect("array type");
6289 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
6291 index
= expr_const();
6292 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
6293 expect("invalid index");
6297 t
= pointed_type(t
);
6298 c
+= index
* type_size(t
, &align
);
6304 if ((t
& VT_BTYPE
) != VT_STRUCT
)
6305 expect("struct/union type");
6306 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
6318 t
= f
->t
| (t
& ~VT_TYPE
);
6333 t
= pointed_type(t
);
6334 c
+= index
* type_size(t
, &align
);
6338 error("too many field init");
6339 t
= f
->t
| (t
& ~VT_TYPE
);
6343 decl_initializer(t
, sec
, c
, 0, size_only
);
6347 #define EXPR_CONST 1
6350 /* store a value or an expression directly in global data or in local array */
6351 static void init_putv(int t
, Section
*sec
, unsigned long c
,
6352 int v
, int expr_type
)
6354 int saved_global_expr
, bt
;
6362 /* compound literals must be allocated globally in this case */
6363 saved_global_expr
= global_expr
;
6366 global_expr
= saved_global_expr
;
6367 /* NOTE: symbols are accepted */
6368 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
6369 error("initializer element is not constant");
6377 /* XXX: not portable */
6378 /* XXX: generate error if incorrect relocation */
6381 ptr
= sec
->data
+ c
;
6382 if ((vtop
->r
& VT_SYM
) &&
6388 error("initializer element is not computable at load time");
6391 *(char *)ptr
= vtop
->c
.i
;
6394 *(short *)ptr
= vtop
->c
.i
;
6397 *(double *)ptr
= vtop
->c
.d
;
6400 *(long double *)ptr
= vtop
->c
.ld
;
6403 *(long long *)ptr
= vtop
->c
.ll
;
6406 if (vtop
->r
& VT_SYM
) {
6407 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
6409 *(int *)ptr
= vtop
->c
.i
;
6414 vset(t
, VT_LOCAL
, c
);
6421 /* put zeros for variable based init */
6422 static void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
6427 /* nothing to do because globals are already set to zero */
6429 gfunc_start(&gf
, FUNC_CDECL
);
6434 vset(VT_INT
, VT_LOCAL
, c
);
6436 vpush_global_sym(func_old_type
, TOK_memset
);
6441 /* 't' contains the type and storage info. 'c' is the offset of the
6442 object in section 'sec'. If 'sec' is NULL, it means stack based
6443 allocation. 'first' is true if array '{' must be read (multi
6444 dimension implicit array init handling). 'size_only' is true if
6445 size only evaluation is wanted (only for arrays). */
6446 static void decl_initializer(int t
, Section
*sec
, unsigned long c
,
6447 int first
, int size_only
)
6449 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
6450 int t1
, size1
, align1
, expr_type
;
6454 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
6457 t1
= pointed_type(t
);
6458 size1
= type_size(t1
, &align1
);
6461 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
6467 /* only parse strings here if correct type (otherwise: handle
6468 them as ((w)char *) expressions */
6469 if ((tok
== TOK_LSTR
&&
6470 (t1
& VT_BTYPE
) == VT_INT
) ||
6472 (t1
& VT_BTYPE
) == VT_BYTE
)) {
6473 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6478 /* compute maximum number of chars wanted */
6480 cstr_len
= cstr
->size
;
6482 cstr_len
= cstr
->size
/ sizeof(int);
6485 if (n
>= 0 && nb
> (n
- array_length
))
6486 nb
= n
- array_length
;
6489 warning("initializer-string for array is too long");
6490 /* in order to go faster for common case (char
6491 string in global variable, we handle it
6493 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
6494 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
6498 ch
= ((unsigned char *)cstr
->data
)[i
];
6500 ch
= ((int *)cstr
->data
)[i
];
6501 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
6509 /* only add trailing zero if enough storage (no
6510 warning in this case since it is standard) */
6511 if (n
< 0 || array_length
< n
) {
6513 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
6519 while (tok
!= '}') {
6520 decl_designator(t
, sec
, c
, &index
, NULL
, size_only
);
6521 if (n
>= 0 && index
>= n
)
6522 error("index too large");
6523 /* must put zero in holes (note that doing it that way
6524 ensures that it even works with designators) */
6525 if (!size_only
&& array_length
< index
) {
6526 init_putz(t1
, sec
, c
+ array_length
* size1
,
6527 (index
- array_length
) * size1
);
6530 if (index
> array_length
)
6531 array_length
= index
;
6532 /* special test for multi dimensional arrays (may not
6533 be strictly correct if designators are used at the
6535 if (index
>= n
&& no_oblock
)
6544 /* put zeros at the end */
6545 if (!size_only
&& n
>= 0 && array_length
< n
) {
6546 init_putz(t1
, sec
, c
+ array_length
* size1
,
6547 (n
- array_length
) * size1
);
6549 /* patch type size if needed */
6551 s
->c
= array_length
;
6552 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
6553 /* XXX: union needs only one init */
6555 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
6560 while (tok
!= '}') {
6561 decl_designator(t
, sec
, c
, NULL
, &f
, size_only
);
6562 /* fill with zero between fields */
6564 if (!size_only
&& array_length
< index
) {
6565 init_putz(t
, sec
, c
+ array_length
,
6566 index
- array_length
);
6568 index
= index
+ type_size(f
->t
, &align1
);
6569 if (index
> array_length
)
6570 array_length
= index
;
6576 /* put zeros at the end */
6577 if (!size_only
&& array_length
< n
) {
6578 init_putz(t
, sec
, c
+ array_length
,
6582 } else if (tok
== '{') {
6584 decl_initializer(t
, sec
, c
, first
, size_only
);
6586 } else if (size_only
) {
6587 /* just skip expression */
6589 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
6593 else if (tok
== ')')
6598 /* currently, we always use constant expression for globals
6599 (may change for scripting case) */
6600 expr_type
= EXPR_CONST
;
6602 expr_type
= EXPR_ANY
;
6603 init_putv(t
, sec
, c
, 0, expr_type
);
6607 /* parse an initializer for type 't' if 'has_init' is non zero, and
6608 allocate space in local or global data space ('r' is either
6609 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6610 variable 'v' of scope 'scope' is declared before initializers are
6611 parsed. If 'v' is zero, then a reference to the new object is put
6612 in the value stack. If 'has_init' is 2, a special parsing is done
6613 to handle string constants. */
6614 static void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
,
6615 int has_init
, int v
, int scope
)
6617 int size
, align
, addr
, data_offset
;
6619 ParseState saved_parse_state
;
6620 TokenString init_str
;
6623 size
= type_size(t
, &align
);
6624 /* If unknown size, we must evaluate it before
6625 evaluating initializers because
6626 initializers can generate global data too
6627 (e.g. string pointers or ISOC99 compound
6628 literals). It also simplifies local
6629 initializers handling */
6630 tok_str_new(&init_str
);
6633 error("unknown type size");
6634 /* get all init string */
6635 if (has_init
== 2) {
6636 /* only get strings */
6637 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6638 tok_str_add_tok(&init_str
);
6643 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
6645 error("unexpected end of file in initializer");
6646 tok_str_add_tok(&init_str
);
6649 else if (tok
== '}') {
6657 tok_str_add(&init_str
, -1);
6658 tok_str_add(&init_str
, 0);
6661 save_parse_state(&saved_parse_state
);
6663 macro_ptr
= init_str
.str
;
6665 decl_initializer(t
, NULL
, 0, 1, 1);
6666 /* prepare second initializer parsing */
6667 macro_ptr
= init_str
.str
;
6670 /* if still unknown size, error */
6671 size
= type_size(t
, &align
);
6673 error("unknown type size");
6675 /* take into account specified alignment if bigger */
6676 if (ad
->aligned
> align
)
6677 align
= ad
->aligned
;
6678 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
6680 if (do_bounds_check
&& (t
& VT_ARRAY
))
6682 #ifdef TCC_TARGET_IL
6683 /* XXX: ugly patch to allocate local variables for IL, just
6688 loc
= (loc
- size
) & -align
;
6691 /* handles bounds */
6692 /* XXX: currently, since we do only one pass, we cannot track
6693 '&' operators, so we add only arrays */
6694 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
6695 unsigned long *bounds_ptr
;
6696 /* add padding between regions */
6698 /* then add local bound info */
6699 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
6700 bounds_ptr
[0] = addr
;
6701 bounds_ptr
[1] = size
;
6704 /* compute section */
6712 data_offset
= sec
->data_offset
;
6713 data_offset
= (data_offset
+ align
- 1) & -align
;
6715 /* very important to increment global pointer at this time
6716 because initializers themselves can create new initializers */
6717 data_offset
+= size
;
6718 /* add padding if bound check */
6719 if (do_bounds_check
)
6721 sec
->data_offset
= data_offset
;
6722 /* allocate section space to put the data */
6723 if (sec
->sh_type
!= SHT_NOBITS
&&
6724 data_offset
> sec
->data_allocated
)
6725 section_realloc(sec
, data_offset
);
6729 /* local variable */
6730 sym_push(v
, t
, r
, addr
);
6732 /* push local reference */
6739 if (scope
== VT_CONST
) {
6740 /* global scope: see if already defined */
6744 if (!is_compatible_types(sym
->t
, t
))
6745 error("incompatible types for redefinition of '%s'",
6746 get_tok_str(v
, NULL
));
6747 if (!(sym
->t
& VT_EXTERN
))
6748 error("redefinition of '%s'", get_tok_str(v
, NULL
));
6749 sym
->t
&= ~VT_EXTERN
;
6752 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
6754 put_extern_sym(sym
, sec
, addr
, size
);
6758 /* push global reference */
6759 sym
= get_sym_ref(t
, sec
, addr
, size
);
6761 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
6765 /* handles bounds now because the symbol must be defined
6766 before for the relocation */
6767 if (do_bounds_check
) {
6768 unsigned long *bounds_ptr
;
6770 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
6771 /* then add global bound info */
6772 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
6773 bounds_ptr
[0] = 0; /* relocated */
6774 bounds_ptr
[1] = size
;
6778 decl_initializer(t
, sec
, addr
, 1, 0);
6779 /* restore parse state if needed */
6781 tok_str_free(init_str
.str
);
6782 restore_parse_state(&saved_parse_state
);
6787 void put_func_debug(Sym
*sym
)
6792 /* XXX: we put here a dummy type */
6793 snprintf(buf
, sizeof(buf
), "%s:%c1",
6794 funcname
, sym
->t
& VT_STATIC
? 'f' : 'F');
6795 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
6796 cur_text_section
, sym
->c
);
6801 /* not finished : try to put some local vars in registers */
6802 //#define CONFIG_REG_VARS
6804 #ifdef CONFIG_REG_VARS
6805 void add_var_ref(int t
)
6807 printf("%s:%d: &%s\n",
6808 file
->filename
, file
->line_num
,
6809 get_tok_str(t
, NULL
));
6812 /* first pass on a function with heuristic to extract variable usage
6813 and pointer references to local variables for register allocation */
6814 void analyse_function(void)
6821 /* any symbol coming after '&' is considered as being a
6822 variable whose reference is taken. It is highly unaccurate
6823 but it is difficult to do better without a complete parse */
6826 /* if '& number', then no need to examine next tokens */
6827 if (tok
== TOK_CINT
||
6829 tok
== TOK_CLLONG
||
6830 tok
== TOK_CULLONG
) {
6832 } else if (tok
>= TOK_UIDENT
) {
6833 /* if '& ident [' or '& ident ->', then ident address
6837 if (tok
!= '[' && tok
!= TOK_ARROW
)
6841 while (tok
!= '}' && tok
!= ';' &&
6842 !((tok
== ',' || tok
== ')') && level
== 0)) {
6843 if (tok
>= TOK_UIDENT
) {
6845 } else if (tok
== '(') {
6847 } else if (tok
== ')') {
6860 /* parse an old style function declaration list */
6861 /* XXX: check multiple parameter */
6862 static void func_decl_list(Sym
*func_sym
)
6867 /* parse each declaration */
6868 while (tok
!= '{' && tok
!= ';' && tok
!= TOK_EOF
) {
6869 if (!parse_btype(&b
, &ad
))
6870 expect("declaration list");
6871 if (((b
& VT_BTYPE
) == VT_ENUM
||
6872 (b
& VT_BTYPE
) == VT_STRUCT
) &&
6874 /* we accept no variable after */
6877 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
6878 /* find parameter in function parameter list */
6881 if ((s
->v
& ~SYM_FIELD
) == v
)
6885 error("declaration for parameter '%s' but no such parameter",
6886 get_tok_str(v
, NULL
));
6888 /* check that no storage specifier except 'register' was given */
6889 if (t
& (VT_EXTERN
| VT_STATIC
| VT_TYPEDEF
))
6890 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
6891 /* we can add the type (NOTE: it could be local to the function) */
6893 /* accept other parameters */
6904 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6905 static void decl(int l
)
6907 int t
, b
, v
, has_init
, r
;
6912 if (!parse_btype(&b
, &ad
)) {
6913 /* skip redundant ';' */
6914 /* XXX: find more elegant solution */
6919 /* special test for old K&R protos without explicit int
6920 type. Only accepted when defining global data */
6921 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
6925 if (((b
& VT_BTYPE
) == VT_ENUM
||
6926 (b
& VT_BTYPE
) == VT_STRUCT
) &&
6928 /* we accept no variable after */
6932 while (1) { /* iterate thru each declaration */
6933 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
6937 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
6938 printf("type = '%s'\n", buf
);
6941 if ((t
& VT_BTYPE
) == VT_FUNC
) {
6942 /* if old style function prototype, we accept a
6944 sym
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
6945 if (sym
->c
== FUNC_OLD
)
6946 func_decl_list(sym
);
6950 #ifdef CONFIG_REG_VARS
6951 TokenString func_str
;
6952 ParseState saved_parse_state
;
6957 error("cannot use local functions");
6959 expect("function definition");
6961 #ifdef CONFIG_REG_VARS
6962 /* parse all function code and record it */
6964 tok_str_new(&func_str
);
6970 error("unexpected end of file");
6971 tok_str_add_tok(&func_str
);
6976 } else if (t
== '}') {
6978 if (block_level
== 0)
6982 tok_str_add(&func_str
, -1);
6983 tok_str_add(&func_str
, 0);
6985 save_parse_state(&saved_parse_state
);
6987 macro_ptr
= func_str
.str
;
6992 /* compute text section */
6993 cur_text_section
= ad
.section
;
6994 if (!cur_text_section
)
6995 cur_text_section
= text_section
;
6996 ind
= cur_text_section
->data_offset
;
6997 funcname
= get_tok_str(v
, NULL
);
7000 /* if symbol is already defined, then put complete type */
7003 /* put function symbol */
7004 sym
= sym_push1(&global_stack
, v
, t
, 0);
7006 /* NOTE: we patch the symbol size later */
7007 put_extern_sym(sym
, cur_text_section
, ind
, 0);
7009 sym
->r
= VT_SYM
| VT_CONST
;
7010 /* put debug symbol */
7012 put_func_debug(sym
);
7013 /* push a dummy symbol to enable local sym storage */
7014 sym_push1(&local_stack
, 0, 0, 0);
7018 #ifdef CONFIG_REG_VARS
7019 macro_ptr
= func_str
.str
;
7022 block(NULL
, NULL
, NULL
, NULL
, 0);
7025 cur_text_section
->data_offset
= ind
;
7026 /* look if any labels are undefined. Define symbols if
7027 '&&label' was used. */
7030 for(s
= label_stack
.top
; s
!= NULL
; s
= s
->prev
) {
7031 if (s
->r
& LABEL_FORWARD
) {
7032 error("label '%s' used but not defined",
7033 get_tok_str(s
->v
, NULL
));
7036 /* define corresponding symbol. A size of
7038 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
7042 sym_pop(&label_stack
, NULL
); /* reset label stack */
7043 sym_pop(&local_stack
, NULL
); /* reset local stack */
7044 /* end of function */
7045 /* patch symbol size */
7046 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
7049 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
7051 funcname
= ""; /* for safety */
7052 func_vt
= VT_VOID
; /* for safety */
7053 ind
= 0; /* for safety */
7055 #ifdef CONFIG_REG_VARS
7056 tok_str_free(func_str
.str
);
7057 restore_parse_state(&saved_parse_state
);
7061 if (b
& VT_TYPEDEF
) {
7062 /* save typedefed type */
7063 /* XXX: test storage specifiers ? */
7064 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
7065 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
7066 /* external function definition */
7067 external_sym(v
, t
, 0);
7069 /* not lvalue if array */
7071 if (!(t
& VT_ARRAY
))
7072 r
|= lvalue_type(t
);
7073 if (b
& VT_EXTERN
) {
7074 /* external variable */
7075 external_sym(v
, t
, r
);
7081 has_init
= (tok
== '=');
7084 decl_initializer_alloc(t
, &ad
, r
,
7098 /* free define stack until top reaches 'b' */
7099 static void free_defines(Sym
*b
)
7103 top
= define_stack
.top
;
7106 /* do not free args or predefined defines */
7108 tok_str_free((int *)top
->c
);
7109 sym_pop(&define_stack
, top1
);
7114 /* compile the C file opened in 'file'. Return non zero if errors. */
7115 static int tcc_compile(TCCState
*s1
)
7117 Sym
*define_start
, *sym
;
7119 volatile int section_sym
;
7123 printf("%s: **** new file\n", file
->filename
);
7126 s1
->include_stack_ptr
= s1
->include_stack
;
7127 /* XXX: move that before to avoid having to initialize
7128 file->ifdef_stack_ptr ? */
7129 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
7130 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
7132 /* XXX: not ANSI compliant: bound checking says error */
7134 anon_sym
= SYM_FIRST_ANOM
;
7136 /* file info: full path + filename */
7137 section_sym
= 0; /* avoid warning */
7139 section_sym
= put_elf_sym(symtab_section
, 0, 0,
7140 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
7141 text_section
->sh_num
, NULL
);
7142 getcwd(buf
, sizeof(buf
));
7143 pstrcat(buf
, sizeof(buf
), "/");
7144 put_stabs_r(buf
, N_SO
, 0, 0,
7145 text_section
->data_offset
, text_section
, section_sym
);
7146 put_stabs_r(file
->filename
, N_SO
, 0, 0,
7147 text_section
->data_offset
, text_section
, section_sym
);
7149 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
7150 symbols can be safely used */
7151 put_elf_sym(symtab_section
, 0, 0,
7152 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
7153 SHN_ABS
, file
->filename
);
7155 /* define common 'char *' type because it is often used internally
7156 for arrays and struct dereference */
7157 char_pointer_type
= mk_pointer(VT_BYTE
);
7158 /* define an old type function 'int func()' */
7160 sym
= sym_push(p
, 0, FUNC_CDECL
, FUNC_OLD
);
7161 func_old_type
= VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
7163 /* define 'void *alloca(unsigned int)' builtin function */
7168 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
7169 s1
= sym_push(0, VT_UNSIGNED
| VT_INT
, 0, 0);
7172 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
7176 define_start
= define_stack
.top
;
7178 if (setjmp(s1
->error_jmp_buf
) == 0) {
7180 s1
->error_set_jmp_enabled
= 1;
7183 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7187 expect("declaration");
7189 /* end of translation unit info */
7191 put_stabs_r(NULL
, N_SO
, 0, 0,
7192 text_section
->data_offset
, text_section
, section_sym
);
7195 s1
->error_set_jmp_enabled
= 0;
7197 /* reset define stack, but leave -Dsymbols (may be incorrect if
7198 they are undefined) */
7199 free_defines(define_start
);
7201 sym_pop(&global_stack
, NULL
);
7203 return s1
->nb_errors
!= 0 ? -1 : 0;
7206 int tcc_compile_string(TCCState
*s
, const char *str
)
7208 BufferedFile bf1
, *bf
= &bf1
;
7211 /* init file structure */
7213 bf
->buf_ptr
= (char *)str
;
7214 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
7215 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
7219 ret
= tcc_compile(s
);
7221 /* currently, no need to close */
7225 /* define a symbol. A value can also be provided with the '=' operator */
7226 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
7228 BufferedFile bf1
, *bf
= &bf1
;
7230 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
7231 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
7235 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
7237 /* init file structure */
7239 bf
->buf_ptr
= bf
->buffer
;
7240 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
7241 bf
->filename
[0] = '\0';
7245 s1
->include_stack_ptr
= s1
->include_stack
;
7247 /* parse with define parser */
7249 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7255 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
7259 ts
= tok_alloc(sym
, strlen(sym
));
7260 s
= sym_find1(&define_stack
, tok
);
7261 /* undefine symbol by putting an invalid name */
7263 sym_undef(&define_stack
, s
);
7268 /* print the position in the source file of PC value 'pc' by reading
7269 the stabs debug information */
7270 static void rt_printline(unsigned long wanted_pc
)
7272 Stab_Sym
*sym
, *sym_end
;
7273 char func_name
[128], last_func_name
[128];
7274 unsigned long func_addr
, last_pc
, pc
;
7275 const char *incl_files
[INCLUDE_STACK_SIZE
];
7276 int incl_index
, len
, last_line_num
, i
;
7277 const char *str
, *p
;
7279 fprintf(stderr
, "0x%08lx:", wanted_pc
);
7281 func_name
[0] = '\0';
7284 last_func_name
[0] = '\0';
7285 last_pc
= 0xffffffff;
7287 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
7288 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
7289 while (sym
< sym_end
) {
7290 switch(sym
->n_type
) {
7291 /* function start or end */
7293 if (sym
->n_strx
== 0) {
7294 /* we test if between last line and end of function */
7295 pc
= sym
->n_value
+ func_addr
;
7296 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7298 func_name
[0] = '\0';
7301 str
= stabstr_section
->data
+ sym
->n_strx
;
7302 p
= strchr(str
, ':');
7304 pstrcpy(func_name
, sizeof(func_name
), str
);
7307 if (len
> sizeof(func_name
) - 1)
7308 len
= sizeof(func_name
) - 1;
7309 memcpy(func_name
, str
, len
);
7310 func_name
[len
] = '\0';
7312 func_addr
= sym
->n_value
;
7315 /* line number info */
7317 pc
= sym
->n_value
+ func_addr
;
7318 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7321 last_line_num
= sym
->n_desc
;
7323 strcpy(last_func_name
, func_name
);
7327 str
= stabstr_section
->data
+ sym
->n_strx
;
7329 if (incl_index
< INCLUDE_STACK_SIZE
) {
7330 incl_files
[incl_index
++] = str
;
7338 if (sym
->n_strx
== 0) {
7339 incl_index
= 0; /* end of translation unit */
7341 str
= stabstr_section
->data
+ sym
->n_strx
;
7342 /* do not add path */
7344 if (len
> 0 && str
[len
- 1] != '/')
7352 /* second pass: we try symtab symbols (no line number info) */
7355 Elf32_Sym
*sym
, *sym_end
;
7358 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
7359 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
7362 type
= ELF32_ST_TYPE(sym
->st_info
);
7363 if (type
== STT_FUNC
) {
7364 if (wanted_pc
>= sym
->st_value
&&
7365 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
7366 pstrcpy(last_func_name
, sizeof(last_func_name
),
7367 strtab_section
->data
+ sym
->st_name
);
7373 /* did not find any info: */
7374 fprintf(stderr
, " ???\n");
7377 if (last_func_name
[0] != '\0') {
7378 fprintf(stderr
, " %s()", last_func_name
);
7380 if (incl_index
> 0) {
7381 fprintf(stderr
, " (%s:%d",
7382 incl_files
[incl_index
- 1], last_line_num
);
7383 for(i
= incl_index
- 2; i
>= 0; i
--)
7384 fprintf(stderr
, ", included from %s", incl_files
[i
]);
7385 fprintf(stderr
, ")");
7387 fprintf(stderr
, "\n");
7397 /* return the PC at frame level 'level'. Return non zero if not found */
7398 static int rt_get_caller_pc(unsigned long *paddr
,
7399 struct ucontext
*uc
, int level
)
7405 *paddr
= uc
->uc_mcontext
.gregs
[EIP
];
7408 fp
= uc
->uc_mcontext
.gregs
[EBP
];
7409 for(i
=1;i
<level
;i
++) {
7410 /* XXX: check address validity with program info */
7411 if (fp
<= 0x1000 || fp
>= 0xc0000000)
7413 fp
= ((unsigned long *)fp
)[0];
7415 *paddr
= ((unsigned long *)fp
)[1];
7420 #error add corresponding function
7423 /* emit a run time error at position 'pc' */
7424 void rt_error(struct ucontext
*uc
, const char *fmt
, ...)
7431 fprintf(stderr
, "Runtime error: ");
7432 vfprintf(stderr
, fmt
, ap
);
7433 fprintf(stderr
, "\n");
7434 for(i
=0;i
<num_callers
;i
++) {
7435 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
7438 fprintf(stderr
, "at ");
7440 fprintf(stderr
, "by ");
7448 /* signal handler for fatal errors */
7449 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
7451 struct ucontext
*uc
= puc
;
7455 switch(siginf
->si_code
) {
7458 rt_error(uc
, "division by zero");
7461 rt_error(uc
, "floating point exception");
7467 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
7468 rt_error(uc
, *rt_bound_error_msg
);
7470 rt_error(uc
, "dereferencing invalid pointer");
7473 rt_error(uc
, "illegal instruction");
7476 rt_error(uc
, "abort() called");
7479 rt_error(uc
, "caught signal %d", signum
);
7486 /* do all relocations (needed before using tcc_get_symbol()) */
7487 int tcc_relocate(TCCState
*s1
)
7494 tcc_add_runtime(s1
);
7496 relocate_common_syms();
7498 /* compute relocation address : section are relocated in place. We
7499 also alloc the bss space */
7500 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7501 s
= s1
->sections
[i
];
7502 if (s
->sh_flags
& SHF_ALLOC
) {
7503 if (s
->sh_type
== SHT_NOBITS
)
7504 s
->data
= tcc_mallocz(s
->data_offset
);
7505 s
->sh_addr
= (unsigned long)s
->data
;
7509 relocate_syms(s1
, 1);
7511 if (s1
->nb_errors
!= 0)
7514 /* relocate each section */
7515 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7516 s
= s1
->sections
[i
];
7518 relocate_section(s1
, s
);
7523 /* launch the compiled program with the given arguments */
7524 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
7526 int (*prog_main
)(int, char **);
7528 if (tcc_relocate(s1
) < 0)
7531 prog_main
= tcc_get_symbol(s1
, "main");
7535 error("debug mode currently not available for Windows");
7537 struct sigaction sigact
;
7538 /* install TCC signal handlers to print debug info on fatal
7540 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
7541 sigact
.sa_sigaction
= sig_error
;
7542 sigemptyset(&sigact
.sa_mask
);
7543 sigaction(SIGFPE
, &sigact
, NULL
);
7544 sigaction(SIGILL
, &sigact
, NULL
);
7545 sigaction(SIGSEGV
, &sigact
, NULL
);
7546 sigaction(SIGBUS
, &sigact
, NULL
);
7547 sigaction(SIGABRT
, &sigact
, NULL
);
7551 #ifdef CONFIG_TCC_BCHECK
7552 if (do_bounds_check
) {
7553 void (*bound_init
)(void);
7555 /* set error function */
7556 rt_bound_error_msg
= (void *)tcc_get_symbol(s1
, "__bound_error_msg");
7558 /* XXX: use .init section so that it also work in binary ? */
7559 bound_init
= (void *)tcc_get_symbol(s1
, "__bound_init");
7563 return (*prog_main
)(argc
, argv
);
7566 TCCState
*tcc_new(void)
7571 s
= tcc_mallocz(sizeof(TCCState
));
7575 s
->output_type
= TCC_OUTPUT_MEMORY
;
7577 /* default include paths */
7578 tcc_add_sysinclude_path(s
, "/usr/local/include");
7579 tcc_add_sysinclude_path(s
, "/usr/include");
7580 tcc_add_sysinclude_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
7582 /* add all tokens */
7584 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
7586 tok_ident
= TOK_IDENT
;
7591 tok_alloc(p
, r
- p
- 1);
7595 /* we add dummy defines for some special macros to speed up tests
7596 and to have working defined() */
7597 sym_push1(&define_stack
, TOK___LINE__
, MACRO_OBJ
, 0);
7598 sym_push1(&define_stack
, TOK___FILE__
, MACRO_OBJ
, 0);
7599 sym_push1(&define_stack
, TOK___DATE__
, MACRO_OBJ
, 0);
7600 sym_push1(&define_stack
, TOK___TIME__
, MACRO_OBJ
, 0);
7602 /* standard defines */
7603 tcc_define_symbol(s
, "__STDC__", NULL
);
7604 #if defined(TCC_TARGET_I386)
7605 tcc_define_symbol(s
, "__i386__", NULL
);
7608 tcc_define_symbol(s
, "linux", NULL
);
7610 /* tiny C specific defines */
7611 tcc_define_symbol(s
, "__TINYC__", NULL
);
7613 /* default library paths */
7614 tcc_add_library_path(s
, "/usr/local/lib");
7615 tcc_add_library_path(s
, "/usr/lib");
7616 tcc_add_library_path(s
, "/lib");
7618 /* no section zero */
7619 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
7621 /* create standard sections */
7622 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
7623 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
7624 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
7626 /* symbols are always generated for linking stage */
7627 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
7629 ".hashtab", SHF_PRIVATE
);
7630 strtab_section
= symtab_section
->link
;
7632 /* private symbol table for dynamic symbols */
7633 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
7635 ".dynhashtab", SHF_PRIVATE
);
7639 void tcc_delete(TCCState
*s1
)
7643 /* free -D defines */
7647 n
= tok_ident
- TOK_IDENT
;
7648 for(i
= 0; i
< n
; i
++)
7649 tcc_free(table_ident
[i
]);
7650 tcc_free(table_ident
);
7652 /* free all sections */
7654 free_section(symtab_section
->hash
);
7656 free_section(s1
->dynsymtab_section
->hash
);
7657 free_section(s1
->dynsymtab_section
->link
);
7658 free_section(s1
->dynsymtab_section
);
7660 for(i
= 1; i
< s1
->nb_sections
; i
++)
7661 free_section(s1
->sections
[i
]);
7662 tcc_free(s1
->sections
);
7664 /* free loaded dlls array */
7665 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
7666 tcc_free(s1
->loaded_dlls
[i
]);
7667 tcc_free(s1
->loaded_dlls
);
7670 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
7671 tcc_free(s1
->library_paths
[i
]);
7672 tcc_free(s1
->library_paths
);
7674 /* cached includes */
7675 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
7676 tcc_free(s1
->cached_includes
[i
]);
7677 tcc_free(s1
->cached_includes
);
7679 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
7680 tcc_free(s1
->include_paths
[i
]);
7681 tcc_free(s1
->include_paths
);
7683 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
7684 tcc_free(s1
->sysinclude_paths
[i
]);
7685 tcc_free(s1
->sysinclude_paths
);
7690 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
7694 pathname1
= tcc_strdup(pathname
);
7695 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
7699 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
7703 pathname1
= tcc_strdup(pathname
);
7704 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
7708 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
7713 BufferedFile
*saved_file
;
7715 /* find source file type with extension */
7716 ext
= strrchr(filename
, '.');
7722 file
= tcc_open(s1
, filename
);
7724 if (flags
& AFF_PRINT_ERROR
) {
7725 error_noabort("file '%s' not found", filename
);
7731 if (!ext
|| !strcmp(ext
, "c")) {
7732 /* C file assumed */
7733 ret
= tcc_compile(s1
);
7736 /* assume executable format: auto guess file type */
7737 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
)) {
7738 error_noabort("could not read header");
7741 lseek(fd
, 0, SEEK_SET
);
7743 if (ehdr
.e_ident
[0] == ELFMAG0
&&
7744 ehdr
.e_ident
[1] == ELFMAG1
&&
7745 ehdr
.e_ident
[2] == ELFMAG2
&&
7746 ehdr
.e_ident
[3] == ELFMAG3
) {
7747 file
->line_num
= 0; /* do not display line number if error */
7748 if (ehdr
.e_type
== ET_REL
) {
7749 ret
= tcc_load_object_file(s1
, fd
, 0);
7750 } else if (ehdr
.e_type
== ET_DYN
) {
7751 ret
= tcc_load_dll(s1
, fd
, filename
,
7752 (flags
& AFF_REFERENCED_DLL
) != 0);
7754 error_noabort("unrecognized ELF file");
7757 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
7758 file
->line_num
= 0; /* do not display line number if error */
7759 ret
= tcc_load_archive(s1
, fd
);
7761 /* as GNU ld, consider it is an ld script if not recognized */
7762 ret
= tcc_load_ldscript(s1
);
7764 error_noabort("unrecognized file type");
7779 int tcc_add_file(TCCState
*s
, const char *filename
)
7781 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
7784 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
7788 pathname1
= tcc_strdup(pathname
);
7789 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
7793 /* find and load a dll. Return non zero if not found */
7794 /* XXX: add '-rpath' option support ? */
7795 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
7800 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
7801 snprintf(buf
, sizeof(buf
), "%s/%s",
7802 s
->library_paths
[i
], filename
);
7803 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
7809 /* the library name is the same as the argument of the '-l' option */
7810 int tcc_add_library(TCCState
*s
, const char *libraryname
)
7816 /* first we look for the dynamic library if not static linking */
7817 if (!s
->static_link
) {
7818 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
7819 /* if we output to memory, then we simply we dlopen(). */
7820 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
7821 /* Since the libc is already loaded, we don't need to load it again */
7822 if (!strcmp(libraryname
, "c"))
7824 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
7828 if (tcc_add_dll(s
, buf
, 0) == 0)
7833 /* then we look for the static library */
7834 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
7835 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
7836 s
->library_paths
[i
], libraryname
);
7837 if (tcc_add_file_internal(s
, buf
, 0) == 0)
7843 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
7845 add_elf_sym(symtab_section
, val
, 0,
7846 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7851 int tcc_set_output_type(TCCState
*s
, int output_type
)
7853 s
->output_type
= output_type
;
7855 /* if bound checking, then add corresponding sections */
7856 #ifdef CONFIG_TCC_BCHECK
7857 if (do_bounds_check
) {
7859 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
7860 /* create bounds sections */
7861 bounds_section
= new_section(s
, ".bounds",
7862 SHT_PROGBITS
, SHF_ALLOC
);
7863 lbounds_section
= new_section(s
, ".lbounds",
7864 SHT_PROGBITS
, SHF_ALLOC
);
7868 /* add debug sections */
7871 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
7872 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
7873 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
7874 put_elf_str(stabstr_section
, "");
7875 stab_section
->link
= stabstr_section
;
7876 /* put first entry */
7877 put_stabs("", 0, 0, 0, 0);
7880 /* add libc crt1/crti objects */
7881 if (output_type
== TCC_OUTPUT_EXE
||
7882 output_type
== TCC_OUTPUT_DLL
) {
7883 if (output_type
!= TCC_OUTPUT_DLL
)
7884 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
7885 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
7890 #if !defined(LIBTCC)
7894 printf("tcc version 0.9.13 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7895 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7896 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
7897 " [--] infile1 [infile2... --] [infile_args...]\n"
7899 "General options:\n"
7900 " -c compile only - generate an object file\n"
7901 " -o outfile set output filename\n"
7902 " -- allows multiples input files if no -o option given. Also\n"
7903 " separate input files from runtime arguments\n"
7904 " -Bdir set tcc internal library path\n"
7905 " -bench output compilation statistics\n"
7906 "Preprocessor options:\n"
7907 " -Idir add include path 'dir'\n"
7908 " -Dsym[=val] define 'sym' with value 'val'\n"
7909 " -Usym undefine 'sym'\n"
7911 " -Ldir add library path 'dir'\n"
7912 " -llib link with dynamic or static library 'lib'\n"
7913 " -shared generate a shared library\n"
7914 " -static static linking\n"
7915 " -r relocatable output\n"
7916 "Debugger options:\n"
7917 " -g generate runtime debug info\n"
7918 #ifdef CONFIG_TCC_BCHECK
7919 " -b compile with built-in memory and bounds checker (implies -g)\n"
7921 " -bt N show N callers in stack traces\n"
7925 int main(int argc
, char **argv
)
7928 int optind
, output_type
, multiple_files
, i
, reloc_output
;
7931 int nb_files
, nb_libraries
, nb_objfiles
, dminus
, ret
;
7932 char objfilename
[1024];
7935 output_type
= TCC_OUTPUT_MEMORY
;
7946 if (optind
>= argc
) {
7954 /* add a new file */
7955 dynarray_add((void ***)&files
, &nb_files
, r
);
7956 if (!multiple_files
) {
7958 /* argv[0] will be this file */
7961 } else if (r
[1] == '-') {
7962 /* '--' enables multiple files input and also ends several file input */
7963 if (dminus
&& multiple_files
) {
7964 optind
--; /* argv[0] will be '--' */
7969 } else if (r
[1] == 'h' || r
[1] == '?') {
7973 } else if (r
[1] == 'I') {
7974 if (tcc_add_include_path(s
, r
+ 2) < 0)
7975 error("too many include paths");
7976 } else if (r
[1] == 'D') {
7979 value
= strchr(sym
, '=');
7984 tcc_define_symbol(s
, sym
, value
);
7985 } else if (r
[1] == 'U') {
7986 tcc_undefine_symbol(s
, r
+ 2);
7987 } else if (r
[1] == 'L') {
7988 tcc_add_library_path(s
, r
+ 2);
7989 } else if (r
[1] == 'B') {
7990 /* set tcc utilities path (mainly for tcc development) */
7991 tcc_lib_path
= r
+ 2;
7992 } else if (r
[1] == 'l') {
7993 dynarray_add((void ***)&files
, &nb_files
, r
);
7995 } else if (!strcmp(r
+ 1, "bench")) {
7997 } else if (!strcmp(r
+ 1, "bt")) {
7998 num_callers
= atoi(argv
[optind
++]);
8000 #ifdef CONFIG_TCC_BCHECK
8002 do_bounds_check
= 1;
8008 } else if (r
[1] == 'c') {
8010 output_type
= TCC_OUTPUT_OBJ
;
8011 } else if (!strcmp(r
+ 1, "static")) {
8013 } else if (!strcmp(r
+ 1, "shared")) {
8014 output_type
= TCC_OUTPUT_DLL
;
8015 } else if (r
[1] == 'o') {
8019 outfile
= argv
[optind
++];
8020 } else if (r
[1] == 'r') {
8021 /* generate a .o merging several output files */
8023 output_type
= TCC_OUTPUT_OBJ
;
8024 } else if (r
[1] == 'W' || r
[1] == 'O' || r
[1] == 'm' || r
[1] == 'f') {
8025 /* ignore those options to be a drop-in replacement for gcc */
8027 error("invalid option -- '%s'", r
);
8031 nb_objfiles
= nb_files
- nb_libraries
;
8033 /* if outfile provided without other options, we output an
8035 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
8036 output_type
= TCC_OUTPUT_EXE
;
8038 /* check -c consistency : only single file handled. XXX: checks file type */
8039 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
8040 /* accepts only a single input file */
8041 if (nb_objfiles
!= 1)
8042 error("cannot specify multiple files with -c");
8043 if (nb_libraries
!= 0)
8044 error("cannot specify libraries with -c");
8047 /* compute default outfile name */
8048 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
8049 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
8051 /* add .o extension */
8052 pstrcpy(objfilename
, sizeof(objfilename
) - 1, files
[0]);
8053 ext
= strrchr(objfilename
, '.');
8055 goto default_outfile
;
8056 strcpy(ext
+ 1, "o");
8059 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
8061 outfile
= objfilename
;
8064 tcc_set_output_type(s
, output_type
);
8066 /* compile or add each files or library */
8067 for(i
= 0;i
< nb_files
; i
++) {
8068 const char *filename
;
8070 filename
= files
[i
];
8071 if (filename
[0] == '-') {
8072 if (tcc_add_library(s
, filename
+ 2) < 0)
8073 error("cannot find %s", filename
);
8075 if (tcc_add_file(s
, filename
) < 0) {
8082 /* free all files */
8086 printf("total: %d idents, %d lines, %d bytes\n",
8087 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
8090 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
8091 tcc_output_file(s
, outfile
);
8094 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
8097 /* XXX: cannot do it with bound checking because of the malloc hooks */
8098 if (!do_bounds_check
)
8103 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);