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 /* amount of virtual memory associated to a section (currently, we do
47 #define SECTION_VSIZE (1024 * 1024)
49 #define INCLUDE_STACK_SIZE 32
50 #define IFDEF_STACK_SIZE 64
51 #define VSTACK_SIZE 64
52 #define STRING_MAX_SIZE 1024
53 #define INCLUDE_PATHS_MAX 32
55 #define TOK_HASH_SIZE 2048 /* must be a power of two */
56 #define TOK_ALLOC_INCR 512 /* must be a power of two */
57 #define SYM_HASH_SIZE 1031
59 /* token symbol management */
60 typedef struct TokenSym
{
61 struct TokenSym
*hash_next
;
62 int tok
; /* token number */
68 typedef union CValue
{
74 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
76 unsigned long long ull
;
83 typedef struct SValue
{
85 unsigned short r
; /* register + flags */
86 unsigned short r2
; /* second register, used for 'long long'
87 type. If not used, set to VT_CONST */
88 CValue c
; /* constant */
91 /* symbol management */
93 int v
; /* symbol token */
94 int t
; /* associated type */
95 int r
; /* associated register */
96 int c
; /* associated number */
97 struct Sym
*next
; /* next related symbol */
98 struct Sym
*prev
; /* prev symbol in stack */
99 struct Sym
*hash_next
; /* next symbol in hash table */
102 typedef struct SymStack
{
104 struct Sym
*hash
[SYM_HASH_SIZE
];
107 /* relocation entry (currently only used for functions or variables */
108 typedef struct Reloc
{
109 int type
; /* type of relocation */
110 int addr
; /* address of relocation */
111 struct Reloc
*next
; /* next relocation */
114 #define RELOC_ADDR32 1 /* 32 bits relocation */
115 #define RELOC_REL32 2 /* 32 bits relative relocation */
117 /* section definition */
118 typedef struct Section
{
119 char name
[64]; /* section name */
120 unsigned char *data
; /* section data */
121 unsigned char *data_ptr
; /* current data pointer */
122 int sh_num
; /* elf section number */
123 int sh_type
; /* elf section type */
124 int sh_flags
; /* elf section flags */
125 int sh_entsize
; /* elf entry size */
126 struct Section
*link
; /* link to another section */
127 struct Section
*next
;
130 /* GNUC attribute definition */
131 typedef struct AttributeDef
{
134 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
137 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
138 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
139 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
141 /* stored in 'Sym.c' field */
142 #define FUNC_NEW 1 /* ansi function prototype */
143 #define FUNC_OLD 2 /* old function prototype */
144 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
146 /* stored in 'Sym.r' field */
147 #define FUNC_CDECL 0 /* standard c call */
148 #define FUNC_STDCALL 1 /* pascal c call */
150 /* field 'Sym.t' for macros */
151 #define MACRO_OBJ 0 /* object like macro */
152 #define MACRO_FUNC 1 /* function like macro */
154 /* type_decl() types */
155 #define TYPE_ABSTRACT 1 /* type without variable */
156 #define TYPE_DIRECT 2 /* type with variable */
158 #define IO_BUF_SIZE 8192
160 typedef struct BufferedFile
{
161 unsigned char *buf_ptr
;
162 unsigned char *buf_end
;
164 int line_num
; /* current line number - here to simply code */
165 char filename
[1024]; /* current filename - here to simply code */
166 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
169 #define CH_EOB 0 /* end of buffer or '\0' char in file */
170 #define CH_EOF (-1) /* end of file */
173 struct BufferedFile
*file
;
174 int ch
, ch1
, tok
, tok1
;
178 Section
*first_section
;
180 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
181 Section
*cur_text_section
; /* current section where function code is
183 /* bound check related sections */
184 Section
*bounds_section
; /* contains global data bound description */
185 Section
*lbounds_section
; /* contains local data bound description */
187 Section
*stab_section
, *stabstr_section
, *symtab_section
, *strtab_section
;
189 /* loc : local variable index
190 ind : output code index
192 anon_sym: anonymous symbol index
195 prog
, ind
, loc
, const_wanted
;
196 int global_expr
; /* true if compound literals must be allocated
197 globally (used during initializers parsing */
198 int func_vt
, func_vc
; /* current function return type (used by
199 return instruction) */
200 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
202 TokenSym
**table_ident
;
203 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
204 char token_buf
[STRING_MAX_SIZE
+ 1];
206 /* contains global symbols which remain between each translation unit */
207 SymStack extern_stack
;
208 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
210 SValue vstack
[VSTACK_SIZE
], *vtop
;
211 int *macro_ptr
, *macro_ptr_allocated
;
212 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
], **include_stack_ptr
;
213 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
214 char *include_paths
[INCLUDE_PATHS_MAX
];
215 int nb_include_paths
;
216 int char_pointer_type
;
218 /* compile with debug symbol (and use them if error during execution) */
221 /* compile with built-in memory and bounds checker */
222 int do_bounds_check
= 0;
224 /* display benchmark infos */
229 /* use GNU C extensions */
232 /* use Tiny C extensions */
235 /* The current value can be: */
236 #define VT_VALMASK 0x00ff
237 #define VT_CONST 0x00f0 /* constant in vc
238 (must be first non register value) */
239 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
240 #define VT_LOCAL 0x00f2 /* offset on stack */
241 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
242 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
243 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
244 #define VT_LVAL 0x0100 /* var is an lvalue */
245 #define VT_FORWARD 0x0200 /* value is forward reference */
246 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
247 char/short stored in integer registers) */
248 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
249 dereferencing value */
252 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
254 #define VT_INT 0 /* integer type */
255 #define VT_BYTE 1 /* signed byte type */
256 #define VT_SHORT 2 /* short type */
257 #define VT_VOID 3 /* void type */
258 #define VT_PTR 4 /* pointer increment */
259 #define VT_ENUM 5 /* enum definition */
260 #define VT_FUNC 6 /* function type */
261 #define VT_STRUCT 7 /* struct/union definition */
262 #define VT_FLOAT 8 /* IEEE float */
263 #define VT_DOUBLE 9 /* IEEE double */
264 #define VT_LDOUBLE 10 /* IEEE long double */
265 #define VT_BOOL 11 /* ISOC99 boolean type */
266 #define VT_LLONG 12 /* 64 bit integer */
267 #define VT_LONG 13 /* long integer (NEVER USED as type, only
269 #define VT_BTYPE 0x000f /* mask for basic type */
270 #define VT_UNSIGNED 0x0010 /* unsigned type */
271 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
272 #define VT_BITFIELD 0x0040 /* bitfield modifier */
275 #define VT_EXTERN 0x00000080 /* extern definition */
276 #define VT_STATIC 0x00000100 /* static variable */
277 #define VT_TYPEDEF 0x00000200 /* typedef definition */
279 /* type mask (except storage) */
280 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
284 /* warning: the following compare tokens depend on i386 asm code */
296 #define TOK_LAND 0xa0
300 #define TOK_MID 0xa3 /* inc/dec, to void constant */
302 #define TOK_UDIV 0xb0 /* unsigned division */
303 #define TOK_UMOD 0xb1 /* unsigned modulo */
304 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
305 #define TOK_CINT 0xb3 /* number in tokc */
306 #define TOK_CCHAR 0xb4 /* char constant in tokc */
307 #define TOK_STR 0xb5 /* pointer to string in tokc */
308 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
309 #define TOK_LCHAR 0xb7
310 #define TOK_LSTR 0xb8
311 #define TOK_CFLOAT 0xb9 /* float constant */
312 #define TOK_CDOUBLE 0xc0 /* double constant */
313 #define TOK_CLDOUBLE 0xc1 /* long double constant */
314 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
315 #define TOK_ADDC1 0xc3 /* add with carry generation */
316 #define TOK_ADDC2 0xc4 /* add with carry use */
317 #define TOK_SUBC1 0xc5 /* add with carry generation */
318 #define TOK_SUBC2 0xc6 /* add with carry use */
319 #define TOK_CUINT 0xc8 /* unsigned int constant */
320 #define TOK_CLLONG 0xc9 /* long long constant */
321 #define TOK_CULLONG 0xca /* unsigned long long constant */
322 #define TOK_ARROW 0xcb
323 #define TOK_DOTS 0xcc /* three dots */
324 #define TOK_SHR 0xcd /* unsigned shift right */
326 #define TOK_SHL 0x01 /* shift left */
327 #define TOK_SAR 0x02 /* signed shift right */
329 /* assignement operators : normal operator or 0x80 */
330 #define TOK_A_MOD 0xa5
331 #define TOK_A_AND 0xa6
332 #define TOK_A_MUL 0xaa
333 #define TOK_A_ADD 0xab
334 #define TOK_A_SUB 0xad
335 #define TOK_A_DIV 0xaf
336 #define TOK_A_XOR 0xde
337 #define TOK_A_OR 0xfc
338 #define TOK_A_SHL 0x81
339 #define TOK_A_SAR 0x82
341 #define TOK_EOF (-1) /* end of file */
343 /* all identificators and strings have token above that */
344 #define TOK_IDENT 256
365 /* ignored types Must have contiguous values */
371 TOK___SIGNED__
, /* gcc keyword */
374 TOK___INLINE__
, /* gcc keyword */
377 /* unsupported type */
391 /* preprocessor only */
392 TOK_UIDENT
, /* first "user" ident (not keyword) */
393 TOK_DEFINE
= TOK_UIDENT
,
409 /* special identifiers */
412 /* attribute identifiers */
430 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
431 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
432 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
433 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
434 "sizeof\0__attribute__\0"
435 /* the following are not keywords. They are included to ease parsing */
436 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
437 "defined\0undef\0error\0line\0"
438 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
441 "section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0"
442 "cdecl\0__cdecl\0__cdecl__\0stdcall\0__stdcall\0__stdcall__\0"
443 "noreturn\0__noreturn__\0"
447 #define snprintf _snprintf
448 /* currently incorrect */
449 long double strtold(const char *nptr
, char **endptr
)
451 return (long double)strtod(nptr
, endptr
);
453 float strtof(const char *nptr
, char **endptr
)
455 return (float)strtod(nptr
, endptr
);
458 /* XXX: need to define this to use them in non ISOC99 context */
459 extern float strtof (const char *__nptr
, char **__endptr
);
460 extern long double strtold (const char *__nptr
, char **__endptr
);
465 void next_nomacro(void);
466 int expr_const(void);
470 void decl_initializer(int t
, int r
, int c
, int first
, int size_only
);
471 int decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
);
473 void gv2(int rc1
, int rc2
);
474 void move_reg(int r
, int s
);
475 void save_regs(void);
476 void save_reg(int r
);
482 void macro_subst(int **tok_str
, int *tok_len
,
483 Sym
**nested_list
, int *macro_str
);
484 int save_reg_forced(int r
);
486 void force_charshort_cast(int t
);
487 void gen_cast(int t
);
489 Sym
*sym_find(int v
);
490 Sym
*sym_push(int v
, int t
, int r
, int c
);
493 int type_size(int t
, int *a
);
494 int pointed_type(int t
);
495 int pointed_size(int t
);
496 int is_compatible_types(int t1
, int t2
);
497 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
498 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
500 void error(const char *fmt
, ...);
501 void rt_error(unsigned long pc
, const char *fmt
, ...);
503 void vset(int t
, int r
, int v
);
504 void type_to_str(char *buf
, int buf_size
,
505 int t
, const char *varstr
);
507 /* section generation */
508 void greloc(Sym
*s
, int addr
, int type
);
509 static int put_elf_str(Section
*s
, const char *sym
);
510 static void put_elf_sym(Section
*s
,
511 unsigned long value
, unsigned long size
,
512 int info
, int other
, int shndx
, const char *name
);
513 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
);
514 static void put_stabn(int type
, int other
, int desc
, int value
);
515 static void put_stabd(int type
, int other
, int desc
);
517 /* true if float/double/long double type */
518 static inline int is_float(int t
)
522 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
527 #include "i386-gen.c"
529 #ifdef CONFIG_TCC_STATIC
531 #define RTLD_LAZY 0x001
532 #define RTLD_NOW 0x002
533 #define RTLD_GLOBAL 0x100
535 /* dummy function for profiling */
536 void *dlopen(const char *filename
, int flag
)
541 const char *dlerror(void)
546 typedef struct TCCSyms
{
551 #define TCCSYM(a) { #a, &a, },
553 /* add the symbol you want here if no dynamic linking is done */
554 static TCCSyms tcc_syms
[] = {
562 void *dlsym(void *handle
, const char *symbol
)
566 while (p
->str
!= NULL
) {
567 if (!strcmp(p
->str
, symbol
))
576 /********************************************************/
577 /* runtime library is there */
578 /* XXX: we suppose that the host compiler handles 'long long'. It
579 would not be difficult to suppress this assumption */
581 long long __divll(long long a
, long long b
)
586 long long __modll(long long a
, long long b
)
591 unsigned long long __divull(unsigned long long a
, unsigned long long b
)
596 unsigned long long __modull(unsigned long long a
, unsigned long long b
)
601 long long __sardi3(long long a
, int b
)
606 unsigned long long __shrdi3(unsigned long long a
, int b
)
611 long long __shldi3(long long a
, int b
)
616 float __ulltof(unsigned long long a
)
621 double __ulltod(unsigned long long a
)
626 long double __ulltold(unsigned long long a
)
628 return (long double)a
;
631 unsigned long long __ftoull(float a
)
633 return (unsigned long long)a
;
636 unsigned long long __dtoull(double a
)
638 return (unsigned long long)a
;
641 unsigned long long __ldtoull(long double a
)
643 return (unsigned long long)a
;
647 /********************************************************/
649 /* copy a string and truncate it. */
650 char *pstrcpy(char *buf
, int buf_size
, const char *s
)
657 q_end
= buf
+ buf_size
- 1;
669 /* strcat and truncate. */
670 char *pstrcat(char *buf
, int buf_size
, const char *s
)
675 pstrcpy(buf
+ len
, buf_size
- len
, s
);
679 Section
*new_section(const char *name
, int sh_type
, int sh_flags
)
681 Section
*sec
, **psec
;
684 sec
= malloc(sizeof(Section
));
686 error("memory full");
687 memset(sec
, 0, sizeof(Section
));
688 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
690 sec
->sh_num
= ++section_num
;
691 sec
->sh_type
= sh_type
;
692 sec
->sh_flags
= sh_flags
;
694 /* XXX: currently, a single malloc */
695 data
= malloc(SECTION_VSIZE
);
697 error("could not alloc section '%s'", name
);
699 data
= mmap(NULL
, SECTION_VSIZE
,
700 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
701 MAP_PRIVATE
| MAP_ANONYMOUS
,
703 if (data
== (void *)(-1))
704 error("could not mmap section '%s'", name
);
707 sec
->data_ptr
= data
;
708 psec
= &first_section
;
709 while (*psec
!= NULL
)
710 psec
= &(*psec
)->next
;
716 /* return a reference to a section, and create it if it does not
718 Section
*find_section(const char *name
)
722 for(sec
= first_section
; sec
!= NULL
; sec
= sec
->next
) {
723 if (!strcmp(name
, sec
->name
))
726 /* sections are created as PROGBITS */
727 return new_section(name
, SHT_PROGBITS
, SHF_ALLOC
);
730 /* add a new relocation entry to symbol 's' */
731 void greloc(Sym
*s
, int addr
, int type
)
734 p
= malloc(sizeof(Reloc
));
736 error("memory full");
739 p
->next
= (Reloc
*)s
->c
;
743 /* patch each relocation entry with value 'val' */
744 void greloc_patch(Sym
*s
, int val
)
751 greloc_patch1(p
, val
);
760 static inline int isid(int c
)
762 return (c
>= 'a' && c
<= 'z') ||
763 (c
>= 'A' && c
<= 'Z') ||
767 static inline int isnum(int c
)
769 return c
>= '0' && c
<= '9';
772 static inline int toup(int c
)
774 if (ch
>= 'a' && ch
<= 'z')
775 return ch
- 'a' + 'A';
783 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
784 fprintf(stderr
, "In file included from %s:%d:\n",
785 (*f
)->filename
, (*f
)->line_num
);
786 fprintf(stderr
, "%s:%d: ", file
->filename
, file
->line_num
);
789 void error(const char *fmt
, ...)
794 vfprintf(stderr
, fmt
, ap
);
795 fprintf(stderr
, "\n");
800 void expect(const char *msg
)
802 error("%s expected", msg
);
805 void warning(const char *fmt
, ...)
811 fprintf(stderr
, "warning: ");
812 vfprintf(stderr
, fmt
, ap
);
813 fprintf(stderr
, "\n");
820 error("'%c' expected", c
);
824 void test_lvalue(void)
826 if (!(vtop
->r
& VT_LVAL
))
830 TokenSym
*tok_alloc(const char *str
, int len
)
832 TokenSym
*ts
, **pts
, **ptable
;
839 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
841 pts
= &hash_ident
[h
];
846 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
848 pts
= &(ts
->hash_next
);
851 if (tok_ident
>= SYM_FIRST_ANOM
)
852 error("memory full");
854 /* expand token table if needed */
855 i
= tok_ident
- TOK_IDENT
;
856 if ((i
% TOK_ALLOC_INCR
) == 0) {
857 ptable
= realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
859 error("memory full");
860 table_ident
= ptable
;
863 ts
= malloc(sizeof(TokenSym
) + len
);
865 error("memory full");
867 ts
->tok
= tok_ident
++;
869 ts
->hash_next
= NULL
;
870 memcpy(ts
->str
, str
, len
+ 1);
875 void add_char(char **pp
, int c
)
879 if (c
== '\'' || c
== '\"' || c
== '\\') {
880 /* XXX: could be more precise if char or string */
883 if (c
>= 32 && c
<= 126) {
890 *p
++ = '0' + ((c
>> 6) & 7);
891 *p
++ = '0' + ((c
>> 3) & 7);
892 *p
++ = '0' + (c
& 7);
898 /* XXX: buffer overflow */
899 char *get_tok_str(int v
, CValue
*cv
)
901 static char buf
[STRING_MAX_SIZE
+ 1];
906 if (v
== TOK_CINT
|| v
== TOK_CUINT
) {
907 sprintf(buf
, "%u", cv
->ui
);
909 } else if (v
== TOK_CCHAR
|| v
== TOK_LCHAR
) {
916 } else if (v
== TOK_STR
|| v
== TOK_LSTR
) {
920 for(i
=0;i
<ts
->len
;i
++)
921 add_char(&p
, ts
->str
[i
]);
925 } else if (v
< TOK_IDENT
) {
930 } else if (v
< tok_ident
) {
931 return table_ident
[v
- TOK_IDENT
]->str
;
933 /* should never happen */
938 /* push, without hashing */
939 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
942 s
= malloc(sizeof(Sym
));
944 error("memory full");
955 /* find a symbol and return its associated structure. 's' is the top
956 of the symbol stack */
957 Sym
*sym_find2(Sym
*s
, int v
)
967 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
969 /* find a symbol and return its associated structure. 'st' is the
971 Sym
*sym_find1(SymStack
*st
, int v
)
975 s
= st
->hash
[HASH_SYM(v
)];
984 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
987 s
= sym_push2(&st
->top
, v
, t
, c
);
988 /* add in hash table */
990 ps
= &st
->hash
[HASH_SYM(v
)];
997 /* find a symbol in the right symbol space */
1001 s
= sym_find1(&local_stack
, v
);
1003 s
= sym_find1(&global_stack
, v
);
1007 /* push a given symbol on the symbol stack */
1008 Sym
*sym_push(int v
, int t
, int r
, int c
)
1011 if (local_stack
.top
)
1012 s
= sym_push1(&local_stack
, v
, t
, c
);
1014 s
= sym_push1(&global_stack
, v
, t
, c
);
1019 /* pop symbols until top reaches 'b' */
1020 void sym_pop(SymStack
*st
, Sym
*b
)
1027 /* free hash table entry, except if symbol was freed (only
1028 used for #undef symbols) */
1030 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1037 /* undefined a hashed symbol (used for #undef). Its name is set to
1039 void sym_undef(SymStack
*st
, Sym
*s
)
1042 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1043 while (*ss
!= NULL
) {
1046 ss
= &(*ss
)->hash_next
;
1054 BufferedFile
*tcc_open(const char *filename
)
1059 fd
= open(filename
, O_RDONLY
);
1062 bf
= malloc(sizeof(BufferedFile
));
1068 bf
->buf_ptr
= bf
->buffer
;
1069 bf
->buf_end
= bf
->buffer
;
1070 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1071 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1073 // printf("opening '%s'\n", filename);
1077 void tcc_close(BufferedFile
*bf
)
1079 total_lines
+= bf
->line_num
;
1084 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1085 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1087 /* fill input buffer and return next char */
1088 int tcc_getc_slow(BufferedFile
*bf
)
1091 /* only tries to read if really end of buffer */
1092 if (bf
->buf_ptr
>= bf
->buf_end
) {
1094 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1101 bf
->buf_ptr
= bf
->buffer
;
1102 bf
->buf_end
= bf
->buffer
+ len
;
1103 *bf
->buf_end
= CH_EOB
;
1105 if (bf
->buf_ptr
< bf
->buf_end
) {
1106 return *bf
->buf_ptr
++;
1108 bf
->buf_ptr
= bf
->buf_end
;
1113 /* no need to put that inline */
1114 void handle_eob(void)
1117 ch1
= tcc_getc_slow(file
);
1121 if (include_stack_ptr
== include_stack
)
1123 /* add end of include file debug info */
1125 put_stabd(N_EINCL
, 0, 0);
1127 /* pop include stack */
1129 include_stack_ptr
--;
1130 file
= *include_stack_ptr
;
1134 /* read next char from current input file */
1135 static inline void inp(void)
1137 ch1
= TCC_GETC(file
);
1138 /* end of buffer/file handling */
1143 // printf("ch1=%c 0x%x\n", ch1, ch1);
1146 /* input with '\\n' handling */
1147 static inline void minp(void)
1152 if (ch
== '\\' && ch1
== '\n') {
1156 //printf("ch=%c 0x%x\n", ch, ch);
1160 /* same as minp, but also skip comments */
1168 /* single line C++ comments */
1170 while (ch1
!= '\n' && ch1
!= -1)
1173 ch
= ' '; /* return space */
1174 } else if (ch1
== '*') {
1180 if (c
== '*' && ch1
== '/') {
1182 ch
= ' '; /* return space */
1194 void skip_spaces(void)
1196 while (ch
== ' ' || ch
== '\t')
1200 /* skip block of text until #else, #elif or #endif. skip also pairs of
1202 void preprocess_skip(void)
1207 while (ch
!= '\n') {
1218 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1220 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1222 else if (tok
== TOK_ENDIF
)
1228 /* return the number of additionnal 'ints' necessary to store the
1230 static inline int tok_ext_size(int t
)
1247 return LDOUBLE_SIZE
/ 4;
1253 void tok_add(int **tok_str
, int *tok_len
, int t
)
1258 if ((len
& 63) == 0) {
1259 str
= realloc(str
, (len
+ 64) * sizeof(int));
1268 void tok_add2(int **tok_str
, int *tok_len
, int t
, CValue
*cv
)
1272 tok_add(tok_str
, tok_len
, t
);
1273 n
= tok_ext_size(t
);
1275 tok_add(tok_str
, tok_len
, cv
->tab
[i
]);
1278 /* get a token from an integer array and increment pointer accordingly */
1279 int tok_get(int **tok_str
, CValue
*cv
)
1285 n
= tok_ext_size(t
);
1292 /* eval an expression for #if/#elif */
1293 int expr_preprocess(void)
1295 int *str
, len
, c
, t
;
1303 next(); /* do macro subst */
1304 if (tok
== TOK_DEFINED
) {
1309 c
= sym_find1(&define_stack
, tok
) != 0;
1314 } else if (tok
>= TOK_IDENT
) {
1315 /* if undefined macro */
1319 tok_add2(&str
, &len
, tok
, &tokc
);
1321 tok_add(&str
, &len
, -1); /* simulate end of file */
1322 tok_add(&str
, &len
, 0);
1323 /* now evaluate C constant expression */
1332 #if defined(DEBUG) || defined(PP_DEBUG)
1333 void tok_print(int *str
)
1339 t
= tok_get(&str
, &cval
);
1342 printf(" %s", get_tok_str(t
, &cval
));
1348 /* parse after #define */
1349 void parse_define(void)
1351 Sym
*s
, *first
, **ps
;
1352 int v
, t
, *str
, len
;
1355 /* XXX: should check if same macro (ANSI) */
1358 /* '(' must be just after macro definition for MACRO_FUNC */
1363 while (tok
!= ')') {
1364 if (tok
== TOK_DOTS
)
1365 tok
= TOK___VA_ARGS__
;
1366 s
= sym_push1(&define_stack
, tok
| SYM_FIELD
, 0, 0);
1380 if (ch
== '\n' || ch
== -1)
1383 tok_add2(&str
, &len
, tok
, &tokc
);
1385 tok_add(&str
, &len
, 0);
1387 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1390 s
= sym_push1(&define_stack
, v
, t
, (int)str
);
1394 void preprocess(void)
1397 char buf
[1024], *q
, *p
;
1405 if (tok
== TOK_DEFINE
) {
1408 } else if (tok
== TOK_UNDEF
) {
1410 s
= sym_find1(&define_stack
, tok
);
1411 /* undefine symbol by putting an invalid name */
1413 sym_undef(&define_stack
, s
);
1414 } else if (tok
== TOK_INCLUDE
) {
1419 } else if (ch
== '\"') {
1424 while (ch
!= c
&& ch
!= '\n' && ch
!= -1) {
1425 if ((q
- buf
) < sizeof(buf
) - 1)
1433 error("#include syntax error");
1434 pstrcpy(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
1437 /* eat all spaces and comments after include */
1438 /* XXX: slightly incorrect */
1439 while (ch1
!= '\n' && ch1
!= -1)
1442 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1443 error("memory full");
1445 /* first search in current dir if "header.h" */
1447 p
= strrchr(file
->filename
, '/');
1449 size
= p
+ 1 - file
->filename
;
1450 if (size
> sizeof(buf1
) - 1)
1451 size
= sizeof(buf1
) - 1;
1452 memcpy(buf1
, file
->filename
, size
);
1454 pstrcat(buf1
, sizeof(buf1
), buf
);
1459 /* now search in standard include path */
1460 for(i
=nb_include_paths
- 1;i
>=0;i
--) {
1461 strcpy(buf1
, include_paths
[i
]);
1468 error("include file '%s' not found", buf1
);
1471 /* push current file in stack */
1472 /* XXX: fix current line init */
1473 *include_stack_ptr
++ = file
;
1475 /* add include file debug info */
1477 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
1479 } else if (tok
== TOK_IFNDEF
) {
1482 } else if (tok
== TOK_IF
) {
1483 c
= expr_preprocess();
1485 } else if (tok
== TOK_IFDEF
) {
1489 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1491 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1492 error("memory full");
1493 *ifdef_stack_ptr
++ = c
;
1495 } else if (tok
== TOK_ELSE
) {
1496 if (ifdef_stack_ptr
== ifdef_stack
)
1497 error("#else without matching #if");
1498 if (ifdef_stack_ptr
[-1] & 2)
1499 error("#else after #else");
1500 c
= (ifdef_stack_ptr
[-1] ^= 3);
1502 } else if (tok
== TOK_ELIF
) {
1503 if (ifdef_stack_ptr
== ifdef_stack
)
1504 error("#elif without matching #if");
1505 c
= ifdef_stack_ptr
[-1];
1507 error("#elif after #else");
1508 /* last #if/#elif expression was true: we skip */
1511 c
= expr_preprocess();
1512 ifdef_stack_ptr
[-1] = c
;
1519 } else if (tok
== TOK_ENDIF
) {
1520 if (ifdef_stack_ptr
== ifdef_stack
)
1521 error("#endif without matching #if");
1523 } else if (tok
== TOK_LINE
) {
1525 if (tok
!= TOK_CINT
)
1527 file
->line_num
= tokc
.i
;
1533 pstrcpy(file
->filename
, sizeof(file
->filename
),
1534 get_tok_str(tok
, &tokc
));
1536 } else if (tok
== TOK_ERROR
) {
1539 /* ignore other preprocess commands or #! for C scripts */
1540 while (ch
!= '\n' && ch
!= -1)
1544 /* read a number in base b */
1550 if (ch
>= 'a' && ch
<= 'f')
1552 else if (ch
>= 'A' && ch
<= 'F')
1558 if (t
< 0 || t
>= b
)
1566 /* read a character for string or char constant and eval escape codes */
1575 /* at most three octal digits */
1579 c
= c
* 8 + ch
- '0';
1582 c
= c
* 8 + ch
- '0';
1587 } else if (ch
== 'x') {
1605 else if (ch
== 'e' && gnu_ext
)
1607 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
1610 error("invalid escaped char");
1617 /* we use 64 bit numbers */
1620 /* bn = (bn << shift) | or_val */
1621 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
1625 for(i
=0;i
<BN_SIZE
;i
++) {
1627 bn
[i
] = (v
<< shift
) | or_val
;
1628 or_val
= v
>> (32 - shift
);
1632 void bn_zero(unsigned int *bn
)
1635 for(i
=0;i
<BN_SIZE
;i
++) {
1640 void parse_number(void)
1642 int b
, t
, shift
, frac_bits
, s
, exp_val
;
1644 unsigned int bn
[BN_SIZE
];
1654 /* special dot handling */
1655 if (ch
>= '0' && ch
<= '9') {
1656 goto float_frac_parse
;
1657 } else if (ch
== '.') {
1668 } else if (t
== '0') {
1669 if (ch
== 'x' || ch
== 'X') {
1673 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
1679 /* parse all digits. cannot check octal numbers at this stage
1680 because of floating point constants */
1682 if (ch
>= 'a' && ch
<= 'f')
1684 else if (ch
>= 'A' && ch
<= 'F')
1692 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
1694 error("number too long");
1700 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
1701 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
1703 /* NOTE: strtox should support that for hexa numbers, but
1704 non ISOC99 libcs do not support it, so we prefer to do
1706 /* hexadecimal or binary floats */
1707 /* XXX: handle overflows */
1719 } else if (t
>= 'a') {
1721 } else if (t
>= 'A') {
1726 bn_lshift(bn
, shift
, t
);
1733 if (t
>= 'a' && t
<= 'f') {
1735 } else if (t
>= 'A' && t
<= 'F') {
1737 } else if (t
>= '0' && t
<= '9') {
1743 error("invalid digit");
1744 bn_lshift(bn
, shift
, t
);
1749 if (ch
!= 'p' && ch
!= 'P')
1750 error("exponent expected");
1756 } else if (ch
== '-') {
1760 if (ch
< '0' || ch
> '9')
1761 error("exponent digits expected");
1762 while (ch
>= '0' && ch
<= '9') {
1763 exp_val
= exp_val
* 10 + ch
- '0';
1766 exp_val
= exp_val
* s
;
1768 /* now we can generate the number */
1769 /* XXX: should patch directly float number */
1770 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
1771 d
= ldexp(d
, exp_val
- frac_bits
);
1776 /* float : should handle overflow */
1778 } else if (t
== 'L') {
1781 /* XXX: not large enough */
1782 tokc
.ld
= (long double)d
;
1788 /* decimal floats */
1790 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1795 while (ch
>= '0' && ch
<= '9') {
1796 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1802 if (ch
== 'e' || ch
== 'E') {
1803 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1807 if (ch
== '-' || ch
== '+') {
1808 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1813 if (ch
< '0' || ch
> '9')
1814 error("exponent digits expected");
1815 while (ch
>= '0' && ch
<= '9') {
1816 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1828 tokc
.f
= strtof(token_buf
, NULL
);
1829 } else if (t
== 'L') {
1832 tokc
.ld
= strtold(token_buf
, NULL
);
1835 tokc
.d
= strtod(token_buf
, NULL
);
1839 unsigned long long n
, n1
;
1842 /* integer number */
1845 if (b
== 10 && *q
== '0') {
1852 /* no need for checks except for base 10 / 8 errors */
1855 } else if (t
>= 'a') {
1857 } else if (t
>= 'A') {
1862 error("invalid digit");
1866 /* detect overflow */
1868 error("integer constant overflow");
1871 /* XXX: not exactly ANSI compliant */
1872 if ((n
& 0xffffffff00000000LL
) != 0) {
1877 } else if (n
> 0x7fffffff) {
1887 error("three 'l' in integer constant");
1890 if (tok
== TOK_CINT
)
1892 else if (tok
== TOK_CUINT
)
1896 } else if (t
== 'U') {
1897 if (tok
== TOK_CINT
)
1899 else if (tok
== TOK_CLLONG
)
1906 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
1914 /* return next token without macro substitution */
1915 void next_nomacro1(void)
1923 while (ch
== '\n') {
1925 while (ch
== ' ' || ch
== '\t')
1928 /* preprocessor command if # at start of line after
1933 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
1951 while (isid(ch
) || isnum(ch
)) {
1952 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1953 error("ident too long");
1958 ts
= tok_alloc(token_buf
, q
- token_buf
);
1960 } else if (isnum(ch
) || ch
== '.') {
1962 } else if (ch
== '\'') {
1970 } else if (ch
== '\"') {
1975 while (ch
!= '\"') {
1978 error("unterminated string");
1979 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1980 error("string too long");
1984 tokc
.ts
= tok_alloc(token_buf
, q
- token_buf
);
1987 q
= "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
1992 if (*q
== tok
&& q
[1] == ch
) {
1995 /* three chars tests */
1996 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2001 } else if (tok
== TOK_DOTS
) {
2003 error("parse error");
2010 /* single char substitutions */
2013 else if (tok
== '>')
2018 /* return next token without macro substitution. Can read input from
2025 tok
= tok_get(¯o_ptr
, &tokc
);
2031 /* substitute args in macro_str and return allocated string */
2032 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2034 int *st
, last_tok
, t
, notfirst
, *str
, len
;
2043 t
= tok_get(¯o_str
, &cval
);
2048 t
= tok_get(¯o_str
, &cval
);
2051 s
= sym_find2(args
, t
);
2053 token_buf
[0] = '\0';
2058 pstrcat(token_buf
, sizeof(token_buf
), " ");
2059 t
= tok_get(&st
, &cval
);
2060 pstrcat(token_buf
, sizeof(token_buf
), get_tok_str(t
, &cval
));
2064 printf("stringize: %s\n", token_buf
);
2067 ts
= tok_alloc(token_buf
, 0);
2069 tok_add2(&str
, &len
, TOK_STR
, &cval
);
2071 tok_add2(&str
, &len
, t
, &cval
);
2073 } else if (t
>= TOK_IDENT
) {
2074 s
= sym_find2(args
, t
);
2077 /* if '##' is present before or after , no arg substitution */
2078 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2080 tok_add(&str
, &len
, *st
++);
2082 macro_subst(&str
, &len
, nested_list
, st
);
2085 tok_add(&str
, &len
, t
);
2088 tok_add2(&str
, &len
, t
, &cval
);
2092 tok_add(&str
, &len
, 0);
2096 /* handle the '##' operator */
2097 int *macro_twosharps(int *macro_str
)
2100 int *macro_str1
, macro_str1_len
, *macro_ptr1
;
2112 while (*macro_ptr
== TOK_TWOSHARPS
) {
2114 macro_ptr1
= macro_ptr
;
2117 t
= tok_get(¯o_ptr
, &cval
);
2118 /* XXX: we handle only most common cases:
2119 ident + ident or ident + number */
2120 if (tok
>= TOK_IDENT
&&
2121 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
2122 p
= get_tok_str(tok
, &tokc
);
2123 pstrcpy(token_buf
, sizeof(token_buf
), p
);
2124 p
= get_tok_str(t
, &cval
);
2125 pstrcat(token_buf
, sizeof(token_buf
), p
);
2126 ts
= tok_alloc(token_buf
, 0);
2127 tok
= ts
->tok
; /* modify current token */
2129 /* cannot merge tokens: skip '##' */
2130 macro_ptr
= macro_ptr1
;
2135 tok_add2(¯o_str1
, ¯o_str1_len
, tok
, &tokc
);
2137 tok_add(¯o_str1
, ¯o_str1_len
, 0);
2143 /* do macro substitution of macro_str and add result to
2144 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2145 substituted. 'nested_list' is the list of all macros we got inside
2146 to avoid recursing. */
2147 void macro_subst(int **tok_str
, int *tok_len
,
2148 Sym
**nested_list
, int *macro_str
)
2150 Sym
*s
, *args
, *sa
, *sa1
;
2151 int *str
, parlevel
, len
, *mstr
, t
, *saved_macro_ptr
;
2152 int mstr_allocated
, *macro_str1
;
2155 saved_macro_ptr
= macro_ptr
;
2156 macro_ptr
= macro_str
;
2159 /* first scan for '##' operator handling */
2160 macro_str1
= macro_twosharps(macro_str
);
2161 macro_ptr
= macro_str1
;
2168 /* special macros */
2169 if (tok
== TOK___LINE__
) {
2170 cval
.i
= file
->line_num
;
2171 tok_add2(tok_str
, tok_len
, TOK_CINT
, &cval
);
2172 } else if (tok
== TOK___FILE__
) {
2173 cval
.ts
= tok_alloc(file
->filename
, 0);
2174 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
2175 } else if (tok
== TOK___DATE__
) {
2176 cval
.ts
= tok_alloc("Jan 1 1970", 0);
2177 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
2178 } else if (tok
== TOK___TIME__
) {
2179 cval
.ts
= tok_alloc("00:00:00", 0);
2180 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
2181 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
2182 /* if symbol is a macro, prepare substitution */
2183 /* if nested substitution, do nothing */
2184 if (sym_find2(*nested_list
, tok
))
2188 if (s
->t
== MACRO_FUNC
) {
2189 /* NOTE: we do not use next_nomacro to avoid eating the
2190 next token. XXX: find better solution */
2194 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
2198 if (t
!= '(') /* no macro subst */
2201 /* argument macro */
2206 /* NOTE: empty args are allowed, except if no args */
2208 /* handle '()' case */
2209 if (!args
&& tok
== ')')
2212 error("macro '%s' used with too many args",
2213 get_tok_str(s
->v
, 0));
2217 while ((parlevel
> 0 ||
2220 sa
->v
== (TOK___VA_ARGS__
| SYM_FIELD
)))) &&
2224 else if (tok
== ')')
2226 tok_add2(&str
, &len
, tok
, &tokc
);
2229 tok_add(&str
, &len
, 0);
2230 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, 0, (int)str
);
2239 error("macro '%s' used with too few args",
2240 get_tok_str(s
->v
, 0));
2242 /* now subst each arg */
2243 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2254 sym_push2(nested_list
, s
->v
, 0, 0);
2255 macro_subst(tok_str
, tok_len
, nested_list
, mstr
);
2256 /* pop nested defined symbol */
2258 *nested_list
= sa1
->prev
;
2264 /* no need to add if reading input stream */
2267 tok_add2(tok_str
, tok_len
, tok
, &tokc
);
2269 /* only replace one macro while parsing input stream */
2273 macro_ptr
= saved_macro_ptr
;
2278 /* return next token with macro substitution */
2284 /* special 'ungettok' case for label parsing */
2292 /* if not reading from macro substituted string, then try to substitute */
2296 macro_subst(&ptr
, &len
, &nested_list
, NULL
);
2298 tok_add(&ptr
, &len
, 0);
2300 macro_ptr_allocated
= ptr
;
2308 /* end of macro string: free it */
2309 free(macro_ptr_allocated
);
2316 printf("token = %s\n", get_tok_str(tok
, tokc
));
2320 void swap(int *p
, int *q
)
2328 void vsetc(int t
, int r
, CValue
*vc
)
2330 if (vtop
>= vstack
+ VSTACK_SIZE
)
2331 error("memory full");
2332 /* cannot let cpu flags if other instruction are generated */
2333 /* XXX: VT_JMP test too ? */
2334 if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
2339 vtop
->r2
= VT_CONST
;
2343 /* push integer constant */
2348 vsetc(VT_INT
, VT_CONST
, &cval
);
2351 void vset(int t
, int r
, int v
)
2368 void vpushv(SValue
*v
)
2370 if (vtop
>= vstack
+ VSTACK_SIZE
)
2371 error("memory full");
2381 /* save r to the memory stack, and mark it as being free */
2382 void save_reg(int r
)
2384 int l
, i
, saved
, t
, size
, align
;
2387 /* modify all stack values */
2390 for(p
=vstack
;p
<=vtop
;p
++) {
2391 i
= p
->r
& VT_VALMASK
;
2392 if ((p
->r
& VT_VALMASK
) == r
||
2393 (p
->r2
& VT_VALMASK
) == r
) {
2394 /* must save value on stack if not already done */
2396 /* store register in the stack */
2398 if ((p
->r
& VT_LVAL
) ||
2399 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
2401 size
= type_size(t
, &align
);
2402 loc
= (loc
- size
) & -align
;
2404 sv
.r
= VT_LOCAL
| VT_LVAL
;
2407 /* XXX: x86 specific: need to pop fp register ST0 if saved */
2409 o(0xd9dd); /* fstp %st(1) */
2411 /* special long long case */
2412 if ((p
->t
& VT_BTYPE
) == VT_LLONG
) {
2419 /* mark that stack entry as being saved on the stack */
2431 /* find a free register of class 'rc'. If none, save one register */
2437 /* find a free register */
2438 for(r
=0;r
<NB_REGS
;r
++) {
2439 if (reg_classes
[r
] & rc
) {
2440 for(p
=vstack
;p
<=vtop
;p
++) {
2441 if ((p
->r
& VT_VALMASK
) == r
||
2442 (p
->r2
& VT_VALMASK
) == r
)
2450 /* no register left : free the first one on the stack (VERY
2451 IMPORTANT to start from the bottom to ensure that we don't
2452 spill registers used in gen_opi()) */
2453 for(p
=vstack
;p
<=vtop
;p
++) {
2454 r
= p
->r
& VT_VALMASK
;
2455 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
2463 void save_regs(void)
2468 for(p
=vstack
;p
<=vtop
;p
++) {
2469 r
= p
->r
& VT_VALMASK
;
2476 /* move register 's' to 'r', and flush previous value of r to memory
2478 void move_reg(int r
, int s
)
2491 /* get address of vtop (vtop MUST BE an lvalue) */
2494 vtop
->r
&= ~VT_LVAL
;
2495 /* tricky: if saved lvalue, then we can go back to lvalue */
2496 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
2497 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
2500 /* generate lvalue bound code */
2503 vtop
->r
&= ~VT_MUSTBOUND
;
2504 /* if lvalue, then use checking code before dereferencing */
2505 if (vtop
->r
& VT_LVAL
) {
2508 gen_bounded_ptr_add1();
2509 gen_bounded_ptr_add2(1);
2514 /* store vtop a register belonging to class 'rc'. lvalues are
2515 converted to values. Cannot be used if cannot be converted to
2516 register value (such as structures). */
2519 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
, data_offset
;
2520 unsigned long long ll
;
2522 /* NOTE: get_reg can modify vstack[] */
2523 if (vtop
->t
& VT_BITFIELD
) {
2524 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2525 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2526 /* remove bit field info to avoid loops */
2527 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2528 /* generate shifts */
2529 vpushi(32 - (bit_pos
+ bit_size
));
2531 vpushi(32 - bit_size
);
2532 /* NOTE: transformed to SHR if unsigned */
2536 if (is_float(vtop
->t
) &&
2537 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2538 /* CPUs usually cannot use float constants, so we store them
2539 generically in data segment */
2540 size
= type_size(vtop
->t
, &align
);
2541 data_offset
= (int)data_section
->data_ptr
;
2542 data_offset
= (data_offset
+ align
- 1) & -align
;
2543 /* XXX: not portable yet */
2546 ((int *)data_offset
)[i
] = vtop
->c
.tab
[i
];
2548 vtop
->c
.ul
= data_offset
;
2549 data_offset
+= size
<< 2;
2550 data_section
->data_ptr
= (unsigned char *)data_offset
;
2552 if (vtop
->r
& VT_MUSTBOUND
)
2555 r
= vtop
->r
& VT_VALMASK
;
2556 /* need to reload if:
2558 - lvalue (need to dereference pointer)
2559 - already a register, but not in the right class */
2560 if (r
>= VT_CONST
||
2561 (vtop
->r
& VT_LVAL
) ||
2562 !(reg_classes
[r
] & rc
) ||
2563 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
2564 !(reg_classes
[vtop
->r2
] & rc
))) {
2566 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
2567 /* two register type load : expand to two words
2569 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2572 vtop
->c
.ui
= ll
; /* first word */
2574 vtop
->r
= r
; /* save register value */
2575 vpushi(ll
>> 32); /* second word */
2576 } else if (r
>= VT_CONST
||
2577 (vtop
->r
& VT_LVAL
)) {
2578 /* load from memory */
2581 vtop
[-1].r
= r
; /* save register value */
2582 /* increment pointer to get second word */
2589 /* move registers */
2592 vtop
[-1].r
= r
; /* save register value */
2593 vtop
->r
= vtop
[-1].r2
;
2595 /* allocate second register */
2602 /* write second register */
2605 /* one register type load */
2614 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2615 void gv2(int rc1
, int rc2
)
2617 /* generate more generic register first */
2623 /* test if reload is needed for first register */
2624 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2634 /* test if reload is needed for first register */
2635 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2641 /* expand long long on stack in two int registers */
2646 u
= vtop
->t
& VT_UNSIGNED
;
2649 vtop
[0].r
= vtop
[-1].r2
;
2650 vtop
[0].r2
= VT_CONST
;
2651 vtop
[-1].r2
= VT_CONST
;
2652 vtop
[0].t
= VT_INT
| u
;
2653 vtop
[-1].t
= VT_INT
| u
;
2656 /* build a long long from two ints */
2659 gv2(RC_INT
, RC_INT
);
2660 vtop
[-1].r2
= vtop
[0].r
;
2665 /* rotate n first stack elements to the bottom */
2672 for(i
=-n
+1;i
!=0;i
++)
2673 vtop
[i
] = vtop
[i
+1];
2677 /* pop stack value */
2680 /* for x86, we need to pop the FP stack */
2681 if ((vtop
->r
& VT_VALMASK
) == REG_ST0
) {
2682 o(0xd9dd); /* fstp %st(1) */
2687 /* convert stack entry to register and duplicate its value in another
2695 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2702 /* stack: H L L1 H1 */
2710 /* duplicate value */
2721 load(r1
, &sv
); /* move r to r1 */
2723 /* duplicates value */
2728 /* generate CPU independent (unsigned) long long operations */
2729 void gen_opl(int op
)
2731 int t
, a
, b
, op1
, c
, i
;
2750 /* call generic long long function */
2751 gfunc_start(&gf
, FUNC_CDECL
);
2758 vtop
->r2
= REG_LRET
;
2771 /* stack: L1 H1 L2 H2 */
2776 vtop
[-2] = vtop
[-3];
2779 /* stack: H1 H2 L1 L2 */
2785 /* stack: H1 H2 L1 L2 ML MH */
2788 /* stack: ML MH H1 H2 L1 L2 */
2792 /* stack: ML MH H1 L2 H2 L1 */
2797 /* stack: ML MH M1 M2 */
2800 } else if (op
== '+' || op
== '-') {
2801 /* XXX: add non carry method too (for MIPS or alpha) */
2807 /* stack: H1 H2 (L1 op L2) */
2810 gen_op(op1
+ 1); /* TOK_xxxC2 */
2813 /* stack: H1 H2 (L1 op L2) */
2816 /* stack: (L1 op L2) H1 H2 */
2818 /* stack: (L1 op L2) (H1 op H2) */
2826 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
) {
2831 /* stack: L H shift */
2833 /* constant: simpler */
2834 /* NOTE: all comments are for SHL. the other cases are
2835 done by swaping words */
2846 if (op
!= TOK_SAR
) {
2876 /* XXX: should provide a faster fallback on x86 ? */
2891 /* compare operations */
2897 /* stack: L1 H1 L2 H2 */
2899 vtop
[-1] = vtop
[-2];
2901 /* stack: L1 L2 H1 H2 */
2904 /* when values are equal, we need to compare low words. since
2905 the jump is inverted, we invert the test too. */
2908 else if (op1
== TOK_GT
)
2910 else if (op1
== TOK_ULT
)
2912 else if (op1
== TOK_UGT
)
2917 if (op1
!= TOK_NE
) {
2921 /* generate non equal test */
2922 /* XXX: NOT PORTABLE yet */
2926 b
= psym(0x850f, 0);
2932 vset(VT_INT
, VT_JMPI
, a
);
2937 /* handle constant optimizations and various machine independant opt */
2938 void gen_opc(int op
)
2945 /* currently, we cannot do computations with forward symbols */
2946 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
2947 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
2951 case '+': v1
->c
.i
+= fc
; break;
2952 case '-': v1
->c
.i
-= fc
; break;
2953 case '&': v1
->c
.i
&= fc
; break;
2954 case '^': v1
->c
.i
^= fc
; break;
2955 case '|': v1
->c
.i
|= fc
; break;
2956 case '*': v1
->c
.i
*= fc
; break;
2963 /* if division by zero, generate explicit division */
2966 error("division by zero in constant");
2970 default: v1
->c
.i
/= fc
; break;
2971 case '%': v1
->c
.i
%= fc
; break;
2972 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
2973 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
2976 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
2977 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
2978 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
2980 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
2981 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
2982 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
2983 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
2984 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
2985 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
2986 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
2987 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
2988 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
2989 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
2991 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
2992 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
2998 /* if commutative ops, put c2 as constant */
2999 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3000 op
== '|' || op
== '*')) {
3005 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3008 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3009 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3015 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3016 /* try to use shifts instead of muls or divs */
3017 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3026 else if (op
== TOK_PDIV
)
3034 /* call low level op generator */
3040 int pointed_size(int t
)
3042 return type_size(pointed_type(t
), &t
);
3046 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3048 char buf1
[256], buf2
[256];
3052 if (!is_compatible_types(t1
, t2
)) {
3053 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3054 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3055 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3060 /* generic gen_op: handles types problems */
3063 int u
, t1
, t2
, bt1
, bt2
, t
;
3067 bt1
= t1
& VT_BTYPE
;
3068 bt2
= t2
& VT_BTYPE
;
3070 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3071 /* at least one operand is a pointer */
3072 /* relationnal op: must be both pointers */
3073 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3074 // check_pointer_types(vtop, vtop - 1);
3075 /* pointers are handled are unsigned */
3076 t
= VT_INT
| VT_UNSIGNED
;
3079 /* if both pointers, then it must be the '-' op */
3080 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3081 (t2
& VT_BTYPE
) == VT_PTR
) {
3083 error("cannot use pointers here");
3084 // check_pointer_types(vtop - 1, vtop);
3085 /* XXX: check that types are compatible */
3086 u
= pointed_size(t1
);
3088 /* set to integer type */
3093 /* exactly one pointer : must be '+' or '-'. */
3094 if (op
!= '-' && op
!= '+')
3095 error("cannot use pointers here");
3096 /* Put pointer as first operand */
3097 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3101 /* XXX: cast to int ? (long long case) */
3102 vpushi(pointed_size(vtop
[-1].t
));
3104 if (do_bounds_check
) {
3105 /* if bounded pointers, we generate a special code to
3112 gen_bounded_ptr_add1();
3113 gen_bounded_ptr_add2(0);
3117 /* put again type if gen_opc() swaped operands */
3120 } else if (is_float(bt1
) || is_float(bt2
)) {
3121 /* compute bigger type and do implicit casts */
3122 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3124 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3129 /* floats can only be used for a few operations */
3130 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3131 (op
< TOK_ULT
|| op
> TOK_GT
))
3132 error("invalid operands for binary operation");
3134 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3135 /* cast to biggest op */
3137 /* convert to unsigned if it does not fit in a long long */
3138 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3139 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
3143 /* integer operations */
3145 /* convert to unsigned if it does not fit in an integer */
3146 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
3147 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3150 /* XXX: currently, some unsigned operations are explicit, so
3151 we modify them here */
3152 if (t
& VT_UNSIGNED
) {
3159 else if (op
== TOK_LT
)
3161 else if (op
== TOK_GT
)
3163 else if (op
== TOK_LE
)
3165 else if (op
== TOK_GE
)
3171 /* special case for shifts and long long: we keep the shift as
3173 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3179 else if ((t
& VT_BTYPE
) == VT_LLONG
)
3183 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3184 /* relationnal op: the result is an int */
3192 /* generic itof for unsigned long long case */
3193 void gen_cvt_itof1(int t
)
3197 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3198 (VT_LLONG
| VT_UNSIGNED
)) {
3200 gfunc_start(&gf
, FUNC_CDECL
);
3203 vpushi((int)&__ulltof
);
3204 else if (t
== VT_DOUBLE
)
3205 vpushi((int)&__ulltod
);
3207 vpushi((int)&__ulltold
);
3216 /* generic ftoi for unsigned long long case */
3217 void gen_cvt_ftoi1(int t
)
3222 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3223 /* not handled natively */
3224 gfunc_start(&gf
, FUNC_CDECL
);
3225 st
= vtop
->t
& VT_BTYPE
;
3228 vpushi((int)&__ftoull
);
3229 else if (st
== VT_DOUBLE
)
3230 vpushi((int)&__dtoull
);
3232 vpushi((int)&__ldtoull
);
3236 vtop
->r2
= REG_LRET
;
3242 /* force char or short cast */
3243 void force_charshort_cast(int t
)
3247 /* XXX: add optimization if lvalue : just change type and offset */
3252 if (t
& VT_UNSIGNED
) {
3253 vpushi((1 << bits
) - 1);
3264 /* cast 'vtop' to 't' type */
3265 void gen_cast(int t
)
3267 int sbt
, dbt
, sf
, df
, c
, st1
, dt1
;
3269 /* special delayed cast for char/short */
3270 /* XXX: in some cases (multiple cascaded casts), it may still
3272 if (vtop
->r
& VT_MUSTCAST
) {
3273 vtop
->r
&= ~VT_MUSTCAST
;
3274 force_charshort_cast(vtop
->t
);
3278 sbt
= vtop
->t
& VT_BTYPE
;
3283 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
3285 /* convert from fp to fp */
3287 /* constant case: we can do it now */
3288 /* XXX: in ISOC, cannot do it if error in convert */
3289 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3290 vtop
->c
.f
= (float)vtop
->c
.d
;
3291 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3292 vtop
->c
.f
= (float)vtop
->c
.ld
;
3293 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3294 vtop
->c
.d
= (double)vtop
->c
.f
;
3295 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3296 vtop
->c
.d
= (double)vtop
->c
.ld
;
3297 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3298 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3299 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3300 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3302 /* non constant case: generate code */
3306 /* convert int to fp */
3307 st1
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3310 case VT_LLONG
| VT_UNSIGNED
:
3312 /* XXX: add const cases for long long */
3314 case VT_INT
| VT_UNSIGNED
:
3316 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3317 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
3318 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
3323 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
3324 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
3325 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
3334 /* convert fp to int */
3335 dt1
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3336 /* we handle char/short/etc... with generic code */
3337 if (dt1
!= (VT_INT
| VT_UNSIGNED
) &&
3338 dt1
!= (VT_LLONG
| VT_UNSIGNED
) &&
3343 case VT_LLONG
| VT_UNSIGNED
:
3345 /* XXX: add const cases for long long */
3347 case VT_INT
| VT_UNSIGNED
:
3349 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3350 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3351 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3357 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3358 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3359 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3367 if (dt1
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dt1
) {
3368 /* additionnal cast for char/short/bool... */
3372 } else if (dbt
== VT_LLONG
) {
3373 /* scalar to long long */
3375 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3376 vtop
->c
.ll
= vtop
->c
.ui
;
3378 vtop
->c
.ll
= vtop
->c
.i
;
3380 /* machine independant conversion */
3382 /* generate high word */
3383 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
)) {
3391 /* patch second register */
3392 vtop
[-1].r2
= vtop
->r
;
3395 } else if (dbt
== VT_BOOL
) {
3396 /* scalar to bool */
3399 } else if (dbt
== VT_BYTE
|| dbt
== VT_SHORT
) {
3400 force_charshort_cast(t
);
3401 } else if (dbt
== VT_INT
) {
3403 if (sbt
== VT_LLONG
) {
3404 /* from long long: just take low order word */
3407 } else if (sbt
== VT_PTR
) {
3409 } else if (vtop
->r
& VT_LVAL
) {
3410 /* if lvalue and single word type, nothing to do (XXX:
3411 maybe incorrect for sizeof op) */
3420 /* return type size. Put alignment at 'a' */
3421 int type_size(int t
, int *a
)
3427 if (bt
== VT_STRUCT
) {
3429 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3430 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
3432 } else if (bt
== VT_PTR
) {
3434 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3435 return type_size(s
->t
, a
) * s
->c
;
3440 } else if (bt
== VT_LDOUBLE
) {
3442 return LDOUBLE_SIZE
;
3443 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3446 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
3449 } else if (bt
== VT_SHORT
) {
3453 /* char, void, function, _Bool */
3459 /* return the pointed type of t */
3460 int pointed_type(int t
)
3463 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3464 return s
->t
| (t
& ~VT_TYPE
);
3467 int mk_pointer(int t
)
3471 sym_push(p
, t
, 0, -1);
3472 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
3475 int is_compatible_types(int t1
, int t2
)
3482 bt1
= t1
& VT_BTYPE
;
3483 bt2
= t2
& VT_BTYPE
;
3484 if (bt1
== VT_PTR
) {
3485 t1
= pointed_type(t1
);
3486 /* if function, then convert implicitely to function pointer */
3487 if (bt2
!= VT_FUNC
) {
3490 t2
= pointed_type(t2
);
3492 /* void matches everything */
3495 if (t1
== VT_VOID
|| t2
== VT_VOID
)
3497 return is_compatible_types(t1
, t2
);
3498 } else if (bt1
== VT_STRUCT
) {
3500 } else if (bt1
== VT_FUNC
) {
3503 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
3504 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
3505 if (!is_compatible_types(s1
->t
, s2
->t
))
3507 /* XXX: not complete */
3508 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
3512 while (s1
!= NULL
) {
3515 if (!is_compatible_types(s1
->t
, s2
->t
))
3524 /* XXX: not complete */
3529 /* print a type. If 'varstr' is not NULL, then the variable is also
3530 printed in the type */
3532 /* XXX: add array and function pointers */
3533 void type_to_str(char *buf
, int buf_size
,
3534 int t
, const char *varstr
)
3544 if (t
& VT_UNSIGNED
)
3545 pstrcat(buf
, buf_size
, "unsigned ");
3575 tstr
= "long double";
3577 pstrcat(buf
, buf_size
, tstr
);
3581 if (bt
== VT_STRUCT
)
3585 pstrcat(buf
, buf_size
, tstr
);
3586 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
3587 if (v
>= SYM_FIRST_ANOM
)
3588 pstrcat(buf
, buf_size
, "<anonymous>");
3590 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
3593 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3594 type_to_str(buf
, buf_size
, s
->t
, varstr
);
3595 pstrcat(buf
, buf_size
, "(");
3597 while (sa
!= NULL
) {
3598 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
3599 pstrcat(buf
, buf_size
, buf1
);
3602 pstrcat(buf
, buf_size
, ", ");
3604 pstrcat(buf
, buf_size
, ")");
3607 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3608 pstrcpy(buf1
, sizeof(buf1
), "*");
3610 pstrcat(buf1
, sizeof(buf1
), varstr
);
3611 type_to_str(buf
, buf_size
, s
->t
, buf1
);
3615 pstrcat(buf
, buf_size
, " ");
3616 pstrcat(buf
, buf_size
, varstr
);
3621 /* verify type compatibility to store vtop in 'dt' type, and generate
3623 void gen_assign_cast(int dt
)
3626 char buf1
[256], buf2
[256];
3628 st
= vtop
->t
; /* source type */
3629 if ((dt
& VT_BTYPE
) == VT_PTR
) {
3630 /* special cases for pointers */
3631 /* a function is implicitely a function pointer */
3632 if ((st
& VT_BTYPE
) == VT_FUNC
) {
3633 if (!is_compatible_types(pointed_type(dt
), st
))
3638 /* '0' can also be a pointer */
3639 if ((st
& VT_BTYPE
) == VT_INT
&&
3640 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
) &&
3644 if (!is_compatible_types(dt
, st
)) {
3646 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3647 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3648 error("cannot cast '%s' to '%s'", buf1
, buf2
);
3654 /* store vtop in lvalue pushed on stack */
3657 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
3661 sbt
= vtop
->t
& VT_BTYPE
;
3662 dbt
= ft
& VT_BTYPE
;
3663 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
3664 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
3665 /* optimize char/short casts */
3666 delayed_cast
= VT_MUSTCAST
;
3667 vtop
->t
= ft
& VT_TYPE
;
3670 gen_assign_cast(ft
& VT_TYPE
);
3673 if (sbt
== VT_STRUCT
) {
3674 /* if structure, only generate pointer */
3675 /* structure assignment : generate memcpy */
3676 /* XXX: optimize if small size */
3679 gfunc_start(&gf
, FUNC_CDECL
);
3681 size
= type_size(vtop
->t
, &align
);
3695 vpushi((int)&memcpy
);
3697 /* leave source on stack */
3698 } else if (ft
& VT_BITFIELD
) {
3699 /* bitfield store handling */
3700 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
3701 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3702 /* remove bit field info to avoid loops */
3703 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3705 /* duplicate destination */
3707 vtop
[-1] = vtop
[-2];
3709 /* mask and shift source */
3710 vpushi((1 << bit_size
) - 1);
3714 /* load destination, mask and or with source */
3716 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
3722 /* bound check case */
3723 if (vtop
[-1].r
& VT_MUSTBOUND
) {
3731 r
= gv(rc
); /* generate value */
3732 /* if lvalue was saved on stack, must read it */
3733 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
3735 t
= get_reg(RC_INT
);
3737 sv
.r
= VT_LOCAL
| VT_LVAL
;
3738 sv
.c
.ul
= vtop
[-1].c
.ul
;
3740 vtop
[-1].r
= t
| VT_LVAL
;
3743 /* two word case handling : store second register at word + 4 */
3744 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
3746 /* convert to int to increment easily */
3753 /* XXX: it works because r2 is spilled last ! */
3754 store(vtop
->r2
, vtop
- 1);
3757 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
3758 vtop
->r
|= delayed_cast
;
3762 /* post defines POST/PRE add. c is the token ++ or -- */
3763 void inc(int post
, int c
)
3766 vdup(); /* save lvalue */
3768 gv_dup(); /* duplicate value */
3773 vpushi(c
- TOK_MID
);
3775 vstore(); /* store value */
3777 vpop(); /* if post op, return saved value */
3780 /* Parse GNUC __attribute__ extension. Currently, the following
3781 extensions are recognized:
3782 - aligned(n) : set data/function alignment.
3783 - section(x) : generate data/code in this section.
3784 - unused : currently ignored, but may be used someday.
3786 void parse_attribute(AttributeDef
*ad
)
3793 while (tok
!= ')') {
3794 if (tok
< TOK_IDENT
)
3795 expect("attribute name");
3800 case TOK___SECTION__
:
3803 expect("section name");
3804 ad
->section
= find_section(tokc
.ts
->str
);
3809 case TOK___ALIGNED__
:
3812 if (n
<= 0 || (n
& (n
- 1)) != 0)
3813 error("alignment must be a positive power of two");
3818 case TOK___UNUSED__
:
3819 /* currently, no need to handle it because tcc does not
3820 track unused objects */
3823 case TOK___NORETURN__
:
3824 /* currently, no need to handle it because tcc does not
3825 track unused objects */
3830 ad
->func_call
= FUNC_CDECL
;
3834 case TOK___STDCALL__
:
3835 ad
->func_call
= FUNC_STDCALL
;
3838 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
3839 /* skip parameters */
3840 /* XXX: skip parenthesis too */
3843 while (tok
!= ')' && tok
!= -1)
3857 /* enum/struct/union declaration */
3858 int struct_decl(int u
)
3860 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
3861 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
3865 a
= tok
; /* save decl type */
3870 /* struct already defined ? return it */
3871 /* XXX: check consistency */
3872 s
= sym_find(v
| SYM_STRUCT
);
3875 error("invalid type");
3881 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
3882 /* put struct/union/enum name in type */
3884 u
= u
| (v
<< VT_STRUCT_SHIFT
);
3889 error("struct/union/enum already defined");
3890 /* cannot be empty */
3897 if (a
== TOK_ENUM
) {
3904 /* enum symbols have static storage */
3905 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
3910 parse_btype(&b
, &ad
);
3915 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
3916 if ((t
& VT_BTYPE
) == VT_FUNC
||
3917 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
3918 error("invalid type for '%s'",
3919 get_tok_str(v
, NULL
));
3925 bit_size
= expr_const();
3926 /* XXX: handle v = 0 case for messages */
3928 error("negative width in bit-field '%s'",
3929 get_tok_str(v
, NULL
));
3930 if (v
&& bit_size
== 0)
3931 error("zero width for bit-field '%s'",
3932 get_tok_str(v
, NULL
));
3934 size
= type_size(t
, &align
);
3936 if (bit_size
>= 0) {
3941 error("bitfields must have scalar type");
3943 if (bit_size
> bsize
) {
3944 error("width of '%s' exceeds its type",
3945 get_tok_str(v
, NULL
));
3946 } else if (bit_size
== bsize
) {
3947 /* no need for bit fields */
3949 } else if (bit_size
== 0) {
3950 /* XXX: what to do if only padding in a
3952 /* zero size: means to pad */
3956 /* we do not have enough room ? */
3957 if ((bit_pos
+ bit_size
) > bsize
)
3960 /* XXX: handle LSB first */
3962 (bit_pos
<< VT_STRUCT_SHIFT
) |
3963 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
3964 bit_pos
+= bit_size
;
3970 /* add new memory data only if starting
3972 if (lbit_pos
== 0) {
3973 if (a
== TOK_STRUCT
) {
3974 c
= (c
+ align
- 1) & -align
;
3982 if (align
> maxalign
)
3986 printf("add field %s offset=%d",
3987 get_tok_str(v
, NULL
), offset
);
3988 if (t
& VT_BITFIELD
) {
3989 printf(" pos=%d size=%d",
3990 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
3991 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
3995 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
3999 if (tok
== ';' || tok
== -1)
4009 /* size for struct/union, dummy for enum */
4010 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4015 /* return 0 if no type declaration. otherwise, return the basic type
4018 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4020 int t
, u
, type_found
;
4023 memset(ad
, 0, sizeof(AttributeDef
));
4034 if ((t
& VT_BTYPE
) != 0)
4035 error("too many basic types");
4049 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4050 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4051 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4052 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4066 if ((t
& VT_BTYPE
) == VT_LONG
) {
4067 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4074 u
= struct_decl(VT_ENUM
);
4078 u
= struct_decl(VT_STRUCT
);
4081 /* type modifiers */
4086 case TOK___SIGNED__
:
4089 case TOK___INLINE__
:
4111 /* GNUC attribute */
4112 case TOK___ATTRIBUTE__
:
4113 parse_attribute(ad
);
4117 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4119 t
|= (s
->t
& ~VT_TYPEDEF
);
4126 /* long is never used as type */
4127 if ((t
& VT_BTYPE
) == VT_LONG
)
4128 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4133 int post_type(int t
, AttributeDef
*ad
)
4135 int p
, n
, pt
, l
, t1
;
4136 Sym
**plast
, *s
, *first
;
4140 /* function declaration */
4145 while (tok
!= ')') {
4146 /* read param name and compute offset */
4147 if (l
!= FUNC_OLD
) {
4148 if (!parse_btype(&pt
, &ad1
)) {
4150 error("invalid type");
4157 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4159 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
4160 if ((pt
& VT_BTYPE
) == VT_VOID
)
4161 error("parameter declared as void");
4168 /* array must be transformed to pointer according to ANSI C */
4170 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
4175 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4182 /* if no parameters, then old type prototype */
4186 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4187 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4188 /* we push a anonymous symbol which will contain the function prototype */
4190 s
= sym_push(p
, t
, ad
->func_call
, l
);
4192 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
4193 } else if (tok
== '[') {
4194 /* array definition */
4200 error("invalid array size");
4203 /* parse next post type */
4204 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4205 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4207 /* we push a anonymous symbol which will contain the array
4210 sym_push(p
, t
, 0, n
);
4211 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
4216 /* Read a type declaration (except basic type), and return the
4217 type. 'td' is a bitmask indicating which kind of type decl is
4218 expected. 't' should contain the basic type. 'ad' is the attribute
4219 definition of the basic type. It can be modified by type_decl(). */
4220 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
4225 while (tok
== '*') {
4227 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
4232 /* recursive type */
4233 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4236 /* XXX: this is not correct to modify 'ad' at this point, but
4237 the syntax is not clear */
4238 if (tok
== TOK___ATTRIBUTE__
)
4239 parse_attribute(ad
);
4240 u
= type_decl(ad
, v
, 0, td
);
4244 /* type identifier */
4245 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
4249 if (!(td
& TYPE_ABSTRACT
))
4250 expect("identifier");
4254 /* append t at the end of u */
4255 t
= post_type(t
, ad
);
4256 if (tok
== TOK___ATTRIBUTE__
)
4257 parse_attribute(ad
);
4262 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
4272 /* define a new external reference to a function 'v' of type 'u' */
4273 Sym
*external_sym(int v
, int u
, int r
)
4278 /* push forward reference */
4279 s
= sym_push1(&global_stack
,
4281 s
->r
= r
| VT_CONST
| VT_FORWARD
;
4288 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
4290 if (vtop
->r
& VT_LVAL
)
4292 vtop
->t
= pointed_type(vtop
->t
);
4293 /* an array is never an lvalue */
4294 if (!(vtop
->t
& VT_ARRAY
)) {
4296 /* if bound checking, the referenced pointer must be checked */
4297 if (do_bounds_check
)
4298 vtop
->r
|= VT_MUSTBOUND
;
4302 /* pass a parameter to a function and do type checking and casting */
4303 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
4306 func_type
= func
->c
;
4307 if (func_type
== FUNC_OLD
||
4308 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
4309 /* default casting : only need to convert float to double */
4310 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
4311 gen_cast(VT_DOUBLE
);
4312 } else if (arg
== NULL
) {
4313 error("too many arguments to function");
4315 gen_assign_cast(arg
->t
);
4322 int n
, t
, ft
, fc
, p
, align
, size
, r
, data_offset
;
4327 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
4330 } else if (tok
== TOK_CUINT
) {
4331 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4333 } else if (tok
== TOK_CLLONG
) {
4334 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
4336 } else if (tok
== TOK_CULLONG
) {
4337 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4339 } else if (tok
== TOK_CFLOAT
) {
4340 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
4342 } else if (tok
== TOK_CDOUBLE
) {
4343 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
4345 } else if (tok
== TOK_CLDOUBLE
) {
4346 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
4348 } else if (tok
== TOK___FUNC__
) {
4349 /* special function name identifier */
4350 /* generate (char *) type */
4351 data_offset
= (int)data_section
->data_ptr
;
4352 vset(mk_pointer(VT_BYTE
), VT_CONST
, data_offset
);
4353 strcpy((void *)data_offset
, funcname
);
4354 data_offset
+= strlen(funcname
) + 1;
4355 data_section
->data_ptr
= (unsigned char *)data_offset
;
4357 } else if (tok
== TOK_LSTR
) {
4360 } else if (tok
== TOK_STR
) {
4361 /* string parsing */
4364 type_size(t
, &align
);
4365 data_offset
= (int)data_section
->data_ptr
;
4366 data_offset
= (data_offset
+ align
- 1) & -align
;
4368 /* we must declare it as an array first to use initializer parser */
4369 t
= VT_ARRAY
| mk_pointer(t
);
4370 decl_initializer(t
, VT_CONST
, data_offset
, 1, 0);
4371 data_offset
+= type_size(t
, &align
);
4372 /* put it as pointer */
4373 vset(t
& ~VT_ARRAY
, VT_CONST
, fc
);
4374 data_section
->data_ptr
= (unsigned char *)data_offset
;
4380 if (parse_btype(&t
, &ad
)) {
4381 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4383 /* check ISOC99 compound literal */
4385 /* data is allocated locally by default */
4390 /* all except arrays are lvalues */
4391 if (!(ft
& VT_ARRAY
))
4393 memset(&ad
, 0, sizeof(AttributeDef
));
4394 fc
= decl_initializer_alloc(ft
, &ad
, r
, 1);
4404 } else if (t
== '*') {
4407 } else if (t
== '&') {
4409 /* functions names must be treated as function pointers,
4410 except for unary '&' and sizeof. Since we consider that
4411 functions are not lvalues, we only have to handle it
4412 there and in function calls. */
4413 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4415 vtop
->t
= mk_pointer(vtop
->t
);
4420 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
4421 vtop
->c
.i
= !vtop
->c
.i
;
4422 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
4423 vtop
->c
.i
= vtop
->c
.i
^ 1;
4425 vset(VT_INT
, VT_JMP
, gtst(1, 0));
4435 if (t
== TOK_SIZEOF
) {
4438 if (parse_btype(&t
, &ad
)) {
4439 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4441 /* XXX: some code could be generated: add eval
4453 vpushi(type_size(t
, &t
));
4455 if (t
== TOK_INC
|| t
== TOK_DEC
) {
4458 } else if (t
== '-') {
4467 error("'%s' undeclared", get_tok_str(t
, NULL
));
4468 /* for simple function calls, we tolerate undeclared
4469 external reference */
4471 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
4472 /* int() function */
4473 s
= external_sym(t
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), 0);
4475 vset(s
->t
, s
->r
, s
->c
);
4476 /* if forward reference, we must point to s */
4477 if (vtop
->r
& VT_FORWARD
)
4482 /* post operations */
4484 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4487 } else if (tok
== '.' || tok
== TOK_ARROW
) {
4489 if (tok
== TOK_ARROW
)
4494 /* expect pointer on structure */
4495 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
4496 expect("struct or union");
4497 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4500 while ((s
= s
->next
) != NULL
) {
4505 error("field not found");
4506 /* add field offset to pointer */
4507 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
4510 /* change type to field type, and set to lvalue */
4512 /* an array is never an lvalue */
4513 if (!(vtop
->t
& VT_ARRAY
))
4516 } else if (tok
== '[') {
4522 } else if (tok
== '(') {
4527 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
4528 /* pointer test (no array accepted) */
4529 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4530 vtop
->t
= pointed_type(vtop
->t
);
4531 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4535 expect("function pointer");
4538 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4540 /* get return type */
4541 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
4542 save_regs(); /* save used temporary registers */
4543 gfunc_start(&gf
, s
->r
);
4545 sa
= s
->next
; /* first parameter */
4546 #ifdef INVERT_FUNC_PARAMS
4548 int *str
, len
, parlevel
, *saved_macro_ptr
;
4551 /* read each argument and store it on a stack */
4552 /* XXX: merge it with macro args ? */
4554 while (tok
!= ')') {
4558 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
4562 else if (tok
== ')')
4564 tok_add2(&str
, &len
, tok
, &tokc
);
4567 tok_add(&str
, &len
, -1); /* end of file added */
4568 tok_add(&str
, &len
, 0);
4569 s1
= sym_push2(&args
, 0, 0, (int)str
);
4570 s1
->next
= sa
; /* add reference to argument */
4580 /* now generate code in reverse order by reading the stack */
4581 saved_macro_ptr
= macro_ptr
;
4583 macro_ptr
= (int *)args
->c
;
4587 expect("',' or ')'");
4588 gfunc_param_typed(&gf
, s
, args
->next
);
4590 free((int *)args
->c
);
4594 macro_ptr
= saved_macro_ptr
;
4599 /* compute first implicit argument if a structure is returned */
4600 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
4601 /* get some space for the returned structure */
4602 size
= type_size(s
->t
, &align
);
4603 loc
= (loc
- size
) & -align
;
4605 ret
.r
= VT_LOCAL
| VT_LVAL
;
4606 /* pass it as 'int' to avoid structure arg passing
4608 vset(VT_INT
, VT_LOCAL
, loc
);
4614 /* return in register */
4615 if (is_float(ret
.t
)) {
4618 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
4624 #ifndef INVERT_FUNC_PARAMS
4625 while (tok
!= ')') {
4627 gfunc_param_typed(&gf
, s
, sa
);
4635 error("too few arguments to function");
4639 vsetc(ret
.t
, ret
.r
, &ret
.c
);
4653 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
4654 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
4655 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
4678 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
4679 (l
== 1 && (tok
== '+' || tok
== '-')) ||
4680 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
4681 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
4682 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
4683 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
4684 (l
== 5 && tok
== '&') ||
4685 (l
== 6 && tok
== '^') ||
4686 (l
== 7 && tok
== '|') ||
4687 (l
== 8 && tok
== TOK_LAND
) ||
4688 (l
== 9 && tok
== TOK_LOR
)) {
4697 /* only used if non constant */
4705 if (tok
!= TOK_LAND
) {
4708 vset(VT_INT
, VT_JMPI
, t
);
4725 if (tok
!= TOK_LOR
) {
4728 vset(VT_INT
, VT_JMP
, t
);
4738 /* XXX: better constant handling */
4741 int t
, u
, c
, r1
, r2
, rc
;
4763 /* XXX: long long handling ? */
4765 if (is_float(vtop
->t
))
4768 vtop
--; /* no vpop so that FP stack is not flushed */
4793 /* parse a constant expression and return value in vtop */
4794 void expr_const1(void)
4800 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
4805 /* parse an integer constant and return its value */
4806 int expr_const(void)
4815 /* return the label token if current token is a label, otherwise
4822 /* fast test first */
4823 if (tok
< TOK_UIDENT
)
4825 /* no need to save tokc since we expect an identifier */
4833 /* XXX: may not work in all cases (macros ?) */
4842 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
4847 /* generate line number info */
4849 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
4850 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
4852 last_line_num
= file
->line_num
;
4855 if (tok
== TOK_IF
) {
4862 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4864 if (c
== TOK_ELSE
) {
4868 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4869 gsym(d
); /* patch else jmp */
4872 } else if (tok
== TOK_WHILE
) {
4880 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
4881 oad(0xe9, d
- ind
- 5); /* jmp */
4884 } else if (tok
== '{') {
4887 s
= local_stack
.top
;
4888 while (tok
!= '}') {
4891 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4893 /* pop locally defined symbols */
4894 sym_pop(&local_stack
, s
);
4896 } else if (tok
== TOK_RETURN
) {
4900 gen_assign_cast(func_vt
);
4901 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
4902 /* if returning structure, must copy it to implicit
4903 first pointer arg location */
4904 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
4907 /* copy structure value to pointer */
4909 } else if (is_float(func_vt
)) {
4914 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4917 rsym
= gjmp(rsym
); /* jmp */
4918 } else if (tok
== TOK_BREAK
) {
4921 error("cannot break");
4922 *bsym
= gjmp(*bsym
);
4925 } else if (tok
== TOK_CONTINUE
) {
4928 error("cannot continue");
4929 *csym
= gjmp(*csym
);
4932 } else if (tok
== TOK_FOR
) {
4955 oad(0xe9, d
- ind
- 5); /* jmp */
4959 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
4960 oad(0xe9, c
- ind
- 5); /* jmp */
4964 if (tok
== TOK_DO
) {
4969 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
4980 if (tok
== TOK_SWITCH
) {
4984 /* XXX: other types than integer */
4985 case_reg
= gv(RC_INT
);
4989 b
= gjmp(0); /* jump to first case */
4991 block(&a
, csym
, &b
, &c
, case_reg
);
4992 /* if no default, jmp after switch */
5000 if (tok
== TOK_CASE
) {
5007 if (gnu_ext
&& tok
== TOK_DOTS
) {
5011 warning("empty case range");
5013 /* since a case is like a label, we must skip it with a jmp */
5016 vset(VT_INT
, case_reg
, 0);
5020 *case_sym
= gtst(1, 0);
5023 *case_sym
= gtst(1, 0);
5024 vset(VT_INT
, case_reg
, 0);
5027 *case_sym
= gtst(1, *case_sym
);
5031 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5033 if (tok
== TOK_DEFAULT
) {
5039 error("too many 'default'");
5041 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5043 if (tok
== TOK_GOTO
) {
5045 s
= sym_find1(&label_stack
, tok
);
5046 /* put forward definition if needed */
5048 s
= sym_push1(&label_stack
, tok
, VT_FORWARD
, 0);
5049 /* label already defined */
5050 if (s
->t
& VT_FORWARD
)
5051 s
->c
= gjmp(s
->c
); /* jmp xxx */
5053 oad(0xe9, s
->c
- ind
- 5); /* jmp xxx */
5060 s
= sym_find1(&label_stack
, b
);
5062 if (!(s
->t
& VT_FORWARD
))
5063 error("multiple defined label");
5068 sym_push1(&label_stack
, b
, 0, ind
);
5070 /* we accept this, but it is a mistake */
5072 warning("deprecated use of label at end of compound statement");
5074 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5076 /* expression case */
5086 /* t is the array or struct type. c is the array or struct
5087 address. cur_index/cur_field is the pointer to the current
5088 value. 'size_only' is true if only size info is needed (only used
5090 void decl_designator(int t
, int r
, int c
,
5091 int *cur_index
, Sym
**cur_field
,
5095 int notfirst
, index
, align
, l
;
5098 if (gnu_ext
&& (l
= is_label()) != 0)
5101 while (tok
== '[' || tok
== '.') {
5103 if (!(t
& VT_ARRAY
))
5104 expect("array type");
5105 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5107 index
= expr_const();
5108 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5109 expect("invalid index");
5113 t
= pointed_type(t
);
5114 c
+= index
* type_size(t
, &align
);
5120 if ((t
& VT_BTYPE
) != VT_STRUCT
)
5121 expect("struct/union type");
5122 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5134 t
= f
->t
| (t
& ~VT_TYPE
);
5149 t
= pointed_type(t
);
5150 c
+= index
* type_size(t
, &align
);
5154 error("too many field init");
5155 t
= f
->t
| (t
& ~VT_TYPE
);
5159 decl_initializer(t
, r
, c
, 0, size_only
);
5163 #define EXPR_CONST 1
5166 /* store a value or an expression directly in global data or in local array */
5167 void init_putv(int t
, int r
, int c
,
5168 int v
, int expr_type
)
5170 int saved_global_expr
, bt
;
5177 /* compound literals must be allocated globally in this case */
5178 saved_global_expr
= global_expr
;
5181 global_expr
= saved_global_expr
;
5188 if ((r
& VT_VALMASK
) == VT_CONST
) {
5189 /* XXX: not portable */
5194 *(char *)c
= vtop
->c
.i
;
5197 *(short *)c
= vtop
->c
.i
;
5200 *(double *)c
= vtop
->c
.d
;
5203 *(long double *)c
= vtop
->c
.ld
;
5206 *(long long *)c
= vtop
->c
.ll
;
5209 *(int *)c
= vtop
->c
.i
;
5221 /* put zeros for variable based init */
5222 void init_putz(int t
, int r
, int c
, int size
)
5226 if ((r
& VT_VALMASK
) == VT_CONST
) {
5227 /* nothing to do because globals are already set to zero */
5229 gfunc_start(&gf
, FUNC_CDECL
);
5234 vset(VT_INT
, VT_LOCAL
, c
);
5236 vpushi((int)&memset
);
5241 /* 't' contains the type and storage info. c is the address of the
5242 object. 'first' is true if array '{' must be read (multi dimension
5243 implicit array init handling). 'size_only' is true if size only
5244 evaluation is wanted (only for arrays). */
5245 void decl_initializer(int t
, int r
, int c
, int first
, int size_only
)
5247 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
5248 int t1
, size1
, align1
, expr_type
;
5253 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5256 t1
= pointed_type(t
);
5257 size1
= type_size(t1
, &align1
);
5260 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5266 /* only parse strings here if correct type (otherwise: handle
5267 them as ((w)char *) expressions */
5268 if ((tok
== TOK_LSTR
&&
5269 (t1
& VT_BTYPE
) == VT_INT
) ||
5271 (t1
& VT_BTYPE
) == VT_BYTE
)) {
5272 /* XXX: move multiple string parsing in parser ? */
5273 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5275 /* compute maximum number of chars wanted */
5277 if (n
>= 0 && nb
> (n
- array_length
))
5278 nb
= n
- array_length
;
5281 warning("initializer-string for array is too long");
5283 init_putv(t1
, r
, c
+ (array_length
+ i
) * size1
,
5284 ts
->str
[i
], EXPR_VAL
);
5290 /* only add trailing zero if enough storage (no
5291 warning in this case since it is standard) */
5292 if (n
< 0 || array_length
< n
) {
5294 init_putv(t1
, r
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5300 while (tok
!= '}') {
5301 decl_designator(t
, r
, c
, &index
, NULL
, size_only
);
5302 if (n
>= 0 && index
>= n
)
5303 error("index too large");
5304 /* must put zero in holes (note that doing it that way
5305 ensures that it even works with designators) */
5306 if (!size_only
&& array_length
< index
) {
5307 init_putz(t1
, r
, c
+ array_length
* size1
,
5308 (index
- array_length
) * size1
);
5311 if (index
> array_length
)
5312 array_length
= index
;
5313 /* special test for multi dimensional arrays (may not
5314 be strictly correct if designators are used at the
5316 if (index
>= n
&& no_oblock
)
5325 /* put zeros at the end */
5326 if (!size_only
&& n
>= 0 && array_length
< n
) {
5327 init_putz(t1
, r
, c
+ array_length
* size1
,
5328 (n
- array_length
) * size1
);
5330 /* patch type size if needed */
5332 s
->c
= array_length
;
5333 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
5334 /* XXX: union needs only one init */
5336 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5341 while (tok
!= '}') {
5342 decl_designator(t
, r
, c
, NULL
, &f
, size_only
);
5343 /* fill with zero between fields */
5345 if (!size_only
&& array_length
< index
) {
5346 init_putz(t
, r
, c
+ array_length
,
5347 index
- array_length
);
5349 index
= index
+ type_size(f
->t
, &align1
);
5350 if (index
> array_length
)
5351 array_length
= index
;
5357 /* put zeros at the end */
5358 if (!size_only
&& array_length
< n
) {
5359 init_putz(t
, r
, c
+ array_length
,
5363 } else if (tok
== '{') {
5365 decl_initializer(t
, r
, c
, first
, size_only
);
5367 } else if (size_only
) {
5368 /* just skip expression */
5370 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
5374 else if (tok
== ')')
5379 /* currently, we always use constant expression for globals
5380 (may change for scripting case) */
5381 expr_type
= EXPR_CONST
;
5382 if ((r
& VT_VALMASK
) == VT_LOCAL
)
5383 expr_type
= EXPR_ANY
;
5384 init_putv(t
, r
, c
, 0, expr_type
);
5388 /* parse an initializer for type 't' if 'has_init' is true, and
5389 allocate space in local or global data space ('r' is either
5390 VT_LOCAL or VT_CONST). The allocated address in returned */
5391 int decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
)
5393 int size
, align
, addr
, tok1
, data_offset
;
5394 int *init_str
, init_len
, level
, *saved_macro_ptr
;
5397 size
= type_size(t
, &align
);
5398 /* If unknown size, we must evaluate it before
5399 evaluating initializers because
5400 initializers can generate global data too
5401 (e.g. string pointers or ISOC99 compound
5402 literals). It also simplifies local
5403 initializers handling */
5406 saved_macro_ptr
= NULL
; /* avoid warning */
5410 error("unknown type size");
5411 /* get all init string */
5413 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5415 error("unexpected end of file in initializer");
5416 tok_add2(&init_str
, &init_len
, tok
, &tokc
);
5419 else if (tok
== '}') {
5427 tok_add(&init_str
, &init_len
, -1);
5428 tok_add(&init_str
, &init_len
, 0);
5431 saved_macro_ptr
= macro_ptr
;
5432 macro_ptr
= init_str
;
5434 decl_initializer(t
, r
, 0, 1, 1);
5435 /* prepare second initializer parsing */
5436 macro_ptr
= init_str
;
5439 /* if still unknown size, error */
5440 size
= type_size(t
, &align
);
5442 error("unknown type size");
5444 /* take into account specified alignment if bigger */
5445 if (ad
->aligned
> align
)
5446 align
= ad
->aligned
;
5447 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5448 if (do_bounds_check
&& (t
& VT_ARRAY
))
5450 loc
= (loc
- size
) & -align
;
5452 /* handles bounds */
5453 /* XXX: currently, since we do only one pass, we cannot track
5454 '&' operators, so we add only arrays */
5455 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
5457 /* add padding between regions */
5459 /* then add local bound info */
5460 bounds_ptr
= (int *)lbounds_section
->data_ptr
;
5461 *bounds_ptr
++ = addr
;
5462 *bounds_ptr
++ = size
;
5463 lbounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5466 /* compute section */
5474 data_offset
= (int)sec
->data_ptr
;
5475 data_offset
= (data_offset
+ align
- 1) & -align
;
5477 /* very important to increment global
5478 pointer at this time because
5479 initializers themselves can create new
5481 data_offset
+= size
;
5482 /* handles bounds */
5483 if (do_bounds_check
) {
5485 /* first, we need to add at least one byte between each region */
5487 /* then add global bound info */
5488 bounds_ptr
= (int *)bounds_section
->data_ptr
;
5489 *bounds_ptr
++ = addr
;
5490 *bounds_ptr
++ = size
;
5491 bounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5493 sec
->data_ptr
= (unsigned char *)data_offset
;
5496 decl_initializer(t
, r
, addr
, 1, 0);
5497 /* restore parse state if needed */
5500 macro_ptr
= saved_macro_ptr
;
5507 void put_func_debug(int t
)
5516 put_elf_sym(symtab_section
, ind
, 0,
5517 ELF32_ST_INFO(bind
, STT_FUNC
), 0,
5518 cur_text_section
->sh_num
, funcname
);
5520 /* XXX: we put here a dummy type */
5521 snprintf(buf
, sizeof(buf
), "%s:%c1",
5522 funcname
, t
& VT_STATIC
? 'f' : 'F');
5523 put_stabs(buf
, N_FUN
, 0, file
->line_num
, ind
);
5529 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5532 int t
, b
, v
, addr
, has_init
, r
;
5537 if (!parse_btype(&b
, &ad
)) {
5538 /* skip redundant ';' */
5539 /* XXX: find more elegant solution */
5544 /* special test for old K&R protos without explicit int
5545 type. Only accepted when defining global data */
5546 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
5550 if (((b
& VT_BTYPE
) == VT_ENUM
||
5551 (b
& VT_BTYPE
) == VT_STRUCT
) &&
5553 /* we accept no variable after */
5557 while (1) { /* iterate thru each declaration */
5558 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
5562 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
5563 printf("type = '%s'\n", buf
);
5568 error("cannot use local functions");
5570 expect("function definition");
5571 /* compute text section */
5572 cur_text_section
= ad
.section
;
5573 if (!cur_text_section
)
5574 cur_text_section
= text_section
;
5575 ind
= (int)cur_text_section
->data_ptr
;
5576 /* patch forward references */
5577 if ((sym
= sym_find(v
)) && (sym
->r
& VT_FORWARD
)) {
5578 greloc_patch(sym
, ind
);
5581 /* put function address */
5582 sym
= sym_push1(&global_stack
, v
, t
, ind
);
5585 funcname
= get_tok_str(v
, NULL
);
5586 /* put debug symbol */
5589 /* push a dummy symbol to enable local sym storage */
5590 sym_push1(&local_stack
, 0, 0, 0);
5594 block(NULL
, NULL
, NULL
, NULL
, 0);
5597 cur_text_section
->data_ptr
= (unsigned char *)ind
;
5598 sym_pop(&label_stack
, NULL
); /* reset label stack */
5599 sym_pop(&local_stack
, NULL
); /* reset local stack */
5600 /* end of function */
5602 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
5604 funcname
= ""; /* for safety */
5605 func_vt
= VT_VOID
; /* for safety */
5606 ind
= 0; /* for safety */
5609 if (b
& VT_TYPEDEF
) {
5610 /* save typedefed type */
5611 /* XXX: test storage specifiers ? */
5612 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
5613 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
5614 /* external function definition */
5615 external_sym(v
, t
, 0);
5617 /* not lvalue if array */
5619 if (!(t
& VT_ARRAY
))
5621 if (b
& VT_EXTERN
) {
5622 /* external variable */
5623 external_sym(v
, t
, r
);
5629 has_init
= (tok
== '=');
5632 addr
= decl_initializer_alloc(t
, &ad
, r
,
5634 if (l
== VT_CONST
) {
5635 /* global scope: see if already defined */
5639 if (!is_compatible_types(sym
->t
, t
))
5640 error("incompatible types for redefinition of '%s'",
5641 get_tok_str(v
, NULL
));
5642 if (!(sym
->r
& VT_FORWARD
))
5643 error("redefinition of '%s'", get_tok_str(v
, NULL
));
5644 greloc_patch(sym
, addr
);
5647 sym_push(v
, t
, r
, addr
);
5661 /* put all global symbols in the extern stack and do all the
5662 resolving which can be done without using external symbols from DLLs */
5663 /* XXX: could try to verify types, but would not to save them in
5665 void resolve_global_syms(void)
5667 Sym
*s
, *s1
, *ext_sym
;
5670 s
= global_stack
.top
;
5673 /* do not save static or typedefed symbols or types */
5674 if (!(s
->t
& (VT_STATIC
| VT_TYPEDEF
)) &&
5675 !(s
->v
& (SYM_FIELD
| SYM_STRUCT
)) &&
5676 (s
->v
< SYM_FIRST_ANOM
)) {
5677 ext_sym
= sym_find1(&extern_stack
, s
->v
);
5679 /* if the symbol do not exist, we simply save it */
5680 ext_sym
= sym_push1(&extern_stack
, s
->v
, s
->t
, s
->c
);
5682 } else if (ext_sym
->r
& VT_FORWARD
) {
5683 /* external symbol already exists, but only as forward
5685 if (!(s
->r
& VT_FORWARD
)) {
5686 /* s is not forward, so we can relocate all symbols */
5687 greloc_patch(ext_sym
, s
->c
);
5689 /* the two symbols are forward: merge them */
5690 p
= (Reloc
**)&ext_sym
->c
;
5696 /* external symbol already exists and is defined :
5697 patch all references to it */
5698 if (!(s
->r
& VT_FORWARD
))
5699 error("'%s' defined twice", get_tok_str(s
->v
, NULL
));
5700 greloc_patch(s
, ext_sym
->c
);
5707 /* compile a C file. Return non zero if errors. */
5708 int tcc_compile_file(const char *filename1
)
5715 file
= tcc_open(filename1
);
5717 error("file '%s' not found", filename1
);
5718 include_stack_ptr
= include_stack
;
5719 ifdef_stack_ptr
= ifdef_stack
;
5722 anon_sym
= SYM_FIRST_ANOM
;
5724 /* file info: full path + filename */
5726 getcwd(buf
, sizeof(buf
));
5727 pstrcat(buf
, sizeof(buf
), "/");
5728 put_stabs(buf
, N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
5729 put_stabs(file
->filename
, N_SO
, 0, 0,
5730 (unsigned long)text_section
->data_ptr
);
5732 /* define common 'char *' type because it is often used internally
5733 for arrays and struct dereference */
5734 char_pointer_type
= mk_pointer(VT_BYTE
);
5736 define_start
= define_stack
.top
;
5738 ch
= '\n'; /* needed to parse correctly first preprocessor command */
5742 expect("declaration");
5745 /* end of translation unit info */
5747 put_stabn(N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
5750 /* reset define stack, but leave -Dsymbols (may be incorrect if
5751 they are undefined) */
5752 sym_pop(&define_stack
, define_start
);
5754 resolve_global_syms();
5756 sym_pop(&global_stack
, NULL
);
5761 /* define a symbol. A value can also be provided with the '=' operator */
5762 /* XXX: currently only handles integers and string defines. should use
5763 tcc parser, but would need a custom 'FILE *' */
5764 void define_symbol(const char *sym
)
5767 BufferedFile bf1
, *bf
= &bf1
;
5769 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
5770 p
= strchr(bf
->buffer
, '=');
5773 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " 1");
5778 /* init file structure */
5780 bf
->buf_ptr
= bf
->buffer
;
5781 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
5782 bf
->filename
[0] = '\0';
5786 include_stack_ptr
= include_stack
;
5788 /* parse with define parser */
5790 ch
= '\n'; /* needed to parse correctly first preprocessor command */
5796 void undef_symbol(const char *sym
)
5800 ts
= tok_alloc(sym
, 0);
5801 s
= sym_find1(&define_stack
, tok
);
5802 /* undefine symbol by putting an invalid name */
5804 sym_undef(&define_stack
, s
);
5807 /* open a dynamic library so that its symbol are available for
5808 compiled programs */
5809 void open_dll(char *libname
)
5814 snprintf(buf
, sizeof(buf
), "lib%s.so", libname
);
5815 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
5817 error((char *)dlerror());
5820 static void *resolve_sym(const char *sym
)
5823 if (do_bounds_check
) {
5824 ptr
= bound_resolve_sym(sym
);
5828 return dlsym(NULL
, sym
);
5831 void resolve_extern_syms(void)
5837 s
= extern_stack
.top
;
5840 if (s
->r
& VT_FORWARD
) {
5841 /* if there is at least one relocation to do, then find it
5844 str
= get_tok_str(s
->v
, NULL
);
5845 addr
= (int)resolve_sym(str
);
5847 error("unresolved external reference '%s'", str
);
5848 greloc_patch(s
, addr
);
5855 static int put_elf_str(Section
*s
, const char *sym
)
5858 offset
= s
->data_ptr
- s
->data
;
5868 static void put_elf_sym(Section
*s
,
5869 unsigned long value
, unsigned long size
,
5870 int info
, int other
, int shndx
, const char *name
)
5875 sym
= (Elf32_Sym
*)s
->data_ptr
;
5877 name_offset
= put_elf_str(s
->link
, name
);
5880 sym
->st_name
= name_offset
;
5881 sym
->st_value
= value
;
5882 sym
->st_size
= size
;
5883 sym
->st_info
= info
;
5884 sym
->st_other
= other
;
5885 sym
->st_shndx
= shndx
;
5886 s
->data_ptr
+= sizeof(Elf32_Sym
);
5889 /* put stab debug information */
5892 unsigned long n_strx
; /* index into string table of name */
5893 unsigned char n_type
; /* type of symbol */
5894 unsigned char n_other
; /* misc info (usually empty) */
5895 unsigned short n_desc
; /* description field */
5896 unsigned long n_value
; /* value of symbol */
5899 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
)
5903 sym
= (Stab_Sym
*)stab_section
->data_ptr
;
5905 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
5910 sym
->n_other
= other
;
5912 sym
->n_value
= value
;
5914 stab_section
->data_ptr
+= sizeof(Stab_Sym
);
5917 static void put_stabn(int type
, int other
, int desc
, int value
)
5919 put_stabs(NULL
, type
, other
, desc
, value
);
5922 static void put_stabd(int type
, int other
, int desc
)
5924 put_stabs(NULL
, type
, other
, desc
, 0);
5927 /* output an ELF file (currently, only for testing) */
5928 /* XXX: generate dynamic reloc info + DLL tables */
5929 /* XXX: generate startup code */
5930 /* XXX: better program header generation */
5931 /* XXX: handle realloc'ed sections (instead of mmaping them) */
5932 void build_exe(char *filename
)
5936 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
;
5937 Section
*sec
, *strsec
;
5938 Elf32_Shdr
*shdr
, *sh
;
5939 Elf32_Phdr
*phdr
, *ph
;
5941 memset(&ehdr
, 0, sizeof(ehdr
));
5943 /* we add a section for symbols */
5944 strsec
= new_section(".shstrtab", SHT_STRTAB
, 0);
5945 put_elf_str(strsec
, "");
5947 /* count number of sections and compute number of program segments */
5948 shnum
= 1; /* section index zero is reserved */
5950 for(sec
= first_section
; sec
!= NULL
; sec
= sec
->next
) {
5952 if (sec
->sh_flags
& SHF_ALLOC
)
5955 /* allocate section headers */
5956 shdr
= malloc(shnum
* sizeof(Elf32_Shdr
));
5958 error("memory full");
5959 memset(shdr
, 0, shnum
* sizeof(Elf32_Shdr
));
5960 /* allocate program segment headers */
5961 phdr
= malloc(phnum
* sizeof(Elf32_Phdr
));
5963 error("memory full");
5964 memset(phdr
, 0, phnum
* sizeof(Elf32_Phdr
));
5966 /* XXX: find correct load order */
5967 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
5968 for(sec
= first_section
, i
= 1; sec
!= NULL
; sec
= sec
->next
, i
++) {
5970 sh
->sh_name
= put_elf_str(strsec
, sec
->name
);
5971 sh
->sh_type
= sec
->sh_type
;
5972 sh
->sh_flags
= sec
->sh_flags
;
5973 sh
->sh_entsize
= sec
->sh_entsize
;
5975 sh
->sh_link
= sec
->link
->sh_num
;
5976 if (sh
->sh_type
== SHT_STRTAB
) {
5977 sh
->sh_addralign
= 1;
5978 } else if (sh
->sh_type
== SHT_SYMTAB
||
5979 (sh
->sh_flags
& SHF_ALLOC
) == 0) {
5980 sh
->sh_addralign
= 4;
5982 sh
->sh_addr
= (Elf32_Word
)sec
->data
;
5983 sh
->sh_addralign
= 4096;
5985 sh
->sh_size
= (Elf32_Word
)sec
->data_ptr
- (Elf32_Word
)sec
->data
;
5986 /* align to section start */
5987 file_offset
= (file_offset
+ sh
->sh_addralign
- 1) &
5988 ~(sh
->sh_addralign
- 1);
5989 sh
->sh_offset
= file_offset
;
5990 file_offset
+= sh
->sh_size
;
5992 /* build program headers (simplistic - not fully correct) */
5994 for(i
=1;i
<shnum
;i
++) {
5996 if (sh
->sh_type
== SHT_PROGBITS
&&
5997 (sh
->sh_flags
& SHF_ALLOC
) != 0) {
5999 ph
->p_type
= PT_LOAD
;
6000 ph
->p_offset
= sh
->sh_offset
;
6001 ph
->p_vaddr
= sh
->sh_addr
;
6002 ph
->p_paddr
= ph
->p_vaddr
;
6003 ph
->p_filesz
= sh
->sh_size
;
6004 ph
->p_memsz
= sh
->sh_size
;
6006 if (sh
->sh_flags
& SHF_WRITE
)
6007 ph
->p_flags
|= PF_W
;
6008 if (sh
->sh_flags
& SHF_EXECINSTR
)
6009 ph
->p_flags
|= PF_X
;
6010 ph
->p_align
= sh
->sh_addralign
;
6015 file_offset
= (file_offset
+ 3) & -4;
6018 ehdr
.e_ident
[0] = ELFMAG0
;
6019 ehdr
.e_ident
[1] = ELFMAG1
;
6020 ehdr
.e_ident
[2] = ELFMAG2
;
6021 ehdr
.e_ident
[3] = ELFMAG3
;
6022 ehdr
.e_ident
[4] = ELFCLASS32
;
6023 ehdr
.e_ident
[5] = ELFDATA2LSB
;
6024 ehdr
.e_ident
[6] = EV_CURRENT
;
6025 ehdr
.e_type
= ET_EXEC
;
6026 ehdr
.e_machine
= EM_386
;
6027 ehdr
.e_version
= EV_CURRENT
;
6028 ehdr
.e_entry
= 0; /* XXX: patch it */
6029 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
6030 ehdr
.e_shoff
= file_offset
;
6031 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
6032 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
6033 ehdr
.e_phnum
= phnum
;
6034 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
6035 ehdr
.e_shnum
= shnum
;
6036 ehdr
.e_shstrndx
= shnum
- 1;
6038 /* write elf file */
6039 f
= fopen(filename
, "w");
6041 error("could not write '%s'", filename
);
6042 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
6043 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
6044 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
6045 for(sec
= first_section
, i
= 1; sec
!= NULL
; sec
= sec
->next
, i
++) {
6047 while (offset
< sh
->sh_offset
) {
6051 size
= sec
->data_ptr
- sec
->data
;
6052 fwrite(sec
->data
, 1, size
, f
);
6055 while (offset
< ehdr
.e_shoff
) {
6059 fwrite(shdr
, 1, shnum
* sizeof(Elf32_Shdr
), f
);
6063 /* print the position in the source file of PC value 'pc' by reading
6064 the stabs debug information */
6065 static void rt_printline(unsigned long wanted_pc
)
6067 Stab_Sym
*sym
, *sym_end
;
6068 char func_name
[128];
6069 unsigned long func_addr
, last_pc
, pc
;
6070 const char *incl_files
[INCLUDE_STACK_SIZE
];
6071 int incl_index
, len
, last_line_num
, i
;
6072 const char *str
, *p
;
6074 func_name
[0] = '\0';
6077 last_pc
= 0xffffffff;
6079 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
6080 sym_end
= (Stab_Sym
*)stab_section
->data_ptr
;
6081 while (sym
< sym_end
) {
6082 switch(sym
->n_type
) {
6083 /* function start or end */
6085 if (sym
->n_strx
== 0) {
6086 func_name
[0] = '\0';
6089 str
= stabstr_section
->data
+ sym
->n_strx
;
6090 p
= strchr(str
, ':');
6092 pstrcpy(func_name
, sizeof(func_name
), str
);
6095 if (len
> sizeof(func_name
) - 1)
6096 len
= sizeof(func_name
) - 1;
6097 memcpy(func_name
, str
, len
);
6098 func_name
[len
] = '\0';
6100 func_addr
= sym
->n_value
;
6103 /* line number info */
6105 pc
= sym
->n_value
+ func_addr
;
6106 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
6109 last_line_num
= sym
->n_desc
;
6113 str
= stabstr_section
->data
+ sym
->n_strx
;
6115 if (incl_index
< INCLUDE_STACK_SIZE
) {
6116 incl_files
[incl_index
++] = str
;
6124 if (sym
->n_strx
== 0) {
6125 incl_index
= 0; /* end of translation unit */
6127 str
= stabstr_section
->data
+ sym
->n_strx
;
6128 /* do not add path */
6130 if (len
> 0 && str
[len
- 1] != '/')
6137 /* did not find line number info: */
6138 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
6141 for(i
= 0; i
< incl_index
- 1; i
++)
6142 fprintf(stderr
, "In file included from %s\n",
6144 if (incl_index
> 0) {
6145 fprintf(stderr
, "%s:%d: ",
6146 incl_files
[incl_index
- 1], last_line_num
);
6148 if (func_name
[0] != '\0') {
6149 fprintf(stderr
, "in function '%s()': ", func_name
);
6153 /* emit a run time error at position 'pc' */
6154 void rt_error(unsigned long pc
, const char *fmt
, ...)
6160 vfprintf(stderr
, fmt
, ap
);
6161 fprintf(stderr
, "\n");
6167 /* signal handler for fatal errors */
6168 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
6170 struct ucontext
*uc
= puc
;
6174 pc
= uc
->uc_mcontext
.gregs
[14];
6176 #error please put the right sigcontext field
6181 switch(siginf
->si_code
) {
6184 rt_error(pc
, "division by zero");
6187 rt_error(pc
, "floating point exception");
6193 rt_error(pc
, "dereferencing invalid pointer");
6196 rt_error(pc
, "illegal instruction");
6199 rt_error(pc
, "abort() called");
6202 rt_error(pc
, "caught signal %d", signum
);
6209 /* launch the compiled program with the given arguments */
6210 int launch_exe(int argc
, char **argv
)
6215 s
= sym_find1(&extern_stack
, TOK_MAIN
);
6216 if (!s
|| (s
->r
& VT_FORWARD
))
6217 error("main() not defined");
6221 error("debug mode currently not available for Windows");
6223 struct sigaction sigact
;
6224 /* install TCC signal handlers to print debug info on fatal
6226 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
6227 sigact
.sa_sigaction
= sig_error
;
6228 sigemptyset(&sigact
.sa_mask
);
6229 sigaction(SIGFPE
, &sigact
, NULL
);
6230 sigaction(SIGILL
, &sigact
, NULL
);
6231 sigaction(SIGSEGV
, &sigact
, NULL
);
6232 sigaction(SIGBUS
, &sigact
, NULL
);
6233 sigaction(SIGABRT
, &sigact
, NULL
);
6237 if (do_bounds_check
) {
6239 error("bound checking currently not available for Windows");
6243 /* add all known static regions */
6244 p
= (int *)bounds_section
->data
;
6245 p_end
= (int *)bounds_section
->data_ptr
;
6247 __bound_new_region((void *)p
[0], p
[1]);
6253 t
= (int (*)())s
->c
;
6254 return (*t
)(argc
, argv
);
6260 printf("tcc version 0.9.4 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
6261 "usage: tcc [-Idir] [-Dsym[=val]] [-Usym] [-llib] [-g] [-b]\n"
6262 " [-i infile] infile [infile_args...]\n"
6264 "-Idir : add include path 'dir'\n"
6265 "-Dsym[=val] : define 'sym' with value 'val'\n"
6266 "-Usym : undefine 'sym'\n"
6267 "-llib : link with dynamic library 'lib'\n"
6268 "-g : generate runtime debug info\n"
6269 "-b : compile with built-in memory and bounds checker (implies -g)\n"
6270 "-i infile : compile infile\n"
6274 int main(int argc
, char **argv
)
6276 char *p
, *r
, *outfile
;
6279 include_paths
[0] = "/usr/include";
6280 include_paths
[1] = "/usr/lib/tcc";
6281 include_paths
[2] = "/usr/local/lib/tcc";
6282 nb_include_paths
= 3;
6284 /* add all tokens */
6285 tok_ident
= TOK_IDENT
;
6290 tok_alloc(p
, r
- p
- 1);
6294 /* standard defines */
6295 define_symbol("__STDC__");
6297 define_symbol("__i386__");
6299 /* tiny C specific defines */
6300 define_symbol("__TINYC__");
6302 /* create standard sections */
6303 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
6304 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6305 /* XXX: should change type to SHT_NOBITS */
6306 bss_section
= new_section(".bss", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6311 if (optind
>= argc
) {
6321 if (nb_include_paths
>= INCLUDE_PATHS_MAX
)
6322 error("too many include paths");
6323 include_paths
[nb_include_paths
++] = r
+ 2;
6324 } else if (r
[1] == 'D') {
6325 define_symbol(r
+ 2);
6326 } else if (r
[1] == 'U') {
6327 undef_symbol(r
+ 2);
6328 } else if (r
[1] == 'l') {
6330 } else if (r
[1] == 'i') {
6333 tcc_compile_file(argv
[optind
++]);
6334 } else if (!strcmp(r
+ 1, "bench")) {
6336 } else if (r
[1] == 'b') {
6337 if (!do_bounds_check
) {
6338 do_bounds_check
= 1;
6340 define_symbol("__BOUNDS_CHECKING_ON");
6341 /* create bounds sections */
6342 bounds_section
= new_section(".bounds",
6343 SHT_PROGBITS
, SHF_ALLOC
);
6344 lbounds_section
= new_section(".lbounds",
6345 SHT_PROGBITS
, SHF_ALLOC
);
6346 /* debug is implied */
6349 } else if (r
[1] == 'g') {
6355 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
6356 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
6357 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
6358 put_elf_str(stabstr_section
, "");
6359 stab_section
->link
= stabstr_section
;
6360 /* put first entry */
6361 put_stabs("", 0, 0, 0, 0);
6364 symtab_section
= new_section(".symtab", SHT_SYMTAB
, 0);
6365 symtab_section
->sh_entsize
= sizeof(Elf32_Sym
);
6366 strtab_section
= new_section(".strtab", SHT_STRTAB
, 0);
6367 put_elf_str(strtab_section
, "");
6368 symtab_section
->link
= strtab_section
;
6369 put_elf_sym(symtab_section
, 0, 0, 0, 0, 0, NULL
);
6371 } else if (r
[1] == 'o') {
6372 /* currently, only for testing, so not documented */
6375 outfile
= argv
[optind
++];
6377 fprintf(stderr
, "invalid option -- '%s'\n", r
);
6382 tcc_compile_file(argv
[optind
]);
6385 printf("total: %d idents, %d lines, %d bytes\n",
6386 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
6389 resolve_extern_syms();
6395 return launch_exe(argc
- optind
, argv
+ optind
);