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.
25 #ifndef CONFIG_TCC_STATIC
30 /* preprocessor debug */
33 /* these sizes are dummy for unix, because malloc() does not use
34 memory when the pages are not used */
35 #define TEXT_SIZE (4*1024*1024)
36 #define DATA_SIZE (4*1024*1024)
38 #define INCLUDE_STACK_SIZE 32
39 #define IFDEF_STACK_SIZE 64
40 #define VSTACK_SIZE 64
41 #define STRING_MAX_SIZE 1024
42 #define INCLUDE_PATHS_MAX 32
44 #define TOK_HASH_SIZE 521
45 #define TOK_ALLOC_INCR 256 /* must be a power of two */
46 #define SYM_HASH_SIZE 263
48 /* token symbol management */
49 typedef struct TokenSym
{
50 struct TokenSym
*hash_next
;
51 int tok
; /* token number */
57 typedef union CValue
{
63 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
65 unsigned long long ull
;
72 typedef struct SValue
{
77 /* symbol management */
79 int v
; /* symbol token */
80 int t
; /* associated type */
81 int c
; /* associated number */
82 struct Sym
*next
; /* next related symbol */
83 struct Sym
*prev
; /* prev symbol in stack */
84 struct Sym
*hash_next
; /* next symbol in hash table */
87 typedef struct SymStack
{
89 struct Sym
*hash
[SYM_HASH_SIZE
];
92 /* relocation entry (currently only used for functions or variables */
93 typedef struct Reloc
{
94 int type
; /* type of relocation */
95 int addr
; /* address of relocation */
96 struct Reloc
*next
; /* next relocation */
99 #define RELOC_ADDR32 1 /* 32 bits relocation */
100 #define RELOC_REL32 2 /* 32 bits relative relocation */
103 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
104 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
105 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
107 #define FUNC_NEW 1 /* ansi function prototype */
108 #define FUNC_OLD 2 /* old function prototype */
109 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
111 /* field 'Sym.t' for macros */
112 #define MACRO_OBJ 0 /* object like macro */
113 #define MACRO_FUNC 1 /* function like macro */
115 /* type_decl() types */
116 #define TYPE_ABSTRACT 1 /* type without variable */
117 #define TYPE_DIRECT 2 /* type with variable */
128 int ch
, ch1
, tok
, tok1
;
131 /* loc : local variable index
132 glo : global variable index
133 ind : output code ptr
136 anon_sym: anonymous symbol index
139 prog
, ind
, loc
, glo
, const_wanted
;
140 int global_expr
; /* true if compound literals must be allocated
141 globally (used during initializers parsing */
142 int func_vt
, func_vc
; /* current function return type (used by
143 return instruction) */
145 TokenSym
**table_ident
;
146 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
147 char token_buf
[STRING_MAX_SIZE
+ 1];
148 char *filename
, *funcname
;
149 /* contains global symbols which remain between each translation unit */
150 SymStack extern_stack
;
151 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
153 SValue vstack
[VSTACK_SIZE
], *vtop
;
154 int *macro_ptr
, *macro_ptr_allocated
;
155 IncludeFile include_stack
[INCLUDE_STACK_SIZE
], *include_stack_ptr
;
156 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
157 char *include_paths
[INCLUDE_PATHS_MAX
];
158 int nb_include_paths
;
160 /* use GNU C extensions */
163 /* use Tiny C extensions */
166 /* The current value can be: */
167 #define VT_VALMASK 0x000f
168 #define VT_CONST 0x000a /* constant in vc
169 (must be first non register value) */
170 #define VT_LLOCAL 0x000b /* lvalue, offset on stack */
171 #define VT_LOCAL 0x000c /* offset on stack */
172 #define VT_CMP 0x000d /* the value is stored in processor flags (in vc) */
173 #define VT_JMP 0x000e /* value is the consequence of jmp true */
174 #define VT_JMPI 0x000f /* value is the consequence of jmp false */
175 #define VT_LVAL 0x0010 /* var is an lvalue */
176 #define VT_LVALN -17 /* ~VT_LVAL */
177 #define VT_FORWARD 0x0020 /* value is forward reference
178 (only used for functions) */
180 #define VT_EXTERN 0x00000040 /* extern definition */
181 #define VT_STATIC 0x00000080 /* static variable */
182 #define VT_TYPEDEF 0x00000100 /* typedef definition */
185 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
187 #define VT_BTYPE_SHIFT 9
188 #define VT_INT (0 << VT_BTYPE_SHIFT) /* integer type */
189 #define VT_BYTE (1 << VT_BTYPE_SHIFT) /* signed byte type */
190 #define VT_SHORT (2 << VT_BTYPE_SHIFT) /* short type */
191 #define VT_VOID (3 << VT_BTYPE_SHIFT) /* void type */
192 #define VT_PTR (4 << VT_BTYPE_SHIFT) /* pointer increment */
193 #define VT_ENUM (5 << VT_BTYPE_SHIFT) /* enum definition */
194 #define VT_FUNC (6 << VT_BTYPE_SHIFT) /* function type */
195 #define VT_STRUCT (7 << VT_BTYPE_SHIFT) /* struct/union definition */
196 #define VT_FLOAT (8 << VT_BTYPE_SHIFT) /* IEEE float */
197 #define VT_DOUBLE (9 << VT_BTYPE_SHIFT) /* IEEE double */
198 #define VT_LDOUBLE (10 << VT_BTYPE_SHIFT) /* IEEE long double */
199 #define VT_BOOL (11 << VT_BTYPE_SHIFT) /* ISOC99 boolean type */
200 #define VT_LLONG (12 << VT_BTYPE_SHIFT) /* 64 bit integer */
201 #define VT_LONG (13 << VT_BTYPE_SHIFT) /* long integer (NEVER
204 #define VT_BTYPE (0xf << VT_BTYPE_SHIFT) /* mask for basic type */
205 #define VT_UNSIGNED (0x10 << VT_BTYPE_SHIFT) /* unsigned type */
206 #define VT_ARRAY (0x20 << VT_BTYPE_SHIFT) /* array type (also has VT_PTR) */
207 #define VT_BITFIELD (0x40 << VT_BTYPE_SHIFT) /* bitfield modifier */
209 #define VT_TYPE 0xfffffe00 /* type mask */
213 /* warning: the following compare tokens depend on i386 asm code */
225 #define TOK_LAND 0xa0
229 #define TOK_MID 0xa3 /* inc/dec, to void constant */
231 #define TOK_ARROW 0xa7
232 #define TOK_DOTS 0xa8 /* three dots */
233 #define TOK_SHR 0xa9 /* unsigned shift right */
234 #define TOK_UDIV 0xb0 /* unsigned division */
235 #define TOK_UMOD 0xb1 /* unsigned modulo */
236 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
237 #define TOK_NUM 0xb3 /* number in tokc */
238 #define TOK_CCHAR 0xb4 /* char constant in tokc */
239 #define TOK_STR 0xb5 /* pointer to string in tokc */
240 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
241 #define TOK_LCHAR 0xb7
242 #define TOK_LSTR 0xb8
243 #define TOK_CFLOAT 0xb9 /* float constant */
244 #define TOK_CDOUBLE 0xc0 /* double constant */
245 #define TOK_CLDOUBLE 0xc1 /* long double constant */
247 #define TOK_SHL 0x01 /* shift left */
248 #define TOK_SAR 0x02 /* signed shift right */
250 /* assignement operators : normal operator or 0x80 */
251 #define TOK_A_MOD 0xa5
252 #define TOK_A_AND 0xa6
253 #define TOK_A_MUL 0xaa
254 #define TOK_A_ADD 0xab
255 #define TOK_A_SUB 0xad
256 #define TOK_A_DIV 0xaf
257 #define TOK_A_XOR 0xde
258 #define TOK_A_OR 0xfc
259 #define TOK_A_SHL 0x81
260 #define TOK_A_SAR 0x82
262 /* all identificators and strings have token above that */
263 #define TOK_IDENT 256
284 /* ignored types Must have contiguous values */
294 /* unsupported type */
307 /* preprocessor only */
308 TOK_UIDENT
, /* first "user" ident (not keyword) */
309 TOK_DEFINE
= TOK_UIDENT
,
325 /* special identifiers */
330 /* XXX: need to define this to use them in non ISOC99 context */
331 extern float strtof (const char *__nptr
, char **__endptr
);
332 extern long double strtold (const char *__nptr
, char **__endptr
);
336 void next_nomacro(void);
337 int expr_const(void);
341 void decl_initializer(int t
, int c
, int first
, int size_only
);
342 int decl_initializer_alloc(int t
, int has_init
);
344 void move_reg(int r
, int s
);
345 void save_reg(int r
);
351 void macro_subst(int **tok_str
, int *tok_len
,
352 Sym
**nested_list
, int *macro_str
);
353 int save_reg_forced(int r
);
355 void gen_cast(int t
);
357 int type_size(int t
, int *a
);
358 int pointed_type(int t
);
359 int pointed_size(int t
);
361 int type_decl(int *v
, int t
, int td
);
362 void error(const char *fmt
, ...);
363 void vset(int t
, int v
);
365 /* true if float/double/long double type */
366 static inline int is_float(int t
)
370 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
373 #include "i386-gen.c"
375 #ifdef CONFIG_TCC_STATIC
377 #define RTLD_LAZY 0x001
378 #define RTLD_NOW 0x002
379 #define RTLD_GLOBAL 0x100
381 /* dummy function for profiling */
382 void *dlopen(const char *filename
, int flag
)
387 const char *dlerror(void)
392 typedef struct TCCSyms
{
397 #define TCCSYM(a) { #a, &a, },
399 /* add the symbol you want here if no dynamic linking is done */
400 static TCCSyms tcc_syms
[] = {
408 void *dlsym(void *handle
, char *symbol
)
412 while (p
->str
!= NULL
) {
413 if (!strcmp(p
->str
, symbol
))
422 static inline int isid(int c
)
424 return (c
>= 'a' && c
<= 'z') ||
425 (c
>= 'A' && c
<= 'Z') ||
429 static inline int isnum(int c
)
431 return c
>= '0' & c
<= '9';
434 static inline int toup(int c
)
436 if (ch
>= 'a' && ch
<= 'z')
437 return ch
- 'a' + 'A';
445 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
446 fprintf(stderr
, "In file included from %s:%d:\n",
447 f
->filename
, f
->line_num
);
448 fprintf(stderr
, "%s:%d: ", filename
, line_num
);
451 void error(const char *fmt
, ...)
456 vfprintf(stderr
, fmt
, ap
);
457 fprintf(stderr
, "\n");
462 void expect(const char *msg
)
464 error("%s expected", msg
);
467 void warning(const char *msg
)
470 fprintf(stderr
, "warning: %s\n", msg
);
476 error("'%c' expected", c
);
480 void test_lvalue(void)
482 if (!(vtop
->t
& VT_LVAL
))
486 TokenSym
*tok_alloc(char *str
, int len
)
488 TokenSym
*ts
, **pts
, **ptable
;
495 h
= ((h
<< 8) | (str
[i
] & 0xff)) % TOK_HASH_SIZE
;
497 pts
= &hash_ident
[h
];
502 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
504 pts
= &(ts
->hash_next
);
507 if (tok_ident
>= SYM_FIRST_ANOM
)
508 error("memory full");
510 /* expand token table if needed */
511 i
= tok_ident
- TOK_IDENT
;
512 if ((i
% TOK_ALLOC_INCR
) == 0) {
513 ptable
= realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
515 error("memory full");
516 table_ident
= ptable
;
519 ts
= malloc(sizeof(TokenSym
) + len
);
521 error("memory full");
523 ts
->tok
= tok_ident
++;
525 ts
->hash_next
= NULL
;
526 memcpy(ts
->str
, str
, len
+ 1);
531 void add_char(char **pp
, int c
)
535 if (c
== '\'' || c
== '\"' || c
== '\\') {
536 /* XXX: could be more precise if char or string */
539 if (c
>= 32 && c
<= 126) {
546 *p
++ = '0' + ((c
>> 6) & 7);
547 *p
++ = '0' + ((c
>> 3) & 7);
548 *p
++ = '0' + (c
& 7);
554 /* XXX: buffer overflow */
555 char *get_tok_str(int v
, CValue
*cv
)
557 static char buf
[STRING_MAX_SIZE
+ 1];
563 sprintf(buf
, "%u", cv
->ui
);
565 } else if (v
== TOK_CCHAR
|| v
== TOK_LCHAR
) {
572 } else if (v
== TOK_STR
|| v
== TOK_LSTR
) {
576 for(i
=0;i
<ts
->len
;i
++)
577 add_char(&p
, ts
->str
[i
]);
581 } else if (v
< TOK_IDENT
) {
586 } else if (v
< tok_ident
) {
587 return table_ident
[v
- TOK_IDENT
]->str
;
589 /* should never happen */
594 /* push, without hashing */
595 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
598 s
= malloc(sizeof(Sym
));
600 error("memory full");
611 /* find a symbol and return its associated structure. 's' is the top
612 of the symbol stack */
613 Sym
*sym_find2(Sym
*s
, int v
)
623 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
625 /* find a symbol and return its associated structure. 'st' is the
627 Sym
*sym_find1(SymStack
*st
, int v
)
631 s
= st
->hash
[HASH_SYM(v
)];
640 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
643 s
= sym_push2(&st
->top
, v
, t
, c
);
644 /* add in hash table */
646 ps
= &st
->hash
[HASH_SYM(v
)];
653 /* find a symbol in the right symbol space */
657 s
= sym_find1(&local_stack
, v
);
659 s
= sym_find1(&global_stack
, v
);
663 /* push a given symbol on the symbol stack */
664 Sym
*sym_push(int v
, int t
, int c
)
667 return sym_push1(&local_stack
, v
, t
, c
);
669 return sym_push1(&global_stack
, v
, t
, c
);
672 /* pop symbols until top reaches 'b' */
673 void sym_pop(SymStack
*st
, Sym
*b
)
680 /* free hash table entry, except if symbol was freed (only
681 used for #undef symbols) */
683 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
690 /* undefined a hashed symbol (used for #undef). Its name is set to
692 void sym_undef(SymStack
*st
, Sym
*s
)
695 ss
= &st
->hash
[HASH_SYM(s
->v
)];
696 while (*ss
!= NULL
) {
699 ss
= &(*ss
)->hash_next
;
705 /* no need to put that inline */
708 if (include_stack_ptr
== include_stack
)
710 /* pop include stack */
714 file
= include_stack_ptr
->file
;
715 filename
= include_stack_ptr
->filename
;
716 line_num
= include_stack_ptr
->line_num
;
720 /* read next char from current input file */
721 static inline void inp(void)
724 /* faster than fgetc */
725 ch1
= getc_unlocked(file
);
727 if (handle_eof() < 0)
734 // printf("ch1=%c 0x%x\n", ch1, ch1);
737 /* input with '\\n' handling */
738 static inline void minp(void)
743 if (ch
== '\\' && ch1
== '\n') {
747 //printf("ch=%c 0x%x\n", ch, ch);
751 /* same as minp, but also skip comments */
759 /* single line C++ comments */
761 while (ch1
!= '\n' && ch1
!= -1)
764 ch
= ' '; /* return space */
765 } else if (ch1
== '*') {
771 if (c
== '*' && ch1
== '/') {
773 ch
= ' '; /* return space */
785 void skip_spaces(void)
787 while (ch
== ' ' || ch
== '\t')
791 /* skip block of text until #else, #elif or #endif. skip also pairs of
793 void preprocess_skip()
809 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
811 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
813 else if (tok
== TOK_ENDIF
)
819 /* return the number of additionnal 'ints' necessary to store the
821 static inline int tok_ext_size(int t
)
835 return LDOUBLE_SIZE
/ 4;
841 void tok_add(int **tok_str
, int *tok_len
, int t
)
846 if ((len
& 63) == 0) {
847 str
= realloc(str
, (len
+ 64) * sizeof(int));
856 void tok_add2(int **tok_str
, int *tok_len
, int t
, CValue
*cv
)
860 tok_add(tok_str
, tok_len
, t
);
863 tok_add(tok_str
, tok_len
, cv
->tab
[i
]);
866 /* get a token from an integer array and increment pointer accordingly */
867 int tok_get(int **tok_str
, CValue
*cv
)
880 /* eval an expression for #if/#elif */
881 int expr_preprocess(void)
891 next(); /* do macro subst */
892 if (tok
== TOK_DEFINED
) {
897 c
= sym_find1(&define_stack
, tok
) != 0;
902 } else if (tok
>= TOK_IDENT
) {
903 /* if undefined macro */
907 tok_add2(&str
, &len
, tok
, &tokc
);
909 tok_add(&str
, &len
, -1); /* simulate end of file */
910 tok_add(&str
, &len
, 0);
911 /* now evaluate C constant expression */
921 void tok_print(int *str
)
927 t
= tok_get(&str
, &cval
);
930 printf(" %s", get_tok_str(t
, &cval
));
936 /* XXX: should be more factorized */
937 void define_symbol(char *sym
)
943 ts
= tok_alloc(sym
, 0);
947 tok_add2(&str
, &len
, TOK_NUM
, &cval
);
948 tok_add(&str
, &len
, 0);
949 sym_push1(&define_stack
, ts
->tok
, MACRO_OBJ
, (int)str
);
952 void preprocess(void)
954 int size
, i
, c
, v
, t
, *str
, len
;
955 char buf
[1024], *q
, *p
;
958 Sym
**ps
, *first
, *s
;
963 if (tok
== TOK_DEFINE
) {
966 /* XXX: should check if same macro (ANSI) */
969 /* '(' must be just after macro definition for MACRO_FUNC */
976 tok
= TOK___VA_ARGS__
;
977 s
= sym_push1(&define_stack
, tok
| SYM_FIELD
, 0, 0);
991 if (ch
== '\n' || ch
== -1)
994 tok_add2(&str
, &len
, tok
, &tokc
);
996 tok_add(&str
, &len
, 0);
998 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1001 s
= sym_push1(&define_stack
, v
, t
, (int)str
);
1003 } else if (tok
== TOK_UNDEF
) {
1005 s
= sym_find1(&define_stack
, tok
);
1006 /* undefine symbol by putting an invalid name */
1008 sym_undef(&define_stack
, s
);
1009 } else if (tok
== TOK_INCLUDE
) {
1014 } else if (ch
== '\"') {
1019 while (ch
!= c
&& ch
!= '\n' && ch
!= -1) {
1020 if ((q
- buf
) < sizeof(buf
) - 1)
1028 error("#include syntax error");
1029 /* XXX: buffer overflow */
1030 strcpy(buf
, get_tok_str(tok
, &tokc
));
1033 /* eat all spaces and comments after include */
1034 /* XXX: slightly incorrect */
1035 while (ch1
!= '\n' && ch1
!= -1)
1038 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1039 error("memory full");
1041 /* first search in current dir if "header.h" */
1042 /* XXX: buffer overflow */
1044 p
= strrchr(filename
, '/');
1046 size
= p
+ 1 - filename
;
1047 memcpy(buf1
, filename
, size
);
1050 f
= fopen(buf1
, "r");
1054 /* now search in standard include path */
1055 for(i
=nb_include_paths
- 1;i
>=0;i
--) {
1056 strcpy(buf1
, include_paths
[i
]);
1059 f
= fopen(buf1
, "r");
1063 error("include file '%s' not found", buf1
);
1066 /* push current file in stack */
1067 /* XXX: fix current line init */
1068 include_stack_ptr
->file
= file
;
1069 include_stack_ptr
->filename
= filename
;
1070 include_stack_ptr
->line_num
= line_num
;
1071 include_stack_ptr
++;
1073 filename
= strdup(buf1
);
1075 } else if (tok
== TOK_IFNDEF
) {
1078 } else if (tok
== TOK_IF
) {
1079 c
= expr_preprocess();
1081 } else if (tok
== TOK_IFDEF
) {
1085 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1087 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1088 error("memory full");
1089 *ifdef_stack_ptr
++ = c
;
1091 } else if (tok
== TOK_ELSE
) {
1092 if (ifdef_stack_ptr
== ifdef_stack
||
1093 (ifdef_stack_ptr
[-1] & 2))
1094 error("#else after #else");
1095 c
= (ifdef_stack_ptr
[-1] ^= 3);
1097 } else if (tok
== TOK_ELIF
) {
1098 if (ifdef_stack_ptr
== ifdef_stack
||
1099 ifdef_stack_ptr
[-1] > 1)
1100 error("#elif after #else");
1101 c
= expr_preprocess();
1102 ifdef_stack_ptr
[-1] = c
;
1108 } else if (tok
== TOK_ENDIF
) {
1109 if (ifdef_stack_ptr
== ifdef_stack
)
1112 } else if (tok
== TOK_LINE
) {
1122 /* XXX: potential memory leak */
1123 filename
= strdup(get_tok_str(tok
, &tokc
));
1125 } else if (tok
== TOK_ERROR
) {
1128 /* ignore other preprocess commands or #! for C scripts */
1129 while (ch
!= '\n' && ch
!= -1)
1133 /* read a number in base b */
1139 if (ch
>= 'a' & ch
<= 'f')
1141 else if (ch
>= 'A' & ch
<= 'F')
1155 /* read a character for string or char constant and eval escape codes */
1164 /* at most three octal digits */
1168 c
= c
* 8 + ch
- '0';
1171 c
= c
* 8 + ch
- '0';
1176 } else if (ch
== 'x') {
1194 else if (ch
== 'e' && gnu_ext
)
1196 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
1199 error("invalid escaped char");
1206 /* we use 64 bit numbers */
1209 /* bn = (bn << shift) | or_val */
1210 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
1214 for(i
=0;i
<BN_SIZE
;i
++) {
1216 bn
[i
] = (v
<< shift
) | or_val
;
1217 or_val
= v
>> (32 - shift
);
1221 void bn_zero(unsigned int *bn
)
1224 for(i
=0;i
<BN_SIZE
;i
++) {
1229 void parse_number(void)
1231 int b
, t
, shift
, frac_bits
, s
, exp_val
;
1234 unsigned int bn
[BN_SIZE
];
1244 /* special dot handling */
1245 if (ch
>= '0' && ch
<= '9') {
1246 goto float_frac_parse
;
1247 } else if (ch
== '.') {
1258 } else if (t
== '0') {
1259 if (ch
== 'x' || ch
== 'X') {
1263 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
1269 /* parse all digits. cannot check octal numbers at this stage
1270 because of floating point constants */
1272 if (ch
>= 'a' & ch
<= 'f')
1274 else if (ch
>= 'A' & ch
<= 'F')
1282 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
1284 error("number too long");
1290 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
1291 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
1293 /* NOTE: strtox should support that for hexa numbers, but
1294 non ISOC99 libcs do not support it, so we prefer to do
1296 /* hexadecimal or binary floats */
1297 /* XXX: handle overflows */
1309 } else if (t
>= 'a') {
1311 } else if (t
>= 'A') {
1316 bn_lshift(bn
, shift
, t
);
1323 if (t
>= 'a' && t
<= 'f') {
1325 } else if (t
>= 'A' && t
<= 'F') {
1327 } else if (t
>= '0' && t
<= '9') {
1333 error("invalid digit");
1334 bn_lshift(bn
, shift
, t
);
1339 if (ch
!= 'p' && ch
!= 'P')
1340 error("exponent expected");
1346 } else if (ch
== '-') {
1350 if (ch
< '0' || ch
> '9')
1351 error("exponent digits expected");
1352 while (ch
>= '0' && ch
<= '9') {
1353 exp_val
= exp_val
* 10 + ch
- '0';
1356 exp_val
= exp_val
* s
;
1358 /* now we can generate the number */
1359 /* XXX: should patch directly float number */
1360 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
1361 d
= ldexp(d
, exp_val
- frac_bits
);
1366 /* float : should handle overflow */
1368 } else if (t
== 'L') {
1371 /* XXX: not large enough */
1372 tokc
.ld
= (long double)d
;
1378 /* decimal floats */
1380 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1385 while (ch
>= '0' && ch
<= '9') {
1386 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1392 if (ch
== 'e' || ch
== 'E') {
1393 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1397 if (ch
== '-' || ch
== '+') {
1398 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1403 if (ch
< '0' || ch
> '9')
1404 error("exponent digits expected");
1405 while (ch
>= '0' && ch
<= '9') {
1406 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1418 tokc
.f
= strtof(token_buf
, NULL
);
1419 } else if (t
== 'L') {
1422 tokc
.ld
= strtold(token_buf
, NULL
);
1425 tokc
.d
= strtod(token_buf
, NULL
);
1429 /* integer number */
1432 if (b
== 10 && *q
== '0') {
1439 /* no need for checks except for base 10 / 8 errors */
1442 } else if (t
>= 'a') {
1444 } else if (t
>= 'A') {
1449 error("invalid digit");
1453 /* detect overflow */
1455 error("integer constant overflow");
1459 /* XXX: add unsigned constant support (ANSI) */
1460 while (ch
== 'L' || ch
== 'l' || ch
== 'U' || ch
== 'u')
1466 /* return next token without macro substitution */
1467 void next_nomacro1(void)
1475 while (ch
== '\n') {
1477 while (ch
== ' ' || ch
== 9)
1480 /* preprocessor command if # at start of line after
1485 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
1503 while (isid(ch
) || isnum(ch
)) {
1504 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1505 error("ident too long");
1510 ts
= tok_alloc(token_buf
, q
- token_buf
);
1512 } else if (isnum(ch
) || ch
== '.') {
1514 } else if (ch
== '\'') {
1522 } else if (ch
== '\"') {
1527 while (ch
!= '\"') {
1530 error("unterminated string");
1531 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1532 error("string too long");
1536 tokc
.ts
= tok_alloc(token_buf
, q
- token_buf
);
1539 q
= "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\247..\250##\266";
1544 if (*q
== tok
&& q
[1] == ch
) {
1547 /* three chars tests */
1548 if (tok
== TOK_SHL
| tok
== TOK_SAR
) {
1553 } else if (tok
== TOK_DOTS
) {
1555 error("parse error");
1562 /* single char substitutions */
1565 else if (tok
== '>')
1570 /* return next token without macro substitution. Can read input from
1577 tok
= tok_get(¯o_ptr
, &tokc
);
1583 /* substitute args in macro_str and return allocated string */
1584 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
1586 int *st
, last_tok
, t
, notfirst
, *str
, len
;
1595 t
= tok_get(¯o_str
, &cval
);
1600 t
= tok_get(¯o_str
, &cval
);
1603 s
= sym_find2(args
, t
);
1605 token_buf
[0] = '\0';
1607 /* XXX: buffer overflow */
1611 strcat(token_buf
, " ");
1612 t
= tok_get(&st
, &cval
);
1613 strcat(token_buf
, get_tok_str(t
, &cval
));
1617 printf("stringize: %s\n", token_buf
);
1620 ts
= tok_alloc(token_buf
, 0);
1622 tok_add2(&str
, &len
, TOK_STR
, &cval
);
1624 tok_add2(&str
, &len
, t
, &cval
);
1626 } else if (t
>= TOK_IDENT
) {
1627 s
= sym_find2(args
, t
);
1630 /* if '##' is present before or after , no arg substitution */
1631 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
1633 tok_add(&str
, &len
, *st
++);
1635 macro_subst(&str
, &len
, nested_list
, st
);
1638 tok_add(&str
, &len
, t
);
1641 tok_add2(&str
, &len
, t
, &cval
);
1645 tok_add(&str
, &len
, 0);
1649 /* handle the '##' operator */
1650 int *macro_twosharps(int *macro_str
)
1653 int *macro_str1
, macro_str1_len
, *macro_ptr1
;
1665 while (*macro_ptr
== TOK_TWOSHARPS
) {
1667 macro_ptr1
= macro_ptr
;
1670 t
= tok_get(¯o_ptr
, &cval
);
1671 /* XXX: we handle only most common cases:
1672 ident + ident or ident + number */
1673 if (tok
>= TOK_IDENT
&&
1674 (t
>= TOK_IDENT
|| t
== TOK_NUM
)) {
1675 /* XXX: buffer overflow */
1676 p
= get_tok_str(tok
, &tokc
);
1677 strcpy(token_buf
, p
);
1678 p
= get_tok_str(t
, &cval
);
1679 strcat(token_buf
, p
);
1680 ts
= tok_alloc(token_buf
, 0);
1681 tok
= ts
->tok
; /* modify current token */
1683 /* cannot merge tokens: skip '##' */
1684 macro_ptr
= macro_ptr1
;
1689 tok_add2(¯o_str1
, ¯o_str1_len
, tok
, &tokc
);
1691 tok_add(¯o_str1
, ¯o_str1_len
, 0);
1697 /* do macro substitution of macro_str and add result to
1698 (tok_str,tok_len). If macro_str is NULL, then input stream token is
1699 substituted. 'nested_list' is the list of all macros we got inside
1700 to avoid recursing. */
1701 void macro_subst(int **tok_str
, int *tok_len
,
1702 Sym
**nested_list
, int *macro_str
)
1704 Sym
*s
, *args
, *sa
, *sa1
;
1705 int *str
, parlevel
, len
, *mstr
, t
, *saved_macro_ptr
;
1706 int mstr_allocated
, *macro_str1
;
1709 saved_macro_ptr
= macro_ptr
;
1710 macro_ptr
= macro_str
;
1713 /* first scan for '##' operator handling */
1714 macro_str1
= macro_twosharps(macro_str
);
1715 macro_ptr
= macro_str1
;
1722 /* special macros */
1723 if (tok
== TOK___LINE__
) {
1725 tok_add2(tok_str
, tok_len
, TOK_NUM
, &cval
);
1726 } else if (tok
== TOK___FILE__
) {
1727 cval
.ts
= tok_alloc(filename
, 0);
1728 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
1729 } else if (tok
== TOK___DATE__
) {
1730 cval
.ts
= tok_alloc("Jan 1 1970", 0);
1731 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
1732 } else if (tok
== TOK___TIME__
) {
1733 cval
.ts
= tok_alloc("00:00:00", 0);
1734 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
1735 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
1736 /* if symbol is a macro, prepare substitution */
1737 /* if nested substitution, do nothing */
1738 if (sym_find2(*nested_list
, tok
))
1742 if (s
->t
== MACRO_FUNC
) {
1743 /* NOTE: we do not use next_nomacro to avoid eating the
1744 next token. XXX: find better solution */
1748 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
1752 if (t
!= '(') /* no macro subst */
1755 /* argument macro */
1760 while (tok
!= ')' && sa
) {
1764 while ((parlevel
> 0 ||
1767 sa
->v
== (TOK___VA_ARGS__
| SYM_FIELD
)))) &&
1771 else if (tok
== ')')
1773 tok_add2(&str
, &len
, tok
, &tokc
);
1776 tok_add(&str
, &len
, 0);
1777 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, 0, (int)str
);
1785 /* now subst each arg */
1786 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
1797 sym_push2(nested_list
, s
->v
, 0, 0);
1798 macro_subst(tok_str
, tok_len
, nested_list
, mstr
);
1799 /* pop nested defined symbol */
1801 *nested_list
= sa1
->prev
;
1807 /* no need to add if reading input stream */
1810 tok_add2(tok_str
, tok_len
, tok
, &tokc
);
1812 /* only replace one macro while parsing input stream */
1816 macro_ptr
= saved_macro_ptr
;
1821 /* return next token with macro substitution */
1827 /* special 'ungettok' case for label parsing */
1835 /* if not reading from macro substuted string, then try to substitute */
1839 macro_subst(&ptr
, &len
, &nested_list
, NULL
);
1841 tok_add(&ptr
, &len
, 0);
1843 macro_ptr_allocated
= ptr
;
1851 /* end of macro string: free it */
1852 free(macro_ptr_allocated
);
1859 printf("token = %s\n", get_tok_str(tok
, tokc
));
1863 void swap(int *p
, int *q
)
1871 void vsetc(int t
, CValue
*vc
)
1873 if (vtop
>= vstack
+ VSTACK_SIZE
)
1874 error("memory full");
1875 /* cannot let cpu flags if other instruction are generated */
1876 /* XXX: VT_JMP test too ? */
1877 if ((vtop
->t
& VT_VALMASK
) == VT_CMP
)
1884 void vset(int t
, int v
)
1903 if (vtop
>= vstack
+ VSTACK_SIZE
)
1904 error("memory full");
1909 int save_reg_forced(int r
)
1914 /* store register */
1915 loc
= (loc
- 4) & -3;
1916 store(r
, VT_LOCAL
, loc
);
1919 /* modify all stack values */
1920 for(p
=vstack
;p
<=vtop
;p
++) {
1921 i
= p
->t
& VT_VALMASK
;
1927 p
->t
= (p
->t
& VT_TYPE
) | VT_LVAL
| t
;
1934 /* save r to memory. and mark it as being free */
1935 void save_reg(int r
)
1940 /* modify all stack values */
1941 for(p
=vstack
;p
<=vtop
;p
++) {
1942 i
= p
->t
& VT_VALMASK
;
1950 /* find a free register of class 'rc'. If none, save one register */
1956 /* find a free register */
1957 for(r
=0;r
<NB_REGS
;r
++) {
1958 if (reg_classes
[r
] & rc
) {
1959 for(p
=vstack
;p
<=vtop
;p
++) {
1960 i
= p
->t
& VT_VALMASK
;
1969 /* no register left : free the first one on the stack (very
1970 important to start from the bottom to ensure that we don't
1971 spill registers used in gen_op()) */
1972 for(p
=vstack
;p
<=vtop
;p
++) {
1973 r
= p
->t
& VT_VALMASK
;
1974 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
1987 for(p
=vstack
;p
<=vtop
;p
++) {
1988 r
= p
->t
& VT_VALMASK
;
1995 /* move register 's' to 'r', and flush previous value of r to memory
1997 void move_reg(int r
, int s
)
2005 /* convert a (vtop->t, vtop->c) in register. lvalues are converted as
2006 values. Cannot be used if cannot be converted to register value
2007 (such as structures). */
2010 int r
, bit_pos
, bit_size
, rc
, size
, align
, i
;
2012 /* NOTE: get_reg can modify vstack[] */
2013 if (vtop
->t
& VT_BITFIELD
) {
2014 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2015 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2016 /* remove bit field info to avoid loops */
2017 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2018 /* generate shifts */
2019 vset(VT_CONST
, 32 - (bit_pos
+ bit_size
));
2021 vset(VT_CONST
, 32 - bit_size
);
2022 /* NOTE: transformed to SHR if unsigned */
2026 if (is_float(vtop
->t
) && (vtop
->t
& (VT_CONST
| VT_LVAL
)) == VT_CONST
) {
2027 /* CPUs usually cannot use float constants, so we store them
2028 generically in data segment */
2029 size
= type_size(vtop
->t
, &align
);
2030 glo
= (glo
+ align
- 1) & -align
;
2031 /* XXX: not portable yet */
2034 ((int *)glo
)[i
] = vtop
->c
.tab
[i
];
2039 r
= vtop
->t
& VT_VALMASK
;
2040 if (r
>= VT_CONST
|| (vtop
->t
& VT_LVAL
)) {
2041 if (is_float(vtop
->t
))
2042 rc
= REG_CLASS_FLOAT
;
2047 load(r
, vtop
->t
, vtop
->c
.ul
);
2048 vtop
->t
= (vtop
->t
& VT_TYPE
) | r
;
2053 /* handle constant optimizations and various machine independant opt */
2054 void gen_opc(int op
)
2061 /* currently, we cannot do computations with forward symbols */
2062 c1
= (v1
->t
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
2063 c2
= (v2
->t
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
2067 case '+': v1
->c
.i
+= fc
; break;
2068 case '-': v1
->c
.i
-= fc
; break;
2069 case '&': v1
->c
.i
&= fc
; break;
2070 case '^': v1
->c
.i
^= fc
; break;
2071 case '|': v1
->c
.i
|= fc
; break;
2072 case '*': v1
->c
.i
*= fc
; break;
2074 case '/': v1
->c
.i
/= fc
; break; /* XXX: zero case ? */
2075 case '%': v1
->c
.i
%= fc
; break; /* XXX: zero case ? */
2076 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break; /* XXX: zero case ? */
2077 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break; /* XXX: zero case ? */
2078 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
2079 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
2080 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
2082 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
2083 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
2084 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
2085 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
2086 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
2087 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
2088 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
2089 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
2090 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
2091 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
2093 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
2094 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
2100 /* if commutative ops, put c2 as constant */
2101 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
2102 op
== '|' || op
== '*')) {
2107 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
2110 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
2111 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
2117 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
2118 /* try to use shifts instead of muls or divs */
2119 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
2128 else if (op
== TOK_PDIV
)
2136 /* call low level op generator */
2137 /* XXX: remove explicit registers */
2143 int pointed_size(int t
)
2145 return type_size(pointed_type(t
), &t
);
2148 /* generic gen_op: handles types problems */
2151 int u
, t1
, t2
, bt1
, bt2
, t
;
2155 bt1
= t1
& VT_BTYPE
;
2156 bt2
= t2
& VT_BTYPE
;
2158 if (is_float(bt1
) || is_float(bt2
)) {
2159 /* compute bigger type and do implicit casts */
2160 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
2162 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
2167 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
2168 op
< TOK_EQ
|| op
> TOK_GT
)
2169 error("invalid operands for binary operation");
2179 if (op
>= TOK_EQ
&& op
<= TOK_GT
) {
2180 /* the result is an int */
2181 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | VT_INT
;
2183 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | t
;
2185 } else if (op
== '+' || op
== '-') {
2186 if ((t1
& VT_BTYPE
) == VT_PTR
&&
2187 (t2
& VT_BTYPE
) == VT_PTR
) {
2189 error("invalid type");
2190 /* XXX: check that types are compatible */
2191 u
= pointed_size(t1
);
2193 /* set to integer type */
2194 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | VT_INT
;
2197 } else if ((t1
& VT_BTYPE
) == VT_PTR
||
2198 (t2
& VT_BTYPE
) == VT_PTR
) {
2199 if ((t2
& VT_BTYPE
) == VT_PTR
) {
2203 /* stack-4 contains pointer, stack-2 value to add */
2204 vset(VT_CONST
, pointed_size(vtop
[-1].t
));
2207 /* put again type if gen_opc() swaped operands */
2208 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | (t1
& VT_TYPE
);
2213 /* XXX: test types and compute returned value */
2214 if ((t1
| t2
) & VT_UNSIGNED
||
2215 (t1
& VT_BTYPE
) == VT_PTR
||
2216 (t2
& VT_BTYPE
) == VT_PTR
) {
2223 else if (op
== TOK_LT
)
2225 else if (op
== TOK_GT
)
2227 else if (op
== TOK_LE
)
2229 else if (op
== TOK_GE
)
2236 /* cast 'vtop' to 't' type */
2237 void gen_cast(int t
)
2239 int r
, bits
, sbt
, dbt
, sf
, df
, c
, st1
, dt1
;
2241 r
= vtop
->t
& VT_VALMASK
;
2242 if (!(t
& VT_LVAL
)) {
2243 /* if not lvalue, then we convert now */
2245 sbt
= vtop
->t
& VT_BTYPE
;
2249 c
= (vtop
->t
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
2251 /* convert from fp to fp */
2253 /* constant case: we can do it now */
2254 /* XXX: in ISOC, cannot do it if error in convert */
2255 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
2256 vtop
->c
.f
= (float)vtop
->c
.d
;
2257 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
2258 vtop
->c
.f
= (float)vtop
->c
.ld
;
2259 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
2260 vtop
->c
.d
= (double)vtop
->c
.f
;
2261 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
2262 vtop
->c
.d
= (double)vtop
->c
.ld
;
2263 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
2264 vtop
->c
.ld
= (long double)vtop
->c
.f
;
2265 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
2266 vtop
->c
.ld
= (long double)vtop
->c
.d
;
2268 /* non constant case: generate code */
2272 /* convert int to fp */
2273 /* XXX: add const cases */
2274 st1
= vtop
->t
& (VT_BTYPE
| VT_UNSIGNED
);
2277 case VT_LLONG
| VT_UNSIGNED
:
2279 /* well, currently not needed */
2281 case VT_INT
| VT_UNSIGNED
:
2283 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
2284 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
2285 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
2290 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
2291 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
2292 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
2301 /* convert fp to int */
2302 dt1
= t
& (VT_BTYPE
| VT_UNSIGNED
);
2303 /* we handle char/short/etc... with generic code */
2304 if (dt1
!= VT_INT
| VT_UNSIGNED
&&
2305 dt1
!= VT_LLONG
| VT_UNSIGNED
&&
2310 case VT_LLONG
| VT_UNSIGNED
:
2312 /* well, currently not needed */
2314 case VT_INT
| VT_UNSIGNED
:
2316 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
2317 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
2318 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
2324 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
2325 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
2326 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
2334 if (dt1
== VT_INT
&& (t
& (VT_TYPE
| VT_UNSIGNED
)) != dt1
) {
2335 /* additionnal cast for char/short/bool... */
2336 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | dt1
;
2339 } else if (dbt
== VT_BOOL
) {
2342 } else if (dbt
== VT_BYTE
|| dbt
== VT_SHORT
) {
2347 if (t
& VT_UNSIGNED
) {
2348 vset(VT_CONST
, (1 << bits
) - 1);
2352 vset(VT_CONST
, bits
);
2354 vset(VT_CONST
, bits
);
2360 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | t
;
2363 /* return type size. Put alignment at 'a' */
2364 int type_size(int t
, int *a
)
2370 if (bt
== VT_STRUCT
) {
2372 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
2373 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
2375 } else if (bt
== VT_PTR
) {
2377 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
2378 return type_size(s
->t
, a
) * s
->c
;
2383 } else if (bt
== VT_LDOUBLE
) {
2385 return LDOUBLE_SIZE
;
2386 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
2389 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
2392 } else if (bt
== VT_SHORT
) {
2396 /* char, void, function, _Bool */
2402 /* return the pointed type of t */
2403 int pointed_type(int t
)
2406 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
2407 return s
->t
| (t
& ~VT_TYPE
);
2410 int mk_pointer(int t
)
2415 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
2418 int is_compatible_types(int t1
, int t2
)
2425 bt1
= t1
& VT_BTYPE
;
2426 bt2
= t2
& VT_BTYPE
;
2427 if (bt1
== VT_PTR
) {
2428 t1
= pointed_type(t1
);
2429 /* if function, then convert implicitely to function pointer */
2430 if (bt2
!= VT_FUNC
) {
2433 t2
= pointed_type(t2
);
2435 /* void matches everything */
2438 if (t1
== VT_VOID
|| t2
== VT_VOID
)
2440 return is_compatible_types(t1
, t2
);
2441 } else if (bt1
== VT_STRUCT
) {
2443 } else if (bt1
== VT_FUNC
) {
2446 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
2447 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
2448 if (!is_compatible_types(s1
->t
, s2
->t
))
2450 /* XXX: not complete */
2451 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
2455 while (s1
!= NULL
) {
2458 if (!is_compatible_types(s1
->t
, s2
->t
))
2467 /* XXX: not complete */
2472 int check_assign_types(int t1
, int t2
)
2476 if ((t1
& VT_BTYPE
) == VT_PTR
&&
2477 (t2
& VT_BTYPE
) == VT_FUNC
) {
2478 return is_compatible_types(pointed_type(t1
), t2
);
2480 return is_compatible_types(t1
, t2
);
2484 /* print a type. If 'varstr' is not NULL, then the variable is also
2485 printed in the type */
2486 /* XXX: add array and function pointers */
2487 /* XXX: buffer overflows */
2488 void type_to_str(char *buf
, int buf_size
,
2489 int t
, const char *varstr
)
2498 if (t
& VT_UNSIGNED
)
2499 strcat(buf
, "unsigned ");
2502 strcat(buf
, "void");
2505 strcat(buf
, "_Bool");
2508 strcat(buf
, "char");
2511 strcat(buf
, "short");
2517 strcat(buf
, "long");
2520 strcat(buf
, "long long");
2523 strcat(buf
, "float");
2526 strcat(buf
, "double");
2529 strcat(buf
, "long double");
2533 if (bt
== VT_STRUCT
)
2534 strcat(buf
, "struct ");
2536 strcat(buf
, "enum ");
2537 v
= (unsigned)t
>> VT_STRUCT_SHIFT
;
2538 if (v
>= SYM_FIRST_ANOM
)
2539 strcat(buf
, "<anonymous>");
2541 strcat(buf
, get_tok_str(v
, NULL
));
2544 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
2545 type_to_str(buf
, buf_size
, s
->t
, varstr
);
2548 while (sa
!= NULL
) {
2549 type_to_str(buf1
, sizeof(buf1
), sa
->t
, NULL
);
2558 s
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
2561 strcat(buf1
, varstr
);
2562 type_to_str(buf
, buf_size
, s
->t
, buf1
);
2567 strcat(buf
, varstr
);
2574 /* verify type compatibility to store vtop in 'st' type, and generate
2576 void gen_assign_cast(int dt
)
2579 char buf1
[256], buf2
[256];
2581 st
= vtop
->t
; /* destination type */
2582 if (!check_assign_types(dt
, st
)) {
2583 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
2584 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
2585 error("cannot cast '%s' to '%s'", buf1
, buf2
);
2587 if ((dt
& VT_BTYPE
) == VT_BOOL
|| is_float(dt
)) {
2588 gen_cast(dt
& VT_BTYPE
);
2593 /* store vtop in lvalue pushed on stack */
2596 int ft
, fc
, r
, t
, size
, align
, bit_size
, bit_pos
;
2600 gen_assign_cast(ft
& VT_TYPE
);
2602 if ((vtop
->t
& VT_BTYPE
) == VT_STRUCT
) {
2603 /* if structure, only generate pointer */
2604 /* structure assignment : generate memcpy */
2605 /* XXX: optimize if small size */
2610 size
= type_size(vtop
->t
, &align
);
2611 vset(VT_CONST
, size
);
2614 vtop
->t
&= ~VT_LVAL
;
2618 vtop
->t
&= ~VT_LVAL
;
2622 vset(VT_CONST
, (int)&memcpy
);
2624 /* leave source on stack */
2625 } else if (ft
& VT_BITFIELD
) {
2626 /* bitfield store handling */
2627 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
2628 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2629 /* remove bit field info to avoid loops */
2630 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2632 /* duplicate destination */
2634 vtop
[-1] = vtop
[-2];
2636 /* mask and shift source */
2637 vset(VT_CONST
, (1 << bit_size
) - 1);
2639 vset(VT_CONST
, bit_pos
);
2641 /* load destination, mask and or with source */
2643 vset(VT_CONST
, ~(((1 << bit_size
) - 1) << bit_pos
));
2649 r
= gv(); /* generate value */
2652 /* if lvalue was saved on stack, must read it */
2653 if ((ft
& VT_VALMASK
) == VT_LLOCAL
) {
2654 t
= get_reg(REG_CLASS_INT
);
2655 load(t
, VT_LOCAL
| VT_LVAL
, fc
);
2656 ft
= (ft
& ~VT_VALMASK
) | t
;
2660 vtop
->t
= (ft
& VT_TYPE
) | r
;
2665 /* post defines POST/PRE add. c is the token ++ or -- */
2666 void inc(int post
, int c
)
2672 vdup(); /* room for returned value */
2673 vdup(); /* save lvalue */
2676 /* duplicate value */
2677 /* XXX: handle floats */
2678 r1
= get_reg(REG_CLASS_INT
);
2679 load(r1
, r
, 0); /* move r to r1 */
2680 /* duplicates value */
2681 vtop
[-2].t
= (vtop
->t
& VT_TYPE
) | r1
;
2685 vset(VT_CONST
, c
- TOK_MID
);
2687 vstore(); /* store value */
2689 vpop(); /* if post op, return saved value */
2692 /* enum/struct/union declaration */
2693 int struct_decl(int u
)
2695 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
2696 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
2699 a
= tok
; /* save decl type */
2704 /* struct already defined ? return it */
2705 /* XXX: check consistency */
2706 if (s
= sym_find(v
| SYM_STRUCT
)) {
2708 error("invalid type");
2714 s
= sym_push(v
| SYM_STRUCT
, a
, 0);
2715 /* put struct/union/enum name in type */
2717 u
= u
| (v
<< VT_STRUCT_SHIFT
);
2722 error("struct/union/enum already defined");
2723 /* cannot be empty */
2730 if (a
== TOK_ENUM
) {
2737 /* enum symbols have static storage */
2738 sym_push(v
, VT_CONST
| VT_STATIC
, c
);
2748 t
= type_decl(&v
, b
, TYPE_DIRECT
);
2749 if ((t
& VT_BTYPE
) == VT_FUNC
||
2750 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
2751 error("invalid type for '%s'",
2752 get_tok_str(v
, NULL
));
2758 bit_size
= expr_const();
2759 /* XXX: handle v = 0 case for messages */
2761 error("negative width in bit-field '%s'",
2762 get_tok_str(v
, NULL
));
2763 if (v
&& bit_size
== 0)
2764 error("zero width for bit-field '%s'",
2765 get_tok_str(v
, NULL
));
2767 size
= type_size(t
, &align
);
2769 if (bit_size
>= 0) {
2774 error("bitfields must have scalar type");
2776 if (bit_size
> bsize
) {
2777 error("width of '%s' exceeds its type",
2778 get_tok_str(v
, NULL
));
2779 } else if (bit_size
== bsize
) {
2780 /* no need for bit fields */
2782 } else if (bit_size
== 0) {
2783 /* XXX: what to do if only padding in a
2785 /* zero size: means to pad */
2789 /* we do not have enough room ? */
2790 if ((bit_pos
+ bit_size
) > bsize
)
2793 /* XXX: handle LSB first */
2795 (bit_pos
<< VT_STRUCT_SHIFT
) |
2796 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
2797 bit_pos
+= bit_size
;
2803 /* add new memory data only if starting
2805 if (lbit_pos
== 0) {
2806 if (a
== TOK_STRUCT
) {
2807 c
= (c
+ align
- 1) & -align
;
2815 if (align
> maxalign
)
2819 printf("add field %s offset=%d",
2820 get_tok_str(v
, NULL
), offset
);
2821 if (t
& VT_BITFIELD
) {
2822 printf(" pos=%d size=%d",
2823 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
2824 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
2828 ss
= sym_push(v
| SYM_FIELD
, t
, offset
);
2832 if (tok
== ';' || tok
== -1)
2842 /* size for struct/union, dummy for enum */
2843 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
2848 /* return 0 if no type declaration. otherwise, return the basic type
2850 XXX: A '2' is ored to ensure non zero return if int type.
2866 if ((t
& VT_BTYPE
) != 0)
2867 error("too many basic types %x", t
);
2881 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
2882 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
2883 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
2884 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
2898 if ((t
& VT_BTYPE
) == VT_LONG
) {
2899 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
2906 u
= struct_decl(VT_ENUM
);
2910 u
= struct_decl(VT_STRUCT
);
2913 /* type modifiers */
2943 if (!s
|| !(s
->t
& VT_TYPEDEF
))
2945 t
|= (s
->t
& ~VT_TYPEDEF
);
2952 /* long is never used as type */
2953 if ((t
& VT_BTYPE
) == VT_LONG
)
2954 t
= (t
& ~VT_BTYPE
) | VT_INT
;
2958 int post_type(int t
)
2960 int p
, n
, pt
, l
, t1
;
2961 Sym
**plast
, *s
, *first
;
2964 /* function declaration */
2969 while (tok
!= ')') {
2970 /* read param name and compute offset */
2971 if (l
!= FUNC_OLD
) {
2972 if (!(pt
= ist())) {
2974 error("invalid type");
2981 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
2983 pt
= type_decl(&n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
2984 if ((pt
& VT_BTYPE
) == VT_VOID
)
2985 error("parameter declared as void");
2992 /* array must be transformed to pointer according to ANSI C */
2994 s
= sym_push(n
| SYM_FIELD
, pt
, 0);
2999 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
3006 /* if no parameters, then old type prototype */
3010 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
3011 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
));
3012 /* we push a anonymous symbol which will contain the function prototype */
3014 s
= sym_push(p
, t
, l
);
3016 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
3017 } else if (tok
== '[') {
3018 /* array definition */
3024 error("invalid array size");
3027 /* parse next post type */
3028 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
3029 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
));
3031 /* we push a anonymous symbol which will contain the array
3035 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
3040 /* Read a type declaration (except basic type), and return the
3041 type. If v is true, then also put variable name in 'vtop->c' */
3042 int type_decl(int *v
, int t
, int td
)
3047 t
= t
& -3; /* suppress the ored '2' */
3048 while (tok
== '*') {
3050 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
3055 /* recursive type */
3056 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
3059 u
= type_decl(v
, 0, td
);
3063 /* type identifier */
3064 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
3068 if (!(td
& TYPE_ABSTRACT
))
3069 expect("identifier");
3073 /* append t at the end of u */
3079 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
3089 /* define a new external reference to a function 'v' of type 'u' */
3090 Sym
*external_sym(int v
, int u
)
3095 /* push forward reference */
3096 s
= sym_push1(&global_stack
,
3097 v
, u
| VT_CONST
| VT_FORWARD
, 0);
3104 if (vtop
->t
& VT_LVAL
)
3106 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
3108 vtop
->t
= pointed_type(vtop
->t
);
3109 if (!(vtop
->t
& VT_ARRAY
)) /* an array is never an lvalue */
3113 /* pass a parameter to a function and do type checking and casting */
3114 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
3117 func_type
= func
->c
;
3118 if (func_type
== FUNC_OLD
||
3119 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
3120 /* default casting : only need to convert float to double */
3121 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
)
3122 gen_cast(VT_DOUBLE
);
3123 } else if (arg
== NULL
) {
3124 error("too many arguments to function");
3126 gen_assign_cast(arg
->t
);
3133 int n
, t
, ft
, fc
, p
, align
, size
;
3137 if (tok
== TOK_NUM
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
3138 vset(VT_CONST
| VT_INT
, tokc
.i
);
3140 } else if (tok
== TOK_CFLOAT
) {
3141 vsetc(VT_CONST
| VT_FLOAT
, &tokc
);
3143 } else if (tok
== TOK_CDOUBLE
) {
3144 vsetc(VT_CONST
| VT_DOUBLE
, &tokc
);
3146 } else if (tok
== TOK_CLDOUBLE
) {
3147 vsetc(VT_CONST
| VT_LDOUBLE
, &tokc
);
3149 } else if (tok
== TOK___FUNC__
) {
3150 /* special function name identifier */
3151 /* generate (char *) type */
3152 vset(VT_CONST
| mk_pointer(VT_BYTE
), glo
);
3153 strcpy((void *)glo
, funcname
);
3154 glo
+= strlen(funcname
) + 1;
3156 } else if (tok
== TOK_LSTR
) {
3159 } else if (tok
== TOK_STR
) {
3160 /* string parsing */
3163 type_size(t
, &align
);
3164 glo
= (glo
+ align
- 1) & -align
;
3166 /* we must declare it as an array first to use initializer parser */
3167 t
= VT_CONST
| VT_ARRAY
| mk_pointer(t
);
3168 decl_initializer(t
, glo
, 1, 0);
3169 glo
+= type_size(t
, &align
);
3170 /* put it as pointer */
3171 vset(t
& ~VT_ARRAY
, fc
);
3178 ft
= type_decl(&n
, t
, TYPE_ABSTRACT
);
3180 /* check ISOC99 compound literal */
3182 /* data is allocated locally by default */
3187 /* all except arrays are lvalues */
3188 if (!(ft
& VT_ARRAY
))
3190 fc
= decl_initializer_alloc(ft
, 1);
3200 } else if (t
== '*') {
3203 } else if (t
== '&') {
3205 /* functions names must be treated as function pointers,
3206 except for unary '&' and sizeof. Since we consider that
3207 functions are not lvalues, we only have to handle it
3208 there and in function calls. */
3209 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
3211 vtop
->t
= mk_pointer(vtop
->t
& VT_LVALN
);
3215 if ((vtop
->t
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
3216 vtop
->c
.i
= !vtop
->c
.i
;
3217 else if ((vtop
->t
& VT_VALMASK
) == VT_CMP
)
3218 vtop
->c
.i
= vtop
->c
.i
^ 1;
3220 vset(VT_JMP
, gtst(1, 0));
3230 if (t
== TOK_SIZEOF
) {
3234 t
= type_decl(&n
, t
, TYPE_ABSTRACT
);
3236 /* XXX: some code could be generated: add eval
3248 vset(VT_CONST
, type_size(t
, &t
));
3250 if (t
== TOK_INC
|| t
== TOK_DEC
) {
3253 } else if (t
== '-') {
3262 error("'%s' undeclared", get_tok_str(t
, NULL
));
3263 /* for simple function calls, we tolerate undeclared
3264 external reference */
3266 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
3267 /* int() function */
3268 s
= external_sym(t
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
));
3271 /* if forward reference, we must point to s */
3272 if (vtop
->t
& VT_FORWARD
)
3277 /* post operations */
3279 if (tok
== TOK_INC
| tok
== TOK_DEC
) {
3282 } else if (tok
== '.' | tok
== TOK_ARROW
) {
3284 if (tok
== TOK_ARROW
)
3287 vtop
->t
&= VT_LVALN
;
3289 /* expect pointer on structure */
3290 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
3291 expect("struct or union");
3292 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3295 while (s
= s
->next
) {
3300 error("field not found");
3301 /* add field offset to pointer */
3302 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | VT_INT
; /* change type to int */
3303 vset(VT_CONST
, s
->c
);
3305 /* change type to field type, and set to lvalue */
3306 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | s
->t
;
3307 /* an array is never an lvalue */
3308 if (!(vtop
->t
& VT_ARRAY
))
3311 } else if (tok
== '[') {
3317 } else if (tok
== '(') {
3323 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
3324 /* pointer test (no array accepted) */
3325 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
3326 vtop
->t
= pointed_type(vtop
->t
);
3327 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
3331 expect("function pointer");
3334 vtop
->t
&= ~VT_LVAL
; /* no lvalue */
3336 /* get return type */
3337 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
3338 save_regs(); /* save used temporary registers */
3341 sa
= s
->next
; /* first parameter */
3342 #ifdef INVERT_FUNC_PARAMS
3344 int *str
, len
, parlevel
, *saved_macro_ptr
;
3347 /* read each argument and store it on a stack */
3348 /* XXX: merge it with macro args ? */
3350 while (tok
!= ')') {
3354 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
3358 else if (tok
== ')')
3360 tok_add2(&str
, &len
, tok
, &tokc
);
3363 tok_add(&str
, &len
, -1); /* end of file added */
3364 tok_add(&str
, &len
, 0);
3365 s1
= sym_push2(&args
, 0, 0, (int)str
);
3366 s1
->next
= sa
; /* add reference to argument */
3376 /* now generate code in reverse order by reading the stack */
3377 saved_macro_ptr
= macro_ptr
;
3379 macro_ptr
= (int *)args
->c
;
3383 expect("',' or ')'");
3384 gfunc_param_typed(&gf
, s
, args
->next
);
3386 free((int *)args
->c
);
3390 macro_ptr
= saved_macro_ptr
;
3395 /* compute first implicit argument if a structure is returned */
3396 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
3397 /* get some space for the returned structure */
3398 size
= type_size(s
->t
, &align
);
3399 loc
= (loc
- size
) & -align
;
3400 rett
= s
->t
| VT_LOCAL
| VT_LVAL
;
3401 /* pass it as 'int' to avoid structure arg passing
3403 vset(VT_INT
| VT_LOCAL
, loc
);
3407 rett
= s
->t
| FUNC_RET_REG
; /* return in register */
3410 #ifndef INVERT_FUNC_PARAMS
3411 while (tok
!= ')') {
3413 gfunc_param_typed(&gf
, s
, sa
);
3421 error("too few arguments to function %x", sa
->t
);
3438 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
3439 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
3440 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
3463 while ((l
== 0 & (tok
== '*' | tok
== '/' | tok
== '%')) |
3464 (l
== 1 & (tok
== '+' | tok
== '-')) |
3465 (l
== 2 & (tok
== TOK_SHL
| tok
== TOK_SAR
)) |
3466 (l
== 3 & ((tok
>= TOK_ULE
& tok
<= TOK_GT
) |
3467 tok
== TOK_ULT
| tok
== TOK_UGE
)) |
3468 (l
== 4 & (tok
== TOK_EQ
| tok
== TOK_NE
)) |
3469 (l
== 5 & tok
== '&') |
3470 (l
== 6 & tok
== '^') |
3471 (l
== 7 & tok
== '|') |
3472 (l
== 8 & tok
== TOK_LAND
) |
3473 (l
== 9 & tok
== TOK_LOR
)) {
3482 /* only used if non constant */
3490 if (tok
!= TOK_LAND
) {
3510 if (tok
!= TOK_LOR
) {
3523 /* XXX: better constant handling */
3526 int t
, u
, c
, r1
, r2
;
3558 vtop
->t
= (vtop
->t
& VT_TYPE
) | r1
;
3575 /* parse a constant expression and return value in vtop */
3576 void expr_const1(void)
3582 if ((vtop
->t
& (VT_CONST
| VT_LVAL
)) != VT_CONST
)
3587 /* parse an integer constant and return its value */
3588 int expr_const(void)
3597 /* return the label token if current token is a label, otherwise
3604 /* fast test first */
3605 if (tok
< TOK_UIDENT
)
3607 /* no need to save tokc since we expect an identifier */
3615 /* XXX: may not work in all cases (macros ?) */
3624 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
3629 if (tok
== TOK_IF
) {
3636 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
3638 if (c
== TOK_ELSE
) {
3642 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
3643 gsym(d
); /* patch else jmp */
3646 } else if (tok
== TOK_WHILE
) {
3654 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
3655 oad(0xe9, d
- ind
- 5); /* jmp */
3658 } else if (tok
== '{') {
3661 s
= local_stack
.top
;
3662 while (tok
!= '}') {
3665 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
3667 /* pop locally defined symbols */
3668 sym_pop(&local_stack
, s
);
3670 } else if (tok
== TOK_RETURN
) {
3674 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
3675 /* if returning structure, must copy it to implicit
3676 first pointer arg location */
3677 vset(mk_pointer(func_vt
) | VT_LOCAL
| VT_LVAL
, func_vc
);
3680 /* copy structure value to pointer */
3682 } else if (is_float(func_vt
)) {
3683 /* move return value to float return register */
3684 move_reg(FUNC_RET_FREG
, gv());
3686 /* move return value to standard return register */
3687 move_reg(FUNC_RET_REG
, gv());
3692 rsym
= gjmp(rsym
); /* jmp */
3693 } else if (tok
== TOK_BREAK
) {
3696 error("cannot break");
3697 *bsym
= gjmp(*bsym
);
3700 } else if (tok
== TOK_CONTINUE
) {
3703 error("cannot continue");
3704 *csym
= gjmp(*csym
);
3707 } else if (tok
== TOK_FOR
) {
3730 oad(0xe9, d
- ind
- 5); /* jmp */
3734 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
3735 oad(0xe9, c
- ind
- 5); /* jmp */
3739 if (tok
== TOK_DO
) {
3744 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
3755 if (tok
== TOK_SWITCH
) {
3763 b
= gjmp(0); /* jump to first case */
3765 block(&a
, csym
, &b
, &c
, case_reg
);
3766 /* if no default, jmp after switch */
3774 if (tok
== TOK_CASE
) {
3779 /* since a case is like a label, we must skip it with a jmp */
3785 *case_sym
= gtst(1, 0);
3788 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
3790 if (tok
== TOK_DEFAULT
) {
3796 error("too many 'default'");
3798 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
3800 if (tok
== TOK_GOTO
) {
3802 s
= sym_find1(&label_stack
, tok
);
3803 /* put forward definition if needed */
3805 s
= sym_push1(&label_stack
, tok
, VT_FORWARD
, 0);
3806 /* label already defined */
3807 if (s
->t
& VT_FORWARD
)
3808 s
->c
= gjmp(s
->c
); /* jmp xxx */
3810 oad(0xe9, s
->c
- ind
- 5); /* jmp xxx */
3817 s
= sym_find1(&label_stack
, b
);
3819 if (!(s
->t
& VT_FORWARD
))
3820 error("multiple defined label");
3825 sym_push1(&label_stack
, b
, 0, ind
);
3827 /* we accept this, but it is a mistake */
3829 warning("deprecated use of label at end of compound statement");
3831 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
3833 /* expression case */
3843 /* t is the array or struct type. c is the array or struct
3844 address. cur_index/cur_field is the pointer to the current
3845 value. 'size_only' is true if only size info is needed (only used
3847 void decl_designator(int t
, int c
,
3848 int *cur_index
, Sym
**cur_field
,
3852 int notfirst
, index
, align
, l
;
3855 if (gnu_ext
&& (l
= is_label()) != 0)
3858 while (tok
== '[' || tok
== '.') {
3860 if (!(t
& VT_ARRAY
))
3861 expect("array type");
3862 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3864 index
= expr_const();
3865 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
3866 expect("invalid index");
3870 t
= pointed_type(t
);
3871 c
+= index
* type_size(t
, &align
);
3877 if ((t
& VT_BTYPE
) != VT_STRUCT
)
3878 expect("struct/union type");
3879 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3891 t
= f
->t
| (t
& ~VT_TYPE
);
3906 t
= pointed_type(t
);
3907 c
+= index
* type_size(t
, &align
);
3911 error("too many field init");
3912 t
= f
->t
| (t
& ~VT_TYPE
);
3916 decl_initializer(t
, c
, 0, size_only
);
3919 /* store a value or an expression directly in global data or in local array */
3921 void init_putv(int t
, int c
, int v
, int is_expr
)
3923 int saved_global_expr
, bt
;
3925 if ((t
& VT_VALMASK
) == VT_CONST
) {
3927 /* compound literals must be allocated globally in this case */
3928 saved_global_expr
= global_expr
;
3931 global_expr
= saved_global_expr
;
3933 vset(VT_CONST
| VT_INT
, v
);
3935 /* XXX: do casting */
3936 /* XXX: not portable */
3937 bt
= vtop
->t
& VT_BTYPE
;
3940 *(char *)c
= vtop
->c
.i
;
3943 *(short *)c
= vtop
->c
.i
;
3946 *(double *)c
= vtop
->c
.d
;
3949 *(long double *)c
= vtop
->c
.ld
;
3953 *(long long *)c
= vtop
->c
.ll
;
3957 *(int *)c
= vtop
->c
.i
;
3966 vset(VT_CONST
| VT_INT
, v
);
3972 /* put zeros for variable based init */
3973 void init_putz(int t
, int c
, int size
)
3977 if ((t
& VT_VALMASK
) == VT_CONST
) {
3978 /* nothing to do because global are already set to zero */
3981 vset(VT_CONST
, size
);
3987 vset(VT_CONST
, (int)&memset
);
3992 /* 't' contains the type and storage info. c is the address of the
3993 object. 'first' is true if array '{' must be read (multi dimension
3994 implicit array init handling). 'size_only' is true if size only
3995 evaluation is wanted (only for arrays). */
3996 void decl_initializer(int t
, int c
, int first
, int size_only
)
3998 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
3999 int t1
, size1
, align1
;
4004 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
4007 t1
= pointed_type(t
);
4008 size1
= type_size(t1
, &align1
);
4011 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
4017 /* only parse strings here if correct type (otherwise: handle
4018 them as ((w)char *) expressions */
4019 if ((tok
== TOK_LSTR
&&
4020 (t1
& VT_BTYPE
) == VT_INT
) ||
4022 (t1
& VT_BTYPE
) == VT_BYTE
)) {
4023 /* XXX: move multiple string parsing in parser ? */
4024 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
4026 /* compute maximum number of chars wanted */
4028 if (n
>= 0 && nb
> (n
- array_length
))
4029 nb
= n
- array_length
;
4032 warning("initializer-string for array is too long");
4034 init_putv(t1
, c
+ (array_length
+ i
) * size1
,
4041 /* only add trailing zero if enough storage (no
4042 warning in this case since it is standard) */
4043 if (n
< 0 || array_length
< n
) {
4045 init_putv(t1
, c
+ (array_length
* size1
), 0, 0);
4051 while (tok
!= '}') {
4052 decl_designator(t
, c
, &index
, NULL
, size_only
);
4053 if (n
>= 0 && index
>= n
)
4054 error("index too large");
4055 /* must put zero in holes (note that doing it that way
4056 ensures that it even works with designators) */
4057 if (!size_only
&& array_length
< index
) {
4058 init_putz(t1
, c
+ array_length
* size1
,
4059 (index
- array_length
) * size1
);
4062 if (index
> array_length
)
4063 array_length
= index
;
4064 /* special test for multi dimensional arrays (may not
4065 be strictly correct if designators are used at the
4067 if (index
>= n
&& no_oblock
)
4076 /* put zeros at the end */
4077 if (!size_only
&& n
>= 0 && array_length
< n
) {
4078 init_putz(t1
, c
+ array_length
* size1
,
4079 (n
- array_length
) * size1
);
4081 /* patch type size if needed */
4083 s
->c
= array_length
;
4084 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
4085 /* XXX: union needs only one init */
4087 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
4092 while (tok
!= '}') {
4093 decl_designator(t
, c
, NULL
, &f
, size_only
);
4094 /* fill with zero between fields */
4096 if (!size_only
&& array_length
< index
) {
4097 init_putz(t
, c
+ array_length
,
4098 index
- array_length
);
4100 index
= index
+ type_size(f
->t
, &align1
);
4101 if (index
> array_length
)
4102 array_length
= index
;
4108 /* put zeros at the end */
4109 if (!size_only
&& array_length
< n
) {
4110 init_putz(t
, c
+ array_length
,
4114 } else if (tok
== '{') {
4116 decl_initializer(t
, c
, first
, size_only
);
4118 } else if (size_only
) {
4119 /* just skip expression */
4121 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
4125 else if (tok
== ')')
4130 init_putv(t
, c
, 0, 1);
4134 /* parse an initializer for type 't' if 'has_init' is true, and
4135 allocate space in local or global data space. The allocated address
4137 int decl_initializer_alloc(int t
, int has_init
)
4139 int size
, align
, addr
, tok1
;
4140 int *init_str
, init_len
, level
, *saved_macro_ptr
;
4142 size
= type_size(t
, &align
);
4143 /* If unknown size, we must evaluate it before
4144 evaluating initializers because
4145 initializers can generate global data too
4146 (e.g. string pointers or ISOC99 compound
4147 literals). It also simplifies local
4148 initializers handling */
4151 saved_macro_ptr
= NULL
; /* avoid warning */
4155 error("unknown type size");
4156 /* get all init string */
4158 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
4160 error("unexpect end of file in initializer");
4161 tok_add2(&init_str
, &init_len
, tok
, &tokc
);
4164 else if (tok
== '}') {
4172 tok_add(&init_str
, &init_len
, -1);
4173 tok_add(&init_str
, &init_len
, 0);
4176 saved_macro_ptr
= macro_ptr
;
4177 macro_ptr
= init_str
;
4179 decl_initializer(t
, 0, 1, 1);
4180 /* prepare second initializer parsing */
4181 macro_ptr
= init_str
;
4184 /* if still unknown size, error */
4185 size
= type_size(t
, &align
);
4187 error("unknown type size");
4189 if ((t
& VT_VALMASK
) == VT_LOCAL
) {
4190 loc
= (loc
- size
) & -align
;
4193 glo
= (glo
+ align
- 1) & -align
;
4195 /* very important to increment global
4196 pointer at this time because
4197 initializers themselves can create new
4202 decl_initializer(t
, addr
, 1, 0);
4203 /* restore parse state if needed */
4206 macro_ptr
= saved_macro_ptr
;
4214 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
4217 int *a
, t
, b
, v
, u
, addr
, has_init
, size
, align
;
4223 /* skip redundant ';' */
4224 /* XXX: find more elegant solution */
4229 /* special test for old K&R protos without explicit int
4230 type. Only accepted when defining global data */
4231 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
4235 if (((b
& VT_BTYPE
) == VT_ENUM
||
4236 (b
& VT_BTYPE
) == VT_STRUCT
) &&
4238 /* we accept no variable after */
4242 while (1) { /* iterate thru each declaration */
4243 t
= type_decl(&v
, b
, TYPE_DIRECT
);
4247 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
4248 printf("type = '%s'\n", buf
);
4253 error("cannot use local functions");
4255 expect("function definition");
4256 /* patch forward references */
4257 if ((sym
= sym_find(v
)) && (sym
->t
& VT_FORWARD
)) {
4258 greloc_patch(sym
, ind
);
4259 sym
->t
= VT_CONST
| t
;
4261 /* put function address */
4262 sym_push1(&global_stack
, v
, VT_CONST
| t
, ind
);
4264 funcname
= get_tok_str(v
, NULL
);
4265 /* push a dummy symbol to enable local sym storage */
4266 sym_push1(&local_stack
, 0, 0, 0);
4267 /* define parameters */
4268 sym
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
4269 /* XXX: the following is x86 dependant -> move it to
4272 /* if the function returns a structure, then add an
4273 implicit pointer parameter */
4275 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
4279 while (sym
= sym
->next
) {
4281 sym_push(sym
->v
& ~SYM_FIELD
,
4282 u
| VT_LOCAL
| VT_LVAL
,
4284 size
= type_size(u
, &align
);
4285 size
= (size
+ 3) & ~3;
4286 #ifdef FUNC_STRUCT_PARAM_AS_PTR
4287 /* structs are passed as pointer */
4288 if ((u
& VT_BTYPE
) == VT_STRUCT
) {
4295 o(0xe58955); /* push %ebp, mov %esp, %ebp */
4296 a
= (int *)oad(0xec81, 0); /* sub $xxx, %esp */
4298 block(NULL
, NULL
, NULL
, NULL
, 0);
4300 o(0xc3c9); /* leave, ret */
4301 *a
= (-loc
+ 3) & -4; /* align local size to word &
4302 save local variables */
4303 sym_pop(&label_stack
, NULL
); /* reset label stack */
4304 sym_pop(&local_stack
, NULL
); /* reset local stack */
4305 funcname
= ""; /* for safety */
4306 func_vt
= VT_VOID
; /* for safety */
4309 if (b
& VT_TYPEDEF
) {
4310 /* save typedefed type */
4311 /* XXX: test storage specifiers ? */
4312 sym_push(v
, t
| VT_TYPEDEF
, 0);
4313 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
4314 /* external function definition */
4317 /* not lvalue if array */
4318 if (!(t
& VT_ARRAY
))
4320 if (b
& VT_EXTERN
) {
4321 /* external variable */
4328 has_init
= (tok
== '=');
4331 addr
= decl_initializer_alloc(u
, has_init
);
4332 if (l
== VT_CONST
) {
4333 /* global scope: see if already defined */
4337 if (!is_compatible_types(sym
->t
, u
))
4338 error("incompatible types for redefinition of '%s'",
4339 get_tok_str(v
, NULL
));
4340 if (!(sym
->t
& VT_FORWARD
))
4341 error("redefinition of '%s'", get_tok_str(v
, NULL
));
4342 greloc_patch(sym
, addr
);
4345 sym_push(v
, u
, addr
);
4359 /* put all global symbols in the extern stack and do all the
4360 resolving which can be done without using external symbols from DLLs */
4361 /* XXX: could try to verify types, but would not to save them in
4363 void resolve_global_syms(void)
4365 Sym
*s
, *s1
, *ext_sym
;
4368 s
= global_stack
.top
;
4371 /* do not save static or typedefed symbols or types */
4372 if (!(s
->t
& (VT_STATIC
| VT_TYPEDEF
)) &&
4373 !(s
->v
& (SYM_FIELD
| SYM_STRUCT
)) &&
4374 (s
->v
< SYM_FIRST_ANOM
)) {
4375 ext_sym
= sym_find1(&extern_stack
, s
->v
);
4377 /* if the symbol do not exist, we simply save it */
4378 sym_push1(&extern_stack
, s
->v
, s
->t
, s
->c
);
4379 } else if (ext_sym
->t
& VT_FORWARD
) {
4380 /* external symbol already exists, but only as forward
4382 if (!(s
->t
& VT_FORWARD
)) {
4383 /* s is not forward, so we can relocate all symbols */
4384 greloc_patch(ext_sym
, s
->c
);
4386 /* the two symbols are forward: merge them */
4387 p
= (Reloc
**)&ext_sym
->c
;
4393 /* external symbol already exists and is defined :
4394 patch all references to it */
4395 if (!(s
->t
& VT_FORWARD
))
4396 error("'%s' defined twice", get_tok_str(s
->v
, NULL
));
4397 greloc_patch(s
, ext_sym
->c
);
4404 /* compile a C file. Return non zero if errors. */
4405 int tcc_compile_file(const char *filename1
)
4409 filename
= (char *)filename1
;
4413 file
= fopen(filename
, "r");
4415 error("file '%s' not found", filename
);
4416 include_stack_ptr
= include_stack
;
4417 ifdef_stack_ptr
= ifdef_stack
;
4420 anon_sym
= SYM_FIRST_ANOM
;
4422 define_start
= define_stack
.top
;
4424 ch
= '\n'; /* needed to parse correctly first preprocessor command */
4428 expect("declaration");
4431 /* reset define stack, but leave -Dsymbols (may be incorrect if
4432 they are undefined) */
4433 sym_pop(&define_stack
, define_start
);
4435 resolve_global_syms();
4437 sym_pop(&global_stack
, NULL
);
4442 /* open a dynamic library so that its symbol are available for
4443 compiled programs */
4444 void open_dll(char *libname
)
4449 snprintf(buf
, sizeof(buf
), "lib%s.so", libname
);
4450 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
4452 error((char *)dlerror());
4455 void resolve_extern_syms(void)
4461 s
= extern_stack
.top
;
4464 if (s
->t
& VT_FORWARD
) {
4465 /* if there is at least one relocation to do, then find it
4468 str
= get_tok_str(s
->v
, NULL
);
4469 addr
= (int)dlsym(NULL
, str
);
4471 error("unresolved external reference '%s'", str
);
4472 greloc_patch(s
, addr
);
4479 /* output a binary file (for testing) */
4480 void build_exe(char *filename
)
4483 f
= fopen(filename
, "w");
4484 fwrite((void *)prog
, 1, ind
- prog
, f
);
4488 int main(int argc
, char **argv
)
4492 char *p
, *r
, *outfile
;
4495 include_paths
[0] = "/usr/include";
4496 include_paths
[1] = "/usr/lib/tcc";
4497 include_paths
[2] = "/usr/local/lib/tcc";
4498 nb_include_paths
= 3;
4500 /* add all tokens */
4501 tok_ident
= TOK_IDENT
;
4502 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\0define\0include\0ifdef\0ifndef\0elif\0endif\0defined\0undef\0error\0line\0__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0__func__\0main\0";
4506 tok_alloc(p
, r
- p
- 1);
4510 /* standard defines */
4511 define_symbol("__STDC__");
4513 define_symbol("__i386__");
4515 /* tiny C specific defines */
4516 define_symbol("__TINYC__");
4518 glo
= (int)malloc(DATA_SIZE
);
4519 memset((void *)glo
, 0, DATA_SIZE
);
4520 prog
= (int)malloc(TEXT_SIZE
);
4526 if (optind
>= argc
) {
4528 printf("tcc version 0.9.2 - Tiny C Compiler - Copyright (C) 2001 Fabrice Bellard\n"
4529 "usage: tcc [-Idir] [-Dsym] [-llib] [-i infile] infile [infile_args...]\n");
4537 if (nb_include_paths
>= INCLUDE_PATHS_MAX
)
4538 error("too many include paths");
4539 include_paths
[nb_include_paths
++] = r
+ 2;
4540 } else if (r
[1] == 'D') {
4541 define_symbol(r
+ 2);
4542 } else if (r
[1] == 'l') {
4544 } else if (r
[1] == 'i') {
4547 tcc_compile_file(argv
[optind
++]);
4548 } else if (r
[1] == 'o') {
4549 /* currently, only for testing, so not documented */
4552 outfile
= argv
[optind
++];
4554 fprintf(stderr
, "invalid option -- '%s'\n", r
);
4559 tcc_compile_file(argv
[optind
]);
4561 resolve_extern_syms();
4567 s
= sym_find1(&extern_stack
, TOK_MAIN
);
4568 if (!s
|| (s
->t
& VT_FORWARD
))
4569 error("main() not defined");
4570 t
= (int (*)())s
->c
;
4571 return (*t
)(argc
- optind
, argv
+ optind
);