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 /* amount of virtual memory associated to a section (currently, we do
56 #define SECTION_VSIZE (1024 * 1024)
58 #define INCLUDE_STACK_SIZE 32
59 #define IFDEF_STACK_SIZE 64
60 #define VSTACK_SIZE 64
61 #define STRING_MAX_SIZE 1024
62 #define INCLUDE_PATHS_MAX 32
64 #define TOK_HASH_SIZE 2048 /* must be a power of two */
65 #define TOK_ALLOC_INCR 512 /* must be a power of two */
66 #define SYM_HASH_SIZE 1031
68 /* token symbol management */
69 typedef struct TokenSym
{
70 struct TokenSym
*hash_next
;
71 int tok
; /* token number */
77 typedef union CValue
{
83 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
85 unsigned long long ull
;
92 typedef struct SValue
{
94 unsigned short r
; /* register + flags */
95 unsigned short r2
; /* second register, used for 'long long'
96 type. If not used, set to VT_CONST */
97 CValue c
; /* constant */
100 /* symbol management */
102 int v
; /* symbol token */
103 int t
; /* associated type */
104 int r
; /* associated register */
105 int c
; /* associated number */
106 struct Sym
*next
; /* next related symbol */
107 struct Sym
*prev
; /* prev symbol in stack */
108 struct Sym
*hash_next
; /* next symbol in hash table */
111 typedef struct SymStack
{
113 struct Sym
*hash
[SYM_HASH_SIZE
];
116 /* relocation entry (currently only used for functions or variables */
117 typedef struct Reloc
{
118 int type
; /* type of relocation */
119 int addr
; /* address of relocation */
120 struct Reloc
*next
; /* next relocation */
123 #define RELOC_ADDR32 1 /* 32 bits relocation */
124 #define RELOC_REL32 2 /* 32 bits relative relocation */
126 /* section definition */
127 typedef struct Section
{
128 char name
[64]; /* section name */
129 unsigned char *data
; /* section data */
130 unsigned char *data_ptr
; /* current data pointer */
131 int sh_num
; /* elf section number */
132 int sh_type
; /* elf section type */
133 int sh_flags
; /* elf section flags */
134 int sh_entsize
; /* elf entry size */
135 struct Section
*link
; /* link to another section */
136 struct Section
*next
;
139 /* GNUC attribute definition */
140 typedef struct AttributeDef
{
143 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
146 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
147 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
148 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
150 /* stored in 'Sym.c' field */
151 #define FUNC_NEW 1 /* ansi function prototype */
152 #define FUNC_OLD 2 /* old function prototype */
153 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
155 /* stored in 'Sym.r' field */
156 #define FUNC_CDECL 0 /* standard c call */
157 #define FUNC_STDCALL 1 /* pascal c call */
159 /* field 'Sym.t' for macros */
160 #define MACRO_OBJ 0 /* object like macro */
161 #define MACRO_FUNC 1 /* function like macro */
163 /* type_decl() types */
164 #define TYPE_ABSTRACT 1 /* type without variable */
165 #define TYPE_DIRECT 2 /* type with variable */
167 #define IO_BUF_SIZE 8192
169 typedef struct BufferedFile
{
170 unsigned char *buf_ptr
;
171 unsigned char *buf_end
;
173 int line_num
; /* current line number - here to simply code */
174 char filename
[1024]; /* current filename - here to simply code */
175 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
178 #define CH_EOB 0 /* end of buffer or '\0' char in file */
179 #define CH_EOF (-1) /* end of file */
182 struct BufferedFile
*file
;
183 int ch
, ch1
, tok
, tok1
;
187 Section
*first_section
;
189 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
190 Section
*cur_text_section
; /* current section where function code is
192 /* bound check related sections */
193 Section
*bounds_section
; /* contains global data bound description */
194 Section
*lbounds_section
; /* contains local data bound description */
196 Section
*stab_section
, *stabstr_section
, *symtab_section
, *strtab_section
;
198 /* loc : local variable index
199 ind : output code index
201 anon_sym: anonymous symbol index
204 prog
, ind
, loc
, const_wanted
;
205 int global_expr
; /* true if compound literals must be allocated
206 globally (used during initializers parsing */
207 int func_vt
, func_vc
; /* current function return type (used by
208 return instruction) */
209 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
211 TokenSym
**table_ident
;
212 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
213 char token_buf
[STRING_MAX_SIZE
+ 1];
215 /* contains global symbols which remain between each translation unit */
216 SymStack extern_stack
;
217 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
219 SValue vstack
[VSTACK_SIZE
], *vtop
;
220 int *macro_ptr
, *macro_ptr_allocated
;
221 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
], **include_stack_ptr
;
222 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
223 char *include_paths
[INCLUDE_PATHS_MAX
];
224 int nb_include_paths
;
225 int char_pointer_type
;
227 /* compile with debug symbol (and use them if error during execution) */
230 /* compile with built-in memory and bounds checker */
231 int do_bounds_check
= 0;
233 /* display benchmark infos */
238 /* use GNU C extensions */
241 /* use Tiny C extensions */
244 /* The current value can be: */
245 #define VT_VALMASK 0x00ff
246 #define VT_CONST 0x00f0 /* constant in vc
247 (must be first non register value) */
248 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
249 #define VT_LOCAL 0x00f2 /* offset on stack */
250 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
251 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
252 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
253 #define VT_LVAL 0x0100 /* var is an lvalue */
254 #define VT_FORWARD 0x0200 /* value is forward reference */
255 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
256 char/short stored in integer registers) */
257 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
258 dereferencing value */
261 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
263 #define VT_INT 0 /* integer type */
264 #define VT_BYTE 1 /* signed byte type */
265 #define VT_SHORT 2 /* short type */
266 #define VT_VOID 3 /* void type */
267 #define VT_PTR 4 /* pointer increment */
268 #define VT_ENUM 5 /* enum definition */
269 #define VT_FUNC 6 /* function type */
270 #define VT_STRUCT 7 /* struct/union definition */
271 #define VT_FLOAT 8 /* IEEE float */
272 #define VT_DOUBLE 9 /* IEEE double */
273 #define VT_LDOUBLE 10 /* IEEE long double */
274 #define VT_BOOL 11 /* ISOC99 boolean type */
275 #define VT_LLONG 12 /* 64 bit integer */
276 #define VT_LONG 13 /* long integer (NEVER USED as type, only
278 #define VT_BTYPE 0x000f /* mask for basic type */
279 #define VT_UNSIGNED 0x0010 /* unsigned type */
280 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
281 #define VT_BITFIELD 0x0040 /* bitfield modifier */
284 #define VT_EXTERN 0x00000080 /* extern definition */
285 #define VT_STATIC 0x00000100 /* static variable */
286 #define VT_TYPEDEF 0x00000200 /* typedef definition */
288 /* type mask (except storage) */
289 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
293 /* warning: the following compare tokens depend on i386 asm code */
305 #define TOK_LAND 0xa0
309 #define TOK_MID 0xa3 /* inc/dec, to void constant */
311 #define TOK_UDIV 0xb0 /* unsigned division */
312 #define TOK_UMOD 0xb1 /* unsigned modulo */
313 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
314 #define TOK_CINT 0xb3 /* number in tokc */
315 #define TOK_CCHAR 0xb4 /* char constant in tokc */
316 #define TOK_STR 0xb5 /* pointer to string in tokc */
317 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
318 #define TOK_LCHAR 0xb7
319 #define TOK_LSTR 0xb8
320 #define TOK_CFLOAT 0xb9 /* float constant */
321 #define TOK_CDOUBLE 0xc0 /* double constant */
322 #define TOK_CLDOUBLE 0xc1 /* long double constant */
323 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
324 #define TOK_ADDC1 0xc3 /* add with carry generation */
325 #define TOK_ADDC2 0xc4 /* add with carry use */
326 #define TOK_SUBC1 0xc5 /* add with carry generation */
327 #define TOK_SUBC2 0xc6 /* add with carry use */
328 #define TOK_CUINT 0xc8 /* unsigned int constant */
329 #define TOK_CLLONG 0xc9 /* long long constant */
330 #define TOK_CULLONG 0xca /* unsigned long long constant */
331 #define TOK_ARROW 0xcb
332 #define TOK_DOTS 0xcc /* three dots */
333 #define TOK_SHR 0xcd /* unsigned shift right */
335 #define TOK_SHL 0x01 /* shift left */
336 #define TOK_SAR 0x02 /* signed shift right */
338 /* assignement operators : normal operator or 0x80 */
339 #define TOK_A_MOD 0xa5
340 #define TOK_A_AND 0xa6
341 #define TOK_A_MUL 0xaa
342 #define TOK_A_ADD 0xab
343 #define TOK_A_SUB 0xad
344 #define TOK_A_DIV 0xaf
345 #define TOK_A_XOR 0xde
346 #define TOK_A_OR 0xfc
347 #define TOK_A_SHL 0x81
348 #define TOK_A_SAR 0x82
350 #define TOK_EOF (-1) /* end of file */
352 /* all identificators and strings have token above that */
353 #define TOK_IDENT 256
374 /* ignored types Must have contiguous values */
380 TOK___SIGNED__
, /* gcc keyword */
383 TOK___INLINE__
, /* gcc keyword */
386 /* unsupported type */
400 /* preprocessor only */
401 TOK_UIDENT
, /* first "user" ident (not keyword) */
402 TOK_DEFINE
= TOK_UIDENT
,
418 /* special identifiers */
421 /* attribute identifiers */
439 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
440 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
441 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
442 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
443 "sizeof\0__attribute__\0"
444 /* the following are not keywords. They are included to ease parsing */
445 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
446 "defined\0undef\0error\0line\0"
447 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
450 "section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0"
451 "cdecl\0__cdecl\0__cdecl__\0stdcall\0__stdcall\0__stdcall__\0"
452 "noreturn\0__noreturn__\0"
456 #define snprintf _snprintf
457 /* currently incorrect */
458 long double strtold(const char *nptr
, char **endptr
)
460 return (long double)strtod(nptr
, endptr
);
462 float strtof(const char *nptr
, char **endptr
)
464 return (float)strtod(nptr
, endptr
);
467 /* XXX: need to define this to use them in non ISOC99 context */
468 extern float strtof (const char *__nptr
, char **__endptr
);
469 extern long double strtold (const char *__nptr
, char **__endptr
);
472 char *pstrcpy(char *buf
, int buf_size
, const char *s
);
473 char *pstrcat(char *buf
, int buf_size
, const char *s
);
477 void next_nomacro(void);
478 int expr_const(void);
482 void decl_initializer(int t
, int r
, int c
, int first
, int size_only
);
483 int decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
);
485 void gv2(int rc1
, int rc2
);
486 void move_reg(int r
, int s
);
487 void save_regs(void);
488 void save_reg(int r
);
494 void macro_subst(int **tok_str
, int *tok_len
,
495 Sym
**nested_list
, int *macro_str
);
496 int save_reg_forced(int r
);
498 void force_charshort_cast(int t
);
499 void gen_cast(int t
);
501 Sym
*sym_find(int v
);
502 Sym
*sym_push(int v
, int t
, int r
, int c
);
505 int type_size(int t
, int *a
);
506 int pointed_type(int t
);
507 int pointed_size(int t
);
508 int is_compatible_types(int t1
, int t2
);
509 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
510 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
512 void error(const char *fmt
, ...);
513 void rt_error(unsigned long pc
, const char *fmt
, ...);
515 void vset(int t
, int r
, int v
);
516 void type_to_str(char *buf
, int buf_size
,
517 int t
, const char *varstr
);
519 /* section generation */
520 void greloc(Sym
*s
, int addr
, int type
);
521 static int put_elf_str(Section
*s
, const char *sym
);
522 static void put_elf_sym(Section
*s
,
523 unsigned long value
, unsigned long size
,
524 int info
, int other
, int shndx
, const char *name
);
525 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
);
526 static void put_stabn(int type
, int other
, int desc
, int value
);
527 static void put_stabd(int type
, int other
, int desc
);
529 /* true if float/double/long double type */
530 static inline int is_float(int t
)
534 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
539 #ifdef TCC_TARGET_I386
540 #include "i386-gen.c"
546 #ifdef CONFIG_TCC_STATIC
548 #define RTLD_LAZY 0x001
549 #define RTLD_NOW 0x002
550 #define RTLD_GLOBAL 0x100
552 /* dummy function for profiling */
553 void *dlopen(const char *filename
, int flag
)
558 const char *dlerror(void)
563 typedef struct TCCSyms
{
568 #define TCCSYM(a) { #a, &a, },
570 /* add the symbol you want here if no dynamic linking is done */
571 static TCCSyms tcc_syms
[] = {
579 void *dlsym(void *handle
, const char *symbol
)
583 while (p
->str
!= NULL
) {
584 if (!strcmp(p
->str
, symbol
))
593 /********************************************************/
594 /* runtime library is there */
595 /* XXX: we suppose that the host compiler handles 'long long'. It
596 would not be difficult to suppress this assumption */
598 long long __divll(long long a
, long long b
)
603 long long __modll(long long a
, long long b
)
608 unsigned long long __divull(unsigned long long a
, unsigned long long b
)
613 unsigned long long __modull(unsigned long long a
, unsigned long long b
)
618 long long __sardi3(long long a
, int b
)
623 unsigned long long __shrdi3(unsigned long long a
, int b
)
628 long long __shldi3(long long a
, int b
)
633 float __ulltof(unsigned long long a
)
638 double __ulltod(unsigned long long a
)
643 long double __ulltold(unsigned long long a
)
645 return (long double)a
;
648 unsigned long long __ftoull(float a
)
650 return (unsigned long long)a
;
653 unsigned long long __dtoull(double a
)
655 return (unsigned long long)a
;
658 unsigned long long __ldtoull(long double a
)
660 return (unsigned long long)a
;
664 /********************************************************/
666 /* copy a string and truncate it. */
667 char *pstrcpy(char *buf
, int buf_size
, const char *s
)
674 q_end
= buf
+ buf_size
- 1;
686 /* strcat and truncate. */
687 char *pstrcat(char *buf
, int buf_size
, const char *s
)
692 pstrcpy(buf
+ len
, buf_size
- len
, s
);
696 Section
*new_section(const char *name
, int sh_type
, int sh_flags
)
698 Section
*sec
, **psec
;
701 sec
= malloc(sizeof(Section
));
703 error("memory full");
704 memset(sec
, 0, sizeof(Section
));
705 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
707 sec
->sh_num
= ++section_num
;
708 sec
->sh_type
= sh_type
;
709 sec
->sh_flags
= sh_flags
;
711 /* XXX: currently, a single malloc */
712 data
= malloc(SECTION_VSIZE
);
714 error("could not alloc section '%s'", name
);
716 data
= mmap(NULL
, SECTION_VSIZE
,
717 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
718 MAP_PRIVATE
| MAP_ANONYMOUS
,
720 if (data
== (void *)(-1))
721 error("could not mmap section '%s'", name
);
724 sec
->data_ptr
= data
;
725 psec
= &first_section
;
726 while (*psec
!= NULL
)
727 psec
= &(*psec
)->next
;
733 /* return a reference to a section, and create it if it does not
735 Section
*find_section(const char *name
)
739 for(sec
= first_section
; sec
!= NULL
; sec
= sec
->next
) {
740 if (!strcmp(name
, sec
->name
))
743 /* sections are created as PROGBITS */
744 return new_section(name
, SHT_PROGBITS
, SHF_ALLOC
);
747 /* add a new relocation entry to symbol 's' */
748 void greloc(Sym
*s
, int addr
, int type
)
751 p
= malloc(sizeof(Reloc
));
753 error("memory full");
756 p
->next
= (Reloc
*)s
->c
;
760 /* patch each relocation entry with value 'val' */
761 void greloc_patch(Sym
*s
, int val
)
768 greloc_patch1(p
, val
);
777 static inline int isid(int c
)
779 return (c
>= 'a' && c
<= 'z') ||
780 (c
>= 'A' && c
<= 'Z') ||
784 static inline int isnum(int c
)
786 return c
>= '0' && c
<= '9';
789 static inline int toup(int c
)
791 if (ch
>= 'a' && ch
<= 'z')
792 return ch
- 'a' + 'A';
800 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
801 fprintf(stderr
, "In file included from %s:%d:\n",
802 (*f
)->filename
, (*f
)->line_num
);
803 fprintf(stderr
, "%s:%d: ", file
->filename
, file
->line_num
);
806 void error(const char *fmt
, ...)
811 vfprintf(stderr
, fmt
, ap
);
812 fprintf(stderr
, "\n");
817 void expect(const char *msg
)
819 error("%s expected", msg
);
822 void warning(const char *fmt
, ...)
828 fprintf(stderr
, "warning: ");
829 vfprintf(stderr
, fmt
, ap
);
830 fprintf(stderr
, "\n");
837 error("'%c' expected", c
);
841 void test_lvalue(void)
843 if (!(vtop
->r
& VT_LVAL
))
847 TokenSym
*tok_alloc(const char *str
, int len
)
849 TokenSym
*ts
, **pts
, **ptable
;
856 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
858 pts
= &hash_ident
[h
];
863 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
865 pts
= &(ts
->hash_next
);
868 if (tok_ident
>= SYM_FIRST_ANOM
)
869 error("memory full");
871 /* expand token table if needed */
872 i
= tok_ident
- TOK_IDENT
;
873 if ((i
% TOK_ALLOC_INCR
) == 0) {
874 ptable
= realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
876 error("memory full");
877 table_ident
= ptable
;
880 ts
= malloc(sizeof(TokenSym
) + len
);
882 error("memory full");
884 ts
->tok
= tok_ident
++;
886 ts
->hash_next
= NULL
;
887 memcpy(ts
->str
, str
, len
+ 1);
892 void add_char(char **pp
, int c
)
896 if (c
== '\'' || c
== '\"' || c
== '\\') {
897 /* XXX: could be more precise if char or string */
900 if (c
>= 32 && c
<= 126) {
907 *p
++ = '0' + ((c
>> 6) & 7);
908 *p
++ = '0' + ((c
>> 3) & 7);
909 *p
++ = '0' + (c
& 7);
915 /* XXX: buffer overflow */
916 char *get_tok_str(int v
, CValue
*cv
)
918 static char buf
[STRING_MAX_SIZE
+ 1];
923 if (v
== TOK_CINT
|| v
== TOK_CUINT
) {
924 sprintf(buf
, "%u", cv
->ui
);
926 } else if (v
== TOK_CCHAR
|| v
== TOK_LCHAR
) {
933 } else if (v
== TOK_STR
|| v
== TOK_LSTR
) {
937 for(i
=0;i
<ts
->len
;i
++)
938 add_char(&p
, ts
->str
[i
]);
942 } else if (v
< TOK_IDENT
) {
947 } else if (v
< tok_ident
) {
948 return table_ident
[v
- TOK_IDENT
]->str
;
950 /* should never happen */
955 /* push, without hashing */
956 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
959 s
= malloc(sizeof(Sym
));
961 error("memory full");
972 /* find a symbol and return its associated structure. 's' is the top
973 of the symbol stack */
974 Sym
*sym_find2(Sym
*s
, int v
)
984 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
986 /* find a symbol and return its associated structure. 'st' is the
988 Sym
*sym_find1(SymStack
*st
, int v
)
992 s
= st
->hash
[HASH_SYM(v
)];
1001 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1004 s
= sym_push2(&st
->top
, v
, t
, c
);
1005 /* add in hash table */
1007 ps
= &st
->hash
[HASH_SYM(v
)];
1014 /* find a symbol in the right symbol space */
1015 Sym
*sym_find(int v
)
1018 s
= sym_find1(&local_stack
, v
);
1020 s
= sym_find1(&global_stack
, v
);
1024 /* push a given symbol on the symbol stack */
1025 Sym
*sym_push(int v
, int t
, int r
, int c
)
1028 if (local_stack
.top
)
1029 s
= sym_push1(&local_stack
, v
, t
, c
);
1031 s
= sym_push1(&global_stack
, v
, t
, c
);
1036 /* pop symbols until top reaches 'b' */
1037 void sym_pop(SymStack
*st
, Sym
*b
)
1044 /* free hash table entry, except if symbol was freed (only
1045 used for #undef symbols) */
1047 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1054 /* undefined a hashed symbol (used for #undef). Its name is set to
1056 void sym_undef(SymStack
*st
, Sym
*s
)
1059 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1060 while (*ss
!= NULL
) {
1063 ss
= &(*ss
)->hash_next
;
1071 BufferedFile
*tcc_open(const char *filename
)
1076 fd
= open(filename
, O_RDONLY
);
1079 bf
= malloc(sizeof(BufferedFile
));
1085 bf
->buf_ptr
= bf
->buffer
;
1086 bf
->buf_end
= bf
->buffer
;
1087 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1088 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1090 // printf("opening '%s'\n", filename);
1094 void tcc_close(BufferedFile
*bf
)
1096 total_lines
+= bf
->line_num
;
1101 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1102 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1104 /* fill input buffer and return next char */
1105 int tcc_getc_slow(BufferedFile
*bf
)
1108 /* only tries to read if really end of buffer */
1109 if (bf
->buf_ptr
>= bf
->buf_end
) {
1111 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1118 bf
->buf_ptr
= bf
->buffer
;
1119 bf
->buf_end
= bf
->buffer
+ len
;
1120 *bf
->buf_end
= CH_EOB
;
1122 if (bf
->buf_ptr
< bf
->buf_end
) {
1123 return *bf
->buf_ptr
++;
1125 bf
->buf_ptr
= bf
->buf_end
;
1130 /* no need to put that inline */
1131 void handle_eob(void)
1134 ch1
= tcc_getc_slow(file
);
1138 if (include_stack_ptr
== include_stack
)
1140 /* add end of include file debug info */
1142 put_stabd(N_EINCL
, 0, 0);
1144 /* pop include stack */
1146 include_stack_ptr
--;
1147 file
= *include_stack_ptr
;
1151 /* read next char from current input file */
1152 static inline void inp(void)
1154 ch1
= TCC_GETC(file
);
1155 /* end of buffer/file handling */
1160 // printf("ch1=%c 0x%x\n", ch1, ch1);
1163 /* input with '\\n' handling */
1164 static inline void minp(void)
1169 if (ch
== '\\' && ch1
== '\n') {
1173 //printf("ch=%c 0x%x\n", ch, ch);
1177 /* same as minp, but also skip comments */
1185 /* single line C++ comments */
1187 while (ch1
!= '\n' && ch1
!= -1)
1190 ch
= ' '; /* return space */
1191 } else if (ch1
== '*') {
1197 if (c
== '*' && ch1
== '/') {
1199 ch
= ' '; /* return space */
1211 void skip_spaces(void)
1213 while (ch
== ' ' || ch
== '\t')
1217 /* skip block of text until #else, #elif or #endif. skip also pairs of
1219 void preprocess_skip(void)
1224 while (ch
!= '\n') {
1235 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1237 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1239 else if (tok
== TOK_ENDIF
)
1245 /* return the number of additionnal 'ints' necessary to store the
1247 static inline int tok_ext_size(int t
)
1264 return LDOUBLE_SIZE
/ 4;
1270 void tok_add(int **tok_str
, int *tok_len
, int t
)
1275 if ((len
& 63) == 0) {
1276 str
= realloc(str
, (len
+ 64) * sizeof(int));
1285 void tok_add2(int **tok_str
, int *tok_len
, int t
, CValue
*cv
)
1289 tok_add(tok_str
, tok_len
, t
);
1290 n
= tok_ext_size(t
);
1292 tok_add(tok_str
, tok_len
, cv
->tab
[i
]);
1295 /* get a token from an integer array and increment pointer accordingly */
1296 int tok_get(int **tok_str
, CValue
*cv
)
1302 n
= tok_ext_size(t
);
1309 /* eval an expression for #if/#elif */
1310 int expr_preprocess(void)
1312 int *str
, len
, c
, t
;
1320 next(); /* do macro subst */
1321 if (tok
== TOK_DEFINED
) {
1326 c
= sym_find1(&define_stack
, tok
) != 0;
1331 } else if (tok
>= TOK_IDENT
) {
1332 /* if undefined macro */
1336 tok_add2(&str
, &len
, tok
, &tokc
);
1338 tok_add(&str
, &len
, -1); /* simulate end of file */
1339 tok_add(&str
, &len
, 0);
1340 /* now evaluate C constant expression */
1349 #if defined(DEBUG) || defined(PP_DEBUG)
1350 void tok_print(int *str
)
1356 t
= tok_get(&str
, &cval
);
1359 printf(" %s", get_tok_str(t
, &cval
));
1365 /* parse after #define */
1366 void parse_define(void)
1368 Sym
*s
, *first
, **ps
;
1369 int v
, t
, *str
, len
;
1372 /* XXX: should check if same macro (ANSI) */
1375 /* '(' must be just after macro definition for MACRO_FUNC */
1380 while (tok
!= ')') {
1381 if (tok
== TOK_DOTS
)
1382 tok
= TOK___VA_ARGS__
;
1383 s
= sym_push1(&define_stack
, tok
| SYM_FIELD
, 0, 0);
1397 if (ch
== '\n' || ch
== -1)
1400 tok_add2(&str
, &len
, tok
, &tokc
);
1402 tok_add(&str
, &len
, 0);
1404 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1407 s
= sym_push1(&define_stack
, v
, t
, (int)str
);
1411 void preprocess(void)
1414 char buf
[1024], *q
, *p
;
1422 if (tok
== TOK_DEFINE
) {
1425 } else if (tok
== TOK_UNDEF
) {
1427 s
= sym_find1(&define_stack
, tok
);
1428 /* undefine symbol by putting an invalid name */
1430 sym_undef(&define_stack
, s
);
1431 } else if (tok
== TOK_INCLUDE
) {
1436 } else if (ch
== '\"') {
1441 while (ch
!= c
&& ch
!= '\n' && ch
!= -1) {
1442 if ((q
- buf
) < sizeof(buf
) - 1)
1450 error("#include syntax error");
1451 pstrcpy(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
1454 /* eat all spaces and comments after include */
1455 /* XXX: slightly incorrect */
1456 while (ch1
!= '\n' && ch1
!= -1)
1459 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1460 error("memory full");
1462 /* first search in current dir if "header.h" */
1464 p
= strrchr(file
->filename
, '/');
1466 size
= p
+ 1 - file
->filename
;
1467 if (size
> sizeof(buf1
) - 1)
1468 size
= sizeof(buf1
) - 1;
1469 memcpy(buf1
, file
->filename
, size
);
1471 pstrcat(buf1
, sizeof(buf1
), buf
);
1476 /* now search in standard include path */
1477 for(i
=nb_include_paths
- 1;i
>=0;i
--) {
1478 strcpy(buf1
, include_paths
[i
]);
1485 error("include file '%s' not found", buf1
);
1488 /* push current file in stack */
1489 /* XXX: fix current line init */
1490 *include_stack_ptr
++ = file
;
1492 /* add include file debug info */
1494 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
1496 } else if (tok
== TOK_IFNDEF
) {
1499 } else if (tok
== TOK_IF
) {
1500 c
= expr_preprocess();
1502 } else if (tok
== TOK_IFDEF
) {
1506 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1508 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1509 error("memory full");
1510 *ifdef_stack_ptr
++ = c
;
1512 } else if (tok
== TOK_ELSE
) {
1513 if (ifdef_stack_ptr
== ifdef_stack
)
1514 error("#else without matching #if");
1515 if (ifdef_stack_ptr
[-1] & 2)
1516 error("#else after #else");
1517 c
= (ifdef_stack_ptr
[-1] ^= 3);
1519 } else if (tok
== TOK_ELIF
) {
1520 if (ifdef_stack_ptr
== ifdef_stack
)
1521 error("#elif without matching #if");
1522 c
= ifdef_stack_ptr
[-1];
1524 error("#elif after #else");
1525 /* last #if/#elif expression was true: we skip */
1528 c
= expr_preprocess();
1529 ifdef_stack_ptr
[-1] = c
;
1536 } else if (tok
== TOK_ENDIF
) {
1537 if (ifdef_stack_ptr
== ifdef_stack
)
1538 error("#endif without matching #if");
1540 } else if (tok
== TOK_LINE
) {
1542 if (tok
!= TOK_CINT
)
1544 file
->line_num
= tokc
.i
;
1550 pstrcpy(file
->filename
, sizeof(file
->filename
),
1551 get_tok_str(tok
, &tokc
));
1553 } else if (tok
== TOK_ERROR
) {
1556 /* ignore other preprocess commands or #! for C scripts */
1557 while (ch
!= '\n' && ch
!= -1)
1561 /* read a number in base b */
1567 if (ch
>= 'a' && ch
<= 'f')
1569 else if (ch
>= 'A' && ch
<= 'F')
1575 if (t
< 0 || t
>= b
)
1583 /* read a character for string or char constant and eval escape codes */
1592 /* at most three octal digits */
1596 c
= c
* 8 + ch
- '0';
1599 c
= c
* 8 + ch
- '0';
1604 } else if (ch
== 'x') {
1622 else if (ch
== 'e' && gnu_ext
)
1624 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
1627 error("invalid escaped char");
1634 /* we use 64 bit numbers */
1637 /* bn = (bn << shift) | or_val */
1638 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
1642 for(i
=0;i
<BN_SIZE
;i
++) {
1644 bn
[i
] = (v
<< shift
) | or_val
;
1645 or_val
= v
>> (32 - shift
);
1649 void bn_zero(unsigned int *bn
)
1652 for(i
=0;i
<BN_SIZE
;i
++) {
1657 void parse_number(void)
1659 int b
, t
, shift
, frac_bits
, s
, exp_val
;
1661 unsigned int bn
[BN_SIZE
];
1671 /* special dot handling */
1672 if (ch
>= '0' && ch
<= '9') {
1673 goto float_frac_parse
;
1674 } else if (ch
== '.') {
1685 } else if (t
== '0') {
1686 if (ch
== 'x' || ch
== 'X') {
1690 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
1696 /* parse all digits. cannot check octal numbers at this stage
1697 because of floating point constants */
1699 if (ch
>= 'a' && ch
<= 'f')
1701 else if (ch
>= 'A' && ch
<= 'F')
1709 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
1711 error("number too long");
1717 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
1718 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
1720 /* NOTE: strtox should support that for hexa numbers, but
1721 non ISOC99 libcs do not support it, so we prefer to do
1723 /* hexadecimal or binary floats */
1724 /* XXX: handle overflows */
1736 } else if (t
>= 'a') {
1738 } else if (t
>= 'A') {
1743 bn_lshift(bn
, shift
, t
);
1750 if (t
>= 'a' && t
<= 'f') {
1752 } else if (t
>= 'A' && t
<= 'F') {
1754 } else if (t
>= '0' && t
<= '9') {
1760 error("invalid digit");
1761 bn_lshift(bn
, shift
, t
);
1766 if (ch
!= 'p' && ch
!= 'P')
1767 error("exponent expected");
1773 } else if (ch
== '-') {
1777 if (ch
< '0' || ch
> '9')
1778 error("exponent digits expected");
1779 while (ch
>= '0' && ch
<= '9') {
1780 exp_val
= exp_val
* 10 + ch
- '0';
1783 exp_val
= exp_val
* s
;
1785 /* now we can generate the number */
1786 /* XXX: should patch directly float number */
1787 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
1788 d
= ldexp(d
, exp_val
- frac_bits
);
1793 /* float : should handle overflow */
1795 } else if (t
== 'L') {
1798 /* XXX: not large enough */
1799 tokc
.ld
= (long double)d
;
1805 /* decimal floats */
1807 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1812 while (ch
>= '0' && ch
<= '9') {
1813 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1819 if (ch
== 'e' || ch
== 'E') {
1820 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1824 if (ch
== '-' || ch
== '+') {
1825 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1830 if (ch
< '0' || ch
> '9')
1831 error("exponent digits expected");
1832 while (ch
>= '0' && ch
<= '9') {
1833 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1845 tokc
.f
= strtof(token_buf
, NULL
);
1846 } else if (t
== 'L') {
1849 tokc
.ld
= strtold(token_buf
, NULL
);
1852 tokc
.d
= strtod(token_buf
, NULL
);
1856 unsigned long long n
, n1
;
1859 /* integer number */
1862 if (b
== 10 && *q
== '0') {
1869 /* no need for checks except for base 10 / 8 errors */
1872 } else if (t
>= 'a') {
1874 } else if (t
>= 'A') {
1879 error("invalid digit");
1883 /* detect overflow */
1885 error("integer constant overflow");
1888 /* XXX: not exactly ANSI compliant */
1889 if ((n
& 0xffffffff00000000LL
) != 0) {
1894 } else if (n
> 0x7fffffff) {
1904 error("three 'l' in integer constant");
1907 if (tok
== TOK_CINT
)
1909 else if (tok
== TOK_CUINT
)
1913 } else if (t
== 'U') {
1914 if (tok
== TOK_CINT
)
1916 else if (tok
== TOK_CLLONG
)
1923 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
1931 /* return next token without macro substitution */
1932 void next_nomacro1(void)
1940 while (ch
== '\n') {
1942 while (ch
== ' ' || ch
== '\t')
1945 /* preprocessor command if # at start of line after
1950 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
1968 while (isid(ch
) || isnum(ch
)) {
1969 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1970 error("ident too long");
1975 ts
= tok_alloc(token_buf
, q
- token_buf
);
1977 } else if (isnum(ch
) || ch
== '.') {
1979 } else if (ch
== '\'') {
1987 } else if (ch
== '\"') {
1992 while (ch
!= '\"') {
1995 error("unterminated string");
1996 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1997 error("string too long");
2001 tokc
.ts
= tok_alloc(token_buf
, q
- token_buf
);
2004 q
= "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2009 if (*q
== tok
&& q
[1] == ch
) {
2012 /* three chars tests */
2013 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2018 } else if (tok
== TOK_DOTS
) {
2020 error("parse error");
2027 /* single char substitutions */
2030 else if (tok
== '>')
2035 /* return next token without macro substitution. Can read input from
2042 tok
= tok_get(¯o_ptr
, &tokc
);
2048 /* substitute args in macro_str and return allocated string */
2049 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2051 int *st
, last_tok
, t
, notfirst
, *str
, len
;
2060 t
= tok_get(¯o_str
, &cval
);
2065 t
= tok_get(¯o_str
, &cval
);
2068 s
= sym_find2(args
, t
);
2070 token_buf
[0] = '\0';
2075 pstrcat(token_buf
, sizeof(token_buf
), " ");
2076 t
= tok_get(&st
, &cval
);
2077 pstrcat(token_buf
, sizeof(token_buf
), get_tok_str(t
, &cval
));
2081 printf("stringize: %s\n", token_buf
);
2084 ts
= tok_alloc(token_buf
, 0);
2086 tok_add2(&str
, &len
, TOK_STR
, &cval
);
2088 tok_add2(&str
, &len
, t
, &cval
);
2090 } else if (t
>= TOK_IDENT
) {
2091 s
= sym_find2(args
, t
);
2094 /* if '##' is present before or after , no arg substitution */
2095 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2097 tok_add(&str
, &len
, *st
++);
2099 macro_subst(&str
, &len
, nested_list
, st
);
2102 tok_add(&str
, &len
, t
);
2105 tok_add2(&str
, &len
, t
, &cval
);
2109 tok_add(&str
, &len
, 0);
2113 /* handle the '##' operator */
2114 int *macro_twosharps(int *macro_str
)
2117 int *macro_str1
, macro_str1_len
, *macro_ptr1
;
2129 while (*macro_ptr
== TOK_TWOSHARPS
) {
2131 macro_ptr1
= macro_ptr
;
2134 t
= tok_get(¯o_ptr
, &cval
);
2135 /* XXX: we handle only most common cases:
2136 ident + ident or ident + number */
2137 if (tok
>= TOK_IDENT
&&
2138 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
2139 p
= get_tok_str(tok
, &tokc
);
2140 pstrcpy(token_buf
, sizeof(token_buf
), p
);
2141 p
= get_tok_str(t
, &cval
);
2142 pstrcat(token_buf
, sizeof(token_buf
), p
);
2143 ts
= tok_alloc(token_buf
, 0);
2144 tok
= ts
->tok
; /* modify current token */
2146 /* cannot merge tokens: skip '##' */
2147 macro_ptr
= macro_ptr1
;
2152 tok_add2(¯o_str1
, ¯o_str1_len
, tok
, &tokc
);
2154 tok_add(¯o_str1
, ¯o_str1_len
, 0);
2160 /* do macro substitution of macro_str and add result to
2161 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2162 substituted. 'nested_list' is the list of all macros we got inside
2163 to avoid recursing. */
2164 void macro_subst(int **tok_str
, int *tok_len
,
2165 Sym
**nested_list
, int *macro_str
)
2167 Sym
*s
, *args
, *sa
, *sa1
;
2168 int *str
, parlevel
, len
, *mstr
, t
, *saved_macro_ptr
;
2169 int mstr_allocated
, *macro_str1
;
2172 saved_macro_ptr
= macro_ptr
;
2173 macro_ptr
= macro_str
;
2176 /* first scan for '##' operator handling */
2177 macro_str1
= macro_twosharps(macro_str
);
2178 macro_ptr
= macro_str1
;
2185 /* special macros */
2186 if (tok
== TOK___LINE__
) {
2187 cval
.i
= file
->line_num
;
2188 tok_add2(tok_str
, tok_len
, TOK_CINT
, &cval
);
2189 } else if (tok
== TOK___FILE__
) {
2190 cval
.ts
= tok_alloc(file
->filename
, 0);
2191 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
2192 } else if (tok
== TOK___DATE__
) {
2193 cval
.ts
= tok_alloc("Jan 1 1970", 0);
2194 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
2195 } else if (tok
== TOK___TIME__
) {
2196 cval
.ts
= tok_alloc("00:00:00", 0);
2197 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
2198 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
2199 /* if symbol is a macro, prepare substitution */
2200 /* if nested substitution, do nothing */
2201 if (sym_find2(*nested_list
, tok
))
2205 if (s
->t
== MACRO_FUNC
) {
2206 /* NOTE: we do not use next_nomacro to avoid eating the
2207 next token. XXX: find better solution */
2211 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
2215 if (t
!= '(') /* no macro subst */
2218 /* argument macro */
2223 /* NOTE: empty args are allowed, except if no args */
2225 /* handle '()' case */
2226 if (!args
&& tok
== ')')
2229 error("macro '%s' used with too many args",
2230 get_tok_str(s
->v
, 0));
2234 while ((parlevel
> 0 ||
2237 sa
->v
== (TOK___VA_ARGS__
| SYM_FIELD
)))) &&
2241 else if (tok
== ')')
2243 tok_add2(&str
, &len
, tok
, &tokc
);
2246 tok_add(&str
, &len
, 0);
2247 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, 0, (int)str
);
2256 error("macro '%s' used with too few args",
2257 get_tok_str(s
->v
, 0));
2259 /* now subst each arg */
2260 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2271 sym_push2(nested_list
, s
->v
, 0, 0);
2272 macro_subst(tok_str
, tok_len
, nested_list
, mstr
);
2273 /* pop nested defined symbol */
2275 *nested_list
= sa1
->prev
;
2281 /* no need to add if reading input stream */
2284 tok_add2(tok_str
, tok_len
, tok
, &tokc
);
2286 /* only replace one macro while parsing input stream */
2290 macro_ptr
= saved_macro_ptr
;
2295 /* return next token with macro substitution */
2301 /* special 'ungettok' case for label parsing */
2309 /* if not reading from macro substituted string, then try to substitute */
2313 macro_subst(&ptr
, &len
, &nested_list
, NULL
);
2315 tok_add(&ptr
, &len
, 0);
2317 macro_ptr_allocated
= ptr
;
2325 /* end of macro string: free it */
2326 free(macro_ptr_allocated
);
2333 printf("token = %s\n", get_tok_str(tok
, tokc
));
2337 void swap(int *p
, int *q
)
2345 void vsetc(int t
, int r
, CValue
*vc
)
2347 if (vtop
>= vstack
+ VSTACK_SIZE
)
2348 error("memory full");
2349 /* cannot let cpu flags if other instruction are generated */
2350 /* XXX: VT_JMP test too ? */
2351 if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
2356 vtop
->r2
= VT_CONST
;
2360 /* push integer constant */
2365 vsetc(VT_INT
, VT_CONST
, &cval
);
2368 void vset(int t
, int r
, int v
)
2385 void vpushv(SValue
*v
)
2387 if (vtop
>= vstack
+ VSTACK_SIZE
)
2388 error("memory full");
2398 /* save r to the memory stack, and mark it as being free */
2399 void save_reg(int r
)
2401 int l
, i
, saved
, t
, size
, align
;
2404 /* modify all stack values */
2407 for(p
=vstack
;p
<=vtop
;p
++) {
2408 i
= p
->r
& VT_VALMASK
;
2409 if ((p
->r
& VT_VALMASK
) == r
||
2410 (p
->r2
& VT_VALMASK
) == r
) {
2411 /* must save value on stack if not already done */
2413 /* store register in the stack */
2415 if ((p
->r
& VT_LVAL
) ||
2416 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
2418 size
= type_size(t
, &align
);
2419 loc
= (loc
- size
) & -align
;
2421 sv
.r
= VT_LOCAL
| VT_LVAL
;
2424 #ifdef TCC_TARGET_I386
2425 /* x86 specific: need to pop fp register ST0 if saved */
2427 o(0xd9dd); /* fstp %st(1) */
2430 /* special long long case */
2431 if ((p
->t
& VT_BTYPE
) == VT_LLONG
) {
2438 /* mark that stack entry as being saved on the stack */
2450 /* find a free register of class 'rc'. If none, save one register */
2456 /* find a free register */
2457 for(r
=0;r
<NB_REGS
;r
++) {
2458 if (reg_classes
[r
] & rc
) {
2459 for(p
=vstack
;p
<=vtop
;p
++) {
2460 if ((p
->r
& VT_VALMASK
) == r
||
2461 (p
->r2
& VT_VALMASK
) == r
)
2469 /* no register left : free the first one on the stack (VERY
2470 IMPORTANT to start from the bottom to ensure that we don't
2471 spill registers used in gen_opi()) */
2472 for(p
=vstack
;p
<=vtop
;p
++) {
2473 r
= p
->r
& VT_VALMASK
;
2474 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
2482 void save_regs(void)
2487 for(p
=vstack
;p
<=vtop
;p
++) {
2488 r
= p
->r
& VT_VALMASK
;
2495 /* move register 's' to 'r', and flush previous value of r to memory
2497 void move_reg(int r
, int s
)
2510 /* get address of vtop (vtop MUST BE an lvalue) */
2513 vtop
->r
&= ~VT_LVAL
;
2514 /* tricky: if saved lvalue, then we can go back to lvalue */
2515 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
2516 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
2519 /* generate lvalue bound code */
2522 vtop
->r
&= ~VT_MUSTBOUND
;
2523 /* if lvalue, then use checking code before dereferencing */
2524 if (vtop
->r
& VT_LVAL
) {
2527 gen_bounded_ptr_add1();
2528 gen_bounded_ptr_add2(1);
2533 /* store vtop a register belonging to class 'rc'. lvalues are
2534 converted to values. Cannot be used if cannot be converted to
2535 register value (such as structures). */
2538 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
, data_offset
;
2539 unsigned long long ll
;
2541 /* NOTE: get_reg can modify vstack[] */
2542 if (vtop
->t
& VT_BITFIELD
) {
2543 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2544 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2545 /* remove bit field info to avoid loops */
2546 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2547 /* generate shifts */
2548 vpushi(32 - (bit_pos
+ bit_size
));
2550 vpushi(32 - bit_size
);
2551 /* NOTE: transformed to SHR if unsigned */
2555 if (is_float(vtop
->t
) &&
2556 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2557 /* CPUs usually cannot use float constants, so we store them
2558 generically in data segment */
2559 size
= type_size(vtop
->t
, &align
);
2560 data_offset
= (int)data_section
->data_ptr
;
2561 data_offset
= (data_offset
+ align
- 1) & -align
;
2562 /* XXX: not portable yet */
2565 ((int *)data_offset
)[i
] = vtop
->c
.tab
[i
];
2567 vtop
->c
.ul
= data_offset
;
2568 data_offset
+= size
<< 2;
2569 data_section
->data_ptr
= (unsigned char *)data_offset
;
2571 if (vtop
->r
& VT_MUSTBOUND
)
2574 r
= vtop
->r
& VT_VALMASK
;
2575 /* need to reload if:
2577 - lvalue (need to dereference pointer)
2578 - already a register, but not in the right class */
2579 if (r
>= VT_CONST
||
2580 (vtop
->r
& VT_LVAL
) ||
2581 !(reg_classes
[r
] & rc
) ||
2582 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
2583 !(reg_classes
[vtop
->r2
] & rc
))) {
2585 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
2586 /* two register type load : expand to two words
2588 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2591 vtop
->c
.ui
= ll
; /* first word */
2593 vtop
->r
= r
; /* save register value */
2594 vpushi(ll
>> 32); /* second word */
2595 } else if (r
>= VT_CONST
||
2596 (vtop
->r
& VT_LVAL
)) {
2597 /* load from memory */
2600 vtop
[-1].r
= r
; /* save register value */
2601 /* increment pointer to get second word */
2608 /* move registers */
2611 vtop
[-1].r
= r
; /* save register value */
2612 vtop
->r
= vtop
[-1].r2
;
2614 /* allocate second register */
2621 /* write second register */
2624 /* one register type load */
2633 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2634 void gv2(int rc1
, int rc2
)
2636 /* generate more generic register first */
2642 /* test if reload is needed for first register */
2643 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2653 /* test if reload is needed for first register */
2654 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2660 /* expand long long on stack in two int registers */
2665 u
= vtop
->t
& VT_UNSIGNED
;
2668 vtop
[0].r
= vtop
[-1].r2
;
2669 vtop
[0].r2
= VT_CONST
;
2670 vtop
[-1].r2
= VT_CONST
;
2671 vtop
[0].t
= VT_INT
| u
;
2672 vtop
[-1].t
= VT_INT
| u
;
2675 /* build a long long from two ints */
2678 gv2(RC_INT
, RC_INT
);
2679 vtop
[-1].r2
= vtop
[0].r
;
2684 /* rotate n first stack elements to the bottom */
2691 for(i
=-n
+1;i
!=0;i
++)
2692 vtop
[i
] = vtop
[i
+1];
2696 /* pop stack value */
2699 #ifdef TCC_TARGET_I386
2700 /* for x86, we need to pop the FP stack */
2701 if ((vtop
->r
& VT_VALMASK
) == REG_ST0
) {
2702 o(0xd9dd); /* fstp %st(1) */
2708 /* convert stack entry to register and duplicate its value in another
2716 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2723 /* stack: H L L1 H1 */
2731 /* duplicate value */
2742 load(r1
, &sv
); /* move r to r1 */
2744 /* duplicates value */
2749 /* generate CPU independent (unsigned) long long operations */
2750 void gen_opl(int op
)
2752 int t
, a
, b
, op1
, c
, i
;
2771 /* call generic long long function */
2772 gfunc_start(&gf
, FUNC_CDECL
);
2779 vtop
->r2
= REG_LRET
;
2792 /* stack: L1 H1 L2 H2 */
2797 vtop
[-2] = vtop
[-3];
2800 /* stack: H1 H2 L1 L2 */
2806 /* stack: H1 H2 L1 L2 ML MH */
2809 /* stack: ML MH H1 H2 L1 L2 */
2813 /* stack: ML MH H1 L2 H2 L1 */
2818 /* stack: ML MH M1 M2 */
2821 } else if (op
== '+' || op
== '-') {
2822 /* XXX: add non carry method too (for MIPS or alpha) */
2828 /* stack: H1 H2 (L1 op L2) */
2831 gen_op(op1
+ 1); /* TOK_xxxC2 */
2834 /* stack: H1 H2 (L1 op L2) */
2837 /* stack: (L1 op L2) H1 H2 */
2839 /* stack: (L1 op L2) (H1 op H2) */
2847 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
) {
2852 /* stack: L H shift */
2854 /* constant: simpler */
2855 /* NOTE: all comments are for SHL. the other cases are
2856 done by swaping words */
2867 if (op
!= TOK_SAR
) {
2897 /* XXX: should provide a faster fallback on x86 ? */
2912 /* compare operations */
2918 /* stack: L1 H1 L2 H2 */
2920 vtop
[-1] = vtop
[-2];
2922 /* stack: L1 L2 H1 H2 */
2925 /* when values are equal, we need to compare low words. since
2926 the jump is inverted, we invert the test too. */
2929 else if (op1
== TOK_GT
)
2931 else if (op1
== TOK_ULT
)
2933 else if (op1
== TOK_UGT
)
2938 if (op1
!= TOK_NE
) {
2942 /* generate non equal test */
2943 /* XXX: NOT PORTABLE yet */
2947 #ifdef TCC_TARGET_I386
2948 b
= psym(0x850f, 0);
2950 error("not implemented");
2958 vset(VT_INT
, VT_JMPI
, a
);
2963 /* handle constant optimizations and various machine independant opt */
2964 void gen_opc(int op
)
2971 /* currently, we cannot do computations with forward symbols */
2972 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
2973 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
2977 case '+': v1
->c
.i
+= fc
; break;
2978 case '-': v1
->c
.i
-= fc
; break;
2979 case '&': v1
->c
.i
&= fc
; break;
2980 case '^': v1
->c
.i
^= fc
; break;
2981 case '|': v1
->c
.i
|= fc
; break;
2982 case '*': v1
->c
.i
*= fc
; break;
2989 /* if division by zero, generate explicit division */
2992 error("division by zero in constant");
2996 default: v1
->c
.i
/= fc
; break;
2997 case '%': v1
->c
.i
%= fc
; break;
2998 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
2999 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3002 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3003 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3004 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3006 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3007 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3008 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3009 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3010 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3011 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3012 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3013 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3014 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3015 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3017 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3018 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3024 /* if commutative ops, put c2 as constant */
3025 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3026 op
== '|' || op
== '*')) {
3031 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3034 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3035 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3041 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3042 /* try to use shifts instead of muls or divs */
3043 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3052 else if (op
== TOK_PDIV
)
3060 /* call low level op generator */
3066 int pointed_size(int t
)
3068 return type_size(pointed_type(t
), &t
);
3072 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3074 char buf1
[256], buf2
[256];
3078 if (!is_compatible_types(t1
, t2
)) {
3079 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3080 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3081 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3086 /* generic gen_op: handles types problems */
3089 int u
, t1
, t2
, bt1
, bt2
, t
;
3093 bt1
= t1
& VT_BTYPE
;
3094 bt2
= t2
& VT_BTYPE
;
3096 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3097 /* at least one operand is a pointer */
3098 /* relationnal op: must be both pointers */
3099 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3100 // check_pointer_types(vtop, vtop - 1);
3101 /* pointers are handled are unsigned */
3102 t
= VT_INT
| VT_UNSIGNED
;
3105 /* if both pointers, then it must be the '-' op */
3106 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3107 (t2
& VT_BTYPE
) == VT_PTR
) {
3109 error("cannot use pointers here");
3110 // check_pointer_types(vtop - 1, vtop);
3111 /* XXX: check that types are compatible */
3112 u
= pointed_size(t1
);
3114 /* set to integer type */
3119 /* exactly one pointer : must be '+' or '-'. */
3120 if (op
!= '-' && op
!= '+')
3121 error("cannot use pointers here");
3122 /* Put pointer as first operand */
3123 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3127 /* XXX: cast to int ? (long long case) */
3128 vpushi(pointed_size(vtop
[-1].t
));
3130 /* if evaluating constant expression, no code should be
3131 generated, so no bound check */
3132 if (do_bounds_check
&& !const_wanted
) {
3133 /* if bounded pointers, we generate a special code to
3140 gen_bounded_ptr_add1();
3141 gen_bounded_ptr_add2(0);
3145 /* put again type if gen_opc() swaped operands */
3148 } else if (is_float(bt1
) || is_float(bt2
)) {
3149 /* compute bigger type and do implicit casts */
3150 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3152 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3157 /* floats can only be used for a few operations */
3158 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3159 (op
< TOK_ULT
|| op
> TOK_GT
))
3160 error("invalid operands for binary operation");
3162 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3163 /* cast to biggest op */
3165 /* convert to unsigned if it does not fit in a long long */
3166 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3167 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
3171 /* integer operations */
3173 /* convert to unsigned if it does not fit in an integer */
3174 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
3175 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3178 /* XXX: currently, some unsigned operations are explicit, so
3179 we modify them here */
3180 if (t
& VT_UNSIGNED
) {
3187 else if (op
== TOK_LT
)
3189 else if (op
== TOK_GT
)
3191 else if (op
== TOK_LE
)
3193 else if (op
== TOK_GE
)
3199 /* special case for shifts and long long: we keep the shift as
3201 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3207 else if ((t
& VT_BTYPE
) == VT_LLONG
)
3211 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3212 /* relationnal op: the result is an int */
3220 /* generic itof for unsigned long long case */
3221 void gen_cvt_itof1(int t
)
3225 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3226 (VT_LLONG
| VT_UNSIGNED
)) {
3228 gfunc_start(&gf
, FUNC_CDECL
);
3231 vpushi((int)&__ulltof
);
3232 else if (t
== VT_DOUBLE
)
3233 vpushi((int)&__ulltod
);
3235 vpushi((int)&__ulltold
);
3244 /* generic ftoi for unsigned long long case */
3245 void gen_cvt_ftoi1(int t
)
3250 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3251 /* not handled natively */
3252 gfunc_start(&gf
, FUNC_CDECL
);
3253 st
= vtop
->t
& VT_BTYPE
;
3256 vpushi((int)&__ftoull
);
3257 else if (st
== VT_DOUBLE
)
3258 vpushi((int)&__dtoull
);
3260 vpushi((int)&__ldtoull
);
3264 vtop
->r2
= REG_LRET
;
3270 /* force char or short cast */
3271 void force_charshort_cast(int t
)
3275 /* XXX: add optimization if lvalue : just change type and offset */
3280 if (t
& VT_UNSIGNED
) {
3281 vpushi((1 << bits
) - 1);
3292 /* cast 'vtop' to 't' type */
3293 void gen_cast(int t
)
3295 int sbt
, dbt
, sf
, df
, c
, st1
, dt1
;
3297 /* special delayed cast for char/short */
3298 /* XXX: in some cases (multiple cascaded casts), it may still
3300 if (vtop
->r
& VT_MUSTCAST
) {
3301 vtop
->r
&= ~VT_MUSTCAST
;
3302 force_charshort_cast(vtop
->t
);
3306 sbt
= vtop
->t
& VT_BTYPE
;
3311 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
3313 /* convert from fp to fp */
3315 /* constant case: we can do it now */
3316 /* XXX: in ISOC, cannot do it if error in convert */
3317 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3318 vtop
->c
.f
= (float)vtop
->c
.d
;
3319 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3320 vtop
->c
.f
= (float)vtop
->c
.ld
;
3321 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3322 vtop
->c
.d
= (double)vtop
->c
.f
;
3323 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3324 vtop
->c
.d
= (double)vtop
->c
.ld
;
3325 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3326 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3327 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3328 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3330 /* non constant case: generate code */
3334 /* convert int to fp */
3335 st1
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3338 case VT_LLONG
| VT_UNSIGNED
:
3340 /* XXX: add const cases for long long */
3342 case VT_INT
| VT_UNSIGNED
:
3344 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3345 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
3346 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
3351 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
3352 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
3353 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
3362 /* convert fp to int */
3363 dt1
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3364 /* we handle char/short/etc... with generic code */
3365 if (dt1
!= (VT_INT
| VT_UNSIGNED
) &&
3366 dt1
!= (VT_LLONG
| VT_UNSIGNED
) &&
3371 case VT_LLONG
| VT_UNSIGNED
:
3373 /* XXX: add const cases for long long */
3375 case VT_INT
| VT_UNSIGNED
:
3377 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3378 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3379 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3385 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3386 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3387 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3395 if (dt1
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dt1
) {
3396 /* additionnal cast for char/short/bool... */
3400 } else if (dbt
== VT_LLONG
) {
3401 /* scalar to long long */
3403 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3404 vtop
->c
.ll
= vtop
->c
.ui
;
3406 vtop
->c
.ll
= vtop
->c
.i
;
3408 /* machine independant conversion */
3410 /* generate high word */
3411 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
)) {
3419 /* patch second register */
3420 vtop
[-1].r2
= vtop
->r
;
3423 } else if (dbt
== VT_BOOL
) {
3424 /* scalar to bool */
3427 } else if (dbt
== VT_BYTE
|| dbt
== VT_SHORT
) {
3428 force_charshort_cast(t
);
3429 } else if (dbt
== VT_INT
) {
3431 if (sbt
== VT_LLONG
) {
3432 /* from long long: just take low order word */
3435 } else if (sbt
== VT_PTR
) {
3437 } else if (vtop
->r
& VT_LVAL
) {
3438 /* if lvalue and single word type, nothing to do (XXX:
3439 maybe incorrect for sizeof op) */
3448 /* return type size. Put alignment at 'a' */
3449 int type_size(int t
, int *a
)
3455 if (bt
== VT_STRUCT
) {
3457 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3458 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
3460 } else if (bt
== VT_PTR
) {
3462 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3463 return type_size(s
->t
, a
) * s
->c
;
3468 } else if (bt
== VT_LDOUBLE
) {
3470 return LDOUBLE_SIZE
;
3471 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3474 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
3477 } else if (bt
== VT_SHORT
) {
3481 /* char, void, function, _Bool */
3487 /* return the pointed type of t */
3488 int pointed_type(int t
)
3491 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3492 return s
->t
| (t
& ~VT_TYPE
);
3495 int mk_pointer(int t
)
3499 sym_push(p
, t
, 0, -1);
3500 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
3503 int is_compatible_types(int t1
, int t2
)
3510 bt1
= t1
& VT_BTYPE
;
3511 bt2
= t2
& VT_BTYPE
;
3512 if (bt1
== VT_PTR
) {
3513 t1
= pointed_type(t1
);
3514 /* if function, then convert implicitely to function pointer */
3515 if (bt2
!= VT_FUNC
) {
3518 t2
= pointed_type(t2
);
3520 /* void matches everything */
3523 if (t1
== VT_VOID
|| t2
== VT_VOID
)
3525 return is_compatible_types(t1
, t2
);
3526 } else if (bt1
== VT_STRUCT
) {
3528 } else if (bt1
== VT_FUNC
) {
3531 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
3532 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
3533 if (!is_compatible_types(s1
->t
, s2
->t
))
3535 /* XXX: not complete */
3536 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
3540 while (s1
!= NULL
) {
3543 if (!is_compatible_types(s1
->t
, s2
->t
))
3552 /* XXX: not complete */
3557 /* print a type. If 'varstr' is not NULL, then the variable is also
3558 printed in the type */
3560 /* XXX: add array and function pointers */
3561 void type_to_str(char *buf
, int buf_size
,
3562 int t
, const char *varstr
)
3572 if (t
& VT_UNSIGNED
)
3573 pstrcat(buf
, buf_size
, "unsigned ");
3603 tstr
= "long double";
3605 pstrcat(buf
, buf_size
, tstr
);
3609 if (bt
== VT_STRUCT
)
3613 pstrcat(buf
, buf_size
, tstr
);
3614 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
3615 if (v
>= SYM_FIRST_ANOM
)
3616 pstrcat(buf
, buf_size
, "<anonymous>");
3618 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
3621 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3622 type_to_str(buf
, buf_size
, s
->t
, varstr
);
3623 pstrcat(buf
, buf_size
, "(");
3625 while (sa
!= NULL
) {
3626 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
3627 pstrcat(buf
, buf_size
, buf1
);
3630 pstrcat(buf
, buf_size
, ", ");
3632 pstrcat(buf
, buf_size
, ")");
3635 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3636 pstrcpy(buf1
, sizeof(buf1
), "*");
3638 pstrcat(buf1
, sizeof(buf1
), varstr
);
3639 type_to_str(buf
, buf_size
, s
->t
, buf1
);
3643 pstrcat(buf
, buf_size
, " ");
3644 pstrcat(buf
, buf_size
, varstr
);
3649 /* verify type compatibility to store vtop in 'dt' type, and generate
3651 void gen_assign_cast(int dt
)
3654 char buf1
[256], buf2
[256];
3656 st
= vtop
->t
; /* source type */
3657 if ((dt
& VT_BTYPE
) == VT_PTR
) {
3658 /* special cases for pointers */
3659 /* a function is implicitely a function pointer */
3660 if ((st
& VT_BTYPE
) == VT_FUNC
) {
3661 if (!is_compatible_types(pointed_type(dt
), st
))
3666 /* '0' can also be a pointer */
3667 if ((st
& VT_BTYPE
) == VT_INT
&&
3668 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
) &&
3672 if (!is_compatible_types(dt
, st
)) {
3674 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3675 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3676 error("cannot cast '%s' to '%s'", buf1
, buf2
);
3682 /* store vtop in lvalue pushed on stack */
3685 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
3689 sbt
= vtop
->t
& VT_BTYPE
;
3690 dbt
= ft
& VT_BTYPE
;
3691 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
3692 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
3693 /* optimize char/short casts */
3694 delayed_cast
= VT_MUSTCAST
;
3695 vtop
->t
= ft
& VT_TYPE
;
3698 gen_assign_cast(ft
& VT_TYPE
);
3701 if (sbt
== VT_STRUCT
) {
3702 /* if structure, only generate pointer */
3703 /* structure assignment : generate memcpy */
3704 /* XXX: optimize if small size */
3707 gfunc_start(&gf
, FUNC_CDECL
);
3709 size
= type_size(vtop
->t
, &align
);
3723 vpushi((int)&memcpy
);
3725 /* leave source on stack */
3726 } else if (ft
& VT_BITFIELD
) {
3727 /* bitfield store handling */
3728 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
3729 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3730 /* remove bit field info to avoid loops */
3731 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3733 /* duplicate destination */
3735 vtop
[-1] = vtop
[-2];
3737 /* mask and shift source */
3738 vpushi((1 << bit_size
) - 1);
3742 /* load destination, mask and or with source */
3744 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
3750 /* bound check case */
3751 if (vtop
[-1].r
& VT_MUSTBOUND
) {
3759 r
= gv(rc
); /* generate value */
3760 /* if lvalue was saved on stack, must read it */
3761 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
3763 t
= get_reg(RC_INT
);
3765 sv
.r
= VT_LOCAL
| VT_LVAL
;
3766 sv
.c
.ul
= vtop
[-1].c
.ul
;
3768 vtop
[-1].r
= t
| VT_LVAL
;
3771 /* two word case handling : store second register at word + 4 */
3772 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
3774 /* convert to int to increment easily */
3781 /* XXX: it works because r2 is spilled last ! */
3782 store(vtop
->r2
, vtop
- 1);
3785 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
3786 vtop
->r
|= delayed_cast
;
3790 /* post defines POST/PRE add. c is the token ++ or -- */
3791 void inc(int post
, int c
)
3794 vdup(); /* save lvalue */
3796 gv_dup(); /* duplicate value */
3801 vpushi(c
- TOK_MID
);
3803 vstore(); /* store value */
3805 vpop(); /* if post op, return saved value */
3808 /* Parse GNUC __attribute__ extension. Currently, the following
3809 extensions are recognized:
3810 - aligned(n) : set data/function alignment.
3811 - section(x) : generate data/code in this section.
3812 - unused : currently ignored, but may be used someday.
3814 void parse_attribute(AttributeDef
*ad
)
3821 while (tok
!= ')') {
3822 if (tok
< TOK_IDENT
)
3823 expect("attribute name");
3828 case TOK___SECTION__
:
3831 expect("section name");
3832 ad
->section
= find_section(tokc
.ts
->str
);
3837 case TOK___ALIGNED__
:
3840 if (n
<= 0 || (n
& (n
- 1)) != 0)
3841 error("alignment must be a positive power of two");
3846 case TOK___UNUSED__
:
3847 /* currently, no need to handle it because tcc does not
3848 track unused objects */
3851 case TOK___NORETURN__
:
3852 /* currently, no need to handle it because tcc does not
3853 track unused objects */
3858 ad
->func_call
= FUNC_CDECL
;
3862 case TOK___STDCALL__
:
3863 ad
->func_call
= FUNC_STDCALL
;
3866 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
3867 /* skip parameters */
3868 /* XXX: skip parenthesis too */
3871 while (tok
!= ')' && tok
!= -1)
3885 /* enum/struct/union declaration */
3886 int struct_decl(int u
)
3888 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
3889 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
3893 a
= tok
; /* save decl type */
3898 /* struct already defined ? return it */
3899 /* XXX: check consistency */
3900 s
= sym_find(v
| SYM_STRUCT
);
3903 error("invalid type");
3909 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
3910 /* put struct/union/enum name in type */
3912 u
= u
| (v
<< VT_STRUCT_SHIFT
);
3917 error("struct/union/enum already defined");
3918 /* cannot be empty */
3925 if (a
== TOK_ENUM
) {
3932 /* enum symbols have static storage */
3933 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
3938 parse_btype(&b
, &ad
);
3943 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
3944 if ((t
& VT_BTYPE
) == VT_FUNC
||
3945 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
3946 error("invalid type for '%s'",
3947 get_tok_str(v
, NULL
));
3953 bit_size
= expr_const();
3954 /* XXX: handle v = 0 case for messages */
3956 error("negative width in bit-field '%s'",
3957 get_tok_str(v
, NULL
));
3958 if (v
&& bit_size
== 0)
3959 error("zero width for bit-field '%s'",
3960 get_tok_str(v
, NULL
));
3962 size
= type_size(t
, &align
);
3964 if (bit_size
>= 0) {
3969 error("bitfields must have scalar type");
3971 if (bit_size
> bsize
) {
3972 error("width of '%s' exceeds its type",
3973 get_tok_str(v
, NULL
));
3974 } else if (bit_size
== bsize
) {
3975 /* no need for bit fields */
3977 } else if (bit_size
== 0) {
3978 /* XXX: what to do if only padding in a
3980 /* zero size: means to pad */
3984 /* we do not have enough room ? */
3985 if ((bit_pos
+ bit_size
) > bsize
)
3988 /* XXX: handle LSB first */
3990 (bit_pos
<< VT_STRUCT_SHIFT
) |
3991 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
3992 bit_pos
+= bit_size
;
3998 /* add new memory data only if starting
4000 if (lbit_pos
== 0) {
4001 if (a
== TOK_STRUCT
) {
4002 c
= (c
+ align
- 1) & -align
;
4010 if (align
> maxalign
)
4014 printf("add field %s offset=%d",
4015 get_tok_str(v
, NULL
), offset
);
4016 if (t
& VT_BITFIELD
) {
4017 printf(" pos=%d size=%d",
4018 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4019 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4023 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
4027 if (tok
== ';' || tok
== -1)
4037 /* size for struct/union, dummy for enum */
4038 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4043 /* return 0 if no type declaration. otherwise, return the basic type
4046 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4048 int t
, u
, type_found
;
4051 memset(ad
, 0, sizeof(AttributeDef
));
4062 if ((t
& VT_BTYPE
) != 0)
4063 error("too many basic types");
4077 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4078 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4079 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4080 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4094 if ((t
& VT_BTYPE
) == VT_LONG
) {
4095 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4102 u
= struct_decl(VT_ENUM
);
4106 u
= struct_decl(VT_STRUCT
);
4109 /* type modifiers */
4114 case TOK___SIGNED__
:
4117 case TOK___INLINE__
:
4139 /* GNUC attribute */
4140 case TOK___ATTRIBUTE__
:
4141 parse_attribute(ad
);
4145 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4147 t
|= (s
->t
& ~VT_TYPEDEF
);
4154 /* long is never used as type */
4155 if ((t
& VT_BTYPE
) == VT_LONG
)
4156 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4161 int post_type(int t
, AttributeDef
*ad
)
4163 int p
, n
, pt
, l
, t1
;
4164 Sym
**plast
, *s
, *first
;
4168 /* function declaration */
4173 while (tok
!= ')') {
4174 /* read param name and compute offset */
4175 if (l
!= FUNC_OLD
) {
4176 if (!parse_btype(&pt
, &ad1
)) {
4178 error("invalid type");
4185 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4187 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
4188 if ((pt
& VT_BTYPE
) == VT_VOID
)
4189 error("parameter declared as void");
4196 /* array must be transformed to pointer according to ANSI C */
4198 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
4203 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4210 /* if no parameters, then old type prototype */
4214 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4215 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4216 /* we push a anonymous symbol which will contain the function prototype */
4218 s
= sym_push(p
, t
, ad
->func_call
, l
);
4220 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
4221 } else if (tok
== '[') {
4222 /* array definition */
4228 error("invalid array size");
4231 /* parse next post type */
4232 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4233 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4235 /* we push a anonymous symbol which will contain the array
4238 sym_push(p
, t
, 0, n
);
4239 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
4244 /* Read a type declaration (except basic type), and return the
4245 type. 'td' is a bitmask indicating which kind of type decl is
4246 expected. 't' should contain the basic type. 'ad' is the attribute
4247 definition of the basic type. It can be modified by type_decl(). */
4248 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
4253 while (tok
== '*') {
4255 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
4260 /* recursive type */
4261 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4264 /* XXX: this is not correct to modify 'ad' at this point, but
4265 the syntax is not clear */
4266 if (tok
== TOK___ATTRIBUTE__
)
4267 parse_attribute(ad
);
4268 u
= type_decl(ad
, v
, 0, td
);
4272 /* type identifier */
4273 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
4277 if (!(td
& TYPE_ABSTRACT
))
4278 expect("identifier");
4282 /* append t at the end of u */
4283 t
= post_type(t
, ad
);
4284 if (tok
== TOK___ATTRIBUTE__
)
4285 parse_attribute(ad
);
4290 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
4300 /* define a new external reference to a function 'v' of type 'u' */
4301 Sym
*external_sym(int v
, int u
, int r
)
4306 /* push forward reference */
4307 s
= sym_push1(&global_stack
,
4309 s
->r
= r
| VT_CONST
| VT_FORWARD
;
4316 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
4318 if (vtop
->r
& VT_LVAL
)
4320 vtop
->t
= pointed_type(vtop
->t
);
4321 /* an array is never an lvalue */
4322 if (!(vtop
->t
& VT_ARRAY
)) {
4324 /* if bound checking, the referenced pointer must be checked */
4325 if (do_bounds_check
)
4326 vtop
->r
|= VT_MUSTBOUND
;
4330 /* pass a parameter to a function and do type checking and casting */
4331 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
4334 func_type
= func
->c
;
4335 if (func_type
== FUNC_OLD
||
4336 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
4337 /* default casting : only need to convert float to double */
4338 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
4339 gen_cast(VT_DOUBLE
);
4340 } else if (arg
== NULL
) {
4341 error("too many arguments to function");
4343 gen_assign_cast(arg
->t
);
4350 int n
, t
, ft
, fc
, p
, align
, size
, r
, data_offset
;
4355 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
4358 } else if (tok
== TOK_CUINT
) {
4359 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4361 } else if (tok
== TOK_CLLONG
) {
4362 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
4364 } else if (tok
== TOK_CULLONG
) {
4365 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4367 } else if (tok
== TOK_CFLOAT
) {
4368 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
4370 } else if (tok
== TOK_CDOUBLE
) {
4371 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
4373 } else if (tok
== TOK_CLDOUBLE
) {
4374 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
4376 } else if (tok
== TOK___FUNC__
) {
4377 /* special function name identifier */
4378 /* generate (char *) type */
4379 data_offset
= (int)data_section
->data_ptr
;
4380 vset(mk_pointer(VT_BYTE
), VT_CONST
, data_offset
);
4381 strcpy((void *)data_offset
, funcname
);
4382 data_offset
+= strlen(funcname
) + 1;
4383 data_section
->data_ptr
= (unsigned char *)data_offset
;
4385 } else if (tok
== TOK_LSTR
) {
4388 } else if (tok
== TOK_STR
) {
4389 /* string parsing */
4392 type_size(t
, &align
);
4393 data_offset
= (int)data_section
->data_ptr
;
4394 data_offset
= (data_offset
+ align
- 1) & -align
;
4396 /* we must declare it as an array first to use initializer parser */
4397 t
= VT_ARRAY
| mk_pointer(t
);
4398 decl_initializer(t
, VT_CONST
, data_offset
, 1, 0);
4399 data_offset
+= type_size(t
, &align
);
4400 /* put it as pointer */
4401 vset(t
& ~VT_ARRAY
, VT_CONST
, fc
);
4402 data_section
->data_ptr
= (unsigned char *)data_offset
;
4408 if (parse_btype(&t
, &ad
)) {
4409 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4411 /* check ISOC99 compound literal */
4413 /* data is allocated locally by default */
4418 /* all except arrays are lvalues */
4419 if (!(ft
& VT_ARRAY
))
4421 memset(&ad
, 0, sizeof(AttributeDef
));
4422 fc
= decl_initializer_alloc(ft
, &ad
, r
, 1);
4432 } else if (t
== '*') {
4435 } else if (t
== '&') {
4437 /* functions names must be treated as function pointers,
4438 except for unary '&' and sizeof. Since we consider that
4439 functions are not lvalues, we only have to handle it
4440 there and in function calls. */
4441 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4443 vtop
->t
= mk_pointer(vtop
->t
);
4448 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
4449 vtop
->c
.i
= !vtop
->c
.i
;
4450 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
4451 vtop
->c
.i
= vtop
->c
.i
^ 1;
4453 vset(VT_INT
, VT_JMP
, gtst(1, 0));
4463 if (t
== TOK_SIZEOF
) {
4466 if (parse_btype(&t
, &ad
)) {
4467 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4469 /* XXX: some code could be generated: add eval
4481 vpushi(type_size(t
, &t
));
4483 if (t
== TOK_INC
|| t
== TOK_DEC
) {
4486 } else if (t
== '-') {
4495 error("'%s' undeclared", get_tok_str(t
, NULL
));
4496 /* for simple function calls, we tolerate undeclared
4497 external reference */
4499 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
4500 /* int() function */
4501 s
= external_sym(t
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), 0);
4503 vset(s
->t
, s
->r
, s
->c
);
4504 /* if forward reference, we must point to s */
4505 if (vtop
->r
& VT_FORWARD
)
4510 /* post operations */
4512 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4515 } else if (tok
== '.' || tok
== TOK_ARROW
) {
4517 if (tok
== TOK_ARROW
)
4522 /* expect pointer on structure */
4523 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
4524 expect("struct or union");
4525 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4528 while ((s
= s
->next
) != NULL
) {
4533 error("field not found");
4534 /* add field offset to pointer */
4535 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
4538 /* change type to field type, and set to lvalue */
4540 /* an array is never an lvalue */
4541 if (!(vtop
->t
& VT_ARRAY
))
4544 } else if (tok
== '[') {
4550 } else if (tok
== '(') {
4555 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
4556 /* pointer test (no array accepted) */
4557 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4558 vtop
->t
= pointed_type(vtop
->t
);
4559 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4563 expect("function pointer");
4566 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4568 /* get return type */
4569 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
4570 save_regs(); /* save used temporary registers */
4571 gfunc_start(&gf
, s
->r
);
4573 sa
= s
->next
; /* first parameter */
4574 #ifdef INVERT_FUNC_PARAMS
4576 int *str
, len
, parlevel
, *saved_macro_ptr
;
4579 /* read each argument and store it on a stack */
4580 /* XXX: merge it with macro args ? */
4582 while (tok
!= ')') {
4586 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
4590 else if (tok
== ')')
4592 tok_add2(&str
, &len
, tok
, &tokc
);
4595 tok_add(&str
, &len
, -1); /* end of file added */
4596 tok_add(&str
, &len
, 0);
4597 s1
= sym_push2(&args
, 0, 0, (int)str
);
4598 s1
->next
= sa
; /* add reference to argument */
4608 /* now generate code in reverse order by reading the stack */
4609 saved_macro_ptr
= macro_ptr
;
4611 macro_ptr
= (int *)args
->c
;
4615 expect("',' or ')'");
4616 gfunc_param_typed(&gf
, s
, args
->next
);
4618 free((int *)args
->c
);
4622 macro_ptr
= saved_macro_ptr
;
4627 /* compute first implicit argument if a structure is returned */
4628 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
4629 /* get some space for the returned structure */
4630 size
= type_size(s
->t
, &align
);
4631 loc
= (loc
- size
) & -align
;
4633 ret
.r
= VT_LOCAL
| VT_LVAL
;
4634 /* pass it as 'int' to avoid structure arg passing
4636 vset(VT_INT
, VT_LOCAL
, loc
);
4642 /* return in register */
4643 if (is_float(ret
.t
)) {
4646 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
4652 #ifndef INVERT_FUNC_PARAMS
4653 while (tok
!= ')') {
4655 gfunc_param_typed(&gf
, s
, sa
);
4663 error("too few arguments to function");
4667 vsetc(ret
.t
, ret
.r
, &ret
.c
);
4681 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
4682 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
4683 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
4706 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
4707 (l
== 1 && (tok
== '+' || tok
== '-')) ||
4708 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
4709 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
4710 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
4711 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
4712 (l
== 5 && tok
== '&') ||
4713 (l
== 6 && tok
== '^') ||
4714 (l
== 7 && tok
== '|') ||
4715 (l
== 8 && tok
== TOK_LAND
) ||
4716 (l
== 9 && tok
== TOK_LOR
)) {
4725 /* only used if non constant */
4733 if (tok
!= TOK_LAND
) {
4736 vset(VT_INT
, VT_JMPI
, t
);
4753 if (tok
!= TOK_LOR
) {
4756 vset(VT_INT
, VT_JMP
, t
);
4766 /* XXX: better constant handling */
4769 int t
, u
, c
, r1
, r2
, rc
;
4791 /* XXX: long long handling ? */
4793 if (is_float(vtop
->t
))
4796 vtop
--; /* no vpop so that FP stack is not flushed */
4821 /* parse a constant expression and return value in vtop */
4822 void expr_const1(void)
4828 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
4833 /* parse an integer constant and return its value */
4834 int expr_const(void)
4843 /* return the label token if current token is a label, otherwise
4850 /* fast test first */
4851 if (tok
< TOK_UIDENT
)
4853 /* no need to save tokc since we expect an identifier */
4861 /* XXX: may not work in all cases (macros ?) */
4870 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
4875 /* generate line number info */
4877 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
4878 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
4880 last_line_num
= file
->line_num
;
4883 if (tok
== TOK_IF
) {
4890 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4892 if (c
== TOK_ELSE
) {
4896 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4897 gsym(d
); /* patch else jmp */
4900 } else if (tok
== TOK_WHILE
) {
4908 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
4912 } else if (tok
== '{') {
4915 s
= local_stack
.top
;
4916 while (tok
!= '}') {
4919 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4921 /* pop locally defined symbols */
4922 sym_pop(&local_stack
, s
);
4924 } else if (tok
== TOK_RETURN
) {
4928 gen_assign_cast(func_vt
);
4929 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
4930 /* if returning structure, must copy it to implicit
4931 first pointer arg location */
4932 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
4935 /* copy structure value to pointer */
4937 } else if (is_float(func_vt
)) {
4942 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4945 rsym
= gjmp(rsym
); /* jmp */
4946 } else if (tok
== TOK_BREAK
) {
4949 error("cannot break");
4950 *bsym
= gjmp(*bsym
);
4953 } else if (tok
== TOK_CONTINUE
) {
4956 error("cannot continue");
4957 *csym
= gjmp(*csym
);
4960 } else if (tok
== TOK_FOR
) {
4987 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
4992 if (tok
== TOK_DO
) {
4997 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5008 if (tok
== TOK_SWITCH
) {
5012 /* XXX: other types than integer */
5013 case_reg
= gv(RC_INT
);
5017 b
= gjmp(0); /* jump to first case */
5019 block(&a
, csym
, &b
, &c
, case_reg
);
5020 /* if no default, jmp after switch */
5028 if (tok
== TOK_CASE
) {
5035 if (gnu_ext
&& tok
== TOK_DOTS
) {
5039 warning("empty case range");
5041 /* since a case is like a label, we must skip it with a jmp */
5044 vset(VT_INT
, case_reg
, 0);
5048 *case_sym
= gtst(1, 0);
5051 *case_sym
= gtst(1, 0);
5052 vset(VT_INT
, case_reg
, 0);
5055 *case_sym
= gtst(1, *case_sym
);
5059 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5061 if (tok
== TOK_DEFAULT
) {
5067 error("too many 'default'");
5069 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5071 if (tok
== TOK_GOTO
) {
5073 s
= sym_find1(&label_stack
, tok
);
5074 /* put forward definition if needed */
5076 s
= sym_push1(&label_stack
, tok
, VT_FORWARD
, 0);
5077 /* label already defined */
5078 if (s
->t
& VT_FORWARD
)
5088 s
= sym_find1(&label_stack
, b
);
5090 if (!(s
->t
& VT_FORWARD
))
5091 error("multiple defined label");
5096 sym_push1(&label_stack
, b
, 0, ind
);
5098 /* we accept this, but it is a mistake */
5100 warning("deprecated use of label at end of compound statement");
5102 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5104 /* expression case */
5114 /* t is the array or struct type. c is the array or struct
5115 address. cur_index/cur_field is the pointer to the current
5116 value. 'size_only' is true if only size info is needed (only used
5118 void decl_designator(int t
, int r
, int c
,
5119 int *cur_index
, Sym
**cur_field
,
5123 int notfirst
, index
, align
, l
;
5126 if (gnu_ext
&& (l
= is_label()) != 0)
5129 while (tok
== '[' || tok
== '.') {
5131 if (!(t
& VT_ARRAY
))
5132 expect("array type");
5133 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5135 index
= expr_const();
5136 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5137 expect("invalid index");
5141 t
= pointed_type(t
);
5142 c
+= index
* type_size(t
, &align
);
5148 if ((t
& VT_BTYPE
) != VT_STRUCT
)
5149 expect("struct/union type");
5150 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5162 t
= f
->t
| (t
& ~VT_TYPE
);
5177 t
= pointed_type(t
);
5178 c
+= index
* type_size(t
, &align
);
5182 error("too many field init");
5183 t
= f
->t
| (t
& ~VT_TYPE
);
5187 decl_initializer(t
, r
, c
, 0, size_only
);
5191 #define EXPR_CONST 1
5194 /* store a value or an expression directly in global data or in local array */
5195 void init_putv(int t
, int r
, int c
,
5196 int v
, int expr_type
)
5198 int saved_global_expr
, bt
;
5205 /* compound literals must be allocated globally in this case */
5206 saved_global_expr
= global_expr
;
5209 global_expr
= saved_global_expr
;
5216 if ((r
& VT_VALMASK
) == VT_CONST
) {
5217 /* XXX: not portable */
5222 *(char *)c
= vtop
->c
.i
;
5225 *(short *)c
= vtop
->c
.i
;
5228 *(double *)c
= vtop
->c
.d
;
5231 *(long double *)c
= vtop
->c
.ld
;
5234 *(long long *)c
= vtop
->c
.ll
;
5237 *(int *)c
= vtop
->c
.i
;
5249 /* put zeros for variable based init */
5250 void init_putz(int t
, int r
, int c
, int size
)
5254 if ((r
& VT_VALMASK
) == VT_CONST
) {
5255 /* nothing to do because globals are already set to zero */
5257 gfunc_start(&gf
, FUNC_CDECL
);
5262 vset(VT_INT
, VT_LOCAL
, c
);
5264 vpushi((int)&memset
);
5269 /* 't' contains the type and storage info. c is the address of the
5270 object. 'first' is true if array '{' must be read (multi dimension
5271 implicit array init handling). 'size_only' is true if size only
5272 evaluation is wanted (only for arrays). */
5273 void decl_initializer(int t
, int r
, int c
, int first
, int size_only
)
5275 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
5276 int t1
, size1
, align1
, expr_type
;
5281 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5284 t1
= pointed_type(t
);
5285 size1
= type_size(t1
, &align1
);
5288 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5294 /* only parse strings here if correct type (otherwise: handle
5295 them as ((w)char *) expressions */
5296 if ((tok
== TOK_LSTR
&&
5297 (t1
& VT_BTYPE
) == VT_INT
) ||
5299 (t1
& VT_BTYPE
) == VT_BYTE
)) {
5300 /* XXX: move multiple string parsing in parser ? */
5301 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5303 /* compute maximum number of chars wanted */
5305 if (n
>= 0 && nb
> (n
- array_length
))
5306 nb
= n
- array_length
;
5309 warning("initializer-string for array is too long");
5311 init_putv(t1
, r
, c
+ (array_length
+ i
) * size1
,
5312 ts
->str
[i
], EXPR_VAL
);
5318 /* only add trailing zero if enough storage (no
5319 warning in this case since it is standard) */
5320 if (n
< 0 || array_length
< n
) {
5322 init_putv(t1
, r
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5328 while (tok
!= '}') {
5329 decl_designator(t
, r
, c
, &index
, NULL
, size_only
);
5330 if (n
>= 0 && index
>= n
)
5331 error("index too large");
5332 /* must put zero in holes (note that doing it that way
5333 ensures that it even works with designators) */
5334 if (!size_only
&& array_length
< index
) {
5335 init_putz(t1
, r
, c
+ array_length
* size1
,
5336 (index
- array_length
) * size1
);
5339 if (index
> array_length
)
5340 array_length
= index
;
5341 /* special test for multi dimensional arrays (may not
5342 be strictly correct if designators are used at the
5344 if (index
>= n
&& no_oblock
)
5353 /* put zeros at the end */
5354 if (!size_only
&& n
>= 0 && array_length
< n
) {
5355 init_putz(t1
, r
, c
+ array_length
* size1
,
5356 (n
- array_length
) * size1
);
5358 /* patch type size if needed */
5360 s
->c
= array_length
;
5361 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
5362 /* XXX: union needs only one init */
5364 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5369 while (tok
!= '}') {
5370 decl_designator(t
, r
, c
, NULL
, &f
, size_only
);
5371 /* fill with zero between fields */
5373 if (!size_only
&& array_length
< index
) {
5374 init_putz(t
, r
, c
+ array_length
,
5375 index
- array_length
);
5377 index
= index
+ type_size(f
->t
, &align1
);
5378 if (index
> array_length
)
5379 array_length
= index
;
5385 /* put zeros at the end */
5386 if (!size_only
&& array_length
< n
) {
5387 init_putz(t
, r
, c
+ array_length
,
5391 } else if (tok
== '{') {
5393 decl_initializer(t
, r
, c
, first
, size_only
);
5395 } else if (size_only
) {
5396 /* just skip expression */
5398 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
5402 else if (tok
== ')')
5407 /* currently, we always use constant expression for globals
5408 (may change for scripting case) */
5409 expr_type
= EXPR_CONST
;
5410 if ((r
& VT_VALMASK
) == VT_LOCAL
)
5411 expr_type
= EXPR_ANY
;
5412 init_putv(t
, r
, c
, 0, expr_type
);
5416 /* parse an initializer for type 't' if 'has_init' is true, and
5417 allocate space in local or global data space ('r' is either
5418 VT_LOCAL or VT_CONST). The allocated address in returned */
5419 int decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
)
5421 int size
, align
, addr
, tok1
, data_offset
;
5422 int *init_str
, init_len
, level
, *saved_macro_ptr
;
5425 size
= type_size(t
, &align
);
5426 /* If unknown size, we must evaluate it before
5427 evaluating initializers because
5428 initializers can generate global data too
5429 (e.g. string pointers or ISOC99 compound
5430 literals). It also simplifies local
5431 initializers handling */
5434 saved_macro_ptr
= NULL
; /* avoid warning */
5438 error("unknown type size");
5439 /* get all init string */
5441 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5443 error("unexpected end of file in initializer");
5444 tok_add2(&init_str
, &init_len
, tok
, &tokc
);
5447 else if (tok
== '}') {
5455 tok_add(&init_str
, &init_len
, -1);
5456 tok_add(&init_str
, &init_len
, 0);
5459 saved_macro_ptr
= macro_ptr
;
5460 macro_ptr
= init_str
;
5462 decl_initializer(t
, r
, 0, 1, 1);
5463 /* prepare second initializer parsing */
5464 macro_ptr
= init_str
;
5467 /* if still unknown size, error */
5468 size
= type_size(t
, &align
);
5470 error("unknown type size");
5472 /* take into account specified alignment if bigger */
5473 if (ad
->aligned
> align
)
5474 align
= ad
->aligned
;
5475 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5476 if (do_bounds_check
&& (t
& VT_ARRAY
))
5478 #ifdef TCC_TARGET_IL
5479 /* XXX: ugly patch to allocate local variables for IL, just
5484 loc
= (loc
- size
) & -align
;
5487 /* handles bounds */
5488 /* XXX: currently, since we do only one pass, we cannot track
5489 '&' operators, so we add only arrays */
5490 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
5492 /* add padding between regions */
5494 /* then add local bound info */
5495 bounds_ptr
= (int *)lbounds_section
->data_ptr
;
5496 *bounds_ptr
++ = addr
;
5497 *bounds_ptr
++ = size
;
5498 lbounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5501 /* compute section */
5509 data_offset
= (int)sec
->data_ptr
;
5510 data_offset
= (data_offset
+ align
- 1) & -align
;
5512 /* very important to increment global
5513 pointer at this time because
5514 initializers themselves can create new
5516 data_offset
+= size
;
5517 /* handles bounds */
5518 if (do_bounds_check
) {
5520 /* first, we need to add at least one byte between each region */
5522 /* then add global bound info */
5523 bounds_ptr
= (int *)bounds_section
->data_ptr
;
5524 *bounds_ptr
++ = addr
;
5525 *bounds_ptr
++ = size
;
5526 bounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5528 sec
->data_ptr
= (unsigned char *)data_offset
;
5531 decl_initializer(t
, r
, addr
, 1, 0);
5532 /* restore parse state if needed */
5535 macro_ptr
= saved_macro_ptr
;
5542 void put_func_debug(int t
)
5551 put_elf_sym(symtab_section
, ind
, 0,
5552 ELF32_ST_INFO(bind
, STT_FUNC
), 0,
5553 cur_text_section
->sh_num
, funcname
);
5555 /* XXX: we put here a dummy type */
5556 snprintf(buf
, sizeof(buf
), "%s:%c1",
5557 funcname
, t
& VT_STATIC
? 'f' : 'F');
5558 put_stabs(buf
, N_FUN
, 0, file
->line_num
, ind
);
5564 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5567 int t
, b
, v
, addr
, has_init
, r
;
5572 if (!parse_btype(&b
, &ad
)) {
5573 /* skip redundant ';' */
5574 /* XXX: find more elegant solution */
5579 /* special test for old K&R protos without explicit int
5580 type. Only accepted when defining global data */
5581 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
5585 if (((b
& VT_BTYPE
) == VT_ENUM
||
5586 (b
& VT_BTYPE
) == VT_STRUCT
) &&
5588 /* we accept no variable after */
5592 while (1) { /* iterate thru each declaration */
5593 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
5597 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
5598 printf("type = '%s'\n", buf
);
5603 error("cannot use local functions");
5605 expect("function definition");
5606 /* compute text section */
5607 cur_text_section
= ad
.section
;
5608 if (!cur_text_section
)
5609 cur_text_section
= text_section
;
5610 ind
= (int)cur_text_section
->data_ptr
;
5611 /* patch forward references */
5612 if ((sym
= sym_find(v
)) && (sym
->r
& VT_FORWARD
)) {
5613 greloc_patch(sym
, ind
);
5616 /* put function address */
5617 sym
= sym_push1(&global_stack
, v
, t
, ind
);
5620 funcname
= get_tok_str(v
, NULL
);
5621 /* put debug symbol */
5624 /* push a dummy symbol to enable local sym storage */
5625 sym_push1(&local_stack
, 0, 0, 0);
5629 block(NULL
, NULL
, NULL
, NULL
, 0);
5632 cur_text_section
->data_ptr
= (unsigned char *)ind
;
5633 sym_pop(&label_stack
, NULL
); /* reset label stack */
5634 sym_pop(&local_stack
, NULL
); /* reset local stack */
5635 /* end of function */
5637 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
5639 funcname
= ""; /* for safety */
5640 func_vt
= VT_VOID
; /* for safety */
5641 ind
= 0; /* for safety */
5644 if (b
& VT_TYPEDEF
) {
5645 /* save typedefed type */
5646 /* XXX: test storage specifiers ? */
5647 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
5648 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
5649 /* external function definition */
5650 external_sym(v
, t
, 0);
5652 /* not lvalue if array */
5654 if (!(t
& VT_ARRAY
))
5656 if (b
& VT_EXTERN
) {
5657 /* external variable */
5658 external_sym(v
, t
, r
);
5664 has_init
= (tok
== '=');
5667 addr
= decl_initializer_alloc(t
, &ad
, r
,
5669 if (l
== VT_CONST
) {
5670 /* global scope: see if already defined */
5674 if (!is_compatible_types(sym
->t
, t
))
5675 error("incompatible types for redefinition of '%s'",
5676 get_tok_str(v
, NULL
));
5677 if (!(sym
->r
& VT_FORWARD
))
5678 error("redefinition of '%s'", get_tok_str(v
, NULL
));
5679 greloc_patch(sym
, addr
);
5682 sym_push(v
, t
, r
, addr
);
5696 /* put all global symbols in the extern stack and do all the
5697 resolving which can be done without using external symbols from DLLs */
5698 /* XXX: could try to verify types, but would not to save them in
5700 void resolve_global_syms(void)
5702 Sym
*s
, *s1
, *ext_sym
;
5705 s
= global_stack
.top
;
5708 /* do not save static or typedefed symbols or types */
5709 if (!(s
->t
& (VT_STATIC
| VT_TYPEDEF
)) &&
5710 !(s
->v
& (SYM_FIELD
| SYM_STRUCT
)) &&
5711 (s
->v
< SYM_FIRST_ANOM
)) {
5712 ext_sym
= sym_find1(&extern_stack
, s
->v
);
5714 /* if the symbol do not exist, we simply save it */
5715 ext_sym
= sym_push1(&extern_stack
, s
->v
, s
->t
, s
->c
);
5717 } else if (ext_sym
->r
& VT_FORWARD
) {
5718 /* external symbol already exists, but only as forward
5720 if (!(s
->r
& VT_FORWARD
)) {
5721 /* s is not forward, so we can relocate all symbols */
5722 greloc_patch(ext_sym
, s
->c
);
5724 /* the two symbols are forward: merge them */
5725 p
= (Reloc
**)&ext_sym
->c
;
5731 /* external symbol already exists and is defined :
5732 patch all references to it */
5733 if (!(s
->r
& VT_FORWARD
))
5734 error("'%s' defined twice", get_tok_str(s
->v
, NULL
));
5735 greloc_patch(s
, ext_sym
->c
);
5742 /* compile a C file. Return non zero if errors. */
5743 int tcc_compile_file(const char *filename1
)
5750 file
= tcc_open(filename1
);
5752 error("file '%s' not found", filename1
);
5753 include_stack_ptr
= include_stack
;
5754 ifdef_stack_ptr
= ifdef_stack
;
5757 anon_sym
= SYM_FIRST_ANOM
;
5759 /* file info: full path + filename */
5761 getcwd(buf
, sizeof(buf
));
5762 pstrcat(buf
, sizeof(buf
), "/");
5763 put_stabs(buf
, N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
5764 put_stabs(file
->filename
, N_SO
, 0, 0,
5765 (unsigned long)text_section
->data_ptr
);
5767 /* define common 'char *' type because it is often used internally
5768 for arrays and struct dereference */
5769 char_pointer_type
= mk_pointer(VT_BYTE
);
5771 define_start
= define_stack
.top
;
5773 ch
= '\n'; /* needed to parse correctly first preprocessor command */
5777 expect("declaration");
5780 /* end of translation unit info */
5782 put_stabn(N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
5785 /* reset define stack, but leave -Dsymbols (may be incorrect if
5786 they are undefined) */
5787 sym_pop(&define_stack
, define_start
);
5789 resolve_global_syms();
5791 sym_pop(&global_stack
, NULL
);
5796 /* define a symbol. A value can also be provided with the '=' operator */
5797 /* XXX: currently only handles integers and string defines. should use
5798 tcc parser, but would need a custom 'FILE *' */
5799 void define_symbol(const char *sym
)
5802 BufferedFile bf1
, *bf
= &bf1
;
5804 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
5805 p
= strchr(bf
->buffer
, '=');
5808 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " 1");
5813 /* init file structure */
5815 bf
->buf_ptr
= bf
->buffer
;
5816 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
5817 bf
->filename
[0] = '\0';
5821 include_stack_ptr
= include_stack
;
5823 /* parse with define parser */
5825 ch
= '\n'; /* needed to parse correctly first preprocessor command */
5831 void undef_symbol(const char *sym
)
5835 ts
= tok_alloc(sym
, 0);
5836 s
= sym_find1(&define_stack
, tok
);
5837 /* undefine symbol by putting an invalid name */
5839 sym_undef(&define_stack
, s
);
5842 /* open a dynamic library so that its symbol are available for
5843 compiled programs */
5844 void open_dll(char *libname
)
5849 snprintf(buf
, sizeof(buf
), "lib%s.so", libname
);
5850 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
5852 error((char *)dlerror());
5855 static void *resolve_sym(const char *sym
)
5858 if (do_bounds_check
) {
5859 ptr
= bound_resolve_sym(sym
);
5863 return dlsym(NULL
, sym
);
5866 void resolve_extern_syms(void)
5872 s
= extern_stack
.top
;
5875 if (s
->r
& VT_FORWARD
) {
5876 /* if there is at least one relocation to do, then find it
5879 str
= get_tok_str(s
->v
, NULL
);
5880 addr
= (int)resolve_sym(str
);
5882 error("unresolved external reference '%s'", str
);
5883 greloc_patch(s
, addr
);
5890 static int put_elf_str(Section
*s
, const char *sym
)
5893 offset
= s
->data_ptr
- s
->data
;
5903 static void put_elf_sym(Section
*s
,
5904 unsigned long value
, unsigned long size
,
5905 int info
, int other
, int shndx
, const char *name
)
5910 sym
= (Elf32_Sym
*)s
->data_ptr
;
5912 name_offset
= put_elf_str(s
->link
, name
);
5915 sym
->st_name
= name_offset
;
5916 sym
->st_value
= value
;
5917 sym
->st_size
= size
;
5918 sym
->st_info
= info
;
5919 sym
->st_other
= other
;
5920 sym
->st_shndx
= shndx
;
5921 s
->data_ptr
+= sizeof(Elf32_Sym
);
5924 /* put stab debug information */
5927 unsigned long n_strx
; /* index into string table of name */
5928 unsigned char n_type
; /* type of symbol */
5929 unsigned char n_other
; /* misc info (usually empty) */
5930 unsigned short n_desc
; /* description field */
5931 unsigned long n_value
; /* value of symbol */
5934 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
)
5938 sym
= (Stab_Sym
*)stab_section
->data_ptr
;
5940 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
5945 sym
->n_other
= other
;
5947 sym
->n_value
= value
;
5949 stab_section
->data_ptr
+= sizeof(Stab_Sym
);
5952 static void put_stabn(int type
, int other
, int desc
, int value
)
5954 put_stabs(NULL
, type
, other
, desc
, value
);
5957 static void put_stabd(int type
, int other
, int desc
)
5959 put_stabs(NULL
, type
, other
, desc
, 0);
5962 /* output an ELF file (currently, only for testing) */
5963 /* XXX: generate dynamic reloc info + DLL tables */
5964 /* XXX: generate startup code */
5965 /* XXX: better program header generation */
5966 /* XXX: handle realloc'ed sections (instead of mmaping them) */
5967 void build_exe(char *filename
)
5971 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
;
5972 Section
*sec
, *strsec
;
5973 Elf32_Shdr
*shdr
, *sh
;
5974 Elf32_Phdr
*phdr
, *ph
;
5976 memset(&ehdr
, 0, sizeof(ehdr
));
5978 /* we add a section for symbols */
5979 strsec
= new_section(".shstrtab", SHT_STRTAB
, 0);
5980 put_elf_str(strsec
, "");
5982 /* count number of sections and compute number of program segments */
5983 shnum
= 1; /* section index zero is reserved */
5985 for(sec
= first_section
; sec
!= NULL
; sec
= sec
->next
) {
5987 if (sec
->sh_flags
& SHF_ALLOC
)
5990 /* allocate section headers */
5991 shdr
= malloc(shnum
* sizeof(Elf32_Shdr
));
5993 error("memory full");
5994 memset(shdr
, 0, shnum
* sizeof(Elf32_Shdr
));
5995 /* allocate program segment headers */
5996 phdr
= malloc(phnum
* sizeof(Elf32_Phdr
));
5998 error("memory full");
5999 memset(phdr
, 0, phnum
* sizeof(Elf32_Phdr
));
6001 /* XXX: find correct load order */
6002 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
6003 for(sec
= first_section
, i
= 1; sec
!= NULL
; sec
= sec
->next
, i
++) {
6005 sh
->sh_name
= put_elf_str(strsec
, sec
->name
);
6006 sh
->sh_type
= sec
->sh_type
;
6007 sh
->sh_flags
= sec
->sh_flags
;
6008 sh
->sh_entsize
= sec
->sh_entsize
;
6010 sh
->sh_link
= sec
->link
->sh_num
;
6011 if (sh
->sh_type
== SHT_STRTAB
) {
6012 sh
->sh_addralign
= 1;
6013 } else if (sh
->sh_type
== SHT_SYMTAB
||
6014 (sh
->sh_flags
& SHF_ALLOC
) == 0) {
6015 sh
->sh_addralign
= 4;
6017 sh
->sh_addr
= (Elf32_Word
)sec
->data
;
6018 sh
->sh_addralign
= 4096;
6020 sh
->sh_size
= (Elf32_Word
)sec
->data_ptr
- (Elf32_Word
)sec
->data
;
6021 /* align to section start */
6022 file_offset
= (file_offset
+ sh
->sh_addralign
- 1) &
6023 ~(sh
->sh_addralign
- 1);
6024 sh
->sh_offset
= file_offset
;
6025 file_offset
+= sh
->sh_size
;
6027 /* build program headers (simplistic - not fully correct) */
6029 for(i
=1;i
<shnum
;i
++) {
6031 if (sh
->sh_type
== SHT_PROGBITS
&&
6032 (sh
->sh_flags
& SHF_ALLOC
) != 0) {
6034 ph
->p_type
= PT_LOAD
;
6035 ph
->p_offset
= sh
->sh_offset
;
6036 ph
->p_vaddr
= sh
->sh_addr
;
6037 ph
->p_paddr
= ph
->p_vaddr
;
6038 ph
->p_filesz
= sh
->sh_size
;
6039 ph
->p_memsz
= sh
->sh_size
;
6041 if (sh
->sh_flags
& SHF_WRITE
)
6042 ph
->p_flags
|= PF_W
;
6043 if (sh
->sh_flags
& SHF_EXECINSTR
)
6044 ph
->p_flags
|= PF_X
;
6045 ph
->p_align
= sh
->sh_addralign
;
6050 file_offset
= (file_offset
+ 3) & -4;
6053 ehdr
.e_ident
[0] = ELFMAG0
;
6054 ehdr
.e_ident
[1] = ELFMAG1
;
6055 ehdr
.e_ident
[2] = ELFMAG2
;
6056 ehdr
.e_ident
[3] = ELFMAG3
;
6057 ehdr
.e_ident
[4] = ELFCLASS32
;
6058 ehdr
.e_ident
[5] = ELFDATA2LSB
;
6059 ehdr
.e_ident
[6] = EV_CURRENT
;
6060 ehdr
.e_type
= ET_EXEC
;
6061 ehdr
.e_machine
= EM_386
;
6062 ehdr
.e_version
= EV_CURRENT
;
6063 ehdr
.e_entry
= 0; /* XXX: patch it */
6064 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
6065 ehdr
.e_shoff
= file_offset
;
6066 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
6067 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
6068 ehdr
.e_phnum
= phnum
;
6069 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
6070 ehdr
.e_shnum
= shnum
;
6071 ehdr
.e_shstrndx
= shnum
- 1;
6073 /* write elf file */
6074 f
= fopen(filename
, "w");
6076 error("could not write '%s'", filename
);
6077 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
6078 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
6079 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
6080 for(sec
= first_section
, i
= 1; sec
!= NULL
; sec
= sec
->next
, i
++) {
6082 while (offset
< sh
->sh_offset
) {
6086 size
= sec
->data_ptr
- sec
->data
;
6087 fwrite(sec
->data
, 1, size
, f
);
6090 while (offset
< ehdr
.e_shoff
) {
6094 fwrite(shdr
, 1, shnum
* sizeof(Elf32_Shdr
), f
);
6098 /* print the position in the source file of PC value 'pc' by reading
6099 the stabs debug information */
6100 static void rt_printline(unsigned long wanted_pc
)
6102 Stab_Sym
*sym
, *sym_end
;
6103 char func_name
[128];
6104 unsigned long func_addr
, last_pc
, pc
;
6105 const char *incl_files
[INCLUDE_STACK_SIZE
];
6106 int incl_index
, len
, last_line_num
, i
;
6107 const char *str
, *p
;
6109 func_name
[0] = '\0';
6112 last_pc
= 0xffffffff;
6114 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
6115 sym_end
= (Stab_Sym
*)stab_section
->data_ptr
;
6116 while (sym
< sym_end
) {
6117 switch(sym
->n_type
) {
6118 /* function start or end */
6120 if (sym
->n_strx
== 0) {
6121 func_name
[0] = '\0';
6124 str
= stabstr_section
->data
+ sym
->n_strx
;
6125 p
= strchr(str
, ':');
6127 pstrcpy(func_name
, sizeof(func_name
), str
);
6130 if (len
> sizeof(func_name
) - 1)
6131 len
= sizeof(func_name
) - 1;
6132 memcpy(func_name
, str
, len
);
6133 func_name
[len
] = '\0';
6135 func_addr
= sym
->n_value
;
6138 /* line number info */
6140 pc
= sym
->n_value
+ func_addr
;
6141 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
6144 last_line_num
= sym
->n_desc
;
6148 str
= stabstr_section
->data
+ sym
->n_strx
;
6150 if (incl_index
< INCLUDE_STACK_SIZE
) {
6151 incl_files
[incl_index
++] = str
;
6159 if (sym
->n_strx
== 0) {
6160 incl_index
= 0; /* end of translation unit */
6162 str
= stabstr_section
->data
+ sym
->n_strx
;
6163 /* do not add path */
6165 if (len
> 0 && str
[len
- 1] != '/')
6172 /* did not find line number info: */
6173 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
6176 for(i
= 0; i
< incl_index
- 1; i
++)
6177 fprintf(stderr
, "In file included from %s\n",
6179 if (incl_index
> 0) {
6180 fprintf(stderr
, "%s:%d: ",
6181 incl_files
[incl_index
- 1], last_line_num
);
6183 if (func_name
[0] != '\0') {
6184 fprintf(stderr
, "in function '%s()': ", func_name
);
6188 /* emit a run time error at position 'pc' */
6189 void rt_error(unsigned long pc
, const char *fmt
, ...)
6195 vfprintf(stderr
, fmt
, ap
);
6196 fprintf(stderr
, "\n");
6202 /* signal handler for fatal errors */
6203 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
6205 struct ucontext
*uc
= puc
;
6209 pc
= uc
->uc_mcontext
.gregs
[14];
6211 #error please put the right sigcontext field
6216 switch(siginf
->si_code
) {
6219 rt_error(pc
, "division by zero");
6222 rt_error(pc
, "floating point exception");
6228 rt_error(pc
, "dereferencing invalid pointer");
6231 rt_error(pc
, "illegal instruction");
6234 rt_error(pc
, "abort() called");
6237 rt_error(pc
, "caught signal %d", signum
);
6244 /* launch the compiled program with the given arguments */
6245 int launch_exe(int argc
, char **argv
)
6250 s
= sym_find1(&extern_stack
, TOK_MAIN
);
6251 if (!s
|| (s
->r
& VT_FORWARD
))
6252 error("main() not defined");
6256 error("debug mode currently not available for Windows");
6258 struct sigaction sigact
;
6259 /* install TCC signal handlers to print debug info on fatal
6261 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
6262 sigact
.sa_sigaction
= sig_error
;
6263 sigemptyset(&sigact
.sa_mask
);
6264 sigaction(SIGFPE
, &sigact
, NULL
);
6265 sigaction(SIGILL
, &sigact
, NULL
);
6266 sigaction(SIGSEGV
, &sigact
, NULL
);
6267 sigaction(SIGBUS
, &sigact
, NULL
);
6268 sigaction(SIGABRT
, &sigact
, NULL
);
6272 if (do_bounds_check
) {
6274 error("bound checking currently not available for Windows");
6278 /* add all known static regions */
6279 p
= (int *)bounds_section
->data
;
6280 p_end
= (int *)bounds_section
->data_ptr
;
6282 __bound_new_region((void *)p
[0], p
[1]);
6288 t
= (int (*)())s
->c
;
6289 return (*t
)(argc
, argv
);
6295 printf("tcc version 0.9.4 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
6296 "usage: tcc [-Idir] [-Dsym[=val]] [-Usym] [-llib] [-g] [-b]\n"
6297 " [-i infile] infile [infile_args...]\n"
6299 "-Idir : add include path 'dir'\n"
6300 "-Dsym[=val] : define 'sym' with value 'val'\n"
6301 "-Usym : undefine 'sym'\n"
6302 "-llib : link with dynamic library 'lib'\n"
6303 "-g : generate runtime debug info\n"
6304 "-b : compile with built-in memory and bounds checker (implies -g)\n"
6305 "-i infile : compile infile\n"
6309 int main(int argc
, char **argv
)
6311 char *p
, *r
, *outfile
;
6314 include_paths
[0] = "/usr/include";
6315 include_paths
[1] = "/usr/lib/tcc";
6316 include_paths
[2] = "/usr/local/lib/tcc";
6317 nb_include_paths
= 3;
6319 /* add all tokens */
6320 tok_ident
= TOK_IDENT
;
6325 tok_alloc(p
, r
- p
- 1);
6329 /* standard defines */
6330 define_symbol("__STDC__");
6332 define_symbol("__i386__");
6334 /* tiny C specific defines */
6335 define_symbol("__TINYC__");
6337 /* create standard sections */
6338 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
6339 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6340 /* XXX: should change type to SHT_NOBITS */
6341 bss_section
= new_section(".bss", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6346 if (optind
>= argc
) {
6356 if (nb_include_paths
>= INCLUDE_PATHS_MAX
)
6357 error("too many include paths");
6358 include_paths
[nb_include_paths
++] = r
+ 2;
6359 } else if (r
[1] == 'D') {
6360 define_symbol(r
+ 2);
6361 } else if (r
[1] == 'U') {
6362 undef_symbol(r
+ 2);
6363 } else if (r
[1] == 'l') {
6365 } else if (r
[1] == 'i') {
6368 tcc_compile_file(argv
[optind
++]);
6369 } else if (!strcmp(r
+ 1, "bench")) {
6371 } else if (r
[1] == 'b') {
6372 if (!do_bounds_check
) {
6373 do_bounds_check
= 1;
6375 define_symbol("__BOUNDS_CHECKING_ON");
6376 /* create bounds sections */
6377 bounds_section
= new_section(".bounds",
6378 SHT_PROGBITS
, SHF_ALLOC
);
6379 lbounds_section
= new_section(".lbounds",
6380 SHT_PROGBITS
, SHF_ALLOC
);
6381 /* debug is implied */
6384 } else if (r
[1] == 'g') {
6390 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
6391 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
6392 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
6393 put_elf_str(stabstr_section
, "");
6394 stab_section
->link
= stabstr_section
;
6395 /* put first entry */
6396 put_stabs("", 0, 0, 0, 0);
6399 symtab_section
= new_section(".symtab", SHT_SYMTAB
, 0);
6400 symtab_section
->sh_entsize
= sizeof(Elf32_Sym
);
6401 strtab_section
= new_section(".strtab", SHT_STRTAB
, 0);
6402 put_elf_str(strtab_section
, "");
6403 symtab_section
->link
= strtab_section
;
6404 put_elf_sym(symtab_section
, 0, 0, 0, 0, 0, NULL
);
6406 } else if (r
[1] == 'o') {
6407 /* currently, only for testing, so not documented */
6410 outfile
= argv
[optind
++];
6412 fprintf(stderr
, "invalid option -- '%s'\n", r
);
6417 tcc_compile_file(argv
[optind
]);
6420 printf("total: %d idents, %d lines, %d bytes\n",
6421 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
6424 resolve_extern_syms();
6430 return launch_exe(argc
- optind
, argv
+ optind
);