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 */
47 /* target selection */
48 //#define TCC_TARGET_I386 /* i386 code generator */
49 //#define TCC_TARGET_IL /* .NET CLI generator */
51 /* default target is I386 */
52 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
53 #define TCC_TARGET_I386
56 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
57 #define CONFIG_TCC_BCHECK /* enable bound checking code */
60 #ifndef CONFIG_TCC_PREFIX
61 #define CONFIG_TCC_PREFIX "/usr/local"
64 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
65 executables or dlls */
66 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
68 #define INCLUDE_STACK_SIZE 32
69 #define IFDEF_STACK_SIZE 64
70 #define VSTACK_SIZE 64
71 #define STRING_MAX_SIZE 1024
73 #define TOK_HASH_SIZE 2048 /* must be a power of two */
74 #define TOK_ALLOC_INCR 512 /* must be a power of two */
75 #define SYM_HASH_SIZE 1031
77 /* token symbol management */
78 typedef struct TokenSym
{
79 struct TokenSym
*hash_next
;
80 int tok
; /* token number */
85 typedef struct CString
{
86 int size
; /* size in bytes */
87 void *data
; /* either 'char *' or 'int *' */
89 void *data_allocated
; /* if non NULL, data has been malloced */
93 typedef union CValue
{
99 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
101 unsigned long long ull
;
102 struct CString
*cstr
;
109 typedef struct SValue
{
111 unsigned short r
; /* register + flags */
112 unsigned short r2
; /* second register, used for 'long long'
113 type. If not used, set to VT_CONST */
114 CValue c
; /* constant, if VT_CONST */
117 /* symbol management */
119 int v
; /* symbol token */
120 int t
; /* associated type */
121 int r
; /* associated register */
122 int c
; /* associated number */
123 struct Sym
*next
; /* next related symbol */
124 struct Sym
*prev
; /* prev symbol in stack */
125 struct Sym
*hash_next
; /* next symbol in hash table */
128 typedef struct SymStack
{
130 struct Sym
*hash
[SYM_HASH_SIZE
];
133 /* section definition */
134 /* XXX: use directly ELF structure for parameters ? */
135 /* special flag to indicate that the section should not be linked to
137 #define SHF_PRIVATE 0x80000000
139 typedef struct Section
{
140 unsigned long data_offset
; /* current data offset */
141 unsigned char *data
; /* section data */
142 unsigned long data_allocated
; /* used for realloc() handling */
143 int sh_name
; /* elf section name (only used during output) */
144 int sh_num
; /* elf section number */
145 int sh_type
; /* elf section type */
146 int sh_flags
; /* elf section flags */
147 int sh_info
; /* elf section info */
148 int sh_addralign
; /* elf section alignment */
149 int sh_entsize
; /* elf entry size */
150 unsigned long sh_size
; /* section size (only used during output) */
151 unsigned long sh_addr
; /* address at which the section is relocated */
152 unsigned long sh_offset
; /* address at which the section is relocated */
153 int nb_hashed_syms
; /* used to resize the hash table */
154 struct Section
*link
; /* link to another section */
155 struct Section
*reloc
; /* corresponding section for relocation, if any */
156 struct Section
*hash
; /* hash table for symbols */
157 struct Section
*next
;
158 char name
[64]; /* section name */
161 typedef struct DLLReference
{
166 /* GNUC attribute definition */
167 typedef struct AttributeDef
{
170 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
173 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
174 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
175 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
177 /* stored in 'Sym.c' field */
178 #define FUNC_NEW 1 /* ansi function prototype */
179 #define FUNC_OLD 2 /* old function prototype */
180 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
182 /* stored in 'Sym.r' field */
183 #define FUNC_CDECL 0 /* standard c call */
184 #define FUNC_STDCALL 1 /* pascal c call */
186 /* field 'Sym.t' for macros */
187 #define MACRO_OBJ 0 /* object like macro */
188 #define MACRO_FUNC 1 /* function like macro */
190 /* field 'Sym.t' for labels */
191 #define LABEL_FORWARD 1 /* label is forward defined */
193 /* type_decl() types */
194 #define TYPE_ABSTRACT 1 /* type without variable */
195 #define TYPE_DIRECT 2 /* type with variable */
197 #define IO_BUF_SIZE 8192
199 typedef struct BufferedFile
{
200 unsigned char *buf_ptr
;
201 unsigned char *buf_end
;
203 int line_num
; /* current line number - here to simply code */
204 char filename
[1024]; /* current filename - here to simplify code */
205 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
208 #define CH_EOB 0 /* end of buffer or '\0' char in file */
209 #define CH_EOF (-1) /* end of file */
211 /* parsing state (used to save parser state to reparse part of the
212 source several times) */
213 typedef struct ParseState
{
220 /* used to record tokens */
221 typedef struct TokenString
{
228 struct BufferedFile
*file
;
229 int ch
, ch1
, tok
, tok1
;
231 CString tokcstr
; /* current parsed string, if any */
232 int return_linefeed
; /* if true, line feed is returned as a token */
236 int nb_sections
; /* number of sections, including first dummy section */
237 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
238 Section
*cur_text_section
; /* current section where function code is
240 /* bound check related sections */
241 Section
*bounds_section
; /* contains global data bound description */
242 Section
*lbounds_section
; /* contains local data bound description */
243 /* symbol sections */
244 Section
*symtab_section
, *strtab_section
;
245 /* temporary dynamic symbol sections (for dll loading) */
246 Section
*dynsymtab_section
;
247 /* exported dynamic symbol section */
251 unsigned long *got_offsets
;
254 /* give the correspondance from symtab indexes to dynsym indexes */
255 int *symtab_to_dynsym
;
257 /* array of all loaded dlls (including those referenced by loaded
259 DLLReference
**loaded_dlls
;
263 Section
*stab_section
, *stabstr_section
;
265 char **library_paths
;
266 int nb_library_paths
;
268 /* loc : local variable index
269 ind : output code index
271 anon_sym: anonymous symbol index
274 prog
, ind
, loc
, const_wanted
;
275 int global_expr
; /* true if compound literals must be allocated
276 globally (used during initializers parsing */
277 int func_vt
, func_vc
; /* current function return type (used by
278 return instruction) */
279 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
281 TokenSym
**table_ident
;
282 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
283 char token_buf
[STRING_MAX_SIZE
+ 1];
285 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
287 SValue vstack
[VSTACK_SIZE
], *vtop
;
288 int *macro_ptr
, *macro_ptr_allocated
;
289 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
], **include_stack_ptr
;
290 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
291 char **include_paths
;
292 int nb_include_paths
;
293 char **sysinclude_paths
;
294 int nb_sysinclude_paths
;
295 int char_pointer_type
;
298 /* compile with debug symbol (and use them if error during execution) */
301 /* compile with built-in memory and bounds checker */
302 int do_bounds_check
= 0;
304 /* display benchmark infos */
309 /* use GNU C extensions */
312 /* use Tiny C extensions */
315 /* if true, static linking is performed */
318 /* give the path of the tcc libraries */
319 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
325 /* The current value can be: */
326 #define VT_VALMASK 0x00ff
327 #define VT_CONST 0x00f0 /* constant in vc
328 (must be first non register value) */
329 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
330 #define VT_LOCAL 0x00f2 /* offset on stack */
331 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
332 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
333 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
334 #define VT_LVAL 0x0100 /* var is an lvalue */
335 #define VT_SYM 0x0200 /* a symbol value is added */
336 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
337 char/short stored in integer registers) */
338 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
339 dereferencing value */
340 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
341 bounding function call point is in vc */
342 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
343 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
344 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
345 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
348 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
350 #define VT_INT 0 /* integer type */
351 #define VT_BYTE 1 /* signed byte type */
352 #define VT_SHORT 2 /* short type */
353 #define VT_VOID 3 /* void type */
354 #define VT_PTR 4 /* pointer */
355 #define VT_ENUM 5 /* enum definition */
356 #define VT_FUNC 6 /* function type */
357 #define VT_STRUCT 7 /* struct/union definition */
358 #define VT_FLOAT 8 /* IEEE float */
359 #define VT_DOUBLE 9 /* IEEE double */
360 #define VT_LDOUBLE 10 /* IEEE long double */
361 #define VT_BOOL 11 /* ISOC99 boolean type */
362 #define VT_LLONG 12 /* 64 bit integer */
363 #define VT_LONG 13 /* long integer (NEVER USED as type, only
365 #define VT_BTYPE 0x000f /* mask for basic type */
366 #define VT_UNSIGNED 0x0010 /* unsigned type */
367 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
368 #define VT_BITFIELD 0x0040 /* bitfield modifier */
371 #define VT_EXTERN 0x00000080 /* extern definition */
372 #define VT_STATIC 0x00000100 /* static variable */
373 #define VT_TYPEDEF 0x00000200 /* typedef definition */
375 /* type mask (except storage) */
376 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
380 /* warning: the following compare tokens depend on i386 asm code */
392 #define TOK_LAND 0xa0
396 #define TOK_MID 0xa3 /* inc/dec, to void constant */
398 #define TOK_UDIV 0xb0 /* unsigned division */
399 #define TOK_UMOD 0xb1 /* unsigned modulo */
400 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
401 #define TOK_CINT 0xb3 /* number in tokc */
402 #define TOK_CCHAR 0xb4 /* char constant in tokc */
403 #define TOK_STR 0xb5 /* pointer to string in tokc */
404 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
405 #define TOK_LCHAR 0xb7
406 #define TOK_LSTR 0xb8
407 #define TOK_CFLOAT 0xb9 /* float constant */
408 #define TOK_LINENUM 0xba /* line number info */
409 #define TOK_CDOUBLE 0xc0 /* double constant */
410 #define TOK_CLDOUBLE 0xc1 /* long double constant */
411 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
412 #define TOK_ADDC1 0xc3 /* add with carry generation */
413 #define TOK_ADDC2 0xc4 /* add with carry use */
414 #define TOK_SUBC1 0xc5 /* add with carry generation */
415 #define TOK_SUBC2 0xc6 /* add with carry use */
416 #define TOK_CUINT 0xc8 /* unsigned int constant */
417 #define TOK_CLLONG 0xc9 /* long long constant */
418 #define TOK_CULLONG 0xca /* unsigned long long constant */
419 #define TOK_ARROW 0xcb
420 #define TOK_DOTS 0xcc /* three dots */
421 #define TOK_SHR 0xcd /* unsigned shift right */
423 #define TOK_SHL 0x01 /* shift left */
424 #define TOK_SAR 0x02 /* signed shift right */
426 /* assignement operators : normal operator or 0x80 */
427 #define TOK_A_MOD 0xa5
428 #define TOK_A_AND 0xa6
429 #define TOK_A_MUL 0xaa
430 #define TOK_A_ADD 0xab
431 #define TOK_A_SUB 0xad
432 #define TOK_A_DIV 0xaf
433 #define TOK_A_XOR 0xde
434 #define TOK_A_OR 0xfc
435 #define TOK_A_SHL 0x81
436 #define TOK_A_SAR 0x82
438 /* WARNING: the content of this string encodes token numbers */
439 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";
441 #define TOK_EOF (-1) /* end of file */
442 #define TOK_LINEFEED 10 /* line feed */
444 /* all identificators and strings have token above that */
445 #define TOK_IDENT 256
466 /* ignored types Must have contiguous values */
472 TOK___SIGNED__
, /* gcc keyword */
475 TOK___INLINE__
, /* gcc keyword */
478 /* unsupported type */
492 /* preprocessor only */
493 TOK_UIDENT
, /* first "user" ident (not keyword) */
494 TOK_DEFINE
= TOK_UIDENT
,
510 /* special identifiers */
513 #define DEF(id, str) id,
519 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
520 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
521 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
522 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
523 "sizeof\0__attribute__\0"
524 /* the following are not keywords. They are included to ease parsing */
525 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
526 "defined\0undef\0error\0line\0"
527 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
529 /* builtin functions */
530 #define DEF(id, str) str "\0"
536 #define snprintf _snprintf
539 #if defined(WIN32) || defined(TCC_UCLIBC)
540 /* currently incorrect */
541 long double strtold(const char *nptr
, char **endptr
)
543 return (long double)strtod(nptr
, endptr
);
545 float strtof(const char *nptr
, char **endptr
)
547 return (float)strtod(nptr
, endptr
);
550 /* XXX: need to define this to use them in non ISOC99 context */
551 extern float strtof (const char *__nptr
, char **__endptr
);
552 extern long double strtold (const char *__nptr
, char **__endptr
);
555 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
556 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
560 void next_nomacro(void);
561 int expr_const(void);
565 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
);
566 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
569 void gv2(int rc1
, int rc2
);
570 void move_reg(int r
, int s
);
571 void save_regs(int n
);
572 void save_reg(int r
);
578 void macro_subst(TokenString
*tok_str
,
579 Sym
**nested_list
, int *macro_str
);
580 int save_reg_forced(int r
);
582 void force_charshort_cast(int t
);
583 void gen_cast(int t
);
585 Sym
*sym_find(int v
);
586 Sym
*sym_push(int v
, int t
, int r
, int c
);
589 int type_size(int t
, int *a
);
590 int pointed_type(int t
);
591 int pointed_size(int t
);
592 static int lvalue_type(int t
);
593 int is_compatible_types(int t1
, int t2
);
594 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
595 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
597 void error(const char *fmt
, ...);
598 void rt_error(unsigned long pc
, const char *fmt
, ...);
600 void vset(int t
, int r
, int v
);
601 void type_to_str(char *buf
, int buf_size
,
602 int t
, const char *varstr
);
603 char *get_tok_str(int v
, CValue
*cv
);
604 Sym
*external_sym(int v
, int u
, int r
);
605 static Sym
*get_sym_ref(int t
, Section
*sec
,
606 unsigned long offset
, unsigned long size
);
608 /* section generation */
609 static void section_realloc(Section
*sec
, unsigned long new_size
);
610 static void *section_ptr(Section
*sec
, unsigned long size
);
611 static void *section_ptr_add(Section
*sec
, unsigned long size
);
612 static void put_extern_sym(Sym
*sym
, Section
*section
,
613 unsigned long value
, unsigned long size
);
614 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
615 static int put_elf_str(Section
*s
, const char *sym
);
616 static int put_elf_sym(Section
*s
,
617 unsigned long value
, unsigned long size
,
618 int info
, int other
, int shndx
, const char *name
);
619 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
620 int info
, int sh_num
, const char *name
);
621 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
622 int type
, int symbol
);
623 static void put_stabs(const char *str
, int type
, int other
, int desc
,
624 unsigned long value
);
625 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
626 unsigned long value
, Section
*sec
, int sym_index
);
627 static void put_stabn(int type
, int other
, int desc
, int value
);
628 static void put_stabd(int type
, int other
, int desc
);
629 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
631 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
632 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
633 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
635 /* true if float/double/long double type */
636 static inline int is_float(int t
)
640 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
643 #ifdef TCC_TARGET_I386
644 #include "i386-gen.c"
650 #ifdef CONFIG_TCC_STATIC
652 #define RTLD_LAZY 0x001
653 #define RTLD_NOW 0x002
654 #define RTLD_GLOBAL 0x100
656 /* dummy function for profiling */
657 void *dlopen(const char *filename
, int flag
)
662 const char *dlerror(void)
667 typedef struct TCCSyms
{
672 #define TCCSYM(a) { #a, &a, },
674 /* add the symbol you want here if no dynamic linking is done */
675 static TCCSyms tcc_syms
[] = {
683 void *dlsym(void *handle
, const char *symbol
)
687 while (p
->str
!= NULL
) {
688 if (!strcmp(p
->str
, symbol
))
697 /********************************************************/
699 /* we use our own 'finite' function to avoid potential problems with
700 non standard math libs */
701 /* XXX: endianness dependant */
702 int ieee_finite(double d
)
705 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
708 /* copy a string and truncate it. */
709 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
716 q_end
= buf
+ buf_size
- 1;
728 /* strcat and truncate. */
729 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
734 pstrcpy(buf
+ len
, buf_size
- len
, s
);
738 /* memory management */
744 static inline void tcc_free(void *ptr
)
747 mem_cur_size
-= malloc_usable_size(ptr
);
752 static void *tcc_malloc(unsigned long size
)
757 error("memory full");
759 mem_cur_size
+= malloc_usable_size(ptr
);
760 if (mem_cur_size
> mem_max_size
)
761 mem_max_size
= mem_cur_size
;
766 static void *tcc_mallocz(unsigned long size
)
769 ptr
= tcc_malloc(size
);
770 memset(ptr
, 0, size
);
774 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
778 mem_cur_size
-= malloc_usable_size(ptr
);
780 ptr1
= realloc(ptr
, size
);
782 /* NOTE: count not correct if alloc error, but not critical */
783 mem_cur_size
+= malloc_usable_size(ptr1
);
784 if (mem_cur_size
> mem_max_size
)
785 mem_max_size
= mem_cur_size
;
790 static char *tcc_strdup(const char *str
)
793 ptr
= tcc_malloc(strlen(str
) + 1);
798 #define free(p) use_tcc_free(p)
799 #define malloc(s) use_tcc_malloc(s)
800 #define realloc(p, s) use_tcc_realloc(p, s)
802 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
809 /* every power of two we double array size */
810 if ((nb
& (nb
- 1)) == 0) {
815 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
817 error("memory full");
824 Section
*new_section(const char *name
, int sh_type
, int sh_flags
)
828 sec
= tcc_mallocz(sizeof(Section
));
829 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
830 sec
->sh_type
= sh_type
;
831 sec
->sh_flags
= sh_flags
;
838 sec
->sh_addralign
= 4;
841 sec
->sh_addralign
= 1;
844 sec
->sh_addralign
= 32; /* default conservative alignment */
848 /* only add section if not private */
849 if (!(sh_flags
& SHF_PRIVATE
)) {
850 sec
->sh_num
= nb_sections
;
851 dynarray_add((void ***)§ions
, &nb_sections
, sec
);
856 /* realloc section and set its content to zero */
857 static void section_realloc(Section
*sec
, unsigned long new_size
)
862 size
= sec
->data_allocated
;
865 while (size
< new_size
)
867 data
= tcc_realloc(sec
->data
, size
);
869 error("memory full");
870 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
872 sec
->data_allocated
= size
;
875 /* reserve at least 'size' bytes in section 'sec' from
876 sec->data_offset. Optimized for speed */
877 static inline void *section_ptr(Section
*sec
, unsigned long size
)
879 unsigned long offset
, offset1
;
880 offset
= sec
->data_offset
;
881 offset1
= offset
+ size
;
882 if (offset1
> sec
->data_allocated
)
883 section_realloc(sec
, offset1
);
884 return sec
->data
+ offset
;
887 static void *section_ptr_add(Section
*sec
, unsigned long size
)
889 unsigned long offset
, offset1
;
891 offset
= sec
->data_offset
;
892 offset1
= offset
+ size
;
893 if (offset1
> sec
->data_allocated
)
894 section_realloc(sec
, offset1
);
895 sec
->data_offset
= offset1
;
896 return sec
->data
+ offset
;
899 /* return a reference to a section, and create it if it does not
901 Section
*find_section(const char *name
)
905 for(i
= 1; i
< nb_sections
; i
++) {
907 if (!strcmp(name
, sec
->name
))
910 /* sections are created as PROGBITS */
911 return new_section(name
, SHT_PROGBITS
, SHF_ALLOC
);
914 /* update sym->c so that it points to an external symbol in section
915 'section' with value 'value' */
916 static void put_extern_sym(Sym
*sym
, Section
*section
,
917 unsigned long value
, unsigned long size
)
919 int sym_type
, sym_bind
, sh_num
, info
;
925 sh_num
= section
->sh_num
;
929 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
932 sym_type
= STT_OBJECT
;
933 if (sym
->t
& VT_STATIC
)
934 sym_bind
= STB_LOCAL
;
936 sym_bind
= STB_GLOBAL
;
938 name
= get_tok_str(sym
->v
, NULL
);
939 #ifdef CONFIG_TCC_BCHECK
940 if (do_bounds_check
) {
941 /* if bound checking is activated, we change some function
942 names by adding the "__bound" prefix */
954 strcpy(buf
, "__bound_");
961 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
962 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
964 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
965 esym
->st_value
= value
;
966 esym
->st_size
= size
;
967 esym
->st_shndx
= sh_num
;
971 /* add a new relocation entry to symbol 'sym' in section 's' */
972 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
975 put_extern_sym(sym
, NULL
, 0, 0);
976 /* now we can add ELF relocation info */
977 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
980 static inline int isid(int c
)
982 return (c
>= 'a' && c
<= 'z') ||
983 (c
>= 'A' && c
<= 'Z') ||
987 static inline int isnum(int c
)
989 return c
>= '0' && c
<= '9';
992 static inline int toup(int c
)
994 if (ch
>= 'a' && ch
<= 'z')
995 return ch
- 'a' + 'A';
1000 void printline(void)
1005 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
1006 fprintf(stderr
, "In file included from %s:%d:\n",
1007 (*f
)->filename
, (*f
)->line_num
);
1008 if (file
->line_num
> 0) {
1009 fprintf(stderr
, "%s:%d: ", file
->filename
, file
->line_num
);
1011 fprintf(stderr
, "%s: ", file
->filename
);
1014 fprintf(stderr
, "tcc: ");
1018 void error(const char *fmt
, ...)
1023 vfprintf(stderr
, fmt
, ap
);
1024 fprintf(stderr
, "\n");
1029 void expect(const char *msg
)
1031 error("%s expected", msg
);
1034 void warning(const char *fmt
, ...)
1040 fprintf(stderr
, "warning: ");
1041 vfprintf(stderr
, fmt
, ap
);
1042 fprintf(stderr
, "\n");
1049 error("'%c' expected", c
);
1053 void test_lvalue(void)
1055 if (!(vtop
->r
& VT_LVAL
))
1059 TokenSym
*tok_alloc(const char *str
, int len
)
1061 TokenSym
*ts
, **pts
, **ptable
;
1068 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
1070 pts
= &hash_ident
[h
];
1075 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1077 pts
= &(ts
->hash_next
);
1080 if (tok_ident
>= SYM_FIRST_ANOM
)
1081 error("memory full");
1083 /* expand token table if needed */
1084 i
= tok_ident
- TOK_IDENT
;
1085 if ((i
% TOK_ALLOC_INCR
) == 0) {
1086 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1088 error("memory full");
1089 table_ident
= ptable
;
1092 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1093 table_ident
[i
] = ts
;
1094 ts
->tok
= tok_ident
++;
1096 ts
->hash_next
= NULL
;
1097 memcpy(ts
->str
, str
, len
+ 1);
1102 /* CString handling */
1104 static void cstr_realloc(CString
*cstr
, int new_size
)
1109 size
= cstr
->size_allocated
;
1111 size
= 8; /* no need to allocate a too small first string */
1112 while (size
< new_size
)
1114 data
= tcc_realloc(cstr
->data_allocated
, size
);
1116 error("memory full");
1117 cstr
->data_allocated
= data
;
1118 cstr
->size_allocated
= size
;
1123 static void cstr_ccat(CString
*cstr
, int ch
)
1126 size
= cstr
->size
+ 1;
1127 if (size
> cstr
->size_allocated
)
1128 cstr_realloc(cstr
, size
);
1129 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1133 static void cstr_cat(CString
*cstr
, const char *str
)
1145 /* add a wide char */
1146 static void cstr_wccat(CString
*cstr
, int ch
)
1149 size
= cstr
->size
+ sizeof(int);
1150 if (size
> cstr
->size_allocated
)
1151 cstr_realloc(cstr
, size
);
1152 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1156 static void cstr_new(CString
*cstr
)
1158 memset(cstr
, 0, sizeof(CString
));
1161 /* free string and reset it to NULL */
1162 static void cstr_free(CString
*cstr
)
1164 tcc_free(cstr
->data_allocated
);
1168 #define cstr_reset(cstr) cstr_free(cstr)
1170 /* XXX: unicode ? */
1171 static void add_char(CString
*cstr
, int c
)
1173 if (c
== '\'' || c
== '\"' || c
== '\\') {
1174 /* XXX: could be more precise if char or string */
1175 cstr_ccat(cstr
, '\\');
1177 if (c
>= 32 && c
<= 126) {
1180 cstr_ccat(cstr
, '\\');
1182 cstr_ccat(cstr
, 'n');
1184 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1185 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1186 cstr_ccat(cstr
, '0' + (c
& 7));
1191 /* XXX: buffer overflow */
1192 /* XXX: float tokens */
1193 char *get_tok_str(int v
, CValue
*cv
)
1195 static char buf
[STRING_MAX_SIZE
+ 1];
1196 static CString cstr_buf
;
1202 /* NOTE: to go faster, we give a fixed buffer for small strings */
1203 cstr_reset(&cstr_buf
);
1204 cstr_buf
.data
= buf
;
1205 cstr_buf
.size_allocated
= sizeof(buf
);
1211 /* XXX: not exact */
1212 sprintf(p
, "%u", cv
->ui
);
1216 cstr_ccat(&cstr_buf
, '\'');
1217 add_char(&cstr_buf
, cv
->i
);
1218 cstr_ccat(&cstr_buf
, '\'');
1219 cstr_ccat(&cstr_buf
, '\0');
1224 cstr_ccat(&cstr_buf
, '\"');
1226 len
= cstr
->size
- 1;
1228 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1230 len
= (cstr
->size
/ sizeof(int)) - 1;
1232 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1234 cstr_ccat(&cstr_buf
, '\"');
1235 cstr_ccat(&cstr_buf
, '\0');
1244 return strcpy(p
, "<<=");
1246 return strcpy(p
, ">>=");
1248 if (v
< TOK_IDENT
) {
1249 /* search in two bytes table */
1263 } else if (v
< tok_ident
) {
1264 return table_ident
[v
- TOK_IDENT
]->str
;
1265 } else if (v
>= SYM_FIRST_ANOM
) {
1266 /* special name for anonymous symbol */
1267 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1269 /* should never happen */
1274 return cstr_buf
.data
;
1277 /* push, without hashing */
1278 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1281 s
= tcc_malloc(sizeof(Sym
));
1292 /* find a symbol and return its associated structure. 's' is the top
1293 of the symbol stack */
1294 Sym
*sym_find2(Sym
*s
, int v
)
1304 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1306 /* find a symbol and return its associated structure. 'st' is the
1308 Sym
*sym_find1(SymStack
*st
, int v
)
1312 s
= st
->hash
[HASH_SYM(v
)];
1321 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1324 s
= sym_push2(&st
->top
, v
, t
, c
);
1325 /* add in hash table */
1327 ps
= &st
->hash
[HASH_SYM(v
)];
1334 /* find a symbol in the right symbol space */
1335 Sym
*sym_find(int v
)
1338 s
= sym_find1(&local_stack
, v
);
1340 s
= sym_find1(&global_stack
, v
);
1344 /* push a given symbol on the symbol stack */
1345 Sym
*sym_push(int v
, int t
, int r
, int c
)
1348 if (local_stack
.top
)
1349 s
= sym_push1(&local_stack
, v
, t
, c
);
1351 s
= sym_push1(&global_stack
, v
, t
, c
);
1356 /* pop symbols until top reaches 'b' */
1357 void sym_pop(SymStack
*st
, Sym
*b
)
1364 /* free hash table entry, except if symbol was freed (only
1365 used for #undef symbols) */
1367 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1374 /* undefined a hashed symbol (used for #undef). Its name is set to
1376 void sym_undef(SymStack
*st
, Sym
*s
)
1379 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1380 while (*ss
!= NULL
) {
1383 ss
= &(*ss
)->hash_next
;
1391 BufferedFile
*tcc_open(const char *filename
)
1396 fd
= open(filename
, O_RDONLY
);
1399 bf
= tcc_malloc(sizeof(BufferedFile
));
1405 bf
->buf_ptr
= bf
->buffer
;
1406 bf
->buf_end
= bf
->buffer
;
1407 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1408 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1410 // printf("opening '%s'\n", filename);
1414 void tcc_close(BufferedFile
*bf
)
1416 total_lines
+= bf
->line_num
;
1421 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1422 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1424 /* fill input buffer and return next char */
1425 int tcc_getc_slow(BufferedFile
*bf
)
1428 /* only tries to read if really end of buffer */
1429 if (bf
->buf_ptr
>= bf
->buf_end
) {
1431 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1438 bf
->buf_ptr
= bf
->buffer
;
1439 bf
->buf_end
= bf
->buffer
+ len
;
1440 *bf
->buf_end
= CH_EOB
;
1442 if (bf
->buf_ptr
< bf
->buf_end
) {
1443 return *bf
->buf_ptr
++;
1445 bf
->buf_ptr
= bf
->buf_end
;
1450 /* no need to put that inline */
1451 void handle_eob(void)
1454 ch1
= tcc_getc_slow(file
);
1458 if (include_stack_ptr
== include_stack
)
1460 /* add end of include file debug info */
1462 put_stabd(N_EINCL
, 0, 0);
1464 /* pop include stack */
1466 include_stack_ptr
--;
1467 file
= *include_stack_ptr
;
1471 /* read next char from current input file */
1472 static inline void inp(void)
1474 ch1
= TCC_GETC(file
);
1475 /* end of buffer/file handling */
1480 // printf("ch1=%c 0x%x\n", ch1, ch1);
1483 /* input with '\\n' handling */
1484 static inline void minp(void)
1489 if (ch
== '\\' && ch1
== '\n') {
1493 //printf("ch=%c 0x%x\n", ch, ch);
1497 /* same as minp, but also skip comments */
1505 /* single line C++ comments */
1507 while (ch1
!= '\n' && ch1
!= -1)
1510 ch
= ' '; /* return space */
1511 } else if (ch1
== '*') {
1517 if (c
== '*' && ch1
== '/') {
1519 ch
= ' '; /* return space */
1531 void skip_spaces(void)
1533 while (ch
== ' ' || ch
== '\t')
1537 /* skip block of text until #else, #elif or #endif. skip also pairs of
1539 void preprocess_skip(void)
1544 while (ch
!= '\n') {
1555 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1557 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1559 else if (tok
== TOK_ENDIF
)
1565 /* ParseState handling */
1567 /* XXX: currently, no include file info is stored. Thus, we cannot display
1568 accurate messages if the function or data definition spans multiple
1571 /* save current parse state in 's' */
1572 void save_parse_state(ParseState
*s
)
1574 s
->line_num
= file
->line_num
;
1575 s
->macro_ptr
= macro_ptr
;
1580 /* restore parse state from 's' */
1581 void restore_parse_state(ParseState
*s
)
1583 file
->line_num
= s
->line_num
;
1584 macro_ptr
= s
->macro_ptr
;
1589 /* return the number of additionnal 'ints' necessary to store the
1591 static inline int tok_ext_size(int t
)
1609 return LDOUBLE_SIZE
/ 4;
1615 /* token string handling */
1617 static inline void tok_str_new(TokenString
*s
)
1621 s
->last_line_num
= -1;
1624 static void tok_str_free(int *str
)
1635 if (t
== TOK_STR
|| t
== TOK_LSTR
) {
1636 /* XXX: use a macro to be portable on 64 bit ? */
1637 cstr
= (CString
*)(*p
++);
1641 p
+= tok_ext_size(t
);
1647 static void tok_str_add(TokenString
*s
, int t
)
1653 if ((len
& 63) == 0) {
1654 str
= tcc_realloc(str
, (len
+ 64) * sizeof(int));
1663 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1666 CString
*cstr
, *cstr1
;
1670 if (t
== TOK_STR
|| t
== TOK_LSTR
) {
1671 /* special case: need to duplicate string */
1673 cstr
= tcc_malloc(sizeof(CString
));
1676 cstr
->size_allocated
= size
;
1677 cstr
->data_allocated
= tcc_malloc(size
);
1678 cstr
->data
= cstr
->data_allocated
;
1679 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1681 tok_str_add(s
, cv1
.tab
[0]);
1683 n
= tok_ext_size(t
);
1685 tok_str_add(s
, cv
->tab
[i
]);
1689 /* add the current parse token in token string 's' */
1690 static void tok_str_add_tok(TokenString
*s
)
1694 /* save line number info */
1695 if (file
->line_num
!= s
->last_line_num
) {
1696 s
->last_line_num
= file
->line_num
;
1697 cval
.i
= s
->last_line_num
;
1698 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1700 tok_str_add2(s
, tok
, &tokc
);
1703 /* get a token from an integer array and increment pointer accordingly */
1704 static int tok_get(int **tok_str
, CValue
*cv
)
1710 n
= tok_ext_size(t
);
1717 /* eval an expression for #if/#elif */
1718 int expr_preprocess(void)
1724 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1725 next(); /* do macro subst */
1726 if (tok
== TOK_DEFINED
) {
1731 c
= sym_find1(&define_stack
, tok
) != 0;
1736 } else if (tok
>= TOK_IDENT
) {
1737 /* if undefined macro */
1741 tok_str_add_tok(&str
);
1743 tok_str_add(&str
, -1); /* simulate end of file */
1744 tok_str_add(&str
, 0);
1745 /* now evaluate C constant expression */
1746 macro_ptr
= str
.str
;
1750 tok_str_free(str
.str
);
1754 #if defined(DEBUG) || defined(PP_DEBUG)
1755 void tok_print(int *str
)
1761 t
= tok_get(&str
, &cval
);
1764 printf(" %s", get_tok_str(t
, &cval
));
1770 /* parse after #define */
1771 void parse_define(void)
1773 Sym
*s
, *first
, **ps
;
1774 int v
, t
, varg
, is_vaargs
;
1778 /* XXX: should check if same macro (ANSI) */
1781 /* '(' must be just after macro definition for MACRO_FUNC */
1786 while (tok
!= ')') {
1790 if (varg
== TOK_DOTS
) {
1791 varg
= TOK___VA_ARGS__
;
1793 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1797 if (varg
< TOK_IDENT
)
1798 error("badly punctuated parameter list");
1799 s
= sym_push1(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1811 if (ch
== '\n' || ch
== -1)
1814 tok_str_add2(&str
, tok
, &tokc
);
1816 tok_str_add(&str
, 0);
1818 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1821 s
= sym_push1(&define_stack
, v
, t
, (int)str
.str
);
1825 void preprocess(void)
1828 char buf
[1024], *q
, *p
;
1833 return_linefeed
= 1; /* linefeed will be returned as a token */
1837 if (tok
== TOK_DEFINE
) {
1840 } else if (tok
== TOK_UNDEF
) {
1842 s
= sym_find1(&define_stack
, tok
);
1843 /* undefine symbol by putting an invalid name */
1845 sym_undef(&define_stack
, s
);
1846 } else if (tok
== TOK_INCLUDE
) {
1851 } else if (ch
== '\"') {
1856 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
1857 if ((q
- buf
) < sizeof(buf
) - 1)
1862 /* eat all spaces and comments after include */
1863 /* XXX: slightly incorrect */
1864 while (ch1
!= '\n' && ch1
!= CH_EOF
)
1867 /* computed #include : either we have only strings or
1868 we have anything enclosed in '<>' */
1871 if (tok
== TOK_STR
) {
1872 while (tok
!= TOK_LINEFEED
) {
1873 if (tok
!= TOK_STR
) {
1875 error("'#include' expects \"FILENAME\" or <FILENAME>");
1877 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
1883 while (tok
!= TOK_LINEFEED
) {
1884 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
1888 /* check syntax and remove '<>' */
1889 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
1890 goto include_syntax
;
1891 memmove(buf
, buf
+ 1, len
- 2);
1892 buf
[len
- 2] = '\0';
1897 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1898 error("memory full");
1900 /* first search in current dir if "header.h" */
1902 p
= strrchr(file
->filename
, '/');
1904 size
= p
+ 1 - file
->filename
;
1905 if (size
> sizeof(buf1
) - 1)
1906 size
= sizeof(buf1
) - 1;
1907 memcpy(buf1
, file
->filename
, size
);
1909 pstrcat(buf1
, sizeof(buf1
), buf
);
1914 /* now search in all the include paths */
1915 n
= nb_include_paths
+ nb_sysinclude_paths
;
1916 for(i
= 0; i
< n
; i
++) {
1918 if (i
< nb_include_paths
)
1919 path
= include_paths
[i
];
1921 path
= sysinclude_paths
[i
- nb_include_paths
];
1922 pstrcpy(buf1
, sizeof(buf1
), path
);
1923 pstrcat(buf1
, sizeof(buf1
), "/");
1924 pstrcat(buf1
, sizeof(buf1
), buf
);
1929 error("include file '%s' not found", buf
);
1932 /* push current file in stack */
1933 /* XXX: fix current line init */
1934 *include_stack_ptr
++ = file
;
1936 /* add include file debug info */
1938 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
1942 } else if (tok
== TOK_IFNDEF
) {
1945 } else if (tok
== TOK_IF
) {
1946 c
= expr_preprocess();
1948 } else if (tok
== TOK_IFDEF
) {
1952 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1954 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1955 error("memory full");
1956 *ifdef_stack_ptr
++ = c
;
1958 } else if (tok
== TOK_ELSE
) {
1959 if (ifdef_stack_ptr
== ifdef_stack
)
1960 error("#else without matching #if");
1961 if (ifdef_stack_ptr
[-1] & 2)
1962 error("#else after #else");
1963 c
= (ifdef_stack_ptr
[-1] ^= 3);
1965 } else if (tok
== TOK_ELIF
) {
1966 if (ifdef_stack_ptr
== ifdef_stack
)
1967 error("#elif without matching #if");
1968 c
= ifdef_stack_ptr
[-1];
1970 error("#elif after #else");
1971 /* last #if/#elif expression was true: we skip */
1974 c
= expr_preprocess();
1975 ifdef_stack_ptr
[-1] = c
;
1982 } else if (tok
== TOK_ENDIF
) {
1983 if (ifdef_stack_ptr
== ifdef_stack
)
1984 error("#endif without matching #if");
1986 } else if (tok
== TOK_LINE
) {
1989 if (tok
!= TOK_CINT
)
1993 if (tok
!= TOK_LINEFEED
) {
1996 pstrcpy(file
->filename
, sizeof(file
->filename
),
1997 (char *)tokc
.cstr
->data
);
1999 /* NOTE: we do it there to avoid problems with linefeed */
2000 file
->line_num
= line_num
;
2001 } else if (tok
== TOK_ERROR
) {
2004 /* ignore other preprocess commands or #! for C scripts */
2005 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
)
2008 return_linefeed
= 0;
2011 /* read a number in base b */
2012 static int getn(int b
)
2017 if (ch
>= 'a' && ch
<= 'f')
2019 else if (ch
>= 'A' && ch
<= 'F')
2025 if (t
< 0 || t
>= b
)
2033 /* read a character for string or char constant and eval escape codes */
2034 static int getq(void)
2042 /* at most three octal digits */
2046 c
= c
* 8 + ch
- '0';
2049 c
= c
* 8 + ch
- '0';
2054 } else if (ch
== 'x') {
2072 else if (ch
== 'e' && gnu_ext
)
2074 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
2077 error("invalid escaped char");
2084 /* we use 64 bit numbers */
2087 /* bn = (bn << shift) | or_val */
2088 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2092 for(i
=0;i
<BN_SIZE
;i
++) {
2094 bn
[i
] = (v
<< shift
) | or_val
;
2095 or_val
= v
>> (32 - shift
);
2099 void bn_zero(unsigned int *bn
)
2102 for(i
=0;i
<BN_SIZE
;i
++) {
2107 void parse_number(void)
2109 int b
, t
, shift
, frac_bits
, s
, exp_val
;
2111 unsigned int bn
[BN_SIZE
];
2121 /* special dot handling */
2122 if (ch
>= '0' && ch
<= '9') {
2123 goto float_frac_parse
;
2124 } else if (ch
== '.') {
2135 } else if (t
== '0') {
2136 if (ch
== 'x' || ch
== 'X') {
2140 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2146 /* parse all digits. cannot check octal numbers at this stage
2147 because of floating point constants */
2149 if (ch
>= 'a' && ch
<= 'f')
2151 else if (ch
>= 'A' && ch
<= 'F')
2159 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2161 error("number too long");
2167 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2168 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2170 /* NOTE: strtox should support that for hexa numbers, but
2171 non ISOC99 libcs do not support it, so we prefer to do
2173 /* hexadecimal or binary floats */
2174 /* XXX: handle overflows */
2186 } else if (t
>= 'a') {
2188 } else if (t
>= 'A') {
2193 bn_lshift(bn
, shift
, t
);
2200 if (t
>= 'a' && t
<= 'f') {
2202 } else if (t
>= 'A' && t
<= 'F') {
2204 } else if (t
>= '0' && t
<= '9') {
2210 error("invalid digit");
2211 bn_lshift(bn
, shift
, t
);
2216 if (ch
!= 'p' && ch
!= 'P')
2217 error("exponent expected");
2223 } else if (ch
== '-') {
2227 if (ch
< '0' || ch
> '9')
2228 error("exponent digits expected");
2229 while (ch
>= '0' && ch
<= '9') {
2230 exp_val
= exp_val
* 10 + ch
- '0';
2233 exp_val
= exp_val
* s
;
2235 /* now we can generate the number */
2236 /* XXX: should patch directly float number */
2237 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
2238 d
= ldexp(d
, exp_val
- frac_bits
);
2243 /* float : should handle overflow */
2245 } else if (t
== 'L') {
2248 /* XXX: not large enough */
2249 tokc
.ld
= (long double)d
;
2255 /* decimal floats */
2257 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2262 while (ch
>= '0' && ch
<= '9') {
2263 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2269 if (ch
== 'e' || ch
== 'E') {
2270 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2274 if (ch
== '-' || ch
== '+') {
2275 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2280 if (ch
< '0' || ch
> '9')
2281 error("exponent digits expected");
2282 while (ch
>= '0' && ch
<= '9') {
2283 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2295 tokc
.f
= strtof(token_buf
, NULL
);
2296 } else if (t
== 'L') {
2299 tokc
.ld
= strtold(token_buf
, NULL
);
2302 tokc
.d
= strtod(token_buf
, NULL
);
2306 unsigned long long n
, n1
;
2309 /* integer number */
2312 if (b
== 10 && *q
== '0') {
2319 /* no need for checks except for base 10 / 8 errors */
2322 } else if (t
>= 'a') {
2324 } else if (t
>= 'A') {
2329 error("invalid digit");
2333 /* detect overflow */
2335 error("integer constant overflow");
2338 /* XXX: not exactly ANSI compliant */
2339 if ((n
& 0xffffffff00000000LL
) != 0) {
2344 } else if (n
> 0x7fffffff) {
2354 error("three 'l' in integer constant");
2357 if (tok
== TOK_CINT
)
2359 else if (tok
== TOK_CUINT
)
2363 } else if (t
== 'U') {
2364 if (tok
== TOK_CINT
)
2366 else if (tok
== TOK_CLLONG
)
2373 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2381 /* return next token without macro substitution */
2382 void next_nomacro1(void)
2390 while (ch
== '\n') {
2391 /* during preprocessor parsing, '\n' is a token */
2392 if (return_linefeed
) {
2397 while (ch
== ' ' || ch
== '\t')
2400 /* preprocessor command if # at start of line after
2405 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
2423 while (isid(ch
) || isnum(ch
)) {
2424 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2425 error("ident too long");
2430 ts
= tok_alloc(token_buf
, q
- token_buf
);
2432 } else if (isnum(ch
) || ch
== '.') {
2434 } else if (ch
== '\'') {
2439 /* this cast is needed if >= 128 */
2440 if (tok
== TOK_CCHAR
)
2446 } else if (ch
== '\"') {
2450 cstr_reset(&tokcstr
);
2451 while (ch
!= '\"') {
2454 error("unterminated string");
2456 cstr_ccat(&tokcstr
, b
);
2458 cstr_wccat(&tokcstr
, b
);
2461 cstr_ccat(&tokcstr
, '\0');
2463 cstr_wccat(&tokcstr
, '\0');
2464 tokc
.cstr
= &tokcstr
;
2472 if (*q
== tok
&& q
[1] == ch
) {
2475 /* three chars tests */
2476 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2481 } else if (tok
== TOK_DOTS
) {
2483 error("parse error");
2490 /* single char substitutions */
2493 else if (tok
== '>')
2498 /* return next token without macro substitution. Can read input from
2506 tok
= tok_get(¯o_ptr
, &tokc
);
2507 if (tok
== TOK_LINENUM
) {
2508 file
->line_num
= tokc
.i
;
2517 /* substitute args in macro_str and return allocated string */
2518 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2520 int *st
, last_tok
, t
, notfirst
;
2529 t
= tok_get(¯o_str
, &cval
);
2534 t
= tok_get(¯o_str
, &cval
);
2537 s
= sym_find2(args
, t
);
2544 cstr_ccat(&cstr
, ' ');
2545 t
= tok_get(&st
, &cval
);
2546 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
2549 cstr_ccat(&cstr
, '\0');
2551 printf("stringize: %s\n", (char *)cstr
.data
);
2555 tok_str_add2(&str
, TOK_STR
, &cval
);
2558 tok_str_add2(&str
, t
, &cval
);
2560 } else if (t
>= TOK_IDENT
) {
2561 s
= sym_find2(args
, t
);
2564 /* if '##' is present before or after, no arg substitution */
2565 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2566 /* special case for var arg macros : ## eats the
2567 ',' if empty VA_ARGS riable. */
2568 /* XXX: test of the ',' is not 100%
2569 reliable. should fix it to avoid security
2571 if (gnu_ext
&& s
->t
&& *st
== 0 &&
2572 last_tok
== TOK_TWOSHARPS
&&
2573 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
2574 /* suppress ',' '##' */
2579 t1
= tok_get(&st
, &cval
);
2582 tok_str_add2(&str
, t1
, &cval
);
2586 macro_subst(&str
, nested_list
, st
);
2589 tok_str_add(&str
, t
);
2592 tok_str_add2(&str
, t
, &cval
);
2596 tok_str_add(&str
, 0);
2600 /* handle the '##' operator */
2601 int *macro_twosharps(int *macro_str
)
2608 TokenString macro_str1
;
2610 tok_str_new(¯o_str1
);
2616 while (*macro_ptr
== TOK_TWOSHARPS
) {
2618 macro_ptr1
= macro_ptr
;
2621 t
= tok_get(¯o_ptr
, &cval
);
2622 /* XXX: we handle only most common cases:
2623 ident + ident or ident + number */
2624 if (tok
>= TOK_IDENT
&&
2625 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
2626 p
= get_tok_str(tok
, &tokc
);
2627 pstrcpy(token_buf
, sizeof(token_buf
), p
);
2628 p
= get_tok_str(t
, &cval
);
2629 pstrcat(token_buf
, sizeof(token_buf
), p
);
2630 ts
= tok_alloc(token_buf
, 0);
2631 tok
= ts
->tok
; /* modify current token */
2633 /* cannot merge tokens: skip '##' */
2634 macro_ptr
= macro_ptr1
;
2639 tok_str_add2(¯o_str1
, tok
, &tokc
);
2641 tok_str_add(¯o_str1
, 0);
2642 return macro_str1
.str
;
2645 /* do macro substitution of macro_str and add result to
2646 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2647 substituted. 'nested_list' is the list of all macros we got inside
2648 to avoid recursing. */
2649 void macro_subst(TokenString
*tok_str
,
2650 Sym
**nested_list
, int *macro_str
)
2652 Sym
*s
, *args
, *sa
, *sa1
;
2653 int parlevel
, *mstr
, t
, *saved_macro_ptr
;
2654 int mstr_allocated
, *macro_str1
;
2660 saved_macro_ptr
= macro_ptr
;
2661 macro_ptr
= macro_str
;
2664 /* first scan for '##' operator handling */
2665 macro_str1
= macro_twosharps(macro_str
);
2666 macro_ptr
= macro_str1
;
2673 /* special macros */
2674 if (tok
== TOK___LINE__
) {
2675 cval
.i
= file
->line_num
;
2676 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
2677 } else if (tok
== TOK___FILE__
) {
2678 cstrval
= file
->filename
;
2680 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2681 } else if (tok
== TOK___DATE__
) {
2682 cstrval
= "Jan 1 1970";
2684 } else if (tok
== TOK___TIME__
) {
2685 cstrval
= "00:00:00";
2688 cstr_cat(&cstr
, cstrval
);
2689 cstr_ccat(&cstr
, '\0');
2691 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2693 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
2694 /* if symbol is a macro, prepare substitution */
2695 /* if nested substitution, do nothing */
2696 if (sym_find2(*nested_list
, tok
))
2700 if (s
->t
== MACRO_FUNC
) {
2701 /* NOTE: we do not use next_nomacro to avoid eating the
2702 next token. XXX: find better solution */
2706 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
2710 if (t
!= '(') /* no macro subst */
2713 /* argument macro */
2718 /* NOTE: empty args are allowed, except if no args */
2720 /* handle '()' case */
2721 if (!args
&& tok
== ')')
2724 error("macro '%s' used with too many args",
2725 get_tok_str(s
->v
, 0));
2728 /* NOTE: non zero sa->t indicates VA_ARGS */
2729 while ((parlevel
> 0 ||
2731 (tok
!= ',' || sa
->t
))) &&
2735 else if (tok
== ')')
2737 tok_str_add2(&str
, tok
, &tokc
);
2740 tok_str_add(&str
, 0);
2741 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->t
, (int)str
.str
);
2744 /* special case for gcc var args: add an empty
2745 var arg argument if it is omitted */
2746 if (sa
&& sa
->t
&& gnu_ext
)
2756 error("macro '%s' used with too few args",
2757 get_tok_str(s
->v
, 0));
2760 /* now subst each arg */
2761 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2766 tok_str_free((int *)sa
->c
);
2772 sym_push2(nested_list
, s
->v
, 0, 0);
2773 macro_subst(tok_str
, nested_list
, mstr
);
2774 /* pop nested defined symbol */
2776 *nested_list
= sa1
->prev
;
2782 /* no need to add if reading input stream */
2785 tok_str_add2(tok_str
, tok
, &tokc
);
2787 /* only replace one macro while parsing input stream */
2791 macro_ptr
= saved_macro_ptr
;
2793 tok_str_free(macro_str1
);
2796 /* return next token with macro substitution */
2802 /* special 'ungettok' case for label parsing */
2810 /* if not reading from macro substituted string, then try
2812 /* XXX: optimize non macro case */
2815 macro_subst(&str
, &nested_list
, NULL
);
2817 tok_str_add(&str
, 0);
2818 macro_ptr
= str
.str
;
2819 macro_ptr_allocated
= str
.str
;
2827 /* end of macro string: free it */
2828 tok_str_free(macro_ptr_allocated
);
2835 printf("token = %s\n", get_tok_str(tok
, &tokc
));
2839 void swap(int *p
, int *q
)
2847 void vsetc(int t
, int r
, CValue
*vc
)
2849 if (vtop
>= vstack
+ VSTACK_SIZE
)
2850 error("memory full");
2851 /* cannot let cpu flags if other instruction are generated */
2852 /* XXX: VT_JMP test too ? */
2853 if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
2858 vtop
->r2
= VT_CONST
;
2862 /* push integer constant */
2867 vsetc(VT_INT
, VT_CONST
, &cval
);
2870 /* Return a static symbol pointing to a section */
2871 static Sym
*get_sym_ref(int t
, Section
*sec
,
2872 unsigned long offset
, unsigned long size
)
2878 sym
= sym_push1(&global_stack
, v
, t
| VT_STATIC
, 0);
2879 sym
->r
= VT_CONST
| VT_SYM
;
2880 put_extern_sym(sym
, sec
, offset
, size
);
2884 /* push a reference to a section offset by adding a dummy symbol */
2885 void vpush_ref(int t
, Section
*sec
, unsigned long offset
, unsigned long size
)
2889 cval
.sym
= get_sym_ref(t
, sec
, offset
, size
);
2890 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2893 /* push a reference to symbol v */
2894 void vpush_sym(int t
, int v
)
2899 sym
= external_sym(v
, t
, 0);
2901 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2904 void vset(int t
, int r
, int v
)
2921 void vpushv(SValue
*v
)
2923 if (vtop
>= vstack
+ VSTACK_SIZE
)
2924 error("memory full");
2934 /* save r to the memory stack, and mark it as being free */
2935 void save_reg(int r
)
2937 int l
, saved
, t
, size
, align
;
2940 /* modify all stack values */
2943 for(p
=vstack
;p
<=vtop
;p
++) {
2944 if ((p
->r
& VT_VALMASK
) == r
||
2945 (p
->r2
& VT_VALMASK
) == r
) {
2946 /* must save value on stack if not already done */
2948 /* store register in the stack */
2950 if ((p
->r
& VT_LVAL
) ||
2951 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
2953 size
= type_size(t
, &align
);
2954 loc
= (loc
- size
) & -align
;
2956 sv
.r
= VT_LOCAL
| VT_LVAL
;
2959 #ifdef TCC_TARGET_I386
2960 /* x86 specific: need to pop fp register ST0 if saved */
2962 o(0xd9dd); /* fstp %st(1) */
2965 /* special long long case */
2966 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2973 /* mark that stack entry as being saved on the stack */
2974 if (p
->r
& VT_LVAL
) {
2975 /* also suppress the bounded flag because the
2976 relocation address of the function was stored in
2978 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
2980 p
->r
= lvalue_type(p
->t
) | VT_LOCAL
;
2988 /* find a free register of class 'rc'. If none, save one register */
2994 /* find a free register */
2995 for(r
=0;r
<NB_REGS
;r
++) {
2996 if (reg_classes
[r
] & rc
) {
2997 for(p
=vstack
;p
<=vtop
;p
++) {
2998 if ((p
->r
& VT_VALMASK
) == r
||
2999 (p
->r2
& VT_VALMASK
) == r
)
3007 /* no register left : free the first one on the stack (VERY
3008 IMPORTANT to start from the bottom to ensure that we don't
3009 spill registers used in gen_opi()) */
3010 for(p
=vstack
;p
<=vtop
;p
++) {
3011 r
= p
->r
& VT_VALMASK
;
3012 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
3020 /* save registers up to (vtop - n) stack entry */
3021 void save_regs(int n
)
3026 for(p
= vstack
;p
<= p1
; p
++) {
3027 r
= p
->r
& VT_VALMASK
;
3034 /* move register 's' to 'r', and flush previous value of r to memory
3036 void move_reg(int r
, int s
)
3049 /* get address of vtop (vtop MUST BE an lvalue) */
3052 vtop
->r
&= ~VT_LVAL
;
3053 /* tricky: if saved lvalue, then we can go back to lvalue */
3054 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
3055 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
3058 #ifdef CONFIG_TCC_BCHECK
3059 /* generate lvalue bound code */
3064 vtop
->r
&= ~VT_MUSTBOUND
;
3065 /* if lvalue, then use checking code before dereferencing */
3066 if (vtop
->r
& VT_LVAL
) {
3067 /* if not VT_BOUNDED value, then make one */
3068 if (!(vtop
->r
& VT_BOUNDED
)) {
3069 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
3070 /* must save type because we must set it to int to get pointer */
3075 gen_bounded_ptr_add();
3076 vtop
->r
|= lval_type
;
3079 /* then check for dereferencing */
3080 gen_bounded_ptr_deref();
3085 /* store vtop a register belonging to class 'rc'. lvalues are
3086 converted to values. Cannot be used if cannot be converted to
3087 register value (such as structures). */
3090 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
3091 unsigned long long ll
;
3093 /* NOTE: get_reg can modify vstack[] */
3094 if (vtop
->t
& VT_BITFIELD
) {
3095 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
3096 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3097 /* remove bit field info to avoid loops */
3098 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3099 /* generate shifts */
3100 vpushi(32 - (bit_pos
+ bit_size
));
3102 vpushi(32 - bit_size
);
3103 /* NOTE: transformed to SHR if unsigned */
3107 if (is_float(vtop
->t
) &&
3108 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3111 unsigned long offset
;
3113 /* XXX: unify with initializers handling ? */
3114 /* CPUs usually cannot use float constants, so we store them
3115 generically in data segment */
3116 size
= type_size(vtop
->t
, &align
);
3117 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
3118 data_section
->data_offset
= offset
;
3119 /* XXX: not portable yet */
3120 ptr
= section_ptr_add(data_section
, size
);
3123 ptr
[i
] = vtop
->c
.tab
[i
];
3124 sym
= get_sym_ref(vtop
->t
, data_section
, offset
, size
<< 2);
3125 vtop
->r
|= VT_LVAL
| VT_SYM
;
3128 #ifdef CONFIG_TCC_BCHECK
3129 if (vtop
->r
& VT_MUSTBOUND
)
3133 r
= vtop
->r
& VT_VALMASK
;
3134 /* need to reload if:
3136 - lvalue (need to dereference pointer)
3137 - already a register, but not in the right class */
3138 if (r
>= VT_CONST
||
3139 (vtop
->r
& VT_LVAL
) ||
3140 !(reg_classes
[r
] & rc
) ||
3141 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
3142 !(reg_classes
[vtop
->r2
] & rc
))) {
3144 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
3145 /* two register type load : expand to two words
3147 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3150 vtop
->c
.ui
= ll
; /* first word */
3152 vtop
->r
= r
; /* save register value */
3153 vpushi(ll
>> 32); /* second word */
3154 } else if (r
>= VT_CONST
||
3155 (vtop
->r
& VT_LVAL
)) {
3156 /* load from memory */
3159 vtop
[-1].r
= r
; /* save register value */
3160 /* increment pointer to get second word */
3167 /* move registers */
3170 vtop
[-1].r
= r
; /* save register value */
3171 vtop
->r
= vtop
[-1].r2
;
3173 /* allocate second register */
3180 /* write second register */
3182 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
3184 /* lvalue of scalar type : need to use lvalue type
3185 because of possible cast */
3188 /* compute memory access type */
3189 if (vtop
->r
& VT_LVAL_BYTE
)
3191 else if (vtop
->r
& VT_LVAL_SHORT
)
3193 if (vtop
->r
& VT_LVAL_UNSIGNED
)
3197 /* restore wanted type */
3200 /* one register type load */
3209 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3210 void gv2(int rc1
, int rc2
)
3212 /* generate more generic register first */
3218 /* test if reload is needed for first register */
3219 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
3229 /* test if reload is needed for first register */
3230 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
3236 /* expand long long on stack in two int registers */
3241 u
= vtop
->t
& VT_UNSIGNED
;
3244 vtop
[0].r
= vtop
[-1].r2
;
3245 vtop
[0].r2
= VT_CONST
;
3246 vtop
[-1].r2
= VT_CONST
;
3247 vtop
[0].t
= VT_INT
| u
;
3248 vtop
[-1].t
= VT_INT
| u
;
3251 /* build a long long from two ints */
3254 gv2(RC_INT
, RC_INT
);
3255 vtop
[-1].r2
= vtop
[0].r
;
3260 /* rotate n first stack elements to the bottom */
3267 for(i
=-n
+1;i
!=0;i
++)
3268 vtop
[i
] = vtop
[i
+1];
3272 /* pop stack value */
3276 v
= vtop
->r
& VT_VALMASK
;
3277 #ifdef TCC_TARGET_I386
3278 /* for x86, we need to pop the FP stack */
3280 o(0xd9dd); /* fstp %st(1) */
3283 if (v
== VT_JMP
|| v
== VT_JMPI
) {
3284 /* need to put correct jump if && or || without test */
3290 /* convert stack entry to register and duplicate its value in another
3298 if ((t
& VT_BTYPE
) == VT_LLONG
) {
3305 /* stack: H L L1 H1 */
3313 /* duplicate value */
3324 load(r1
, &sv
); /* move r to r1 */
3326 /* duplicates value */
3331 /* generate CPU independent (unsigned) long long operations */
3332 void gen_opl(int op
)
3334 int t
, a
, b
, op1
, c
, i
;
3342 func
= TOK___divdi3
;
3345 func
= TOK___udivdi3
;
3348 func
= TOK___moddi3
;
3351 func
= TOK___umoddi3
;
3353 /* call generic long long function */
3354 gfunc_start(&gf
, FUNC_CDECL
);
3357 vpush_sym(func_old_type
, func
);
3361 vtop
->r2
= REG_LRET
;
3374 /* stack: L1 H1 L2 H2 */
3379 vtop
[-2] = vtop
[-3];
3382 /* stack: H1 H2 L1 L2 */
3388 /* stack: H1 H2 L1 L2 ML MH */
3391 /* stack: ML MH H1 H2 L1 L2 */
3395 /* stack: ML MH H1 L2 H2 L1 */
3400 /* stack: ML MH M1 M2 */
3403 } else if (op
== '+' || op
== '-') {
3404 /* XXX: add non carry method too (for MIPS or alpha) */
3410 /* stack: H1 H2 (L1 op L2) */
3413 gen_op(op1
+ 1); /* TOK_xxxC2 */
3416 /* stack: H1 H2 (L1 op L2) */
3419 /* stack: (L1 op L2) H1 H2 */
3421 /* stack: (L1 op L2) (H1 op H2) */
3429 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3434 /* stack: L H shift */
3436 /* constant: simpler */
3437 /* NOTE: all comments are for SHL. the other cases are
3438 done by swaping words */
3449 if (op
!= TOK_SAR
) {
3479 /* XXX: should provide a faster fallback on x86 ? */
3482 func
= TOK___sardi3
;
3485 func
= TOK___shrdi3
;
3488 func
= TOK___shldi3
;
3494 /* compare operations */
3500 /* stack: L1 H1 L2 H2 */
3502 vtop
[-1] = vtop
[-2];
3504 /* stack: L1 L2 H1 H2 */
3507 /* when values are equal, we need to compare low words. since
3508 the jump is inverted, we invert the test too. */
3511 else if (op1
== TOK_GT
)
3513 else if (op1
== TOK_ULT
)
3515 else if (op1
== TOK_UGT
)
3520 if (op1
!= TOK_NE
) {
3524 /* generate non equal test */
3525 /* XXX: NOT PORTABLE yet */
3529 #ifdef TCC_TARGET_I386
3530 b
= psym(0x850f, 0);
3532 error("not implemented");
3540 vset(VT_INT
, VT_JMPI
, a
);
3545 /* handle integer constant optimizations and various machine
3547 void gen_opic(int op
)
3554 /* currently, we cannot do computations with forward symbols */
3555 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3556 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3560 case '+': v1
->c
.i
+= fc
; break;
3561 case '-': v1
->c
.i
-= fc
; break;
3562 case '&': v1
->c
.i
&= fc
; break;
3563 case '^': v1
->c
.i
^= fc
; break;
3564 case '|': v1
->c
.i
|= fc
; break;
3565 case '*': v1
->c
.i
*= fc
; break;
3572 /* if division by zero, generate explicit division */
3575 error("division by zero in constant");
3579 default: v1
->c
.i
/= fc
; break;
3580 case '%': v1
->c
.i
%= fc
; break;
3581 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3582 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3585 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3586 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3587 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3589 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3590 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3591 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3592 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3593 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3594 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3595 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3596 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3597 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3598 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3600 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3601 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3607 /* if commutative ops, put c2 as constant */
3608 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3609 op
== '|' || op
== '*')) {
3614 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3617 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3618 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3624 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3625 /* try to use shifts instead of muls or divs */
3626 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3635 else if (op
== TOK_PDIV
)
3643 /* call low level op generator */
3649 /* generate a floating point operation with constant propagation */
3650 void gen_opif(int op
)
3658 /* currently, we cannot do computations with forward symbols */
3659 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3660 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3662 if (v1
->t
== VT_FLOAT
) {
3665 } else if (v1
->t
== VT_DOUBLE
) {
3673 /* NOTE: we only do constant propagation if finite number (not
3674 NaN or infinity) (ANSI spec) */
3675 if (!ieee_finite(f1
) || !ieee_finite(f2
))
3679 case '+': f1
+= f2
; break;
3680 case '-': f1
-= f2
; break;
3681 case '*': f1
*= f2
; break;
3685 error("division by zero in constant");
3690 /* XXX: also handles tests ? */
3694 /* XXX: overflow test ? */
3695 if (v1
->t
== VT_FLOAT
) {
3697 } else if (v1
->t
== VT_DOUBLE
) {
3710 int pointed_size(int t
)
3712 return type_size(pointed_type(t
), &t
);
3716 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3718 char buf1
[256], buf2
[256];
3722 if (!is_compatible_types(t1
, t2
)) {
3723 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3724 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3725 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3730 /* generic gen_op: handles types problems */
3733 int u
, t1
, t2
, bt1
, bt2
, t
;
3737 bt1
= t1
& VT_BTYPE
;
3738 bt2
= t2
& VT_BTYPE
;
3740 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3741 /* at least one operand is a pointer */
3742 /* relationnal op: must be both pointers */
3743 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3744 // check_pointer_types(vtop, vtop - 1);
3745 /* pointers are handled are unsigned */
3746 t
= VT_INT
| VT_UNSIGNED
;
3749 /* if both pointers, then it must be the '-' op */
3750 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3751 (t2
& VT_BTYPE
) == VT_PTR
) {
3753 error("cannot use pointers here");
3754 // check_pointer_types(vtop - 1, vtop);
3755 /* XXX: check that types are compatible */
3756 u
= pointed_size(t1
);
3758 /* set to integer type */
3763 /* exactly one pointer : must be '+' or '-'. */
3764 if (op
!= '-' && op
!= '+')
3765 error("cannot use pointers here");
3766 /* Put pointer as first operand */
3767 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3771 /* XXX: cast to int ? (long long case) */
3772 vpushi(pointed_size(vtop
[-1].t
));
3774 #ifdef CONFIG_TCC_BCHECK
3775 /* if evaluating constant expression, no code should be
3776 generated, so no bound check */
3777 if (do_bounds_check
&& !const_wanted
) {
3778 /* if bounded pointers, we generate a special code to
3785 gen_bounded_ptr_add();
3791 /* put again type if gen_opic() swaped operands */
3794 } else if (is_float(bt1
) || is_float(bt2
)) {
3795 /* compute bigger type and do implicit casts */
3796 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3798 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3803 /* floats can only be used for a few operations */
3804 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3805 (op
< TOK_ULT
|| op
> TOK_GT
))
3806 error("invalid operands for binary operation");
3808 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3809 /* cast to biggest op */
3811 /* convert to unsigned if it does not fit in a long long */
3812 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3813 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
3817 /* integer operations */
3819 /* convert to unsigned if it does not fit in an integer */
3820 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
3821 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3824 /* XXX: currently, some unsigned operations are explicit, so
3825 we modify them here */
3826 if (t
& VT_UNSIGNED
) {
3833 else if (op
== TOK_LT
)
3835 else if (op
== TOK_GT
)
3837 else if (op
== TOK_LE
)
3839 else if (op
== TOK_GE
)
3845 /* special case for shifts and long long: we keep the shift as
3847 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3853 else if ((t
& VT_BTYPE
) == VT_LLONG
)
3857 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3858 /* relationnal op: the result is an int */
3866 /* generic itof for unsigned long long case */
3867 void gen_cvt_itof1(int t
)
3871 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3872 (VT_LLONG
| VT_UNSIGNED
)) {
3874 gfunc_start(&gf
, FUNC_CDECL
);
3877 vpush_sym(func_old_type
, TOK___ulltof
);
3878 else if (t
== VT_DOUBLE
)
3879 vpush_sym(func_old_type
, TOK___ulltod
);
3881 vpush_sym(func_old_type
, TOK___ulltold
);
3890 /* generic ftoi for unsigned long long case */
3891 void gen_cvt_ftoi1(int t
)
3896 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3897 /* not handled natively */
3898 gfunc_start(&gf
, FUNC_CDECL
);
3899 st
= vtop
->t
& VT_BTYPE
;
3902 vpush_sym(func_old_type
, TOK___fixunssfdi
);
3903 else if (st
== VT_DOUBLE
)
3904 vpush_sym(func_old_type
, TOK___fixunsdfdi
);
3906 vpush_sym(func_old_type
, TOK___fixunsxfdi
);
3910 vtop
->r2
= REG_LRET
;
3916 /* force char or short cast */
3917 void force_charshort_cast(int t
)
3921 /* XXX: add optimization if lvalue : just change type and offset */
3926 if (t
& VT_UNSIGNED
) {
3927 vpushi((1 << bits
) - 1);
3938 /* cast 'vtop' to 't' type */
3939 void gen_cast(int t
)
3941 int sbt
, dbt
, sf
, df
, c
;
3943 /* special delayed cast for char/short */
3944 /* XXX: in some cases (multiple cascaded casts), it may still
3946 if (vtop
->r
& VT_MUSTCAST
) {
3947 vtop
->r
&= ~VT_MUSTCAST
;
3948 force_charshort_cast(vtop
->t
);
3951 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3952 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3957 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3959 /* convert from fp to fp */
3961 /* constant case: we can do it now */
3962 /* XXX: in ISOC, cannot do it if error in convert */
3963 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3964 vtop
->c
.f
= (float)vtop
->c
.d
;
3965 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3966 vtop
->c
.f
= (float)vtop
->c
.ld
;
3967 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3968 vtop
->c
.d
= (double)vtop
->c
.f
;
3969 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3970 vtop
->c
.d
= (double)vtop
->c
.ld
;
3971 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3972 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3973 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3974 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3976 /* non constant case: generate code */
3980 /* convert int to fp */
3983 case VT_LLONG
| VT_UNSIGNED
:
3985 /* XXX: add const cases for long long */
3987 case VT_INT
| VT_UNSIGNED
:
3989 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3990 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
3991 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
3996 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
3997 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
3998 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
4007 /* convert fp to int */
4008 /* we handle char/short/etc... with generic code */
4009 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
4010 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
4015 case VT_LLONG
| VT_UNSIGNED
:
4017 /* XXX: add const cases for long long */
4019 case VT_INT
| VT_UNSIGNED
:
4021 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4022 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4023 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4029 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4030 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4031 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4039 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
4040 /* additionnal cast for char/short/bool... */
4044 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
4045 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
4046 /* scalar to long long */
4048 if (sbt
== (VT_INT
| VT_UNSIGNED
))
4049 vtop
->c
.ll
= vtop
->c
.ui
;
4051 vtop
->c
.ll
= vtop
->c
.i
;
4053 /* machine independant conversion */
4055 /* generate high word */
4056 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
4064 /* patch second register */
4065 vtop
[-1].r2
= vtop
->r
;
4069 } else if (dbt
== VT_BOOL
) {
4070 /* scalar to bool */
4073 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
4074 (dbt
& VT_BTYPE
) == VT_SHORT
) {
4075 force_charshort_cast(t
);
4076 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
4078 if (sbt
== VT_LLONG
) {
4079 /* from long long: just take low order word */
4083 /* if lvalue and single word type, nothing to do because
4084 the lvalue already contains the real type size (see
4085 VT_LVAL_xxx constants) */
4091 /* return type size. Put alignment at 'a' */
4092 int type_size(int t
, int *a
)
4098 if (bt
== VT_STRUCT
) {
4100 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4101 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
4103 } else if (bt
== VT_PTR
) {
4105 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4106 return type_size(s
->t
, a
) * s
->c
;
4111 } else if (bt
== VT_LDOUBLE
) {
4113 return LDOUBLE_SIZE
;
4114 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
4117 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
4120 } else if (bt
== VT_SHORT
) {
4124 /* char, void, function, _Bool */
4130 /* return the pointed type of t */
4131 int pointed_type(int t
)
4134 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4135 return s
->t
| (t
& ~VT_TYPE
);
4138 int mk_pointer(int t
)
4142 sym_push(p
, t
, 0, -1);
4143 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
4146 int is_compatible_types(int t1
, int t2
)
4153 bt1
= t1
& VT_BTYPE
;
4154 bt2
= t2
& VT_BTYPE
;
4155 if (bt1
== VT_PTR
) {
4156 t1
= pointed_type(t1
);
4157 /* if function, then convert implicitely to function pointer */
4158 if (bt2
!= VT_FUNC
) {
4161 t2
= pointed_type(t2
);
4163 /* void matches everything */
4166 if (t1
== VT_VOID
|| t2
== VT_VOID
)
4168 return is_compatible_types(t1
, t2
);
4169 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4171 } else if (bt1
== VT_FUNC
) {
4174 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
4175 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
4176 if (!is_compatible_types(s1
->t
, s2
->t
))
4178 /* XXX: not complete */
4179 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
4183 while (s1
!= NULL
) {
4186 if (!is_compatible_types(s1
->t
, s2
->t
))
4195 /* XXX: not complete */
4200 /* print a type. If 'varstr' is not NULL, then the variable is also
4201 printed in the type */
4203 /* XXX: add array and function pointers */
4204 void type_to_str(char *buf
, int buf_size
,
4205 int t
, const char *varstr
)
4215 if (t
& VT_UNSIGNED
)
4216 pstrcat(buf
, buf_size
, "unsigned ");
4246 tstr
= "long double";
4248 pstrcat(buf
, buf_size
, tstr
);
4252 if (bt
== VT_STRUCT
)
4256 pstrcat(buf
, buf_size
, tstr
);
4257 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
4258 if (v
>= SYM_FIRST_ANOM
)
4259 pstrcat(buf
, buf_size
, "<anonymous>");
4261 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
4264 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4265 type_to_str(buf
, buf_size
, s
->t
, varstr
);
4266 pstrcat(buf
, buf_size
, "(");
4268 while (sa
!= NULL
) {
4269 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
4270 pstrcat(buf
, buf_size
, buf1
);
4273 pstrcat(buf
, buf_size
, ", ");
4275 pstrcat(buf
, buf_size
, ")");
4278 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4279 pstrcpy(buf1
, sizeof(buf1
), "*");
4281 pstrcat(buf1
, sizeof(buf1
), varstr
);
4282 type_to_str(buf
, buf_size
, s
->t
, buf1
);
4286 pstrcat(buf
, buf_size
, " ");
4287 pstrcat(buf
, buf_size
, varstr
);
4292 /* verify type compatibility to store vtop in 'dt' type, and generate
4294 void gen_assign_cast(int dt
)
4297 char buf1
[256], buf2
[256];
4299 st
= vtop
->t
; /* source type */
4300 if ((dt
& VT_BTYPE
) == VT_PTR
) {
4301 /* special cases for pointers */
4302 /* a function is implicitely a function pointer */
4303 if ((st
& VT_BTYPE
) == VT_FUNC
) {
4304 if (!is_compatible_types(pointed_type(dt
), st
))
4309 /* '0' can also be a pointer */
4310 if ((st
& VT_BTYPE
) == VT_INT
&&
4311 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
4315 if (!is_compatible_types(dt
, st
)) {
4317 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
4318 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
4319 error("cannot cast '%s' to '%s'", buf1
, buf2
);
4325 /* store vtop in lvalue pushed on stack */
4328 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
4332 sbt
= vtop
->t
& VT_BTYPE
;
4333 dbt
= ft
& VT_BTYPE
;
4334 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
4335 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
4336 /* optimize char/short casts */
4337 delayed_cast
= VT_MUSTCAST
;
4338 vtop
->t
= ft
& VT_TYPE
;
4341 gen_assign_cast(ft
& VT_TYPE
);
4344 if (sbt
== VT_STRUCT
) {
4345 /* if structure, only generate pointer */
4346 /* structure assignment : generate memcpy */
4347 /* XXX: optimize if small size */
4349 gfunc_start(&gf
, FUNC_CDECL
);
4351 size
= type_size(vtop
->t
, &align
);
4365 vpush_sym(func_old_type
, TOK_memcpy
);
4367 /* leave source on stack */
4368 } else if (ft
& VT_BITFIELD
) {
4369 /* bitfield store handling */
4370 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
4371 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4372 /* remove bit field info to avoid loops */
4373 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4375 /* duplicate destination */
4377 vtop
[-1] = vtop
[-2];
4379 /* mask and shift source */
4380 vpushi((1 << bit_size
) - 1);
4384 /* load destination, mask and or with source */
4386 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4392 #ifdef CONFIG_TCC_BCHECK
4393 /* bound check case */
4394 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4403 r
= gv(rc
); /* generate value */
4404 /* if lvalue was saved on stack, must read it */
4405 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4407 t
= get_reg(RC_INT
);
4409 sv
.r
= VT_LOCAL
| VT_LVAL
;
4410 sv
.c
.ul
= vtop
[-1].c
.ul
;
4412 vtop
[-1].r
= t
| VT_LVAL
;
4415 /* two word case handling : store second register at word + 4 */
4416 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4418 /* convert to int to increment easily */
4425 /* XXX: it works because r2 is spilled last ! */
4426 store(vtop
->r2
, vtop
- 1);
4429 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4430 vtop
->r
|= delayed_cast
;
4434 /* post defines POST/PRE add. c is the token ++ or -- */
4435 void inc(int post
, int c
)
4438 vdup(); /* save lvalue */
4440 gv_dup(); /* duplicate value */
4445 vpushi(c
- TOK_MID
);
4447 vstore(); /* store value */
4449 vpop(); /* if post op, return saved value */
4452 /* Parse GNUC __attribute__ extension. Currently, the following
4453 extensions are recognized:
4454 - aligned(n) : set data/function alignment.
4455 - section(x) : generate data/code in this section.
4456 - unused : currently ignored, but may be used someday.
4458 void parse_attribute(AttributeDef
*ad
)
4465 while (tok
!= ')') {
4466 if (tok
< TOK_IDENT
)
4467 expect("attribute name");
4472 case TOK___SECTION__
:
4475 expect("section name");
4476 ad
->section
= find_section((char *)tokc
.cstr
->data
);
4481 case TOK___ALIGNED__
:
4484 if (n
<= 0 || (n
& (n
- 1)) != 0)
4485 error("alignment must be a positive power of two");
4490 case TOK___UNUSED__
:
4491 /* currently, no need to handle it because tcc does not
4492 track unused objects */
4495 case TOK___NORETURN__
:
4496 /* currently, no need to handle it because tcc does not
4497 track unused objects */
4502 ad
->func_call
= FUNC_CDECL
;
4506 case TOK___STDCALL__
:
4507 ad
->func_call
= FUNC_STDCALL
;
4510 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4511 /* skip parameters */
4512 /* XXX: skip parenthesis too */
4515 while (tok
!= ')' && tok
!= -1)
4529 /* enum/struct/union declaration */
4530 int struct_decl(int u
)
4532 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4533 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4537 a
= tok
; /* save decl type */
4542 /* struct already defined ? return it */
4543 /* XXX: check consistency */
4544 s
= sym_find(v
| SYM_STRUCT
);
4547 error("invalid type");
4553 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4554 /* put struct/union/enum name in type */
4556 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4561 error("struct/union/enum already defined");
4562 /* cannot be empty */
4569 if (a
== TOK_ENUM
) {
4576 /* enum symbols have static storage */
4577 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4582 parse_btype(&b
, &ad
);
4587 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4588 if ((t
& VT_BTYPE
) == VT_FUNC
||
4589 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4590 error("invalid type for '%s'",
4591 get_tok_str(v
, NULL
));
4597 bit_size
= expr_const();
4598 /* XXX: handle v = 0 case for messages */
4600 error("negative width in bit-field '%s'",
4601 get_tok_str(v
, NULL
));
4602 if (v
&& bit_size
== 0)
4603 error("zero width for bit-field '%s'",
4604 get_tok_str(v
, NULL
));
4606 size
= type_size(t
, &align
);
4608 if (bit_size
>= 0) {
4613 error("bitfields must have scalar type");
4615 if (bit_size
> bsize
) {
4616 error("width of '%s' exceeds its type",
4617 get_tok_str(v
, NULL
));
4618 } else if (bit_size
== bsize
) {
4619 /* no need for bit fields */
4621 } else if (bit_size
== 0) {
4622 /* XXX: what to do if only padding in a
4624 /* zero size: means to pad */
4628 /* we do not have enough room ? */
4629 if ((bit_pos
+ bit_size
) > bsize
)
4632 /* XXX: handle LSB first */
4634 (bit_pos
<< VT_STRUCT_SHIFT
) |
4635 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4636 bit_pos
+= bit_size
;
4642 /* add new memory data only if starting
4644 if (lbit_pos
== 0) {
4645 if (a
== TOK_STRUCT
) {
4646 c
= (c
+ align
- 1) & -align
;
4654 if (align
> maxalign
)
4658 printf("add field %s offset=%d",
4659 get_tok_str(v
, NULL
), offset
);
4660 if (t
& VT_BITFIELD
) {
4661 printf(" pos=%d size=%d",
4662 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4663 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4667 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
4671 if (tok
== ';' || tok
== -1)
4681 /* size for struct/union, dummy for enum */
4682 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4687 /* return 0 if no type declaration. otherwise, return the basic type
4690 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4692 int t
, u
, type_found
;
4695 memset(ad
, 0, sizeof(AttributeDef
));
4706 if ((t
& VT_BTYPE
) != 0)
4707 error("too many basic types");
4721 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4722 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4723 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4724 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4738 if ((t
& VT_BTYPE
) == VT_LONG
) {
4739 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4746 u
= struct_decl(VT_ENUM
);
4750 u
= struct_decl(VT_STRUCT
);
4753 /* type modifiers */
4758 case TOK___SIGNED__
:
4761 case TOK___INLINE__
:
4783 /* GNUC attribute */
4784 case TOK___ATTRIBUTE__
:
4785 parse_attribute(ad
);
4789 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4791 t
|= (s
->t
& ~VT_TYPEDEF
);
4798 /* long is never used as type */
4799 if ((t
& VT_BTYPE
) == VT_LONG
)
4800 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4805 int post_type(int t
, AttributeDef
*ad
)
4807 int p
, n
, pt
, l
, t1
;
4808 Sym
**plast
, *s
, *first
;
4812 /* function declaration */
4817 while (tok
!= ')') {
4818 /* read param name and compute offset */
4819 if (l
!= FUNC_OLD
) {
4820 if (!parse_btype(&pt
, &ad1
)) {
4822 error("invalid type");
4829 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4831 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
4832 if ((pt
& VT_BTYPE
) == VT_VOID
)
4833 error("parameter declared as void");
4840 /* array must be transformed to pointer according to ANSI C */
4842 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
4847 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4854 /* if no parameters, then old type prototype */
4858 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4859 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4860 /* we push a anonymous symbol which will contain the function prototype */
4862 s
= sym_push(p
, t
, ad
->func_call
, l
);
4864 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
4865 } else if (tok
== '[') {
4866 /* array definition */
4872 error("invalid array size");
4875 /* parse next post type */
4876 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4877 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4879 /* we push a anonymous symbol which will contain the array
4882 sym_push(p
, t
, 0, n
);
4883 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
4888 /* Read a type declaration (except basic type), and return the
4889 type. 'td' is a bitmask indicating which kind of type decl is
4890 expected. 't' should contain the basic type. 'ad' is the attribute
4891 definition of the basic type. It can be modified by type_decl(). */
4892 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
4897 while (tok
== '*') {
4899 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
4904 /* recursive type */
4905 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4908 /* XXX: this is not correct to modify 'ad' at this point, but
4909 the syntax is not clear */
4910 if (tok
== TOK___ATTRIBUTE__
)
4911 parse_attribute(ad
);
4912 u
= type_decl(ad
, v
, 0, td
);
4916 /* type identifier */
4917 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
4921 if (!(td
& TYPE_ABSTRACT
))
4922 expect("identifier");
4926 /* append t at the end of u */
4927 t
= post_type(t
, ad
);
4928 if (tok
== TOK___ATTRIBUTE__
)
4929 parse_attribute(ad
);
4934 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
4944 /* define a new external reference to a symbol 'v' of type 'u' */
4945 Sym
*external_sym(int v
, int u
, int r
)
4951 /* push forward reference */
4952 s
= sym_push1(&global_stack
,
4953 v
, u
| VT_EXTERN
, 0);
4954 s
->r
= r
| VT_CONST
| VT_SYM
;
4959 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4960 static int lvalue_type(int t
)
4967 else if (bt
== VT_SHORT
)
4971 if (t
& VT_UNSIGNED
)
4972 r
|= VT_LVAL_UNSIGNED
;
4976 /* indirection with full error checking and bound check */
4977 static void indir(void)
4979 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
4981 if (vtop
->r
& VT_LVAL
)
4983 vtop
->t
= pointed_type(vtop
->t
);
4984 /* an array is never an lvalue */
4985 if (!(vtop
->t
& VT_ARRAY
)) {
4986 vtop
->r
|= lvalue_type(vtop
->t
);
4987 /* if bound checking, the referenced pointer must be checked */
4988 if (do_bounds_check
)
4989 vtop
->r
|= VT_MUSTBOUND
;
4993 /* pass a parameter to a function and do type checking and casting */
4994 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
4997 func_type
= func
->c
;
4998 if (func_type
== FUNC_OLD
||
4999 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5000 /* default casting : only need to convert float to double */
5001 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
5002 gen_cast(VT_DOUBLE
);
5003 } else if (arg
== NULL
) {
5004 error("too many arguments to function");
5006 gen_assign_cast(arg
->t
);
5013 int n
, t
, ft
, fc
, align
, size
, r
, data_offset
;
5018 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
5021 } else if (tok
== TOK_CUINT
) {
5022 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
5024 } else if (tok
== TOK_CLLONG
) {
5025 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
5027 } else if (tok
== TOK_CULLONG
) {
5028 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
5030 } else if (tok
== TOK_CFLOAT
) {
5031 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
5033 } else if (tok
== TOK_CDOUBLE
) {
5034 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
5036 } else if (tok
== TOK_CLDOUBLE
) {
5037 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
5039 } else if (tok
== TOK___FUNC__
) {
5042 /* special function name identifier */
5044 len
= strlen(funcname
) + 1;
5045 /* generate char[len] type */
5046 t
= VT_ARRAY
| mk_pointer(VT_BYTE
);
5047 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5049 vpush_ref(t
, data_section
, data_section
->data_offset
, len
);
5050 ptr
= section_ptr_add(data_section
, len
);
5051 memcpy(ptr
, funcname
, len
);
5053 } else if (tok
== TOK_LSTR
) {
5056 } else if (tok
== TOK_STR
) {
5057 /* string parsing */
5060 type_size(t
, &align
);
5061 data_offset
= data_section
->data_offset
;
5062 data_offset
= (data_offset
+ align
- 1) & -align
;
5064 /* we must declare it as an array first to use initializer parser */
5065 t
= VT_ARRAY
| mk_pointer(t
);
5067 section_ptr(data_section
, 1024);
5068 decl_initializer(t
, data_section
, data_offset
, 1, 0);
5069 size
= type_size(t
, &align
);
5070 data_offset
+= size
;
5071 vpush_ref(t
, data_section
, fc
, size
);
5072 data_section
->data_offset
= data_offset
;
5078 if (parse_btype(&t
, &ad
)) {
5079 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
5081 /* check ISOC99 compound literal */
5083 /* data is allocated locally by default */
5088 /* all except arrays are lvalues */
5089 if (!(ft
& VT_ARRAY
))
5090 r
|= lvalue_type(ft
);
5091 memset(&ad
, 0, sizeof(AttributeDef
));
5092 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
5101 } else if (t
== '*') {
5104 } else if (t
== '&') {
5106 /* functions names must be treated as function pointers,
5107 except for unary '&' and sizeof. Since we consider that
5108 functions are not lvalues, we only have to handle it
5109 there and in function calls. */
5110 /* arrays can also be used although they are not lvalues */
5111 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
5112 !(vtop
->t
& VT_ARRAY
))
5114 vtop
->t
= mk_pointer(vtop
->t
);
5119 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
5120 vtop
->c
.i
= !vtop
->c
.i
;
5121 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
5122 vtop
->c
.i
= vtop
->c
.i
^ 1;
5124 vset(VT_INT
, VT_JMP
, gtst(1, 0));
5132 /* in order to force cast, we add zero */
5134 if ((vtop
->t
& VT_BTYPE
) == VT_PTR
)
5135 error("pointer not accepted for unary plus");
5139 if (t
== TOK_SIZEOF
) {
5142 if (parse_btype(&t
, &ad
)) {
5143 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
5145 /* XXX: some code could be generated: add eval
5157 vpushi(type_size(t
, &t
));
5159 if (t
== TOK_INC
|| t
== TOK_DEC
) {
5162 } else if (t
== '-') {
5169 expect("identifier");
5173 error("'%s' undeclared", get_tok_str(t
, NULL
));
5174 /* for simple function calls, we tolerate undeclared
5175 external reference to int() function */
5176 s
= external_sym(t
, func_old_type
, 0);
5178 vset(s
->t
, s
->r
, s
->c
);
5179 /* if forward reference, we must point to s */
5180 if (vtop
->r
& VT_SYM
)
5185 /* post operations */
5187 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
5190 } else if (tok
== '.' || tok
== TOK_ARROW
) {
5192 if (tok
== TOK_ARROW
)
5197 /* expect pointer on structure */
5198 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
5199 expect("struct or union");
5200 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5203 while ((s
= s
->next
) != NULL
) {
5208 error("field not found");
5209 /* add field offset to pointer */
5210 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
5213 /* change type to field type, and set to lvalue */
5215 /* an array is never an lvalue */
5216 if (!(vtop
->t
& VT_ARRAY
))
5217 vtop
->r
|= lvalue_type(vtop
->t
);
5219 } else if (tok
== '[') {
5225 } else if (tok
== '(') {
5230 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
5231 /* pointer test (no array accepted) */
5232 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
5233 vtop
->t
= pointed_type(vtop
->t
);
5234 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
5238 expect("function pointer");
5241 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
5243 /* get return type */
5244 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
5245 save_regs(0); /* save used temporary registers */
5246 gfunc_start(&gf
, s
->r
);
5248 sa
= s
->next
; /* first parameter */
5249 #ifdef INVERT_FUNC_PARAMS
5253 ParseState saved_parse_state
;
5256 /* read each argument and store it on a stack */
5257 /* XXX: merge it with macro args ? */
5263 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
5267 else if (tok
== ')')
5269 tok_str_add_tok(&str
);
5272 tok_str_add(&str
, -1); /* end of file added */
5273 tok_str_add(&str
, 0);
5274 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
5275 s1
->next
= sa
; /* add reference to argument */
5284 /* now generate code in reverse order by reading the stack */
5285 save_parse_state(&saved_parse_state
);
5287 macro_ptr
= (int *)args
->c
;
5291 expect("',' or ')'");
5292 gfunc_param_typed(&gf
, s
, args
->next
);
5294 tok_str_free((int *)args
->c
);
5298 restore_parse_state(&saved_parse_state
);
5301 /* compute first implicit argument if a structure is returned */
5302 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
5303 /* get some space for the returned structure */
5304 size
= type_size(s
->t
, &align
);
5305 loc
= (loc
- size
) & -align
;
5307 ret
.r
= VT_LOCAL
| VT_LVAL
;
5308 /* pass it as 'int' to avoid structure arg passing
5310 vset(VT_INT
, VT_LOCAL
, loc
);
5316 /* return in register */
5317 if (is_float(ret
.t
)) {
5320 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
5326 #ifndef INVERT_FUNC_PARAMS
5330 gfunc_param_typed(&gf
, s
, sa
);
5340 error("too few arguments to function");
5344 vsetc(ret
.t
, ret
.r
, &ret
.c
);
5358 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
5359 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
5360 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
5383 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
5384 (l
== 1 && (tok
== '+' || tok
== '-')) ||
5385 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
5386 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
5387 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
5388 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
5389 (l
== 5 && tok
== '&') ||
5390 (l
== 6 && tok
== '^') ||
5391 (l
== 7 && tok
== '|') ||
5392 (l
== 8 && tok
== TOK_LAND
) ||
5393 (l
== 9 && tok
== TOK_LOR
)) {
5402 /* only used if non constant */
5410 if (tok
!= TOK_LAND
) {
5413 vset(VT_INT
, VT_JMPI
, t
);
5430 if (tok
!= TOK_LOR
) {
5433 vset(VT_INT
, VT_JMP
, t
);
5443 /* XXX: better constant handling */
5446 int t
, u
, c
, r1
, r2
, rc
;
5466 save_regs(1); /* we need to save all registers here except
5467 at the top because it is a branch point */
5470 /* XXX: long long handling ? */
5472 if (is_float(vtop
->t
))
5475 vtop
--; /* no vpop so that FP stack is not flushed */
5500 /* parse a constant expression and return value in vtop */
5501 void expr_const1(void)
5507 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
5512 /* parse an integer constant and return its value */
5513 int expr_const(void)
5522 /* return the label token if current token is a label, otherwise
5529 /* fast test first */
5530 if (tok
< TOK_UIDENT
)
5532 /* no need to save tokc since we expect an identifier */
5540 /* XXX: may not work in all cases (macros ?) */
5549 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
5554 /* generate line number info */
5556 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
5557 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
5559 last_line_num
= file
->line_num
;
5562 if (tok
== TOK_IF
) {
5569 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5571 if (c
== TOK_ELSE
) {
5575 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5576 gsym(d
); /* patch else jmp */
5579 } else if (tok
== TOK_WHILE
) {
5587 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5591 } else if (tok
== '{') {
5594 s
= local_stack
.top
;
5595 while (tok
!= '}') {
5598 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5600 /* pop locally defined symbols */
5601 sym_pop(&local_stack
, s
);
5603 } else if (tok
== TOK_RETURN
) {
5607 gen_assign_cast(func_vt
);
5608 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5609 /* if returning structure, must copy it to implicit
5610 first pointer arg location */
5611 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
5614 /* copy structure value to pointer */
5616 } else if (is_float(func_vt
)) {
5621 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5624 rsym
= gjmp(rsym
); /* jmp */
5625 } else if (tok
== TOK_BREAK
) {
5628 error("cannot break");
5629 *bsym
= gjmp(*bsym
);
5632 } else if (tok
== TOK_CONTINUE
) {
5635 error("cannot continue");
5636 *csym
= gjmp(*csym
);
5639 } else if (tok
== TOK_FOR
) {
5666 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5671 if (tok
== TOK_DO
) {
5676 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5687 if (tok
== TOK_SWITCH
) {
5691 /* XXX: other types than integer */
5692 case_reg
= gv(RC_INT
);
5696 b
= gjmp(0); /* jump to first case */
5698 block(&a
, csym
, &b
, &c
, case_reg
);
5699 /* if no default, jmp after switch */
5707 if (tok
== TOK_CASE
) {
5714 if (gnu_ext
&& tok
== TOK_DOTS
) {
5718 warning("empty case range");
5720 /* since a case is like a label, we must skip it with a jmp */
5723 vset(VT_INT
, case_reg
, 0);
5727 *case_sym
= gtst(1, 0);
5730 *case_sym
= gtst(1, 0);
5731 vset(VT_INT
, case_reg
, 0);
5734 *case_sym
= gtst(1, *case_sym
);
5738 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5740 if (tok
== TOK_DEFAULT
) {
5746 error("too many 'default'");
5748 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5750 if (tok
== TOK_GOTO
) {
5752 s
= sym_find1(&label_stack
, tok
);
5753 /* put forward definition if needed */
5755 s
= sym_push1(&label_stack
, tok
, LABEL_FORWARD
, 0);
5756 /* label already defined */
5757 if (s
->t
& LABEL_FORWARD
)
5767 s
= sym_find1(&label_stack
, b
);
5769 if (!(s
->t
& LABEL_FORWARD
))
5770 error("multiple defined label");
5775 sym_push1(&label_stack
, b
, 0, ind
);
5777 /* we accept this, but it is a mistake */
5779 warning("deprecated use of label at end of compound statement");
5781 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5783 /* expression case */
5793 /* t is the array or struct type. c is the array or struct
5794 address. cur_index/cur_field is the pointer to the current
5795 value. 'size_only' is true if only size info is needed (only used
5797 void decl_designator(int t
, Section
*sec
, unsigned long c
,
5798 int *cur_index
, Sym
**cur_field
,
5802 int notfirst
, index
, align
, l
;
5805 if (gnu_ext
&& (l
= is_label()) != 0)
5808 while (tok
== '[' || tok
== '.') {
5810 if (!(t
& VT_ARRAY
))
5811 expect("array type");
5812 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5814 index
= expr_const();
5815 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5816 expect("invalid index");
5820 t
= pointed_type(t
);
5821 c
+= index
* type_size(t
, &align
);
5827 if ((t
& VT_BTYPE
) != VT_STRUCT
)
5828 expect("struct/union type");
5829 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5841 t
= f
->t
| (t
& ~VT_TYPE
);
5856 t
= pointed_type(t
);
5857 c
+= index
* type_size(t
, &align
);
5861 error("too many field init");
5862 t
= f
->t
| (t
& ~VT_TYPE
);
5866 decl_initializer(t
, sec
, c
, 0, size_only
);
5870 #define EXPR_CONST 1
5873 /* store a value or an expression directly in global data or in local array */
5874 void init_putv(int t
, Section
*sec
, unsigned long c
,
5875 int v
, int expr_type
)
5877 int saved_global_expr
, bt
;
5885 /* compound literals must be allocated globally in this case */
5886 saved_global_expr
= global_expr
;
5889 global_expr
= saved_global_expr
;
5897 /* XXX: not portable */
5898 /* XXX: generate error if incorrect relocation */
5901 ptr
= sec
->data
+ c
;
5902 if ((vtop
->r
& VT_SYM
) &&
5908 error("initializer element is not computable at load time");
5911 *(char *)ptr
= vtop
->c
.i
;
5914 *(short *)ptr
= vtop
->c
.i
;
5917 *(double *)ptr
= vtop
->c
.d
;
5920 *(long double *)ptr
= vtop
->c
.ld
;
5923 *(long long *)ptr
= vtop
->c
.ll
;
5926 if (vtop
->r
& VT_SYM
) {
5927 greloc(sec
, vtop
->c
.sym
, c
, R_DATA_32
);
5930 *(int *)ptr
= vtop
->c
.i
;
5936 vset(t
, VT_LOCAL
, c
);
5943 /* put zeros for variable based init */
5944 void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
5949 /* nothing to do because globals are already set to zero */
5951 gfunc_start(&gf
, FUNC_CDECL
);
5956 vset(VT_INT
, VT_LOCAL
, c
);
5958 vpush_sym(func_old_type
, TOK_memset
);
5963 /* 't' contains the type and storage info. 'c' is the offset of the
5964 object in section 'sec'. If 'sec' is NULL, it means stack based
5965 allocation. 'first' is true if array '{' must be read (multi
5966 dimension implicit array init handling). 'size_only' is true if
5967 size only evaluation is wanted (only for arrays). */
5968 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
)
5970 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
5971 int t1
, size1
, align1
, expr_type
;
5975 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5978 t1
= pointed_type(t
);
5979 size1
= type_size(t1
, &align1
);
5982 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5988 /* only parse strings here if correct type (otherwise: handle
5989 them as ((w)char *) expressions */
5990 if ((tok
== TOK_LSTR
&&
5991 (t1
& VT_BTYPE
) == VT_INT
) ||
5993 (t1
& VT_BTYPE
) == VT_BYTE
)) {
5994 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5999 /* compute maximum number of chars wanted */
6001 cstr_len
= cstr
->size
;
6003 cstr_len
= cstr
->size
/ sizeof(int);
6006 if (n
>= 0 && nb
> (n
- array_length
))
6007 nb
= n
- array_length
;
6010 warning("initializer-string for array is too long");
6013 ch
= ((unsigned char *)cstr
->data
)[i
];
6015 ch
= ((int *)cstr
->data
)[i
];
6016 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
6023 /* only add trailing zero if enough storage (no
6024 warning in this case since it is standard) */
6025 if (n
< 0 || array_length
< n
) {
6027 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
6033 while (tok
!= '}') {
6034 decl_designator(t
, sec
, c
, &index
, NULL
, size_only
);
6035 if (n
>= 0 && index
>= n
)
6036 error("index too large");
6037 /* must put zero in holes (note that doing it that way
6038 ensures that it even works with designators) */
6039 if (!size_only
&& array_length
< index
) {
6040 init_putz(t1
, sec
, c
+ array_length
* size1
,
6041 (index
- array_length
) * size1
);
6044 if (index
> array_length
)
6045 array_length
= index
;
6046 /* special test for multi dimensional arrays (may not
6047 be strictly correct if designators are used at the
6049 if (index
>= n
&& no_oblock
)
6058 /* put zeros at the end */
6059 if (!size_only
&& n
>= 0 && array_length
< n
) {
6060 init_putz(t1
, sec
, c
+ array_length
* size1
,
6061 (n
- array_length
) * size1
);
6063 /* patch type size if needed */
6065 s
->c
= array_length
;
6066 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
6067 /* XXX: union needs only one init */
6069 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
6074 while (tok
!= '}') {
6075 decl_designator(t
, sec
, c
, NULL
, &f
, size_only
);
6076 /* fill with zero between fields */
6078 if (!size_only
&& array_length
< index
) {
6079 init_putz(t
, sec
, c
+ array_length
,
6080 index
- array_length
);
6082 index
= index
+ type_size(f
->t
, &align1
);
6083 if (index
> array_length
)
6084 array_length
= index
;
6090 /* put zeros at the end */
6091 if (!size_only
&& array_length
< n
) {
6092 init_putz(t
, sec
, c
+ array_length
,
6096 } else if (tok
== '{') {
6098 decl_initializer(t
, sec
, c
, first
, size_only
);
6100 } else if (size_only
) {
6101 /* just skip expression */
6103 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
6107 else if (tok
== ')')
6112 /* currently, we always use constant expression for globals
6113 (may change for scripting case) */
6114 expr_type
= EXPR_CONST
;
6116 expr_type
= EXPR_ANY
;
6117 init_putv(t
, sec
, c
, 0, expr_type
);
6121 /* parse an initializer for type 't' if 'has_init' is true, and
6122 allocate space in local or global data space ('r' is either
6123 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6124 variable 'v' of scope 'scope' is declared before initializers are
6125 parsed. If 'v' is zero, then a reference to the new object is put
6126 in the value stack. */
6127 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
6130 int size
, align
, addr
, data_offset
;
6132 ParseState saved_parse_state
;
6133 TokenString init_str
;
6136 size
= type_size(t
, &align
);
6137 /* If unknown size, we must evaluate it before
6138 evaluating initializers because
6139 initializers can generate global data too
6140 (e.g. string pointers or ISOC99 compound
6141 literals). It also simplifies local
6142 initializers handling */
6143 tok_str_new(&init_str
);
6146 error("unknown type size");
6147 /* get all init string */
6149 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
6151 error("unexpected end of file in initializer");
6152 tok_str_add_tok(&init_str
);
6155 else if (tok
== '}') {
6162 tok_str_add(&init_str
, -1);
6163 tok_str_add(&init_str
, 0);
6166 save_parse_state(&saved_parse_state
);
6168 macro_ptr
= init_str
.str
;
6170 decl_initializer(t
, NULL
, 0, 1, 1);
6171 /* prepare second initializer parsing */
6172 macro_ptr
= init_str
.str
;
6175 /* if still unknown size, error */
6176 size
= type_size(t
, &align
);
6178 error("unknown type size");
6180 /* take into account specified alignment if bigger */
6181 if (ad
->aligned
> align
)
6182 align
= ad
->aligned
;
6183 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
6185 if (do_bounds_check
&& (t
& VT_ARRAY
))
6187 #ifdef TCC_TARGET_IL
6188 /* XXX: ugly patch to allocate local variables for IL, just
6193 loc
= (loc
- size
) & -align
;
6196 /* handles bounds */
6197 /* XXX: currently, since we do only one pass, we cannot track
6198 '&' operators, so we add only arrays */
6199 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
6200 unsigned long *bounds_ptr
;
6201 /* add padding between regions */
6203 /* then add local bound info */
6204 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
6205 bounds_ptr
[0] = addr
;
6206 bounds_ptr
[1] = size
;
6209 /* compute section */
6217 data_offset
= sec
->data_offset
;
6218 data_offset
= (data_offset
+ align
- 1) & -align
;
6220 /* very important to increment global pointer at this time
6221 because initializers themselves can create new initializers */
6222 data_offset
+= size
;
6223 /* add padding if bound check */
6224 if (do_bounds_check
)
6226 sec
->data_offset
= data_offset
;
6227 /* allocate section space to put the data */
6228 if (sec
->sh_type
!= SHT_NOBITS
&&
6229 data_offset
> sec
->data_allocated
)
6230 section_realloc(sec
, data_offset
);
6234 /* local variable */
6235 sym_push(v
, t
, r
, addr
);
6237 /* push local reference */
6244 if (scope
== VT_CONST
) {
6245 /* global scope: see if already defined */
6249 if (!is_compatible_types(sym
->t
, t
))
6250 error("incompatible types for redefinition of '%s'",
6251 get_tok_str(v
, NULL
));
6252 if (!(sym
->t
& VT_EXTERN
))
6253 error("redefinition of '%s'", get_tok_str(v
, NULL
));
6254 sym
->t
&= ~VT_EXTERN
;
6257 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
6259 put_extern_sym(sym
, sec
, addr
, size
);
6263 /* push global reference */
6264 sym
= get_sym_ref(t
, sec
, addr
, size
);
6266 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
6269 /* handles bounds now because the symbol must be defined
6270 before for the relocation */
6271 if (do_bounds_check
) {
6272 unsigned long *bounds_ptr
;
6274 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
6275 /* then add global bound info */
6276 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
6277 bounds_ptr
[0] = 0; /* relocated */
6278 bounds_ptr
[1] = size
;
6282 decl_initializer(t
, sec
, addr
, 1, 0);
6283 /* restore parse state if needed */
6285 tok_str_free(init_str
.str
);
6286 restore_parse_state(&saved_parse_state
);
6291 void put_func_debug(Sym
*sym
)
6296 /* XXX: we put here a dummy type */
6297 snprintf(buf
, sizeof(buf
), "%s:%c1",
6298 funcname
, sym
->t
& VT_STATIC
? 'f' : 'F');
6299 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
6300 cur_text_section
, sym
->c
);
6305 /* not finished : try to put some local vars in registers */
6306 //#define CONFIG_REG_VARS
6308 #ifdef CONFIG_REG_VARS
6309 void add_var_ref(int t
)
6311 printf("%s:%d: &%s\n",
6312 file
->filename
, file
->line_num
,
6313 get_tok_str(t
, NULL
));
6316 /* first pass on a function with heuristic to extract variable usage
6317 and pointer references to local variables for register allocation */
6318 void analyse_function(void)
6325 /* any symbol coming after '&' is considered as being a
6326 variable whose reference is taken. It is highly unaccurate
6327 but it is difficult to do better without a complete parse */
6330 /* if '& number', then no need to examine next tokens */
6331 if (tok
== TOK_CINT
||
6333 tok
== TOK_CLLONG
||
6334 tok
== TOK_CULLONG
) {
6336 } else if (tok
>= TOK_UIDENT
) {
6337 /* if '& ident [' or '& ident ->', then ident address
6341 if (tok
!= '[' && tok
!= TOK_ARROW
)
6345 while (tok
!= '}' && tok
!= ';' &&
6346 !((tok
== ',' || tok
== ')') && level
== 0)) {
6347 if (tok
>= TOK_UIDENT
) {
6349 } else if (tok
== '(') {
6351 } else if (tok
== ')') {
6364 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6367 int t
, b
, v
, has_init
, r
;
6372 if (!parse_btype(&b
, &ad
)) {
6373 /* skip redundant ';' */
6374 /* XXX: find more elegant solution */
6379 /* special test for old K&R protos without explicit int
6380 type. Only accepted when defining global data */
6381 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
6385 if (((b
& VT_BTYPE
) == VT_ENUM
||
6386 (b
& VT_BTYPE
) == VT_STRUCT
) &&
6388 /* we accept no variable after */
6392 while (1) { /* iterate thru each declaration */
6393 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
6397 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
6398 printf("type = '%s'\n", buf
);
6402 #ifdef CONFIG_REG_VARS
6403 TokenString func_str
;
6404 ParseState saved_parse_state
;
6409 error("cannot use local functions");
6411 expect("function definition");
6413 #ifdef CONFIG_REG_VARS
6414 /* parse all function code and record it */
6416 tok_str_new(&func_str
);
6422 error("unexpected end of file");
6423 tok_str_add_tok(&func_str
);
6428 } else if (t
== '}') {
6430 if (block_level
== 0)
6434 tok_str_add(&func_str
, -1);
6435 tok_str_add(&func_str
, 0);
6437 save_parse_state(&saved_parse_state
);
6439 macro_ptr
= func_str
.str
;
6444 /* compute text section */
6445 cur_text_section
= ad
.section
;
6446 if (!cur_text_section
)
6447 cur_text_section
= text_section
;
6448 ind
= cur_text_section
->data_offset
;
6449 funcname
= get_tok_str(v
, NULL
);
6452 /* if symbol is already defined, then put complete type */
6455 /* put function symbol */
6456 sym
= sym_push1(&global_stack
, v
, t
, 0);
6458 /* NOTE: we patch the symbol size later */
6459 put_extern_sym(sym
, cur_text_section
, ind
, 0);
6461 sym
->r
= VT_SYM
| VT_CONST
;
6462 /* put debug symbol */
6464 put_func_debug(sym
);
6465 /* push a dummy symbol to enable local sym storage */
6466 sym_push1(&local_stack
, 0, 0, 0);
6470 #ifdef CONFIG_REG_VARS
6471 macro_ptr
= func_str
.str
;
6474 block(NULL
, NULL
, NULL
, NULL
, 0);
6477 cur_text_section
->data_offset
= ind
;
6478 sym_pop(&label_stack
, NULL
); /* reset label stack */
6479 sym_pop(&local_stack
, NULL
); /* reset local stack */
6480 /* end of function */
6481 /* patch symbol size */
6482 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
6485 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6487 funcname
= ""; /* for safety */
6488 func_vt
= VT_VOID
; /* for safety */
6489 ind
= 0; /* for safety */
6491 #ifdef CONFIG_REG_VARS
6492 tok_str_free(func_str
.str
);
6493 restore_parse_state(&saved_parse_state
);
6497 if (b
& VT_TYPEDEF
) {
6498 /* save typedefed type */
6499 /* XXX: test storage specifiers ? */
6500 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
6501 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
6502 /* external function definition */
6503 external_sym(v
, t
, 0);
6505 /* not lvalue if array */
6507 if (!(t
& VT_ARRAY
))
6508 r
|= lvalue_type(t
);
6509 if (b
& VT_EXTERN
) {
6510 /* external variable */
6511 external_sym(v
, t
, r
);
6517 has_init
= (tok
== '=');
6520 decl_initializer_alloc(t
, &ad
, r
,
6534 /* compile the C file opened in 'file'. Return non zero if errors. */
6535 static int tcc_compile(TCCState
*s
)
6542 include_stack_ptr
= include_stack
;
6543 ifdef_stack_ptr
= ifdef_stack
;
6545 /* XXX: not ANSI compliant: bound checking says error */
6547 anon_sym
= SYM_FIRST_ANOM
;
6549 /* file info: full path + filename */
6550 section_sym
= 0; /* avoid warning */
6552 section_sym
= put_elf_sym(symtab_section
, 0, 0,
6553 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
6554 text_section
->sh_num
, NULL
);
6555 getcwd(buf
, sizeof(buf
));
6556 pstrcat(buf
, sizeof(buf
), "/");
6557 put_stabs_r(buf
, N_SO
, 0, 0,
6558 text_section
->data_offset
, text_section
, section_sym
);
6559 put_stabs_r(file
->filename
, N_SO
, 0, 0,
6560 text_section
->data_offset
, text_section
, section_sym
);
6562 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6563 symbols can be safely used */
6564 put_elf_sym(symtab_section
, 0, 0,
6565 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
6566 SHN_ABS
, file
->filename
);
6568 /* define common 'char *' type because it is often used internally
6569 for arrays and struct dereference */
6570 char_pointer_type
= mk_pointer(VT_BYTE
);
6571 /* define an old type function 'int func()' */
6573 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
6574 func_old_type
= VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
6576 define_start
= define_stack
.top
;
6578 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6582 expect("declaration");
6584 /* end of translation unit info */
6586 put_stabs_r(NULL
, N_SO
, 0, 0,
6587 text_section
->data_offset
, text_section
, section_sym
);
6590 /* reset define stack, but leave -Dsymbols (may be incorrect if
6591 they are undefined) */
6592 sym_pop(&define_stack
, define_start
);
6594 sym_pop(&global_stack
, NULL
);
6599 int tcc_compile_string(TCCState
*s
, const char *str
)
6601 BufferedFile bf1
, *bf
= &bf1
;
6604 /* init file structure */
6606 bf
->buf_ptr
= (char *)str
;
6607 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
6608 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
6612 ret
= tcc_compile(s
);
6614 /* currently, no need to close */
6618 /* define a symbol. A value can also be provided with the '=' operator */
6619 void tcc_define_symbol(TCCState
*s
, const char *sym
, const char *value
)
6621 BufferedFile bf1
, *bf
= &bf1
;
6623 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
6624 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
6628 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
6630 /* init file structure */
6632 bf
->buf_ptr
= bf
->buffer
;
6633 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
6634 bf
->filename
[0] = '\0';
6638 include_stack_ptr
= include_stack
;
6640 /* parse with define parser */
6642 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6648 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
6652 ts
= tok_alloc(sym
, 0);
6653 s
= sym_find1(&define_stack
, tok
);
6654 /* undefine symbol by putting an invalid name */
6656 sym_undef(&define_stack
, s
);
6661 /* print the position in the source file of PC value 'pc' by reading
6662 the stabs debug information */
6663 static void rt_printline(unsigned long wanted_pc
)
6665 Stab_Sym
*sym
, *sym_end
;
6666 char func_name
[128], last_func_name
[128];
6667 unsigned long func_addr
, last_pc
, pc
;
6668 const char *incl_files
[INCLUDE_STACK_SIZE
];
6669 int incl_index
, len
, last_line_num
, i
;
6670 const char *str
, *p
;
6672 func_name
[0] = '\0';
6675 last_func_name
[0] = '\0';
6676 last_pc
= 0xffffffff;
6678 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
6679 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
6680 while (sym
< sym_end
) {
6681 switch(sym
->n_type
) {
6682 /* function start or end */
6684 if (sym
->n_strx
== 0) {
6685 func_name
[0] = '\0';
6688 str
= stabstr_section
->data
+ sym
->n_strx
;
6689 p
= strchr(str
, ':');
6691 pstrcpy(func_name
, sizeof(func_name
), str
);
6694 if (len
> sizeof(func_name
) - 1)
6695 len
= sizeof(func_name
) - 1;
6696 memcpy(func_name
, str
, len
);
6697 func_name
[len
] = '\0';
6699 func_addr
= sym
->n_value
;
6702 /* line number info */
6704 pc
= sym
->n_value
+ func_addr
;
6705 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
6708 last_line_num
= sym
->n_desc
;
6710 strcpy(last_func_name
, func_name
);
6714 str
= stabstr_section
->data
+ sym
->n_strx
;
6716 if (incl_index
< INCLUDE_STACK_SIZE
) {
6717 incl_files
[incl_index
++] = str
;
6725 if (sym
->n_strx
== 0) {
6726 incl_index
= 0; /* end of translation unit */
6728 str
= stabstr_section
->data
+ sym
->n_strx
;
6729 /* do not add path */
6731 if (len
> 0 && str
[len
- 1] != '/')
6738 /* did not find line number info: */
6739 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
6742 for(i
= 0; i
< incl_index
- 1; i
++)
6743 fprintf(stderr
, "In file included from %s\n",
6745 if (incl_index
> 0) {
6746 fprintf(stderr
, "%s:%d: ",
6747 incl_files
[incl_index
- 1], last_line_num
);
6749 if (last_func_name
[0] != '\0') {
6750 fprintf(stderr
, "in function '%s()': ", last_func_name
);
6754 /* emit a run time error at position 'pc' */
6755 void rt_error(unsigned long pc
, const char *fmt
, ...)
6761 vfprintf(stderr
, fmt
, ap
);
6762 fprintf(stderr
, "\n");
6768 /* signal handler for fatal errors */
6769 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
6771 struct ucontext
*uc
= puc
;
6775 pc
= uc
->uc_mcontext
.gregs
[14];
6777 #error please put the right sigcontext field
6782 switch(siginf
->si_code
) {
6785 rt_error(pc
, "division by zero");
6788 rt_error(pc
, "floating point exception");
6794 rt_error(pc
, "dereferencing invalid pointer");
6797 rt_error(pc
, "illegal instruction");
6800 rt_error(pc
, "abort() called");
6803 rt_error(pc
, "caught signal %d", signum
);
6810 /* launch the compiled program with the given arguments */
6811 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
6814 int (*prog_main
)(int, char **);
6817 tcc_add_runtime(s1
);
6819 relocate_common_syms();
6821 /* compute relocation address : section are relocated in place. We
6822 also alloc the bss space */
6823 for(i
= 1; i
< nb_sections
; i
++) {
6825 if (s
->sh_flags
& SHF_ALLOC
) {
6827 if (s
->sh_type
== SHT_NOBITS
) {
6828 data
= tcc_mallocz(s
->data_offset
);
6832 s
->sh_addr
= (unsigned long)data
;
6838 /* relocate each section */
6839 for(i
= 1; i
< nb_sections
; i
++) {
6842 relocate_section(s1
, s
);
6845 prog_main
= (void *)get_elf_sym_val("main");
6849 error("debug mode currently not available for Windows");
6851 struct sigaction sigact
;
6852 /* install TCC signal handlers to print debug info on fatal
6854 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
6855 sigact
.sa_sigaction
= sig_error
;
6856 sigemptyset(&sigact
.sa_mask
);
6857 sigaction(SIGFPE
, &sigact
, NULL
);
6858 sigaction(SIGILL
, &sigact
, NULL
);
6859 sigaction(SIGSEGV
, &sigact
, NULL
);
6860 sigaction(SIGBUS
, &sigact
, NULL
);
6861 sigaction(SIGABRT
, &sigact
, NULL
);
6865 #ifdef CONFIG_TCC_BCHECK
6866 if (do_bounds_check
) {
6867 void (*bound_init
)(void);
6868 void **bound_error_func
;
6870 /* set error function */
6871 bound_error_func
= (void **)get_elf_sym_val("__bound_error_func");
6872 *bound_error_func
= rt_error
;
6874 /* XXX: use .init section so that it also work in binary ? */
6875 bound_init
= (void *)get_elf_sym_val("__bound_init");
6879 return (*prog_main
)(argc
, argv
);
6882 TCCState
*tcc_new(void)
6887 s
= tcc_malloc(sizeof(TCCState
));
6890 s
->output_type
= TCC_OUTPUT_MEMORY
;
6892 /* default include paths */
6893 tcc_add_sysinclude_path(s
, "/usr/local/include");
6894 tcc_add_sysinclude_path(s
, "/usr/include");
6895 tcc_add_sysinclude_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
6897 /* add all tokens */
6898 tok_ident
= TOK_IDENT
;
6903 tok_alloc(p
, r
- p
- 1);
6907 /* standard defines */
6908 tcc_define_symbol(s
, "__STDC__", NULL
);
6909 #if defined(TCC_TARGET_I386)
6910 tcc_define_symbol(s
, "__i386__", NULL
);
6912 /* tiny C specific defines */
6913 tcc_define_symbol(s
, "__TINYC__", NULL
);
6915 /* default library paths */
6916 tcc_add_library_path(s
, "/usr/local/lib");
6917 tcc_add_library_path(s
, "/usr/lib");
6918 tcc_add_library_path(s
, "/lib");
6920 /* no section zero */
6921 dynarray_add((void ***)§ions
, &nb_sections
, NULL
);
6923 /* create standard sections */
6924 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
6925 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6926 bss_section
= new_section(".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
6928 /* symbols are always generated for linking stage */
6929 symtab_section
= new_symtab(".symtab", SHT_SYMTAB
, 0,
6931 ".hashtab", SHF_PRIVATE
);
6932 strtab_section
= symtab_section
->link
;
6934 /* private symbol table for dynamic symbols */
6935 dynsymtab_section
= new_symtab(".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
6937 ".dynhashtab", SHF_PRIVATE
);
6941 void tcc_delete(TCCState
*s
)
6946 int tcc_add_include_path(TCCState
*s
, const char *pathname
)
6950 pathname1
= tcc_strdup(pathname
);
6951 dynarray_add((void ***)&include_paths
, &nb_include_paths
, pathname1
);
6955 int tcc_add_sysinclude_path(TCCState
*s
, const char *pathname
)
6959 pathname1
= tcc_strdup(pathname
);
6960 dynarray_add((void ***)&sysinclude_paths
, &nb_sysinclude_paths
, pathname1
);
6964 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
)
6969 BufferedFile
*saved_file
;
6971 /* find source file type with extension */
6972 ext
= strrchr(filename
, '.');
6978 file
= tcc_open(filename
);
6980 if (flags
& AFF_PRINT_ERROR
) {
6981 error("file '%s' not found", filename
);
6988 if (!ext
|| !strcmp(ext
, "c")) {
6989 /* C file assumed */
6993 /* assume executable format: auto guess file type */
6994 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
6995 error("could not read header");
6996 lseek(fd
, 0, SEEK_SET
);
6998 if (ehdr
.e_ident
[0] == ELFMAG0
&&
6999 ehdr
.e_ident
[1] == ELFMAG1
&&
7000 ehdr
.e_ident
[2] == ELFMAG2
&&
7001 ehdr
.e_ident
[3] == ELFMAG3
) {
7002 file
->line_num
= 0; /* do not display line number if error */
7003 if (ehdr
.e_type
== ET_REL
) {
7004 tcc_load_object_file(s
, fd
, 0);
7005 } else if (ehdr
.e_type
== ET_DYN
) {
7006 tcc_load_dll(s
, fd
, filename
, (flags
& AFF_REFERENCED_DLL
) != 0);
7008 error("unrecognized ELF file");
7010 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
7011 file
->line_num
= 0; /* do not display line number if error */
7012 tcc_load_archive(s
, fd
);
7014 /* as GNU ld, consider it is an ld script if not recognized */
7015 if (tcc_load_ldscript(s
) < 0)
7016 error("unrecognized file type");
7024 void tcc_add_file(TCCState
*s
, const char *filename
)
7026 tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
7029 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
7033 pathname1
= tcc_strdup(pathname
);
7034 dynarray_add((void ***)&library_paths
, &nb_library_paths
, pathname1
);
7038 /* find and load a dll. Return non zero if not found */
7039 /* XXX: add '-rpath' option support ? */
7040 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
7045 for(i
= 0; i
< nb_library_paths
; i
++) {
7046 snprintf(buf
, sizeof(buf
), "%s/%s",
7047 library_paths
[i
], filename
);
7048 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
7054 /* the library name is the same as the argument of the '-l' option */
7055 int tcc_add_library(TCCState
*s
, const char *libraryname
)
7061 /* if we output to memory, then we simply we dlopen(). */
7062 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
7063 /* Since the libc is already loaded, we don't need to load it again */
7064 if (!strcmp(libraryname
, "c"))
7066 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
7067 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
7073 /* first we look for the dynamic library if not static linking */
7075 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
7076 if (tcc_add_dll(s
, buf
, 0) == 0)
7080 /* then we look for the static library */
7081 for(i
= 0; i
< nb_library_paths
; i
++) {
7082 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
7083 library_paths
[i
], libraryname
);
7084 if (tcc_add_file_internal(s
, buf
, 0) == 0)
7090 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
7092 add_elf_sym(symtab_section
, val
, 0,
7093 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7098 int tcc_set_output_type(TCCState
*s
, int output_type
)
7100 s
->output_type
= output_type
;
7102 /* if bound checking, then add corresponding sections */
7103 #ifdef CONFIG_TCC_BCHECK
7104 if (do_bounds_check
) {
7106 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
7107 /* create bounds sections */
7108 bounds_section
= new_section(".bounds",
7109 SHT_PROGBITS
, SHF_ALLOC
);
7110 lbounds_section
= new_section(".lbounds",
7111 SHT_PROGBITS
, SHF_ALLOC
);
7115 /* add debug sections */
7118 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
7119 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
7120 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
7121 put_elf_str(stabstr_section
, "");
7122 stab_section
->link
= stabstr_section
;
7123 /* put first entry */
7124 put_stabs("", 0, 0, 0, 0);
7127 /* add libc crt1/crti objects */
7128 if (output_type
== TCC_OUTPUT_EXE
||
7129 output_type
== TCC_OUTPUT_DLL
) {
7130 if (output_type
!= TCC_OUTPUT_DLL
)
7131 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
7132 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
7137 #if !defined(LIBTCC)
7141 printf("tcc version 0.9.10pre1 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7142 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7143 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
7144 " [--] infile1 [infile2... --] [infile_args...]\n"
7146 "General options:\n"
7147 " -c compile only - generate an object file\n"
7148 " -o outfile set output filename\n"
7149 " -- allows multiples input files if no -o option given. Also\n"
7150 " separate input files from runtime arguments\n"
7151 " -Bdir set tcc internal library path\n"
7152 " -bench output compilation statistics\n"
7153 "Preprocessor options:\n"
7154 " -Idir add include path 'dir'\n"
7155 " -Dsym[=val] define 'sym' with value 'val'\n"
7156 " -Usym undefine 'sym'\n"
7157 "C compiler options:\n"
7158 " -g generate runtime debug info\n"
7159 #ifdef CONFIG_TCC_BCHECK
7160 " -b compile with built-in memory and bounds checker (implies -g)\n"
7163 " -Ldir add library path 'dir'\n"
7164 " -llib link with dynamic or static library 'lib'\n"
7165 " -shared generate a shared library\n"
7166 " -static static linking\n"
7170 int main(int argc
, char **argv
)
7173 int optind
, output_type
, multiple_files
, i
;
7179 output_type
= TCC_OUTPUT_MEMORY
;
7187 if (optind
>= argc
) {
7197 /* '--' enables multiple files input */
7199 } else if (r
[1] == 'h' || r
[1] == '?') {
7201 } else if (r
[1] == 'I') {
7202 if (tcc_add_include_path(s
, r
+ 2) < 0)
7203 error("too many include paths");
7204 } else if (r
[1] == 'D') {
7207 value
= strchr(sym
, '=');
7212 tcc_define_symbol(s
, sym
, value
);
7213 } else if (r
[1] == 'U') {
7214 tcc_undefine_symbol(s
, r
+ 2);
7215 } else if (r
[1] == 'L') {
7216 tcc_add_library_path(s
, r
+ 2);
7217 } else if (r
[1] == 'B') {
7218 /* set tcc utilities path (mainly for tcc development) */
7219 tcc_lib_path
= r
+ 2;
7220 } else if (r
[1] == 'l') {
7221 dynarray_add((void ***)&libraries
, &nb_libraries
, r
+ 2);
7222 } else if (!strcmp(r
+ 1, "bench")) {
7225 #ifdef CONFIG_TCC_BCHECK
7227 do_bounds_check
= 1;
7233 } else if (r
[1] == 'c') {
7235 output_type
= TCC_OUTPUT_OBJ
;
7236 } else if (!strcmp(r
+ 1, "static")) {
7238 } else if (!strcmp(r
+ 1, "shared")) {
7239 output_type
= TCC_OUTPUT_DLL
;
7240 } else if (r
[1] == 'o') {
7244 outfile
= argv
[optind
++];
7246 error("invalid option -- '%s'", r
);
7250 /* if outfile provided without other options, we output an
7252 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
7253 output_type
= TCC_OUTPUT_EXE
;
7255 tcc_set_output_type(s
, output_type
);
7257 tcc_add_file(s
, argv
[optind
]);
7258 if (multiple_files
) {
7259 while ((optind
+ 1) < argc
) {
7264 error("'--' expected");
7271 /* add specified libraries */
7272 for(i
= 0; i
< nb_libraries
;i
++) {
7273 if (tcc_add_library(s
, libraries
[i
]) < 0)
7274 error("cannot find -l%s", libraries
[i
]);
7278 printf("total: %d idents, %d lines, %d bytes\n",
7279 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
7281 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);
7285 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
7286 tcc_output_file(s
, outfile
);
7289 return tcc_run(s
, argc
- optind
, argv
+ optind
);