2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 #include <sys/ucontext.h>
37 #ifndef CONFIG_TCC_STATIC
42 /* preprocessor debug */
45 /* target selection */
46 //#define TCC_TARGET_I386 /* i386 code generator */
47 //#define TCC_TARGET_IL /* .NET CLI generator */
49 /* default target is I386 */
50 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
51 #define TCC_TARGET_I386
54 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
55 #define CONFIG_TCC_BCHECK /* enable bound checking code */
58 /* amount of virtual memory associated to a section (currently, we do
60 #define SECTION_VSIZE (1024 * 1024)
62 #define INCLUDE_STACK_SIZE 32
63 #define IFDEF_STACK_SIZE 64
64 #define VSTACK_SIZE 64
65 #define STRING_MAX_SIZE 1024
66 #define INCLUDE_PATHS_MAX 32
68 #define TOK_HASH_SIZE 2048 /* must be a power of two */
69 #define TOK_ALLOC_INCR 512 /* must be a power of two */
70 #define SYM_HASH_SIZE 1031
72 /* token symbol management */
73 typedef struct TokenSym
{
74 struct TokenSym
*hash_next
;
75 int tok
; /* token number */
81 typedef union CValue
{
87 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
89 unsigned long long ull
;
96 typedef struct SValue
{
98 unsigned short r
; /* register + flags */
99 unsigned short r2
; /* second register, used for 'long long'
100 type. If not used, set to VT_CONST */
101 CValue c
; /* constant */
104 /* symbol management */
106 int v
; /* symbol token */
107 int t
; /* associated type */
108 int r
; /* associated register */
109 int c
; /* associated number */
110 struct Sym
*next
; /* next related symbol */
111 struct Sym
*prev
; /* prev symbol in stack */
112 struct Sym
*hash_next
; /* next symbol in hash table */
115 typedef struct SymStack
{
117 struct Sym
*hash
[SYM_HASH_SIZE
];
120 /* relocation entry (currently only used for functions or variables */
121 typedef struct Reloc
{
122 int type
; /* type of relocation */
123 int addr
; /* address of relocation */
124 struct Reloc
*next
; /* next relocation */
127 #define RELOC_ADDR32 1 /* 32 bits relocation */
128 #define RELOC_REL32 2 /* 32 bits relative relocation */
130 /* section definition */
131 typedef struct Section
{
132 char name
[64]; /* section name */
133 unsigned char *data
; /* section data */
134 unsigned char *data_ptr
; /* current data pointer */
135 int sh_num
; /* elf section number */
136 int sh_type
; /* elf section type */
137 int sh_flags
; /* elf section flags */
138 int sh_entsize
; /* elf entry size */
139 struct Section
*link
; /* link to another section */
140 struct Section
*next
;
143 /* GNUC attribute definition */
144 typedef struct AttributeDef
{
147 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
150 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
151 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
152 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
154 /* stored in 'Sym.c' field */
155 #define FUNC_NEW 1 /* ansi function prototype */
156 #define FUNC_OLD 2 /* old function prototype */
157 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
159 /* stored in 'Sym.r' field */
160 #define FUNC_CDECL 0 /* standard c call */
161 #define FUNC_STDCALL 1 /* pascal c call */
163 /* field 'Sym.t' for macros */
164 #define MACRO_OBJ 0 /* object like macro */
165 #define MACRO_FUNC 1 /* function like macro */
167 /* type_decl() types */
168 #define TYPE_ABSTRACT 1 /* type without variable */
169 #define TYPE_DIRECT 2 /* type with variable */
171 #define IO_BUF_SIZE 8192
173 typedef struct BufferedFile
{
174 unsigned char *buf_ptr
;
175 unsigned char *buf_end
;
177 int line_num
; /* current line number - here to simply code */
178 char filename
[1024]; /* current filename - here to simply code */
179 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
182 #define CH_EOB 0 /* end of buffer or '\0' char in file */
183 #define CH_EOF (-1) /* end of file */
186 struct BufferedFile
*file
;
187 int ch
, ch1
, tok
, tok1
;
191 Section
*first_section
;
193 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
194 Section
*cur_text_section
; /* current section where function code is
196 /* bound check related sections */
197 Section
*bounds_section
; /* contains global data bound description */
198 Section
*lbounds_section
; /* contains local data bound description */
200 Section
*stab_section
, *stabstr_section
, *symtab_section
, *strtab_section
;
202 /* loc : local variable index
203 ind : output code index
205 anon_sym: anonymous symbol index
208 prog
, ind
, loc
, const_wanted
;
209 int global_expr
; /* true if compound literals must be allocated
210 globally (used during initializers parsing */
211 int func_vt
, func_vc
; /* current function return type (used by
212 return instruction) */
213 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
215 TokenSym
**table_ident
;
216 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
217 char token_buf
[STRING_MAX_SIZE
+ 1];
219 /* contains global symbols which remain between each translation unit */
220 SymStack extern_stack
;
221 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
223 SValue vstack
[VSTACK_SIZE
], *vtop
;
224 int *macro_ptr
, *macro_ptr_allocated
;
225 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
], **include_stack_ptr
;
226 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
227 char *include_paths
[INCLUDE_PATHS_MAX
];
228 int nb_include_paths
;
229 int char_pointer_type
;
231 /* compile with debug symbol (and use them if error during execution) */
234 /* compile with built-in memory and bounds checker */
235 int do_bounds_check
= 0;
237 /* display benchmark infos */
242 /* use GNU C extensions */
245 /* use Tiny C extensions */
248 /* The current value can be: */
249 #define VT_VALMASK 0x00ff
250 #define VT_CONST 0x00f0 /* constant in vc
251 (must be first non register value) */
252 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
253 #define VT_LOCAL 0x00f2 /* offset on stack */
254 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
255 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
256 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
257 #define VT_LVAL 0x0100 /* var is an lvalue */
258 #define VT_FORWARD 0x0200 /* value is forward reference */
259 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
260 char/short stored in integer registers) */
261 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
262 dereferencing value */
265 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
267 #define VT_INT 0 /* integer type */
268 #define VT_BYTE 1 /* signed byte type */
269 #define VT_SHORT 2 /* short type */
270 #define VT_VOID 3 /* void type */
271 #define VT_PTR 4 /* pointer increment */
272 #define VT_ENUM 5 /* enum definition */
273 #define VT_FUNC 6 /* function type */
274 #define VT_STRUCT 7 /* struct/union definition */
275 #define VT_FLOAT 8 /* IEEE float */
276 #define VT_DOUBLE 9 /* IEEE double */
277 #define VT_LDOUBLE 10 /* IEEE long double */
278 #define VT_BOOL 11 /* ISOC99 boolean type */
279 #define VT_LLONG 12 /* 64 bit integer */
280 #define VT_LONG 13 /* long integer (NEVER USED as type, only
282 #define VT_BTYPE 0x000f /* mask for basic type */
283 #define VT_UNSIGNED 0x0010 /* unsigned type */
284 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
285 #define VT_BITFIELD 0x0040 /* bitfield modifier */
288 #define VT_EXTERN 0x00000080 /* extern definition */
289 #define VT_STATIC 0x00000100 /* static variable */
290 #define VT_TYPEDEF 0x00000200 /* typedef definition */
292 /* type mask (except storage) */
293 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
297 /* warning: the following compare tokens depend on i386 asm code */
309 #define TOK_LAND 0xa0
313 #define TOK_MID 0xa3 /* inc/dec, to void constant */
315 #define TOK_UDIV 0xb0 /* unsigned division */
316 #define TOK_UMOD 0xb1 /* unsigned modulo */
317 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
318 #define TOK_CINT 0xb3 /* number in tokc */
319 #define TOK_CCHAR 0xb4 /* char constant in tokc */
320 #define TOK_STR 0xb5 /* pointer to string in tokc */
321 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
322 #define TOK_LCHAR 0xb7
323 #define TOK_LSTR 0xb8
324 #define TOK_CFLOAT 0xb9 /* float constant */
325 #define TOK_CDOUBLE 0xc0 /* double constant */
326 #define TOK_CLDOUBLE 0xc1 /* long double constant */
327 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
328 #define TOK_ADDC1 0xc3 /* add with carry generation */
329 #define TOK_ADDC2 0xc4 /* add with carry use */
330 #define TOK_SUBC1 0xc5 /* add with carry generation */
331 #define TOK_SUBC2 0xc6 /* add with carry use */
332 #define TOK_CUINT 0xc8 /* unsigned int constant */
333 #define TOK_CLLONG 0xc9 /* long long constant */
334 #define TOK_CULLONG 0xca /* unsigned long long constant */
335 #define TOK_ARROW 0xcb
336 #define TOK_DOTS 0xcc /* three dots */
337 #define TOK_SHR 0xcd /* unsigned shift right */
339 #define TOK_SHL 0x01 /* shift left */
340 #define TOK_SAR 0x02 /* signed shift right */
342 /* assignement operators : normal operator or 0x80 */
343 #define TOK_A_MOD 0xa5
344 #define TOK_A_AND 0xa6
345 #define TOK_A_MUL 0xaa
346 #define TOK_A_ADD 0xab
347 #define TOK_A_SUB 0xad
348 #define TOK_A_DIV 0xaf
349 #define TOK_A_XOR 0xde
350 #define TOK_A_OR 0xfc
351 #define TOK_A_SHL 0x81
352 #define TOK_A_SAR 0x82
354 #define TOK_EOF (-1) /* end of file */
356 /* all identificators and strings have token above that */
357 #define TOK_IDENT 256
378 /* ignored types Must have contiguous values */
384 TOK___SIGNED__
, /* gcc keyword */
387 TOK___INLINE__
, /* gcc keyword */
390 /* unsupported type */
404 /* preprocessor only */
405 TOK_UIDENT
, /* first "user" ident (not keyword) */
406 TOK_DEFINE
= TOK_UIDENT
,
422 /* special identifiers */
425 /* attribute identifiers */
443 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
444 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
445 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
446 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
447 "sizeof\0__attribute__\0"
448 /* the following are not keywords. They are included to ease parsing */
449 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
450 "defined\0undef\0error\0line\0"
451 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
454 "section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0"
455 "cdecl\0__cdecl\0__cdecl__\0stdcall\0__stdcall\0__stdcall__\0"
456 "noreturn\0__noreturn__\0"
460 #define snprintf _snprintf
463 #if defined(WIN32) || defined(TCC_UCLIBC)
464 /* currently incorrect */
465 long double strtold(const char *nptr
, char **endptr
)
467 return (long double)strtod(nptr
, endptr
);
469 float strtof(const char *nptr
, char **endptr
)
471 return (float)strtod(nptr
, endptr
);
474 /* XXX: need to define this to use them in non ISOC99 context */
475 extern float strtof (const char *__nptr
, char **__endptr
);
476 extern long double strtold (const char *__nptr
, char **__endptr
);
479 char *pstrcpy(char *buf
, int buf_size
, const char *s
);
480 char *pstrcat(char *buf
, int buf_size
, const char *s
);
484 void next_nomacro(void);
485 int expr_const(void);
489 void decl_initializer(int t
, int r
, int c
, int first
, int size_only
);
490 int decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
);
492 void gv2(int rc1
, int rc2
);
493 void move_reg(int r
, int s
);
494 void save_regs(void);
495 void save_reg(int r
);
501 void macro_subst(int **tok_str
, int *tok_len
,
502 Sym
**nested_list
, int *macro_str
);
503 int save_reg_forced(int r
);
505 void force_charshort_cast(int t
);
506 void gen_cast(int t
);
508 Sym
*sym_find(int v
);
509 Sym
*sym_push(int v
, int t
, int r
, int c
);
512 int type_size(int t
, int *a
);
513 int pointed_type(int t
);
514 int pointed_size(int t
);
515 int is_compatible_types(int t1
, int t2
);
516 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
517 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
519 void error(const char *fmt
, ...);
520 void rt_error(unsigned long pc
, const char *fmt
, ...);
522 void vset(int t
, int r
, int v
);
523 void type_to_str(char *buf
, int buf_size
,
524 int t
, const char *varstr
);
526 /* section generation */
527 void greloc(Sym
*s
, int addr
, int type
);
528 static int put_elf_str(Section
*s
, const char *sym
);
529 static void put_elf_sym(Section
*s
,
530 unsigned long value
, unsigned long size
,
531 int info
, int other
, int shndx
, const char *name
);
532 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
);
533 static void put_stabn(int type
, int other
, int desc
, int value
);
534 static void put_stabd(int type
, int other
, int desc
);
536 /* true if float/double/long double type */
537 static inline int is_float(int t
)
541 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
544 #ifdef CONFIG_TCC_BCHECK
548 #ifdef TCC_TARGET_I386
549 #include "i386-gen.c"
555 #ifdef CONFIG_TCC_STATIC
557 #define RTLD_LAZY 0x001
558 #define RTLD_NOW 0x002
559 #define RTLD_GLOBAL 0x100
561 /* dummy function for profiling */
562 void *dlopen(const char *filename
, int flag
)
567 const char *dlerror(void)
572 typedef struct TCCSyms
{
577 #define TCCSYM(a) { #a, &a, },
579 /* add the symbol you want here if no dynamic linking is done */
580 static TCCSyms tcc_syms
[] = {
588 void *dlsym(void *handle
, const char *symbol
)
592 while (p
->str
!= NULL
) {
593 if (!strcmp(p
->str
, symbol
))
602 /********************************************************/
603 /* runtime library is there */
604 /* XXX: we suppose that the host compiler handles 'long long'. It
605 would not be difficult to suppress this assumption */
607 long long __divll(long long a
, long long b
)
612 long long __modll(long long a
, long long b
)
617 unsigned long long __divull(unsigned long long a
, unsigned long long b
)
622 unsigned long long __modull(unsigned long long a
, unsigned long long b
)
627 long long __sardi3(long long a
, int b
)
632 unsigned long long __shrdi3(unsigned long long a
, int b
)
637 long long __shldi3(long long a
, int b
)
642 float __ulltof(unsigned long long a
)
647 double __ulltod(unsigned long long a
)
652 long double __ulltold(unsigned long long a
)
654 return (long double)a
;
657 unsigned long long __ftoull(float a
)
659 return (unsigned long long)a
;
662 unsigned long long __dtoull(double a
)
664 return (unsigned long long)a
;
667 unsigned long long __ldtoull(long double a
)
669 return (unsigned long long)a
;
673 /********************************************************/
675 /* we use our own 'finite' function to avoid potential problems with
676 non standard math libs */
677 /* XXX: endianness dependant */
678 int ieee_finite(double d
)
681 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
684 /* copy a string and truncate it. */
685 char *pstrcpy(char *buf
, int buf_size
, const char *s
)
692 q_end
= buf
+ buf_size
- 1;
704 /* strcat and truncate. */
705 char *pstrcat(char *buf
, int buf_size
, const char *s
)
710 pstrcpy(buf
+ len
, buf_size
- len
, s
);
714 Section
*new_section(const char *name
, int sh_type
, int sh_flags
)
716 Section
*sec
, **psec
;
719 sec
= malloc(sizeof(Section
));
721 error("memory full");
722 memset(sec
, 0, sizeof(Section
));
723 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
725 sec
->sh_num
= ++section_num
;
726 sec
->sh_type
= sh_type
;
727 sec
->sh_flags
= sh_flags
;
729 /* XXX: currently, a single malloc */
730 data
= malloc(SECTION_VSIZE
);
732 error("could not alloc section '%s'", name
);
734 data
= mmap(NULL
, SECTION_VSIZE
,
735 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
736 MAP_PRIVATE
| MAP_ANONYMOUS
,
738 if (data
== (void *)(-1))
739 error("could not mmap section '%s'", name
);
742 sec
->data_ptr
= data
;
743 psec
= &first_section
;
744 while (*psec
!= NULL
)
745 psec
= &(*psec
)->next
;
751 /* return a reference to a section, and create it if it does not
753 Section
*find_section(const char *name
)
757 for(sec
= first_section
; sec
!= NULL
; sec
= sec
->next
) {
758 if (!strcmp(name
, sec
->name
))
761 /* sections are created as PROGBITS */
762 return new_section(name
, SHT_PROGBITS
, SHF_ALLOC
);
765 /* add a new relocation entry to symbol 's' */
766 void greloc(Sym
*s
, int addr
, int type
)
769 p
= malloc(sizeof(Reloc
));
771 error("memory full");
774 p
->next
= (Reloc
*)s
->c
;
778 /* patch each relocation entry with value 'val' */
779 void greloc_patch(Sym
*s
, int val
)
786 greloc_patch1(p
, val
);
795 static inline int isid(int c
)
797 return (c
>= 'a' && c
<= 'z') ||
798 (c
>= 'A' && c
<= 'Z') ||
802 static inline int isnum(int c
)
804 return c
>= '0' && c
<= '9';
807 static inline int toup(int c
)
809 if (ch
>= 'a' && ch
<= 'z')
810 return ch
- 'a' + 'A';
819 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
820 fprintf(stderr
, "In file included from %s:%d:\n",
821 (*f
)->filename
, (*f
)->line_num
);
822 fprintf(stderr
, "%s:%d: ", file
->filename
, file
->line_num
);
824 fprintf(stderr
, "tcc: ");
828 void error(const char *fmt
, ...)
833 vfprintf(stderr
, fmt
, ap
);
834 fprintf(stderr
, "\n");
839 void expect(const char *msg
)
841 error("%s expected", msg
);
844 void warning(const char *fmt
, ...)
850 fprintf(stderr
, "warning: ");
851 vfprintf(stderr
, fmt
, ap
);
852 fprintf(stderr
, "\n");
859 error("'%c' expected", c
);
863 void test_lvalue(void)
865 if (!(vtop
->r
& VT_LVAL
))
869 TokenSym
*tok_alloc(const char *str
, int len
)
871 TokenSym
*ts
, **pts
, **ptable
;
878 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
880 pts
= &hash_ident
[h
];
885 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
887 pts
= &(ts
->hash_next
);
890 if (tok_ident
>= SYM_FIRST_ANOM
)
891 error("memory full");
893 /* expand token table if needed */
894 i
= tok_ident
- TOK_IDENT
;
895 if ((i
% TOK_ALLOC_INCR
) == 0) {
896 ptable
= realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
898 error("memory full");
899 table_ident
= ptable
;
902 ts
= malloc(sizeof(TokenSym
) + len
);
904 error("memory full");
906 ts
->tok
= tok_ident
++;
908 ts
->hash_next
= NULL
;
909 memcpy(ts
->str
, str
, len
+ 1);
914 void add_char(char **pp
, int c
)
918 if (c
== '\'' || c
== '\"' || c
== '\\') {
919 /* XXX: could be more precise if char or string */
922 if (c
>= 32 && c
<= 126) {
929 *p
++ = '0' + ((c
>> 6) & 7);
930 *p
++ = '0' + ((c
>> 3) & 7);
931 *p
++ = '0' + (c
& 7);
937 /* XXX: buffer overflow */
938 char *get_tok_str(int v
, CValue
*cv
)
940 static char buf
[STRING_MAX_SIZE
+ 1];
945 if (v
== TOK_CINT
|| v
== TOK_CUINT
) {
946 sprintf(buf
, "%u", cv
->ui
);
948 } else if (v
== TOK_CCHAR
|| v
== TOK_LCHAR
) {
955 } else if (v
== TOK_STR
|| v
== TOK_LSTR
) {
959 for(i
=0;i
<ts
->len
;i
++)
960 add_char(&p
, ts
->str
[i
]);
964 } else if (v
< TOK_IDENT
) {
969 } else if (v
< tok_ident
) {
970 return table_ident
[v
- TOK_IDENT
]->str
;
972 /* should never happen */
977 /* push, without hashing */
978 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
981 s
= malloc(sizeof(Sym
));
983 error("memory full");
994 /* find a symbol and return its associated structure. 's' is the top
995 of the symbol stack */
996 Sym
*sym_find2(Sym
*s
, int v
)
1006 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1008 /* find a symbol and return its associated structure. 'st' is the
1010 Sym
*sym_find1(SymStack
*st
, int v
)
1014 s
= st
->hash
[HASH_SYM(v
)];
1023 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1026 s
= sym_push2(&st
->top
, v
, t
, c
);
1027 /* add in hash table */
1029 ps
= &st
->hash
[HASH_SYM(v
)];
1036 /* find a symbol in the right symbol space */
1037 Sym
*sym_find(int v
)
1040 s
= sym_find1(&local_stack
, v
);
1042 s
= sym_find1(&global_stack
, v
);
1046 /* push a given symbol on the symbol stack */
1047 Sym
*sym_push(int v
, int t
, int r
, int c
)
1050 if (local_stack
.top
)
1051 s
= sym_push1(&local_stack
, v
, t
, c
);
1053 s
= sym_push1(&global_stack
, v
, t
, c
);
1058 /* pop symbols until top reaches 'b' */
1059 void sym_pop(SymStack
*st
, Sym
*b
)
1066 /* free hash table entry, except if symbol was freed (only
1067 used for #undef symbols) */
1069 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1076 /* undefined a hashed symbol (used for #undef). Its name is set to
1078 void sym_undef(SymStack
*st
, Sym
*s
)
1081 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1082 while (*ss
!= NULL
) {
1085 ss
= &(*ss
)->hash_next
;
1093 BufferedFile
*tcc_open(const char *filename
)
1098 fd
= open(filename
, O_RDONLY
);
1101 bf
= malloc(sizeof(BufferedFile
));
1107 bf
->buf_ptr
= bf
->buffer
;
1108 bf
->buf_end
= bf
->buffer
;
1109 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1110 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1112 // printf("opening '%s'\n", filename);
1116 void tcc_close(BufferedFile
*bf
)
1118 total_lines
+= bf
->line_num
;
1123 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1124 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1126 /* fill input buffer and return next char */
1127 int tcc_getc_slow(BufferedFile
*bf
)
1130 /* only tries to read if really end of buffer */
1131 if (bf
->buf_ptr
>= bf
->buf_end
) {
1133 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1140 bf
->buf_ptr
= bf
->buffer
;
1141 bf
->buf_end
= bf
->buffer
+ len
;
1142 *bf
->buf_end
= CH_EOB
;
1144 if (bf
->buf_ptr
< bf
->buf_end
) {
1145 return *bf
->buf_ptr
++;
1147 bf
->buf_ptr
= bf
->buf_end
;
1152 /* no need to put that inline */
1153 void handle_eob(void)
1156 ch1
= tcc_getc_slow(file
);
1160 if (include_stack_ptr
== include_stack
)
1162 /* add end of include file debug info */
1164 put_stabd(N_EINCL
, 0, 0);
1166 /* pop include stack */
1168 include_stack_ptr
--;
1169 file
= *include_stack_ptr
;
1173 /* read next char from current input file */
1174 static inline void inp(void)
1176 ch1
= TCC_GETC(file
);
1177 /* end of buffer/file handling */
1182 // printf("ch1=%c 0x%x\n", ch1, ch1);
1185 /* input with '\\n' handling */
1186 static inline void minp(void)
1191 if (ch
== '\\' && ch1
== '\n') {
1195 //printf("ch=%c 0x%x\n", ch, ch);
1199 /* same as minp, but also skip comments */
1207 /* single line C++ comments */
1209 while (ch1
!= '\n' && ch1
!= -1)
1212 ch
= ' '; /* return space */
1213 } else if (ch1
== '*') {
1219 if (c
== '*' && ch1
== '/') {
1221 ch
= ' '; /* return space */
1233 void skip_spaces(void)
1235 while (ch
== ' ' || ch
== '\t')
1239 /* skip block of text until #else, #elif or #endif. skip also pairs of
1241 void preprocess_skip(void)
1246 while (ch
!= '\n') {
1257 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1259 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1261 else if (tok
== TOK_ENDIF
)
1267 /* return the number of additionnal 'ints' necessary to store the
1269 static inline int tok_ext_size(int t
)
1286 return LDOUBLE_SIZE
/ 4;
1292 void tok_add(int **tok_str
, int *tok_len
, int t
)
1297 if ((len
& 63) == 0) {
1298 str
= realloc(str
, (len
+ 64) * sizeof(int));
1307 void tok_add2(int **tok_str
, int *tok_len
, int t
, CValue
*cv
)
1311 tok_add(tok_str
, tok_len
, t
);
1312 n
= tok_ext_size(t
);
1314 tok_add(tok_str
, tok_len
, cv
->tab
[i
]);
1317 /* get a token from an integer array and increment pointer accordingly */
1318 int tok_get(int **tok_str
, CValue
*cv
)
1324 n
= tok_ext_size(t
);
1331 /* eval an expression for #if/#elif */
1332 int expr_preprocess(void)
1334 int *str
, len
, c
, t
;
1342 next(); /* do macro subst */
1343 if (tok
== TOK_DEFINED
) {
1348 c
= sym_find1(&define_stack
, tok
) != 0;
1353 } else if (tok
>= TOK_IDENT
) {
1354 /* if undefined macro */
1358 tok_add2(&str
, &len
, tok
, &tokc
);
1360 tok_add(&str
, &len
, -1); /* simulate end of file */
1361 tok_add(&str
, &len
, 0);
1362 /* now evaluate C constant expression */
1371 #if defined(DEBUG) || defined(PP_DEBUG)
1372 void tok_print(int *str
)
1378 t
= tok_get(&str
, &cval
);
1381 printf(" %s", get_tok_str(t
, &cval
));
1387 /* parse after #define */
1388 void parse_define(void)
1390 Sym
*s
, *first
, **ps
;
1391 int v
, t
, *str
, len
;
1394 /* XXX: should check if same macro (ANSI) */
1397 /* '(' must be just after macro definition for MACRO_FUNC */
1402 while (tok
!= ')') {
1403 if (tok
== TOK_DOTS
)
1404 tok
= TOK___VA_ARGS__
;
1405 s
= sym_push1(&define_stack
, tok
| SYM_FIELD
, 0, 0);
1419 if (ch
== '\n' || ch
== -1)
1422 tok_add2(&str
, &len
, tok
, &tokc
);
1424 tok_add(&str
, &len
, 0);
1426 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1429 s
= sym_push1(&define_stack
, v
, t
, (int)str
);
1433 void preprocess(void)
1436 char buf
[1024], *q
, *p
;
1444 if (tok
== TOK_DEFINE
) {
1447 } else if (tok
== TOK_UNDEF
) {
1449 s
= sym_find1(&define_stack
, tok
);
1450 /* undefine symbol by putting an invalid name */
1452 sym_undef(&define_stack
, s
);
1453 } else if (tok
== TOK_INCLUDE
) {
1458 } else if (ch
== '\"') {
1463 while (ch
!= c
&& ch
!= '\n' && ch
!= -1) {
1464 if ((q
- buf
) < sizeof(buf
) - 1)
1472 error("#include syntax error");
1473 pstrcpy(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
1476 /* eat all spaces and comments after include */
1477 /* XXX: slightly incorrect */
1478 while (ch1
!= '\n' && ch1
!= -1)
1481 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1482 error("memory full");
1484 /* first search in current dir if "header.h" */
1486 p
= strrchr(file
->filename
, '/');
1488 size
= p
+ 1 - file
->filename
;
1489 if (size
> sizeof(buf1
) - 1)
1490 size
= sizeof(buf1
) - 1;
1491 memcpy(buf1
, file
->filename
, size
);
1493 pstrcat(buf1
, sizeof(buf1
), buf
);
1498 /* now search in standard include path */
1499 for(i
=nb_include_paths
- 1;i
>=0;i
--) {
1500 strcpy(buf1
, include_paths
[i
]);
1507 error("include file '%s' not found", buf1
);
1510 /* push current file in stack */
1511 /* XXX: fix current line init */
1512 *include_stack_ptr
++ = file
;
1514 /* add include file debug info */
1516 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
1518 } else if (tok
== TOK_IFNDEF
) {
1521 } else if (tok
== TOK_IF
) {
1522 c
= expr_preprocess();
1524 } else if (tok
== TOK_IFDEF
) {
1528 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1530 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1531 error("memory full");
1532 *ifdef_stack_ptr
++ = c
;
1534 } else if (tok
== TOK_ELSE
) {
1535 if (ifdef_stack_ptr
== ifdef_stack
)
1536 error("#else without matching #if");
1537 if (ifdef_stack_ptr
[-1] & 2)
1538 error("#else after #else");
1539 c
= (ifdef_stack_ptr
[-1] ^= 3);
1541 } else if (tok
== TOK_ELIF
) {
1542 if (ifdef_stack_ptr
== ifdef_stack
)
1543 error("#elif without matching #if");
1544 c
= ifdef_stack_ptr
[-1];
1546 error("#elif after #else");
1547 /* last #if/#elif expression was true: we skip */
1550 c
= expr_preprocess();
1551 ifdef_stack_ptr
[-1] = c
;
1558 } else if (tok
== TOK_ENDIF
) {
1559 if (ifdef_stack_ptr
== ifdef_stack
)
1560 error("#endif without matching #if");
1562 } else if (tok
== TOK_LINE
) {
1564 if (tok
!= TOK_CINT
)
1566 file
->line_num
= tokc
.i
;
1572 pstrcpy(file
->filename
, sizeof(file
->filename
),
1573 get_tok_str(tok
, &tokc
));
1575 } else if (tok
== TOK_ERROR
) {
1578 /* ignore other preprocess commands or #! for C scripts */
1579 while (ch
!= '\n' && ch
!= -1)
1583 /* read a number in base b */
1589 if (ch
>= 'a' && ch
<= 'f')
1591 else if (ch
>= 'A' && ch
<= 'F')
1597 if (t
< 0 || t
>= b
)
1605 /* read a character for string or char constant and eval escape codes */
1614 /* at most three octal digits */
1618 c
= c
* 8 + ch
- '0';
1621 c
= c
* 8 + ch
- '0';
1626 } else if (ch
== 'x') {
1644 else if (ch
== 'e' && gnu_ext
)
1646 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
1649 error("invalid escaped char");
1656 /* we use 64 bit numbers */
1659 /* bn = (bn << shift) | or_val */
1660 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
1664 for(i
=0;i
<BN_SIZE
;i
++) {
1666 bn
[i
] = (v
<< shift
) | or_val
;
1667 or_val
= v
>> (32 - shift
);
1671 void bn_zero(unsigned int *bn
)
1674 for(i
=0;i
<BN_SIZE
;i
++) {
1679 void parse_number(void)
1681 int b
, t
, shift
, frac_bits
, s
, exp_val
;
1683 unsigned int bn
[BN_SIZE
];
1693 /* special dot handling */
1694 if (ch
>= '0' && ch
<= '9') {
1695 goto float_frac_parse
;
1696 } else if (ch
== '.') {
1707 } else if (t
== '0') {
1708 if (ch
== 'x' || ch
== 'X') {
1712 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
1718 /* parse all digits. cannot check octal numbers at this stage
1719 because of floating point constants */
1721 if (ch
>= 'a' && ch
<= 'f')
1723 else if (ch
>= 'A' && ch
<= 'F')
1731 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
1733 error("number too long");
1739 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
1740 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
1742 /* NOTE: strtox should support that for hexa numbers, but
1743 non ISOC99 libcs do not support it, so we prefer to do
1745 /* hexadecimal or binary floats */
1746 /* XXX: handle overflows */
1758 } else if (t
>= 'a') {
1760 } else if (t
>= 'A') {
1765 bn_lshift(bn
, shift
, t
);
1772 if (t
>= 'a' && t
<= 'f') {
1774 } else if (t
>= 'A' && t
<= 'F') {
1776 } else if (t
>= '0' && t
<= '9') {
1782 error("invalid digit");
1783 bn_lshift(bn
, shift
, t
);
1788 if (ch
!= 'p' && ch
!= 'P')
1789 error("exponent expected");
1795 } else if (ch
== '-') {
1799 if (ch
< '0' || ch
> '9')
1800 error("exponent digits expected");
1801 while (ch
>= '0' && ch
<= '9') {
1802 exp_val
= exp_val
* 10 + ch
- '0';
1805 exp_val
= exp_val
* s
;
1807 /* now we can generate the number */
1808 /* XXX: should patch directly float number */
1809 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
1810 d
= ldexp(d
, exp_val
- frac_bits
);
1815 /* float : should handle overflow */
1817 } else if (t
== 'L') {
1820 /* XXX: not large enough */
1821 tokc
.ld
= (long double)d
;
1827 /* decimal floats */
1829 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1834 while (ch
>= '0' && ch
<= '9') {
1835 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1841 if (ch
== 'e' || ch
== 'E') {
1842 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1846 if (ch
== '-' || ch
== '+') {
1847 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1852 if (ch
< '0' || ch
> '9')
1853 error("exponent digits expected");
1854 while (ch
>= '0' && ch
<= '9') {
1855 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1867 tokc
.f
= strtof(token_buf
, NULL
);
1868 } else if (t
== 'L') {
1871 tokc
.ld
= strtold(token_buf
, NULL
);
1874 tokc
.d
= strtod(token_buf
, NULL
);
1878 unsigned long long n
, n1
;
1881 /* integer number */
1884 if (b
== 10 && *q
== '0') {
1891 /* no need for checks except for base 10 / 8 errors */
1894 } else if (t
>= 'a') {
1896 } else if (t
>= 'A') {
1901 error("invalid digit");
1905 /* detect overflow */
1907 error("integer constant overflow");
1910 /* XXX: not exactly ANSI compliant */
1911 if ((n
& 0xffffffff00000000LL
) != 0) {
1916 } else if (n
> 0x7fffffff) {
1926 error("three 'l' in integer constant");
1929 if (tok
== TOK_CINT
)
1931 else if (tok
== TOK_CUINT
)
1935 } else if (t
== 'U') {
1936 if (tok
== TOK_CINT
)
1938 else if (tok
== TOK_CLLONG
)
1945 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
1953 /* return next token without macro substitution */
1954 void next_nomacro1(void)
1962 while (ch
== '\n') {
1964 while (ch
== ' ' || ch
== '\t')
1967 /* preprocessor command if # at start of line after
1972 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
1990 while (isid(ch
) || isnum(ch
)) {
1991 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1992 error("ident too long");
1997 ts
= tok_alloc(token_buf
, q
- token_buf
);
1999 } else if (isnum(ch
) || ch
== '.') {
2001 } else if (ch
== '\'') {
2009 } else if (ch
== '\"') {
2014 while (ch
!= '\"') {
2017 error("unterminated string");
2018 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2019 error("string too long");
2023 tokc
.ts
= tok_alloc(token_buf
, q
- token_buf
);
2026 q
= "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2031 if (*q
== tok
&& q
[1] == ch
) {
2034 /* three chars tests */
2035 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2040 } else if (tok
== TOK_DOTS
) {
2042 error("parse error");
2049 /* single char substitutions */
2052 else if (tok
== '>')
2057 /* return next token without macro substitution. Can read input from
2064 tok
= tok_get(¯o_ptr
, &tokc
);
2070 /* substitute args in macro_str and return allocated string */
2071 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2073 int *st
, last_tok
, t
, notfirst
, *str
, len
;
2082 t
= tok_get(¯o_str
, &cval
);
2087 t
= tok_get(¯o_str
, &cval
);
2090 s
= sym_find2(args
, t
);
2092 token_buf
[0] = '\0';
2097 pstrcat(token_buf
, sizeof(token_buf
), " ");
2098 t
= tok_get(&st
, &cval
);
2099 pstrcat(token_buf
, sizeof(token_buf
), get_tok_str(t
, &cval
));
2103 printf("stringize: %s\n", token_buf
);
2106 ts
= tok_alloc(token_buf
, 0);
2108 tok_add2(&str
, &len
, TOK_STR
, &cval
);
2110 tok_add2(&str
, &len
, t
, &cval
);
2112 } else if (t
>= TOK_IDENT
) {
2113 s
= sym_find2(args
, t
);
2116 /* if '##' is present before or after , no arg substitution */
2117 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2119 tok_add(&str
, &len
, *st
++);
2121 macro_subst(&str
, &len
, nested_list
, st
);
2124 tok_add(&str
, &len
, t
);
2127 tok_add2(&str
, &len
, t
, &cval
);
2131 tok_add(&str
, &len
, 0);
2135 /* handle the '##' operator */
2136 int *macro_twosharps(int *macro_str
)
2139 int *macro_str1
, macro_str1_len
, *macro_ptr1
;
2151 while (*macro_ptr
== TOK_TWOSHARPS
) {
2153 macro_ptr1
= macro_ptr
;
2156 t
= tok_get(¯o_ptr
, &cval
);
2157 /* XXX: we handle only most common cases:
2158 ident + ident or ident + number */
2159 if (tok
>= TOK_IDENT
&&
2160 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
2161 p
= get_tok_str(tok
, &tokc
);
2162 pstrcpy(token_buf
, sizeof(token_buf
), p
);
2163 p
= get_tok_str(t
, &cval
);
2164 pstrcat(token_buf
, sizeof(token_buf
), p
);
2165 ts
= tok_alloc(token_buf
, 0);
2166 tok
= ts
->tok
; /* modify current token */
2168 /* cannot merge tokens: skip '##' */
2169 macro_ptr
= macro_ptr1
;
2174 tok_add2(¯o_str1
, ¯o_str1_len
, tok
, &tokc
);
2176 tok_add(¯o_str1
, ¯o_str1_len
, 0);
2182 /* do macro substitution of macro_str and add result to
2183 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2184 substituted. 'nested_list' is the list of all macros we got inside
2185 to avoid recursing. */
2186 void macro_subst(int **tok_str
, int *tok_len
,
2187 Sym
**nested_list
, int *macro_str
)
2189 Sym
*s
, *args
, *sa
, *sa1
;
2190 int *str
, parlevel
, len
, *mstr
, t
, *saved_macro_ptr
;
2191 int mstr_allocated
, *macro_str1
;
2194 saved_macro_ptr
= macro_ptr
;
2195 macro_ptr
= macro_str
;
2198 /* first scan for '##' operator handling */
2199 macro_str1
= macro_twosharps(macro_str
);
2200 macro_ptr
= macro_str1
;
2207 /* special macros */
2208 if (tok
== TOK___LINE__
) {
2209 cval
.i
= file
->line_num
;
2210 tok_add2(tok_str
, tok_len
, TOK_CINT
, &cval
);
2211 } else if (tok
== TOK___FILE__
) {
2212 cval
.ts
= tok_alloc(file
->filename
, 0);
2213 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
2214 } else if (tok
== TOK___DATE__
) {
2215 cval
.ts
= tok_alloc("Jan 1 1970", 0);
2216 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
2217 } else if (tok
== TOK___TIME__
) {
2218 cval
.ts
= tok_alloc("00:00:00", 0);
2219 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
2220 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
2221 /* if symbol is a macro, prepare substitution */
2222 /* if nested substitution, do nothing */
2223 if (sym_find2(*nested_list
, tok
))
2227 if (s
->t
== MACRO_FUNC
) {
2228 /* NOTE: we do not use next_nomacro to avoid eating the
2229 next token. XXX: find better solution */
2233 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
2237 if (t
!= '(') /* no macro subst */
2240 /* argument macro */
2245 /* NOTE: empty args are allowed, except if no args */
2247 /* handle '()' case */
2248 if (!args
&& tok
== ')')
2251 error("macro '%s' used with too many args",
2252 get_tok_str(s
->v
, 0));
2256 while ((parlevel
> 0 ||
2259 sa
->v
== (TOK___VA_ARGS__
| SYM_FIELD
)))) &&
2263 else if (tok
== ')')
2265 tok_add2(&str
, &len
, tok
, &tokc
);
2268 tok_add(&str
, &len
, 0);
2269 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, 0, (int)str
);
2278 error("macro '%s' used with too few args",
2279 get_tok_str(s
->v
, 0));
2281 /* now subst each arg */
2282 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2293 sym_push2(nested_list
, s
->v
, 0, 0);
2294 macro_subst(tok_str
, tok_len
, nested_list
, mstr
);
2295 /* pop nested defined symbol */
2297 *nested_list
= sa1
->prev
;
2303 /* no need to add if reading input stream */
2306 tok_add2(tok_str
, tok_len
, tok
, &tokc
);
2308 /* only replace one macro while parsing input stream */
2312 macro_ptr
= saved_macro_ptr
;
2317 /* return next token with macro substitution */
2323 /* special 'ungettok' case for label parsing */
2331 /* if not reading from macro substituted string, then try to substitute */
2335 macro_subst(&ptr
, &len
, &nested_list
, NULL
);
2337 tok_add(&ptr
, &len
, 0);
2339 macro_ptr_allocated
= ptr
;
2347 /* end of macro string: free it */
2348 free(macro_ptr_allocated
);
2355 printf("token = %s\n", get_tok_str(tok
, tokc
));
2359 void swap(int *p
, int *q
)
2367 void vsetc(int t
, int r
, CValue
*vc
)
2369 if (vtop
>= vstack
+ VSTACK_SIZE
)
2370 error("memory full");
2371 /* cannot let cpu flags if other instruction are generated */
2372 /* XXX: VT_JMP test too ? */
2373 if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
2378 vtop
->r2
= VT_CONST
;
2382 /* push integer constant */
2387 vsetc(VT_INT
, VT_CONST
, &cval
);
2390 void vset(int t
, int r
, int v
)
2407 void vpushv(SValue
*v
)
2409 if (vtop
>= vstack
+ VSTACK_SIZE
)
2410 error("memory full");
2420 /* save r to the memory stack, and mark it as being free */
2421 void save_reg(int r
)
2423 int l
, i
, saved
, t
, size
, align
;
2426 /* modify all stack values */
2429 for(p
=vstack
;p
<=vtop
;p
++) {
2430 i
= p
->r
& VT_VALMASK
;
2431 if ((p
->r
& VT_VALMASK
) == r
||
2432 (p
->r2
& VT_VALMASK
) == r
) {
2433 /* must save value on stack if not already done */
2435 /* store register in the stack */
2437 if ((p
->r
& VT_LVAL
) ||
2438 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
2440 size
= type_size(t
, &align
);
2441 loc
= (loc
- size
) & -align
;
2443 sv
.r
= VT_LOCAL
| VT_LVAL
;
2446 #ifdef TCC_TARGET_I386
2447 /* x86 specific: need to pop fp register ST0 if saved */
2449 o(0xd9dd); /* fstp %st(1) */
2452 /* special long long case */
2453 if ((p
->t
& VT_BTYPE
) == VT_LLONG
) {
2460 /* mark that stack entry as being saved on the stack */
2472 /* find a free register of class 'rc'. If none, save one register */
2478 /* find a free register */
2479 for(r
=0;r
<NB_REGS
;r
++) {
2480 if (reg_classes
[r
] & rc
) {
2481 for(p
=vstack
;p
<=vtop
;p
++) {
2482 if ((p
->r
& VT_VALMASK
) == r
||
2483 (p
->r2
& VT_VALMASK
) == r
)
2491 /* no register left : free the first one on the stack (VERY
2492 IMPORTANT to start from the bottom to ensure that we don't
2493 spill registers used in gen_opi()) */
2494 for(p
=vstack
;p
<=vtop
;p
++) {
2495 r
= p
->r
& VT_VALMASK
;
2496 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
2504 void save_regs(void)
2509 for(p
=vstack
;p
<=vtop
;p
++) {
2510 r
= p
->r
& VT_VALMASK
;
2517 /* move register 's' to 'r', and flush previous value of r to memory
2519 void move_reg(int r
, int s
)
2532 /* get address of vtop (vtop MUST BE an lvalue) */
2535 vtop
->r
&= ~VT_LVAL
;
2536 /* tricky: if saved lvalue, then we can go back to lvalue */
2537 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
2538 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
2541 #ifdef CONFIG_TCC_BCHECK
2542 /* generate lvalue bound code */
2545 vtop
->r
&= ~VT_MUSTBOUND
;
2546 /* if lvalue, then use checking code before dereferencing */
2547 if (vtop
->r
& VT_LVAL
) {
2550 gen_bounded_ptr_add1();
2551 gen_bounded_ptr_add2(1);
2557 /* store vtop a register belonging to class 'rc'. lvalues are
2558 converted to values. Cannot be used if cannot be converted to
2559 register value (such as structures). */
2562 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
, data_offset
;
2563 unsigned long long ll
;
2565 /* NOTE: get_reg can modify vstack[] */
2566 if (vtop
->t
& VT_BITFIELD
) {
2567 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2568 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2569 /* remove bit field info to avoid loops */
2570 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2571 /* generate shifts */
2572 vpushi(32 - (bit_pos
+ bit_size
));
2574 vpushi(32 - bit_size
);
2575 /* NOTE: transformed to SHR if unsigned */
2579 if (is_float(vtop
->t
) &&
2580 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2581 /* CPUs usually cannot use float constants, so we store them
2582 generically in data segment */
2583 size
= type_size(vtop
->t
, &align
);
2584 data_offset
= (int)data_section
->data_ptr
;
2585 data_offset
= (data_offset
+ align
- 1) & -align
;
2586 /* XXX: not portable yet */
2589 ((int *)data_offset
)[i
] = vtop
->c
.tab
[i
];
2591 vtop
->c
.ul
= data_offset
;
2592 data_offset
+= size
<< 2;
2593 data_section
->data_ptr
= (unsigned char *)data_offset
;
2595 #ifdef CONFIG_TCC_BCHECK
2596 if (vtop
->r
& VT_MUSTBOUND
)
2600 r
= vtop
->r
& VT_VALMASK
;
2601 /* need to reload if:
2603 - lvalue (need to dereference pointer)
2604 - already a register, but not in the right class */
2605 if (r
>= VT_CONST
||
2606 (vtop
->r
& VT_LVAL
) ||
2607 !(reg_classes
[r
] & rc
) ||
2608 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
2609 !(reg_classes
[vtop
->r2
] & rc
))) {
2611 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
2612 /* two register type load : expand to two words
2614 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2617 vtop
->c
.ui
= ll
; /* first word */
2619 vtop
->r
= r
; /* save register value */
2620 vpushi(ll
>> 32); /* second word */
2621 } else if (r
>= VT_CONST
||
2622 (vtop
->r
& VT_LVAL
)) {
2623 /* load from memory */
2626 vtop
[-1].r
= r
; /* save register value */
2627 /* increment pointer to get second word */
2634 /* move registers */
2637 vtop
[-1].r
= r
; /* save register value */
2638 vtop
->r
= vtop
[-1].r2
;
2640 /* allocate second register */
2647 /* write second register */
2650 /* one register type load */
2659 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2660 void gv2(int rc1
, int rc2
)
2662 /* generate more generic register first */
2668 /* test if reload is needed for first register */
2669 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2679 /* test if reload is needed for first register */
2680 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2686 /* expand long long on stack in two int registers */
2691 u
= vtop
->t
& VT_UNSIGNED
;
2694 vtop
[0].r
= vtop
[-1].r2
;
2695 vtop
[0].r2
= VT_CONST
;
2696 vtop
[-1].r2
= VT_CONST
;
2697 vtop
[0].t
= VT_INT
| u
;
2698 vtop
[-1].t
= VT_INT
| u
;
2701 /* build a long long from two ints */
2704 gv2(RC_INT
, RC_INT
);
2705 vtop
[-1].r2
= vtop
[0].r
;
2710 /* rotate n first stack elements to the bottom */
2717 for(i
=-n
+1;i
!=0;i
++)
2718 vtop
[i
] = vtop
[i
+1];
2722 /* pop stack value */
2725 #ifdef TCC_TARGET_I386
2726 /* for x86, we need to pop the FP stack */
2727 if ((vtop
->r
& VT_VALMASK
) == REG_ST0
) {
2728 o(0xd9dd); /* fstp %st(1) */
2734 /* convert stack entry to register and duplicate its value in another
2742 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2749 /* stack: H L L1 H1 */
2757 /* duplicate value */
2768 load(r1
, &sv
); /* move r to r1 */
2770 /* duplicates value */
2775 /* generate CPU independent (unsigned) long long operations */
2776 void gen_opl(int op
)
2778 int t
, a
, b
, op1
, c
, i
;
2797 /* call generic long long function */
2798 gfunc_start(&gf
, FUNC_CDECL
);
2805 vtop
->r2
= REG_LRET
;
2818 /* stack: L1 H1 L2 H2 */
2823 vtop
[-2] = vtop
[-3];
2826 /* stack: H1 H2 L1 L2 */
2832 /* stack: H1 H2 L1 L2 ML MH */
2835 /* stack: ML MH H1 H2 L1 L2 */
2839 /* stack: ML MH H1 L2 H2 L1 */
2844 /* stack: ML MH M1 M2 */
2847 } else if (op
== '+' || op
== '-') {
2848 /* XXX: add non carry method too (for MIPS or alpha) */
2854 /* stack: H1 H2 (L1 op L2) */
2857 gen_op(op1
+ 1); /* TOK_xxxC2 */
2860 /* stack: H1 H2 (L1 op L2) */
2863 /* stack: (L1 op L2) H1 H2 */
2865 /* stack: (L1 op L2) (H1 op H2) */
2873 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
) {
2878 /* stack: L H shift */
2880 /* constant: simpler */
2881 /* NOTE: all comments are for SHL. the other cases are
2882 done by swaping words */
2893 if (op
!= TOK_SAR
) {
2923 /* XXX: should provide a faster fallback on x86 ? */
2938 /* compare operations */
2944 /* stack: L1 H1 L2 H2 */
2946 vtop
[-1] = vtop
[-2];
2948 /* stack: L1 L2 H1 H2 */
2951 /* when values are equal, we need to compare low words. since
2952 the jump is inverted, we invert the test too. */
2955 else if (op1
== TOK_GT
)
2957 else if (op1
== TOK_ULT
)
2959 else if (op1
== TOK_UGT
)
2964 if (op1
!= TOK_NE
) {
2968 /* generate non equal test */
2969 /* XXX: NOT PORTABLE yet */
2973 #ifdef TCC_TARGET_I386
2974 b
= psym(0x850f, 0);
2976 error("not implemented");
2984 vset(VT_INT
, VT_JMPI
, a
);
2989 /* handle integer constant optimizations and various machine
2991 void gen_opic(int op
)
2998 /* currently, we cannot do computations with forward symbols */
2999 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
3000 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
3004 case '+': v1
->c
.i
+= fc
; break;
3005 case '-': v1
->c
.i
-= fc
; break;
3006 case '&': v1
->c
.i
&= fc
; break;
3007 case '^': v1
->c
.i
^= fc
; break;
3008 case '|': v1
->c
.i
|= fc
; break;
3009 case '*': v1
->c
.i
*= fc
; break;
3016 /* if division by zero, generate explicit division */
3019 error("division by zero in constant");
3023 default: v1
->c
.i
/= fc
; break;
3024 case '%': v1
->c
.i
%= fc
; break;
3025 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3026 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3029 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3030 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3031 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3033 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3034 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3035 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3036 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3037 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3038 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3039 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3040 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3041 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3042 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3044 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3045 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3051 /* if commutative ops, put c2 as constant */
3052 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3053 op
== '|' || op
== '*')) {
3058 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3061 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3062 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3068 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3069 /* try to use shifts instead of muls or divs */
3070 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3079 else if (op
== TOK_PDIV
)
3087 /* call low level op generator */
3093 /* generate a floating point operation with constant propagation */
3094 void gen_opif(int op
)
3102 /* currently, we cannot do computations with forward symbols */
3103 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
3104 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
3106 if (v1
->t
== VT_FLOAT
) {
3109 } else if (v1
->t
== VT_DOUBLE
) {
3117 /* NOTE: we only do constant propagation if finite number (not
3118 NaN or infinity) (ANSI spec) */
3119 if (!ieee_finite(f1
) || !ieee_finite(f2
))
3123 case '+': f1
+= f2
; break;
3124 case '-': f1
-= f2
; break;
3125 case '*': f1
*= f2
; break;
3129 error("division by zero in constant");
3134 /* XXX: also handles tests ? */
3138 /* XXX: overflow test ? */
3139 if (v1
->t
== VT_FLOAT
) {
3141 } else if (v1
->t
== VT_DOUBLE
) {
3154 int pointed_size(int t
)
3156 return type_size(pointed_type(t
), &t
);
3160 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3162 char buf1
[256], buf2
[256];
3166 if (!is_compatible_types(t1
, t2
)) {
3167 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3168 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3169 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3174 /* generic gen_op: handles types problems */
3177 int u
, t1
, t2
, bt1
, bt2
, t
;
3181 bt1
= t1
& VT_BTYPE
;
3182 bt2
= t2
& VT_BTYPE
;
3184 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3185 /* at least one operand is a pointer */
3186 /* relationnal op: must be both pointers */
3187 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3188 // check_pointer_types(vtop, vtop - 1);
3189 /* pointers are handled are unsigned */
3190 t
= VT_INT
| VT_UNSIGNED
;
3193 /* if both pointers, then it must be the '-' op */
3194 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3195 (t2
& VT_BTYPE
) == VT_PTR
) {
3197 error("cannot use pointers here");
3198 // check_pointer_types(vtop - 1, vtop);
3199 /* XXX: check that types are compatible */
3200 u
= pointed_size(t1
);
3202 /* set to integer type */
3207 /* exactly one pointer : must be '+' or '-'. */
3208 if (op
!= '-' && op
!= '+')
3209 error("cannot use pointers here");
3210 /* Put pointer as first operand */
3211 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3215 /* XXX: cast to int ? (long long case) */
3216 vpushi(pointed_size(vtop
[-1].t
));
3218 #ifdef CONFIG_TCC_BCHECK
3219 /* if evaluating constant expression, no code should be
3220 generated, so no bound check */
3221 if (do_bounds_check
&& !const_wanted
) {
3222 /* if bounded pointers, we generate a special code to
3229 gen_bounded_ptr_add1();
3230 gen_bounded_ptr_add2(0);
3236 /* put again type if gen_opic() swaped operands */
3239 } else if (is_float(bt1
) || is_float(bt2
)) {
3240 /* compute bigger type and do implicit casts */
3241 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3243 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3248 /* floats can only be used for a few operations */
3249 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3250 (op
< TOK_ULT
|| op
> TOK_GT
))
3251 error("invalid operands for binary operation");
3253 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3254 /* cast to biggest op */
3256 /* convert to unsigned if it does not fit in a long long */
3257 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3258 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
3262 /* integer operations */
3264 /* convert to unsigned if it does not fit in an integer */
3265 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
3266 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3269 /* XXX: currently, some unsigned operations are explicit, so
3270 we modify them here */
3271 if (t
& VT_UNSIGNED
) {
3278 else if (op
== TOK_LT
)
3280 else if (op
== TOK_GT
)
3282 else if (op
== TOK_LE
)
3284 else if (op
== TOK_GE
)
3290 /* special case for shifts and long long: we keep the shift as
3292 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3298 else if ((t
& VT_BTYPE
) == VT_LLONG
)
3302 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3303 /* relationnal op: the result is an int */
3311 /* generic itof for unsigned long long case */
3312 void gen_cvt_itof1(int t
)
3316 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3317 (VT_LLONG
| VT_UNSIGNED
)) {
3319 gfunc_start(&gf
, FUNC_CDECL
);
3322 vpushi((int)&__ulltof
);
3323 else if (t
== VT_DOUBLE
)
3324 vpushi((int)&__ulltod
);
3326 vpushi((int)&__ulltold
);
3335 /* generic ftoi for unsigned long long case */
3336 void gen_cvt_ftoi1(int t
)
3341 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3342 /* not handled natively */
3343 gfunc_start(&gf
, FUNC_CDECL
);
3344 st
= vtop
->t
& VT_BTYPE
;
3347 vpushi((int)&__ftoull
);
3348 else if (st
== VT_DOUBLE
)
3349 vpushi((int)&__dtoull
);
3351 vpushi((int)&__ldtoull
);
3355 vtop
->r2
= REG_LRET
;
3361 /* force char or short cast */
3362 void force_charshort_cast(int t
)
3366 /* XXX: add optimization if lvalue : just change type and offset */
3371 if (t
& VT_UNSIGNED
) {
3372 vpushi((1 << bits
) - 1);
3383 /* cast 'vtop' to 't' type */
3384 void gen_cast(int t
)
3386 int sbt
, dbt
, sf
, df
, c
, st1
, dt1
;
3388 /* special delayed cast for char/short */
3389 /* XXX: in some cases (multiple cascaded casts), it may still
3391 if (vtop
->r
& VT_MUSTCAST
) {
3392 vtop
->r
&= ~VT_MUSTCAST
;
3393 force_charshort_cast(vtop
->t
);
3397 sbt
= vtop
->t
& VT_BTYPE
;
3402 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
3404 /* convert from fp to fp */
3406 /* constant case: we can do it now */
3407 /* XXX: in ISOC, cannot do it if error in convert */
3408 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3409 vtop
->c
.f
= (float)vtop
->c
.d
;
3410 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3411 vtop
->c
.f
= (float)vtop
->c
.ld
;
3412 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3413 vtop
->c
.d
= (double)vtop
->c
.f
;
3414 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3415 vtop
->c
.d
= (double)vtop
->c
.ld
;
3416 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3417 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3418 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3419 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3421 /* non constant case: generate code */
3425 /* convert int to fp */
3426 st1
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3429 case VT_LLONG
| VT_UNSIGNED
:
3431 /* XXX: add const cases for long long */
3433 case VT_INT
| VT_UNSIGNED
:
3435 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3436 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
3437 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
3442 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
3443 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
3444 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
3453 /* convert fp to int */
3454 dt1
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3455 /* we handle char/short/etc... with generic code */
3456 if (dt1
!= (VT_INT
| VT_UNSIGNED
) &&
3457 dt1
!= (VT_LLONG
| VT_UNSIGNED
) &&
3462 case VT_LLONG
| VT_UNSIGNED
:
3464 /* XXX: add const cases for long long */
3466 case VT_INT
| VT_UNSIGNED
:
3468 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3469 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3470 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3476 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3477 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3478 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3486 if (dt1
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dt1
) {
3487 /* additionnal cast for char/short/bool... */
3491 } else if (dbt
== VT_LLONG
) {
3492 /* scalar to long long */
3494 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3495 vtop
->c
.ll
= vtop
->c
.ui
;
3497 vtop
->c
.ll
= vtop
->c
.i
;
3499 /* machine independant conversion */
3501 /* generate high word */
3502 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
)) {
3510 /* patch second register */
3511 vtop
[-1].r2
= vtop
->r
;
3514 } else if (dbt
== VT_BOOL
) {
3515 /* scalar to bool */
3518 } else if (dbt
== VT_BYTE
|| dbt
== VT_SHORT
) {
3519 force_charshort_cast(t
);
3520 } else if (dbt
== VT_INT
) {
3522 if (sbt
== VT_LLONG
) {
3523 /* from long long: just take low order word */
3526 } else if (sbt
== VT_PTR
) {
3528 } else if (vtop
->r
& VT_LVAL
) {
3529 /* if lvalue and single word type, nothing to do (XXX:
3530 maybe incorrect for sizeof op) */
3539 /* return type size. Put alignment at 'a' */
3540 int type_size(int t
, int *a
)
3546 if (bt
== VT_STRUCT
) {
3548 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3549 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
3551 } else if (bt
== VT_PTR
) {
3553 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3554 return type_size(s
->t
, a
) * s
->c
;
3559 } else if (bt
== VT_LDOUBLE
) {
3561 return LDOUBLE_SIZE
;
3562 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3565 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
3568 } else if (bt
== VT_SHORT
) {
3572 /* char, void, function, _Bool */
3578 /* return the pointed type of t */
3579 int pointed_type(int t
)
3582 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3583 return s
->t
| (t
& ~VT_TYPE
);
3586 int mk_pointer(int t
)
3590 sym_push(p
, t
, 0, -1);
3591 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
3594 int is_compatible_types(int t1
, int t2
)
3601 bt1
= t1
& VT_BTYPE
;
3602 bt2
= t2
& VT_BTYPE
;
3603 if (bt1
== VT_PTR
) {
3604 t1
= pointed_type(t1
);
3605 /* if function, then convert implicitely to function pointer */
3606 if (bt2
!= VT_FUNC
) {
3609 t2
= pointed_type(t2
);
3611 /* void matches everything */
3614 if (t1
== VT_VOID
|| t2
== VT_VOID
)
3616 return is_compatible_types(t1
, t2
);
3617 } else if (bt1
== VT_STRUCT
) {
3619 } else if (bt1
== VT_FUNC
) {
3622 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
3623 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
3624 if (!is_compatible_types(s1
->t
, s2
->t
))
3626 /* XXX: not complete */
3627 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
3631 while (s1
!= NULL
) {
3634 if (!is_compatible_types(s1
->t
, s2
->t
))
3643 /* XXX: not complete */
3648 /* print a type. If 'varstr' is not NULL, then the variable is also
3649 printed in the type */
3651 /* XXX: add array and function pointers */
3652 void type_to_str(char *buf
, int buf_size
,
3653 int t
, const char *varstr
)
3663 if (t
& VT_UNSIGNED
)
3664 pstrcat(buf
, buf_size
, "unsigned ");
3694 tstr
= "long double";
3696 pstrcat(buf
, buf_size
, tstr
);
3700 if (bt
== VT_STRUCT
)
3704 pstrcat(buf
, buf_size
, tstr
);
3705 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
3706 if (v
>= SYM_FIRST_ANOM
)
3707 pstrcat(buf
, buf_size
, "<anonymous>");
3709 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
3712 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3713 type_to_str(buf
, buf_size
, s
->t
, varstr
);
3714 pstrcat(buf
, buf_size
, "(");
3716 while (sa
!= NULL
) {
3717 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
3718 pstrcat(buf
, buf_size
, buf1
);
3721 pstrcat(buf
, buf_size
, ", ");
3723 pstrcat(buf
, buf_size
, ")");
3726 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3727 pstrcpy(buf1
, sizeof(buf1
), "*");
3729 pstrcat(buf1
, sizeof(buf1
), varstr
);
3730 type_to_str(buf
, buf_size
, s
->t
, buf1
);
3734 pstrcat(buf
, buf_size
, " ");
3735 pstrcat(buf
, buf_size
, varstr
);
3740 /* verify type compatibility to store vtop in 'dt' type, and generate
3742 void gen_assign_cast(int dt
)
3745 char buf1
[256], buf2
[256];
3747 st
= vtop
->t
; /* source type */
3748 if ((dt
& VT_BTYPE
) == VT_PTR
) {
3749 /* special cases for pointers */
3750 /* a function is implicitely a function pointer */
3751 if ((st
& VT_BTYPE
) == VT_FUNC
) {
3752 if (!is_compatible_types(pointed_type(dt
), st
))
3757 /* '0' can also be a pointer */
3758 if ((st
& VT_BTYPE
) == VT_INT
&&
3759 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
) &&
3763 if (!is_compatible_types(dt
, st
)) {
3765 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3766 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3767 error("cannot cast '%s' to '%s'", buf1
, buf2
);
3773 /* store vtop in lvalue pushed on stack */
3776 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
3780 sbt
= vtop
->t
& VT_BTYPE
;
3781 dbt
= ft
& VT_BTYPE
;
3782 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
3783 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
3784 /* optimize char/short casts */
3785 delayed_cast
= VT_MUSTCAST
;
3786 vtop
->t
= ft
& VT_TYPE
;
3789 gen_assign_cast(ft
& VT_TYPE
);
3792 if (sbt
== VT_STRUCT
) {
3793 /* if structure, only generate pointer */
3794 /* structure assignment : generate memcpy */
3795 /* XXX: optimize if small size */
3798 gfunc_start(&gf
, FUNC_CDECL
);
3800 size
= type_size(vtop
->t
, &align
);
3814 vpushi((int)&memcpy
);
3816 /* leave source on stack */
3817 } else if (ft
& VT_BITFIELD
) {
3818 /* bitfield store handling */
3819 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
3820 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3821 /* remove bit field info to avoid loops */
3822 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3824 /* duplicate destination */
3826 vtop
[-1] = vtop
[-2];
3828 /* mask and shift source */
3829 vpushi((1 << bit_size
) - 1);
3833 /* load destination, mask and or with source */
3835 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
3841 #ifdef CONFIG_TCC_BCHECK
3842 /* bound check case */
3843 if (vtop
[-1].r
& VT_MUSTBOUND
) {
3852 r
= gv(rc
); /* generate value */
3853 /* if lvalue was saved on stack, must read it */
3854 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
3856 t
= get_reg(RC_INT
);
3858 sv
.r
= VT_LOCAL
| VT_LVAL
;
3859 sv
.c
.ul
= vtop
[-1].c
.ul
;
3861 vtop
[-1].r
= t
| VT_LVAL
;
3864 /* two word case handling : store second register at word + 4 */
3865 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
3867 /* convert to int to increment easily */
3874 /* XXX: it works because r2 is spilled last ! */
3875 store(vtop
->r2
, vtop
- 1);
3878 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
3879 vtop
->r
|= delayed_cast
;
3883 /* post defines POST/PRE add. c is the token ++ or -- */
3884 void inc(int post
, int c
)
3887 vdup(); /* save lvalue */
3889 gv_dup(); /* duplicate value */
3894 vpushi(c
- TOK_MID
);
3896 vstore(); /* store value */
3898 vpop(); /* if post op, return saved value */
3901 /* Parse GNUC __attribute__ extension. Currently, the following
3902 extensions are recognized:
3903 - aligned(n) : set data/function alignment.
3904 - section(x) : generate data/code in this section.
3905 - unused : currently ignored, but may be used someday.
3907 void parse_attribute(AttributeDef
*ad
)
3914 while (tok
!= ')') {
3915 if (tok
< TOK_IDENT
)
3916 expect("attribute name");
3921 case TOK___SECTION__
:
3924 expect("section name");
3925 ad
->section
= find_section(tokc
.ts
->str
);
3930 case TOK___ALIGNED__
:
3933 if (n
<= 0 || (n
& (n
- 1)) != 0)
3934 error("alignment must be a positive power of two");
3939 case TOK___UNUSED__
:
3940 /* currently, no need to handle it because tcc does not
3941 track unused objects */
3944 case TOK___NORETURN__
:
3945 /* currently, no need to handle it because tcc does not
3946 track unused objects */
3951 ad
->func_call
= FUNC_CDECL
;
3955 case TOK___STDCALL__
:
3956 ad
->func_call
= FUNC_STDCALL
;
3959 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
3960 /* skip parameters */
3961 /* XXX: skip parenthesis too */
3964 while (tok
!= ')' && tok
!= -1)
3978 /* enum/struct/union declaration */
3979 int struct_decl(int u
)
3981 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
3982 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
3986 a
= tok
; /* save decl type */
3991 /* struct already defined ? return it */
3992 /* XXX: check consistency */
3993 s
= sym_find(v
| SYM_STRUCT
);
3996 error("invalid type");
4002 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4003 /* put struct/union/enum name in type */
4005 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4010 error("struct/union/enum already defined");
4011 /* cannot be empty */
4018 if (a
== TOK_ENUM
) {
4025 /* enum symbols have static storage */
4026 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4031 parse_btype(&b
, &ad
);
4036 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4037 if ((t
& VT_BTYPE
) == VT_FUNC
||
4038 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4039 error("invalid type for '%s'",
4040 get_tok_str(v
, NULL
));
4046 bit_size
= expr_const();
4047 /* XXX: handle v = 0 case for messages */
4049 error("negative width in bit-field '%s'",
4050 get_tok_str(v
, NULL
));
4051 if (v
&& bit_size
== 0)
4052 error("zero width for bit-field '%s'",
4053 get_tok_str(v
, NULL
));
4055 size
= type_size(t
, &align
);
4057 if (bit_size
>= 0) {
4062 error("bitfields must have scalar type");
4064 if (bit_size
> bsize
) {
4065 error("width of '%s' exceeds its type",
4066 get_tok_str(v
, NULL
));
4067 } else if (bit_size
== bsize
) {
4068 /* no need for bit fields */
4070 } else if (bit_size
== 0) {
4071 /* XXX: what to do if only padding in a
4073 /* zero size: means to pad */
4077 /* we do not have enough room ? */
4078 if ((bit_pos
+ bit_size
) > bsize
)
4081 /* XXX: handle LSB first */
4083 (bit_pos
<< VT_STRUCT_SHIFT
) |
4084 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4085 bit_pos
+= bit_size
;
4091 /* add new memory data only if starting
4093 if (lbit_pos
== 0) {
4094 if (a
== TOK_STRUCT
) {
4095 c
= (c
+ align
- 1) & -align
;
4103 if (align
> maxalign
)
4107 printf("add field %s offset=%d",
4108 get_tok_str(v
, NULL
), offset
);
4109 if (t
& VT_BITFIELD
) {
4110 printf(" pos=%d size=%d",
4111 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4112 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4116 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
4120 if (tok
== ';' || tok
== -1)
4130 /* size for struct/union, dummy for enum */
4131 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4136 /* return 0 if no type declaration. otherwise, return the basic type
4139 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4141 int t
, u
, type_found
;
4144 memset(ad
, 0, sizeof(AttributeDef
));
4155 if ((t
& VT_BTYPE
) != 0)
4156 error("too many basic types");
4170 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4171 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4172 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4173 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4187 if ((t
& VT_BTYPE
) == VT_LONG
) {
4188 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4195 u
= struct_decl(VT_ENUM
);
4199 u
= struct_decl(VT_STRUCT
);
4202 /* type modifiers */
4207 case TOK___SIGNED__
:
4210 case TOK___INLINE__
:
4232 /* GNUC attribute */
4233 case TOK___ATTRIBUTE__
:
4234 parse_attribute(ad
);
4238 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4240 t
|= (s
->t
& ~VT_TYPEDEF
);
4247 /* long is never used as type */
4248 if ((t
& VT_BTYPE
) == VT_LONG
)
4249 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4254 int post_type(int t
, AttributeDef
*ad
)
4256 int p
, n
, pt
, l
, t1
;
4257 Sym
**plast
, *s
, *first
;
4261 /* function declaration */
4266 while (tok
!= ')') {
4267 /* read param name and compute offset */
4268 if (l
!= FUNC_OLD
) {
4269 if (!parse_btype(&pt
, &ad1
)) {
4271 error("invalid type");
4278 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4280 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
4281 if ((pt
& VT_BTYPE
) == VT_VOID
)
4282 error("parameter declared as void");
4289 /* array must be transformed to pointer according to ANSI C */
4291 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
4296 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4303 /* if no parameters, then old type prototype */
4307 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4308 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4309 /* we push a anonymous symbol which will contain the function prototype */
4311 s
= sym_push(p
, t
, ad
->func_call
, l
);
4313 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
4314 } else if (tok
== '[') {
4315 /* array definition */
4321 error("invalid array size");
4324 /* parse next post type */
4325 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4326 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4328 /* we push a anonymous symbol which will contain the array
4331 sym_push(p
, t
, 0, n
);
4332 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
4337 /* Read a type declaration (except basic type), and return the
4338 type. 'td' is a bitmask indicating which kind of type decl is
4339 expected. 't' should contain the basic type. 'ad' is the attribute
4340 definition of the basic type. It can be modified by type_decl(). */
4341 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
4346 while (tok
== '*') {
4348 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
4353 /* recursive type */
4354 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4357 /* XXX: this is not correct to modify 'ad' at this point, but
4358 the syntax is not clear */
4359 if (tok
== TOK___ATTRIBUTE__
)
4360 parse_attribute(ad
);
4361 u
= type_decl(ad
, v
, 0, td
);
4365 /* type identifier */
4366 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
4370 if (!(td
& TYPE_ABSTRACT
))
4371 expect("identifier");
4375 /* append t at the end of u */
4376 t
= post_type(t
, ad
);
4377 if (tok
== TOK___ATTRIBUTE__
)
4378 parse_attribute(ad
);
4383 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
4393 /* define a new external reference to a function 'v' of type 'u' */
4394 Sym
*external_sym(int v
, int u
, int r
)
4399 /* push forward reference */
4400 s
= sym_push1(&global_stack
,
4402 s
->r
= r
| VT_CONST
| VT_FORWARD
;
4409 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
4411 if (vtop
->r
& VT_LVAL
)
4413 vtop
->t
= pointed_type(vtop
->t
);
4414 /* an array is never an lvalue */
4415 if (!(vtop
->t
& VT_ARRAY
)) {
4417 /* if bound checking, the referenced pointer must be checked */
4418 if (do_bounds_check
)
4419 vtop
->r
|= VT_MUSTBOUND
;
4423 /* pass a parameter to a function and do type checking and casting */
4424 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
4427 func_type
= func
->c
;
4428 if (func_type
== FUNC_OLD
||
4429 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
4430 /* default casting : only need to convert float to double */
4431 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
4432 gen_cast(VT_DOUBLE
);
4433 } else if (arg
== NULL
) {
4434 error("too many arguments to function");
4436 gen_assign_cast(arg
->t
);
4443 int n
, t
, ft
, fc
, p
, align
, size
, r
, data_offset
;
4448 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
4451 } else if (tok
== TOK_CUINT
) {
4452 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4454 } else if (tok
== TOK_CLLONG
) {
4455 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
4457 } else if (tok
== TOK_CULLONG
) {
4458 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4460 } else if (tok
== TOK_CFLOAT
) {
4461 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
4463 } else if (tok
== TOK_CDOUBLE
) {
4464 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
4466 } else if (tok
== TOK_CLDOUBLE
) {
4467 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
4469 } else if (tok
== TOK___FUNC__
) {
4470 /* special function name identifier */
4471 /* generate (char *) type */
4472 data_offset
= (int)data_section
->data_ptr
;
4473 vset(mk_pointer(VT_BYTE
), VT_CONST
, data_offset
);
4474 strcpy((void *)data_offset
, funcname
);
4475 data_offset
+= strlen(funcname
) + 1;
4476 data_section
->data_ptr
= (unsigned char *)data_offset
;
4478 } else if (tok
== TOK_LSTR
) {
4481 } else if (tok
== TOK_STR
) {
4482 /* string parsing */
4485 type_size(t
, &align
);
4486 data_offset
= (int)data_section
->data_ptr
;
4487 data_offset
= (data_offset
+ align
- 1) & -align
;
4489 /* we must declare it as an array first to use initializer parser */
4490 t
= VT_ARRAY
| mk_pointer(t
);
4491 decl_initializer(t
, VT_CONST
, data_offset
, 1, 0);
4492 data_offset
+= type_size(t
, &align
);
4493 /* put it as pointer */
4494 vset(t
& ~VT_ARRAY
, VT_CONST
, fc
);
4495 data_section
->data_ptr
= (unsigned char *)data_offset
;
4501 if (parse_btype(&t
, &ad
)) {
4502 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4504 /* check ISOC99 compound literal */
4506 /* data is allocated locally by default */
4511 /* all except arrays are lvalues */
4512 if (!(ft
& VT_ARRAY
))
4514 memset(&ad
, 0, sizeof(AttributeDef
));
4515 fc
= decl_initializer_alloc(ft
, &ad
, r
, 1);
4525 } else if (t
== '*') {
4528 } else if (t
== '&') {
4530 /* functions names must be treated as function pointers,
4531 except for unary '&' and sizeof. Since we consider that
4532 functions are not lvalues, we only have to handle it
4533 there and in function calls. */
4534 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4536 vtop
->t
= mk_pointer(vtop
->t
);
4541 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
4542 vtop
->c
.i
= !vtop
->c
.i
;
4543 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
4544 vtop
->c
.i
= vtop
->c
.i
^ 1;
4546 vset(VT_INT
, VT_JMP
, gtst(1, 0));
4556 if (t
== TOK_SIZEOF
) {
4559 if (parse_btype(&t
, &ad
)) {
4560 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4562 /* XXX: some code could be generated: add eval
4574 vpushi(type_size(t
, &t
));
4576 if (t
== TOK_INC
|| t
== TOK_DEC
) {
4579 } else if (t
== '-') {
4588 error("'%s' undeclared", get_tok_str(t
, NULL
));
4589 /* for simple function calls, we tolerate undeclared
4590 external reference */
4592 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
4593 /* int() function */
4594 s
= external_sym(t
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), 0);
4596 vset(s
->t
, s
->r
, s
->c
);
4597 /* if forward reference, we must point to s */
4598 if (vtop
->r
& VT_FORWARD
)
4603 /* post operations */
4605 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4608 } else if (tok
== '.' || tok
== TOK_ARROW
) {
4610 if (tok
== TOK_ARROW
)
4615 /* expect pointer on structure */
4616 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
4617 expect("struct or union");
4618 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4621 while ((s
= s
->next
) != NULL
) {
4626 error("field not found");
4627 /* add field offset to pointer */
4628 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
4631 /* change type to field type, and set to lvalue */
4633 /* an array is never an lvalue */
4634 if (!(vtop
->t
& VT_ARRAY
))
4637 } else if (tok
== '[') {
4643 } else if (tok
== '(') {
4648 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
4649 /* pointer test (no array accepted) */
4650 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4651 vtop
->t
= pointed_type(vtop
->t
);
4652 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4656 expect("function pointer");
4659 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4661 /* get return type */
4662 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
4663 save_regs(); /* save used temporary registers */
4664 gfunc_start(&gf
, s
->r
);
4666 sa
= s
->next
; /* first parameter */
4667 #ifdef INVERT_FUNC_PARAMS
4669 int *str
, len
, parlevel
, *saved_macro_ptr
;
4672 /* read each argument and store it on a stack */
4673 /* XXX: merge it with macro args ? */
4675 while (tok
!= ')') {
4679 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
4683 else if (tok
== ')')
4685 tok_add2(&str
, &len
, tok
, &tokc
);
4688 tok_add(&str
, &len
, -1); /* end of file added */
4689 tok_add(&str
, &len
, 0);
4690 s1
= sym_push2(&args
, 0, 0, (int)str
);
4691 s1
->next
= sa
; /* add reference to argument */
4701 /* now generate code in reverse order by reading the stack */
4702 saved_macro_ptr
= macro_ptr
;
4704 macro_ptr
= (int *)args
->c
;
4708 expect("',' or ')'");
4709 gfunc_param_typed(&gf
, s
, args
->next
);
4711 free((int *)args
->c
);
4715 macro_ptr
= saved_macro_ptr
;
4720 /* compute first implicit argument if a structure is returned */
4721 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
4722 /* get some space for the returned structure */
4723 size
= type_size(s
->t
, &align
);
4724 loc
= (loc
- size
) & -align
;
4726 ret
.r
= VT_LOCAL
| VT_LVAL
;
4727 /* pass it as 'int' to avoid structure arg passing
4729 vset(VT_INT
, VT_LOCAL
, loc
);
4735 /* return in register */
4736 if (is_float(ret
.t
)) {
4739 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
4745 #ifndef INVERT_FUNC_PARAMS
4746 while (tok
!= ')') {
4748 gfunc_param_typed(&gf
, s
, sa
);
4756 error("too few arguments to function");
4760 vsetc(ret
.t
, ret
.r
, &ret
.c
);
4774 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
4775 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
4776 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
4799 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
4800 (l
== 1 && (tok
== '+' || tok
== '-')) ||
4801 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
4802 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
4803 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
4804 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
4805 (l
== 5 && tok
== '&') ||
4806 (l
== 6 && tok
== '^') ||
4807 (l
== 7 && tok
== '|') ||
4808 (l
== 8 && tok
== TOK_LAND
) ||
4809 (l
== 9 && tok
== TOK_LOR
)) {
4818 /* only used if non constant */
4826 if (tok
!= TOK_LAND
) {
4829 vset(VT_INT
, VT_JMPI
, t
);
4846 if (tok
!= TOK_LOR
) {
4849 vset(VT_INT
, VT_JMP
, t
);
4859 /* XXX: better constant handling */
4862 int t
, u
, c
, r1
, r2
, rc
;
4884 /* XXX: long long handling ? */
4886 if (is_float(vtop
->t
))
4889 vtop
--; /* no vpop so that FP stack is not flushed */
4914 /* parse a constant expression and return value in vtop */
4915 void expr_const1(void)
4921 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
4926 /* parse an integer constant and return its value */
4927 int expr_const(void)
4936 /* return the label token if current token is a label, otherwise
4943 /* fast test first */
4944 if (tok
< TOK_UIDENT
)
4946 /* no need to save tokc since we expect an identifier */
4954 /* XXX: may not work in all cases (macros ?) */
4963 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
4968 /* generate line number info */
4970 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
4971 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
4973 last_line_num
= file
->line_num
;
4976 if (tok
== TOK_IF
) {
4983 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4985 if (c
== TOK_ELSE
) {
4989 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4990 gsym(d
); /* patch else jmp */
4993 } else if (tok
== TOK_WHILE
) {
5001 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5005 } else if (tok
== '{') {
5008 s
= local_stack
.top
;
5009 while (tok
!= '}') {
5012 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5014 /* pop locally defined symbols */
5015 sym_pop(&local_stack
, s
);
5017 } else if (tok
== TOK_RETURN
) {
5021 gen_assign_cast(func_vt
);
5022 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5023 /* if returning structure, must copy it to implicit
5024 first pointer arg location */
5025 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
5028 /* copy structure value to pointer */
5030 } else if (is_float(func_vt
)) {
5035 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5038 rsym
= gjmp(rsym
); /* jmp */
5039 } else if (tok
== TOK_BREAK
) {
5042 error("cannot break");
5043 *bsym
= gjmp(*bsym
);
5046 } else if (tok
== TOK_CONTINUE
) {
5049 error("cannot continue");
5050 *csym
= gjmp(*csym
);
5053 } else if (tok
== TOK_FOR
) {
5080 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5085 if (tok
== TOK_DO
) {
5090 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5101 if (tok
== TOK_SWITCH
) {
5105 /* XXX: other types than integer */
5106 case_reg
= gv(RC_INT
);
5110 b
= gjmp(0); /* jump to first case */
5112 block(&a
, csym
, &b
, &c
, case_reg
);
5113 /* if no default, jmp after switch */
5121 if (tok
== TOK_CASE
) {
5128 if (gnu_ext
&& tok
== TOK_DOTS
) {
5132 warning("empty case range");
5134 /* since a case is like a label, we must skip it with a jmp */
5137 vset(VT_INT
, case_reg
, 0);
5141 *case_sym
= gtst(1, 0);
5144 *case_sym
= gtst(1, 0);
5145 vset(VT_INT
, case_reg
, 0);
5148 *case_sym
= gtst(1, *case_sym
);
5152 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5154 if (tok
== TOK_DEFAULT
) {
5160 error("too many 'default'");
5162 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5164 if (tok
== TOK_GOTO
) {
5166 s
= sym_find1(&label_stack
, tok
);
5167 /* put forward definition if needed */
5169 s
= sym_push1(&label_stack
, tok
, VT_FORWARD
, 0);
5170 /* label already defined */
5171 if (s
->t
& VT_FORWARD
)
5181 s
= sym_find1(&label_stack
, b
);
5183 if (!(s
->t
& VT_FORWARD
))
5184 error("multiple defined label");
5189 sym_push1(&label_stack
, b
, 0, ind
);
5191 /* we accept this, but it is a mistake */
5193 warning("deprecated use of label at end of compound statement");
5195 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5197 /* expression case */
5207 /* t is the array or struct type. c is the array or struct
5208 address. cur_index/cur_field is the pointer to the current
5209 value. 'size_only' is true if only size info is needed (only used
5211 void decl_designator(int t
, int r
, int c
,
5212 int *cur_index
, Sym
**cur_field
,
5216 int notfirst
, index
, align
, l
;
5219 if (gnu_ext
&& (l
= is_label()) != 0)
5222 while (tok
== '[' || tok
== '.') {
5224 if (!(t
& VT_ARRAY
))
5225 expect("array type");
5226 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5228 index
= expr_const();
5229 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5230 expect("invalid index");
5234 t
= pointed_type(t
);
5235 c
+= index
* type_size(t
, &align
);
5241 if ((t
& VT_BTYPE
) != VT_STRUCT
)
5242 expect("struct/union type");
5243 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5255 t
= f
->t
| (t
& ~VT_TYPE
);
5270 t
= pointed_type(t
);
5271 c
+= index
* type_size(t
, &align
);
5275 error("too many field init");
5276 t
= f
->t
| (t
& ~VT_TYPE
);
5280 decl_initializer(t
, r
, c
, 0, size_only
);
5284 #define EXPR_CONST 1
5287 /* store a value or an expression directly in global data or in local array */
5288 void init_putv(int t
, int r
, int c
,
5289 int v
, int expr_type
)
5291 int saved_global_expr
, bt
;
5298 /* compound literals must be allocated globally in this case */
5299 saved_global_expr
= global_expr
;
5302 global_expr
= saved_global_expr
;
5309 if ((r
& VT_VALMASK
) == VT_CONST
) {
5310 /* XXX: not portable */
5315 *(char *)c
= vtop
->c
.i
;
5318 *(short *)c
= vtop
->c
.i
;
5321 *(double *)c
= vtop
->c
.d
;
5324 *(long double *)c
= vtop
->c
.ld
;
5327 *(long long *)c
= vtop
->c
.ll
;
5330 *(int *)c
= vtop
->c
.i
;
5342 /* put zeros for variable based init */
5343 void init_putz(int t
, int r
, int c
, int size
)
5347 if ((r
& VT_VALMASK
) == VT_CONST
) {
5348 /* nothing to do because globals are already set to zero */
5350 gfunc_start(&gf
, FUNC_CDECL
);
5355 vset(VT_INT
, VT_LOCAL
, c
);
5357 vpushi((int)&memset
);
5362 /* 't' contains the type and storage info. c is the address of the
5363 object. 'first' is true if array '{' must be read (multi dimension
5364 implicit array init handling). 'size_only' is true if size only
5365 evaluation is wanted (only for arrays). */
5366 void decl_initializer(int t
, int r
, int c
, int first
, int size_only
)
5368 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
5369 int t1
, size1
, align1
, expr_type
;
5374 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5377 t1
= pointed_type(t
);
5378 size1
= type_size(t1
, &align1
);
5381 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5387 /* only parse strings here if correct type (otherwise: handle
5388 them as ((w)char *) expressions */
5389 if ((tok
== TOK_LSTR
&&
5390 (t1
& VT_BTYPE
) == VT_INT
) ||
5392 (t1
& VT_BTYPE
) == VT_BYTE
)) {
5393 /* XXX: move multiple string parsing in parser ? */
5394 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5396 /* compute maximum number of chars wanted */
5398 if (n
>= 0 && nb
> (n
- array_length
))
5399 nb
= n
- array_length
;
5402 warning("initializer-string for array is too long");
5404 init_putv(t1
, r
, c
+ (array_length
+ i
) * size1
,
5405 ts
->str
[i
], EXPR_VAL
);
5411 /* only add trailing zero if enough storage (no
5412 warning in this case since it is standard) */
5413 if (n
< 0 || array_length
< n
) {
5415 init_putv(t1
, r
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5421 while (tok
!= '}') {
5422 decl_designator(t
, r
, c
, &index
, NULL
, size_only
);
5423 if (n
>= 0 && index
>= n
)
5424 error("index too large");
5425 /* must put zero in holes (note that doing it that way
5426 ensures that it even works with designators) */
5427 if (!size_only
&& array_length
< index
) {
5428 init_putz(t1
, r
, c
+ array_length
* size1
,
5429 (index
- array_length
) * size1
);
5432 if (index
> array_length
)
5433 array_length
= index
;
5434 /* special test for multi dimensional arrays (may not
5435 be strictly correct if designators are used at the
5437 if (index
>= n
&& no_oblock
)
5446 /* put zeros at the end */
5447 if (!size_only
&& n
>= 0 && array_length
< n
) {
5448 init_putz(t1
, r
, c
+ array_length
* size1
,
5449 (n
- array_length
) * size1
);
5451 /* patch type size if needed */
5453 s
->c
= array_length
;
5454 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
5455 /* XXX: union needs only one init */
5457 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5462 while (tok
!= '}') {
5463 decl_designator(t
, r
, c
, NULL
, &f
, size_only
);
5464 /* fill with zero between fields */
5466 if (!size_only
&& array_length
< index
) {
5467 init_putz(t
, r
, c
+ array_length
,
5468 index
- array_length
);
5470 index
= index
+ type_size(f
->t
, &align1
);
5471 if (index
> array_length
)
5472 array_length
= index
;
5478 /* put zeros at the end */
5479 if (!size_only
&& array_length
< n
) {
5480 init_putz(t
, r
, c
+ array_length
,
5484 } else if (tok
== '{') {
5486 decl_initializer(t
, r
, c
, first
, size_only
);
5488 } else if (size_only
) {
5489 /* just skip expression */
5491 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
5495 else if (tok
== ')')
5500 /* currently, we always use constant expression for globals
5501 (may change for scripting case) */
5502 expr_type
= EXPR_CONST
;
5503 if ((r
& VT_VALMASK
) == VT_LOCAL
)
5504 expr_type
= EXPR_ANY
;
5505 init_putv(t
, r
, c
, 0, expr_type
);
5509 /* parse an initializer for type 't' if 'has_init' is true, and
5510 allocate space in local or global data space ('r' is either
5511 VT_LOCAL or VT_CONST). The allocated address in returned */
5512 int decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
)
5514 int size
, align
, addr
, tok1
, data_offset
;
5515 int *init_str
, init_len
, level
, *saved_macro_ptr
;
5518 size
= type_size(t
, &align
);
5519 /* If unknown size, we must evaluate it before
5520 evaluating initializers because
5521 initializers can generate global data too
5522 (e.g. string pointers or ISOC99 compound
5523 literals). It also simplifies local
5524 initializers handling */
5527 saved_macro_ptr
= NULL
; /* avoid warning */
5531 error("unknown type size");
5532 /* get all init string */
5534 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5536 error("unexpected end of file in initializer");
5537 tok_add2(&init_str
, &init_len
, tok
, &tokc
);
5540 else if (tok
== '}') {
5548 tok_add(&init_str
, &init_len
, -1);
5549 tok_add(&init_str
, &init_len
, 0);
5552 saved_macro_ptr
= macro_ptr
;
5553 macro_ptr
= init_str
;
5555 decl_initializer(t
, r
, 0, 1, 1);
5556 /* prepare second initializer parsing */
5557 macro_ptr
= init_str
;
5560 /* if still unknown size, error */
5561 size
= type_size(t
, &align
);
5563 error("unknown type size");
5565 /* take into account specified alignment if bigger */
5566 if (ad
->aligned
> align
)
5567 align
= ad
->aligned
;
5568 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5569 if (do_bounds_check
&& (t
& VT_ARRAY
))
5571 #ifdef TCC_TARGET_IL
5572 /* XXX: ugly patch to allocate local variables for IL, just
5577 loc
= (loc
- size
) & -align
;
5580 /* handles bounds */
5581 /* XXX: currently, since we do only one pass, we cannot track
5582 '&' operators, so we add only arrays */
5583 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
5585 /* add padding between regions */
5587 /* then add local bound info */
5588 bounds_ptr
= (int *)lbounds_section
->data_ptr
;
5589 *bounds_ptr
++ = addr
;
5590 *bounds_ptr
++ = size
;
5591 lbounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5594 /* compute section */
5602 data_offset
= (int)sec
->data_ptr
;
5603 data_offset
= (data_offset
+ align
- 1) & -align
;
5605 /* very important to increment global
5606 pointer at this time because
5607 initializers themselves can create new
5609 data_offset
+= size
;
5610 /* handles bounds */
5611 if (do_bounds_check
) {
5613 /* first, we need to add at least one byte between each region */
5615 /* then add global bound info */
5616 bounds_ptr
= (int *)bounds_section
->data_ptr
;
5617 *bounds_ptr
++ = addr
;
5618 *bounds_ptr
++ = size
;
5619 bounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5621 sec
->data_ptr
= (unsigned char *)data_offset
;
5624 decl_initializer(t
, r
, addr
, 1, 0);
5625 /* restore parse state if needed */
5628 macro_ptr
= saved_macro_ptr
;
5635 void put_func_debug(int t
)
5644 put_elf_sym(symtab_section
, ind
, 0,
5645 ELF32_ST_INFO(bind
, STT_FUNC
), 0,
5646 cur_text_section
->sh_num
, funcname
);
5648 /* XXX: we put here a dummy type */
5649 snprintf(buf
, sizeof(buf
), "%s:%c1",
5650 funcname
, t
& VT_STATIC
? 'f' : 'F');
5651 put_stabs(buf
, N_FUN
, 0, file
->line_num
, ind
);
5657 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5660 int t
, b
, v
, addr
, has_init
, r
;
5665 if (!parse_btype(&b
, &ad
)) {
5666 /* skip redundant ';' */
5667 /* XXX: find more elegant solution */
5672 /* special test for old K&R protos without explicit int
5673 type. Only accepted when defining global data */
5674 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
5678 if (((b
& VT_BTYPE
) == VT_ENUM
||
5679 (b
& VT_BTYPE
) == VT_STRUCT
) &&
5681 /* we accept no variable after */
5685 while (1) { /* iterate thru each declaration */
5686 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
5690 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
5691 printf("type = '%s'\n", buf
);
5696 error("cannot use local functions");
5698 expect("function definition");
5699 /* compute text section */
5700 cur_text_section
= ad
.section
;
5701 if (!cur_text_section
)
5702 cur_text_section
= text_section
;
5703 ind
= (int)cur_text_section
->data_ptr
;
5704 /* patch forward references */
5705 if ((sym
= sym_find(v
)) && (sym
->r
& VT_FORWARD
)) {
5706 greloc_patch(sym
, ind
);
5709 /* put function address */
5710 sym
= sym_push1(&global_stack
, v
, t
, ind
);
5713 funcname
= get_tok_str(v
, NULL
);
5714 /* put debug symbol */
5717 /* push a dummy symbol to enable local sym storage */
5718 sym_push1(&local_stack
, 0, 0, 0);
5722 block(NULL
, NULL
, NULL
, NULL
, 0);
5725 cur_text_section
->data_ptr
= (unsigned char *)ind
;
5726 sym_pop(&label_stack
, NULL
); /* reset label stack */
5727 sym_pop(&local_stack
, NULL
); /* reset local stack */
5728 /* end of function */
5730 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
5732 funcname
= ""; /* for safety */
5733 func_vt
= VT_VOID
; /* for safety */
5734 ind
= 0; /* for safety */
5737 if (b
& VT_TYPEDEF
) {
5738 /* save typedefed type */
5739 /* XXX: test storage specifiers ? */
5740 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
5741 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
5742 /* external function definition */
5743 external_sym(v
, t
, 0);
5745 /* not lvalue if array */
5747 if (!(t
& VT_ARRAY
))
5749 if (b
& VT_EXTERN
) {
5750 /* external variable */
5751 external_sym(v
, t
, r
);
5757 has_init
= (tok
== '=');
5760 addr
= decl_initializer_alloc(t
, &ad
, r
,
5762 if (l
== VT_CONST
) {
5763 /* global scope: see if already defined */
5767 if (!is_compatible_types(sym
->t
, t
))
5768 error("incompatible types for redefinition of '%s'",
5769 get_tok_str(v
, NULL
));
5770 if (!(sym
->r
& VT_FORWARD
))
5771 error("redefinition of '%s'", get_tok_str(v
, NULL
));
5772 greloc_patch(sym
, addr
);
5775 sym_push(v
, t
, r
, addr
);
5789 /* put all global symbols in the extern stack and do all the
5790 resolving which can be done without using external symbols from DLLs */
5791 /* XXX: could try to verify types, but would not to save them in
5793 void resolve_global_syms(void)
5795 Sym
*s
, *s1
, *ext_sym
;
5798 s
= global_stack
.top
;
5801 /* do not save static or typedefed symbols or types */
5802 if (!(s
->t
& (VT_STATIC
| VT_TYPEDEF
)) &&
5803 !(s
->v
& (SYM_FIELD
| SYM_STRUCT
)) &&
5804 (s
->v
< SYM_FIRST_ANOM
)) {
5805 ext_sym
= sym_find1(&extern_stack
, s
->v
);
5807 /* if the symbol do not exist, we simply save it */
5808 ext_sym
= sym_push1(&extern_stack
, s
->v
, s
->t
, s
->c
);
5810 } else if (ext_sym
->r
& VT_FORWARD
) {
5811 /* external symbol already exists, but only as forward
5813 if (!(s
->r
& VT_FORWARD
)) {
5814 /* s is not forward, so we can relocate all symbols */
5815 greloc_patch(ext_sym
, s
->c
);
5817 /* the two symbols are forward: merge them */
5818 p
= (Reloc
**)&ext_sym
->c
;
5824 /* external symbol already exists and is defined :
5825 patch all references to it */
5826 if (!(s
->r
& VT_FORWARD
))
5827 error("'%s' defined twice", get_tok_str(s
->v
, NULL
));
5828 greloc_patch(s
, ext_sym
->c
);
5835 /* compile a C file. Return non zero if errors. */
5836 int tcc_compile_file(const char *filename1
)
5843 file
= tcc_open(filename1
);
5845 error("file '%s' not found", filename1
);
5846 include_stack_ptr
= include_stack
;
5847 ifdef_stack_ptr
= ifdef_stack
;
5850 anon_sym
= SYM_FIRST_ANOM
;
5852 /* file info: full path + filename */
5854 getcwd(buf
, sizeof(buf
));
5855 pstrcat(buf
, sizeof(buf
), "/");
5856 put_stabs(buf
, N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
5857 put_stabs(file
->filename
, N_SO
, 0, 0,
5858 (unsigned long)text_section
->data_ptr
);
5860 /* define common 'char *' type because it is often used internally
5861 for arrays and struct dereference */
5862 char_pointer_type
= mk_pointer(VT_BYTE
);
5864 define_start
= define_stack
.top
;
5866 ch
= '\n'; /* needed to parse correctly first preprocessor command */
5870 expect("declaration");
5873 /* end of translation unit info */
5875 put_stabn(N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
5878 /* reset define stack, but leave -Dsymbols (may be incorrect if
5879 they are undefined) */
5880 sym_pop(&define_stack
, define_start
);
5882 resolve_global_syms();
5884 sym_pop(&global_stack
, NULL
);
5889 /* define a symbol. A value can also be provided with the '=' operator */
5890 /* XXX: currently only handles integers and string defines. should use
5891 tcc parser, but would need a custom 'FILE *' */
5892 void define_symbol(const char *sym
)
5895 BufferedFile bf1
, *bf
= &bf1
;
5897 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
5898 p
= strchr(bf
->buffer
, '=');
5901 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " 1");
5906 /* init file structure */
5908 bf
->buf_ptr
= bf
->buffer
;
5909 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
5910 bf
->filename
[0] = '\0';
5914 include_stack_ptr
= include_stack
;
5916 /* parse with define parser */
5918 ch
= '\n'; /* needed to parse correctly first preprocessor command */
5924 void undef_symbol(const char *sym
)
5928 ts
= tok_alloc(sym
, 0);
5929 s
= sym_find1(&define_stack
, tok
);
5930 /* undefine symbol by putting an invalid name */
5932 sym_undef(&define_stack
, s
);
5935 /* open a dynamic library so that its symbol are available for
5936 compiled programs */
5937 void open_dll(char *libname
)
5942 snprintf(buf
, sizeof(buf
), "lib%s.so", libname
);
5943 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
5945 error((char *)dlerror());
5948 static void *resolve_sym(const char *sym
)
5950 #ifdef CONFIG_TCC_BCHECK
5951 if (do_bounds_check
) {
5953 ptr
= bound_resolve_sym(sym
);
5958 return dlsym(NULL
, sym
);
5961 void resolve_extern_syms(void)
5967 s
= extern_stack
.top
;
5970 if (s
->r
& VT_FORWARD
) {
5971 /* if there is at least one relocation to do, then find it
5974 str
= get_tok_str(s
->v
, NULL
);
5975 addr
= (int)resolve_sym(str
);
5977 error("unresolved external reference '%s'", str
);
5978 greloc_patch(s
, addr
);
5985 static int put_elf_str(Section
*s
, const char *sym
)
5988 offset
= s
->data_ptr
- s
->data
;
5998 static void put_elf_sym(Section
*s
,
5999 unsigned long value
, unsigned long size
,
6000 int info
, int other
, int shndx
, const char *name
)
6005 sym
= (Elf32_Sym
*)s
->data_ptr
;
6007 name_offset
= put_elf_str(s
->link
, name
);
6010 sym
->st_name
= name_offset
;
6011 sym
->st_value
= value
;
6012 sym
->st_size
= size
;
6013 sym
->st_info
= info
;
6014 sym
->st_other
= other
;
6015 sym
->st_shndx
= shndx
;
6016 s
->data_ptr
+= sizeof(Elf32_Sym
);
6019 /* put stab debug information */
6022 unsigned long n_strx
; /* index into string table of name */
6023 unsigned char n_type
; /* type of symbol */
6024 unsigned char n_other
; /* misc info (usually empty) */
6025 unsigned short n_desc
; /* description field */
6026 unsigned long n_value
; /* value of symbol */
6029 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
)
6033 sym
= (Stab_Sym
*)stab_section
->data_ptr
;
6035 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
6040 sym
->n_other
= other
;
6042 sym
->n_value
= value
;
6044 stab_section
->data_ptr
+= sizeof(Stab_Sym
);
6047 static void put_stabn(int type
, int other
, int desc
, int value
)
6049 put_stabs(NULL
, type
, other
, desc
, value
);
6052 static void put_stabd(int type
, int other
, int desc
)
6054 put_stabs(NULL
, type
, other
, desc
, 0);
6057 /* output an ELF file (currently, only for testing) */
6058 /* XXX: generate dynamic reloc info + DLL tables */
6059 /* XXX: generate startup code */
6060 /* XXX: better program header generation */
6061 /* XXX: handle realloc'ed sections (instead of mmaping them) */
6062 void build_exe(char *filename
)
6066 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
;
6067 Section
*sec
, *strsec
;
6068 Elf32_Shdr
*shdr
, *sh
;
6069 Elf32_Phdr
*phdr
, *ph
;
6071 memset(&ehdr
, 0, sizeof(ehdr
));
6073 /* we add a section for symbols */
6074 strsec
= new_section(".shstrtab", SHT_STRTAB
, 0);
6075 put_elf_str(strsec
, "");
6077 /* count number of sections and compute number of program segments */
6078 shnum
= 1; /* section index zero is reserved */
6080 for(sec
= first_section
; sec
!= NULL
; sec
= sec
->next
) {
6082 if (sec
->sh_flags
& SHF_ALLOC
)
6085 /* allocate section headers */
6086 shdr
= malloc(shnum
* sizeof(Elf32_Shdr
));
6088 error("memory full");
6089 memset(shdr
, 0, shnum
* sizeof(Elf32_Shdr
));
6090 /* allocate program segment headers */
6091 phdr
= malloc(phnum
* sizeof(Elf32_Phdr
));
6093 error("memory full");
6094 memset(phdr
, 0, phnum
* sizeof(Elf32_Phdr
));
6096 /* XXX: find correct load order */
6097 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
6098 for(sec
= first_section
, i
= 1; sec
!= NULL
; sec
= sec
->next
, i
++) {
6100 sh
->sh_name
= put_elf_str(strsec
, sec
->name
);
6101 sh
->sh_type
= sec
->sh_type
;
6102 sh
->sh_flags
= sec
->sh_flags
;
6103 sh
->sh_entsize
= sec
->sh_entsize
;
6105 sh
->sh_link
= sec
->link
->sh_num
;
6106 if (sh
->sh_type
== SHT_STRTAB
) {
6107 sh
->sh_addralign
= 1;
6108 } else if (sh
->sh_type
== SHT_SYMTAB
||
6109 (sh
->sh_flags
& SHF_ALLOC
) == 0) {
6110 sh
->sh_addralign
= 4;
6112 sh
->sh_addr
= (Elf32_Word
)sec
->data
;
6113 sh
->sh_addralign
= 4096;
6115 sh
->sh_size
= (Elf32_Word
)sec
->data_ptr
- (Elf32_Word
)sec
->data
;
6116 /* align to section start */
6117 file_offset
= (file_offset
+ sh
->sh_addralign
- 1) &
6118 ~(sh
->sh_addralign
- 1);
6119 sh
->sh_offset
= file_offset
;
6120 file_offset
+= sh
->sh_size
;
6122 /* build program headers (simplistic - not fully correct) */
6124 for(i
=1;i
<shnum
;i
++) {
6126 if (sh
->sh_type
== SHT_PROGBITS
&&
6127 (sh
->sh_flags
& SHF_ALLOC
) != 0) {
6129 ph
->p_type
= PT_LOAD
;
6130 ph
->p_offset
= sh
->sh_offset
;
6131 ph
->p_vaddr
= sh
->sh_addr
;
6132 ph
->p_paddr
= ph
->p_vaddr
;
6133 ph
->p_filesz
= sh
->sh_size
;
6134 ph
->p_memsz
= sh
->sh_size
;
6136 if (sh
->sh_flags
& SHF_WRITE
)
6137 ph
->p_flags
|= PF_W
;
6138 if (sh
->sh_flags
& SHF_EXECINSTR
)
6139 ph
->p_flags
|= PF_X
;
6140 ph
->p_align
= sh
->sh_addralign
;
6145 file_offset
= (file_offset
+ 3) & -4;
6148 ehdr
.e_ident
[0] = ELFMAG0
;
6149 ehdr
.e_ident
[1] = ELFMAG1
;
6150 ehdr
.e_ident
[2] = ELFMAG2
;
6151 ehdr
.e_ident
[3] = ELFMAG3
;
6152 ehdr
.e_ident
[4] = ELFCLASS32
;
6153 ehdr
.e_ident
[5] = ELFDATA2LSB
;
6154 ehdr
.e_ident
[6] = EV_CURRENT
;
6155 ehdr
.e_type
= ET_EXEC
;
6156 ehdr
.e_machine
= EM_386
;
6157 ehdr
.e_version
= EV_CURRENT
;
6158 ehdr
.e_entry
= 0; /* XXX: patch it */
6159 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
6160 ehdr
.e_shoff
= file_offset
;
6161 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
6162 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
6163 ehdr
.e_phnum
= phnum
;
6164 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
6165 ehdr
.e_shnum
= shnum
;
6166 ehdr
.e_shstrndx
= shnum
- 1;
6168 /* write elf file */
6169 f
= fopen(filename
, "w");
6171 error("could not write '%s'", filename
);
6172 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
6173 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
6174 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
6175 for(sec
= first_section
, i
= 1; sec
!= NULL
; sec
= sec
->next
, i
++) {
6177 while (offset
< sh
->sh_offset
) {
6181 size
= sec
->data_ptr
- sec
->data
;
6182 fwrite(sec
->data
, 1, size
, f
);
6185 while (offset
< ehdr
.e_shoff
) {
6189 fwrite(shdr
, 1, shnum
* sizeof(Elf32_Shdr
), f
);
6193 /* print the position in the source file of PC value 'pc' by reading
6194 the stabs debug information */
6195 static void rt_printline(unsigned long wanted_pc
)
6197 Stab_Sym
*sym
, *sym_end
;
6198 char func_name
[128];
6199 unsigned long func_addr
, last_pc
, pc
;
6200 const char *incl_files
[INCLUDE_STACK_SIZE
];
6201 int incl_index
, len
, last_line_num
, i
;
6202 const char *str
, *p
;
6204 func_name
[0] = '\0';
6207 last_pc
= 0xffffffff;
6209 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
6210 sym_end
= (Stab_Sym
*)stab_section
->data_ptr
;
6211 while (sym
< sym_end
) {
6212 switch(sym
->n_type
) {
6213 /* function start or end */
6215 if (sym
->n_strx
== 0) {
6216 func_name
[0] = '\0';
6219 str
= stabstr_section
->data
+ sym
->n_strx
;
6220 p
= strchr(str
, ':');
6222 pstrcpy(func_name
, sizeof(func_name
), str
);
6225 if (len
> sizeof(func_name
) - 1)
6226 len
= sizeof(func_name
) - 1;
6227 memcpy(func_name
, str
, len
);
6228 func_name
[len
] = '\0';
6230 func_addr
= sym
->n_value
;
6233 /* line number info */
6235 pc
= sym
->n_value
+ func_addr
;
6236 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
6239 last_line_num
= sym
->n_desc
;
6243 str
= stabstr_section
->data
+ sym
->n_strx
;
6245 if (incl_index
< INCLUDE_STACK_SIZE
) {
6246 incl_files
[incl_index
++] = str
;
6254 if (sym
->n_strx
== 0) {
6255 incl_index
= 0; /* end of translation unit */
6257 str
= stabstr_section
->data
+ sym
->n_strx
;
6258 /* do not add path */
6260 if (len
> 0 && str
[len
- 1] != '/')
6267 /* did not find line number info: */
6268 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
6271 for(i
= 0; i
< incl_index
- 1; i
++)
6272 fprintf(stderr
, "In file included from %s\n",
6274 if (incl_index
> 0) {
6275 fprintf(stderr
, "%s:%d: ",
6276 incl_files
[incl_index
- 1], last_line_num
);
6278 if (func_name
[0] != '\0') {
6279 fprintf(stderr
, "in function '%s()': ", func_name
);
6283 /* emit a run time error at position 'pc' */
6284 void rt_error(unsigned long pc
, const char *fmt
, ...)
6290 vfprintf(stderr
, fmt
, ap
);
6291 fprintf(stderr
, "\n");
6297 /* signal handler for fatal errors */
6298 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
6300 struct ucontext
*uc
= puc
;
6304 pc
= uc
->uc_mcontext
.gregs
[14];
6306 #error please put the right sigcontext field
6311 switch(siginf
->si_code
) {
6314 rt_error(pc
, "division by zero");
6317 rt_error(pc
, "floating point exception");
6323 rt_error(pc
, "dereferencing invalid pointer");
6326 rt_error(pc
, "illegal instruction");
6329 rt_error(pc
, "abort() called");
6332 rt_error(pc
, "caught signal %d", signum
);
6339 /* launch the compiled program with the given arguments */
6340 int launch_exe(int argc
, char **argv
)
6345 s
= sym_find1(&extern_stack
, TOK_MAIN
);
6346 if (!s
|| (s
->r
& VT_FORWARD
))
6347 error("main() not defined");
6351 error("debug mode currently not available for Windows");
6353 struct sigaction sigact
;
6354 /* install TCC signal handlers to print debug info on fatal
6356 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
6357 sigact
.sa_sigaction
= sig_error
;
6358 sigemptyset(&sigact
.sa_mask
);
6359 sigaction(SIGFPE
, &sigact
, NULL
);
6360 sigaction(SIGILL
, &sigact
, NULL
);
6361 sigaction(SIGSEGV
, &sigact
, NULL
);
6362 sigaction(SIGBUS
, &sigact
, NULL
);
6363 sigaction(SIGABRT
, &sigact
, NULL
);
6367 #ifdef CONFIG_TCC_BCHECK
6368 if (do_bounds_check
) {
6371 /* add all known static regions */
6372 p
= (int *)bounds_section
->data
;
6373 p_end
= (int *)bounds_section
->data_ptr
;
6375 __bound_new_region((void *)p
[0], p
[1]);
6381 t
= (int (*)())s
->c
;
6382 return (*t
)(argc
, argv
);
6388 printf("tcc version 0.9.6 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
6389 "usage: tcc [-Idir] [-Dsym[=val]] [-Usym] [-llib] [-g] [-b]\n"
6390 " [-i infile] infile [infile_args...]\n"
6392 "-Idir : add include path 'dir'\n"
6393 "-Dsym[=val] : define 'sym' with value 'val'\n"
6394 "-Usym : undefine 'sym'\n"
6395 "-llib : link with dynamic library 'lib'\n"
6396 "-g : generate runtime debug info\n"
6397 #ifdef CONFIG_TCC_BCHECK
6398 "-b : compile with built-in memory and bounds checker (implies -g)\n"
6400 "-i infile : compile infile\n"
6404 int main(int argc
, char **argv
)
6406 char *p
, *r
, *outfile
;
6409 include_paths
[0] = "/usr/include";
6410 include_paths
[1] = "/usr/lib/tcc";
6411 include_paths
[2] = "/usr/local/lib/tcc";
6412 nb_include_paths
= 3;
6414 /* add all tokens */
6415 tok_ident
= TOK_IDENT
;
6420 tok_alloc(p
, r
- p
- 1);
6424 /* standard defines */
6425 define_symbol("__STDC__");
6427 define_symbol("__i386__");
6429 /* tiny C specific defines */
6430 define_symbol("__TINYC__");
6432 /* create standard sections */
6433 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
6434 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6435 /* XXX: should change type to SHT_NOBITS */
6436 bss_section
= new_section(".bss", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6441 if (optind
>= argc
) {
6451 if (nb_include_paths
>= INCLUDE_PATHS_MAX
)
6452 error("too many include paths");
6453 include_paths
[nb_include_paths
++] = r
+ 2;
6454 } else if (r
[1] == 'D') {
6455 define_symbol(r
+ 2);
6456 } else if (r
[1] == 'U') {
6457 undef_symbol(r
+ 2);
6458 } else if (r
[1] == 'l') {
6460 } else if (r
[1] == 'i') {
6463 tcc_compile_file(argv
[optind
++]);
6464 } else if (!strcmp(r
+ 1, "bench")) {
6466 #ifdef CONFIG_TCC_BCHECK
6467 } else if (r
[1] == 'b') {
6468 if (!do_bounds_check
) {
6469 do_bounds_check
= 1;
6471 define_symbol("__BOUNDS_CHECKING_ON");
6472 /* create bounds sections */
6473 bounds_section
= new_section(".bounds",
6474 SHT_PROGBITS
, SHF_ALLOC
);
6475 lbounds_section
= new_section(".lbounds",
6476 SHT_PROGBITS
, SHF_ALLOC
);
6477 /* debug is implied */
6481 } else if (r
[1] == 'g') {
6482 #ifdef CONFIG_TCC_BCHECK
6489 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
6490 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
6491 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
6492 put_elf_str(stabstr_section
, "");
6493 stab_section
->link
= stabstr_section
;
6494 /* put first entry */
6495 put_stabs("", 0, 0, 0, 0);
6498 symtab_section
= new_section(".symtab", SHT_SYMTAB
, 0);
6499 symtab_section
->sh_entsize
= sizeof(Elf32_Sym
);
6500 strtab_section
= new_section(".strtab", SHT_STRTAB
, 0);
6501 put_elf_str(strtab_section
, "");
6502 symtab_section
->link
= strtab_section
;
6503 put_elf_sym(symtab_section
, 0, 0, 0, 0, 0, NULL
);
6505 } else if (r
[1] == 'o') {
6506 /* currently, only for testing, so not documented */
6509 outfile
= argv
[optind
++];
6511 error("invalid option -- '%s'", r
);
6515 tcc_compile_file(argv
[optind
]);
6518 printf("total: %d idents, %d lines, %d bytes\n",
6519 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
6522 resolve_extern_syms();
6528 return launch_exe(argc
- optind
, argv
+ optind
);