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 global_expr
; /* true if compound literals must be allocated
274 globally (used during initializers parsing */
275 int func_vt
, func_vc
; /* current function return type (used by
276 return instruction) */
277 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
279 TokenSym
**table_ident
;
280 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
281 char token_buf
[STRING_MAX_SIZE
+ 1];
283 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
285 SValue vstack
[VSTACK_SIZE
], *vtop
;
286 int *macro_ptr
, *macro_ptr_allocated
;
287 int char_pointer_type
;
290 /* compile with debug symbol (and use them if error during execution) */
293 /* compile with built-in memory and bounds checker */
294 int do_bounds_check
= 0;
296 /* display benchmark infos */
301 /* use GNU C extensions */
304 /* use Tiny C extensions */
307 /* XXX: suppress that ASAP */
308 static struct TCCState
*tcc_state
;
310 /* give the path of the tcc libraries */
311 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
316 BufferedFile
**include_stack_ptr
;
317 int *ifdef_stack_ptr
;
319 /* include file handling */
320 char **include_paths
;
321 int nb_include_paths
;
322 char **sysinclude_paths
;
323 int nb_sysinclude_paths
;
324 CachedInclude
**cached_includes
;
325 int nb_cached_includes
;
327 char **library_paths
;
328 int nb_library_paths
;
330 /* array of all loaded dlls (including those referenced by loaded
332 DLLReference
**loaded_dlls
;
337 int nb_sections
; /* number of sections, including first dummy section */
341 unsigned long *got_offsets
;
344 /* give the correspondance from symtab indexes to dynsym indexes */
345 int *symtab_to_dynsym
;
347 /* temporary dynamic symbol sections (for dll loading) */
348 Section
*dynsymtab_section
;
349 /* exported dynamic symbol section */
352 /* if true, static linking is performed */
357 void (*error_func
)(void *opaque
, const char *msg
);
358 int error_set_jmp_enabled
;
359 jmp_buf error_jmp_buf
;
362 /* see include_stack_ptr */
363 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
365 /* see ifdef_stack_ptr */
366 int ifdef_stack
[IFDEF_STACK_SIZE
];
369 /* The current value can be: */
370 #define VT_VALMASK 0x00ff
371 #define VT_CONST 0x00f0 /* constant in vc
372 (must be first non register value) */
373 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
374 #define VT_LOCAL 0x00f2 /* offset on stack */
375 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
376 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
377 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
378 #define VT_LVAL 0x0100 /* var is an lvalue */
379 #define VT_SYM 0x0200 /* a symbol value is added */
380 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
381 char/short stored in integer registers) */
382 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
383 dereferencing value */
384 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
385 bounding function call point is in vc */
386 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
387 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
388 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
389 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
392 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
394 #define VT_INT 0 /* integer type */
395 #define VT_BYTE 1 /* signed byte type */
396 #define VT_SHORT 2 /* short type */
397 #define VT_VOID 3 /* void type */
398 #define VT_PTR 4 /* pointer */
399 #define VT_ENUM 5 /* enum definition */
400 #define VT_FUNC 6 /* function type */
401 #define VT_STRUCT 7 /* struct/union definition */
402 #define VT_FLOAT 8 /* IEEE float */
403 #define VT_DOUBLE 9 /* IEEE double */
404 #define VT_LDOUBLE 10 /* IEEE long double */
405 #define VT_BOOL 11 /* ISOC99 boolean type */
406 #define VT_LLONG 12 /* 64 bit integer */
407 #define VT_LONG 13 /* long integer (NEVER USED as type, only
409 #define VT_BTYPE 0x000f /* mask for basic type */
410 #define VT_UNSIGNED 0x0010 /* unsigned type */
411 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
412 #define VT_BITFIELD 0x0040 /* bitfield modifier */
415 #define VT_EXTERN 0x00000080 /* extern definition */
416 #define VT_STATIC 0x00000100 /* static variable */
417 #define VT_TYPEDEF 0x00000200 /* typedef definition */
419 /* type mask (except storage) */
420 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
424 /* warning: the following compare tokens depend on i386 asm code */
436 #define TOK_LAND 0xa0
440 #define TOK_MID 0xa3 /* inc/dec, to void constant */
442 #define TOK_UDIV 0xb0 /* unsigned division */
443 #define TOK_UMOD 0xb1 /* unsigned modulo */
444 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
445 #define TOK_CINT 0xb3 /* number in tokc */
446 #define TOK_CCHAR 0xb4 /* char constant in tokc */
447 #define TOK_STR 0xb5 /* pointer to string in tokc */
448 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
449 #define TOK_LCHAR 0xb7
450 #define TOK_LSTR 0xb8
451 #define TOK_CFLOAT 0xb9 /* float constant */
452 #define TOK_LINENUM 0xba /* line number info */
453 #define TOK_CDOUBLE 0xc0 /* double constant */
454 #define TOK_CLDOUBLE 0xc1 /* long double constant */
455 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
456 #define TOK_ADDC1 0xc3 /* add with carry generation */
457 #define TOK_ADDC2 0xc4 /* add with carry use */
458 #define TOK_SUBC1 0xc5 /* add with carry generation */
459 #define TOK_SUBC2 0xc6 /* add with carry use */
460 #define TOK_CUINT 0xc8 /* unsigned int constant */
461 #define TOK_CLLONG 0xc9 /* long long constant */
462 #define TOK_CULLONG 0xca /* unsigned long long constant */
463 #define TOK_ARROW 0xcb
464 #define TOK_DOTS 0xcc /* three dots */
465 #define TOK_SHR 0xcd /* unsigned shift right */
467 #define TOK_SHL 0x01 /* shift left */
468 #define TOK_SAR 0x02 /* signed shift right */
470 /* assignement operators : normal operator or 0x80 */
471 #define TOK_A_MOD 0xa5
472 #define TOK_A_AND 0xa6
473 #define TOK_A_MUL 0xaa
474 #define TOK_A_ADD 0xab
475 #define TOK_A_SUB 0xad
476 #define TOK_A_DIV 0xaf
477 #define TOK_A_XOR 0xde
478 #define TOK_A_OR 0xfc
479 #define TOK_A_SHL 0x81
480 #define TOK_A_SAR 0x82
482 /* WARNING: the content of this string encodes token numbers */
483 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";
485 #define TOK_EOF (-1) /* end of file */
486 #define TOK_LINEFEED 10 /* line feed */
488 /* all identificators and strings have token above that */
489 #define TOK_IDENT 256
510 /* ignored types Must have contiguous values */
516 TOK___SIGNED__
, /* gcc keyword */
519 TOK___INLINE__
, /* gcc keyword */
522 /* unsupported type */
536 /* preprocessor only */
537 TOK_UIDENT
, /* first "user" ident (not keyword) */
538 TOK_DEFINE
= TOK_UIDENT
,
549 #define DEF(id, str) id,
555 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
556 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
557 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
558 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
559 "sizeof\0__attribute__\0"
560 /* the following are not keywords. They are included to ease parsing */
561 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
562 "defined\0undef\0error\0line\0"
563 /* builtin functions */
564 #define DEF(id, str) str "\0"
570 #define snprintf _snprintf
573 #if defined(WIN32) || defined(TCC_UCLIBC)
574 /* currently incorrect */
575 long double strtold(const char *nptr
, char **endptr
)
577 return (long double)strtod(nptr
, endptr
);
579 float strtof(const char *nptr
, char **endptr
)
581 return (float)strtod(nptr
, endptr
);
584 /* XXX: need to define this to use them in non ISOC99 context */
585 extern float strtof (const char *__nptr
, char **__endptr
);
586 extern long double strtold (const char *__nptr
, char **__endptr
);
589 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
590 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
594 void next_nomacro(void);
595 static int expr_const(void);
599 static void decl_initializer(int t
, Section
*sec
, unsigned long c
,
600 int first
, int size_only
);
601 static void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
,
602 int has_init
, int v
, int scope
);
604 void gv2(int rc1
, int rc2
);
605 void move_reg(int r
, int s
);
606 void save_regs(int n
);
607 void save_reg(int r
);
613 static void macro_subst(TokenString
*tok_str
,
614 Sym
**nested_list
, int *macro_str
);
615 int save_reg_forced(int r
);
617 void force_charshort_cast(int t
);
618 void gen_cast(int t
);
620 Sym
*sym_find(int v
);
621 Sym
*sym_push(int v
, int t
, int r
, int c
);
624 int type_size(int t
, int *a
);
625 int pointed_type(int t
);
626 int pointed_size(int t
);
627 static int lvalue_type(int t
);
628 int is_compatible_types(int t1
, int t2
);
629 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
630 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
632 void error(const char *fmt
, ...);
633 void rt_error(unsigned long pc
, const char *fmt
, ...);
635 void vset(int t
, int r
, int v
);
636 void type_to_str(char *buf
, int buf_size
,
637 int t
, const char *varstr
);
638 char *get_tok_str(int v
, CValue
*cv
);
639 static Sym
*get_sym_ref(int t
, Section
*sec
,
640 unsigned long offset
, unsigned long size
);
641 static Sym
*external_global_sym(int v
, int u
, int r
);
643 /* section generation */
644 static void section_realloc(Section
*sec
, unsigned long new_size
);
645 static void *section_ptr_add(Section
*sec
, unsigned long size
);
646 static void put_extern_sym(Sym
*sym
, Section
*section
,
647 unsigned long value
, unsigned long size
);
648 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
649 static int put_elf_str(Section
*s
, const char *sym
);
650 static int put_elf_sym(Section
*s
,
651 unsigned long value
, unsigned long size
,
652 int info
, int other
, int shndx
, const char *name
);
653 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
654 int info
, int sh_num
, const char *name
);
655 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
656 int type
, int symbol
);
657 static void put_stabs(const char *str
, int type
, int other
, int desc
,
658 unsigned long value
);
659 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
660 unsigned long value
, Section
*sec
, int sym_index
);
661 static void put_stabn(int type
, int other
, int desc
, int value
);
662 static void put_stabd(int type
, int other
, int desc
);
663 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
665 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
666 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
667 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
669 /* true if float/double/long double type */
670 static inline int is_float(int t
)
674 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
677 #ifdef TCC_TARGET_I386
678 #include "i386-gen.c"
684 #ifdef CONFIG_TCC_STATIC
686 #define RTLD_LAZY 0x001
687 #define RTLD_NOW 0x002
688 #define RTLD_GLOBAL 0x100
690 /* dummy function for profiling */
691 void *dlopen(const char *filename
, int flag
)
696 const char *dlerror(void)
701 typedef struct TCCSyms
{
706 #define TCCSYM(a) { #a, &a, },
708 /* add the symbol you want here if no dynamic linking is done */
709 static TCCSyms tcc_syms
[] = {
717 void *dlsym(void *handle
, const char *symbol
)
721 while (p
->str
!= NULL
) {
722 if (!strcmp(p
->str
, symbol
))
731 /********************************************************/
733 /* we use our own 'finite' function to avoid potential problems with
734 non standard math libs */
735 /* XXX: endianness dependant */
736 int ieee_finite(double d
)
739 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
742 /* copy a string and truncate it. */
743 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
750 q_end
= buf
+ buf_size
- 1;
762 /* strcat and truncate. */
763 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
768 pstrcpy(buf
+ len
, buf_size
- len
, s
);
772 /* memory management */
778 static inline void tcc_free(void *ptr
)
781 mem_cur_size
-= malloc_usable_size(ptr
);
786 static void *tcc_malloc(unsigned long size
)
791 error("memory full");
793 mem_cur_size
+= malloc_usable_size(ptr
);
794 if (mem_cur_size
> mem_max_size
)
795 mem_max_size
= mem_cur_size
;
800 static void *tcc_mallocz(unsigned long size
)
803 ptr
= tcc_malloc(size
);
804 memset(ptr
, 0, size
);
808 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
812 mem_cur_size
-= malloc_usable_size(ptr
);
814 ptr1
= realloc(ptr
, size
);
816 /* NOTE: count not correct if alloc error, but not critical */
817 mem_cur_size
+= malloc_usable_size(ptr1
);
818 if (mem_cur_size
> mem_max_size
)
819 mem_max_size
= mem_cur_size
;
824 static char *tcc_strdup(const char *str
)
827 ptr
= tcc_malloc(strlen(str
) + 1);
832 #define free(p) use_tcc_free(p)
833 #define malloc(s) use_tcc_malloc(s)
834 #define realloc(p, s) use_tcc_realloc(p, s)
836 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
843 /* every power of two we double array size */
844 if ((nb
& (nb
- 1)) == 0) {
849 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
851 error("memory full");
858 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
862 sec
= tcc_mallocz(sizeof(Section
));
863 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
864 sec
->sh_type
= sh_type
;
865 sec
->sh_flags
= sh_flags
;
872 sec
->sh_addralign
= 4;
875 sec
->sh_addralign
= 1;
878 sec
->sh_addralign
= 32; /* default conservative alignment */
882 /* only add section if not private */
883 if (!(sh_flags
& SHF_PRIVATE
)) {
884 sec
->sh_num
= s1
->nb_sections
;
885 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
890 static void free_section(Section
*s
)
896 /* realloc section and set its content to zero */
897 static void section_realloc(Section
*sec
, unsigned long new_size
)
902 size
= sec
->data_allocated
;
905 while (size
< new_size
)
907 data
= tcc_realloc(sec
->data
, size
);
909 error("memory full");
910 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
912 sec
->data_allocated
= size
;
915 /* reserve at least 'size' bytes in section 'sec' from
917 static void *section_ptr_add(Section
*sec
, unsigned long size
)
919 unsigned long offset
, offset1
;
921 offset
= sec
->data_offset
;
922 offset1
= offset
+ size
;
923 if (offset1
> sec
->data_allocated
)
924 section_realloc(sec
, offset1
);
925 sec
->data_offset
= offset1
;
926 return sec
->data
+ offset
;
929 /* return a reference to a section, and create it if it does not
931 Section
*find_section(TCCState
*s1
, const char *name
)
935 for(i
= 1; i
< s1
->nb_sections
; i
++) {
936 sec
= s1
->sections
[i
];
937 if (!strcmp(name
, sec
->name
))
940 /* sections are created as PROGBITS */
941 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
944 /* update sym->c so that it points to an external symbol in section
945 'section' with value 'value' */
946 static void put_extern_sym(Sym
*sym
, Section
*section
,
947 unsigned long value
, unsigned long size
)
949 int sym_type
, sym_bind
, sh_num
, info
;
955 sh_num
= section
->sh_num
;
959 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
962 sym_type
= STT_OBJECT
;
963 if (sym
->t
& VT_STATIC
)
964 sym_bind
= STB_LOCAL
;
966 sym_bind
= STB_GLOBAL
;
968 name
= get_tok_str(sym
->v
, NULL
);
969 #ifdef CONFIG_TCC_BCHECK
970 if (do_bounds_check
) {
971 /* if bound checking is activated, we change some function
972 names by adding the "__bound" prefix */
975 /* XXX: we rely only on malloc hooks */
987 strcpy(buf
, "__bound_");
994 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
995 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
997 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
998 esym
->st_value
= value
;
999 esym
->st_size
= size
;
1000 esym
->st_shndx
= sh_num
;
1004 /* add a new relocation entry to symbol 'sym' in section 's' */
1005 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
1008 put_extern_sym(sym
, NULL
, 0, 0);
1009 /* now we can add ELF relocation info */
1010 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
1013 static inline int isid(int c
)
1015 return (c
>= 'a' && c
<= 'z') ||
1016 (c
>= 'A' && c
<= 'Z') ||
1020 static inline int isnum(int c
)
1022 return c
>= '0' && c
<= '9';
1025 static inline int isoct(int c
)
1027 return c
>= '0' && c
<= '7';
1030 static inline int toup(int c
)
1032 if (ch
>= 'a' && ch
<= 'z')
1033 return ch
- 'a' + 'A';
1038 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1042 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1045 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1049 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1053 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1060 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1061 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1062 (*f
)->filename
, (*f
)->line_num
);
1063 if (file
->line_num
> 0) {
1064 strcat_printf(buf
, sizeof(buf
),
1065 "%s:%d: ", file
->filename
, file
->line_num
);
1067 strcat_printf(buf
, sizeof(buf
),
1068 "%s: ", file
->filename
);
1071 strcat_printf(buf
, sizeof(buf
),
1075 strcat_printf(buf
, sizeof(buf
), "warning: ");
1076 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1078 if (!s1
->error_func
) {
1079 /* default case: stderr */
1080 fprintf(stderr
, "%s\n", buf
);
1082 s1
->error_func(s1
->error_opaque
, buf
);
1088 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1089 void (*error_func
)(void *opaque
, const char *msg
))
1091 s
->error_opaque
= error_opaque
;
1092 s
->error_func
= error_func
;
1096 /* error without aborting current compilation */
1097 void error_noabort(const char *fmt
, ...)
1099 TCCState
*s1
= tcc_state
;
1103 error1(s1
, 0, fmt
, ap
);
1107 void error(const char *fmt
, ...)
1109 TCCState
*s1
= tcc_state
;
1113 error1(s1
, 0, fmt
, ap
);
1115 /* better than nothing: in some cases, we accept to handle errors */
1116 if (s1
->error_set_jmp_enabled
) {
1117 longjmp(s1
->error_jmp_buf
, 1);
1119 /* XXX: suppress it someday */
1124 void expect(const char *msg
)
1126 error("%s expected", msg
);
1129 void warning(const char *fmt
, ...)
1131 TCCState
*s1
= tcc_state
;
1135 error1(s1
, 1, fmt
, ap
);
1142 error("'%c' expected", c
);
1146 void test_lvalue(void)
1148 if (!(vtop
->r
& VT_LVAL
))
1152 TokenSym
*tok_alloc(const char *str
, int len
)
1154 TokenSym
*ts
, **pts
, **ptable
;
1159 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
1161 pts
= &hash_ident
[h
];
1166 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1168 pts
= &(ts
->hash_next
);
1171 if (tok_ident
>= SYM_FIRST_ANOM
)
1172 error("memory full");
1174 /* expand token table if needed */
1175 i
= tok_ident
- TOK_IDENT
;
1176 if ((i
% TOK_ALLOC_INCR
) == 0) {
1177 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1179 error("memory full");
1180 table_ident
= ptable
;
1183 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1184 table_ident
[i
] = ts
;
1185 ts
->tok
= tok_ident
++;
1187 ts
->hash_next
= NULL
;
1188 memcpy(ts
->str
, str
, len
+ 1);
1193 /* CString handling */
1195 static void cstr_realloc(CString
*cstr
, int new_size
)
1200 size
= cstr
->size_allocated
;
1202 size
= 8; /* no need to allocate a too small first string */
1203 while (size
< new_size
)
1205 data
= tcc_realloc(cstr
->data_allocated
, size
);
1207 error("memory full");
1208 cstr
->data_allocated
= data
;
1209 cstr
->size_allocated
= size
;
1214 static void cstr_ccat(CString
*cstr
, int ch
)
1217 size
= cstr
->size
+ 1;
1218 if (size
> cstr
->size_allocated
)
1219 cstr_realloc(cstr
, size
);
1220 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1224 static void cstr_cat(CString
*cstr
, const char *str
)
1236 /* add a wide char */
1237 static void cstr_wccat(CString
*cstr
, int ch
)
1240 size
= cstr
->size
+ sizeof(int);
1241 if (size
> cstr
->size_allocated
)
1242 cstr_realloc(cstr
, size
);
1243 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1247 static void cstr_new(CString
*cstr
)
1249 memset(cstr
, 0, sizeof(CString
));
1252 /* free string and reset it to NULL */
1253 static void cstr_free(CString
*cstr
)
1255 tcc_free(cstr
->data_allocated
);
1259 #define cstr_reset(cstr) cstr_free(cstr)
1261 /* XXX: unicode ? */
1262 static void add_char(CString
*cstr
, int c
)
1264 if (c
== '\'' || c
== '\"' || c
== '\\') {
1265 /* XXX: could be more precise if char or string */
1266 cstr_ccat(cstr
, '\\');
1268 if (c
>= 32 && c
<= 126) {
1271 cstr_ccat(cstr
, '\\');
1273 cstr_ccat(cstr
, 'n');
1275 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1276 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1277 cstr_ccat(cstr
, '0' + (c
& 7));
1282 /* XXX: buffer overflow */
1283 /* XXX: float tokens */
1284 char *get_tok_str(int v
, CValue
*cv
)
1286 static char buf
[STRING_MAX_SIZE
+ 1];
1287 static CString cstr_buf
;
1293 /* NOTE: to go faster, we give a fixed buffer for small strings */
1294 cstr_reset(&cstr_buf
);
1295 cstr_buf
.data
= buf
;
1296 cstr_buf
.size_allocated
= sizeof(buf
);
1302 /* XXX: not quite exact, but useful for ## in macros */
1303 sprintf(p
, "%u", cv
->ui
);
1307 /* XXX: not quite exact, but useful for ## in macros */
1308 sprintf(p
, "%Lu", cv
->ull
);
1312 cstr_ccat(&cstr_buf
, '\'');
1313 add_char(&cstr_buf
, cv
->i
);
1314 cstr_ccat(&cstr_buf
, '\'');
1315 cstr_ccat(&cstr_buf
, '\0');
1320 cstr_ccat(&cstr_buf
, '\"');
1322 len
= cstr
->size
- 1;
1324 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1326 len
= (cstr
->size
/ sizeof(int)) - 1;
1328 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1330 cstr_ccat(&cstr_buf
, '\"');
1331 cstr_ccat(&cstr_buf
, '\0');
1340 return strcpy(p
, "<<=");
1342 return strcpy(p
, ">>=");
1344 if (v
< TOK_IDENT
) {
1345 /* search in two bytes table */
1359 } else if (v
< tok_ident
) {
1360 return table_ident
[v
- TOK_IDENT
]->str
;
1361 } else if (v
>= SYM_FIRST_ANOM
) {
1362 /* special name for anonymous symbol */
1363 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1365 /* should never happen */
1370 return cstr_buf
.data
;
1373 /* push, without hashing */
1374 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1377 s
= tcc_malloc(sizeof(Sym
));
1388 /* find a symbol and return its associated structure. 's' is the top
1389 of the symbol stack */
1390 Sym
*sym_find2(Sym
*s
, int v
)
1400 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1402 /* find a symbol and return its associated structure. 'st' is the
1404 Sym
*sym_find1(SymStack
*st
, int v
)
1408 s
= st
->hash
[HASH_SYM(v
)];
1417 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1420 s
= sym_push2(&st
->top
, v
, t
, c
);
1421 /* add in hash table */
1423 ps
= &st
->hash
[HASH_SYM(v
)];
1430 /* find a symbol in the right symbol space */
1431 Sym
*sym_find(int v
)
1434 s
= sym_find1(&local_stack
, v
);
1436 s
= sym_find1(&global_stack
, v
);
1440 /* push a given symbol on the symbol stack */
1441 Sym
*sym_push(int v
, int t
, int r
, int c
)
1444 if (local_stack
.top
)
1445 s
= sym_push1(&local_stack
, v
, t
, c
);
1447 s
= sym_push1(&global_stack
, v
, t
, c
);
1452 /* pop symbols until top reaches 'b' */
1453 void sym_pop(SymStack
*st
, Sym
*b
)
1460 /* free hash table entry, except if symbol was freed (only
1461 used for #undef symbols) */
1463 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1470 /* undefined a hashed symbol (used for #undef). Its name is set to
1472 void sym_undef(SymStack
*st
, Sym
*s
)
1475 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1476 while (*ss
!= NULL
) {
1479 ss
= &(*ss
)->hash_next
;
1487 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1492 fd
= open(filename
, O_RDONLY
);
1495 bf
= tcc_malloc(sizeof(BufferedFile
));
1501 bf
->buf_ptr
= bf
->buffer
;
1502 bf
->buf_end
= bf
->buffer
;
1503 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1504 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1506 bf
->ifndef_macro
= 0;
1507 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1508 // printf("opening '%s'\n", filename);
1512 void tcc_close(BufferedFile
*bf
)
1514 total_lines
+= bf
->line_num
;
1519 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1520 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1522 /* fill input buffer and return next char */
1523 int tcc_getc_slow(BufferedFile
*bf
)
1526 /* only tries to read if really end of buffer */
1527 if (bf
->buf_ptr
>= bf
->buf_end
) {
1529 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1536 bf
->buf_ptr
= bf
->buffer
;
1537 bf
->buf_end
= bf
->buffer
+ len
;
1538 *bf
->buf_end
= CH_EOB
;
1540 if (bf
->buf_ptr
< bf
->buf_end
) {
1541 return *bf
->buf_ptr
++;
1543 bf
->buf_ptr
= bf
->buf_end
;
1548 /* no need to put that inline */
1549 void handle_eob(void)
1551 TCCState
*s1
= tcc_state
;
1553 ch1
= tcc_getc_slow(file
);
1557 if (return_linefeed
) {
1561 if (s1
->include_stack_ptr
== s1
->include_stack
)
1563 /* add end of include file debug info */
1565 put_stabd(N_EINCL
, 0, 0);
1567 /* pop include stack */
1569 s1
->include_stack_ptr
--;
1570 file
= *s1
->include_stack_ptr
;
1574 /* read next char from current input file */
1575 static inline void inp(void)
1577 ch1
= TCC_GETC(file
);
1578 /* end of buffer/file handling */
1583 // printf("ch1=%c 0x%x\n", ch1, ch1);
1586 /* handle '\\n' and '\\r\n' */
1587 static void handle_stray(void)
1592 } else if (ch1
== '\r') {
1595 error("invalid character after '\\'");
1602 } while (ch
== '\\');
1605 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1607 static inline void minp(void)
1616 /* same as minp, but also skip comments */
1617 static void cinp(void)
1624 /* single line C++ comments */
1626 while (ch1
!= '\n' && ch1
!= CH_EOF
)
1628 ch
= ' '; /* return space */
1629 } else if (ch1
== '*') {
1632 while (ch1
!= CH_EOF
) {
1635 if (c
== '*' && ch1
== '/') {
1637 ch
= ' '; /* return space */
1649 /* space exlcuding newline */
1650 static inline int is_space(int ch
)
1652 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1655 static inline void skip_spaces(void)
1657 while (is_space(ch
))
1661 /* skip block of text until #else, #elif or #endif. skip also pairs of
1663 void preprocess_skip(void)
1668 while (ch
!= '\n') {
1679 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1681 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1683 else if (tok
== TOK_ENDIF
)
1689 /* ParseState handling */
1691 /* XXX: currently, no include file info is stored. Thus, we cannot display
1692 accurate messages if the function or data definition spans multiple
1695 /* save current parse state in 's' */
1696 void save_parse_state(ParseState
*s
)
1698 s
->line_num
= file
->line_num
;
1699 s
->macro_ptr
= macro_ptr
;
1704 /* restore parse state from 's' */
1705 void restore_parse_state(ParseState
*s
)
1707 file
->line_num
= s
->line_num
;
1708 macro_ptr
= s
->macro_ptr
;
1713 /* return the number of additionnal 'ints' necessary to store the
1715 static inline int tok_ext_size(int t
)
1733 return LDOUBLE_SIZE
/ 4;
1739 /* token string handling */
1741 static inline void tok_str_new(TokenString
*s
)
1745 s
->last_line_num
= -1;
1748 static void tok_str_free(int *str
)
1759 if (t
== TOK_STR
|| t
== TOK_LSTR
) {
1760 /* XXX: use a macro to be portable on 64 bit ? */
1761 cstr
= (CString
*)(*p
++);
1765 p
+= tok_ext_size(t
);
1771 static void tok_str_add(TokenString
*s
, int t
)
1777 if ((len
& 63) == 0) {
1778 str
= tcc_realloc(str
, (len
+ 64) * sizeof(int));
1787 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1790 CString
*cstr
, *cstr1
;
1794 if (t
== TOK_STR
|| t
== TOK_LSTR
) {
1795 /* special case: need to duplicate string */
1797 cstr
= tcc_malloc(sizeof(CString
));
1800 cstr
->size_allocated
= size
;
1801 cstr
->data_allocated
= tcc_malloc(size
);
1802 cstr
->data
= cstr
->data_allocated
;
1803 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1805 tok_str_add(s
, cv1
.tab
[0]);
1807 n
= tok_ext_size(t
);
1809 tok_str_add(s
, cv
->tab
[i
]);
1813 /* add the current parse token in token string 's' */
1814 static void tok_str_add_tok(TokenString
*s
)
1818 /* save line number info */
1819 if (file
->line_num
!= s
->last_line_num
) {
1820 s
->last_line_num
= file
->line_num
;
1821 cval
.i
= s
->last_line_num
;
1822 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1824 tok_str_add2(s
, tok
, &tokc
);
1827 /* get a token from an integer array and increment pointer accordingly */
1828 static int tok_get(int **tok_str
, CValue
*cv
)
1834 n
= tok_ext_size(t
);
1841 /* eval an expression for #if/#elif */
1842 int expr_preprocess(void)
1848 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1849 next(); /* do macro subst */
1850 if (tok
== TOK_DEFINED
) {
1855 c
= sym_find1(&define_stack
, tok
) != 0;
1860 } else if (tok
>= TOK_IDENT
) {
1861 /* if undefined macro */
1865 tok_str_add_tok(&str
);
1867 tok_str_add(&str
, -1); /* simulate end of file */
1868 tok_str_add(&str
, 0);
1869 /* now evaluate C constant expression */
1870 macro_ptr
= str
.str
;
1874 tok_str_free(str
.str
);
1878 #if defined(DEBUG) || defined(PP_DEBUG)
1879 void tok_print(int *str
)
1885 t
= tok_get(&str
, &cval
);
1888 printf(" %s", get_tok_str(t
, &cval
));
1894 /* parse after #define */
1895 void parse_define(void)
1897 Sym
*s
, *first
, **ps
;
1898 int v
, t
, varg
, is_vaargs
;
1902 /* XXX: should check if same macro (ANSI) */
1905 /* '(' must be just after macro definition for MACRO_FUNC */
1910 while (tok
!= ')') {
1914 if (varg
== TOK_DOTS
) {
1915 varg
= TOK___VA_ARGS__
;
1917 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1921 if (varg
< TOK_IDENT
)
1922 error("badly punctuated parameter list");
1923 s
= sym_push1(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1934 /* EOF testing necessary for '-D' handling */
1935 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1936 tok_str_add2(&str
, tok
, &tokc
);
1939 tok_str_add(&str
, 0);
1941 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1944 s
= sym_push1(&define_stack
, v
, t
, (int)str
.str
);
1948 /* XXX: use a token or a hash table to accelerate matching ? */
1949 static CachedInclude
*search_cached_include(TCCState
*s1
,
1950 int type
, const char *filename
)
1955 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
1956 e
= s1
->cached_includes
[i
];
1957 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
1963 static inline void add_cached_include(TCCState
*s1
, int type
,
1964 const char *filename
, int ifndef_macro
)
1968 if (search_cached_include(s1
, type
, filename
))
1971 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
1973 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
1977 strcpy(e
->filename
, filename
);
1978 e
->ifndef_macro
= ifndef_macro
;
1979 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
1984 INCLUDE_STATE_NONE
= 0,
1985 INCLUDE_STATE_SEEK_IFNDEF
,
1988 void preprocess(void)
1990 TCCState
*s1
= tcc_state
;
1992 enum IncludeState state
;
1993 char buf
[1024], *q
, *p
;
1999 return_linefeed
= 1; /* linefeed will be returned as a
2000 token. EOF is also returned as line feed */
2001 state
= INCLUDE_STATE_NONE
;
2007 if (tok
== TOK_DEFINE
) {
2010 } else if (tok
== TOK_UNDEF
) {
2012 s
= sym_find1(&define_stack
, tok
);
2013 /* undefine symbol by putting an invalid name */
2015 sym_undef(&define_stack
, s
);
2016 } else if (tok
== TOK_INCLUDE
) {
2021 } else if (ch
== '\"') {
2026 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2027 if ((q
- buf
) < sizeof(buf
) - 1)
2032 /* eat all spaces and comments after include */
2033 /* XXX: slightly incorrect */
2034 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2037 /* computed #include : either we have only strings or
2038 we have anything enclosed in '<>' */
2041 if (tok
== TOK_STR
) {
2042 while (tok
!= TOK_LINEFEED
) {
2043 if (tok
!= TOK_STR
) {
2045 error("'#include' expects \"FILENAME\" or <FILENAME>");
2047 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2053 while (tok
!= TOK_LINEFEED
) {
2054 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2058 /* check syntax and remove '<>' */
2059 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2060 goto include_syntax
;
2061 memmove(buf
, buf
+ 1, len
- 2);
2062 buf
[len
- 2] = '\0';
2068 e
= search_cached_include(s1
, c
, buf
);
2069 if (e
&& sym_find1(&define_stack
, e
->ifndef_macro
)) {
2070 /* no need to parse the include because the 'ifndef macro'
2073 printf("%s: skipping %s\n", file
->filename
, buf
);
2077 /* first search in current dir if "header.h" */
2079 p
= strrchr(file
->filename
, '/');
2081 size
= p
+ 1 - file
->filename
;
2082 if (size
> sizeof(buf1
) - 1)
2083 size
= sizeof(buf1
) - 1;
2084 memcpy(buf1
, file
->filename
, size
);
2086 pstrcat(buf1
, sizeof(buf1
), buf
);
2087 f
= tcc_open(s1
, buf1
);
2091 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2092 error("#include recursion too deep");
2093 /* now search in all the include paths */
2094 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2095 for(i
= 0; i
< n
; i
++) {
2097 if (i
< s1
->nb_include_paths
)
2098 path
= s1
->include_paths
[i
];
2100 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2101 pstrcpy(buf1
, sizeof(buf1
), path
);
2102 pstrcat(buf1
, sizeof(buf1
), "/");
2103 pstrcat(buf1
, sizeof(buf1
), buf
);
2104 f
= tcc_open(s1
, buf1
);
2108 error("include file '%s' not found", buf
);
2112 printf("%s: including %s\n", file
->filename
, buf1
);
2115 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2116 /* push current file in stack */
2117 /* XXX: fix current line init */
2118 *s1
->include_stack_ptr
++ = file
;
2120 /* add include file debug info */
2122 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2124 /* we check for the construct: #ifndef IDENT \n #define IDENT */
2126 /* get first non space char */
2127 while (is_space(ch
) || ch
== '\n')
2131 state
= INCLUDE_STATE_SEEK_IFNDEF
;
2134 } else if (tok
== TOK_IFNDEF
) {
2137 } else if (tok
== TOK_IF
) {
2138 c
= expr_preprocess();
2140 } else if (tok
== TOK_IFDEF
) {
2144 if (tok
< TOK_IDENT
)
2145 error("invalid argument for '#if%sdef'", c
? "n" : "");
2146 if (state
== INCLUDE_STATE_SEEK_IFNDEF
) {
2148 file
->ifndef_macro
= tok
;
2150 state
= INCLUDE_STATE_NONE
;
2152 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
2154 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2155 error("memory full");
2156 *s1
->ifdef_stack_ptr
++ = c
;
2158 } else if (tok
== TOK_ELSE
) {
2159 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2160 error("#else without matching #if");
2161 if (s1
->ifdef_stack_ptr
[-1] & 2)
2162 error("#else after #else");
2163 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2165 } else if (tok
== TOK_ELIF
) {
2166 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2167 error("#elif without matching #if");
2168 c
= s1
->ifdef_stack_ptr
[-1];
2170 error("#elif after #else");
2171 /* last #if/#elif expression was true: we skip */
2174 c
= expr_preprocess();
2175 s1
->ifdef_stack_ptr
[-1] = c
;
2180 state
= INCLUDE_STATE_NONE
;
2183 } else if (tok
== TOK_ENDIF
) {
2184 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2185 error("#endif without matching #if");
2186 if (file
->ifndef_macro
&&
2187 s1
->ifdef_stack_ptr
== (file
->ifdef_stack_ptr
+ 1)) {
2188 /* '#ifndef macro \n #define macro' was at the start of
2189 file. Now we check if an '#endif' is exactly at the end
2191 while (tok
!= TOK_LINEFEED
)
2193 /* XXX: should also skip comments, but it is more complicated */
2195 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
2196 file
->ifndef_macro
);
2198 /* if not end of file, we must desactivate the ifndef
2200 file
->ifndef_macro
= 0;
2203 s1
->ifdef_stack_ptr
--;
2204 } else if (tok
== TOK_LINE
) {
2207 if (tok
!= TOK_CINT
)
2211 if (tok
!= TOK_LINEFEED
) {
2214 pstrcpy(file
->filename
, sizeof(file
->filename
),
2215 (char *)tokc
.cstr
->data
);
2217 /* NOTE: we do it there to avoid problems with linefeed */
2218 file
->line_num
= line_num
;
2219 } else if (tok
== TOK_ERROR
) {
2222 /* ignore other preprocess commands or #! for C scripts */
2223 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
)
2226 return_linefeed
= 0;
2229 /* read a number in base b */
2230 static int getn(int b
)
2235 if (ch
>= 'a' && ch
<= 'f')
2237 else if (ch
>= 'A' && ch
<= 'F')
2243 if (t
< 0 || t
>= b
)
2251 /* read a character for string or char constant and eval escape codes */
2252 static int getq(void)
2260 /* at most three octal digits */
2264 c
= c
* 8 + ch
- '0';
2267 c
= c
* 8 + ch
- '0';
2272 } else if (ch
== 'x') {
2290 else if (ch
== 'e' && gnu_ext
)
2292 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
2295 error("invalid escaped char");
2298 } else if (c
== '\r' && ch
== '\n') {
2305 /* we use 64 bit numbers */
2308 /* bn = (bn << shift) | or_val */
2309 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2313 for(i
=0;i
<BN_SIZE
;i
++) {
2315 bn
[i
] = (v
<< shift
) | or_val
;
2316 or_val
= v
>> (32 - shift
);
2320 void bn_zero(unsigned int *bn
)
2323 for(i
=0;i
<BN_SIZE
;i
++) {
2328 void parse_number(void)
2330 int b
, t
, shift
, frac_bits
, s
, exp_val
;
2332 unsigned int bn
[BN_SIZE
];
2342 /* special dot handling */
2343 if (ch
>= '0' && ch
<= '9') {
2344 goto float_frac_parse
;
2345 } else if (ch
== '.') {
2356 } else if (t
== '0') {
2357 if (ch
== 'x' || ch
== 'X') {
2361 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2367 /* parse all digits. cannot check octal numbers at this stage
2368 because of floating point constants */
2370 if (ch
>= 'a' && ch
<= 'f')
2372 else if (ch
>= 'A' && ch
<= 'F')
2380 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2382 error("number too long");
2388 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2389 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2391 /* NOTE: strtox should support that for hexa numbers, but
2392 non ISOC99 libcs do not support it, so we prefer to do
2394 /* hexadecimal or binary floats */
2395 /* XXX: handle overflows */
2407 } else if (t
>= 'a') {
2409 } else if (t
>= 'A') {
2414 bn_lshift(bn
, shift
, t
);
2421 if (t
>= 'a' && t
<= 'f') {
2423 } else if (t
>= 'A' && t
<= 'F') {
2425 } else if (t
>= '0' && t
<= '9') {
2431 error("invalid digit");
2432 bn_lshift(bn
, shift
, t
);
2437 if (ch
!= 'p' && ch
!= 'P')
2438 error("exponent expected");
2444 } else if (ch
== '-') {
2448 if (ch
< '0' || ch
> '9')
2449 error("exponent digits expected");
2450 while (ch
>= '0' && ch
<= '9') {
2451 exp_val
= exp_val
* 10 + ch
- '0';
2454 exp_val
= exp_val
* s
;
2456 /* now we can generate the number */
2457 /* XXX: should patch directly float number */
2458 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
2459 d
= ldexp(d
, exp_val
- frac_bits
);
2464 /* float : should handle overflow */
2466 } else if (t
== 'L') {
2469 /* XXX: not large enough */
2470 tokc
.ld
= (long double)d
;
2476 /* decimal floats */
2478 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2483 while (ch
>= '0' && ch
<= '9') {
2484 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2490 if (ch
== 'e' || ch
== 'E') {
2491 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2495 if (ch
== '-' || ch
== '+') {
2496 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2501 if (ch
< '0' || ch
> '9')
2502 error("exponent digits expected");
2503 while (ch
>= '0' && ch
<= '9') {
2504 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2516 tokc
.f
= strtof(token_buf
, NULL
);
2517 } else if (t
== 'L') {
2520 tokc
.ld
= strtold(token_buf
, NULL
);
2523 tokc
.d
= strtod(token_buf
, NULL
);
2527 unsigned long long n
, n1
;
2530 /* integer number */
2533 if (b
== 10 && *q
== '0') {
2540 /* no need for checks except for base 10 / 8 errors */
2543 } else if (t
>= 'a') {
2545 } else if (t
>= 'A') {
2550 error("invalid digit");
2554 /* detect overflow */
2556 error("integer constant overflow");
2559 /* XXX: not exactly ANSI compliant */
2560 if ((n
& 0xffffffff00000000LL
) != 0) {
2565 } else if (n
> 0x7fffffff) {
2575 error("three 'l' in integer constant");
2578 if (tok
== TOK_CINT
)
2580 else if (tok
== TOK_CUINT
)
2584 } else if (t
== 'U') {
2585 if (tok
== TOK_CINT
)
2587 else if (tok
== TOK_CLLONG
)
2594 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2602 /* return next token without macro substitution */
2603 static inline void next_nomacro1(void)
2611 while (ch
== '\n') {
2612 /* during preprocessor parsing, '\n' is a token */
2613 if (return_linefeed
) {
2620 /* preprocessor command if # at start of line after
2643 while (isid(ch
) || isnum(ch
)) {
2644 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2645 error("ident too long");
2650 ts
= tok_alloc(token_buf
, q
- token_buf
);
2652 } else if (isnum(ch
) || ch
== '.') {
2654 } else if (ch
== '\'') {
2659 /* this cast is needed if >= 128 */
2660 if (tok
== TOK_CCHAR
)
2666 } else if (ch
== '\"') {
2670 cstr_reset(&tokcstr
);
2671 while (ch
!= '\"') {
2674 error("unterminated string");
2676 cstr_ccat(&tokcstr
, b
);
2678 cstr_wccat(&tokcstr
, b
);
2681 cstr_ccat(&tokcstr
, '\0');
2683 cstr_wccat(&tokcstr
, '\0');
2684 tokc
.cstr
= &tokcstr
;
2692 if (*q
== tok
&& q
[1] == ch
) {
2695 /* three chars tests */
2696 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2701 } else if (tok
== TOK_DOTS
) {
2703 error("parse error");
2710 /* single char substitutions */
2713 else if (tok
== '>')
2718 /* return next token without macro substitution. Can read input from
2726 tok
= tok_get(¯o_ptr
, &tokc
);
2727 if (tok
== TOK_LINENUM
) {
2728 file
->line_num
= tokc
.i
;
2737 /* substitute args in macro_str and return allocated string */
2738 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2740 int *st
, last_tok
, t
, notfirst
;
2749 t
= tok_get(¯o_str
, &cval
);
2754 t
= tok_get(¯o_str
, &cval
);
2757 s
= sym_find2(args
, t
);
2764 cstr_ccat(&cstr
, ' ');
2765 t
= tok_get(&st
, &cval
);
2766 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
2769 cstr_ccat(&cstr
, '\0');
2771 printf("stringize: %s\n", (char *)cstr
.data
);
2775 tok_str_add2(&str
, TOK_STR
, &cval
);
2778 tok_str_add2(&str
, t
, &cval
);
2780 } else if (t
>= TOK_IDENT
) {
2781 s
= sym_find2(args
, t
);
2784 /* if '##' is present before or after, no arg substitution */
2785 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2786 /* special case for var arg macros : ## eats the
2787 ',' if empty VA_ARGS variable. */
2788 /* XXX: test of the ',' is not 100%
2789 reliable. should fix it to avoid security
2791 if (gnu_ext
&& s
->t
&&
2792 last_tok
== TOK_TWOSHARPS
&&
2793 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
2795 /* suppress ',' '##' */
2798 /* suppress '##' and add variable */
2806 t1
= tok_get(&st
, &cval
);
2809 tok_str_add2(&str
, t1
, &cval
);
2813 macro_subst(&str
, nested_list
, st
);
2816 tok_str_add(&str
, t
);
2819 tok_str_add2(&str
, t
, &cval
);
2823 tok_str_add(&str
, 0);
2827 /* not inline to save space */
2828 static int is_tok_num(int t
)
2830 return (t
== TOK_CINT
|| t
== TOK_CUINT
||
2831 t
== TOK_CLLONG
|| t
== TOK_CULLONG
);
2834 /* handle the '##' operator */
2835 static int *macro_twosharps(void)
2840 const char *p1
, *p2
;
2842 TokenString macro_str1
;
2844 tok_str_new(¯o_str1
);
2850 while (*macro_ptr
== TOK_TWOSHARPS
) {
2852 macro_ptr1
= macro_ptr
;
2855 t
= tok_get(¯o_ptr
, &cval
);
2856 /* XXX: not exact, but cannot do more without
2857 modifying the whole preprocessing architecture ! */
2858 /* XXX: handle arbitrary size */
2859 p1
= get_tok_str(tok
, &tokc
);
2860 pstrcpy(token_buf
, sizeof(token_buf
), p1
);
2861 p2
= get_tok_str(t
, &cval
);
2862 if (tok
>= TOK_IDENT
&&
2863 (t
>= TOK_IDENT
|| is_tok_num(t
))) {
2864 pstrcat(token_buf
, sizeof(token_buf
), p2
);
2865 ts
= tok_alloc(token_buf
, strlen(token_buf
));
2866 tok
= ts
->tok
; /* modify current token */
2867 } else if (is_tok_num(tok
) && is_tok_num(t
)) {
2868 unsigned long long n
;
2870 pstrcat(token_buf
, sizeof(token_buf
), p2
);
2871 n
= strtoull(token_buf
, NULL
, 10);
2872 if ((n
& 0xffffffff00000000LL
) != 0) {
2877 } else if (n
> 0x7fffffff) {
2882 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2886 } else if (is_tok_num(tok
) && t
>= TOK_IDENT
) {
2887 /* incorrect, but suffisant for '1LL' case */
2890 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", token_buf
, p2
);
2891 /* cannot merge tokens: skip '##' */
2892 macro_ptr
= macro_ptr1
;
2897 tok_str_add2(¯o_str1
, tok
, &tokc
);
2899 tok_str_add(¯o_str1
, 0);
2900 return macro_str1
.str
;
2904 /* do macro substitution of current token with macro 's' and add
2905 result to (tok_str,tok_len). 'nested_list' is the list of all
2906 macros we got inside to avoid recursing. Return non zero if no
2907 substitution needs to be done */
2908 static int macro_subst_tok(TokenString
*tok_str
,
2909 Sym
**nested_list
, Sym
*s
)
2911 Sym
*args
, *sa
, *sa1
;
2912 int mstr_allocated
, parlevel
, *mstr
, t
;
2918 /* if symbol is a macro, prepare substitution */
2919 /* if nested substitution, do nothing */
2920 if (sym_find2(*nested_list
, tok
))
2923 /* special macros */
2924 if (tok
== TOK___LINE__
) {
2925 cval
.i
= file
->line_num
;
2926 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
2927 } else if (tok
== TOK___FILE__
) {
2928 cstrval
= file
->filename
;
2930 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2931 } else if (tok
== TOK___DATE__
) {
2932 cstrval
= "Jan 1 2002";
2934 } else if (tok
== TOK___TIME__
) {
2935 cstrval
= "00:00:00";
2938 cstr_cat(&cstr
, cstrval
);
2939 cstr_ccat(&cstr
, '\0');
2941 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2946 if (s
->t
== MACRO_FUNC
) {
2947 /* NOTE: we do not use next_nomacro to avoid eating the
2948 next token. XXX: find better solution */
2952 while (is_space(ch
) || ch
== '\n')
2956 if (t
!= '(') /* no macro subst */
2959 /* argument macro */
2964 /* NOTE: empty args are allowed, except if no args */
2966 /* handle '()' case */
2967 if (!args
&& tok
== ')')
2970 error("macro '%s' used with too many args",
2971 get_tok_str(s
->v
, 0));
2974 /* NOTE: non zero sa->t indicates VA_ARGS */
2975 while ((parlevel
> 0 ||
2977 (tok
!= ',' || sa
->t
))) &&
2981 else if (tok
== ')')
2983 tok_str_add2(&str
, tok
, &tokc
);
2986 tok_str_add(&str
, 0);
2987 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->t
, (int)str
.str
);
2990 /* special case for gcc var args: add an empty
2991 var arg argument if it is omitted */
2992 if (sa
&& sa
->t
&& gnu_ext
)
3002 error("macro '%s' used with too few args",
3003 get_tok_str(s
->v
, 0));
3006 /* now subst each arg */
3007 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3012 tok_str_free((int *)sa
->c
);
3018 sym_push2(nested_list
, s
->v
, 0, 0);
3019 macro_subst(tok_str
, nested_list
, mstr
);
3020 /* pop nested defined symbol */
3022 *nested_list
= sa1
->prev
;
3030 /* do macro substitution of macro_str and add result to
3031 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3032 inside to avoid recursing. */
3033 static void macro_subst(TokenString
*tok_str
,
3034 Sym
**nested_list
, int *macro_str
)
3037 int *saved_macro_ptr
;
3040 saved_macro_ptr
= macro_ptr
;
3041 macro_ptr
= macro_str
;
3042 /* first scan for '##' operator handling */
3043 macro_str1
= macro_twosharps();
3044 macro_ptr
= macro_str1
;
3050 s
= sym_find1(&define_stack
, tok
);
3052 if (macro_subst_tok(tok_str
, nested_list
, s
) != 0)
3056 tok_str_add2(tok_str
, tok
, &tokc
);
3059 macro_ptr
= saved_macro_ptr
;
3060 tok_str_free(macro_str1
);
3063 /* return next token with macro substitution */
3066 Sym
*nested_list
, *s
;
3069 /* special 'ungettok' case for label parsing */
3078 /* if not reading from macro substituted string, then try
3079 to substitute macros */
3080 if (tok
>= TOK_IDENT
) {
3081 s
= sym_find1(&define_stack
, tok
);
3083 /* we have a macro: we try to substitute */
3086 if (macro_subst_tok(&str
, &nested_list
, s
) == 0) {
3087 /* substitution done, NOTE: maybe empty */
3088 tok_str_add(&str
, 0);
3089 macro_ptr
= str
.str
;
3090 macro_ptr_allocated
= str
.str
;
3097 /* end of macro string: free it */
3098 tok_str_free(macro_ptr_allocated
);
3105 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3109 void swap(int *p
, int *q
)
3117 void vsetc(int t
, int r
, CValue
*vc
)
3121 if (vtop
>= vstack
+ VSTACK_SIZE
)
3122 error("memory full");
3123 /* cannot let cpu flags if other instruction are generated. Also
3124 avoid leaving VT_JMP anywhere except on the top of the stack
3125 because it would complicate the code generator. */
3126 if (vtop
>= vstack
) {
3127 v
= vtop
->r
& VT_VALMASK
;
3128 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
3134 vtop
->r2
= VT_CONST
;
3138 /* push integer constant */
3143 vsetc(VT_INT
, VT_CONST
, &cval
);
3146 /* Return a static symbol pointing to a section */
3147 static Sym
*get_sym_ref(int t
, Section
*sec
,
3148 unsigned long offset
, unsigned long size
)
3154 sym
= sym_push1(&global_stack
, v
, t
| VT_STATIC
, 0);
3155 sym
->r
= VT_CONST
| VT_SYM
;
3156 put_extern_sym(sym
, sec
, offset
, size
);
3160 /* push a reference to a section offset by adding a dummy symbol */
3161 static void vpush_ref(int t
, Section
*sec
, unsigned long offset
, unsigned long size
)
3166 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
3167 vtop
->sym
= get_sym_ref(t
, sec
, offset
, size
);
3170 /* define a new external reference to a symbol 'v' of type 'u' */
3171 static Sym
*external_global_sym(int v
, int u
, int r
)
3177 /* push forward reference */
3178 s
= sym_push1(&global_stack
,
3179 v
, u
| VT_EXTERN
, 0);
3180 s
->r
= r
| VT_CONST
| VT_SYM
;
3185 /* define a new external reference to a symbol 'v' of type 'u' */
3186 static Sym
*external_sym(int v
, int u
, int r
)
3192 /* push forward reference */
3193 s
= sym_push(v
, u
| VT_EXTERN
, r
| VT_CONST
| VT_SYM
, 0);
3198 /* push a reference to global symbol v */
3199 static void vpush_global_sym(int t
, int v
)
3204 sym
= external_global_sym(v
, t
, 0);
3206 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
3210 void vset(int t
, int r
, int v
)
3227 void vpushv(SValue
*v
)
3229 if (vtop
>= vstack
+ VSTACK_SIZE
)
3230 error("memory full");
3240 /* save r to the memory stack, and mark it as being free */
3241 void save_reg(int r
)
3243 int l
, saved
, t
, size
, align
;
3246 /* modify all stack values */
3249 for(p
=vstack
;p
<=vtop
;p
++) {
3250 if ((p
->r
& VT_VALMASK
) == r
||
3251 (p
->r2
& VT_VALMASK
) == r
) {
3252 /* must save value on stack if not already done */
3254 /* NOTE: must reload 'r' because r might be equal to r2 */
3255 r
= p
->r
& VT_VALMASK
;
3256 /* store register in the stack */
3258 if ((p
->r
& VT_LVAL
) ||
3259 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
3261 size
= type_size(t
, &align
);
3262 loc
= (loc
- size
) & -align
;
3264 sv
.r
= VT_LOCAL
| VT_LVAL
;
3267 #ifdef TCC_TARGET_I386
3268 /* x86 specific: need to pop fp register ST0 if saved */
3270 o(0xd9dd); /* fstp %st(1) */
3273 /* special long long case */
3274 if ((t
& VT_BTYPE
) == VT_LLONG
) {
3281 /* mark that stack entry as being saved on the stack */
3282 if (p
->r
& VT_LVAL
) {
3283 /* also suppress the bounded flag because the
3284 relocation address of the function was stored in
3286 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
3288 p
->r
= lvalue_type(p
->t
) | VT_LOCAL
;
3296 /* find a free register of class 'rc'. If none, save one register */
3302 /* find a free register */
3303 for(r
=0;r
<NB_REGS
;r
++) {
3304 if (reg_classes
[r
] & rc
) {
3305 for(p
=vstack
;p
<=vtop
;p
++) {
3306 if ((p
->r
& VT_VALMASK
) == r
||
3307 (p
->r2
& VT_VALMASK
) == r
)
3315 /* no register left : free the first one on the stack (VERY
3316 IMPORTANT to start from the bottom to ensure that we don't
3317 spill registers used in gen_opi()) */
3318 for(p
=vstack
;p
<=vtop
;p
++) {
3319 r
= p
->r
& VT_VALMASK
;
3320 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
3322 /* also look at second register (if long long) */
3323 r
= p
->r2
& VT_VALMASK
;
3324 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
3330 /* Should never comes here */
3334 /* save registers up to (vtop - n) stack entry */
3335 void save_regs(int n
)
3340 for(p
= vstack
;p
<= p1
; p
++) {
3341 r
= p
->r
& VT_VALMASK
;
3348 /* move register 's' to 'r', and flush previous value of r to memory
3350 void move_reg(int r
, int s
)
3363 /* get address of vtop (vtop MUST BE an lvalue) */
3366 vtop
->r
&= ~VT_LVAL
;
3367 /* tricky: if saved lvalue, then we can go back to lvalue */
3368 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
3369 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
3372 #ifdef CONFIG_TCC_BCHECK
3373 /* generate lvalue bound code */
3378 vtop
->r
&= ~VT_MUSTBOUND
;
3379 /* if lvalue, then use checking code before dereferencing */
3380 if (vtop
->r
& VT_LVAL
) {
3381 /* if not VT_BOUNDED value, then make one */
3382 if (!(vtop
->r
& VT_BOUNDED
)) {
3383 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
3384 /* must save type because we must set it to int to get pointer */
3389 gen_bounded_ptr_add();
3390 vtop
->r
|= lval_type
;
3393 /* then check for dereferencing */
3394 gen_bounded_ptr_deref();
3399 /* store vtop a register belonging to class 'rc'. lvalues are
3400 converted to values. Cannot be used if cannot be converted to
3401 register value (such as structures). */
3404 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
3405 unsigned long long ll
;
3407 /* NOTE: get_reg can modify vstack[] */
3408 if (vtop
->t
& VT_BITFIELD
) {
3409 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
3410 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3411 /* remove bit field info to avoid loops */
3412 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3413 /* generate shifts */
3414 vpushi(32 - (bit_pos
+ bit_size
));
3416 vpushi(32 - bit_size
);
3417 /* NOTE: transformed to SHR if unsigned */
3421 if (is_float(vtop
->t
) &&
3422 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3425 unsigned long offset
;
3427 /* XXX: unify with initializers handling ? */
3428 /* CPUs usually cannot use float constants, so we store them
3429 generically in data segment */
3430 size
= type_size(vtop
->t
, &align
);
3431 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
3432 data_section
->data_offset
= offset
;
3433 /* XXX: not portable yet */
3434 ptr
= section_ptr_add(data_section
, size
);
3437 ptr
[i
] = vtop
->c
.tab
[i
];
3438 sym
= get_sym_ref(vtop
->t
, data_section
, offset
, size
<< 2);
3439 vtop
->r
|= VT_LVAL
| VT_SYM
;
3443 #ifdef CONFIG_TCC_BCHECK
3444 if (vtop
->r
& VT_MUSTBOUND
)
3448 r
= vtop
->r
& VT_VALMASK
;
3449 /* need to reload if:
3451 - lvalue (need to dereference pointer)
3452 - already a register, but not in the right class */
3453 if (r
>= VT_CONST
||
3454 (vtop
->r
& VT_LVAL
) ||
3455 !(reg_classes
[r
] & rc
) ||
3456 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
3457 !(reg_classes
[vtop
->r2
] & rc
))) {
3459 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
3460 /* two register type load : expand to two words
3462 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3465 vtop
->c
.ui
= ll
; /* first word */
3467 vtop
->r
= r
; /* save register value */
3468 vpushi(ll
>> 32); /* second word */
3469 } else if (r
>= VT_CONST
||
3470 (vtop
->r
& VT_LVAL
)) {
3471 /* load from memory */
3474 vtop
[-1].r
= r
; /* save register value */
3475 /* increment pointer to get second word */
3482 /* move registers */
3485 vtop
[-1].r
= r
; /* save register value */
3486 vtop
->r
= vtop
[-1].r2
;
3488 /* allocate second register */
3495 /* write second register */
3497 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
3499 /* lvalue of scalar type : need to use lvalue type
3500 because of possible cast */
3503 /* compute memory access type */
3504 if (vtop
->r
& VT_LVAL_BYTE
)
3506 else if (vtop
->r
& VT_LVAL_SHORT
)
3508 if (vtop
->r
& VT_LVAL_UNSIGNED
)
3512 /* restore wanted type */
3515 /* one register type load */
3524 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3525 void gv2(int rc1
, int rc2
)
3529 /* generate more generic register first. But VT_JMP or VT_CMP
3530 values must be generated first in all cases to avoid possible
3532 v
= vtop
[0].r
& VT_VALMASK
;
3533 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
3538 /* test if reload is needed for first register */
3539 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
3549 /* test if reload is needed for first register */
3550 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
3556 /* expand long long on stack in two int registers */
3561 u
= vtop
->t
& VT_UNSIGNED
;
3564 vtop
[0].r
= vtop
[-1].r2
;
3565 vtop
[0].r2
= VT_CONST
;
3566 vtop
[-1].r2
= VT_CONST
;
3567 vtop
[0].t
= VT_INT
| u
;
3568 vtop
[-1].t
= VT_INT
| u
;
3571 /* build a long long from two ints */
3574 gv2(RC_INT
, RC_INT
);
3575 vtop
[-1].r2
= vtop
[0].r
;
3580 /* rotate n first stack elements to the bottom */
3587 for(i
=-n
+1;i
!=0;i
++)
3588 vtop
[i
] = vtop
[i
+1];
3592 /* pop stack value */
3596 v
= vtop
->r
& VT_VALMASK
;
3597 #ifdef TCC_TARGET_I386
3598 /* for x86, we need to pop the FP stack */
3600 o(0xd9dd); /* fstp %st(1) */
3603 if (v
== VT_JMP
|| v
== VT_JMPI
) {
3604 /* need to put correct jump if && or || without test */
3610 /* convert stack entry to register and duplicate its value in another
3618 if ((t
& VT_BTYPE
) == VT_LLONG
) {
3625 /* stack: H L L1 H1 */
3633 /* duplicate value */
3644 load(r1
, &sv
); /* move r to r1 */
3646 /* duplicates value */
3651 /* generate CPU independent (unsigned) long long operations */
3652 void gen_opl(int op
)
3654 int t
, a
, b
, op1
, c
, i
;
3662 func
= TOK___divdi3
;
3665 func
= TOK___udivdi3
;
3668 func
= TOK___moddi3
;
3671 func
= TOK___umoddi3
;
3673 /* call generic long long function */
3674 gfunc_start(&gf
, FUNC_CDECL
);
3677 vpush_global_sym(func_old_type
, func
);
3681 vtop
->r2
= REG_LRET
;
3694 /* stack: L1 H1 L2 H2 */
3699 vtop
[-2] = vtop
[-3];
3702 /* stack: H1 H2 L1 L2 */
3708 /* stack: H1 H2 L1 L2 ML MH */
3711 /* stack: ML MH H1 H2 L1 L2 */
3715 /* stack: ML MH H1 L2 H2 L1 */
3720 /* stack: ML MH M1 M2 */
3723 } else if (op
== '+' || op
== '-') {
3724 /* XXX: add non carry method too (for MIPS or alpha) */
3730 /* stack: H1 H2 (L1 op L2) */
3733 gen_op(op1
+ 1); /* TOK_xxxC2 */
3736 /* stack: H1 H2 (L1 op L2) */
3739 /* stack: (L1 op L2) H1 H2 */
3741 /* stack: (L1 op L2) (H1 op H2) */
3749 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3754 /* stack: L H shift */
3756 /* constant: simpler */
3757 /* NOTE: all comments are for SHL. the other cases are
3758 done by swaping words */
3769 if (op
!= TOK_SAR
) {
3802 /* XXX: should provide a faster fallback on x86 ? */
3805 func
= TOK___sardi3
;
3808 func
= TOK___shrdi3
;
3811 func
= TOK___shldi3
;
3817 /* compare operations */
3823 /* stack: L1 H1 L2 H2 */
3825 vtop
[-1] = vtop
[-2];
3827 /* stack: L1 L2 H1 H2 */
3830 /* when values are equal, we need to compare low words. since
3831 the jump is inverted, we invert the test too. */
3834 else if (op1
== TOK_GT
)
3836 else if (op1
== TOK_ULT
)
3838 else if (op1
== TOK_UGT
)
3843 if (op1
!= TOK_NE
) {
3847 /* generate non equal test */
3848 /* XXX: NOT PORTABLE yet */
3852 #ifdef TCC_TARGET_I386
3853 b
= psym(0x850f, 0);
3855 error("not implemented");
3863 vset(VT_INT
, VT_JMPI
, a
);
3868 /* handle integer constant optimizations and various machine
3870 void gen_opic(int op
)
3877 /* currently, we cannot do computations with forward symbols */
3878 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3879 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3883 case '+': v1
->c
.i
+= fc
; break;
3884 case '-': v1
->c
.i
-= fc
; break;
3885 case '&': v1
->c
.i
&= fc
; break;
3886 case '^': v1
->c
.i
^= fc
; break;
3887 case '|': v1
->c
.i
|= fc
; break;
3888 case '*': v1
->c
.i
*= fc
; break;
3895 /* if division by zero, generate explicit division */
3898 error("division by zero in constant");
3902 default: v1
->c
.i
/= fc
; break;
3903 case '%': v1
->c
.i
%= fc
; break;
3904 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3905 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3908 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3909 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3910 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3912 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3913 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3914 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3915 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3916 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3917 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3918 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3919 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3920 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3921 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3923 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3924 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3930 /* if commutative ops, put c2 as constant */
3931 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3932 op
== '|' || op
== '*')) {
3937 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3940 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3941 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3947 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3948 /* try to use shifts instead of muls or divs */
3949 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3958 else if (op
== TOK_PDIV
)
3964 } else if (c2
&& (op
== '+' || op
== '-') &&
3965 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
3966 (VT_CONST
| VT_SYM
)) {
3967 /* symbol + constant case */
3974 /* call low level op generator */
3980 /* generate a floating point operation with constant propagation */
3981 void gen_opif(int op
)
3989 /* currently, we cannot do computations with forward symbols */
3990 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3991 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3993 if (v1
->t
== VT_FLOAT
) {
3996 } else if (v1
->t
== VT_DOUBLE
) {
4004 /* NOTE: we only do constant propagation if finite number (not
4005 NaN or infinity) (ANSI spec) */
4006 if (!ieee_finite(f1
) || !ieee_finite(f2
))
4010 case '+': f1
+= f2
; break;
4011 case '-': f1
-= f2
; break;
4012 case '*': f1
*= f2
; break;
4016 error("division by zero in constant");
4021 /* XXX: also handles tests ? */
4025 /* XXX: overflow test ? */
4026 if (v1
->t
== VT_FLOAT
) {
4028 } else if (v1
->t
== VT_DOUBLE
) {
4040 int pointed_size(int t
)
4042 return type_size(pointed_type(t
), &t
);
4046 void check_pointer_types(SValue
*p1
, SValue
*p2
)
4048 char buf1
[256], buf2
[256];
4052 if (!is_compatible_types(t1
, t2
)) {
4053 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
4054 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
4055 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
4060 /* generic gen_op: handles types problems */
4063 int u
, t1
, t2
, bt1
, bt2
, t
;
4067 bt1
= t1
& VT_BTYPE
;
4068 bt2
= t2
& VT_BTYPE
;
4070 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
4071 /* at least one operand is a pointer */
4072 /* relationnal op: must be both pointers */
4073 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4074 // check_pointer_types(vtop, vtop - 1);
4075 /* pointers are handled are unsigned */
4076 t
= VT_INT
| VT_UNSIGNED
;
4079 /* if both pointers, then it must be the '-' op */
4080 if ((t1
& VT_BTYPE
) == VT_PTR
&&
4081 (t2
& VT_BTYPE
) == VT_PTR
) {
4083 error("cannot use pointers here");
4084 // check_pointer_types(vtop - 1, vtop);
4085 /* XXX: check that types are compatible */
4086 u
= pointed_size(t1
);
4088 /* set to integer type */
4093 /* exactly one pointer : must be '+' or '-'. */
4094 if (op
!= '-' && op
!= '+')
4095 error("cannot use pointers here");
4096 /* Put pointer as first operand */
4097 if ((t2
& VT_BTYPE
) == VT_PTR
) {
4101 /* XXX: cast to int ? (long long case) */
4102 vpushi(pointed_size(vtop
[-1].t
));
4104 #ifdef CONFIG_TCC_BCHECK
4105 /* if evaluating constant expression, no code should be
4106 generated, so no bound check */
4107 if (do_bounds_check
&& !const_wanted
) {
4108 /* if bounded pointers, we generate a special code to
4115 gen_bounded_ptr_add();
4121 /* put again type if gen_opic() swaped operands */
4124 } else if (is_float(bt1
) || is_float(bt2
)) {
4125 /* compute bigger type and do implicit casts */
4126 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
4128 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
4133 /* floats can only be used for a few operations */
4134 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
4135 (op
< TOK_ULT
|| op
> TOK_GT
))
4136 error("invalid operands for binary operation");
4138 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
4139 /* cast to biggest op */
4141 /* convert to unsigned if it does not fit in a long long */
4142 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4143 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4147 /* integer operations */
4149 /* convert to unsigned if it does not fit in an integer */
4150 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4151 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4154 /* XXX: currently, some unsigned operations are explicit, so
4155 we modify them here */
4156 if (t
& VT_UNSIGNED
) {
4163 else if (op
== TOK_LT
)
4165 else if (op
== TOK_GT
)
4167 else if (op
== TOK_LE
)
4169 else if (op
== TOK_GE
)
4175 /* special case for shifts and long long: we keep the shift as
4177 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
4183 else if ((t
& VT_BTYPE
) == VT_LLONG
)
4187 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4188 /* relationnal op: the result is an int */
4196 /* generic itof for unsigned long long case */
4197 void gen_cvt_itof1(int t
)
4201 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
4202 (VT_LLONG
| VT_UNSIGNED
)) {
4204 gfunc_start(&gf
, FUNC_CDECL
);
4207 vpush_global_sym(func_old_type
, TOK___ulltof
);
4208 else if (t
== VT_DOUBLE
)
4209 vpush_global_sym(func_old_type
, TOK___ulltod
);
4211 vpush_global_sym(func_old_type
, TOK___ulltold
);
4220 /* generic ftoi for unsigned long long case */
4221 void gen_cvt_ftoi1(int t
)
4226 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
4227 /* not handled natively */
4228 gfunc_start(&gf
, FUNC_CDECL
);
4229 st
= vtop
->t
& VT_BTYPE
;
4232 vpush_global_sym(func_old_type
, TOK___fixunssfdi
);
4233 else if (st
== VT_DOUBLE
)
4234 vpush_global_sym(func_old_type
, TOK___fixunsdfdi
);
4236 vpush_global_sym(func_old_type
, TOK___fixunsxfdi
);
4240 vtop
->r2
= REG_LRET
;
4246 /* force char or short cast */
4247 void force_charshort_cast(int t
)
4251 /* XXX: add optimization if lvalue : just change type and offset */
4256 if (t
& VT_UNSIGNED
) {
4257 vpushi((1 << bits
) - 1);
4268 /* cast 'vtop' to 't' type */
4269 void gen_cast(int t
)
4271 int sbt
, dbt
, sf
, df
, c
;
4273 /* special delayed cast for char/short */
4274 /* XXX: in some cases (multiple cascaded casts), it may still
4276 if (vtop
->r
& VT_MUSTCAST
) {
4277 vtop
->r
&= ~VT_MUSTCAST
;
4278 force_charshort_cast(vtop
->t
);
4281 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
4282 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
4287 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4289 /* convert from fp to fp */
4291 /* constant case: we can do it now */
4292 /* XXX: in ISOC, cannot do it if error in convert */
4293 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
4294 vtop
->c
.f
= (float)vtop
->c
.d
;
4295 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
4296 vtop
->c
.f
= (float)vtop
->c
.ld
;
4297 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
4298 vtop
->c
.d
= (double)vtop
->c
.f
;
4299 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
4300 vtop
->c
.d
= (double)vtop
->c
.ld
;
4301 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
4302 vtop
->c
.ld
= (long double)vtop
->c
.f
;
4303 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
4304 vtop
->c
.ld
= (long double)vtop
->c
.d
;
4306 /* non constant case: generate code */
4310 /* convert int to fp */
4313 case VT_LLONG
| VT_UNSIGNED
:
4315 /* XXX: add const cases for long long */
4317 case VT_INT
| VT_UNSIGNED
:
4319 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
4320 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
4321 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
4326 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
4327 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
4328 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
4337 /* convert fp to int */
4338 /* we handle char/short/etc... with generic code */
4339 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
4340 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
4345 case VT_LLONG
| VT_UNSIGNED
:
4347 /* XXX: add const cases for long long */
4349 case VT_INT
| VT_UNSIGNED
:
4351 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4352 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4353 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4359 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4360 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4361 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4369 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
4370 /* additionnal cast for char/short/bool... */
4374 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
4375 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
4376 /* scalar to long long */
4378 if (sbt
== (VT_INT
| VT_UNSIGNED
))
4379 vtop
->c
.ll
= vtop
->c
.ui
;
4381 vtop
->c
.ll
= vtop
->c
.i
;
4383 /* machine independant conversion */
4385 /* generate high word */
4386 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
4394 /* patch second register */
4395 vtop
[-1].r2
= vtop
->r
;
4399 } else if (dbt
== VT_BOOL
) {
4400 /* scalar to bool */
4403 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
4404 (dbt
& VT_BTYPE
) == VT_SHORT
) {
4405 force_charshort_cast(t
);
4406 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
4408 if (sbt
== VT_LLONG
) {
4409 /* from long long: just take low order word */
4413 /* if lvalue and single word type, nothing to do because
4414 the lvalue already contains the real type size (see
4415 VT_LVAL_xxx constants) */
4421 /* return type size. Put alignment at 'a' */
4422 int type_size(int t
, int *a
)
4428 if (bt
== VT_STRUCT
) {
4430 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4431 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
4433 } else if (bt
== VT_PTR
) {
4435 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4436 return type_size(s
->t
, a
) * s
->c
;
4441 } else if (bt
== VT_LDOUBLE
) {
4443 return LDOUBLE_SIZE
;
4444 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
4447 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
4450 } else if (bt
== VT_SHORT
) {
4454 /* char, void, function, _Bool */
4460 /* return the pointed type of t */
4461 int pointed_type(int t
)
4464 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4465 return s
->t
| (t
& ~VT_TYPE
);
4468 int mk_pointer(int t
)
4472 sym_push(p
, t
, 0, -1);
4473 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
4476 int is_compatible_types(int t1
, int t2
)
4483 bt1
= t1
& VT_BTYPE
;
4484 bt2
= t2
& VT_BTYPE
;
4485 if (bt1
== VT_PTR
) {
4486 t1
= pointed_type(t1
);
4487 /* if function, then convert implicitely to function pointer */
4488 if (bt2
!= VT_FUNC
) {
4491 t2
= pointed_type(t2
);
4493 /* void matches everything */
4496 if (t1
== VT_VOID
|| t2
== VT_VOID
)
4498 return is_compatible_types(t1
, t2
);
4499 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4501 } else if (bt1
== VT_FUNC
) {
4504 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
4505 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
4506 if (!is_compatible_types(s1
->t
, s2
->t
))
4508 /* XXX: not complete */
4509 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
4513 while (s1
!= NULL
) {
4516 if (!is_compatible_types(s1
->t
, s2
->t
))
4525 /* XXX: not complete */
4530 /* print a type. If 'varstr' is not NULL, then the variable is also
4531 printed in the type */
4533 /* XXX: add array and function pointers */
4534 void type_to_str(char *buf
, int buf_size
,
4535 int t
, const char *varstr
)
4545 if (t
& VT_UNSIGNED
)
4546 pstrcat(buf
, buf_size
, "unsigned ");
4576 tstr
= "long double";
4578 pstrcat(buf
, buf_size
, tstr
);
4582 if (bt
== VT_STRUCT
)
4586 pstrcat(buf
, buf_size
, tstr
);
4587 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
4588 if (v
>= SYM_FIRST_ANOM
)
4589 pstrcat(buf
, buf_size
, "<anonymous>");
4591 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
4594 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4595 type_to_str(buf
, buf_size
, s
->t
, varstr
);
4596 pstrcat(buf
, buf_size
, "(");
4598 while (sa
!= NULL
) {
4599 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
4600 pstrcat(buf
, buf_size
, buf1
);
4603 pstrcat(buf
, buf_size
, ", ");
4605 pstrcat(buf
, buf_size
, ")");
4608 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4609 pstrcpy(buf1
, sizeof(buf1
), "*");
4611 pstrcat(buf1
, sizeof(buf1
), varstr
);
4612 type_to_str(buf
, buf_size
, s
->t
, buf1
);
4616 pstrcat(buf
, buf_size
, " ");
4617 pstrcat(buf
, buf_size
, varstr
);
4622 /* verify type compatibility to store vtop in 'dt' type, and generate
4624 void gen_assign_cast(int dt
)
4627 char buf1
[256], buf2
[256];
4629 st
= vtop
->t
; /* source type */
4630 if ((dt
& VT_BTYPE
) == VT_PTR
) {
4631 /* special cases for pointers */
4632 /* a function is implicitely a function pointer */
4633 if ((st
& VT_BTYPE
) == VT_FUNC
) {
4634 if (!is_compatible_types(pointed_type(dt
), st
))
4639 /* '0' can also be a pointer */
4640 if ((st
& VT_BTYPE
) == VT_INT
&&
4641 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
4645 if (!is_compatible_types(dt
, st
)) {
4647 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
4648 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
4649 error("cannot cast '%s' to '%s'", buf1
, buf2
);
4655 /* store vtop in lvalue pushed on stack */
4658 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
4662 sbt
= vtop
->t
& VT_BTYPE
;
4663 dbt
= ft
& VT_BTYPE
;
4664 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
4665 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
4666 /* optimize char/short casts */
4667 delayed_cast
= VT_MUSTCAST
;
4668 vtop
->t
= ft
& VT_TYPE
;
4671 gen_assign_cast(ft
& VT_TYPE
);
4674 if (sbt
== VT_STRUCT
) {
4675 /* if structure, only generate pointer */
4676 /* structure assignment : generate memcpy */
4677 /* XXX: optimize if small size */
4679 gfunc_start(&gf
, FUNC_CDECL
);
4681 size
= type_size(vtop
->t
, &align
);
4695 vpush_global_sym(func_old_type
, TOK_memcpy
);
4697 /* leave source on stack */
4698 } else if (ft
& VT_BITFIELD
) {
4699 /* bitfield store handling */
4700 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
4701 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4702 /* remove bit field info to avoid loops */
4703 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4705 /* duplicate destination */
4707 vtop
[-1] = vtop
[-2];
4709 /* mask and shift source */
4710 vpushi((1 << bit_size
) - 1);
4714 /* load destination, mask and or with source */
4716 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4722 #ifdef CONFIG_TCC_BCHECK
4723 /* bound check case */
4724 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4733 r
= gv(rc
); /* generate value */
4734 /* if lvalue was saved on stack, must read it */
4735 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4737 t
= get_reg(RC_INT
);
4739 sv
.r
= VT_LOCAL
| VT_LVAL
;
4740 sv
.c
.ul
= vtop
[-1].c
.ul
;
4742 vtop
[-1].r
= t
| VT_LVAL
;
4745 /* two word case handling : store second register at word + 4 */
4746 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4748 /* convert to int to increment easily */
4755 /* XXX: it works because r2 is spilled last ! */
4756 store(vtop
->r2
, vtop
- 1);
4759 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4760 vtop
->r
|= delayed_cast
;
4764 /* post defines POST/PRE add. c is the token ++ or -- */
4765 void inc(int post
, int c
)
4768 vdup(); /* save lvalue */
4770 gv_dup(); /* duplicate value */
4775 vpushi(c
- TOK_MID
);
4777 vstore(); /* store value */
4779 vpop(); /* if post op, return saved value */
4782 /* Parse GNUC __attribute__ extension. Currently, the following
4783 extensions are recognized:
4784 - aligned(n) : set data/function alignment.
4785 - section(x) : generate data/code in this section.
4786 - unused : currently ignored, but may be used someday.
4788 void parse_attribute(AttributeDef
*ad
)
4795 while (tok
!= ')') {
4796 if (tok
< TOK_IDENT
)
4797 expect("attribute name");
4802 case TOK___SECTION__
:
4805 expect("section name");
4806 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
4811 case TOK___ALIGNED__
:
4814 if (n
<= 0 || (n
& (n
- 1)) != 0)
4815 error("alignment must be a positive power of two");
4820 case TOK___UNUSED__
:
4821 /* currently, no need to handle it because tcc does not
4822 track unused objects */
4825 case TOK___NORETURN__
:
4826 /* currently, no need to handle it because tcc does not
4827 track unused objects */
4832 ad
->func_call
= FUNC_CDECL
;
4836 case TOK___STDCALL__
:
4837 ad
->func_call
= FUNC_STDCALL
;
4840 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4841 /* skip parameters */
4842 /* XXX: skip parenthesis too */
4845 while (tok
!= ')' && tok
!= -1)
4859 /* enum/struct/union declaration */
4860 int struct_decl(int u
)
4862 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4863 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4867 a
= tok
; /* save decl type */
4872 /* struct already defined ? return it */
4873 /* XXX: check consistency */
4874 s
= sym_find(v
| SYM_STRUCT
);
4877 error("invalid type");
4883 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4884 /* put struct/union/enum name in type */
4886 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4891 error("struct/union/enum already defined");
4892 /* cannot be empty */
4899 if (a
== TOK_ENUM
) {
4906 /* enum symbols have static storage */
4907 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4912 parse_btype(&b
, &ad
);
4917 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4918 if ((t
& VT_BTYPE
) == VT_FUNC
||
4919 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4920 error("invalid type for '%s'",
4921 get_tok_str(v
, NULL
));
4927 bit_size
= expr_const();
4928 /* XXX: handle v = 0 case for messages */
4930 error("negative width in bit-field '%s'",
4931 get_tok_str(v
, NULL
));
4932 if (v
&& bit_size
== 0)
4933 error("zero width for bit-field '%s'",
4934 get_tok_str(v
, NULL
));
4936 size
= type_size(t
, &align
);
4938 if (bit_size
>= 0) {
4943 error("bitfields must have scalar type");
4945 if (bit_size
> bsize
) {
4946 error("width of '%s' exceeds its type",
4947 get_tok_str(v
, NULL
));
4948 } else if (bit_size
== bsize
) {
4949 /* no need for bit fields */
4951 } else if (bit_size
== 0) {
4952 /* XXX: what to do if only padding in a
4954 /* zero size: means to pad */
4958 /* we do not have enough room ? */
4959 if ((bit_pos
+ bit_size
) > bsize
)
4962 /* XXX: handle LSB first */
4964 (bit_pos
<< VT_STRUCT_SHIFT
) |
4965 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4966 bit_pos
+= bit_size
;
4972 /* add new memory data only if starting
4974 if (lbit_pos
== 0) {
4975 if (a
== TOK_STRUCT
) {
4976 c
= (c
+ align
- 1) & -align
;
4984 if (align
> maxalign
)
4988 printf("add field %s offset=%d",
4989 get_tok_str(v
, NULL
), offset
);
4990 if (t
& VT_BITFIELD
) {
4991 printf(" pos=%d size=%d",
4992 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4993 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4997 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
5001 if (tok
== ';' || tok
== -1)
5011 /* size for struct/union, dummy for enum */
5012 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
5017 /* return 0 if no type declaration. otherwise, return the basic type
5020 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
5022 int t
, u
, type_found
;
5025 memset(ad
, 0, sizeof(AttributeDef
));
5036 if ((t
& VT_BTYPE
) != 0)
5037 error("too many basic types");
5051 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
5052 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5053 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
5054 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
5068 if ((t
& VT_BTYPE
) == VT_LONG
) {
5069 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5076 u
= struct_decl(VT_ENUM
);
5080 u
= struct_decl(VT_STRUCT
);
5083 /* type modifiers */
5088 case TOK___SIGNED__
:
5091 case TOK___INLINE__
:
5113 /* GNUC attribute */
5114 case TOK___ATTRIBUTE__
:
5115 parse_attribute(ad
);
5119 if (!s
|| !(s
->t
& VT_TYPEDEF
))
5121 t
|= (s
->t
& ~VT_TYPEDEF
);
5128 /* long is never used as type */
5129 if ((t
& VT_BTYPE
) == VT_LONG
)
5130 t
= (t
& ~VT_BTYPE
) | VT_INT
;
5135 int post_type(int t
, AttributeDef
*ad
)
5137 int p
, n
, pt
, l
, t1
;
5138 Sym
**plast
, *s
, *first
;
5142 /* function declaration */
5147 while (tok
!= ')') {
5148 /* read param name and compute offset */
5149 if (l
!= FUNC_OLD
) {
5150 if (!parse_btype(&pt
, &ad1
)) {
5152 error("invalid type");
5159 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5161 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
5162 if ((pt
& VT_BTYPE
) == VT_VOID
)
5163 error("parameter declared as void");
5170 /* array must be transformed to pointer according to ANSI C */
5172 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
5177 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5184 /* if no parameters, then old type prototype */
5188 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5189 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
5190 /* we push a anonymous symbol which will contain the function prototype */
5192 s
= sym_push(p
, t
, ad
->func_call
, l
);
5194 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
5195 } else if (tok
== '[') {
5196 /* array definition */
5202 error("invalid array size");
5205 /* parse next post type */
5206 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5207 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
5209 /* we push a anonymous symbol which will contain the array
5212 sym_push(p
, t
, 0, n
);
5213 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
5218 /* Read a type declaration (except basic type), and return the
5219 type. 'td' is a bitmask indicating which kind of type decl is
5220 expected. 't' should contain the basic type. 'ad' is the attribute
5221 definition of the basic type. It can be modified by type_decl(). */
5222 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
5227 while (tok
== '*') {
5229 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
5234 /* recursive type */
5235 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5238 /* XXX: this is not correct to modify 'ad' at this point, but
5239 the syntax is not clear */
5240 if (tok
== TOK___ATTRIBUTE__
)
5241 parse_attribute(ad
);
5242 u
= type_decl(ad
, v
, 0, td
);
5246 /* type identifier */
5247 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
5251 if (!(td
& TYPE_ABSTRACT
))
5252 expect("identifier");
5256 /* append t at the end of u */
5257 t
= post_type(t
, ad
);
5258 if (tok
== TOK___ATTRIBUTE__
)
5259 parse_attribute(ad
);
5264 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
5274 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5275 static int lvalue_type(int t
)
5282 else if (bt
== VT_SHORT
)
5286 if (t
& VT_UNSIGNED
)
5287 r
|= VT_LVAL_UNSIGNED
;
5291 /* indirection with full error checking and bound check */
5292 static void indir(void)
5294 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
5296 if (vtop
->r
& VT_LVAL
)
5298 vtop
->t
= pointed_type(vtop
->t
);
5299 /* an array is never an lvalue */
5300 if (!(vtop
->t
& VT_ARRAY
)) {
5301 vtop
->r
|= lvalue_type(vtop
->t
);
5302 /* if bound checking, the referenced pointer must be checked */
5303 if (do_bounds_check
)
5304 vtop
->r
|= VT_MUSTBOUND
;
5308 /* pass a parameter to a function and do type checking and casting */
5309 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
5312 func_type
= func
->c
;
5313 if (func_type
== FUNC_OLD
||
5314 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5315 /* default casting : only need to convert float to double */
5316 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
5317 gen_cast(VT_DOUBLE
);
5318 } else if (arg
== NULL
) {
5319 error("too many arguments to function");
5321 gen_assign_cast(arg
->t
);
5328 int n
, t
, ft
, align
, size
, r
;
5333 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
5336 } else if (tok
== TOK_CUINT
) {
5337 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
5339 } else if (tok
== TOK_CLLONG
) {
5340 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
5342 } else if (tok
== TOK_CULLONG
) {
5343 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
5345 } else if (tok
== TOK_CFLOAT
) {
5346 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
5348 } else if (tok
== TOK_CDOUBLE
) {
5349 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
5351 } else if (tok
== TOK_CLDOUBLE
) {
5352 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
5354 } else if (tok
== TOK___FUNC__
|| (tok
== TOK___FUNCTION__
&& gnu_ext
)) {
5357 /* special function name identifier */
5359 len
= strlen(funcname
) + 1;
5360 /* generate char[len] type */
5361 t
= VT_ARRAY
| mk_pointer(VT_BYTE
);
5362 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5364 vpush_ref(t
, data_section
, data_section
->data_offset
, len
);
5365 ptr
= section_ptr_add(data_section
, len
);
5366 memcpy(ptr
, funcname
, len
);
5368 } else if (tok
== TOK_LSTR
) {
5371 } else if (tok
== TOK_STR
) {
5372 /* string parsing */
5375 t
= VT_ARRAY
| mk_pointer(t
);
5376 memset(&ad
, 0, sizeof(AttributeDef
));
5377 decl_initializer_alloc(t
, &ad
, VT_CONST
, 2, 0, 0);
5383 if (parse_btype(&t
, &ad
)) {
5384 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
5386 /* check ISOC99 compound literal */
5388 /* data is allocated locally by default */
5393 /* all except arrays are lvalues */
5394 if (!(ft
& VT_ARRAY
))
5395 r
|= lvalue_type(ft
);
5396 memset(&ad
, 0, sizeof(AttributeDef
));
5397 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
5406 } else if (t
== '*') {
5409 } else if (t
== '&') {
5411 /* functions names must be treated as function pointers,
5412 except for unary '&' and sizeof. Since we consider that
5413 functions are not lvalues, we only have to handle it
5414 there and in function calls. */
5415 /* arrays can also be used although they are not lvalues */
5416 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
5417 !(vtop
->t
& VT_ARRAY
))
5419 vtop
->t
= mk_pointer(vtop
->t
);
5424 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
5425 vtop
->c
.i
= !vtop
->c
.i
;
5426 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
5427 vtop
->c
.i
= vtop
->c
.i
^ 1;
5429 vset(VT_INT
, VT_JMP
, gtst(1, 0));
5437 /* in order to force cast, we add zero */
5439 if ((vtop
->t
& VT_BTYPE
) == VT_PTR
)
5440 error("pointer not accepted for unary plus");
5444 if (t
== TOK_SIZEOF
) {
5447 if (parse_btype(&t
, &ad
)) {
5448 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
5450 /* XXX: some code could be generated: add eval
5462 vpushi(type_size(t
, &t
));
5464 if (t
== TOK_INC
|| t
== TOK_DEC
) {
5467 } else if (t
== '-') {
5474 expect("identifier");
5478 error("'%s' undeclared", get_tok_str(t
, NULL
));
5479 /* for simple function calls, we tolerate undeclared
5480 external reference to int() function */
5481 s
= external_global_sym(t
, func_old_type
, 0);
5483 vset(s
->t
, s
->r
, s
->c
);
5484 /* if forward reference, we must point to s */
5485 if (vtop
->r
& VT_SYM
) {
5492 /* post operations */
5494 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
5497 } else if (tok
== '.' || tok
== TOK_ARROW
) {
5499 if (tok
== TOK_ARROW
)
5504 /* expect pointer on structure */
5505 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
5506 expect("struct or union");
5507 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5510 while ((s
= s
->next
) != NULL
) {
5515 error("field not found");
5516 /* add field offset to pointer */
5517 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
5520 /* change type to field type, and set to lvalue */
5522 /* an array is never an lvalue */
5523 if (!(vtop
->t
& VT_ARRAY
)) {
5524 vtop
->r
|= lvalue_type(vtop
->t
);
5525 /* if bound checking, the referenced pointer must be checked */
5526 if (do_bounds_check
)
5527 vtop
->r
|= VT_MUSTBOUND
;
5530 } else if (tok
== '[') {
5536 } else if (tok
== '(') {
5541 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
5542 /* pointer test (no array accepted) */
5543 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
5544 vtop
->t
= pointed_type(vtop
->t
);
5545 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
5549 expect("function pointer");
5552 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
5554 /* get return type */
5555 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
5556 save_regs(0); /* save used temporary registers */
5557 gfunc_start(&gf
, s
->r
);
5559 sa
= s
->next
; /* first parameter */
5560 #ifdef INVERT_FUNC_PARAMS
5564 ParseState saved_parse_state
;
5567 /* read each argument and store it on a stack */
5573 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
5577 else if (tok
== ')')
5579 tok_str_add_tok(&str
);
5582 tok_str_add(&str
, -1); /* end of file added */
5583 tok_str_add(&str
, 0);
5584 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
5585 s1
->next
= sa
; /* add reference to argument */
5594 /* now generate code in reverse order by reading the stack */
5595 save_parse_state(&saved_parse_state
);
5597 macro_ptr
= (int *)args
->c
;
5601 expect("',' or ')'");
5602 gfunc_param_typed(&gf
, s
, args
->next
);
5604 tok_str_free((int *)args
->c
);
5608 restore_parse_state(&saved_parse_state
);
5611 /* compute first implicit argument if a structure is returned */
5612 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
5613 /* get some space for the returned structure */
5614 size
= type_size(s
->t
, &align
);
5615 loc
= (loc
- size
) & -align
;
5617 ret
.r
= VT_LOCAL
| VT_LVAL
;
5618 /* pass it as 'int' to avoid structure arg passing
5620 vset(VT_INT
, VT_LOCAL
, loc
);
5626 /* return in register */
5627 if (is_float(ret
.t
)) {
5630 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
5636 #ifndef INVERT_FUNC_PARAMS
5640 gfunc_param_typed(&gf
, s
, sa
);
5650 error("too few arguments to function");
5654 vsetc(ret
.t
, ret
.r
, &ret
.c
);
5668 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
5669 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
5670 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
5693 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
5694 (l
== 1 && (tok
== '+' || tok
== '-')) ||
5695 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
5696 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
5697 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
5698 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
5699 (l
== 5 && tok
== '&') ||
5700 (l
== 6 && tok
== '^') ||
5701 (l
== 7 && tok
== '|') ||
5702 (l
== 8 && tok
== TOK_LAND
) ||
5703 (l
== 9 && tok
== TOK_LOR
)) {
5712 /* only used if non constant */
5720 if (tok
!= TOK_LAND
) {
5723 vset(VT_INT
, VT_JMPI
, t
);
5740 if (tok
!= TOK_LOR
) {
5743 vset(VT_INT
, VT_JMP
, t
);
5753 /* XXX: better constant handling */
5756 int tt
, u
, r1
, r2
, rc
, t1
, t2
, t
, bt1
, bt2
;
5778 save_regs(1); /* we need to save all registers here except
5779 at the top because it is a branch point */
5783 bt1
= t1
& VT_BTYPE
;
5784 sv
= *vtop
; /* save value to handle it later */
5785 vtop
--; /* no vpop so that FP stack is not flushed */
5793 bt2
= t2
& VT_BTYPE
;
5794 /* cast operands to correct type according to ISOC rules */
5795 if (is_float(bt1
) || is_float(bt2
)) {
5796 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5798 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5803 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5804 /* cast to biggest op */
5806 /* convert to unsigned if it does not fit in a long long */
5807 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5808 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5810 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5811 /* XXX: test pointer compatibility */
5813 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
5814 /* XXX: test structure compatibility */
5816 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
5817 /* NOTE: as an extension, we accept void on only one side */
5820 /* integer operations */
5822 /* convert to unsigned if it does not fit in an integer */
5823 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5824 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5828 /* now we convert second operand */
5833 } else if ((t
& VT_BTYPE
) == VT_LLONG
) {
5834 /* for long longs, we use fixed registers to avoid having
5835 to handle a complicated move */
5839 /* this is horrible, but we must also convert first
5843 /* put again first value and cast it */
5865 /* parse a constant expression and return value in vtop. */
5866 static void expr_const1(void)
5875 /* parse an integer constant and return its value. */
5876 static int expr_const(void)
5880 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
5881 expect("constant expression");
5887 /* return the label token if current token is a label, otherwise
5894 /* fast test first */
5895 if (tok
< TOK_UIDENT
)
5897 /* no need to save tokc since we expect an identifier */
5905 /* XXX: may not work in all cases (macros ?) */
5914 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
5919 /* generate line number info */
5921 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
5922 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
5924 last_line_num
= file
->line_num
;
5927 if (tok
== TOK_IF
) {
5934 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5936 if (c
== TOK_ELSE
) {
5940 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5941 gsym(d
); /* patch else jmp */
5944 } else if (tok
== TOK_WHILE
) {
5952 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5956 } else if (tok
== '{') {
5959 s
= local_stack
.top
;
5960 while (tok
!= '}') {
5963 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5965 /* pop locally defined symbols */
5966 sym_pop(&local_stack
, s
);
5968 } else if (tok
== TOK_RETURN
) {
5972 gen_assign_cast(func_vt
);
5973 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5974 /* if returning structure, must copy it to implicit
5975 first pointer arg location */
5976 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
5979 /* copy structure value to pointer */
5981 } else if (is_float(func_vt
)) {
5986 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5989 rsym
= gjmp(rsym
); /* jmp */
5990 } else if (tok
== TOK_BREAK
) {
5993 error("cannot break");
5994 *bsym
= gjmp(*bsym
);
5997 } else if (tok
== TOK_CONTINUE
) {
6000 error("cannot continue");
6001 *csym
= gjmp(*csym
);
6004 } else if (tok
== TOK_FOR
) {
6031 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6036 if (tok
== TOK_DO
) {
6041 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6052 if (tok
== TOK_SWITCH
) {
6056 /* XXX: other types than integer */
6057 case_reg
= gv(RC_INT
);
6061 b
= gjmp(0); /* jump to first case */
6063 block(&a
, csym
, &b
, &c
, case_reg
);
6064 /* if no default, jmp after switch */
6072 if (tok
== TOK_CASE
) {
6079 if (gnu_ext
&& tok
== TOK_DOTS
) {
6083 warning("empty case range");
6085 /* since a case is like a label, we must skip it with a jmp */
6088 vset(VT_INT
, case_reg
, 0);
6092 *case_sym
= gtst(1, 0);
6095 *case_sym
= gtst(1, 0);
6096 vset(VT_INT
, case_reg
, 0);
6099 *case_sym
= gtst(1, *case_sym
);
6103 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6105 if (tok
== TOK_DEFAULT
) {
6111 error("too many 'default'");
6113 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6115 if (tok
== TOK_GOTO
) {
6117 s
= sym_find1(&label_stack
, tok
);
6118 /* put forward definition if needed */
6120 s
= sym_push1(&label_stack
, tok
, LABEL_FORWARD
, 0);
6121 /* label already defined */
6122 if (s
->t
& LABEL_FORWARD
)
6132 s
= sym_find1(&label_stack
, b
);
6134 if (!(s
->t
& LABEL_FORWARD
))
6135 error("multiple defined label");
6140 sym_push1(&label_stack
, b
, 0, ind
);
6142 /* we accept this, but it is a mistake */
6144 warning("deprecated use of label at end of compound statement");
6146 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6148 /* expression case */
6158 /* t is the array or struct type. c is the array or struct
6159 address. cur_index/cur_field is the pointer to the current
6160 value. 'size_only' is true if only size info is needed (only used
6162 static void decl_designator(int t
, Section
*sec
, unsigned long c
,
6163 int *cur_index
, Sym
**cur_field
,
6167 int notfirst
, index
, align
, l
;
6170 if (gnu_ext
&& (l
= is_label()) != 0)
6173 while (tok
== '[' || tok
== '.') {
6175 if (!(t
& VT_ARRAY
))
6176 expect("array type");
6177 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
6179 index
= expr_const();
6180 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
6181 expect("invalid index");
6185 t
= pointed_type(t
);
6186 c
+= index
* type_size(t
, &align
);
6192 if ((t
& VT_BTYPE
) != VT_STRUCT
)
6193 expect("struct/union type");
6194 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
6206 t
= f
->t
| (t
& ~VT_TYPE
);
6221 t
= pointed_type(t
);
6222 c
+= index
* type_size(t
, &align
);
6226 error("too many field init");
6227 t
= f
->t
| (t
& ~VT_TYPE
);
6231 decl_initializer(t
, sec
, c
, 0, size_only
);
6235 #define EXPR_CONST 1
6238 /* store a value or an expression directly in global data or in local array */
6239 static void init_putv(int t
, Section
*sec
, unsigned long c
,
6240 int v
, int expr_type
)
6242 int saved_global_expr
, bt
;
6250 /* compound literals must be allocated globally in this case */
6251 saved_global_expr
= global_expr
;
6254 global_expr
= saved_global_expr
;
6255 /* NOTE: symbols are accepted */
6256 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
6257 error("initializer element is not constant");
6265 /* XXX: not portable */
6266 /* XXX: generate error if incorrect relocation */
6269 ptr
= sec
->data
+ c
;
6270 if ((vtop
->r
& VT_SYM
) &&
6276 error("initializer element is not computable at load time");
6279 *(char *)ptr
= vtop
->c
.i
;
6282 *(short *)ptr
= vtop
->c
.i
;
6285 *(double *)ptr
= vtop
->c
.d
;
6288 *(long double *)ptr
= vtop
->c
.ld
;
6291 *(long long *)ptr
= vtop
->c
.ll
;
6294 if (vtop
->r
& VT_SYM
) {
6295 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
6297 *(int *)ptr
= vtop
->c
.i
;
6302 vset(t
, VT_LOCAL
, c
);
6309 /* put zeros for variable based init */
6310 static void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
6315 /* nothing to do because globals are already set to zero */
6317 gfunc_start(&gf
, FUNC_CDECL
);
6322 vset(VT_INT
, VT_LOCAL
, c
);
6324 vpush_global_sym(func_old_type
, TOK_memset
);
6329 /* 't' contains the type and storage info. 'c' is the offset of the
6330 object in section 'sec'. If 'sec' is NULL, it means stack based
6331 allocation. 'first' is true if array '{' must be read (multi
6332 dimension implicit array init handling). 'size_only' is true if
6333 size only evaluation is wanted (only for arrays). */
6334 static void decl_initializer(int t
, Section
*sec
, unsigned long c
,
6335 int first
, int size_only
)
6337 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
6338 int t1
, size1
, align1
, expr_type
;
6342 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
6345 t1
= pointed_type(t
);
6346 size1
= type_size(t1
, &align1
);
6349 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
6355 /* only parse strings here if correct type (otherwise: handle
6356 them as ((w)char *) expressions */
6357 if ((tok
== TOK_LSTR
&&
6358 (t1
& VT_BTYPE
) == VT_INT
) ||
6360 (t1
& VT_BTYPE
) == VT_BYTE
)) {
6361 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6366 /* compute maximum number of chars wanted */
6368 cstr_len
= cstr
->size
;
6370 cstr_len
= cstr
->size
/ sizeof(int);
6373 if (n
>= 0 && nb
> (n
- array_length
))
6374 nb
= n
- array_length
;
6377 warning("initializer-string for array is too long");
6378 /* in order to go faster for common case (char
6379 string in global variable, we handle it
6381 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
6382 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
6386 ch
= ((unsigned char *)cstr
->data
)[i
];
6388 ch
= ((int *)cstr
->data
)[i
];
6389 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
6397 /* only add trailing zero if enough storage (no
6398 warning in this case since it is standard) */
6399 if (n
< 0 || array_length
< n
) {
6401 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
6407 while (tok
!= '}') {
6408 decl_designator(t
, sec
, c
, &index
, NULL
, size_only
);
6409 if (n
>= 0 && index
>= n
)
6410 error("index too large");
6411 /* must put zero in holes (note that doing it that way
6412 ensures that it even works with designators) */
6413 if (!size_only
&& array_length
< index
) {
6414 init_putz(t1
, sec
, c
+ array_length
* size1
,
6415 (index
- array_length
) * size1
);
6418 if (index
> array_length
)
6419 array_length
= index
;
6420 /* special test for multi dimensional arrays (may not
6421 be strictly correct if designators are used at the
6423 if (index
>= n
&& no_oblock
)
6432 /* put zeros at the end */
6433 if (!size_only
&& n
>= 0 && array_length
< n
) {
6434 init_putz(t1
, sec
, c
+ array_length
* size1
,
6435 (n
- array_length
) * size1
);
6437 /* patch type size if needed */
6439 s
->c
= array_length
;
6440 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
6441 /* XXX: union needs only one init */
6443 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
6448 while (tok
!= '}') {
6449 decl_designator(t
, sec
, c
, NULL
, &f
, size_only
);
6450 /* fill with zero between fields */
6452 if (!size_only
&& array_length
< index
) {
6453 init_putz(t
, sec
, c
+ array_length
,
6454 index
- array_length
);
6456 index
= index
+ type_size(f
->t
, &align1
);
6457 if (index
> array_length
)
6458 array_length
= index
;
6464 /* put zeros at the end */
6465 if (!size_only
&& array_length
< n
) {
6466 init_putz(t
, sec
, c
+ array_length
,
6470 } else if (tok
== '{') {
6472 decl_initializer(t
, sec
, c
, first
, size_only
);
6474 } else if (size_only
) {
6475 /* just skip expression */
6477 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
6481 else if (tok
== ')')
6486 /* currently, we always use constant expression for globals
6487 (may change for scripting case) */
6488 expr_type
= EXPR_CONST
;
6490 expr_type
= EXPR_ANY
;
6491 init_putv(t
, sec
, c
, 0, expr_type
);
6495 /* parse an initializer for type 't' if 'has_init' is non zero, and
6496 allocate space in local or global data space ('r' is either
6497 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6498 variable 'v' of scope 'scope' is declared before initializers are
6499 parsed. If 'v' is zero, then a reference to the new object is put
6500 in the value stack. If 'has_init' is 2, a special parsing is done
6501 to handle string constants. */
6502 static void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
,
6503 int has_init
, int v
, int scope
)
6505 int size
, align
, addr
, data_offset
;
6507 ParseState saved_parse_state
;
6508 TokenString init_str
;
6511 size
= type_size(t
, &align
);
6512 /* If unknown size, we must evaluate it before
6513 evaluating initializers because
6514 initializers can generate global data too
6515 (e.g. string pointers or ISOC99 compound
6516 literals). It also simplifies local
6517 initializers handling */
6518 tok_str_new(&init_str
);
6521 error("unknown type size");
6522 /* get all init string */
6523 if (has_init
== 2) {
6524 /* only get strings */
6525 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6526 tok_str_add_tok(&init_str
);
6531 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
6533 error("unexpected end of file in initializer");
6534 tok_str_add_tok(&init_str
);
6537 else if (tok
== '}') {
6545 tok_str_add(&init_str
, -1);
6546 tok_str_add(&init_str
, 0);
6549 save_parse_state(&saved_parse_state
);
6551 macro_ptr
= init_str
.str
;
6553 decl_initializer(t
, NULL
, 0, 1, 1);
6554 /* prepare second initializer parsing */
6555 macro_ptr
= init_str
.str
;
6558 /* if still unknown size, error */
6559 size
= type_size(t
, &align
);
6561 error("unknown type size");
6563 /* take into account specified alignment if bigger */
6564 if (ad
->aligned
> align
)
6565 align
= ad
->aligned
;
6566 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
6568 if (do_bounds_check
&& (t
& VT_ARRAY
))
6570 #ifdef TCC_TARGET_IL
6571 /* XXX: ugly patch to allocate local variables for IL, just
6576 loc
= (loc
- size
) & -align
;
6579 /* handles bounds */
6580 /* XXX: currently, since we do only one pass, we cannot track
6581 '&' operators, so we add only arrays */
6582 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
6583 unsigned long *bounds_ptr
;
6584 /* add padding between regions */
6586 /* then add local bound info */
6587 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
6588 bounds_ptr
[0] = addr
;
6589 bounds_ptr
[1] = size
;
6592 /* compute section */
6600 data_offset
= sec
->data_offset
;
6601 data_offset
= (data_offset
+ align
- 1) & -align
;
6603 /* very important to increment global pointer at this time
6604 because initializers themselves can create new initializers */
6605 data_offset
+= size
;
6606 /* add padding if bound check */
6607 if (do_bounds_check
)
6609 sec
->data_offset
= data_offset
;
6610 /* allocate section space to put the data */
6611 if (sec
->sh_type
!= SHT_NOBITS
&&
6612 data_offset
> sec
->data_allocated
)
6613 section_realloc(sec
, data_offset
);
6617 /* local variable */
6618 sym_push(v
, t
, r
, addr
);
6620 /* push local reference */
6627 if (scope
== VT_CONST
) {
6628 /* global scope: see if already defined */
6632 if (!is_compatible_types(sym
->t
, t
))
6633 error("incompatible types for redefinition of '%s'",
6634 get_tok_str(v
, NULL
));
6635 if (!(sym
->t
& VT_EXTERN
))
6636 error("redefinition of '%s'", get_tok_str(v
, NULL
));
6637 sym
->t
&= ~VT_EXTERN
;
6640 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
6642 put_extern_sym(sym
, sec
, addr
, size
);
6646 /* push global reference */
6647 sym
= get_sym_ref(t
, sec
, addr
, size
);
6649 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
6653 /* handles bounds now because the symbol must be defined
6654 before for the relocation */
6655 if (do_bounds_check
) {
6656 unsigned long *bounds_ptr
;
6658 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
6659 /* then add global bound info */
6660 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
6661 bounds_ptr
[0] = 0; /* relocated */
6662 bounds_ptr
[1] = size
;
6666 decl_initializer(t
, sec
, addr
, 1, 0);
6667 /* restore parse state if needed */
6669 tok_str_free(init_str
.str
);
6670 restore_parse_state(&saved_parse_state
);
6675 void put_func_debug(Sym
*sym
)
6680 /* XXX: we put here a dummy type */
6681 snprintf(buf
, sizeof(buf
), "%s:%c1",
6682 funcname
, sym
->t
& VT_STATIC
? 'f' : 'F');
6683 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
6684 cur_text_section
, sym
->c
);
6689 /* not finished : try to put some local vars in registers */
6690 //#define CONFIG_REG_VARS
6692 #ifdef CONFIG_REG_VARS
6693 void add_var_ref(int t
)
6695 printf("%s:%d: &%s\n",
6696 file
->filename
, file
->line_num
,
6697 get_tok_str(t
, NULL
));
6700 /* first pass on a function with heuristic to extract variable usage
6701 and pointer references to local variables for register allocation */
6702 void analyse_function(void)
6709 /* any symbol coming after '&' is considered as being a
6710 variable whose reference is taken. It is highly unaccurate
6711 but it is difficult to do better without a complete parse */
6714 /* if '& number', then no need to examine next tokens */
6715 if (tok
== TOK_CINT
||
6717 tok
== TOK_CLLONG
||
6718 tok
== TOK_CULLONG
) {
6720 } else if (tok
>= TOK_UIDENT
) {
6721 /* if '& ident [' or '& ident ->', then ident address
6725 if (tok
!= '[' && tok
!= TOK_ARROW
)
6729 while (tok
!= '}' && tok
!= ';' &&
6730 !((tok
== ',' || tok
== ')') && level
== 0)) {
6731 if (tok
>= TOK_UIDENT
) {
6733 } else if (tok
== '(') {
6735 } else if (tok
== ')') {
6748 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6751 int t
, b
, v
, has_init
, r
;
6756 if (!parse_btype(&b
, &ad
)) {
6757 /* skip redundant ';' */
6758 /* XXX: find more elegant solution */
6763 /* special test for old K&R protos without explicit int
6764 type. Only accepted when defining global data */
6765 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
6769 if (((b
& VT_BTYPE
) == VT_ENUM
||
6770 (b
& VT_BTYPE
) == VT_STRUCT
) &&
6772 /* we accept no variable after */
6776 while (1) { /* iterate thru each declaration */
6777 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
6781 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
6782 printf("type = '%s'\n", buf
);
6786 #ifdef CONFIG_REG_VARS
6787 TokenString func_str
;
6788 ParseState saved_parse_state
;
6793 error("cannot use local functions");
6795 expect("function definition");
6797 #ifdef CONFIG_REG_VARS
6798 /* parse all function code and record it */
6800 tok_str_new(&func_str
);
6806 error("unexpected end of file");
6807 tok_str_add_tok(&func_str
);
6812 } else if (t
== '}') {
6814 if (block_level
== 0)
6818 tok_str_add(&func_str
, -1);
6819 tok_str_add(&func_str
, 0);
6821 save_parse_state(&saved_parse_state
);
6823 macro_ptr
= func_str
.str
;
6828 /* compute text section */
6829 cur_text_section
= ad
.section
;
6830 if (!cur_text_section
)
6831 cur_text_section
= text_section
;
6832 ind
= cur_text_section
->data_offset
;
6833 funcname
= get_tok_str(v
, NULL
);
6836 /* if symbol is already defined, then put complete type */
6839 /* put function symbol */
6840 sym
= sym_push1(&global_stack
, v
, t
, 0);
6842 /* NOTE: we patch the symbol size later */
6843 put_extern_sym(sym
, cur_text_section
, ind
, 0);
6845 sym
->r
= VT_SYM
| VT_CONST
;
6846 /* put debug symbol */
6848 put_func_debug(sym
);
6849 /* push a dummy symbol to enable local sym storage */
6850 sym_push1(&local_stack
, 0, 0, 0);
6854 #ifdef CONFIG_REG_VARS
6855 macro_ptr
= func_str
.str
;
6858 block(NULL
, NULL
, NULL
, NULL
, 0);
6861 cur_text_section
->data_offset
= ind
;
6862 sym_pop(&label_stack
, NULL
); /* reset label stack */
6863 sym_pop(&local_stack
, NULL
); /* reset local stack */
6864 /* end of function */
6865 /* patch symbol size */
6866 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
6869 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6871 funcname
= ""; /* for safety */
6872 func_vt
= VT_VOID
; /* for safety */
6873 ind
= 0; /* for safety */
6875 #ifdef CONFIG_REG_VARS
6876 tok_str_free(func_str
.str
);
6877 restore_parse_state(&saved_parse_state
);
6881 if (b
& VT_TYPEDEF
) {
6882 /* save typedefed type */
6883 /* XXX: test storage specifiers ? */
6884 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
6885 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
6886 /* external function definition */
6887 external_sym(v
, t
, 0);
6889 /* not lvalue if array */
6891 if (!(t
& VT_ARRAY
))
6892 r
|= lvalue_type(t
);
6893 if (b
& VT_EXTERN
) {
6894 /* external variable */
6895 external_sym(v
, t
, r
);
6901 has_init
= (tok
== '=');
6904 decl_initializer_alloc(t
, &ad
, r
,
6918 /* free define stack until top reaches 'b' */
6919 static void free_defines(Sym
*b
)
6923 top
= define_stack
.top
;
6926 /* do not free args or predefined defines */
6928 tok_str_free((int *)top
->c
);
6929 sym_pop(&define_stack
, top1
);
6934 /* compile the C file opened in 'file'. Return non zero if errors. */
6935 static int tcc_compile(TCCState
*s1
)
6937 Sym
*define_start
, *sym
;
6939 volatile int section_sym
;
6943 printf("%s: **** new file\n", file
->filename
);
6946 s1
->include_stack_ptr
= s1
->include_stack
;
6947 /* XXX: move that before to avoid having to initialize
6948 file->ifdef_stack_ptr ? */
6949 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
6950 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
6952 /* XXX: not ANSI compliant: bound checking says error */
6954 anon_sym
= SYM_FIRST_ANOM
;
6956 /* file info: full path + filename */
6957 section_sym
= 0; /* avoid warning */
6959 section_sym
= put_elf_sym(symtab_section
, 0, 0,
6960 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
6961 text_section
->sh_num
, NULL
);
6962 getcwd(buf
, sizeof(buf
));
6963 pstrcat(buf
, sizeof(buf
), "/");
6964 put_stabs_r(buf
, N_SO
, 0, 0,
6965 text_section
->data_offset
, text_section
, section_sym
);
6966 put_stabs_r(file
->filename
, N_SO
, 0, 0,
6967 text_section
->data_offset
, text_section
, section_sym
);
6969 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6970 symbols can be safely used */
6971 put_elf_sym(symtab_section
, 0, 0,
6972 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
6973 SHN_ABS
, file
->filename
);
6975 /* define common 'char *' type because it is often used internally
6976 for arrays and struct dereference */
6977 char_pointer_type
= mk_pointer(VT_BYTE
);
6978 /* define an old type function 'int func()' */
6980 sym
= sym_push(p
, 0, FUNC_CDECL
, FUNC_OLD
);
6981 func_old_type
= VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
6983 /* define 'void *alloca(unsigned int)' builtin function */
6988 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
6989 s1
= sym_push(0, VT_UNSIGNED
| VT_INT
, 0, 0);
6992 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
6996 define_start
= define_stack
.top
;
6998 if (setjmp(s1
->error_jmp_buf
) == 0) {
7000 s1
->error_set_jmp_enabled
= 1;
7003 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7007 expect("declaration");
7009 /* end of translation unit info */
7011 put_stabs_r(NULL
, N_SO
, 0, 0,
7012 text_section
->data_offset
, text_section
, section_sym
);
7015 s1
->error_set_jmp_enabled
= 0;
7017 /* reset define stack, but leave -Dsymbols (may be incorrect if
7018 they are undefined) */
7019 free_defines(define_start
);
7021 sym_pop(&global_stack
, NULL
);
7023 return s1
->nb_errors
!= 0 ? -1 : 0;
7026 int tcc_compile_string(TCCState
*s
, const char *str
)
7028 BufferedFile bf1
, *bf
= &bf1
;
7031 /* init file structure */
7033 bf
->buf_ptr
= (char *)str
;
7034 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
7035 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
7039 ret
= tcc_compile(s
);
7041 /* currently, no need to close */
7045 /* define a symbol. A value can also be provided with the '=' operator */
7046 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
7048 BufferedFile bf1
, *bf
= &bf1
;
7050 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
7051 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
7055 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
7057 /* init file structure */
7059 bf
->buf_ptr
= bf
->buffer
;
7060 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
7061 bf
->filename
[0] = '\0';
7065 s1
->include_stack_ptr
= s1
->include_stack
;
7067 /* parse with define parser */
7069 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7075 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
7079 ts
= tok_alloc(sym
, strlen(sym
));
7080 s
= sym_find1(&define_stack
, tok
);
7081 /* undefine symbol by putting an invalid name */
7083 sym_undef(&define_stack
, s
);
7088 /* print the position in the source file of PC value 'pc' by reading
7089 the stabs debug information */
7090 static void rt_printline(unsigned long wanted_pc
)
7092 Stab_Sym
*sym
, *sym_end
;
7093 char func_name
[128], last_func_name
[128];
7094 unsigned long func_addr
, last_pc
, pc
;
7095 const char *incl_files
[INCLUDE_STACK_SIZE
];
7096 int incl_index
, len
, last_line_num
, i
;
7097 const char *str
, *p
;
7099 func_name
[0] = '\0';
7102 last_func_name
[0] = '\0';
7103 last_pc
= 0xffffffff;
7105 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
7106 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
7107 while (sym
< sym_end
) {
7108 switch(sym
->n_type
) {
7109 /* function start or end */
7111 if (sym
->n_strx
== 0) {
7112 func_name
[0] = '\0';
7115 str
= stabstr_section
->data
+ sym
->n_strx
;
7116 p
= strchr(str
, ':');
7118 pstrcpy(func_name
, sizeof(func_name
), str
);
7121 if (len
> sizeof(func_name
) - 1)
7122 len
= sizeof(func_name
) - 1;
7123 memcpy(func_name
, str
, len
);
7124 func_name
[len
] = '\0';
7126 func_addr
= sym
->n_value
;
7129 /* line number info */
7131 pc
= sym
->n_value
+ func_addr
;
7132 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7135 last_line_num
= sym
->n_desc
;
7137 strcpy(last_func_name
, func_name
);
7141 str
= stabstr_section
->data
+ sym
->n_strx
;
7143 if (incl_index
< INCLUDE_STACK_SIZE
) {
7144 incl_files
[incl_index
++] = str
;
7152 if (sym
->n_strx
== 0) {
7153 incl_index
= 0; /* end of translation unit */
7155 str
= stabstr_section
->data
+ sym
->n_strx
;
7156 /* do not add path */
7158 if (len
> 0 && str
[len
- 1] != '/')
7165 /* did not find line number info: */
7166 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
7169 for(i
= 0; i
< incl_index
- 1; i
++)
7170 fprintf(stderr
, "In file included from %s\n",
7172 if (incl_index
> 0) {
7173 fprintf(stderr
, "%s:%d: ",
7174 incl_files
[incl_index
- 1], last_line_num
);
7176 if (last_func_name
[0] != '\0') {
7177 fprintf(stderr
, "in function '%s()': ", last_func_name
);
7181 /* emit a run time error at position 'pc' */
7182 void rt_error(unsigned long pc
, const char *fmt
, ...)
7188 vfprintf(stderr
, fmt
, ap
);
7189 fprintf(stderr
, "\n");
7195 /* signal handler for fatal errors */
7196 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
7198 struct ucontext
*uc
= puc
;
7202 pc
= uc
->uc_mcontext
.gregs
[14];
7204 #error please put the right sigcontext field
7209 switch(siginf
->si_code
) {
7212 rt_error(pc
, "division by zero");
7215 rt_error(pc
, "floating point exception");
7221 rt_error(pc
, "dereferencing invalid pointer");
7224 rt_error(pc
, "illegal instruction");
7227 rt_error(pc
, "abort() called");
7230 rt_error(pc
, "caught signal %d", signum
);
7237 /* do all relocations (needed before using tcc_get_symbol()) */
7238 int tcc_relocate(TCCState
*s1
)
7245 tcc_add_runtime(s1
);
7247 relocate_common_syms();
7249 /* compute relocation address : section are relocated in place. We
7250 also alloc the bss space */
7251 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7252 s
= s1
->sections
[i
];
7253 if (s
->sh_flags
& SHF_ALLOC
) {
7254 if (s
->sh_type
== SHT_NOBITS
)
7255 s
->data
= tcc_mallocz(s
->data_offset
);
7256 s
->sh_addr
= (unsigned long)s
->data
;
7260 relocate_syms(s1
, 1);
7262 if (s1
->nb_errors
!= 0)
7265 /* relocate each section */
7266 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7267 s
= s1
->sections
[i
];
7269 relocate_section(s1
, s
);
7274 /* launch the compiled program with the given arguments */
7275 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
7277 int (*prog_main
)(int, char **);
7279 if (tcc_relocate(s1
) < 0)
7282 prog_main
= tcc_get_symbol(s1
, "main");
7286 error("debug mode currently not available for Windows");
7288 struct sigaction sigact
;
7289 /* install TCC signal handlers to print debug info on fatal
7291 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
7292 sigact
.sa_sigaction
= sig_error
;
7293 sigemptyset(&sigact
.sa_mask
);
7294 sigaction(SIGFPE
, &sigact
, NULL
);
7295 sigaction(SIGILL
, &sigact
, NULL
);
7296 sigaction(SIGSEGV
, &sigact
, NULL
);
7297 sigaction(SIGBUS
, &sigact
, NULL
);
7298 sigaction(SIGABRT
, &sigact
, NULL
);
7302 #ifdef CONFIG_TCC_BCHECK
7303 if (do_bounds_check
) {
7304 void (*bound_init
)(void);
7305 void **bound_error_func
;
7307 /* set error function */
7308 bound_error_func
= (void **)tcc_get_symbol(s1
, "__bound_error_func");
7309 *bound_error_func
= rt_error
;
7311 /* XXX: use .init section so that it also work in binary ? */
7312 bound_init
= (void *)tcc_get_symbol(s1
, "__bound_init");
7316 return (*prog_main
)(argc
, argv
);
7319 TCCState
*tcc_new(void)
7324 s
= tcc_mallocz(sizeof(TCCState
));
7328 s
->output_type
= TCC_OUTPUT_MEMORY
;
7330 /* default include paths */
7331 tcc_add_sysinclude_path(s
, "/usr/local/include");
7332 tcc_add_sysinclude_path(s
, "/usr/include");
7333 tcc_add_sysinclude_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
7335 /* add all tokens */
7337 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
7339 tok_ident
= TOK_IDENT
;
7344 tok_alloc(p
, r
- p
- 1);
7348 /* we add dummy defines for some special macros to speed up tests
7349 and to have working defined() */
7350 sym_push1(&define_stack
, TOK___LINE__
, MACRO_OBJ
, 0);
7351 sym_push1(&define_stack
, TOK___FILE__
, MACRO_OBJ
, 0);
7352 sym_push1(&define_stack
, TOK___DATE__
, MACRO_OBJ
, 0);
7353 sym_push1(&define_stack
, TOK___TIME__
, MACRO_OBJ
, 0);
7355 /* standard defines */
7356 tcc_define_symbol(s
, "__STDC__", NULL
);
7357 #if defined(TCC_TARGET_I386)
7358 tcc_define_symbol(s
, "__i386__", NULL
);
7361 tcc_define_symbol(s
, "linux", NULL
);
7363 /* tiny C specific defines */
7364 tcc_define_symbol(s
, "__TINYC__", NULL
);
7366 /* default library paths */
7367 tcc_add_library_path(s
, "/usr/local/lib");
7368 tcc_add_library_path(s
, "/usr/lib");
7369 tcc_add_library_path(s
, "/lib");
7371 /* no section zero */
7372 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
7374 /* create standard sections */
7375 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
7376 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
7377 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
7379 /* symbols are always generated for linking stage */
7380 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
7382 ".hashtab", SHF_PRIVATE
);
7383 strtab_section
= symtab_section
->link
;
7385 /* private symbol table for dynamic symbols */
7386 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
7388 ".dynhashtab", SHF_PRIVATE
);
7392 void tcc_delete(TCCState
*s1
)
7396 /* free -D defines */
7400 n
= tok_ident
- TOK_IDENT
;
7401 for(i
= 0; i
< n
; i
++)
7402 tcc_free(table_ident
[i
]);
7403 tcc_free(table_ident
);
7405 /* free all sections */
7407 free_section(symtab_section
->hash
);
7409 free_section(s1
->dynsymtab_section
->hash
);
7410 free_section(s1
->dynsymtab_section
->link
);
7411 free_section(s1
->dynsymtab_section
);
7413 for(i
= 1; i
< s1
->nb_sections
; i
++)
7414 free_section(s1
->sections
[i
]);
7415 tcc_free(s1
->sections
);
7417 /* free loaded dlls array */
7418 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
7419 tcc_free(s1
->loaded_dlls
[i
]);
7420 tcc_free(s1
->loaded_dlls
);
7423 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
7424 tcc_free(s1
->library_paths
[i
]);
7425 tcc_free(s1
->library_paths
);
7427 /* cached includes */
7428 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
7429 tcc_free(s1
->cached_includes
[i
]);
7430 tcc_free(s1
->cached_includes
);
7432 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
7433 tcc_free(s1
->include_paths
[i
]);
7434 tcc_free(s1
->include_paths
);
7436 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
7437 tcc_free(s1
->sysinclude_paths
[i
]);
7438 tcc_free(s1
->sysinclude_paths
);
7443 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
7447 pathname1
= tcc_strdup(pathname
);
7448 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
7452 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
7456 pathname1
= tcc_strdup(pathname
);
7457 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
7461 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
7466 BufferedFile
*saved_file
;
7468 /* find source file type with extension */
7469 ext
= strrchr(filename
, '.');
7475 file
= tcc_open(s1
, filename
);
7477 if (flags
& AFF_PRINT_ERROR
) {
7478 error_noabort("file '%s' not found", filename
);
7484 if (!ext
|| !strcmp(ext
, "c")) {
7485 /* C file assumed */
7486 ret
= tcc_compile(s1
);
7489 /* assume executable format: auto guess file type */
7490 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
)) {
7491 error_noabort("could not read header");
7494 lseek(fd
, 0, SEEK_SET
);
7496 if (ehdr
.e_ident
[0] == ELFMAG0
&&
7497 ehdr
.e_ident
[1] == ELFMAG1
&&
7498 ehdr
.e_ident
[2] == ELFMAG2
&&
7499 ehdr
.e_ident
[3] == ELFMAG3
) {
7500 file
->line_num
= 0; /* do not display line number if error */
7501 if (ehdr
.e_type
== ET_REL
) {
7502 ret
= tcc_load_object_file(s1
, fd
, 0);
7503 } else if (ehdr
.e_type
== ET_DYN
) {
7504 ret
= tcc_load_dll(s1
, fd
, filename
,
7505 (flags
& AFF_REFERENCED_DLL
) != 0);
7507 error_noabort("unrecognized ELF file");
7510 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
7511 file
->line_num
= 0; /* do not display line number if error */
7512 ret
= tcc_load_archive(s1
, fd
);
7514 /* as GNU ld, consider it is an ld script if not recognized */
7515 ret
= tcc_load_ldscript(s1
);
7517 error_noabort("unrecognized file type");
7532 int tcc_add_file(TCCState
*s
, const char *filename
)
7534 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
7537 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
7541 pathname1
= tcc_strdup(pathname
);
7542 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
7546 /* find and load a dll. Return non zero if not found */
7547 /* XXX: add '-rpath' option support ? */
7548 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
7553 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
7554 snprintf(buf
, sizeof(buf
), "%s/%s",
7555 s
->library_paths
[i
], filename
);
7556 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
7562 /* the library name is the same as the argument of the '-l' option */
7563 int tcc_add_library(TCCState
*s
, const char *libraryname
)
7569 /* first we look for the dynamic library if not static linking */
7570 if (!s
->static_link
) {
7571 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
7572 /* if we output to memory, then we simply we dlopen(). */
7573 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
7574 /* Since the libc is already loaded, we don't need to load it again */
7575 if (!strcmp(libraryname
, "c"))
7577 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
7581 if (tcc_add_dll(s
, buf
, 0) == 0)
7586 /* then we look for the static library */
7587 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
7588 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
7589 s
->library_paths
[i
], libraryname
);
7590 if (tcc_add_file_internal(s
, buf
, 0) == 0)
7596 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
7598 add_elf_sym(symtab_section
, val
, 0,
7599 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7604 int tcc_set_output_type(TCCState
*s
, int output_type
)
7606 s
->output_type
= output_type
;
7608 /* if bound checking, then add corresponding sections */
7609 #ifdef CONFIG_TCC_BCHECK
7610 if (do_bounds_check
) {
7612 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
7613 /* create bounds sections */
7614 bounds_section
= new_section(s
, ".bounds",
7615 SHT_PROGBITS
, SHF_ALLOC
);
7616 lbounds_section
= new_section(s
, ".lbounds",
7617 SHT_PROGBITS
, SHF_ALLOC
);
7621 /* add debug sections */
7624 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
7625 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
7626 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
7627 put_elf_str(stabstr_section
, "");
7628 stab_section
->link
= stabstr_section
;
7629 /* put first entry */
7630 put_stabs("", 0, 0, 0, 0);
7633 /* add libc crt1/crti objects */
7634 if (output_type
== TCC_OUTPUT_EXE
||
7635 output_type
== TCC_OUTPUT_DLL
) {
7636 if (output_type
!= TCC_OUTPUT_DLL
)
7637 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
7638 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
7643 #if !defined(LIBTCC)
7647 printf("tcc version 0.9.12 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7648 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7649 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
7650 " [--] infile1 [infile2... --] [infile_args...]\n"
7652 "General options:\n"
7653 " -c compile only - generate an object file\n"
7654 " -o outfile set output filename\n"
7655 " -- allows multiples input files if no -o option given. Also\n"
7656 " separate input files from runtime arguments\n"
7657 " -Bdir set tcc internal library path\n"
7658 " -bench output compilation statistics\n"
7659 "Preprocessor options:\n"
7660 " -Idir add include path 'dir'\n"
7661 " -Dsym[=val] define 'sym' with value 'val'\n"
7662 " -Usym undefine 'sym'\n"
7663 "C compiler options:\n"
7664 " -g generate runtime debug info\n"
7665 #ifdef CONFIG_TCC_BCHECK
7666 " -b compile with built-in memory and bounds checker (implies -g)\n"
7669 " -Ldir add library path 'dir'\n"
7670 " -llib link with dynamic or static library 'lib'\n"
7671 " -shared generate a shared library\n"
7672 " -static static linking\n"
7673 " -r relocatable output\n"
7677 int main(int argc
, char **argv
)
7680 int optind
, output_type
, multiple_files
, i
, reloc_output
;
7683 int nb_files
, nb_libraries
, nb_objfiles
, dminus
, ret
;
7684 char objfilename
[1024];
7687 output_type
= TCC_OUTPUT_MEMORY
;
7698 if (optind
>= argc
) {
7706 /* add a new file */
7707 dynarray_add((void ***)&files
, &nb_files
, r
);
7708 if (!multiple_files
) {
7710 /* argv[0] will be this file */
7713 } else if (r
[1] == '-') {
7714 /* '--' enables multiple files input and also ends several file input */
7715 if (dminus
&& multiple_files
) {
7716 optind
--; /* argv[0] will be '--' */
7721 } else if (r
[1] == 'h' || r
[1] == '?') {
7725 } else if (r
[1] == 'I') {
7726 if (tcc_add_include_path(s
, r
+ 2) < 0)
7727 error("too many include paths");
7728 } else if (r
[1] == 'D') {
7731 value
= strchr(sym
, '=');
7736 tcc_define_symbol(s
, sym
, value
);
7737 } else if (r
[1] == 'U') {
7738 tcc_undefine_symbol(s
, r
+ 2);
7739 } else if (r
[1] == 'L') {
7740 tcc_add_library_path(s
, r
+ 2);
7741 } else if (r
[1] == 'B') {
7742 /* set tcc utilities path (mainly for tcc development) */
7743 tcc_lib_path
= r
+ 2;
7744 } else if (r
[1] == 'l') {
7745 dynarray_add((void ***)&files
, &nb_files
, r
);
7747 } else if (!strcmp(r
+ 1, "bench")) {
7750 #ifdef CONFIG_TCC_BCHECK
7752 do_bounds_check
= 1;
7758 } else if (r
[1] == 'c') {
7760 output_type
= TCC_OUTPUT_OBJ
;
7761 } else if (!strcmp(r
+ 1, "static")) {
7763 } else if (!strcmp(r
+ 1, "shared")) {
7764 output_type
= TCC_OUTPUT_DLL
;
7765 } else if (r
[1] == 'o') {
7769 outfile
= argv
[optind
++];
7770 } else if (r
[1] == 'r') {
7771 /* generate a .o merging several output files */
7773 output_type
= TCC_OUTPUT_OBJ
;
7774 } else if (r
[1] == 'W' || r
[1] == 'O' || r
[1] == 'm' || r
[1] == 'f') {
7775 /* ignore those options to be a drop-in replacement for gcc */
7777 error("invalid option -- '%s'", r
);
7781 nb_objfiles
= nb_files
- nb_libraries
;
7783 /* if outfile provided without other options, we output an
7785 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
7786 output_type
= TCC_OUTPUT_EXE
;
7788 /* check -c consistency : only single file handled. XXX: checks file type */
7789 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
7790 /* accepts only a single input file */
7791 if (nb_objfiles
!= 1)
7792 error("cannot specify multiple files with -c");
7793 if (nb_libraries
!= 0)
7794 error("cannot specify libraries with -c");
7797 /* compute default outfile name */
7798 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
7799 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
7801 /* add .o extension */
7802 pstrcpy(objfilename
, sizeof(objfilename
) - 1, files
[0]);
7803 ext
= strrchr(objfilename
, '.');
7805 goto default_outfile
;
7806 strcpy(ext
+ 1, "o");
7809 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
7811 outfile
= objfilename
;
7814 tcc_set_output_type(s
, output_type
);
7816 /* compile or add each files or library */
7817 for(i
= 0;i
< nb_files
; i
++) {
7818 const char *filename
;
7820 filename
= files
[i
];
7821 if (filename
[0] == '-') {
7822 if (tcc_add_library(s
, filename
+ 2) < 0)
7823 error("cannot find %s", filename
);
7825 if (tcc_add_file(s
, filename
) < 0) {
7832 /* free all files */
7836 printf("total: %d idents, %d lines, %d bytes\n",
7837 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
7840 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
7841 tcc_output_file(s
, outfile
);
7844 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
7851 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);