2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001 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.
27 #ifndef CONFIG_TCC_STATIC
32 /* preprocessor debug */
35 /* these sizes are dummy for unix, because malloc() does not use
36 memory when the pages are not used */
37 #define TEXT_SIZE (4*1024*1024)
38 #define DATA_SIZE (4*1024*1024)
40 /* amount of virtual memory associate to a section (currently, we do
42 #define SECTION_VSIZE (1024 * 1024)
44 #define INCLUDE_STACK_SIZE 32
45 #define IFDEF_STACK_SIZE 64
46 #define VSTACK_SIZE 64
47 #define STRING_MAX_SIZE 1024
48 #define INCLUDE_PATHS_MAX 32
50 #define TOK_HASH_SIZE 521
51 #define TOK_ALLOC_INCR 256 /* must be a power of two */
52 #define SYM_HASH_SIZE 263
54 /* token symbol management */
55 typedef struct TokenSym
{
56 struct TokenSym
*hash_next
;
57 int tok
; /* token number */
63 typedef union CValue
{
69 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
71 unsigned long long ull
;
78 typedef struct SValue
{
80 unsigned short r
; /* register + flags */
81 unsigned short r2
; /* second register, used for 'long long'
82 type. If not used, set to VT_CONST */
83 CValue c
; /* constant */
86 /* symbol management */
88 int v
; /* symbol token */
89 int t
; /* associated type */
90 int r
; /* associated register */
91 int c
; /* associated number */
92 struct Sym
*next
; /* next related symbol */
93 struct Sym
*prev
; /* prev symbol in stack */
94 struct Sym
*hash_next
; /* next symbol in hash table */
97 typedef struct SymStack
{
99 struct Sym
*hash
[SYM_HASH_SIZE
];
102 /* relocation entry (currently only used for functions or variables */
103 typedef struct Reloc
{
104 int type
; /* type of relocation */
105 int addr
; /* address of relocation */
106 struct Reloc
*next
; /* next relocation */
109 #define RELOC_ADDR32 1 /* 32 bits relocation */
110 #define RELOC_REL32 2 /* 32 bits relative relocation */
112 /* section definition */
113 typedef struct Section
{
114 char name
[64]; /* section name */
115 unsigned char *data
; /* section data */
116 unsigned char *data_ptr
; /* current data pointer */
117 struct Section
*next
;
120 /* GNUC attribute definition */
121 typedef struct AttributeDef
{
126 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
127 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
128 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
130 #define FUNC_NEW 1 /* ansi function prototype */
131 #define FUNC_OLD 2 /* old function prototype */
132 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
134 /* field 'Sym.t' for macros */
135 #define MACRO_OBJ 0 /* object like macro */
136 #define MACRO_FUNC 1 /* function like macro */
138 /* type_decl() types */
139 #define TYPE_ABSTRACT 1 /* type without variable */
140 #define TYPE_DIRECT 2 /* type with variable */
151 int ch
, ch1
, tok
, tok1
;
155 Section
*first_section
;
156 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
157 Section
*cur_text_section
; /* current section where function code is
160 /* loc : local variable index
161 ind : output code index
163 anon_sym: anonymous symbol index
166 prog
, ind
, loc
, const_wanted
;
167 int global_expr
; /* true if compound literals must be allocated
168 globally (used during initializers parsing */
169 int func_vt
, func_vc
; /* current function return type (used by
170 return instruction) */
172 TokenSym
**table_ident
;
173 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
174 char token_buf
[STRING_MAX_SIZE
+ 1];
175 char *filename
, *funcname
;
176 /* contains global symbols which remain between each translation unit */
177 SymStack extern_stack
;
178 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
180 SValue vstack
[VSTACK_SIZE
], *vtop
;
181 int *macro_ptr
, *macro_ptr_allocated
;
182 IncludeFile include_stack
[INCLUDE_STACK_SIZE
], *include_stack_ptr
;
183 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
184 char *include_paths
[INCLUDE_PATHS_MAX
];
185 int nb_include_paths
;
187 /* use GNU C extensions */
190 /* use Tiny C extensions */
193 /* The current value can be: */
194 #define VT_VALMASK 0x00ff
195 #define VT_CONST 0x00f0 /* constant in vc
196 (must be first non register value) */
197 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
198 #define VT_LOCAL 0x00f2 /* offset on stack */
199 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
200 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
201 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
202 #define VT_LVAL 0x0100 /* var is an lvalue */
203 #define VT_FORWARD 0x0200 /* value is forward reference */
204 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (user for
205 bool/char/short stored in int registers) */
208 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
210 #define VT_INT 0 /* integer type */
211 #define VT_BYTE 1 /* signed byte type */
212 #define VT_SHORT 2 /* short type */
213 #define VT_VOID 3 /* void type */
214 #define VT_PTR 4 /* pointer increment */
215 #define VT_ENUM 5 /* enum definition */
216 #define VT_FUNC 6 /* function type */
217 #define VT_STRUCT 7 /* struct/union definition */
218 #define VT_FLOAT 8 /* IEEE float */
219 #define VT_DOUBLE 9 /* IEEE double */
220 #define VT_LDOUBLE 10 /* IEEE long double */
221 #define VT_BOOL 11 /* ISOC99 boolean type */
222 #define VT_LLONG 12 /* 64 bit integer */
223 #define VT_LONG 13 /* long integer (NEVER USED as type, only
225 #define VT_BTYPE 0x000f /* mask for basic type */
226 #define VT_UNSIGNED 0x0010 /* unsigned type */
227 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
228 #define VT_BITFIELD 0x0040 /* bitfield modifier */
231 #define VT_EXTERN 0x00000080 /* extern definition */
232 #define VT_STATIC 0x00000100 /* static variable */
233 #define VT_TYPEDEF 0x00000200 /* typedef definition */
235 /* type mask (except storage) */
236 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
240 /* warning: the following compare tokens depend on i386 asm code */
252 #define TOK_LAND 0xa0
256 #define TOK_MID 0xa3 /* inc/dec, to void constant */
258 #define TOK_UDIV 0xb0 /* unsigned division */
259 #define TOK_UMOD 0xb1 /* unsigned modulo */
260 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
261 #define TOK_CINT 0xb3 /* number in tokc */
262 #define TOK_CCHAR 0xb4 /* char constant in tokc */
263 #define TOK_STR 0xb5 /* pointer to string in tokc */
264 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
265 #define TOK_LCHAR 0xb7
266 #define TOK_LSTR 0xb8
267 #define TOK_CFLOAT 0xb9 /* float constant */
268 #define TOK_CDOUBLE 0xc0 /* double constant */
269 #define TOK_CLDOUBLE 0xc1 /* long double constant */
270 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
271 #define TOK_ADDC1 0xc3 /* add with carry generation */
272 #define TOK_ADDC2 0xc4 /* add with carry use */
273 #define TOK_SUBC1 0xc5 /* add with carry generation */
274 #define TOK_SUBC2 0xc6 /* add with carry use */
275 #define TOK_CUINT 0xc8 /* unsigned int constant */
276 #define TOK_CLLONG 0xc9 /* long long constant */
277 #define TOK_CULLONG 0xca /* unsigned long long constant */
278 #define TOK_ARROW 0xcb
279 #define TOK_DOTS 0xcc /* three dots */
280 #define TOK_SHR 0xcd /* unsigned shift right */
282 #define TOK_SHL 0x01 /* shift left */
283 #define TOK_SAR 0x02 /* signed shift right */
285 /* assignement operators : normal operator or 0x80 */
286 #define TOK_A_MOD 0xa5
287 #define TOK_A_AND 0xa6
288 #define TOK_A_MUL 0xaa
289 #define TOK_A_ADD 0xab
290 #define TOK_A_SUB 0xad
291 #define TOK_A_DIV 0xaf
292 #define TOK_A_XOR 0xde
293 #define TOK_A_OR 0xfc
294 #define TOK_A_SHL 0x81
295 #define TOK_A_SAR 0x82
297 /* all identificators and strings have token above that */
298 #define TOK_IDENT 256
319 /* ignored types Must have contiguous values */
329 /* unsupported type */
343 /* preprocessor only */
344 TOK_UIDENT
, /* first "user" ident (not keyword) */
345 TOK_DEFINE
= TOK_UIDENT
,
361 /* special identifiers */
364 /* attribute identifiers */
373 /* XXX: need to define this to use them in non ISOC99 context */
374 extern float strtof (const char *__nptr
, char **__endptr
);
375 extern long double strtold (const char *__nptr
, char **__endptr
);
379 void next_nomacro(void);
380 int expr_const(void);
384 void decl_initializer(int t
, int r
, int c
, int first
, int size_only
);
385 int decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
);
387 void move_reg(int r
, int s
);
388 void save_reg(int r
);
394 void macro_subst(int **tok_str
, int *tok_len
,
395 Sym
**nested_list
, int *macro_str
);
396 int save_reg_forced(int r
);
398 void force_charshort_cast(int t
);
399 void gen_cast(int t
);
403 int type_size(int t
, int *a
);
404 int pointed_type(int t
);
405 int pointed_size(int t
);
406 int is_compatible_types(int t1
, int t2
);
407 int parse_btype(int *type_ptr
, AttributeDef
*ad
);
408 int type_decl(int *v
, int t
, int td
);
410 void error(const char *fmt
, ...);
412 void vset(int t
, int r
, int v
);
413 void greloc(Sym
*s
, int addr
, int type
);
414 void type_to_str(char *buf
, int buf_size
,
415 int t
, const char *varstr
);
417 /* true if float/double/long double type */
418 static inline int is_float(int t
)
422 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
425 #include "i386-gen.c"
427 #ifdef CONFIG_TCC_STATIC
429 #define RTLD_LAZY 0x001
430 #define RTLD_NOW 0x002
431 #define RTLD_GLOBAL 0x100
433 /* dummy function for profiling */
434 void *dlopen(const char *filename
, int flag
)
439 const char *dlerror(void)
444 typedef struct TCCSyms
{
449 #define TCCSYM(a) { #a, &a, },
451 /* add the symbol you want here if no dynamic linking is done */
452 static TCCSyms tcc_syms
[] = {
460 void *dlsym(void *handle
, char *symbol
)
464 while (p
->str
!= NULL
) {
465 if (!strcmp(p
->str
, symbol
))
474 /********************************************************/
475 /* runtime library is there */
476 /* XXX: we suppose that the host compiler handles 'long long'. It
477 would not be difficult to suppress this assumption */
479 /* XXX: these functions are defined in libgcc. Should provide a
480 portable code too. */
481 long long __divll(long long a
, long long b
)
486 long long __modll(long long a
, long long b
)
491 unsigned long long __divull(unsigned long long a
, unsigned long long b
)
496 unsigned long long __modull(unsigned long long a
, unsigned long long b
)
501 long long __sardi3(long long a
, int b
)
506 unsigned long long __shrdi3(unsigned long long a
, int b
)
511 long long __shldi3(long long a
, int b
)
516 float __ulltof(unsigned long long a
)
521 double __ulltod(unsigned long long a
)
526 long double __ulltold(unsigned long long a
)
528 return (long double)a
;
531 unsigned long long __ftoull(float a
)
533 return (unsigned long long)a
;
536 unsigned long long __dtoull(double a
)
538 return (unsigned long long)a
;
541 unsigned long long __ldtoull(long double a
)
543 return (unsigned long long)a
;
547 /********************************************************/
549 /* copy a string and trucate it */
550 char *pstrcpy(char *buf
, int buf_size
, const char *s
)
556 q_end
= buf
+ buf_size
- 1;
567 Section
*new_section(const char *name
)
569 Section
*sec
, **psec
;
572 sec
= malloc(sizeof(Section
));
574 error("memory full");
575 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
576 data
= mmap(NULL
, SECTION_VSIZE
,
577 PROT_EXEC
| PROT_READ
| PROT_WRITE
,
578 MAP_PRIVATE
| MAP_ANONYMOUS
,
580 if (data
== (void *)(-1))
581 error("could not mmap section '%s'", name
);
583 sec
->data_ptr
= data
;
584 psec
= &first_section
;
585 while (*psec
!= NULL
)
586 psec
= &(*psec
)->next
;
592 /* return a reference to a section, and create it if it does not
594 Section
*find_section(const char *name
)
598 for(sec
= first_section
; sec
!= NULL
; sec
= sec
->next
) {
599 if (!strcmp(name
, sec
->name
))
602 return new_section(name
);
605 /* add a new relocation entry to symbol 's' */
606 void greloc(Sym
*s
, int addr
, int type
)
609 p
= malloc(sizeof(Reloc
));
611 error("memory full");
614 p
->next
= (Reloc
*)s
->c
;
618 /* patch each relocation entry with value 'val' */
619 void greloc_patch(Sym
*s
, int val
)
626 greloc_patch1(p
, val
);
635 static inline int isid(int c
)
637 return (c
>= 'a' && c
<= 'z') ||
638 (c
>= 'A' && c
<= 'Z') ||
642 static inline int isnum(int c
)
644 return c
>= '0' && c
<= '9';
647 static inline int toup(int c
)
649 if (ch
>= 'a' && ch
<= 'z')
650 return ch
- 'a' + 'A';
658 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
659 fprintf(stderr
, "In file included from %s:%d:\n",
660 f
->filename
, f
->line_num
);
661 fprintf(stderr
, "%s:%d: ", filename
, line_num
);
664 void error(const char *fmt
, ...)
669 vfprintf(stderr
, fmt
, ap
);
670 fprintf(stderr
, "\n");
675 void expect(const char *msg
)
677 error("%s expected", msg
);
680 void warning(const char *fmt
, ...)
686 fprintf(stderr
, "warning: ");
687 vfprintf(stderr
, fmt
, ap
);
688 fprintf(stderr
, "\n");
695 error("'%c' expected", c
);
699 void test_lvalue(void)
701 if (!(vtop
->r
& VT_LVAL
))
705 TokenSym
*tok_alloc(const char *str
, int len
)
707 TokenSym
*ts
, **pts
, **ptable
;
714 h
= ((h
<< 8) | (str
[i
] & 0xff)) % TOK_HASH_SIZE
;
716 pts
= &hash_ident
[h
];
721 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
723 pts
= &(ts
->hash_next
);
726 if (tok_ident
>= SYM_FIRST_ANOM
)
727 error("memory full");
729 /* expand token table if needed */
730 i
= tok_ident
- TOK_IDENT
;
731 if ((i
% TOK_ALLOC_INCR
) == 0) {
732 ptable
= realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
734 error("memory full");
735 table_ident
= ptable
;
738 ts
= malloc(sizeof(TokenSym
) + len
);
740 error("memory full");
742 ts
->tok
= tok_ident
++;
744 ts
->hash_next
= NULL
;
745 memcpy(ts
->str
, str
, len
+ 1);
750 void add_char(char **pp
, int c
)
754 if (c
== '\'' || c
== '\"' || c
== '\\') {
755 /* XXX: could be more precise if char or string */
758 if (c
>= 32 && c
<= 126) {
765 *p
++ = '0' + ((c
>> 6) & 7);
766 *p
++ = '0' + ((c
>> 3) & 7);
767 *p
++ = '0' + (c
& 7);
773 /* XXX: buffer overflow */
774 char *get_tok_str(int v
, CValue
*cv
)
776 static char buf
[STRING_MAX_SIZE
+ 1];
781 if (v
== TOK_CINT
|| v
== TOK_CUINT
) {
782 sprintf(buf
, "%u", cv
->ui
);
784 } else if (v
== TOK_CCHAR
|| v
== TOK_LCHAR
) {
791 } else if (v
== TOK_STR
|| v
== TOK_LSTR
) {
795 for(i
=0;i
<ts
->len
;i
++)
796 add_char(&p
, ts
->str
[i
]);
800 } else if (v
< TOK_IDENT
) {
805 } else if (v
< tok_ident
) {
806 return table_ident
[v
- TOK_IDENT
]->str
;
808 /* should never happen */
813 /* push, without hashing */
814 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
817 s
= malloc(sizeof(Sym
));
819 error("memory full");
830 /* find a symbol and return its associated structure. 's' is the top
831 of the symbol stack */
832 Sym
*sym_find2(Sym
*s
, int v
)
842 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
844 /* find a symbol and return its associated structure. 'st' is the
846 Sym
*sym_find1(SymStack
*st
, int v
)
850 s
= st
->hash
[HASH_SYM(v
)];
859 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
862 s
= sym_push2(&st
->top
, v
, t
, c
);
863 /* add in hash table */
865 ps
= &st
->hash
[HASH_SYM(v
)];
872 /* find a symbol in the right symbol space */
876 s
= sym_find1(&local_stack
, v
);
878 s
= sym_find1(&global_stack
, v
);
882 /* push a given symbol on the symbol stack */
883 Sym
*sym_push(int v
, int t
, int r
, int c
)
887 s
= sym_push1(&local_stack
, v
, t
, c
);
889 s
= sym_push1(&global_stack
, v
, t
, c
);
894 /* pop symbols until top reaches 'b' */
895 void sym_pop(SymStack
*st
, Sym
*b
)
902 /* free hash table entry, except if symbol was freed (only
903 used for #undef symbols) */
905 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
912 /* undefined a hashed symbol (used for #undef). Its name is set to
914 void sym_undef(SymStack
*st
, Sym
*s
)
917 ss
= &st
->hash
[HASH_SYM(s
->v
)];
918 while (*ss
!= NULL
) {
921 ss
= &(*ss
)->hash_next
;
927 /* no need to put that inline */
930 if (include_stack_ptr
== include_stack
)
932 /* pop include stack */
936 file
= include_stack_ptr
->file
;
937 filename
= include_stack_ptr
->filename
;
938 line_num
= include_stack_ptr
->line_num
;
942 /* read next char from current input file */
943 static inline void inp(void)
946 /* faster than fgetc */
947 ch1
= getc_unlocked(file
);
949 if (handle_eof() < 0)
956 // printf("ch1=%c 0x%x\n", ch1, ch1);
959 /* input with '\\n' handling */
960 static inline void minp(void)
965 if (ch
== '\\' && ch1
== '\n') {
969 //printf("ch=%c 0x%x\n", ch, ch);
973 /* same as minp, but also skip comments */
981 /* single line C++ comments */
983 while (ch1
!= '\n' && ch1
!= -1)
986 ch
= ' '; /* return space */
987 } else if (ch1
== '*') {
993 if (c
== '*' && ch1
== '/') {
995 ch
= ' '; /* return space */
1007 void skip_spaces(void)
1009 while (ch
== ' ' || ch
== '\t')
1013 /* skip block of text until #else, #elif or #endif. skip also pairs of
1015 void preprocess_skip()
1020 while (ch
!= '\n') {
1031 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1033 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1035 else if (tok
== TOK_ENDIF
)
1041 /* return the number of additionnal 'ints' necessary to store the
1043 static inline int tok_ext_size(int t
)
1060 return LDOUBLE_SIZE
/ 4;
1066 void tok_add(int **tok_str
, int *tok_len
, int t
)
1071 if ((len
& 63) == 0) {
1072 str
= realloc(str
, (len
+ 64) * sizeof(int));
1081 void tok_add2(int **tok_str
, int *tok_len
, int t
, CValue
*cv
)
1085 tok_add(tok_str
, tok_len
, t
);
1086 n
= tok_ext_size(t
);
1088 tok_add(tok_str
, tok_len
, cv
->tab
[i
]);
1091 /* get a token from an integer array and increment pointer accordingly */
1092 int tok_get(int **tok_str
, CValue
*cv
)
1098 n
= tok_ext_size(t
);
1105 /* eval an expression for #if/#elif */
1106 int expr_preprocess(void)
1108 int *str
, len
, c
, t
;
1116 next(); /* do macro subst */
1117 if (tok
== TOK_DEFINED
) {
1122 c
= sym_find1(&define_stack
, tok
) != 0;
1127 } else if (tok
>= TOK_IDENT
) {
1128 /* if undefined macro */
1132 tok_add2(&str
, &len
, tok
, &tokc
);
1134 tok_add(&str
, &len
, -1); /* simulate end of file */
1135 tok_add(&str
, &len
, 0);
1136 /* now evaluate C constant expression */
1146 void tok_print(int *str
)
1152 t
= tok_get(&str
, &cval
);
1155 printf(" %s", get_tok_str(t
, &cval
));
1161 void preprocess(void)
1163 int size
, i
, c
, v
, t
, *str
, len
;
1164 char buf
[1024], *q
, *p
;
1167 Sym
**ps
, *first
, *s
;
1172 if (tok
== TOK_DEFINE
) {
1175 /* XXX: should check if same macro (ANSI) */
1178 /* '(' must be just after macro definition for MACRO_FUNC */
1183 while (tok
!= ')') {
1184 if (tok
== TOK_DOTS
)
1185 tok
= TOK___VA_ARGS__
;
1186 s
= sym_push1(&define_stack
, tok
| SYM_FIELD
, 0, 0);
1200 if (ch
== '\n' || ch
== -1)
1203 tok_add2(&str
, &len
, tok
, &tokc
);
1205 tok_add(&str
, &len
, 0);
1207 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1210 s
= sym_push1(&define_stack
, v
, t
, (int)str
);
1212 } else if (tok
== TOK_UNDEF
) {
1214 s
= sym_find1(&define_stack
, tok
);
1215 /* undefine symbol by putting an invalid name */
1217 sym_undef(&define_stack
, s
);
1218 } else if (tok
== TOK_INCLUDE
) {
1223 } else if (ch
== '\"') {
1228 while (ch
!= c
&& ch
!= '\n' && ch
!= -1) {
1229 if ((q
- buf
) < sizeof(buf
) - 1)
1237 error("#include syntax error");
1238 /* XXX: buffer overflow */
1239 strcpy(buf
, get_tok_str(tok
, &tokc
));
1242 /* eat all spaces and comments after include */
1243 /* XXX: slightly incorrect */
1244 while (ch1
!= '\n' && ch1
!= -1)
1247 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1248 error("memory full");
1250 /* first search in current dir if "header.h" */
1251 /* XXX: buffer overflow */
1253 p
= strrchr(filename
, '/');
1255 size
= p
+ 1 - filename
;
1256 memcpy(buf1
, filename
, size
);
1259 f
= fopen(buf1
, "r");
1263 /* now search in standard include path */
1264 for(i
=nb_include_paths
- 1;i
>=0;i
--) {
1265 strcpy(buf1
, include_paths
[i
]);
1268 f
= fopen(buf1
, "r");
1272 error("include file '%s' not found", buf1
);
1275 /* push current file in stack */
1276 /* XXX: fix current line init */
1277 include_stack_ptr
->file
= file
;
1278 include_stack_ptr
->filename
= filename
;
1279 include_stack_ptr
->line_num
= line_num
;
1280 include_stack_ptr
++;
1282 filename
= strdup(buf1
);
1284 } else if (tok
== TOK_IFNDEF
) {
1287 } else if (tok
== TOK_IF
) {
1288 c
= expr_preprocess();
1290 } else if (tok
== TOK_IFDEF
) {
1294 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1296 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1297 error("memory full");
1298 *ifdef_stack_ptr
++ = c
;
1300 } else if (tok
== TOK_ELSE
) {
1301 if (ifdef_stack_ptr
== ifdef_stack
||
1302 (ifdef_stack_ptr
[-1] & 2))
1303 error("#else after #else");
1304 c
= (ifdef_stack_ptr
[-1] ^= 3);
1306 } else if (tok
== TOK_ELIF
) {
1307 if (ifdef_stack_ptr
== ifdef_stack
||
1308 ifdef_stack_ptr
[-1] > 1)
1309 error("#elif after #else");
1310 c
= expr_preprocess();
1311 ifdef_stack_ptr
[-1] = c
;
1317 } else if (tok
== TOK_ENDIF
) {
1318 if (ifdef_stack_ptr
== ifdef_stack
)
1321 } else if (tok
== TOK_LINE
) {
1323 if (tok
!= TOK_CINT
)
1331 /* XXX: potential memory leak */
1332 filename
= strdup(get_tok_str(tok
, &tokc
));
1334 } else if (tok
== TOK_ERROR
) {
1337 /* ignore other preprocess commands or #! for C scripts */
1338 while (ch
!= '\n' && ch
!= -1)
1342 /* read a number in base b */
1348 if (ch
>= 'a' && ch
<= 'f')
1350 else if (ch
>= 'A' && ch
<= 'F')
1356 if (t
< 0 || t
>= b
)
1364 /* read a character for string or char constant and eval escape codes */
1373 /* at most three octal digits */
1377 c
= c
* 8 + ch
- '0';
1380 c
= c
* 8 + ch
- '0';
1385 } else if (ch
== 'x') {
1403 else if (ch
== 'e' && gnu_ext
)
1405 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
1408 error("invalid escaped char");
1415 /* we use 64 bit numbers */
1418 /* bn = (bn << shift) | or_val */
1419 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
1423 for(i
=0;i
<BN_SIZE
;i
++) {
1425 bn
[i
] = (v
<< shift
) | or_val
;
1426 or_val
= v
>> (32 - shift
);
1430 void bn_zero(unsigned int *bn
)
1433 for(i
=0;i
<BN_SIZE
;i
++) {
1438 void parse_number(void)
1440 int b
, t
, shift
, frac_bits
, s
, exp_val
;
1442 unsigned int bn
[BN_SIZE
];
1452 /* special dot handling */
1453 if (ch
>= '0' && ch
<= '9') {
1454 goto float_frac_parse
;
1455 } else if (ch
== '.') {
1466 } else if (t
== '0') {
1467 if (ch
== 'x' || ch
== 'X') {
1471 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
1477 /* parse all digits. cannot check octal numbers at this stage
1478 because of floating point constants */
1480 if (ch
>= 'a' && ch
<= 'f')
1482 else if (ch
>= 'A' && ch
<= 'F')
1490 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
1492 error("number too long");
1498 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
1499 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
1501 /* NOTE: strtox should support that for hexa numbers, but
1502 non ISOC99 libcs do not support it, so we prefer to do
1504 /* hexadecimal or binary floats */
1505 /* XXX: handle overflows */
1517 } else if (t
>= 'a') {
1519 } else if (t
>= 'A') {
1524 bn_lshift(bn
, shift
, t
);
1531 if (t
>= 'a' && t
<= 'f') {
1533 } else if (t
>= 'A' && t
<= 'F') {
1535 } else if (t
>= '0' && t
<= '9') {
1541 error("invalid digit");
1542 bn_lshift(bn
, shift
, t
);
1547 if (ch
!= 'p' && ch
!= 'P')
1548 error("exponent expected");
1554 } else if (ch
== '-') {
1558 if (ch
< '0' || ch
> '9')
1559 error("exponent digits expected");
1560 while (ch
>= '0' && ch
<= '9') {
1561 exp_val
= exp_val
* 10 + ch
- '0';
1564 exp_val
= exp_val
* s
;
1566 /* now we can generate the number */
1567 /* XXX: should patch directly float number */
1568 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
1569 d
= ldexp(d
, exp_val
- frac_bits
);
1574 /* float : should handle overflow */
1576 } else if (t
== 'L') {
1579 /* XXX: not large enough */
1580 tokc
.ld
= (long double)d
;
1586 /* decimal floats */
1588 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1593 while (ch
>= '0' && ch
<= '9') {
1594 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1600 if (ch
== 'e' || ch
== 'E') {
1601 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1605 if (ch
== '-' || ch
== '+') {
1606 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1611 if (ch
< '0' || ch
> '9')
1612 error("exponent digits expected");
1613 while (ch
>= '0' && ch
<= '9') {
1614 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1626 tokc
.f
= strtof(token_buf
, NULL
);
1627 } else if (t
== 'L') {
1630 tokc
.ld
= strtold(token_buf
, NULL
);
1633 tokc
.d
= strtod(token_buf
, NULL
);
1637 unsigned long long n
, n1
;
1640 /* integer number */
1643 if (b
== 10 && *q
== '0') {
1650 /* no need for checks except for base 10 / 8 errors */
1653 } else if (t
>= 'a') {
1655 } else if (t
>= 'A') {
1660 error("invalid digit");
1664 /* detect overflow */
1666 error("integer constant overflow");
1669 /* XXX: not exactly ANSI compliant */
1670 if ((n
& 0xffffffff00000000LL
) != 0) {
1675 } else if (n
> 0x7fffffff) {
1685 error("three 'l' in integer constant");
1688 if (tok
== TOK_CINT
)
1690 else if (tok
== TOK_CUINT
)
1694 } else if (t
== 'U') {
1695 if (tok
== TOK_CINT
)
1697 else if (tok
== TOK_CLLONG
)
1704 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
1712 /* return next token without macro substitution */
1713 void next_nomacro1(void)
1721 while (ch
== '\n') {
1723 while (ch
== ' ' || ch
== 9)
1726 /* preprocessor command if # at start of line after
1731 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
1749 while (isid(ch
) || isnum(ch
)) {
1750 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1751 error("ident too long");
1756 ts
= tok_alloc(token_buf
, q
- token_buf
);
1758 } else if (isnum(ch
) || ch
== '.') {
1760 } else if (ch
== '\'') {
1768 } else if (ch
== '\"') {
1773 while (ch
!= '\"') {
1776 error("unterminated string");
1777 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1778 error("string too long");
1782 tokc
.ts
= tok_alloc(token_buf
, q
- token_buf
);
1785 q
= "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
1790 if (*q
== tok
&& q
[1] == ch
) {
1793 /* three chars tests */
1794 if (tok
== TOK_SHL
|| tok
== TOK_SAR
) {
1799 } else if (tok
== TOK_DOTS
) {
1801 error("parse error");
1808 /* single char substitutions */
1811 else if (tok
== '>')
1816 /* return next token without macro substitution. Can read input from
1823 tok
= tok_get(¯o_ptr
, &tokc
);
1829 /* substitute args in macro_str and return allocated string */
1830 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
1832 int *st
, last_tok
, t
, notfirst
, *str
, len
;
1841 t
= tok_get(¯o_str
, &cval
);
1846 t
= tok_get(¯o_str
, &cval
);
1849 s
= sym_find2(args
, t
);
1851 token_buf
[0] = '\0';
1853 /* XXX: buffer overflow */
1857 strcat(token_buf
, " ");
1858 t
= tok_get(&st
, &cval
);
1859 strcat(token_buf
, get_tok_str(t
, &cval
));
1863 printf("stringize: %s\n", token_buf
);
1866 ts
= tok_alloc(token_buf
, 0);
1868 tok_add2(&str
, &len
, TOK_STR
, &cval
);
1870 tok_add2(&str
, &len
, t
, &cval
);
1872 } else if (t
>= TOK_IDENT
) {
1873 s
= sym_find2(args
, t
);
1876 /* if '##' is present before or after , no arg substitution */
1877 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
1879 tok_add(&str
, &len
, *st
++);
1881 macro_subst(&str
, &len
, nested_list
, st
);
1884 tok_add(&str
, &len
, t
);
1887 tok_add2(&str
, &len
, t
, &cval
);
1891 tok_add(&str
, &len
, 0);
1895 /* handle the '##' operator */
1896 int *macro_twosharps(int *macro_str
)
1899 int *macro_str1
, macro_str1_len
, *macro_ptr1
;
1911 while (*macro_ptr
== TOK_TWOSHARPS
) {
1913 macro_ptr1
= macro_ptr
;
1916 t
= tok_get(¯o_ptr
, &cval
);
1917 /* XXX: we handle only most common cases:
1918 ident + ident or ident + number */
1919 if (tok
>= TOK_IDENT
&&
1920 (t
>= TOK_IDENT
|| t
== TOK_CINT
)) {
1921 /* XXX: buffer overflow */
1922 p
= get_tok_str(tok
, &tokc
);
1923 strcpy(token_buf
, p
);
1924 p
= get_tok_str(t
, &cval
);
1925 strcat(token_buf
, p
);
1926 ts
= tok_alloc(token_buf
, 0);
1927 tok
= ts
->tok
; /* modify current token */
1929 /* cannot merge tokens: skip '##' */
1930 macro_ptr
= macro_ptr1
;
1935 tok_add2(¯o_str1
, ¯o_str1_len
, tok
, &tokc
);
1937 tok_add(¯o_str1
, ¯o_str1_len
, 0);
1943 /* do macro substitution of macro_str and add result to
1944 (tok_str,tok_len). If macro_str is NULL, then input stream token is
1945 substituted. 'nested_list' is the list of all macros we got inside
1946 to avoid recursing. */
1947 void macro_subst(int **tok_str
, int *tok_len
,
1948 Sym
**nested_list
, int *macro_str
)
1950 Sym
*s
, *args
, *sa
, *sa1
;
1951 int *str
, parlevel
, len
, *mstr
, t
, *saved_macro_ptr
;
1952 int mstr_allocated
, *macro_str1
;
1955 saved_macro_ptr
= macro_ptr
;
1956 macro_ptr
= macro_str
;
1959 /* first scan for '##' operator handling */
1960 macro_str1
= macro_twosharps(macro_str
);
1961 macro_ptr
= macro_str1
;
1968 /* special macros */
1969 if (tok
== TOK___LINE__
) {
1971 tok_add2(tok_str
, tok_len
, TOK_CINT
, &cval
);
1972 } else if (tok
== TOK___FILE__
) {
1973 cval
.ts
= tok_alloc(filename
, 0);
1974 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
1975 } else if (tok
== TOK___DATE__
) {
1976 cval
.ts
= tok_alloc("Jan 1 1970", 0);
1977 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
1978 } else if (tok
== TOK___TIME__
) {
1979 cval
.ts
= tok_alloc("00:00:00", 0);
1980 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
1981 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
1982 /* if symbol is a macro, prepare substitution */
1983 /* if nested substitution, do nothing */
1984 if (sym_find2(*nested_list
, tok
))
1988 if (s
->t
== MACRO_FUNC
) {
1989 /* NOTE: we do not use next_nomacro to avoid eating the
1990 next token. XXX: find better solution */
1994 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
1998 if (t
!= '(') /* no macro subst */
2001 /* argument macro */
2006 while (tok
!= ')' && sa
) {
2010 while ((parlevel
> 0 ||
2013 sa
->v
== (TOK___VA_ARGS__
| SYM_FIELD
)))) &&
2017 else if (tok
== ')')
2019 tok_add2(&str
, &len
, tok
, &tokc
);
2022 tok_add(&str
, &len
, 0);
2023 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, 0, (int)str
);
2031 /* now subst each arg */
2032 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
2043 sym_push2(nested_list
, s
->v
, 0, 0);
2044 macro_subst(tok_str
, tok_len
, nested_list
, mstr
);
2045 /* pop nested defined symbol */
2047 *nested_list
= sa1
->prev
;
2053 /* no need to add if reading input stream */
2056 tok_add2(tok_str
, tok_len
, tok
, &tokc
);
2058 /* only replace one macro while parsing input stream */
2062 macro_ptr
= saved_macro_ptr
;
2067 /* return next token with macro substitution */
2073 /* special 'ungettok' case for label parsing */
2081 /* if not reading from macro substuted string, then try to substitute */
2085 macro_subst(&ptr
, &len
, &nested_list
, NULL
);
2087 tok_add(&ptr
, &len
, 0);
2089 macro_ptr_allocated
= ptr
;
2097 /* end of macro string: free it */
2098 free(macro_ptr_allocated
);
2105 printf("token = %s\n", get_tok_str(tok
, tokc
));
2109 void swap(int *p
, int *q
)
2117 void vsetc(int t
, int r
, CValue
*vc
)
2119 if (vtop
>= vstack
+ VSTACK_SIZE
)
2120 error("memory full");
2121 /* cannot let cpu flags if other instruction are generated */
2122 /* XXX: VT_JMP test too ? */
2123 if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
2128 vtop
->r2
= VT_CONST
;
2132 /* push integer constant */
2137 vsetc(VT_INT
, VT_CONST
, &cval
);
2140 void vset(int t
, int r
, int v
)
2157 void vpushv(SValue
*v
)
2159 if (vtop
>= vstack
+ VSTACK_SIZE
)
2160 error("memory full");
2170 /* save r to the memory stack, and mark it as being free */
2171 void save_reg(int r
)
2173 int l
, i
, saved
, t
, size
, align
;
2176 /* modify all stack values */
2179 for(p
=vstack
;p
<=vtop
;p
++) {
2180 i
= p
->r
& VT_VALMASK
;
2181 if ((p
->r
& VT_VALMASK
) == r
||
2182 (p
->r2
& VT_VALMASK
) == r
) {
2183 /* must save value on stack if not already done */
2185 /* store register in the stack */
2187 if (!is_float(t
) && (t
& VT_BTYPE
) != VT_LLONG
)
2189 size
= type_size(t
, &align
);
2190 loc
= (loc
- size
) & -align
;
2192 sv
.r
= VT_LOCAL
| VT_LVAL
;
2195 /* XXX: x86 specific: need to pop fp register ST0 if saved */
2197 o(0xd9dd); /* fstp %st(1) */
2199 /* special long long case */
2200 if ((p
->t
& VT_BTYPE
) == VT_LLONG
) {
2207 /* mark that stack entry as being saved on the stack */
2219 /* find a free register of class 'rc'. If none, save one register */
2225 /* find a free register */
2226 for(r
=0;r
<NB_REGS
;r
++) {
2227 if (reg_classes
[r
] & rc
) {
2228 for(p
=vstack
;p
<=vtop
;p
++) {
2229 if ((p
->r
& VT_VALMASK
) == r
||
2230 (p
->r2
& VT_VALMASK
) == r
)
2238 /* no register left : free the first one on the stack (VERY
2239 IMPORTANT to start from the bottom to ensure that we don't
2240 spill registers used in gen_opi()) */
2241 for(p
=vstack
;p
<=vtop
;p
++) {
2242 r
= p
->r
& VT_VALMASK
;
2243 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
2251 void save_regs(void)
2256 for(p
=vstack
;p
<=vtop
;p
++) {
2257 r
= p
->r
& VT_VALMASK
;
2264 /* move register 's' to 'r', and flush previous value of r to memory
2266 void move_reg(int r
, int s
)
2279 /* store vtop a register belonging to class 'rc'. lvalues are
2280 converted to values. Cannot be used if cannot be converted to
2281 register value (such as structures). */
2284 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
, data_offset
;
2285 unsigned long long ll
;
2287 /* NOTE: get_reg can modify vstack[] */
2288 if (vtop
->t
& VT_BITFIELD
) {
2289 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2290 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2291 /* remove bit field info to avoid loops */
2292 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2293 /* generate shifts */
2294 vpushi(32 - (bit_pos
+ bit_size
));
2296 vpushi(32 - bit_size
);
2297 /* NOTE: transformed to SHR if unsigned */
2301 if (is_float(vtop
->t
) &&
2302 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2303 /* CPUs usually cannot use float constants, so we store them
2304 generically in data segment */
2305 size
= type_size(vtop
->t
, &align
);
2306 data_offset
= (int)data_section
->data_ptr
;
2307 data_offset
= (data_offset
+ align
- 1) & -align
;
2308 /* XXX: not portable yet */
2311 ((int *)data_offset
)[i
] = vtop
->c
.tab
[i
];
2313 vtop
->c
.ul
= data_offset
;
2314 data_offset
+= size
<< 2;
2315 data_section
->data_ptr
= (unsigned char *)data_offset
;
2317 r
= vtop
->r
& VT_VALMASK
;
2318 /* need to reload if:
2320 - lvalue (need to dereference pointer)
2321 - already a register, but not in the right class */
2322 if (r
>= VT_CONST
||
2323 (vtop
->r
& VT_LVAL
) ||
2324 !(reg_classes
[r
] & rc
) ||
2325 ((vtop
->t
& VT_BTYPE
) == VT_LLONG
&&
2326 !(reg_classes
[vtop
->r2
] & rc
))) {
2328 if ((vtop
->t
& VT_BTYPE
) == VT_LLONG
) {
2329 /* two register type load : expand to two words
2331 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
2334 vtop
->c
.ui
= ll
; /* first word */
2336 vtop
->r
= r
; /* save register value */
2337 vpushi(ll
>> 32); /* second word */
2338 } else if (r
>= VT_CONST
||
2339 (vtop
->r
& VT_LVAL
)) {
2340 /* load from memory */
2343 vtop
[-1].r
= r
; /* save register value */
2344 /* increment pointer to get second word */
2346 vtop
->r
&= ~VT_LVAL
;
2351 /* move registers */
2354 vtop
[-1].r
= r
; /* save register value */
2355 vtop
->r
= vtop
[-1].r2
;
2357 /* allocate second register */
2364 /* write second register */
2367 /* one register type load */
2376 /* expand long long on stack in two int registers */
2381 u
= vtop
->t
& VT_UNSIGNED
;
2384 vtop
[0].r
= vtop
[-1].r2
;
2385 vtop
[0].r2
= VT_CONST
;
2386 vtop
[-1].r2
= VT_CONST
;
2387 vtop
[0].t
= VT_INT
| u
;
2388 vtop
[-1].t
= VT_INT
| u
;
2391 /* build a long long from two ints */
2398 vtop
[-1].r2
= vtop
[0].r
;
2403 /* rotate n first stack elements to the bottom */
2410 for(i
=-n
+1;i
!=0;i
++)
2411 vtop
[i
] = vtop
[i
+1];
2415 /* pop stack value */
2418 /* for x86, we need to pop the FP stack */
2419 if ((vtop
->r
& VT_VALMASK
) == REG_ST0
) {
2420 o(0xd9dd); /* fstp %st(1) */
2425 /* convert stack entry to register and duplicate its value in another
2433 if ((t
& VT_BTYPE
) == VT_LLONG
) {
2440 /* stack: H L L1 H1 */
2448 /* duplicate value */
2459 load(r1
, &sv
); /* move r to r1 */
2461 /* duplicates value */
2466 /* generate CPU independent (unsigned) long long operations */
2467 void gen_opl(int op
)
2469 int t
, a
, b
, op1
, c
, i
;
2488 /* call generic long long function */
2496 vtop
->r2
= REG_LRET
;
2509 /* stack: L1 H1 L2 H2 */
2514 vtop
[-2] = vtop
[-3];
2517 /* stack: H1 H2 L1 L2 */
2523 /* stack: H1 H2 L1 L2 ML MH */
2526 /* stack: ML MH H1 H2 L1 L2 */
2530 /* stack: ML MH H1 L2 H2 L1 */
2535 /* stack: ML MH M1 M2 */
2538 } else if (op
== '+' || op
== '-') {
2539 /* XXX: add non carry method too (for MIPS ?) */
2545 /* stack: H1 H2 (L1 op L2) */
2548 gen_op(op1
+ 1); /* TOK_xxxC2 */
2551 /* stack: H1 H2 (L1 op L2) */
2554 /* stack: (L1 op L2) H1 H2 */
2556 /* stack: (L1 op L2) (H1 op H2) */
2564 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
) {
2569 /* stack: L H shift */
2571 /* constant: simpler */
2572 /* NOTE: all comments are for SHL. the other cases are
2573 done by swaping words */
2584 if (op
!= TOK_SAR
) {
2614 /* XXX: should provide a faster fallback on x86 ? */
2629 /* compare operations */
2635 /* stack: L1 H1 L2 H2 */
2637 vtop
[-1] = vtop
[-2];
2639 /* stack: L1 L2 H1 H2 */
2642 /* when values are equal, we need to compare low words. since
2643 the jump is inverted, we invert the test too. */
2646 else if (op1
== TOK_GT
)
2648 else if (op1
== TOK_ULT
)
2650 else if (op1
== TOK_UGT
)
2655 if (op1
!= TOK_NE
) {
2659 /* generate non equal test */
2660 /* XXX: NOT PORTABLE yet */
2664 b
= psym(0x850f, 0);
2670 vset(VT_INT
, VT_JMPI
, a
);
2675 /* handle constant optimizations and various machine independant opt */
2676 void gen_opc(int op
)
2683 /* currently, we cannot do computations with forward symbols */
2684 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
2685 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
2689 case '+': v1
->c
.i
+= fc
; break;
2690 case '-': v1
->c
.i
-= fc
; break;
2691 case '&': v1
->c
.i
&= fc
; break;
2692 case '^': v1
->c
.i
^= fc
; break;
2693 case '|': v1
->c
.i
|= fc
; break;
2694 case '*': v1
->c
.i
*= fc
; break;
2696 case '/': v1
->c
.i
/= fc
; break; /* XXX: zero case ? */
2697 case '%': v1
->c
.i
%= fc
; break; /* XXX: zero case ? */
2698 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break; /* XXX: zero case ? */
2699 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break; /* XXX: zero case ? */
2700 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
2701 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
2702 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
2704 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
2705 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
2706 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
2707 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
2708 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
2709 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
2710 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
2711 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
2712 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
2713 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
2715 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
2716 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
2722 /* if commutative ops, put c2 as constant */
2723 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
2724 op
== '|' || op
== '*')) {
2729 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
2732 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
2733 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
2739 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
2740 /* try to use shifts instead of muls or divs */
2741 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
2750 else if (op
== TOK_PDIV
)
2758 /* call low level op generator */
2759 /* XXX: remove explicit registers */
2765 int pointed_size(int t
)
2767 return type_size(pointed_type(t
), &t
);
2771 void check_pointer_types(SValue
*p1
, SValue
*p2
)
2773 char buf1
[256], buf2
[256];
2777 if (!is_compatible_types(t1
, t2
)) {
2778 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
2779 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
2780 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
2785 /* generic gen_op: handles types problems */
2788 int u
, t1
, t2
, bt1
, bt2
, t
;
2792 bt1
= t1
& VT_BTYPE
;
2793 bt2
= t2
& VT_BTYPE
;
2795 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
2796 /* at least one operand is a pointer */
2797 /* relationnal op: must be both pointers */
2798 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
2799 // check_pointer_types(vtop, vtop - 1);
2800 /* pointers are handled are unsigned */
2801 t
= VT_INT
| VT_UNSIGNED
;
2804 /* if both pointers, then it must be the '-' op */
2805 if ((t1
& VT_BTYPE
) == VT_PTR
&&
2806 (t2
& VT_BTYPE
) == VT_PTR
) {
2808 error("cannot use pointers here");
2809 // check_pointer_types(vtop - 1, vtop);
2810 /* XXX: check that types are compatible */
2811 u
= pointed_size(t1
);
2813 /* set to integer type */
2818 /* exactly one pointer : must be '+' or '-'. */
2819 if (op
!= '-' && op
!= '+')
2820 error("cannot use pointers here");
2821 /* Put pointer as first operand */
2822 if ((t2
& VT_BTYPE
) == VT_PTR
) {
2826 /* XXX: cast to int ? (long long case) */
2827 vpushi(pointed_size(vtop
[-1].t
));
2830 /* put again type if gen_opc() swaped operands */
2833 } else if (is_float(bt1
) || is_float(bt2
)) {
2834 /* compute bigger type and do implicit casts */
2835 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
2837 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
2842 /* floats can only be used for a few operations */
2843 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
2844 (op
< TOK_ULT
|| op
> TOK_GT
))
2845 error("invalid operands for binary operation");
2847 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
2848 /* cast to biggest op */
2850 /* convert to unsigned if it does not fit in a long long */
2851 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
2852 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
2856 /* integer operations */
2858 /* convert to unsigned if it does not fit in an integer */
2859 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
2860 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
2863 /* XXX: currently, some unsigned operations are explicit, so
2864 we modify them here */
2865 if (t
& VT_UNSIGNED
) {
2872 else if (op
== TOK_LT
)
2874 else if (op
== TOK_GT
)
2876 else if (op
== TOK_LE
)
2878 else if (op
== TOK_GE
)
2884 /* special case for shifts and long long: we keep the shift as
2886 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
2892 else if ((t
& VT_BTYPE
) == VT_LLONG
)
2896 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
2897 /* relationnal op: the result is an int */
2905 /* generic itof for unsigned long long case */
2906 void gen_cvt_itof1(int t
)
2910 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
2911 (VT_LLONG
| VT_UNSIGNED
)) {
2916 vpushi((int)&__ulltof
);
2917 else if (t
== VT_DOUBLE
)
2918 vpushi((int)&__ulltod
);
2920 vpushi((int)&__ulltold
);
2929 /* generic ftoi for unsigned long long case */
2930 void gen_cvt_ftoi1(int t
)
2935 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
2936 /* not handled natively */
2938 st
= vtop
->t
& VT_BTYPE
;
2941 vpushi((int)&__ftoull
);
2942 else if (st
== VT_DOUBLE
)
2943 vpushi((int)&__dtoull
);
2945 vpushi((int)&__ldtoull
);
2949 vtop
->r2
= REG_LRET
;
2955 /* force char or short cast */
2956 void force_charshort_cast(int t
)
2960 /* XXX: add optimization if lvalue : just change type and offset */
2965 if (t
& VT_UNSIGNED
) {
2966 vpushi((1 << bits
) - 1);
2977 /* cast 'vtop' to 't' type */
2978 void gen_cast(int t
)
2980 int sbt
, dbt
, sf
, df
, c
, st1
, dt1
;
2982 /* special delayed cast for char/short */
2983 /* XXX: in some cases (multiple cascaded casts), it may still
2985 if (vtop
->r
& VT_MUSTCAST
) {
2986 vtop
->r
&= ~VT_MUSTCAST
;
2987 force_charshort_cast(vtop
->t
);
2991 sbt
= vtop
->t
& VT_BTYPE
;
2996 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
2998 /* convert from fp to fp */
3000 /* constant case: we can do it now */
3001 /* XXX: in ISOC, cannot do it if error in convert */
3002 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
3003 vtop
->c
.f
= (float)vtop
->c
.d
;
3004 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
3005 vtop
->c
.f
= (float)vtop
->c
.ld
;
3006 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
3007 vtop
->c
.d
= (double)vtop
->c
.f
;
3008 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
3009 vtop
->c
.d
= (double)vtop
->c
.ld
;
3010 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
3011 vtop
->c
.ld
= (long double)vtop
->c
.f
;
3012 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
3013 vtop
->c
.ld
= (long double)vtop
->c
.d
;
3015 /* non constant case: generate code */
3019 /* convert int to fp */
3020 st1
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
3023 case VT_LLONG
| VT_UNSIGNED
:
3025 /* XXX: add const cases for long long */
3027 case VT_INT
| VT_UNSIGNED
:
3029 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
3030 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
3031 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
3036 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
3037 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
3038 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
3047 /* convert fp to int */
3048 dt1
= t
& (VT_BTYPE
| VT_UNSIGNED
);
3049 /* we handle char/short/etc... with generic code */
3050 if (dt1
!= (VT_INT
| VT_UNSIGNED
) &&
3051 dt1
!= (VT_LLONG
| VT_UNSIGNED
) &&
3056 case VT_LLONG
| VT_UNSIGNED
:
3058 /* XXX: add const cases for long long */
3060 case VT_INT
| VT_UNSIGNED
:
3062 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3063 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3064 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
3070 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3071 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3072 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
3080 if (dt1
== VT_INT
&& (t
& (VT_BTYPE
| VT_UNSIGNED
)) != dt1
) {
3081 /* additionnal cast for char/short/bool... */
3085 } else if (dbt
== VT_LLONG
) {
3086 /* scalar to long long */
3088 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
3089 vtop
->c
.ll
= vtop
->c
.ui
;
3091 vtop
->c
.ll
= vtop
->c
.i
;
3093 /* machine independant conversion */
3095 /* generate high word */
3096 if ((vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
)) {
3104 /* patch second register */
3105 vtop
[-1].r2
= vtop
->r
;
3108 } else if (dbt
== VT_BOOL
) {
3109 /* scalar to bool */
3112 } else if (dbt
== VT_BYTE
|| dbt
== VT_SHORT
) {
3113 force_charshort_cast(t
);
3114 } else if (dbt
== VT_INT
) {
3116 if (sbt
== VT_LLONG
) {
3117 /* from long long: just take low order word */
3120 } else if (vtop
->r
& VT_LVAL
) {
3121 /* if lvalue and single word type, nothing to do (XXX:
3122 maybe incorrect for sizeof op) */
3131 /* return type size. Put alignment at 'a' */
3132 int type_size(int t
, int *a
)
3138 if (bt
== VT_STRUCT
) {
3140 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3141 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
3143 } else if (bt
== VT_PTR
) {
3145 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3146 return type_size(s
->t
, a
) * s
->c
;
3151 } else if (bt
== VT_LDOUBLE
) {
3153 return LDOUBLE_SIZE
;
3154 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
3157 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
3160 } else if (bt
== VT_SHORT
) {
3164 /* char, void, function, _Bool */
3170 /* return the pointed type of t */
3171 int pointed_type(int t
)
3174 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3175 return s
->t
| (t
& ~VT_TYPE
);
3178 int mk_pointer(int t
)
3182 sym_push(p
, t
, 0, -1);
3183 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
3186 int is_compatible_types(int t1
, int t2
)
3193 bt1
= t1
& VT_BTYPE
;
3194 bt2
= t2
& VT_BTYPE
;
3195 if (bt1
== VT_PTR
) {
3196 t1
= pointed_type(t1
);
3197 /* if function, then convert implicitely to function pointer */
3198 if (bt2
!= VT_FUNC
) {
3201 t2
= pointed_type(t2
);
3203 /* void matches everything */
3206 if (t1
== VT_VOID
|| t2
== VT_VOID
)
3208 return is_compatible_types(t1
, t2
);
3209 } else if (bt1
== VT_STRUCT
) {
3211 } else if (bt1
== VT_FUNC
) {
3214 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
3215 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
3216 if (!is_compatible_types(s1
->t
, s2
->t
))
3218 /* XXX: not complete */
3219 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
3223 while (s1
!= NULL
) {
3226 if (!is_compatible_types(s1
->t
, s2
->t
))
3235 /* XXX: not complete */
3240 int check_assign_types(int t1
, int t2
)
3244 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3245 (t2
& VT_BTYPE
) == VT_FUNC
) {
3246 return is_compatible_types(pointed_type(t1
), t2
);
3248 return is_compatible_types(t1
, t2
);
3252 /* print a type. If 'varstr' is not NULL, then the variable is also
3253 printed in the type */
3255 /* XXX: add array and function pointers */
3256 /* XXX: buffer overflows */
3257 void type_to_str(char *buf
, int buf_size
,
3258 int t
, const char *varstr
)
3267 if (t
& VT_UNSIGNED
)
3268 strcat(buf
, "unsigned ");
3271 strcat(buf
, "void");
3274 strcat(buf
, "_Bool");
3277 strcat(buf
, "char");
3280 strcat(buf
, "short");
3286 strcat(buf
, "long");
3289 strcat(buf
, "long long");
3292 strcat(buf
, "float");
3295 strcat(buf
, "double");
3298 strcat(buf
, "long double");
3302 if (bt
== VT_STRUCT
)
3303 strcat(buf
, "struct ");
3305 strcat(buf
, "enum ");
3306 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
3307 if (v
>= SYM_FIRST_ANOM
)
3308 strcat(buf
, "<anonymous>");
3310 strcat(buf
, get_tok_str(v
, NULL
));
3313 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3314 type_to_str(buf
, buf_size
, s
->t
, varstr
);
3317 while (sa
!= NULL
) {
3318 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
3327 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3330 strcat(buf1
, varstr
);
3331 type_to_str(buf
, buf_size
, s
->t
, buf1
);
3336 strcat(buf
, varstr
);
3343 /* verify type compatibility to store vtop in 'st' type, and generate
3345 void gen_assign_cast(int dt
)
3348 char buf1
[256], buf2
[256];
3350 st
= vtop
->t
; /* destination type */
3351 if (!check_assign_types(dt
, st
)) {
3352 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
3353 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
3354 error("cannot cast '%s' to '%s'", buf1
, buf2
);
3360 /* store vtop in lvalue pushed on stack */
3363 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
3367 sbt
= vtop
->t
& VT_BTYPE
;
3368 dbt
= ft
& VT_BTYPE
;
3369 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
3370 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
3371 /* optimize char/short casts */
3372 delayed_cast
= VT_MUSTCAST
;
3373 vtop
->t
= ft
& VT_TYPE
;
3376 gen_assign_cast(ft
& VT_TYPE
);
3379 if (sbt
== VT_STRUCT
) {
3380 /* if structure, only generate pointer */
3381 /* structure assignment : generate memcpy */
3382 /* XXX: optimize if small size */
3387 size
= type_size(vtop
->t
, &align
);
3392 vtop
->r
&= ~VT_LVAL
;
3397 vtop
->r
&= ~VT_LVAL
;
3401 vpushi((int)&memcpy
);
3403 /* leave source on stack */
3404 } else if (ft
& VT_BITFIELD
) {
3405 /* bitfield store handling */
3406 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
3407 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3408 /* remove bit field info to avoid loops */
3409 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3411 /* duplicate destination */
3413 vtop
[-1] = vtop
[-2];
3415 /* mask and shift source */
3416 vpushi((1 << bit_size
) - 1);
3420 /* load destination, mask and or with source */
3422 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
3431 r
= gv(rc
); /* generate value (XXX: move that to store code) */
3432 /* if lvalue was saved on stack, must read it */
3433 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
3435 t
= get_reg(RC_INT
);
3437 sv
.r
= VT_LOCAL
| VT_LVAL
;
3438 sv
.c
.ul
= vtop
[-1].c
.ul
;
3440 vtop
[-1].r
= t
| VT_LVAL
;
3443 /* two word case handling : store second register at word + 4 */
3444 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
3446 /* convert to int to increment easily */
3448 vtop
->r
&= ~VT_LVAL
;
3453 /* XXX: it works because r2 is spilled last ! */
3454 store(vtop
->r2
, vtop
- 1);
3457 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
3458 vtop
->r
|= delayed_cast
;
3462 /* post defines POST/PRE add. c is the token ++ or -- */
3463 void inc(int post
, int c
)
3466 vdup(); /* save lvalue */
3468 gv_dup(); /* duplicate value */
3473 vpushi(c
- TOK_MID
);
3475 vstore(); /* store value */
3477 vpop(); /* if post op, return saved value */
3480 /* Parse GNUC __attribute__ extension. Currently, the following
3481 extensions are recognized:
3482 - aligned(n) : set data/function alignment.
3483 - section(x) : generate data/code in this section.
3484 - unused : currently ignored, but may be used someday.
3486 void parse_attribute(AttributeDef
*ad
)
3493 while (tok
!= ')') {
3494 if (tok
< TOK_IDENT
)
3495 expect("attribute name");
3500 case TOK___SECTION__
:
3503 expect("section name");
3504 ad
->section
= find_section(tokc
.ts
->str
);
3509 case TOK___ALIGNED__
:
3512 if (n
<= 0 || (n
& (n
- 1)) != 0)
3513 error("alignment must be a positive power of two");
3518 case TOK___UNUSED__
:
3519 /* currently, no need to handle it because tcc does not
3520 track unused objects */
3523 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
3524 /* skip parameters */
3525 /* XXX: skip parenthesis too */
3528 while (tok
!= ')' && tok
!= -1)
3542 /* enum/struct/union declaration */
3543 int struct_decl(int u
)
3545 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
3546 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
3550 a
= tok
; /* save decl type */
3555 /* struct already defined ? return it */
3556 /* XXX: check consistency */
3557 s
= sym_find(v
| SYM_STRUCT
);
3560 error("invalid type");
3566 s
= sym_push(v
| SYM_STRUCT
, a
, 0, 0);
3567 /* put struct/union/enum name in type */
3569 u
= u
| (v
<< VT_STRUCT_SHIFT
);
3574 error("struct/union/enum already defined");
3575 /* cannot be empty */
3582 if (a
== TOK_ENUM
) {
3589 /* enum symbols have static storage */
3590 sym_push(v
, VT_STATIC
| VT_INT
, VT_CONST
, c
);
3595 parse_btype(&b
, &ad
);
3600 t
= type_decl(&v
, b
, TYPE_DIRECT
);
3601 if ((t
& VT_BTYPE
) == VT_FUNC
||
3602 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
3603 error("invalid type for '%s'",
3604 get_tok_str(v
, NULL
));
3610 bit_size
= expr_const();
3611 /* XXX: handle v = 0 case for messages */
3613 error("negative width in bit-field '%s'",
3614 get_tok_str(v
, NULL
));
3615 if (v
&& bit_size
== 0)
3616 error("zero width for bit-field '%s'",
3617 get_tok_str(v
, NULL
));
3619 size
= type_size(t
, &align
);
3621 if (bit_size
>= 0) {
3626 error("bitfields must have scalar type");
3628 if (bit_size
> bsize
) {
3629 error("width of '%s' exceeds its type",
3630 get_tok_str(v
, NULL
));
3631 } else if (bit_size
== bsize
) {
3632 /* no need for bit fields */
3634 } else if (bit_size
== 0) {
3635 /* XXX: what to do if only padding in a
3637 /* zero size: means to pad */
3641 /* we do not have enough room ? */
3642 if ((bit_pos
+ bit_size
) > bsize
)
3645 /* XXX: handle LSB first */
3647 (bit_pos
<< VT_STRUCT_SHIFT
) |
3648 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
3649 bit_pos
+= bit_size
;
3655 /* add new memory data only if starting
3657 if (lbit_pos
== 0) {
3658 if (a
== TOK_STRUCT
) {
3659 c
= (c
+ align
- 1) & -align
;
3667 if (align
> maxalign
)
3671 printf("add field %s offset=%d",
3672 get_tok_str(v
, NULL
), offset
);
3673 if (t
& VT_BITFIELD
) {
3674 printf(" pos=%d size=%d",
3675 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
3676 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
3680 ss
= sym_push(v
| SYM_FIELD
, t
, 0, offset
);
3684 if (tok
== ';' || tok
== -1)
3694 /* size for struct/union, dummy for enum */
3695 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
3700 /* return 0 if no type declaration. otherwise, return the basic type
3703 int parse_btype(int *type_ptr
, AttributeDef
*ad
)
3705 int t
, u
, type_found
;
3708 memset(ad
, 0, sizeof(AttributeDef
));
3719 if ((t
& VT_BTYPE
) != 0)
3720 error("too many basic types");
3734 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
3735 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
3736 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
3737 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
3751 if ((t
& VT_BTYPE
) == VT_LONG
) {
3752 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
3759 u
= struct_decl(VT_ENUM
);
3763 u
= struct_decl(VT_STRUCT
);
3766 /* type modifiers */
3794 /* GNUC attribute */
3795 case TOK___ATTRIBUTE__
:
3796 parse_attribute(ad
);
3800 if (!s
|| !(s
->t
& VT_TYPEDEF
))
3802 t
|= (s
->t
& ~VT_TYPEDEF
);
3809 /* long is never used as type */
3810 if ((t
& VT_BTYPE
) == VT_LONG
)
3811 t
= (t
& ~VT_BTYPE
) | VT_INT
;
3816 int post_type(int t
)
3818 int p
, n
, pt
, l
, t1
;
3819 Sym
**plast
, *s
, *first
;
3823 /* function declaration */
3828 while (tok
!= ')') {
3829 /* read param name and compute offset */
3830 if (l
!= FUNC_OLD
) {
3831 if (!parse_btype(&pt
, &ad
)) {
3833 error("invalid type");
3840 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
3842 pt
= type_decl(&n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
3843 if ((pt
& VT_BTYPE
) == VT_VOID
)
3844 error("parameter declared as void");
3851 /* array must be transformed to pointer according to ANSI C */
3853 s
= sym_push(n
| SYM_FIELD
, pt
, 0, 0);
3858 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
3865 /* if no parameters, then old type prototype */
3869 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
3870 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
));
3871 /* we push a anonymous symbol which will contain the function prototype */
3873 s
= sym_push(p
, t
, 0, l
);
3875 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
3876 } else if (tok
== '[') {
3877 /* array definition */
3883 error("invalid array size");
3886 /* parse next post type */
3887 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
3888 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
));
3890 /* we push a anonymous symbol which will contain the array
3893 sym_push(p
, t
, 0, n
);
3894 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
3899 /* Read a type declaration (except basic type), and return the
3900 type. If v is true, then also put variable name in 'vtop->c' */
3901 int type_decl(int *v
, int t
, int td
)
3906 while (tok
== '*') {
3908 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
3913 /* recursive type */
3914 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3917 u
= type_decl(v
, 0, td
);
3921 /* type identifier */
3922 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
3926 if (!(td
& TYPE_ABSTRACT
))
3927 expect("identifier");
3931 /* append t at the end of u */
3937 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
3947 /* define a new external reference to a function 'v' of type 'u' */
3948 Sym
*external_sym(int v
, int u
, int r
)
3953 /* push forward reference */
3954 s
= sym_push1(&global_stack
,
3956 s
->r
= r
| VT_CONST
| VT_FORWARD
;
3963 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
3965 if (vtop
->r
& VT_LVAL
)
3967 vtop
->t
= pointed_type(vtop
->t
);
3968 if (!(vtop
->t
& VT_ARRAY
)) /* an array is never an lvalue */
3972 /* pass a parameter to a function and do type checking and casting */
3973 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
3976 func_type
= func
->c
;
3977 if (func_type
== FUNC_OLD
||
3978 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
3979 /* default casting : only need to convert float to double */
3980 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
3981 gen_cast(VT_DOUBLE
);
3982 } else if (arg
== NULL
) {
3983 error("too many arguments to function");
3985 gen_assign_cast(arg
->t
);
3992 int n
, t
, ft
, fc
, p
, align
, size
, r
, data_offset
;
3997 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
4000 } else if (tok
== TOK_CUINT
) {
4001 vsetc(VT_INT
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4003 } else if (tok
== TOK_CLLONG
) {
4004 vsetc(VT_LLONG
, VT_CONST
, &tokc
);
4006 } else if (tok
== TOK_CULLONG
) {
4007 vsetc(VT_LLONG
| VT_UNSIGNED
, VT_CONST
, &tokc
);
4009 } else if (tok
== TOK_CFLOAT
) {
4010 vsetc(VT_FLOAT
, VT_CONST
, &tokc
);
4012 } else if (tok
== TOK_CDOUBLE
) {
4013 vsetc(VT_DOUBLE
, VT_CONST
, &tokc
);
4015 } else if (tok
== TOK_CLDOUBLE
) {
4016 vsetc(VT_LDOUBLE
, VT_CONST
, &tokc
);
4018 } else if (tok
== TOK___FUNC__
) {
4019 /* special function name identifier */
4020 /* generate (char *) type */
4021 data_offset
= (int)data_section
->data_ptr
;
4022 vset(mk_pointer(VT_BYTE
), VT_CONST
, data_offset
);
4023 strcpy((void *)data_offset
, funcname
);
4024 data_offset
+= strlen(funcname
) + 1;
4025 data_section
->data_ptr
= (unsigned char *)data_offset
;
4027 } else if (tok
== TOK_LSTR
) {
4030 } else if (tok
== TOK_STR
) {
4031 /* string parsing */
4034 type_size(t
, &align
);
4035 data_offset
= (int)data_section
->data_ptr
;
4036 data_offset
= (data_offset
+ align
- 1) & -align
;
4038 /* we must declare it as an array first to use initializer parser */
4039 t
= VT_ARRAY
| mk_pointer(t
);
4040 decl_initializer(t
, VT_CONST
, data_offset
, 1, 0);
4041 data_offset
+= type_size(t
, &align
);
4042 /* put it as pointer */
4043 vset(t
& ~VT_ARRAY
, VT_CONST
, fc
);
4044 data_section
->data_ptr
= (unsigned char *)data_offset
;
4050 if (parse_btype(&t
, &ad
)) {
4051 ft
= type_decl(&n
, t
, TYPE_ABSTRACT
);
4053 /* check ISOC99 compound literal */
4055 /* data is allocated locally by default */
4060 /* all except arrays are lvalues */
4061 if (!(ft
& VT_ARRAY
))
4063 memset(&ad
, 0, sizeof(AttributeDef
));
4064 fc
= decl_initializer_alloc(ft
, &ad
, r
, 1);
4074 } else if (t
== '*') {
4077 } else if (t
== '&') {
4079 /* functions names must be treated as function pointers,
4080 except for unary '&' and sizeof. Since we consider that
4081 functions are not lvalues, we only have to handle it
4082 there and in function calls. */
4083 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4085 vtop
->t
= mk_pointer(vtop
->t
);
4086 vtop
->r
&= ~VT_LVAL
;
4090 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
4091 vtop
->c
.i
= !vtop
->c
.i
;
4092 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
4093 vtop
->c
.i
= vtop
->c
.i
^ 1;
4095 vset(VT_INT
, VT_JMP
, gtst(1, 0));
4105 if (t
== TOK_SIZEOF
) {
4108 if (parse_btype(&t
, &ad
)) {
4109 t
= type_decl(&n
, t
, TYPE_ABSTRACT
);
4111 /* XXX: some code could be generated: add eval
4123 vpushi(type_size(t
, &t
));
4125 if (t
== TOK_INC
|| t
== TOK_DEC
) {
4128 } else if (t
== '-') {
4137 error("'%s' undeclared", get_tok_str(t
, NULL
));
4138 /* for simple function calls, we tolerate undeclared
4139 external reference */
4141 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
4142 /* int() function */
4143 s
= external_sym(t
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), 0);
4145 vset(s
->t
, s
->r
, s
->c
);
4146 /* if forward reference, we must point to s */
4147 if (vtop
->r
& VT_FORWARD
)
4152 /* post operations */
4154 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
4157 } else if (tok
== '.' || tok
== TOK_ARROW
) {
4159 if (tok
== TOK_ARROW
)
4162 vtop
->r
&= ~VT_LVAL
;
4164 /* expect pointer on structure */
4165 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
4166 expect("struct or union");
4167 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4170 while ((s
= s
->next
) != NULL
) {
4175 error("field not found");
4176 /* add field offset to pointer */
4177 vtop
->t
= VT_INT
; /* change type to int */
4180 /* change type to field type, and set to lvalue */
4182 /* an array is never an lvalue */
4183 if (!(vtop
->t
& VT_ARRAY
))
4186 } else if (tok
== '[') {
4192 } else if (tok
== '(') {
4197 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
4198 /* pointer test (no array accepted) */
4199 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
4200 vtop
->t
= pointed_type(vtop
->t
);
4201 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
4205 expect("function pointer");
4208 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
4210 /* get return type */
4211 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
4212 save_regs(); /* save used temporary registers */
4215 sa
= s
->next
; /* first parameter */
4216 #ifdef INVERT_FUNC_PARAMS
4218 int *str
, len
, parlevel
, *saved_macro_ptr
;
4221 /* read each argument and store it on a stack */
4222 /* XXX: merge it with macro args ? */
4224 while (tok
!= ')') {
4228 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
4232 else if (tok
== ')')
4234 tok_add2(&str
, &len
, tok
, &tokc
);
4237 tok_add(&str
, &len
, -1); /* end of file added */
4238 tok_add(&str
, &len
, 0);
4239 s1
= sym_push2(&args
, 0, 0, (int)str
);
4240 s1
->next
= sa
; /* add reference to argument */
4250 /* now generate code in reverse order by reading the stack */
4251 saved_macro_ptr
= macro_ptr
;
4253 macro_ptr
= (int *)args
->c
;
4257 expect("',' or ')'");
4258 gfunc_param_typed(&gf
, s
, args
->next
);
4260 free((int *)args
->c
);
4264 macro_ptr
= saved_macro_ptr
;
4269 /* compute first implicit argument if a structure is returned */
4270 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
4271 /* get some space for the returned structure */
4272 size
= type_size(s
->t
, &align
);
4273 loc
= (loc
- size
) & -align
;
4275 ret
.r
= VT_LOCAL
| VT_LVAL
;
4276 /* pass it as 'int' to avoid structure arg passing
4278 vset(VT_INT
, VT_LOCAL
, loc
);
4284 /* return in register */
4285 if (is_float(ret
.t
)) {
4288 if ((ret
.t
& VT_BTYPE
) == VT_LLONG
)
4294 #ifndef INVERT_FUNC_PARAMS
4295 while (tok
!= ')') {
4297 gfunc_param_typed(&gf
, s
, sa
);
4305 error("too few arguments to function");
4309 vsetc(ret
.t
, ret
.r
, &ret
.c
);
4323 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
4324 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
4325 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
4348 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
4349 (l
== 1 && (tok
== '+' || tok
== '-')) ||
4350 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
4351 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
4352 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
4353 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
4354 (l
== 5 && tok
== '&') ||
4355 (l
== 6 && tok
== '^') ||
4356 (l
== 7 && tok
== '|') ||
4357 (l
== 8 && tok
== TOK_LAND
) ||
4358 (l
== 9 && tok
== TOK_LOR
)) {
4367 /* only used if non constant */
4375 if (tok
!= TOK_LAND
) {
4378 vset(VT_INT
, VT_JMPI
, t
);
4395 if (tok
!= TOK_LOR
) {
4398 vset(VT_INT
, VT_JMP
, t
);
4408 /* XXX: better constant handling */
4411 int t
, u
, c
, r1
, r2
, rc
;
4433 /* XXX: long long handling ? */
4435 if (is_float(vtop
->t
))
4463 /* parse a constant expression and return value in vtop */
4464 void expr_const1(void)
4470 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
4475 /* parse an integer constant and return its value */
4476 int expr_const(void)
4485 /* return the label token if current token is a label, otherwise
4492 /* fast test first */
4493 if (tok
< TOK_UIDENT
)
4495 /* no need to save tokc since we expect an identifier */
4503 /* XXX: may not work in all cases (macros ?) */
4512 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
4517 if (tok
== TOK_IF
) {
4524 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4526 if (c
== TOK_ELSE
) {
4530 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4531 gsym(d
); /* patch else jmp */
4534 } else if (tok
== TOK_WHILE
) {
4542 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
4543 oad(0xe9, d
- ind
- 5); /* jmp */
4546 } else if (tok
== '{') {
4549 s
= local_stack
.top
;
4550 while (tok
!= '}') {
4553 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4555 /* pop locally defined symbols */
4556 sym_pop(&local_stack
, s
);
4558 } else if (tok
== TOK_RETURN
) {
4562 gen_assign_cast(func_vt
);
4563 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
4564 /* if returning structure, must copy it to implicit
4565 first pointer arg location */
4566 vset(mk_pointer(func_vt
), VT_LOCAL
| VT_LVAL
, func_vc
);
4569 /* copy structure value to pointer */
4571 } else if (is_float(func_vt
)) {
4579 rsym
= gjmp(rsym
); /* jmp */
4580 } else if (tok
== TOK_BREAK
) {
4583 error("cannot break");
4584 *bsym
= gjmp(*bsym
);
4587 } else if (tok
== TOK_CONTINUE
) {
4590 error("cannot continue");
4591 *csym
= gjmp(*csym
);
4594 } else if (tok
== TOK_FOR
) {
4617 oad(0xe9, d
- ind
- 5); /* jmp */
4621 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
4622 oad(0xe9, c
- ind
- 5); /* jmp */
4626 if (tok
== TOK_DO
) {
4631 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
4642 if (tok
== TOK_SWITCH
) {
4646 /* XXX: other types than integer */
4647 case_reg
= gv(RC_INT
);
4651 b
= gjmp(0); /* jump to first case */
4653 block(&a
, csym
, &b
, &c
, case_reg
);
4654 /* if no default, jmp after switch */
4662 if (tok
== TOK_CASE
) {
4669 if (gnu_ext
&& tok
== TOK_DOTS
) {
4673 warning("empty case range");
4675 /* since a case is like a label, we must skip it with a jmp */
4678 vset(VT_INT
, case_reg
, 0);
4682 *case_sym
= gtst(1, 0);
4685 *case_sym
= gtst(1, 0);
4686 vset(VT_INT
, case_reg
, 0);
4689 *case_sym
= gtst(1, *case_sym
);
4693 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4695 if (tok
== TOK_DEFAULT
) {
4701 error("too many 'default'");
4703 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4705 if (tok
== TOK_GOTO
) {
4707 s
= sym_find1(&label_stack
, tok
);
4708 /* put forward definition if needed */
4710 s
= sym_push1(&label_stack
, tok
, VT_FORWARD
, 0);
4711 /* label already defined */
4712 if (s
->t
& VT_FORWARD
)
4713 s
->c
= gjmp(s
->c
); /* jmp xxx */
4715 oad(0xe9, s
->c
- ind
- 5); /* jmp xxx */
4722 s
= sym_find1(&label_stack
, b
);
4724 if (!(s
->t
& VT_FORWARD
))
4725 error("multiple defined label");
4730 sym_push1(&label_stack
, b
, 0, ind
);
4732 /* we accept this, but it is a mistake */
4734 warning("deprecated use of label at end of compound statement");
4736 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
4738 /* expression case */
4748 /* t is the array or struct type. c is the array or struct
4749 address. cur_index/cur_field is the pointer to the current
4750 value. 'size_only' is true if only size info is needed (only used
4752 void decl_designator(int t
, int r
, int c
,
4753 int *cur_index
, Sym
**cur_field
,
4757 int notfirst
, index
, align
, l
;
4760 if (gnu_ext
&& (l
= is_label()) != 0)
4763 while (tok
== '[' || tok
== '.') {
4765 if (!(t
& VT_ARRAY
))
4766 expect("array type");
4767 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4769 index
= expr_const();
4770 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
4771 expect("invalid index");
4775 t
= pointed_type(t
);
4776 c
+= index
* type_size(t
, &align
);
4782 if ((t
& VT_BTYPE
) != VT_STRUCT
)
4783 expect("struct/union type");
4784 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4796 t
= f
->t
| (t
& ~VT_TYPE
);
4811 t
= pointed_type(t
);
4812 c
+= index
* type_size(t
, &align
);
4816 error("too many field init");
4817 t
= f
->t
| (t
& ~VT_TYPE
);
4821 decl_initializer(t
, r
, c
, 0, size_only
);
4825 #define EXPR_CONST 1
4828 /* store a value or an expression directly in global data or in local array */
4829 void init_putv(int t
, int r
, int c
,
4830 int v
, int expr_type
)
4832 int saved_global_expr
, bt
;
4839 /* compound literals must be allocated globally in this case */
4840 saved_global_expr
= global_expr
;
4843 global_expr
= saved_global_expr
;
4850 if ((r
& VT_VALMASK
) == VT_CONST
) {
4851 /* XXX: do casting */
4852 /* XXX: not portable */
4853 bt
= vtop
->t
& VT_BTYPE
;
4856 *(char *)c
= vtop
->c
.i
;
4859 *(short *)c
= vtop
->c
.i
;
4862 *(double *)c
= vtop
->c
.d
;
4865 *(long double *)c
= vtop
->c
.ld
;
4869 *(long long *)c
= vtop
->c
.ll
;
4873 *(int *)c
= vtop
->c
.i
;
4885 /* put zeros for variable based init */
4886 void init_putz(int t
, int r
, int c
, int size
)
4890 if ((r
& VT_VALMASK
) == VT_CONST
) {
4891 /* nothing to do because global are already set to zero */
4898 vset(VT_INT
, VT_LOCAL
, c
);
4900 vpushi((int)&memset
);
4905 /* 't' contains the type and storage info. c is the address of the
4906 object. 'first' is true if array '{' must be read (multi dimension
4907 implicit array init handling). 'size_only' is true if size only
4908 evaluation is wanted (only for arrays). */
4909 void decl_initializer(int t
, int r
, int c
, int first
, int size_only
)
4911 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
4912 int t1
, size1
, align1
, expr_type
;
4917 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4920 t1
= pointed_type(t
);
4921 size1
= type_size(t1
, &align1
);
4924 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
4930 /* only parse strings here if correct type (otherwise: handle
4931 them as ((w)char *) expressions */
4932 if ((tok
== TOK_LSTR
&&
4933 (t1
& VT_BTYPE
) == VT_INT
) ||
4935 (t1
& VT_BTYPE
) == VT_BYTE
)) {
4936 /* XXX: move multiple string parsing in parser ? */
4937 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
4939 /* compute maximum number of chars wanted */
4941 if (n
>= 0 && nb
> (n
- array_length
))
4942 nb
= n
- array_length
;
4945 warning("initializer-string for array is too long");
4947 init_putv(t1
, r
, c
+ (array_length
+ i
) * size1
,
4948 ts
->str
[i
], EXPR_VAL
);
4954 /* only add trailing zero if enough storage (no
4955 warning in this case since it is standard) */
4956 if (n
< 0 || array_length
< n
) {
4958 init_putv(t1
, r
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
4964 while (tok
!= '}') {
4965 decl_designator(t
, r
, c
, &index
, NULL
, size_only
);
4966 if (n
>= 0 && index
>= n
)
4967 error("index too large");
4968 /* must put zero in holes (note that doing it that way
4969 ensures that it even works with designators) */
4970 if (!size_only
&& array_length
< index
) {
4971 init_putz(t1
, r
, c
+ array_length
* size1
,
4972 (index
- array_length
) * size1
);
4975 if (index
> array_length
)
4976 array_length
= index
;
4977 /* special test for multi dimensional arrays (may not
4978 be strictly correct if designators are used at the
4980 if (index
>= n
&& no_oblock
)
4989 /* put zeros at the end */
4990 if (!size_only
&& n
>= 0 && array_length
< n
) {
4991 init_putz(t1
, r
, c
+ array_length
* size1
,
4992 (n
- array_length
) * size1
);
4994 /* patch type size if needed */
4996 s
->c
= array_length
;
4997 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
4998 /* XXX: union needs only one init */
5000 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
5005 while (tok
!= '}') {
5006 decl_designator(t
, r
, c
, NULL
, &f
, size_only
);
5007 /* fill with zero between fields */
5009 if (!size_only
&& array_length
< index
) {
5010 init_putz(t
, r
, c
+ array_length
,
5011 index
- array_length
);
5013 index
= index
+ type_size(f
->t
, &align1
);
5014 if (index
> array_length
)
5015 array_length
= index
;
5021 /* put zeros at the end */
5022 if (!size_only
&& array_length
< n
) {
5023 init_putz(t
, r
, c
+ array_length
,
5027 } else if (tok
== '{') {
5029 decl_initializer(t
, r
, c
, first
, size_only
);
5031 } else if (size_only
) {
5032 /* just skip expression */
5034 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
5038 else if (tok
== ')')
5043 /* currently, we always use constant expression for globals
5044 (may change for scripting case) */
5045 expr_type
= EXPR_CONST
;
5046 if ((r
& VT_VALMASK
) == VT_LOCAL
)
5047 expr_type
= EXPR_ANY
;
5048 init_putv(t
, r
, c
, 0, expr_type
);
5052 /* parse an initializer for type 't' if 'has_init' is true, and
5053 allocate space in local or global data space ('r' is either
5054 VT_LOCAL or VT_CONST). The allocated address in returned */
5055 int decl_initializer_alloc(int t
, AttributeDef
*ad
, int r
, int has_init
)
5057 int size
, align
, addr
, tok1
, data_offset
;
5058 int *init_str
, init_len
, level
, *saved_macro_ptr
;
5061 size
= type_size(t
, &align
);
5062 /* If unknown size, we must evaluate it before
5063 evaluating initializers because
5064 initializers can generate global data too
5065 (e.g. string pointers or ISOC99 compound
5066 literals). It also simplifies local
5067 initializers handling */
5070 saved_macro_ptr
= NULL
; /* avoid warning */
5074 error("unknown type size");
5075 /* get all init string */
5077 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
5079 error("unexpected end of file in initializer");
5080 tok_add2(&init_str
, &init_len
, tok
, &tokc
);
5083 else if (tok
== '}') {
5091 tok_add(&init_str
, &init_len
, -1);
5092 tok_add(&init_str
, &init_len
, 0);
5095 saved_macro_ptr
= macro_ptr
;
5096 macro_ptr
= init_str
;
5098 decl_initializer(t
, r
, 0, 1, 1);
5099 /* prepare second initializer parsing */
5100 macro_ptr
= init_str
;
5103 /* if still unknown size, error */
5104 size
= type_size(t
, &align
);
5106 error("unknown type size");
5108 /* take into account specified alignment if bigger */
5109 if (ad
->aligned
> align
)
5110 align
= ad
->aligned
;
5111 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
5112 loc
= (loc
- size
) & -align
;
5115 /* compute section */
5123 data_offset
= (int)sec
->data_ptr
;
5124 data_offset
= (data_offset
+ align
- 1) & -align
;
5126 /* very important to increment global
5127 pointer at this time because
5128 initializers themselves can create new
5130 data_offset
+= size
;
5131 sec
->data_ptr
= (unsigned char *)data_offset
;
5134 decl_initializer(t
, r
, addr
, 1, 0);
5135 /* restore parse state if needed */
5138 macro_ptr
= saved_macro_ptr
;
5145 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
5148 int *a
, t
, b
, v
, addr
, has_init
, size
, align
, r
, u
;
5153 if (!parse_btype(&b
, &ad
)) {
5154 /* skip redundant ';' */
5155 /* XXX: find more elegant solution */
5160 /* special test for old K&R protos without explicit int
5161 type. Only accepted when defining global data */
5162 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
5166 if (((b
& VT_BTYPE
) == VT_ENUM
||
5167 (b
& VT_BTYPE
) == VT_STRUCT
) &&
5169 /* we accept no variable after */
5173 while (1) { /* iterate thru each declaration */
5174 t
= type_decl(&v
, b
, TYPE_DIRECT
);
5175 /* currently, we do not parse attribute in
5176 type_decl(). May change if needed */
5177 if (tok
== TOK___ATTRIBUTE__
)
5178 parse_attribute(&ad
);
5182 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
5183 printf("type = '%s'\n", buf
);
5188 error("cannot use local functions");
5190 expect("function definition");
5191 /* compute text section */
5192 cur_text_section
= ad
.section
;
5193 if (!cur_text_section
)
5194 cur_text_section
= text_section
;
5195 ind
= (int)cur_text_section
->data_ptr
;
5196 /* patch forward references */
5197 if ((sym
= sym_find(v
)) && (sym
->r
& VT_FORWARD
)) {
5198 greloc_patch(sym
, ind
);
5201 /* put function address */
5202 sym
= sym_push1(&global_stack
, v
, t
, ind
);
5205 funcname
= get_tok_str(v
, NULL
);
5206 /* push a dummy symbol to enable local sym storage */
5207 sym_push1(&local_stack
, 0, 0, 0);
5208 /* define parameters */
5209 sym
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
5210 /* XXX: the following is x86 dependant -> move it to
5213 /* if the function returns a structure, then add an
5214 implicit pointer parameter */
5216 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
5220 while ((sym
= sym
->next
) != NULL
) {
5222 sym_push(sym
->v
& ~SYM_FIELD
, u
,
5223 VT_LOCAL
| VT_LVAL
, addr
);
5224 size
= type_size(u
, &align
);
5225 size
= (size
+ 3) & ~3;
5226 #ifdef FUNC_STRUCT_PARAM_AS_PTR
5227 /* structs are passed as pointer */
5228 if ((u
& VT_BTYPE
) == VT_STRUCT
) {
5235 o(0xe58955); /* push %ebp, mov %esp, %ebp */
5236 a
= (int *)oad(0xec81, 0); /* sub $xxx, %esp */
5238 block(NULL
, NULL
, NULL
, NULL
, 0);
5240 o(0xc3c9); /* leave, ret */
5241 *a
= (-loc
+ 3) & -4; /* align local size to word &
5242 save local variables */
5243 cur_text_section
->data_ptr
= (unsigned char *)ind
;
5244 sym_pop(&label_stack
, NULL
); /* reset label stack */
5245 sym_pop(&local_stack
, NULL
); /* reset local stack */
5246 funcname
= ""; /* for safety */
5247 func_vt
= VT_VOID
; /* for safety */
5250 if (b
& VT_TYPEDEF
) {
5251 /* save typedefed type */
5252 /* XXX: test storage specifiers ? */
5253 sym_push(v
, t
| VT_TYPEDEF
, 0, 0);
5254 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
5255 /* external function definition */
5256 external_sym(v
, t
, 0);
5258 /* not lvalue if array */
5260 if (!(t
& VT_ARRAY
))
5262 if (b
& VT_EXTERN
) {
5263 /* external variable */
5264 external_sym(v
, t
, r
);
5270 has_init
= (tok
== '=');
5273 addr
= decl_initializer_alloc(t
, &ad
, r
,
5275 if (l
== VT_CONST
) {
5276 /* global scope: see if already defined */
5280 if (!is_compatible_types(sym
->t
, t
))
5281 error("incompatible types for redefinition of '%s'",
5282 get_tok_str(v
, NULL
));
5283 if (!(sym
->r
& VT_FORWARD
))
5284 error("redefinition of '%s'", get_tok_str(v
, NULL
));
5285 greloc_patch(sym
, addr
);
5288 sym_push(v
, t
, r
, addr
);
5302 /* put all global symbols in the extern stack and do all the
5303 resolving which can be done without using external symbols from DLLs */
5304 /* XXX: could try to verify types, but would not to save them in
5306 void resolve_global_syms(void)
5308 Sym
*s
, *s1
, *ext_sym
;
5311 s
= global_stack
.top
;
5314 /* do not save static or typedefed symbols or types */
5315 if (!(s
->t
& (VT_STATIC
| VT_TYPEDEF
)) &&
5316 !(s
->v
& (SYM_FIELD
| SYM_STRUCT
)) &&
5317 (s
->v
< SYM_FIRST_ANOM
)) {
5318 ext_sym
= sym_find1(&extern_stack
, s
->v
);
5320 /* if the symbol do not exist, we simply save it */
5321 ext_sym
= sym_push1(&extern_stack
, s
->v
, s
->t
, s
->c
);
5323 } else if (ext_sym
->r
& VT_FORWARD
) {
5324 /* external symbol already exists, but only as forward
5326 if (!(s
->r
& VT_FORWARD
)) {
5327 /* s is not forward, so we can relocate all symbols */
5328 greloc_patch(ext_sym
, s
->c
);
5330 /* the two symbols are forward: merge them */
5331 p
= (Reloc
**)&ext_sym
->c
;
5337 /* external symbol already exists and is defined :
5338 patch all references to it */
5339 if (!(s
->r
& VT_FORWARD
))
5340 error("'%s' defined twice", get_tok_str(s
->v
, NULL
));
5341 greloc_patch(s
, ext_sym
->c
);
5348 /* compile a C file. Return non zero if errors. */
5349 int tcc_compile_file(const char *filename1
)
5355 filename
= (char *)filename1
;
5357 file
= fopen(filename
, "r");
5359 error("file '%s' not found", filename
);
5360 include_stack_ptr
= include_stack
;
5361 ifdef_stack_ptr
= ifdef_stack
;
5364 anon_sym
= SYM_FIRST_ANOM
;
5366 define_start
= define_stack
.top
;
5368 ch
= '\n'; /* needed to parse correctly first preprocessor command */
5372 expect("declaration");
5375 /* reset define stack, but leave -Dsymbols (may be incorrect if
5376 they are undefined) */
5377 sym_pop(&define_stack
, define_start
);
5379 resolve_global_syms();
5381 sym_pop(&global_stack
, NULL
);
5386 /* define a symbol. A value can also be provided with the '=' operator */
5387 /* XXX: currently only handles integers and string defines. should use
5388 tcc parser, but would need a custom 'FILE *' */
5389 void define_symbol(const char *sym
)
5397 p
= strchr(sym
, '=');
5399 /* XXX: buffer overflow */
5404 if (len
> sizeof(buf
) - 1)
5405 len
= sizeof(buf
) - 1;
5406 memcpy(buf
, sym
, len
);
5411 ts
= tok_alloc(buf
, 0);
5417 tok_add2(&str
, &len
, TOK_CINT
, &cval
);
5420 cval
.ts
= tok_alloc(p
, 0);
5421 tok_add2(&str
, &len
, TOK_STR
, &cval
);
5423 tok_add(&str
, &len
, 0);
5424 sym_push1(&define_stack
, ts
->tok
, MACRO_OBJ
, (int)str
);
5427 void undef_symbol(const char *sym
)
5431 printf("undef %s\n", sym
);
5432 ts
= tok_alloc(sym
, 0);
5433 s
= sym_find1(&define_stack
, tok
);
5434 /* undefine symbol by putting an invalid name */
5436 sym_undef(&define_stack
, s
);
5439 /* open a dynamic library so that its symbol are available for
5440 compiled programs */
5441 void open_dll(char *libname
)
5446 snprintf(buf
, sizeof(buf
), "lib%s.so", libname
);
5447 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
5449 error((char *)dlerror());
5452 void resolve_extern_syms(void)
5458 s
= extern_stack
.top
;
5461 if (s
->r
& VT_FORWARD
) {
5462 /* if there is at least one relocation to do, then find it
5465 str
= get_tok_str(s
->v
, NULL
);
5466 addr
= (int)dlsym(NULL
, str
);
5468 error("unresolved external reference '%s'", str
);
5469 greloc_patch(s
, addr
);
5476 /* output a binary file (for testing) */
5477 void build_exe(char *filename
)
5480 f
= fopen(filename
, "w");
5481 fwrite(text_section
->data
, 1, text_section
->data_ptr
- text_section
->data
, f
);
5487 printf("tcc version 0.9.3 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
5488 "usage: tcc [-Idir] [-Dsym[=val]] [-Usym] [-llib] [-i infile] infile [infile_args...]\n");
5491 int main(int argc
, char **argv
)
5495 char *p
, *r
, *outfile
;
5498 include_paths
[0] = "/usr/include";
5499 include_paths
[1] = "/usr/lib/tcc";
5500 include_paths
[2] = "/usr/local/lib/tcc";
5501 nb_include_paths
= 3;
5503 /* add all tokens */
5504 tok_ident
= TOK_IDENT
;
5505 p
= "int\0void\0char\0if\0else\0while\0break\0return\0for\0extern\0static\0unsigned\0goto\0do\0continue\0switch\0case\0const\0volatile\0long\0register\0signed\0auto\0inline\0restrict\0float\0double\0_Bool\0short\0struct\0union\0typedef\0default\0enum\0sizeof\0__attribute__\0define\0include\0ifdef\0ifndef\0elif\0endif\0defined\0undef\0error\0line\0__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0__func__\0main\0section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0";
5509 tok_alloc(p
, r
- p
- 1);
5513 /* standard defines */
5514 define_symbol("__STDC__");
5516 define_symbol("__i386__");
5518 /* tiny C specific defines */
5519 define_symbol("__TINYC__");
5521 /* create standard sections */
5522 text_section
= new_section(".text");
5523 data_section
= new_section(".data");
5524 bss_section
= new_section(".bss");
5529 if (optind
>= argc
) {
5539 if (nb_include_paths
>= INCLUDE_PATHS_MAX
)
5540 error("too many include paths");
5541 include_paths
[nb_include_paths
++] = r
+ 2;
5542 } else if (r
[1] == 'D') {
5543 define_symbol(r
+ 2);
5544 } else if (r
[1] == 'U') {
5545 undef_symbol(r
+ 2);
5546 } else if (r
[1] == 'l') {
5548 } else if (r
[1] == 'i') {
5551 tcc_compile_file(argv
[optind
++]);
5552 } else if (r
[1] == 'o') {
5553 /* currently, only for testing, so not documented */
5556 outfile
= argv
[optind
++];
5558 fprintf(stderr
, "invalid option -- '%s'\n", r
);
5563 tcc_compile_file(argv
[optind
]);
5565 resolve_extern_syms();
5571 s
= sym_find1(&extern_stack
, TOK_MAIN
);
5572 if (!s
|| (s
->r
& VT_FORWARD
))
5573 error("main() not defined");
5574 t
= (int (*)())s
->c
;
5575 return (*t
)(argc
- optind
, argv
+ optind
);