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
{
68 typedef struct SValue
{
73 /* symbol management */
75 int v
; /* symbol token */
76 int t
; /* associated type */
77 int c
; /* associated number */
78 struct Sym
*next
; /* next related symbol */
79 struct Sym
*prev
; /* prev symbol in stack */
80 struct Sym
*hash_next
; /* next symbol in hash table */
83 typedef struct SymStack
{
85 struct Sym
*hash
[SYM_HASH_SIZE
];
88 /* relocation entry (currently only used for functions or variables */
89 typedef struct Reloc
{
90 int type
; /* type of relocation */
91 int addr
; /* address of relocation */
92 struct Reloc
*next
; /* next relocation */
95 #define RELOC_ADDR32 1 /* 32 bits relocation */
96 #define RELOC_REL32 2 /* 32 bits relative relocation */
99 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
100 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
101 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
103 #define FUNC_NEW 1 /* ansi function prototype */
104 #define FUNC_OLD 2 /* old function prototype */
105 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
107 /* field 'Sym.t' for macros */
108 #define MACRO_OBJ 0 /* object like macro */
109 #define MACRO_FUNC 1 /* function like macro */
111 /* type_decl() types */
112 #define TYPE_ABSTRACT 1 /* type without variable */
113 #define TYPE_DIRECT 2 /* type with variable */
124 int ch
, ch1
, tok
, tok1
;
127 /* loc : local variable index
128 glo : global variable index
129 ind : output code ptr
132 anon_sym: anonymous symbol index
135 prog
, ind
, loc
, glo
, const_wanted
;
136 int global_expr
; /* true if compound literals must be allocated
137 globally (used during initializers parsing */
138 int func_vt
, func_vc
; /* current function return type (used by
139 return instruction) */
141 TokenSym
**table_ident
;
142 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
143 char token_buf
[STRING_MAX_SIZE
+ 1];
144 char *filename
, *funcname
;
145 /* contains global symbols which remain between each translation unit */
146 SymStack extern_stack
;
147 SymStack define_stack
, global_stack
, local_stack
, label_stack
;
149 SValue vstack
[VSTACK_SIZE
], *vtop
;
150 int *macro_ptr
, *macro_ptr_allocated
;
151 IncludeFile include_stack
[INCLUDE_STACK_SIZE
], *include_stack_ptr
;
152 int ifdef_stack
[IFDEF_STACK_SIZE
], *ifdef_stack_ptr
;
153 char *include_paths
[INCLUDE_PATHS_MAX
];
154 int nb_include_paths
;
156 /* use GNU C extensions */
159 /* use Tiny C extensions */
162 /* The current value can be: */
163 #define VT_VALMASK 0x000f
164 #define VT_CONST 0x000a /* constant in vc
165 (must be first non register value) */
166 #define VT_LLOCAL 0x000b /* lvalue, offset on stack */
167 #define VT_LOCAL 0x000c /* offset on stack */
168 #define VT_CMP 0x000d /* the value is stored in processor flags (in vc) */
169 #define VT_JMP 0x000e /* value is the consequence of jmp true */
170 #define VT_JMPI 0x000f /* value is the consequence of jmp false */
171 #define VT_LVAL 0x0010 /* var is an lvalue */
172 #define VT_LVALN -17 /* ~VT_LVAL */
173 #define VT_FORWARD 0x0020 /* value is forward reference
174 (only used for functions) */
176 #define VT_EXTERN 0x00000040 /* extern definition */
177 #define VT_STATIC 0x00000080 /* static variable */
178 #define VT_TYPEDEF 0x00000100 /* typedef definition */
181 #define VT_STRUCT_SHIFT 16 /* structure/enum name shift (16 bits left) */
183 #define VT_BTYPE_SHIFT 9
184 #define VT_INT (0 << VT_BTYPE_SHIFT) /* integer type */
185 #define VT_BYTE (1 << VT_BTYPE_SHIFT) /* signed byte type */
186 #define VT_SHORT (2 << VT_BTYPE_SHIFT) /* short type */
187 #define VT_VOID (3 << VT_BTYPE_SHIFT) /* void type */
188 #define VT_PTR (4 << VT_BTYPE_SHIFT) /* pointer increment */
189 #define VT_ENUM (5 << VT_BTYPE_SHIFT) /* enum definition */
190 #define VT_FUNC (6 << VT_BTYPE_SHIFT) /* function type */
191 #define VT_STRUCT (7 << VT_BTYPE_SHIFT) /* struct/union definition */
192 #define VT_FLOAT (8 << VT_BTYPE_SHIFT) /* IEEE float */
193 #define VT_DOUBLE (9 << VT_BTYPE_SHIFT) /* IEEE double */
194 #define VT_LDOUBLE (10 << VT_BTYPE_SHIFT) /* IEEE long double */
195 #define VT_BOOL (11 << VT_BTYPE_SHIFT) /* ISOC99 boolean type */
196 #define VT_LLONG (12 << VT_BTYPE_SHIFT) /* 64 bit integer */
197 #define VT_LONG (13 << VT_BTYPE_SHIFT) /* long integer (NEVER
200 #define VT_BTYPE (0xf << VT_BTYPE_SHIFT) /* mask for basic type */
201 #define VT_UNSIGNED (0x10 << VT_BTYPE_SHIFT) /* unsigned type */
202 #define VT_ARRAY (0x20 << VT_BTYPE_SHIFT) /* array type (also has VT_PTR) */
203 #define VT_BITFIELD (0x40 << VT_BTYPE_SHIFT) /* bitfield modifier */
205 #define VT_TYPE 0xfffffe00 /* type mask */
209 /* warning: the following compare tokens depend on i386 asm code */
221 #define TOK_LAND 0xa0
225 #define TOK_MID 0xa3 /* inc/dec, to void constant */
227 #define TOK_ARROW 0xa7
228 #define TOK_DOTS 0xa8 /* three dots */
229 #define TOK_SHR 0xa9 /* unsigned shift right */
230 #define TOK_UDIV 0xb0 /* unsigned division */
231 #define TOK_UMOD 0xb1 /* unsigned modulo */
232 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
233 #define TOK_NUM 0xb3 /* number in tokc */
234 #define TOK_CCHAR 0xb4 /* char constant in tokc */
235 #define TOK_STR 0xb5 /* pointer to string in tokc */
236 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
237 #define TOK_LCHAR 0xb7
238 #define TOK_LSTR 0xb8
239 #define TOK_CFLOAT 0xb9 /* float constant */
240 #define TOK_CDOUBLE 0xc0 /* double constant */
241 #define TOK_CLDOUBLE 0xc1 /* long double constant */
243 #define TOK_SHL 0x01 /* shift left */
244 #define TOK_SAR 0x02 /* signed shift right */
246 /* assignement operators : normal operator or 0x80 */
247 #define TOK_A_MOD 0xa5
248 #define TOK_A_AND 0xa6
249 #define TOK_A_MUL 0xaa
250 #define TOK_A_ADD 0xab
251 #define TOK_A_SUB 0xad
252 #define TOK_A_DIV 0xaf
253 #define TOK_A_XOR 0xde
254 #define TOK_A_OR 0xfc
255 #define TOK_A_SHL 0x81
256 #define TOK_A_SAR 0x82
258 /* all identificators and strings have token above that */
259 #define TOK_IDENT 256
280 /* ignored types Must have contiguous values */
290 /* unsupported type */
303 /* preprocessor only */
304 TOK_UIDENT
, /* first "user" ident (not keyword) */
305 TOK_DEFINE
= TOK_UIDENT
,
321 /* special identifiers */
326 /* XXX: need to define this to use them in non ISOC99 context */
327 extern float strtof (const char *__nptr
, char **__endptr
);
328 extern long double strtold (const char *__nptr
, char **__endptr
);
332 void next_nomacro(void);
333 int expr_const(void);
337 void decl_initializer(int t
, int c
, int first
, int size_only
);
338 int decl_initializer_alloc(int t
, int has_init
);
340 void move_reg(int r
, int s
);
341 void save_reg(int r
);
347 void macro_subst(int **tok_str
, int *tok_len
,
348 Sym
**nested_list
, int *macro_str
);
349 int save_reg_forced(int r
);
351 void gen_cast(int t
);
353 int type_size(int t
, int *a
);
354 int pointed_type(int t
);
355 int pointed_size(int t
);
357 int type_decl(int *v
, int t
, int td
);
358 void error(const char *fmt
, ...);
359 void vset(int t
, int v
);
361 #include "i386-gen.c"
363 #ifdef CONFIG_TCC_STATIC
365 #define RTLD_LAZY 0x001
366 #define RTLD_NOW 0x002
367 #define RTLD_GLOBAL 0x100
369 /* dummy function for profiling */
370 void *dlopen(const char *filename
, int flag
)
375 const char *dlerror(void)
380 typedef struct TCCSyms
{
385 #define TCCSYM(a) { #a, &a, },
387 /* add the symbol you want here if no dynamic linking is done */
388 static TCCSyms tcc_syms
[] = {
396 void *dlsym(void *handle
, char *symbol
)
400 while (p
->str
!= NULL
) {
401 if (!strcmp(p
->str
, symbol
))
410 static inline int isid(int c
)
412 return (c
>= 'a' && c
<= 'z') ||
413 (c
>= 'A' && c
<= 'Z') ||
417 static inline int isnum(int c
)
419 return c
>= '0' & c
<= '9';
422 static inline int toup(int c
)
424 if (ch
>= 'a' && ch
<= 'z')
425 return ch
- 'a' + 'A';
433 for(f
= include_stack
; f
< include_stack_ptr
; f
++)
434 fprintf(stderr
, "In file included from %s:%d:\n",
435 f
->filename
, f
->line_num
);
436 fprintf(stderr
, "%s:%d: ", filename
, line_num
);
439 void error(const char *fmt
, ...)
444 vfprintf(stderr
, fmt
, ap
);
445 fprintf(stderr
, "\n");
450 void expect(const char *msg
)
452 error("%s expected", msg
);
455 void warning(const char *msg
)
458 fprintf(stderr
, "warning: %s\n", msg
);
464 error("'%c' expected", c
);
468 void test_lvalue(void)
470 if (!(vtop
->t
& VT_LVAL
))
474 TokenSym
*tok_alloc(char *str
, int len
)
476 TokenSym
*ts
, **pts
, **ptable
;
483 h
= ((h
<< 8) | (str
[i
] & 0xff)) % TOK_HASH_SIZE
;
485 pts
= &hash_ident
[h
];
490 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
492 pts
= &(ts
->hash_next
);
495 if (tok_ident
>= SYM_FIRST_ANOM
)
496 error("memory full");
498 /* expand token table if needed */
499 i
= tok_ident
- TOK_IDENT
;
500 if ((i
% TOK_ALLOC_INCR
) == 0) {
501 ptable
= realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
503 error("memory full");
504 table_ident
= ptable
;
507 ts
= malloc(sizeof(TokenSym
) + len
);
509 error("memory full");
511 ts
->tok
= tok_ident
++;
513 ts
->hash_next
= NULL
;
514 memcpy(ts
->str
, str
, len
+ 1);
519 void add_char(char **pp
, int c
)
523 if (c
== '\'' || c
== '\"' || c
== '\\') {
524 /* XXX: could be more precise if char or string */
527 if (c
>= 32 && c
<= 126) {
534 *p
++ = '0' + ((c
>> 6) & 7);
535 *p
++ = '0' + ((c
>> 3) & 7);
536 *p
++ = '0' + (c
& 7);
542 /* XXX: buffer overflow */
543 char *get_tok_str(int v
, CValue
*cv
)
545 static char buf
[STRING_MAX_SIZE
+ 1];
551 sprintf(buf
, "%u", cv
->ui
);
553 } else if (v
== TOK_CCHAR
|| v
== TOK_LCHAR
) {
560 } else if (v
== TOK_STR
|| v
== TOK_LSTR
) {
564 for(i
=0;i
<ts
->len
;i
++)
565 add_char(&p
, ts
->str
[i
]);
569 } else if (v
< TOK_IDENT
) {
574 } else if (v
< tok_ident
) {
575 return table_ident
[v
- TOK_IDENT
]->str
;
577 /* should never happen */
582 /* push, without hashing */
583 Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
586 s
= malloc(sizeof(Sym
));
588 error("memory full");
599 /* find a symbol and return its associated structure. 's' is the top
600 of the symbol stack */
601 Sym
*sym_find2(Sym
*s
, int v
)
611 #define HASH_SYM(v) ((unsigned)(v) % SYM_HASH_SIZE)
613 /* find a symbol and return its associated structure. 'st' is the
615 Sym
*sym_find1(SymStack
*st
, int v
)
619 s
= st
->hash
[HASH_SYM(v
)];
628 Sym
*sym_push1(SymStack
*st
, int v
, int t
, int c
)
631 s
= sym_push2(&st
->top
, v
, t
, c
);
632 /* add in hash table */
634 ps
= &st
->hash
[HASH_SYM(v
)];
641 /* find a symbol in the right symbol space */
645 s
= sym_find1(&local_stack
, v
);
647 s
= sym_find1(&global_stack
, v
);
651 /* push a given symbol on the symbol stack */
652 Sym
*sym_push(int v
, int t
, int c
)
655 return sym_push1(&local_stack
, v
, t
, c
);
657 return sym_push1(&global_stack
, v
, t
, c
);
660 /* pop symbols until top reaches 'b' */
661 void sym_pop(SymStack
*st
, Sym
*b
)
668 /* free hash table entry, except if symbol was freed (only
669 used for #undef symbols) */
671 st
->hash
[HASH_SYM(s
->v
)] = s
->hash_next
;
678 /* undefined a hashed symbol (used for #undef). Its name is set to
680 void sym_undef(SymStack
*st
, Sym
*s
)
683 ss
= &st
->hash
[HASH_SYM(s
->v
)];
684 while (*ss
!= NULL
) {
687 ss
= &(*ss
)->hash_next
;
693 /* no need to put that inline */
696 if (include_stack_ptr
== include_stack
)
698 /* pop include stack */
702 file
= include_stack_ptr
->file
;
703 filename
= include_stack_ptr
->filename
;
704 line_num
= include_stack_ptr
->line_num
;
708 /* read next char from current input file */
709 static inline void inp(void)
712 /* faster than fgetc */
713 ch1
= getc_unlocked(file
);
715 if (handle_eof() < 0)
722 // printf("ch1=%c 0x%x\n", ch1, ch1);
725 /* input with '\\n' handling */
726 static inline void minp(void)
731 if (ch
== '\\' && ch1
== '\n') {
735 //printf("ch=%c 0x%x\n", ch, ch);
739 /* same as minp, but also skip comments */
747 /* single line C++ comments */
749 while (ch1
!= '\n' && ch1
!= -1)
752 ch
= ' '; /* return space */
753 } else if (ch1
== '*') {
759 if (c
== '*' && ch1
== '/') {
761 ch
= ' '; /* return space */
773 void skip_spaces(void)
775 while (ch
== ' ' || ch
== '\t')
779 /* skip block of text until #else, #elif or #endif. skip also pairs of
781 void preprocess_skip()
797 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
799 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
801 else if (tok
== TOK_ENDIF
)
807 /* return the number of additionnal 'ints' necessary to store the
809 static inline int tok_ext_size(int t
)
823 return LDOUBLE_SIZE
/ 4;
829 void tok_add(int **tok_str
, int *tok_len
, int t
)
834 if ((len
& 63) == 0) {
835 str
= realloc(str
, (len
+ 64) * sizeof(int));
844 void tok_add2(int **tok_str
, int *tok_len
, int t
, CValue
*cv
)
848 tok_add(tok_str
, tok_len
, t
);
851 tok_add(tok_str
, tok_len
, cv
->tab
[i
]);
854 /* get a token from an integer array and increment pointer accordingly */
855 int tok_get(int **tok_str
, CValue
*cv
)
868 /* eval an expression for #if/#elif */
869 int expr_preprocess(void)
879 next(); /* do macro subst */
880 if (tok
== TOK_DEFINED
) {
885 c
= sym_find1(&define_stack
, tok
) != 0;
890 } else if (tok
>= TOK_IDENT
) {
891 /* if undefined macro */
895 tok_add2(&str
, &len
, tok
, &tokc
);
897 tok_add(&str
, &len
, -1); /* simulate end of file */
898 tok_add(&str
, &len
, 0);
899 /* now evaluate C constant expression */
909 void tok_print(int *str
)
915 t
= tok_get(&str
, &cval
);
918 printf(" %s", get_tok_str(t
, &cval
));
924 /* XXX: should be more factorized */
925 void define_symbol(char *sym
)
931 ts
= tok_alloc(sym
, 0);
935 tok_add2(&str
, &len
, TOK_NUM
, &cval
);
936 tok_add(&str
, &len
, 0);
937 sym_push1(&define_stack
, ts
->tok
, MACRO_OBJ
, (int)str
);
940 void preprocess(void)
942 int size
, i
, c
, v
, t
, *str
, len
;
943 char buf
[1024], *q
, *p
;
946 Sym
**ps
, *first
, *s
;
951 if (tok
== TOK_DEFINE
) {
954 /* XXX: should check if same macro (ANSI) */
957 /* '(' must be just after macro definition for MACRO_FUNC */
964 tok
= TOK___VA_ARGS__
;
965 s
= sym_push1(&define_stack
, tok
| SYM_FIELD
, 0, 0);
979 if (ch
== '\n' || ch
== -1)
982 tok_add2(&str
, &len
, tok
, &tokc
);
984 tok_add(&str
, &len
, 0);
986 printf("define %s %d: ", get_tok_str(v
, 0), t
);
989 s
= sym_push1(&define_stack
, v
, t
, (int)str
);
991 } else if (tok
== TOK_UNDEF
) {
993 s
= sym_find1(&define_stack
, tok
);
994 /* undefine symbol by putting an invalid name */
996 sym_undef(&define_stack
, s
);
997 } else if (tok
== TOK_INCLUDE
) {
1002 } else if (ch
== '\"') {
1007 while (ch
!= c
&& ch
!= '\n' && ch
!= -1) {
1008 if ((q
- buf
) < sizeof(buf
) - 1)
1016 error("#include syntax error");
1017 /* XXX: buffer overflow */
1018 strcpy(buf
, get_tok_str(tok
, &tokc
));
1021 /* eat all spaces and comments after include */
1022 /* XXX: slightly incorrect */
1023 while (ch1
!= '\n' && ch1
!= -1)
1026 if (include_stack_ptr
>= include_stack
+ INCLUDE_STACK_SIZE
)
1027 error("memory full");
1029 /* first search in current dir if "header.h" */
1030 /* XXX: buffer overflow */
1032 p
= strrchr(filename
, '/');
1034 size
= p
+ 1 - filename
;
1035 memcpy(buf1
, filename
, size
);
1038 f
= fopen(buf1
, "r");
1042 /* now search in standard include path */
1043 for(i
=nb_include_paths
- 1;i
>=0;i
--) {
1044 strcpy(buf1
, include_paths
[i
]);
1047 f
= fopen(buf1
, "r");
1051 error("include file '%s' not found", buf1
);
1054 /* push current file in stack */
1055 /* XXX: fix current line init */
1056 include_stack_ptr
->file
= file
;
1057 include_stack_ptr
->filename
= filename
;
1058 include_stack_ptr
->line_num
= line_num
;
1059 include_stack_ptr
++;
1061 filename
= strdup(buf1
);
1063 } else if (tok
== TOK_IFNDEF
) {
1066 } else if (tok
== TOK_IF
) {
1067 c
= expr_preprocess();
1069 } else if (tok
== TOK_IFDEF
) {
1073 c
= (sym_find1(&define_stack
, tok
) != 0) ^ c
;
1075 if (ifdef_stack_ptr
>= ifdef_stack
+ IFDEF_STACK_SIZE
)
1076 error("memory full");
1077 *ifdef_stack_ptr
++ = c
;
1079 } else if (tok
== TOK_ELSE
) {
1080 if (ifdef_stack_ptr
== ifdef_stack
||
1081 (ifdef_stack_ptr
[-1] & 2))
1082 error("#else after #else");
1083 c
= (ifdef_stack_ptr
[-1] ^= 3);
1085 } else if (tok
== TOK_ELIF
) {
1086 if (ifdef_stack_ptr
== ifdef_stack
||
1087 ifdef_stack_ptr
[-1] > 1)
1088 error("#elif after #else");
1089 c
= expr_preprocess();
1090 ifdef_stack_ptr
[-1] = c
;
1096 } else if (tok
== TOK_ENDIF
) {
1097 if (ifdef_stack_ptr
== ifdef_stack
)
1100 } else if (tok
== TOK_LINE
) {
1110 /* XXX: potential memory leak */
1111 filename
= strdup(get_tok_str(tok
, &tokc
));
1113 } else if (tok
== TOK_ERROR
) {
1116 /* ignore other preprocess commands or #! for C scripts */
1117 while (ch
!= '\n' && ch
!= -1)
1121 /* read a number in base b */
1127 if (ch
>= 'a' & ch
<= 'f')
1129 else if (ch
>= 'A' & ch
<= 'F')
1143 /* read a character for string or char constant and eval escape codes */
1152 /* at most three octal digits */
1156 c
= c
* 8 + ch
- '0';
1159 c
= c
* 8 + ch
- '0';
1164 } else if (ch
== 'x') {
1182 else if (ch
== 'e' && gnu_ext
)
1184 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
1187 error("invalid escaped char");
1194 /* we use 64 bit numbers */
1197 /* bn = (bn << shift) | or_val */
1198 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
1202 for(i
=0;i
<BN_SIZE
;i
++) {
1204 bn
[i
] = (v
<< shift
) | or_val
;
1205 or_val
= v
>> (32 - shift
);
1209 void bn_zero(unsigned int *bn
)
1212 for(i
=0;i
<BN_SIZE
;i
++) {
1217 void parse_number(void)
1219 int b
, t
, shift
, frac_bits
, s
, exp_val
;
1222 unsigned int bn
[BN_SIZE
];
1233 /* special dot handling */
1234 if (ch
>= '0' && ch
<= '9') {
1235 goto float_frac_parse
;
1236 } else if (ch
== '.') {
1247 } else if (t
== '0') {
1248 if (ch
== 'x' || ch
== 'X') {
1252 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
1258 /* parse all digits. cannot check octal numbers at this stage
1259 because of floating point constants */
1261 if (ch
>= 'a' & ch
<= 'f')
1263 else if (ch
>= 'A' & ch
<= 'F')
1271 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
1273 error("number too long");
1279 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
1280 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
1282 /* NOTE: strtox should support that for hexa numbers, but
1283 non ISOC99 libcs do not support it, so we prefer to do
1285 /* hexadecimal or binary floats */
1286 /* XXX: handle overflows */
1298 } else if (t
>= 'a') {
1300 } else if (t
>= 'A') {
1305 bn_lshift(bn
, shift
, t
);
1312 if (t
>= 'a' && t
<= 'f') {
1314 } else if (t
>= 'A' && t
<= 'F') {
1316 } else if (t
>= '0' && t
<= '9') {
1322 error("invalid digit");
1323 bn_lshift(bn
, shift
, t
);
1328 if (ch
!= 'p' && ch
!= 'P')
1329 error("exponent expected");
1335 } else if (ch
== '-') {
1339 if (ch
< '0' || ch
> '9')
1340 error("exponent digits expected");
1341 while (ch
>= '0' && ch
<= '9') {
1342 exp_val
= exp_val
* 10 + ch
- '0';
1345 exp_val
= exp_val
* s
;
1346 printf("num=%08x %08x %d %d\n", bn
[1], bn
[0], frac_bits
, exp_val
);
1348 /* now we can generate the number */
1349 /* XXX: should patch directly float number */
1350 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
1351 d
= ldexp(d
, exp_val
- frac_bits
);
1356 /* float : should handle overflow */
1358 } else if (t
== 'L') {
1361 /* XXX: not large enough */
1362 cval
.ld
= (long double)d
;
1368 /* decimal floats */
1370 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1375 while (ch
>= '0' && ch
<= '9') {
1376 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1382 if (ch
== 'e' || ch
== 'E') {
1383 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1387 if (ch
== '-' || ch
== '+') {
1388 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1393 if (ch
< '0' || ch
> '9')
1394 error("exponent digits expected");
1395 while (ch
>= '0' && ch
<= '9') {
1396 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1408 cval
.f
= strtof(token_buf
, NULL
);
1409 } else if (t
== 'L') {
1412 cval
.ld
= strtold(token_buf
, NULL
);
1415 cval
.d
= strtod(token_buf
, NULL
);
1419 /* integer number */
1422 if (b
== 10 && *q
== '0') {
1429 /* no need for checks except for base 10 / 8 errors */
1432 } else if (t
>= 'a') {
1434 } else if (t
>= 'A') {
1439 error("invalid digit");
1443 /* detect overflow */
1445 error("integer constant overflow");
1449 /* XXX: add unsigned constant support (ANSI) */
1450 while (ch
== 'L' || ch
== 'l' || ch
== 'U' || ch
== 'u')
1456 /* return next token without macro substitution */
1457 void next_nomacro1(void)
1465 while (ch
== '\n') {
1467 while (ch
== ' ' || ch
== 9)
1470 /* preprocessor command if # at start of line after
1475 if (ch
!= ' ' && ch
!= '\t' && ch
!= '\f')
1493 while (isid(ch
) || isnum(ch
)) {
1494 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1495 error("ident too long");
1500 ts
= tok_alloc(token_buf
, q
- token_buf
);
1502 } else if (isnum(ch
) || ch
== '.') {
1504 } else if (ch
== '\'') {
1512 } else if (ch
== '\"') {
1517 while (ch
!= '\"') {
1520 error("unterminated string");
1521 if (q
>= token_buf
+ STRING_MAX_SIZE
)
1522 error("string too long");
1526 tokc
.ts
= tok_alloc(token_buf
, q
- token_buf
);
1529 q
= "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\247..\250##\266";
1534 if (*q
== tok
&& q
[1] == ch
) {
1537 /* three chars tests */
1538 if (tok
== TOK_SHL
| tok
== TOK_SAR
) {
1543 } else if (tok
== TOK_DOTS
) {
1545 error("parse error");
1552 /* single char substitutions */
1555 else if (tok
== '>')
1560 /* return next token without macro substitution. Can read input from
1567 tok
= tok_get(¯o_ptr
, &tokc
);
1573 /* substitute args in macro_str and return allocated string */
1574 int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
1576 int *st
, last_tok
, t
, notfirst
, *str
, len
;
1585 t
= tok_get(¯o_str
, &cval
);
1590 t
= tok_get(¯o_str
, &cval
);
1593 s
= sym_find2(args
, t
);
1595 token_buf
[0] = '\0';
1597 /* XXX: buffer overflow */
1601 strcat(token_buf
, " ");
1602 t
= tok_get(&st
, &cval
);
1603 strcat(token_buf
, get_tok_str(t
, &cval
));
1607 printf("stringize: %s\n", token_buf
);
1610 ts
= tok_alloc(token_buf
, 0);
1612 tok_add2(&str
, &len
, TOK_STR
, &cval
);
1614 tok_add2(&str
, &len
, t
, &cval
);
1616 } else if (t
>= TOK_IDENT
) {
1617 s
= sym_find2(args
, t
);
1620 /* if '##' is present before or after , no arg substitution */
1621 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
1623 tok_add(&str
, &len
, *st
++);
1625 macro_subst(&str
, &len
, nested_list
, st
);
1628 tok_add(&str
, &len
, t
);
1631 tok_add2(&str
, &len
, t
, &cval
);
1635 tok_add(&str
, &len
, 0);
1639 /* handle the '##' operator */
1640 int *macro_twosharps(int *macro_str
)
1643 int *macro_str1
, macro_str1_len
, *macro_ptr1
;
1655 while (*macro_ptr
== TOK_TWOSHARPS
) {
1657 macro_ptr1
= macro_ptr
;
1660 t
= tok_get(¯o_ptr
, &cval
);
1661 /* XXX: we handle only most common cases:
1662 ident + ident or ident + number */
1663 if (tok
>= TOK_IDENT
&&
1664 (t
>= TOK_IDENT
|| t
== TOK_NUM
)) {
1665 /* XXX: buffer overflow */
1666 p
= get_tok_str(tok
, &tokc
);
1667 strcpy(token_buf
, p
);
1668 p
= get_tok_str(t
, &cval
);
1669 strcat(token_buf
, p
);
1670 ts
= tok_alloc(token_buf
, 0);
1671 tok
= ts
->tok
; /* modify current token */
1673 /* cannot merge tokens: skip '##' */
1674 macro_ptr
= macro_ptr1
;
1679 tok_add2(¯o_str1
, ¯o_str1_len
, tok
, &tokc
);
1681 tok_add(¯o_str1
, ¯o_str1_len
, 0);
1687 /* do macro substitution of macro_str and add result to
1688 (tok_str,tok_len). If macro_str is NULL, then input stream token is
1689 substituted. 'nested_list' is the list of all macros we got inside
1690 to avoid recursing. */
1691 void macro_subst(int **tok_str
, int *tok_len
,
1692 Sym
**nested_list
, int *macro_str
)
1694 Sym
*s
, *args
, *sa
, *sa1
;
1695 int *str
, parlevel
, len
, *mstr
, t
, *saved_macro_ptr
;
1696 int mstr_allocated
, *macro_str1
;
1699 saved_macro_ptr
= macro_ptr
;
1700 macro_ptr
= macro_str
;
1703 /* first scan for '##' operator handling */
1704 macro_str1
= macro_twosharps(macro_str
);
1705 macro_ptr
= macro_str1
;
1712 /* special macros */
1713 if (tok
== TOK___LINE__
) {
1715 tok_add2(tok_str
, tok_len
, TOK_NUM
, &cval
);
1716 } else if (tok
== TOK___FILE__
) {
1717 cval
.ts
= tok_alloc(filename
, 0);
1718 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
1719 } else if (tok
== TOK___DATE__
) {
1720 cval
.ts
= tok_alloc("Jan 1 1970", 0);
1721 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
1722 } else if (tok
== TOK___TIME__
) {
1723 cval
.ts
= tok_alloc("00:00:00", 0);
1724 tok_add2(tok_str
, tok_len
, TOK_STR
, &cval
);
1725 } else if ((s
= sym_find1(&define_stack
, tok
)) != NULL
) {
1726 /* if symbol is a macro, prepare substitution */
1727 /* if nested substitution, do nothing */
1728 if (sym_find2(*nested_list
, tok
))
1732 if (s
->t
== MACRO_FUNC
) {
1733 /* NOTE: we do not use next_nomacro to avoid eating the
1734 next token. XXX: find better solution */
1738 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
1742 if (t
!= '(') /* no macro subst */
1745 /* argument macro */
1750 while (tok
!= ')' && sa
) {
1754 while ((parlevel
> 0 ||
1757 sa
->v
== (TOK___VA_ARGS__
| SYM_FIELD
)))) &&
1761 else if (tok
== ')')
1763 tok_add2(&str
, &len
, tok
, &tokc
);
1766 tok_add(&str
, &len
, 0);
1767 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, 0, (int)str
);
1775 /* now subst each arg */
1776 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
1787 sym_push2(nested_list
, s
->v
, 0, 0);
1788 macro_subst(tok_str
, tok_len
, nested_list
, mstr
);
1789 /* pop nested defined symbol */
1791 *nested_list
= sa1
->prev
;
1797 /* no need to add if reading input stream */
1800 tok_add2(tok_str
, tok_len
, tok
, &tokc
);
1802 /* only replace one macro while parsing input stream */
1806 macro_ptr
= saved_macro_ptr
;
1811 /* return next token with macro substitution */
1817 /* special 'ungettok' case for label parsing */
1825 /* if not reading from macro substuted string, then try to substitute */
1829 macro_subst(&ptr
, &len
, &nested_list
, NULL
);
1831 tok_add(&ptr
, &len
, 0);
1833 macro_ptr_allocated
= ptr
;
1841 /* end of macro string: free it */
1842 free(macro_ptr_allocated
);
1849 printf("token = %s\n", get_tok_str(tok
, tokc
));
1853 void swap(int *p
, int *q
)
1861 void vset(int t
, int v
)
1863 if (vtop
>= vstack
+ VSTACK_SIZE
)
1864 error("memory full");
1865 /* cannot let cpu flags if other instruction are generated */
1866 /* XXX: VT_JMP test too ? */
1867 if ((vtop
->t
& VT_VALMASK
) == VT_CMP
)
1890 if (vtop
>= vstack
+ VSTACK_SIZE
)
1891 error("memory full");
1896 int save_reg_forced(int r
)
1901 /* store register */
1902 loc
= (loc
- 4) & -3;
1903 store(r
, VT_LOCAL
, loc
);
1906 /* modify all stack values */
1907 for(p
=vstack
;p
<=vtop
;p
++) {
1908 i
= p
->t
& VT_VALMASK
;
1914 p
->t
= (p
->t
& VT_TYPE
) | VT_LVAL
| t
;
1921 /* save r to memory. and mark it as being free */
1922 void save_reg(int r
)
1927 /* modify all stack values */
1928 for(p
=vstack
;p
<=vtop
;p
++) {
1929 i
= p
->t
& VT_VALMASK
;
1937 /* find a free register of class 'rc'. If none, save one register */
1943 /* find a free register */
1944 for(r
=0;r
<NB_REGS
;r
++) {
1945 if (reg_classes
[r
] & rc
) {
1946 for(p
=vstack
;p
<=vtop
;p
++) {
1947 i
= p
->t
& VT_VALMASK
;
1956 /* no register left : free the first one on the stack (very
1957 important to start from the bottom to ensure that we don't
1958 spill registers used in gen_op()) */
1959 for(p
=vstack
;p
<=vtop
;p
++) {
1960 r
= p
->t
& VT_VALMASK
;
1961 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
1974 for(p
=vstack
;p
<=vtop
;p
++) {
1975 r
= p
->t
& VT_VALMASK
;
1982 /* move register 's' to 'r', and flush previous value of r to memory
1984 void move_reg(int r
, int s
)
1992 /* convert a (vtop->t, vtop->c) in register. lvalues are converted as
1993 values. Cannot be used if cannot be converted to register value
1994 (such as structures). */
1997 int r
, bit_pos
, bit_size
, rc
;
1999 /* NOTE: get_reg can modify vstack[] */
2000 if (vtop
->t
& VT_BITFIELD
) {
2001 bit_pos
= (vtop
->t
>> VT_STRUCT_SHIFT
) & 0x3f;
2002 bit_size
= (vtop
->t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2003 /* remove bit field info to avoid loops */
2004 vtop
->t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2005 /* generate shifts */
2006 vset(VT_CONST
, 32 - (bit_pos
+ bit_size
));
2008 vset(VT_CONST
, 32 - bit_size
);
2009 /* NOTE: transformed to SHR if unsigned */
2013 r
= vtop
->t
& VT_VALMASK
;
2014 if (r
>= VT_CONST
|| (vtop
->t
& VT_LVAL
)) {
2015 if ((vtop
->t
& VT_BTYPE
) == VT_FLOAT
||
2016 (vtop
->t
& VT_BTYPE
) == VT_DOUBLE
)
2017 rc
= REG_CLASS_FLOAT
;
2022 load(r
, vtop
->t
, vtop
->c
);
2023 vtop
->t
= (vtop
->t
& VT_TYPE
) | r
;
2028 /* handle constant optimizations and various machine independant opt */
2029 void gen_opc(int op
)
2036 /* currently, we cannot do computations with forward symbols */
2037 c1
= (v1
->t
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
2038 c2
= (v2
->t
& (VT_VALMASK
| VT_LVAL
| VT_FORWARD
)) == VT_CONST
;
2042 case '+': v1
->c
+= fc
; break;
2043 case '-': v1
->c
-= fc
; break;
2044 case '&': v1
->c
&= fc
; break;
2045 case '^': v1
->c
^= fc
; break;
2046 case '|': v1
->c
|= fc
; break;
2047 case '*': v1
->c
*= fc
; break;
2049 case '/': v1
->c
/= fc
; break; /* XXX: zero case ? */
2050 case '%': v1
->c
%= fc
; break; /* XXX: zero case ? */
2051 case TOK_UDIV
: v1
->c
= (unsigned)v1
->c
/ fc
; break; /* XXX: zero case ? */
2052 case TOK_UMOD
: v1
->c
= (unsigned)v1
->c
% fc
; break; /* XXX: zero case ? */
2053 case TOK_SHL
: v1
->c
<<= fc
; break;
2054 case TOK_SHR
: v1
->c
= (unsigned)v1
->c
>> fc
; break;
2055 case TOK_SAR
: v1
->c
>>= fc
; break;
2057 case TOK_ULT
: v1
->c
= (unsigned)v1
->c
< (unsigned)fc
; break;
2058 case TOK_UGE
: v1
->c
= (unsigned)v1
->c
>= (unsigned)fc
; break;
2059 case TOK_EQ
: v1
->c
= v1
->c
== fc
; break;
2060 case TOK_NE
: v1
->c
= v1
->c
!= fc
; break;
2061 case TOK_ULE
: v1
->c
= (unsigned)v1
->c
<= (unsigned)fc
; break;
2062 case TOK_UGT
: v1
->c
= (unsigned)v1
->c
> (unsigned)fc
; break;
2063 case TOK_LT
: v1
->c
= v1
->c
< fc
; break;
2064 case TOK_GE
: v1
->c
= v1
->c
>= fc
; break;
2065 case TOK_LE
: v1
->c
= v1
->c
<= fc
; break;
2066 case TOK_GT
: v1
->c
= v1
->c
> fc
; break;
2068 case TOK_LAND
: v1
->c
= v1
->c
&& fc
; break;
2069 case TOK_LOR
: v1
->c
= v1
->c
|| fc
; break;
2075 /* if commutative ops, put c2 as constant */
2076 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
2077 op
== '|' || op
== '*')) {
2082 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
2085 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
2086 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
2092 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
2093 /* try to use shifts instead of muls or divs */
2094 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
2103 else if (op
== TOK_PDIV
)
2111 /* call low level op generator */
2112 /* XXX: remove explicit registers */
2118 int pointed_size(int t
)
2120 return type_size(pointed_type(t
), &t
);
2123 /* true if float/double/long double type */
2124 static inline int is_float(int t
)
2128 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
2131 /* generic gen_op: handles types problems */
2134 int u
, t1
, t2
, bt1
, bt2
, t
;
2138 bt1
= t1
& VT_BTYPE
;
2139 bt2
= t2
& VT_BTYPE
;
2141 if (is_float(bt1
) || is_float(bt2
)) {
2142 /* compute bigger type and do implicit casts */
2143 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
2145 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
2150 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
2151 op
< TOK_EQ
|| op
> TOK_GT
)
2152 error("invalid operands for binary operation");
2162 if (op
>= TOK_EQ
&& op
<= TOK_GT
) {
2163 /* the result is an int */
2164 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | VT_INT
;
2166 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | t
;
2168 } else if (op
== '+' || op
== '-') {
2169 if ((t1
& VT_BTYPE
) == VT_PTR
&&
2170 (t2
& VT_BTYPE
) == VT_PTR
) {
2172 error("invalid type");
2173 /* XXX: check that types are compatible */
2174 u
= pointed_size(t1
);
2176 /* set to integer type */
2177 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | VT_INT
;
2180 } else if ((t1
& VT_BTYPE
) == VT_PTR
||
2181 (t2
& VT_BTYPE
) == VT_PTR
) {
2182 if ((t2
& VT_BTYPE
) == VT_PTR
) {
2186 /* stack-4 contains pointer, stack-2 value to add */
2187 vset(VT_CONST
, pointed_size(vtop
[-1].t
));
2190 /* put again type if gen_opc() swaped operands */
2191 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | (t1
& VT_TYPE
);
2196 /* XXX: test types and compute returned value */
2197 if ((t1
| t2
) & VT_UNSIGNED
||
2198 (t1
& VT_BTYPE
) == VT_PTR
||
2199 (t2
& VT_BTYPE
) == VT_PTR
) {
2206 else if (op
== TOK_LT
)
2208 else if (op
== TOK_GT
)
2210 else if (op
== TOK_LE
)
2212 else if (op
== TOK_GE
)
2219 /* cast 'vtop' to 't' type */
2220 void gen_cast(int t
)
2222 int r
, bits
, bt
, vbt
;
2224 r
= vtop
->t
& VT_VALMASK
;
2225 if (!(t
& VT_LVAL
)) {
2226 /* if not lvalue, then we convert now */
2228 vbt
= vtop
->t
& VT_BTYPE
;
2231 /* need to generate value and do explicit cast */
2234 } else if (bt
== VT_BOOL
) {
2237 } else if (bt
== VT_BYTE
|| bt
== VT_SHORT
) {
2242 if (t
& VT_UNSIGNED
) {
2243 vset(VT_CONST
, (1 << bits
) - 1);
2247 vset(VT_CONST
, bits
);
2249 vset(VT_CONST
, bits
);
2255 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | t
;
2258 /* return type size. Put alignment at 'a' */
2259 int type_size(int t
, int *a
)
2265 if (bt
== VT_STRUCT
) {
2267 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
2268 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
2270 } else if (bt
== VT_PTR
) {
2272 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
2273 return type_size(s
->t
, a
) * s
->c
;
2278 } else if (bt
== VT_LDOUBLE
) {
2280 return LDOUBLE_SIZE
;
2281 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
2284 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
2287 } else if (bt
== VT_SHORT
) {
2291 /* char, void, function, _Bool */
2297 /* return the pointed type of t */
2298 int pointed_type(int t
)
2301 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
2302 return s
->t
| (t
& ~VT_TYPE
);
2305 int mk_pointer(int t
)
2310 return VT_PTR
| (p
<< VT_STRUCT_SHIFT
) | (t
& ~VT_TYPE
);
2313 /* store vtop in lvalue pushed on stack */
2316 int ft
, fc
, r
, t
, size
, align
, bit_size
, bit_pos
;
2320 if ((vtop
->t
& VT_BTYPE
) == VT_STRUCT
) {
2321 /* if structure, only generate pointer */
2322 /* structure assignment : generate memcpy */
2323 /* XXX: optimize if small size */
2328 size
= type_size(vtop
->t
, &align
);
2329 vset(VT_CONST
, size
);
2332 vtop
->t
&= ~VT_LVAL
;
2336 vtop
->t
&= ~VT_LVAL
;
2340 vset(VT_CONST
, (int)&memcpy
);
2342 /* leave source on stack */
2343 } else if (ft
& VT_BITFIELD
) {
2344 /* bitfield store handling */
2345 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
2346 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
2347 /* remove bit field info to avoid loops */
2348 vtop
[-1].t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
2350 /* duplicate destination */
2352 vtop
[-1] = vtop
[-2];
2354 /* mask and shift source */
2355 vset(VT_CONST
, (1 << bit_size
) - 1);
2357 vset(VT_CONST
, bit_pos
);
2359 /* load destination, mask and or with source */
2361 vset(VT_CONST
, ~(((1 << bit_size
) - 1) << bit_pos
));
2367 /* generate cast if needed implicit cast for bool */
2368 if ((ft
& VT_BTYPE
) == VT_BOOL
) {
2371 r
= gv(); /* generate value */
2374 /* if lvalue was saved on stack, must read it */
2375 if ((ft
& VT_VALMASK
) == VT_LLOCAL
) {
2376 t
= get_reg(REG_CLASS_INT
);
2377 load(t
, VT_LOCAL
| VT_LVAL
, fc
);
2378 ft
= (ft
& ~VT_VALMASK
) | t
;
2382 vtop
->t
= (ft
& VT_TYPE
) | r
;
2387 /* post defines POST/PRE add. c is the token ++ or -- */
2388 void inc(int post
, int c
)
2394 vdup(); /* room for returned value */
2395 vdup(); /* save lvalue */
2398 /* duplicate value */
2399 /* XXX: handle floats */
2400 r1
= get_reg(REG_CLASS_INT
);
2401 load(r1
, r
, 0); /* move r to r1 */
2402 /* duplicates value */
2403 vtop
[-2].t
= (vtop
->t
& VT_TYPE
) | r1
;
2407 vset(VT_CONST
, c
- TOK_MID
);
2409 vstore(); /* store value */
2411 vpop(); /* if post op, return saved value */
2414 /* enum/struct/union declaration */
2415 int struct_decl(int u
)
2417 int a
, t
, b
, v
, size
, align
, maxalign
, c
, offset
;
2418 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
2421 a
= tok
; /* save decl type */
2426 /* struct already defined ? return it */
2427 /* XXX: check consistency */
2428 if (s
= sym_find(v
| SYM_STRUCT
)) {
2430 error("invalid type");
2436 s
= sym_push(v
| SYM_STRUCT
, a
, 0);
2437 /* put struct/union/enum name in type */
2439 u
= u
| (v
<< VT_STRUCT_SHIFT
);
2444 error("struct/union/enum already defined");
2445 /* cannot be empty */
2452 if (a
== TOK_ENUM
) {
2459 /* enum symbols have static storage */
2460 sym_push(v
, VT_CONST
| VT_STATIC
, c
);
2470 t
= type_decl(&v
, b
, TYPE_DIRECT
);
2471 if ((t
& VT_BTYPE
) == VT_FUNC
||
2472 (t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
2473 error("invalid type for '%s'", get_tok_str(v
, 0));
2479 bit_size
= expr_const();
2480 /* XXX: handle v = 0 case for messages */
2482 error("negative width in bit-field '%s'",
2484 if (v
&& bit_size
== 0)
2485 error("zero width for bit-field '%s'",
2488 size
= type_size(t
, &align
);
2490 if (bit_size
>= 0) {
2495 error("bitfields must have scalar type");
2497 if (bit_size
> bsize
) {
2498 error("width of '%s' exceeds its type",
2500 } else if (bit_size
== bsize
) {
2501 /* no need for bit fields */
2503 } else if (bit_size
== 0) {
2504 /* XXX: what to do if only padding in a
2506 /* zero size: means to pad */
2510 /* we do not have enough room ? */
2511 if ((bit_pos
+ bit_size
) > bsize
)
2514 /* XXX: handle LSB first */
2516 (bit_pos
<< VT_STRUCT_SHIFT
) |
2517 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
2518 bit_pos
+= bit_size
;
2524 /* add new memory data only if starting
2526 if (lbit_pos
== 0) {
2527 if (a
== TOK_STRUCT
) {
2528 c
= (c
+ align
- 1) & -align
;
2536 if (align
> maxalign
)
2540 printf("add field %s offset=%d",
2541 get_tok_str(v
, 0), offset
);
2542 if (t
& VT_BITFIELD
) {
2543 printf(" pos=%d size=%d",
2544 (t
>> VT_STRUCT_SHIFT
) & 0x3f,
2545 (t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
2549 ss
= sym_push(v
| SYM_FIELD
, t
, offset
);
2553 if (tok
== ';' || tok
== -1)
2563 /* size for struct/union, dummy for enum */
2564 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
2569 /* return 0 if no type declaration. otherwise, return the basic type
2571 XXX: A '2' is ored to ensure non zero return if int type.
2587 if ((t
& VT_BTYPE
) != 0)
2588 error("too many basic types %x", t
);
2602 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
2603 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
2604 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
2605 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
2619 if ((t
& VT_BTYPE
) == VT_LONG
) {
2620 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
2627 u
= struct_decl(VT_ENUM
);
2631 u
= struct_decl(VT_STRUCT
);
2634 /* type modifiers */
2664 if (!s
|| !(s
->t
& VT_TYPEDEF
))
2666 t
|= (s
->t
& ~VT_TYPEDEF
);
2673 /* long is never used as type */
2674 if ((t
& VT_BTYPE
) == VT_LONG
)
2675 t
= (t
& ~VT_BTYPE
) | VT_INT
;
2679 int post_type(int t
)
2681 int p
, n
, pt
, l
, t1
;
2682 Sym
**plast
, *s
, *first
;
2685 /* function declaration */
2690 while (tok
!= ')') {
2691 /* read param name and compute offset */
2692 if (l
!= FUNC_OLD
) {
2693 if (!(pt
= ist())) {
2695 error("invalid type");
2701 if ((pt
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
2704 pt
= type_decl(&n
, pt
, TYPE_DIRECT
| TYPE_ABSTRACT
);
2711 /* array must be transformed to pointer according to ANSI C */
2713 s
= sym_push(n
| SYM_FIELD
, pt
, 0);
2718 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
2726 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
2727 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
));
2728 /* we push a anonymous symbol which will contain the function prototype */
2730 s
= sym_push(p
, t
, l
);
2732 t
= t1
| VT_FUNC
| (p
<< VT_STRUCT_SHIFT
);
2733 } else if (tok
== '[') {
2734 /* array definition */
2740 error("invalid array size");
2743 /* parse next post type */
2744 t1
= t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
2745 t
= post_type(t
& ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
));
2747 /* we push a anonymous symbol which will contain the array
2751 t
= t1
| VT_ARRAY
| VT_PTR
| (p
<< VT_STRUCT_SHIFT
);
2756 /* Read a type declaration (except basic type), and return the
2757 type. If v is true, then also put variable name in 'vtop->c' */
2758 int type_decl(int *v
, int t
, int td
)
2763 t
= t
& -3; /* suppress the ored '2' */
2764 while (tok
== '*') {
2766 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
2771 /* recursive type */
2772 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
2775 u
= type_decl(v
, 0, td
);
2779 /* type identifier */
2780 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
2784 if (!(td
& TYPE_ABSTRACT
))
2785 expect("identifier");
2789 /* append t at the end of u */
2795 s
= sym_find((unsigned)p
>> VT_STRUCT_SHIFT
);
2805 /* define a new external reference to a function 'v' of type 'u' */
2806 Sym
*external_sym(int v
, int u
)
2811 /* push forward reference */
2812 s
= sym_push1(&global_stack
,
2813 v
, u
| VT_CONST
| VT_FORWARD
, 0);
2820 if (vtop
->t
& VT_LVAL
)
2822 if ((vtop
->t
& VT_BTYPE
) != VT_PTR
)
2824 vtop
->t
= pointed_type(vtop
->t
);
2825 if (!(vtop
->t
& VT_ARRAY
)) /* an array is never an lvalue */
2831 int n
, t
, ft
, fc
, p
, align
, size
;
2835 if (tok
== TOK_NUM
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
2836 vset(VT_CONST
| VT_INT
, tokc
.i
);
2838 } else if (tok
== TOK_CFLOAT
) {
2839 /* currently, cannot do more */
2840 vset(VT_CONST
| VT_FLOAT
, 0);
2842 } else if (tok
== TOK_CDOUBLE
) {
2843 /* currently, cannot do more */
2844 vset(VT_CONST
| VT_DOUBLE
, 0);
2846 } else if (tok
== TOK_CLDOUBLE
) {
2847 /* currently, cannot do more */
2848 vset(VT_CONST
| VT_LDOUBLE
, 0);
2850 } else if (tok
== TOK___FUNC__
) {
2851 /* special function name identifier */
2852 /* generate (char *) type */
2853 vset(VT_CONST
| mk_pointer(VT_BYTE
), glo
);
2854 strcpy((void *)glo
, funcname
);
2855 glo
+= strlen(funcname
) + 1;
2857 } else if (tok
== TOK_LSTR
) {
2860 } else if (tok
== TOK_STR
) {
2861 /* string parsing */
2864 type_size(t
, &align
);
2865 glo
= (glo
+ align
- 1) & -align
;
2867 /* we must declare it as an array first to use initializer parser */
2868 t
= VT_CONST
| VT_ARRAY
| mk_pointer(t
);
2869 decl_initializer(t
, glo
, 1, 0);
2870 glo
+= type_size(t
, &align
);
2871 /* put it as pointer */
2872 vset(t
& ~VT_ARRAY
, fc
);
2879 ft
= type_decl(&n
, t
, TYPE_ABSTRACT
);
2881 /* check ISOC99 compound literal */
2883 /* data is allocated locally by default */
2888 /* all except arrays are lvalues */
2889 if (!(ft
& VT_ARRAY
))
2891 fc
= decl_initializer_alloc(ft
, 1);
2901 } else if (t
== '*') {
2904 } else if (t
== '&') {
2906 /* functions names must be treated as function pointers,
2907 except for unary '&' and sizeof. Since we consider that
2908 functions are not lvalues, we only have to handle it
2909 there and in function calls. */
2910 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
2912 vtop
->t
= mk_pointer(vtop
->t
& VT_LVALN
);
2916 if ((vtop
->t
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
)
2918 else if ((vtop
->t
& VT_VALMASK
) == VT_CMP
)
2919 vtop
->c
= vtop
->c
^ 1;
2921 vset(VT_JMP
, gtst(1, 0));
2931 if (t
== TOK_SIZEOF
) {
2935 t
= type_decl(&n
, t
, TYPE_ABSTRACT
);
2937 /* XXX: some code could be generated: add eval
2949 vset(VT_CONST
, type_size(t
, &t
));
2951 if (t
== TOK_INC
|| t
== TOK_DEC
) {
2954 } else if (t
== '-') {
2963 error("'%s' undeclared", get_tok_str(t
, 0));
2964 /* for simple function calls, we tolerate undeclared
2965 external reference */
2967 sym_push1(&global_stack
, p
, 0, FUNC_OLD
);
2968 /* int() function */
2969 s
= external_sym(t
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
));
2972 /* if forward reference, we must point to s */
2973 if (vtop
->t
& VT_FORWARD
)
2978 /* post operations */
2980 if (tok
== TOK_INC
| tok
== TOK_DEC
) {
2983 } else if (tok
== '.' | tok
== TOK_ARROW
) {
2985 if (tok
== TOK_ARROW
)
2988 vtop
->t
&= VT_LVALN
;
2990 /* expect pointer on structure */
2991 if ((vtop
->t
& VT_BTYPE
) != VT_STRUCT
)
2992 expect("struct or union");
2993 s
= sym_find(((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
2996 while (s
= s
->next
) {
3001 error("field not found");
3002 /* add field offset to pointer */
3003 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | VT_INT
; /* change type to int */
3004 vset(VT_CONST
, s
->c
);
3006 /* change type to field type, and set to lvalue */
3007 vtop
->t
= (vtop
->t
& ~VT_TYPE
) | s
->t
;
3008 /* an array is never an lvalue */
3009 if (!(vtop
->t
& VT_ARRAY
))
3012 } else if (tok
== '[') {
3018 } else if (tok
== '(') {
3022 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
) {
3023 /* pointer test (no array accepted) */
3024 if ((vtop
->t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
3025 vtop
->t
= pointed_type(vtop
->t
);
3026 if ((vtop
->t
& VT_BTYPE
) != VT_FUNC
)
3030 expect("function pointer");
3033 vtop
->t
&= ~VT_LVAL
; /* no lvalue */
3036 /* get return type */
3037 s
= sym_find((unsigned)vtop
->t
>> VT_STRUCT_SHIFT
);
3038 save_regs(); /* save used temporary registers */
3041 #ifdef INVERT_FUNC_PARAMS
3043 int *str
, len
, parlevel
, *saved_macro_ptr
;
3046 /* read each argument and store it on a stack */
3047 /* XXX: merge it with macro args ? */
3049 while (tok
!= ')') {
3053 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
3057 else if (tok
== ')')
3059 tok_add2(&str
, &len
, tok
, &tokc
);
3062 tok_add(&str
, &len
, -1); /* end of file added */
3063 tok_add(&str
, &len
, 0);
3064 sym_push2(&args
, 0, 0, (int)str
);
3072 /* now generate code in reverse order by reading the stack */
3073 saved_macro_ptr
= macro_ptr
;
3075 macro_ptr
= (int *)args
->c
;
3079 expect("',' or ')'");
3082 free((int *)args
->c
);
3086 macro_ptr
= saved_macro_ptr
;
3091 /* compute first implicit argument if a structure is returned */
3092 if ((s
->t
& VT_BTYPE
) == VT_STRUCT
) {
3093 /* get some space for the returned structure */
3094 size
= type_size(s
->t
, &align
);
3095 loc
= (loc
- size
) & -align
;
3096 rett
= s
->t
| VT_LOCAL
| VT_LVAL
;
3097 /* pass it as 'int' to avoid structure arg passing
3099 vset(VT_INT
| VT_LOCAL
, loc
);
3103 rett
= s
->t
| FUNC_RET_REG
; /* return in register */
3106 #ifndef INVERT_FUNC_PARAMS
3107 while (tok
!= ')') {
3124 int is_compatible_types(int t1
, int t2
)
3131 bt1
= t1
& VT_BTYPE
;
3132 bt2
= t2
& VT_BTYPE
;
3133 if (bt1
== VT_PTR
) {
3134 t1
= pointed_type(t1
);
3135 /* if function, then convert implicitely to function pointer */
3136 if (bt2
!= VT_FUNC
) {
3139 t2
= pointed_type(t2
);
3141 /* void matches everything */
3144 if (t1
== VT_VOID
|| t2
== VT_VOID
)
3146 return is_compatible_types(t1
, t2
);
3147 } else if (bt1
== VT_STRUCT
) {
3149 } else if (bt1
== VT_FUNC
) {
3152 s1
= sym_find(((unsigned)t1
>> VT_STRUCT_SHIFT
));
3153 s2
= sym_find(((unsigned)t2
>> VT_STRUCT_SHIFT
));
3154 if (!is_compatible_types(s1
->t
, s2
->t
))
3156 /* XXX: not complete */
3157 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
3161 while (s1
!= NULL
) {
3164 if (!is_compatible_types(s1
->t
, s2
->t
))
3173 /* XXX: not complete */
3178 int check_assign_types(int t1
, int t2
)
3182 if ((t1
& VT_BTYPE
) == VT_PTR
&&
3183 (t2
& VT_BTYPE
) == VT_FUNC
) {
3184 return is_compatible_types(pointed_type(t1
), t2
);
3186 return is_compatible_types(t1
, t2
);
3197 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
3198 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
3199 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
3205 if (!check_assign_types(vtop
[-1].t
, vtop
[0].t
))
3206 warning("incompatible types");
3224 while ((l
== 0 & (tok
== '*' | tok
== '/' | tok
== '%')) |
3225 (l
== 1 & (tok
== '+' | tok
== '-')) |
3226 (l
== 2 & (tok
== TOK_SHL
| tok
== TOK_SAR
)) |
3227 (l
== 3 & ((tok
>= TOK_ULE
& tok
<= TOK_GT
) |
3228 tok
== TOK_ULT
| tok
== TOK_UGE
)) |
3229 (l
== 4 & (tok
== TOK_EQ
| tok
== TOK_NE
)) |
3230 (l
== 5 & tok
== '&') |
3231 (l
== 6 & tok
== '^') |
3232 (l
== 7 & tok
== '|') |
3233 (l
== 8 & tok
== TOK_LAND
) |
3234 (l
== 9 & tok
== TOK_LOR
)) {
3243 /* only used if non constant */
3251 if (tok
!= TOK_LAND
) {
3271 if (tok
!= TOK_LOR
) {
3284 /* XXX: better constant handling */
3287 int t
, u
, c
, r1
, r2
;
3319 vtop
->t
= (vtop
->t
& VT_TYPE
) | r1
;
3336 int expr_const(void)
3342 if ((vtop
->t
& (VT_CONST
| VT_LVAL
)) != VT_CONST
)
3350 /* return the label token if current token is a label, otherwise
3357 /* fast test first */
3358 if (tok
< TOK_UIDENT
)
3360 /* no need to save tokc since we expect an identifier */
3368 /* XXX: may not work in all cases (macros ?) */
3377 void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
3382 if (tok
== TOK_IF
) {
3389 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
3391 if (c
== TOK_ELSE
) {
3395 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
3396 gsym(d
); /* patch else jmp */
3399 } else if (tok
== TOK_WHILE
) {
3407 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
3408 oad(0xe9, d
- ind
- 5); /* jmp */
3411 } else if (tok
== '{') {
3414 s
= local_stack
.top
;
3415 while (tok
!= '}') {
3418 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
3420 /* pop locally defined symbols */
3421 sym_pop(&local_stack
, s
);
3423 } else if (tok
== TOK_RETURN
) {
3427 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
3428 /* if returning structure, must copy it to implicit
3429 first pointer arg location */
3430 vset(mk_pointer(func_vt
) | VT_LOCAL
| VT_LVAL
, func_vc
);
3433 /* copy structure value to pointer */
3436 /* move return value to standard return register */
3437 move_reg(FUNC_RET_REG
, gv());
3442 rsym
= gjmp(rsym
); /* jmp */
3443 } else if (tok
== TOK_BREAK
) {
3446 error("cannot break");
3447 *bsym
= gjmp(*bsym
);
3450 } else if (tok
== TOK_CONTINUE
) {
3453 error("cannot continue");
3454 *csym
= gjmp(*csym
);
3457 } else if (tok
== TOK_FOR
) {
3480 oad(0xe9, d
- ind
- 5); /* jmp */
3484 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
3485 oad(0xe9, c
- ind
- 5); /* jmp */
3489 if (tok
== TOK_DO
) {
3494 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
3505 if (tok
== TOK_SWITCH
) {
3513 b
= gjmp(0); /* jump to first case */
3515 block(&a
, csym
, &b
, &c
, case_reg
);
3516 /* if no default, jmp after switch */
3524 if (tok
== TOK_CASE
) {
3529 /* since a case is like a label, we must skip it with a jmp */
3535 *case_sym
= gtst(1, 0);
3538 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
3540 if (tok
== TOK_DEFAULT
) {
3546 error("too many 'default'");
3548 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
3550 if (tok
== TOK_GOTO
) {
3552 s
= sym_find1(&label_stack
, tok
);
3553 /* put forward definition if needed */
3555 s
= sym_push1(&label_stack
, tok
, VT_FORWARD
, 0);
3556 /* label already defined */
3557 if (s
->t
& VT_FORWARD
)
3558 s
->c
= gjmp(s
->c
); /* jmp xxx */
3560 oad(0xe9, s
->c
- ind
- 5); /* jmp xxx */
3567 s
= sym_find1(&label_stack
, b
);
3569 if (!(s
->t
& VT_FORWARD
))
3570 error("multiple defined label");
3575 sym_push1(&label_stack
, b
, 0, ind
);
3577 /* we accept this, but it is a mistake */
3579 warning("deprecated use of label at end of compound statement");
3581 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
3583 /* expression case */
3593 /* t is the array or struct type. c is the array or struct
3594 address. cur_index/cur_field is the pointer to the current
3595 value. 'size_only' is true if only size info is needed (only used
3597 void decl_designator(int t
, int c
,
3598 int *cur_index
, Sym
**cur_field
,
3602 int notfirst
, index
, align
, l
;
3605 if (gnu_ext
&& (l
= is_label()) != 0)
3608 while (tok
== '[' || tok
== '.') {
3610 if (!(t
& VT_ARRAY
))
3611 expect("array type");
3612 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3614 index
= expr_const();
3615 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
3616 expect("invalid index");
3620 t
= pointed_type(t
);
3621 c
+= index
* type_size(t
, &align
);
3627 if ((t
& VT_BTYPE
) != VT_STRUCT
)
3628 expect("struct/union type");
3629 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3641 t
= f
->t
| (t
& ~VT_TYPE
);
3656 t
= pointed_type(t
);
3657 c
+= index
* type_size(t
, &align
);
3661 error("too many field init");
3662 t
= f
->t
| (t
& ~VT_TYPE
);
3666 decl_initializer(t
, c
, 0, size_only
);
3669 /* store a value or an expression directly in global data or in local array */
3671 void init_putv(int t
, int c
, int v
, int is_expr
)
3673 int saved_global_expr
;
3675 if ((t
& VT_VALMASK
) == VT_CONST
) {
3677 /* compound literals must be allocated globally in this case */
3678 saved_global_expr
= global_expr
;
3681 global_expr
= saved_global_expr
;
3683 if ((t
& VT_BTYPE
) == VT_BYTE
)
3685 else if ((t
& VT_BTYPE
) == VT_SHORT
)
3700 /* put zeros for variable based init */
3701 void init_putz(int t
, int c
, int size
)
3705 if ((t
& VT_VALMASK
) == VT_CONST
) {
3706 /* nothing to do because global are already set to zero */
3709 vset(VT_CONST
, size
);
3715 vset(VT_CONST
, (int)&memset
);
3720 /* 't' contains the type and storage info. c is the address of the
3721 object. 'first' is true if array '{' must be read (multi dimension
3722 implicit array init handling). 'size_only' is true if size only
3723 evaluation is wanted (only for arrays). */
3724 void decl_initializer(int t
, int c
, int first
, int size_only
)
3726 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
3727 int t1
, size1
, align1
;
3732 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
));
3735 t1
= pointed_type(t
);
3736 size1
= type_size(t1
, &align1
);
3739 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
3745 /* only parse strings here if correct type (otherwise: handle
3746 them as ((w)char *) expressions */
3747 if ((tok
== TOK_LSTR
&&
3748 (t1
& VT_BTYPE
) == VT_INT
) ||
3750 (t1
& VT_BTYPE
) == VT_BYTE
)) {
3751 /* XXX: move multiple string parsing in parser ? */
3752 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
3754 /* compute maximum number of chars wanted */
3756 if (n
>= 0 && nb
> (n
- array_length
))
3757 nb
= n
- array_length
;
3760 warning("initializer-string for array is too long");
3762 init_putv(t1
, c
+ (array_length
+ i
) * size1
,
3769 /* only add trailing zero if enough storage (no
3770 warning in this case since it is standard) */
3771 if (n
< 0 || array_length
< n
) {
3773 init_putv(t1
, c
+ (array_length
* size1
), 0, 0);
3779 while (tok
!= '}') {
3780 decl_designator(t
, c
, &index
, NULL
, size_only
);
3781 if (n
>= 0 && index
>= n
)
3782 error("index too large");
3783 /* must put zero in holes (note that doing it that way
3784 ensures that it even works with designators) */
3785 if (!size_only
&& array_length
< index
) {
3786 init_putz(t1
, c
+ array_length
* size1
,
3787 (index
- array_length
) * size1
);
3790 if (index
> array_length
)
3791 array_length
= index
;
3792 /* special test for multi dimensional arrays (may not
3793 be strictly correct if designators are used at the
3795 if (index
>= n
&& no_oblock
)
3804 /* put zeros at the end */
3805 if (!size_only
&& n
>= 0 && array_length
< n
) {
3806 init_putz(t1
, c
+ array_length
* size1
,
3807 (n
- array_length
) * size1
);
3809 /* patch type size if needed */
3811 s
->c
= array_length
;
3812 } else if ((t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
3813 /* XXX: union needs only one init */
3815 s
= sym_find(((unsigned)t
>> VT_STRUCT_SHIFT
) | SYM_STRUCT
);
3820 while (tok
!= '}') {
3821 decl_designator(t
, c
, NULL
, &f
, size_only
);
3822 /* fill with zero between fields */
3824 if (!size_only
&& array_length
< index
) {
3825 init_putz(t
, c
+ array_length
,
3826 index
- array_length
);
3828 index
= index
+ type_size(f
->t
, &align1
);
3829 if (index
> array_length
)
3830 array_length
= index
;
3836 /* put zeros at the end */
3837 if (!size_only
&& array_length
< n
) {
3838 init_putz(t
, c
+ array_length
,
3842 } else if (tok
== '{') {
3844 decl_initializer(t
, c
, first
, size_only
);
3846 } else if (size_only
) {
3847 /* just skip expression */
3849 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
3853 else if (tok
== ')')
3858 init_putv(t
, c
, 0, 1);
3862 /* parse an initializer for type 't' if 'has_init' is true, and
3863 allocate space in local or global data space. The allocated address
3865 int decl_initializer_alloc(int t
, int has_init
)
3867 int size
, align
, addr
, tok1
;
3868 int *init_str
, init_len
, level
, *saved_macro_ptr
;
3870 size
= type_size(t
, &align
);
3871 /* If unknown size, we must evaluate it before
3872 evaluating initializers because
3873 initializers can generate global data too
3874 (e.g. string pointers or ISOC99 compound
3875 literals). It also simplifies local
3876 initializers handling */
3879 saved_macro_ptr
= NULL
; /* avoid warning */
3883 error("unknown type size");
3884 /* get all init string */
3886 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
3888 error("unexpect end of file in initializer");
3889 tok_add2(&init_str
, &init_len
, tok
, &tokc
);
3892 else if (tok
== '}') {
3900 tok_add(&init_str
, &init_len
, -1);
3901 tok_add(&init_str
, &init_len
, 0);
3904 saved_macro_ptr
= macro_ptr
;
3905 macro_ptr
= init_str
;
3907 decl_initializer(t
, 0, 1, 1);
3908 /* prepare second initializer parsing */
3909 macro_ptr
= init_str
;
3912 /* if still unknown size, error */
3913 size
= type_size(t
, &align
);
3915 error("unknown type size");
3917 if ((t
& VT_VALMASK
) == VT_LOCAL
) {
3918 loc
= (loc
- size
) & -align
;
3921 glo
= (glo
+ align
- 1) & -align
;
3923 /* very important to increment global
3924 pointer at this time because
3925 initializers themselves can create new
3930 decl_initializer(t
, addr
, 1, 0);
3931 /* restore parse state if needed */
3934 macro_ptr
= saved_macro_ptr
;
3942 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
3945 int *a
, t
, b
, v
, u
, addr
, has_init
, size
, align
;
3951 /* skip redundant ';' */
3952 /* XXX: find more elegant solution */
3957 /* special test for old K&R protos without explicit int
3958 type. Only accepted when defining global data */
3959 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
3963 if (((b
& VT_BTYPE
) == VT_ENUM
||
3964 (b
& VT_BTYPE
) == VT_STRUCT
) &&
3966 /* we accept no variable after */
3970 while (1) { /* iterate thru each declaration */
3971 t
= type_decl(&v
, b
, TYPE_DIRECT
);
3974 error("cannot use local functions");
3976 expect("function definition");
3977 /* patch forward references */
3978 if ((sym
= sym_find(v
)) && (sym
->t
& VT_FORWARD
)) {
3979 greloc_patch(sym
, ind
);
3980 sym
->t
= VT_CONST
| t
;
3982 /* put function address */
3983 sym_push1(&global_stack
, v
, VT_CONST
| t
, ind
);
3985 funcname
= get_tok_str(v
, 0);
3986 /* push a dummy symbol to enable local sym storage */
3987 sym_push1(&local_stack
, 0, 0, 0);
3988 /* define parameters */
3989 sym
= sym_find((unsigned)t
>> VT_STRUCT_SHIFT
);
3990 /* XXX: the following is x86 dependant -> move it to
3993 /* if the function returns a structure, then add an
3994 implicit pointer parameter */
3996 if ((func_vt
& VT_BTYPE
) == VT_STRUCT
) {
4000 while (sym
= sym
->next
) {
4002 sym_push(sym
->v
& ~SYM_FIELD
,
4003 u
| VT_LOCAL
| VT_LVAL
,
4005 if ((u
& VT_BTYPE
) == VT_STRUCT
) {
4006 #ifdef FUNC_STRUCT_PARAM_AS_PTR
4007 /* structs are passed as pointer */
4010 /* structs are directly put on stack (x86
4012 size
= type_size(u
, &align
);
4013 size
= (size
+ 3) & ~3;
4016 /* XXX: size will be different someday */
4022 o(0xe58955); /* push %ebp, mov %esp, %ebp */
4023 a
= (int *)oad(0xec81, 0); /* sub $xxx, %esp */
4025 block(0, 0, 0, 0, 0);
4027 o(0xc3c9); /* leave, ret */
4028 *a
= (-loc
+ 3) & -4; /* align local size to word &
4029 save local variables */
4030 sym_pop(&label_stack
, NULL
); /* reset label stack */
4031 sym_pop(&local_stack
, NULL
); /* reset local stack */
4032 funcname
= ""; /* for safety */
4033 func_vt
= VT_VOID
; /* for safety */
4036 if (b
& VT_TYPEDEF
) {
4037 /* save typedefed type */
4038 /* XXX: test storage specifiers ? */
4039 sym_push(v
, t
| VT_TYPEDEF
, 0);
4040 } else if ((t
& VT_BTYPE
) == VT_FUNC
) {
4041 /* external function definition */
4044 /* not lvalue if array */
4045 if (!(t
& VT_ARRAY
))
4047 if (b
& VT_EXTERN
) {
4048 /* external variable */
4055 has_init
= (tok
== '=');
4058 addr
= decl_initializer_alloc(u
, has_init
);
4059 if (l
== VT_CONST
) {
4060 /* global scope: see if already defined */
4064 if (!is_compatible_types(sym
->t
, u
))
4065 error("incompatible types for redefinition of '%s'",
4067 if (!(sym
->t
& VT_FORWARD
))
4068 error("redefinition of '%s'", get_tok_str(v
, 0));
4069 greloc_patch(sym
, addr
);
4072 sym_push(v
, u
, addr
);
4086 /* put all global symbols in the extern stack and do all the
4087 resolving which can be done without using external symbols from DLLs */
4088 /* XXX: could try to verify types, but would not to save them in
4090 void resolve_global_syms(void)
4092 Sym
*s
, *s1
, *ext_sym
;
4095 s
= global_stack
.top
;
4098 /* do not save static or typedefed symbols or types */
4099 if (!(s
->t
& (VT_STATIC
| VT_TYPEDEF
)) &&
4100 !(s
->v
& (SYM_FIELD
| SYM_STRUCT
)) &&
4101 (s
->v
< SYM_FIRST_ANOM
)) {
4102 ext_sym
= sym_find1(&extern_stack
, s
->v
);
4104 /* if the symbol do not exist, we simply save it */
4105 sym_push1(&extern_stack
, s
->v
, s
->t
, s
->c
);
4106 } else if (ext_sym
->t
& VT_FORWARD
) {
4107 /* external symbol already exists, but only as forward
4109 if (!(s
->t
& VT_FORWARD
)) {
4110 /* s is not forward, so we can relocate all symbols */
4111 greloc_patch(ext_sym
, s
->c
);
4113 /* the two symbols are forward: merge them */
4114 p
= (Reloc
**)&ext_sym
->c
;
4120 /* external symbol already exists and is defined :
4121 patch all references to it */
4122 if (!(s
->t
& VT_FORWARD
))
4123 error("'%s' defined twice", get_tok_str(s
->v
, 0));
4124 greloc_patch(s
, ext_sym
->c
);
4131 /* compile a C file. Return non zero if errors. */
4132 int tcc_compile_file(const char *filename1
)
4136 filename
= (char *)filename1
;
4140 file
= fopen(filename
, "r");
4142 error("file '%s' not found", filename
);
4143 include_stack_ptr
= include_stack
;
4144 ifdef_stack_ptr
= ifdef_stack
;
4147 anon_sym
= SYM_FIRST_ANOM
;
4149 define_start
= define_stack
.top
;
4151 ch
= '\n'; /* needed to parse correctly first preprocessor command */
4155 expect("declaration");
4158 /* reset define stack, but leave -Dsymbols (may be incorrect if
4159 they are undefined) */
4160 sym_pop(&define_stack
, define_start
);
4162 resolve_global_syms();
4164 sym_pop(&global_stack
, NULL
);
4169 /* open a dynamic library so that its symbol are available for
4170 compiled programs */
4171 void open_dll(char *libname
)
4176 snprintf(buf
, sizeof(buf
), "lib%s.so", libname
);
4177 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
4179 error((char *)dlerror());
4182 void resolve_extern_syms(void)
4188 s
= extern_stack
.top
;
4191 if (s
->t
& VT_FORWARD
) {
4192 /* if there is at least one relocation to do, then find it
4195 str
= get_tok_str(s
->v
, 0);
4196 addr
= (int)dlsym(NULL
, str
);
4198 error("unresolved external reference '%s'", str
);
4199 greloc_patch(s
, addr
);
4206 /* output a binary file (for testing) */
4207 void build_exe(char *filename
)
4210 f
= fopen(filename
, "w");
4211 fwrite((void *)prog
, 1, ind
- prog
, f
);
4215 int main(int argc
, char **argv
)
4219 char *p
, *r
, *outfile
;
4222 include_paths
[0] = "/usr/include";
4223 include_paths
[1] = "/usr/lib/tcc";
4224 include_paths
[2] = "/usr/local/lib/tcc";
4225 nb_include_paths
= 3;
4227 /* add all tokens */
4228 tok_ident
= TOK_IDENT
;
4229 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";
4233 tok_alloc(p
, r
- p
- 1);
4237 /* standard defines */
4238 define_symbol("__STDC__");
4240 define_symbol("__i386__");
4242 /* tiny C specific defines */
4243 define_symbol("__TINYC__");
4245 glo
= (int)malloc(DATA_SIZE
);
4246 memset((void *)glo
, 0, DATA_SIZE
);
4247 prog
= (int)malloc(TEXT_SIZE
);
4253 if (optind
>= argc
) {
4255 printf("tcc version 0.9.2 - Tiny C Compiler - Copyright (C) 2001 Fabrice Bellard\n"
4256 "usage: tcc [-Idir] [-Dsym] [-llib] [-i infile] infile [infile_args...]\n");
4264 if (nb_include_paths
>= INCLUDE_PATHS_MAX
)
4265 error("too many include paths");
4266 include_paths
[nb_include_paths
++] = r
+ 2;
4267 } else if (r
[1] == 'D') {
4268 define_symbol(r
+ 2);
4269 } else if (r
[1] == 'l') {
4271 } else if (r
[1] == 'i') {
4274 tcc_compile_file(argv
[optind
++]);
4275 } else if (r
[1] == 'o') {
4276 /* currently, only for testing, so not documented */
4279 outfile
= argv
[optind
++];
4281 fprintf(stderr
, "invalid option -- '%s'\n", r
);
4286 tcc_compile_file(argv
[optind
]);
4288 resolve_extern_syms();
4294 s
= sym_find1(&extern_stack
, TOK_MAIN
);
4295 if (!s
|| (s
->t
& VT_FORWARD
))
4296 error("main() not defined");
4297 t
= (int (*)())s
->c
;
4298 return (*t
)(argc
- optind
, argv
+ optind
);