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.
31 #include <sys/ucontext.h>
35 #ifndef CONFIG_TCC_STATIC
42 /* preprocessor debug */
44 /* include file debug */
49 /* target selection */
50 //#define TCC_TARGET_I386 /* i386 code generator */
51 //#define TCC_TARGET_IL /* .NET CLI generator */
53 /* default target is I386 */
54 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
55 #define TCC_TARGET_I386
58 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
59 #define CONFIG_TCC_BCHECK /* enable bound checking code */
62 #ifndef CONFIG_TCC_PREFIX
63 #define CONFIG_TCC_PREFIX "/usr/local"
66 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
67 executables or dlls */
68 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
70 #define INCLUDE_STACK_SIZE 32
71 #define IFDEF_STACK_SIZE 64
72 #define VSTACK_SIZE 64
73 #define STRING_MAX_SIZE 1024
75 #define TOK_HASH_SIZE 2048 /* must be a power of two */
76 #define TOK_ALLOC_INCR 512 /* must be a power of two */
77 #define SYM_HASH_SIZE 1031
79 /* token symbol management */
80 typedef struct TokenSym
{
81 struct TokenSym
*hash_next
;
82 int tok
; /* token number */
87 typedef struct CString
{
88 int size
; /* size in bytes */
89 void *data
; /* either 'char *' or 'int *' */
91 void *data_allocated
; /* if non NULL, data has been malloced */
95 typedef union CValue
{
101 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
103 unsigned long long ull
;
104 struct CString
*cstr
;
110 typedef struct SValue
{
112 unsigned short r
; /* register + flags */
113 unsigned short r2
; /* second register, used for 'long long'
114 type. If not used, set to VT_CONST */
115 CValue c
; /* constant, if VT_CONST */
116 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
119 /* symbol management */
121 int v
; /* symbol token */
122 int t
; /* associated type */
123 int r
; /* associated register */
124 int c
; /* associated number */
125 struct Sym
*next
; /* next related symbol */
126 struct Sym
*prev
; /* prev symbol in stack */
127 struct Sym
*hash_next
; /* next symbol in hash table */
130 typedef struct SymStack
{
132 struct Sym
*hash
[SYM_HASH_SIZE
];
135 /* section definition */
136 /* XXX: use directly ELF structure for parameters ? */
137 /* special flag to indicate that the section should not be linked to
139 #define SHF_PRIVATE 0x80000000
141 typedef struct Section
{
142 unsigned long data_offset
; /* current data offset */
143 unsigned char *data
; /* section data */
144 unsigned long data_allocated
; /* used for realloc() handling */
145 int sh_name
; /* elf section name (only used during output) */
146 int sh_num
; /* elf section number */
147 int sh_type
; /* elf section type */
148 int sh_flags
; /* elf section flags */
149 int sh_info
; /* elf section info */
150 int sh_addralign
; /* elf section alignment */
151 int sh_entsize
; /* elf entry size */
152 unsigned long sh_size
; /* section size (only used during output) */
153 unsigned long sh_addr
; /* address at which the section is relocated */
154 unsigned long sh_offset
; /* address at which the section is relocated */
155 int nb_hashed_syms
; /* used to resize the hash table */
156 struct Section
*link
; /* link to another section */
157 struct Section
*reloc
; /* corresponding section for relocation, if any */
158 struct Section
*hash
; /* hash table for symbols */
159 struct Section
*next
;
160 char name
[64]; /* section name */
163 typedef struct DLLReference
{
168 /* GNUC attribute definition */
169 typedef struct AttributeDef
{
172 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
175 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
176 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
177 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
179 /* stored in 'Sym.c' field */
180 #define FUNC_NEW 1 /* ansi function prototype */
181 #define FUNC_OLD 2 /* old function prototype */
182 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
184 /* stored in 'Sym.r' field */
185 #define FUNC_CDECL 0 /* standard c call */
186 #define FUNC_STDCALL 1 /* pascal c call */
188 /* field 'Sym.t' for macros */
189 #define MACRO_OBJ 0 /* object like macro */
190 #define MACRO_FUNC 1 /* function like macro */
192 /* field 'Sym.t' for labels */
193 #define LABEL_FORWARD 1 /* label is forward defined */
195 /* type_decl() types */
196 #define TYPE_ABSTRACT 1 /* type without variable */
197 #define TYPE_DIRECT 2 /* type with variable */
199 #define IO_BUF_SIZE 8192
201 typedef struct BufferedFile
{
202 unsigned char *buf_ptr
;
203 unsigned char *buf_end
;
205 int line_num
; /* current line number - here to simply code */
206 int ifndef_macro
; /*'#ifndef macro \n #define macro' search */
207 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
208 char inc_type
; /* type of include */
209 char inc_filename
[512]; /* filename specified by the user */
210 char filename
[1024]; /* current filename - here to simplify code */
211 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
214 #define CH_EOB 0 /* end of buffer or '\0' char in file */
215 #define CH_EOF (-1) /* end of file */
217 /* parsing state (used to save parser state to reparse part of the
218 source several times) */
219 typedef struct ParseState
{
226 /* used to record tokens */
227 typedef struct TokenString
{
233 /* include file cache, used to find files faster and also to eliminate
234 inclusion if the include file is protected by #ifndef ... #endif */
235 typedef struct CachedInclude
{
237 char type
; /* '"' or '>' to give include type */
238 char filename
[1]; /* path specified in #include */
242 struct BufferedFile
*file
;
243 int ch
, ch1
, tok
, tok1
;
245 CString tokcstr
; /* current parsed string, if any */
246 /* if true, line feed is returned as a token. line feed is also
249 /* set to TRUE if eof was reached */
253 int nb_sections
; /* number of sections, including first dummy section */
254 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
255 Section
*cur_text_section
; /* current section where function code is
257 /* bound check related sections */
258 Section
*bounds_section
; /* contains global data bound description */
259 Section
*lbounds_section
; /* contains local data bound description */
260 /* symbol sections */
261 Section
*symtab_section
, *strtab_section
;
262 /* temporary dynamic symbol sections (for dll loading) */
263 Section
*dynsymtab_section
;
264 /* exported dynamic symbol section */
268 unsigned long *got_offsets
;
271 /* give the correspondance from symtab indexes to dynsym indexes */
272 int *symtab_to_dynsym
;
274 /* array of all loaded dlls (including those referenced by loaded
276 DLLReference
**loaded_dlls
;
280 Section
*stab_section
, *stabstr_section
;
282 char **library_paths
;
283 int nb_library_paths
;
285 CachedInclude
**cached_includes
;
286 int nb_cached_includes
;
288 /* loc : local variable index
289 ind : output code index
291 anon_sym: anonymous symbol index
295 /* expression generation modifiers */
296 int const_wanted
; /* true if constant wanted */
297 int global_expr
; /* true if compound literals must be allocated
298 globally (used during initializers parsing */
299 int func_vt
, func_vc
; /* current function return type (used by
300 return instruction) */
301 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
303 TokenSym
**table_ident
;
304 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
305 char token_buf
[STRING_MAX_SIZE
+ 1];
307 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
309 SValue vstack
[VSTACK_SIZE
], *vtop
;
310 int *macro_ptr
, *macro_ptr_allocated
;
311 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
], **include_stack_ptr
;
312 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
313 char **include_paths
;
314 int nb_include_paths
;
315 char **sysinclude_paths
;
316 int nb_sysinclude_paths
;
317 int char_pointer_type
;
320 /* compile with debug symbol (and use them if error during execution) */
323 /* compile with built-in memory and bounds checker */
324 int do_bounds_check
= 0;
326 /* display benchmark infos */
331 /* use GNU C extensions */
334 /* use Tiny C extensions */
337 /* if true, static linking is performed */
340 /* give the path of the tcc libraries */
341 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
347 /* The current value can be: */
348 #define VT_VALMASK 0x00ff
349 #define VT_CONST 0x00f0 /* constant in vc
350 (must be first non register value) */
351 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
352 #define VT_LOCAL 0x00f2 /* offset on stack */
353 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
354 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
355 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
356 #define VT_LVAL 0x0100 /* var is an lvalue */
357 #define VT_SYM 0x0200 /* a symbol value is added */
358 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
359 char/short stored in integer registers) */
360 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
361 dereferencing value */
362 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
363 bounding function call point is in vc */
364 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
365 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
366 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
367 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
370 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
372 #define VT_INT 0 /* integer type */
373 #define VT_BYTE 1 /* signed byte type */
374 #define VT_SHORT 2 /* short type */
375 #define VT_VOID 3 /* void type */
376 #define VT_PTR 4 /* pointer */
377 #define VT_ENUM 5 /* enum definition */
378 #define VT_FUNC 6 /* function type */
379 #define VT_STRUCT 7 /* struct/union definition */
380 #define VT_FLOAT 8 /* IEEE float */
381 #define VT_DOUBLE 9 /* IEEE double */
382 #define VT_LDOUBLE 10 /* IEEE long double */
383 #define VT_BOOL 11 /* ISOC99 boolean type */
384 #define VT_LLONG 12 /* 64 bit integer */
385 #define VT_LONG 13 /* long integer (NEVER USED as type, only
387 #define VT_BTYPE 0x000f /* mask for basic type */
388 #define VT_UNSIGNED 0x0010 /* unsigned type */
389 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
390 #define VT_BITFIELD 0x0040 /* bitfield modifier */
393 #define VT_EXTERN 0x00000080 /* extern definition */
394 #define VT_STATIC 0x00000100 /* static variable */
395 #define VT_TYPEDEF 0x00000200 /* typedef definition */
397 /* type mask (except storage) */
398 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
402 /* warning: the following compare tokens depend on i386 asm code */
414 #define TOK_LAND 0xa0
418 #define TOK_MID 0xa3 /* inc/dec, to void constant */
420 #define TOK_UDIV 0xb0 /* unsigned division */
421 #define TOK_UMOD 0xb1 /* unsigned modulo */
422 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
423 #define TOK_CINT 0xb3 /* number in tokc */
424 #define TOK_CCHAR 0xb4 /* char constant in tokc */
425 #define TOK_STR 0xb5 /* pointer to string in tokc */
426 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
427 #define TOK_LCHAR 0xb7
428 #define TOK_LSTR 0xb8
429 #define TOK_CFLOAT 0xb9 /* float constant */
430 #define TOK_LINENUM 0xba /* line number info */
431 #define TOK_CDOUBLE 0xc0 /* double constant */
432 #define TOK_CLDOUBLE 0xc1 /* long double constant */
433 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
434 #define TOK_ADDC1 0xc3 /* add with carry generation */
435 #define TOK_ADDC2 0xc4 /* add with carry use */
436 #define TOK_SUBC1 0xc5 /* add with carry generation */
437 #define TOK_SUBC2 0xc6 /* add with carry use */
438 #define TOK_CUINT 0xc8 /* unsigned int constant */
439 #define TOK_CLLONG 0xc9 /* long long constant */
440 #define TOK_CULLONG 0xca /* unsigned long long constant */
441 #define TOK_ARROW 0xcb
442 #define TOK_DOTS 0xcc /* three dots */
443 #define TOK_SHR 0xcd /* unsigned shift right */
445 #define TOK_SHL 0x01 /* shift left */
446 #define TOK_SAR 0x02 /* signed shift right */
448 /* assignement operators : normal operator or 0x80 */
449 #define TOK_A_MOD 0xa5
450 #define TOK_A_AND 0xa6
451 #define TOK_A_MUL 0xaa
452 #define TOK_A_ADD 0xab
453 #define TOK_A_SUB 0xad
454 #define TOK_A_DIV 0xaf
455 #define TOK_A_XOR 0xde
456 #define TOK_A_OR 0xfc
457 #define TOK_A_SHL 0x81
458 #define TOK_A_SAR 0x82
460 /* WARNING: the content of this string encodes token numbers */
461 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";
463 #define TOK_EOF (-1) /* end of file */
464 #define TOK_LINEFEED 10 /* line feed */
466 /* all identificators and strings have token above that */
467 #define TOK_IDENT 256
488 /* ignored types Must have contiguous values */
494 TOK___SIGNED__
, /* gcc keyword */
497 TOK___INLINE__
, /* gcc keyword */
500 /* unsupported type */
514 /* preprocessor only */
515 TOK_UIDENT
, /* first "user" ident (not keyword) */
516 TOK_DEFINE
= TOK_UIDENT
,
527 #define DEF(id, str) id,
533 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
534 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
535 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
536 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
537 "sizeof\0__attribute__\0"
538 /* the following are not keywords. They are included to ease parsing */
539 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
540 "defined\0undef\0error\0line\0"
541 /* builtin functions */
542 #define DEF(id, str) str "\0"
548 #define snprintf _snprintf
551 #if defined(WIN32) || defined(TCC_UCLIBC)
552 /* currently incorrect */
553 long double strtold(const char *nptr
, char **endptr
)
555 return (long double)strtod(nptr
, endptr
);
557 float strtof(const char *nptr
, char **endptr
)
559 return (float)strtod(nptr
, endptr
);
562 /* XXX: need to define this to use them in non ISOC99 context */
563 extern float strtof (const char *__nptr
, char **__endptr
);
564 extern long double strtold (const char *__nptr
, char **__endptr
);
567 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
568 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
572 void next_nomacro(void);
573 static int expr_const(void);
577 static void decl_initializer(int t
, Section
*sec
, unsigned long c
,
578 int first
, int size_only
);
579 static void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
,
580 int has_init
, int v
, int scope
);
582 void gv2(int rc1
, int rc2
);
583 void move_reg(int r
, int s
);
584 void save_regs(int n
);
585 void save_reg(int r
);
591 static void macro_subst(TokenString
*tok_str
,
592 Sym
**nested_list
, int *macro_str
);
593 int save_reg_forced(int r
);
595 void force_charshort_cast(int t
);
596 void gen_cast(int t
);
598 Sym
*sym_find(int v
);
599 Sym
*sym_push(int v
, int t
, int r
, int c
);
602 int type_size(int t
, int *a
);
603 int pointed_type(int t
);
604 int pointed_size(int t
);
605 static int lvalue_type(int t
);
606 int is_compatible_types(int t1
, int t2
);
607 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
608 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
610 void error(const char *fmt
, ...);
611 void rt_error(unsigned long pc
, const char *fmt
, ...);
613 void vset(int t
, int r
, int v
);
614 void type_to_str(char *buf
, int buf_size
,
615 int t
, const char *varstr
);
616 char *get_tok_str(int v
, CValue
*cv
);
617 static Sym
*get_sym_ref(int t
, Section
*sec
,
618 unsigned long offset
, unsigned long size
);
619 static Sym
*external_global_sym(int v
, int u
, int r
);
621 /* section generation */
622 static void section_realloc(Section
*sec
, unsigned long new_size
);
623 static void *section_ptr_add(Section
*sec
, unsigned long size
);
624 static void put_extern_sym(Sym
*sym
, Section
*section
,
625 unsigned long value
, unsigned long size
);
626 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
627 static int put_elf_str(Section
*s
, const char *sym
);
628 static int put_elf_sym(Section
*s
,
629 unsigned long value
, unsigned long size
,
630 int info
, int other
, int shndx
, const char *name
);
631 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
632 int info
, int sh_num
, const char *name
);
633 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
634 int type
, int symbol
);
635 static void put_stabs(const char *str
, int type
, int other
, int desc
,
636 unsigned long value
);
637 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
638 unsigned long value
, Section
*sec
, int sym_index
);
639 static void put_stabn(int type
, int other
, int desc
, int value
);
640 static void put_stabd(int type
, int other
, int desc
);
641 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
643 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
644 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
645 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
647 /* true if float/double/long double type */
648 static inline int is_float(int t
)
652 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
655 #ifdef TCC_TARGET_I386
656 #include "i386-gen.c"
662 #ifdef CONFIG_TCC_STATIC
664 #define RTLD_LAZY 0x001
665 #define RTLD_NOW 0x002
666 #define RTLD_GLOBAL 0x100
668 /* dummy function for profiling */
669 void *dlopen(const char *filename
, int flag
)
674 const char *dlerror(void)
679 typedef struct TCCSyms
{
684 #define TCCSYM(a) { #a, &a, },
686 /* add the symbol you want here if no dynamic linking is done */
687 static TCCSyms tcc_syms
[] = {
695 void *dlsym(void *handle
, const char *symbol
)
699 while (p
->str
!= NULL
) {
700 if (!strcmp(p
->str
, symbol
))
709 /********************************************************/
711 /* we use our own 'finite' function to avoid potential problems with
712 non standard math libs */
713 /* XXX: endianness dependant */
714 int ieee_finite(double d
)
717 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
720 /* copy a string and truncate it. */
721 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
728 q_end
= buf
+ buf_size
- 1;
740 /* strcat and truncate. */
741 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
746 pstrcpy(buf
+ len
, buf_size
- len
, s
);
750 /* memory management */
756 static inline void tcc_free(void *ptr
)
759 mem_cur_size
-= malloc_usable_size(ptr
);
764 static void *tcc_malloc(unsigned long size
)
769 error("memory full");
771 mem_cur_size
+= malloc_usable_size(ptr
);
772 if (mem_cur_size
> mem_max_size
)
773 mem_max_size
= mem_cur_size
;
778 static void *tcc_mallocz(unsigned long size
)
781 ptr
= tcc_malloc(size
);
782 memset(ptr
, 0, size
);
786 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
790 mem_cur_size
-= malloc_usable_size(ptr
);
792 ptr1
= realloc(ptr
, size
);
794 /* NOTE: count not correct if alloc error, but not critical */
795 mem_cur_size
+= malloc_usable_size(ptr1
);
796 if (mem_cur_size
> mem_max_size
)
797 mem_max_size
= mem_cur_size
;
802 static char *tcc_strdup(const char *str
)
805 ptr
= tcc_malloc(strlen(str
) + 1);
810 #define free(p) use_tcc_free(p)
811 #define malloc(s) use_tcc_malloc(s)
812 #define realloc(p, s) use_tcc_realloc(p, s)
814 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
821 /* every power of two we double array size */
822 if ((nb
& (nb
- 1)) == 0) {
827 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
829 error("memory full");
836 Section
*new_section(const char *name
, int sh_type
, int sh_flags
)
840 sec
= tcc_mallocz(sizeof(Section
));
841 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
842 sec
->sh_type
= sh_type
;
843 sec
->sh_flags
= sh_flags
;
850 sec
->sh_addralign
= 4;
853 sec
->sh_addralign
= 1;
856 sec
->sh_addralign
= 32; /* default conservative alignment */
860 /* only add section if not private */
861 if (!(sh_flags
& SHF_PRIVATE
)) {
862 sec
->sh_num
= nb_sections
;
863 dynarray_add((void ***)§ions
, &nb_sections
, sec
);
868 /* realloc section and set its content to zero */
869 static void section_realloc(Section
*sec
, unsigned long new_size
)
874 size
= sec
->data_allocated
;
877 while (size
< new_size
)
879 data
= tcc_realloc(sec
->data
, size
);
881 error("memory full");
882 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
884 sec
->data_allocated
= size
;
887 /* reserve at least 'size' bytes in section 'sec' from
889 static void *section_ptr_add(Section
*sec
, unsigned long size
)
891 unsigned long offset
, offset1
;
893 offset
= sec
->data_offset
;
894 offset1
= offset
+ size
;
895 if (offset1
> sec
->data_allocated
)
896 section_realloc(sec
, offset1
);
897 sec
->data_offset
= offset1
;
898 return sec
->data
+ offset
;
901 /* return a reference to a section, and create it if it does not
903 Section
*find_section(const char *name
)
907 for(i
= 1; i
< nb_sections
; i
++) {
909 if (!strcmp(name
, sec
->name
))
912 /* sections are created as PROGBITS */
913 return new_section(name
, SHT_PROGBITS
, SHF_ALLOC
);
916 /* update sym->c so that it points to an external symbol in section
917 'section' with value 'value' */
918 static void put_extern_sym(Sym
*sym
, Section
*section
,
919 unsigned long value
, unsigned long size
)
921 int sym_type
, sym_bind
, sh_num
, info
;
927 sh_num
= section
->sh_num
;
931 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
934 sym_type
= STT_OBJECT
;
935 if (sym
->t
& VT_STATIC
)
936 sym_bind
= STB_LOCAL
;
938 sym_bind
= STB_GLOBAL
;
940 name
= get_tok_str(sym
->v
, NULL
);
941 #ifdef CONFIG_TCC_BCHECK
942 if (do_bounds_check
) {
943 /* if bound checking is activated, we change some function
944 names by adding the "__bound" prefix */
947 /* XXX: we rely only on malloc hooks */
959 strcpy(buf
, "__bound_");
966 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
967 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
969 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
970 esym
->st_value
= value
;
971 esym
->st_size
= size
;
972 esym
->st_shndx
= sh_num
;
976 /* add a new relocation entry to symbol 'sym' in section 's' */
977 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
980 put_extern_sym(sym
, NULL
, 0, 0);
981 /* now we can add ELF relocation info */
982 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
985 static inline int isid(int c
)
987 return (c
>= 'a' && c
<= 'z') ||
988 (c
>= 'A' && c
<= 'Z') ||
992 static inline int isnum(int c
)
994 return c
>= '0' && c
<= '9';
997 static inline int isoct(int c
)
999 return c
>= '0' && c
<= '7';
1002 static inline int toup(int c
)
1004 if (ch
>= 'a' && ch
<= 'z')
1005 return ch
- 'a' + 'A';
1010 void printline(void)
1015 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
1016 fprintf(stderr
, "In file included from %s:%d:\n",
1017 (*f
)->filename
, (*f
)->line_num
);
1018 if (file
->line_num
> 0) {
1019 fprintf(stderr
, "%s:%d: ", file
->filename
, file
->line_num
);
1021 fprintf(stderr
, "%s: ", file
->filename
);
1024 fprintf(stderr
, "tcc: ");
1028 void error(const char *fmt
, ...)
1033 vfprintf(stderr
, fmt
, ap
);
1034 fprintf(stderr
, "\n");
1039 void expect(const char *msg
)
1041 error("%s expected", msg
);
1044 void warning(const char *fmt
, ...)
1050 fprintf(stderr
, "warning: ");
1051 vfprintf(stderr
, fmt
, ap
);
1052 fprintf(stderr
, "\n");
1059 error("'%c' expected", c
);
1063 void test_lvalue(void)
1065 if (!(vtop
->r
& VT_LVAL
))
1069 TokenSym
*tok_alloc(const char *str
, int len
)
1071 TokenSym
*ts
, **pts
, **ptable
;
1076 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
1078 pts
= &hash_ident
[h
];
1083 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1085 pts
= &(ts
->hash_next
);
1088 if (tok_ident
>= SYM_FIRST_ANOM
)
1089 error("memory full");
1091 /* expand token table if needed */
1092 i
= tok_ident
- TOK_IDENT
;
1093 if ((i
% TOK_ALLOC_INCR
) == 0) {
1094 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1096 error("memory full");
1097 table_ident
= ptable
;
1100 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1101 table_ident
[i
] = ts
;
1102 ts
->tok
= tok_ident
++;
1104 ts
->hash_next
= NULL
;
1105 memcpy(ts
->str
, str
, len
+ 1);
1110 /* CString handling */
1112 static void cstr_realloc(CString
*cstr
, int new_size
)
1117 size
= cstr
->size_allocated
;
1119 size
= 8; /* no need to allocate a too small first string */
1120 while (size
< new_size
)
1122 data
= tcc_realloc(cstr
->data_allocated
, size
);
1124 error("memory full");
1125 cstr
->data_allocated
= data
;
1126 cstr
->size_allocated
= size
;
1131 static void cstr_ccat(CString
*cstr
, int ch
)
1134 size
= cstr
->size
+ 1;
1135 if (size
> cstr
->size_allocated
)
1136 cstr_realloc(cstr
, size
);
1137 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1141 static void cstr_cat(CString
*cstr
, const char *str
)
1153 /* add a wide char */
1154 static void cstr_wccat(CString
*cstr
, int ch
)
1157 size
= cstr
->size
+ sizeof(int);
1158 if (size
> cstr
->size_allocated
)
1159 cstr_realloc(cstr
, size
);
1160 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1164 static void cstr_new(CString
*cstr
)
1166 memset(cstr
, 0, sizeof(CString
));
1169 /* free string and reset it to NULL */
1170 static void cstr_free(CString
*cstr
)
1172 tcc_free(cstr
->data_allocated
);
1176 #define cstr_reset(cstr) cstr_free(cstr)
1178 /* XXX: unicode ? */
1179 static void add_char(CString
*cstr
, int c
)
1181 if (c
== '\'' || c
== '\"' || c
== '\\') {
1182 /* XXX: could be more precise if char or string */
1183 cstr_ccat(cstr
, '\\');
1185 if (c
>= 32 && c
<= 126) {
1188 cstr_ccat(cstr
, '\\');
1190 cstr_ccat(cstr
, 'n');
1192 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1193 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1194 cstr_ccat(cstr
, '0' + (c
& 7));
1199 /* XXX: buffer overflow */
1200 /* XXX: float tokens */
1201 char *get_tok_str(int v
, CValue
*cv
)
1203 static char buf
[STRING_MAX_SIZE
+ 1];
1204 static CString cstr_buf
;
1210 /* NOTE: to go faster, we give a fixed buffer for small strings */
1211 cstr_reset(&cstr_buf
);
1212 cstr_buf
.data
= buf
;
1213 cstr_buf
.size_allocated
= sizeof(buf
);
1219 /* XXX: not exact */
1220 sprintf(p
, "%u", cv
->ui
);
1224 cstr_ccat(&cstr_buf
, '\'');
1225 add_char(&cstr_buf
, cv
->i
);
1226 cstr_ccat(&cstr_buf
, '\'');
1227 cstr_ccat(&cstr_buf
, '\0');
1232 cstr_ccat(&cstr_buf
, '\"');
1234 len
= cstr
->size
- 1;
1236 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1238 len
= (cstr
->size
/ sizeof(int)) - 1;
1240 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1242 cstr_ccat(&cstr_buf
, '\"');
1243 cstr_ccat(&cstr_buf
, '\0');
1252 return strcpy(p
, "<<=");
1254 return strcpy(p
, ">>=");
1256 if (v
< TOK_IDENT
) {
1257 /* search in two bytes table */
1271 } else if (v
< tok_ident
) {
1272 return table_ident
[v
- TOK_IDENT
]->str
;
1273 } else if (v
>= SYM_FIRST_ANOM
) {
1274 /* special name for anonymous symbol */
1275 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1277 /* should never happen */
1282 return cstr_buf
.data
;
1285 /* push, without hashing */
1286 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1289 s
= tcc_malloc(sizeof(Sym
));
1300 /* find a symbol and return its associated structure. 's' is the top
1301 of the symbol stack */
1302 Sym
*sym_find2(Sym
*s
, int v
)
1312 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1314 /* find a symbol and return its associated structure. 'st' is the
1316 Sym
*sym_find1(SymStack
*st
, int v
)
1320 s
= st
->hash
[HASH_SYM(v
)];
1329 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1332 s
= sym_push2(&st
->top
, v
, t
, c
);
1333 /* add in hash table */
1335 ps
= &st
->hash
[HASH_SYM(v
)];
1342 /* find a symbol in the right symbol space */
1343 Sym
*sym_find(int v
)
1346 s
= sym_find1(&local_stack
, v
);
1348 s
= sym_find1(&global_stack
, v
);
1352 /* push a given symbol on the symbol stack */
1353 Sym
*sym_push(int v
, int t
, int r
, int c
)
1356 if (local_stack
.top
)
1357 s
= sym_push1(&local_stack
, v
, t
, c
);
1359 s
= sym_push1(&global_stack
, v
, t
, c
);
1364 /* pop symbols until top reaches 'b' */
1365 void sym_pop(SymStack
*st
, Sym
*b
)
1372 /* free hash table entry, except if symbol was freed (only
1373 used for #undef symbols) */
1375 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1382 /* undefined a hashed symbol (used for #undef). Its name is set to
1384 void sym_undef(SymStack
*st
, Sym
*s
)
1387 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1388 while (*ss
!= NULL
) {
1391 ss
= &(*ss
)->hash_next
;
1399 BufferedFile
*tcc_open(const char *filename
)
1404 fd
= open(filename
, O_RDONLY
);
1407 bf
= tcc_malloc(sizeof(BufferedFile
));
1413 bf
->buf_ptr
= bf
->buffer
;
1414 bf
->buf_end
= bf
->buffer
;
1415 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1416 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1418 bf
->ifndef_macro
= 0;
1419 bf
->ifdef_stack_ptr
= ifdef_stack_ptr
;
1420 // printf("opening '%s'\n", filename);
1424 void tcc_close(BufferedFile
*bf
)
1426 total_lines
+= bf
->line_num
;
1431 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1432 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1434 /* fill input buffer and return next char */
1435 int tcc_getc_slow(BufferedFile
*bf
)
1438 /* only tries to read if really end of buffer */
1439 if (bf
->buf_ptr
>= bf
->buf_end
) {
1441 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1448 bf
->buf_ptr
= bf
->buffer
;
1449 bf
->buf_end
= bf
->buffer
+ len
;
1450 *bf
->buf_end
= CH_EOB
;
1452 if (bf
->buf_ptr
< bf
->buf_end
) {
1453 return *bf
->buf_ptr
++;
1455 bf
->buf_ptr
= bf
->buf_end
;
1460 /* no need to put that inline */
1461 void handle_eob(void)
1464 ch1
= tcc_getc_slow(file
);
1468 if (return_linefeed
) {
1472 if (include_stack_ptr
== include_stack
)
1474 /* add end of include file debug info */
1476 put_stabd(N_EINCL
, 0, 0);
1478 /* pop include stack */
1480 include_stack_ptr
--;
1481 file
= *include_stack_ptr
;
1485 /* read next char from current input file */
1486 static inline void inp(void)
1488 ch1
= TCC_GETC(file
);
1489 /* end of buffer/file handling */
1494 // printf("ch1=%c 0x%x\n", ch1, ch1);
1497 /* handle '\\n' and '\\r\n' */
1498 static void handle_stray(void)
1503 } else if (ch1
== '\r') {
1506 error("invalid character after '\\'");
1513 } while (ch
== '\\');
1516 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1518 static inline void minp(void)
1527 /* same as minp, but also skip comments */
1528 static void cinp(void)
1535 /* single line C++ comments */
1537 while (ch1
!= '\n' && ch1
!= CH_EOF
)
1539 ch
= ' '; /* return space */
1540 } else if (ch1
== '*') {
1543 while (ch1
!= CH_EOF
) {
1546 if (c
== '*' && ch1
== '/') {
1548 ch
= ' '; /* return space */
1560 /* space exlcuding newline */
1561 static inline int is_space(int ch
)
1563 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1566 static inline void skip_spaces(void)
1568 while (is_space(ch
))
1572 /* skip block of text until #else, #elif or #endif. skip also pairs of
1574 void preprocess_skip(void)
1579 while (ch
!= '\n') {
1590 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1592 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1594 else if (tok
== TOK_ENDIF
)
1600 /* ParseState handling */
1602 /* XXX: currently, no include file info is stored. Thus, we cannot display
1603 accurate messages if the function or data definition spans multiple
1606 /* save current parse state in 's' */
1607 void save_parse_state(ParseState
*s
)
1609 s
->line_num
= file
->line_num
;
1610 s
->macro_ptr
= macro_ptr
;
1615 /* restore parse state from 's' */
1616 void restore_parse_state(ParseState
*s
)
1618 file
->line_num
= s
->line_num
;
1619 macro_ptr
= s
->macro_ptr
;
1624 /* return the number of additionnal 'ints' necessary to store the
1626 static inline int tok_ext_size(int t
)
1644 return LDOUBLE_SIZE
/ 4;
1650 /* token string handling */
1652 static inline void tok_str_new(TokenString
*s
)
1656 s
->last_line_num
= -1;
1659 static void tok_str_free(int *str
)
1670 if (t
== TOK_STR
|| t
== TOK_LSTR
) {
1671 /* XXX: use a macro to be portable on 64 bit ? */
1672 cstr
= (CString
*)(*p
++);
1676 p
+= tok_ext_size(t
);
1682 static void tok_str_add(TokenString
*s
, int t
)
1688 if ((len
& 63) == 0) {
1689 str
= tcc_realloc(str
, (len
+ 64) * sizeof(int));
1698 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1701 CString
*cstr
, *cstr1
;
1705 if (t
== TOK_STR
|| t
== TOK_LSTR
) {
1706 /* special case: need to duplicate string */
1708 cstr
= tcc_malloc(sizeof(CString
));
1711 cstr
->size_allocated
= size
;
1712 cstr
->data_allocated
= tcc_malloc(size
);
1713 cstr
->data
= cstr
->data_allocated
;
1714 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1716 tok_str_add(s
, cv1
.tab
[0]);
1718 n
= tok_ext_size(t
);
1720 tok_str_add(s
, cv
->tab
[i
]);
1724 /* add the current parse token in token string 's' */
1725 static void tok_str_add_tok(TokenString
*s
)
1729 /* save line number info */
1730 if (file
->line_num
!= s
->last_line_num
) {
1731 s
->last_line_num
= file
->line_num
;
1732 cval
.i
= s
->last_line_num
;
1733 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1735 tok_str_add2(s
, tok
, &tokc
);
1738 /* get a token from an integer array and increment pointer accordingly */
1739 static int tok_get(int **tok_str
, CValue
*cv
)
1745 n
= tok_ext_size(t
);
1752 /* eval an expression for #if/#elif */
1753 int expr_preprocess(void)
1759 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1760 next(); /* do macro subst */
1761 if (tok
== TOK_DEFINED
) {
1766 c
= sym_find1(&define_stack
, tok
) != 0;
1771 } else if (tok
>= TOK_IDENT
) {
1772 /* if undefined macro */
1776 tok_str_add_tok(&str
);
1778 tok_str_add(&str
, -1); /* simulate end of file */
1779 tok_str_add(&str
, 0);
1780 /* now evaluate C constant expression */
1781 macro_ptr
= str
.str
;
1785 tok_str_free(str
.str
);
1789 #if defined(DEBUG) || defined(PP_DEBUG)
1790 void tok_print(int *str
)
1796 t
= tok_get(&str
, &cval
);
1799 printf(" %s", get_tok_str(t
, &cval
));
1805 /* parse after #define */
1806 void parse_define(void)
1808 Sym
*s
, *first
, **ps
;
1809 int v
, t
, varg
, is_vaargs
;
1813 /* XXX: should check if same macro (ANSI) */
1816 /* '(' must be just after macro definition for MACRO_FUNC */
1821 while (tok
!= ')') {
1825 if (varg
== TOK_DOTS
) {
1826 varg
= TOK___VA_ARGS__
;
1828 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1832 if (varg
< TOK_IDENT
)
1833 error("badly punctuated parameter list");
1834 s
= sym_push1(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1845 /* EOF testing necessary for '-D' handling */
1846 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1847 tok_str_add2(&str
, tok
, &tokc
);
1850 tok_str_add(&str
, 0);
1852 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1855 s
= sym_push1(&define_stack
, v
, t
, (int)str
.str
);
1859 /* XXX: use a token or a hash table to accelerate matching ? */
1860 static CachedInclude
*search_cached_include(int type
, const char *filename
)
1865 for(i
= 0;i
< nb_cached_includes
; i
++) {
1866 e
= cached_includes
[i
];
1867 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
1873 static inline void add_cached_include(int type
,
1874 const char *filename
, int ifndef_macro
)
1878 if (search_cached_include(type
, filename
))
1881 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
1883 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
1887 strcpy(e
->filename
, filename
);
1888 e
->ifndef_macro
= ifndef_macro
;
1889 dynarray_add((void ***)&cached_includes
, &nb_cached_includes
, e
);
1894 INCLUDE_STATE_NONE
= 0,
1895 INCLUDE_STATE_SEEK_IFNDEF
,
1898 void preprocess(void)
1901 enum IncludeState state
;
1902 char buf
[1024], *q
, *p
;
1908 return_linefeed
= 1; /* linefeed will be returned as a
1909 token. EOF is also returned as line feed */
1910 state
= INCLUDE_STATE_NONE
;
1916 if (tok
== TOK_DEFINE
) {
1919 } else if (tok
== TOK_UNDEF
) {
1921 s
= sym_find1(&define_stack
, tok
);
1922 /* undefine symbol by putting an invalid name */
1924 sym_undef(&define_stack
, s
);
1925 } else if (tok
== TOK_INCLUDE
) {
1930 } else if (ch
== '\"') {
1935 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
1936 if ((q
- buf
) < sizeof(buf
) - 1)
1941 /* eat all spaces and comments after include */
1942 /* XXX: slightly incorrect */
1943 while (ch1
!= '\n' && ch1
!= CH_EOF
)
1946 /* computed #include : either we have only strings or
1947 we have anything enclosed in '<>' */
1950 if (tok
== TOK_STR
) {
1951 while (tok
!= TOK_LINEFEED
) {
1952 if (tok
!= TOK_STR
) {
1954 error("'#include' expects \"FILENAME\" or <FILENAME>");
1956 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
1962 while (tok
!= TOK_LINEFEED
) {
1963 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
1967 /* check syntax and remove '<>' */
1968 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
1969 goto include_syntax
;
1970 memmove(buf
, buf
+ 1, len
- 2);
1971 buf
[len
- 2] = '\0';
1977 e
= search_cached_include(c
, buf
);
1978 if (e
&& sym_find1(&define_stack
, e
->ifndef_macro
)) {
1979 /* no need to parse the include because the 'ifndef macro'
1982 printf("%s: skipping %s\n", file
->filename
, buf
);
1986 /* first search in current dir if "header.h" */
1988 p
= strrchr(file
->filename
, '/');
1990 size
= p
+ 1 - file
->filename
;
1991 if (size
> sizeof(buf1
) - 1)
1992 size
= sizeof(buf1
) - 1;
1993 memcpy(buf1
, file
->filename
, size
);
1995 pstrcat(buf1
, sizeof(buf1
), buf
);
2000 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
2001 error("#include recursion too deep");
2002 /* now search in all the include paths */
2003 n
= nb_include_paths
+ nb_sysinclude_paths
;
2004 for(i
= 0; i
< n
; i
++) {
2006 if (i
< nb_include_paths
)
2007 path
= include_paths
[i
];
2009 path
= sysinclude_paths
[i
- nb_include_paths
];
2010 pstrcpy(buf1
, sizeof(buf1
), path
);
2011 pstrcat(buf1
, sizeof(buf1
), "/");
2012 pstrcat(buf1
, sizeof(buf1
), buf
);
2017 error("include file '%s' not found", buf
);
2021 printf("%s: including %s\n", file
->filename
, buf1
);
2024 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2025 /* push current file in stack */
2026 /* XXX: fix current line init */
2027 *include_stack_ptr
++ = file
;
2029 /* add include file debug info */
2031 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2033 /* we check for the construct: #ifndef IDENT \n #define IDENT */
2035 /* get first non space char */
2036 while (is_space(ch
) || ch
== '\n')
2040 state
= INCLUDE_STATE_SEEK_IFNDEF
;
2043 } else if (tok
== TOK_IFNDEF
) {
2046 } else if (tok
== TOK_IF
) {
2047 c
= expr_preprocess();
2049 } else if (tok
== TOK_IFDEF
) {
2053 if (tok
< TOK_IDENT
)
2054 error("invalid argument for '#if%sdef'", c
? "n" : "");
2055 if (state
== INCLUDE_STATE_SEEK_IFNDEF
) {
2057 file
->ifndef_macro
= tok
;
2059 state
= INCLUDE_STATE_NONE
;
2061 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
2063 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
2064 error("memory full");
2065 *ifdef_stack_ptr
++ = c
;
2067 } else if (tok
== TOK_ELSE
) {
2068 if (ifdef_stack_ptr
== ifdef_stack
)
2069 error("#else without matching #if");
2070 if (ifdef_stack_ptr
[-1] & 2)
2071 error("#else after #else");
2072 c
= (ifdef_stack_ptr
[-1] ^= 3);
2074 } else if (tok
== TOK_ELIF
) {
2075 if (ifdef_stack_ptr
== ifdef_stack
)
2076 error("#elif without matching #if");
2077 c
= ifdef_stack_ptr
[-1];
2079 error("#elif after #else");
2080 /* last #if/#elif expression was true: we skip */
2083 c
= expr_preprocess();
2084 ifdef_stack_ptr
[-1] = c
;
2089 state
= INCLUDE_STATE_NONE
;
2092 } else if (tok
== TOK_ENDIF
) {
2093 if (ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2094 error("#endif without matching #if");
2095 if (file
->ifndef_macro
&&
2096 ifdef_stack_ptr
== (file
->ifdef_stack_ptr
+ 1)) {
2097 /* '#ifndef macro \n #define macro' was at the start of
2098 file. Now we check if an '#endif' is exactly at the end
2100 while (tok
!= TOK_LINEFEED
)
2102 /* XXX: should also skip comments, but it is more complicated */
2104 add_cached_include(file
->inc_type
, file
->inc_filename
,
2105 file
->ifndef_macro
);
2107 /* if not end of file, we must desactivate the ifndef
2109 file
->ifndef_macro
= 0;
2113 } else if (tok
== TOK_LINE
) {
2116 if (tok
!= TOK_CINT
)
2120 if (tok
!= TOK_LINEFEED
) {
2123 pstrcpy(file
->filename
, sizeof(file
->filename
),
2124 (char *)tokc
.cstr
->data
);
2126 /* NOTE: we do it there to avoid problems with linefeed */
2127 file
->line_num
= line_num
;
2128 } else if (tok
== TOK_ERROR
) {
2131 /* ignore other preprocess commands or #! for C scripts */
2132 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
)
2135 return_linefeed
= 0;
2138 /* read a number in base b */
2139 static int getn(int b
)
2144 if (ch
>= 'a' && ch
<= 'f')
2146 else if (ch
>= 'A' && ch
<= 'F')
2152 if (t
< 0 || t
>= b
)
2160 /* read a character for string or char constant and eval escape codes */
2161 static int getq(void)
2169 /* at most three octal digits */
2173 c
= c
* 8 + ch
- '0';
2176 c
= c
* 8 + ch
- '0';
2181 } else if (ch
== 'x') {
2199 else if (ch
== 'e' && gnu_ext
)
2201 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
2204 error("invalid escaped char");
2207 } else if (c
== '\r' && ch
== '\n') {
2214 /* we use 64 bit numbers */
2217 /* bn = (bn << shift) | or_val */
2218 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2222 for(i
=0;i
<BN_SIZE
;i
++) {
2224 bn
[i
] = (v
<< shift
) | or_val
;
2225 or_val
= v
>> (32 - shift
);
2229 void bn_zero(unsigned int *bn
)
2232 for(i
=0;i
<BN_SIZE
;i
++) {
2237 void parse_number(void)
2239 int b
, t
, shift
, frac_bits
, s
, exp_val
;
2241 unsigned int bn
[BN_SIZE
];
2251 /* special dot handling */
2252 if (ch
>= '0' && ch
<= '9') {
2253 goto float_frac_parse
;
2254 } else if (ch
== '.') {
2265 } else if (t
== '0') {
2266 if (ch
== 'x' || ch
== 'X') {
2270 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2276 /* parse all digits. cannot check octal numbers at this stage
2277 because of floating point constants */
2279 if (ch
>= 'a' && ch
<= 'f')
2281 else if (ch
>= 'A' && ch
<= 'F')
2289 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2291 error("number too long");
2297 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2298 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2300 /* NOTE: strtox should support that for hexa numbers, but
2301 non ISOC99 libcs do not support it, so we prefer to do
2303 /* hexadecimal or binary floats */
2304 /* XXX: handle overflows */
2316 } else if (t
>= 'a') {
2318 } else if (t
>= 'A') {
2323 bn_lshift(bn
, shift
, t
);
2330 if (t
>= 'a' && t
<= 'f') {
2332 } else if (t
>= 'A' && t
<= 'F') {
2334 } else if (t
>= '0' && t
<= '9') {
2340 error("invalid digit");
2341 bn_lshift(bn
, shift
, t
);
2346 if (ch
!= 'p' && ch
!= 'P')
2347 error("exponent expected");
2353 } else if (ch
== '-') {
2357 if (ch
< '0' || ch
> '9')
2358 error("exponent digits expected");
2359 while (ch
>= '0' && ch
<= '9') {
2360 exp_val
= exp_val
* 10 + ch
- '0';
2363 exp_val
= exp_val
* s
;
2365 /* now we can generate the number */
2366 /* XXX: should patch directly float number */
2367 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
2368 d
= ldexp(d
, exp_val
- frac_bits
);
2373 /* float : should handle overflow */
2375 } else if (t
== 'L') {
2378 /* XXX: not large enough */
2379 tokc
.ld
= (long double)d
;
2385 /* decimal floats */
2387 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2392 while (ch
>= '0' && ch
<= '9') {
2393 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2399 if (ch
== 'e' || ch
== 'E') {
2400 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2404 if (ch
== '-' || ch
== '+') {
2405 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2410 if (ch
< '0' || ch
> '9')
2411 error("exponent digits expected");
2412 while (ch
>= '0' && ch
<= '9') {
2413 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2425 tokc
.f
= strtof(token_buf
, NULL
);
2426 } else if (t
== 'L') {
2429 tokc
.ld
= strtold(token_buf
, NULL
);
2432 tokc
.d
= strtod(token_buf
, NULL
);
2436 unsigned long long n
, n1
;
2439 /* integer number */
2442 if (b
== 10 && *q
== '0') {
2449 /* no need for checks except for base 10 / 8 errors */
2452 } else if (t
>= 'a') {
2454 } else if (t
>= 'A') {
2459 error("invalid digit");
2463 /* detect overflow */
2465 error("integer constant overflow");
2468 /* XXX: not exactly ANSI compliant */
2469 if ((n
& 0xffffffff00000000LL
) != 0) {
2474 } else if (n
> 0x7fffffff) {
2484 error("three 'l' in integer constant");
2487 if (tok
== TOK_CINT
)
2489 else if (tok
== TOK_CUINT
)
2493 } else if (t
== 'U') {
2494 if (tok
== TOK_CINT
)
2496 else if (tok
== TOK_CLLONG
)
2503 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2511 /* return next token without macro substitution */
2512 static inline void next_nomacro1(void)
2520 while (ch
== '\n') {
2521 /* during preprocessor parsing, '\n' is a token */
2522 if (return_linefeed
) {
2529 /* preprocessor command if # at start of line after
2552 while (isid(ch
) || isnum(ch
)) {
2553 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2554 error("ident too long");
2559 ts
= tok_alloc(token_buf
, q
- token_buf
);
2561 } else if (isnum(ch
) || ch
== '.') {
2563 } else if (ch
== '\'') {
2568 /* this cast is needed if >= 128 */
2569 if (tok
== TOK_CCHAR
)
2575 } else if (ch
== '\"') {
2579 cstr_reset(&tokcstr
);
2580 while (ch
!= '\"') {
2583 error("unterminated string");
2585 cstr_ccat(&tokcstr
, b
);
2587 cstr_wccat(&tokcstr
, b
);
2590 cstr_ccat(&tokcstr
, '\0');
2592 cstr_wccat(&tokcstr
, '\0');
2593 tokc
.cstr
= &tokcstr
;
2601 if (*q
== tok
&& q
[1] == ch
) {
2604 /* three chars tests */
2605 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2610 } else if (tok
== TOK_DOTS
) {
2612 error("parse error");
2619 /* single char substitutions */
2622 else if (tok
== '>')
2627 /* return next token without macro substitution. Can read input from
2635 tok
= tok_get(¯o_ptr
, &tokc
);
2636 if (tok
== TOK_LINENUM
) {
2637 file
->line_num
= tokc
.i
;
2646 /* substitute args in macro_str and return allocated string */
2647 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2649 int *st
, last_tok
, t
, notfirst
;
2658 t
= tok_get(¯o_str
, &cval
);
2663 t
= tok_get(¯o_str
, &cval
);
2666 s
= sym_find2(args
, t
);
2673 cstr_ccat(&cstr
, ' ');
2674 t
= tok_get(&st
, &cval
);
2675 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
2678 cstr_ccat(&cstr
, '\0');
2680 printf("stringize: %s\n", (char *)cstr
.data
);
2684 tok_str_add2(&str
, TOK_STR
, &cval
);
2687 tok_str_add2(&str
, t
, &cval
);
2689 } else if (t
>= TOK_IDENT
) {
2690 s
= sym_find2(args
, t
);
2693 /* if '##' is present before or after, no arg substitution */
2694 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2695 /* special case for var arg macros : ## eats the
2696 ',' if empty VA_ARGS riable. */
2697 /* XXX: test of the ',' is not 100%
2698 reliable. should fix it to avoid security
2700 if (gnu_ext
&& s
->t
&& *st
== 0 &&
2701 last_tok
== TOK_TWOSHARPS
&&
2702 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
2703 /* suppress ',' '##' */
2708 t1
= tok_get(&st
, &cval
);
2711 tok_str_add2(&str
, t1
, &cval
);
2715 macro_subst(&str
, nested_list
, st
);
2718 tok_str_add(&str
, t
);
2721 tok_str_add2(&str
, t
, &cval
);
2725 tok_str_add(&str
, 0);
2729 /* handle the '##' operator */
2730 static int *macro_twosharps(void)
2737 TokenString macro_str1
;
2739 tok_str_new(¯o_str1
);
2745 while (*macro_ptr
== TOK_TWOSHARPS
) {
2747 macro_ptr1
= macro_ptr
;
2750 t
= tok_get(¯o_ptr
, &cval
);
2751 /* XXX: we handle only most common cases:
2752 ident + ident or ident + number */
2753 if (tok
>= TOK_IDENT
&&
2754 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
2755 p
= get_tok_str(tok
, &tokc
);
2756 pstrcpy(token_buf
, sizeof(token_buf
), p
);
2757 p
= get_tok_str(t
, &cval
);
2758 pstrcat(token_buf
, sizeof(token_buf
), p
);
2759 ts
= tok_alloc(token_buf
, strlen(token_buf
));
2760 tok
= ts
->tok
; /* modify current token */
2762 /* cannot merge tokens: skip '##' */
2763 macro_ptr
= macro_ptr1
;
2768 tok_str_add2(¯o_str1
, tok
, &tokc
);
2770 tok_str_add(¯o_str1
, 0);
2771 return macro_str1
.str
;
2775 /* do macro substitution of current token with macro 's' and add
2776 result to (tok_str,tok_len). 'nested_list' is the list of all
2777 macros we got inside to avoid recursing. Return non zero if no
2778 substitution needs to be done */
2779 static int macro_subst_tok(TokenString
*tok_str
,
2780 Sym
**nested_list
, Sym
*s
)
2782 Sym
*args
, *sa
, *sa1
;
2783 int mstr_allocated
, parlevel
, *mstr
, t
;
2789 /* if symbol is a macro, prepare substitution */
2790 /* if nested substitution, do nothing */
2791 if (sym_find2(*nested_list
, tok
))
2794 /* special macros */
2795 if (tok
== TOK___LINE__
) {
2796 cval
.i
= file
->line_num
;
2797 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
2798 } else if (tok
== TOK___FILE__
) {
2799 cstrval
= file
->filename
;
2801 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2802 } else if (tok
== TOK___DATE__
) {
2803 cstrval
= "Jan 1 2002";
2805 } else if (tok
== TOK___TIME__
) {
2806 cstrval
= "00:00:00";
2809 cstr_cat(&cstr
, cstrval
);
2810 cstr_ccat(&cstr
, '\0');
2812 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2817 if (s
->t
== MACRO_FUNC
) {
2818 /* NOTE: we do not use next_nomacro to avoid eating the
2819 next token. XXX: find better solution */
2823 while (is_space(ch
) || ch
== '\n')
2827 if (t
!= '(') /* no macro subst */
2830 /* argument macro */
2835 /* NOTE: empty args are allowed, except if no args */
2837 /* handle '()' case */
2838 if (!args
&& tok
== ')')
2841 error("macro '%s' used with too many args",
2842 get_tok_str(s
->v
, 0));
2845 /* NOTE: non zero sa->t indicates VA_ARGS */
2846 while ((parlevel
> 0 ||
2848 (tok
!= ',' || sa
->t
))) &&
2852 else if (tok
== ')')
2854 tok_str_add2(&str
, tok
, &tokc
);
2857 tok_str_add(&str
, 0);
2858 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->t
, (int)str
.str
);
2861 /* special case for gcc var args: add an empty
2862 var arg argument if it is omitted */
2863 if (sa
&& sa
->t
&& gnu_ext
)
2873 error("macro '%s' used with too few args",
2874 get_tok_str(s
->v
, 0));
2877 /* now subst each arg */
2878 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2883 tok_str_free((int *)sa
->c
);
2889 sym_push2(nested_list
, s
->v
, 0, 0);
2890 macro_subst(tok_str
, nested_list
, mstr
);
2891 /* pop nested defined symbol */
2893 *nested_list
= sa1
->prev
;
2901 /* do macro substitution of macro_str and add result to
2902 (tok_str,tok_len). 'nested_list' is the list of all macros we got
2903 inside to avoid recursing. */
2904 static void macro_subst(TokenString
*tok_str
,
2905 Sym
**nested_list
, int *macro_str
)
2908 int *saved_macro_ptr
;
2911 saved_macro_ptr
= macro_ptr
;
2912 macro_ptr
= macro_str
;
2913 /* first scan for '##' operator handling */
2914 macro_str1
= macro_twosharps();
2915 macro_ptr
= macro_str1
;
2921 s
= sym_find1(&define_stack
, tok
);
2923 if (macro_subst_tok(tok_str
, nested_list
, s
) != 0)
2927 tok_str_add2(tok_str
, tok
, &tokc
);
2930 macro_ptr
= saved_macro_ptr
;
2931 tok_str_free(macro_str1
);
2934 /* return next token with macro substitution */
2937 Sym
*nested_list
, *s
;
2940 /* special 'ungettok' case for label parsing */
2949 /* if not reading from macro substituted string, then try
2950 to substitute macros */
2951 if (tok
>= TOK_IDENT
) {
2952 s
= sym_find1(&define_stack
, tok
);
2954 /* we have a macro: we try to substitute */
2957 if (macro_subst_tok(&str
, &nested_list
, s
) == 0) {
2958 /* substitution done, NOTE: maybe empty */
2959 tok_str_add(&str
, 0);
2960 macro_ptr
= str
.str
;
2961 macro_ptr_allocated
= str
.str
;
2968 /* end of macro string: free it */
2969 tok_str_free(macro_ptr_allocated
);
2976 printf("token = %s\n", get_tok_str(tok
, &tokc
));
2980 void swap(int *p
, int *q
)
2988 void vsetc(int t
, int r
, CValue
*vc
)
2992 if (vtop
>= vstack
+ VSTACK_SIZE
)
2993 error("memory full");
2994 /* cannot let cpu flags if other instruction are generated. Also
2995 avoid leaving VT_JMP anywhere except on the top of the stack
2996 because it would complicate the code generator. */
2997 if (vtop
>= vstack
) {
2998 v
= vtop
->r
& VT_VALMASK
;
2999 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
3005 vtop
->r2
= VT_CONST
;
3009 /* push integer constant */
3014 vsetc(VT_INT
, VT_CONST
, &cval
);
3017 /* Return a static symbol pointing to a section */
3018 static Sym
*get_sym_ref(int t
, Section
*sec
,
3019 unsigned long offset
, unsigned long size
)
3025 sym
= sym_push1(&global_stack
, v
, t
| VT_STATIC
, 0);
3026 sym
->r
= VT_CONST
| VT_SYM
;
3027 put_extern_sym(sym
, sec
, offset
, size
);
3031 /* push a reference to a section offset by adding a dummy symbol */
3032 static void vpush_ref(int t
, Section
*sec
, unsigned long offset
, unsigned long size
)
3037 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
3038 vtop
->sym
= get_sym_ref(t
, sec
, offset
, size
);
3041 /* define a new external reference to a symbol 'v' of type 'u' */
3042 static Sym
*external_global_sym(int v
, int u
, int r
)
3048 /* push forward reference */
3049 s
= sym_push1(&global_stack
,
3050 v
, u
| VT_EXTERN
, 0);
3051 s
->r
= r
| VT_CONST
| VT_SYM
;
3056 /* define a new external reference to a symbol 'v' of type 'u' */
3057 static Sym
*external_sym(int v
, int u
, int r
)
3063 /* push forward reference */
3064 s
= sym_push(v
, u
| VT_EXTERN
, r
| VT_CONST
| VT_SYM
, 0);
3069 /* push a reference to global symbol v */
3070 static void vpush_global_sym(int t
, int v
)
3075 sym
= external_global_sym(v
, t
, 0);
3077 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
3081 void vset(int t
, int r
, int v
)
3098 void vpushv(SValue
*v
)
3100 if (vtop
>= vstack
+ VSTACK_SIZE
)
3101 error("memory full");
3111 /* save r to the memory stack, and mark it as being free */
3112 void save_reg(int r
)
3114 int l
, saved
, t
, size
, align
;
3117 /* modify all stack values */
3120 for(p
=vstack
;p
<=vtop
;p
++) {
3121 if ((p
->r
& VT_VALMASK
) == r
||
3122 (p
->r2
& VT_VALMASK
) == r
) {
3123 /* must save value on stack if not already done */
3125 /* store register in the stack */
3127 if ((p
->r
& VT_LVAL
) ||
3128 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
3130 size
= type_size(t
, &align
);
3131 loc
= (loc
- size
) & -align
;
3133 sv
.r
= VT_LOCAL
| VT_LVAL
;
3136 #ifdef TCC_TARGET_I386
3137 /* x86 specific: need to pop fp register ST0 if saved */
3139 o(0xd9dd); /* fstp %st(1) */
3142 /* special long long case */
3143 if ((t
& VT_BTYPE
) == VT_LLONG
) {
3150 /* mark that stack entry as being saved on the stack */
3151 if (p
->r
& VT_LVAL
) {
3152 /* also suppress the bounded flag because the
3153 relocation address of the function was stored in
3155 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
3157 p
->r
= lvalue_type(p
->t
) | VT_LOCAL
;
3165 /* find a free register of class 'rc'. If none, save one register */
3171 /* find a free register */
3172 for(r
=0;r
<NB_REGS
;r
++) {
3173 if (reg_classes
[r
] & rc
) {
3174 for(p
=vstack
;p
<=vtop
;p
++) {
3175 if ((p
->r
& VT_VALMASK
) == r
||
3176 (p
->r2
& VT_VALMASK
) == r
)
3184 /* no register left : free the first one on the stack (VERY
3185 IMPORTANT to start from the bottom to ensure that we don't
3186 spill registers used in gen_opi()) */
3187 for(p
=vstack
;p
<=vtop
;p
++) {
3188 r
= p
->r
& VT_VALMASK
;
3189 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
3197 /* save registers up to (vtop - n) stack entry */
3198 void save_regs(int n
)
3203 for(p
= vstack
;p
<= p1
; p
++) {
3204 r
= p
->r
& VT_VALMASK
;
3211 /* move register 's' to 'r', and flush previous value of r to memory
3213 void move_reg(int r
, int s
)
3226 /* get address of vtop (vtop MUST BE an lvalue) */
3229 vtop
->r
&= ~VT_LVAL
;
3230 /* tricky: if saved lvalue, then we can go back to lvalue */
3231 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
3232 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
3235 #ifdef CONFIG_TCC_BCHECK
3236 /* generate lvalue bound code */
3241 vtop
->r
&= ~VT_MUSTBOUND
;
3242 /* if lvalue, then use checking code before dereferencing */
3243 if (vtop
->r
& VT_LVAL
) {
3244 /* if not VT_BOUNDED value, then make one */
3245 if (!(vtop
->r
& VT_BOUNDED
)) {
3246 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
3247 /* must save type because we must set it to int to get pointer */
3252 gen_bounded_ptr_add();
3253 vtop
->r
|= lval_type
;
3256 /* then check for dereferencing */
3257 gen_bounded_ptr_deref();
3262 /* store vtop a register belonging to class 'rc'. lvalues are
3263 converted to values. Cannot be used if cannot be converted to
3264 register value (such as structures). */
3267 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
3268 unsigned long long ll
;
3270 /* NOTE: get_reg can modify vstack[] */
3271 if (vtop
->t
& VT_BITFIELD
) {
3272 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
3273 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3274 /* remove bit field info to avoid loops */
3275 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3276 /* generate shifts */
3277 vpushi(32 - (bit_pos
+ bit_size
));
3279 vpushi(32 - bit_size
);
3280 /* NOTE: transformed to SHR if unsigned */
3284 if (is_float(vtop
->t
) &&
3285 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3288 unsigned long offset
;
3290 /* XXX: unify with initializers handling ? */
3291 /* CPUs usually cannot use float constants, so we store them
3292 generically in data segment */
3293 size
= type_size(vtop
->t
, &align
);
3294 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
3295 data_section
->data_offset
= offset
;
3296 /* XXX: not portable yet */
3297 ptr
= section_ptr_add(data_section
, size
);
3300 ptr
[i
] = vtop
->c
.tab
[i
];
3301 sym
= get_sym_ref(vtop
->t
, data_section
, offset
, size
<< 2);
3302 vtop
->r
|= VT_LVAL
| VT_SYM
;
3306 #ifdef CONFIG_TCC_BCHECK
3307 if (vtop
->r
& VT_MUSTBOUND
)
3311 r
= vtop
->r
& VT_VALMASK
;
3312 /* need to reload if:
3314 - lvalue (need to dereference pointer)
3315 - already a register, but not in the right class */
3316 if (r
>= VT_CONST
||
3317 (vtop
->r
& VT_LVAL
) ||
3318 !(reg_classes
[r
] & rc
) ||
3319 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
3320 !(reg_classes
[vtop
->r2
] & rc
))) {
3322 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
3323 /* two register type load : expand to two words
3325 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3328 vtop
->c
.ui
= ll
; /* first word */
3330 vtop
->r
= r
; /* save register value */
3331 vpushi(ll
>> 32); /* second word */
3332 } else if (r
>= VT_CONST
||
3333 (vtop
->r
& VT_LVAL
)) {
3334 /* load from memory */
3337 vtop
[-1].r
= r
; /* save register value */
3338 /* increment pointer to get second word */
3345 /* move registers */
3348 vtop
[-1].r
= r
; /* save register value */
3349 vtop
->r
= vtop
[-1].r2
;
3351 /* allocate second register */
3358 /* write second register */
3360 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
3362 /* lvalue of scalar type : need to use lvalue type
3363 because of possible cast */
3366 /* compute memory access type */
3367 if (vtop
->r
& VT_LVAL_BYTE
)
3369 else if (vtop
->r
& VT_LVAL_SHORT
)
3371 if (vtop
->r
& VT_LVAL_UNSIGNED
)
3375 /* restore wanted type */
3378 /* one register type load */
3387 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3388 void gv2(int rc1
, int rc2
)
3392 /* generate more generic register first. But VT_JMP or VT_CMP
3393 values must be generated first in all cases to avoid possible
3395 v
= vtop
[0].r
& VT_VALMASK
;
3396 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
3401 /* test if reload is needed for first register */
3402 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
3412 /* test if reload is needed for first register */
3413 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
3419 /* expand long long on stack in two int registers */
3424 u
= vtop
->t
& VT_UNSIGNED
;
3427 vtop
[0].r
= vtop
[-1].r2
;
3428 vtop
[0].r2
= VT_CONST
;
3429 vtop
[-1].r2
= VT_CONST
;
3430 vtop
[0].t
= VT_INT
| u
;
3431 vtop
[-1].t
= VT_INT
| u
;
3434 /* build a long long from two ints */
3437 gv2(RC_INT
, RC_INT
);
3438 vtop
[-1].r2
= vtop
[0].r
;
3443 /* rotate n first stack elements to the bottom */
3450 for(i
=-n
+1;i
!=0;i
++)
3451 vtop
[i
] = vtop
[i
+1];
3455 /* pop stack value */
3459 v
= vtop
->r
& VT_VALMASK
;
3460 #ifdef TCC_TARGET_I386
3461 /* for x86, we need to pop the FP stack */
3463 o(0xd9dd); /* fstp %st(1) */
3466 if (v
== VT_JMP
|| v
== VT_JMPI
) {
3467 /* need to put correct jump if && or || without test */
3473 /* convert stack entry to register and duplicate its value in another
3481 if ((t
& VT_BTYPE
) == VT_LLONG
) {
3488 /* stack: H L L1 H1 */
3496 /* duplicate value */
3507 load(r1
, &sv
); /* move r to r1 */
3509 /* duplicates value */
3514 /* generate CPU independent (unsigned) long long operations */
3515 void gen_opl(int op
)
3517 int t
, a
, b
, op1
, c
, i
;
3525 func
= TOK___divdi3
;
3528 func
= TOK___udivdi3
;
3531 func
= TOK___moddi3
;
3534 func
= TOK___umoddi3
;
3536 /* call generic long long function */
3537 gfunc_start(&gf
, FUNC_CDECL
);
3540 vpush_global_sym(func_old_type
, func
);
3544 vtop
->r2
= REG_LRET
;
3557 /* stack: L1 H1 L2 H2 */
3562 vtop
[-2] = vtop
[-3];
3565 /* stack: H1 H2 L1 L2 */
3571 /* stack: H1 H2 L1 L2 ML MH */
3574 /* stack: ML MH H1 H2 L1 L2 */
3578 /* stack: ML MH H1 L2 H2 L1 */
3583 /* stack: ML MH M1 M2 */
3586 } else if (op
== '+' || op
== '-') {
3587 /* XXX: add non carry method too (for MIPS or alpha) */
3593 /* stack: H1 H2 (L1 op L2) */
3596 gen_op(op1
+ 1); /* TOK_xxxC2 */
3599 /* stack: H1 H2 (L1 op L2) */
3602 /* stack: (L1 op L2) H1 H2 */
3604 /* stack: (L1 op L2) (H1 op H2) */
3612 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3617 /* stack: L H shift */
3619 /* constant: simpler */
3620 /* NOTE: all comments are for SHL. the other cases are
3621 done by swaping words */
3632 if (op
!= TOK_SAR
) {
3662 /* XXX: should provide a faster fallback on x86 ? */
3665 func
= TOK___sardi3
;
3668 func
= TOK___shrdi3
;
3671 func
= TOK___shldi3
;
3677 /* compare operations */
3683 /* stack: L1 H1 L2 H2 */
3685 vtop
[-1] = vtop
[-2];
3687 /* stack: L1 L2 H1 H2 */
3690 /* when values are equal, we need to compare low words. since
3691 the jump is inverted, we invert the test too. */
3694 else if (op1
== TOK_GT
)
3696 else if (op1
== TOK_ULT
)
3698 else if (op1
== TOK_UGT
)
3703 if (op1
!= TOK_NE
) {
3707 /* generate non equal test */
3708 /* XXX: NOT PORTABLE yet */
3712 #ifdef TCC_TARGET_I386
3713 b
= psym(0x850f, 0);
3715 error("not implemented");
3723 vset(VT_INT
, VT_JMPI
, a
);
3728 /* handle integer constant optimizations and various machine
3730 void gen_opic(int op
)
3737 /* currently, we cannot do computations with forward symbols */
3738 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3739 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3743 case '+': v1
->c
.i
+= fc
; break;
3744 case '-': v1
->c
.i
-= fc
; break;
3745 case '&': v1
->c
.i
&= fc
; break;
3746 case '^': v1
->c
.i
^= fc
; break;
3747 case '|': v1
->c
.i
|= fc
; break;
3748 case '*': v1
->c
.i
*= fc
; break;
3755 /* if division by zero, generate explicit division */
3758 error("division by zero in constant");
3762 default: v1
->c
.i
/= fc
; break;
3763 case '%': v1
->c
.i
%= fc
; break;
3764 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3765 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3768 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3769 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3770 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3772 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3773 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3774 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3775 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3776 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3777 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3778 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3779 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3780 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3781 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3783 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3784 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3790 /* if commutative ops, put c2 as constant */
3791 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3792 op
== '|' || op
== '*')) {
3797 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3800 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3801 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3807 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3808 /* try to use shifts instead of muls or divs */
3809 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3818 else if (op
== TOK_PDIV
)
3824 } else if (c2
&& (op
== '+' || op
== '-') &&
3825 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
3826 (VT_CONST
| VT_SYM
)) {
3827 /* symbol + constant case */
3834 /* call low level op generator */
3840 /* generate a floating point operation with constant propagation */
3841 void gen_opif(int op
)
3849 /* currently, we cannot do computations with forward symbols */
3850 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3851 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3853 if (v1
->t
== VT_FLOAT
) {
3856 } else if (v1
->t
== VT_DOUBLE
) {
3864 /* NOTE: we only do constant propagation if finite number (not
3865 NaN or infinity) (ANSI spec) */
3866 if (!ieee_finite(f1
) || !ieee_finite(f2
))
3870 case '+': f1
+= f2
; break;
3871 case '-': f1
-= f2
; break;
3872 case '*': f1
*= f2
; break;
3876 error("division by zero in constant");
3881 /* XXX: also handles tests ? */
3885 /* XXX: overflow test ? */
3886 if (v1
->t
== VT_FLOAT
) {
3888 } else if (v1
->t
== VT_DOUBLE
) {
3900 int pointed_size(int t
)
3902 return type_size(pointed_type(t
), &t
);
3906 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3908 char buf1
[256], buf2
[256];
3912 if (!is_compatible_types(t1
, t2
)) {
3913 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3914 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3915 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3920 /* generic gen_op: handles types problems */
3923 int u
, t1
, t2
, bt1
, bt2
, t
;
3927 bt1
= t1
& VT_BTYPE
;
3928 bt2
= t2
& VT_BTYPE
;
3930 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3931 /* at least one operand is a pointer */
3932 /* relationnal op: must be both pointers */
3933 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3934 // check_pointer_types(vtop, vtop - 1);
3935 /* pointers are handled are unsigned */
3936 t
= VT_INT
| VT_UNSIGNED
;
3939 /* if both pointers, then it must be the '-' op */
3940 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3941 (t2
& VT_BTYPE
) == VT_PTR
) {
3943 error("cannot use pointers here");
3944 // check_pointer_types(vtop - 1, vtop);
3945 /* XXX: check that types are compatible */
3946 u
= pointed_size(t1
);
3948 /* set to integer type */
3953 /* exactly one pointer : must be '+' or '-'. */
3954 if (op
!= '-' && op
!= '+')
3955 error("cannot use pointers here");
3956 /* Put pointer as first operand */
3957 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3961 /* XXX: cast to int ? (long long case) */
3962 vpushi(pointed_size(vtop
[-1].t
));
3964 #ifdef CONFIG_TCC_BCHECK
3965 /* if evaluating constant expression, no code should be
3966 generated, so no bound check */
3967 if (do_bounds_check
&& !const_wanted
) {
3968 /* if bounded pointers, we generate a special code to
3975 gen_bounded_ptr_add();
3981 /* put again type if gen_opic() swaped operands */
3984 } else if (is_float(bt1
) || is_float(bt2
)) {
3985 /* compute bigger type and do implicit casts */
3986 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3988 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3993 /* floats can only be used for a few operations */
3994 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3995 (op
< TOK_ULT
|| op
> TOK_GT
))
3996 error("invalid operands for binary operation");
3998 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3999 /* cast to biggest op */
4001 /* convert to unsigned if it does not fit in a long long */
4002 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4003 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4007 /* integer operations */
4009 /* convert to unsigned if it does not fit in an integer */
4010 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4011 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4014 /* XXX: currently, some unsigned operations are explicit, so
4015 we modify them here */
4016 if (t
& VT_UNSIGNED
) {
4023 else if (op
== TOK_LT
)
4025 else if (op
== TOK_GT
)
4027 else if (op
== TOK_LE
)
4029 else if (op
== TOK_GE
)
4035 /* special case for shifts and long long: we keep the shift as
4037 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
4043 else if ((t
& VT_BTYPE
) == VT_LLONG
)
4047 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4048 /* relationnal op: the result is an int */
4056 /* generic itof for unsigned long long case */
4057 void gen_cvt_itof1(int t
)
4061 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
4062 (VT_LLONG
| VT_UNSIGNED
)) {
4064 gfunc_start(&gf
, FUNC_CDECL
);
4067 vpush_global_sym(func_old_type
, TOK___ulltof
);
4068 else if (t
== VT_DOUBLE
)
4069 vpush_global_sym(func_old_type
, TOK___ulltod
);
4071 vpush_global_sym(func_old_type
, TOK___ulltold
);
4080 /* generic ftoi for unsigned long long case */
4081 void gen_cvt_ftoi1(int t
)
4086 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
4087 /* not handled natively */
4088 gfunc_start(&gf
, FUNC_CDECL
);
4089 st
= vtop
->t
& VT_BTYPE
;
4092 vpush_global_sym(func_old_type
, TOK___fixunssfdi
);
4093 else if (st
== VT_DOUBLE
)
4094 vpush_global_sym(func_old_type
, TOK___fixunsdfdi
);
4096 vpush_global_sym(func_old_type
, TOK___fixunsxfdi
);
4100 vtop
->r2
= REG_LRET
;
4106 /* force char or short cast */
4107 void force_charshort_cast(int t
)
4111 /* XXX: add optimization if lvalue : just change type and offset */
4116 if (t
& VT_UNSIGNED
) {
4117 vpushi((1 << bits
) - 1);
4128 /* cast 'vtop' to 't' type */
4129 void gen_cast(int t
)
4131 int sbt
, dbt
, sf
, df
, c
;
4133 /* special delayed cast for char/short */
4134 /* XXX: in some cases (multiple cascaded casts), it may still
4136 if (vtop
->r
& VT_MUSTCAST
) {
4137 vtop
->r
&= ~VT_MUSTCAST
;
4138 force_charshort_cast(vtop
->t
);
4141 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
4142 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
4147 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4149 /* convert from fp to fp */
4151 /* constant case: we can do it now */
4152 /* XXX: in ISOC, cannot do it if error in convert */
4153 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
4154 vtop
->c
.f
= (float)vtop
->c
.d
;
4155 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
4156 vtop
->c
.f
= (float)vtop
->c
.ld
;
4157 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
4158 vtop
->c
.d
= (double)vtop
->c
.f
;
4159 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
4160 vtop
->c
.d
= (double)vtop
->c
.ld
;
4161 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
4162 vtop
->c
.ld
= (long double)vtop
->c
.f
;
4163 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
4164 vtop
->c
.ld
= (long double)vtop
->c
.d
;
4166 /* non constant case: generate code */
4170 /* convert int to fp */
4173 case VT_LLONG
| VT_UNSIGNED
:
4175 /* XXX: add const cases for long long */
4177 case VT_INT
| VT_UNSIGNED
:
4179 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
4180 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
4181 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
4186 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
4187 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
4188 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
4197 /* convert fp to int */
4198 /* we handle char/short/etc... with generic code */
4199 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
4200 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
4205 case VT_LLONG
| VT_UNSIGNED
:
4207 /* XXX: add const cases for long long */
4209 case VT_INT
| VT_UNSIGNED
:
4211 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4212 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4213 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4219 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4220 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4221 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4229 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
4230 /* additionnal cast for char/short/bool... */
4234 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
4235 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
4236 /* scalar to long long */
4238 if (sbt
== (VT_INT
| VT_UNSIGNED
))
4239 vtop
->c
.ll
= vtop
->c
.ui
;
4241 vtop
->c
.ll
= vtop
->c
.i
;
4243 /* machine independant conversion */
4245 /* generate high word */
4246 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
4254 /* patch second register */
4255 vtop
[-1].r2
= vtop
->r
;
4259 } else if (dbt
== VT_BOOL
) {
4260 /* scalar to bool */
4263 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
4264 (dbt
& VT_BTYPE
) == VT_SHORT
) {
4265 force_charshort_cast(t
);
4266 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
4268 if (sbt
== VT_LLONG
) {
4269 /* from long long: just take low order word */
4273 /* if lvalue and single word type, nothing to do because
4274 the lvalue already contains the real type size (see
4275 VT_LVAL_xxx constants) */
4281 /* return type size. Put alignment at 'a' */
4282 int type_size(int t
, int *a
)
4288 if (bt
== VT_STRUCT
) {
4290 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4291 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
4293 } else if (bt
== VT_PTR
) {
4295 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4296 return type_size(s
->t
, a
) * s
->c
;
4301 } else if (bt
== VT_LDOUBLE
) {
4303 return LDOUBLE_SIZE
;
4304 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
4307 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
4310 } else if (bt
== VT_SHORT
) {
4314 /* char, void, function, _Bool */
4320 /* return the pointed type of t */
4321 int pointed_type(int t
)
4324 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4325 return s
->t
| (t
& ~VT_TYPE
);
4328 int mk_pointer(int t
)
4332 sym_push(p
, t
, 0, -1);
4333 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
4336 int is_compatible_types(int t1
, int t2
)
4343 bt1
= t1
& VT_BTYPE
;
4344 bt2
= t2
& VT_BTYPE
;
4345 if (bt1
== VT_PTR
) {
4346 t1
= pointed_type(t1
);
4347 /* if function, then convert implicitely to function pointer */
4348 if (bt2
!= VT_FUNC
) {
4351 t2
= pointed_type(t2
);
4353 /* void matches everything */
4356 if (t1
== VT_VOID
|| t2
== VT_VOID
)
4358 return is_compatible_types(t1
, t2
);
4359 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4361 } else if (bt1
== VT_FUNC
) {
4364 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
4365 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
4366 if (!is_compatible_types(s1
->t
, s2
->t
))
4368 /* XXX: not complete */
4369 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
4373 while (s1
!= NULL
) {
4376 if (!is_compatible_types(s1
->t
, s2
->t
))
4385 /* XXX: not complete */
4390 /* print a type. If 'varstr' is not NULL, then the variable is also
4391 printed in the type */
4393 /* XXX: add array and function pointers */
4394 void type_to_str(char *buf
, int buf_size
,
4395 int t
, const char *varstr
)
4405 if (t
& VT_UNSIGNED
)
4406 pstrcat(buf
, buf_size
, "unsigned ");
4436 tstr
= "long double";
4438 pstrcat(buf
, buf_size
, tstr
);
4442 if (bt
== VT_STRUCT
)
4446 pstrcat(buf
, buf_size
, tstr
);
4447 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
4448 if (v
>= SYM_FIRST_ANOM
)
4449 pstrcat(buf
, buf_size
, "<anonymous>");
4451 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
4454 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4455 type_to_str(buf
, buf_size
, s
->t
, varstr
);
4456 pstrcat(buf
, buf_size
, "(");
4458 while (sa
!= NULL
) {
4459 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
4460 pstrcat(buf
, buf_size
, buf1
);
4463 pstrcat(buf
, buf_size
, ", ");
4465 pstrcat(buf
, buf_size
, ")");
4468 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4469 pstrcpy(buf1
, sizeof(buf1
), "*");
4471 pstrcat(buf1
, sizeof(buf1
), varstr
);
4472 type_to_str(buf
, buf_size
, s
->t
, buf1
);
4476 pstrcat(buf
, buf_size
, " ");
4477 pstrcat(buf
, buf_size
, varstr
);
4482 /* verify type compatibility to store vtop in 'dt' type, and generate
4484 void gen_assign_cast(int dt
)
4487 char buf1
[256], buf2
[256];
4489 st
= vtop
->t
; /* source type */
4490 if ((dt
& VT_BTYPE
) == VT_PTR
) {
4491 /* special cases for pointers */
4492 /* a function is implicitely a function pointer */
4493 if ((st
& VT_BTYPE
) == VT_FUNC
) {
4494 if (!is_compatible_types(pointed_type(dt
), st
))
4499 /* '0' can also be a pointer */
4500 if ((st
& VT_BTYPE
) == VT_INT
&&
4501 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
4505 if (!is_compatible_types(dt
, st
)) {
4507 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
4508 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
4509 error("cannot cast '%s' to '%s'", buf1
, buf2
);
4515 /* store vtop in lvalue pushed on stack */
4518 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
4522 sbt
= vtop
->t
& VT_BTYPE
;
4523 dbt
= ft
& VT_BTYPE
;
4524 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
4525 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
4526 /* optimize char/short casts */
4527 delayed_cast
= VT_MUSTCAST
;
4528 vtop
->t
= ft
& VT_TYPE
;
4531 gen_assign_cast(ft
& VT_TYPE
);
4534 if (sbt
== VT_STRUCT
) {
4535 /* if structure, only generate pointer */
4536 /* structure assignment : generate memcpy */
4537 /* XXX: optimize if small size */
4539 gfunc_start(&gf
, FUNC_CDECL
);
4541 size
= type_size(vtop
->t
, &align
);
4555 vpush_global_sym(func_old_type
, TOK_memcpy
);
4557 /* leave source on stack */
4558 } else if (ft
& VT_BITFIELD
) {
4559 /* bitfield store handling */
4560 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
4561 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4562 /* remove bit field info to avoid loops */
4563 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4565 /* duplicate destination */
4567 vtop
[-1] = vtop
[-2];
4569 /* mask and shift source */
4570 vpushi((1 << bit_size
) - 1);
4574 /* load destination, mask and or with source */
4576 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4582 #ifdef CONFIG_TCC_BCHECK
4583 /* bound check case */
4584 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4593 r
= gv(rc
); /* generate value */
4594 /* if lvalue was saved on stack, must read it */
4595 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4597 t
= get_reg(RC_INT
);
4599 sv
.r
= VT_LOCAL
| VT_LVAL
;
4600 sv
.c
.ul
= vtop
[-1].c
.ul
;
4602 vtop
[-1].r
= t
| VT_LVAL
;
4605 /* two word case handling : store second register at word + 4 */
4606 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4608 /* convert to int to increment easily */
4615 /* XXX: it works because r2 is spilled last ! */
4616 store(vtop
->r2
, vtop
- 1);
4619 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4620 vtop
->r
|= delayed_cast
;
4624 /* post defines POST/PRE add. c is the token ++ or -- */
4625 void inc(int post
, int c
)
4628 vdup(); /* save lvalue */
4630 gv_dup(); /* duplicate value */
4635 vpushi(c
- TOK_MID
);
4637 vstore(); /* store value */
4639 vpop(); /* if post op, return saved value */
4642 /* Parse GNUC __attribute__ extension. Currently, the following
4643 extensions are recognized:
4644 - aligned(n) : set data/function alignment.
4645 - section(x) : generate data/code in this section.
4646 - unused : currently ignored, but may be used someday.
4648 void parse_attribute(AttributeDef
*ad
)
4655 while (tok
!= ')') {
4656 if (tok
< TOK_IDENT
)
4657 expect("attribute name");
4662 case TOK___SECTION__
:
4665 expect("section name");
4666 ad
->section
= find_section((char *)tokc
.cstr
->data
);
4671 case TOK___ALIGNED__
:
4674 if (n
<= 0 || (n
& (n
- 1)) != 0)
4675 error("alignment must be a positive power of two");
4680 case TOK___UNUSED__
:
4681 /* currently, no need to handle it because tcc does not
4682 track unused objects */
4685 case TOK___NORETURN__
:
4686 /* currently, no need to handle it because tcc does not
4687 track unused objects */
4692 ad
->func_call
= FUNC_CDECL
;
4696 case TOK___STDCALL__
:
4697 ad
->func_call
= FUNC_STDCALL
;
4700 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4701 /* skip parameters */
4702 /* XXX: skip parenthesis too */
4705 while (tok
!= ')' && tok
!= -1)
4719 /* enum/struct/union declaration */
4720 int struct_decl(int u
)
4722 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4723 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4727 a
= tok
; /* save decl type */
4732 /* struct already defined ? return it */
4733 /* XXX: check consistency */
4734 s
= sym_find(v
| SYM_STRUCT
);
4737 error("invalid type");
4743 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4744 /* put struct/union/enum name in type */
4746 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4751 error("struct/union/enum already defined");
4752 /* cannot be empty */
4759 if (a
== TOK_ENUM
) {
4766 /* enum symbols have static storage */
4767 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4772 parse_btype(&b
, &ad
);
4777 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4778 if ((t
& VT_BTYPE
) == VT_FUNC
||
4779 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4780 error("invalid type for '%s'",
4781 get_tok_str(v
, NULL
));
4787 bit_size
= expr_const();
4788 /* XXX: handle v = 0 case for messages */
4790 error("negative width in bit-field '%s'",
4791 get_tok_str(v
, NULL
));
4792 if (v
&& bit_size
== 0)
4793 error("zero width for bit-field '%s'",
4794 get_tok_str(v
, NULL
));
4796 size
= type_size(t
, &align
);
4798 if (bit_size
>= 0) {
4803 error("bitfields must have scalar type");
4805 if (bit_size
> bsize
) {
4806 error("width of '%s' exceeds its type",
4807 get_tok_str(v
, NULL
));
4808 } else if (bit_size
== bsize
) {
4809 /* no need for bit fields */
4811 } else if (bit_size
== 0) {
4812 /* XXX: what to do if only padding in a
4814 /* zero size: means to pad */
4818 /* we do not have enough room ? */
4819 if ((bit_pos
+ bit_size
) > bsize
)
4822 /* XXX: handle LSB first */
4824 (bit_pos
<< VT_STRUCT_SHIFT
) |
4825 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4826 bit_pos
+= bit_size
;
4832 /* add new memory data only if starting
4834 if (lbit_pos
== 0) {
4835 if (a
== TOK_STRUCT
) {
4836 c
= (c
+ align
- 1) & -align
;
4844 if (align
> maxalign
)
4848 printf("add field %s offset=%d",
4849 get_tok_str(v
, NULL
), offset
);
4850 if (t
& VT_BITFIELD
) {
4851 printf(" pos=%d size=%d",
4852 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4853 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4857 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
4861 if (tok
== ';' || tok
== -1)
4871 /* size for struct/union, dummy for enum */
4872 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4877 /* return 0 if no type declaration. otherwise, return the basic type
4880 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4882 int t
, u
, type_found
;
4885 memset(ad
, 0, sizeof(AttributeDef
));
4896 if ((t
& VT_BTYPE
) != 0)
4897 error("too many basic types");
4911 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4912 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4913 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4914 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4928 if ((t
& VT_BTYPE
) == VT_LONG
) {
4929 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4936 u
= struct_decl(VT_ENUM
);
4940 u
= struct_decl(VT_STRUCT
);
4943 /* type modifiers */
4948 case TOK___SIGNED__
:
4951 case TOK___INLINE__
:
4973 /* GNUC attribute */
4974 case TOK___ATTRIBUTE__
:
4975 parse_attribute(ad
);
4979 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4981 t
|= (s
->t
& ~VT_TYPEDEF
);
4988 /* long is never used as type */
4989 if ((t
& VT_BTYPE
) == VT_LONG
)
4990 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4995 int post_type(int t
, AttributeDef
*ad
)
4997 int p
, n
, pt
, l
, t1
;
4998 Sym
**plast
, *s
, *first
;
5002 /* function declaration */
5007 while (tok
!= ')') {
5008 /* read param name and compute offset */
5009 if (l
!= FUNC_OLD
) {
5010 if (!parse_btype(&pt
, &ad1
)) {
5012 error("invalid type");
5019 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5021 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
5022 if ((pt
& VT_BTYPE
) == VT_VOID
)
5023 error("parameter declared as void");
5030 /* array must be transformed to pointer according to ANSI C */
5032 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
5037 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5044 /* if no parameters, then old type prototype */
5048 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5049 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
5050 /* we push a anonymous symbol which will contain the function prototype */
5052 s
= sym_push(p
, t
, ad
->func_call
, l
);
5054 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
5055 } else if (tok
== '[') {
5056 /* array definition */
5062 error("invalid array size");
5065 /* parse next post type */
5066 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5067 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
5069 /* we push a anonymous symbol which will contain the array
5072 sym_push(p
, t
, 0, n
);
5073 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
5078 /* Read a type declaration (except basic type), and return the
5079 type. 'td' is a bitmask indicating which kind of type decl is
5080 expected. 't' should contain the basic type. 'ad' is the attribute
5081 definition of the basic type. It can be modified by type_decl(). */
5082 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
5087 while (tok
== '*') {
5089 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
5094 /* recursive type */
5095 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5098 /* XXX: this is not correct to modify 'ad' at this point, but
5099 the syntax is not clear */
5100 if (tok
== TOK___ATTRIBUTE__
)
5101 parse_attribute(ad
);
5102 u
= type_decl(ad
, v
, 0, td
);
5106 /* type identifier */
5107 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
5111 if (!(td
& TYPE_ABSTRACT
))
5112 expect("identifier");
5116 /* append t at the end of u */
5117 t
= post_type(t
, ad
);
5118 if (tok
== TOK___ATTRIBUTE__
)
5119 parse_attribute(ad
);
5124 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
5134 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5135 static int lvalue_type(int t
)
5142 else if (bt
== VT_SHORT
)
5146 if (t
& VT_UNSIGNED
)
5147 r
|= VT_LVAL_UNSIGNED
;
5151 /* indirection with full error checking and bound check */
5152 static void indir(void)
5154 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
5156 if (vtop
->r
& VT_LVAL
)
5158 vtop
->t
= pointed_type(vtop
->t
);
5159 /* an array is never an lvalue */
5160 if (!(vtop
->t
& VT_ARRAY
)) {
5161 vtop
->r
|= lvalue_type(vtop
->t
);
5162 /* if bound checking, the referenced pointer must be checked */
5163 if (do_bounds_check
)
5164 vtop
->r
|= VT_MUSTBOUND
;
5168 /* pass a parameter to a function and do type checking and casting */
5169 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
5172 func_type
= func
->c
;
5173 if (func_type
== FUNC_OLD
||
5174 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5175 /* default casting : only need to convert float to double */
5176 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
5177 gen_cast(VT_DOUBLE
);
5178 } else if (arg
== NULL
) {
5179 error("too many arguments to function");
5181 gen_assign_cast(arg
->t
);
5188 int n
, t
, ft
, align
, size
, r
;
5193 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
5196 } else if (tok
== TOK_CUINT
) {
5197 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
5199 } else if (tok
== TOK_CLLONG
) {
5200 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
5202 } else if (tok
== TOK_CULLONG
) {
5203 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
5205 } else if (tok
== TOK_CFLOAT
) {
5206 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
5208 } else if (tok
== TOK_CDOUBLE
) {
5209 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
5211 } else if (tok
== TOK_CLDOUBLE
) {
5212 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
5214 } else if (tok
== TOK___FUNC__
|| (tok
== TOK___FUNCTION__
&& gnu_ext
)) {
5217 /* special function name identifier */
5219 len
= strlen(funcname
) + 1;
5220 /* generate char[len] type */
5221 t
= VT_ARRAY
| mk_pointer(VT_BYTE
);
5222 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5224 vpush_ref(t
, data_section
, data_section
->data_offset
, len
);
5225 ptr
= section_ptr_add(data_section
, len
);
5226 memcpy(ptr
, funcname
, len
);
5228 } else if (tok
== TOK_LSTR
) {
5231 } else if (tok
== TOK_STR
) {
5232 /* string parsing */
5235 t
= VT_ARRAY
| mk_pointer(t
);
5236 memset(&ad
, 0, sizeof(AttributeDef
));
5237 decl_initializer_alloc(t
, &ad
, VT_CONST
, 2, 0, 0);
5243 if (parse_btype(&t
, &ad
)) {
5244 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
5246 /* check ISOC99 compound literal */
5248 /* data is allocated locally by default */
5253 /* all except arrays are lvalues */
5254 if (!(ft
& VT_ARRAY
))
5255 r
|= lvalue_type(ft
);
5256 memset(&ad
, 0, sizeof(AttributeDef
));
5257 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
5266 } else if (t
== '*') {
5269 } else if (t
== '&') {
5271 /* functions names must be treated as function pointers,
5272 except for unary '&' and sizeof. Since we consider that
5273 functions are not lvalues, we only have to handle it
5274 there and in function calls. */
5275 /* arrays can also be used although they are not lvalues */
5276 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
5277 !(vtop
->t
& VT_ARRAY
))
5279 vtop
->t
= mk_pointer(vtop
->t
);
5284 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
5285 vtop
->c
.i
= !vtop
->c
.i
;
5286 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
5287 vtop
->c
.i
= vtop
->c
.i
^ 1;
5289 vset(VT_INT
, VT_JMP
, gtst(1, 0));
5297 /* in order to force cast, we add zero */
5299 if ((vtop
->t
& VT_BTYPE
) == VT_PTR
)
5300 error("pointer not accepted for unary plus");
5304 if (t
== TOK_SIZEOF
) {
5307 if (parse_btype(&t
, &ad
)) {
5308 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
5310 /* XXX: some code could be generated: add eval
5322 vpushi(type_size(t
, &t
));
5324 if (t
== TOK_INC
|| t
== TOK_DEC
) {
5327 } else if (t
== '-') {
5334 expect("identifier");
5338 error("'%s' undeclared", get_tok_str(t
, NULL
));
5339 /* for simple function calls, we tolerate undeclared
5340 external reference to int() function */
5341 s
= external_global_sym(t
, func_old_type
, 0);
5343 vset(s
->t
, s
->r
, s
->c
);
5344 /* if forward reference, we must point to s */
5345 if (vtop
->r
& VT_SYM
) {
5352 /* post operations */
5354 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
5357 } else if (tok
== '.' || tok
== TOK_ARROW
) {
5359 if (tok
== TOK_ARROW
)
5364 /* expect pointer on structure */
5365 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
5366 expect("struct or union");
5367 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5370 while ((s
= s
->next
) != NULL
) {
5375 error("field not found");
5376 /* add field offset to pointer */
5377 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
5380 /* change type to field type, and set to lvalue */
5382 /* an array is never an lvalue */
5383 if (!(vtop
->t
& VT_ARRAY
)) {
5384 vtop
->r
|= lvalue_type(vtop
->t
);
5385 /* if bound checking, the referenced pointer must be checked */
5386 if (do_bounds_check
)
5387 vtop
->r
|= VT_MUSTBOUND
;
5390 } else if (tok
== '[') {
5396 } else if (tok
== '(') {
5401 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
5402 /* pointer test (no array accepted) */
5403 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
5404 vtop
->t
= pointed_type(vtop
->t
);
5405 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
5409 expect("function pointer");
5412 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
5414 /* get return type */
5415 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
5416 save_regs(0); /* save used temporary registers */
5417 gfunc_start(&gf
, s
->r
);
5419 sa
= s
->next
; /* first parameter */
5420 #ifdef INVERT_FUNC_PARAMS
5424 ParseState saved_parse_state
;
5427 /* read each argument and store it on a stack */
5433 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
5437 else if (tok
== ')')
5439 tok_str_add_tok(&str
);
5442 tok_str_add(&str
, -1); /* end of file added */
5443 tok_str_add(&str
, 0);
5444 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
5445 s1
->next
= sa
; /* add reference to argument */
5454 /* now generate code in reverse order by reading the stack */
5455 save_parse_state(&saved_parse_state
);
5457 macro_ptr
= (int *)args
->c
;
5461 expect("',' or ')'");
5462 gfunc_param_typed(&gf
, s
, args
->next
);
5464 tok_str_free((int *)args
->c
);
5468 restore_parse_state(&saved_parse_state
);
5471 /* compute first implicit argument if a structure is returned */
5472 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
5473 /* get some space for the returned structure */
5474 size
= type_size(s
->t
, &align
);
5475 loc
= (loc
- size
) & -align
;
5477 ret
.r
= VT_LOCAL
| VT_LVAL
;
5478 /* pass it as 'int' to avoid structure arg passing
5480 vset(VT_INT
, VT_LOCAL
, loc
);
5486 /* return in register */
5487 if (is_float(ret
.t
)) {
5490 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
5496 #ifndef INVERT_FUNC_PARAMS
5500 gfunc_param_typed(&gf
, s
, sa
);
5510 error("too few arguments to function");
5514 vsetc(ret
.t
, ret
.r
, &ret
.c
);
5528 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
5529 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
5530 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
5553 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
5554 (l
== 1 && (tok
== '+' || tok
== '-')) ||
5555 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
5556 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
5557 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
5558 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
5559 (l
== 5 && tok
== '&') ||
5560 (l
== 6 && tok
== '^') ||
5561 (l
== 7 && tok
== '|') ||
5562 (l
== 8 && tok
== TOK_LAND
) ||
5563 (l
== 9 && tok
== TOK_LOR
)) {
5572 /* only used if non constant */
5580 if (tok
!= TOK_LAND
) {
5583 vset(VT_INT
, VT_JMPI
, t
);
5600 if (tok
!= TOK_LOR
) {
5603 vset(VT_INT
, VT_JMP
, t
);
5613 /* XXX: better constant handling */
5616 int tt
, u
, r1
, r2
, rc
, t1
, t2
, t
, bt1
, bt2
;
5638 save_regs(1); /* we need to save all registers here except
5639 at the top because it is a branch point */
5643 bt1
= t1
& VT_BTYPE
;
5644 sv
= *vtop
; /* save value to handle it later */
5645 vtop
--; /* no vpop so that FP stack is not flushed */
5653 bt2
= t2
& VT_BTYPE
;
5654 /* cast operands to correct type according to ISOC rules */
5655 if (is_float(bt1
) || is_float(bt2
)) {
5656 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
5658 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
5663 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
5664 /* cast to biggest op */
5666 /* convert to unsigned if it does not fit in a long long */
5667 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
5668 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
5670 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
5671 /* XXX: test pointer compatibility */
5673 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
5674 /* XXX: test structure compatibility */
5676 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
5677 /* NOTE: as an extension, we accept void on only one side */
5680 /* integer operations */
5682 /* convert to unsigned if it does not fit in an integer */
5683 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
5684 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
5688 /* now we convert second operand */
5693 } else if ((t
& VT_BTYPE
) == VT_LLONG
) {
5694 /* for long longs, we use fixed registers to avoid having
5695 to handle a complicated move */
5699 /* this is horrible, but we must also convert first
5703 /* put again first value and cast it */
5725 /* parse a constant expression and return value in vtop. */
5726 static void expr_const1(void)
5735 /* parse an integer constant and return its value. */
5736 static int expr_const(void)
5740 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
5741 expect("constant expression");
5747 /* return the label token if current token is a label, otherwise
5754 /* fast test first */
5755 if (tok
< TOK_UIDENT
)
5757 /* no need to save tokc since we expect an identifier */
5765 /* XXX: may not work in all cases (macros ?) */
5774 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
5779 /* generate line number info */
5781 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
5782 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
5784 last_line_num
= file
->line_num
;
5787 if (tok
== TOK_IF
) {
5794 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5796 if (c
== TOK_ELSE
) {
5800 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5801 gsym(d
); /* patch else jmp */
5804 } else if (tok
== TOK_WHILE
) {
5812 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5816 } else if (tok
== '{') {
5819 s
= local_stack
.top
;
5820 while (tok
!= '}') {
5823 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5825 /* pop locally defined symbols */
5826 sym_pop(&local_stack
, s
);
5828 } else if (tok
== TOK_RETURN
) {
5832 gen_assign_cast(func_vt
);
5833 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5834 /* if returning structure, must copy it to implicit
5835 first pointer arg location */
5836 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
5839 /* copy structure value to pointer */
5841 } else if (is_float(func_vt
)) {
5846 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5849 rsym
= gjmp(rsym
); /* jmp */
5850 } else if (tok
== TOK_BREAK
) {
5853 error("cannot break");
5854 *bsym
= gjmp(*bsym
);
5857 } else if (tok
== TOK_CONTINUE
) {
5860 error("cannot continue");
5861 *csym
= gjmp(*csym
);
5864 } else if (tok
== TOK_FOR
) {
5891 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5896 if (tok
== TOK_DO
) {
5901 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5912 if (tok
== TOK_SWITCH
) {
5916 /* XXX: other types than integer */
5917 case_reg
= gv(RC_INT
);
5921 b
= gjmp(0); /* jump to first case */
5923 block(&a
, csym
, &b
, &c
, case_reg
);
5924 /* if no default, jmp after switch */
5932 if (tok
== TOK_CASE
) {
5939 if (gnu_ext
&& tok
== TOK_DOTS
) {
5943 warning("empty case range");
5945 /* since a case is like a label, we must skip it with a jmp */
5948 vset(VT_INT
, case_reg
, 0);
5952 *case_sym
= gtst(1, 0);
5955 *case_sym
= gtst(1, 0);
5956 vset(VT_INT
, case_reg
, 0);
5959 *case_sym
= gtst(1, *case_sym
);
5963 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5965 if (tok
== TOK_DEFAULT
) {
5971 error("too many 'default'");
5973 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5975 if (tok
== TOK_GOTO
) {
5977 s
= sym_find1(&label_stack
, tok
);
5978 /* put forward definition if needed */
5980 s
= sym_push1(&label_stack
, tok
, LABEL_FORWARD
, 0);
5981 /* label already defined */
5982 if (s
->t
& LABEL_FORWARD
)
5992 s
= sym_find1(&label_stack
, b
);
5994 if (!(s
->t
& LABEL_FORWARD
))
5995 error("multiple defined label");
6000 sym_push1(&label_stack
, b
, 0, ind
);
6002 /* we accept this, but it is a mistake */
6004 warning("deprecated use of label at end of compound statement");
6006 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6008 /* expression case */
6018 /* t is the array or struct type. c is the array or struct
6019 address. cur_index/cur_field is the pointer to the current
6020 value. 'size_only' is true if only size info is needed (only used
6022 static void decl_designator(int t
, Section
*sec
, unsigned long c
,
6023 int *cur_index
, Sym
**cur_field
,
6027 int notfirst
, index
, align
, l
;
6030 if (gnu_ext
&& (l
= is_label()) != 0)
6033 while (tok
== '[' || tok
== '.') {
6035 if (!(t
& VT_ARRAY
))
6036 expect("array type");
6037 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
6039 index
= expr_const();
6040 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
6041 expect("invalid index");
6045 t
= pointed_type(t
);
6046 c
+= index
* type_size(t
, &align
);
6052 if ((t
& VT_BTYPE
) != VT_STRUCT
)
6053 expect("struct/union type");
6054 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
6066 t
= f
->t
| (t
& ~VT_TYPE
);
6081 t
= pointed_type(t
);
6082 c
+= index
* type_size(t
, &align
);
6086 error("too many field init");
6087 t
= f
->t
| (t
& ~VT_TYPE
);
6091 decl_initializer(t
, sec
, c
, 0, size_only
);
6095 #define EXPR_CONST 1
6098 /* store a value or an expression directly in global data or in local array */
6099 static void init_putv(int t
, Section
*sec
, unsigned long c
,
6100 int v
, int expr_type
)
6102 int saved_global_expr
, bt
;
6110 /* compound literals must be allocated globally in this case */
6111 saved_global_expr
= global_expr
;
6114 global_expr
= saved_global_expr
;
6115 /* NOTE: symbols are accepted */
6116 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
6117 error("initializer element is not constant");
6125 /* XXX: not portable */
6126 /* XXX: generate error if incorrect relocation */
6129 ptr
= sec
->data
+ c
;
6130 if ((vtop
->r
& VT_SYM
) &&
6136 error("initializer element is not computable at load time");
6139 *(char *)ptr
= vtop
->c
.i
;
6142 *(short *)ptr
= vtop
->c
.i
;
6145 *(double *)ptr
= vtop
->c
.d
;
6148 *(long double *)ptr
= vtop
->c
.ld
;
6151 *(long long *)ptr
= vtop
->c
.ll
;
6154 if (vtop
->r
& VT_SYM
) {
6155 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
6157 *(int *)ptr
= vtop
->c
.i
;
6162 vset(t
, VT_LOCAL
, c
);
6169 /* put zeros for variable based init */
6170 static void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
6175 /* nothing to do because globals are already set to zero */
6177 gfunc_start(&gf
, FUNC_CDECL
);
6182 vset(VT_INT
, VT_LOCAL
, c
);
6184 vpush_global_sym(func_old_type
, TOK_memset
);
6189 /* 't' contains the type and storage info. 'c' is the offset of the
6190 object in section 'sec'. If 'sec' is NULL, it means stack based
6191 allocation. 'first' is true if array '{' must be read (multi
6192 dimension implicit array init handling). 'size_only' is true if
6193 size only evaluation is wanted (only for arrays). */
6194 static void decl_initializer(int t
, Section
*sec
, unsigned long c
,
6195 int first
, int size_only
)
6197 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
6198 int t1
, size1
, align1
, expr_type
;
6202 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
6205 t1
= pointed_type(t
);
6206 size1
= type_size(t1
, &align1
);
6209 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
6215 /* only parse strings here if correct type (otherwise: handle
6216 them as ((w)char *) expressions */
6217 if ((tok
== TOK_LSTR
&&
6218 (t1
& VT_BTYPE
) == VT_INT
) ||
6220 (t1
& VT_BTYPE
) == VT_BYTE
)) {
6221 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6226 /* compute maximum number of chars wanted */
6228 cstr_len
= cstr
->size
;
6230 cstr_len
= cstr
->size
/ sizeof(int);
6233 if (n
>= 0 && nb
> (n
- array_length
))
6234 nb
= n
- array_length
;
6237 warning("initializer-string for array is too long");
6238 /* in order to go faster for common case (char
6239 string in global variable, we handle it
6241 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
6242 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
6246 ch
= ((unsigned char *)cstr
->data
)[i
];
6248 ch
= ((int *)cstr
->data
)[i
];
6249 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
6257 /* only add trailing zero if enough storage (no
6258 warning in this case since it is standard) */
6259 if (n
< 0 || array_length
< n
) {
6261 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
6267 while (tok
!= '}') {
6268 decl_designator(t
, sec
, c
, &index
, NULL
, size_only
);
6269 if (n
>= 0 && index
>= n
)
6270 error("index too large");
6271 /* must put zero in holes (note that doing it that way
6272 ensures that it even works with designators) */
6273 if (!size_only
&& array_length
< index
) {
6274 init_putz(t1
, sec
, c
+ array_length
* size1
,
6275 (index
- array_length
) * size1
);
6278 if (index
> array_length
)
6279 array_length
= index
;
6280 /* special test for multi dimensional arrays (may not
6281 be strictly correct if designators are used at the
6283 if (index
>= n
&& no_oblock
)
6292 /* put zeros at the end */
6293 if (!size_only
&& n
>= 0 && array_length
< n
) {
6294 init_putz(t1
, sec
, c
+ array_length
* size1
,
6295 (n
- array_length
) * size1
);
6297 /* patch type size if needed */
6299 s
->c
= array_length
;
6300 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
6301 /* XXX: union needs only one init */
6303 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
6308 while (tok
!= '}') {
6309 decl_designator(t
, sec
, c
, NULL
, &f
, size_only
);
6310 /* fill with zero between fields */
6312 if (!size_only
&& array_length
< index
) {
6313 init_putz(t
, sec
, c
+ array_length
,
6314 index
- array_length
);
6316 index
= index
+ type_size(f
->t
, &align1
);
6317 if (index
> array_length
)
6318 array_length
= index
;
6324 /* put zeros at the end */
6325 if (!size_only
&& array_length
< n
) {
6326 init_putz(t
, sec
, c
+ array_length
,
6330 } else if (tok
== '{') {
6332 decl_initializer(t
, sec
, c
, first
, size_only
);
6334 } else if (size_only
) {
6335 /* just skip expression */
6337 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
6341 else if (tok
== ')')
6346 /* currently, we always use constant expression for globals
6347 (may change for scripting case) */
6348 expr_type
= EXPR_CONST
;
6350 expr_type
= EXPR_ANY
;
6351 init_putv(t
, sec
, c
, 0, expr_type
);
6355 /* parse an initializer for type 't' if 'has_init' is non zero, and
6356 allocate space in local or global data space ('r' is either
6357 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6358 variable 'v' of scope 'scope' is declared before initializers are
6359 parsed. If 'v' is zero, then a reference to the new object is put
6360 in the value stack. If 'has_init' is 2, a special parsing is done
6361 to handle string constants. */
6362 static void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
,
6363 int has_init
, int v
, int scope
)
6365 int size
, align
, addr
, data_offset
;
6367 ParseState saved_parse_state
;
6368 TokenString init_str
;
6371 size
= type_size(t
, &align
);
6372 /* If unknown size, we must evaluate it before
6373 evaluating initializers because
6374 initializers can generate global data too
6375 (e.g. string pointers or ISOC99 compound
6376 literals). It also simplifies local
6377 initializers handling */
6378 tok_str_new(&init_str
);
6381 error("unknown type size");
6382 /* get all init string */
6383 if (has_init
== 2) {
6384 /* only get strings */
6385 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6386 tok_str_add_tok(&init_str
);
6391 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
6393 error("unexpected end of file in initializer");
6394 tok_str_add_tok(&init_str
);
6397 else if (tok
== '}') {
6405 tok_str_add(&init_str
, -1);
6406 tok_str_add(&init_str
, 0);
6409 save_parse_state(&saved_parse_state
);
6411 macro_ptr
= init_str
.str
;
6413 decl_initializer(t
, NULL
, 0, 1, 1);
6414 /* prepare second initializer parsing */
6415 macro_ptr
= init_str
.str
;
6418 /* if still unknown size, error */
6419 size
= type_size(t
, &align
);
6421 error("unknown type size");
6423 /* take into account specified alignment if bigger */
6424 if (ad
->aligned
> align
)
6425 align
= ad
->aligned
;
6426 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
6428 if (do_bounds_check
&& (t
& VT_ARRAY
))
6430 #ifdef TCC_TARGET_IL
6431 /* XXX: ugly patch to allocate local variables for IL, just
6436 loc
= (loc
- size
) & -align
;
6439 /* handles bounds */
6440 /* XXX: currently, since we do only one pass, we cannot track
6441 '&' operators, so we add only arrays */
6442 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
6443 unsigned long *bounds_ptr
;
6444 /* add padding between regions */
6446 /* then add local bound info */
6447 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
6448 bounds_ptr
[0] = addr
;
6449 bounds_ptr
[1] = size
;
6452 /* compute section */
6460 data_offset
= sec
->data_offset
;
6461 data_offset
= (data_offset
+ align
- 1) & -align
;
6463 /* very important to increment global pointer at this time
6464 because initializers themselves can create new initializers */
6465 data_offset
+= size
;
6466 /* add padding if bound check */
6467 if (do_bounds_check
)
6469 sec
->data_offset
= data_offset
;
6470 /* allocate section space to put the data */
6471 if (sec
->sh_type
!= SHT_NOBITS
&&
6472 data_offset
> sec
->data_allocated
)
6473 section_realloc(sec
, data_offset
);
6477 /* local variable */
6478 sym_push(v
, t
, r
, addr
);
6480 /* push local reference */
6487 if (scope
== VT_CONST
) {
6488 /* global scope: see if already defined */
6492 if (!is_compatible_types(sym
->t
, t
))
6493 error("incompatible types for redefinition of '%s'",
6494 get_tok_str(v
, NULL
));
6495 if (!(sym
->t
& VT_EXTERN
))
6496 error("redefinition of '%s'", get_tok_str(v
, NULL
));
6497 sym
->t
&= ~VT_EXTERN
;
6500 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
6502 put_extern_sym(sym
, sec
, addr
, size
);
6506 /* push global reference */
6507 sym
= get_sym_ref(t
, sec
, addr
, size
);
6509 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
6513 /* handles bounds now because the symbol must be defined
6514 before for the relocation */
6515 if (do_bounds_check
) {
6516 unsigned long *bounds_ptr
;
6518 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
6519 /* then add global bound info */
6520 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
6521 bounds_ptr
[0] = 0; /* relocated */
6522 bounds_ptr
[1] = size
;
6526 decl_initializer(t
, sec
, addr
, 1, 0);
6527 /* restore parse state if needed */
6529 tok_str_free(init_str
.str
);
6530 restore_parse_state(&saved_parse_state
);
6535 void put_func_debug(Sym
*sym
)
6540 /* XXX: we put here a dummy type */
6541 snprintf(buf
, sizeof(buf
), "%s:%c1",
6542 funcname
, sym
->t
& VT_STATIC
? 'f' : 'F');
6543 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
6544 cur_text_section
, sym
->c
);
6549 /* not finished : try to put some local vars in registers */
6550 //#define CONFIG_REG_VARS
6552 #ifdef CONFIG_REG_VARS
6553 void add_var_ref(int t
)
6555 printf("%s:%d: &%s\n",
6556 file
->filename
, file
->line_num
,
6557 get_tok_str(t
, NULL
));
6560 /* first pass on a function with heuristic to extract variable usage
6561 and pointer references to local variables for register allocation */
6562 void analyse_function(void)
6569 /* any symbol coming after '&' is considered as being a
6570 variable whose reference is taken. It is highly unaccurate
6571 but it is difficult to do better without a complete parse */
6574 /* if '& number', then no need to examine next tokens */
6575 if (tok
== TOK_CINT
||
6577 tok
== TOK_CLLONG
||
6578 tok
== TOK_CULLONG
) {
6580 } else if (tok
>= TOK_UIDENT
) {
6581 /* if '& ident [' or '& ident ->', then ident address
6585 if (tok
!= '[' && tok
!= TOK_ARROW
)
6589 while (tok
!= '}' && tok
!= ';' &&
6590 !((tok
== ',' || tok
== ')') && level
== 0)) {
6591 if (tok
>= TOK_UIDENT
) {
6593 } else if (tok
== '(') {
6595 } else if (tok
== ')') {
6608 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6611 int t
, b
, v
, has_init
, r
;
6616 if (!parse_btype(&b
, &ad
)) {
6617 /* skip redundant ';' */
6618 /* XXX: find more elegant solution */
6623 /* special test for old K&R protos without explicit int
6624 type. Only accepted when defining global data */
6625 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
6629 if (((b
& VT_BTYPE
) == VT_ENUM
||
6630 (b
& VT_BTYPE
) == VT_STRUCT
) &&
6632 /* we accept no variable after */
6636 while (1) { /* iterate thru each declaration */
6637 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
6641 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
6642 printf("type = '%s'\n", buf
);
6646 #ifdef CONFIG_REG_VARS
6647 TokenString func_str
;
6648 ParseState saved_parse_state
;
6653 error("cannot use local functions");
6655 expect("function definition");
6657 #ifdef CONFIG_REG_VARS
6658 /* parse all function code and record it */
6660 tok_str_new(&func_str
);
6666 error("unexpected end of file");
6667 tok_str_add_tok(&func_str
);
6672 } else if (t
== '}') {
6674 if (block_level
== 0)
6678 tok_str_add(&func_str
, -1);
6679 tok_str_add(&func_str
, 0);
6681 save_parse_state(&saved_parse_state
);
6683 macro_ptr
= func_str
.str
;
6688 /* compute text section */
6689 cur_text_section
= ad
.section
;
6690 if (!cur_text_section
)
6691 cur_text_section
= text_section
;
6692 ind
= cur_text_section
->data_offset
;
6693 funcname
= get_tok_str(v
, NULL
);
6696 /* if symbol is already defined, then put complete type */
6699 /* put function symbol */
6700 sym
= sym_push1(&global_stack
, v
, t
, 0);
6702 /* NOTE: we patch the symbol size later */
6703 put_extern_sym(sym
, cur_text_section
, ind
, 0);
6705 sym
->r
= VT_SYM
| VT_CONST
;
6706 /* put debug symbol */
6708 put_func_debug(sym
);
6709 /* push a dummy symbol to enable local sym storage */
6710 sym_push1(&local_stack
, 0, 0, 0);
6714 #ifdef CONFIG_REG_VARS
6715 macro_ptr
= func_str
.str
;
6718 block(NULL
, NULL
, NULL
, NULL
, 0);
6721 cur_text_section
->data_offset
= ind
;
6722 sym_pop(&label_stack
, NULL
); /* reset label stack */
6723 sym_pop(&local_stack
, NULL
); /* reset local stack */
6724 /* end of function */
6725 /* patch symbol size */
6726 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
6729 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6731 funcname
= ""; /* for safety */
6732 func_vt
= VT_VOID
; /* for safety */
6733 ind
= 0; /* for safety */
6735 #ifdef CONFIG_REG_VARS
6736 tok_str_free(func_str
.str
);
6737 restore_parse_state(&saved_parse_state
);
6741 if (b
& VT_TYPEDEF
) {
6742 /* save typedefed type */
6743 /* XXX: test storage specifiers ? */
6744 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
6745 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
6746 /* external function definition */
6747 external_sym(v
, t
, 0);
6749 /* not lvalue if array */
6751 if (!(t
& VT_ARRAY
))
6752 r
|= lvalue_type(t
);
6753 if (b
& VT_EXTERN
) {
6754 /* external variable */
6755 external_sym(v
, t
, r
);
6761 has_init
= (tok
== '=');
6764 decl_initializer_alloc(t
, &ad
, r
,
6778 /* compile the C file opened in 'file'. Return non zero if errors. */
6779 static int tcc_compile(TCCState
*s
)
6781 Sym
*define_start
, *sym
;
6786 printf("%s: **** new file\n", file
->filename
);
6789 include_stack_ptr
= include_stack
;
6790 /* XXX: move that before to avoid having to initialize
6791 file->ifdef_stack_ptr ? */
6792 ifdef_stack_ptr
= ifdef_stack
;
6793 file
->ifdef_stack_ptr
= ifdef_stack_ptr
;
6795 /* XXX: not ANSI compliant: bound checking says error */
6797 anon_sym
= SYM_FIRST_ANOM
;
6799 /* file info: full path + filename */
6800 section_sym
= 0; /* avoid warning */
6802 section_sym
= put_elf_sym(symtab_section
, 0, 0,
6803 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
6804 text_section
->sh_num
, NULL
);
6805 getcwd(buf
, sizeof(buf
));
6806 pstrcat(buf
, sizeof(buf
), "/");
6807 put_stabs_r(buf
, N_SO
, 0, 0,
6808 text_section
->data_offset
, text_section
, section_sym
);
6809 put_stabs_r(file
->filename
, N_SO
, 0, 0,
6810 text_section
->data_offset
, text_section
, section_sym
);
6812 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6813 symbols can be safely used */
6814 put_elf_sym(symtab_section
, 0, 0,
6815 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
6816 SHN_ABS
, file
->filename
);
6818 /* define common 'char *' type because it is often used internally
6819 for arrays and struct dereference */
6820 char_pointer_type
= mk_pointer(VT_BYTE
);
6821 /* define an old type function 'int func()' */
6823 sym
= sym_push(p
, 0, FUNC_CDECL
, FUNC_OLD
);
6824 func_old_type
= VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
6826 /* define 'void *alloca(unsigned int)' builtin function */
6831 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
6832 s1
= sym_push(0, VT_UNSIGNED
| VT_INT
, 0, 0);
6835 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
6839 define_start
= define_stack
.top
;
6841 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6845 expect("declaration");
6847 /* end of translation unit info */
6849 put_stabs_r(NULL
, N_SO
, 0, 0,
6850 text_section
->data_offset
, text_section
, section_sym
);
6853 /* reset define stack, but leave -Dsymbols (may be incorrect if
6854 they are undefined) */
6855 sym_pop(&define_stack
, define_start
);
6857 sym_pop(&global_stack
, NULL
);
6862 int tcc_compile_string(TCCState
*s
, const char *str
)
6864 BufferedFile bf1
, *bf
= &bf1
;
6867 /* init file structure */
6869 bf
->buf_ptr
= (char *)str
;
6870 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
6871 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
6875 ret
= tcc_compile(s
);
6877 /* currently, no need to close */
6881 /* define a symbol. A value can also be provided with the '=' operator */
6882 void tcc_define_symbol(TCCState
*s
, const char *sym
, const char *value
)
6884 BufferedFile bf1
, *bf
= &bf1
;
6886 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
6887 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
6891 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
6893 /* init file structure */
6895 bf
->buf_ptr
= bf
->buffer
;
6896 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
6897 bf
->filename
[0] = '\0';
6901 include_stack_ptr
= include_stack
;
6903 /* parse with define parser */
6905 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6911 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
6915 ts
= tok_alloc(sym
, strlen(sym
));
6916 s
= sym_find1(&define_stack
, tok
);
6917 /* undefine symbol by putting an invalid name */
6919 sym_undef(&define_stack
, s
);
6924 /* print the position in the source file of PC value 'pc' by reading
6925 the stabs debug information */
6926 static void rt_printline(unsigned long wanted_pc
)
6928 Stab_Sym
*sym
, *sym_end
;
6929 char func_name
[128], last_func_name
[128];
6930 unsigned long func_addr
, last_pc
, pc
;
6931 const char *incl_files
[INCLUDE_STACK_SIZE
];
6932 int incl_index
, len
, last_line_num
, i
;
6933 const char *str
, *p
;
6935 func_name
[0] = '\0';
6938 last_func_name
[0] = '\0';
6939 last_pc
= 0xffffffff;
6941 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
6942 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
6943 while (sym
< sym_end
) {
6944 switch(sym
->n_type
) {
6945 /* function start or end */
6947 if (sym
->n_strx
== 0) {
6948 func_name
[0] = '\0';
6951 str
= stabstr_section
->data
+ sym
->n_strx
;
6952 p
= strchr(str
, ':');
6954 pstrcpy(func_name
, sizeof(func_name
), str
);
6957 if (len
> sizeof(func_name
) - 1)
6958 len
= sizeof(func_name
) - 1;
6959 memcpy(func_name
, str
, len
);
6960 func_name
[len
] = '\0';
6962 func_addr
= sym
->n_value
;
6965 /* line number info */
6967 pc
= sym
->n_value
+ func_addr
;
6968 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
6971 last_line_num
= sym
->n_desc
;
6973 strcpy(last_func_name
, func_name
);
6977 str
= stabstr_section
->data
+ sym
->n_strx
;
6979 if (incl_index
< INCLUDE_STACK_SIZE
) {
6980 incl_files
[incl_index
++] = str
;
6988 if (sym
->n_strx
== 0) {
6989 incl_index
= 0; /* end of translation unit */
6991 str
= stabstr_section
->data
+ sym
->n_strx
;
6992 /* do not add path */
6994 if (len
> 0 && str
[len
- 1] != '/')
7001 /* did not find line number info: */
7002 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
7005 for(i
= 0; i
< incl_index
- 1; i
++)
7006 fprintf(stderr
, "In file included from %s\n",
7008 if (incl_index
> 0) {
7009 fprintf(stderr
, "%s:%d: ",
7010 incl_files
[incl_index
- 1], last_line_num
);
7012 if (last_func_name
[0] != '\0') {
7013 fprintf(stderr
, "in function '%s()': ", last_func_name
);
7017 /* emit a run time error at position 'pc' */
7018 void rt_error(unsigned long pc
, const char *fmt
, ...)
7024 vfprintf(stderr
, fmt
, ap
);
7025 fprintf(stderr
, "\n");
7031 /* signal handler for fatal errors */
7032 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
7034 struct ucontext
*uc
= puc
;
7038 pc
= uc
->uc_mcontext
.gregs
[14];
7040 #error please put the right sigcontext field
7045 switch(siginf
->si_code
) {
7048 rt_error(pc
, "division by zero");
7051 rt_error(pc
, "floating point exception");
7057 rt_error(pc
, "dereferencing invalid pointer");
7060 rt_error(pc
, "illegal instruction");
7063 rt_error(pc
, "abort() called");
7066 rt_error(pc
, "caught signal %d", signum
);
7073 /* do all relocations (needed before using tcc_get_symbol()) */
7074 void tcc_relocate(TCCState
*s1
)
7079 tcc_add_runtime(s1
);
7081 relocate_common_syms();
7083 /* compute relocation address : section are relocated in place. We
7084 also alloc the bss space */
7085 for(i
= 1; i
< nb_sections
; i
++) {
7087 if (s
->sh_flags
& SHF_ALLOC
) {
7089 if (s
->sh_type
== SHT_NOBITS
) {
7090 data
= tcc_mallocz(s
->data_offset
);
7094 s
->sh_addr
= (unsigned long)data
;
7100 /* relocate each section */
7101 for(i
= 1; i
< nb_sections
; i
++) {
7104 relocate_section(s1
, s
);
7108 /* launch the compiled program with the given arguments */
7109 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
7111 int (*prog_main
)(int, char **);
7115 prog_main
= tcc_get_symbol(s1
, "main");
7119 error("debug mode currently not available for Windows");
7121 struct sigaction sigact
;
7122 /* install TCC signal handlers to print debug info on fatal
7124 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
7125 sigact
.sa_sigaction
= sig_error
;
7126 sigemptyset(&sigact
.sa_mask
);
7127 sigaction(SIGFPE
, &sigact
, NULL
);
7128 sigaction(SIGILL
, &sigact
, NULL
);
7129 sigaction(SIGSEGV
, &sigact
, NULL
);
7130 sigaction(SIGBUS
, &sigact
, NULL
);
7131 sigaction(SIGABRT
, &sigact
, NULL
);
7135 #ifdef CONFIG_TCC_BCHECK
7136 if (do_bounds_check
) {
7137 void (*bound_init
)(void);
7138 void **bound_error_func
;
7140 /* set error function */
7141 bound_error_func
= (void **)tcc_get_symbol(s1
, "__bound_error_func");
7142 *bound_error_func
= rt_error
;
7144 /* XXX: use .init section so that it also work in binary ? */
7145 bound_init
= (void *)tcc_get_symbol(s1
, "__bound_init");
7149 return (*prog_main
)(argc
, argv
);
7152 TCCState
*tcc_new(void)
7157 s
= tcc_malloc(sizeof(TCCState
));
7160 s
->output_type
= TCC_OUTPUT_MEMORY
;
7162 /* default include paths */
7163 tcc_add_sysinclude_path(s
, "/usr/local/include");
7164 tcc_add_sysinclude_path(s
, "/usr/include");
7165 tcc_add_sysinclude_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
7167 /* add all tokens */
7168 tok_ident
= TOK_IDENT
;
7173 tok_alloc(p
, r
- p
- 1);
7177 /* we add dummy defines for some special macros to speed up tests
7178 and to have working defined() */
7179 sym_push1(&define_stack
, TOK___LINE__
, MACRO_OBJ
, 0);
7180 sym_push1(&define_stack
, TOK___FILE__
, MACRO_OBJ
, 0);
7181 sym_push1(&define_stack
, TOK___DATE__
, MACRO_OBJ
, 0);
7182 sym_push1(&define_stack
, TOK___TIME__
, MACRO_OBJ
, 0);
7184 /* standard defines */
7185 tcc_define_symbol(s
, "__STDC__", NULL
);
7186 #if defined(TCC_TARGET_I386)
7187 tcc_define_symbol(s
, "__i386__", NULL
);
7190 tcc_define_symbol(s
, "linux", NULL
);
7192 /* tiny C specific defines */
7193 tcc_define_symbol(s
, "__TINYC__", NULL
);
7195 /* default library paths */
7196 tcc_add_library_path(s
, "/usr/local/lib");
7197 tcc_add_library_path(s
, "/usr/lib");
7198 tcc_add_library_path(s
, "/lib");
7200 /* no section zero */
7201 dynarray_add((void ***)§ions
, &nb_sections
, NULL
);
7203 /* create standard sections */
7204 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
7205 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
7206 bss_section
= new_section(".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
7208 /* symbols are always generated for linking stage */
7209 symtab_section
= new_symtab(".symtab", SHT_SYMTAB
, 0,
7211 ".hashtab", SHF_PRIVATE
);
7212 strtab_section
= symtab_section
->link
;
7214 /* private symbol table for dynamic symbols */
7215 dynsymtab_section
= new_symtab(".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
7217 ".dynhashtab", SHF_PRIVATE
);
7221 void tcc_delete(TCCState
*s
)
7226 int tcc_add_include_path(TCCState
*s
, const char *pathname
)
7230 pathname1
= tcc_strdup(pathname
);
7231 dynarray_add((void ***)&include_paths
, &nb_include_paths
, pathname1
);
7235 int tcc_add_sysinclude_path(TCCState
*s
, const char *pathname
)
7239 pathname1
= tcc_strdup(pathname
);
7240 dynarray_add((void ***)&sysinclude_paths
, &nb_sysinclude_paths
, pathname1
);
7244 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
)
7249 BufferedFile
*saved_file
;
7251 /* find source file type with extension */
7252 ext
= strrchr(filename
, '.');
7258 file
= tcc_open(filename
);
7260 if (flags
& AFF_PRINT_ERROR
) {
7261 error("file '%s' not found", filename
);
7268 if (!ext
|| !strcmp(ext
, "c")) {
7269 /* C file assumed */
7273 /* assume executable format: auto guess file type */
7274 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
7275 error("could not read header");
7276 lseek(fd
, 0, SEEK_SET
);
7278 if (ehdr
.e_ident
[0] == ELFMAG0
&&
7279 ehdr
.e_ident
[1] == ELFMAG1
&&
7280 ehdr
.e_ident
[2] == ELFMAG2
&&
7281 ehdr
.e_ident
[3] == ELFMAG3
) {
7282 file
->line_num
= 0; /* do not display line number if error */
7283 if (ehdr
.e_type
== ET_REL
) {
7284 tcc_load_object_file(s
, fd
, 0);
7285 } else if (ehdr
.e_type
== ET_DYN
) {
7286 tcc_load_dll(s
, fd
, filename
, (flags
& AFF_REFERENCED_DLL
) != 0);
7288 error("unrecognized ELF file");
7290 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
7291 file
->line_num
= 0; /* do not display line number if error */
7292 tcc_load_archive(s
, fd
);
7294 /* as GNU ld, consider it is an ld script if not recognized */
7295 if (tcc_load_ldscript(s
) < 0)
7296 error("unrecognized file type");
7304 void tcc_add_file(TCCState
*s
, const char *filename
)
7306 tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
7309 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
7313 pathname1
= tcc_strdup(pathname
);
7314 dynarray_add((void ***)&library_paths
, &nb_library_paths
, pathname1
);
7318 /* find and load a dll. Return non zero if not found */
7319 /* XXX: add '-rpath' option support ? */
7320 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
7325 for(i
= 0; i
< nb_library_paths
; i
++) {
7326 snprintf(buf
, sizeof(buf
), "%s/%s",
7327 library_paths
[i
], filename
);
7328 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
7334 /* the library name is the same as the argument of the '-l' option */
7335 int tcc_add_library(TCCState
*s
, const char *libraryname
)
7341 /* first we look for the dynamic library if not static linking */
7343 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
7344 /* if we output to memory, then we simply we dlopen(). */
7345 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
7346 /* Since the libc is already loaded, we don't need to load it again */
7347 if (!strcmp(libraryname
, "c"))
7349 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
7353 if (tcc_add_dll(s
, buf
, 0) == 0)
7358 /* then we look for the static library */
7359 for(i
= 0; i
< nb_library_paths
; i
++) {
7360 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
7361 library_paths
[i
], libraryname
);
7362 if (tcc_add_file_internal(s
, buf
, 0) == 0)
7368 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
7370 add_elf_sym(symtab_section
, val
, 0,
7371 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7376 int tcc_set_output_type(TCCState
*s
, int output_type
)
7378 s
->output_type
= output_type
;
7380 /* if bound checking, then add corresponding sections */
7381 #ifdef CONFIG_TCC_BCHECK
7382 if (do_bounds_check
) {
7384 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
7385 /* create bounds sections */
7386 bounds_section
= new_section(".bounds",
7387 SHT_PROGBITS
, SHF_ALLOC
);
7388 lbounds_section
= new_section(".lbounds",
7389 SHT_PROGBITS
, SHF_ALLOC
);
7393 /* add debug sections */
7396 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
7397 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
7398 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
7399 put_elf_str(stabstr_section
, "");
7400 stab_section
->link
= stabstr_section
;
7401 /* put first entry */
7402 put_stabs("", 0, 0, 0, 0);
7405 /* add libc crt1/crti objects */
7406 if (output_type
== TCC_OUTPUT_EXE
||
7407 output_type
== TCC_OUTPUT_DLL
) {
7408 if (output_type
!= TCC_OUTPUT_DLL
)
7409 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
7410 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
7415 #if !defined(LIBTCC)
7419 printf("tcc version 0.9.12 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7420 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7421 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
7422 " [--] infile1 [infile2... --] [infile_args...]\n"
7424 "General options:\n"
7425 " -c compile only - generate an object file\n"
7426 " -o outfile set output filename\n"
7427 " -- allows multiples input files if no -o option given. Also\n"
7428 " separate input files from runtime arguments\n"
7429 " -Bdir set tcc internal library path\n"
7430 " -bench output compilation statistics\n"
7431 "Preprocessor options:\n"
7432 " -Idir add include path 'dir'\n"
7433 " -Dsym[=val] define 'sym' with value 'val'\n"
7434 " -Usym undefine 'sym'\n"
7435 "C compiler options:\n"
7436 " -g generate runtime debug info\n"
7437 #ifdef CONFIG_TCC_BCHECK
7438 " -b compile with built-in memory and bounds checker (implies -g)\n"
7441 " -Ldir add library path 'dir'\n"
7442 " -llib link with dynamic or static library 'lib'\n"
7443 " -shared generate a shared library\n"
7444 " -static static linking\n"
7445 " -r relocatable output\n"
7449 int main(int argc
, char **argv
)
7452 int optind
, output_type
, multiple_files
, i
, reloc_output
;
7455 int nb_files
, nb_libraries
, nb_objfiles
, dminus
;
7456 char objfilename
[1024];
7459 output_type
= TCC_OUTPUT_MEMORY
;
7470 if (optind
>= argc
) {
7478 /* add a new file */
7479 dynarray_add((void ***)&files
, &nb_files
, r
);
7480 if (!multiple_files
) {
7482 /* argv[0] will be this file */
7485 } else if (r
[1] == '-') {
7486 /* '--' enables multiple files input and also ends several file input */
7487 if (dminus
&& multiple_files
) {
7488 optind
--; /* argv[0] will be '--' */
7493 } else if (r
[1] == 'h' || r
[1] == '?') {
7497 } else if (r
[1] == 'I') {
7498 if (tcc_add_include_path(s
, r
+ 2) < 0)
7499 error("too many include paths");
7500 } else if (r
[1] == 'D') {
7503 value
= strchr(sym
, '=');
7508 tcc_define_symbol(s
, sym
, value
);
7509 } else if (r
[1] == 'U') {
7510 tcc_undefine_symbol(s
, r
+ 2);
7511 } else if (r
[1] == 'L') {
7512 tcc_add_library_path(s
, r
+ 2);
7513 } else if (r
[1] == 'B') {
7514 /* set tcc utilities path (mainly for tcc development) */
7515 tcc_lib_path
= r
+ 2;
7516 } else if (r
[1] == 'l') {
7517 dynarray_add((void ***)&files
, &nb_files
, r
);
7519 } else if (!strcmp(r
+ 1, "bench")) {
7522 #ifdef CONFIG_TCC_BCHECK
7524 do_bounds_check
= 1;
7530 } else if (r
[1] == 'c') {
7532 output_type
= TCC_OUTPUT_OBJ
;
7533 } else if (!strcmp(r
+ 1, "static")) {
7535 } else if (!strcmp(r
+ 1, "shared")) {
7536 output_type
= TCC_OUTPUT_DLL
;
7537 } else if (r
[1] == 'o') {
7541 outfile
= argv
[optind
++];
7542 } else if (r
[1] == 'r') {
7543 /* generate a .o merging several output files */
7545 output_type
= TCC_OUTPUT_OBJ
;
7547 error("invalid option -- '%s'", r
);
7551 nb_objfiles
= nb_files
- nb_libraries
;
7553 /* if outfile provided without other options, we output an
7555 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
7556 output_type
= TCC_OUTPUT_EXE
;
7558 /* check -c consistency : only single file handled. XXX: checks file type */
7559 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
7560 /* accepts only a single input file */
7561 if (nb_objfiles
!= 1)
7562 error("cannot specify multiple files with -c");
7563 if (nb_libraries
!= 0)
7564 error("cannot specify libraries with -c");
7567 /* compute default outfile name */
7568 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
7569 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
7571 /* add .o extension */
7572 pstrcpy(objfilename
, sizeof(objfilename
) - 1, files
[0]);
7573 ext
= strrchr(objfilename
, '.');
7575 goto default_outfile
;
7576 strcpy(ext
+ 1, "o");
7579 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
7581 outfile
= objfilename
;
7584 tcc_set_output_type(s
, output_type
);
7586 /* compile or add each files or library */
7587 for(i
= 0;i
< nb_files
; i
++) {
7588 const char *filename
;
7590 filename
= files
[i
];
7591 if (filename
[0] == '-') {
7592 if (tcc_add_library(s
, filename
+ 2) < 0)
7593 error("cannot find %s", filename
);
7595 tcc_add_file(s
, filename
);
7600 printf("total: %d idents, %d lines, %d bytes\n",
7601 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
7603 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);
7607 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
7608 tcc_output_file(s
, outfile
);
7611 return tcc_run(s
, argc
- optind
, argv
+ optind
);