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
,
505 #define DEF(id, str) id,
511 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
512 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
513 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
514 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
515 "sizeof\0__attribute__\0"
516 /* the following are not keywords. They are included to ease parsing */
517 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
518 "defined\0undef\0error\0line\0"
519 /* builtin functions */
520 #define DEF(id, str) str "\0"
526 #define snprintf _snprintf
529 #if defined(WIN32) || defined(TCC_UCLIBC)
530 /* currently incorrect */
531 long double strtold(const char *nptr
, char **endptr
)
533 return (long double)strtod(nptr
, endptr
);
535 float strtof(const char *nptr
, char **endptr
)
537 return (float)strtod(nptr
, endptr
);
540 /* XXX: need to define this to use them in non ISOC99 context */
541 extern float strtof (const char *__nptr
, char **__endptr
);
542 extern long double strtold (const char *__nptr
, char **__endptr
);
545 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
546 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
550 void next_nomacro(void);
551 int expr_const(void);
555 static void decl_initializer(int t
, Section
*sec
, unsigned long c
,
556 int first
, int size_only
);
557 static void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
,
558 int has_init
, int v
, int scope
);
560 void gv2(int rc1
, int rc2
);
561 void move_reg(int r
, int s
);
562 void save_regs(int n
);
563 void save_reg(int r
);
569 void macro_subst(TokenString
*tok_str
,
570 Sym
**nested_list
, int *macro_str
);
571 int save_reg_forced(int r
);
573 void force_charshort_cast(int t
);
574 void gen_cast(int t
);
576 Sym
*sym_find(int v
);
577 Sym
*sym_push(int v
, int t
, int r
, int c
);
580 int type_size(int t
, int *a
);
581 int pointed_type(int t
);
582 int pointed_size(int t
);
583 static int lvalue_type(int t
);
584 int is_compatible_types(int t1
, int t2
);
585 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
586 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
588 void error(const char *fmt
, ...);
589 void rt_error(unsigned long pc
, const char *fmt
, ...);
591 void vset(int t
, int r
, int v
);
592 void type_to_str(char *buf
, int buf_size
,
593 int t
, const char *varstr
);
594 char *get_tok_str(int v
, CValue
*cv
);
595 Sym
*external_sym(int v
, int u
, int r
);
596 static Sym
*get_sym_ref(int t
, Section
*sec
,
597 unsigned long offset
, unsigned long size
);
599 /* section generation */
600 static void section_realloc(Section
*sec
, unsigned long new_size
);
601 static void *section_ptr_add(Section
*sec
, unsigned long size
);
602 static void put_extern_sym(Sym
*sym
, Section
*section
,
603 unsigned long value
, unsigned long size
);
604 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
605 static int put_elf_str(Section
*s
, const char *sym
);
606 static int put_elf_sym(Section
*s
,
607 unsigned long value
, unsigned long size
,
608 int info
, int other
, int shndx
, const char *name
);
609 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
610 int info
, int sh_num
, const char *name
);
611 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
612 int type
, int symbol
);
613 static void put_stabs(const char *str
, int type
, int other
, int desc
,
614 unsigned long value
);
615 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
616 unsigned long value
, Section
*sec
, int sym_index
);
617 static void put_stabn(int type
, int other
, int desc
, int value
);
618 static void put_stabd(int type
, int other
, int desc
);
619 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
621 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
622 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
623 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
625 /* true if float/double/long double type */
626 static inline int is_float(int t
)
630 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
633 #ifdef TCC_TARGET_I386
634 #include "i386-gen.c"
640 #ifdef CONFIG_TCC_STATIC
642 #define RTLD_LAZY 0x001
643 #define RTLD_NOW 0x002
644 #define RTLD_GLOBAL 0x100
646 /* dummy function for profiling */
647 void *dlopen(const char *filename
, int flag
)
652 const char *dlerror(void)
657 typedef struct TCCSyms
{
662 #define TCCSYM(a) { #a, &a, },
664 /* add the symbol you want here if no dynamic linking is done */
665 static TCCSyms tcc_syms
[] = {
673 void *dlsym(void *handle
, const char *symbol
)
677 while (p
->str
!= NULL
) {
678 if (!strcmp(p
->str
, symbol
))
687 /********************************************************/
689 /* we use our own 'finite' function to avoid potential problems with
690 non standard math libs */
691 /* XXX: endianness dependant */
692 int ieee_finite(double d
)
695 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
698 /* copy a string and truncate it. */
699 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
706 q_end
= buf
+ buf_size
- 1;
718 /* strcat and truncate. */
719 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
724 pstrcpy(buf
+ len
, buf_size
- len
, s
);
728 /* memory management */
734 static inline void tcc_free(void *ptr
)
737 mem_cur_size
-= malloc_usable_size(ptr
);
742 static void *tcc_malloc(unsigned long size
)
747 error("memory full");
749 mem_cur_size
+= malloc_usable_size(ptr
);
750 if (mem_cur_size
> mem_max_size
)
751 mem_max_size
= mem_cur_size
;
756 static void *tcc_mallocz(unsigned long size
)
759 ptr
= tcc_malloc(size
);
760 memset(ptr
, 0, size
);
764 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
768 mem_cur_size
-= malloc_usable_size(ptr
);
770 ptr1
= realloc(ptr
, size
);
772 /* NOTE: count not correct if alloc error, but not critical */
773 mem_cur_size
+= malloc_usable_size(ptr1
);
774 if (mem_cur_size
> mem_max_size
)
775 mem_max_size
= mem_cur_size
;
780 static char *tcc_strdup(const char *str
)
783 ptr
= tcc_malloc(strlen(str
) + 1);
788 #define free(p) use_tcc_free(p)
789 #define malloc(s) use_tcc_malloc(s)
790 #define realloc(p, s) use_tcc_realloc(p, s)
792 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
799 /* every power of two we double array size */
800 if ((nb
& (nb
- 1)) == 0) {
805 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
807 error("memory full");
814 Section
*new_section(const char *name
, int sh_type
, int sh_flags
)
818 sec
= tcc_mallocz(sizeof(Section
));
819 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
820 sec
->sh_type
= sh_type
;
821 sec
->sh_flags
= sh_flags
;
828 sec
->sh_addralign
= 4;
831 sec
->sh_addralign
= 1;
834 sec
->sh_addralign
= 32; /* default conservative alignment */
838 /* only add section if not private */
839 if (!(sh_flags
& SHF_PRIVATE
)) {
840 sec
->sh_num
= nb_sections
;
841 dynarray_add((void ***)§ions
, &nb_sections
, sec
);
846 /* realloc section and set its content to zero */
847 static void section_realloc(Section
*sec
, unsigned long new_size
)
852 size
= sec
->data_allocated
;
855 while (size
< new_size
)
857 data
= tcc_realloc(sec
->data
, size
);
859 error("memory full");
860 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
862 sec
->data_allocated
= size
;
865 /* reserve at least 'size' bytes in section 'sec' from
867 static void *section_ptr_add(Section
*sec
, unsigned long size
)
869 unsigned long offset
, offset1
;
871 offset
= sec
->data_offset
;
872 offset1
= offset
+ size
;
873 if (offset1
> sec
->data_allocated
)
874 section_realloc(sec
, offset1
);
875 sec
->data_offset
= offset1
;
876 return sec
->data
+ offset
;
879 /* return a reference to a section, and create it if it does not
881 Section
*find_section(const char *name
)
885 for(i
= 1; i
< nb_sections
; i
++) {
887 if (!strcmp(name
, sec
->name
))
890 /* sections are created as PROGBITS */
891 return new_section(name
, SHT_PROGBITS
, SHF_ALLOC
);
894 /* update sym->c so that it points to an external symbol in section
895 'section' with value 'value' */
896 static void put_extern_sym(Sym
*sym
, Section
*section
,
897 unsigned long value
, unsigned long size
)
899 int sym_type
, sym_bind
, sh_num
, info
;
905 sh_num
= section
->sh_num
;
909 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
912 sym_type
= STT_OBJECT
;
913 if (sym
->t
& VT_STATIC
)
914 sym_bind
= STB_LOCAL
;
916 sym_bind
= STB_GLOBAL
;
918 name
= get_tok_str(sym
->v
, NULL
);
919 #ifdef CONFIG_TCC_BCHECK
920 if (do_bounds_check
) {
921 /* if bound checking is activated, we change some function
922 names by adding the "__bound" prefix */
934 strcpy(buf
, "__bound_");
941 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
942 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
944 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
945 esym
->st_value
= value
;
946 esym
->st_size
= size
;
947 esym
->st_shndx
= sh_num
;
951 /* add a new relocation entry to symbol 'sym' in section 's' */
952 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
955 put_extern_sym(sym
, NULL
, 0, 0);
956 /* now we can add ELF relocation info */
957 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
960 static inline int isid(int c
)
962 return (c
>= 'a' && c
<= 'z') ||
963 (c
>= 'A' && c
<= 'Z') ||
967 static inline int isnum(int c
)
969 return c
>= '0' && c
<= '9';
972 static inline int toup(int c
)
974 if (ch
>= 'a' && ch
<= 'z')
975 return ch
- 'a' + 'A';
985 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
986 fprintf(stderr
, "In file included from %s:%d:\n",
987 (*f
)->filename
, (*f
)->line_num
);
988 if (file
->line_num
> 0) {
989 fprintf(stderr
, "%s:%d: ", file
->filename
, file
->line_num
);
991 fprintf(stderr
, "%s: ", file
->filename
);
994 fprintf(stderr
, "tcc: ");
998 void error(const char *fmt
, ...)
1003 vfprintf(stderr
, fmt
, ap
);
1004 fprintf(stderr
, "\n");
1009 void expect(const char *msg
)
1011 error("%s expected", msg
);
1014 void warning(const char *fmt
, ...)
1020 fprintf(stderr
, "warning: ");
1021 vfprintf(stderr
, fmt
, ap
);
1022 fprintf(stderr
, "\n");
1029 error("'%c' expected", c
);
1033 void test_lvalue(void)
1035 if (!(vtop
->r
& VT_LVAL
))
1039 TokenSym
*tok_alloc(const char *str
, int len
)
1041 TokenSym
*ts
, **pts
, **ptable
;
1048 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
1050 pts
= &hash_ident
[h
];
1055 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1057 pts
= &(ts
->hash_next
);
1060 if (tok_ident
>= SYM_FIRST_ANOM
)
1061 error("memory full");
1063 /* expand token table if needed */
1064 i
= tok_ident
- TOK_IDENT
;
1065 if ((i
% TOK_ALLOC_INCR
) == 0) {
1066 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1068 error("memory full");
1069 table_ident
= ptable
;
1072 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1073 table_ident
[i
] = ts
;
1074 ts
->tok
= tok_ident
++;
1076 ts
->hash_next
= NULL
;
1077 memcpy(ts
->str
, str
, len
+ 1);
1082 /* CString handling */
1084 static void cstr_realloc(CString
*cstr
, int new_size
)
1089 size
= cstr
->size_allocated
;
1091 size
= 8; /* no need to allocate a too small first string */
1092 while (size
< new_size
)
1094 data
= tcc_realloc(cstr
->data_allocated
, size
);
1096 error("memory full");
1097 cstr
->data_allocated
= data
;
1098 cstr
->size_allocated
= size
;
1103 static void cstr_ccat(CString
*cstr
, int ch
)
1106 size
= cstr
->size
+ 1;
1107 if (size
> cstr
->size_allocated
)
1108 cstr_realloc(cstr
, size
);
1109 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1113 static void cstr_cat(CString
*cstr
, const char *str
)
1125 /* add a wide char */
1126 static void cstr_wccat(CString
*cstr
, int ch
)
1129 size
= cstr
->size
+ sizeof(int);
1130 if (size
> cstr
->size_allocated
)
1131 cstr_realloc(cstr
, size
);
1132 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1136 static void cstr_new(CString
*cstr
)
1138 memset(cstr
, 0, sizeof(CString
));
1141 /* free string and reset it to NULL */
1142 static void cstr_free(CString
*cstr
)
1144 tcc_free(cstr
->data_allocated
);
1148 #define cstr_reset(cstr) cstr_free(cstr)
1150 /* XXX: unicode ? */
1151 static void add_char(CString
*cstr
, int c
)
1153 if (c
== '\'' || c
== '\"' || c
== '\\') {
1154 /* XXX: could be more precise if char or string */
1155 cstr_ccat(cstr
, '\\');
1157 if (c
>= 32 && c
<= 126) {
1160 cstr_ccat(cstr
, '\\');
1162 cstr_ccat(cstr
, 'n');
1164 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1165 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1166 cstr_ccat(cstr
, '0' + (c
& 7));
1171 /* XXX: buffer overflow */
1172 /* XXX: float tokens */
1173 char *get_tok_str(int v
, CValue
*cv
)
1175 static char buf
[STRING_MAX_SIZE
+ 1];
1176 static CString cstr_buf
;
1182 /* NOTE: to go faster, we give a fixed buffer for small strings */
1183 cstr_reset(&cstr_buf
);
1184 cstr_buf
.data
= buf
;
1185 cstr_buf
.size_allocated
= sizeof(buf
);
1191 /* XXX: not exact */
1192 sprintf(p
, "%u", cv
->ui
);
1196 cstr_ccat(&cstr_buf
, '\'');
1197 add_char(&cstr_buf
, cv
->i
);
1198 cstr_ccat(&cstr_buf
, '\'');
1199 cstr_ccat(&cstr_buf
, '\0');
1204 cstr_ccat(&cstr_buf
, '\"');
1206 len
= cstr
->size
- 1;
1208 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1210 len
= (cstr
->size
/ sizeof(int)) - 1;
1212 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1214 cstr_ccat(&cstr_buf
, '\"');
1215 cstr_ccat(&cstr_buf
, '\0');
1224 return strcpy(p
, "<<=");
1226 return strcpy(p
, ">>=");
1228 if (v
< TOK_IDENT
) {
1229 /* search in two bytes table */
1243 } else if (v
< tok_ident
) {
1244 return table_ident
[v
- TOK_IDENT
]->str
;
1245 } else if (v
>= SYM_FIRST_ANOM
) {
1246 /* special name for anonymous symbol */
1247 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1249 /* should never happen */
1254 return cstr_buf
.data
;
1257 /* push, without hashing */
1258 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1261 s
= tcc_malloc(sizeof(Sym
));
1272 /* find a symbol and return its associated structure. 's' is the top
1273 of the symbol stack */
1274 Sym
*sym_find2(Sym
*s
, int v
)
1284 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1286 /* find a symbol and return its associated structure. 'st' is the
1288 Sym
*sym_find1(SymStack
*st
, int v
)
1292 s
= st
->hash
[HASH_SYM(v
)];
1301 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1304 s
= sym_push2(&st
->top
, v
, t
, c
);
1305 /* add in hash table */
1307 ps
= &st
->hash
[HASH_SYM(v
)];
1314 /* find a symbol in the right symbol space */
1315 Sym
*sym_find(int v
)
1318 s
= sym_find1(&local_stack
, v
);
1320 s
= sym_find1(&global_stack
, v
);
1324 /* push a given symbol on the symbol stack */
1325 Sym
*sym_push(int v
, int t
, int r
, int c
)
1328 if (local_stack
.top
)
1329 s
= sym_push1(&local_stack
, v
, t
, c
);
1331 s
= sym_push1(&global_stack
, v
, t
, c
);
1336 /* pop symbols until top reaches 'b' */
1337 void sym_pop(SymStack
*st
, Sym
*b
)
1344 /* free hash table entry, except if symbol was freed (only
1345 used for #undef symbols) */
1347 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1354 /* undefined a hashed symbol (used for #undef). Its name is set to
1356 void sym_undef(SymStack
*st
, Sym
*s
)
1359 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1360 while (*ss
!= NULL
) {
1363 ss
= &(*ss
)->hash_next
;
1371 BufferedFile
*tcc_open(const char *filename
)
1376 fd
= open(filename
, O_RDONLY
);
1379 bf
= tcc_malloc(sizeof(BufferedFile
));
1385 bf
->buf_ptr
= bf
->buffer
;
1386 bf
->buf_end
= bf
->buffer
;
1387 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1388 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1390 // printf("opening '%s'\n", filename);
1394 void tcc_close(BufferedFile
*bf
)
1396 total_lines
+= bf
->line_num
;
1401 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1402 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1404 /* fill input buffer and return next char */
1405 int tcc_getc_slow(BufferedFile
*bf
)
1408 /* only tries to read if really end of buffer */
1409 if (bf
->buf_ptr
>= bf
->buf_end
) {
1411 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1418 bf
->buf_ptr
= bf
->buffer
;
1419 bf
->buf_end
= bf
->buffer
+ len
;
1420 *bf
->buf_end
= CH_EOB
;
1422 if (bf
->buf_ptr
< bf
->buf_end
) {
1423 return *bf
->buf_ptr
++;
1425 bf
->buf_ptr
= bf
->buf_end
;
1430 /* no need to put that inline */
1431 void handle_eob(void)
1434 ch1
= tcc_getc_slow(file
);
1438 if (include_stack_ptr
== include_stack
)
1440 /* add end of include file debug info */
1442 put_stabd(N_EINCL
, 0, 0);
1444 /* pop include stack */
1446 include_stack_ptr
--;
1447 file
= *include_stack_ptr
;
1451 /* read next char from current input file */
1452 static inline void inp(void)
1454 ch1
= TCC_GETC(file
);
1455 /* end of buffer/file handling */
1460 // printf("ch1=%c 0x%x\n", ch1, ch1);
1463 /* handle '\\n' and '\\r\n' */
1464 static void handle_stray(void)
1469 } else if (ch1
== '\r') {
1472 error("invalid character after '\\'");
1479 } while (ch
== '\\');
1482 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1484 static inline void minp(void)
1493 /* same as minp, but also skip comments */
1494 static void cinp(void)
1501 /* single line C++ comments */
1503 while (ch1
!= '\n' && ch1
!= CH_EOF
)
1505 ch
= ' '; /* return space */
1506 } else if (ch1
== '*') {
1509 while (ch1
!= CH_EOF
) {
1512 if (c
== '*' && ch1
== '/') {
1514 ch
= ' '; /* return space */
1526 /* space exlcuding newline */
1527 static inline int is_space(int ch
)
1529 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1532 static inline void skip_spaces(void)
1534 while (is_space(ch
))
1538 /* skip block of text until #else, #elif or #endif. skip also pairs of
1540 void preprocess_skip(void)
1545 while (ch
!= '\n') {
1556 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1558 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1560 else if (tok
== TOK_ENDIF
)
1566 /* ParseState handling */
1568 /* XXX: currently, no include file info is stored. Thus, we cannot display
1569 accurate messages if the function or data definition spans multiple
1572 /* save current parse state in 's' */
1573 void save_parse_state(ParseState
*s
)
1575 s
->line_num
= file
->line_num
;
1576 s
->macro_ptr
= macro_ptr
;
1581 /* restore parse state from 's' */
1582 void restore_parse_state(ParseState
*s
)
1584 file
->line_num
= s
->line_num
;
1585 macro_ptr
= s
->macro_ptr
;
1590 /* return the number of additionnal 'ints' necessary to store the
1592 static inline int tok_ext_size(int t
)
1610 return LDOUBLE_SIZE
/ 4;
1616 /* token string handling */
1618 static inline void tok_str_new(TokenString
*s
)
1622 s
->last_line_num
= -1;
1625 static void tok_str_free(int *str
)
1636 if (t
== TOK_STR
|| t
== TOK_LSTR
) {
1637 /* XXX: use a macro to be portable on 64 bit ? */
1638 cstr
= (CString
*)(*p
++);
1642 p
+= tok_ext_size(t
);
1648 static void tok_str_add(TokenString
*s
, int t
)
1654 if ((len
& 63) == 0) {
1655 str
= tcc_realloc(str
, (len
+ 64) * sizeof(int));
1664 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1667 CString
*cstr
, *cstr1
;
1671 if (t
== TOK_STR
|| t
== TOK_LSTR
) {
1672 /* special case: need to duplicate string */
1674 cstr
= tcc_malloc(sizeof(CString
));
1677 cstr
->size_allocated
= size
;
1678 cstr
->data_allocated
= tcc_malloc(size
);
1679 cstr
->data
= cstr
->data_allocated
;
1680 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1682 tok_str_add(s
, cv1
.tab
[0]);
1684 n
= tok_ext_size(t
);
1686 tok_str_add(s
, cv
->tab
[i
]);
1690 /* add the current parse token in token string 's' */
1691 static void tok_str_add_tok(TokenString
*s
)
1695 /* save line number info */
1696 if (file
->line_num
!= s
->last_line_num
) {
1697 s
->last_line_num
= file
->line_num
;
1698 cval
.i
= s
->last_line_num
;
1699 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1701 tok_str_add2(s
, tok
, &tokc
);
1704 /* get a token from an integer array and increment pointer accordingly */
1705 static int tok_get(int **tok_str
, CValue
*cv
)
1711 n
= tok_ext_size(t
);
1718 /* eval an expression for #if/#elif */
1719 int expr_preprocess(void)
1725 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1726 next(); /* do macro subst */
1727 if (tok
== TOK_DEFINED
) {
1732 c
= sym_find1(&define_stack
, tok
) != 0;
1737 } else if (tok
>= TOK_IDENT
) {
1738 /* if undefined macro */
1742 tok_str_add_tok(&str
);
1744 tok_str_add(&str
, -1); /* simulate end of file */
1745 tok_str_add(&str
, 0);
1746 /* now evaluate C constant expression */
1747 macro_ptr
= str
.str
;
1751 tok_str_free(str
.str
);
1755 #if defined(DEBUG) || defined(PP_DEBUG)
1756 void tok_print(int *str
)
1762 t
= tok_get(&str
, &cval
);
1765 printf(" %s", get_tok_str(t
, &cval
));
1771 /* parse after #define */
1772 void parse_define(void)
1774 Sym
*s
, *first
, **ps
;
1775 int v
, t
, varg
, is_vaargs
;
1779 /* XXX: should check if same macro (ANSI) */
1782 /* '(' must be just after macro definition for MACRO_FUNC */
1787 while (tok
!= ')') {
1791 if (varg
== TOK_DOTS
) {
1792 varg
= TOK___VA_ARGS__
;
1794 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1798 if (varg
< TOK_IDENT
)
1799 error("badly punctuated parameter list");
1800 s
= sym_push1(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1812 if (ch
== '\n' || ch
== CH_EOF
)
1815 tok_str_add2(&str
, tok
, &tokc
);
1817 tok_str_add(&str
, 0);
1819 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1822 s
= sym_push1(&define_stack
, v
, t
, (int)str
.str
);
1826 void preprocess(void)
1829 char buf
[1024], *q
, *p
;
1834 return_linefeed
= 1; /* linefeed will be returned as a token */
1838 if (tok
== TOK_DEFINE
) {
1841 } else if (tok
== TOK_UNDEF
) {
1843 s
= sym_find1(&define_stack
, tok
);
1844 /* undefine symbol by putting an invalid name */
1846 sym_undef(&define_stack
, s
);
1847 } else if (tok
== TOK_INCLUDE
) {
1852 } else if (ch
== '\"') {
1857 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
1858 if ((q
- buf
) < sizeof(buf
) - 1)
1863 /* eat all spaces and comments after include */
1864 /* XXX: slightly incorrect */
1865 while (ch1
!= '\n' && ch1
!= CH_EOF
)
1868 /* computed #include : either we have only strings or
1869 we have anything enclosed in '<>' */
1872 if (tok
== TOK_STR
) {
1873 while (tok
!= TOK_LINEFEED
) {
1874 if (tok
!= TOK_STR
) {
1876 error("'#include' expects \"FILENAME\" or <FILENAME>");
1878 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
1884 while (tok
!= TOK_LINEFEED
) {
1885 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
1889 /* check syntax and remove '<>' */
1890 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
1891 goto include_syntax
;
1892 memmove(buf
, buf
+ 1, len
- 2);
1893 buf
[len
- 2] = '\0';
1898 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1899 error("memory full");
1901 /* first search in current dir if "header.h" */
1903 p
= strrchr(file
->filename
, '/');
1905 size
= p
+ 1 - file
->filename
;
1906 if (size
> sizeof(buf1
) - 1)
1907 size
= sizeof(buf1
) - 1;
1908 memcpy(buf1
, file
->filename
, size
);
1910 pstrcat(buf1
, sizeof(buf1
), buf
);
1915 /* now search in all the include paths */
1916 n
= nb_include_paths
+ nb_sysinclude_paths
;
1917 for(i
= 0; i
< n
; i
++) {
1919 if (i
< nb_include_paths
)
1920 path
= include_paths
[i
];
1922 path
= sysinclude_paths
[i
- nb_include_paths
];
1923 pstrcpy(buf1
, sizeof(buf1
), path
);
1924 pstrcat(buf1
, sizeof(buf1
), "/");
1925 pstrcat(buf1
, sizeof(buf1
), buf
);
1930 error("include file '%s' not found", buf
);
1933 /* push current file in stack */
1934 /* XXX: fix current line init */
1935 *include_stack_ptr
++ = file
;
1937 /* add include file debug info */
1939 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
1943 } else if (tok
== TOK_IFNDEF
) {
1946 } else if (tok
== TOK_IF
) {
1947 c
= expr_preprocess();
1949 } else if (tok
== TOK_IFDEF
) {
1953 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1955 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1956 error("memory full");
1957 *ifdef_stack_ptr
++ = c
;
1959 } else if (tok
== TOK_ELSE
) {
1960 if (ifdef_stack_ptr
== ifdef_stack
)
1961 error("#else without matching #if");
1962 if (ifdef_stack_ptr
[-1] & 2)
1963 error("#else after #else");
1964 c
= (ifdef_stack_ptr
[-1] ^= 3);
1966 } else if (tok
== TOK_ELIF
) {
1967 if (ifdef_stack_ptr
== ifdef_stack
)
1968 error("#elif without matching #if");
1969 c
= ifdef_stack_ptr
[-1];
1971 error("#elif after #else");
1972 /* last #if/#elif expression was true: we skip */
1975 c
= expr_preprocess();
1976 ifdef_stack_ptr
[-1] = c
;
1983 } else if (tok
== TOK_ENDIF
) {
1984 if (ifdef_stack_ptr
== ifdef_stack
)
1985 error("#endif without matching #if");
1987 } else if (tok
== TOK_LINE
) {
1990 if (tok
!= TOK_CINT
)
1994 if (tok
!= TOK_LINEFEED
) {
1997 pstrcpy(file
->filename
, sizeof(file
->filename
),
1998 (char *)tokc
.cstr
->data
);
2000 /* NOTE: we do it there to avoid problems with linefeed */
2001 file
->line_num
= line_num
;
2002 } else if (tok
== TOK_ERROR
) {
2005 /* ignore other preprocess commands or #! for C scripts */
2006 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
)
2009 return_linefeed
= 0;
2012 /* read a number in base b */
2013 static int getn(int b
)
2018 if (ch
>= 'a' && ch
<= 'f')
2020 else if (ch
>= 'A' && ch
<= 'F')
2026 if (t
< 0 || t
>= b
)
2034 /* read a character for string or char constant and eval escape codes */
2035 static int getq(void)
2043 /* at most three octal digits */
2047 c
= c
* 8 + ch
- '0';
2050 c
= c
* 8 + ch
- '0';
2055 } else if (ch
== 'x') {
2073 else if (ch
== 'e' && gnu_ext
)
2075 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
2078 error("invalid escaped char");
2081 } else if (c
== '\r' && ch
== '\n') {
2088 /* we use 64 bit numbers */
2091 /* bn = (bn << shift) | or_val */
2092 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2096 for(i
=0;i
<BN_SIZE
;i
++) {
2098 bn
[i
] = (v
<< shift
) | or_val
;
2099 or_val
= v
>> (32 - shift
);
2103 void bn_zero(unsigned int *bn
)
2106 for(i
=0;i
<BN_SIZE
;i
++) {
2111 void parse_number(void)
2113 int b
, t
, shift
, frac_bits
, s
, exp_val
;
2115 unsigned int bn
[BN_SIZE
];
2125 /* special dot handling */
2126 if (ch
>= '0' && ch
<= '9') {
2127 goto float_frac_parse
;
2128 } else if (ch
== '.') {
2139 } else if (t
== '0') {
2140 if (ch
== 'x' || ch
== 'X') {
2144 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2150 /* parse all digits. cannot check octal numbers at this stage
2151 because of floating point constants */
2153 if (ch
>= 'a' && ch
<= 'f')
2155 else if (ch
>= 'A' && ch
<= 'F')
2163 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2165 error("number too long");
2171 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2172 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2174 /* NOTE: strtox should support that for hexa numbers, but
2175 non ISOC99 libcs do not support it, so we prefer to do
2177 /* hexadecimal or binary floats */
2178 /* XXX: handle overflows */
2190 } else if (t
>= 'a') {
2192 } else if (t
>= 'A') {
2197 bn_lshift(bn
, shift
, t
);
2204 if (t
>= 'a' && t
<= 'f') {
2206 } else if (t
>= 'A' && t
<= 'F') {
2208 } else if (t
>= '0' && t
<= '9') {
2214 error("invalid digit");
2215 bn_lshift(bn
, shift
, t
);
2220 if (ch
!= 'p' && ch
!= 'P')
2221 error("exponent expected");
2227 } else if (ch
== '-') {
2231 if (ch
< '0' || ch
> '9')
2232 error("exponent digits expected");
2233 while (ch
>= '0' && ch
<= '9') {
2234 exp_val
= exp_val
* 10 + ch
- '0';
2237 exp_val
= exp_val
* s
;
2239 /* now we can generate the number */
2240 /* XXX: should patch directly float number */
2241 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
2242 d
= ldexp(d
, exp_val
- frac_bits
);
2247 /* float : should handle overflow */
2249 } else if (t
== 'L') {
2252 /* XXX: not large enough */
2253 tokc
.ld
= (long double)d
;
2259 /* decimal floats */
2261 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2266 while (ch
>= '0' && ch
<= '9') {
2267 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2273 if (ch
== 'e' || ch
== 'E') {
2274 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2278 if (ch
== '-' || ch
== '+') {
2279 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2284 if (ch
< '0' || ch
> '9')
2285 error("exponent digits expected");
2286 while (ch
>= '0' && ch
<= '9') {
2287 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2299 tokc
.f
= strtof(token_buf
, NULL
);
2300 } else if (t
== 'L') {
2303 tokc
.ld
= strtold(token_buf
, NULL
);
2306 tokc
.d
= strtod(token_buf
, NULL
);
2310 unsigned long long n
, n1
;
2313 /* integer number */
2316 if (b
== 10 && *q
== '0') {
2323 /* no need for checks except for base 10 / 8 errors */
2326 } else if (t
>= 'a') {
2328 } else if (t
>= 'A') {
2333 error("invalid digit");
2337 /* detect overflow */
2339 error("integer constant overflow");
2342 /* XXX: not exactly ANSI compliant */
2343 if ((n
& 0xffffffff00000000LL
) != 0) {
2348 } else if (n
> 0x7fffffff) {
2358 error("three 'l' in integer constant");
2361 if (tok
== TOK_CINT
)
2363 else if (tok
== TOK_CUINT
)
2367 } else if (t
== 'U') {
2368 if (tok
== TOK_CINT
)
2370 else if (tok
== TOK_CLLONG
)
2377 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2385 /* return next token without macro substitution */
2386 void next_nomacro1(void)
2394 while (ch
== '\n') {
2395 /* during preprocessor parsing, '\n' is a token */
2396 if (return_linefeed
) {
2403 /* preprocessor command if # at start of line after
2426 while (isid(ch
) || isnum(ch
)) {
2427 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2428 error("ident too long");
2433 ts
= tok_alloc(token_buf
, q
- token_buf
);
2435 } else if (isnum(ch
) || ch
== '.') {
2437 } else if (ch
== '\'') {
2442 /* this cast is needed if >= 128 */
2443 if (tok
== TOK_CCHAR
)
2449 } else if (ch
== '\"') {
2453 cstr_reset(&tokcstr
);
2454 while (ch
!= '\"') {
2457 error("unterminated string");
2459 cstr_ccat(&tokcstr
, b
);
2461 cstr_wccat(&tokcstr
, b
);
2464 cstr_ccat(&tokcstr
, '\0');
2466 cstr_wccat(&tokcstr
, '\0');
2467 tokc
.cstr
= &tokcstr
;
2475 if (*q
== tok
&& q
[1] == ch
) {
2478 /* three chars tests */
2479 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2484 } else if (tok
== TOK_DOTS
) {
2486 error("parse error");
2493 /* single char substitutions */
2496 else if (tok
== '>')
2501 /* return next token without macro substitution. Can read input from
2509 tok
= tok_get(¯o_ptr
, &tokc
);
2510 if (tok
== TOK_LINENUM
) {
2511 file
->line_num
= tokc
.i
;
2520 /* substitute args in macro_str and return allocated string */
2521 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2523 int *st
, last_tok
, t
, notfirst
;
2532 t
= tok_get(¯o_str
, &cval
);
2537 t
= tok_get(¯o_str
, &cval
);
2540 s
= sym_find2(args
, t
);
2547 cstr_ccat(&cstr
, ' ');
2548 t
= tok_get(&st
, &cval
);
2549 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
2552 cstr_ccat(&cstr
, '\0');
2554 printf("stringize: %s\n", (char *)cstr
.data
);
2558 tok_str_add2(&str
, TOK_STR
, &cval
);
2561 tok_str_add2(&str
, t
, &cval
);
2563 } else if (t
>= TOK_IDENT
) {
2564 s
= sym_find2(args
, t
);
2567 /* if '##' is present before or after, no arg substitution */
2568 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2569 /* special case for var arg macros : ## eats the
2570 ',' if empty VA_ARGS riable. */
2571 /* XXX: test of the ',' is not 100%
2572 reliable. should fix it to avoid security
2574 if (gnu_ext
&& s
->t
&& *st
== 0 &&
2575 last_tok
== TOK_TWOSHARPS
&&
2576 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
2577 /* suppress ',' '##' */
2582 t1
= tok_get(&st
, &cval
);
2585 tok_str_add2(&str
, t1
, &cval
);
2589 macro_subst(&str
, nested_list
, st
);
2592 tok_str_add(&str
, t
);
2595 tok_str_add2(&str
, t
, &cval
);
2599 tok_str_add(&str
, 0);
2603 /* handle the '##' operator */
2604 int *macro_twosharps(int *macro_str
)
2611 TokenString macro_str1
;
2613 tok_str_new(¯o_str1
);
2619 while (*macro_ptr
== TOK_TWOSHARPS
) {
2621 macro_ptr1
= macro_ptr
;
2624 t
= tok_get(¯o_ptr
, &cval
);
2625 /* XXX: we handle only most common cases:
2626 ident + ident or ident + number */
2627 if (tok
>= TOK_IDENT
&&
2628 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
2629 p
= get_tok_str(tok
, &tokc
);
2630 pstrcpy(token_buf
, sizeof(token_buf
), p
);
2631 p
= get_tok_str(t
, &cval
);
2632 pstrcat(token_buf
, sizeof(token_buf
), p
);
2633 ts
= tok_alloc(token_buf
, 0);
2634 tok
= ts
->tok
; /* modify current token */
2636 /* cannot merge tokens: skip '##' */
2637 macro_ptr
= macro_ptr1
;
2642 tok_str_add2(¯o_str1
, tok
, &tokc
);
2644 tok_str_add(¯o_str1
, 0);
2645 return macro_str1
.str
;
2648 /* do macro substitution of macro_str and add result to
2649 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2650 substituted. 'nested_list' is the list of all macros we got inside
2651 to avoid recursing. */
2652 void macro_subst(TokenString
*tok_str
,
2653 Sym
**nested_list
, int *macro_str
)
2655 Sym
*s
, *args
, *sa
, *sa1
;
2656 int parlevel
, *mstr
, t
, *saved_macro_ptr
;
2657 int mstr_allocated
, *macro_str1
;
2663 saved_macro_ptr
= macro_ptr
;
2664 macro_ptr
= macro_str
;
2667 /* first scan for '##' operator handling */
2668 macro_str1
= macro_twosharps(macro_str
);
2669 macro_ptr
= macro_str1
;
2676 if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
2677 /* if symbol is a macro, prepare substitution */
2678 /* if nested substitution, do nothing */
2679 if (sym_find2(*nested_list
, tok
))
2682 /* special macros */
2683 if (tok
== TOK___LINE__
) {
2684 cval
.i
= file
->line_num
;
2685 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
2686 } else if (tok
== TOK___FILE__
) {
2687 cstrval
= file
->filename
;
2689 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2690 } else if (tok
== TOK___DATE__
) {
2691 cstrval
= "Jan 1 2002";
2693 } else if (tok
== TOK___TIME__
) {
2694 cstrval
= "00:00:00";
2696 } else if (tok
== TOK___FUNCTION__
) {
2700 cstr_cat(&cstr
, cstrval
);
2701 cstr_ccat(&cstr
, '\0');
2703 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2708 if (s
->t
== MACRO_FUNC
) {
2709 /* NOTE: we do not use next_nomacro to avoid eating the
2710 next token. XXX: find better solution */
2714 while (is_space(ch
) || ch
== '\n')
2718 if (t
!= '(') /* no macro subst */
2721 /* argument macro */
2726 /* NOTE: empty args are allowed, except if no args */
2728 /* handle '()' case */
2729 if (!args
&& tok
== ')')
2732 error("macro '%s' used with too many args",
2733 get_tok_str(s
->v
, 0));
2736 /* NOTE: non zero sa->t indicates VA_ARGS */
2737 while ((parlevel
> 0 ||
2739 (tok
!= ',' || sa
->t
))) &&
2743 else if (tok
== ')')
2745 tok_str_add2(&str
, tok
, &tokc
);
2748 tok_str_add(&str
, 0);
2749 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->t
, (int)str
.str
);
2752 /* special case for gcc var args: add an empty
2753 var arg argument if it is omitted */
2754 if (sa
&& sa
->t
&& gnu_ext
)
2764 error("macro '%s' used with too few args",
2765 get_tok_str(s
->v
, 0));
2768 /* now subst each arg */
2769 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2774 tok_str_free((int *)sa
->c
);
2780 sym_push2(nested_list
, s
->v
, 0, 0);
2781 macro_subst(tok_str
, nested_list
, mstr
);
2782 /* pop nested defined symbol */
2784 *nested_list
= sa1
->prev
;
2791 /* no need to add if reading input stream */
2794 tok_str_add2(tok_str
, tok
, &tokc
);
2796 /* only replace one macro while parsing input stream */
2800 macro_ptr
= saved_macro_ptr
;
2802 tok_str_free(macro_str1
);
2805 /* return next token with macro substitution */
2811 /* special 'ungettok' case for label parsing */
2819 /* if not reading from macro substituted string, then try
2821 /* XXX: optimize non macro case */
2824 macro_subst(&str
, &nested_list
, NULL
);
2826 tok_str_add(&str
, 0);
2827 macro_ptr
= str
.str
;
2828 macro_ptr_allocated
= str
.str
;
2836 /* end of macro string: free it */
2837 tok_str_free(macro_ptr_allocated
);
2844 printf("token = %s\n", get_tok_str(tok
, &tokc
));
2848 void swap(int *p
, int *q
)
2856 void vsetc(int t
, int r
, CValue
*vc
)
2858 if (vtop
>= vstack
+ VSTACK_SIZE
)
2859 error("memory full");
2860 /* cannot let cpu flags if other instruction are generated */
2861 /* XXX: VT_JMP test too ? */
2862 if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
2867 vtop
->r2
= VT_CONST
;
2871 /* push integer constant */
2876 vsetc(VT_INT
, VT_CONST
, &cval
);
2879 /* Return a static symbol pointing to a section */
2880 static Sym
*get_sym_ref(int t
, Section
*sec
,
2881 unsigned long offset
, unsigned long size
)
2887 sym
= sym_push1(&global_stack
, v
, t
| VT_STATIC
, 0);
2888 sym
->r
= VT_CONST
| VT_SYM
;
2889 put_extern_sym(sym
, sec
, offset
, size
);
2893 /* push a reference to a section offset by adding a dummy symbol */
2894 void vpush_ref(int t
, Section
*sec
, unsigned long offset
, unsigned long size
)
2898 cval
.sym
= get_sym_ref(t
, sec
, offset
, size
);
2899 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2902 /* push a reference to global symbol v */
2903 void vpush_sym(int t
, int v
)
2908 sym
= external_sym(v
, t
, 0);
2910 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2913 void vset(int t
, int r
, int v
)
2930 void vpushv(SValue
*v
)
2932 if (vtop
>= vstack
+ VSTACK_SIZE
)
2933 error("memory full");
2943 /* save r to the memory stack, and mark it as being free */
2944 void save_reg(int r
)
2946 int l
, saved
, t
, size
, align
;
2949 /* modify all stack values */
2952 for(p
=vstack
;p
<=vtop
;p
++) {
2953 if ((p
->r
& VT_VALMASK
) == r
||
2954 (p
->r2
& VT_VALMASK
) == r
) {
2955 /* must save value on stack if not already done */
2957 /* store register in the stack */
2959 if ((p
->r
& VT_LVAL
) ||
2960 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
2962 size
= type_size(t
, &align
);
2963 loc
= (loc
- size
) & -align
;
2965 sv
.r
= VT_LOCAL
| VT_LVAL
;
2968 #ifdef TCC_TARGET_I386
2969 /* x86 specific: need to pop fp register ST0 if saved */
2971 o(0xd9dd); /* fstp %st(1) */
2974 /* special long long case */
2975 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2982 /* mark that stack entry as being saved on the stack */
2983 if (p
->r
& VT_LVAL
) {
2984 /* also suppress the bounded flag because the
2985 relocation address of the function was stored in
2987 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
2989 p
->r
= lvalue_type(p
->t
) | VT_LOCAL
;
2997 /* find a free register of class 'rc'. If none, save one register */
3003 /* find a free register */
3004 for(r
=0;r
<NB_REGS
;r
++) {
3005 if (reg_classes
[r
] & rc
) {
3006 for(p
=vstack
;p
<=vtop
;p
++) {
3007 if ((p
->r
& VT_VALMASK
) == r
||
3008 (p
->r2
& VT_VALMASK
) == r
)
3016 /* no register left : free the first one on the stack (VERY
3017 IMPORTANT to start from the bottom to ensure that we don't
3018 spill registers used in gen_opi()) */
3019 for(p
=vstack
;p
<=vtop
;p
++) {
3020 r
= p
->r
& VT_VALMASK
;
3021 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
3029 /* save registers up to (vtop - n) stack entry */
3030 void save_regs(int n
)
3035 for(p
= vstack
;p
<= p1
; p
++) {
3036 r
= p
->r
& VT_VALMASK
;
3043 /* move register 's' to 'r', and flush previous value of r to memory
3045 void move_reg(int r
, int s
)
3058 /* get address of vtop (vtop MUST BE an lvalue) */
3061 vtop
->r
&= ~VT_LVAL
;
3062 /* tricky: if saved lvalue, then we can go back to lvalue */
3063 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
3064 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
3067 #ifdef CONFIG_TCC_BCHECK
3068 /* generate lvalue bound code */
3073 vtop
->r
&= ~VT_MUSTBOUND
;
3074 /* if lvalue, then use checking code before dereferencing */
3075 if (vtop
->r
& VT_LVAL
) {
3076 /* if not VT_BOUNDED value, then make one */
3077 if (!(vtop
->r
& VT_BOUNDED
)) {
3078 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
3079 /* must save type because we must set it to int to get pointer */
3084 gen_bounded_ptr_add();
3085 vtop
->r
|= lval_type
;
3088 /* then check for dereferencing */
3089 gen_bounded_ptr_deref();
3094 /* store vtop a register belonging to class 'rc'. lvalues are
3095 converted to values. Cannot be used if cannot be converted to
3096 register value (such as structures). */
3099 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
3100 unsigned long long ll
;
3102 /* NOTE: get_reg can modify vstack[] */
3103 if (vtop
->t
& VT_BITFIELD
) {
3104 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
3105 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3106 /* remove bit field info to avoid loops */
3107 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3108 /* generate shifts */
3109 vpushi(32 - (bit_pos
+ bit_size
));
3111 vpushi(32 - bit_size
);
3112 /* NOTE: transformed to SHR if unsigned */
3116 if (is_float(vtop
->t
) &&
3117 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3120 unsigned long offset
;
3122 /* XXX: unify with initializers handling ? */
3123 /* CPUs usually cannot use float constants, so we store them
3124 generically in data segment */
3125 size
= type_size(vtop
->t
, &align
);
3126 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
3127 data_section
->data_offset
= offset
;
3128 /* XXX: not portable yet */
3129 ptr
= section_ptr_add(data_section
, size
);
3132 ptr
[i
] = vtop
->c
.tab
[i
];
3133 sym
= get_sym_ref(vtop
->t
, data_section
, offset
, size
<< 2);
3134 vtop
->r
|= VT_LVAL
| VT_SYM
;
3137 #ifdef CONFIG_TCC_BCHECK
3138 if (vtop
->r
& VT_MUSTBOUND
)
3142 r
= vtop
->r
& VT_VALMASK
;
3143 /* need to reload if:
3145 - lvalue (need to dereference pointer)
3146 - already a register, but not in the right class */
3147 if (r
>= VT_CONST
||
3148 (vtop
->r
& VT_LVAL
) ||
3149 !(reg_classes
[r
] & rc
) ||
3150 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
3151 !(reg_classes
[vtop
->r2
] & rc
))) {
3153 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
3154 /* two register type load : expand to two words
3156 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3159 vtop
->c
.ui
= ll
; /* first word */
3161 vtop
->r
= r
; /* save register value */
3162 vpushi(ll
>> 32); /* second word */
3163 } else if (r
>= VT_CONST
||
3164 (vtop
->r
& VT_LVAL
)) {
3165 /* load from memory */
3168 vtop
[-1].r
= r
; /* save register value */
3169 /* increment pointer to get second word */
3176 /* move registers */
3179 vtop
[-1].r
= r
; /* save register value */
3180 vtop
->r
= vtop
[-1].r2
;
3182 /* allocate second register */
3189 /* write second register */
3191 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
3193 /* lvalue of scalar type : need to use lvalue type
3194 because of possible cast */
3197 /* compute memory access type */
3198 if (vtop
->r
& VT_LVAL_BYTE
)
3200 else if (vtop
->r
& VT_LVAL_SHORT
)
3202 if (vtop
->r
& VT_LVAL_UNSIGNED
)
3206 /* restore wanted type */
3209 /* one register type load */
3218 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3219 void gv2(int rc1
, int rc2
)
3221 /* generate more generic register first */
3227 /* test if reload is needed for first register */
3228 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
3238 /* test if reload is needed for first register */
3239 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
3245 /* expand long long on stack in two int registers */
3250 u
= vtop
->t
& VT_UNSIGNED
;
3253 vtop
[0].r
= vtop
[-1].r2
;
3254 vtop
[0].r2
= VT_CONST
;
3255 vtop
[-1].r2
= VT_CONST
;
3256 vtop
[0].t
= VT_INT
| u
;
3257 vtop
[-1].t
= VT_INT
| u
;
3260 /* build a long long from two ints */
3263 gv2(RC_INT
, RC_INT
);
3264 vtop
[-1].r2
= vtop
[0].r
;
3269 /* rotate n first stack elements to the bottom */
3276 for(i
=-n
+1;i
!=0;i
++)
3277 vtop
[i
] = vtop
[i
+1];
3281 /* pop stack value */
3285 v
= vtop
->r
& VT_VALMASK
;
3286 #ifdef TCC_TARGET_I386
3287 /* for x86, we need to pop the FP stack */
3289 o(0xd9dd); /* fstp %st(1) */
3292 if (v
== VT_JMP
|| v
== VT_JMPI
) {
3293 /* need to put correct jump if && or || without test */
3299 /* convert stack entry to register and duplicate its value in another
3307 if ((t
& VT_BTYPE
) == VT_LLONG
) {
3314 /* stack: H L L1 H1 */
3322 /* duplicate value */
3333 load(r1
, &sv
); /* move r to r1 */
3335 /* duplicates value */
3340 /* generate CPU independent (unsigned) long long operations */
3341 void gen_opl(int op
)
3343 int t
, a
, b
, op1
, c
, i
;
3351 func
= TOK___divdi3
;
3354 func
= TOK___udivdi3
;
3357 func
= TOK___moddi3
;
3360 func
= TOK___umoddi3
;
3362 /* call generic long long function */
3363 gfunc_start(&gf
, FUNC_CDECL
);
3366 vpush_sym(func_old_type
, func
);
3370 vtop
->r2
= REG_LRET
;
3383 /* stack: L1 H1 L2 H2 */
3388 vtop
[-2] = vtop
[-3];
3391 /* stack: H1 H2 L1 L2 */
3397 /* stack: H1 H2 L1 L2 ML MH */
3400 /* stack: ML MH H1 H2 L1 L2 */
3404 /* stack: ML MH H1 L2 H2 L1 */
3409 /* stack: ML MH M1 M2 */
3412 } else if (op
== '+' || op
== '-') {
3413 /* XXX: add non carry method too (for MIPS or alpha) */
3419 /* stack: H1 H2 (L1 op L2) */
3422 gen_op(op1
+ 1); /* TOK_xxxC2 */
3425 /* stack: H1 H2 (L1 op L2) */
3428 /* stack: (L1 op L2) H1 H2 */
3430 /* stack: (L1 op L2) (H1 op H2) */
3438 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3443 /* stack: L H shift */
3445 /* constant: simpler */
3446 /* NOTE: all comments are for SHL. the other cases are
3447 done by swaping words */
3458 if (op
!= TOK_SAR
) {
3488 /* XXX: should provide a faster fallback on x86 ? */
3491 func
= TOK___sardi3
;
3494 func
= TOK___shrdi3
;
3497 func
= TOK___shldi3
;
3503 /* compare operations */
3509 /* stack: L1 H1 L2 H2 */
3511 vtop
[-1] = vtop
[-2];
3513 /* stack: L1 L2 H1 H2 */
3516 /* when values are equal, we need to compare low words. since
3517 the jump is inverted, we invert the test too. */
3520 else if (op1
== TOK_GT
)
3522 else if (op1
== TOK_ULT
)
3524 else if (op1
== TOK_UGT
)
3529 if (op1
!= TOK_NE
) {
3533 /* generate non equal test */
3534 /* XXX: NOT PORTABLE yet */
3538 #ifdef TCC_TARGET_I386
3539 b
= psym(0x850f, 0);
3541 error("not implemented");
3549 vset(VT_INT
, VT_JMPI
, a
);
3554 /* handle integer constant optimizations and various machine
3556 void gen_opic(int op
)
3563 /* currently, we cannot do computations with forward symbols */
3564 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3565 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3569 case '+': v1
->c
.i
+= fc
; break;
3570 case '-': v1
->c
.i
-= fc
; break;
3571 case '&': v1
->c
.i
&= fc
; break;
3572 case '^': v1
->c
.i
^= fc
; break;
3573 case '|': v1
->c
.i
|= fc
; break;
3574 case '*': v1
->c
.i
*= fc
; break;
3581 /* if division by zero, generate explicit division */
3584 error("division by zero in constant");
3588 default: v1
->c
.i
/= fc
; break;
3589 case '%': v1
->c
.i
%= fc
; break;
3590 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3591 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3594 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3595 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3596 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3598 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3599 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3600 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3601 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3602 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3603 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3604 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3605 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3606 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3607 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3609 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3610 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3616 /* if commutative ops, put c2 as constant */
3617 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3618 op
== '|' || op
== '*')) {
3623 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3626 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3627 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3633 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3634 /* try to use shifts instead of muls or divs */
3635 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3644 else if (op
== TOK_PDIV
)
3652 /* call low level op generator */
3658 /* generate a floating point operation with constant propagation */
3659 void gen_opif(int op
)
3667 /* currently, we cannot do computations with forward symbols */
3668 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3669 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3671 if (v1
->t
== VT_FLOAT
) {
3674 } else if (v1
->t
== VT_DOUBLE
) {
3682 /* NOTE: we only do constant propagation if finite number (not
3683 NaN or infinity) (ANSI spec) */
3684 if (!ieee_finite(f1
) || !ieee_finite(f2
))
3688 case '+': f1
+= f2
; break;
3689 case '-': f1
-= f2
; break;
3690 case '*': f1
*= f2
; break;
3694 error("division by zero in constant");
3699 /* XXX: also handles tests ? */
3703 /* XXX: overflow test ? */
3704 if (v1
->t
== VT_FLOAT
) {
3706 } else if (v1
->t
== VT_DOUBLE
) {
3719 int pointed_size(int t
)
3721 return type_size(pointed_type(t
), &t
);
3725 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3727 char buf1
[256], buf2
[256];
3731 if (!is_compatible_types(t1
, t2
)) {
3732 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3733 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3734 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3739 /* generic gen_op: handles types problems */
3742 int u
, t1
, t2
, bt1
, bt2
, t
;
3746 bt1
= t1
& VT_BTYPE
;
3747 bt2
= t2
& VT_BTYPE
;
3749 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3750 /* at least one operand is a pointer */
3751 /* relationnal op: must be both pointers */
3752 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3753 // check_pointer_types(vtop, vtop - 1);
3754 /* pointers are handled are unsigned */
3755 t
= VT_INT
| VT_UNSIGNED
;
3758 /* if both pointers, then it must be the '-' op */
3759 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3760 (t2
& VT_BTYPE
) == VT_PTR
) {
3762 error("cannot use pointers here");
3763 // check_pointer_types(vtop - 1, vtop);
3764 /* XXX: check that types are compatible */
3765 u
= pointed_size(t1
);
3767 /* set to integer type */
3772 /* exactly one pointer : must be '+' or '-'. */
3773 if (op
!= '-' && op
!= '+')
3774 error("cannot use pointers here");
3775 /* Put pointer as first operand */
3776 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3780 /* XXX: cast to int ? (long long case) */
3781 vpushi(pointed_size(vtop
[-1].t
));
3783 #ifdef CONFIG_TCC_BCHECK
3784 /* if evaluating constant expression, no code should be
3785 generated, so no bound check */
3786 if (do_bounds_check
&& !const_wanted
) {
3787 /* if bounded pointers, we generate a special code to
3794 gen_bounded_ptr_add();
3800 /* put again type if gen_opic() swaped operands */
3803 } else if (is_float(bt1
) || is_float(bt2
)) {
3804 /* compute bigger type and do implicit casts */
3805 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3807 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3812 /* floats can only be used for a few operations */
3813 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3814 (op
< TOK_ULT
|| op
> TOK_GT
))
3815 error("invalid operands for binary operation");
3817 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3818 /* cast to biggest op */
3820 /* convert to unsigned if it does not fit in a long long */
3821 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3822 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
3826 /* integer operations */
3828 /* convert to unsigned if it does not fit in an integer */
3829 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
3830 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3833 /* XXX: currently, some unsigned operations are explicit, so
3834 we modify them here */
3835 if (t
& VT_UNSIGNED
) {
3842 else if (op
== TOK_LT
)
3844 else if (op
== TOK_GT
)
3846 else if (op
== TOK_LE
)
3848 else if (op
== TOK_GE
)
3854 /* special case for shifts and long long: we keep the shift as
3856 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3862 else if ((t
& VT_BTYPE
) == VT_LLONG
)
3866 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3867 /* relationnal op: the result is an int */
3875 /* generic itof for unsigned long long case */
3876 void gen_cvt_itof1(int t
)
3880 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3881 (VT_LLONG
| VT_UNSIGNED
)) {
3883 gfunc_start(&gf
, FUNC_CDECL
);
3886 vpush_sym(func_old_type
, TOK___ulltof
);
3887 else if (t
== VT_DOUBLE
)
3888 vpush_sym(func_old_type
, TOK___ulltod
);
3890 vpush_sym(func_old_type
, TOK___ulltold
);
3899 /* generic ftoi for unsigned long long case */
3900 void gen_cvt_ftoi1(int t
)
3905 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3906 /* not handled natively */
3907 gfunc_start(&gf
, FUNC_CDECL
);
3908 st
= vtop
->t
& VT_BTYPE
;
3911 vpush_sym(func_old_type
, TOK___fixunssfdi
);
3912 else if (st
== VT_DOUBLE
)
3913 vpush_sym(func_old_type
, TOK___fixunsdfdi
);
3915 vpush_sym(func_old_type
, TOK___fixunsxfdi
);
3919 vtop
->r2
= REG_LRET
;
3925 /* force char or short cast */
3926 void force_charshort_cast(int t
)
3930 /* XXX: add optimization if lvalue : just change type and offset */
3935 if (t
& VT_UNSIGNED
) {
3936 vpushi((1 << bits
) - 1);
3947 /* cast 'vtop' to 't' type */
3948 void gen_cast(int t
)
3950 int sbt
, dbt
, sf
, df
, c
;
3952 /* special delayed cast for char/short */
3953 /* XXX: in some cases (multiple cascaded casts), it may still
3955 if (vtop
->r
& VT_MUSTCAST
) {
3956 vtop
->r
&= ~VT_MUSTCAST
;
3957 force_charshort_cast(vtop
->t
);
3960 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3961 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3966 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3968 /* convert from fp to fp */
3970 /* constant case: we can do it now */
3971 /* XXX: in ISOC, cannot do it if error in convert */
3972 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3973 vtop
->c
.f
= (float)vtop
->c
.d
;
3974 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3975 vtop
->c
.f
= (float)vtop
->c
.ld
;
3976 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3977 vtop
->c
.d
= (double)vtop
->c
.f
;
3978 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3979 vtop
->c
.d
= (double)vtop
->c
.ld
;
3980 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3981 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3982 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3983 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3985 /* non constant case: generate code */
3989 /* convert int to fp */
3992 case VT_LLONG
| VT_UNSIGNED
:
3994 /* XXX: add const cases for long long */
3996 case VT_INT
| VT_UNSIGNED
:
3998 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3999 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
4000 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
4005 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
4006 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
4007 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
4016 /* convert fp to int */
4017 /* we handle char/short/etc... with generic code */
4018 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
4019 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
4024 case VT_LLONG
| VT_UNSIGNED
:
4026 /* XXX: add const cases for long long */
4028 case VT_INT
| VT_UNSIGNED
:
4030 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4031 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4032 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4038 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4039 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4040 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4048 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
4049 /* additionnal cast for char/short/bool... */
4053 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
4054 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
4055 /* scalar to long long */
4057 if (sbt
== (VT_INT
| VT_UNSIGNED
))
4058 vtop
->c
.ll
= vtop
->c
.ui
;
4060 vtop
->c
.ll
= vtop
->c
.i
;
4062 /* machine independant conversion */
4064 /* generate high word */
4065 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
4073 /* patch second register */
4074 vtop
[-1].r2
= vtop
->r
;
4078 } else if (dbt
== VT_BOOL
) {
4079 /* scalar to bool */
4082 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
4083 (dbt
& VT_BTYPE
) == VT_SHORT
) {
4084 force_charshort_cast(t
);
4085 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
4087 if (sbt
== VT_LLONG
) {
4088 /* from long long: just take low order word */
4092 /* if lvalue and single word type, nothing to do because
4093 the lvalue already contains the real type size (see
4094 VT_LVAL_xxx constants) */
4100 /* return type size. Put alignment at 'a' */
4101 int type_size(int t
, int *a
)
4107 if (bt
== VT_STRUCT
) {
4109 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4110 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
4112 } else if (bt
== VT_PTR
) {
4114 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4115 return type_size(s
->t
, a
) * s
->c
;
4120 } else if (bt
== VT_LDOUBLE
) {
4122 return LDOUBLE_SIZE
;
4123 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
4126 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
4129 } else if (bt
== VT_SHORT
) {
4133 /* char, void, function, _Bool */
4139 /* return the pointed type of t */
4140 int pointed_type(int t
)
4143 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4144 return s
->t
| (t
& ~VT_TYPE
);
4147 int mk_pointer(int t
)
4151 sym_push(p
, t
, 0, -1);
4152 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
4155 int is_compatible_types(int t1
, int t2
)
4162 bt1
= t1
& VT_BTYPE
;
4163 bt2
= t2
& VT_BTYPE
;
4164 if (bt1
== VT_PTR
) {
4165 t1
= pointed_type(t1
);
4166 /* if function, then convert implicitely to function pointer */
4167 if (bt2
!= VT_FUNC
) {
4170 t2
= pointed_type(t2
);
4172 /* void matches everything */
4175 if (t1
== VT_VOID
|| t2
== VT_VOID
)
4177 return is_compatible_types(t1
, t2
);
4178 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4180 } else if (bt1
== VT_FUNC
) {
4183 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
4184 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
4185 if (!is_compatible_types(s1
->t
, s2
->t
))
4187 /* XXX: not complete */
4188 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
4192 while (s1
!= NULL
) {
4195 if (!is_compatible_types(s1
->t
, s2
->t
))
4204 /* XXX: not complete */
4209 /* print a type. If 'varstr' is not NULL, then the variable is also
4210 printed in the type */
4212 /* XXX: add array and function pointers */
4213 void type_to_str(char *buf
, int buf_size
,
4214 int t
, const char *varstr
)
4224 if (t
& VT_UNSIGNED
)
4225 pstrcat(buf
, buf_size
, "unsigned ");
4255 tstr
= "long double";
4257 pstrcat(buf
, buf_size
, tstr
);
4261 if (bt
== VT_STRUCT
)
4265 pstrcat(buf
, buf_size
, tstr
);
4266 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
4267 if (v
>= SYM_FIRST_ANOM
)
4268 pstrcat(buf
, buf_size
, "<anonymous>");
4270 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
4273 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4274 type_to_str(buf
, buf_size
, s
->t
, varstr
);
4275 pstrcat(buf
, buf_size
, "(");
4277 while (sa
!= NULL
) {
4278 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
4279 pstrcat(buf
, buf_size
, buf1
);
4282 pstrcat(buf
, buf_size
, ", ");
4284 pstrcat(buf
, buf_size
, ")");
4287 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4288 pstrcpy(buf1
, sizeof(buf1
), "*");
4290 pstrcat(buf1
, sizeof(buf1
), varstr
);
4291 type_to_str(buf
, buf_size
, s
->t
, buf1
);
4295 pstrcat(buf
, buf_size
, " ");
4296 pstrcat(buf
, buf_size
, varstr
);
4301 /* verify type compatibility to store vtop in 'dt' type, and generate
4303 void gen_assign_cast(int dt
)
4306 char buf1
[256], buf2
[256];
4308 st
= vtop
->t
; /* source type */
4309 if ((dt
& VT_BTYPE
) == VT_PTR
) {
4310 /* special cases for pointers */
4311 /* a function is implicitely a function pointer */
4312 if ((st
& VT_BTYPE
) == VT_FUNC
) {
4313 if (!is_compatible_types(pointed_type(dt
), st
))
4318 /* '0' can also be a pointer */
4319 if ((st
& VT_BTYPE
) == VT_INT
&&
4320 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
4324 if (!is_compatible_types(dt
, st
)) {
4326 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
4327 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
4328 error("cannot cast '%s' to '%s'", buf1
, buf2
);
4334 /* store vtop in lvalue pushed on stack */
4337 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
4341 sbt
= vtop
->t
& VT_BTYPE
;
4342 dbt
= ft
& VT_BTYPE
;
4343 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
4344 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
4345 /* optimize char/short casts */
4346 delayed_cast
= VT_MUSTCAST
;
4347 vtop
->t
= ft
& VT_TYPE
;
4350 gen_assign_cast(ft
& VT_TYPE
);
4353 if (sbt
== VT_STRUCT
) {
4354 /* if structure, only generate pointer */
4355 /* structure assignment : generate memcpy */
4356 /* XXX: optimize if small size */
4358 gfunc_start(&gf
, FUNC_CDECL
);
4360 size
= type_size(vtop
->t
, &align
);
4374 vpush_sym(func_old_type
, TOK_memcpy
);
4376 /* leave source on stack */
4377 } else if (ft
& VT_BITFIELD
) {
4378 /* bitfield store handling */
4379 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
4380 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
4381 /* remove bit field info to avoid loops */
4382 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
4384 /* duplicate destination */
4386 vtop
[-1] = vtop
[-2];
4388 /* mask and shift source */
4389 vpushi((1 << bit_size
) - 1);
4393 /* load destination, mask and or with source */
4395 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4401 #ifdef CONFIG_TCC_BCHECK
4402 /* bound check case */
4403 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4412 r
= gv(rc
); /* generate value */
4413 /* if lvalue was saved on stack, must read it */
4414 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4416 t
= get_reg(RC_INT
);
4418 sv
.r
= VT_LOCAL
| VT_LVAL
;
4419 sv
.c
.ul
= vtop
[-1].c
.ul
;
4421 vtop
[-1].r
= t
| VT_LVAL
;
4424 /* two word case handling : store second register at word + 4 */
4425 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4427 /* convert to int to increment easily */
4434 /* XXX: it works because r2 is spilled last ! */
4435 store(vtop
->r2
, vtop
- 1);
4438 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4439 vtop
->r
|= delayed_cast
;
4443 /* post defines POST/PRE add. c is the token ++ or -- */
4444 void inc(int post
, int c
)
4447 vdup(); /* save lvalue */
4449 gv_dup(); /* duplicate value */
4454 vpushi(c
- TOK_MID
);
4456 vstore(); /* store value */
4458 vpop(); /* if post op, return saved value */
4461 /* Parse GNUC __attribute__ extension. Currently, the following
4462 extensions are recognized:
4463 - aligned(n) : set data/function alignment.
4464 - section(x) : generate data/code in this section.
4465 - unused : currently ignored, but may be used someday.
4467 void parse_attribute(AttributeDef
*ad
)
4474 while (tok
!= ')') {
4475 if (tok
< TOK_IDENT
)
4476 expect("attribute name");
4481 case TOK___SECTION__
:
4484 expect("section name");
4485 ad
->section
= find_section((char *)tokc
.cstr
->data
);
4490 case TOK___ALIGNED__
:
4493 if (n
<= 0 || (n
& (n
- 1)) != 0)
4494 error("alignment must be a positive power of two");
4499 case TOK___UNUSED__
:
4500 /* currently, no need to handle it because tcc does not
4501 track unused objects */
4504 case TOK___NORETURN__
:
4505 /* currently, no need to handle it because tcc does not
4506 track unused objects */
4511 ad
->func_call
= FUNC_CDECL
;
4515 case TOK___STDCALL__
:
4516 ad
->func_call
= FUNC_STDCALL
;
4519 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4520 /* skip parameters */
4521 /* XXX: skip parenthesis too */
4524 while (tok
!= ')' && tok
!= -1)
4538 /* enum/struct/union declaration */
4539 int struct_decl(int u
)
4541 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4542 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4546 a
= tok
; /* save decl type */
4551 /* struct already defined ? return it */
4552 /* XXX: check consistency */
4553 s
= sym_find(v
| SYM_STRUCT
);
4556 error("invalid type");
4562 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4563 /* put struct/union/enum name in type */
4565 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4570 error("struct/union/enum already defined");
4571 /* cannot be empty */
4578 if (a
== TOK_ENUM
) {
4585 /* enum symbols have static storage */
4586 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4591 parse_btype(&b
, &ad
);
4596 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4597 if ((t
& VT_BTYPE
) == VT_FUNC
||
4598 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4599 error("invalid type for '%s'",
4600 get_tok_str(v
, NULL
));
4606 bit_size
= expr_const();
4607 /* XXX: handle v = 0 case for messages */
4609 error("negative width in bit-field '%s'",
4610 get_tok_str(v
, NULL
));
4611 if (v
&& bit_size
== 0)
4612 error("zero width for bit-field '%s'",
4613 get_tok_str(v
, NULL
));
4615 size
= type_size(t
, &align
);
4617 if (bit_size
>= 0) {
4622 error("bitfields must have scalar type");
4624 if (bit_size
> bsize
) {
4625 error("width of '%s' exceeds its type",
4626 get_tok_str(v
, NULL
));
4627 } else if (bit_size
== bsize
) {
4628 /* no need for bit fields */
4630 } else if (bit_size
== 0) {
4631 /* XXX: what to do if only padding in a
4633 /* zero size: means to pad */
4637 /* we do not have enough room ? */
4638 if ((bit_pos
+ bit_size
) > bsize
)
4641 /* XXX: handle LSB first */
4643 (bit_pos
<< VT_STRUCT_SHIFT
) |
4644 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4645 bit_pos
+= bit_size
;
4651 /* add new memory data only if starting
4653 if (lbit_pos
== 0) {
4654 if (a
== TOK_STRUCT
) {
4655 c
= (c
+ align
- 1) & -align
;
4663 if (align
> maxalign
)
4667 printf("add field %s offset=%d",
4668 get_tok_str(v
, NULL
), offset
);
4669 if (t
& VT_BITFIELD
) {
4670 printf(" pos=%d size=%d",
4671 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4672 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4676 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
4680 if (tok
== ';' || tok
== -1)
4690 /* size for struct/union, dummy for enum */
4691 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4696 /* return 0 if no type declaration. otherwise, return the basic type
4699 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4701 int t
, u
, type_found
;
4704 memset(ad
, 0, sizeof(AttributeDef
));
4715 if ((t
& VT_BTYPE
) != 0)
4716 error("too many basic types");
4730 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4731 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4732 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4733 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4747 if ((t
& VT_BTYPE
) == VT_LONG
) {
4748 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4755 u
= struct_decl(VT_ENUM
);
4759 u
= struct_decl(VT_STRUCT
);
4762 /* type modifiers */
4767 case TOK___SIGNED__
:
4770 case TOK___INLINE__
:
4792 /* GNUC attribute */
4793 case TOK___ATTRIBUTE__
:
4794 parse_attribute(ad
);
4798 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4800 t
|= (s
->t
& ~VT_TYPEDEF
);
4807 /* long is never used as type */
4808 if ((t
& VT_BTYPE
) == VT_LONG
)
4809 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4814 int post_type(int t
, AttributeDef
*ad
)
4816 int p
, n
, pt
, l
, t1
;
4817 Sym
**plast
, *s
, *first
;
4821 /* function declaration */
4826 while (tok
!= ')') {
4827 /* read param name and compute offset */
4828 if (l
!= FUNC_OLD
) {
4829 if (!parse_btype(&pt
, &ad1
)) {
4831 error("invalid type");
4838 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4840 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
4841 if ((pt
& VT_BTYPE
) == VT_VOID
)
4842 error("parameter declared as void");
4849 /* array must be transformed to pointer according to ANSI C */
4851 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
4856 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4863 /* if no parameters, then old type prototype */
4867 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4868 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4869 /* we push a anonymous symbol which will contain the function prototype */
4871 s
= sym_push(p
, t
, ad
->func_call
, l
);
4873 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
4874 } else if (tok
== '[') {
4875 /* array definition */
4881 error("invalid array size");
4884 /* parse next post type */
4885 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4886 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4888 /* we push a anonymous symbol which will contain the array
4891 sym_push(p
, t
, 0, n
);
4892 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
4897 /* Read a type declaration (except basic type), and return the
4898 type. 'td' is a bitmask indicating which kind of type decl is
4899 expected. 't' should contain the basic type. 'ad' is the attribute
4900 definition of the basic type. It can be modified by type_decl(). */
4901 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
4906 while (tok
== '*') {
4908 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
4913 /* recursive type */
4914 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4917 /* XXX: this is not correct to modify 'ad' at this point, but
4918 the syntax is not clear */
4919 if (tok
== TOK___ATTRIBUTE__
)
4920 parse_attribute(ad
);
4921 u
= type_decl(ad
, v
, 0, td
);
4925 /* type identifier */
4926 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
4930 if (!(td
& TYPE_ABSTRACT
))
4931 expect("identifier");
4935 /* append t at the end of u */
4936 t
= post_type(t
, ad
);
4937 if (tok
== TOK___ATTRIBUTE__
)
4938 parse_attribute(ad
);
4943 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
4953 /* define a new external reference to a symbol 'v' of type 'u' */
4954 Sym
*external_sym(int v
, int u
, int r
)
4960 /* push forward reference */
4961 s
= sym_push1(&global_stack
,
4962 v
, u
| VT_EXTERN
, 0);
4963 s
->r
= r
| VT_CONST
| VT_SYM
;
4968 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4969 static int lvalue_type(int t
)
4976 else if (bt
== VT_SHORT
)
4980 if (t
& VT_UNSIGNED
)
4981 r
|= VT_LVAL_UNSIGNED
;
4985 /* indirection with full error checking and bound check */
4986 static void indir(void)
4988 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
4990 if (vtop
->r
& VT_LVAL
)
4992 vtop
->t
= pointed_type(vtop
->t
);
4993 /* an array is never an lvalue */
4994 if (!(vtop
->t
& VT_ARRAY
)) {
4995 vtop
->r
|= lvalue_type(vtop
->t
);
4996 /* if bound checking, the referenced pointer must be checked */
4997 if (do_bounds_check
)
4998 vtop
->r
|= VT_MUSTBOUND
;
5002 /* pass a parameter to a function and do type checking and casting */
5003 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
5006 func_type
= func
->c
;
5007 if (func_type
== FUNC_OLD
||
5008 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5009 /* default casting : only need to convert float to double */
5010 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
5011 gen_cast(VT_DOUBLE
);
5012 } else if (arg
== NULL
) {
5013 error("too many arguments to function");
5015 gen_assign_cast(arg
->t
);
5022 int n
, t
, ft
, align
, size
, r
;
5027 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
5030 } else if (tok
== TOK_CUINT
) {
5031 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
5033 } else if (tok
== TOK_CLLONG
) {
5034 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
5036 } else if (tok
== TOK_CULLONG
) {
5037 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
5039 } else if (tok
== TOK_CFLOAT
) {
5040 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
5042 } else if (tok
== TOK_CDOUBLE
) {
5043 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
5045 } else if (tok
== TOK_CLDOUBLE
) {
5046 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
5048 } else if (tok
== TOK___FUNC__
) {
5051 /* special function name identifier */
5053 len
= strlen(funcname
) + 1;
5054 /* generate char[len] type */
5055 t
= VT_ARRAY
| mk_pointer(VT_BYTE
);
5056 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5058 vpush_ref(t
, data_section
, data_section
->data_offset
, len
);
5059 ptr
= section_ptr_add(data_section
, len
);
5060 memcpy(ptr
, funcname
, len
);
5062 } else if (tok
== TOK_LSTR
) {
5065 } else if (tok
== TOK_STR
) {
5066 /* string parsing */
5069 t
= VT_ARRAY
| mk_pointer(t
);
5070 memset(&ad
, 0, sizeof(AttributeDef
));
5071 decl_initializer_alloc(t
, &ad
, VT_CONST
, 2, 0, 0);
5077 if (parse_btype(&t
, &ad
)) {
5078 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
5080 /* check ISOC99 compound literal */
5082 /* data is allocated locally by default */
5087 /* all except arrays are lvalues */
5088 if (!(ft
& VT_ARRAY
))
5089 r
|= lvalue_type(ft
);
5090 memset(&ad
, 0, sizeof(AttributeDef
));
5091 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
5100 } else if (t
== '*') {
5103 } else if (t
== '&') {
5105 /* functions names must be treated as function pointers,
5106 except for unary '&' and sizeof. Since we consider that
5107 functions are not lvalues, we only have to handle it
5108 there and in function calls. */
5109 /* arrays can also be used although they are not lvalues */
5110 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
5111 !(vtop
->t
& VT_ARRAY
))
5113 vtop
->t
= mk_pointer(vtop
->t
);
5118 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
5119 vtop
->c
.i
= !vtop
->c
.i
;
5120 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
5121 vtop
->c
.i
= vtop
->c
.i
^ 1;
5123 vset(VT_INT
, VT_JMP
, gtst(1, 0));
5131 /* in order to force cast, we add zero */
5133 if ((vtop
->t
& VT_BTYPE
) == VT_PTR
)
5134 error("pointer not accepted for unary plus");
5138 if (t
== TOK_SIZEOF
) {
5141 if (parse_btype(&t
, &ad
)) {
5142 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
5144 /* XXX: some code could be generated: add eval
5156 vpushi(type_size(t
, &t
));
5158 if (t
== TOK_INC
|| t
== TOK_DEC
) {
5161 } else if (t
== '-') {
5168 expect("identifier");
5172 error("'%s' undeclared", get_tok_str(t
, NULL
));
5173 /* for simple function calls, we tolerate undeclared
5174 external reference to int() function */
5175 s
= external_sym(t
, func_old_type
, 0);
5177 vset(s
->t
, s
->r
, s
->c
);
5178 /* if forward reference, we must point to s */
5179 if (vtop
->r
& VT_SYM
)
5184 /* post operations */
5186 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
5189 } else if (tok
== '.' || tok
== TOK_ARROW
) {
5191 if (tok
== TOK_ARROW
)
5196 /* expect pointer on structure */
5197 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
5198 expect("struct or union");
5199 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5202 while ((s
= s
->next
) != NULL
) {
5207 error("field not found");
5208 /* add field offset to pointer */
5209 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
5212 /* change type to field type, and set to lvalue */
5214 /* an array is never an lvalue */
5215 if (!(vtop
->t
& VT_ARRAY
))
5216 vtop
->r
|= lvalue_type(vtop
->t
);
5218 } else if (tok
== '[') {
5224 } else if (tok
== '(') {
5229 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
5230 /* pointer test (no array accepted) */
5231 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
5232 vtop
->t
= pointed_type(vtop
->t
);
5233 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
5237 expect("function pointer");
5240 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
5242 /* get return type */
5243 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
5244 save_regs(0); /* save used temporary registers */
5245 gfunc_start(&gf
, s
->r
);
5247 sa
= s
->next
; /* first parameter */
5248 #ifdef INVERT_FUNC_PARAMS
5252 ParseState saved_parse_state
;
5255 /* read each argument and store it on a stack */
5256 /* XXX: merge it with macro args ? */
5262 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
5266 else if (tok
== ')')
5268 tok_str_add_tok(&str
);
5271 tok_str_add(&str
, -1); /* end of file added */
5272 tok_str_add(&str
, 0);
5273 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
5274 s1
->next
= sa
; /* add reference to argument */
5283 /* now generate code in reverse order by reading the stack */
5284 save_parse_state(&saved_parse_state
);
5286 macro_ptr
= (int *)args
->c
;
5290 expect("',' or ')'");
5291 gfunc_param_typed(&gf
, s
, args
->next
);
5293 tok_str_free((int *)args
->c
);
5297 restore_parse_state(&saved_parse_state
);
5300 /* compute first implicit argument if a structure is returned */
5301 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
5302 /* get some space for the returned structure */
5303 size
= type_size(s
->t
, &align
);
5304 loc
= (loc
- size
) & -align
;
5306 ret
.r
= VT_LOCAL
| VT_LVAL
;
5307 /* pass it as 'int' to avoid structure arg passing
5309 vset(VT_INT
, VT_LOCAL
, loc
);
5315 /* return in register */
5316 if (is_float(ret
.t
)) {
5319 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
5325 #ifndef INVERT_FUNC_PARAMS
5329 gfunc_param_typed(&gf
, s
, sa
);
5339 error("too few arguments to function");
5343 vsetc(ret
.t
, ret
.r
, &ret
.c
);
5357 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
5358 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
5359 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
5382 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
5383 (l
== 1 && (tok
== '+' || tok
== '-')) ||
5384 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
5385 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
5386 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
5387 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
5388 (l
== 5 && tok
== '&') ||
5389 (l
== 6 && tok
== '^') ||
5390 (l
== 7 && tok
== '|') ||
5391 (l
== 8 && tok
== TOK_LAND
) ||
5392 (l
== 9 && tok
== TOK_LOR
)) {
5401 /* only used if non constant */
5409 if (tok
!= TOK_LAND
) {
5412 vset(VT_INT
, VT_JMPI
, t
);
5429 if (tok
!= TOK_LOR
) {
5432 vset(VT_INT
, VT_JMP
, t
);
5442 /* XXX: better constant handling */
5445 int t
, u
, c
, r1
, r2
, rc
;
5465 save_regs(1); /* we need to save all registers here except
5466 at the top because it is a branch point */
5469 /* XXX: long long handling ? */
5471 if (is_float(vtop
->t
))
5474 vtop
--; /* no vpop so that FP stack is not flushed */
5499 /* parse a constant expression and return value in vtop */
5500 void expr_const1(void)
5506 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
5511 /* parse an integer constant and return its value */
5512 int expr_const(void)
5521 /* return the label token if current token is a label, otherwise
5528 /* fast test first */
5529 if (tok
< TOK_UIDENT
)
5531 /* no need to save tokc since we expect an identifier */
5539 /* XXX: may not work in all cases (macros ?) */
5548 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
5553 /* generate line number info */
5555 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
5556 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
5558 last_line_num
= file
->line_num
;
5561 if (tok
== TOK_IF
) {
5568 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5570 if (c
== TOK_ELSE
) {
5574 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5575 gsym(d
); /* patch else jmp */
5578 } else if (tok
== TOK_WHILE
) {
5586 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5590 } else if (tok
== '{') {
5593 s
= local_stack
.top
;
5594 while (tok
!= '}') {
5597 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5599 /* pop locally defined symbols */
5600 sym_pop(&local_stack
, s
);
5602 } else if (tok
== TOK_RETURN
) {
5606 gen_assign_cast(func_vt
);
5607 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5608 /* if returning structure, must copy it to implicit
5609 first pointer arg location */
5610 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
5613 /* copy structure value to pointer */
5615 } else if (is_float(func_vt
)) {
5620 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5623 rsym
= gjmp(rsym
); /* jmp */
5624 } else if (tok
== TOK_BREAK
) {
5627 error("cannot break");
5628 *bsym
= gjmp(*bsym
);
5631 } else if (tok
== TOK_CONTINUE
) {
5634 error("cannot continue");
5635 *csym
= gjmp(*csym
);
5638 } else if (tok
== TOK_FOR
) {
5665 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5670 if (tok
== TOK_DO
) {
5675 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5686 if (tok
== TOK_SWITCH
) {
5690 /* XXX: other types than integer */
5691 case_reg
= gv(RC_INT
);
5695 b
= gjmp(0); /* jump to first case */
5697 block(&a
, csym
, &b
, &c
, case_reg
);
5698 /* if no default, jmp after switch */
5706 if (tok
== TOK_CASE
) {
5713 if (gnu_ext
&& tok
== TOK_DOTS
) {
5717 warning("empty case range");
5719 /* since a case is like a label, we must skip it with a jmp */
5722 vset(VT_INT
, case_reg
, 0);
5726 *case_sym
= gtst(1, 0);
5729 *case_sym
= gtst(1, 0);
5730 vset(VT_INT
, case_reg
, 0);
5733 *case_sym
= gtst(1, *case_sym
);
5737 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5739 if (tok
== TOK_DEFAULT
) {
5745 error("too many 'default'");
5747 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5749 if (tok
== TOK_GOTO
) {
5751 s
= sym_find1(&label_stack
, tok
);
5752 /* put forward definition if needed */
5754 s
= sym_push1(&label_stack
, tok
, LABEL_FORWARD
, 0);
5755 /* label already defined */
5756 if (s
->t
& LABEL_FORWARD
)
5766 s
= sym_find1(&label_stack
, b
);
5768 if (!(s
->t
& LABEL_FORWARD
))
5769 error("multiple defined label");
5774 sym_push1(&label_stack
, b
, 0, ind
);
5776 /* we accept this, but it is a mistake */
5778 warning("deprecated use of label at end of compound statement");
5780 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5782 /* expression case */
5792 /* t is the array or struct type. c is the array or struct
5793 address. cur_index/cur_field is the pointer to the current
5794 value. 'size_only' is true if only size info is needed (only used
5796 static void decl_designator(int t
, Section
*sec
, unsigned long c
,
5797 int *cur_index
, Sym
**cur_field
,
5801 int notfirst
, index
, align
, l
;
5804 if (gnu_ext
&& (l
= is_label()) != 0)
5807 while (tok
== '[' || tok
== '.') {
5809 if (!(t
& VT_ARRAY
))
5810 expect("array type");
5811 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5813 index
= expr_const();
5814 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5815 expect("invalid index");
5819 t
= pointed_type(t
);
5820 c
+= index
* type_size(t
, &align
);
5826 if ((t
& VT_BTYPE
) != VT_STRUCT
)
5827 expect("struct/union type");
5828 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5840 t
= f
->t
| (t
& ~VT_TYPE
);
5855 t
= pointed_type(t
);
5856 c
+= index
* type_size(t
, &align
);
5860 error("too many field init");
5861 t
= f
->t
| (t
& ~VT_TYPE
);
5865 decl_initializer(t
, sec
, c
, 0, size_only
);
5869 #define EXPR_CONST 1
5872 /* store a value or an expression directly in global data or in local array */
5873 static void init_putv(int t
, Section
*sec
, unsigned long c
,
5874 int v
, int expr_type
)
5876 int saved_global_expr
, bt
;
5884 /* compound literals must be allocated globally in this case */
5885 saved_global_expr
= global_expr
;
5888 global_expr
= saved_global_expr
;
5896 /* XXX: not portable */
5897 /* XXX: generate error if incorrect relocation */
5900 ptr
= sec
->data
+ c
;
5901 if ((vtop
->r
& VT_SYM
) &&
5907 error("initializer element is not computable at load time");
5910 *(char *)ptr
= vtop
->c
.i
;
5913 *(short *)ptr
= vtop
->c
.i
;
5916 *(double *)ptr
= vtop
->c
.d
;
5919 *(long double *)ptr
= vtop
->c
.ld
;
5922 *(long long *)ptr
= vtop
->c
.ll
;
5925 if (vtop
->r
& VT_SYM
) {
5926 greloc(sec
, vtop
->c
.sym
, c
, R_DATA_32
);
5929 *(int *)ptr
= vtop
->c
.i
;
5935 vset(t
, VT_LOCAL
, c
);
5942 /* put zeros for variable based init */
5943 static void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
5948 /* nothing to do because globals are already set to zero */
5950 gfunc_start(&gf
, FUNC_CDECL
);
5955 vset(VT_INT
, VT_LOCAL
, c
);
5957 vpush_sym(func_old_type
, TOK_memset
);
5962 /* 't' contains the type and storage info. 'c' is the offset of the
5963 object in section 'sec'. If 'sec' is NULL, it means stack based
5964 allocation. 'first' is true if array '{' must be read (multi
5965 dimension implicit array init handling). 'size_only' is true if
5966 size only evaluation is wanted (only for arrays). */
5967 static void decl_initializer(int t
, Section
*sec
, unsigned long c
,
5968 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 non zero, 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. If 'has_init' is 2, a special parsing is done
6127 to handle string constants. */
6128 static void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
,
6129 int has_init
, int v
, int scope
)
6131 int size
, align
, addr
, data_offset
;
6133 ParseState saved_parse_state
;
6134 TokenString init_str
;
6137 size
= type_size(t
, &align
);
6138 /* If unknown size, we must evaluate it before
6139 evaluating initializers because
6140 initializers can generate global data too
6141 (e.g. string pointers or ISOC99 compound
6142 literals). It also simplifies local
6143 initializers handling */
6144 tok_str_new(&init_str
);
6147 error("unknown type size");
6148 /* get all init string */
6149 if (has_init
== 2) {
6150 /* only get strings */
6151 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6152 tok_str_add_tok(&init_str
);
6157 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
6159 error("unexpected end of file in initializer");
6160 tok_str_add_tok(&init_str
);
6163 else if (tok
== '}') {
6171 tok_str_add(&init_str
, -1);
6172 tok_str_add(&init_str
, 0);
6175 save_parse_state(&saved_parse_state
);
6177 macro_ptr
= init_str
.str
;
6179 decl_initializer(t
, NULL
, 0, 1, 1);
6180 /* prepare second initializer parsing */
6181 macro_ptr
= init_str
.str
;
6184 /* if still unknown size, error */
6185 size
= type_size(t
, &align
);
6187 error("unknown type size");
6189 /* take into account specified alignment if bigger */
6190 if (ad
->aligned
> align
)
6191 align
= ad
->aligned
;
6192 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
6194 if (do_bounds_check
&& (t
& VT_ARRAY
))
6196 #ifdef TCC_TARGET_IL
6197 /* XXX: ugly patch to allocate local variables for IL, just
6202 loc
= (loc
- size
) & -align
;
6205 /* handles bounds */
6206 /* XXX: currently, since we do only one pass, we cannot track
6207 '&' operators, so we add only arrays */
6208 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
6209 unsigned long *bounds_ptr
;
6210 /* add padding between regions */
6212 /* then add local bound info */
6213 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
6214 bounds_ptr
[0] = addr
;
6215 bounds_ptr
[1] = size
;
6218 /* compute section */
6226 data_offset
= sec
->data_offset
;
6227 data_offset
= (data_offset
+ align
- 1) & -align
;
6229 /* very important to increment global pointer at this time
6230 because initializers themselves can create new initializers */
6231 data_offset
+= size
;
6232 /* add padding if bound check */
6233 if (do_bounds_check
)
6235 sec
->data_offset
= data_offset
;
6236 /* allocate section space to put the data */
6237 if (sec
->sh_type
!= SHT_NOBITS
&&
6238 data_offset
> sec
->data_allocated
)
6239 section_realloc(sec
, data_offset
);
6243 /* local variable */
6244 sym_push(v
, t
, r
, addr
);
6246 /* push local reference */
6253 if (scope
== VT_CONST
) {
6254 /* global scope: see if already defined */
6258 if (!is_compatible_types(sym
->t
, t
))
6259 error("incompatible types for redefinition of '%s'",
6260 get_tok_str(v
, NULL
));
6261 if (!(sym
->t
& VT_EXTERN
))
6262 error("redefinition of '%s'", get_tok_str(v
, NULL
));
6263 sym
->t
&= ~VT_EXTERN
;
6266 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
6268 put_extern_sym(sym
, sec
, addr
, size
);
6272 /* push global reference */
6273 sym
= get_sym_ref(t
, sec
, addr
, size
);
6275 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
6278 /* handles bounds now because the symbol must be defined
6279 before for the relocation */
6280 if (do_bounds_check
) {
6281 unsigned long *bounds_ptr
;
6283 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
6284 /* then add global bound info */
6285 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
6286 bounds_ptr
[0] = 0; /* relocated */
6287 bounds_ptr
[1] = size
;
6291 decl_initializer(t
, sec
, addr
, 1, 0);
6292 /* restore parse state if needed */
6294 tok_str_free(init_str
.str
);
6295 restore_parse_state(&saved_parse_state
);
6300 void put_func_debug(Sym
*sym
)
6305 /* XXX: we put here a dummy type */
6306 snprintf(buf
, sizeof(buf
), "%s:%c1",
6307 funcname
, sym
->t
& VT_STATIC
? 'f' : 'F');
6308 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
6309 cur_text_section
, sym
->c
);
6314 /* not finished : try to put some local vars in registers */
6315 //#define CONFIG_REG_VARS
6317 #ifdef CONFIG_REG_VARS
6318 void add_var_ref(int t
)
6320 printf("%s:%d: &%s\n",
6321 file
->filename
, file
->line_num
,
6322 get_tok_str(t
, NULL
));
6325 /* first pass on a function with heuristic to extract variable usage
6326 and pointer references to local variables for register allocation */
6327 void analyse_function(void)
6334 /* any symbol coming after '&' is considered as being a
6335 variable whose reference is taken. It is highly unaccurate
6336 but it is difficult to do better without a complete parse */
6339 /* if '& number', then no need to examine next tokens */
6340 if (tok
== TOK_CINT
||
6342 tok
== TOK_CLLONG
||
6343 tok
== TOK_CULLONG
) {
6345 } else if (tok
>= TOK_UIDENT
) {
6346 /* if '& ident [' or '& ident ->', then ident address
6350 if (tok
!= '[' && tok
!= TOK_ARROW
)
6354 while (tok
!= '}' && tok
!= ';' &&
6355 !((tok
== ',' || tok
== ')') && level
== 0)) {
6356 if (tok
>= TOK_UIDENT
) {
6358 } else if (tok
== '(') {
6360 } else if (tok
== ')') {
6373 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
6376 int t
, b
, v
, has_init
, r
;
6381 if (!parse_btype(&b
, &ad
)) {
6382 /* skip redundant ';' */
6383 /* XXX: find more elegant solution */
6388 /* special test for old K&R protos without explicit int
6389 type. Only accepted when defining global data */
6390 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
6394 if (((b
& VT_BTYPE
) == VT_ENUM
||
6395 (b
& VT_BTYPE
) == VT_STRUCT
) &&
6397 /* we accept no variable after */
6401 while (1) { /* iterate thru each declaration */
6402 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
6406 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
6407 printf("type = '%s'\n", buf
);
6411 #ifdef CONFIG_REG_VARS
6412 TokenString func_str
;
6413 ParseState saved_parse_state
;
6418 error("cannot use local functions");
6420 expect("function definition");
6422 #ifdef CONFIG_REG_VARS
6423 /* parse all function code and record it */
6425 tok_str_new(&func_str
);
6431 error("unexpected end of file");
6432 tok_str_add_tok(&func_str
);
6437 } else if (t
== '}') {
6439 if (block_level
== 0)
6443 tok_str_add(&func_str
, -1);
6444 tok_str_add(&func_str
, 0);
6446 save_parse_state(&saved_parse_state
);
6448 macro_ptr
= func_str
.str
;
6453 /* compute text section */
6454 cur_text_section
= ad
.section
;
6455 if (!cur_text_section
)
6456 cur_text_section
= text_section
;
6457 ind
= cur_text_section
->data_offset
;
6458 funcname
= get_tok_str(v
, NULL
);
6461 /* if symbol is already defined, then put complete type */
6464 /* put function symbol */
6465 sym
= sym_push1(&global_stack
, v
, t
, 0);
6467 /* NOTE: we patch the symbol size later */
6468 put_extern_sym(sym
, cur_text_section
, ind
, 0);
6470 sym
->r
= VT_SYM
| VT_CONST
;
6471 /* put debug symbol */
6473 put_func_debug(sym
);
6474 /* push a dummy symbol to enable local sym storage */
6475 sym_push1(&local_stack
, 0, 0, 0);
6479 #ifdef CONFIG_REG_VARS
6480 macro_ptr
= func_str
.str
;
6483 block(NULL
, NULL
, NULL
, NULL
, 0);
6486 cur_text_section
->data_offset
= ind
;
6487 sym_pop(&label_stack
, NULL
); /* reset label stack */
6488 sym_pop(&local_stack
, NULL
); /* reset local stack */
6489 /* end of function */
6490 /* patch symbol size */
6491 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
6494 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6496 funcname
= ""; /* for safety */
6497 func_vt
= VT_VOID
; /* for safety */
6498 ind
= 0; /* for safety */
6500 #ifdef CONFIG_REG_VARS
6501 tok_str_free(func_str
.str
);
6502 restore_parse_state(&saved_parse_state
);
6506 if (b
& VT_TYPEDEF
) {
6507 /* save typedefed type */
6508 /* XXX: test storage specifiers ? */
6509 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
6510 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
6511 /* external function definition */
6512 external_sym(v
, t
, 0);
6514 /* not lvalue if array */
6516 if (!(t
& VT_ARRAY
))
6517 r
|= lvalue_type(t
);
6518 if (b
& VT_EXTERN
) {
6519 /* external variable */
6520 external_sym(v
, t
, r
);
6526 has_init
= (tok
== '=');
6529 decl_initializer_alloc(t
, &ad
, r
,
6543 /* compile the C file opened in 'file'. Return non zero if errors. */
6544 static int tcc_compile(TCCState
*s
)
6546 Sym
*define_start
, *sym
;
6551 include_stack_ptr
= include_stack
;
6552 ifdef_stack_ptr
= ifdef_stack
;
6554 /* XXX: not ANSI compliant: bound checking says error */
6556 anon_sym
= SYM_FIRST_ANOM
;
6558 /* file info: full path + filename */
6559 section_sym
= 0; /* avoid warning */
6561 section_sym
= put_elf_sym(symtab_section
, 0, 0,
6562 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
6563 text_section
->sh_num
, NULL
);
6564 getcwd(buf
, sizeof(buf
));
6565 pstrcat(buf
, sizeof(buf
), "/");
6566 put_stabs_r(buf
, N_SO
, 0, 0,
6567 text_section
->data_offset
, text_section
, section_sym
);
6568 put_stabs_r(file
->filename
, N_SO
, 0, 0,
6569 text_section
->data_offset
, text_section
, section_sym
);
6571 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
6572 symbols can be safely used */
6573 put_elf_sym(symtab_section
, 0, 0,
6574 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
6575 SHN_ABS
, file
->filename
);
6577 /* define common 'char *' type because it is often used internally
6578 for arrays and struct dereference */
6579 char_pointer_type
= mk_pointer(VT_BYTE
);
6580 /* define an old type function 'int func()' */
6582 sym
= sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
6583 sym
->r
= FUNC_CDECL
;
6584 func_old_type
= VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
6586 define_start
= define_stack
.top
;
6588 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6592 expect("declaration");
6594 /* end of translation unit info */
6596 put_stabs_r(NULL
, N_SO
, 0, 0,
6597 text_section
->data_offset
, text_section
, section_sym
);
6600 /* reset define stack, but leave -Dsymbols (may be incorrect if
6601 they are undefined) */
6602 sym_pop(&define_stack
, define_start
);
6604 sym_pop(&global_stack
, NULL
);
6609 int tcc_compile_string(TCCState
*s
, const char *str
)
6611 BufferedFile bf1
, *bf
= &bf1
;
6614 /* init file structure */
6616 bf
->buf_ptr
= (char *)str
;
6617 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
6618 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
6622 ret
= tcc_compile(s
);
6624 /* currently, no need to close */
6628 /* define a symbol. A value can also be provided with the '=' operator */
6629 void tcc_define_symbol(TCCState
*s
, const char *sym
, const char *value
)
6631 BufferedFile bf1
, *bf
= &bf1
;
6633 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
6634 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
6638 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
6640 /* init file structure */
6642 bf
->buf_ptr
= bf
->buffer
;
6643 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
6644 bf
->filename
[0] = '\0';
6648 include_stack_ptr
= include_stack
;
6650 /* parse with define parser */
6652 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6658 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
6662 ts
= tok_alloc(sym
, 0);
6663 s
= sym_find1(&define_stack
, tok
);
6664 /* undefine symbol by putting an invalid name */
6666 sym_undef(&define_stack
, s
);
6671 /* print the position in the source file of PC value 'pc' by reading
6672 the stabs debug information */
6673 static void rt_printline(unsigned long wanted_pc
)
6675 Stab_Sym
*sym
, *sym_end
;
6676 char func_name
[128], last_func_name
[128];
6677 unsigned long func_addr
, last_pc
, pc
;
6678 const char *incl_files
[INCLUDE_STACK_SIZE
];
6679 int incl_index
, len
, last_line_num
, i
;
6680 const char *str
, *p
;
6682 func_name
[0] = '\0';
6685 last_func_name
[0] = '\0';
6686 last_pc
= 0xffffffff;
6688 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
6689 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
6690 while (sym
< sym_end
) {
6691 switch(sym
->n_type
) {
6692 /* function start or end */
6694 if (sym
->n_strx
== 0) {
6695 func_name
[0] = '\0';
6698 str
= stabstr_section
->data
+ sym
->n_strx
;
6699 p
= strchr(str
, ':');
6701 pstrcpy(func_name
, sizeof(func_name
), str
);
6704 if (len
> sizeof(func_name
) - 1)
6705 len
= sizeof(func_name
) - 1;
6706 memcpy(func_name
, str
, len
);
6707 func_name
[len
] = '\0';
6709 func_addr
= sym
->n_value
;
6712 /* line number info */
6714 pc
= sym
->n_value
+ func_addr
;
6715 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
6718 last_line_num
= sym
->n_desc
;
6720 strcpy(last_func_name
, func_name
);
6724 str
= stabstr_section
->data
+ sym
->n_strx
;
6726 if (incl_index
< INCLUDE_STACK_SIZE
) {
6727 incl_files
[incl_index
++] = str
;
6735 if (sym
->n_strx
== 0) {
6736 incl_index
= 0; /* end of translation unit */
6738 str
= stabstr_section
->data
+ sym
->n_strx
;
6739 /* do not add path */
6741 if (len
> 0 && str
[len
- 1] != '/')
6748 /* did not find line number info: */
6749 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
6752 for(i
= 0; i
< incl_index
- 1; i
++)
6753 fprintf(stderr
, "In file included from %s\n",
6755 if (incl_index
> 0) {
6756 fprintf(stderr
, "%s:%d: ",
6757 incl_files
[incl_index
- 1], last_line_num
);
6759 if (last_func_name
[0] != '\0') {
6760 fprintf(stderr
, "in function '%s()': ", last_func_name
);
6764 /* emit a run time error at position 'pc' */
6765 void rt_error(unsigned long pc
, const char *fmt
, ...)
6771 vfprintf(stderr
, fmt
, ap
);
6772 fprintf(stderr
, "\n");
6778 /* signal handler for fatal errors */
6779 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
6781 struct ucontext
*uc
= puc
;
6785 pc
= uc
->uc_mcontext
.gregs
[14];
6787 #error please put the right sigcontext field
6792 switch(siginf
->si_code
) {
6795 rt_error(pc
, "division by zero");
6798 rt_error(pc
, "floating point exception");
6804 rt_error(pc
, "dereferencing invalid pointer");
6807 rt_error(pc
, "illegal instruction");
6810 rt_error(pc
, "abort() called");
6813 rt_error(pc
, "caught signal %d", signum
);
6820 /* launch the compiled program with the given arguments */
6821 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
6824 int (*prog_main
)(int, char **);
6827 tcc_add_runtime(s1
);
6829 relocate_common_syms();
6831 /* compute relocation address : section are relocated in place. We
6832 also alloc the bss space */
6833 for(i
= 1; i
< nb_sections
; i
++) {
6835 if (s
->sh_flags
& SHF_ALLOC
) {
6837 if (s
->sh_type
== SHT_NOBITS
) {
6838 data
= tcc_mallocz(s
->data_offset
);
6842 s
->sh_addr
= (unsigned long)data
;
6848 /* relocate each section */
6849 for(i
= 1; i
< nb_sections
; i
++) {
6852 relocate_section(s1
, s
);
6855 prog_main
= (void *)get_elf_sym_val("main");
6859 error("debug mode currently not available for Windows");
6861 struct sigaction sigact
;
6862 /* install TCC signal handlers to print debug info on fatal
6864 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
6865 sigact
.sa_sigaction
= sig_error
;
6866 sigemptyset(&sigact
.sa_mask
);
6867 sigaction(SIGFPE
, &sigact
, NULL
);
6868 sigaction(SIGILL
, &sigact
, NULL
);
6869 sigaction(SIGSEGV
, &sigact
, NULL
);
6870 sigaction(SIGBUS
, &sigact
, NULL
);
6871 sigaction(SIGABRT
, &sigact
, NULL
);
6875 #ifdef CONFIG_TCC_BCHECK
6876 if (do_bounds_check
) {
6877 void (*bound_init
)(void);
6878 void **bound_error_func
;
6880 /* set error function */
6881 bound_error_func
= (void **)get_elf_sym_val("__bound_error_func");
6882 *bound_error_func
= rt_error
;
6884 /* XXX: use .init section so that it also work in binary ? */
6885 bound_init
= (void *)get_elf_sym_val("__bound_init");
6889 return (*prog_main
)(argc
, argv
);
6892 TCCState
*tcc_new(void)
6897 s
= tcc_malloc(sizeof(TCCState
));
6900 s
->output_type
= TCC_OUTPUT_MEMORY
;
6902 /* default include paths */
6903 tcc_add_sysinclude_path(s
, "/usr/local/include");
6904 tcc_add_sysinclude_path(s
, "/usr/include");
6905 tcc_add_sysinclude_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
6907 /* add all tokens */
6908 tok_ident
= TOK_IDENT
;
6913 tok_alloc(p
, r
- p
- 1);
6917 /* we add dummy defines for some special macros to speed up tests
6918 and to have working defined() */
6919 sym_push1(&define_stack
, TOK___LINE__
, MACRO_OBJ
, 0);
6920 sym_push1(&define_stack
, TOK___FILE__
, MACRO_OBJ
, 0);
6921 sym_push1(&define_stack
, TOK___DATE__
, MACRO_OBJ
, 0);
6922 sym_push1(&define_stack
, TOK___TIME__
, MACRO_OBJ
, 0);
6923 sym_push1(&define_stack
, TOK___FUNCTION__
, MACRO_OBJ
, 0);
6925 /* standard defines */
6926 tcc_define_symbol(s
, "__STDC__", NULL
);
6927 #if defined(TCC_TARGET_I386)
6928 tcc_define_symbol(s
, "__i386__", NULL
);
6931 tcc_define_symbol(s
, "linux", NULL
);
6933 /* tiny C specific defines */
6934 tcc_define_symbol(s
, "__TINYC__", NULL
);
6936 /* default library paths */
6937 tcc_add_library_path(s
, "/usr/local/lib");
6938 tcc_add_library_path(s
, "/usr/lib");
6939 tcc_add_library_path(s
, "/lib");
6941 /* no section zero */
6942 dynarray_add((void ***)§ions
, &nb_sections
, NULL
);
6944 /* create standard sections */
6945 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
6946 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6947 bss_section
= new_section(".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
6949 /* symbols are always generated for linking stage */
6950 symtab_section
= new_symtab(".symtab", SHT_SYMTAB
, 0,
6952 ".hashtab", SHF_PRIVATE
);
6953 strtab_section
= symtab_section
->link
;
6955 /* private symbol table for dynamic symbols */
6956 dynsymtab_section
= new_symtab(".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
6958 ".dynhashtab", SHF_PRIVATE
);
6962 void tcc_delete(TCCState
*s
)
6967 int tcc_add_include_path(TCCState
*s
, const char *pathname
)
6971 pathname1
= tcc_strdup(pathname
);
6972 dynarray_add((void ***)&include_paths
, &nb_include_paths
, pathname1
);
6976 int tcc_add_sysinclude_path(TCCState
*s
, const char *pathname
)
6980 pathname1
= tcc_strdup(pathname
);
6981 dynarray_add((void ***)&sysinclude_paths
, &nb_sysinclude_paths
, pathname1
);
6985 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
)
6990 BufferedFile
*saved_file
;
6992 /* find source file type with extension */
6993 ext
= strrchr(filename
, '.');
6999 file
= tcc_open(filename
);
7001 if (flags
& AFF_PRINT_ERROR
) {
7002 error("file '%s' not found", filename
);
7009 if (!ext
|| !strcmp(ext
, "c")) {
7010 /* C file assumed */
7014 /* assume executable format: auto guess file type */
7015 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
7016 error("could not read header");
7017 lseek(fd
, 0, SEEK_SET
);
7019 if (ehdr
.e_ident
[0] == ELFMAG0
&&
7020 ehdr
.e_ident
[1] == ELFMAG1
&&
7021 ehdr
.e_ident
[2] == ELFMAG2
&&
7022 ehdr
.e_ident
[3] == ELFMAG3
) {
7023 file
->line_num
= 0; /* do not display line number if error */
7024 if (ehdr
.e_type
== ET_REL
) {
7025 tcc_load_object_file(s
, fd
, 0);
7026 } else if (ehdr
.e_type
== ET_DYN
) {
7027 tcc_load_dll(s
, fd
, filename
, (flags
& AFF_REFERENCED_DLL
) != 0);
7029 error("unrecognized ELF file");
7031 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
7032 file
->line_num
= 0; /* do not display line number if error */
7033 tcc_load_archive(s
, fd
);
7035 /* as GNU ld, consider it is an ld script if not recognized */
7036 if (tcc_load_ldscript(s
) < 0)
7037 error("unrecognized file type");
7045 void tcc_add_file(TCCState
*s
, const char *filename
)
7047 tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
7050 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
7054 pathname1
= tcc_strdup(pathname
);
7055 dynarray_add((void ***)&library_paths
, &nb_library_paths
, pathname1
);
7059 /* find and load a dll. Return non zero if not found */
7060 /* XXX: add '-rpath' option support ? */
7061 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
7066 for(i
= 0; i
< nb_library_paths
; i
++) {
7067 snprintf(buf
, sizeof(buf
), "%s/%s",
7068 library_paths
[i
], filename
);
7069 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
7075 /* the library name is the same as the argument of the '-l' option */
7076 int tcc_add_library(TCCState
*s
, const char *libraryname
)
7082 /* if we output to memory, then we simply we dlopen(). */
7083 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
7084 /* Since the libc is already loaded, we don't need to load it again */
7085 if (!strcmp(libraryname
, "c"))
7087 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
7088 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
7094 /* first we look for the dynamic library if not static linking */
7096 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
7097 if (tcc_add_dll(s
, buf
, 0) == 0)
7101 /* then we look for the static library */
7102 for(i
= 0; i
< nb_library_paths
; i
++) {
7103 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
7104 library_paths
[i
], libraryname
);
7105 if (tcc_add_file_internal(s
, buf
, 0) == 0)
7111 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
7113 add_elf_sym(symtab_section
, val
, 0,
7114 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
7119 int tcc_set_output_type(TCCState
*s
, int output_type
)
7121 s
->output_type
= output_type
;
7123 /* if bound checking, then add corresponding sections */
7124 #ifdef CONFIG_TCC_BCHECK
7125 if (do_bounds_check
) {
7127 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
7128 /* create bounds sections */
7129 bounds_section
= new_section(".bounds",
7130 SHT_PROGBITS
, SHF_ALLOC
);
7131 lbounds_section
= new_section(".lbounds",
7132 SHT_PROGBITS
, SHF_ALLOC
);
7136 /* add debug sections */
7139 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
7140 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
7141 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
7142 put_elf_str(stabstr_section
, "");
7143 stab_section
->link
= stabstr_section
;
7144 /* put first entry */
7145 put_stabs("", 0, 0, 0, 0);
7148 /* add libc crt1/crti objects */
7149 if (output_type
== TCC_OUTPUT_EXE
||
7150 output_type
== TCC_OUTPUT_DLL
) {
7151 if (output_type
!= TCC_OUTPUT_DLL
)
7152 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
7153 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
7158 #if !defined(LIBTCC)
7162 printf("tcc version 0.9.10 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
7163 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
7164 " [-g] [-b] [-Ldir] [-llib] [-shared] [-static]\n"
7165 " [--] infile1 [infile2... --] [infile_args...]\n"
7167 "General options:\n"
7168 " -c compile only - generate an object file\n"
7169 " -o outfile set output filename\n"
7170 " -- allows multiples input files if no -o option given. Also\n"
7171 " separate input files from runtime arguments\n"
7172 " -Bdir set tcc internal library path\n"
7173 " -bench output compilation statistics\n"
7174 "Preprocessor options:\n"
7175 " -Idir add include path 'dir'\n"
7176 " -Dsym[=val] define 'sym' with value 'val'\n"
7177 " -Usym undefine 'sym'\n"
7178 "C compiler options:\n"
7179 " -g generate runtime debug info\n"
7180 #ifdef CONFIG_TCC_BCHECK
7181 " -b compile with built-in memory and bounds checker (implies -g)\n"
7184 " -Ldir add library path 'dir'\n"
7185 " -llib link with dynamic or static library 'lib'\n"
7186 " -shared generate a shared library\n"
7187 " -static static linking\n"
7191 int main(int argc
, char **argv
)
7194 int optind
, output_type
, multiple_files
, i
;
7200 output_type
= TCC_OUTPUT_MEMORY
;
7208 if (optind
>= argc
) {
7218 /* '--' enables multiple files input */
7220 } else if (r
[1] == 'h' || r
[1] == '?') {
7222 } else if (r
[1] == 'I') {
7223 if (tcc_add_include_path(s
, r
+ 2) < 0)
7224 error("too many include paths");
7225 } else if (r
[1] == 'D') {
7228 value
= strchr(sym
, '=');
7233 tcc_define_symbol(s
, sym
, value
);
7234 } else if (r
[1] == 'U') {
7235 tcc_undefine_symbol(s
, r
+ 2);
7236 } else if (r
[1] == 'L') {
7237 tcc_add_library_path(s
, r
+ 2);
7238 } else if (r
[1] == 'B') {
7239 /* set tcc utilities path (mainly for tcc development) */
7240 tcc_lib_path
= r
+ 2;
7241 } else if (r
[1] == 'l') {
7242 dynarray_add((void ***)&libraries
, &nb_libraries
, r
+ 2);
7243 } else if (!strcmp(r
+ 1, "bench")) {
7246 #ifdef CONFIG_TCC_BCHECK
7248 do_bounds_check
= 1;
7254 } else if (r
[1] == 'c') {
7256 output_type
= TCC_OUTPUT_OBJ
;
7257 } else if (!strcmp(r
+ 1, "static")) {
7259 } else if (!strcmp(r
+ 1, "shared")) {
7260 output_type
= TCC_OUTPUT_DLL
;
7261 } else if (r
[1] == 'o') {
7265 outfile
= argv
[optind
++];
7267 error("invalid option -- '%s'", r
);
7271 /* if outfile provided without other options, we output an
7273 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
7274 output_type
= TCC_OUTPUT_EXE
;
7276 tcc_set_output_type(s
, output_type
);
7278 tcc_add_file(s
, argv
[optind
]);
7279 if (multiple_files
) {
7280 while ((optind
+ 1) < argc
) {
7285 error("'--' expected");
7292 /* add specified libraries */
7293 for(i
= 0; i
< nb_libraries
;i
++) {
7294 if (tcc_add_library(s
, libraries
[i
]) < 0)
7295 error("cannot find -l%s", libraries
[i
]);
7299 printf("total: %d idents, %d lines, %d bytes\n",
7300 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
7302 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);
7306 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
7307 tcc_output_file(s
, outfile
);
7310 return tcc_run(s
, argc
- optind
, argv
+ optind
);