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.t' 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 /* XXX: suppress that ASAP */
309 static struct TCCState
*tcc_state
;
311 /* give the path of the tcc libraries */
312 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
317 BufferedFile
**include_stack_ptr
;
318 int *ifdef_stack_ptr
;
320 /* include file handling */
321 char **include_paths
;
322 int nb_include_paths
;
323 char **sysinclude_paths
;
324 int nb_sysinclude_paths
;
325 CachedInclude
**cached_includes
;
326 int nb_cached_includes
;
328 char **library_paths
;
329 int nb_library_paths
;
331 /* array of all loaded dlls (including those referenced by loaded
333 DLLReference
**loaded_dlls
;
338 int nb_sections
; /* number of sections, including first dummy section */
342 unsigned long *got_offsets
;
345 /* give the correspondance from symtab indexes to dynsym indexes */
346 int *symtab_to_dynsym
;
348 /* temporary dynamic symbol sections (for dll loading) */
349 Section
*dynsymtab_section
;
350 /* exported dynamic symbol section */
353 /* if true, static linking is performed */
358 void (*error_func
)(void *opaque
, const char *msg
);
359 int error_set_jmp_enabled
;
360 jmp_buf error_jmp_buf
;
363 /* see include_stack_ptr */
364 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
366 /* see ifdef_stack_ptr */
367 int ifdef_stack
[IFDEF_STACK_SIZE
];
370 /* The current value can be: */
371 #define VT_VALMASK 0x00ff
372 #define VT_CONST 0x00f0 /* constant in vc
373 (must be first non register value) */
374 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
375 #define VT_LOCAL 0x00f2 /* offset on stack */
376 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
377 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
378 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
379 #define VT_LVAL 0x0100 /* var is an lvalue */
380 #define VT_SYM 0x0200 /* a symbol value is added */
381 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
382 char/short stored in integer registers) */
383 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
384 dereferencing value */
385 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
386 bounding function call point is in vc */
387 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
388 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
389 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
390 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
393 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
395 #define VT_INT 0 /* integer type */
396 #define VT_BYTE 1 /* signed byte type */
397 #define VT_SHORT 2 /* short type */
398 #define VT_VOID 3 /* void type */
399 #define VT_PTR 4 /* pointer */
400 #define VT_ENUM 5 /* enum definition */
401 #define VT_FUNC 6 /* function type */
402 #define VT_STRUCT 7 /* struct/union definition */
403 #define VT_FLOAT 8 /* IEEE float */
404 #define VT_DOUBLE 9 /* IEEE double */
405 #define VT_LDOUBLE 10 /* IEEE long double */
406 #define VT_BOOL 11 /* ISOC99 boolean type */
407 #define VT_LLONG 12 /* 64 bit integer */
408 #define VT_LONG 13 /* long integer (NEVER USED as type, only
410 #define VT_BTYPE 0x000f /* mask for basic type */
411 #define VT_UNSIGNED 0x0010 /* unsigned type */
412 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
413 #define VT_BITFIELD 0x0040 /* bitfield modifier */
416 #define VT_EXTERN 0x00000080 /* extern definition */
417 #define VT_STATIC 0x00000100 /* static variable */
418 #define VT_TYPEDEF 0x00000200 /* typedef definition */
420 /* type mask (except storage) */
421 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
425 /* warning: the following compare tokens depend on i386 asm code */
437 #define TOK_LAND 0xa0
441 #define TOK_MID 0xa3 /* inc/dec, to void constant */
443 #define TOK_UDIV 0xb0 /* unsigned division */
444 #define TOK_UMOD 0xb1 /* unsigned modulo */
445 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
446 #define TOK_CINT 0xb3 /* number in tokc */
447 #define TOK_CCHAR 0xb4 /* char constant in tokc */
448 #define TOK_STR 0xb5 /* pointer to string in tokc */
449 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
450 #define TOK_LCHAR 0xb7
451 #define TOK_LSTR 0xb8
452 #define TOK_CFLOAT 0xb9 /* float constant */
453 #define TOK_LINENUM 0xba /* line number info */
454 #define TOK_CDOUBLE 0xc0 /* double constant */
455 #define TOK_CLDOUBLE 0xc1 /* long double constant */
456 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
457 #define TOK_ADDC1 0xc3 /* add with carry generation */
458 #define TOK_ADDC2 0xc4 /* add with carry use */
459 #define TOK_SUBC1 0xc5 /* add with carry generation */
460 #define TOK_SUBC2 0xc6 /* add with carry use */
461 #define TOK_CUINT 0xc8 /* unsigned int constant */
462 #define TOK_CLLONG 0xc9 /* long long constant */
463 #define TOK_CULLONG 0xca /* unsigned long long constant */
464 #define TOK_ARROW 0xcb
465 #define TOK_DOTS 0xcc /* three dots */
466 #define TOK_SHR 0xcd /* unsigned shift right */
467 #define TOK_PPNUM 0xce /* preprocessor number */
469 #define TOK_SHL 0x01 /* shift left */
470 #define TOK_SAR 0x02 /* signed shift right */
472 /* assignement operators : normal operator or 0x80 */
473 #define TOK_A_MOD 0xa5
474 #define TOK_A_AND 0xa6
475 #define TOK_A_MUL 0xaa
476 #define TOK_A_ADD 0xab
477 #define TOK_A_SUB 0xad
478 #define TOK_A_DIV 0xaf
479 #define TOK_A_XOR 0xde
480 #define TOK_A_OR 0xfc
481 #define TOK_A_SHL 0x81
482 #define TOK_A_SAR 0x82
484 /* WARNING: the content of this string encodes token numbers */
485 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";
487 #define TOK_EOF (-1) /* end of file */
488 #define TOK_LINEFEED 10 /* line feed */
490 /* all identificators and strings have token above that */
491 #define TOK_IDENT 256
494 TOK_LAST
= TOK_IDENT
- 1,
495 #define DEF(id, str) id,
500 static const char *tcc_keywords
=
501 #define DEF(id, str) str "\0"
506 #define TOK_UIDENT TOK_DEFINE
509 #define snprintf _snprintf
512 #if defined(WIN32) || defined(TCC_UCLIBC)
513 /* currently incorrect */
514 long double strtold(const char *nptr
, char **endptr
)
516 return (long double)strtod(nptr
, endptr
);
518 float strtof(const char *nptr
, char **endptr
)
520 return (float)strtod(nptr
, endptr
);
523 /* XXX: need to define this to use them in non ISOC99 context */
524 extern float strtof (const char *__nptr
, char **__endptr
);
525 extern long double strtold (const char *__nptr
, char **__endptr
);
528 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
529 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
531 static void sum(int l
);
532 static void next(void);
533 static void next_nomacro(void);
534 static int parse_expr_type(void);
535 static int expr_type(void);
536 static int unary_type(void);
537 static int expr_const(void);
538 static void expr_eq(void);
539 static void gexpr(void);
540 static void decl(int l
);
541 static void decl_initializer(int t
, Section
*sec
, unsigned long c
,
542 int first
, int size_only
);
543 static void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
,
544 int has_init
, int v
, int scope
);
546 void gv2(int rc1
, int rc2
);
547 void move_reg(int r
, int s
);
548 void save_regs(int n
);
549 void save_reg(int r
);
555 static void macro_subst(TokenString
*tok_str
,
556 Sym
**nested_list
, int *macro_str
);
557 int save_reg_forced(int r
);
559 void force_charshort_cast(int t
);
560 void gen_cast(int t
);
562 Sym
*sym_find(int v
);
563 Sym
*sym_push(int v
, int t
, int r
, int c
);
566 int type_size(int t
, int *a
);
567 int pointed_type(int t
);
568 int pointed_size(int t
);
569 static int lvalue_type(int t
);
570 int is_compatible_types(int t1
, int t2
);
571 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
572 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
574 void error(const char *fmt
, ...);
575 void rt_error(unsigned long pc
, const char *fmt
, ...);
577 void vset(int t
, int r
, int v
);
578 void type_to_str(char *buf
, int buf_size
,
579 int t
, const char *varstr
);
580 char *get_tok_str(int v
, CValue
*cv
);
581 static Sym
*get_sym_ref(int t
, Section
*sec
,
582 unsigned long offset
, unsigned long size
);
583 static Sym
*external_global_sym(int v
, int u
, int r
);
585 /* section generation */
586 static void section_realloc(Section
*sec
, unsigned long new_size
);
587 static void *section_ptr_add(Section
*sec
, unsigned long size
);
588 static void put_extern_sym(Sym
*sym
, Section
*section
,
589 unsigned long value
, unsigned long size
);
590 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
591 static int put_elf_str(Section
*s
, const char *sym
);
592 static int put_elf_sym(Section
*s
,
593 unsigned long value
, unsigned long size
,
594 int info
, int other
, int shndx
, const char *name
);
595 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
596 int info
, int sh_num
, const char *name
);
597 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
598 int type
, int symbol
);
599 static void put_stabs(const char *str
, int type
, int other
, int desc
,
600 unsigned long value
);
601 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
602 unsigned long value
, Section
*sec
, int sym_index
);
603 static void put_stabn(int type
, int other
, int desc
, int value
);
604 static void put_stabd(int type
, int other
, int desc
);
605 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
607 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
608 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
609 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
611 /* true if float/double/long double type */
612 static inline int is_float(int t
)
616 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
619 #ifdef TCC_TARGET_I386
620 #include "i386-gen.c"
626 #ifdef CONFIG_TCC_STATIC
628 #define RTLD_LAZY 0x001
629 #define RTLD_NOW 0x002
630 #define RTLD_GLOBAL 0x100
632 /* dummy function for profiling */
633 void *dlopen(const char *filename
, int flag
)
638 const char *dlerror(void)
643 typedef struct TCCSyms
{
648 #define TCCSYM(a) { #a, &a, },
650 /* add the symbol you want here if no dynamic linking is done */
651 static TCCSyms tcc_syms
[] = {
659 void *dlsym(void *handle
, const char *symbol
)
663 while (p
->str
!= NULL
) {
664 if (!strcmp(p
->str
, symbol
))
673 /********************************************************/
675 /* we use our own 'finite' function to avoid potential problems with
676 non standard math libs */
677 /* XXX: endianness dependant */
678 int ieee_finite(double d
)
681 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
684 /* copy a string and truncate it. */
685 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
692 q_end
= buf
+ buf_size
- 1;
704 /* strcat and truncate. */
705 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
710 pstrcpy(buf
+ len
, buf_size
- len
, s
);
714 /* memory management */
720 static inline void tcc_free(void *ptr
)
723 mem_cur_size
-= malloc_usable_size(ptr
);
728 static void *tcc_malloc(unsigned long size
)
733 error("memory full");
735 mem_cur_size
+= malloc_usable_size(ptr
);
736 if (mem_cur_size
> mem_max_size
)
737 mem_max_size
= mem_cur_size
;
742 static void *tcc_mallocz(unsigned long size
)
745 ptr
= tcc_malloc(size
);
746 memset(ptr
, 0, size
);
750 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
754 mem_cur_size
-= malloc_usable_size(ptr
);
756 ptr1
= realloc(ptr
, size
);
758 /* NOTE: count not correct if alloc error, but not critical */
759 mem_cur_size
+= malloc_usable_size(ptr1
);
760 if (mem_cur_size
> mem_max_size
)
761 mem_max_size
= mem_cur_size
;
766 static char *tcc_strdup(const char *str
)
769 ptr
= tcc_malloc(strlen(str
) + 1);
774 #define free(p) use_tcc_free(p)
775 #define malloc(s) use_tcc_malloc(s)
776 #define realloc(p, s) use_tcc_realloc(p, s)
778 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
785 /* every power of two we double array size */
786 if ((nb
& (nb
- 1)) == 0) {
791 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
793 error("memory full");
800 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
804 sec
= tcc_mallocz(sizeof(Section
));
805 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
806 sec
->sh_type
= sh_type
;
807 sec
->sh_flags
= sh_flags
;
814 sec
->sh_addralign
= 4;
817 sec
->sh_addralign
= 1;
820 sec
->sh_addralign
= 32; /* default conservative alignment */
824 /* only add section if not private */
825 if (!(sh_flags
& SHF_PRIVATE
)) {
826 sec
->sh_num
= s1
->nb_sections
;
827 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
832 static void free_section(Section
*s
)
838 /* realloc section and set its content to zero */
839 static void section_realloc(Section
*sec
, unsigned long new_size
)
844 size
= sec
->data_allocated
;
847 while (size
< new_size
)
849 data
= tcc_realloc(sec
->data
, size
);
851 error("memory full");
852 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
854 sec
->data_allocated
= size
;
857 /* reserve at least 'size' bytes in section 'sec' from
859 static void *section_ptr_add(Section
*sec
, unsigned long size
)
861 unsigned long offset
, offset1
;
863 offset
= sec
->data_offset
;
864 offset1
= offset
+ size
;
865 if (offset1
> sec
->data_allocated
)
866 section_realloc(sec
, offset1
);
867 sec
->data_offset
= offset1
;
868 return sec
->data
+ offset
;
871 /* return a reference to a section, and create it if it does not
873 Section
*find_section(TCCState
*s1
, const char *name
)
877 for(i
= 1; i
< s1
->nb_sections
; i
++) {
878 sec
= s1
->sections
[i
];
879 if (!strcmp(name
, sec
->name
))
882 /* sections are created as PROGBITS */
883 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
886 /* update sym->c so that it points to an external symbol in section
887 'section' with value 'value' */
888 static void put_extern_sym(Sym
*sym
, Section
*section
,
889 unsigned long value
, unsigned long size
)
891 int sym_type
, sym_bind
, sh_num
, info
;
897 sh_num
= section
->sh_num
;
901 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
904 sym_type
= STT_OBJECT
;
905 if (sym
->t
& VT_STATIC
)
906 sym_bind
= STB_LOCAL
;
908 sym_bind
= STB_GLOBAL
;
910 name
= get_tok_str(sym
->v
, NULL
);
911 #ifdef CONFIG_TCC_BCHECK
912 if (do_bounds_check
) {
913 /* if bound checking is activated, we change some function
914 names by adding the "__bound" prefix */
917 /* XXX: we rely only on malloc hooks */
929 strcpy(buf
, "__bound_");
936 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
937 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
939 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
940 esym
->st_value
= value
;
941 esym
->st_size
= size
;
942 esym
->st_shndx
= sh_num
;
946 /* add a new relocation entry to symbol 'sym' in section 's' */
947 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
950 put_extern_sym(sym
, NULL
, 0, 0);
951 /* now we can add ELF relocation info */
952 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
955 static inline int isid(int c
)
957 return (c
>= 'a' && c
<= 'z') ||
958 (c
>= 'A' && c
<= 'Z') ||
962 static inline int isnum(int c
)
964 return c
>= '0' && c
<= '9';
967 static inline int isoct(int c
)
969 return c
>= '0' && c
<= '7';
972 static inline int toup(int c
)
974 if (c
>= 'a' && c
<= 'z')
975 return c
- 'a' + 'A';
980 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
984 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
987 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
991 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
995 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1002 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1003 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1004 (*f
)->filename
, (*f
)->line_num
);
1005 if (file
->line_num
> 0) {
1006 strcat_printf(buf
, sizeof(buf
),
1007 "%s:%d: ", file
->filename
, file
->line_num
);
1009 strcat_printf(buf
, sizeof(buf
),
1010 "%s: ", file
->filename
);
1013 strcat_printf(buf
, sizeof(buf
),
1017 strcat_printf(buf
, sizeof(buf
), "warning: ");
1018 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1020 if (!s1
->error_func
) {
1021 /* default case: stderr */
1022 fprintf(stderr
, "%s\n", buf
);
1024 s1
->error_func(s1
->error_opaque
, buf
);
1031 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1032 void (*error_func
)(void *opaque
, const char *msg
))
1034 s
->error_opaque
= error_opaque
;
1035 s
->error_func
= error_func
;
1039 /* error without aborting current compilation */
1040 void error_noabort(const char *fmt
, ...)
1042 TCCState
*s1
= tcc_state
;
1046 error1(s1
, 0, fmt
, ap
);
1050 void error(const char *fmt
, ...)
1052 TCCState
*s1
= tcc_state
;
1056 error1(s1
, 0, fmt
, ap
);
1058 /* better than nothing: in some cases, we accept to handle errors */
1059 if (s1
->error_set_jmp_enabled
) {
1060 longjmp(s1
->error_jmp_buf
, 1);
1062 /* XXX: suppress it someday */
1067 void expect(const char *msg
)
1069 error("%s expected", msg
);
1072 void warning(const char *fmt
, ...)
1074 TCCState
*s1
= tcc_state
;
1078 error1(s1
, 1, fmt
, ap
);
1085 error("'%c' expected", c
);
1089 void test_lvalue(void)
1091 if (!(vtop
->r
& VT_LVAL
))
1095 TokenSym
*tok_alloc(const char *str
, int len
)
1097 TokenSym
*ts
, **pts
, **ptable
;
1102 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
1104 pts
= &hash_ident
[h
];
1109 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1111 pts
= &(ts
->hash_next
);
1114 if (tok_ident
>= SYM_FIRST_ANOM
)
1115 error("memory full");
1117 /* expand token table if needed */
1118 i
= tok_ident
- TOK_IDENT
;
1119 if ((i
% TOK_ALLOC_INCR
) == 0) {
1120 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1122 error("memory full");
1123 table_ident
= ptable
;
1126 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1127 table_ident
[i
] = ts
;
1128 ts
->tok
= tok_ident
++;
1130 ts
->hash_next
= NULL
;
1131 memcpy(ts
->str
, str
, len
+ 1);
1136 /* CString handling */
1138 static void cstr_realloc(CString
*cstr
, int new_size
)
1143 size
= cstr
->size_allocated
;
1145 size
= 8; /* no need to allocate a too small first string */
1146 while (size
< new_size
)
1148 data
= tcc_realloc(cstr
->data_allocated
, size
);
1150 error("memory full");
1151 cstr
->data_allocated
= data
;
1152 cstr
->size_allocated
= size
;
1157 static void cstr_ccat(CString
*cstr
, int ch
)
1160 size
= cstr
->size
+ 1;
1161 if (size
> cstr
->size_allocated
)
1162 cstr_realloc(cstr
, size
);
1163 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1167 static void cstr_cat(CString
*cstr
, const char *str
)
1179 /* add a wide char */
1180 static void cstr_wccat(CString
*cstr
, int ch
)
1183 size
= cstr
->size
+ sizeof(int);
1184 if (size
> cstr
->size_allocated
)
1185 cstr_realloc(cstr
, size
);
1186 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1190 static void cstr_new(CString
*cstr
)
1192 memset(cstr
, 0, sizeof(CString
));
1195 /* free string and reset it to NULL */
1196 static void cstr_free(CString
*cstr
)
1198 tcc_free(cstr
->data_allocated
);
1202 #define cstr_reset(cstr) cstr_free(cstr)
1204 /* XXX: unicode ? */
1205 static void add_char(CString
*cstr
, int c
)
1207 if (c
== '\'' || c
== '\"' || c
== '\\') {
1208 /* XXX: could be more precise if char or string */
1209 cstr_ccat(cstr
, '\\');
1211 if (c
>= 32 && c
<= 126) {
1214 cstr_ccat(cstr
, '\\');
1216 cstr_ccat(cstr
, 'n');
1218 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1219 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1220 cstr_ccat(cstr
, '0' + (c
& 7));
1225 /* XXX: buffer overflow */
1226 /* XXX: float tokens */
1227 char *get_tok_str(int v
, CValue
*cv
)
1229 static char buf
[STRING_MAX_SIZE
+ 1];
1230 static CString cstr_buf
;
1236 /* NOTE: to go faster, we give a fixed buffer for small strings */
1237 cstr_reset(&cstr_buf
);
1238 cstr_buf
.data
= buf
;
1239 cstr_buf
.size_allocated
= sizeof(buf
);
1245 /* XXX: not quite exact, but only useful for testing */
1246 sprintf(p
, "%u", cv
->ui
);
1250 /* XXX: not quite exact, but only useful for testing */
1251 sprintf(p
, "%Lu", cv
->ull
);
1255 cstr_ccat(&cstr_buf
, '\'');
1256 add_char(&cstr_buf
, cv
->i
);
1257 cstr_ccat(&cstr_buf
, '\'');
1258 cstr_ccat(&cstr_buf
, '\0');
1262 len
= cstr
->size
- 1;
1264 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1265 cstr_ccat(&cstr_buf
, '\0');
1270 cstr_ccat(&cstr_buf
, '\"');
1272 len
= cstr
->size
- 1;
1274 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1276 len
= (cstr
->size
/ sizeof(int)) - 1;
1278 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1280 cstr_ccat(&cstr_buf
, '\"');
1281 cstr_ccat(&cstr_buf
, '\0');
1290 return strcpy(p
, "<<=");
1292 return strcpy(p
, ">>=");
1294 if (v
< TOK_IDENT
) {
1295 /* search in two bytes table */
1309 } else if (v
< tok_ident
) {
1310 return table_ident
[v
- TOK_IDENT
]->str
;
1311 } else if (v
>= SYM_FIRST_ANOM
) {
1312 /* special name for anonymous symbol */
1313 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1315 /* should never happen */
1320 return cstr_buf
.data
;
1323 /* push, without hashing */
1324 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1327 s
= tcc_malloc(sizeof(Sym
));
1338 /* find a symbol and return its associated structure. 's' is the top
1339 of the symbol stack */
1340 Sym
*sym_find2(Sym
*s
, int v
)
1350 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1352 /* find a symbol and return its associated structure. 'st' is the
1354 Sym
*sym_find1(SymStack
*st
, int v
)
1358 s
= st
->hash
[HASH_SYM(v
)];
1367 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1370 s
= sym_push2(&st
->top
, v
, t
, c
);
1371 /* add in hash table */
1373 ps
= &st
->hash
[HASH_SYM(v
)];
1380 /* find a symbol in the right symbol space */
1381 Sym
*sym_find(int v
)
1384 s
= sym_find1(&local_stack
, v
);
1386 s
= sym_find1(&global_stack
, v
);
1390 /* push a given symbol on the symbol stack */
1391 Sym
*sym_push(int v
, int t
, int r
, int c
)
1394 if (local_stack
.top
)
1395 s
= sym_push1(&local_stack
, v
, t
, c
);
1397 s
= sym_push1(&global_stack
, v
, t
, c
);
1402 /* pop symbols until top reaches 'b' */
1403 void sym_pop(SymStack
*st
, Sym
*b
)
1410 /* free hash table entry, except if symbol was freed (only
1411 used for #undef symbols) */
1413 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1420 /* undefined a hashed symbol (used for #undef). Its name is set to
1422 void sym_undef(SymStack
*st
, Sym
*s
)
1425 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1426 while (*ss
!= NULL
) {
1429 ss
= &(*ss
)->hash_next
;
1437 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1442 fd
= open(filename
, O_RDONLY
);
1445 bf
= tcc_malloc(sizeof(BufferedFile
));
1451 bf
->buf_ptr
= bf
->buffer
;
1452 bf
->buf_end
= bf
->buffer
;
1453 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1454 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1456 bf
->ifndef_macro
= 0;
1457 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1458 // printf("opening '%s'\n", filename);
1462 void tcc_close(BufferedFile
*bf
)
1464 total_lines
+= bf
->line_num
;
1469 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1470 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1472 /* fill input buffer and return next char */
1473 int tcc_getc_slow(BufferedFile
*bf
)
1476 /* only tries to read if really end of buffer */
1477 if (bf
->buf_ptr
>= bf
->buf_end
) {
1479 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1486 bf
->buf_ptr
= bf
->buffer
;
1487 bf
->buf_end
= bf
->buffer
+ len
;
1488 *bf
->buf_end
= CH_EOB
;
1490 if (bf
->buf_ptr
< bf
->buf_end
) {
1491 return *bf
->buf_ptr
++;
1493 bf
->buf_ptr
= bf
->buf_end
;
1498 /* no need to put that inline */
1499 void handle_eob(void)
1501 TCCState
*s1
= tcc_state
;
1503 ch1
= tcc_getc_slow(file
);
1507 if (return_linefeed
) {
1511 if (s1
->include_stack_ptr
== s1
->include_stack
)
1513 /* add end of include file debug info */
1515 put_stabd(N_EINCL
, 0, 0);
1517 /* pop include stack */
1519 s1
->include_stack_ptr
--;
1520 file
= *s1
->include_stack_ptr
;
1524 /* read next char from current input file */
1525 static inline void inp(void)
1527 ch1
= TCC_GETC(file
);
1528 /* end of buffer/file handling */
1533 // printf("ch1=%c 0x%x\n", ch1, ch1);
1536 /* handle '\\n' and '\\r\n' */
1537 static void handle_stray(void)
1542 } else if (ch1
== '\r') {
1545 error("invalid character after '\\'");
1552 } while (ch
== '\\');
1555 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1557 static inline void minp(void)
1566 /* same as minp, but also skip comments */
1567 static void cinp(void)
1574 /* single line C++ comments */
1576 while (ch1
!= '\n' && ch1
!= CH_EOF
)
1578 ch
= ' '; /* return space */
1579 } else if (ch1
== '*') {
1582 while (ch1
!= CH_EOF
) {
1585 if (c
== '*' && ch1
== '/') {
1587 ch
= ' '; /* return space */
1599 /* space exlcuding newline */
1600 static inline int is_space(int ch
)
1602 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1605 static inline void skip_spaces(void)
1607 while (is_space(ch
))
1611 /* skip block of text until #else, #elif or #endif. skip also pairs of
1613 void preprocess_skip(void)
1618 while (ch
!= '\n') {
1629 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1631 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1633 else if (tok
== TOK_ENDIF
)
1639 /* ParseState handling */
1641 /* XXX: currently, no include file info is stored. Thus, we cannot display
1642 accurate messages if the function or data definition spans multiple
1645 /* save current parse state in 's' */
1646 void save_parse_state(ParseState
*s
)
1648 s
->line_num
= file
->line_num
;
1649 s
->macro_ptr
= macro_ptr
;
1654 /* restore parse state from 's' */
1655 void restore_parse_state(ParseState
*s
)
1657 file
->line_num
= s
->line_num
;
1658 macro_ptr
= s
->macro_ptr
;
1663 /* return the number of additionnal 'ints' necessary to store the
1665 static inline int tok_ext_size(int t
)
1684 return LDOUBLE_SIZE
/ 4;
1690 /* token string handling */
1692 static inline void tok_str_new(TokenString
*s
)
1696 s
->last_line_num
= -1;
1699 static void tok_str_free(int *str
)
1710 if (t
== TOK_STR
|| t
== TOK_LSTR
|| t
== TOK_PPNUM
) {
1711 /* XXX: use a macro to be portable on 64 bit ? */
1712 cstr
= (CString
*)(*p
++);
1716 p
+= tok_ext_size(t
);
1722 static void tok_str_add(TokenString
*s
, int t
)
1728 if ((len
& 63) == 0) {
1729 str
= tcc_realloc(str
, (len
+ 64) * sizeof(int));
1738 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1741 CString
*cstr
, *cstr1
;
1745 if (t
== TOK_STR
|| t
== TOK_LSTR
|| t
== TOK_PPNUM
) {
1746 /* special case: need to duplicate string */
1748 cstr
= tcc_malloc(sizeof(CString
));
1751 cstr
->size_allocated
= size
;
1752 cstr
->data_allocated
= tcc_malloc(size
);
1753 cstr
->data
= cstr
->data_allocated
;
1754 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1756 tok_str_add(s
, cv1
.tab
[0]);
1758 n
= tok_ext_size(t
);
1760 tok_str_add(s
, cv
->tab
[i
]);
1764 /* add the current parse token in token string 's' */
1765 static void tok_str_add_tok(TokenString
*s
)
1769 /* save line number info */
1770 if (file
->line_num
!= s
->last_line_num
) {
1771 s
->last_line_num
= file
->line_num
;
1772 cval
.i
= s
->last_line_num
;
1773 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1775 tok_str_add2(s
, tok
, &tokc
);
1778 /* get a token from an integer array and increment pointer accordingly */
1779 static int tok_get(int **tok_str
, CValue
*cv
)
1785 n
= tok_ext_size(t
);
1792 /* eval an expression for #if/#elif */
1793 int expr_preprocess(void)
1799 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1800 next(); /* do macro subst */
1801 if (tok
== TOK_DEFINED
) {
1806 c
= sym_find1(&define_stack
, tok
) != 0;
1811 } else if (tok
>= TOK_IDENT
) {
1812 /* if undefined macro */
1816 tok_str_add_tok(&str
);
1818 tok_str_add(&str
, -1); /* simulate end of file */
1819 tok_str_add(&str
, 0);
1820 /* now evaluate C constant expression */
1821 macro_ptr
= str
.str
;
1825 tok_str_free(str
.str
);
1829 #if defined(DEBUG) || defined(PP_DEBUG)
1830 void tok_print(int *str
)
1836 t
= tok_get(&str
, &cval
);
1839 printf(" %s", get_tok_str(t
, &cval
));
1845 /* parse after #define */
1846 void parse_define(void)
1848 Sym
*s
, *first
, **ps
;
1849 int v
, t
, varg
, is_vaargs
;
1853 /* XXX: should check if same macro (ANSI) */
1856 /* '(' must be just after macro definition for MACRO_FUNC */
1861 while (tok
!= ')') {
1865 if (varg
== TOK_DOTS
) {
1866 varg
= TOK___VA_ARGS__
;
1868 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1872 if (varg
< TOK_IDENT
)
1873 error("badly punctuated parameter list");
1874 s
= sym_push1(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1885 /* EOF testing necessary for '-D' handling */
1886 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1887 tok_str_add2(&str
, tok
, &tokc
);
1890 tok_str_add(&str
, 0);
1892 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1895 s
= sym_push1(&define_stack
, v
, t
, (int)str
.str
);
1899 /* XXX: use a token or a hash table to accelerate matching ? */
1900 static CachedInclude
*search_cached_include(TCCState
*s1
,
1901 int type
, const char *filename
)
1906 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
1907 e
= s1
->cached_includes
[i
];
1908 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
1914 static inline void add_cached_include(TCCState
*s1
, int type
,
1915 const char *filename
, int ifndef_macro
)
1919 if (search_cached_include(s1
, type
, filename
))
1922 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
1924 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
1928 strcpy(e
->filename
, filename
);
1929 e
->ifndef_macro
= ifndef_macro
;
1930 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
1935 INCLUDE_STATE_NONE
= 0,
1936 INCLUDE_STATE_SEEK_IFNDEF
,
1939 void preprocess(void)
1941 TCCState
*s1
= tcc_state
;
1943 enum IncludeState state
;
1944 char buf
[1024], *q
, *p
;
1950 return_linefeed
= 1; /* linefeed will be returned as a
1951 token. EOF is also returned as line feed */
1952 state
= INCLUDE_STATE_NONE
;
1958 if (tok
== TOK_DEFINE
) {
1961 } else if (tok
== TOK_UNDEF
) {
1963 s
= sym_find1(&define_stack
, tok
);
1964 /* undefine symbol by putting an invalid name */
1966 sym_undef(&define_stack
, s
);
1967 } else if (tok
== TOK_INCLUDE
) {
1972 } else if (ch
== '\"') {
1977 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
1978 if ((q
- buf
) < sizeof(buf
) - 1)
1983 /* eat all spaces and comments after include */
1984 /* XXX: slightly incorrect */
1985 while (ch1
!= '\n' && ch1
!= CH_EOF
)
1988 /* computed #include : either we have only strings or
1989 we have anything enclosed in '<>' */
1992 if (tok
== TOK_STR
) {
1993 while (tok
!= TOK_LINEFEED
) {
1994 if (tok
!= TOK_STR
) {
1996 error("'#include' expects \"FILENAME\" or <FILENAME>");
1998 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2004 while (tok
!= TOK_LINEFEED
) {
2005 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2009 /* check syntax and remove '<>' */
2010 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2011 goto include_syntax
;
2012 memmove(buf
, buf
+ 1, len
- 2);
2013 buf
[len
- 2] = '\0';
2019 e
= search_cached_include(s1
, c
, buf
);
2020 if (e
&& sym_find1(&define_stack
, e
->ifndef_macro
)) {
2021 /* no need to parse the include because the 'ifndef macro'
2024 printf("%s: skipping %s\n", file
->filename
, buf
);
2028 /* first search in current dir if "header.h" */
2030 p
= strrchr(file
->filename
, '/');
2032 size
= p
+ 1 - file
->filename
;
2033 if (size
> sizeof(buf1
) - 1)
2034 size
= sizeof(buf1
) - 1;
2035 memcpy(buf1
, file
->filename
, size
);
2037 pstrcat(buf1
, sizeof(buf1
), buf
);
2038 f
= tcc_open(s1
, buf1
);
2042 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2043 error("#include recursion too deep");
2044 /* now search in all the include paths */
2045 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2046 for(i
= 0; i
< n
; i
++) {
2048 if (i
< s1
->nb_include_paths
)
2049 path
= s1
->include_paths
[i
];
2051 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2052 pstrcpy(buf1
, sizeof(buf1
), path
);
2053 pstrcat(buf1
, sizeof(buf1
), "/");
2054 pstrcat(buf1
, sizeof(buf1
), buf
);
2055 f
= tcc_open(s1
, buf1
);
2059 error("include file '%s' not found", buf
);
2063 printf("%s: including %s\n", file
->filename
, buf1
);
2066 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2067 /* push current file in stack */
2068 /* XXX: fix current line init */
2069 *s1
->include_stack_ptr
++ = file
;
2071 /* add include file debug info */
2073 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2075 /* we check for the construct: #ifndef IDENT \n #define IDENT */
2077 /* get first non space char */
2078 while (is_space(ch
) || ch
== '\n')
2082 state
= INCLUDE_STATE_SEEK_IFNDEF
;
2085 } else if (tok
== TOK_IFNDEF
) {
2088 } else if (tok
== TOK_IF
) {
2089 c
= expr_preprocess();
2091 } else if (tok
== TOK_IFDEF
) {
2095 if (tok
< TOK_IDENT
)
2096 error("invalid argument for '#if%sdef'", c
? "n" : "");
2097 if (state
== INCLUDE_STATE_SEEK_IFNDEF
) {
2099 file
->ifndef_macro
= tok
;
2101 state
= INCLUDE_STATE_NONE
;
2103 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
2105 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2106 error("memory full");
2107 *s1
->ifdef_stack_ptr
++ = c
;
2109 } else if (tok
== TOK_ELSE
) {
2110 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2111 error("#else without matching #if");
2112 if (s1
->ifdef_stack_ptr
[-1] & 2)
2113 error("#else after #else");
2114 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2116 } else if (tok
== TOK_ELIF
) {
2117 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2118 error("#elif without matching #if");
2119 c
= s1
->ifdef_stack_ptr
[-1];
2121 error("#elif after #else");
2122 /* last #if/#elif expression was true: we skip */
2125 c
= expr_preprocess();
2126 s1
->ifdef_stack_ptr
[-1] = c
;
2131 state
= INCLUDE_STATE_NONE
;
2134 } else if (tok
== TOK_ENDIF
) {
2135 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2136 error("#endif without matching #if");
2137 if (file
->ifndef_macro
&&
2138 s1
->ifdef_stack_ptr
== (file
->ifdef_stack_ptr
+ 1)) {
2139 /* '#ifndef macro \n #define macro' was at the start of
2140 file. Now we check if an '#endif' is exactly at the end
2142 while (tok
!= TOK_LINEFEED
)
2144 /* XXX: should also skip comments, but it is more complicated */
2146 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
2147 file
->ifndef_macro
);
2149 /* if not end of file, we must desactivate the ifndef
2151 file
->ifndef_macro
= 0;
2154 s1
->ifdef_stack_ptr
--;
2155 } else if (tok
== TOK_LINE
) {
2158 if (tok
!= TOK_CINT
)
2162 if (tok
!= TOK_LINEFEED
) {
2165 pstrcpy(file
->filename
, sizeof(file
->filename
),
2166 (char *)tokc
.cstr
->data
);
2168 /* NOTE: we do it there to avoid problems with linefeed */
2169 file
->line_num
= line_num
;
2170 } else if (tok
== TOK_ERROR
) {
2173 /* ignore other preprocess commands or #! for C scripts */
2174 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
)
2177 return_linefeed
= 0;
2180 /* read a number in base b */
2181 static int getn(int b
)
2186 if (ch
>= 'a' && ch
<= 'f')
2188 else if (ch
>= 'A' && ch
<= 'F')
2194 if (t
< 0 || t
>= b
)
2202 /* read a character for string or char constant and eval escape codes */
2203 static int getq(void)
2211 /* at most three octal digits */
2215 c
= c
* 8 + ch
- '0';
2218 c
= c
* 8 + ch
- '0';
2223 } else if (ch
== 'x') {
2241 else if (ch
== 'e' && gnu_ext
)
2243 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
2246 error("invalid escaped char");
2249 } else if (c
== '\r' && ch
== '\n') {
2256 /* we use 64 bit numbers */
2259 /* bn = (bn << shift) | or_val */
2260 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2264 for(i
=0;i
<BN_SIZE
;i
++) {
2266 bn
[i
] = (v
<< shift
) | or_val
;
2267 or_val
= v
>> (32 - shift
);
2271 void bn_zero(unsigned int *bn
)
2274 for(i
=0;i
<BN_SIZE
;i
++) {
2279 /* parse number in null terminated string 'p' and return it in the
2281 void parse_number(const char *p
)
2283 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
2285 unsigned int bn
[BN_SIZE
];
2296 goto float_frac_parse
;
2297 } else if (t
== '0') {
2298 if (ch
== 'x' || ch
== 'X') {
2302 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2308 /* parse all digits. cannot check octal numbers at this stage
2309 because of floating point constants */
2311 if (ch
>= 'a' && ch
<= 'f')
2313 else if (ch
>= 'A' && ch
<= 'F')
2321 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2323 error("number too long");
2329 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2330 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2332 /* NOTE: strtox should support that for hexa numbers, but
2333 non ISOC99 libcs do not support it, so we prefer to do
2335 /* hexadecimal or binary floats */
2336 /* XXX: handle overflows */
2348 } else if (t
>= 'a') {
2350 } else if (t
>= 'A') {
2355 bn_lshift(bn
, shift
, t
);
2362 if (t
>= 'a' && t
<= 'f') {
2364 } else if (t
>= 'A' && t
<= 'F') {
2366 } else if (t
>= '0' && t
<= '9') {
2372 error("invalid digit");
2373 bn_lshift(bn
, shift
, t
);
2378 if (ch
!= 'p' && ch
!= 'P')
2379 error("exponent expected");
2385 } else if (ch
== '-') {
2389 if (ch
< '0' || ch
> '9')
2390 error("exponent digits expected");
2391 while (ch
>= '0' && ch
<= '9') {
2392 exp_val
= exp_val
* 10 + ch
- '0';
2395 exp_val
= exp_val
* s
;
2397 /* now we can generate the number */
2398 /* XXX: should patch directly float number */
2399 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
2400 d
= ldexp(d
, exp_val
- frac_bits
);
2405 /* float : should handle overflow */
2407 } else if (t
== 'L') {
2410 /* XXX: not large enough */
2411 tokc
.ld
= (long double)d
;
2417 /* decimal floats */
2419 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2424 while (ch
>= '0' && ch
<= '9') {
2425 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2431 if (ch
== 'e' || ch
== 'E') {
2432 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2436 if (ch
== '-' || ch
== '+') {
2437 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2442 if (ch
< '0' || ch
> '9')
2443 error("exponent digits expected");
2444 while (ch
>= '0' && ch
<= '9') {
2445 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2457 tokc
.f
= strtof(token_buf
, NULL
);
2458 } else if (t
== 'L') {
2461 tokc
.ld
= strtold(token_buf
, NULL
);
2464 tokc
.d
= strtod(token_buf
, NULL
);
2468 unsigned long long n
, n1
;
2471 /* integer number */
2474 if (b
== 10 && *q
== '0') {
2481 /* no need for checks except for base 10 / 8 errors */
2484 } else if (t
>= 'a') {
2486 } else if (t
>= 'A') {
2491 error("invalid digit");
2495 /* detect overflow */
2496 /* XXX: this test is not reliable */
2498 error("integer constant overflow");
2501 /* XXX: not exactly ANSI compliant */
2502 if ((n
& 0xffffffff00000000LL
) != 0) {
2507 } else if (n
> 0x7fffffff) {
2518 error("three 'l's in integer constant");
2521 if (tok
== TOK_CINT
)
2523 else if (tok
== TOK_CUINT
)
2527 } else if (t
== 'U') {
2529 error("two 'u's in integer constant");
2531 if (tok
== TOK_CINT
)
2533 else if (tok
== TOK_CLLONG
)
2540 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2547 /* return next token without macro substitution */
2548 static inline void next_nomacro1(void)
2556 while (ch
== '\n') {
2557 /* during preprocessor parsing, '\n' is a token */
2558 if (return_linefeed
) {
2565 /* preprocessor command if # at start of line after
2588 while (isid(ch
) || isnum(ch
)) {
2589 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2590 error("ident too long");
2595 ts
= tok_alloc(token_buf
, q
- token_buf
);
2597 } else if (isnum(ch
)) {
2599 cstr_reset(&tokcstr
);
2600 /* after the first digit, accept digits, alpha, '.' or sign if
2601 prefixed by 'eEpP' */
2605 cstr_ccat(&tokcstr
, ch
);
2607 if (!(isnum(ch
) || isid(ch
) || ch
== '.' ||
2608 ((ch
== '+' || ch
== '-') &&
2609 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
2612 /* We add a trailing '\0' to ease parsing */
2613 cstr_ccat(&tokcstr
, '\0');
2614 tokc
.cstr
= &tokcstr
;
2616 } else if (ch
== '.') {
2617 /* special dot handling because it can also start a number */
2620 cstr_reset(&tokcstr
);
2621 cstr_ccat(&tokcstr
, '.');
2633 } else if (ch
== '\'') {
2638 /* this cast is needed if >= 128 */
2639 if (tok
== TOK_CCHAR
)
2645 } else if (ch
== '\"') {
2649 cstr_reset(&tokcstr
);
2650 while (ch
!= '\"') {
2653 error("unterminated string");
2655 cstr_ccat(&tokcstr
, b
);
2657 cstr_wccat(&tokcstr
, b
);
2660 cstr_ccat(&tokcstr
, '\0');
2662 cstr_wccat(&tokcstr
, '\0');
2663 tokc
.cstr
= &tokcstr
;
2671 if (*q
== tok
&& q
[1] == ch
) {
2674 /* three chars tests */
2675 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2680 } else if (tok
== TOK_DOTS
) {
2682 error("parse error");
2689 /* single char substitutions */
2692 else if (tok
== '>')
2697 /* return next token without macro substitution. Can read input from
2699 static void next_nomacro(void)
2705 tok
= tok_get(¯o_ptr
, &tokc
);
2706 if (tok
== TOK_LINENUM
) {
2707 file
->line_num
= tokc
.i
;
2716 /* substitute args in macro_str and return allocated string */
2717 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2719 int *st
, last_tok
, t
, notfirst
;
2728 t
= tok_get(¯o_str
, &cval
);
2733 t
= tok_get(¯o_str
, &cval
);
2736 s
= sym_find2(args
, t
);
2743 cstr_ccat(&cstr
, ' ');
2744 t
= tok_get(&st
, &cval
);
2745 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
2748 cstr_ccat(&cstr
, '\0');
2750 printf("stringize: %s\n", (char *)cstr
.data
);
2754 tok_str_add2(&str
, TOK_STR
, &cval
);
2757 tok_str_add2(&str
, t
, &cval
);
2759 } else if (t
>= TOK_IDENT
) {
2760 s
= sym_find2(args
, t
);
2763 /* if '##' is present before or after, no arg substitution */
2764 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2765 /* special case for var arg macros : ## eats the
2766 ',' if empty VA_ARGS variable. */
2767 /* XXX: test of the ',' is not 100%
2768 reliable. should fix it to avoid security
2770 if (gnu_ext
&& s
->t
&&
2771 last_tok
== TOK_TWOSHARPS
&&
2772 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
2774 /* suppress ',' '##' */
2777 /* suppress '##' and add variable */
2785 t1
= tok_get(&st
, &cval
);
2788 tok_str_add2(&str
, t1
, &cval
);
2792 macro_subst(&str
, nested_list
, st
);
2795 tok_str_add(&str
, t
);
2798 tok_str_add2(&str
, t
, &cval
);
2802 tok_str_add(&str
, 0);
2806 /* handle the '##' operator */
2807 static int *macro_twosharps(void)
2812 const char *p1
, *p2
;
2814 TokenString macro_str1
;
2818 tok_str_new(¯o_str1
);
2824 while (*macro_ptr
== TOK_TWOSHARPS
) {
2826 macro_ptr1
= macro_ptr
;
2829 t
= tok_get(¯o_ptr
, &cval
);
2831 /* We concatenate the two tokens if we have an
2832 identifier or a preprocessing number */
2834 p1
= get_tok_str(tok
, &tokc
);
2835 cstr_cat(&cstr
, p1
);
2836 p2
= get_tok_str(t
, &cval
);
2837 cstr_cat(&cstr
, p2
);
2838 cstr_ccat(&cstr
, '\0');
2840 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
2841 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
2842 if (tok
== TOK_PPNUM
) {
2843 /* if number, then create a number token */
2844 /* NOTE: no need to allocate because
2845 tok_str_add2() does it */
2848 /* if identifier, we must do a test to
2849 validate we have a correct identifier */
2850 if (t
== TOK_PPNUM
) {
2860 if (!isnum(c
) && !isid(c
))
2864 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
2865 tok
= ts
->tok
; /* modify current token */
2868 const char *str
= cstr
.data
;
2869 const unsigned char *q
;
2871 /* we look for a valid token */
2872 /* XXX: do more extensive checks */
2873 if (!strcmp(str
, ">>=")) {
2875 } else if (!strcmp(str
, "<<=")) {
2877 } else if (strlen(str
) == 2) {
2878 /* search in two bytes table */
2883 if (q
[0] == str
[0] && q
[1] == str
[1])
2890 /* NOTE: because get_tok_str use a static buffer,
2893 p1
= get_tok_str(tok
, &tokc
);
2894 cstr_cat(&cstr
, p1
);
2895 cstr_ccat(&cstr
, '\0');
2896 p2
= get_tok_str(t
, &cval
);
2897 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
2898 /* cannot merge tokens: just add them separately */
2899 tok_str_add2(¯o_str1
, tok
, &tokc
);
2900 /* XXX: free associated memory ? */
2907 tok_str_add2(¯o_str1
, tok
, &tokc
);
2910 tok_str_add(¯o_str1
, 0);
2911 return macro_str1
.str
;
2915 /* do macro substitution of current token with macro 's' and add
2916 result to (tok_str,tok_len). 'nested_list' is the list of all
2917 macros we got inside to avoid recursing. Return non zero if no
2918 substitution needs to be done */
2919 static int macro_subst_tok(TokenString
*tok_str
,
2920 Sym
**nested_list
, Sym
*s
)
2922 Sym
*args
, *sa
, *sa1
;
2923 int mstr_allocated
, parlevel
, *mstr
, t
;
2929 /* if symbol is a macro, prepare substitution */
2930 /* if nested substitution, do nothing */
2931 if (sym_find2(*nested_list
, tok
))
2934 /* special macros */
2935 if (tok
== TOK___LINE__
) {
2936 cval
.i
= file
->line_num
;
2937 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
2938 } else if (tok
== TOK___FILE__
) {
2939 cstrval
= file
->filename
;
2941 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2942 } else if (tok
== TOK___DATE__
) {
2943 cstrval
= "Jan 1 2002";
2945 } else if (tok
== TOK___TIME__
) {
2946 cstrval
= "00:00:00";
2949 cstr_cat(&cstr
, cstrval
);
2950 cstr_ccat(&cstr
, '\0');
2952 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2957 if (s
->t
== MACRO_FUNC
) {
2958 /* NOTE: we do not use next_nomacro to avoid eating the
2959 next token. XXX: find better solution */
2963 while (is_space(ch
) || ch
== '\n')
2967 if (t
!= '(') /* no macro subst */
2970 /* argument macro */
2975 /* NOTE: empty args are allowed, except if no args */
2977 /* handle '()' case */
2978 if (!args
&& tok
== ')')
2981 error("macro '%s' used with too many args",
2982 get_tok_str(s
->v
, 0));
2985 /* NOTE: non zero sa->t indicates VA_ARGS */
2986 while ((parlevel
> 0 ||
2988 (tok
!= ',' || sa
->t
))) &&
2992 else if (tok
== ')')
2994 tok_str_add2(&str
, tok
, &tokc
);
2997 tok_str_add(&str
, 0);
2998 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->t
, (int)str
.str
);
3001 /* special case for gcc var args: add an empty
3002 var arg argument if it is omitted */
3003 if (sa
&& sa
->t
&& gnu_ext
)
3013 error("macro '%s' used with too few args",
3014 get_tok_str(s
->v
, 0));
3017 /* now subst each arg */
3018 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3023 tok_str_free((int *)sa
->c
);
3029 sym_push2(nested_list
, s
->v
, 0, 0);
3030 macro_subst(tok_str
, nested_list
, mstr
);
3031 /* pop nested defined symbol */
3033 *nested_list
= sa1
->prev
;
3041 /* do macro substitution of macro_str and add result to
3042 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3043 inside to avoid recursing. */
3044 static void macro_subst(TokenString
*tok_str
,
3045 Sym
**nested_list
, int *macro_str
)
3048 int *saved_macro_ptr
;
3051 saved_macro_ptr
= macro_ptr
;
3052 macro_ptr
= macro_str
;
3053 /* first scan for '##' operator handling */
3054 macro_str1
= macro_twosharps();
3055 macro_ptr
= macro_str1
;
3061 s
= sym_find1(&define_stack
, tok
);
3063 if (macro_subst_tok(tok_str
, nested_list
, s
) != 0)
3067 tok_str_add2(tok_str
, tok
, &tokc
);
3070 macro_ptr
= saved_macro_ptr
;
3071 tok_str_free(macro_str1
);
3074 /* return next token with macro substitution */
3075 static void next(void)
3077 Sym
*nested_list
, *s
;
3080 /* special 'ungettok' case for label parsing */
3089 /* if not reading from macro substituted string, then try
3090 to substitute macros */
3091 if (tok
>= TOK_IDENT
) {
3092 s
= sym_find1(&define_stack
, tok
);
3094 /* we have a macro: we try to substitute */
3097 if (macro_subst_tok(&str
, &nested_list
, s
) == 0) {
3098 /* substitution done, NOTE: maybe empty */
3099 tok_str_add(&str
, 0);
3100 macro_ptr
= str
.str
;
3101 macro_ptr_allocated
= str
.str
;
3108 /* end of macro string: free it */
3109 tok_str_free(macro_ptr_allocated
);
3115 /* convert preprocessor tokens into C tokens */
3116 if (tok
== TOK_PPNUM
) {
3117 parse_number((char *)tokc
.cstr
->data
);
3121 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3125 void swap(int *p
, int *q
)
3133 void vsetc(int t
, int r
, CValue
*vc
)
3137 if (vtop
>= vstack
+ VSTACK_SIZE
)
3138 error("memory full");
3139 /* cannot let cpu flags if other instruction are generated. Also
3140 avoid leaving VT_JMP anywhere except on the top of the stack
3141 because it would complicate the code generator. */
3142 if (vtop
>= vstack
) {
3143 v
= vtop
->r
& VT_VALMASK
;
3144 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
3150 vtop
->r2
= VT_CONST
;
3154 /* push integer constant */
3159 vsetc(VT_INT
, VT_CONST
, &cval
);
3162 /* Return a static symbol pointing to a section */
3163 static Sym
*get_sym_ref(int t
, Section
*sec
,
3164 unsigned long offset
, unsigned long size
)
3170 sym
= sym_push1(&global_stack
, v
, t
| VT_STATIC
, 0);
3171 sym
->r
= VT_CONST
| VT_SYM
;
3172 put_extern_sym(sym
, sec
, offset
, size
);
3176 /* push a reference to a section offset by adding a dummy symbol */
3177 static void vpush_ref(int t
, Section
*sec
, unsigned long offset
, unsigned long size
)
3182 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
3183 vtop
->sym
= get_sym_ref(t
, sec
, offset
, size
);
3186 /* define a new external reference to a symbol 'v' of type 'u' */
3187 static Sym
*external_global_sym(int v
, int u
, int r
)
3193 /* push forward reference */
3194 s
= sym_push1(&global_stack
,
3195 v
, u
| VT_EXTERN
, 0);
3196 s
->r
= r
| VT_CONST
| VT_SYM
;
3201 /* define a new external reference to a symbol 'v' of type 'u' */
3202 static Sym
*external_sym(int v
, int u
, int r
)
3208 /* push forward reference */
3209 s
= sym_push(v
, u
| VT_EXTERN
, r
| VT_CONST
| VT_SYM
, 0);
3214 /* push a reference to global symbol v */
3215 static void vpush_global_sym(int t
, int v
)
3220 sym
= external_global_sym(v
, t
, 0);
3222 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
3226 void vset(int t
, int r
, int v
)
3243 void vpushv(SValue
*v
)
3245 if (vtop
>= vstack
+ VSTACK_SIZE
)
3246 error("memory full");
3256 /* save r to the memory stack, and mark it as being free */
3257 void save_reg(int r
)
3259 int l
, saved
, t
, size
, align
;
3262 /* modify all stack values */
3265 for(p
=vstack
;p
<=vtop
;p
++) {
3266 if ((p
->r
& VT_VALMASK
) == r
||
3267 (p
->r2
& VT_VALMASK
) == r
) {
3268 /* must save value on stack if not already done */
3270 /* NOTE: must reload 'r' because r might be equal to r2 */
3271 r
= p
->r
& VT_VALMASK
;
3272 /* store register in the stack */
3274 if ((p
->r
& VT_LVAL
) ||
3275 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
3277 size
= type_size(t
, &align
);
3278 loc
= (loc
- size
) & -align
;
3280 sv
.r
= VT_LOCAL
| VT_LVAL
;
3283 #ifdef TCC_TARGET_I386
3284 /* x86 specific: need to pop fp register ST0 if saved */
3286 o(0xd9dd); /* fstp %st(1) */
3289 /* special long long case */
3290 if ((t
& VT_BTYPE
) == VT_LLONG
) {
3297 /* mark that stack entry as being saved on the stack */
3298 if (p
->r
& VT_LVAL
) {
3299 /* also suppress the bounded flag because the
3300 relocation address of the function was stored in
3302 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
3304 p
->r
= lvalue_type(p
->t
) | VT_LOCAL
;
3312 /* find a free register of class 'rc'. If none, save one register */
3318 /* find a free register */
3319 for(r
=0;r
<NB_REGS
;r
++) {
3320 if (reg_classes
[r
] & rc
) {
3321 for(p
=vstack
;p
<=vtop
;p
++) {
3322 if ((p
->r
& VT_VALMASK
) == r
||
3323 (p
->r2
& VT_VALMASK
) == r
)
3331 /* no register left : free the first one on the stack (VERY
3332 IMPORTANT to start from the bottom to ensure that we don't
3333 spill registers used in gen_opi()) */
3334 for(p
=vstack
;p
<=vtop
;p
++) {
3335 r
= p
->r
& VT_VALMASK
;
3336 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
3338 /* also look at second register (if long long) */
3339 r
= p
->r2
& VT_VALMASK
;
3340 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
3346 /* Should never comes here */
3350 /* save registers up to (vtop - n) stack entry */
3351 void save_regs(int n
)
3356 for(p
= vstack
;p
<= p1
; p
++) {
3357 r
= p
->r
& VT_VALMASK
;
3364 /* move register 's' to 'r', and flush previous value of r to memory
3366 void move_reg(int r
, int s
)
3379 /* get address of vtop (vtop MUST BE an lvalue) */
3382 vtop
->r
&= ~VT_LVAL
;
3383 /* tricky: if saved lvalue, then we can go back to lvalue */
3384 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
3385 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
3388 #ifdef CONFIG_TCC_BCHECK
3389 /* generate lvalue bound code */
3394 vtop
->r
&= ~VT_MUSTBOUND
;
3395 /* if lvalue, then use checking code before dereferencing */
3396 if (vtop
->r
& VT_LVAL
) {
3397 /* if not VT_BOUNDED value, then make one */
3398 if (!(vtop
->r
& VT_BOUNDED
)) {
3399 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
3400 /* must save type because we must set it to int to get pointer */
3405 gen_bounded_ptr_add();
3406 vtop
->r
|= lval_type
;
3409 /* then check for dereferencing */
3410 gen_bounded_ptr_deref();
3415 /* store vtop a register belonging to class 'rc'. lvalues are
3416 converted to values. Cannot be used if cannot be converted to
3417 register value (such as structures). */
3420 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
3421 unsigned long long ll
;
3423 /* NOTE: get_reg can modify vstack[] */
3424 if (vtop
->t
& VT_BITFIELD
) {
3425 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
3426 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3427 /* remove bit field info to avoid loops */
3428 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3429 /* generate shifts */
3430 vpushi(32 - (bit_pos
+ bit_size
));
3432 vpushi(32 - bit_size
);
3433 /* NOTE: transformed to SHR if unsigned */
3437 if (is_float(vtop
->t
) &&
3438 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3441 unsigned long offset
;
3443 /* XXX: unify with initializers handling ? */
3444 /* CPUs usually cannot use float constants, so we store them
3445 generically in data segment */
3446 size
= type_size(vtop
->t
, &align
);
3447 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
3448 data_section
->data_offset
= offset
;
3449 /* XXX: not portable yet */
3450 ptr
= section_ptr_add(data_section
, size
);
3453 ptr
[i
] = vtop
->c
.tab
[i
];
3454 sym
= get_sym_ref(vtop
->t
, data_section
, offset
, size
<< 2);
3455 vtop
->r
|= VT_LVAL
| VT_SYM
;
3459 #ifdef CONFIG_TCC_BCHECK
3460 if (vtop
->r
& VT_MUSTBOUND
)
3464 r
= vtop
->r
& VT_VALMASK
;
3465 /* need to reload if:
3467 - lvalue (need to dereference pointer)
3468 - already a register, but not in the right class */
3469 if (r
>= VT_CONST
||
3470 (vtop
->r
& VT_LVAL
) ||
3471 !(reg_classes
[r
] & rc
) ||
3472 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
3473 !(reg_classes
[vtop
->r2
] & rc
))) {
3475 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
3476 /* two register type load : expand to two words
3478 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3481 vtop
->c
.ui
= ll
; /* first word */
3483 vtop
->r
= r
; /* save register value */
3484 vpushi(ll
>> 32); /* second word */
3485 } else if (r
>= VT_CONST
||
3486 (vtop
->r
& VT_LVAL
)) {
3487 /* load from memory */
3490 vtop
[-1].r
= r
; /* save register value */
3491 /* increment pointer to get second word */
3498 /* move registers */
3501 vtop
[-1].r
= r
; /* save register value */
3502 vtop
->r
= vtop
[-1].r2
;
3504 /* allocate second register */
3511 /* write second register */
3513 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
3515 /* lvalue of scalar type : need to use lvalue type
3516 because of possible cast */
3519 /* compute memory access type */
3520 if (vtop
->r
& VT_LVAL_BYTE
)
3522 else if (vtop
->r
& VT_LVAL_SHORT
)
3524 if (vtop
->r
& VT_LVAL_UNSIGNED
)
3528 /* restore wanted type */
3531 /* one register type load */
3540 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3541 void gv2(int rc1
, int rc2
)
3545 /* generate more generic register first. But VT_JMP or VT_CMP
3546 values must be generated first in all cases to avoid possible
3548 v
= vtop
[0].r
& VT_VALMASK
;
3549 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
3554 /* test if reload is needed for first register */
3555 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
3565 /* test if reload is needed for first register */
3566 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
3572 /* expand long long on stack in two int registers */
3577 u
= vtop
->t
& VT_UNSIGNED
;
3580 vtop
[0].r
= vtop
[-1].r2
;
3581 vtop
[0].r2
= VT_CONST
;
3582 vtop
[-1].r2
= VT_CONST
;
3583 vtop
[0].t
= VT_INT
| u
;
3584 vtop
[-1].t
= VT_INT
| u
;
3587 /* build a long long from two ints */
3590 gv2(RC_INT
, RC_INT
);
3591 vtop
[-1].r2
= vtop
[0].r
;
3596 /* rotate n first stack elements to the bottom */
3603 for(i
=-n
+1;i
!=0;i
++)
3604 vtop
[i
] = vtop
[i
+1];
3608 /* pop stack value */
3612 v
= vtop
->r
& VT_VALMASK
;
3613 #ifdef TCC_TARGET_I386
3614 /* for x86, we need to pop the FP stack */
3615 if (v
== REG_ST0
&& !nocode_wanted
) {
3616 o(0xd9dd); /* fstp %st(1) */
3619 if (v
== VT_JMP
|| v
== VT_JMPI
) {
3620 /* need to put correct jump if && or || without test */
3626 /* convert stack entry to register and duplicate its value in another
3634 if ((t
& VT_BTYPE
) == VT_LLONG
) {
3641 /* stack: H L L1 H1 */
3649 /* duplicate value */
3660 load(r1
, &sv
); /* move r to r1 */
3662 /* duplicates value */
3667 /* generate CPU independent (unsigned) long long operations */
3668 void gen_opl(int op
)
3670 int t
, a
, b
, op1
, c
, i
;
3678 func
= TOK___divdi3
;
3681 func
= TOK___udivdi3
;
3684 func
= TOK___moddi3
;
3687 func
= TOK___umoddi3
;
3689 /* call generic long long function */
3690 gfunc_start(&gf
, FUNC_CDECL
);
3693 vpush_global_sym(func_old_type
, func
);
3697 vtop
->r2
= REG_LRET
;
3710 /* stack: L1 H1 L2 H2 */
3715 vtop
[-2] = vtop
[-3];
3718 /* stack: H1 H2 L1 L2 */
3724 /* stack: H1 H2 L1 L2 ML MH */
3727 /* stack: ML MH H1 H2 L1 L2 */
3731 /* stack: ML MH H1 L2 H2 L1 */
3736 /* stack: ML MH M1 M2 */
3739 } else if (op
== '+' || op
== '-') {
3740 /* XXX: add non carry method too (for MIPS or alpha) */
3746 /* stack: H1 H2 (L1 op L2) */
3749 gen_op(op1
+ 1); /* TOK_xxxC2 */
3752 /* stack: H1 H2 (L1 op L2) */
3755 /* stack: (L1 op L2) H1 H2 */
3757 /* stack: (L1 op L2) (H1 op H2) */
3765 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3770 /* stack: L H shift */
3772 /* constant: simpler */
3773 /* NOTE: all comments are for SHL. the other cases are
3774 done by swaping words */
3785 if (op
!= TOK_SAR
) {
3818 /* XXX: should provide a faster fallback on x86 ? */
3821 func
= TOK___sardi3
;
3824 func
= TOK___shrdi3
;
3827 func
= TOK___shldi3
;
3833 /* compare operations */
3839 /* stack: L1 H1 L2 H2 */
3841 vtop
[-1] = vtop
[-2];
3843 /* stack: L1 L2 H1 H2 */
3846 /* when values are equal, we need to compare low words. since
3847 the jump is inverted, we invert the test too. */
3850 else if (op1
== TOK_GT
)
3852 else if (op1
== TOK_ULT
)
3854 else if (op1
== TOK_UGT
)
3859 if (op1
!= TOK_NE
) {
3863 /* generate non equal test */
3864 /* XXX: NOT PORTABLE yet */
3868 #ifdef TCC_TARGET_I386
3869 b
= psym(0x850f, 0);
3871 error("not implemented");
3879 vset(VT_INT
, VT_JMPI
, a
);
3884 /* handle integer constant optimizations and various machine
3886 void gen_opic(int op
)
3893 /* currently, we cannot do computations with forward symbols */
3894 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3895 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3899 case '+': v1
->c
.i
+= fc
; break;
3900 case '-': v1
->c
.i
-= fc
; break;
3901 case '&': v1
->c
.i
&= fc
; break;
3902 case '^': v1
->c
.i
^= fc
; break;
3903 case '|': v1
->c
.i
|= fc
; break;
3904 case '*': v1
->c
.i
*= fc
; break;
3911 /* if division by zero, generate explicit division */
3914 error("division by zero in constant");
3918 default: v1
->c
.i
/= fc
; break;
3919 case '%': v1
->c
.i
%= fc
; break;
3920 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3921 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3924 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3925 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3926 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3928 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3929 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3930 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3931 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3932 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3933 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3934 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3935 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3936 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3937 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3939 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3940 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3946 /* if commutative ops, put c2 as constant */
3947 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3948 op
== '|' || op
== '*')) {
3953 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3956 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3957 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3963 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3964 /* try to use shifts instead of muls or divs */
3965 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3974 else if (op
== TOK_PDIV
)
3980 } else if (c2
&& (op
== '+' || op
== '-') &&
3981 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
3982 (VT_CONST
| VT_SYM
)) {
3983 /* symbol + constant case */
3990 if (!nocode_wanted
) {
3991 /* call low level op generator */
4000 /* generate a floating point operation with constant propagation */
4001 void gen_opif(int op
)
4009 /* currently, we cannot do computations with forward symbols */
4010 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4011 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4013 if (v1
->t
== VT_FLOAT
) {
4016 } else if (v1
->t
== VT_DOUBLE
) {
4024 /* NOTE: we only do constant propagation if finite number (not
4025 NaN or infinity) (ANSI spec) */
4026 if (!ieee_finite(f1
) || !ieee_finite(f2
))
4030 case '+': f1
+= f2
; break;
4031 case '-': f1
-= f2
; break;
4032 case '*': f1
*= f2
; break;
4036 error("division by zero in constant");
4041 /* XXX: also handles tests ? */
4045 /* XXX: overflow test ? */
4046 if (v1
->t
== VT_FLOAT
) {
4048 } else if (v1
->t
== VT_DOUBLE
) {
4056 if (!nocode_wanted
) {
4064 int pointed_size(int t
)
4066 return type_size(pointed_type(t
), &t
);
4070 void check_pointer_types(SValue
*p1
, SValue
*p2
)
4072 char buf1
[256], buf2
[256];
4076 if (!is_compatible_types(t1
, t2
)) {
4077 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
4078 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
4079 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
4084 /* generic gen_op: handles types problems */
4087 int u
, t1
, t2
, bt1
, bt2
, t
;
4091 bt1
= t1
& VT_BTYPE
;
4092 bt2
= t2
& VT_BTYPE
;
4094 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
4095 /* at least one operand is a pointer */
4096 /* relationnal op: must be both pointers */
4097 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4098 // check_pointer_types(vtop, vtop - 1);
4099 /* pointers are handled are unsigned */
4100 t
= VT_INT
| VT_UNSIGNED
;
4103 /* if both pointers, then it must be the '-' op */
4104 if ((t1
& VT_BTYPE
) == VT_PTR
&&
4105 (t2
& VT_BTYPE
) == VT_PTR
) {
4107 error("cannot use pointers here");
4108 // check_pointer_types(vtop - 1, vtop);
4109 /* XXX: check that types are compatible */
4110 u
= pointed_size(t1
);
4112 /* set to integer type */
4117 /* exactly one pointer : must be '+' or '-'. */
4118 if (op
!= '-' && op
!= '+')
4119 error("cannot use pointers here");
4120 /* Put pointer as first operand */
4121 if ((t2
& VT_BTYPE
) == VT_PTR
) {
4125 /* XXX: cast to int ? (long long case) */
4126 vpushi(pointed_size(vtop
[-1].t
));
4128 #ifdef CONFIG_TCC_BCHECK
4129 /* if evaluating constant expression, no code should be
4130 generated, so no bound check */
4131 if (do_bounds_check
&& !const_wanted
) {
4132 /* if bounded pointers, we generate a special code to
4139 gen_bounded_ptr_add();
4145 /* put again type if gen_opic() swaped operands */
4148 } else if (is_float(bt1
) || is_float(bt2
)) {
4149 /* compute bigger type and do implicit casts */
4150 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
4152 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
4157 /* floats can only be used for a few operations */
4158 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
4159 (op
< TOK_ULT
|| op
> TOK_GT
))
4160 error("invalid operands for binary operation");
4162 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
4163 /* cast to biggest op */
4165 /* convert to unsigned if it does not fit in a long long */
4166 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4167 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4171 /* integer operations */
4173 /* convert to unsigned if it does not fit in an integer */
4174 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4175 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4178 /* XXX: currently, some unsigned operations are explicit, so
4179 we modify them here */
4180 if (t
& VT_UNSIGNED
) {
4187 else if (op
== TOK_LT
)
4189 else if (op
== TOK_GT
)
4191 else if (op
== TOK_LE
)
4193 else if (op
== TOK_GE
)
4199 /* special case for shifts and long long: we keep the shift as
4201 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
4207 else if ((t
& VT_BTYPE
) == VT_LLONG
)
4211 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4212 /* relationnal op: the result is an int */
4220 /* generic itof for unsigned long long case */
4221 void gen_cvt_itof1(int t
)
4225 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
4226 (VT_LLONG
| VT_UNSIGNED
)) {
4228 gfunc_start(&gf
, FUNC_CDECL
);
4231 vpush_global_sym(func_old_type
, TOK___ulltof
);
4232 else if (t
== VT_DOUBLE
)
4233 vpush_global_sym(func_old_type
, TOK___ulltod
);
4235 vpush_global_sym(func_old_type
, TOK___ulltold
);
4244 /* generic ftoi for unsigned long long case */
4245 void gen_cvt_ftoi1(int t
)
4250 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
4251 /* not handled natively */
4252 gfunc_start(&gf
, FUNC_CDECL
);
4253 st
= vtop
->t
& VT_BTYPE
;
4256 vpush_global_sym(func_old_type
, TOK___fixunssfdi
);
4257 else if (st
== VT_DOUBLE
)
4258 vpush_global_sym(func_old_type
, TOK___fixunsdfdi
);
4260 vpush_global_sym(func_old_type
, TOK___fixunsxfdi
);
4264 vtop
->r2
= REG_LRET
;
4270 /* force char or short cast */
4271 void force_charshort_cast(int t
)
4275 /* XXX: add optimization if lvalue : just change type and offset */
4280 if (t
& VT_UNSIGNED
) {
4281 vpushi((1 << bits
) - 1);
4292 /* cast 'vtop' to 't' type */
4293 void gen_cast(int t
)
4295 int sbt
, dbt
, sf
, df
, c
;
4297 /* special delayed cast for char/short */
4298 /* XXX: in some cases (multiple cascaded casts), it may still
4300 if (vtop
->r
& VT_MUSTCAST
) {
4301 vtop
->r
&= ~VT_MUSTCAST
;
4302 force_charshort_cast(vtop
->t
);
4305 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
4306 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
4308 if (sbt
!= dbt
&& !nocode_wanted
) {
4311 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4313 /* convert from fp to fp */
4315 /* constant case: we can do it now */
4316 /* XXX: in ISOC, cannot do it if error in convert */
4317 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
4318 vtop
->c
.f
= (float)vtop
->c
.d
;
4319 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
4320 vtop
->c
.f
= (float)vtop
->c
.ld
;
4321 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
4322 vtop
->c
.d
= (double)vtop
->c
.f
;
4323 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
4324 vtop
->c
.d
= (double)vtop
->c
.ld
;
4325 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
4326 vtop
->c
.ld
= (long double)vtop
->c
.f
;
4327 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
4328 vtop
->c
.ld
= (long double)vtop
->c
.d
;
4330 /* non constant case: generate code */
4334 /* convert int to fp */
4337 case VT_LLONG
| VT_UNSIGNED
:
4339 /* XXX: add const cases for long long */
4341 case VT_INT
| VT_UNSIGNED
:
4343 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
4344 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
4345 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
4350 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
4351 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
4352 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
4361 /* convert fp to int */
4362 /* we handle char/short/etc... with generic code */
4363 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
4364 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
4369 case VT_LLONG
| VT_UNSIGNED
:
4371 /* XXX: add const cases for long long */
4373 case VT_INT
| VT_UNSIGNED
:
4375 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4376 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4377 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4383 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4384 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4385 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4393 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
4394 /* additionnal cast for char/short/bool... */
4398 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
4399 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
4400 /* scalar to long long */
4402 if (sbt
== (VT_INT
| VT_UNSIGNED
))
4403 vtop
->c
.ll
= vtop
->c
.ui
;
4405 vtop
->c
.ll
= vtop
->c
.i
;
4407 /* machine independant conversion */
4409 /* generate high word */
4410 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
4418 /* patch second register */
4419 vtop
[-1].r2
= vtop
->r
;
4423 } else if (dbt
== VT_BOOL
) {
4424 /* scalar to bool */
4427 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
4428 (dbt
& VT_BTYPE
) == VT_SHORT
) {
4429 force_charshort_cast(t
);
4430 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
4432 if (sbt
== VT_LLONG
) {
4433 /* from long long: just take low order word */
4437 /* if lvalue and single word type, nothing to do because
4438 the lvalue already contains the real type size (see
4439 VT_LVAL_xxx constants) */
4445 /* return type size. Put alignment at 'a' */
4446 int type_size(int t
, int *a
)
4452 if (bt
== VT_STRUCT
) {
4454 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4455 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
4457 } else if (bt
== VT_PTR
) {
4459 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4460 return type_size(s
->t
, a
) * s
->c
;
4465 } else if (bt
== VT_LDOUBLE
) {
4467 return LDOUBLE_SIZE
;
4468 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
4471 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
4474 } else if (bt
== VT_SHORT
) {
4478 /* char, void, function, _Bool */
4484 /* return the pointed type of t */
4485 int pointed_type(int t
)
4488 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4489 return s
->t
| (t
& ~VT_TYPE
);
4492 int mk_pointer(int t
)
4496 sym_push(p
, t
, 0, -1);
4497 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
4500 int is_compatible_types(int t1
, int t2
)
4507 bt1
= t1
& VT_BTYPE
;
4508 bt2
= t2
& VT_BTYPE
;
4509 if (bt1
== VT_PTR
) {
4510 t1
= pointed_type(t1
);
4511 /* if function, then convert implicitely to function pointer */
4512 if (bt2
!= VT_FUNC
) {
4515 t2
= pointed_type(t2
);
4517 /* void matches everything */
4520 if (t1
== VT_VOID
|| t2
== VT_VOID
)
4522 return is_compatible_types(t1
, t2
);
4523 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4525 } else if (bt1
== VT_FUNC
) {
4528 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
4529 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
4530 if (!is_compatible_types(s1
->t
, s2
->t
))
4532 /* XXX: not complete */
4533 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
4537 while (s1
!= NULL
) {
4540 if (!is_compatible_types(s1
->t
, s2
->t
))
4549 /* XXX: not complete */
4554 /* print a type. If 'varstr' is not NULL, then the variable is also
4555 printed in the type */
4557 /* XXX: add array and function pointers */
4558 void type_to_str(char *buf
, int buf_size
,
4559 int t
, const char *varstr
)
4569 if (t
& VT_UNSIGNED
)
4570 pstrcat(buf
, buf_size
, "unsigned ");
4600 tstr
= "long double";
4602 pstrcat(buf
, buf_size
, tstr
);
4606 if (bt
== VT_STRUCT
)
4610 pstrcat(buf
, buf_size
, tstr
);
4611 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
4612 if (v
>= SYM_FIRST_ANOM
)
4613 pstrcat(buf
, buf_size
, "<anonymous>");
4615 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
4618 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4619 type_to_str(buf
, buf_size
, s
->t
, varstr
);
4620 pstrcat(buf
, buf_size
, "(");
4622 while (sa
!= NULL
) {
4623 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
4624 pstrcat(buf
, buf_size
, buf1
);
4627 pstrcat(buf
, buf_size
, ", ");
4629 pstrcat(buf
, buf_size
, ")");
4632 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4633 pstrcpy(buf1
, sizeof(buf1
), "*");
4635 pstrcat(buf1
, sizeof(buf1
), varstr
);
4636 type_to_str(buf
, buf_size
, s
->t
, buf1
);
4640 pstrcat(buf
, buf_size
, " ");
4641 pstrcat(buf
, buf_size
, varstr
);
4646 /* verify type compatibility to store vtop in 'dt' type, and generate
4648 void gen_assign_cast(int dt
)
4651 char buf1
[256], buf2
[256];
4653 st
= vtop
->t
; /* source type */
4654 if ((dt
& VT_BTYPE
) == VT_PTR
) {
4655 /* special cases for pointers */
4656 /* a function is implicitely a function pointer */
4657 if ((st
& VT_BTYPE
) == VT_FUNC
) {
4658 if (!is_compatible_types(pointed_type(dt
), st
))
4663 /* '0' can also be a pointer */
4664 if ((st
& VT_BTYPE
) == VT_INT
&&
4665 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
4669 if (!is_compatible_types(dt
, st
)) {
4671 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
4672 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
4673 error("cannot cast '%s' to '%s'", buf1
, buf2
);
4679 /* store vtop in lvalue pushed on stack */
4682 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
4686 sbt
= vtop
->t
& VT_BTYPE
;
4687 dbt
= ft
& VT_BTYPE
;
4688 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
4689 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
4690 /* optimize char/short casts */
4691 delayed_cast
= VT_MUSTCAST
;
4692 vtop
->t
= ft
& VT_TYPE
;
4695 gen_assign_cast(ft
& VT_TYPE
);
4698 if (sbt
== VT_STRUCT
) {
4699 /* if structure, only generate pointer */
4700 /* structure assignment : generate memcpy */
4701 /* XXX: optimize if small size */
4702 if (!nocode_wanted
) {
4704 gfunc_start(&gf
, FUNC_CDECL
);
4706 size
= type_size(vtop
->t
, &align
);
4720 vpush_global_sym(func_old_type
, TOK_memcpy
);
4726 /* leave source on stack */
4727 } else if (ft
& VT_BITFIELD
) {
4728 /* bitfield store handling */
4729 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
4730 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4731 /* remove bit field info to avoid loops */
4732 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4734 /* duplicate destination */
4736 vtop
[-1] = vtop
[-2];
4738 /* mask and shift source */
4739 vpushi((1 << bit_size
) - 1);
4743 /* load destination, mask and or with source */
4745 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4751 #ifdef CONFIG_TCC_BCHECK
4752 /* bound check case */
4753 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4759 if (!nocode_wanted
) {
4763 r
= gv(rc
); /* generate value */
4764 /* if lvalue was saved on stack, must read it */
4765 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4767 t
= get_reg(RC_INT
);
4769 sv
.r
= VT_LOCAL
| VT_LVAL
;
4770 sv
.c
.ul
= vtop
[-1].c
.ul
;
4772 vtop
[-1].r
= t
| VT_LVAL
;
4775 /* two word case handling : store second register at word + 4 */
4776 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4778 /* convert to int to increment easily */
4785 /* XXX: it works because r2 is spilled last ! */
4786 store(vtop
->r2
, vtop
- 1);
4790 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4791 vtop
->r
|= delayed_cast
;
4795 /* post defines POST/PRE add. c is the token ++ or -- */
4796 void inc(int post
, int c
)
4799 vdup(); /* save lvalue */
4801 gv_dup(); /* duplicate value */
4806 vpushi(c
- TOK_MID
);
4808 vstore(); /* store value */
4810 vpop(); /* if post op, return saved value */
4813 /* Parse GNUC __attribute__ extension. Currently, the following
4814 extensions are recognized:
4815 - aligned(n) : set data/function alignment.
4816 - section(x) : generate data/code in this section.
4817 - unused : currently ignored, but may be used someday.
4819 void parse_attribute(AttributeDef
*ad
)
4826 while (tok
!= ')') {
4827 if (tok
< TOK_IDENT
)
4828 expect("attribute name");
4833 case TOK___SECTION__
:
4836 expect("section name");
4837 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
4842 case TOK___ALIGNED__
:
4845 if (n
<= 0 || (n
& (n
- 1)) != 0)
4846 error("alignment must be a positive power of two");
4851 case TOK___UNUSED__
:
4852 /* currently, no need to handle it because tcc does not
4853 track unused objects */
4856 case TOK___NORETURN__
:
4857 /* currently, no need to handle it because tcc does not
4858 track unused objects */
4863 ad
->func_call
= FUNC_CDECL
;
4867 case TOK___STDCALL__
:
4868 ad
->func_call
= FUNC_STDCALL
;
4871 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4872 /* skip parameters */
4873 /* XXX: skip parenthesis too */
4876 while (tok
!= ')' && tok
!= -1)
4890 /* enum/struct/union declaration */
4891 int struct_decl(int u
)
4893 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4894 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4898 a
= tok
; /* save decl type */
4903 /* struct already defined ? return it */
4904 /* XXX: check consistency */
4905 s
= sym_find(v
| SYM_STRUCT
);
4908 error("invalid type");
4914 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4915 /* put struct/union/enum name in type */
4917 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4922 error("struct/union/enum already defined");
4923 /* cannot be empty */
4930 if (a
== TOK_ENUM
) {
4937 /* enum symbols have static storage */
4938 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4943 parse_btype(&b
, &ad
);
4948 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4949 if ((t
& VT_BTYPE
) == VT_FUNC
||
4950 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4951 error("invalid type for '%s'",
4952 get_tok_str(v
, NULL
));
4958 bit_size
= expr_const();
4959 /* XXX: handle v = 0 case for messages */
4961 error("negative width in bit-field '%s'",
4962 get_tok_str(v
, NULL
));
4963 if (v
&& bit_size
== 0)
4964 error("zero width for bit-field '%s'",
4965 get_tok_str(v
, NULL
));
4967 size
= type_size(t
, &align
);
4969 if (bit_size
>= 0) {
4974 error("bitfields must have scalar type");
4976 if (bit_size
> bsize
) {
4977 error("width of '%s' exceeds its type",
4978 get_tok_str(v
, NULL
));
4979 } else if (bit_size
== bsize
) {
4980 /* no need for bit fields */
4982 } else if (bit_size
== 0) {
4983 /* XXX: what to do if only padding in a
4985 /* zero size: means to pad */
4989 /* we do not have enough room ? */
4990 if ((bit_pos
+ bit_size
) > bsize
)
4993 /* XXX: handle LSB first */
4995 (bit_pos
<< VT_STRUCT_SHIFT
) |
4996 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4997 bit_pos
+= bit_size
;
5003 /* add new memory data only if starting
5005 if (lbit_pos
== 0) {
5006 if (a
== TOK_STRUCT
) {
5007 c
= (c
+ align
- 1) & -align
;
5015 if (align
> maxalign
)
5019 printf("add field %s offset=%d",
5020 get_tok_str(v
, NULL
), offset
);
5021 if (t
& VT_BITFIELD
) {
5022 printf(" pos=%d size=%d",
5023 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
5024 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
5028 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
5032 if (tok
== ';' || tok
== -1)
5042 /* size for struct/union, dummy for enum */
5043 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
5048 /* return 0 if no type declaration. otherwise, return the basic type
5051 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
5053 int t
, u
, type_found
;
5056 memset(ad
, 0, sizeof(AttributeDef
));
5067 if ((t
& VT_BTYPE
) != 0)
5068 error("too many basic types");
5082 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
5083 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5084 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
5085 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
5099 if ((t
& VT_BTYPE
) == VT_LONG
) {
5100 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5107 u
= struct_decl(VT_ENUM
);
5111 u
= struct_decl(VT_STRUCT
);
5114 /* type modifiers */
5119 case TOK___SIGNED__
:
5122 case TOK___INLINE__
:
5144 /* GNUC attribute */
5145 case TOK___ATTRIBUTE__
:
5146 parse_attribute(ad
);
5151 u
= parse_expr_type();
5155 if (!s
|| !(s
->t
& VT_TYPEDEF
))
5157 t
|= (s
->t
& ~VT_TYPEDEF
);
5164 /* long is never used as type */
5165 if ((t
& VT_BTYPE
) == VT_LONG
)
5166 t
= (t
& ~VT_BTYPE
) | VT_INT
;
5171 int post_type(int t
, AttributeDef
*ad
)
5173 int p
, n
, pt
, l
, t1
;
5174 Sym
**plast
, *s
, *first
;
5178 /* function declaration */
5183 while (tok
!= ')') {
5184 /* read param name and compute offset */
5185 if (l
!= FUNC_OLD
) {
5186 if (!parse_btype(&pt
, &ad1
)) {
5188 error("invalid type");
5195 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5197 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
5198 if ((pt
& VT_BTYPE
) == VT_VOID
)
5199 error("parameter declared as void");
5206 /* array must be transformed to pointer according to ANSI C */
5208 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
5213 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5220 /* if no parameters, then old type prototype */
5224 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5225 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
5226 /* we push a anonymous symbol which will contain the function prototype */
5228 s
= sym_push(p
, t
, ad
->func_call
, l
);
5230 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
5231 } else if (tok
== '[') {
5232 /* array definition */
5238 error("invalid array size");
5241 /* parse next post type */
5242 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5243 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
5245 /* we push a anonymous symbol which will contain the array
5248 sym_push(p
, t
, 0, n
);
5249 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
5254 /* Read a type declaration (except basic type), and return the
5255 type. 'td' is a bitmask indicating which kind of type decl is
5256 expected. 't' should contain the basic type. 'ad' is the attribute
5257 definition of the basic type. It can be modified by type_decl(). */
5258 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
5263 while (tok
== '*') {
5265 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
5270 /* recursive type */
5271 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5274 /* XXX: this is not correct to modify 'ad' at this point, but
5275 the syntax is not clear */
5276 if (tok
== TOK___ATTRIBUTE__
)
5277 parse_attribute(ad
);
5278 u
= type_decl(ad
, v
, 0, td
);
5282 /* type identifier */
5283 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
5287 if (!(td
& TYPE_ABSTRACT
))
5288 expect("identifier");
5292 /* append t at the end of u */
5293 t
= post_type(t
, ad
);
5294 if (tok
== TOK___ATTRIBUTE__
)
5295 parse_attribute(ad
);
5300 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
5310 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5311 static int lvalue_type(int t
)
5318 else if (bt
== VT_SHORT
)
5322 if (t
& VT_UNSIGNED
)
5323 r
|= VT_LVAL_UNSIGNED
;
5327 /* indirection with full error checking and bound check */
5328 static void indir(void)
5330 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
5332 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
5334 vtop
->t
= pointed_type(vtop
->t
);
5335 /* an array is never an lvalue */
5336 if (!(vtop
->t
& VT_ARRAY
)) {
5337 vtop
->r
|= lvalue_type(vtop
->t
);
5338 /* if bound checking, the referenced pointer must be checked */
5339 if (do_bounds_check
)
5340 vtop
->r
|= VT_MUSTBOUND
;
5344 /* pass a parameter to a function and do type checking and casting */
5345 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
5348 func_type
= func
->c
;
5349 if (func_type
== FUNC_OLD
||
5350 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5351 /* default casting : only need to convert float to double */
5352 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
5353 gen_cast(VT_DOUBLE
);
5354 } else if (arg
== NULL
) {
5355 error("too many arguments to function");
5357 gen_assign_cast(arg
->t
);
5359 if (!nocode_wanted
) {
5366 /* parse an expression of the form '(type)' or '(expr)' and return its
5368 static int parse_expr_type(void)
5374 if (parse_btype(&ft
, &ad
)) {
5375 ft
= type_decl(&ad
, &n
, ft
, TYPE_ABSTRACT
);
5383 static void unary(void)
5385 int n
, t
, ft
, align
, size
, r
;
5390 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
5393 } else if (tok
== TOK_CUINT
) {
5394 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
5396 } else if (tok
== TOK_CLLONG
) {
5397 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
5399 } else if (tok
== TOK_CULLONG
) {
5400 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
5402 } else if (tok
== TOK_CFLOAT
) {
5403 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
5405 } else if (tok
== TOK_CDOUBLE
) {
5406 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
5408 } else if (tok
== TOK_CLDOUBLE
) {
5409 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
5411 } else if (tok
== TOK___FUNC__
|| (tok
== TOK___FUNCTION__
&& gnu_ext
)) {
5414 /* special function name identifier */
5416 len
= strlen(funcname
) + 1;
5417 /* generate char[len] type */
5418 t
= VT_ARRAY
| mk_pointer(VT_BYTE
);
5419 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5421 vpush_ref(t
, data_section
, data_section
->data_offset
, len
);
5422 ptr
= section_ptr_add(data_section
, len
);
5423 memcpy(ptr
, funcname
, len
);
5425 } else if (tok
== TOK_LSTR
) {
5428 } else if (tok
== TOK_STR
) {
5429 /* string parsing */
5432 t
= VT_ARRAY
| mk_pointer(t
);
5433 memset(&ad
, 0, sizeof(AttributeDef
));
5434 decl_initializer_alloc(t
, &ad
, VT_CONST
, 2, 0, 0);
5440 if (parse_btype(&t
, &ad
)) {
5441 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
5443 /* check ISOC99 compound literal */
5445 /* data is allocated locally by default */
5450 /* all except arrays are lvalues */
5451 if (!(ft
& VT_ARRAY
))
5452 r
|= lvalue_type(ft
);
5453 memset(&ad
, 0, sizeof(AttributeDef
));
5454 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
5463 } else if (t
== '*') {
5466 } else if (t
== '&') {
5468 /* functions names must be treated as function pointers,
5469 except for unary '&' and sizeof. Since we consider that
5470 functions are not lvalues, we only have to handle it
5471 there and in function calls. */
5472 /* arrays can also be used although they are not lvalues */
5473 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
5474 !(vtop
->t
& VT_ARRAY
))
5476 vtop
->t
= mk_pointer(vtop
->t
);
5481 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
5482 vtop
->c
.i
= !vtop
->c
.i
;
5483 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
5484 vtop
->c
.i
= vtop
->c
.i
^ 1;
5486 vset(VT_INT
, VT_JMP
, gtst(1, 0));
5494 /* in order to force cast, we add zero */
5496 if ((vtop
->t
& VT_BTYPE
) == VT_PTR
)
5497 error("pointer not accepted for unary plus");
5501 if (t
== TOK_SIZEOF
|| t
== TOK_ALIGNOF
) {
5503 ft
= parse_expr_type();
5507 size
= type_size(ft
, &align
);
5508 if (t
== TOK_SIZEOF
)
5513 if (t
== TOK_INC
|| t
== TOK_DEC
) {
5516 } else if (t
== '-') {
5523 expect("identifier");
5527 error("'%s' undeclared", get_tok_str(t
, NULL
));
5528 /* for simple function calls, we tolerate undeclared
5529 external reference to int() function */
5530 s
= external_global_sym(t
, func_old_type
, 0);
5532 vset(s
->t
, s
->r
, s
->c
);
5533 /* if forward reference, we must point to s */
5534 if (vtop
->r
& VT_SYM
) {
5541 /* post operations */
5543 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
5546 } else if (tok
== '.' || tok
== TOK_ARROW
) {
5548 if (tok
== TOK_ARROW
)
5553 /* expect pointer on structure */
5554 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
5555 expect("struct or union");
5556 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5559 while ((s
= s
->next
) != NULL
) {
5564 error("field not found");
5565 /* add field offset to pointer */
5566 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
5569 /* change type to field type, and set to lvalue */
5571 /* an array is never an lvalue */
5572 if (!(vtop
->t
& VT_ARRAY
)) {
5573 vtop
->r
|= lvalue_type(vtop
->t
);
5574 /* if bound checking, the referenced pointer must be checked */
5575 if (do_bounds_check
)
5576 vtop
->r
|= VT_MUSTBOUND
;
5579 } else if (tok
== '[') {
5585 } else if (tok
== '(') {
5590 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
5591 /* pointer test (no array accepted) */
5592 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
5593 vtop
->t
= pointed_type(vtop
->t
);
5594 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
5598 expect("function pointer");
5601 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
5603 /* get return type */
5604 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
5605 if (!nocode_wanted
) {
5606 save_regs(0); /* save used temporary registers */
5607 gfunc_start(&gf
, s
->r
);
5610 sa
= s
->next
; /* first parameter */
5611 #ifdef INVERT_FUNC_PARAMS
5615 ParseState saved_parse_state
;
5618 /* read each argument and store it on a stack */
5624 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
5628 else if (tok
== ')')
5630 tok_str_add_tok(&str
);
5633 tok_str_add(&str
, -1); /* end of file added */
5634 tok_str_add(&str
, 0);
5635 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
5636 s1
->next
= sa
; /* add reference to argument */
5645 /* now generate code in reverse order by reading the stack */
5646 save_parse_state(&saved_parse_state
);
5648 macro_ptr
= (int *)args
->c
;
5652 expect("',' or ')'");
5653 gfunc_param_typed(&gf
, s
, args
->next
);
5655 tok_str_free((int *)args
->c
);
5659 restore_parse_state(&saved_parse_state
);
5662 /* compute first implicit argument if a structure is returned */
5663 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
5664 /* get some space for the returned structure */
5665 size
= type_size(s
->t
, &align
);
5666 loc
= (loc
- size
) & -align
;
5668 ret
.r
= VT_LOCAL
| VT_LVAL
;
5669 /* pass it as 'int' to avoid structure arg passing
5671 vset(VT_INT
, VT_LOCAL
, loc
);
5680 /* return in register */
5681 if (is_float(ret
.t
)) {
5684 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
5690 #ifndef INVERT_FUNC_PARAMS
5694 gfunc_param_typed(&gf
, s
, sa
);
5704 error("too few arguments to function");
5711 vsetc(ret
.t
, ret
.r
, &ret
.c
);
5719 static void uneq(void)
5725 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
5726 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
5727 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
5742 static void sum(int l
)
5750 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
5751 (l
== 1 && (tok
== '+' || tok
== '-')) ||
5752 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
5753 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
5754 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
5755 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
5756 (l
== 5 && tok
== '&') ||
5757 (l
== 6 && tok
== '^') ||
5758 (l
== 7 && tok
== '|') ||
5759 (l
== 8 && tok
== TOK_LAND
) ||
5760 (l
== 9 && tok
== TOK_LOR
)) {
5769 /* only used if non constant */
5770 static void eand(void)
5777 if (tok
!= TOK_LAND
) {
5780 vset(VT_INT
, VT_JMPI
, t
);
5790 static void eor(void)
5797 if (tok
!= TOK_LOR
) {
5800 vset(VT_INT
, VT_JMP
, t
);
5810 /* XXX: better constant handling */
5811 static void expr_eq(void)
5813 int tt
, u
, r1
, r2
, rc
, t1
, t2
, t
, bt1
, bt2
;
5835 save_regs(1); /* we need to save all registers here except
5836 at the top because it is a branch point */
5840 bt1
= t1
& VT_BTYPE
;
5841 sv
= *vtop
; /* save value to handle it later */
5842 vtop
--; /* no vpop so that FP stack is not flushed */
5850 bt2
= t2
& VT_BTYPE
;
5851 /* cast operands to correct type according to ISOC rules */
5852 if (is_float(bt1
) || is_float(bt2
)) {
5853 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5855 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5860 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5861 /* cast to biggest op */
5863 /* convert to unsigned if it does not fit in a long long */
5864 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5865 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5867 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5868 /* XXX: test pointer compatibility */
5870 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
5871 /* XXX: test structure compatibility */
5873 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
5874 /* NOTE: as an extension, we accept void on only one side */
5877 /* integer operations */
5879 /* convert to unsigned if it does not fit in an integer */
5880 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5881 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5885 /* now we convert second operand */
5890 } else if ((t
& VT_BTYPE
) == VT_LLONG
) {
5891 /* for long longs, we use fixed registers to avoid having
5892 to handle a complicated move */
5896 /* this is horrible, but we must also convert first
5900 /* put again first value and cast it */
5911 static void gexpr(void)
5922 /* parse an expression and return its type without any side effect. */
5923 static int expr_type(void)
5936 /* parse a unary expression and return its type without any side
5938 static int unary_type(void)
5951 /* parse a constant expression and return value in vtop. */
5952 static void expr_const1(void)
5961 /* parse an integer constant and return its value. */
5962 static int expr_const(void)
5966 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
5967 expect("constant expression");
5973 /* return the label token if current token is a label, otherwise
5975 static int is_label(void)
5980 /* fast test first */
5981 if (tok
< TOK_UIDENT
)
5983 /* no need to save tokc since we expect an identifier */
5991 /* XXX: may not work in all cases (macros ?) */
6000 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
6005 /* generate line number info */
6007 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
6008 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
6010 last_line_num
= file
->line_num
;
6013 if (tok
== TOK_IF
) {
6020 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6022 if (c
== TOK_ELSE
) {
6026 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6027 gsym(d
); /* patch else jmp */
6030 } else if (tok
== TOK_WHILE
) {
6038 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6042 } else if (tok
== '{') {
6045 s
= local_stack
.top
;
6046 while (tok
!= '}') {
6049 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6051 /* pop locally defined symbols */
6052 sym_pop(&local_stack
, s
);
6054 } else if (tok
== TOK_RETURN
) {
6058 gen_assign_cast(func_vt
);
6059 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
6060 /* if returning structure, must copy it to implicit
6061 first pointer arg location */
6062 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
6065 /* copy structure value to pointer */
6067 } else if (is_float(func_vt
)) {
6072 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6075 rsym
= gjmp(rsym
); /* jmp */
6076 } else if (tok
== TOK_BREAK
) {
6079 error("cannot break");
6080 *bsym
= gjmp(*bsym
);
6083 } else if (tok
== TOK_CONTINUE
) {
6086 error("cannot continue");
6087 *csym
= gjmp(*csym
);
6090 } else if (tok
== TOK_FOR
) {
6117 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6122 if (tok
== TOK_DO
) {
6127 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6138 if (tok
== TOK_SWITCH
) {
6142 /* XXX: other types than integer */
6143 case_reg
= gv(RC_INT
);
6147 b
= gjmp(0); /* jump to first case */
6149 block(&a
, csym
, &b
, &c
, case_reg
);
6150 /* if no default, jmp after switch */
6158 if (tok
== TOK_CASE
) {
6165 if (gnu_ext
&& tok
== TOK_DOTS
) {
6169 warning("empty case range");
6171 /* since a case is like a label, we must skip it with a jmp */
6174 vset(VT_INT
, case_reg
, 0);
6178 *case_sym
= gtst(1, 0);
6181 *case_sym
= gtst(1, 0);
6182 vset(VT_INT
, case_reg
, 0);
6185 *case_sym
= gtst(1, *case_sym
);
6189 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6191 if (tok
== TOK_DEFAULT
) {
6197 error("too many 'default'");
6199 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6201 if (tok
== TOK_GOTO
) {
6203 s
= sym_find1(&label_stack
, tok
);
6204 /* put forward definition if needed */
6206 s
= sym_push1(&label_stack
, tok
, LABEL_FORWARD
, 0);
6207 /* label already defined */
6208 if (s
->t
& LABEL_FORWARD
)
6218 s
= sym_find1(&label_stack
, b
);
6220 if (!(s
->t
& LABEL_FORWARD
))
6221 error("multiple defined label");
6226 sym_push1(&label_stack
, b
, 0, ind
);
6228 /* we accept this, but it is a mistake */
6230 warning("deprecated use of label at end of compound statement");
6232 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6234 /* expression case */
6244 /* t is the array or struct type. c is the array or struct
6245 address. cur_index/cur_field is the pointer to the current
6246 value. 'size_only' is true if only size info is needed (only used
6248 static void decl_designator(int t
, Section
*sec
, unsigned long c
,
6249 int *cur_index
, Sym
**cur_field
,
6253 int notfirst
, index
, align
, l
;
6256 if (gnu_ext
&& (l
= is_label()) != 0)
6259 while (tok
== '[' || tok
== '.') {
6261 if (!(t
& VT_ARRAY
))
6262 expect("array type");
6263 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
6265 index
= expr_const();
6266 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
6267 expect("invalid index");
6271 t
= pointed_type(t
);
6272 c
+= index
* type_size(t
, &align
);
6278 if ((t
& VT_BTYPE
) != VT_STRUCT
)
6279 expect("struct/union type");
6280 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
6292 t
= f
->t
| (t
& ~VT_TYPE
);
6307 t
= pointed_type(t
);
6308 c
+= index
* type_size(t
, &align
);
6312 error("too many field init");
6313 t
= f
->t
| (t
& ~VT_TYPE
);
6317 decl_initializer(t
, sec
, c
, 0, size_only
);
6321 #define EXPR_CONST 1
6324 /* store a value or an expression directly in global data or in local array */
6325 static void init_putv(int t
, Section
*sec
, unsigned long c
,
6326 int v
, int expr_type
)
6328 int saved_global_expr
, bt
;
6336 /* compound literals must be allocated globally in this case */
6337 saved_global_expr
= global_expr
;
6340 global_expr
= saved_global_expr
;
6341 /* NOTE: symbols are accepted */
6342 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
6343 error("initializer element is not constant");
6351 /* XXX: not portable */
6352 /* XXX: generate error if incorrect relocation */
6355 ptr
= sec
->data
+ c
;
6356 if ((vtop
->r
& VT_SYM
) &&
6362 error("initializer element is not computable at load time");
6365 *(char *)ptr
= vtop
->c
.i
;
6368 *(short *)ptr
= vtop
->c
.i
;
6371 *(double *)ptr
= vtop
->c
.d
;
6374 *(long double *)ptr
= vtop
->c
.ld
;
6377 *(long long *)ptr
= vtop
->c
.ll
;
6380 if (vtop
->r
& VT_SYM
) {
6381 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
6383 *(int *)ptr
= vtop
->c
.i
;
6388 vset(t
, VT_LOCAL
, c
);
6395 /* put zeros for variable based init */
6396 static void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
6401 /* nothing to do because globals are already set to zero */
6403 gfunc_start(&gf
, FUNC_CDECL
);
6408 vset(VT_INT
, VT_LOCAL
, c
);
6410 vpush_global_sym(func_old_type
, TOK_memset
);
6415 /* 't' contains the type and storage info. 'c' is the offset of the
6416 object in section 'sec'. If 'sec' is NULL, it means stack based
6417 allocation. 'first' is true if array '{' must be read (multi
6418 dimension implicit array init handling). 'size_only' is true if
6419 size only evaluation is wanted (only for arrays). */
6420 static void decl_initializer(int t
, Section
*sec
, unsigned long c
,
6421 int first
, int size_only
)
6423 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
6424 int t1
, size1
, align1
, expr_type
;
6428 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
6431 t1
= pointed_type(t
);
6432 size1
= type_size(t1
, &align1
);
6435 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
6441 /* only parse strings here if correct type (otherwise: handle
6442 them as ((w)char *) expressions */
6443 if ((tok
== TOK_LSTR
&&
6444 (t1
& VT_BTYPE
) == VT_INT
) ||
6446 (t1
& VT_BTYPE
) == VT_BYTE
)) {
6447 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6452 /* compute maximum number of chars wanted */
6454 cstr_len
= cstr
->size
;
6456 cstr_len
= cstr
->size
/ sizeof(int);
6459 if (n
>= 0 && nb
> (n
- array_length
))
6460 nb
= n
- array_length
;
6463 warning("initializer-string for array is too long");
6464 /* in order to go faster for common case (char
6465 string in global variable, we handle it
6467 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
6468 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
6472 ch
= ((unsigned char *)cstr
->data
)[i
];
6474 ch
= ((int *)cstr
->data
)[i
];
6475 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
6483 /* only add trailing zero if enough storage (no
6484 warning in this case since it is standard) */
6485 if (n
< 0 || array_length
< n
) {
6487 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
6493 while (tok
!= '}') {
6494 decl_designator(t
, sec
, c
, &index
, NULL
, size_only
);
6495 if (n
>= 0 && index
>= n
)
6496 error("index too large");
6497 /* must put zero in holes (note that doing it that way
6498 ensures that it even works with designators) */
6499 if (!size_only
&& array_length
< index
) {
6500 init_putz(t1
, sec
, c
+ array_length
* size1
,
6501 (index
- array_length
) * size1
);
6504 if (index
> array_length
)
6505 array_length
= index
;
6506 /* special test for multi dimensional arrays (may not
6507 be strictly correct if designators are used at the
6509 if (index
>= n
&& no_oblock
)
6518 /* put zeros at the end */
6519 if (!size_only
&& n
>= 0 && array_length
< n
) {
6520 init_putz(t1
, sec
, c
+ array_length
* size1
,
6521 (n
- array_length
) * size1
);
6523 /* patch type size if needed */
6525 s
->c
= array_length
;
6526 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
6527 /* XXX: union needs only one init */
6529 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
6534 while (tok
!= '}') {
6535 decl_designator(t
, sec
, c
, NULL
, &f
, size_only
);
6536 /* fill with zero between fields */
6538 if (!size_only
&& array_length
< index
) {
6539 init_putz(t
, sec
, c
+ array_length
,
6540 index
- array_length
);
6542 index
= index
+ type_size(f
->t
, &align1
);
6543 if (index
> array_length
)
6544 array_length
= index
;
6550 /* put zeros at the end */
6551 if (!size_only
&& array_length
< n
) {
6552 init_putz(t
, sec
, c
+ array_length
,
6556 } else if (tok
== '{') {
6558 decl_initializer(t
, sec
, c
, first
, size_only
);
6560 } else if (size_only
) {
6561 /* just skip expression */
6563 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
6567 else if (tok
== ')')
6572 /* currently, we always use constant expression for globals
6573 (may change for scripting case) */
6574 expr_type
= EXPR_CONST
;
6576 expr_type
= EXPR_ANY
;
6577 init_putv(t
, sec
, c
, 0, expr_type
);
6581 /* parse an initializer for type 't' if 'has_init' is non zero, and
6582 allocate space in local or global data space ('r' is either
6583 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6584 variable 'v' of scope 'scope' is declared before initializers are
6585 parsed. If 'v' is zero, then a reference to the new object is put
6586 in the value stack. If 'has_init' is 2, a special parsing is done
6587 to handle string constants. */
6588 static void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
,
6589 int has_init
, int v
, int scope
)
6591 int size
, align
, addr
, data_offset
;
6593 ParseState saved_parse_state
;
6594 TokenString init_str
;
6597 size
= type_size(t
, &align
);
6598 /* If unknown size, we must evaluate it before
6599 evaluating initializers because
6600 initializers can generate global data too
6601 (e.g. string pointers or ISOC99 compound
6602 literals). It also simplifies local
6603 initializers handling */
6604 tok_str_new(&init_str
);
6607 error("unknown type size");
6608 /* get all init string */
6609 if (has_init
== 2) {
6610 /* only get strings */
6611 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6612 tok_str_add_tok(&init_str
);
6617 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
6619 error("unexpected end of file in initializer");
6620 tok_str_add_tok(&init_str
);
6623 else if (tok
== '}') {
6631 tok_str_add(&init_str
, -1);
6632 tok_str_add(&init_str
, 0);
6635 save_parse_state(&saved_parse_state
);
6637 macro_ptr
= init_str
.str
;
6639 decl_initializer(t
, NULL
, 0, 1, 1);
6640 /* prepare second initializer parsing */
6641 macro_ptr
= init_str
.str
;
6644 /* if still unknown size, error */
6645 size
= type_size(t
, &align
);
6647 error("unknown type size");
6649 /* take into account specified alignment if bigger */
6650 if (ad
->aligned
> align
)
6651 align
= ad
->aligned
;
6652 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
6654 if (do_bounds_check
&& (t
& VT_ARRAY
))
6656 #ifdef TCC_TARGET_IL
6657 /* XXX: ugly patch to allocate local variables for IL, just
6662 loc
= (loc
- size
) & -align
;
6665 /* handles bounds */
6666 /* XXX: currently, since we do only one pass, we cannot track
6667 '&' operators, so we add only arrays */
6668 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
6669 unsigned long *bounds_ptr
;
6670 /* add padding between regions */
6672 /* then add local bound info */
6673 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
6674 bounds_ptr
[0] = addr
;
6675 bounds_ptr
[1] = size
;
6678 /* compute section */
6686 data_offset
= sec
->data_offset
;
6687 data_offset
= (data_offset
+ align
- 1) & -align
;
6689 /* very important to increment global pointer at this time
6690 because initializers themselves can create new initializers */
6691 data_offset
+= size
;
6692 /* add padding if bound check */
6693 if (do_bounds_check
)
6695 sec
->data_offset
= data_offset
;
6696 /* allocate section space to put the data */
6697 if (sec
->sh_type
!= SHT_NOBITS
&&
6698 data_offset
> sec
->data_allocated
)
6699 section_realloc(sec
, data_offset
);
6703 /* local variable */
6704 sym_push(v
, t
, r
, addr
);
6706 /* push local reference */
6713 if (scope
== VT_CONST
) {
6714 /* global scope: see if already defined */
6718 if (!is_compatible_types(sym
->t
, t
))
6719 error("incompatible types for redefinition of '%s'",
6720 get_tok_str(v
, NULL
));
6721 if (!(sym
->t
& VT_EXTERN
))
6722 error("redefinition of '%s'", get_tok_str(v
, NULL
));
6723 sym
->t
&= ~VT_EXTERN
;
6726 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
6728 put_extern_sym(sym
, sec
, addr
, size
);
6732 /* push global reference */
6733 sym
= get_sym_ref(t
, sec
, addr
, size
);
6735 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
6739 /* handles bounds now because the symbol must be defined
6740 before for the relocation */
6741 if (do_bounds_check
) {
6742 unsigned long *bounds_ptr
;
6744 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
6745 /* then add global bound info */
6746 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
6747 bounds_ptr
[0] = 0; /* relocated */
6748 bounds_ptr
[1] = size
;
6752 decl_initializer(t
, sec
, addr
, 1, 0);
6753 /* restore parse state if needed */
6755 tok_str_free(init_str
.str
);
6756 restore_parse_state(&saved_parse_state
);
6761 void put_func_debug(Sym
*sym
)
6766 /* XXX: we put here a dummy type */
6767 snprintf(buf
, sizeof(buf
), "%s:%c1",
6768 funcname
, sym
->t
& VT_STATIC
? 'f' : 'F');
6769 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
6770 cur_text_section
, sym
->c
);
6775 /* not finished : try to put some local vars in registers */
6776 //#define CONFIG_REG_VARS
6778 #ifdef CONFIG_REG_VARS
6779 void add_var_ref(int t
)
6781 printf("%s:%d: &%s\n",
6782 file
->filename
, file
->line_num
,
6783 get_tok_str(t
, NULL
));
6786 /* first pass on a function with heuristic to extract variable usage
6787 and pointer references to local variables for register allocation */
6788 void analyse_function(void)
6795 /* any symbol coming after '&' is considered as being a
6796 variable whose reference is taken. It is highly unaccurate
6797 but it is difficult to do better without a complete parse */
6800 /* if '& number', then no need to examine next tokens */
6801 if (tok
== TOK_CINT
||
6803 tok
== TOK_CLLONG
||
6804 tok
== TOK_CULLONG
) {
6806 } else if (tok
>= TOK_UIDENT
) {
6807 /* if '& ident [' or '& ident ->', then ident address
6811 if (tok
!= '[' && tok
!= TOK_ARROW
)
6815 while (tok
!= '}' && tok
!= ';' &&
6816 !((tok
== ',' || tok
== ')') && level
== 0)) {
6817 if (tok
>= TOK_UIDENT
) {
6819 } else if (tok
== '(') {
6821 } else if (tok
== ')') {
6834 /* parse an old style function declaration list */
6835 /* XXX: check multiple parameter */
6836 static void func_decl_list(Sym
*func_sym
)
6841 /* parse each declaration */
6842 while (tok
!= '{' && tok
!= ';' && tok
!= TOK_EOF
) {
6843 if (!parse_btype(&b
, &ad
))
6844 expect("declaration list");
6845 if (((b
& VT_BTYPE
) == VT_ENUM
||
6846 (b
& VT_BTYPE
) == VT_STRUCT
) &&
6848 /* we accept no variable after */
6851 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
6852 /* find parameter in function parameter list */
6855 if ((s
->v
& ~SYM_FIELD
) == v
)
6859 error("declaration for parameter '%s' but no such parameter",
6860 get_tok_str(v
, NULL
));
6862 /* check that no storage specifier except 'register' was given */
6863 if (t
& (VT_EXTERN
| VT_STATIC
| VT_TYPEDEF
))
6864 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
6865 /* we can add the type (NOTE: it could be local to the function) */
6867 /* accept other parameters */
6878 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6879 static void decl(int l
)
6881 int t
, b
, v
, has_init
, r
;
6886 if (!parse_btype(&b
, &ad
)) {
6887 /* skip redundant ';' */
6888 /* XXX: find more elegant solution */
6893 /* special test for old K&R protos without explicit int
6894 type. Only accepted when defining global data */
6895 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
6899 if (((b
& VT_BTYPE
) == VT_ENUM
||
6900 (b
& VT_BTYPE
) == VT_STRUCT
) &&
6902 /* we accept no variable after */
6906 while (1) { /* iterate thru each declaration */
6907 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
6911 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
6912 printf("type = '%s'\n", buf
);
6915 if ((t
& VT_BTYPE
) == VT_FUNC
) {
6916 /* if old style function prototype, we accept a
6918 sym
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
6919 if (sym
->c
== FUNC_OLD
)
6920 func_decl_list(sym
);
6924 #ifdef CONFIG_REG_VARS
6925 TokenString func_str
;
6926 ParseState saved_parse_state
;
6931 error("cannot use local functions");
6933 expect("function definition");
6935 #ifdef CONFIG_REG_VARS
6936 /* parse all function code and record it */
6938 tok_str_new(&func_str
);
6944 error("unexpected end of file");
6945 tok_str_add_tok(&func_str
);
6950 } else if (t
== '}') {
6952 if (block_level
== 0)
6956 tok_str_add(&func_str
, -1);
6957 tok_str_add(&func_str
, 0);
6959 save_parse_state(&saved_parse_state
);
6961 macro_ptr
= func_str
.str
;
6966 /* compute text section */
6967 cur_text_section
= ad
.section
;
6968 if (!cur_text_section
)
6969 cur_text_section
= text_section
;
6970 ind
= cur_text_section
->data_offset
;
6971 funcname
= get_tok_str(v
, NULL
);
6974 /* if symbol is already defined, then put complete type */
6977 /* put function symbol */
6978 sym
= sym_push1(&global_stack
, v
, t
, 0);
6980 /* NOTE: we patch the symbol size later */
6981 put_extern_sym(sym
, cur_text_section
, ind
, 0);
6983 sym
->r
= VT_SYM
| VT_CONST
;
6984 /* put debug symbol */
6986 put_func_debug(sym
);
6987 /* push a dummy symbol to enable local sym storage */
6988 sym_push1(&local_stack
, 0, 0, 0);
6992 #ifdef CONFIG_REG_VARS
6993 macro_ptr
= func_str
.str
;
6996 block(NULL
, NULL
, NULL
, NULL
, 0);
6999 cur_text_section
->data_offset
= ind
;
7000 sym_pop(&label_stack
, NULL
); /* reset label stack */
7001 sym_pop(&local_stack
, NULL
); /* reset local stack */
7002 /* end of function */
7003 /* patch symbol size */
7004 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
7007 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
7009 funcname
= ""; /* for safety */
7010 func_vt
= VT_VOID
; /* for safety */
7011 ind
= 0; /* for safety */
7013 #ifdef CONFIG_REG_VARS
7014 tok_str_free(func_str
.str
);
7015 restore_parse_state(&saved_parse_state
);
7019 if (b
& VT_TYPEDEF
) {
7020 /* save typedefed type */
7021 /* XXX: test storage specifiers ? */
7022 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
7023 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
7024 /* external function definition */
7025 external_sym(v
, t
, 0);
7027 /* not lvalue if array */
7029 if (!(t
& VT_ARRAY
))
7030 r
|= lvalue_type(t
);
7031 if (b
& VT_EXTERN
) {
7032 /* external variable */
7033 external_sym(v
, t
, r
);
7039 has_init
= (tok
== '=');
7042 decl_initializer_alloc(t
, &ad
, r
,
7056 /* free define stack until top reaches 'b' */
7057 static void free_defines(Sym
*b
)
7061 top
= define_stack
.top
;
7064 /* do not free args or predefined defines */
7066 tok_str_free((int *)top
->c
);
7067 sym_pop(&define_stack
, top1
);
7072 /* compile the C file opened in 'file'. Return non zero if errors. */
7073 static int tcc_compile(TCCState
*s1
)
7075 Sym
*define_start
, *sym
;
7077 volatile int section_sym
;
7081 printf("%s: **** new file\n", file
->filename
);
7084 s1
->include_stack_ptr
= s1
->include_stack
;
7085 /* XXX: move that before to avoid having to initialize
7086 file->ifdef_stack_ptr ? */
7087 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
7088 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
7090 /* XXX: not ANSI compliant: bound checking says error */
7092 anon_sym
= SYM_FIRST_ANOM
;
7094 /* file info: full path + filename */
7095 section_sym
= 0; /* avoid warning */
7097 section_sym
= put_elf_sym(symtab_section
, 0, 0,
7098 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
7099 text_section
->sh_num
, NULL
);
7100 getcwd(buf
, sizeof(buf
));
7101 pstrcat(buf
, sizeof(buf
), "/");
7102 put_stabs_r(buf
, N_SO
, 0, 0,
7103 text_section
->data_offset
, text_section
, section_sym
);
7104 put_stabs_r(file
->filename
, N_SO
, 0, 0,
7105 text_section
->data_offset
, text_section
, section_sym
);
7107 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
7108 symbols can be safely used */
7109 put_elf_sym(symtab_section
, 0, 0,
7110 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
7111 SHN_ABS
, file
->filename
);
7113 /* define common 'char *' type because it is often used internally
7114 for arrays and struct dereference */
7115 char_pointer_type
= mk_pointer(VT_BYTE
);
7116 /* define an old type function 'int func()' */
7118 sym
= sym_push(p
, 0, FUNC_CDECL
, FUNC_OLD
);
7119 func_old_type
= VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
7121 /* define 'void *alloca(unsigned int)' builtin function */
7126 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
7127 s1
= sym_push(0, VT_UNSIGNED
| VT_INT
, 0, 0);
7130 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
7134 define_start
= define_stack
.top
;
7136 if (setjmp(s1
->error_jmp_buf
) == 0) {
7138 s1
->error_set_jmp_enabled
= 1;
7141 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7145 expect("declaration");
7147 /* end of translation unit info */
7149 put_stabs_r(NULL
, N_SO
, 0, 0,
7150 text_section
->data_offset
, text_section
, section_sym
);
7153 s1
->error_set_jmp_enabled
= 0;
7155 /* reset define stack, but leave -Dsymbols (may be incorrect if
7156 they are undefined) */
7157 free_defines(define_start
);
7159 sym_pop(&global_stack
, NULL
);
7161 return s1
->nb_errors
!= 0 ? -1 : 0;
7164 int tcc_compile_string(TCCState
*s
, const char *str
)
7166 BufferedFile bf1
, *bf
= &bf1
;
7169 /* init file structure */
7171 bf
->buf_ptr
= (char *)str
;
7172 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
7173 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
7177 ret
= tcc_compile(s
);
7179 /* currently, no need to close */
7183 /* define a symbol. A value can also be provided with the '=' operator */
7184 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
7186 BufferedFile bf1
, *bf
= &bf1
;
7188 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
7189 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
7193 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
7195 /* init file structure */
7197 bf
->buf_ptr
= bf
->buffer
;
7198 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
7199 bf
->filename
[0] = '\0';
7203 s1
->include_stack_ptr
= s1
->include_stack
;
7205 /* parse with define parser */
7207 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7213 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
7217 ts
= tok_alloc(sym
, strlen(sym
));
7218 s
= sym_find1(&define_stack
, tok
);
7219 /* undefine symbol by putting an invalid name */
7221 sym_undef(&define_stack
, s
);
7226 /* print the position in the source file of PC value 'pc' by reading
7227 the stabs debug information */
7228 static void rt_printline(unsigned long wanted_pc
)
7230 Stab_Sym
*sym
, *sym_end
;
7231 char func_name
[128], last_func_name
[128];
7232 unsigned long func_addr
, last_pc
, pc
;
7233 const char *incl_files
[INCLUDE_STACK_SIZE
];
7234 int incl_index
, len
, last_line_num
, i
;
7235 const char *str
, *p
;
7237 func_name
[0] = '\0';
7240 last_func_name
[0] = '\0';
7241 last_pc
= 0xffffffff;
7243 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
7244 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
7245 while (sym
< sym_end
) {
7246 switch(sym
->n_type
) {
7247 /* function start or end */
7249 if (sym
->n_strx
== 0) {
7250 func_name
[0] = '\0';
7253 str
= stabstr_section
->data
+ sym
->n_strx
;
7254 p
= strchr(str
, ':');
7256 pstrcpy(func_name
, sizeof(func_name
), str
);
7259 if (len
> sizeof(func_name
) - 1)
7260 len
= sizeof(func_name
) - 1;
7261 memcpy(func_name
, str
, len
);
7262 func_name
[len
] = '\0';
7264 func_addr
= sym
->n_value
;
7267 /* line number info */
7269 pc
= sym
->n_value
+ func_addr
;
7270 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7273 last_line_num
= sym
->n_desc
;
7275 strcpy(last_func_name
, func_name
);
7279 str
= stabstr_section
->data
+ sym
->n_strx
;
7281 if (incl_index
< INCLUDE_STACK_SIZE
) {
7282 incl_files
[incl_index
++] = str
;
7290 if (sym
->n_strx
== 0) {
7291 incl_index
= 0; /* end of translation unit */
7293 str
= stabstr_section
->data
+ sym
->n_strx
;
7294 /* do not add path */
7296 if (len
> 0 && str
[len
- 1] != '/')
7303 /* did not find line number info: */
7304 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
7307 for(i
= 0; i
< incl_index
- 1; i
++)
7308 fprintf(stderr
, "In file included from %s\n",
7310 if (incl_index
> 0) {
7311 fprintf(stderr
, "%s:%d: ",
7312 incl_files
[incl_index
- 1], last_line_num
);
7314 if (last_func_name
[0] != '\0') {
7315 fprintf(stderr
, "in function '%s()': ", last_func_name
);
7319 /* emit a run time error at position 'pc' */
7320 void rt_error(unsigned long pc
, const char *fmt
, ...)
7326 vfprintf(stderr
, fmt
, ap
);
7327 fprintf(stderr
, "\n");
7333 /* signal handler for fatal errors */
7334 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
7336 struct ucontext
*uc
= puc
;
7340 pc
= uc
->uc_mcontext
.gregs
[14];
7342 #error please put the right sigcontext field
7347 switch(siginf
->si_code
) {
7350 rt_error(pc
, "division by zero");
7353 rt_error(pc
, "floating point exception");
7359 rt_error(pc
, "dereferencing invalid pointer");
7362 rt_error(pc
, "illegal instruction");
7365 rt_error(pc
, "abort() called");
7368 rt_error(pc
, "caught signal %d", signum
);
7375 /* do all relocations (needed before using tcc_get_symbol()) */
7376 int tcc_relocate(TCCState
*s1
)
7383 tcc_add_runtime(s1
);
7385 relocate_common_syms();
7387 /* compute relocation address : section are relocated in place. We
7388 also alloc the bss space */
7389 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7390 s
= s1
->sections
[i
];
7391 if (s
->sh_flags
& SHF_ALLOC
) {
7392 if (s
->sh_type
== SHT_NOBITS
)
7393 s
->data
= tcc_mallocz(s
->data_offset
);
7394 s
->sh_addr
= (unsigned long)s
->data
;
7398 relocate_syms(s1
, 1);
7400 if (s1
->nb_errors
!= 0)
7403 /* relocate each section */
7404 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7405 s
= s1
->sections
[i
];
7407 relocate_section(s1
, s
);
7412 /* launch the compiled program with the given arguments */
7413 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
7415 int (*prog_main
)(int, char **);
7417 if (tcc_relocate(s1
) < 0)
7420 prog_main
= tcc_get_symbol(s1
, "main");
7424 error("debug mode currently not available for Windows");
7426 struct sigaction sigact
;
7427 /* install TCC signal handlers to print debug info on fatal
7429 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
7430 sigact
.sa_sigaction
= sig_error
;
7431 sigemptyset(&sigact
.sa_mask
);
7432 sigaction(SIGFPE
, &sigact
, NULL
);
7433 sigaction(SIGILL
, &sigact
, NULL
);
7434 sigaction(SIGSEGV
, &sigact
, NULL
);
7435 sigaction(SIGBUS
, &sigact
, NULL
);
7436 sigaction(SIGABRT
, &sigact
, NULL
);
7440 #ifdef CONFIG_TCC_BCHECK
7441 if (do_bounds_check
) {
7442 void (*bound_init
)(void);
7443 void **bound_error_func
;
7445 /* set error function */
7446 bound_error_func
= (void **)tcc_get_symbol(s1
, "__bound_error_func");
7447 *bound_error_func
= rt_error
;
7449 /* XXX: use .init section so that it also work in binary ? */
7450 bound_init
= (void *)tcc_get_symbol(s1
, "__bound_init");
7454 return (*prog_main
)(argc
, argv
);
7457 TCCState
*tcc_new(void)
7462 s
= tcc_mallocz(sizeof(TCCState
));
7466 s
->output_type
= TCC_OUTPUT_MEMORY
;
7468 /* default include paths */
7469 tcc_add_sysinclude_path(s
, "/usr/local/include");
7470 tcc_add_sysinclude_path(s
, "/usr/include");
7471 tcc_add_sysinclude_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
7473 /* add all tokens */
7475 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
7477 tok_ident
= TOK_IDENT
;
7482 tok_alloc(p
, r
- p
- 1);
7486 /* we add dummy defines for some special macros to speed up tests
7487 and to have working defined() */
7488 sym_push1(&define_stack
, TOK___LINE__
, MACRO_OBJ
, 0);
7489 sym_push1(&define_stack
, TOK___FILE__
, MACRO_OBJ
, 0);
7490 sym_push1(&define_stack
, TOK___DATE__
, MACRO_OBJ
, 0);
7491 sym_push1(&define_stack
, TOK___TIME__
, MACRO_OBJ
, 0);
7493 /* standard defines */
7494 tcc_define_symbol(s
, "__STDC__", NULL
);
7495 #if defined(TCC_TARGET_I386)
7496 tcc_define_symbol(s
, "__i386__", NULL
);
7499 tcc_define_symbol(s
, "linux", NULL
);
7501 /* tiny C specific defines */
7502 tcc_define_symbol(s
, "__TINYC__", NULL
);
7504 /* default library paths */
7505 tcc_add_library_path(s
, "/usr/local/lib");
7506 tcc_add_library_path(s
, "/usr/lib");
7507 tcc_add_library_path(s
, "/lib");
7509 /* no section zero */
7510 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
7512 /* create standard sections */
7513 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
7514 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
7515 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
7517 /* symbols are always generated for linking stage */
7518 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
7520 ".hashtab", SHF_PRIVATE
);
7521 strtab_section
= symtab_section
->link
;
7523 /* private symbol table for dynamic symbols */
7524 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
7526 ".dynhashtab", SHF_PRIVATE
);
7530 void tcc_delete(TCCState
*s1
)
7534 /* free -D defines */
7538 n
= tok_ident
- TOK_IDENT
;
7539 for(i
= 0; i
< n
; i
++)
7540 tcc_free(table_ident
[i
]);
7541 tcc_free(table_ident
);
7543 /* free all sections */
7545 free_section(symtab_section
->hash
);
7547 free_section(s1
->dynsymtab_section
->hash
);
7548 free_section(s1
->dynsymtab_section
->link
);
7549 free_section(s1
->dynsymtab_section
);
7551 for(i
= 1; i
< s1
->nb_sections
; i
++)
7552 free_section(s1
->sections
[i
]);
7553 tcc_free(s1
->sections
);
7555 /* free loaded dlls array */
7556 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
7557 tcc_free(s1
->loaded_dlls
[i
]);
7558 tcc_free(s1
->loaded_dlls
);
7561 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
7562 tcc_free(s1
->library_paths
[i
]);
7563 tcc_free(s1
->library_paths
);
7565 /* cached includes */
7566 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
7567 tcc_free(s1
->cached_includes
[i
]);
7568 tcc_free(s1
->cached_includes
);
7570 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
7571 tcc_free(s1
->include_paths
[i
]);
7572 tcc_free(s1
->include_paths
);
7574 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
7575 tcc_free(s1
->sysinclude_paths
[i
]);
7576 tcc_free(s1
->sysinclude_paths
);
7581 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
7585 pathname1
= tcc_strdup(pathname
);
7586 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
7590 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
7594 pathname1
= tcc_strdup(pathname
);
7595 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
7599 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
7604 BufferedFile
*saved_file
;
7606 /* find source file type with extension */
7607 ext
= strrchr(filename
, '.');
7613 file
= tcc_open(s1
, filename
);
7615 if (flags
& AFF_PRINT_ERROR
) {
7616 error_noabort("file '%s' not found", filename
);
7622 if (!ext
|| !strcmp(ext
, "c")) {
7623 /* C file assumed */
7624 ret
= tcc_compile(s1
);
7627 /* assume executable format: auto guess file type */
7628 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
)) {
7629 error_noabort("could not read header");
7632 lseek(fd
, 0, SEEK_SET
);
7634 if (ehdr
.e_ident
[0] == ELFMAG0
&&
7635 ehdr
.e_ident
[1] == ELFMAG1
&&
7636 ehdr
.e_ident
[2] == ELFMAG2
&&
7637 ehdr
.e_ident
[3] == ELFMAG3
) {
7638 file
->line_num
= 0; /* do not display line number if error */
7639 if (ehdr
.e_type
== ET_REL
) {
7640 ret
= tcc_load_object_file(s1
, fd
, 0);
7641 } else if (ehdr
.e_type
== ET_DYN
) {
7642 ret
= tcc_load_dll(s1
, fd
, filename
,
7643 (flags
& AFF_REFERENCED_DLL
) != 0);
7645 error_noabort("unrecognized ELF file");
7648 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
7649 file
->line_num
= 0; /* do not display line number if error */
7650 ret
= tcc_load_archive(s1
, fd
);
7652 /* as GNU ld, consider it is an ld script if not recognized */
7653 ret
= tcc_load_ldscript(s1
);
7655 error_noabort("unrecognized file type");
7670 int tcc_add_file(TCCState
*s
, const char *filename
)
7672 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
7675 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
7679 pathname1
= tcc_strdup(pathname
);
7680 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
7684 /* find and load a dll. Return non zero if not found */
7685 /* XXX: add '-rpath' option support ? */
7686 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
7691 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
7692 snprintf(buf
, sizeof(buf
), "%s/%s",
7693 s
->library_paths
[i
], filename
);
7694 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
7700 /* the library name is the same as the argument of the '-l' option */
7701 int tcc_add_library(TCCState
*s
, const char *libraryname
)
7707 /* first we look for the dynamic library if not static linking */
7708 if (!s
->static_link
) {
7709 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
7710 /* if we output to memory, then we simply we dlopen(). */
7711 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
7712 /* Since the libc is already loaded, we don't need to load it again */
7713 if (!strcmp(libraryname
, "c"))
7715 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
7719 if (tcc_add_dll(s
, buf
, 0) == 0)
7724 /* then we look for the static library */
7725 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
7726 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
7727 s
->library_paths
[i
], libraryname
);
7728 if (tcc_add_file_internal(s
, buf
, 0) == 0)
7734 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
7736 add_elf_sym(symtab_section
, val
, 0,
7737 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7742 int tcc_set_output_type(TCCState
*s
, int output_type
)
7744 s
->output_type
= output_type
;
7746 /* if bound checking, then add corresponding sections */
7747 #ifdef CONFIG_TCC_BCHECK
7748 if (do_bounds_check
) {
7750 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
7751 /* create bounds sections */
7752 bounds_section
= new_section(s
, ".bounds",
7753 SHT_PROGBITS
, SHF_ALLOC
);
7754 lbounds_section
= new_section(s
, ".lbounds",
7755 SHT_PROGBITS
, SHF_ALLOC
);
7759 /* add debug sections */
7762 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
7763 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
7764 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
7765 put_elf_str(stabstr_section
, "");
7766 stab_section
->link
= stabstr_section
;
7767 /* put first entry */
7768 put_stabs("", 0, 0, 0, 0);
7771 /* add libc crt1/crti objects */
7772 if (output_type
== TCC_OUTPUT_EXE
||
7773 output_type
== TCC_OUTPUT_DLL
) {
7774 if (output_type
!= TCC_OUTPUT_DLL
)
7775 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
7776 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
7781 #if !defined(LIBTCC)
7785 printf("tcc version 0.9.12 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7786 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7787 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
7788 " [--] infile1 [infile2... --] [infile_args...]\n"
7790 "General options:\n"
7791 " -c compile only - generate an object file\n"
7792 " -o outfile set output filename\n"
7793 " -- allows multiples input files if no -o option given. Also\n"
7794 " separate input files from runtime arguments\n"
7795 " -Bdir set tcc internal library path\n"
7796 " -bench output compilation statistics\n"
7797 "Preprocessor options:\n"
7798 " -Idir add include path 'dir'\n"
7799 " -Dsym[=val] define 'sym' with value 'val'\n"
7800 " -Usym undefine 'sym'\n"
7801 "C compiler options:\n"
7802 " -g generate runtime debug info\n"
7803 #ifdef CONFIG_TCC_BCHECK
7804 " -b compile with built-in memory and bounds checker (implies -g)\n"
7807 " -Ldir add library path 'dir'\n"
7808 " -llib link with dynamic or static library 'lib'\n"
7809 " -shared generate a shared library\n"
7810 " -static static linking\n"
7811 " -r relocatable output\n"
7815 int main(int argc
, char **argv
)
7818 int optind
, output_type
, multiple_files
, i
, reloc_output
;
7821 int nb_files
, nb_libraries
, nb_objfiles
, dminus
, ret
;
7822 char objfilename
[1024];
7825 output_type
= TCC_OUTPUT_MEMORY
;
7836 if (optind
>= argc
) {
7844 /* add a new file */
7845 dynarray_add((void ***)&files
, &nb_files
, r
);
7846 if (!multiple_files
) {
7848 /* argv[0] will be this file */
7851 } else if (r
[1] == '-') {
7852 /* '--' enables multiple files input and also ends several file input */
7853 if (dminus
&& multiple_files
) {
7854 optind
--; /* argv[0] will be '--' */
7859 } else if (r
[1] == 'h' || r
[1] == '?') {
7863 } else if (r
[1] == 'I') {
7864 if (tcc_add_include_path(s
, r
+ 2) < 0)
7865 error("too many include paths");
7866 } else if (r
[1] == 'D') {
7869 value
= strchr(sym
, '=');
7874 tcc_define_symbol(s
, sym
, value
);
7875 } else if (r
[1] == 'U') {
7876 tcc_undefine_symbol(s
, r
+ 2);
7877 } else if (r
[1] == 'L') {
7878 tcc_add_library_path(s
, r
+ 2);
7879 } else if (r
[1] == 'B') {
7880 /* set tcc utilities path (mainly for tcc development) */
7881 tcc_lib_path
= r
+ 2;
7882 } else if (r
[1] == 'l') {
7883 dynarray_add((void ***)&files
, &nb_files
, r
);
7885 } else if (!strcmp(r
+ 1, "bench")) {
7888 #ifdef CONFIG_TCC_BCHECK
7890 do_bounds_check
= 1;
7896 } else if (r
[1] == 'c') {
7898 output_type
= TCC_OUTPUT_OBJ
;
7899 } else if (!strcmp(r
+ 1, "static")) {
7901 } else if (!strcmp(r
+ 1, "shared")) {
7902 output_type
= TCC_OUTPUT_DLL
;
7903 } else if (r
[1] == 'o') {
7907 outfile
= argv
[optind
++];
7908 } else if (r
[1] == 'r') {
7909 /* generate a .o merging several output files */
7911 output_type
= TCC_OUTPUT_OBJ
;
7912 } else if (r
[1] == 'W' || r
[1] == 'O' || r
[1] == 'm' || r
[1] == 'f') {
7913 /* ignore those options to be a drop-in replacement for gcc */
7915 error("invalid option -- '%s'", r
);
7919 nb_objfiles
= nb_files
- nb_libraries
;
7921 /* if outfile provided without other options, we output an
7923 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
7924 output_type
= TCC_OUTPUT_EXE
;
7926 /* check -c consistency : only single file handled. XXX: checks file type */
7927 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
7928 /* accepts only a single input file */
7929 if (nb_objfiles
!= 1)
7930 error("cannot specify multiple files with -c");
7931 if (nb_libraries
!= 0)
7932 error("cannot specify libraries with -c");
7935 /* compute default outfile name */
7936 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
7937 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
7939 /* add .o extension */
7940 pstrcpy(objfilename
, sizeof(objfilename
) - 1, files
[0]);
7941 ext
= strrchr(objfilename
, '.');
7943 goto default_outfile
;
7944 strcpy(ext
+ 1, "o");
7947 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
7949 outfile
= objfilename
;
7952 tcc_set_output_type(s
, output_type
);
7954 /* compile or add each files or library */
7955 for(i
= 0;i
< nb_files
; i
++) {
7956 const char *filename
;
7958 filename
= files
[i
];
7959 if (filename
[0] == '-') {
7960 if (tcc_add_library(s
, filename
+ 2) < 0)
7961 error("cannot find %s", filename
);
7963 if (tcc_add_file(s
, filename
) < 0) {
7970 /* free all files */
7974 printf("total: %d idents, %d lines, %d bytes\n",
7975 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
7978 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
7979 tcc_output_file(s
, outfile
);
7982 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
7989 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);