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
44 /* preprocessor debug */
47 /* target selection */
48 //#define TCC_TARGET_I386 /* i386 code generator */
49 //#define TCC_TARGET_IL /* .NET CLI generator */
51 /* default target is I386 */
52 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
53 #define TCC_TARGET_I386
56 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
57 #define CONFIG_TCC_BCHECK /* enable bound checking code */
60 #ifndef CONFIG_TCC_PREFIX
61 #define CONFIG_TCC_PREFIX "/usr/local"
64 /* amount of virtual memory associated to a section (currently, we do
66 #define SECTION_VSIZE (1024 * 1024)
68 #define INCLUDE_STACK_SIZE 32
69 #define IFDEF_STACK_SIZE 64
70 #define VSTACK_SIZE 64
71 #define STRING_MAX_SIZE 1024
72 #define INCLUDE_PATHS_MAX 32
74 #define TOK_HASH_SIZE 2048 /* must be a power of two */
75 #define TOK_ALLOC_INCR 512 /* must be a power of two */
76 #define SYM_HASH_SIZE 1031
77 #define ELF_SYM_HASH_SIZE 2048 /* must be a power of two */
79 /* token symbol management */
80 typedef struct TokenSym
{
81 struct TokenSym
*hash_next
;
82 int tok
; /* token number */
88 typedef union CValue
{
94 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
96 unsigned long long ull
;
103 typedef struct SValue
{
105 unsigned short r
; /* register + flags */
106 unsigned short r2
; /* second register, used for 'long long'
107 type. If not used, set to VT_CONST */
108 CValue c
; /* constant, if VT_CONST */
111 /* symbol management */
113 int v
; /* symbol token */
114 int t
; /* associated type */
115 int r
; /* associated register */
116 int c
; /* associated number */
117 struct Sym
*next
; /* next related symbol */
118 struct Sym
*prev
; /* prev symbol in stack */
119 struct Sym
*hash_next
; /* next symbol in hash table */
122 typedef struct SymStack
{
124 struct Sym
*hash
[SYM_HASH_SIZE
];
127 /* section definition */
128 typedef struct Section
{
129 unsigned char *data
; /* section data */
130 unsigned char *data_ptr
; /* current data pointer */
131 int sh_num
; /* elf section number */
132 int sh_type
; /* elf section type */
133 int sh_flags
; /* elf section flags */
134 /* special flag to indicate that the section should not be linked to
136 #define SHF_PRIVATE 0x80000000
137 int sh_entsize
; /* elf entry size */
138 unsigned long addr
; /* address at which the section is relocated */
139 struct Section
*link
; /* link to another section */
140 struct Section
*reloc
; /* corresponding section for relocation, if any */
141 struct Section
*reloc_sec
;/* relocation: pointer to corresponding
143 struct Section
*hash
; /* hash table for symbols */
144 struct Section
*next
;
145 char name
[64]; /* section name */
148 /* GNUC attribute definition */
149 typedef struct AttributeDef
{
152 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
155 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
156 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
157 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
159 /* stored in 'Sym.c' field */
160 #define FUNC_NEW 1 /* ansi function prototype */
161 #define FUNC_OLD 2 /* old function prototype */
162 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
164 /* stored in 'Sym.r' field */
165 #define FUNC_CDECL 0 /* standard c call */
166 #define FUNC_STDCALL 1 /* pascal c call */
168 /* field 'Sym.t' for macros */
169 #define MACRO_OBJ 0 /* object like macro */
170 #define MACRO_FUNC 1 /* function like macro */
172 /* field 'Sym.t' for labels */
173 #define LABEL_FORWARD 1 /* label is forward defined */
175 /* type_decl() types */
176 #define TYPE_ABSTRACT 1 /* type without variable */
177 #define TYPE_DIRECT 2 /* type with variable */
179 #define IO_BUF_SIZE 8192
181 typedef struct BufferedFile
{
182 unsigned char *buf_ptr
;
183 unsigned char *buf_end
;
185 int line_num
; /* current line number - here to simply code */
186 char filename
[1024]; /* current filename - here to simply code */
187 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
190 #define CH_EOB 0 /* end of buffer or '\0' char in file */
191 #define CH_EOF (-1) /* end of file */
193 /* parsing state (used to save parser state to reparse part of the
194 source several times) */
195 typedef struct ParseState
{
202 /* used to record tokens */
203 typedef struct TokenString
{
210 struct BufferedFile
*file
;
211 int ch
, ch1
, tok
, tok1
;
215 /* XXX: suppress first_section */
216 Section
*first_section
, **sections
;
217 int nb_sections
; /* number of sections, including first dummy section */
218 int nb_allocated_sections
;
219 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
220 Section
*cur_text_section
; /* current section where function code is
222 /* bound check related sections */
223 Section
*bounds_section
; /* contains global data bound description */
224 Section
*lbounds_section
; /* contains local data bound description */
225 /* symbol sections */
226 Section
*symtab_section
, *strtab_section
, *hashtab_section
;
229 Section
*stab_section
, *stabstr_section
;
231 /* loc : local variable index
232 ind : output code index
234 anon_sym: anonymous symbol index
237 prog
, ind
, loc
, const_wanted
;
238 int global_expr
; /* true if compound literals must be allocated
239 globally (used during initializers parsing */
240 int func_vt
, func_vc
; /* current function return type (used by
241 return instruction) */
242 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
244 TokenSym
**table_ident
;
245 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
246 char token_buf
[STRING_MAX_SIZE
+ 1];
248 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
250 SValue vstack
[VSTACK_SIZE
], *vtop
;
251 int *macro_ptr
, *macro_ptr_allocated
;
252 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
], **include_stack_ptr
;
253 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
254 char *include_paths
[INCLUDE_PATHS_MAX
];
255 int nb_include_paths
;
256 int char_pointer_type
;
258 /* compile with debug symbol (and use them if error during execution) */
261 /* compile with built-in memory and bounds checker */
262 int do_bounds_check
= 0;
264 /* display benchmark infos */
269 /* use GNU C extensions */
272 /* use Tiny C extensions */
279 /* The current value can be: */
280 #define VT_VALMASK 0x00ff
281 #define VT_CONST 0x00f0 /* constant in vc
282 (must be first non register value) */
283 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
284 #define VT_LOCAL 0x00f2 /* offset on stack */
285 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
286 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
287 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
288 #define VT_LVAL 0x0100 /* var is an lvalue */
289 #define VT_SYM 0x0200 /* a symbol value is added */
290 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
291 char/short stored in integer registers) */
292 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
293 dereferencing value */
294 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
295 bounding function call point is in vc */
296 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
297 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
298 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
299 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
302 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
304 #define VT_INT 0 /* integer type */
305 #define VT_BYTE 1 /* signed byte type */
306 #define VT_SHORT 2 /* short type */
307 #define VT_VOID 3 /* void type */
308 #define VT_PTR 4 /* pointer */
309 #define VT_ENUM 5 /* enum definition */
310 #define VT_FUNC 6 /* function type */
311 #define VT_STRUCT 7 /* struct/union definition */
312 #define VT_FLOAT 8 /* IEEE float */
313 #define VT_DOUBLE 9 /* IEEE double */
314 #define VT_LDOUBLE 10 /* IEEE long double */
315 #define VT_BOOL 11 /* ISOC99 boolean type */
316 #define VT_LLONG 12 /* 64 bit integer */
317 #define VT_LONG 13 /* long integer (NEVER USED as type, only
319 #define VT_BTYPE 0x000f /* mask for basic type */
320 #define VT_UNSIGNED 0x0010 /* unsigned type */
321 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
322 #define VT_BITFIELD 0x0040 /* bitfield modifier */
325 #define VT_EXTERN 0x00000080 /* extern definition */
326 #define VT_STATIC 0x00000100 /* static variable */
327 #define VT_TYPEDEF 0x00000200 /* typedef definition */
329 /* type mask (except storage) */
330 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
334 /* warning: the following compare tokens depend on i386 asm code */
346 #define TOK_LAND 0xa0
350 #define TOK_MID 0xa3 /* inc/dec, to void constant */
352 #define TOK_UDIV 0xb0 /* unsigned division */
353 #define TOK_UMOD 0xb1 /* unsigned modulo */
354 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
355 #define TOK_CINT 0xb3 /* number in tokc */
356 #define TOK_CCHAR 0xb4 /* char constant in tokc */
357 #define TOK_STR 0xb5 /* pointer to string in tokc */
358 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
359 #define TOK_LCHAR 0xb7
360 #define TOK_LSTR 0xb8
361 #define TOK_CFLOAT 0xb9 /* float constant */
362 #define TOK_LINENUM 0xba /* line number info */
363 #define TOK_CDOUBLE 0xc0 /* double constant */
364 #define TOK_CLDOUBLE 0xc1 /* long double constant */
365 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
366 #define TOK_ADDC1 0xc3 /* add with carry generation */
367 #define TOK_ADDC2 0xc4 /* add with carry use */
368 #define TOK_SUBC1 0xc5 /* add with carry generation */
369 #define TOK_SUBC2 0xc6 /* add with carry use */
370 #define TOK_CUINT 0xc8 /* unsigned int constant */
371 #define TOK_CLLONG 0xc9 /* long long constant */
372 #define TOK_CULLONG 0xca /* unsigned long long constant */
373 #define TOK_ARROW 0xcb
374 #define TOK_DOTS 0xcc /* three dots */
375 #define TOK_SHR 0xcd /* unsigned shift right */
377 #define TOK_SHL 0x01 /* shift left */
378 #define TOK_SAR 0x02 /* signed shift right */
380 /* assignement operators : normal operator or 0x80 */
381 #define TOK_A_MOD 0xa5
382 #define TOK_A_AND 0xa6
383 #define TOK_A_MUL 0xaa
384 #define TOK_A_ADD 0xab
385 #define TOK_A_SUB 0xad
386 #define TOK_A_DIV 0xaf
387 #define TOK_A_XOR 0xde
388 #define TOK_A_OR 0xfc
389 #define TOK_A_SHL 0x81
390 #define TOK_A_SAR 0x82
392 #define TOK_EOF (-1) /* end of file */
394 /* all identificators and strings have token above that */
395 #define TOK_IDENT 256
416 /* ignored types Must have contiguous values */
422 TOK___SIGNED__
, /* gcc keyword */
425 TOK___INLINE__
, /* gcc keyword */
428 /* unsupported type */
442 /* preprocessor only */
443 TOK_UIDENT
, /* first "user" ident (not keyword) */
444 TOK_DEFINE
= TOK_UIDENT
,
460 /* special identifiers */
463 /* attribute identifiers */
481 "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0"
482 "unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0"
483 "register\0signed\0__signed__\0auto\0inline\0__inline__\0restrict\0"
484 "float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0"
485 "sizeof\0__attribute__\0"
486 /* the following are not keywords. They are included to ease parsing */
487 "define\0include\0ifdef\0ifndef\0elif\0endif\0"
488 "defined\0undef\0error\0line\0"
489 "__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
492 "section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0"
493 "cdecl\0__cdecl\0__cdecl__\0stdcall\0__stdcall\0__stdcall__\0"
494 "noreturn\0__noreturn__\0"
498 #define snprintf _snprintf
501 #if defined(WIN32) || defined(TCC_UCLIBC)
502 /* currently incorrect */
503 long double strtold(const char *nptr
, char **endptr
)
505 return (long double)strtod(nptr
, endptr
);
507 float strtof(const char *nptr
, char **endptr
)
509 return (float)strtod(nptr
, endptr
);
512 /* XXX: need to define this to use them in non ISOC99 context */
513 extern float strtof (const char *__nptr
, char **__endptr
);
514 extern long double strtold (const char *__nptr
, char **__endptr
);
517 char *pstrcpy(char *buf
, int buf_size
, const char *s
);
518 char *pstrcat(char *buf
, int buf_size
, const char *s
);
522 void next_nomacro(void);
523 int expr_const(void);
527 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
);
528 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
531 void gv2(int rc1
, int rc2
);
532 void move_reg(int r
, int s
);
533 void save_regs(int n
);
534 void save_reg(int r
);
540 void macro_subst(TokenString
*tok_str
,
541 Sym
**nested_list
, int *macro_str
);
542 int save_reg_forced(int r
);
544 void force_charshort_cast(int t
);
545 void gen_cast(int t
);
547 Sym
*sym_find(int v
);
548 Sym
*sym_push(int v
, int t
, int r
, int c
);
551 int type_size(int t
, int *a
);
552 int pointed_type(int t
);
553 int pointed_size(int t
);
554 int is_compatible_types(int t1
, int t2
);
555 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
556 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
);
558 void error(const char *fmt
, ...);
559 void rt_error(unsigned long pc
, const char *fmt
, ...);
561 void vset(int t
, int r
, int v
);
562 void type_to_str(char *buf
, int buf_size
,
563 int t
, const char *varstr
);
564 char *get_tok_str(int v
, CValue
*cv
);
566 /* section generation */
567 void put_extern_sym(Sym
*sym
, Section
*section
, unsigned long value
);
568 void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
569 static int put_elf_str(Section
*s
, const char *sym
);
570 static int put_elf_sym(Section
*s
,
571 unsigned long value
, unsigned long size
,
572 int info
, int other
, int shndx
, const char *name
);
573 static void put_elf_reloc(Section
*s
, unsigned long offset
,
574 int type
, int symbol
);
575 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
);
576 static void put_stabn(int type
, int other
, int desc
, int value
);
577 static void put_stabd(int type
, int other
, int desc
);
579 /* true if float/double/long double type */
580 static inline int is_float(int t
)
584 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
587 #ifdef CONFIG_TCC_BCHECK
591 #ifdef TCC_TARGET_I386
592 #include "i386-gen.c"
598 #ifdef CONFIG_TCC_STATIC
600 #define RTLD_LAZY 0x001
601 #define RTLD_NOW 0x002
602 #define RTLD_GLOBAL 0x100
604 /* dummy function for profiling */
605 void *dlopen(const char *filename
, int flag
)
610 const char *dlerror(void)
615 typedef struct TCCSyms
{
620 #define TCCSYM(a) { #a, &a, },
622 /* add the symbol you want here if no dynamic linking is done */
623 static TCCSyms tcc_syms
[] = {
631 void *dlsym(void *handle
, const char *symbol
)
635 while (p
->str
!= NULL
) {
636 if (!strcmp(p
->str
, symbol
))
645 /********************************************************/
646 /* runtime library is there */
647 /* XXX: we suppose that the host compiler handles 'long long'. It
648 would not be difficult to suppress this assumption */
650 long long __divll(long long a
, long long b
)
655 long long __modll(long long a
, long long b
)
660 unsigned long long __divull(unsigned long long a
, unsigned long long b
)
665 unsigned long long __modull(unsigned long long a
, unsigned long long b
)
670 long long __sardi3(long long a
, int b
)
675 unsigned long long __shrdi3(unsigned long long a
, int b
)
680 long long __shldi3(long long a
, int b
)
685 float __ulltof(unsigned long long a
)
690 double __ulltod(unsigned long long a
)
695 long double __ulltold(unsigned long long a
)
697 return (long double)a
;
700 unsigned long long __ftoull(float a
)
702 return (unsigned long long)a
;
705 unsigned long long __dtoull(double a
)
707 return (unsigned long long)a
;
710 unsigned long long __ldtoull(long double a
)
712 return (unsigned long long)a
;
716 /********************************************************/
718 /* we use our own 'finite' function to avoid potential problems with
719 non standard math libs */
720 /* XXX: endianness dependant */
721 int ieee_finite(double d
)
724 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
727 /* copy a string and truncate it. */
728 char *pstrcpy(char *buf
, int buf_size
, const char *s
)
735 q_end
= buf
+ buf_size
- 1;
747 /* strcat and truncate. */
748 char *pstrcat(char *buf
, int buf_size
, const char *s
)
753 pstrcpy(buf
+ len
, buf_size
- len
, s
);
757 Section
*new_section(const char *name
, int sh_type
, int sh_flags
)
759 Section
*sec
, **psec
;
762 sec
= malloc(sizeof(Section
));
764 error("memory full");
765 memset(sec
, 0, sizeof(Section
));
766 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
767 sec
->sh_type
= sh_type
;
768 sec
->sh_flags
= sh_flags
;
770 /* XXX: currently, a single malloc */
771 data
= malloc(SECTION_VSIZE
);
773 error("could not alloc section '%s'", name
);
775 data
= mmap(NULL
, SECTION_VSIZE
,
776 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
777 MAP_PRIVATE
| MAP_ANONYMOUS
,
779 if (data
== (void *)(-1))
780 error("could not mmap section '%s'", name
);
783 sec
->data_ptr
= data
;
785 if (!(sh_flags
& SHF_PRIVATE
)) {
786 /* only add section if not private */
788 psec
= &first_section
;
789 while (*psec
!= NULL
)
790 psec
= &(*psec
)->next
;
794 if ((nb_sections
+ 1) > nb_allocated_sections
) {
795 if (nb_allocated_sections
== 0)
796 nb_allocated_sections
= 1;
797 nb_allocated_sections
*= 2;
798 sections
= realloc(sections
,
799 nb_allocated_sections
* sizeof(Section
*));
801 error("memory full");
803 sections
[nb_sections
] = sec
;
804 sec
->sh_num
= nb_sections
;
810 /* return a reference to a section, and create it if it does not
812 Section
*find_section(const char *name
)
816 for(sec
= first_section
; sec
!= NULL
; sec
= sec
->next
) {
817 if (!strcmp(name
, sec
->name
))
820 /* sections are created as PROGBITS */
821 return new_section(name
, SHT_PROGBITS
, SHF_ALLOC
);
824 /* add a new relocation entry to symbol 'sym' in section 's' */
825 void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
828 put_extern_sym(sym
, NULL
, 0);
829 /* now we can add ELF relocation info */
830 put_elf_reloc(s
, offset
, type
, sym
->c
);
833 static inline int isid(int c
)
835 return (c
>= 'a' && c
<= 'z') ||
836 (c
>= 'A' && c
<= 'Z') ||
840 static inline int isnum(int c
)
842 return c
>= '0' && c
<= '9';
845 static inline int toup(int c
)
847 if (ch
>= 'a' && ch
<= 'z')
848 return ch
- 'a' + 'A';
857 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
858 fprintf(stderr
, "In file included from %s:%d:\n",
859 (*f
)->filename
, (*f
)->line_num
);
860 fprintf(stderr
, "%s:%d: ", file
->filename
, file
->line_num
);
862 fprintf(stderr
, "tcc: ");
866 void error(const char *fmt
, ...)
871 vfprintf(stderr
, fmt
, ap
);
872 fprintf(stderr
, "\n");
877 void expect(const char *msg
)
879 error("%s expected", msg
);
882 void warning(const char *fmt
, ...)
888 fprintf(stderr
, "warning: ");
889 vfprintf(stderr
, fmt
, ap
);
890 fprintf(stderr
, "\n");
897 error("'%c' expected", c
);
901 void test_lvalue(void)
903 if (!(vtop
->r
& VT_LVAL
))
907 TokenSym
*tok_alloc(const char *str
, int len
)
909 TokenSym
*ts
, **pts
, **ptable
;
916 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
918 pts
= &hash_ident
[h
];
923 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
925 pts
= &(ts
->hash_next
);
928 if (tok_ident
>= SYM_FIRST_ANOM
)
929 error("memory full");
931 /* expand token table if needed */
932 i
= tok_ident
- TOK_IDENT
;
933 if ((i
% TOK_ALLOC_INCR
) == 0) {
934 ptable
= realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
936 error("memory full");
937 table_ident
= ptable
;
940 ts
= malloc(sizeof(TokenSym
) + len
);
942 error("memory full");
944 ts
->tok
= tok_ident
++;
946 ts
->hash_next
= NULL
;
947 memcpy(ts
->str
, str
, len
+ 1);
952 void add_char(char **pp
, int c
)
956 if (c
== '\'' || c
== '\"' || c
== '\\') {
957 /* XXX: could be more precise if char or string */
960 if (c
>= 32 && c
<= 126) {
967 *p
++ = '0' + ((c
>> 6) & 7);
968 *p
++ = '0' + ((c
>> 3) & 7);
969 *p
++ = '0' + (c
& 7);
975 /* XXX: buffer overflow */
976 char *get_tok_str(int v
, CValue
*cv
)
978 static char buf
[STRING_MAX_SIZE
+ 1];
983 if (v
== TOK_CINT
|| v
== TOK_CUINT
) {
984 sprintf(buf
, "%u", cv
->ui
);
986 } else if (v
== TOK_CCHAR
|| v
== TOK_LCHAR
) {
993 } else if (v
== TOK_STR
|| v
== TOK_LSTR
) {
997 for(i
=0;i
<ts
->len
;i
++)
998 add_char(&p
, ts
->str
[i
]);
1002 } else if (v
< TOK_IDENT
) {
1007 } else if (v
< tok_ident
) {
1008 return table_ident
[v
- TOK_IDENT
]->str
;
1010 /* should never happen */
1015 /* push, without hashing */
1016 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1019 s
= malloc(sizeof(Sym
));
1021 error("memory full");
1032 /* find a symbol and return its associated structure. 's' is the top
1033 of the symbol stack */
1034 Sym
*sym_find2(Sym
*s
, int v
)
1044 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
1046 /* find a symbol and return its associated structure. 'st' is the
1048 Sym
*sym_find1(SymStack
*st
, int v
)
1052 s
= st
->hash
[HASH_SYM(v
)];
1061 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
1064 s
= sym_push2(&st
->top
, v
, t
, c
);
1065 /* add in hash table */
1067 ps
= &st
->hash
[HASH_SYM(v
)];
1074 /* find a symbol in the right symbol space */
1075 Sym
*sym_find(int v
)
1078 s
= sym_find1(&local_stack
, v
);
1080 s
= sym_find1(&global_stack
, v
);
1084 /* push a given symbol on the symbol stack */
1085 Sym
*sym_push(int v
, int t
, int r
, int c
)
1088 if (local_stack
.top
)
1089 s
= sym_push1(&local_stack
, v
, t
, c
);
1091 s
= sym_push1(&global_stack
, v
, t
, c
);
1096 /* pop symbols until top reaches 'b' */
1097 void sym_pop(SymStack
*st
, Sym
*b
)
1104 /* free hash table entry, except if symbol was freed (only
1105 used for #undef symbols) */
1107 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
1114 /* undefined a hashed symbol (used for #undef). Its name is set to
1116 void sym_undef(SymStack
*st
, Sym
*s
)
1119 ss
= &st
->hash
[HASH_SYM(s
->v
)];
1120 while (*ss
!= NULL
) {
1123 ss
= &(*ss
)->hash_next
;
1131 BufferedFile
*tcc_open(const char *filename
)
1136 fd
= open(filename
, O_RDONLY
);
1139 bf
= malloc(sizeof(BufferedFile
));
1145 bf
->buf_ptr
= bf
->buffer
;
1146 bf
->buf_end
= bf
->buffer
;
1147 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1148 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1150 // printf("opening '%s'\n", filename);
1154 void tcc_close(BufferedFile
*bf
)
1156 total_lines
+= bf
->line_num
;
1161 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1162 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1164 /* fill input buffer and return next char */
1165 int tcc_getc_slow(BufferedFile
*bf
)
1168 /* only tries to read if really end of buffer */
1169 if (bf
->buf_ptr
>= bf
->buf_end
) {
1171 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1178 bf
->buf_ptr
= bf
->buffer
;
1179 bf
->buf_end
= bf
->buffer
+ len
;
1180 *bf
->buf_end
= CH_EOB
;
1182 if (bf
->buf_ptr
< bf
->buf_end
) {
1183 return *bf
->buf_ptr
++;
1185 bf
->buf_ptr
= bf
->buf_end
;
1190 /* no need to put that inline */
1191 void handle_eob(void)
1194 ch1
= tcc_getc_slow(file
);
1198 if (include_stack_ptr
== include_stack
)
1200 /* add end of include file debug info */
1202 put_stabd(N_EINCL
, 0, 0);
1204 /* pop include stack */
1206 include_stack_ptr
--;
1207 file
= *include_stack_ptr
;
1211 /* read next char from current input file */
1212 static inline void inp(void)
1214 ch1
= TCC_GETC(file
);
1215 /* end of buffer/file handling */
1220 // printf("ch1=%c 0x%x\n", ch1, ch1);
1223 /* input with '\\n' handling */
1224 static inline void minp(void)
1229 if (ch
== '\\' && ch1
== '\n') {
1233 //printf("ch=%c 0x%x\n", ch, ch);
1237 /* same as minp, but also skip comments */
1245 /* single line C++ comments */
1247 while (ch1
!= '\n' && ch1
!= -1)
1250 ch
= ' '; /* return space */
1251 } else if (ch1
== '*') {
1257 if (c
== '*' && ch1
== '/') {
1259 ch
= ' '; /* return space */
1271 void skip_spaces(void)
1273 while (ch
== ' ' || ch
== '\t')
1277 /* skip block of text until #else, #elif or #endif. skip also pairs of
1279 void preprocess_skip(void)
1284 while (ch
!= '\n') {
1295 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1297 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1299 else if (tok
== TOK_ENDIF
)
1305 /* ParseState handling */
1307 /* XXX: currently, no include file info is stored. Thus, we cannot display
1308 accurate messages if the function or data definition spans multiple
1311 /* save current parse state in 's' */
1312 void save_parse_state(ParseState
*s
)
1314 s
->line_num
= file
->line_num
;
1315 s
->macro_ptr
= macro_ptr
;
1320 /* restore parse state from 's' */
1321 void restore_parse_state(ParseState
*s
)
1323 file
->line_num
= s
->line_num
;
1324 macro_ptr
= s
->macro_ptr
;
1329 /* return the number of additionnal 'ints' necessary to store the
1331 static inline int tok_ext_size(int t
)
1349 return LDOUBLE_SIZE
/ 4;
1355 /* token string handling */
1357 static inline void tok_str_new(TokenString
*s
)
1361 s
->last_line_num
= -1;
1364 static void tok_str_add(TokenString
*s
, int t
)
1370 if ((len
& 63) == 0) {
1371 str
= realloc(str
, (len
+ 64) * sizeof(int));
1380 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1384 n
= tok_ext_size(t
);
1386 tok_str_add(s
, cv
->tab
[i
]);
1389 /* add the current parse token in token string 's' */
1390 static void tok_str_add_tok(TokenString
*s
)
1394 /* save line number info */
1395 if (file
->line_num
!= s
->last_line_num
) {
1396 s
->last_line_num
= file
->line_num
;
1397 cval
.i
= s
->last_line_num
;
1398 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1400 tok_str_add2(s
, tok
, &tokc
);
1403 /* get a token from an integer array and increment pointer accordingly */
1404 static int tok_get(int **tok_str
, CValue
*cv
)
1410 n
= tok_ext_size(t
);
1417 /* eval an expression for #if/#elif */
1418 int expr_preprocess(void)
1428 next(); /* do macro subst */
1429 if (tok
== TOK_DEFINED
) {
1434 c
= sym_find1(&define_stack
, tok
) != 0;
1439 } else if (tok
>= TOK_IDENT
) {
1440 /* if undefined macro */
1444 tok_str_add_tok(&str
);
1446 tok_str_add(&str
, -1); /* simulate end of file */
1447 tok_str_add(&str
, 0);
1448 /* now evaluate C constant expression */
1449 macro_ptr
= str
.str
;
1457 #if defined(DEBUG) || defined(PP_DEBUG)
1458 void tok_print(int *str
)
1464 t
= tok_get(&str
, &cval
);
1467 printf(" %s", get_tok_str(t
, &cval
));
1473 /* parse after #define */
1474 void parse_define(void)
1476 Sym
*s
, *first
, **ps
;
1477 int v
, t
, varg
, is_vaargs
;
1481 /* XXX: should check if same macro (ANSI) */
1484 /* '(' must be just after macro definition for MACRO_FUNC */
1489 while (tok
!= ')') {
1493 if (varg
== TOK_DOTS
) {
1494 varg
= TOK___VA_ARGS__
;
1496 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1500 if (varg
< TOK_IDENT
)
1501 error("badly punctuated parameter list");
1502 s
= sym_push1(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1514 if (ch
== '\n' || ch
== -1)
1517 tok_str_add2(&str
, tok
, &tokc
);
1519 tok_str_add(&str
, 0);
1521 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1524 s
= sym_push1(&define_stack
, v
, t
, (int)str
.str
);
1528 void preprocess(void)
1531 char buf
[1024], *q
, *p
;
1539 if (tok
== TOK_DEFINE
) {
1542 } else if (tok
== TOK_UNDEF
) {
1544 s
= sym_find1(&define_stack
, tok
);
1545 /* undefine symbol by putting an invalid name */
1547 sym_undef(&define_stack
, s
);
1548 } else if (tok
== TOK_INCLUDE
) {
1553 } else if (ch
== '\"') {
1558 while (ch
!= c
&& ch
!= '\n' && ch
!= -1) {
1559 if ((q
- buf
) < sizeof(buf
) - 1)
1567 error("#include syntax error");
1568 pstrcpy(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
1571 /* eat all spaces and comments after include */
1572 /* XXX: slightly incorrect */
1573 while (ch1
!= '\n' && ch1
!= -1)
1576 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1577 error("memory full");
1579 /* first search in current dir if "header.h" */
1581 p
= strrchr(file
->filename
, '/');
1583 size
= p
+ 1 - file
->filename
;
1584 if (size
> sizeof(buf1
) - 1)
1585 size
= sizeof(buf1
) - 1;
1586 memcpy(buf1
, file
->filename
, size
);
1588 pstrcat(buf1
, sizeof(buf1
), buf
);
1593 /* now search in standard include path */
1594 for(i
=nb_include_paths
- 1;i
>=0;i
--) {
1595 strcpy(buf1
, include_paths
[i
]);
1602 error("include file '%s' not found", buf
);
1605 /* push current file in stack */
1606 /* XXX: fix current line init */
1607 *include_stack_ptr
++ = file
;
1609 /* add include file debug info */
1611 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
1613 } else if (tok
== TOK_IFNDEF
) {
1616 } else if (tok
== TOK_IF
) {
1617 c
= expr_preprocess();
1619 } else if (tok
== TOK_IFDEF
) {
1623 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1625 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1626 error("memory full");
1627 *ifdef_stack_ptr
++ = c
;
1629 } else if (tok
== TOK_ELSE
) {
1630 if (ifdef_stack_ptr
== ifdef_stack
)
1631 error("#else without matching #if");
1632 if (ifdef_stack_ptr
[-1] & 2)
1633 error("#else after #else");
1634 c
= (ifdef_stack_ptr
[-1] ^= 3);
1636 } else if (tok
== TOK_ELIF
) {
1637 if (ifdef_stack_ptr
== ifdef_stack
)
1638 error("#elif without matching #if");
1639 c
= ifdef_stack_ptr
[-1];
1641 error("#elif after #else");
1642 /* last #if/#elif expression was true: we skip */
1645 c
= expr_preprocess();
1646 ifdef_stack_ptr
[-1] = c
;
1653 } else if (tok
== TOK_ENDIF
) {
1654 if (ifdef_stack_ptr
== ifdef_stack
)
1655 error("#endif without matching #if");
1657 } else if (tok
== TOK_LINE
) {
1659 if (tok
!= TOK_CINT
)
1661 file
->line_num
= tokc
.i
;
1667 pstrcpy(file
->filename
, sizeof(file
->filename
),
1668 get_tok_str(tok
, &tokc
));
1670 } else if (tok
== TOK_ERROR
) {
1673 /* ignore other preprocess commands or #! for C scripts */
1674 while (ch
!= '\n' && ch
!= -1)
1678 /* read a number in base b */
1684 if (ch
>= 'a' && ch
<= 'f')
1686 else if (ch
>= 'A' && ch
<= 'F')
1692 if (t
< 0 || t
>= b
)
1700 /* read a character for string or char constant and eval escape codes */
1709 /* at most three octal digits */
1713 c
= c
* 8 + ch
- '0';
1716 c
= c
* 8 + ch
- '0';
1721 } else if (ch
== 'x') {
1739 else if (ch
== 'e' && gnu_ext
)
1741 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
1744 error("invalid escaped char");
1751 /* we use 64 bit numbers */
1754 /* bn = (bn << shift) | or_val */
1755 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
1759 for(i
=0;i
<BN_SIZE
;i
++) {
1761 bn
[i
] = (v
<< shift
) | or_val
;
1762 or_val
= v
>> (32 - shift
);
1766 void bn_zero(unsigned int *bn
)
1769 for(i
=0;i
<BN_SIZE
;i
++) {
1774 void parse_number(void)
1776 int b
, t
, shift
, frac_bits
, s
, exp_val
;
1778 unsigned int bn
[BN_SIZE
];
1788 /* special dot handling */
1789 if (ch
>= '0' && ch
<= '9') {
1790 goto float_frac_parse
;
1791 } else if (ch
== '.') {
1802 } else if (t
== '0') {
1803 if (ch
== 'x' || ch
== 'X') {
1807 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
1813 /* parse all digits. cannot check octal numbers at this stage
1814 because of floating point constants */
1816 if (ch
>= 'a' && ch
<= 'f')
1818 else if (ch
>= 'A' && ch
<= 'F')
1826 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
1828 error("number too long");
1834 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
1835 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
1837 /* NOTE: strtox should support that for hexa numbers, but
1838 non ISOC99 libcs do not support it, so we prefer to do
1840 /* hexadecimal or binary floats */
1841 /* XXX: handle overflows */
1853 } else if (t
>= 'a') {
1855 } else if (t
>= 'A') {
1860 bn_lshift(bn
, shift
, t
);
1867 if (t
>= 'a' && t
<= 'f') {
1869 } else if (t
>= 'A' && t
<= 'F') {
1871 } else if (t
>= '0' && t
<= '9') {
1877 error("invalid digit");
1878 bn_lshift(bn
, shift
, t
);
1883 if (ch
!= 'p' && ch
!= 'P')
1884 error("exponent expected");
1890 } else if (ch
== '-') {
1894 if (ch
< '0' || ch
> '9')
1895 error("exponent digits expected");
1896 while (ch
>= '0' && ch
<= '9') {
1897 exp_val
= exp_val
* 10 + ch
- '0';
1900 exp_val
= exp_val
* s
;
1902 /* now we can generate the number */
1903 /* XXX: should patch directly float number */
1904 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
1905 d
= ldexp(d
, exp_val
- frac_bits
);
1910 /* float : should handle overflow */
1912 } else if (t
== 'L') {
1915 /* XXX: not large enough */
1916 tokc
.ld
= (long double)d
;
1922 /* decimal floats */
1924 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1929 while (ch
>= '0' && ch
<= '9') {
1930 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1936 if (ch
== 'e' || ch
== 'E') {
1937 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1941 if (ch
== '-' || ch
== '+') {
1942 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1947 if (ch
< '0' || ch
> '9')
1948 error("exponent digits expected");
1949 while (ch
>= '0' && ch
<= '9') {
1950 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1962 tokc
.f
= strtof(token_buf
, NULL
);
1963 } else if (t
== 'L') {
1966 tokc
.ld
= strtold(token_buf
, NULL
);
1969 tokc
.d
= strtod(token_buf
, NULL
);
1973 unsigned long long n
, n1
;
1976 /* integer number */
1979 if (b
== 10 && *q
== '0') {
1986 /* no need for checks except for base 10 / 8 errors */
1989 } else if (t
>= 'a') {
1991 } else if (t
>= 'A') {
1996 error("invalid digit");
2000 /* detect overflow */
2002 error("integer constant overflow");
2005 /* XXX: not exactly ANSI compliant */
2006 if ((n
& 0xffffffff00000000LL
) != 0) {
2011 } else if (n
> 0x7fffffff) {
2021 error("three 'l' in integer constant");
2024 if (tok
== TOK_CINT
)
2026 else if (tok
== TOK_CUINT
)
2030 } else if (t
== 'U') {
2031 if (tok
== TOK_CINT
)
2033 else if (tok
== TOK_CLLONG
)
2040 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2048 /* return next token without macro substitution */
2049 void next_nomacro1(void)
2057 while (ch
== '\n') {
2059 while (ch
== ' ' || ch
== '\t')
2062 /* preprocessor command if # at start of line after
2067 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
2085 while (isid(ch
) || isnum(ch
)) {
2086 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2087 error("ident too long");
2092 ts
= tok_alloc(token_buf
, q
- token_buf
);
2094 } else if (isnum(ch
) || ch
== '.') {
2096 } else if (ch
== '\'') {
2104 } else if (ch
== '\"') {
2109 while (ch
!= '\"') {
2112 error("unterminated string");
2113 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2114 error("string too long");
2118 tokc
.ts
= tok_alloc(token_buf
, q
- token_buf
);
2121 q
= "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2126 if (*q
== tok
&& q
[1] == ch
) {
2129 /* three chars tests */
2130 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
2135 } else if (tok
== TOK_DOTS
) {
2137 error("parse error");
2144 /* single char substitutions */
2147 else if (tok
== '>')
2152 /* return next token without macro substitution. Can read input from
2160 tok
= tok_get(¯o_ptr
, &tokc
);
2161 if (tok
== TOK_LINENUM
) {
2162 file
->line_num
= tokc
.i
;
2171 /* substitute args in macro_str and return allocated string */
2172 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
2174 int *st
, last_tok
, t
, notfirst
;
2183 t
= tok_get(¯o_str
, &cval
);
2188 t
= tok_get(¯o_str
, &cval
);
2191 s
= sym_find2(args
, t
);
2193 token_buf
[0] = '\0';
2198 pstrcat(token_buf
, sizeof(token_buf
), " ");
2199 t
= tok_get(&st
, &cval
);
2200 pstrcat(token_buf
, sizeof(token_buf
), get_tok_str(t
, &cval
));
2204 printf("stringize: %s\n", token_buf
);
2207 ts
= tok_alloc(token_buf
, 0);
2209 tok_str_add2(&str
, TOK_STR
, &cval
);
2211 tok_str_add2(&str
, t
, &cval
);
2213 } else if (t
>= TOK_IDENT
) {
2214 s
= sym_find2(args
, t
);
2217 /* if '##' is present before or after, no arg substitution */
2218 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
2219 /* special case for var arg macros : ## eats the
2220 ',' if empty VA_ARGS riable. */
2221 /* XXX: test of the ',' is not 100%
2222 reliable. should fix it to avoid security
2224 if (gnu_ext
&& s
->t
&& *st
== 0 &&
2225 last_tok
== TOK_TWOSHARPS
&&
2226 str
.len
>= 2&& str
.str
[str
.len
- 2] == ',') {
2227 /* suppress ',' '##' */
2231 tok_str_add(&str
, *st
++);
2234 macro_subst(&str
, nested_list
, st
);
2237 tok_str_add(&str
, t
);
2240 tok_str_add2(&str
, t
, &cval
);
2244 tok_str_add(&str
, 0);
2248 /* handle the '##' operator */
2249 int *macro_twosharps(int *macro_str
)
2256 TokenString macro_str1
;
2258 tok_str_new(¯o_str1
);
2264 while (*macro_ptr
== TOK_TWOSHARPS
) {
2266 macro_ptr1
= macro_ptr
;
2269 t
= tok_get(¯o_ptr
, &cval
);
2270 /* XXX: we handle only most common cases:
2271 ident + ident or ident + number */
2272 if (tok
>= TOK_IDENT
&&
2273 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
2274 p
= get_tok_str(tok
, &tokc
);
2275 pstrcpy(token_buf
, sizeof(token_buf
), p
);
2276 p
= get_tok_str(t
, &cval
);
2277 pstrcat(token_buf
, sizeof(token_buf
), p
);
2278 ts
= tok_alloc(token_buf
, 0);
2279 tok
= ts
->tok
; /* modify current token */
2281 /* cannot merge tokens: skip '##' */
2282 macro_ptr
= macro_ptr1
;
2287 tok_str_add2(¯o_str1
, tok
, &tokc
);
2289 tok_str_add(¯o_str1
, 0);
2290 return macro_str1
.str
;
2293 /* do macro substitution of macro_str and add result to
2294 (tok_str,tok_len). If macro_str is NULL, then input stream token is
2295 substituted. 'nested_list' is the list of all macros we got inside
2296 to avoid recursing. */
2297 void macro_subst(TokenString
*tok_str
,
2298 Sym
**nested_list
, int *macro_str
)
2300 Sym
*s
, *args
, *sa
, *sa1
;
2301 int parlevel
, *mstr
, t
, *saved_macro_ptr
;
2302 int mstr_allocated
, *macro_str1
;
2306 saved_macro_ptr
= macro_ptr
;
2307 macro_ptr
= macro_str
;
2310 /* first scan for '##' operator handling */
2311 macro_str1
= macro_twosharps(macro_str
);
2312 macro_ptr
= macro_str1
;
2319 /* special macros */
2320 if (tok
== TOK___LINE__
) {
2321 cval
.i
= file
->line_num
;
2322 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
2323 } else if (tok
== TOK___FILE__
) {
2324 cval
.ts
= tok_alloc(file
->filename
, 0);
2325 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2326 } else if (tok
== TOK___DATE__
) {
2327 cval
.ts
= tok_alloc("Jan 1 1970", 0);
2328 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2329 } else if (tok
== TOK___TIME__
) {
2330 cval
.ts
= tok_alloc("00:00:00", 0);
2331 tok_str_add2(tok_str
, TOK_STR
, &cval
);
2332 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
2333 /* if symbol is a macro, prepare substitution */
2334 /* if nested substitution, do nothing */
2335 if (sym_find2(*nested_list
, tok
))
2339 if (s
->t
== MACRO_FUNC
) {
2340 /* NOTE: we do not use next_nomacro to avoid eating the
2341 next token. XXX: find better solution */
2345 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
2349 if (t
!= '(') /* no macro subst */
2352 /* argument macro */
2357 /* NOTE: empty args are allowed, except if no args */
2359 /* handle '()' case */
2360 if (!args
&& tok
== ')')
2363 error("macro '%s' used with too many args",
2364 get_tok_str(s
->v
, 0));
2367 /* NOTE: non zero sa->t indicates VA_ARGS */
2368 while ((parlevel
> 0 ||
2370 (tok
!= ',' || sa
->t
))) &&
2374 else if (tok
== ')')
2376 tok_str_add2(&str
, tok
, &tokc
);
2379 tok_str_add(&str
, 0);
2380 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->t
, (int)str
.str
);
2383 /* special case for gcc var args: add an empty
2384 var arg argument if it is omitted */
2385 if (sa
&& sa
->t
&& gnu_ext
)
2395 error("macro '%s' used with too few args",
2396 get_tok_str(s
->v
, 0));
2399 /* now subst each arg */
2400 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2411 sym_push2(nested_list
, s
->v
, 0, 0);
2412 macro_subst(tok_str
, nested_list
, mstr
);
2413 /* pop nested defined symbol */
2415 *nested_list
= sa1
->prev
;
2421 /* no need to add if reading input stream */
2424 tok_str_add2(tok_str
, tok
, &tokc
);
2426 /* only replace one macro while parsing input stream */
2430 macro_ptr
= saved_macro_ptr
;
2435 /* return next token with macro substitution */
2441 /* special 'ungettok' case for label parsing */
2449 /* if not reading from macro substituted string, then try
2451 /* XXX: optimize non macro case */
2454 macro_subst(&str
, &nested_list
, NULL
);
2456 tok_str_add(&str
, 0);
2457 macro_ptr
= str
.str
;
2458 macro_ptr_allocated
= str
.str
;
2466 /* end of macro string: free it */
2467 free(macro_ptr_allocated
);
2474 printf("token = %s\n", get_tok_str(tok
, tokc
));
2478 void swap(int *p
, int *q
)
2486 void vsetc(int t
, int r
, CValue
*vc
)
2488 if (vtop
>= vstack
+ VSTACK_SIZE
)
2489 error("memory full");
2490 /* cannot let cpu flags if other instruction are generated */
2491 /* XXX: VT_JMP test too ? */
2492 if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
2497 vtop
->r2
= VT_CONST
;
2501 /* push integer constant */
2506 vsetc(VT_INT
, VT_CONST
, &cval
);
2509 /* push a reference to a section offset by adding a dummy symbol */
2510 void vpush_ref(int t
, Section
*sec
, unsigned long offset
)
2517 sym
= sym_push1(&global_stack
, v
, t
| VT_STATIC
, 0);
2518 sym
->r
= VT_CONST
| VT_SYM
;
2519 put_extern_sym(sym
, sec
, offset
);
2521 vsetc(t
, VT_CONST
| VT_SYM
, &cval
);
2524 void vset(int t
, int r
, int v
)
2541 void vpushv(SValue
*v
)
2543 if (vtop
>= vstack
+ VSTACK_SIZE
)
2544 error("memory full");
2554 /* save r to the memory stack, and mark it as being free */
2555 void save_reg(int r
)
2557 int l
, i
, saved
, t
, size
, align
;
2560 /* modify all stack values */
2563 for(p
=vstack
;p
<=vtop
;p
++) {
2564 i
= p
->r
& VT_VALMASK
;
2565 if ((p
->r
& VT_VALMASK
) == r
||
2566 (p
->r2
& VT_VALMASK
) == r
) {
2567 /* must save value on stack if not already done */
2569 /* store register in the stack */
2571 if ((p
->r
& VT_LVAL
) ||
2572 (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
))
2574 size
= type_size(t
, &align
);
2575 loc
= (loc
- size
) & -align
;
2577 sv
.r
= VT_LOCAL
| VT_LVAL
;
2580 #ifdef TCC_TARGET_I386
2581 /* x86 specific: need to pop fp register ST0 if saved */
2583 o(0xd9dd); /* fstp %st(1) */
2586 /* special long long case */
2587 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2594 /* mark that stack entry as being saved on the stack */
2606 /* find a free register of class 'rc'. If none, save one register */
2612 /* find a free register */
2613 for(r
=0;r
<NB_REGS
;r
++) {
2614 if (reg_classes
[r
] & rc
) {
2615 for(p
=vstack
;p
<=vtop
;p
++) {
2616 if ((p
->r
& VT_VALMASK
) == r
||
2617 (p
->r2
& VT_VALMASK
) == r
)
2625 /* no register left : free the first one on the stack (VERY
2626 IMPORTANT to start from the bottom to ensure that we don't
2627 spill registers used in gen_opi()) */
2628 for(p
=vstack
;p
<=vtop
;p
++) {
2629 r
= p
->r
& VT_VALMASK
;
2630 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
2638 /* save registers up to (vtop - n) stack entry */
2639 void save_regs(int n
)
2644 for(p
= vstack
;p
<= p1
; p
++) {
2645 r
= p
->r
& VT_VALMASK
;
2652 /* move register 's' to 'r', and flush previous value of r to memory
2654 void move_reg(int r
, int s
)
2667 /* get address of vtop (vtop MUST BE an lvalue) */
2670 vtop
->r
&= ~VT_LVAL
;
2671 /* tricky: if saved lvalue, then we can go back to lvalue */
2672 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
2673 vtop
->r
= (vtop
->r
& ~VT_VALMASK
) | VT_LOCAL
| VT_LVAL
;
2676 #ifdef CONFIG_TCC_BCHECK
2677 /* generate lvalue bound code */
2682 vtop
->r
&= ~VT_MUSTBOUND
;
2683 /* if lvalue, then use checking code before dereferencing */
2684 if (vtop
->r
& VT_LVAL
) {
2685 /* if not VT_BOUNDED value, then make one */
2686 if (!(vtop
->r
& VT_BOUNDED
)) {
2687 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
2690 gen_bounded_ptr_add();
2691 vtop
->r
|= lval_type
;
2693 /* then check for dereferencing */
2694 gen_bounded_ptr_deref();
2699 /* store vtop a register belonging to class 'rc'. lvalues are
2700 converted to values. Cannot be used if cannot be converted to
2701 register value (such as structures). */
2704 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
, data_offset
;
2705 unsigned long long ll
;
2707 /* NOTE: get_reg can modify vstack[] */
2708 if (vtop
->t
& VT_BITFIELD
) {
2709 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2710 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2711 /* remove bit field info to avoid loops */
2712 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2713 /* generate shifts */
2714 vpushi(32 - (bit_pos
+ bit_size
));
2716 vpushi(32 - bit_size
);
2717 /* NOTE: transformed to SHR if unsigned */
2721 if (is_float(vtop
->t
) &&
2722 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2723 /* CPUs usually cannot use float constants, so we store them
2724 generically in data segment */
2725 size
= type_size(vtop
->t
, &align
);
2726 data_offset
= (int)data_section
->data_ptr
;
2727 data_offset
= (data_offset
+ align
- 1) & -align
;
2728 /* XXX: not portable yet */
2731 ((int *)data_offset
)[i
] = vtop
->c
.tab
[i
];
2733 vtop
->c
.ul
= data_offset
;
2734 data_offset
+= size
<< 2;
2735 data_section
->data_ptr
= (unsigned char *)data_offset
;
2737 #ifdef CONFIG_TCC_BCHECK
2738 if (vtop
->r
& VT_MUSTBOUND
)
2742 r
= vtop
->r
& VT_VALMASK
;
2743 /* need to reload if:
2745 - lvalue (need to dereference pointer)
2746 - already a register, but not in the right class */
2747 if (r
>= VT_CONST
||
2748 (vtop
->r
& VT_LVAL
) ||
2749 !(reg_classes
[r
] & rc
) ||
2750 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
2751 !(reg_classes
[vtop
->r2
] & rc
))) {
2753 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
2754 /* two register type load : expand to two words
2756 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2759 vtop
->c
.ui
= ll
; /* first word */
2761 vtop
->r
= r
; /* save register value */
2762 vpushi(ll
>> 32); /* second word */
2763 } else if (r
>= VT_CONST
||
2764 (vtop
->r
& VT_LVAL
)) {
2765 /* load from memory */
2768 vtop
[-1].r
= r
; /* save register value */
2769 /* increment pointer to get second word */
2776 /* move registers */
2779 vtop
[-1].r
= r
; /* save register value */
2780 vtop
->r
= vtop
[-1].r2
;
2782 /* allocate second register */
2789 /* write second register */
2791 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->t
)) {
2793 /* lvalue of scalar type : need to use lvalue type
2794 because of possible cast */
2797 /* compute memory access type */
2798 if (vtop
->r
& VT_LVAL_BYTE
)
2800 else if (vtop
->r
& VT_LVAL_SHORT
)
2802 if (vtop
->r
& VT_LVAL_UNSIGNED
)
2806 /* restore wanted type */
2809 /* one register type load */
2818 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
2819 void gv2(int rc1
, int rc2
)
2821 /* generate more generic register first */
2827 /* test if reload is needed for first register */
2828 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
2838 /* test if reload is needed for first register */
2839 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
2845 /* expand long long on stack in two int registers */
2850 u
= vtop
->t
& VT_UNSIGNED
;
2853 vtop
[0].r
= vtop
[-1].r2
;
2854 vtop
[0].r2
= VT_CONST
;
2855 vtop
[-1].r2
= VT_CONST
;
2856 vtop
[0].t
= VT_INT
| u
;
2857 vtop
[-1].t
= VT_INT
| u
;
2860 /* build a long long from two ints */
2863 gv2(RC_INT
, RC_INT
);
2864 vtop
[-1].r2
= vtop
[0].r
;
2869 /* rotate n first stack elements to the bottom */
2876 for(i
=-n
+1;i
!=0;i
++)
2877 vtop
[i
] = vtop
[i
+1];
2881 /* pop stack value */
2885 v
= vtop
->r
& VT_VALMASK
;
2886 #ifdef TCC_TARGET_I386
2887 /* for x86, we need to pop the FP stack */
2889 o(0xd9dd); /* fstp %st(1) */
2892 if (v
== VT_JMP
|| v
== VT_JMPI
) {
2893 /* need to put correct jump if && or || without test */
2899 /* convert stack entry to register and duplicate its value in another
2907 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2914 /* stack: H L L1 H1 */
2922 /* duplicate value */
2933 load(r1
, &sv
); /* move r to r1 */
2935 /* duplicates value */
2940 /* generate CPU independent (unsigned) long long operations */
2941 void gen_opl(int op
)
2943 int t
, a
, b
, op1
, c
, i
;
2962 /* call generic long long function */
2963 gfunc_start(&gf
, FUNC_CDECL
);
2970 vtop
->r2
= REG_LRET
;
2983 /* stack: L1 H1 L2 H2 */
2988 vtop
[-2] = vtop
[-3];
2991 /* stack: H1 H2 L1 L2 */
2997 /* stack: H1 H2 L1 L2 ML MH */
3000 /* stack: ML MH H1 H2 L1 L2 */
3004 /* stack: ML MH H1 L2 H2 L1 */
3009 /* stack: ML MH M1 M2 */
3012 } else if (op
== '+' || op
== '-') {
3013 /* XXX: add non carry method too (for MIPS or alpha) */
3019 /* stack: H1 H2 (L1 op L2) */
3022 gen_op(op1
+ 1); /* TOK_xxxC2 */
3025 /* stack: H1 H2 (L1 op L2) */
3028 /* stack: (L1 op L2) H1 H2 */
3030 /* stack: (L1 op L2) (H1 op H2) */
3038 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
3043 /* stack: L H shift */
3045 /* constant: simpler */
3046 /* NOTE: all comments are for SHL. the other cases are
3047 done by swaping words */
3058 if (op
!= TOK_SAR
) {
3088 /* XXX: should provide a faster fallback on x86 ? */
3103 /* compare operations */
3109 /* stack: L1 H1 L2 H2 */
3111 vtop
[-1] = vtop
[-2];
3113 /* stack: L1 L2 H1 H2 */
3116 /* when values are equal, we need to compare low words. since
3117 the jump is inverted, we invert the test too. */
3120 else if (op1
== TOK_GT
)
3122 else if (op1
== TOK_ULT
)
3124 else if (op1
== TOK_UGT
)
3129 if (op1
!= TOK_NE
) {
3133 /* generate non equal test */
3134 /* XXX: NOT PORTABLE yet */
3138 #ifdef TCC_TARGET_I386
3139 b
= psym(0x850f, 0);
3141 error("not implemented");
3149 vset(VT_INT
, VT_JMPI
, a
);
3154 /* handle integer constant optimizations and various machine
3156 void gen_opic(int op
)
3163 /* currently, we cannot do computations with forward symbols */
3164 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3165 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3169 case '+': v1
->c
.i
+= fc
; break;
3170 case '-': v1
->c
.i
-= fc
; break;
3171 case '&': v1
->c
.i
&= fc
; break;
3172 case '^': v1
->c
.i
^= fc
; break;
3173 case '|': v1
->c
.i
|= fc
; break;
3174 case '*': v1
->c
.i
*= fc
; break;
3181 /* if division by zero, generate explicit division */
3184 error("division by zero in constant");
3188 default: v1
->c
.i
/= fc
; break;
3189 case '%': v1
->c
.i
%= fc
; break;
3190 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
3191 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
3194 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
3195 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
3196 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
3198 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
3199 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
3200 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
3201 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
3202 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
3203 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
3204 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
3205 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
3206 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
3207 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
3209 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
3210 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
3216 /* if commutative ops, put c2 as constant */
3217 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
3218 op
== '|' || op
== '*')) {
3223 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
3226 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
3227 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
3233 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
3234 /* try to use shifts instead of muls or divs */
3235 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
3244 else if (op
== TOK_PDIV
)
3252 /* call low level op generator */
3258 /* generate a floating point operation with constant propagation */
3259 void gen_opif(int op
)
3267 /* currently, we cannot do computations with forward symbols */
3268 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3269 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3271 if (v1
->t
== VT_FLOAT
) {
3274 } else if (v1
->t
== VT_DOUBLE
) {
3282 /* NOTE: we only do constant propagation if finite number (not
3283 NaN or infinity) (ANSI spec) */
3284 if (!ieee_finite(f1
) || !ieee_finite(f2
))
3288 case '+': f1
+= f2
; break;
3289 case '-': f1
-= f2
; break;
3290 case '*': f1
*= f2
; break;
3294 error("division by zero in constant");
3299 /* XXX: also handles tests ? */
3303 /* XXX: overflow test ? */
3304 if (v1
->t
== VT_FLOAT
) {
3306 } else if (v1
->t
== VT_DOUBLE
) {
3319 int pointed_size(int t
)
3321 return type_size(pointed_type(t
), &t
);
3325 void check_pointer_types(SValue
*p1
, SValue
*p2
)
3327 char buf1
[256], buf2
[256];
3331 if (!is_compatible_types(t1
, t2
)) {
3332 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
3333 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
3334 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
3339 /* generic gen_op: handles types problems */
3342 int u
, t1
, t2
, bt1
, bt2
, t
;
3346 bt1
= t1
& VT_BTYPE
;
3347 bt2
= t2
& VT_BTYPE
;
3349 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
3350 /* at least one operand is a pointer */
3351 /* relationnal op: must be both pointers */
3352 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3353 // check_pointer_types(vtop, vtop - 1);
3354 /* pointers are handled are unsigned */
3355 t
= VT_INT
| VT_UNSIGNED
;
3358 /* if both pointers, then it must be the '-' op */
3359 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3360 (t2
& VT_BTYPE
) == VT_PTR
) {
3362 error("cannot use pointers here");
3363 // check_pointer_types(vtop - 1, vtop);
3364 /* XXX: check that types are compatible */
3365 u
= pointed_size(t1
);
3367 /* set to integer type */
3372 /* exactly one pointer : must be '+' or '-'. */
3373 if (op
!= '-' && op
!= '+')
3374 error("cannot use pointers here");
3375 /* Put pointer as first operand */
3376 if ((t2
& VT_BTYPE
) == VT_PTR
) {
3380 /* XXX: cast to int ? (long long case) */
3381 vpushi(pointed_size(vtop
[-1].t
));
3383 #ifdef CONFIG_TCC_BCHECK
3384 /* if evaluating constant expression, no code should be
3385 generated, so no bound check */
3386 if (do_bounds_check
&& !const_wanted
) {
3387 /* if bounded pointers, we generate a special code to
3394 gen_bounded_ptr_add();
3400 /* put again type if gen_opic() swaped operands */
3403 } else if (is_float(bt1
) || is_float(bt2
)) {
3404 /* compute bigger type and do implicit casts */
3405 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
3407 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
3412 /* floats can only be used for a few operations */
3413 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
3414 (op
< TOK_ULT
|| op
> TOK_GT
))
3415 error("invalid operands for binary operation");
3417 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
3418 /* cast to biggest op */
3420 /* convert to unsigned if it does not fit in a long long */
3421 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
3422 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
3426 /* integer operations */
3428 /* convert to unsigned if it does not fit in an integer */
3429 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
3430 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3433 /* XXX: currently, some unsigned operations are explicit, so
3434 we modify them here */
3435 if (t
& VT_UNSIGNED
) {
3442 else if (op
== TOK_LT
)
3444 else if (op
== TOK_GT
)
3446 else if (op
== TOK_LE
)
3448 else if (op
== TOK_GE
)
3454 /* special case for shifts and long long: we keep the shift as
3456 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
3462 else if ((t
& VT_BTYPE
) == VT_LLONG
)
3466 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
3467 /* relationnal op: the result is an int */
3475 /* generic itof for unsigned long long case */
3476 void gen_cvt_itof1(int t
)
3480 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
3481 (VT_LLONG
| VT_UNSIGNED
)) {
3483 gfunc_start(&gf
, FUNC_CDECL
);
3486 vpushi((int)&__ulltof
);
3487 else if (t
== VT_DOUBLE
)
3488 vpushi((int)&__ulltod
);
3490 vpushi((int)&__ulltold
);
3499 /* generic ftoi for unsigned long long case */
3500 void gen_cvt_ftoi1(int t
)
3505 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
3506 /* not handled natively */
3507 gfunc_start(&gf
, FUNC_CDECL
);
3508 st
= vtop
->t
& VT_BTYPE
;
3511 vpushi((int)&__ftoull
);
3512 else if (st
== VT_DOUBLE
)
3513 vpushi((int)&__dtoull
);
3515 vpushi((int)&__ldtoull
);
3519 vtop
->r2
= REG_LRET
;
3525 /* force char or short cast */
3526 void force_charshort_cast(int t
)
3530 /* XXX: add optimization if lvalue : just change type and offset */
3535 if (t
& VT_UNSIGNED
) {
3536 vpushi((1 << bits
) - 1);
3547 /* cast 'vtop' to 't' type */
3548 void gen_cast(int t
)
3550 int sbt
, dbt
, sf
, df
, c
;
3552 /* special delayed cast for char/short */
3553 /* XXX: in some cases (multiple cascaded casts), it may still
3555 if (vtop
->r
& VT_MUSTCAST
) {
3556 vtop
->r
&= ~VT_MUSTCAST
;
3557 force_charshort_cast(vtop
->t
);
3560 dbt
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3561 sbt
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3566 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
3568 /* convert from fp to fp */
3570 /* constant case: we can do it now */
3571 /* XXX: in ISOC, cannot do it if error in convert */
3572 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3573 vtop
->c
.f
= (float)vtop
->c
.d
;
3574 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3575 vtop
->c
.f
= (float)vtop
->c
.ld
;
3576 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3577 vtop
->c
.d
= (double)vtop
->c
.f
;
3578 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3579 vtop
->c
.d
= (double)vtop
->c
.ld
;
3580 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3581 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3582 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3583 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3585 /* non constant case: generate code */
3589 /* convert int to fp */
3592 case VT_LLONG
| VT_UNSIGNED
:
3594 /* XXX: add const cases for long long */
3596 case VT_INT
| VT_UNSIGNED
:
3598 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3599 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
3600 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
3605 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
3606 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
3607 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
3616 /* convert fp to int */
3617 /* we handle char/short/etc... with generic code */
3618 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
3619 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
3624 case VT_LLONG
| VT_UNSIGNED
:
3626 /* XXX: add const cases for long long */
3628 case VT_INT
| VT_UNSIGNED
:
3630 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3631 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3632 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3638 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3639 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3640 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3648 if (dbt
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
3649 /* additionnal cast for char/short/bool... */
3653 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
3654 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
3655 /* scalar to long long */
3657 if (sbt
== (VT_INT
| VT_UNSIGNED
))
3658 vtop
->c
.ll
= vtop
->c
.ui
;
3660 vtop
->c
.ll
= vtop
->c
.i
;
3662 /* machine independant conversion */
3664 /* generate high word */
3665 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
3673 /* patch second register */
3674 vtop
[-1].r2
= vtop
->r
;
3678 } else if (dbt
== VT_BOOL
) {
3679 /* scalar to bool */
3682 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
3683 (dbt
& VT_BTYPE
) == VT_SHORT
) {
3684 force_charshort_cast(t
);
3685 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
3687 if (sbt
== VT_LLONG
) {
3688 /* from long long: just take low order word */
3692 /* if lvalue and single word type, nothing to do because
3693 the lvalue already contains the real type size (see
3694 VT_LVAL_xxx constants) */
3700 /* return type size. Put alignment at 'a' */
3701 int type_size(int t
, int *a
)
3707 if (bt
== VT_STRUCT
) {
3709 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3710 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
3712 } else if (bt
== VT_PTR
) {
3714 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3715 return type_size(s
->t
, a
) * s
->c
;
3720 } else if (bt
== VT_LDOUBLE
) {
3722 return LDOUBLE_SIZE
;
3723 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3726 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
3729 } else if (bt
== VT_SHORT
) {
3733 /* char, void, function, _Bool */
3739 /* return the pointed type of t */
3740 int pointed_type(int t
)
3743 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3744 return s
->t
| (t
& ~VT_TYPE
);
3747 int mk_pointer(int t
)
3751 sym_push(p
, t
, 0, -1);
3752 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
3755 int is_compatible_types(int t1
, int t2
)
3762 bt1
= t1
& VT_BTYPE
;
3763 bt2
= t2
& VT_BTYPE
;
3764 if (bt1
== VT_PTR
) {
3765 t1
= pointed_type(t1
);
3766 /* if function, then convert implicitely to function pointer */
3767 if (bt2
!= VT_FUNC
) {
3770 t2
= pointed_type(t2
);
3772 /* void matches everything */
3775 if (t1
== VT_VOID
|| t2
== VT_VOID
)
3777 return is_compatible_types(t1
, t2
);
3778 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
3780 } else if (bt1
== VT_FUNC
) {
3783 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
3784 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
3785 if (!is_compatible_types(s1
->t
, s2
->t
))
3787 /* XXX: not complete */
3788 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
3792 while (s1
!= NULL
) {
3795 if (!is_compatible_types(s1
->t
, s2
->t
))
3804 /* XXX: not complete */
3809 /* print a type. If 'varstr' is not NULL, then the variable is also
3810 printed in the type */
3812 /* XXX: add array and function pointers */
3813 void type_to_str(char *buf
, int buf_size
,
3814 int t
, const char *varstr
)
3824 if (t
& VT_UNSIGNED
)
3825 pstrcat(buf
, buf_size
, "unsigned ");
3855 tstr
= "long double";
3857 pstrcat(buf
, buf_size
, tstr
);
3861 if (bt
== VT_STRUCT
)
3865 pstrcat(buf
, buf_size
, tstr
);
3866 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
3867 if (v
>= SYM_FIRST_ANOM
)
3868 pstrcat(buf
, buf_size
, "<anonymous>");
3870 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
3873 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3874 type_to_str(buf
, buf_size
, s
->t
, varstr
);
3875 pstrcat(buf
, buf_size
, "(");
3877 while (sa
!= NULL
) {
3878 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
3879 pstrcat(buf
, buf_size
, buf1
);
3882 pstrcat(buf
, buf_size
, ", ");
3884 pstrcat(buf
, buf_size
, ")");
3887 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3888 pstrcpy(buf1
, sizeof(buf1
), "*");
3890 pstrcat(buf1
, sizeof(buf1
), varstr
);
3891 type_to_str(buf
, buf_size
, s
->t
, buf1
);
3895 pstrcat(buf
, buf_size
, " ");
3896 pstrcat(buf
, buf_size
, varstr
);
3901 /* verify type compatibility to store vtop in 'dt' type, and generate
3903 void gen_assign_cast(int dt
)
3906 char buf1
[256], buf2
[256];
3908 st
= vtop
->t
; /* source type */
3909 if ((dt
& VT_BTYPE
) == VT_PTR
) {
3910 /* special cases for pointers */
3911 /* a function is implicitely a function pointer */
3912 if ((st
& VT_BTYPE
) == VT_FUNC
) {
3913 if (!is_compatible_types(pointed_type(dt
), st
))
3918 /* '0' can also be a pointer */
3919 if ((st
& VT_BTYPE
) == VT_INT
&&
3920 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
3924 if (!is_compatible_types(dt
, st
)) {
3926 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3927 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3928 error("cannot cast '%s' to '%s'", buf1
, buf2
);
3934 /* store vtop in lvalue pushed on stack */
3937 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
3941 sbt
= vtop
->t
& VT_BTYPE
;
3942 dbt
= ft
& VT_BTYPE
;
3943 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
3944 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
3945 /* optimize char/short casts */
3946 delayed_cast
= VT_MUSTCAST
;
3947 vtop
->t
= ft
& VT_TYPE
;
3950 gen_assign_cast(ft
& VT_TYPE
);
3953 if (sbt
== VT_STRUCT
) {
3954 /* if structure, only generate pointer */
3955 /* structure assignment : generate memcpy */
3956 /* XXX: optimize if small size */
3958 gfunc_start(&gf
, FUNC_CDECL
);
3960 size
= type_size(vtop
->t
, &align
);
3974 vpushi((int)&memcpy
);
3976 /* leave source on stack */
3977 } else if (ft
& VT_BITFIELD
) {
3978 /* bitfield store handling */
3979 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
3980 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3981 /* remove bit field info to avoid loops */
3982 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3984 /* duplicate destination */
3986 vtop
[-1] = vtop
[-2];
3988 /* mask and shift source */
3989 vpushi((1 << bit_size
) - 1);
3993 /* load destination, mask and or with source */
3995 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
4001 #ifdef CONFIG_TCC_BCHECK
4002 /* bound check case */
4003 if (vtop
[-1].r
& VT_MUSTBOUND
) {
4012 r
= gv(rc
); /* generate value */
4013 /* if lvalue was saved on stack, must read it */
4014 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
4016 t
= get_reg(RC_INT
);
4018 sv
.r
= VT_LOCAL
| VT_LVAL
;
4019 sv
.c
.ul
= vtop
[-1].c
.ul
;
4021 vtop
[-1].r
= t
| VT_LVAL
;
4024 /* two word case handling : store second register at word + 4 */
4025 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
4027 /* convert to int to increment easily */
4034 /* XXX: it works because r2 is spilled last ! */
4035 store(vtop
->r2
, vtop
- 1);
4038 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
4039 vtop
->r
|= delayed_cast
;
4043 /* post defines POST/PRE add. c is the token ++ or -- */
4044 void inc(int post
, int c
)
4047 vdup(); /* save lvalue */
4049 gv_dup(); /* duplicate value */
4054 vpushi(c
- TOK_MID
);
4056 vstore(); /* store value */
4058 vpop(); /* if post op, return saved value */
4061 /* Parse GNUC __attribute__ extension. Currently, the following
4062 extensions are recognized:
4063 - aligned(n) : set data/function alignment.
4064 - section(x) : generate data/code in this section.
4065 - unused : currently ignored, but may be used someday.
4067 void parse_attribute(AttributeDef
*ad
)
4074 while (tok
!= ')') {
4075 if (tok
< TOK_IDENT
)
4076 expect("attribute name");
4081 case TOK___SECTION__
:
4084 expect("section name");
4085 ad
->section
= find_section(tokc
.ts
->str
);
4090 case TOK___ALIGNED__
:
4093 if (n
<= 0 || (n
& (n
- 1)) != 0)
4094 error("alignment must be a positive power of two");
4099 case TOK___UNUSED__
:
4100 /* currently, no need to handle it because tcc does not
4101 track unused objects */
4104 case TOK___NORETURN__
:
4105 /* currently, no need to handle it because tcc does not
4106 track unused objects */
4111 ad
->func_call
= FUNC_CDECL
;
4115 case TOK___STDCALL__
:
4116 ad
->func_call
= FUNC_STDCALL
;
4119 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
4120 /* skip parameters */
4121 /* XXX: skip parenthesis too */
4124 while (tok
!= ')' && tok
!= -1)
4138 /* enum/struct/union declaration */
4139 int struct_decl(int u
)
4141 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
4142 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
4146 a
= tok
; /* save decl type */
4151 /* struct already defined ? return it */
4152 /* XXX: check consistency */
4153 s
= sym_find(v
| SYM_STRUCT
);
4156 error("invalid type");
4162 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
4163 /* put struct/union/enum name in type */
4165 u
= u
| (v
<< VT_STRUCT_SHIFT
);
4170 error("struct/union/enum already defined");
4171 /* cannot be empty */
4178 if (a
== TOK_ENUM
) {
4185 /* enum symbols have static storage */
4186 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
4191 parse_btype(&b
, &ad
);
4196 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
4197 if ((t
& VT_BTYPE
) == VT_FUNC
||
4198 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
4199 error("invalid type for '%s'",
4200 get_tok_str(v
, NULL
));
4206 bit_size
= expr_const();
4207 /* XXX: handle v = 0 case for messages */
4209 error("negative width in bit-field '%s'",
4210 get_tok_str(v
, NULL
));
4211 if (v
&& bit_size
== 0)
4212 error("zero width for bit-field '%s'",
4213 get_tok_str(v
, NULL
));
4215 size
= type_size(t
, &align
);
4217 if (bit_size
>= 0) {
4222 error("bitfields must have scalar type");
4224 if (bit_size
> bsize
) {
4225 error("width of '%s' exceeds its type",
4226 get_tok_str(v
, NULL
));
4227 } else if (bit_size
== bsize
) {
4228 /* no need for bit fields */
4230 } else if (bit_size
== 0) {
4231 /* XXX: what to do if only padding in a
4233 /* zero size: means to pad */
4237 /* we do not have enough room ? */
4238 if ((bit_pos
+ bit_size
) > bsize
)
4241 /* XXX: handle LSB first */
4243 (bit_pos
<< VT_STRUCT_SHIFT
) |
4244 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
4245 bit_pos
+= bit_size
;
4251 /* add new memory data only if starting
4253 if (lbit_pos
== 0) {
4254 if (a
== TOK_STRUCT
) {
4255 c
= (c
+ align
- 1) & -align
;
4263 if (align
> maxalign
)
4267 printf("add field %s offset=%d",
4268 get_tok_str(v
, NULL
), offset
);
4269 if (t
& VT_BITFIELD
) {
4270 printf(" pos=%d size=%d",
4271 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
4272 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
4276 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
4280 if (tok
== ';' || tok
== -1)
4290 /* size for struct/union, dummy for enum */
4291 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
4296 /* return 0 if no type declaration. otherwise, return the basic type
4299 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
4301 int t
, u
, type_found
;
4304 memset(ad
, 0, sizeof(AttributeDef
));
4315 if ((t
& VT_BTYPE
) != 0)
4316 error("too many basic types");
4330 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
4331 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4332 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
4333 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
4347 if ((t
& VT_BTYPE
) == VT_LONG
) {
4348 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
4355 u
= struct_decl(VT_ENUM
);
4359 u
= struct_decl(VT_STRUCT
);
4362 /* type modifiers */
4367 case TOK___SIGNED__
:
4370 case TOK___INLINE__
:
4392 /* GNUC attribute */
4393 case TOK___ATTRIBUTE__
:
4394 parse_attribute(ad
);
4398 if (!s
|| !(s
->t
& VT_TYPEDEF
))
4400 t
|= (s
->t
& ~VT_TYPEDEF
);
4407 /* long is never used as type */
4408 if ((t
& VT_BTYPE
) == VT_LONG
)
4409 t
= (t
& ~VT_BTYPE
) | VT_INT
;
4414 int post_type(int t
, AttributeDef
*ad
)
4416 int p
, n
, pt
, l
, t1
;
4417 Sym
**plast
, *s
, *first
;
4421 /* function declaration */
4426 while (tok
!= ')') {
4427 /* read param name and compute offset */
4428 if (l
!= FUNC_OLD
) {
4429 if (!parse_btype(&pt
, &ad1
)) {
4431 error("invalid type");
4438 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
4440 pt
= type_decl(&ad1
, &n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
4441 if ((pt
& VT_BTYPE
) == VT_VOID
)
4442 error("parameter declared as void");
4449 /* array must be transformed to pointer according to ANSI C */
4451 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
4456 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
4463 /* if no parameters, then old type prototype */
4467 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4468 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4469 /* we push a anonymous symbol which will contain the function prototype */
4471 s
= sym_push(p
, t
, ad
->func_call
, l
);
4473 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
4474 } else if (tok
== '[') {
4475 /* array definition */
4481 error("invalid array size");
4484 /* parse next post type */
4485 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
4486 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
), ad
);
4488 /* we push a anonymous symbol which will contain the array
4491 sym_push(p
, t
, 0, n
);
4492 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
4497 /* Read a type declaration (except basic type), and return the
4498 type. 'td' is a bitmask indicating which kind of type decl is
4499 expected. 't' should contain the basic type. 'ad' is the attribute
4500 definition of the basic type. It can be modified by type_decl(). */
4501 int type_decl(AttributeDef
*ad
, int *v
, int t
, int td
)
4506 while (tok
== '*') {
4508 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
4513 /* recursive type */
4514 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
4517 /* XXX: this is not correct to modify 'ad' at this point, but
4518 the syntax is not clear */
4519 if (tok
== TOK___ATTRIBUTE__
)
4520 parse_attribute(ad
);
4521 u
= type_decl(ad
, v
, 0, td
);
4525 /* type identifier */
4526 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
4530 if (!(td
& TYPE_ABSTRACT
))
4531 expect("identifier");
4535 /* append t at the end of u */
4536 t
= post_type(t
, ad
);
4537 if (tok
== TOK___ATTRIBUTE__
)
4538 parse_attribute(ad
);
4543 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
4553 /* define a new external reference to a symbol 'v' of type 'u' */
4554 Sym
*external_sym(int v
, int u
, int r
)
4560 /* push forward reference */
4561 s
= sym_push1(&global_stack
,
4562 v
, u
| VT_EXTERN
, 0);
4563 s
->r
= r
| VT_CONST
| VT_SYM
;
4568 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
4569 static int lvalue_type(int t
)
4576 else if (bt
== VT_SHORT
)
4580 if (t
& VT_UNSIGNED
)
4581 r
|= VT_LVAL_UNSIGNED
;
4585 /* indirection with full error checking and bound check */
4586 static void indir(void)
4588 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
4590 if (vtop
->r
& VT_LVAL
)
4592 vtop
->t
= pointed_type(vtop
->t
);
4593 /* an array is never an lvalue */
4594 if (!(vtop
->t
& VT_ARRAY
)) {
4595 vtop
->r
|= lvalue_type(vtop
->t
);
4596 /* if bound checking, the referenced pointer must be checked */
4597 if (do_bounds_check
)
4598 vtop
->r
|= VT_MUSTBOUND
;
4602 /* pass a parameter to a function and do type checking and casting */
4603 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
4606 func_type
= func
->c
;
4607 if (func_type
== FUNC_OLD
||
4608 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
4609 /* default casting : only need to convert float to double */
4610 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
4611 gen_cast(VT_DOUBLE
);
4612 } else if (arg
== NULL
) {
4613 error("too many arguments to function");
4615 gen_assign_cast(arg
->t
);
4622 int n
, t
, ft
, fc
, p
, align
, size
, r
, data_offset
;
4627 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
4630 } else if (tok
== TOK_CUINT
) {
4631 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4633 } else if (tok
== TOK_CLLONG
) {
4634 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
4636 } else if (tok
== TOK_CULLONG
) {
4637 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4639 } else if (tok
== TOK_CFLOAT
) {
4640 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
4642 } else if (tok
== TOK_CDOUBLE
) {
4643 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
4645 } else if (tok
== TOK_CLDOUBLE
) {
4646 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
4648 } else if (tok
== TOK___FUNC__
) {
4649 /* special function name identifier */
4650 /* generate (char *) type */
4651 data_offset
= data_section
->data_ptr
- data_section
->data
;
4652 vpush_ref(mk_pointer(VT_BYTE
), data_section
, data_offset
);
4653 strcpy(data_section
->data
+ data_offset
, funcname
);
4654 data_offset
+= strlen(funcname
) + 1;
4655 data_section
->data_ptr
= data_section
->data
+ data_offset
;
4657 } else if (tok
== TOK_LSTR
) {
4660 } else if (tok
== TOK_STR
) {
4661 /* string parsing */
4664 type_size(t
, &align
);
4665 data_offset
= data_section
->data_ptr
- data_section
->data
;
4666 data_offset
= (data_offset
+ align
- 1) & -align
;
4668 /* we must declare it as an array first to use initializer parser */
4669 t
= VT_ARRAY
| mk_pointer(t
);
4670 decl_initializer(t
, data_section
, data_offset
, 1, 0);
4671 data_offset
+= type_size(t
, &align
);
4672 /* put it as pointer */
4673 vpush_ref(t
& ~VT_ARRAY
, data_section
, fc
);
4674 data_section
->data_ptr
= data_section
->data
+ data_offset
;
4680 if (parse_btype(&t
, &ad
)) {
4681 ft
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4683 /* check ISOC99 compound literal */
4685 /* data is allocated locally by default */
4690 /* all except arrays are lvalues */
4691 if (!(ft
& VT_ARRAY
))
4692 r
|= lvalue_type(ft
);
4693 memset(&ad
, 0, sizeof(AttributeDef
));
4694 decl_initializer_alloc(ft
, &ad
, r
, 1, 0, 0);
4703 } else if (t
== '*') {
4706 } else if (t
== '&') {
4708 /* functions names must be treated as function pointers,
4709 except for unary '&' and sizeof. Since we consider that
4710 functions are not lvalues, we only have to handle it
4711 there and in function calls. */
4712 /* arrays can also be used although they are not lvalues */
4713 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
&&
4714 !(vtop
->t
& VT_ARRAY
))
4716 vtop
->t
= mk_pointer(vtop
->t
);
4721 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
4722 vtop
->c
.i
= !vtop
->c
.i
;
4723 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
4724 vtop
->c
.i
= vtop
->c
.i
^ 1;
4726 vset(VT_INT
, VT_JMP
, gtst(1, 0));
4736 if (t
== TOK_SIZEOF
) {
4739 if (parse_btype(&t
, &ad
)) {
4740 t
= type_decl(&ad
, &n
, t
, TYPE_ABSTRACT
);
4742 /* XXX: some code could be generated: add eval
4754 vpushi(type_size(t
, &t
));
4756 if (t
== TOK_INC
|| t
== TOK_DEC
) {
4759 } else if (t
== '-') {
4766 expect("identifier");
4770 error("'%s' undeclared", get_tok_str(t
, NULL
));
4771 /* for simple function calls, we tolerate undeclared
4772 external reference */
4774 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
4775 /* int() function */
4776 s
= external_sym(t
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), 0);
4778 vset(s
->t
, s
->r
, s
->c
);
4779 /* if forward reference, we must point to s */
4780 if (vtop
->r
& VT_SYM
)
4785 /* post operations */
4787 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4790 } else if (tok
== '.' || tok
== TOK_ARROW
) {
4792 if (tok
== TOK_ARROW
)
4797 /* expect pointer on structure */
4798 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
4799 expect("struct or union");
4800 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4803 while ((s
= s
->next
) != NULL
) {
4808 error("field not found");
4809 /* add field offset to pointer */
4810 vtop
->t
= char_pointer_type
; /* change type to 'char *' */
4813 /* change type to field type, and set to lvalue */
4815 /* an array is never an lvalue */
4816 if (!(vtop
->t
& VT_ARRAY
))
4817 vtop
->r
|= lvalue_type(vtop
->t
);
4819 } else if (tok
== '[') {
4825 } else if (tok
== '(') {
4830 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
4831 /* pointer test (no array accepted) */
4832 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4833 vtop
->t
= pointed_type(vtop
->t
);
4834 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4838 expect("function pointer");
4841 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4843 /* get return type */
4844 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
4845 save_regs(0); /* save used temporary registers */
4846 gfunc_start(&gf
, s
->r
);
4848 sa
= s
->next
; /* first parameter */
4849 #ifdef INVERT_FUNC_PARAMS
4853 ParseState saved_parse_state
;
4856 /* read each argument and store it on a stack */
4857 /* XXX: merge it with macro args ? */
4863 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
4867 else if (tok
== ')')
4869 tok_str_add_tok(&str
);
4872 tok_str_add(&str
, -1); /* end of file added */
4873 tok_str_add(&str
, 0);
4874 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
4875 s1
->next
= sa
; /* add reference to argument */
4884 /* now generate code in reverse order by reading the stack */
4885 save_parse_state(&saved_parse_state
);
4887 macro_ptr
= (int *)args
->c
;
4891 expect("',' or ')'");
4892 gfunc_param_typed(&gf
, s
, args
->next
);
4894 free((int *)args
->c
);
4898 restore_parse_state(&saved_parse_state
);
4901 /* compute first implicit argument if a structure is returned */
4902 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
4903 /* get some space for the returned structure */
4904 size
= type_size(s
->t
, &align
);
4905 loc
= (loc
- size
) & -align
;
4907 ret
.r
= VT_LOCAL
| VT_LVAL
;
4908 /* pass it as 'int' to avoid structure arg passing
4910 vset(VT_INT
, VT_LOCAL
, loc
);
4916 /* return in register */
4917 if (is_float(ret
.t
)) {
4920 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
4926 #ifndef INVERT_FUNC_PARAMS
4930 gfunc_param_typed(&gf
, s
, sa
);
4940 error("too few arguments to function");
4944 vsetc(ret
.t
, ret
.r
, &ret
.c
);
4958 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
4959 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
4960 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
4983 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
4984 (l
== 1 && (tok
== '+' || tok
== '-')) ||
4985 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
4986 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
4987 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
4988 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
4989 (l
== 5 && tok
== '&') ||
4990 (l
== 6 && tok
== '^') ||
4991 (l
== 7 && tok
== '|') ||
4992 (l
== 8 && tok
== TOK_LAND
) ||
4993 (l
== 9 && tok
== TOK_LOR
)) {
5002 /* only used if non constant */
5010 if (tok
!= TOK_LAND
) {
5013 vset(VT_INT
, VT_JMPI
, t
);
5030 if (tok
!= TOK_LOR
) {
5033 vset(VT_INT
, VT_JMP
, t
);
5043 /* XXX: better constant handling */
5046 int t
, u
, c
, r1
, r2
, rc
;
5066 save_regs(1); /* we need to save all registers here except
5067 at the top because it is a branch point */
5070 /* XXX: long long handling ? */
5072 if (is_float(vtop
->t
))
5075 vtop
--; /* no vpop so that FP stack is not flushed */
5100 /* parse a constant expression and return value in vtop */
5101 void expr_const1(void)
5107 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
5112 /* parse an integer constant and return its value */
5113 int expr_const(void)
5122 /* return the label token if current token is a label, otherwise
5129 /* fast test first */
5130 if (tok
< TOK_UIDENT
)
5132 /* no need to save tokc since we expect an identifier */
5140 /* XXX: may not work in all cases (macros ?) */
5149 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
5154 /* generate line number info */
5156 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
5157 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
5159 last_line_num
= file
->line_num
;
5162 if (tok
== TOK_IF
) {
5169 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5171 if (c
== TOK_ELSE
) {
5175 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5176 gsym(d
); /* patch else jmp */
5179 } else if (tok
== TOK_WHILE
) {
5187 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5191 } else if (tok
== '{') {
5194 s
= local_stack
.top
;
5195 while (tok
!= '}') {
5198 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5200 /* pop locally defined symbols */
5201 sym_pop(&local_stack
, s
);
5203 } else if (tok
== TOK_RETURN
) {
5207 gen_assign_cast(func_vt
);
5208 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5209 /* if returning structure, must copy it to implicit
5210 first pointer arg location */
5211 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
5214 /* copy structure value to pointer */
5216 } else if (is_float(func_vt
)) {
5221 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5224 rsym
= gjmp(rsym
); /* jmp */
5225 } else if (tok
== TOK_BREAK
) {
5228 error("cannot break");
5229 *bsym
= gjmp(*bsym
);
5232 } else if (tok
== TOK_CONTINUE
) {
5235 error("cannot continue");
5236 *csym
= gjmp(*csym
);
5239 } else if (tok
== TOK_FOR
) {
5266 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5271 if (tok
== TOK_DO
) {
5276 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
5287 if (tok
== TOK_SWITCH
) {
5291 /* XXX: other types than integer */
5292 case_reg
= gv(RC_INT
);
5296 b
= gjmp(0); /* jump to first case */
5298 block(&a
, csym
, &b
, &c
, case_reg
);
5299 /* if no default, jmp after switch */
5307 if (tok
== TOK_CASE
) {
5314 if (gnu_ext
&& tok
== TOK_DOTS
) {
5318 warning("empty case range");
5320 /* since a case is like a label, we must skip it with a jmp */
5323 vset(VT_INT
, case_reg
, 0);
5327 *case_sym
= gtst(1, 0);
5330 *case_sym
= gtst(1, 0);
5331 vset(VT_INT
, case_reg
, 0);
5334 *case_sym
= gtst(1, *case_sym
);
5338 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5340 if (tok
== TOK_DEFAULT
) {
5346 error("too many 'default'");
5348 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5350 if (tok
== TOK_GOTO
) {
5352 s
= sym_find1(&label_stack
, tok
);
5353 /* put forward definition if needed */
5355 s
= sym_push1(&label_stack
, tok
, LABEL_FORWARD
, 0);
5356 /* label already defined */
5357 if (s
->t
& LABEL_FORWARD
)
5367 s
= sym_find1(&label_stack
, b
);
5369 if (!(s
->t
& LABEL_FORWARD
))
5370 error("multiple defined label");
5375 sym_push1(&label_stack
, b
, 0, ind
);
5377 /* we accept this, but it is a mistake */
5379 warning("deprecated use of label at end of compound statement");
5381 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
5383 /* expression case */
5393 /* t is the array or struct type. c is the array or struct
5394 address. cur_index/cur_field is the pointer to the current
5395 value. 'size_only' is true if only size info is needed (only used
5397 void decl_designator(int t
, Section
*sec
, unsigned long c
,
5398 int *cur_index
, Sym
**cur_field
,
5402 int notfirst
, index
, align
, l
;
5405 if (gnu_ext
&& (l
= is_label()) != 0)
5408 while (tok
== '[' || tok
== '.') {
5410 if (!(t
& VT_ARRAY
))
5411 expect("array type");
5412 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5414 index
= expr_const();
5415 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
5416 expect("invalid index");
5420 t
= pointed_type(t
);
5421 c
+= index
* type_size(t
, &align
);
5427 if ((t
& VT_BTYPE
) != VT_STRUCT
)
5428 expect("struct/union type");
5429 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5441 t
= f
->t
| (t
& ~VT_TYPE
);
5456 t
= pointed_type(t
);
5457 c
+= index
* type_size(t
, &align
);
5461 error("too many field init");
5462 t
= f
->t
| (t
& ~VT_TYPE
);
5466 decl_initializer(t
, sec
, c
, 0, size_only
);
5470 #define EXPR_CONST 1
5473 /* store a value or an expression directly in global data or in local array */
5474 void init_putv(int t
, Section
*sec
, unsigned long c
,
5475 int v
, int expr_type
)
5477 int saved_global_expr
, bt
;
5485 /* compound literals must be allocated globally in this case */
5486 saved_global_expr
= global_expr
;
5489 global_expr
= saved_global_expr
;
5497 /* XXX: not portable */
5498 /* XXX: generate error if incorrect relocation */
5501 ptr
= sec
->data
+ c
;
5502 if ((vtop
->r
& VT_SYM
) &&
5508 error("initializer element is not computable at load time");
5511 *(char *)ptr
= vtop
->c
.i
;
5514 *(short *)ptr
= vtop
->c
.i
;
5517 *(double *)ptr
= vtop
->c
.d
;
5520 *(long double *)ptr
= vtop
->c
.ld
;
5523 *(long long *)ptr
= vtop
->c
.ll
;
5526 if (vtop
->r
& VT_SYM
) {
5527 greloc(sec
, vtop
->c
.sym
, c
, R_DATA_32
);
5530 *(int *)ptr
= vtop
->c
.i
;
5536 vset(t
, VT_LOCAL
, c
);
5543 /* put zeros for variable based init */
5544 void init_putz(int t
, Section
*sec
, unsigned long c
, int size
)
5549 /* nothing to do because globals are already set to zero */
5551 gfunc_start(&gf
, FUNC_CDECL
);
5556 vset(VT_INT
, VT_LOCAL
, c
);
5558 vpushi((int)&memset
);
5563 /* 't' contains the type and storage info. 'c' is the offset of the
5564 object in section 'sec'. If 'sec' is NULL, it means stack based
5565 allocation. 'first' is true if array '{' must be read (multi
5566 dimension implicit array init handling). 'size_only' is true if
5567 size only evaluation is wanted (only for arrays). */
5568 void decl_initializer(int t
, Section
*sec
, unsigned long c
, int first
, int size_only
)
5570 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
5571 int t1
, size1
, align1
, expr_type
;
5576 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
5579 t1
= pointed_type(t
);
5580 size1
= type_size(t1
, &align1
);
5583 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
5589 /* only parse strings here if correct type (otherwise: handle
5590 them as ((w)char *) expressions */
5591 if ((tok
== TOK_LSTR
&&
5592 (t1
& VT_BTYPE
) == VT_INT
) ||
5594 (t1
& VT_BTYPE
) == VT_BYTE
)) {
5595 /* XXX: move multiple string parsing in parser ? */
5596 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
5598 /* compute maximum number of chars wanted */
5600 if (n
>= 0 && nb
> (n
- array_length
))
5601 nb
= n
- array_length
;
5604 warning("initializer-string for array is too long");
5606 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
5607 ts
->str
[i
], EXPR_VAL
);
5613 /* only add trailing zero if enough storage (no
5614 warning in this case since it is standard) */
5615 if (n
< 0 || array_length
< n
) {
5617 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
5623 while (tok
!= '}') {
5624 decl_designator(t
, sec
, c
, &index
, NULL
, size_only
);
5625 if (n
>= 0 && index
>= n
)
5626 error("index too large");
5627 /* must put zero in holes (note that doing it that way
5628 ensures that it even works with designators) */
5629 if (!size_only
&& array_length
< index
) {
5630 init_putz(t1
, sec
, c
+ array_length
* size1
,
5631 (index
- array_length
) * size1
);
5634 if (index
> array_length
)
5635 array_length
= index
;
5636 /* special test for multi dimensional arrays (may not
5637 be strictly correct if designators are used at the
5639 if (index
>= n
&& no_oblock
)
5648 /* put zeros at the end */
5649 if (!size_only
&& n
>= 0 && array_length
< n
) {
5650 init_putz(t1
, sec
, c
+ array_length
* size1
,
5651 (n
- array_length
) * size1
);
5653 /* patch type size if needed */
5655 s
->c
= array_length
;
5656 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
5657 /* XXX: union needs only one init */
5659 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5664 while (tok
!= '}') {
5665 decl_designator(t
, sec
, c
, NULL
, &f
, size_only
);
5666 /* fill with zero between fields */
5668 if (!size_only
&& array_length
< index
) {
5669 init_putz(t
, sec
, c
+ array_length
,
5670 index
- array_length
);
5672 index
= index
+ type_size(f
->t
, &align1
);
5673 if (index
> array_length
)
5674 array_length
= index
;
5680 /* put zeros at the end */
5681 if (!size_only
&& array_length
< n
) {
5682 init_putz(t
, sec
, c
+ array_length
,
5686 } else if (tok
== '{') {
5688 decl_initializer(t
, sec
, c
, first
, size_only
);
5690 } else if (size_only
) {
5691 /* just skip expression */
5693 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
5697 else if (tok
== ')')
5702 /* currently, we always use constant expression for globals
5703 (may change for scripting case) */
5704 expr_type
= EXPR_CONST
;
5706 expr_type
= EXPR_ANY
;
5707 init_putv(t
, sec
, c
, 0, expr_type
);
5711 /* parse an initializer for type 't' if 'has_init' is true, and
5712 allocate space in local or global data space ('r' is either
5713 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
5714 variable 'v' of scope 'scope' is declared before initializers are
5715 parsed. If 'v' is zero, then a reference to the new object is put
5716 in the value stack. */
5717 void decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
,
5720 int size
, align
, addr
, data_offset
;
5722 ParseState saved_parse_state
;
5723 TokenString init_str
;
5726 size
= type_size(t
, &align
);
5727 /* If unknown size, we must evaluate it before
5728 evaluating initializers because
5729 initializers can generate global data too
5730 (e.g. string pointers or ISOC99 compound
5731 literals). It also simplifies local
5732 initializers handling */
5733 tok_str_new(&init_str
);
5736 error("unknown type size");
5737 /* get all init string */
5739 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5741 error("unexpected end of file in initializer");
5742 tok_str_add_tok(&init_str
);
5745 else if (tok
== '}') {
5752 tok_str_add(&init_str
, -1);
5753 tok_str_add(&init_str
, 0);
5756 save_parse_state(&saved_parse_state
);
5758 macro_ptr
= init_str
.str
;
5760 decl_initializer(t
, NULL
, 0, 1, 1);
5761 /* prepare second initializer parsing */
5762 macro_ptr
= init_str
.str
;
5765 /* if still unknown size, error */
5766 size
= type_size(t
, &align
);
5768 error("unknown type size");
5770 /* take into account specified alignment if bigger */
5771 if (ad
->aligned
> align
)
5772 align
= ad
->aligned
;
5773 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5775 if (do_bounds_check
&& (t
& VT_ARRAY
))
5777 #ifdef TCC_TARGET_IL
5778 /* XXX: ugly patch to allocate local variables for IL, just
5783 loc
= (loc
- size
) & -align
;
5786 /* handles bounds */
5787 /* XXX: currently, since we do only one pass, we cannot track
5788 '&' operators, so we add only arrays */
5789 if (do_bounds_check
&& (t
& VT_ARRAY
)) {
5791 /* add padding between regions */
5793 /* then add local bound info */
5794 bounds_ptr
= (int *)lbounds_section
->data_ptr
;
5795 *bounds_ptr
++ = addr
;
5796 *bounds_ptr
++ = size
;
5797 lbounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5800 /* compute section */
5808 data_offset
= sec
->data_ptr
- sec
->data
;
5809 data_offset
= (data_offset
+ align
- 1) & -align
;
5811 /* very important to increment global pointer at this time
5812 because initializers themselves can create new initializers */
5813 data_offset
+= size
;
5814 /* handles bounds */
5815 if (do_bounds_check
) {
5817 /* first, we need to add at least one byte between each region */
5819 /* then add global bound info */
5820 bounds_ptr
= (int *)bounds_section
->data_ptr
;
5821 /* XXX: add relocation */
5822 *bounds_ptr
++ = addr
+ (unsigned long)sec
->data
;
5823 *bounds_ptr
++ = size
;
5824 bounds_section
->data_ptr
= (unsigned char *)bounds_ptr
;
5826 sec
->data_ptr
= sec
->data
+ data_offset
;
5832 /* local variable */
5833 sym_push(v
, t
, r
, addr
);
5835 if (scope
== VT_CONST
) {
5836 /* global scope: see if already defined */
5840 if (!is_compatible_types(sym
->t
, t
))
5841 error("incompatible types for redefinition of '%s'",
5842 get_tok_str(v
, NULL
));
5843 if (!(sym
->t
& VT_EXTERN
))
5844 error("redefinition of '%s'", get_tok_str(v
, NULL
));
5845 sym
->t
&= ~VT_EXTERN
;
5848 sym
= sym_push(v
, t
, r
| VT_SYM
, 0);
5850 put_extern_sym(sym
, sec
, addr
);
5854 /* push local reference */
5857 /* push global reference */
5858 vpush_ref(t
, sec
, addr
);
5862 decl_initializer(t
, sec
, addr
, 1, 0);
5863 /* restore parse state if needed */
5866 restore_parse_state(&saved_parse_state
);
5871 void put_func_debug(int t
)
5876 /* XXX: we put here a dummy type */
5877 snprintf(buf
, sizeof(buf
), "%s:%c1",
5878 funcname
, t
& VT_STATIC
? 'f' : 'F');
5879 put_stabs(buf
, N_FUN
, 0, file
->line_num
, ind
);
5885 /* not finished : try to put some local vars in registers */
5886 //#define CONFIG_REG_VARS
5888 #ifdef CONFIG_REG_VARS
5889 void add_var_ref(int t
)
5891 printf("%s:%d: &%s\n",
5892 file
->filename
, file
->line_num
,
5893 get_tok_str(t
, NULL
));
5896 /* first pass on a function with heuristic to extract variable usage
5897 and pointer references to local variables for register allocation */
5898 void analyse_function(void)
5905 /* any symbol coming after '&' is considered as being a
5906 variable whose reference is taken. It is highly unaccurate
5907 but it is difficult to do better without a complete parse */
5910 /* if '& number', then no need to examine next tokens */
5911 if (tok
== TOK_CINT
||
5913 tok
== TOK_CLLONG
||
5914 tok
== TOK_CULLONG
) {
5916 } else if (tok
>= TOK_UIDENT
) {
5917 /* if '& ident [' or '& ident ->', then ident address
5921 if (tok
!= '[' && tok
!= TOK_ARROW
)
5925 while (tok
!= '}' && tok
!= ';' &&
5926 !((tok
== ',' || tok
== ')') && level
== 0)) {
5927 if (tok
>= TOK_UIDENT
) {
5929 } else if (tok
== '(') {
5931 } else if (tok
== ')') {
5944 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5947 int t
, b
, v
, has_init
, r
;
5952 if (!parse_btype(&b
, &ad
)) {
5953 /* skip redundant ';' */
5954 /* XXX: find more elegant solution */
5959 /* special test for old K&R protos without explicit int
5960 type. Only accepted when defining global data */
5961 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
5965 if (((b
& VT_BTYPE
) == VT_ENUM
||
5966 (b
& VT_BTYPE
) == VT_STRUCT
) &&
5968 /* we accept no variable after */
5972 while (1) { /* iterate thru each declaration */
5973 t
= type_decl(&ad
, &v
, b
, TYPE_DIRECT
);
5977 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
5978 printf("type = '%s'\n", buf
);
5982 #ifdef CONFIG_REG_VARS
5983 TokenString func_str
;
5984 ParseState saved_parse_state
;
5989 error("cannot use local functions");
5991 expect("function definition");
5993 #ifdef CONFIG_REG_VARS
5994 /* parse all function code and record it */
5996 tok_str_new(&func_str
);
6002 error("unexpected end of file");
6003 tok_str_add_tok(&func_str
);
6008 } else if (t
== '}') {
6010 if (block_level
== 0)
6014 tok_str_add(&func_str
, -1);
6015 tok_str_add(&func_str
, 0);
6017 save_parse_state(&saved_parse_state
);
6019 macro_ptr
= func_str
.str
;
6024 /* compute text section */
6025 cur_text_section
= ad
.section
;
6026 if (!cur_text_section
)
6027 cur_text_section
= text_section
;
6028 ind
= (int)cur_text_section
->data_ptr
;
6029 funcname
= get_tok_str(v
, NULL
);
6032 /* if symbol is already defined, then put complete type */
6035 /* put function symbol */
6036 sym
= sym_push1(&global_stack
, v
, t
, 0);
6038 put_extern_sym(sym
, cur_text_section
,
6039 ind
- (int)cur_text_section
->data
);
6040 sym
->r
= VT_SYM
| VT_CONST
;
6041 /* put debug symbol */
6044 /* push a dummy symbol to enable local sym storage */
6045 sym_push1(&local_stack
, 0, 0, 0);
6049 #ifdef CONFIG_REG_VARS
6050 macro_ptr
= func_str
.str
;
6053 block(NULL
, NULL
, NULL
, NULL
, 0);
6056 cur_text_section
->data_ptr
= (unsigned char *)ind
;
6057 sym_pop(&label_stack
, NULL
); /* reset label stack */
6058 sym_pop(&local_stack
, NULL
); /* reset local stack */
6059 /* end of function */
6061 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
6063 funcname
= ""; /* for safety */
6064 func_vt
= VT_VOID
; /* for safety */
6065 ind
= 0; /* for safety */
6067 #ifdef CONFIG_REG_VARS
6069 restore_parse_state(&saved_parse_state
);
6073 if (b
& VT_TYPEDEF
) {
6074 /* save typedefed type */
6075 /* XXX: test storage specifiers ? */
6076 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
6077 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
6078 /* external function definition */
6079 external_sym(v
, t
, 0);
6081 /* not lvalue if array */
6083 if (!(t
& VT_ARRAY
))
6084 r
|= lvalue_type(t
);
6085 if (b
& VT_EXTERN
) {
6086 /* external variable */
6087 external_sym(v
, t
, r
);
6093 has_init
= (tok
== '=');
6096 decl_initializer_alloc(t
, &ad
, r
,
6110 /* compile the C file opened in 'file'. Return non zero if errors. */
6111 int tcc_compile(TCCState
*s
)
6117 include_stack_ptr
= include_stack
;
6118 ifdef_stack_ptr
= ifdef_stack
;
6121 anon_sym
= SYM_FIRST_ANOM
;
6123 /* file info: full path + filename */
6125 getcwd(buf
, sizeof(buf
));
6126 pstrcat(buf
, sizeof(buf
), "/");
6127 put_stabs(buf
, N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
6128 put_stabs(file
->filename
, N_SO
, 0, 0,
6129 (unsigned long)text_section
->data_ptr
);
6131 /* define common 'char *' type because it is often used internally
6132 for arrays and struct dereference */
6133 char_pointer_type
= mk_pointer(VT_BYTE
);
6135 define_start
= define_stack
.top
;
6137 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6141 expect("declaration");
6143 /* end of translation unit info */
6145 put_stabn(N_SO
, 0, 0, (unsigned long)text_section
->data_ptr
);
6148 /* reset define stack, but leave -Dsymbols (may be incorrect if
6149 they are undefined) */
6150 sym_pop(&define_stack
, define_start
);
6152 sym_pop(&global_stack
, NULL
);
6157 int tcc_compile_file(TCCState
*s
, const char *filename1
)
6160 file
= tcc_open(filename1
);
6162 error("file '%s' not found", filename1
);
6163 ret
= tcc_compile(s
);
6168 int tcc_compile_string(TCCState
*s
, const char *str
)
6170 BufferedFile bf1
, *bf
= &bf1
;
6173 /* init file structure */
6175 bf
->buf_ptr
= (char *)str
;
6176 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
6177 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
6181 ret
= tcc_compile(s
);
6183 /* currently, no need to close */
6187 /* define a symbol. A value can also be provided with the '=' operator */
6188 void tcc_define_symbol(TCCState
*s
, const char *sym
, const char *value
)
6190 BufferedFile bf1
, *bf
= &bf1
;
6192 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
6193 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
6197 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
6199 /* init file structure */
6201 bf
->buf_ptr
= bf
->buffer
;
6202 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
6203 bf
->filename
[0] = '\0';
6207 include_stack_ptr
= include_stack
;
6209 /* parse with define parser */
6211 ch
= '\n'; /* needed to parse correctly first preprocessor command */
6217 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
6221 ts
= tok_alloc(sym
, 0);
6222 s
= sym_find1(&define_stack
, tok
);
6223 /* undefine symbol by putting an invalid name */
6225 sym_undef(&define_stack
, s
);
6228 /* open a dynamic library so that its symbol are available for
6229 compiled programs */
6230 /* XXX: open the lib only to actually run the program */
6231 int tcc_add_dll(TCCState
*s
, const char *library_name
)
6235 h
= dlopen(library_name
, RTLD_GLOBAL
| RTLD_LAZY
);
6237 error((char *)dlerror());
6241 static int put_elf_str(Section
*s
, const char *sym
)
6244 offset
= s
->data_ptr
- s
->data
;
6254 /* elf symbol hashing function */
6255 static unsigned long elf_hash(const unsigned char *name
)
6257 unsigned long h
= 0, g
;
6260 h
= (h
<< 4) + *name
++;
6269 /* return the symbol number */
6270 static int put_elf_sym(Section
*s
,
6271 unsigned long value
, unsigned long size
,
6272 int info
, int other
, int shndx
, const char *name
)
6274 int name_offset
, nbuckets
, h
, sym_index
;
6278 sym
= (Elf32_Sym
*)s
->data_ptr
;
6280 name_offset
= put_elf_str(s
->link
, name
);
6283 /* XXX: endianness */
6284 sym
->st_name
= name_offset
;
6285 sym
->st_value
= value
;
6286 sym
->st_size
= size
;
6287 sym
->st_info
= info
;
6288 sym
->st_other
= other
;
6289 sym
->st_shndx
= shndx
;
6290 sym_index
= sym
- (Elf32_Sym
*)s
->data
;
6292 if (hs
&& ELF32_ST_BIND(info
) == STB_GLOBAL
) {
6293 /* add another hashing entry */
6294 nbuckets
= ((int *)hs
->data
)[0];
6295 ((int *)hs
->data
)[1]++;
6296 h
= elf_hash(name
) % nbuckets
;
6297 ((int *)hs
->data
)[2 + nbuckets
+ sym_index
] = ((int *)hs
->data
)[2 + h
];
6298 ((int *)hs
->data
)[2 + h
] = sym_index
;
6300 s
->data_ptr
+= sizeof(Elf32_Sym
);
6304 /* find global ELF symbol 'name' and return its index. Return 0 if not
6306 static int find_elf_sym(Section
*s
, const char *name
)
6310 int nbuckets
, sym_index
, h
;
6316 nbuckets
= ((int *)hs
->data
)[0];
6317 h
= elf_hash(name
) % nbuckets
;
6318 sym_index
= ((int *)hs
->data
)[2 + h
];
6319 while (sym_index
!= 0) {
6320 sym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
6321 name1
= s
->link
->data
+ sym
->st_name
;
6322 if (!strcmp(name
, name1
))
6324 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
6329 /* update sym->c so that it points to an external symbol in section
6330 'section' with value 'value' */
6331 /* XXX: get rid of put_elf_sym */
6332 void put_extern_sym(Sym
*sym
, Section
*section
, unsigned long value
)
6334 int sym_type
, sym_bind
, sh_num
;
6339 sh_num
= section
->sh_num
;
6343 if ((sym
->t
& VT_BTYPE
) == VT_FUNC
)
6344 sym_type
= STT_FUNC
;
6346 sym_type
= STT_OBJECT
;
6347 if (sym
->t
& VT_STATIC
)
6348 sym_bind
= STB_LOCAL
;
6350 sym_bind
= STB_GLOBAL
;
6351 /* if the symbol is global, then we look if it is already
6353 /* NOTE: name can be NULL if anonymous symbol */
6354 name
= get_tok_str(sym
->v
, NULL
);
6355 if (sym_bind
== STB_GLOBAL
) {
6356 sym
->c
= find_elf_sym(symtab_section
, name
);
6359 /* check if not defined */
6361 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
6362 if (esym
->st_shndx
!= SHN_UNDEF
)
6363 error("'%s' defined twice", name
);
6364 esym
->st_shndx
= sh_num
;
6365 esym
->st_value
= value
;
6369 sym
->c
= put_elf_sym(symtab_section
, value
, 0,
6370 ELF32_ST_INFO(sym_bind
, sym_type
), 0,
6374 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
6375 esym
->st_value
= value
;
6376 esym
->st_shndx
= sh_num
;
6380 /* put relocation */
6381 static void put_elf_reloc(Section
*s
, unsigned long offset
,
6382 int type
, int symbol
)
6390 /* if no relocation section, create it */
6391 snprintf(buf
, sizeof(buf
), ".rel%s", s
->name
);
6392 sr
= new_section(buf
, SHT_REL
, 0);
6393 sr
->sh_entsize
= sizeof(Elf32_Rel
);
6394 sr
->link
= symtab_section
;
6398 rel
= (Elf32_Rel
*)sr
->data_ptr
;
6399 /* XXX: endianness */
6400 rel
->r_offset
= offset
;
6401 rel
->r_info
= ELF32_R_INFO(symbol
, type
);
6402 sr
->data_ptr
+= sizeof(Elf32_Rel
);
6405 /* put stab debug information */
6408 unsigned long n_strx
; /* index into string table of name */
6409 unsigned char n_type
; /* type of symbol */
6410 unsigned char n_other
; /* misc info (usually empty) */
6411 unsigned short n_desc
; /* description field */
6412 unsigned long n_value
; /* value of symbol */
6415 static void put_stabs(const char *str
, int type
, int other
, int desc
, int value
)
6419 sym
= (Stab_Sym
*)stab_section
->data_ptr
;
6421 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
6426 sym
->n_other
= other
;
6428 sym
->n_value
= value
;
6430 stab_section
->data_ptr
+= sizeof(Stab_Sym
);
6433 static void put_stabn(int type
, int other
, int desc
, int value
)
6435 put_stabs(NULL
, type
, other
, desc
, value
);
6438 static void put_stabd(int type
, int other
, int desc
)
6440 put_stabs(NULL
, type
, other
, desc
, 0);
6443 /* output an ELF file (currently, only for testing) */
6444 /* XXX: generate dynamic reloc info + DLL tables */
6445 /* XXX: generate startup code */
6446 /* XXX: better program header generation */
6447 /* XXX: handle realloc'ed sections (instead of mmaping them) */
6448 int tcc_output_file(TCCState
*s
, const char *filename
, int file_type
)
6452 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
;
6453 Section
*sec
, *strsec
;
6454 Elf32_Shdr
*shdr
, *sh
;
6455 Elf32_Phdr
*phdr
, *ph
;
6457 memset(&ehdr
, 0, sizeof(ehdr
));
6459 /* we add a section for symbols */
6460 strsec
= new_section(".shstrtab", SHT_STRTAB
, 0);
6461 put_elf_str(strsec
, "");
6463 /* count number of sections and compute number of program segments */
6464 shnum
= 1; /* section index zero is reserved */
6466 for(sec
= first_section
; sec
!= NULL
; sec
= sec
->next
) {
6468 if ((sec
->sh_flags
& SHF_ALLOC
) &&
6469 file_type
!= TCC_FILE_OBJ
)
6472 /* allocate section headers */
6473 shdr
= malloc(shnum
* sizeof(Elf32_Shdr
));
6475 error("memory full");
6476 memset(shdr
, 0, shnum
* sizeof(Elf32_Shdr
));
6478 /* allocate program segment headers */
6479 phdr
= malloc(phnum
* sizeof(Elf32_Phdr
));
6481 error("memory full");
6482 memset(phdr
, 0, phnum
* sizeof(Elf32_Phdr
));
6484 /* XXX: find correct load order */
6485 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
6486 for(sec
= first_section
, i
= 1; sec
!= NULL
; sec
= sec
->next
, i
++) {
6488 sh
->sh_name
= put_elf_str(strsec
, sec
->name
);
6489 sh
->sh_type
= sec
->sh_type
;
6490 sh
->sh_flags
= sec
->sh_flags
;
6491 sh
->sh_entsize
= sec
->sh_entsize
;
6493 sh
->sh_link
= sec
->link
->sh_num
;
6495 sh
->sh_info
= sec
->reloc_sec
->sh_num
;
6496 if (sh
->sh_type
== SHT_STRTAB
) {
6497 sh
->sh_addralign
= 1;
6498 } else if (sh
->sh_type
== SHT_SYMTAB
||
6499 (sh
->sh_flags
& SHF_ALLOC
) == 0) {
6500 sh
->sh_addralign
= 4;
6502 sh
->sh_addr
= (Elf32_Word
)sec
->data
;
6503 sh
->sh_addralign
= 4096;
6505 sh
->sh_size
= (Elf32_Word
)sec
->data_ptr
- (Elf32_Word
)sec
->data
;
6506 /* align to section start */
6507 file_offset
= (file_offset
+ sh
->sh_addralign
- 1) &
6508 ~(sh
->sh_addralign
- 1);
6509 sh
->sh_offset
= file_offset
;
6510 file_offset
+= sh
->sh_size
;
6512 /* build program headers (simplistic - not fully correct) */
6515 for(i
=1;i
<shnum
;i
++) {
6517 if (sh
->sh_type
== SHT_PROGBITS
&&
6518 (sh
->sh_flags
& SHF_ALLOC
) != 0) {
6520 ph
->p_type
= PT_LOAD
;
6521 ph
->p_offset
= sh
->sh_offset
;
6522 ph
->p_vaddr
= sh
->sh_addr
;
6523 ph
->p_paddr
= ph
->p_vaddr
;
6524 ph
->p_filesz
= sh
->sh_size
;
6525 ph
->p_memsz
= sh
->sh_size
;
6527 if (sh
->sh_flags
& SHF_WRITE
)
6528 ph
->p_flags
|= PF_W
;
6529 if (sh
->sh_flags
& SHF_EXECINSTR
)
6530 ph
->p_flags
|= PF_X
;
6531 ph
->p_align
= sh
->sh_addralign
;
6537 file_offset
= (file_offset
+ 3) & -4;
6540 ehdr
.e_ident
[0] = ELFMAG0
;
6541 ehdr
.e_ident
[1] = ELFMAG1
;
6542 ehdr
.e_ident
[2] = ELFMAG2
;
6543 ehdr
.e_ident
[3] = ELFMAG3
;
6544 ehdr
.e_ident
[4] = ELFCLASS32
;
6545 ehdr
.e_ident
[5] = ELFDATA2LSB
;
6546 ehdr
.e_ident
[6] = EV_CURRENT
;
6550 ehdr
.e_type
= ET_EXEC
;
6553 ehdr
.e_type
= ET_DYN
;
6556 ehdr
.e_type
= ET_REL
;
6559 ehdr
.e_machine
= EM_386
;
6560 ehdr
.e_version
= EV_CURRENT
;
6561 ehdr
.e_entry
= 0; /* XXX: patch it */
6562 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
6563 ehdr
.e_shoff
= file_offset
;
6564 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
6565 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
6566 ehdr
.e_phnum
= phnum
;
6567 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
6568 ehdr
.e_shnum
= shnum
;
6569 ehdr
.e_shstrndx
= shnum
- 1;
6571 /* write elf file */
6572 f
= fopen(filename
, "w");
6574 error("could not write '%s'", filename
);
6575 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
6576 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
6577 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
6578 for(sec
= first_section
, i
= 1; sec
!= NULL
; sec
= sec
->next
, i
++) {
6580 while (offset
< sh
->sh_offset
) {
6584 size
= sec
->data_ptr
- sec
->data
;
6585 fwrite(sec
->data
, 1, size
, f
);
6588 while (offset
< ehdr
.e_shoff
) {
6592 fwrite(shdr
, 1, shnum
* sizeof(Elf32_Shdr
), f
);
6600 /* print the position in the source file of PC value 'pc' by reading
6601 the stabs debug information */
6602 static void rt_printline(unsigned long wanted_pc
)
6604 Stab_Sym
*sym
, *sym_end
;
6605 char func_name
[128];
6606 unsigned long func_addr
, last_pc
, pc
;
6607 const char *incl_files
[INCLUDE_STACK_SIZE
];
6608 int incl_index
, len
, last_line_num
, i
;
6609 const char *str
, *p
;
6611 func_name
[0] = '\0';
6614 last_pc
= 0xffffffff;
6616 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
6617 sym_end
= (Stab_Sym
*)stab_section
->data_ptr
;
6618 while (sym
< sym_end
) {
6619 switch(sym
->n_type
) {
6620 /* function start or end */
6622 if (sym
->n_strx
== 0) {
6623 func_name
[0] = '\0';
6626 str
= stabstr_section
->data
+ sym
->n_strx
;
6627 p
= strchr(str
, ':');
6629 pstrcpy(func_name
, sizeof(func_name
), str
);
6632 if (len
> sizeof(func_name
) - 1)
6633 len
= sizeof(func_name
) - 1;
6634 memcpy(func_name
, str
, len
);
6635 func_name
[len
] = '\0';
6637 func_addr
= sym
->n_value
;
6640 /* line number info */
6642 pc
= sym
->n_value
+ func_addr
;
6643 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
6646 last_line_num
= sym
->n_desc
;
6650 str
= stabstr_section
->data
+ sym
->n_strx
;
6652 if (incl_index
< INCLUDE_STACK_SIZE
) {
6653 incl_files
[incl_index
++] = str
;
6661 if (sym
->n_strx
== 0) {
6662 incl_index
= 0; /* end of translation unit */
6664 str
= stabstr_section
->data
+ sym
->n_strx
;
6665 /* do not add path */
6667 if (len
> 0 && str
[len
- 1] != '/')
6674 /* did not find line number info: */
6675 fprintf(stderr
, "(no debug info, pc=0x%08lx): ", wanted_pc
);
6678 for(i
= 0; i
< incl_index
- 1; i
++)
6679 fprintf(stderr
, "In file included from %s\n",
6681 if (incl_index
> 0) {
6682 fprintf(stderr
, "%s:%d: ",
6683 incl_files
[incl_index
- 1], last_line_num
);
6685 if (func_name
[0] != '\0') {
6686 fprintf(stderr
, "in function '%s()': ", func_name
);
6690 /* emit a run time error at position 'pc' */
6691 void rt_error(unsigned long pc
, const char *fmt
, ...)
6697 vfprintf(stderr
, fmt
, ap
);
6698 fprintf(stderr
, "\n");
6704 /* signal handler for fatal errors */
6705 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
6707 struct ucontext
*uc
= puc
;
6711 pc
= uc
->uc_mcontext
.gregs
[14];
6713 #error please put the right sigcontext field
6718 switch(siginf
->si_code
) {
6721 rt_error(pc
, "division by zero");
6724 rt_error(pc
, "floating point exception");
6730 rt_error(pc
, "dereferencing invalid pointer");
6733 rt_error(pc
, "illegal instruction");
6736 rt_error(pc
, "abort() called");
6739 rt_error(pc
, "caught signal %d", signum
);
6746 static void *resolve_sym(const char *sym
)
6748 #ifdef CONFIG_TCC_BCHECK
6749 if (do_bounds_check
) {
6751 ptr
= bound_resolve_sym(sym
);
6756 return dlsym(NULL
, sym
);
6759 static void resolve_extern_syms(void)
6765 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
6766 sym
< (Elf32_Sym
*)symtab_section
->data_ptr
;
6768 if (sym
->st_shndx
== SHN_UNDEF
) {
6769 name
= symtab_section
->link
->data
+ sym
->st_name
;
6770 addr
= (unsigned long)resolve_sym(name
);
6772 error("unresolved external reference '%s'", name
);
6773 sym
->st_value
= addr
;
6774 sym
->st_shndx
= SHN_ABS
;
6779 static unsigned long get_sym_val(int sym_index
)
6784 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
6785 val
= sym
->st_value
;
6786 if (sym
->st_shndx
!= SHN_ABS
)
6787 val
+= sections
[sym
->st_shndx
]->addr
;
6791 /* relocate sections */
6792 static void relocate_section(Section
*s
)
6803 for(rel
= (Elf32_Rel
*)sr
->data
;
6804 rel
< (Elf32_Rel
*)sr
->data_ptr
;
6806 ptr
= s
->data
+ rel
->r_offset
;
6807 val
= get_sym_val(ELF32_R_SYM(rel
->r_info
));
6808 type
= ELF32_R_TYPE(rel
->r_info
);
6809 greloc_patch(ptr
, s
->addr
+ rel
->r_offset
, val
, type
);
6813 /* relocate all the code and data */
6814 static void relocate_program(void)
6818 /* compute relocation address : section are relocated in place */
6819 for(s
= first_section
; s
!= NULL
; s
= s
->next
) {
6820 if (s
->sh_type
== SHT_PROGBITS
)
6821 s
->addr
= (unsigned long)s
->data
;
6824 /* relocate each section */
6825 for(s
= first_section
; s
!= NULL
; s
= s
->next
) {
6826 if (s
->sh_type
== SHT_PROGBITS
)
6827 relocate_section(s
);
6831 /* launch the compiled program with the given arguments */
6832 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
6834 int (*prog_main
)(int, char **);
6837 resolve_extern_syms();
6841 sym_index
= find_elf_sym(symtab_section
, "main");
6843 error("main() not defined");
6844 prog_main
= (void *)get_sym_val(sym_index
);
6848 error("debug mode currently not available for Windows");
6850 struct sigaction sigact
;
6851 /* install TCC signal handlers to print debug info on fatal
6853 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
6854 sigact
.sa_sigaction
= sig_error
;
6855 sigemptyset(&sigact
.sa_mask
);
6856 sigaction(SIGFPE
, &sigact
, NULL
);
6857 sigaction(SIGILL
, &sigact
, NULL
);
6858 sigaction(SIGSEGV
, &sigact
, NULL
);
6859 sigaction(SIGBUS
, &sigact
, NULL
);
6860 sigaction(SIGABRT
, &sigact
, NULL
);
6864 #ifdef CONFIG_TCC_BCHECK
6865 if (do_bounds_check
) {
6868 /* add all known static regions */
6869 p
= (int *)bounds_section
->data
;
6870 p_end
= (int *)bounds_section
->data_ptr
;
6872 __bound_new_region((void *)p
[0], p
[1]);
6878 return (*prog_main
)(argc
, argv
);
6881 TCCState
*tcc_new(void)
6886 s
= malloc(sizeof(TCCState
));
6890 /* default include paths */
6891 nb_include_paths
= 0;
6892 tcc_add_include_path(s
, "/usr/include");
6893 tcc_add_include_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
6895 /* add all tokens */
6896 tok_ident
= TOK_IDENT
;
6901 tok_alloc(p
, r
- p
- 1);
6905 /* standard defines */
6906 tcc_define_symbol(s
, "__STDC__", NULL
);
6908 tcc_define_symbol(s
, "__i386__", NULL
);
6910 /* tiny C specific defines */
6911 tcc_define_symbol(s
, "__TINYC__", NULL
);
6913 /* create standard sections */
6915 text_section
= new_section(".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
6916 data_section
= new_section(".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6917 /* XXX: should change type to SHT_NOBITS */
6918 bss_section
= new_section(".bss", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
6920 /* symbols are always generated for linking stage */
6921 symtab_section
= new_section(".symtab", SHT_SYMTAB
, 0);
6922 symtab_section
->sh_entsize
= sizeof(Elf32_Sym
);
6923 strtab_section
= new_section(".strtab", SHT_STRTAB
, 0);
6924 put_elf_str(strtab_section
, "");
6925 symtab_section
->link
= strtab_section
;
6926 put_elf_sym(symtab_section
, 0, 0, 0, 0, 0, NULL
);
6928 /* private hash table for extern symbols */
6929 hashtab_section
= new_section(".hashtab", SHT_HASH
, SHF_PRIVATE
);
6930 ((int *)hashtab_section
->data
)[0] = ELF_SYM_HASH_SIZE
;
6931 ((int *)hashtab_section
->data
)[1] = 1;
6932 hashtab_section
->data_ptr
+= (2 + ELF_SYM_HASH_SIZE
+ 1) * 4;
6933 symtab_section
->hash
= hashtab_section
;
6937 void tcc_delete(TCCState
*s
)
6942 int tcc_add_include_path(TCCState
*s
, const char *pathname
)
6946 if (nb_include_paths
>= INCLUDE_PATHS_MAX
)
6948 pathname1
= strdup(pathname
);
6951 include_paths
[nb_include_paths
++] = pathname1
;
6955 #if !defined(LIBTCC)
6959 printf("tcc version 0.9.8 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
6960 "usage: tcc [-Idir] [-Dsym[=val]] [-Usym] [-llib] [-g] [-b]\n"
6961 " [-i infile] [-bench] infile [infile_args...]\n"
6963 "-Idir : add include path 'dir'\n"
6964 "-Dsym[=val] : define 'sym' with value 'val'\n"
6965 "-Usym : undefine 'sym'\n"
6966 "-llib : link with dynamic library 'lib'\n"
6967 "-g : generate runtime debug info\n"
6968 #ifdef CONFIG_TCC_BCHECK
6969 "-b : compile with built-in memory and bounds checker (implies -g)\n"
6971 "-i infile : compile infile\n"
6972 "-bench : output compilation statistics\n"
6976 int main(int argc
, char **argv
)
6979 int optind
, file_type
;
6983 file_type
= TCC_FILE_EXE
;
6988 if (optind
>= argc
) {
6998 if (tcc_add_include_path(s
, r
+ 2) < 0)
6999 error("too many include paths");
7000 } else if (r
[1] == 'D') {
7003 value
= strchr(sym
, '=');
7008 tcc_define_symbol(s
, sym
, value
);
7009 } else if (r
[1] == 'U') {
7010 tcc_undefine_symbol(s
, r
+ 2);
7011 } else if (r
[1] == 'l') {
7013 snprintf(buf
, sizeof(buf
), "lib%s.so", r
+ 2);
7014 tcc_add_dll(s
, buf
);
7015 } else if (r
[1] == 'i') {
7018 tcc_compile_file(s
, argv
[optind
++]);
7019 } else if (!strcmp(r
+ 1, "bench")) {
7021 #ifdef CONFIG_TCC_BCHECK
7022 } else if (r
[1] == 'b') {
7023 if (!do_bounds_check
) {
7024 do_bounds_check
= 1;
7026 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
7027 /* create bounds sections */
7028 bounds_section
= new_section(".bounds",
7029 SHT_PROGBITS
, SHF_ALLOC
);
7030 lbounds_section
= new_section(".lbounds",
7031 SHT_PROGBITS
, SHF_ALLOC
);
7032 /* debug is implied */
7036 } else if (r
[1] == 'g') {
7037 #ifdef CONFIG_TCC_BCHECK
7044 stab_section
= new_section(".stab", SHT_PROGBITS
, 0);
7045 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
7046 stabstr_section
= new_section(".stabstr", SHT_STRTAB
, 0);
7047 put_elf_str(stabstr_section
, "");
7048 stab_section
->link
= stabstr_section
;
7049 /* put first entry */
7050 put_stabs("", 0, 0, 0, 0);
7053 /* the following options are only for testing, so not
7056 file_type
= TCC_FILE_OBJ
;
7057 } else if (!strcmp(r
+ 1, "shared")) {
7058 file_type
= TCC_FILE_DLL
;
7059 } else if (r
[1] == 'o') {
7062 outfile
= argv
[optind
++];
7064 error("invalid option -- '%s'", r
);
7068 tcc_compile_file(s
, argv
[optind
]);
7071 printf("total: %d idents, %d lines, %d bytes\n",
7072 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
);
7076 tcc_output_file(s
, outfile
, file_type
);
7079 return tcc_run(s
, argc
- optind
, argv
+ optind
);