2 * TCC - Tiny C Compiler
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 #include <sys/timeb.h>
36 #include <sys/ucontext.h>
40 #ifndef CONFIG_TCC_STATIC
48 /* preprocessor debug */
50 /* include file debug */
55 /* target selection */
56 //#define TCC_TARGET_I386 /* i386 code generator */
57 //#define TCC_TARGET_IL /* .NET CLI generator */
59 /* default target is I386 */
60 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
61 #define TCC_TARGET_I386
64 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
65 #define CONFIG_TCC_BCHECK /* enable bound checking code */
68 #ifndef CONFIG_TCC_PREFIX
69 #define CONFIG_TCC_PREFIX "/usr/local"
72 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
73 executables or dlls */
74 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
76 #define INCLUDE_STACK_SIZE 32
77 #define IFDEF_STACK_SIZE 64
78 #define VSTACK_SIZE 64
79 #define STRING_MAX_SIZE 1024
81 #define TOK_HASH_SIZE 2048 /* must be a power of two */
82 #define TOK_ALLOC_INCR 512 /* must be a power of two */
84 /* token symbol management */
85 typedef struct TokenSym
{
86 struct TokenSym
*hash_next
;
87 struct Sym
*sym_define
; /* direct pointer to define */
88 struct Sym
*sym_label
; /* direct pointer to label */
89 struct Sym
*sym_struct
; /* direct pointer to structure */
90 struct Sym
*sym_identifier
; /* direct pointer to identifier */
91 int tok
; /* token number */
96 typedef struct CString
{
97 int size
; /* size in bytes */
98 void *data
; /* either 'char *' or 'int *' */
100 void *data_allocated
; /* if non NULL, data has been malloced */
103 /* type definition */
104 typedef struct CType
{
110 typedef union CValue
{
116 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
118 unsigned long long ull
;
119 struct CString
*cstr
;
125 typedef struct SValue
{
126 CType type
; /* type */
127 unsigned short r
; /* register + flags */
128 unsigned short r2
; /* second register, used for 'long long'
129 type. If not used, set to VT_CONST */
130 CValue c
; /* constant, if VT_CONST */
131 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
134 /* symbol management */
136 int v
; /* symbol token */
137 int r
; /* associated register */
138 int c
; /* associated number */
139 CType type
; /* associated type */
140 struct Sym
*next
; /* next related symbol */
141 struct Sym
*prev
; /* prev symbol in stack */
142 struct Sym
*prev_tok
; /* previous symbol for this token */
145 /* section definition */
146 /* XXX: use directly ELF structure for parameters ? */
147 /* special flag to indicate that the section should not be linked to
149 #define SHF_PRIVATE 0x80000000
151 typedef struct Section
{
152 unsigned long data_offset
; /* current data offset */
153 unsigned char *data
; /* section data */
154 unsigned long data_allocated
; /* used for realloc() handling */
155 int sh_name
; /* elf section name (only used during output) */
156 int sh_num
; /* elf section number */
157 int sh_type
; /* elf section type */
158 int sh_flags
; /* elf section flags */
159 int sh_info
; /* elf section info */
160 int sh_addralign
; /* elf section alignment */
161 int sh_entsize
; /* elf entry size */
162 unsigned long sh_size
; /* section size (only used during output) */
163 unsigned long sh_addr
; /* address at which the section is relocated */
164 unsigned long sh_offset
; /* address at which the section is relocated */
165 int nb_hashed_syms
; /* used to resize the hash table */
166 struct Section
*link
; /* link to another section */
167 struct Section
*reloc
; /* corresponding section for relocation, if any */
168 struct Section
*hash
; /* hash table for symbols */
169 struct Section
*next
;
170 char name
[64]; /* section name */
173 typedef struct DLLReference
{
178 /* GNUC attribute definition */
179 typedef struct AttributeDef
{
182 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
185 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
186 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
187 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
189 /* stored in 'Sym.c' field */
190 #define FUNC_NEW 1 /* ansi function prototype */
191 #define FUNC_OLD 2 /* old function prototype */
192 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
194 /* stored in 'Sym.r' field */
195 #define FUNC_CDECL 0 /* standard c call */
196 #define FUNC_STDCALL 1 /* pascal c call */
198 /* field 'Sym.t' for macros */
199 #define MACRO_OBJ 0 /* object like macro */
200 #define MACRO_FUNC 1 /* function like macro */
202 /* field 'Sym.r' for labels */
203 #define LABEL_FORWARD 1 /* label is forward defined */
205 /* type_decl() types */
206 #define TYPE_ABSTRACT 1 /* type without variable */
207 #define TYPE_DIRECT 2 /* type with variable */
209 #define IO_BUF_SIZE 8192
211 typedef struct BufferedFile
{
212 unsigned char *buf_ptr
;
213 unsigned char *buf_end
;
215 int line_num
; /* current line number - here to simply code */
216 int ifndef_macro
; /*'#ifndef macro \n #define macro' search */
217 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
218 char inc_type
; /* type of include */
219 char inc_filename
[512]; /* filename specified by the user */
220 char filename
[1024]; /* current filename - here to simplify code */
221 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
224 #define CH_EOB '\\' /* end of buffer or '\0' char in file */
225 #define CH_EOF (-1) /* end of file */
227 /* parsing state (used to save parser state to reparse part of the
228 source several times) */
229 typedef struct ParseState
{
236 /* used to record tokens */
237 typedef struct TokenString
{
243 /* include file cache, used to find files faster and also to eliminate
244 inclusion if the include file is protected by #ifndef ... #endif */
245 typedef struct CachedInclude
{
247 char type
; /* '"' or '>' to give include type */
248 char filename
[1]; /* path specified in #include */
252 struct BufferedFile
*file
;
255 CString tokcstr
; /* current parsed string, if any */
256 /* if true, line feed is returned as a token. line feed is also
259 /* set to TRUE if eof was reached */
261 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
262 Section
*cur_text_section
; /* current section where function code is
264 /* bound check related sections */
265 Section
*bounds_section
; /* contains global data bound description */
266 Section
*lbounds_section
; /* contains local data bound description */
267 /* symbol sections */
268 Section
*symtab_section
, *strtab_section
;
271 Section
*stab_section
, *stabstr_section
;
273 /* loc : local variable index
274 ind : output code index
276 anon_sym: anonymous symbol index
280 /* expression generation modifiers */
281 int const_wanted
; /* true if constant wanted */
282 int nocode_wanted
; /* true if no code generation wanted for an expression */
283 int global_expr
; /* true if compound literals must be allocated
284 globally (used during initializers parsing */
285 CType func_vt
; /* current function return type (used by return
288 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
290 TokenSym
**table_ident
;
291 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
292 char token_buf
[STRING_MAX_SIZE
+ 1];
294 Sym
*global_stack
, *local_stack
;
298 SValue vstack
[VSTACK_SIZE
], *vtop
;
299 int *macro_ptr
, *macro_ptr_allocated
;
300 /* some predefined types */
301 CType char_pointer_type
, func_old_type
, int_type
;
303 /* compile with debug symbol (and use them if error during execution) */
306 /* compile with built-in memory and bounds checker */
307 int do_bounds_check
= 0;
309 /* display benchmark infos */
314 /* use GNU C extensions */
317 /* use Tiny C extensions */
320 /* max number of callers shown if error */
321 static int num_callers
= 6;
322 static const char **rt_bound_error_msg
;
324 /* XXX: suppress that ASAP */
325 static struct TCCState
*tcc_state
;
327 /* give the path of the tcc libraries */
328 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
333 BufferedFile
**include_stack_ptr
;
334 int *ifdef_stack_ptr
;
336 /* include file handling */
337 char **include_paths
;
338 int nb_include_paths
;
339 char **sysinclude_paths
;
340 int nb_sysinclude_paths
;
341 CachedInclude
**cached_includes
;
342 int nb_cached_includes
;
344 char **library_paths
;
345 int nb_library_paths
;
347 /* array of all loaded dlls (including those referenced by loaded
349 DLLReference
**loaded_dlls
;
354 int nb_sections
; /* number of sections, including first dummy section */
358 unsigned long *got_offsets
;
361 /* give the correspondance from symtab indexes to dynsym indexes */
362 int *symtab_to_dynsym
;
364 /* temporary dynamic symbol sections (for dll loading) */
365 Section
*dynsymtab_section
;
366 /* exported dynamic symbol section */
369 /* if true, static linking is performed */
374 void (*error_func
)(void *opaque
, const char *msg
);
375 int error_set_jmp_enabled
;
376 jmp_buf error_jmp_buf
;
379 /* see include_stack_ptr */
380 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
382 /* see ifdef_stack_ptr */
383 int ifdef_stack
[IFDEF_STACK_SIZE
];
386 /* The current value can be: */
387 #define VT_VALMASK 0x00ff
388 #define VT_CONST 0x00f0 /* constant in vc
389 (must be first non register value) */
390 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
391 #define VT_LOCAL 0x00f2 /* offset on stack */
392 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
393 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
394 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
395 #define VT_LVAL 0x0100 /* var is an lvalue */
396 #define VT_SYM 0x0200 /* a symbol value is added */
397 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
398 char/short stored in integer registers) */
399 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
400 dereferencing value */
401 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
402 bounding function call point is in vc */
403 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
404 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
405 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
406 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
409 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
411 #define VT_INT 0 /* integer type */
412 #define VT_BYTE 1 /* signed byte type */
413 #define VT_SHORT 2 /* short type */
414 #define VT_VOID 3 /* void type */
415 #define VT_PTR 4 /* pointer */
416 #define VT_ENUM 5 /* enum definition */
417 #define VT_FUNC 6 /* function type */
418 #define VT_STRUCT 7 /* struct/union definition */
419 #define VT_FLOAT 8 /* IEEE float */
420 #define VT_DOUBLE 9 /* IEEE double */
421 #define VT_LDOUBLE 10 /* IEEE long double */
422 #define VT_BOOL 11 /* ISOC99 boolean type */
423 #define VT_LLONG 12 /* 64 bit integer */
424 #define VT_LONG 13 /* long integer (NEVER USED as type, only
426 #define VT_BTYPE 0x000f /* mask for basic type */
427 #define VT_UNSIGNED 0x0010 /* unsigned type */
428 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
429 #define VT_BITFIELD 0x0040 /* bitfield modifier */
432 #define VT_EXTERN 0x00000080 /* extern definition */
433 #define VT_STATIC 0x00000100 /* static variable */
434 #define VT_TYPEDEF 0x00000200 /* typedef definition */
436 /* type mask (except storage) */
437 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
441 /* warning: the following compare tokens depend on i386 asm code */
453 #define TOK_LAND 0xa0
457 #define TOK_MID 0xa3 /* inc/dec, to void constant */
459 #define TOK_UDIV 0xb0 /* unsigned division */
460 #define TOK_UMOD 0xb1 /* unsigned modulo */
461 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
462 #define TOK_CINT 0xb3 /* number in tokc */
463 #define TOK_CCHAR 0xb4 /* char constant in tokc */
464 #define TOK_STR 0xb5 /* pointer to string in tokc */
465 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
466 #define TOK_LCHAR 0xb7
467 #define TOK_LSTR 0xb8
468 #define TOK_CFLOAT 0xb9 /* float constant */
469 #define TOK_LINENUM 0xba /* line number info */
470 #define TOK_CDOUBLE 0xc0 /* double constant */
471 #define TOK_CLDOUBLE 0xc1 /* long double constant */
472 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
473 #define TOK_ADDC1 0xc3 /* add with carry generation */
474 #define TOK_ADDC2 0xc4 /* add with carry use */
475 #define TOK_SUBC1 0xc5 /* add with carry generation */
476 #define TOK_SUBC2 0xc6 /* add with carry use */
477 #define TOK_CUINT 0xc8 /* unsigned int constant */
478 #define TOK_CLLONG 0xc9 /* long long constant */
479 #define TOK_CULLONG 0xca /* unsigned long long constant */
480 #define TOK_ARROW 0xcb
481 #define TOK_DOTS 0xcc /* three dots */
482 #define TOK_SHR 0xcd /* unsigned shift right */
483 #define TOK_PPNUM 0xce /* preprocessor number */
485 #define TOK_SHL 0x01 /* shift left */
486 #define TOK_SAR 0x02 /* signed shift right */
488 /* assignement operators : normal operator or 0x80 */
489 #define TOK_A_MOD 0xa5
490 #define TOK_A_AND 0xa6
491 #define TOK_A_MUL 0xaa
492 #define TOK_A_ADD 0xab
493 #define TOK_A_SUB 0xad
494 #define TOK_A_DIV 0xaf
495 #define TOK_A_XOR 0xde
496 #define TOK_A_OR 0xfc
497 #define TOK_A_SHL 0x81
498 #define TOK_A_SAR 0x82
500 /* WARNING: the content of this string encodes token numbers */
501 static char tok_two_chars
[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
503 #define TOK_EOF (-1) /* end of file */
504 #define TOK_LINEFEED 10 /* line feed */
506 /* all identificators and strings have token above that */
507 #define TOK_IDENT 256
510 TOK_LAST
= TOK_IDENT
- 1,
511 #define DEF(id, str) id,
516 static const char *tcc_keywords
=
517 #define DEF(id, str) str "\0"
522 #define TOK_UIDENT TOK_DEFINE
525 #define snprintf _snprintf
526 #define vsnprintf _vsnprintf
529 #if defined(WIN32) || defined(TCC_UCLIBC)
530 /* currently incorrect */
531 long double strtold(const char *nptr
, char **endptr
)
533 return (long double)strtod(nptr
, endptr
);
535 float strtof(const char *nptr
, char **endptr
)
537 return (float)strtod(nptr
, endptr
);
540 /* XXX: need to define this to use them in non ISOC99 context */
541 extern float strtof (const char *__nptr
, char **__endptr
);
542 extern long double strtold (const char *__nptr
, char **__endptr
);
545 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
546 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
548 static void sum(int l
);
549 static void next(void);
550 static void next_nomacro(void);
551 static void parse_expr_type(CType
*type
);
552 static void expr_type(CType
*type
);
553 static void unary_type(CType
*type
);
554 static int expr_const(void);
555 static void expr_eq(void);
556 static void gexpr(void);
557 static void decl(int l
);
558 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
559 int first
, int size_only
);
560 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
561 int has_init
, int v
, int scope
);
563 void gv2(int rc1
, int rc2
);
564 void move_reg(int r
, int s
);
565 void save_regs(int n
);
566 void save_reg(int r
);
572 static void macro_subst(TokenString
*tok_str
,
573 Sym
**nested_list
, int *macro_str
);
574 int save_reg_forced(int r
);
576 void force_charshort_cast(int t
);
577 static void gen_cast(CType
*type
);
579 static Sym
*sym_find(int v
);
580 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
583 int type_size(CType
*type
, int *a
);
584 static inline CType
*pointed_type(CType
*type
);
585 static int pointed_size(CType
*type
);
586 static int lvalue_type(int t
);
587 static int is_compatible_types(CType
*type1
, CType
*type2
);
588 static int parse_btype(CType
*type
, AttributeDef
*ad
);
589 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
591 void error(const char *fmt
, ...);
593 void vset(CType
*type
, int r
, int v
);
594 void type_to_str(char *buf
, int buf_size
,
595 CType
*type
, const char *varstr
);
596 char *get_tok_str(int v
, CValue
*cv
);
597 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
598 unsigned long offset
, unsigned long size
);
599 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
601 /* section generation */
602 static void section_realloc(Section
*sec
, unsigned long new_size
);
603 static void *section_ptr_add(Section
*sec
, unsigned long size
);
604 static void put_extern_sym(Sym
*sym
, Section
*section
,
605 unsigned long value
, unsigned long size
);
606 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
607 static int put_elf_str(Section
*s
, const char *sym
);
608 static int put_elf_sym(Section
*s
,
609 unsigned long value
, unsigned long size
,
610 int info
, int other
, int shndx
, const char *name
);
611 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
612 int info
, int sh_num
, const char *name
);
613 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
614 int type
, int symbol
);
615 static void put_stabs(const char *str
, int type
, int other
, int desc
,
616 unsigned long value
);
617 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
618 unsigned long value
, Section
*sec
, int sym_index
);
619 static void put_stabn(int type
, int other
, int desc
, int value
);
620 static void put_stabd(int type
, int other
, int desc
);
621 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
623 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
624 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
625 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
627 /* true if float/double/long double type */
628 static inline int is_float(int t
)
632 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
635 #ifdef TCC_TARGET_I386
636 #include "i386-gen.c"
642 #ifdef CONFIG_TCC_STATIC
644 #define RTLD_LAZY 0x001
645 #define RTLD_NOW 0x002
646 #define RTLD_GLOBAL 0x100
647 #define RTLD_DEFAULT NULL
649 /* dummy function for profiling */
650 void *dlopen(const char *filename
, int flag
)
655 const char *dlerror(void)
660 typedef struct TCCSyms
{
665 #define TCCSYM(a) { #a, &a, },
667 /* add the symbol you want here if no dynamic linking is done */
668 static TCCSyms tcc_syms
[] = {
676 void *dlsym(void *handle
, const char *symbol
)
680 while (p
->str
!= NULL
) {
681 if (!strcmp(p
->str
, symbol
))
690 /********************************************************/
692 /* we use our own 'finite' function to avoid potential problems with
693 non standard math libs */
694 /* XXX: endianness dependant */
695 int ieee_finite(double d
)
698 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
701 /* copy a string and truncate it. */
702 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
709 q_end
= buf
+ buf_size
- 1;
721 /* strcat and truncate. */
722 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
727 pstrcpy(buf
+ len
, buf_size
- len
, s
);
731 /* memory management */
737 static inline void tcc_free(void *ptr
)
740 mem_cur_size
-= malloc_usable_size(ptr
);
745 static void *tcc_malloc(unsigned long size
)
750 error("memory full");
752 mem_cur_size
+= malloc_usable_size(ptr
);
753 if (mem_cur_size
> mem_max_size
)
754 mem_max_size
= mem_cur_size
;
759 static void *tcc_mallocz(unsigned long size
)
762 ptr
= tcc_malloc(size
);
763 memset(ptr
, 0, size
);
767 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
771 mem_cur_size
-= malloc_usable_size(ptr
);
773 ptr1
= realloc(ptr
, size
);
775 /* NOTE: count not correct if alloc error, but not critical */
776 mem_cur_size
+= malloc_usable_size(ptr1
);
777 if (mem_cur_size
> mem_max_size
)
778 mem_max_size
= mem_cur_size
;
783 static char *tcc_strdup(const char *str
)
786 ptr
= tcc_malloc(strlen(str
) + 1);
791 #define free(p) use_tcc_free(p)
792 #define malloc(s) use_tcc_malloc(s)
793 #define realloc(p, s) use_tcc_realloc(p, s)
795 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
802 /* every power of two we double array size */
803 if ((nb
& (nb
- 1)) == 0) {
808 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
810 error("memory full");
817 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
821 sec
= tcc_mallocz(sizeof(Section
));
822 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
823 sec
->sh_type
= sh_type
;
824 sec
->sh_flags
= sh_flags
;
831 sec
->sh_addralign
= 4;
834 sec
->sh_addralign
= 1;
837 sec
->sh_addralign
= 32; /* default conservative alignment */
841 /* only add section if not private */
842 if (!(sh_flags
& SHF_PRIVATE
)) {
843 sec
->sh_num
= s1
->nb_sections
;
844 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
849 static void free_section(Section
*s
)
855 /* realloc section and set its content to zero */
856 static void section_realloc(Section
*sec
, unsigned long new_size
)
861 size
= sec
->data_allocated
;
864 while (size
< new_size
)
866 data
= tcc_realloc(sec
->data
, size
);
868 error("memory full");
869 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
871 sec
->data_allocated
= size
;
874 /* reserve at least 'size' bytes in section 'sec' from
876 static void *section_ptr_add(Section
*sec
, unsigned long size
)
878 unsigned long offset
, offset1
;
880 offset
= sec
->data_offset
;
881 offset1
= offset
+ size
;
882 if (offset1
> sec
->data_allocated
)
883 section_realloc(sec
, offset1
);
884 sec
->data_offset
= offset1
;
885 return sec
->data
+ offset
;
888 /* return a reference to a section, and create it if it does not
890 Section
*find_section(TCCState
*s1
, const char *name
)
894 for(i
= 1; i
< s1
->nb_sections
; i
++) {
895 sec
= s1
->sections
[i
];
896 if (!strcmp(name
, sec
->name
))
899 /* sections are created as PROGBITS */
900 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
903 /* update sym->c so that it points to an external symbol in section
904 'section' with value 'value' */
905 static void put_extern_sym(Sym
*sym
, Section
*section
,
906 unsigned long value
, unsigned long size
)
908 int sym_type
, sym_bind
, sh_num
, info
;
913 sh_num
= section
->sh_num
;
917 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
)
920 sym_type
= STT_OBJECT
;
921 if (sym
->type
.t
& VT_STATIC
)
922 sym_bind
= STB_LOCAL
;
924 sym_bind
= STB_GLOBAL
;
926 name
= get_tok_str(sym
->v
, NULL
);
927 #ifdef CONFIG_TCC_BCHECK
928 if (do_bounds_check
) {
931 /* XXX: avoid doing that for statics ? */
932 /* if bound checking is activated, we change some function
933 names by adding the "__bound" prefix */
936 /* XXX: we rely only on malloc hooks */
948 strcpy(buf
, "__bound_");
955 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
956 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
958 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
959 esym
->st_value
= value
;
960 esym
->st_size
= size
;
961 esym
->st_shndx
= sh_num
;
965 /* add a new relocation entry to symbol 'sym' in section 's' */
966 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
969 put_extern_sym(sym
, NULL
, 0, 0);
970 /* now we can add ELF relocation info */
971 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
974 static inline int isid(int c
)
976 return (c
>= 'a' && c
<= 'z') ||
977 (c
>= 'A' && c
<= 'Z') ||
981 static inline int isnum(int c
)
983 return c
>= '0' && c
<= '9';
986 static inline int isoct(int c
)
988 return c
>= '0' && c
<= '7';
991 static inline int toup(int c
)
993 if (c
>= 'a' && c
<= 'z')
994 return c
- 'a' + 'A';
999 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1003 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1006 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1010 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1014 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1021 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1022 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1023 (*f
)->filename
, (*f
)->line_num
);
1024 if (file
->line_num
> 0) {
1025 strcat_printf(buf
, sizeof(buf
),
1026 "%s:%d: ", file
->filename
, file
->line_num
);
1028 strcat_printf(buf
, sizeof(buf
),
1029 "%s: ", file
->filename
);
1032 strcat_printf(buf
, sizeof(buf
),
1036 strcat_printf(buf
, sizeof(buf
), "warning: ");
1037 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1039 if (!s1
->error_func
) {
1040 /* default case: stderr */
1041 fprintf(stderr
, "%s\n", buf
);
1043 s1
->error_func(s1
->error_opaque
, buf
);
1050 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1051 void (*error_func
)(void *opaque
, const char *msg
))
1053 s
->error_opaque
= error_opaque
;
1054 s
->error_func
= error_func
;
1058 /* error without aborting current compilation */
1059 void error_noabort(const char *fmt
, ...)
1061 TCCState
*s1
= tcc_state
;
1065 error1(s1
, 0, fmt
, ap
);
1069 void error(const char *fmt
, ...)
1071 TCCState
*s1
= tcc_state
;
1075 error1(s1
, 0, fmt
, ap
);
1077 /* better than nothing: in some cases, we accept to handle errors */
1078 if (s1
->error_set_jmp_enabled
) {
1079 longjmp(s1
->error_jmp_buf
, 1);
1081 /* XXX: suppress it someday */
1086 void expect(const char *msg
)
1088 error("%s expected", msg
);
1091 void warning(const char *fmt
, ...)
1093 TCCState
*s1
= tcc_state
;
1097 error1(s1
, 1, fmt
, ap
);
1104 error("'%c' expected", c
);
1108 void test_lvalue(void)
1110 if (!(vtop
->r
& VT_LVAL
))
1114 TokenSym
*tok_alloc(const char *str
, int len
)
1116 TokenSym
*ts
, **pts
, **ptable
;
1121 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
1123 pts
= &hash_ident
[h
];
1128 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1130 pts
= &(ts
->hash_next
);
1133 if (tok_ident
>= SYM_FIRST_ANOM
)
1134 error("memory full");
1136 /* expand token table if needed */
1137 i
= tok_ident
- TOK_IDENT
;
1138 if ((i
% TOK_ALLOC_INCR
) == 0) {
1139 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1141 error("memory full");
1142 table_ident
= ptable
;
1145 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1146 table_ident
[i
] = ts
;
1147 ts
->tok
= tok_ident
++;
1148 ts
->sym_define
= NULL
;
1149 ts
->sym_label
= NULL
;
1150 ts
->sym_struct
= NULL
;
1151 ts
->sym_identifier
= NULL
;
1153 ts
->hash_next
= NULL
;
1154 memcpy(ts
->str
, str
, len
);
1155 ts
->str
[len
] = '\0';
1160 /* CString handling */
1162 static void cstr_realloc(CString
*cstr
, int new_size
)
1167 size
= cstr
->size_allocated
;
1169 size
= 8; /* no need to allocate a too small first string */
1170 while (size
< new_size
)
1172 data
= tcc_realloc(cstr
->data_allocated
, size
);
1174 error("memory full");
1175 cstr
->data_allocated
= data
;
1176 cstr
->size_allocated
= size
;
1181 static void cstr_ccat(CString
*cstr
, int ch
)
1184 size
= cstr
->size
+ 1;
1185 if (size
> cstr
->size_allocated
)
1186 cstr_realloc(cstr
, size
);
1187 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1191 static void cstr_cat(CString
*cstr
, const char *str
)
1203 /* add a wide char */
1204 static void cstr_wccat(CString
*cstr
, int ch
)
1207 size
= cstr
->size
+ sizeof(int);
1208 if (size
> cstr
->size_allocated
)
1209 cstr_realloc(cstr
, size
);
1210 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1214 static void cstr_new(CString
*cstr
)
1216 memset(cstr
, 0, sizeof(CString
));
1219 /* free string and reset it to NULL */
1220 static void cstr_free(CString
*cstr
)
1222 tcc_free(cstr
->data_allocated
);
1226 #define cstr_reset(cstr) cstr_free(cstr)
1228 /* XXX: unicode ? */
1229 static void add_char(CString
*cstr
, int c
)
1231 if (c
== '\'' || c
== '\"' || c
== '\\') {
1232 /* XXX: could be more precise if char or string */
1233 cstr_ccat(cstr
, '\\');
1235 if (c
>= 32 && c
<= 126) {
1238 cstr_ccat(cstr
, '\\');
1240 cstr_ccat(cstr
, 'n');
1242 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1243 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1244 cstr_ccat(cstr
, '0' + (c
& 7));
1249 /* XXX: buffer overflow */
1250 /* XXX: float tokens */
1251 char *get_tok_str(int v
, CValue
*cv
)
1253 static char buf
[STRING_MAX_SIZE
+ 1];
1254 static CString cstr_buf
;
1260 /* NOTE: to go faster, we give a fixed buffer for small strings */
1261 cstr_reset(&cstr_buf
);
1262 cstr_buf
.data
= buf
;
1263 cstr_buf
.size_allocated
= sizeof(buf
);
1269 /* XXX: not quite exact, but only useful for testing */
1270 sprintf(p
, "%u", cv
->ui
);
1274 /* XXX: not quite exact, but only useful for testing */
1275 sprintf(p
, "%Lu", cv
->ull
);
1279 cstr_ccat(&cstr_buf
, '\'');
1280 add_char(&cstr_buf
, cv
->i
);
1281 cstr_ccat(&cstr_buf
, '\'');
1282 cstr_ccat(&cstr_buf
, '\0');
1286 len
= cstr
->size
- 1;
1288 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1289 cstr_ccat(&cstr_buf
, '\0');
1294 cstr_ccat(&cstr_buf
, '\"');
1296 len
= cstr
->size
- 1;
1298 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1300 len
= (cstr
->size
/ sizeof(int)) - 1;
1302 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1304 cstr_ccat(&cstr_buf
, '\"');
1305 cstr_ccat(&cstr_buf
, '\0');
1314 return strcpy(p
, "<<=");
1316 return strcpy(p
, ">>=");
1318 if (v
< TOK_IDENT
) {
1319 /* search in two bytes table */
1333 } else if (v
< tok_ident
) {
1334 return table_ident
[v
- TOK_IDENT
]->str
;
1335 } else if (v
>= SYM_FIRST_ANOM
) {
1336 /* special name for anonymous symbol */
1337 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1339 /* should never happen */
1344 return cstr_buf
.data
;
1347 /* push, without hashing */
1348 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1351 s
= tcc_malloc(sizeof(Sym
));
1362 /* find a symbol and return its associated structure. 's' is the top
1363 of the symbol stack */
1364 static Sym
*sym_find2(Sym
*s
, int v
)
1374 /* structure lookup */
1375 static Sym
*struct_find(int v
)
1378 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1380 return table_ident
[v
]->sym_struct
;
1383 /* find an identifier */
1384 static inline Sym
*sym_find(int v
)
1387 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1389 return table_ident
[v
]->sym_identifier
;
1392 /* push a given symbol on the symbol stack */
1393 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1402 s
= sym_push2(ps
, v
, type
->t
, c
);
1403 s
->type
.ref
= type
->ref
;
1405 /* don't record fields or anonymous symbols */
1407 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1408 /* record symbol in token array */
1409 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1411 ps
= &ts
->sym_struct
;
1413 ps
= &ts
->sym_identifier
;
1420 /* push a global identifier */
1421 static Sym
*global_identifier_push(int v
, int t
, int c
)
1424 s
= sym_push2(&global_stack
, v
, t
, c
);
1425 /* don't record anonymous symbol */
1426 if (v
< SYM_FIRST_ANOM
) {
1427 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1428 /* modify the top most local identifier, so that
1429 sym_identifier will point to 's' when popped */
1431 ps
= &(*ps
)->prev_tok
;
1438 /* pop symbols until top reaches 'b' */
1439 static void sym_pop(Sym
**ptop
, Sym
*b
)
1449 /* remove symbol in token array */
1451 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1452 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1454 ps
= &ts
->sym_struct
;
1456 ps
= &ts
->sym_identifier
;
1467 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1472 fd
= open(filename
, O_RDONLY
);
1475 bf
= tcc_malloc(sizeof(BufferedFile
));
1481 bf
->buf_ptr
= bf
->buffer
;
1482 bf
->buf_end
= bf
->buffer
;
1483 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1484 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1486 bf
->ifndef_macro
= 0;
1487 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1488 // printf("opening '%s'\n", filename);
1492 void tcc_close(BufferedFile
*bf
)
1494 total_lines
+= bf
->line_num
;
1499 /* fill input buffer and return next char */
1500 int tcc_getc_slow(BufferedFile
*bf
)
1503 /* only tries to read if really end of buffer */
1504 if (bf
->buf_ptr
>= bf
->buf_end
) {
1506 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1513 bf
->buf_ptr
= bf
->buffer
;
1514 bf
->buf_end
= bf
->buffer
+ len
;
1515 *bf
->buf_end
= CH_EOB
;
1517 if (bf
->buf_ptr
< bf
->buf_end
) {
1518 return *bf
->buf_ptr
++;
1520 bf
->buf_ptr
= bf
->buf_end
;
1525 /* no need to put that inline */
1526 void handle_eob(void)
1528 TCCState
*s1
= tcc_state
;
1530 /* no need to do anything if not at EOB */
1531 if (file
->buf_ptr
<= file
->buf_end
)
1535 ch
= tcc_getc_slow(file
);
1539 if (return_linefeed
) {
1543 if (s1
->include_stack_ptr
== s1
->include_stack
)
1545 /* add end of include file debug info */
1547 put_stabd(N_EINCL
, 0, 0);
1549 /* pop include stack */
1551 s1
->include_stack_ptr
--;
1552 file
= *s1
->include_stack_ptr
;
1556 /* read next char from current input file and handle end of input buffer */
1557 static inline void inp(void)
1559 ch
= *(file
->buf_ptr
++);
1560 /* end of buffer/file handling */
1565 /* handle '\[\r]\n' */
1566 static void handle_stray(void)
1568 while (ch
== '\\') {
1573 } else if (ch
== '\r') {
1581 error("stray '\\' in program");
1586 /* input with '\[\r]\n' handling. Note that this function cannot
1587 handle other characters after '\', so you cannot call it inside
1588 strings or comments */
1589 static void minp(void)
1597 static void parse_line_comment(void)
1599 /* single line C++ comments */
1600 /* XXX: accept '\\\n' ? */
1602 while (ch
!= '\n' && ch
!= TOK_EOF
)
1606 static void parse_comment(void)
1611 /* fast skip loop */
1612 while (ch
!= '\n' && ch
!= '*' && ch
!= TOK_EOF
)
1614 /* now we can handle all the cases */
1618 } else if (ch
== '*') {
1622 goto end_of_comment
;
1623 } else if (ch
== '\\') {
1628 } else if (ch
== '\r') {
1637 } else if (ch
!= '*') {
1642 error("unexpected end of file in comment");
1651 /* space exlcuding newline */
1652 static inline int is_space(int ch
)
1654 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1657 static inline void skip_spaces(void)
1659 while (is_space(ch
))
1663 /* skip block of text until #else, #elif or #endif. skip also pairs of
1665 void preprocess_skip(void)
1667 int a
, start_of_line
, sep
;
1695 /* XXX: better error message */
1696 if (ch
== TOK_EOF
) {
1697 error("unterminated string");
1698 } else if (ch
== '\n') {
1700 } else if (ch
== '\\') {
1701 /* ignore next char */
1715 } else if (ch
== '/') {
1716 parse_line_comment();
1724 if (start_of_line
) {
1727 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1729 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1731 else if (tok
== TOK_ENDIF
)
1748 /* ParseState handling */
1750 /* XXX: currently, no include file info is stored. Thus, we cannot display
1751 accurate messages if the function or data definition spans multiple
1754 /* save current parse state in 's' */
1755 void save_parse_state(ParseState
*s
)
1757 s
->line_num
= file
->line_num
;
1758 s
->macro_ptr
= macro_ptr
;
1763 /* restore parse state from 's' */
1764 void restore_parse_state(ParseState
*s
)
1766 file
->line_num
= s
->line_num
;
1767 macro_ptr
= s
->macro_ptr
;
1772 /* return the number of additionnal 'ints' necessary to store the
1774 static inline int tok_ext_size(int t
)
1793 return LDOUBLE_SIZE
/ 4;
1799 /* token string handling */
1801 static inline void tok_str_new(TokenString
*s
)
1805 s
->last_line_num
= -1;
1808 static void tok_str_free(int *str
)
1819 if (t
== TOK_STR
|| t
== TOK_LSTR
|| t
== TOK_PPNUM
) {
1820 /* XXX: use a macro to be portable on 64 bit ? */
1821 cstr
= (CString
*)(*p
++);
1825 p
+= tok_ext_size(t
);
1831 static void tok_str_add(TokenString
*s
, int t
)
1837 if ((len
& 63) == 0) {
1838 str
= tcc_realloc(str
, (len
+ 64) * sizeof(int));
1847 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1850 CString
*cstr
, *cstr1
;
1854 if (t
== TOK_STR
|| t
== TOK_LSTR
|| t
== TOK_PPNUM
) {
1855 /* special case: need to duplicate string */
1857 cstr
= tcc_malloc(sizeof(CString
));
1860 cstr
->size_allocated
= size
;
1861 cstr
->data_allocated
= tcc_malloc(size
);
1862 cstr
->data
= cstr
->data_allocated
;
1863 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1865 tok_str_add(s
, cv1
.tab
[0]);
1867 n
= tok_ext_size(t
);
1869 tok_str_add(s
, cv
->tab
[i
]);
1873 /* add the current parse token in token string 's' */
1874 static void tok_str_add_tok(TokenString
*s
)
1878 /* save line number info */
1879 if (file
->line_num
!= s
->last_line_num
) {
1880 s
->last_line_num
= file
->line_num
;
1881 cval
.i
= s
->last_line_num
;
1882 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1884 tok_str_add2(s
, tok
, &tokc
);
1887 /* get a token from an integer array and increment pointer accordingly */
1888 static int tok_get(int **tok_str
, CValue
*cv
)
1894 n
= tok_ext_size(t
);
1901 /* defines handling */
1902 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
1906 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
1907 s
->next
= first_arg
;
1908 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
1911 /* undefined a define symbol. Its name is just set to zero */
1912 static void define_undef(Sym
*s
)
1916 if (v
>= TOK_IDENT
&& v
< tok_ident
)
1917 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
1921 static inline Sym
*define_find(int v
)
1924 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1926 return table_ident
[v
]->sym_define
;
1929 /* free define stack until top reaches 'b' */
1930 static void free_defines(Sym
*b
)
1938 /* do not free args or predefined defines */
1940 tok_str_free((int *)top
->c
);
1942 if (v
>= TOK_IDENT
&& v
< tok_ident
)
1943 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
1951 static Sym
*label_find(int v
)
1954 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1956 return table_ident
[v
]->sym_label
;
1959 static Sym
*label_push(int v
, int flags
)
1962 s
= sym_push2(&label_stack
, v
, 0, 0);
1964 table_ident
[v
- TOK_IDENT
]->sym_label
= s
;
1968 /* eval an expression for #if/#elif */
1969 int expr_preprocess(void)
1975 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1976 next(); /* do macro subst */
1977 if (tok
== TOK_DEFINED
) {
1982 c
= define_find(tok
) != 0;
1987 } else if (tok
>= TOK_IDENT
) {
1988 /* if undefined macro */
1992 tok_str_add_tok(&str
);
1994 tok_str_add(&str
, -1); /* simulate end of file */
1995 tok_str_add(&str
, 0);
1996 /* now evaluate C constant expression */
1997 macro_ptr
= str
.str
;
2001 tok_str_free(str
.str
);
2005 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2006 void tok_print(int *str
)
2012 t
= tok_get(&str
, &cval
);
2015 printf(" %s", get_tok_str(t
, &cval
));
2021 /* parse after #define */
2022 void parse_define(void)
2024 Sym
*s
, *first
, **ps
;
2025 int v
, t
, varg
, is_vaargs
;
2030 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
2031 /* XXX: should check if same macro (ANSI) */
2034 /* '(' must be just after macro definition for MACRO_FUNC */
2039 while (tok
!= ')') {
2043 if (varg
== TOK_DOTS
) {
2044 varg
= TOK___VA_ARGS__
;
2046 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
2050 if (varg
< TOK_IDENT
)
2051 error("badly punctuated parameter list");
2052 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
2063 /* EOF testing necessary for '-D' handling */
2064 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
2065 tok_str_add2(&str
, tok
, &tokc
);
2068 tok_str_add(&str
, 0);
2070 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
2073 define_push(v
, t
, str
.str
, first
);
2076 /* XXX: use a token or a hash table to accelerate matching ? */
2077 static CachedInclude
*search_cached_include(TCCState
*s1
,
2078 int type
, const char *filename
)
2083 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
2084 e
= s1
->cached_includes
[i
];
2085 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2091 static inline void add_cached_include(TCCState
*s1
, int type
,
2092 const char *filename
, int ifndef_macro
)
2096 if (search_cached_include(s1
, type
, filename
))
2099 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2101 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2105 strcpy(e
->filename
, filename
);
2106 e
->ifndef_macro
= ifndef_macro
;
2107 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2112 INCLUDE_STATE_NONE
= 0,
2113 INCLUDE_STATE_SEEK_IFNDEF
,
2116 void preprocess(void)
2118 TCCState
*s1
= tcc_state
;
2119 int size
, i
, c
, n
, line_num
;
2120 enum IncludeState state
;
2121 char buf
[1024], *q
, *p
;
2127 return_linefeed
= 1; /* linefeed will be returned as a
2128 token. EOF is also returned as line feed */
2129 state
= INCLUDE_STATE_NONE
;
2141 s
= define_find(tok
);
2142 /* undefine symbol by putting an invalid name */
2151 } else if (ch
== '\"') {
2156 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2157 if ((q
- buf
) < sizeof(buf
) - 1)
2163 /* eat all spaces and comments after include */
2164 /* XXX: slightly incorrect */
2165 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2169 /* computed #include : either we have only strings or
2170 we have anything enclosed in '<>' */
2173 if (tok
== TOK_STR
) {
2174 while (tok
!= TOK_LINEFEED
) {
2175 if (tok
!= TOK_STR
) {
2177 error("'#include' expects \"FILENAME\" or <FILENAME>");
2179 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2185 while (tok
!= TOK_LINEFEED
) {
2186 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2190 /* check syntax and remove '<>' */
2191 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2192 goto include_syntax
;
2193 memmove(buf
, buf
+ 1, len
- 2);
2194 buf
[len
- 2] = '\0';
2200 e
= search_cached_include(s1
, c
, buf
);
2201 if (e
&& define_find(e
->ifndef_macro
)) {
2202 /* no need to parse the include because the 'ifndef macro'
2205 printf("%s: skipping %s\n", file
->filename
, buf
);
2209 /* first search in current dir if "header.h" */
2211 p
= strrchr(file
->filename
, '/');
2213 size
= p
+ 1 - file
->filename
;
2214 if (size
> sizeof(buf1
) - 1)
2215 size
= sizeof(buf1
) - 1;
2216 memcpy(buf1
, file
->filename
, size
);
2218 pstrcat(buf1
, sizeof(buf1
), buf
);
2219 f
= tcc_open(s1
, buf1
);
2223 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2224 error("#include recursion too deep");
2225 /* now search in all the include paths */
2226 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2227 for(i
= 0; i
< n
; i
++) {
2229 if (i
< s1
->nb_include_paths
)
2230 path
= s1
->include_paths
[i
];
2232 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2233 pstrcpy(buf1
, sizeof(buf1
), path
);
2234 pstrcat(buf1
, sizeof(buf1
), "/");
2235 pstrcat(buf1
, sizeof(buf1
), buf
);
2236 f
= tcc_open(s1
, buf1
);
2240 error("include file '%s' not found", buf
);
2244 printf("%s: including %s\n", file
->filename
, buf1
);
2247 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2248 /* push current file in stack */
2249 /* XXX: fix current line init */
2250 *s1
->include_stack_ptr
++ = file
;
2252 /* add include file debug info */
2254 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2256 /* we check for the construct: #ifndef IDENT \n #define IDENT */
2258 /* get first non space char */
2259 while (is_space(ch
) || ch
== '\n')
2263 state
= INCLUDE_STATE_SEEK_IFNDEF
;
2272 c
= expr_preprocess();
2278 if (tok
< TOK_IDENT
)
2279 error("invalid argument for '#if%sdef'", c
? "n" : "");
2280 if (state
== INCLUDE_STATE_SEEK_IFNDEF
) {
2282 file
->ifndef_macro
= tok
;
2284 state
= INCLUDE_STATE_NONE
;
2286 c
= (define_find(tok
) != 0) ^ c
;
2288 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2289 error("memory full");
2290 *s1
->ifdef_stack_ptr
++ = c
;
2293 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2294 error("#else without matching #if");
2295 if (s1
->ifdef_stack_ptr
[-1] & 2)
2296 error("#else after #else");
2297 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2300 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2301 error("#elif without matching #if");
2302 c
= s1
->ifdef_stack_ptr
[-1];
2304 error("#elif after #else");
2305 /* last #if/#elif expression was true: we skip */
2308 c
= expr_preprocess();
2309 s1
->ifdef_stack_ptr
[-1] = c
;
2314 state
= INCLUDE_STATE_NONE
;
2319 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2320 error("#endif without matching #if");
2321 if (file
->ifndef_macro
&&
2322 s1
->ifdef_stack_ptr
== (file
->ifdef_stack_ptr
+ 1)) {
2323 /* '#ifndef macro \n #define macro' was at the start of
2324 file. Now we check if an '#endif' is exactly at the end
2326 while (tok
!= TOK_LINEFEED
)
2328 /* XXX: should also skip comments, but it is more complicated */
2330 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
2331 file
->ifndef_macro
);
2333 /* if not end of file, we must desactivate the ifndef
2335 file
->ifndef_macro
= 0;
2338 s1
->ifdef_stack_ptr
--;
2342 if (tok
!= TOK_CINT
)
2346 if (tok
!= TOK_LINEFEED
) {
2349 pstrcpy(file
->filename
, sizeof(file
->filename
),
2350 (char *)tokc
.cstr
->data
);
2352 /* NOTE: we do it there to avoid problems with linefeed */
2353 file
->line_num
= line_num
;
2360 while (ch
!= '\n' && ch
!= CH_EOF
) {
2361 if ((q
- buf
) < sizeof(buf
) - 1)
2367 error("#error %s", buf
);
2369 warning("#warning %s", buf
);
2372 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
2373 /* '!' is ignored to allow C scripts. numbers are ignored
2374 to emulate cpp behaviour */
2376 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
2380 /* ignore other preprocess commands or #! for C scripts */
2381 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
)
2384 return_linefeed
= 0;
2387 /* read a number in base b */
2388 static int getn(int b
)
2393 if (ch
>= 'a' && ch
<= 'f')
2395 else if (ch
>= 'A' && ch
<= 'F')
2401 if (t
< 0 || t
>= b
)
2409 /* read a character for string or char constant and eval escape codes */
2410 static int getq(void)
2419 case '0': case '1': case '2': case '3':
2420 case '4': case '5': case '6': case '7':
2421 /* at most three octal digits */
2425 c
= c
* 8 + ch
- '0';
2428 c
= c
* 8 + ch
- '0';
2459 goto invalid_escape
;
2474 goto invalid_escape
;
2479 error("invalid escaped char");
2482 } else if (c
== '\r' && ch
== '\n') {
2489 /* we use 64 bit numbers */
2492 /* bn = (bn << shift) | or_val */
2493 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2497 for(i
=0;i
<BN_SIZE
;i
++) {
2499 bn
[i
] = (v
<< shift
) | or_val
;
2500 or_val
= v
>> (32 - shift
);
2504 void bn_zero(unsigned int *bn
)
2507 for(i
=0;i
<BN_SIZE
;i
++) {
2512 /* parse number in null terminated string 'p' and return it in the
2514 void parse_number(const char *p
)
2516 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
2518 unsigned int bn
[BN_SIZE
];
2529 goto float_frac_parse
;
2530 } else if (t
== '0') {
2531 if (ch
== 'x' || ch
== 'X') {
2535 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2541 /* parse all digits. cannot check octal numbers at this stage
2542 because of floating point constants */
2544 if (ch
>= 'a' && ch
<= 'f')
2546 else if (ch
>= 'A' && ch
<= 'F')
2554 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2556 error("number too long");
2562 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2563 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2565 /* NOTE: strtox should support that for hexa numbers, but
2566 non ISOC99 libcs do not support it, so we prefer to do
2568 /* hexadecimal or binary floats */
2569 /* XXX: handle overflows */
2581 } else if (t
>= 'a') {
2583 } else if (t
>= 'A') {
2588 bn_lshift(bn
, shift
, t
);
2595 if (t
>= 'a' && t
<= 'f') {
2597 } else if (t
>= 'A' && t
<= 'F') {
2599 } else if (t
>= '0' && t
<= '9') {
2605 error("invalid digit");
2606 bn_lshift(bn
, shift
, t
);
2611 if (ch
!= 'p' && ch
!= 'P')
2618 } else if (ch
== '-') {
2622 if (ch
< '0' || ch
> '9')
2623 expect("exponent digits");
2624 while (ch
>= '0' && ch
<= '9') {
2625 exp_val
= exp_val
* 10 + ch
- '0';
2628 exp_val
= exp_val
* s
;
2630 /* now we can generate the number */
2631 /* XXX: should patch directly float number */
2632 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
2633 d
= ldexp(d
, exp_val
- frac_bits
);
2638 /* float : should handle overflow */
2640 } else if (t
== 'L') {
2643 /* XXX: not large enough */
2644 tokc
.ld
= (long double)d
;
2650 /* decimal floats */
2652 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2657 while (ch
>= '0' && ch
<= '9') {
2658 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2664 if (ch
== 'e' || ch
== 'E') {
2665 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2669 if (ch
== '-' || ch
== '+') {
2670 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2675 if (ch
< '0' || ch
> '9')
2676 expect("exponent digits");
2677 while (ch
>= '0' && ch
<= '9') {
2678 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2690 tokc
.f
= strtof(token_buf
, NULL
);
2691 } else if (t
== 'L') {
2694 tokc
.ld
= strtold(token_buf
, NULL
);
2697 tokc
.d
= strtod(token_buf
, NULL
);
2701 unsigned long long n
, n1
;
2704 /* integer number */
2707 if (b
== 10 && *q
== '0') {
2714 /* no need for checks except for base 10 / 8 errors */
2717 } else if (t
>= 'a') {
2719 } else if (t
>= 'A') {
2724 error("invalid digit");
2728 /* detect overflow */
2729 /* XXX: this test is not reliable */
2731 error("integer constant overflow");
2734 /* XXX: not exactly ANSI compliant */
2735 if ((n
& 0xffffffff00000000LL
) != 0) {
2740 } else if (n
> 0x7fffffff) {
2751 error("three 'l's in integer constant");
2754 if (tok
== TOK_CINT
)
2756 else if (tok
== TOK_CUINT
)
2760 } else if (t
== 'U') {
2762 error("two 'u's in integer constant");
2764 if (tok
== TOK_CINT
)
2766 else if (tok
== TOK_CLLONG
)
2773 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2780 /* return next token without macro substitution */
2781 static inline void next_nomacro1(void)
2783 int b
, t
, start_of_line
;
2804 if (return_linefeed
) {
2805 /* XXX: should eat token ? */
2816 if (start_of_line
) {
2822 tok
= TOK_TWOSHARPS
;
2829 case 'a': case 'b': case 'c': case 'd':
2830 case 'e': case 'f': case 'g': case 'h':
2831 case 'i': case 'j': case 'k': case 'l':
2832 case 'm': case 'n': case 'o': case 'p':
2833 case 'q': case 'r': case 's': case 't':
2834 case 'u': case 'v': case 'w': case 'x':
2836 case 'A': case 'B': case 'C': case 'D':
2837 case 'E': case 'F': case 'G': case 'H':
2838 case 'I': case 'J': case 'K':
2839 case 'M': case 'N': case 'O': case 'P':
2840 case 'Q': case 'R': case 'S': case 'T':
2841 case 'U': case 'V': case 'W': case 'X':
2848 while (isid(ch
) || isnum(ch
)) {
2849 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2850 error("ident too long");
2855 ts
= tok_alloc(token_buf
, q
- token_buf
);
2872 case '0': case '1': case '2': case '3':
2873 case '4': case '5': case '6': case '7':
2876 cstr_reset(&tokcstr
);
2877 /* after the first digit, accept digits, alpha, '.' or sign if
2878 prefixed by 'eEpP' */
2882 cstr_ccat(&tokcstr
, ch
);
2884 if (!(isnum(ch
) || isid(ch
) || ch
== '.' ||
2885 ((ch
== '+' || ch
== '-') &&
2886 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
2889 /* We add a trailing '\0' to ease parsing */
2890 cstr_ccat(&tokcstr
, '\0');
2891 tokc
.cstr
= &tokcstr
;
2895 /* special dot handling because it can also start a number */
2898 cstr_reset(&tokcstr
);
2899 cstr_ccat(&tokcstr
, '.');
2917 /* this cast is needed if >= 128 */
2918 if (tok
== TOK_CCHAR
)
2922 error("unterminated character constant");
2929 cstr_reset(&tokcstr
);
2930 while (ch
!= '\"') {
2933 error("unterminated string");
2935 cstr_ccat(&tokcstr
, b
);
2937 cstr_wccat(&tokcstr
, b
);
2940 cstr_ccat(&tokcstr
, '\0');
2942 cstr_wccat(&tokcstr
, '\0');
2943 tokc
.cstr
= &tokcstr
;
2952 } else if (ch
== '<') {
2970 } else if (ch
== '>') {
3007 } else if (ch
== '=') {
3019 } else if (ch
== '=') {
3031 } else if (ch
== '=') {
3043 } else if (ch
== '=') {
3046 } else if (ch
== '>') {
3079 /* comments or operator */
3085 } else if (ch
== '/') {
3086 parse_line_comment();
3088 } else if (ch
== '=') {
3115 error("unrecognized character \\x%02x", ch
);
3118 #if defined(PARSE_DEBUG)
3119 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3123 /* return next token without macro substitution. Can read input from
3125 static void next_nomacro(void)
3131 tok
= tok_get(¯o_ptr
, &tokc
);
3132 if (tok
== TOK_LINENUM
) {
3133 file
->line_num
= tokc
.i
;
3142 /* substitute args in macro_str and return allocated string */
3143 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
3145 int *st
, last_tok
, t
, notfirst
;
3154 t
= tok_get(¯o_str
, &cval
);
3159 t
= tok_get(¯o_str
, &cval
);
3162 s
= sym_find2(args
, t
);
3169 cstr_ccat(&cstr
, ' ');
3170 t
= tok_get(&st
, &cval
);
3171 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
3174 cstr_ccat(&cstr
, '\0');
3176 printf("stringize: %s\n", (char *)cstr
.data
);
3180 tok_str_add2(&str
, TOK_STR
, &cval
);
3183 tok_str_add2(&str
, t
, &cval
);
3185 } else if (t
>= TOK_IDENT
) {
3186 s
= sym_find2(args
, t
);
3189 /* if '##' is present before or after, no arg substitution */
3190 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
3191 /* special case for var arg macros : ## eats the
3192 ',' if empty VA_ARGS variable. */
3193 /* XXX: test of the ',' is not 100%
3194 reliable. should fix it to avoid security
3196 if (gnu_ext
&& s
->type
.t
&&
3197 last_tok
== TOK_TWOSHARPS
&&
3198 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
3200 /* suppress ',' '##' */
3203 /* suppress '##' and add variable */
3211 t1
= tok_get(&st
, &cval
);
3214 tok_str_add2(&str
, t1
, &cval
);
3218 macro_subst(&str
, nested_list
, st
);
3221 tok_str_add(&str
, t
);
3224 tok_str_add2(&str
, t
, &cval
);
3228 tok_str_add(&str
, 0);
3232 /* handle the '##' operator */
3233 static int *macro_twosharps(void)
3238 const char *p1
, *p2
;
3240 TokenString macro_str1
;
3244 tok_str_new(¯o_str1
);
3250 while (*macro_ptr
== TOK_TWOSHARPS
) {
3252 macro_ptr1
= macro_ptr
;
3255 t
= tok_get(¯o_ptr
, &cval
);
3257 /* We concatenate the two tokens if we have an
3258 identifier or a preprocessing number */
3260 p1
= get_tok_str(tok
, &tokc
);
3261 cstr_cat(&cstr
, p1
);
3262 p2
= get_tok_str(t
, &cval
);
3263 cstr_cat(&cstr
, p2
);
3264 cstr_ccat(&cstr
, '\0');
3266 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
3267 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
3268 if (tok
== TOK_PPNUM
) {
3269 /* if number, then create a number token */
3270 /* NOTE: no need to allocate because
3271 tok_str_add2() does it */
3274 /* if identifier, we must do a test to
3275 validate we have a correct identifier */
3276 if (t
== TOK_PPNUM
) {
3286 if (!isnum(c
) && !isid(c
))
3290 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
3291 tok
= ts
->tok
; /* modify current token */
3294 const char *str
= cstr
.data
;
3295 const unsigned char *q
;
3297 /* we look for a valid token */
3298 /* XXX: do more extensive checks */
3299 if (!strcmp(str
, ">>=")) {
3301 } else if (!strcmp(str
, "<<=")) {
3303 } else if (strlen(str
) == 2) {
3304 /* search in two bytes table */
3309 if (q
[0] == str
[0] && q
[1] == str
[1])
3316 /* NOTE: because get_tok_str use a static buffer,
3319 p1
= get_tok_str(tok
, &tokc
);
3320 cstr_cat(&cstr
, p1
);
3321 cstr_ccat(&cstr
, '\0');
3322 p2
= get_tok_str(t
, &cval
);
3323 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
3324 /* cannot merge tokens: just add them separately */
3325 tok_str_add2(¯o_str1
, tok
, &tokc
);
3326 /* XXX: free associated memory ? */
3333 tok_str_add2(¯o_str1
, tok
, &tokc
);
3336 tok_str_add(¯o_str1
, 0);
3337 return macro_str1
.str
;
3341 /* do macro substitution of current token with macro 's' and add
3342 result to (tok_str,tok_len). 'nested_list' is the list of all
3343 macros we got inside to avoid recursing. Return non zero if no
3344 substitution needs to be done */
3345 static int macro_subst_tok(TokenString
*tok_str
,
3346 Sym
**nested_list
, Sym
*s
)
3348 Sym
*args
, *sa
, *sa1
;
3349 int mstr_allocated
, parlevel
, *mstr
, t
;
3355 /* if symbol is a macro, prepare substitution */
3356 /* if nested substitution, do nothing */
3357 if (sym_find2(*nested_list
, tok
))
3360 /* special macros */
3361 if (tok
== TOK___LINE__
) {
3362 cval
.i
= file
->line_num
;
3363 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
3364 } else if (tok
== TOK___FILE__
) {
3365 cstrval
= file
->filename
;
3367 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3368 } else if (tok
== TOK___DATE__
) {
3369 cstrval
= "Jan 1 2002";
3371 } else if (tok
== TOK___TIME__
) {
3372 cstrval
= "00:00:00";
3375 cstr_cat(&cstr
, cstrval
);
3376 cstr_ccat(&cstr
, '\0');
3378 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3383 if (s
->type
.t
== MACRO_FUNC
) {
3384 /* NOTE: we do not use next_nomacro to avoid eating the
3385 next token. XXX: find better solution */
3389 while (is_space(ch
) || ch
== '\n')
3393 if (t
!= '(') /* no macro subst */
3396 /* argument macro */
3401 /* NOTE: empty args are allowed, except if no args */
3403 /* handle '()' case */
3404 if (!args
&& tok
== ')')
3407 error("macro '%s' used with too many args",
3408 get_tok_str(s
->v
, 0));
3411 /* NOTE: non zero sa->t indicates VA_ARGS */
3412 while ((parlevel
> 0 ||
3414 (tok
!= ',' || sa
->type
.t
))) &&
3418 else if (tok
== ')')
3420 tok_str_add2(&str
, tok
, &tokc
);
3423 tok_str_add(&str
, 0);
3424 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
3427 /* special case for gcc var args: add an empty
3428 var arg argument if it is omitted */
3429 if (sa
&& sa
->type
.t
&& gnu_ext
)
3439 error("macro '%s' used with too few args",
3440 get_tok_str(s
->v
, 0));
3443 /* now subst each arg */
3444 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3449 tok_str_free((int *)sa
->c
);
3455 sym_push2(nested_list
, s
->v
, 0, 0);
3456 macro_subst(tok_str
, nested_list
, mstr
);
3457 /* pop nested defined symbol */
3459 *nested_list
= sa1
->prev
;
3467 /* do macro substitution of macro_str and add result to
3468 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3469 inside to avoid recursing. */
3470 static void macro_subst(TokenString
*tok_str
,
3471 Sym
**nested_list
, int *macro_str
)
3474 int *saved_macro_ptr
;
3477 saved_macro_ptr
= macro_ptr
;
3478 macro_ptr
= macro_str
;
3479 /* first scan for '##' operator handling */
3480 macro_str1
= macro_twosharps();
3481 macro_ptr
= macro_str1
;
3487 s
= define_find(tok
);
3489 if (macro_subst_tok(tok_str
, nested_list
, s
) != 0)
3493 tok_str_add2(tok_str
, tok
, &tokc
);
3496 macro_ptr
= saved_macro_ptr
;
3497 tok_str_free(macro_str1
);
3500 /* return next token with macro substitution */
3501 static void next(void)
3503 Sym
*nested_list
, *s
;
3506 /* special 'ungettok' case for label parsing */
3515 /* if not reading from macro substituted string, then try
3516 to substitute macros */
3517 if (tok
>= TOK_IDENT
) {
3518 s
= define_find(tok
);
3520 /* we have a macro: we try to substitute */
3523 if (macro_subst_tok(&str
, &nested_list
, s
) == 0) {
3524 /* substitution done, NOTE: maybe empty */
3525 tok_str_add(&str
, 0);
3526 macro_ptr
= str
.str
;
3527 macro_ptr_allocated
= str
.str
;
3534 /* end of macro string: free it */
3535 tok_str_free(macro_ptr_allocated
);
3541 /* convert preprocessor tokens into C tokens */
3542 if (tok
== TOK_PPNUM
) {
3543 parse_number((char *)tokc
.cstr
->data
);
3548 void swap(int *p
, int *q
)
3556 void vsetc(CType
*type
, int r
, CValue
*vc
)
3560 if (vtop
>= vstack
+ VSTACK_SIZE
)
3561 error("memory full");
3562 /* cannot let cpu flags if other instruction are generated. Also
3563 avoid leaving VT_JMP anywhere except on the top of the stack
3564 because it would complicate the code generator. */
3565 if (vtop
>= vstack
) {
3566 v
= vtop
->r
& VT_VALMASK
;
3567 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
3573 vtop
->r2
= VT_CONST
;
3577 /* push integer constant */
3582 vsetc(&int_type
, VT_CONST
, &cval
);
3585 /* Return a static symbol pointing to a section */
3586 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
3587 unsigned long offset
, unsigned long size
)
3593 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
3594 sym
->type
.ref
= type
->ref
;
3595 sym
->r
= VT_CONST
| VT_SYM
;
3596 put_extern_sym(sym
, sec
, offset
, size
);
3600 /* push a reference to a section offset by adding a dummy symbol */
3601 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
3606 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
3607 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
3610 /* define a new external reference to a symbol 'v' of type 'u' */
3611 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
3617 /* push forward reference */
3618 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
3619 s
->type
.ref
= type
->ref
;
3620 s
->r
= r
| VT_CONST
| VT_SYM
;
3625 /* define a new external reference to a symbol 'v' of type 'u' */
3626 static Sym
*external_sym(int v
, CType
*type
, int r
)
3632 /* push forward reference */
3633 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
3634 s
->type
.t
|= VT_EXTERN
;
3639 /* push a reference to global symbol v */
3640 static void vpush_global_sym(CType
*type
, int v
)
3645 sym
= external_global_sym(v
, type
, 0);
3647 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
3651 void vset(CType
*type
, int r
, int v
)
3656 vsetc(type
, r
, &cval
);
3659 void vseti(int r
, int v
)
3675 void vpushv(SValue
*v
)
3677 if (vtop
>= vstack
+ VSTACK_SIZE
)
3678 error("memory full");
3688 /* save r to the memory stack, and mark it as being free */
3689 void save_reg(int r
)
3691 int l
, saved
, size
, align
;
3695 /* modify all stack values */
3698 for(p
=vstack
;p
<=vtop
;p
++) {
3699 if ((p
->r
& VT_VALMASK
) == r
||
3700 (p
->r2
& VT_VALMASK
) == r
) {
3701 /* must save value on stack if not already done */
3703 /* NOTE: must reload 'r' because r might be equal to r2 */
3704 r
= p
->r
& VT_VALMASK
;
3705 /* store register in the stack */
3707 if ((p
->r
& VT_LVAL
) ||
3708 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
3710 size
= type_size(type
, &align
);
3711 loc
= (loc
- size
) & -align
;
3712 sv
.type
.t
= type
->t
;
3713 sv
.r
= VT_LOCAL
| VT_LVAL
;
3716 #ifdef TCC_TARGET_I386
3717 /* x86 specific: need to pop fp register ST0 if saved */
3719 o(0xd9dd); /* fstp %st(1) */
3722 /* special long long case */
3723 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
3730 /* mark that stack entry as being saved on the stack */
3731 if (p
->r
& VT_LVAL
) {
3732 /* also suppress the bounded flag because the
3733 relocation address of the function was stored in
3735 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
3737 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
3745 /* find a free register of class 'rc'. If none, save one register */
3751 /* find a free register */
3752 for(r
=0;r
<NB_REGS
;r
++) {
3753 if (reg_classes
[r
] & rc
) {
3754 for(p
=vstack
;p
<=vtop
;p
++) {
3755 if ((p
->r
& VT_VALMASK
) == r
||
3756 (p
->r2
& VT_VALMASK
) == r
)
3764 /* no register left : free the first one on the stack (VERY
3765 IMPORTANT to start from the bottom to ensure that we don't
3766 spill registers used in gen_opi()) */
3767 for(p
=vstack
;p
<=vtop
;p
++) {
3768 r
= p
->r
& VT_VALMASK
;
3769 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
3771 /* also look at second register (if long long) */
3772 r
= p
->r2
& VT_VALMASK
;
3773 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
3779 /* Should never comes here */
3783 /* save registers up to (vtop - n) stack entry */
3784 void save_regs(int n
)
3789 for(p
= vstack
;p
<= p1
; p
++) {
3790 r
= p
->r
& VT_VALMASK
;
3797 /* move register 's' to 'r', and flush previous value of r to memory
3799 void move_reg(int r
, int s
)
3812 /* get address of vtop (vtop MUST BE an lvalue) */
3815 vtop
->r
&= ~VT_LVAL
;
3816 /* tricky: if saved lvalue, then we can go back to lvalue */
3817 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
3818 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
3821 #ifdef CONFIG_TCC_BCHECK
3822 /* generate lvalue bound code */
3828 vtop
->r
&= ~VT_MUSTBOUND
;
3829 /* if lvalue, then use checking code before dereferencing */
3830 if (vtop
->r
& VT_LVAL
) {
3831 /* if not VT_BOUNDED value, then make one */
3832 if (!(vtop
->r
& VT_BOUNDED
)) {
3833 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
3834 /* must save type because we must set it to int to get pointer */
3836 vtop
->type
.t
= VT_INT
;
3839 gen_bounded_ptr_add();
3840 vtop
->r
|= lval_type
;
3843 /* then check for dereferencing */
3844 gen_bounded_ptr_deref();
3849 /* store vtop a register belonging to class 'rc'. lvalues are
3850 converted to values. Cannot be used if cannot be converted to
3851 register value (such as structures). */
3854 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
3855 unsigned long long ll
;
3857 /* NOTE: get_reg can modify vstack[] */
3858 if (vtop
->type
.t
& VT_BITFIELD
) {
3859 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
3860 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3861 /* remove bit field info to avoid loops */
3862 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3863 /* generate shifts */
3864 vpushi(32 - (bit_pos
+ bit_size
));
3866 vpushi(32 - bit_size
);
3867 /* NOTE: transformed to SHR if unsigned */
3871 if (is_float(vtop
->type
.t
) &&
3872 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3875 unsigned long offset
;
3877 /* XXX: unify with initializers handling ? */
3878 /* CPUs usually cannot use float constants, so we store them
3879 generically in data segment */
3880 size
= type_size(&vtop
->type
, &align
);
3881 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
3882 data_section
->data_offset
= offset
;
3883 /* XXX: not portable yet */
3884 ptr
= section_ptr_add(data_section
, size
);
3887 ptr
[i
] = vtop
->c
.tab
[i
];
3888 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
3889 vtop
->r
|= VT_LVAL
| VT_SYM
;
3893 #ifdef CONFIG_TCC_BCHECK
3894 if (vtop
->r
& VT_MUSTBOUND
)
3898 r
= vtop
->r
& VT_VALMASK
;
3899 /* need to reload if:
3901 - lvalue (need to dereference pointer)
3902 - already a register, but not in the right class */
3903 if (r
>= VT_CONST
||
3904 (vtop
->r
& VT_LVAL
) ||
3905 !(reg_classes
[r
] & rc
) ||
3906 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
3907 !(reg_classes
[vtop
->r2
] & rc
))) {
3909 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
3910 /* two register type load : expand to two words
3912 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3915 vtop
->c
.ui
= ll
; /* first word */
3917 vtop
->r
= r
; /* save register value */
3918 vpushi(ll
>> 32); /* second word */
3919 } else if (r
>= VT_CONST
||
3920 (vtop
->r
& VT_LVAL
)) {
3921 /* load from memory */
3924 vtop
[-1].r
= r
; /* save register value */
3925 /* increment pointer to get second word */
3926 vtop
->type
.t
= VT_INT
;
3932 /* move registers */
3935 vtop
[-1].r
= r
; /* save register value */
3936 vtop
->r
= vtop
[-1].r2
;
3938 /* allocate second register */
3945 /* write second register */
3947 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
3949 /* lvalue of scalar type : need to use lvalue type
3950 because of possible cast */
3953 /* compute memory access type */
3954 if (vtop
->r
& VT_LVAL_BYTE
)
3956 else if (vtop
->r
& VT_LVAL_SHORT
)
3958 if (vtop
->r
& VT_LVAL_UNSIGNED
)
3962 /* restore wanted type */
3965 /* one register type load */
3974 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3975 void gv2(int rc1
, int rc2
)
3979 /* generate more generic register first. But VT_JMP or VT_CMP
3980 values must be generated first in all cases to avoid possible
3982 v
= vtop
[0].r
& VT_VALMASK
;
3983 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
3988 /* test if reload is needed for first register */
3989 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
3999 /* test if reload is needed for first register */
4000 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
4006 /* expand long long on stack in two int registers */
4011 u
= vtop
->type
.t
& VT_UNSIGNED
;
4014 vtop
[0].r
= vtop
[-1].r2
;
4015 vtop
[0].r2
= VT_CONST
;
4016 vtop
[-1].r2
= VT_CONST
;
4017 vtop
[0].type
.t
= VT_INT
| u
;
4018 vtop
[-1].type
.t
= VT_INT
| u
;
4021 /* build a long long from two ints */
4024 gv2(RC_INT
, RC_INT
);
4025 vtop
[-1].r2
= vtop
[0].r
;
4026 vtop
[-1].type
.t
= t
;
4030 /* rotate n first stack elements to the bottom */
4037 for(i
=-n
+1;i
!=0;i
++)
4038 vtop
[i
] = vtop
[i
+1];
4042 /* pop stack value */
4046 v
= vtop
->r
& VT_VALMASK
;
4047 #ifdef TCC_TARGET_I386
4048 /* for x86, we need to pop the FP stack */
4049 if (v
== REG_ST0
&& !nocode_wanted
) {
4050 o(0xd9dd); /* fstp %st(1) */
4053 if (v
== VT_JMP
|| v
== VT_JMPI
) {
4054 /* need to put correct jump if && or || without test */
4060 /* convert stack entry to register and duplicate its value in another
4068 if ((t
& VT_BTYPE
) == VT_LLONG
) {
4075 /* stack: H L L1 H1 */
4083 /* duplicate value */
4094 load(r1
, &sv
); /* move r to r1 */
4096 /* duplicates value */
4101 /* generate CPU independent (unsigned) long long operations */
4102 void gen_opl(int op
)
4104 int t
, a
, b
, op1
, c
, i
;
4112 func
= TOK___divdi3
;
4115 func
= TOK___udivdi3
;
4118 func
= TOK___moddi3
;
4121 func
= TOK___umoddi3
;
4123 /* call generic long long function */
4124 gfunc_start(&gf
, FUNC_CDECL
);
4127 vpush_global_sym(&func_old_type
, func
);
4131 vtop
->r2
= REG_LRET
;
4144 /* stack: L1 H1 L2 H2 */
4149 vtop
[-2] = vtop
[-3];
4152 /* stack: H1 H2 L1 L2 */
4158 /* stack: H1 H2 L1 L2 ML MH */
4161 /* stack: ML MH H1 H2 L1 L2 */
4165 /* stack: ML MH H1 L2 H2 L1 */
4170 /* stack: ML MH M1 M2 */
4173 } else if (op
== '+' || op
== '-') {
4174 /* XXX: add non carry method too (for MIPS or alpha) */
4180 /* stack: H1 H2 (L1 op L2) */
4183 gen_op(op1
+ 1); /* TOK_xxxC2 */
4186 /* stack: H1 H2 (L1 op L2) */
4189 /* stack: (L1 op L2) H1 H2 */
4191 /* stack: (L1 op L2) (H1 op H2) */
4199 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4200 t
= vtop
[-1].type
.t
;
4204 /* stack: L H shift */
4206 /* constant: simpler */
4207 /* NOTE: all comments are for SHL. the other cases are
4208 done by swaping words */
4219 if (op
!= TOK_SAR
) {
4252 /* XXX: should provide a faster fallback on x86 ? */
4255 func
= TOK___sardi3
;
4258 func
= TOK___shrdi3
;
4261 func
= TOK___shldi3
;
4267 /* compare operations */
4273 /* stack: L1 H1 L2 H2 */
4275 vtop
[-1] = vtop
[-2];
4277 /* stack: L1 L2 H1 H2 */
4280 /* when values are equal, we need to compare low words. since
4281 the jump is inverted, we invert the test too. */
4284 else if (op1
== TOK_GT
)
4286 else if (op1
== TOK_ULT
)
4288 else if (op1
== TOK_UGT
)
4293 if (op1
!= TOK_NE
) {
4297 /* generate non equal test */
4298 /* XXX: NOT PORTABLE yet */
4302 #ifdef TCC_TARGET_I386
4303 b
= psym(0x850f, 0);
4305 error("not implemented");
4318 /* handle integer constant optimizations and various machine
4320 void gen_opic(int op
)
4327 /* currently, we cannot do computations with forward symbols */
4328 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4329 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4333 case '+': v1
->c
.i
+= fc
; break;
4334 case '-': v1
->c
.i
-= fc
; break;
4335 case '&': v1
->c
.i
&= fc
; break;
4336 case '^': v1
->c
.i
^= fc
; break;
4337 case '|': v1
->c
.i
|= fc
; break;
4338 case '*': v1
->c
.i
*= fc
; break;
4345 /* if division by zero, generate explicit division */
4348 error("division by zero in constant");
4352 default: v1
->c
.i
/= fc
; break;
4353 case '%': v1
->c
.i
%= fc
; break;
4354 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
4355 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
4358 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
4359 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
4360 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
4362 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
4363 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
4364 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
4365 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
4366 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
4367 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
4368 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
4369 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
4370 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
4371 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
4373 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
4374 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
4380 /* if commutative ops, put c2 as constant */
4381 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
4382 op
== '|' || op
== '*')) {
4387 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
4390 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
4391 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
4397 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
4398 /* try to use shifts instead of muls or divs */
4399 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
4408 else if (op
== TOK_PDIV
)
4414 } else if (c2
&& (op
== '+' || op
== '-') &&
4415 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
4416 (VT_CONST
| VT_SYM
)) {
4417 /* symbol + constant case */
4424 if (!nocode_wanted
) {
4425 /* call low level op generator */
4434 /* generate a floating point operation with constant propagation */
4435 void gen_opif(int op
)
4443 /* currently, we cannot do computations with forward symbols */
4444 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4445 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4447 if (v1
->type
.t
== VT_FLOAT
) {
4450 } else if (v1
->type
.t
== VT_DOUBLE
) {
4458 /* NOTE: we only do constant propagation if finite number (not
4459 NaN or infinity) (ANSI spec) */
4460 if (!ieee_finite(f1
) || !ieee_finite(f2
))
4464 case '+': f1
+= f2
; break;
4465 case '-': f1
-= f2
; break;
4466 case '*': f1
*= f2
; break;
4470 error("division by zero in constant");
4475 /* XXX: also handles tests ? */
4479 /* XXX: overflow test ? */
4480 if (v1
->type
.t
== VT_FLOAT
) {
4482 } else if (v1
->type
.t
== VT_DOUBLE
) {
4490 if (!nocode_wanted
) {
4498 static int pointed_size(CType
*type
)
4501 return type_size(pointed_type(type
), &align
);
4505 void check_pointer_types(SValue
*p1
, SValue
*p2
)
4507 char buf1
[256], buf2
[256];
4511 if (!is_compatible_types(t1
, t2
)) {
4512 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
4513 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
4514 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
4519 /* generic gen_op: handles types problems */
4522 int u
, t1
, t2
, bt1
, bt2
, t
;
4525 t1
= vtop
[-1].type
.t
;
4526 t2
= vtop
[0].type
.t
;
4527 bt1
= t1
& VT_BTYPE
;
4528 bt2
= t2
& VT_BTYPE
;
4530 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
4531 /* at least one operand is a pointer */
4532 /* relationnal op: must be both pointers */
4533 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4534 // check_pointer_types(vtop, vtop - 1);
4535 /* pointers are handled are unsigned */
4536 t
= VT_INT
| VT_UNSIGNED
;
4539 /* if both pointers, then it must be the '-' op */
4540 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
4542 error("cannot use pointers here");
4543 // check_pointer_types(vtop - 1, vtop);
4544 /* XXX: check that types are compatible */
4545 u
= pointed_size(&vtop
[-1].type
);
4547 /* set to integer type */
4548 vtop
->type
.t
= VT_INT
;
4552 /* exactly one pointer : must be '+' or '-'. */
4553 if (op
!= '-' && op
!= '+')
4554 error("cannot use pointers here");
4555 /* Put pointer as first operand */
4556 if (bt2
== VT_PTR
) {
4560 type1
= vtop
[-1].type
;
4561 /* XXX: cast to int ? (long long case) */
4562 vpushi(pointed_size(&vtop
[-1].type
));
4564 #ifdef CONFIG_TCC_BCHECK
4565 /* if evaluating constant expression, no code should be
4566 generated, so no bound check */
4567 if (do_bounds_check
&& !const_wanted
) {
4568 /* if bounded pointers, we generate a special code to
4575 gen_bounded_ptr_add();
4581 /* put again type if gen_opic() swaped operands */
4584 } else if (is_float(bt1
) || is_float(bt2
)) {
4585 /* compute bigger type and do implicit casts */
4586 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
4588 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
4593 /* floats can only be used for a few operations */
4594 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
4595 (op
< TOK_ULT
|| op
> TOK_GT
))
4596 error("invalid operands for binary operation");
4598 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
4599 /* cast to biggest op */
4601 /* convert to unsigned if it does not fit in a long long */
4602 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4603 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4607 /* integer operations */
4609 /* convert to unsigned if it does not fit in an integer */
4610 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4611 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4614 /* XXX: currently, some unsigned operations are explicit, so
4615 we modify them here */
4616 if (t
& VT_UNSIGNED
) {
4623 else if (op
== TOK_LT
)
4625 else if (op
== TOK_GT
)
4627 else if (op
== TOK_LE
)
4629 else if (op
== TOK_GE
)
4636 /* special case for shifts and long long: we keep the shift as
4638 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
4643 else if ((t
& VT_BTYPE
) == VT_LLONG
)
4647 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4648 /* relationnal op: the result is an int */
4649 vtop
->type
.t
= VT_INT
;
4656 /* generic itof for unsigned long long case */
4657 void gen_cvt_itof1(int t
)
4661 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
4662 (VT_LLONG
| VT_UNSIGNED
)) {
4664 gfunc_start(&gf
, FUNC_CDECL
);
4667 vpush_global_sym(&func_old_type
, TOK___ulltof
);
4668 else if (t
== VT_DOUBLE
)
4669 vpush_global_sym(&func_old_type
, TOK___ulltod
);
4671 vpush_global_sym(&func_old_type
, TOK___ulltold
);
4680 /* generic ftoi for unsigned long long case */
4681 void gen_cvt_ftoi1(int t
)
4686 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
4687 /* not handled natively */
4688 gfunc_start(&gf
, FUNC_CDECL
);
4689 st
= vtop
->type
.t
& VT_BTYPE
;
4692 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
4693 else if (st
== VT_DOUBLE
)
4694 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
4696 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
4700 vtop
->r2
= REG_LRET
;
4706 /* force char or short cast */
4707 void force_charshort_cast(int t
)
4711 /* XXX: add optimization if lvalue : just change type and offset */
4716 if (t
& VT_UNSIGNED
) {
4717 vpushi((1 << bits
) - 1);
4728 /* cast 'vtop' to 'type' */
4729 static void gen_cast(CType
*type
)
4731 int sbt
, dbt
, sf
, df
, c
;
4733 /* special delayed cast for char/short */
4734 /* XXX: in some cases (multiple cascaded casts), it may still
4736 if (vtop
->r
& VT_MUSTCAST
) {
4737 vtop
->r
&= ~VT_MUSTCAST
;
4738 force_charshort_cast(vtop
->type
.t
);
4741 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
4742 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
4744 if (sbt
!= dbt
&& !nocode_wanted
) {
4747 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4749 /* convert from fp to fp */
4751 /* constant case: we can do it now */
4752 /* XXX: in ISOC, cannot do it if error in convert */
4753 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
4754 vtop
->c
.f
= (float)vtop
->c
.d
;
4755 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
4756 vtop
->c
.f
= (float)vtop
->c
.ld
;
4757 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
4758 vtop
->c
.d
= (double)vtop
->c
.f
;
4759 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
4760 vtop
->c
.d
= (double)vtop
->c
.ld
;
4761 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
4762 vtop
->c
.ld
= (long double)vtop
->c
.f
;
4763 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
4764 vtop
->c
.ld
= (long double)vtop
->c
.d
;
4766 /* non constant case: generate code */
4770 /* convert int to fp */
4773 case VT_LLONG
| VT_UNSIGNED
:
4775 /* XXX: add const cases for long long */
4777 case VT_INT
| VT_UNSIGNED
:
4779 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
4780 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
4781 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
4786 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
4787 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
4788 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
4797 /* convert fp to int */
4798 /* we handle char/short/etc... with generic code */
4799 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
4800 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
4805 case VT_LLONG
| VT_UNSIGNED
:
4807 /* XXX: add const cases for long long */
4809 case VT_INT
| VT_UNSIGNED
:
4811 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4812 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4813 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4819 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4820 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4821 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4829 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
4830 /* additionnal cast for char/short/bool... */
4834 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
4835 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
4836 /* scalar to long long */
4838 if (sbt
== (VT_INT
| VT_UNSIGNED
))
4839 vtop
->c
.ll
= vtop
->c
.ui
;
4841 vtop
->c
.ll
= vtop
->c
.i
;
4843 /* machine independant conversion */
4845 /* generate high word */
4846 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
4854 /* patch second register */
4855 vtop
[-1].r2
= vtop
->r
;
4859 } else if (dbt
== VT_BOOL
) {
4860 /* scalar to bool */
4863 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
4864 (dbt
& VT_BTYPE
) == VT_SHORT
) {
4865 force_charshort_cast(dbt
);
4866 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
4868 if (sbt
== VT_LLONG
) {
4869 /* from long long: just take low order word */
4873 /* if lvalue and single word type, nothing to do because
4874 the lvalue already contains the real type size (see
4875 VT_LVAL_xxx constants) */
4881 /* return type size. Put alignment at 'a' */
4882 int type_size(CType
*type
, int *a
)
4887 bt
= type
->t
& VT_BTYPE
;
4888 if (bt
== VT_STRUCT
) {
4891 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
4893 } else if (bt
== VT_PTR
) {
4894 if (type
->t
& VT_ARRAY
) {
4896 return type_size(&s
->type
, a
) * s
->c
;
4901 } else if (bt
== VT_LDOUBLE
) {
4903 return LDOUBLE_SIZE
;
4904 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
4907 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
4910 } else if (bt
== VT_SHORT
) {
4914 /* char, void, function, _Bool */
4920 /* return the pointed type of t */
4921 static inline CType
*pointed_type(CType
*type
)
4923 return &type
->ref
->type
;
4926 /* modify type so that its it is a pointer to type. */
4927 static void mk_pointer(CType
*type
)
4930 s
= sym_push(SYM_FIELD
, type
, 0, -1);
4931 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
4935 static int is_compatible_types(CType
*type1
, CType
*type2
)
4938 int bt1
, bt2
, t1
, t2
;
4940 t1
= type1
->t
& VT_TYPE
;
4941 t2
= type2
->t
& VT_TYPE
;
4942 bt1
= t1
& VT_BTYPE
;
4943 bt2
= t2
& VT_BTYPE
;
4944 if (bt1
== VT_PTR
) {
4945 type1
= pointed_type(type1
);
4946 /* if function, then convert implicitely to function pointer */
4947 if (bt2
!= VT_FUNC
) {
4950 type2
= pointed_type(type2
);
4952 /* void matches everything */
4953 /* XXX: not fully compliant */
4954 if ((type1
->t
& VT_TYPE
) == VT_VOID
|| (type2
->t
& VT_TYPE
) == VT_VOID
)
4956 return is_compatible_types(type1
, type2
);
4957 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4959 } else if (bt1
== VT_FUNC
) {
4964 if (!is_compatible_types(&s1
->type
, &s2
->type
))
4966 /* XXX: not complete */
4967 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
4971 while (s1
!= NULL
) {
4974 if (!is_compatible_types(&s1
->type
, &s2
->type
))
4983 /* XXX: not complete */
4988 /* print a type. If 'varstr' is not NULL, then the variable is also
4989 printed in the type */
4991 /* XXX: add array and function pointers */
4992 void type_to_str(char *buf
, int buf_size
,
4993 CType
*type
, const char *varstr
)
5000 t
= type
->t
& VT_TYPE
;
5003 if (t
& VT_UNSIGNED
)
5004 pstrcat(buf
, buf_size
, "unsigned ");
5034 tstr
= "long double";
5036 pstrcat(buf
, buf_size
, tstr
);
5040 if (bt
== VT_STRUCT
)
5044 pstrcat(buf
, buf_size
, tstr
);
5046 if (v
>= SYM_FIRST_ANOM
)
5047 pstrcat(buf
, buf_size
, "<anonymous>");
5049 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
5053 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
5054 pstrcat(buf
, buf_size
, "(");
5056 while (sa
!= NULL
) {
5057 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
5058 pstrcat(buf
, buf_size
, buf1
);
5061 pstrcat(buf
, buf_size
, ", ");
5063 pstrcat(buf
, buf_size
, ")");
5067 pstrcpy(buf1
, sizeof(buf1
), "*");
5069 pstrcat(buf1
, sizeof(buf1
), varstr
);
5070 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
5074 pstrcat(buf
, buf_size
, " ");
5075 pstrcat(buf
, buf_size
, varstr
);
5080 /* verify type compatibility to store vtop in 'dt' type, and generate
5082 void gen_assign_cast(CType
*dt
)
5085 char buf1
[256], buf2
[256];
5087 st
= &vtop
->type
; /* source type */
5088 if ((dt
->t
& VT_BTYPE
) == VT_PTR
) {
5089 /* special cases for pointers */
5090 /* a function is implicitely a function pointer */
5091 if ((st
->t
& VT_BTYPE
) == VT_FUNC
) {
5092 if (!is_compatible_types(pointed_type(dt
), st
))
5097 /* '0' can also be a pointer */
5098 if ((st
->t
& VT_BTYPE
) == VT_INT
&&
5099 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
5103 if (!is_compatible_types(dt
, st
)) {
5105 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
5106 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
5107 error("cannot cast '%s' to '%s'", buf1
, buf2
);
5113 /* store vtop in lvalue pushed on stack */
5116 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
5119 ft
= vtop
[-1].type
.t
;
5120 sbt
= vtop
->type
.t
& VT_BTYPE
;
5121 dbt
= ft
& VT_BTYPE
;
5122 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
5123 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
5124 /* optimize char/short casts */
5125 delayed_cast
= VT_MUSTCAST
;
5126 vtop
->type
.t
= ft
& VT_TYPE
;
5129 gen_assign_cast(&vtop
[-1].type
);
5132 if (sbt
== VT_STRUCT
) {
5133 /* if structure, only generate pointer */
5134 /* structure assignment : generate memcpy */
5135 /* XXX: optimize if small size */
5136 if (!nocode_wanted
) {
5138 gfunc_start(&gf
, FUNC_CDECL
);
5140 size
= type_size(&vtop
->type
, &align
);
5144 vtop
->type
.t
= VT_INT
;
5149 vtop
->type
.t
= VT_INT
;
5154 vpush_global_sym(&func_old_type
, TOK_memcpy
);
5160 /* leave source on stack */
5161 } else if (ft
& VT_BITFIELD
) {
5162 /* bitfield store handling */
5163 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
5164 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
5165 /* remove bit field info to avoid loops */
5166 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
5168 /* duplicate destination */
5170 vtop
[-1] = vtop
[-2];
5172 /* mask and shift source */
5173 vpushi((1 << bit_size
) - 1);
5177 /* load destination, mask and or with source */
5179 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
5185 #ifdef CONFIG_TCC_BCHECK
5186 /* bound check case */
5187 if (vtop
[-1].r
& VT_MUSTBOUND
) {
5193 if (!nocode_wanted
) {
5197 r
= gv(rc
); /* generate value */
5198 /* if lvalue was saved on stack, must read it */
5199 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
5201 t
= get_reg(RC_INT
);
5203 sv
.r
= VT_LOCAL
| VT_LVAL
;
5204 sv
.c
.ul
= vtop
[-1].c
.ul
;
5206 vtop
[-1].r
= t
| VT_LVAL
;
5209 /* two word case handling : store second register at word + 4 */
5210 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
5212 /* convert to int to increment easily */
5213 vtop
->type
.t
= VT_INT
;
5219 /* XXX: it works because r2 is spilled last ! */
5220 store(vtop
->r2
, vtop
- 1);
5224 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5225 vtop
->r
|= delayed_cast
;
5229 /* post defines POST/PRE add. c is the token ++ or -- */
5230 void inc(int post
, int c
)
5233 vdup(); /* save lvalue */
5235 gv_dup(); /* duplicate value */
5240 vpushi(c
- TOK_MID
);
5242 vstore(); /* store value */
5244 vpop(); /* if post op, return saved value */
5247 /* Parse GNUC __attribute__ extension. Currently, the following
5248 extensions are recognized:
5249 - aligned(n) : set data/function alignment.
5250 - section(x) : generate data/code in this section.
5251 - unused : currently ignored, but may be used someday.
5253 void parse_attribute(AttributeDef
*ad
)
5260 while (tok
!= ')') {
5261 if (tok
< TOK_IDENT
)
5262 expect("attribute name");
5267 case TOK___SECTION__
:
5270 expect("section name");
5271 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
5276 case TOK___ALIGNED__
:
5279 if (n
<= 0 || (n
& (n
- 1)) != 0)
5280 error("alignment must be a positive power of two");
5285 case TOK___UNUSED__
:
5286 /* currently, no need to handle it because tcc does not
5287 track unused objects */
5290 case TOK___NORETURN__
:
5291 /* currently, no need to handle it because tcc does not
5292 track unused objects */
5297 ad
->func_call
= FUNC_CDECL
;
5301 case TOK___STDCALL__
:
5302 ad
->func_call
= FUNC_STDCALL
;
5305 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
5306 /* skip parameters */
5307 /* XXX: skip parenthesis too */
5310 while (tok
!= ')' && tok
!= -1)
5324 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5325 static void struct_decl(CType
*type
, int u
)
5327 int a
, v
, size
, align
, maxalign
, c
, offset
;
5328 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
5333 a
= tok
; /* save decl type */
5338 /* struct already defined ? return it */
5339 /* XXX: check consistency */
5343 error("invalid type");
5350 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, 0);
5351 /* put struct/union/enum name in type */
5359 error("struct/union/enum already defined");
5360 /* cannot be empty */
5367 if (a
== TOK_ENUM
) {
5374 /* enum symbols have static storage */
5375 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
5376 ss
->type
.t
|= VT_STATIC
;
5381 parse_btype(&btype
, &ad
);
5387 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
);
5388 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
5389 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
5390 error("invalid type for '%s'",
5391 get_tok_str(v
, NULL
));
5395 bit_size
= expr_const();
5396 /* XXX: handle v = 0 case for messages */
5398 error("negative width in bit-field '%s'",
5399 get_tok_str(v
, NULL
));
5400 if (v
&& bit_size
== 0)
5401 error("zero width for bit-field '%s'",
5402 get_tok_str(v
, NULL
));
5404 size
= type_size(&type1
, &align
);
5406 if (bit_size
>= 0) {
5407 bt
= type1
.t
& VT_BTYPE
;
5411 error("bitfields must have scalar type");
5413 if (bit_size
> bsize
) {
5414 error("width of '%s' exceeds its type",
5415 get_tok_str(v
, NULL
));
5416 } else if (bit_size
== bsize
) {
5417 /* no need for bit fields */
5419 } else if (bit_size
== 0) {
5420 /* XXX: what to do if only padding in a
5422 /* zero size: means to pad */
5426 /* we do not have enough room ? */
5427 if ((bit_pos
+ bit_size
) > bsize
)
5430 /* XXX: handle LSB first */
5431 type1
.t
|= VT_BITFIELD
|
5432 (bit_pos
<< VT_STRUCT_SHIFT
) |
5433 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
5434 bit_pos
+= bit_size
;
5440 /* add new memory data only if starting
5442 if (lbit_pos
== 0) {
5443 if (a
== TOK_STRUCT
) {
5444 c
= (c
+ align
- 1) & -align
;
5452 if (align
> maxalign
)
5456 printf("add field %s offset=%d",
5457 get_tok_str(v
, NULL
), offset
);
5458 if (type1
.t
& VT_BITFIELD
) {
5459 printf(" pos=%d size=%d",
5460 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
5461 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
5465 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
5469 if (tok
== ';' || tok
== -1)
5479 /* size for struct/union, dummy for enum */
5480 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
5484 /* return 0 if no type declaration. otherwise, return the basic type
5487 static int parse_btype(CType
*type
, AttributeDef
*ad
)
5489 int t
, u
, type_found
;
5493 memset(ad
, 0, sizeof(AttributeDef
));
5504 if ((t
& VT_BTYPE
) != 0)
5505 error("too many basic types");
5519 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
5520 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5521 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
5522 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
5536 if ((t
& VT_BTYPE
) == VT_LONG
) {
5537 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5544 struct_decl(&type1
, VT_ENUM
);
5547 type
->ref
= type1
.ref
;
5551 struct_decl(&type1
, VT_STRUCT
);
5554 /* type modifiers */
5559 case TOK___SIGNED__
:
5562 case TOK___INLINE__
:
5584 /* GNUC attribute */
5585 case TOK___ATTRIBUTE__
:
5586 parse_attribute(ad
);
5591 parse_expr_type(&type1
);
5595 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
5597 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
5598 type
->ref
= s
->type
.ref
;
5605 /* long is never used as type */
5606 if ((t
& VT_BTYPE
) == VT_LONG
)
5607 t
= (t
& ~VT_BTYPE
) | VT_INT
;
5612 static void post_type(CType
*type
, AttributeDef
*ad
)
5615 Sym
**plast
, *s
, *first
;
5620 /* function declaration */
5625 while (tok
!= ')') {
5626 /* read param name and compute offset */
5627 if (l
!= FUNC_OLD
) {
5628 if (!parse_btype(&pt
, &ad1
)) {
5630 error("invalid type");
5637 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5639 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
5640 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
5641 error("parameter declared as void");
5648 /* array must be transformed to pointer according to ANSI C */
5650 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
5655 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5662 /* if no parameters, then old type prototype */
5666 t1
= type
->t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5667 type
->t
&= ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5668 post_type(type
, ad
);
5669 /* we push a anonymous symbol which will contain the function prototype */
5670 s
= sym_push(SYM_FIELD
, type
, ad
->func_call
, l
);
5672 type
->t
= t1
| VT_FUNC
;
5674 } else if (tok
== '[') {
5675 /* array definition */
5681 error("invalid array size");
5684 /* parse next post type */
5685 t1
= type
->t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5686 type
->t
&= ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5687 post_type(type
, ad
);
5689 /* we push a anonymous symbol which will contain the array
5691 s
= sym_push(SYM_FIELD
, type
, 0, n
);
5692 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
5697 /* Parse a type declaration (except basic type), and return the type
5698 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5699 expected. 'type' should contain the basic type. 'ad' is the
5700 attribute definition of the basic type. It can be modified by
5703 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
5706 CType type1
, *type2
;
5708 while (tok
== '*') {
5710 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
5715 /* recursive type */
5716 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5717 type1
.t
= 0; /* XXX: same as int */
5720 /* XXX: this is not correct to modify 'ad' at this point, but
5721 the syntax is not clear */
5722 if (tok
== TOK___ATTRIBUTE__
)
5723 parse_attribute(ad
);
5724 type_decl(&type1
, ad
, v
, td
);
5727 /* type identifier */
5728 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
5732 if (!(td
& TYPE_ABSTRACT
))
5733 expect("identifier");
5737 post_type(type
, ad
);
5738 if (tok
== TOK___ATTRIBUTE__
)
5739 parse_attribute(ad
);
5742 /* append type at the end of type1 */
5755 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5756 static int lvalue_type(int t
)
5763 else if (bt
== VT_SHORT
)
5767 if (t
& VT_UNSIGNED
)
5768 r
|= VT_LVAL_UNSIGNED
;
5772 /* indirection with full error checking and bound check */
5773 static void indir(void)
5775 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
5777 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
5779 vtop
->type
= *pointed_type(&vtop
->type
);
5780 /* an array is never an lvalue */
5781 if (!(vtop
->type
.t
& VT_ARRAY
)) {
5782 vtop
->r
|= lvalue_type(vtop
->type
.t
);
5783 /* if bound checking, the referenced pointer must be checked */
5784 if (do_bounds_check
)
5785 vtop
->r
|= VT_MUSTBOUND
;
5789 /* pass a parameter to a function and do type checking and casting */
5790 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
5795 func_type
= func
->c
;
5796 if (func_type
== FUNC_OLD
||
5797 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5798 /* default casting : only need to convert float to double */
5799 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
5803 } else if (arg
== NULL
) {
5804 error("too many arguments to function");
5806 gen_assign_cast(&arg
->type
);
5808 if (!nocode_wanted
) {
5815 /* parse an expression of the form '(type)' or '(expr)' and return its
5817 static void parse_expr_type(CType
*type
)
5823 if (parse_btype(type
, &ad
)) {
5824 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
5831 static void vpush_tokc(int t
)
5835 vsetc(&type
, VT_CONST
, &tokc
);
5838 static void unary(void)
5840 int n
, t
, align
, size
, r
;
5846 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
5849 } else if (tok
== TOK_CUINT
) {
5850 vpush_tokc(VT_INT
| VT_UNSIGNED
);
5852 } else if (tok
== TOK_CLLONG
) {
5853 vpush_tokc(VT_LLONG
);
5855 } else if (tok
== TOK_CULLONG
) {
5856 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
5858 } else if (tok
== TOK_CFLOAT
) {
5859 vpush_tokc(VT_FLOAT
);
5861 } else if (tok
== TOK_CDOUBLE
) {
5862 vpush_tokc(VT_DOUBLE
);
5864 } else if (tok
== TOK_CLDOUBLE
) {
5865 vpush_tokc(VT_LDOUBLE
);
5867 } else if (tok
== TOK___FUNC__
|| (tok
== TOK___FUNCTION__
&& gnu_ext
)) {
5870 /* special function name identifier */
5872 len
= strlen(funcname
) + 1;
5873 /* generate char[len] type */
5878 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
5879 ptr
= section_ptr_add(data_section
, len
);
5880 memcpy(ptr
, funcname
, len
);
5882 } else if (tok
== TOK_LSTR
) {
5885 } else if (tok
== TOK_STR
) {
5886 /* string parsing */
5892 memset(&ad
, 0, sizeof(AttributeDef
));
5893 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
5899 if (parse_btype(&type
, &ad
)) {
5900 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
5902 /* check ISOC99 compound literal */
5904 /* data is allocated locally by default */
5909 /* all except arrays are lvalues */
5910 if (!(type
.t
& VT_ARRAY
))
5911 r
|= lvalue_type(type
.t
);
5912 memset(&ad
, 0, sizeof(AttributeDef
));
5913 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
5922 } else if (t
== '*') {
5925 } else if (t
== '&') {
5927 /* functions names must be treated as function pointers,
5928 except for unary '&' and sizeof. Since we consider that
5929 functions are not lvalues, we only have to handle it
5930 there and in function calls. */
5931 /* arrays can also be used although they are not lvalues */
5932 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
5933 !(vtop
->type
.t
& VT_ARRAY
))
5935 mk_pointer(&vtop
->type
);
5937 } else if (t
== '!') {
5939 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
5940 vtop
->c
.i
= !vtop
->c
.i
;
5941 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
5942 vtop
->c
.i
= vtop
->c
.i
^ 1;
5944 vseti(VT_JMP
, gtst(1, 0));
5945 } else if (t
== '~') {
5949 } else if (t
== '+') {
5950 /* in order to force cast, we add zero */
5952 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
5953 error("pointer not accepted for unary plus");
5956 } else if (t
== TOK_SIZEOF
|| t
== TOK_ALIGNOF
) {
5958 parse_expr_type(&type
);
5962 size
= type_size(&type
, &align
);
5963 if (t
== TOK_SIZEOF
)
5967 } else if (t
== TOK_INC
|| t
== TOK_DEC
) {
5970 } else if (t
== '-') {
5974 } else if (t
== TOK_LAND
&& gnu_ext
) {
5975 /* allow to take the address of a label */
5976 if (tok
< TOK_UIDENT
)
5977 expect("label identifier");
5978 s
= label_find(tok
);
5980 s
= label_push(tok
, LABEL_FORWARD
);
5983 s
->type
.t
= VT_VOID
;
5984 mk_pointer(&s
->type
);
5985 s
->type
.t
|= VT_STATIC
;
5987 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
5992 expect("identifier");
5996 error("'%s' undeclared", get_tok_str(t
, NULL
));
5997 /* for simple function calls, we tolerate undeclared
5998 external reference to int() function */
5999 s
= external_global_sym(t
, &func_old_type
, 0);
6001 vset(&s
->type
, s
->r
, s
->c
);
6002 /* if forward reference, we must point to s */
6003 if (vtop
->r
& VT_SYM
) {
6010 /* post operations */
6012 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
6015 } else if (tok
== '.' || tok
== TOK_ARROW
) {
6017 if (tok
== TOK_ARROW
)
6022 /* expect pointer on structure */
6023 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
6024 expect("struct or union");
6028 while ((s
= s
->next
) != NULL
) {
6033 error("field not found");
6034 /* add field offset to pointer */
6035 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
6038 /* change type to field type, and set to lvalue */
6039 vtop
->type
= s
->type
;
6040 /* an array is never an lvalue */
6041 if (!(vtop
->type
.t
& VT_ARRAY
)) {
6042 vtop
->r
|= lvalue_type(vtop
->type
.t
);
6043 /* if bound checking, the referenced pointer must be checked */
6044 if (do_bounds_check
)
6045 vtop
->r
|= VT_MUSTBOUND
;
6048 } else if (tok
== '[') {
6054 } else if (tok
== '(') {
6059 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
6060 /* pointer test (no array accepted) */
6061 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
6062 vtop
->type
= *pointed_type(&vtop
->type
);
6063 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
6067 expect("function pointer");
6070 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
6072 /* get return type */
6074 if (!nocode_wanted
) {
6075 save_regs(0); /* save used temporary registers */
6076 gfunc_start(&gf
, s
->r
);
6079 sa
= s
->next
; /* first parameter */
6080 #ifdef INVERT_FUNC_PARAMS
6084 ParseState saved_parse_state
;
6087 /* read each argument and store it on a stack */
6093 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
6097 else if (tok
== ')')
6099 tok_str_add_tok(&str
);
6102 tok_str_add(&str
, -1); /* end of file added */
6103 tok_str_add(&str
, 0);
6104 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
6105 s1
->next
= sa
; /* add reference to argument */
6114 /* now generate code in reverse order by reading the stack */
6115 save_parse_state(&saved_parse_state
);
6117 macro_ptr
= (int *)args
->c
;
6121 expect("',' or ')'");
6122 gfunc_param_typed(&gf
, s
, args
->next
);
6124 tok_str_free((int *)args
->c
);
6128 restore_parse_state(&saved_parse_state
);
6131 /* compute first implicit argument if a structure is returned */
6132 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
6133 /* get some space for the returned structure */
6134 size
= type_size(&s
->type
, &align
);
6135 loc
= (loc
- size
) & -align
;
6137 ret
.r
= VT_LOCAL
| VT_LVAL
;
6138 /* pass it as 'int' to avoid structure arg passing
6140 vseti(VT_LOCAL
, loc
);
6149 /* return in register */
6150 if (is_float(ret
.type
.t
)) {
6153 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
6159 #ifndef INVERT_FUNC_PARAMS
6163 gfunc_param_typed(&gf
, s
, sa
);
6173 error("too few arguments to function");
6180 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
6188 static void uneq(void)
6194 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
6195 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
6196 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
6211 static void sum(int l
)
6219 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
6220 (l
== 1 && (tok
== '+' || tok
== '-')) ||
6221 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
6222 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
6223 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
6224 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
6225 (l
== 5 && tok
== '&') ||
6226 (l
== 6 && tok
== '^') ||
6227 (l
== 7 && tok
== '|') ||
6228 (l
== 8 && tok
== TOK_LAND
) ||
6229 (l
== 9 && tok
== TOK_LOR
)) {
6238 /* only used if non constant */
6239 static void eand(void)
6246 if (tok
!= TOK_LAND
) {
6259 static void eor(void)
6266 if (tok
!= TOK_LOR
) {
6279 /* XXX: better constant handling */
6280 static void expr_eq(void)
6282 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
6284 CType type
, type1
, type2
;
6305 save_regs(1); /* we need to save all registers here except
6306 at the top because it is a branch point */
6310 sv
= *vtop
; /* save value to handle it later */
6311 vtop
--; /* no vpop so that FP stack is not flushed */
6320 bt1
= t1
& VT_BTYPE
;
6322 bt2
= t2
& VT_BTYPE
;
6323 /* cast operands to correct type according to ISOC rules */
6324 if (is_float(bt1
) || is_float(bt2
)) {
6325 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
6326 type
.t
= VT_LDOUBLE
;
6327 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
6332 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
6333 /* cast to biggest op */
6335 /* convert to unsigned if it does not fit in a long long */
6336 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
6337 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
6338 type
.t
|= VT_UNSIGNED
;
6339 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
6340 /* XXX: test pointer compatibility */
6342 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
6343 /* XXX: test structure compatibility */
6345 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
6346 /* NOTE: as an extension, we accept void on only one side */
6349 /* integer operations */
6351 /* convert to unsigned if it does not fit in an integer */
6352 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
6353 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
6354 type
.t
|= VT_UNSIGNED
;
6357 /* now we convert second operand */
6360 if (is_float(type
.t
)) {
6362 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
6363 /* for long longs, we use fixed registers to avoid having
6364 to handle a complicated move */
6368 /* this is horrible, but we must also convert first
6372 /* put again first value and cast it */
6383 static void gexpr(void)
6394 /* parse an expression and return its type without any side effect. */
6395 static void expr_type(CType
*type
)
6407 /* parse a unary expression and return its type without any side
6409 static void unary_type(CType
*type
)
6421 /* parse a constant expression and return value in vtop. */
6422 static void expr_const1(void)
6431 /* parse an integer constant and return its value. */
6432 static int expr_const(void)
6436 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
6437 expect("constant expression");
6443 /* return the label token if current token is a label, otherwise
6445 static int is_label(void)
6450 /* fast test first */
6451 if (tok
< TOK_UIDENT
)
6453 /* no need to save tokc since we expect an identifier */
6461 /* XXX: may not work in all cases (macros ?) */
6470 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
6475 /* generate line number info */
6477 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
6478 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
6480 last_line_num
= file
->line_num
;
6483 if (tok
== TOK_IF
) {
6490 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6492 if (c
== TOK_ELSE
) {
6496 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6497 gsym(d
); /* patch else jmp */
6500 } else if (tok
== TOK_WHILE
) {
6508 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6512 } else if (tok
== '{') {
6516 while (tok
!= '}') {
6519 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6521 /* pop locally defined symbols */
6522 sym_pop(&local_stack
, s
);
6524 } else if (tok
== TOK_RETURN
) {
6528 gen_assign_cast(&func_vt
);
6529 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
6531 /* if returning structure, must copy it to implicit
6532 first pointer arg location */
6535 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
6538 /* copy structure value to pointer */
6540 } else if (is_float(func_vt
.t
)) {
6545 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6548 rsym
= gjmp(rsym
); /* jmp */
6549 } else if (tok
== TOK_BREAK
) {
6552 error("cannot break");
6553 *bsym
= gjmp(*bsym
);
6556 } else if (tok
== TOK_CONTINUE
) {
6559 error("cannot continue");
6560 *csym
= gjmp(*csym
);
6563 } else if (tok
== TOK_FOR
) {
6590 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6595 if (tok
== TOK_DO
) {
6600 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6611 if (tok
== TOK_SWITCH
) {
6615 /* XXX: other types than integer */
6616 case_reg
= gv(RC_INT
);
6620 b
= gjmp(0); /* jump to first case */
6622 block(&a
, csym
, &b
, &c
, case_reg
);
6623 /* if no default, jmp after switch */
6631 if (tok
== TOK_CASE
) {
6638 if (gnu_ext
&& tok
== TOK_DOTS
) {
6642 warning("empty case range");
6644 /* since a case is like a label, we must skip it with a jmp */
6651 *case_sym
= gtst(1, 0);
6654 *case_sym
= gtst(1, 0);
6658 *case_sym
= gtst(1, *case_sym
);
6662 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6664 if (tok
== TOK_DEFAULT
) {
6670 error("too many 'default'");
6672 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6674 if (tok
== TOK_GOTO
) {
6676 if (tok
== '*' && gnu_ext
) {
6680 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
6683 } else if (tok
>= TOK_UIDENT
) {
6684 s
= label_find(tok
);
6685 /* put forward definition if needed */
6687 s
= label_push(tok
, LABEL_FORWARD
);
6689 /* label already defined */
6690 if (s
->r
& LABEL_FORWARD
)
6691 s
->next
= (void *)gjmp((long)s
->next
);
6693 gjmp_addr((long)s
->next
);
6696 expect("label identifier");
6705 if (!(s
->r
& LABEL_FORWARD
))
6706 error("multiple defined label");
6707 gsym((long)s
->next
);
6709 s
= label_push(b
, 0);
6711 s
->next
= (void *)ind
;
6713 /* we accept this, but it is a mistake */
6715 warning("deprecated use of label at end of compound statement");
6717 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6719 /* expression case */
6729 /* t is the array or struct type. c is the array or struct
6730 address. cur_index/cur_field is the pointer to the current
6731 value. 'size_only' is true if only size info is needed (only used
6733 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
6734 int *cur_index
, Sym
**cur_field
,
6738 int notfirst
, index
, align
, l
;
6742 if (gnu_ext
&& (l
= is_label()) != 0)
6745 while (tok
== '[' || tok
== '.') {
6747 if (!(type
->t
& VT_ARRAY
))
6748 expect("array type");
6751 index
= expr_const();
6752 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
6753 expect("invalid index");
6757 type
= pointed_type(type
);
6758 c
+= index
* type_size(type
, &align
);
6764 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
6765 expect("struct/union type");
6778 /* XXX: suppress this mess by using explicit storage field */
6780 type1
.t
|= (type
->t
& ~VT_TYPE
);
6794 if (type
->t
& VT_ARRAY
) {
6796 type
= pointed_type(type
);
6797 c
+= index
* type_size(type
, &align
);
6801 error("too many field init");
6802 /* XXX: suppress this mess by using explicit storage field */
6804 type1
.t
|= (type
->t
& ~VT_TYPE
);
6809 decl_initializer(type
, sec
, c
, 0, size_only
);
6813 #define EXPR_CONST 1
6816 /* store a value or an expression directly in global data or in local array */
6817 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
6818 int v
, int expr_type
)
6820 int saved_global_expr
, bt
;
6828 /* compound literals must be allocated globally in this case */
6829 saved_global_expr
= global_expr
;
6832 global_expr
= saved_global_expr
;
6833 /* NOTE: symbols are accepted */
6834 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
6835 error("initializer element is not constant");
6843 /* XXX: not portable */
6844 /* XXX: generate error if incorrect relocation */
6845 gen_assign_cast(type
);
6846 bt
= type
->t
& VT_BTYPE
;
6847 ptr
= sec
->data
+ c
;
6848 if ((vtop
->r
& VT_SYM
) &&
6854 error("initializer element is not computable at load time");
6857 *(char *)ptr
= vtop
->c
.i
;
6860 *(short *)ptr
= vtop
->c
.i
;
6863 *(double *)ptr
= vtop
->c
.d
;
6866 *(long double *)ptr
= vtop
->c
.ld
;
6869 *(long long *)ptr
= vtop
->c
.ll
;
6872 if (vtop
->r
& VT_SYM
) {
6873 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
6875 *(int *)ptr
= vtop
->c
.i
;
6880 vset(type
, VT_LOCAL
, c
);
6887 /* put zeros for variable based init */
6888 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
6893 /* nothing to do because globals are already set to zero */
6895 gfunc_start(&gf
, FUNC_CDECL
);
6902 vpush_global_sym(&func_old_type
, TOK_memset
);
6907 /* 't' contains the type and storage info. 'c' is the offset of the
6908 object in section 'sec'. If 'sec' is NULL, it means stack based
6909 allocation. 'first' is true if array '{' must be read (multi
6910 dimension implicit array init handling). 'size_only' is true if
6911 size only evaluation is wanted (only for arrays). */
6912 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
6913 int first
, int size_only
)
6915 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
6916 int size1
, align1
, expr_type
;
6920 if (type
->t
& VT_ARRAY
) {
6924 t1
= pointed_type(type
);
6925 size1
= type_size(t1
, &align1
);
6928 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
6934 /* only parse strings here if correct type (otherwise: handle
6935 them as ((w)char *) expressions */
6936 if ((tok
== TOK_LSTR
&&
6937 (t1
->t
& VT_BTYPE
) == VT_INT
) ||
6939 (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
6940 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6945 /* compute maximum number of chars wanted */
6947 cstr_len
= cstr
->size
;
6949 cstr_len
= cstr
->size
/ sizeof(int);
6952 if (n
>= 0 && nb
> (n
- array_length
))
6953 nb
= n
- array_length
;
6956 warning("initializer-string for array is too long");
6957 /* in order to go faster for common case (char
6958 string in global variable, we handle it
6960 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
6961 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
6965 ch
= ((unsigned char *)cstr
->data
)[i
];
6967 ch
= ((int *)cstr
->data
)[i
];
6968 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
6976 /* only add trailing zero if enough storage (no
6977 warning in this case since it is standard) */
6978 if (n
< 0 || array_length
< n
) {
6980 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
6986 while (tok
!= '}') {
6987 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
6988 if (n
>= 0 && index
>= n
)
6989 error("index too large");
6990 /* must put zero in holes (note that doing it that way
6991 ensures that it even works with designators) */
6992 if (!size_only
&& array_length
< index
) {
6993 init_putz(t1
, sec
, c
+ array_length
* size1
,
6994 (index
- array_length
) * size1
);
6997 if (index
> array_length
)
6998 array_length
= index
;
6999 /* special test for multi dimensional arrays (may not
7000 be strictly correct if designators are used at the
7002 if (index
>= n
&& no_oblock
)
7011 /* put zeros at the end */
7012 if (!size_only
&& n
>= 0 && array_length
< n
) {
7013 init_putz(t1
, sec
, c
+ array_length
* size1
,
7014 (n
- array_length
) * size1
);
7016 /* patch type size if needed */
7018 s
->c
= array_length
;
7019 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
7020 /* XXX: union needs only one init */
7027 while (tok
!= '}') {
7028 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
7029 /* fill with zero between fields */
7031 if (!size_only
&& array_length
< index
) {
7032 init_putz(type
, sec
, c
+ array_length
,
7033 index
- array_length
);
7035 index
= index
+ type_size(&f
->type
, &align1
);
7036 if (index
> array_length
)
7037 array_length
= index
;
7043 /* put zeros at the end */
7044 if (!size_only
&& array_length
< n
) {
7045 init_putz(type
, sec
, c
+ array_length
,
7049 } else if (tok
== '{') {
7051 decl_initializer(type
, sec
, c
, first
, size_only
);
7053 } else if (size_only
) {
7054 /* just skip expression */
7056 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
7060 else if (tok
== ')')
7065 /* currently, we always use constant expression for globals
7066 (may change for scripting case) */
7067 expr_type
= EXPR_CONST
;
7069 expr_type
= EXPR_ANY
;
7070 init_putv(type
, sec
, c
, 0, expr_type
);
7074 /* parse an initializer for type 't' if 'has_init' is non zero, and
7075 allocate space in local or global data space ('r' is either
7076 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
7077 variable 'v' of scope 'scope' is declared before initializers are
7078 parsed. If 'v' is zero, then a reference to the new object is put
7079 in the value stack. If 'has_init' is 2, a special parsing is done
7080 to handle string constants. */
7081 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
7082 int has_init
, int v
, int scope
)
7084 int size
, align
, addr
, data_offset
;
7086 ParseState saved_parse_state
;
7087 TokenString init_str
;
7090 size
= type_size(type
, &align
);
7091 /* If unknown size, we must evaluate it before
7092 evaluating initializers because
7093 initializers can generate global data too
7094 (e.g. string pointers or ISOC99 compound
7095 literals). It also simplifies local
7096 initializers handling */
7097 tok_str_new(&init_str
);
7100 error("unknown type size");
7101 /* get all init string */
7102 if (has_init
== 2) {
7103 /* only get strings */
7104 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
7105 tok_str_add_tok(&init_str
);
7110 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
7112 error("unexpected end of file in initializer");
7113 tok_str_add_tok(&init_str
);
7116 else if (tok
== '}') {
7124 tok_str_add(&init_str
, -1);
7125 tok_str_add(&init_str
, 0);
7128 save_parse_state(&saved_parse_state
);
7130 macro_ptr
= init_str
.str
;
7132 decl_initializer(type
, NULL
, 0, 1, 1);
7133 /* prepare second initializer parsing */
7134 macro_ptr
= init_str
.str
;
7137 /* if still unknown size, error */
7138 size
= type_size(type
, &align
);
7140 error("unknown type size");
7142 /* take into account specified alignment if bigger */
7143 if (ad
->aligned
> align
)
7144 align
= ad
->aligned
;
7145 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
7147 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
7149 #ifdef TCC_TARGET_IL
7150 /* XXX: ugly patch to allocate local variables for IL, just
7155 loc
= (loc
- size
) & -align
;
7158 /* handles bounds */
7159 /* XXX: currently, since we do only one pass, we cannot track
7160 '&' operators, so we add only arrays */
7161 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
7162 unsigned long *bounds_ptr
;
7163 /* add padding between regions */
7165 /* then add local bound info */
7166 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
7167 bounds_ptr
[0] = addr
;
7168 bounds_ptr
[1] = size
;
7171 /* compute section */
7179 data_offset
= sec
->data_offset
;
7180 data_offset
= (data_offset
+ align
- 1) & -align
;
7182 /* very important to increment global pointer at this time
7183 because initializers themselves can create new initializers */
7184 data_offset
+= size
;
7185 /* add padding if bound check */
7186 if (do_bounds_check
)
7188 sec
->data_offset
= data_offset
;
7189 /* allocate section space to put the data */
7190 if (sec
->sh_type
!= SHT_NOBITS
&&
7191 data_offset
> sec
->data_allocated
)
7192 section_realloc(sec
, data_offset
);
7196 /* local variable */
7197 sym_push(v
, type
, r
, addr
);
7199 /* push local reference */
7200 vset(type
, r
, addr
);
7206 if (scope
== VT_CONST
) {
7207 /* global scope: see if already defined */
7211 if (!is_compatible_types(&sym
->type
, type
))
7212 error("incompatible types for redefinition of '%s'",
7213 get_tok_str(v
, NULL
));
7214 if (!(sym
->type
.t
& VT_EXTERN
))
7215 error("redefinition of '%s'", get_tok_str(v
, NULL
));
7216 sym
->type
.t
&= ~VT_EXTERN
;
7219 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
7221 put_extern_sym(sym
, sec
, addr
, size
);
7225 /* push global reference */
7226 sym
= get_sym_ref(type
, sec
, addr
, size
);
7228 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
7232 /* handles bounds now because the symbol must be defined
7233 before for the relocation */
7234 if (do_bounds_check
) {
7235 unsigned long *bounds_ptr
;
7237 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
7238 /* then add global bound info */
7239 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
7240 bounds_ptr
[0] = 0; /* relocated */
7241 bounds_ptr
[1] = size
;
7245 decl_initializer(type
, sec
, addr
, 1, 0);
7246 /* restore parse state if needed */
7248 tok_str_free(init_str
.str
);
7249 restore_parse_state(&saved_parse_state
);
7254 void put_func_debug(Sym
*sym
)
7259 /* XXX: we put here a dummy type */
7260 snprintf(buf
, sizeof(buf
), "%s:%c1",
7261 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
7262 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
7263 cur_text_section
, sym
->c
);
7268 /* not finished : try to put some local vars in registers */
7269 //#define CONFIG_REG_VARS
7271 #ifdef CONFIG_REG_VARS
7272 void add_var_ref(int t
)
7274 printf("%s:%d: &%s\n",
7275 file
->filename
, file
->line_num
,
7276 get_tok_str(t
, NULL
));
7279 /* first pass on a function with heuristic to extract variable usage
7280 and pointer references to local variables for register allocation */
7281 void analyse_function(void)
7288 /* any symbol coming after '&' is considered as being a
7289 variable whose reference is taken. It is highly unaccurate
7290 but it is difficult to do better without a complete parse */
7293 /* if '& number', then no need to examine next tokens */
7294 if (tok
== TOK_CINT
||
7296 tok
== TOK_CLLONG
||
7297 tok
== TOK_CULLONG
) {
7299 } else if (tok
>= TOK_UIDENT
) {
7300 /* if '& ident [' or '& ident ->', then ident address
7304 if (tok
!= '[' && tok
!= TOK_ARROW
)
7308 while (tok
!= '}' && tok
!= ';' &&
7309 !((tok
== ',' || tok
== ')') && level
== 0)) {
7310 if (tok
>= TOK_UIDENT
) {
7312 } else if (tok
== '(') {
7314 } else if (tok
== ')') {
7327 /* parse an old style function declaration list */
7328 /* XXX: check multiple parameter */
7329 static void func_decl_list(Sym
*func_sym
)
7336 /* parse each declaration */
7337 while (tok
!= '{' && tok
!= ';' && tok
!= TOK_EOF
) {
7338 if (!parse_btype(&btype
, &ad
))
7339 expect("declaration list");
7340 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
7341 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
7343 /* we accept no variable after */
7347 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
7348 /* find parameter in function parameter list */
7351 if ((s
->v
& ~SYM_FIELD
) == v
)
7355 error("declaration for parameter '%s' but no such parameter",
7356 get_tok_str(v
, NULL
));
7358 /* check that no storage specifier except 'register' was given */
7359 if (type
.t
& (VT_EXTERN
| VT_STATIC
| VT_TYPEDEF
))
7360 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
7361 /* we can add the type (NOTE: it could be local to the function) */
7363 /* accept other parameters */
7374 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
7375 static void decl(int l
)
7383 if (!parse_btype(&btype
, &ad
)) {
7384 /* skip redundant ';' */
7385 /* XXX: find more elegant solution */
7390 /* special test for old K&R protos without explicit int
7391 type. Only accepted when defining global data */
7392 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
7396 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
7397 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
7399 /* we accept no variable after */
7403 while (1) { /* iterate thru each declaration */
7405 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
7409 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
7410 printf("type = '%s'\n", buf
);
7413 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
7414 /* if old style function prototype, we accept a
7417 if (sym
->c
== FUNC_OLD
)
7418 func_decl_list(sym
);
7422 #ifdef CONFIG_REG_VARS
7423 TokenString func_str
;
7424 ParseState saved_parse_state
;
7429 error("cannot use local functions");
7430 if (!(type
.t
& VT_FUNC
))
7431 expect("function definition");
7433 #ifdef CONFIG_REG_VARS
7434 /* parse all function code and record it */
7436 tok_str_new(&func_str
);
7442 error("unexpected end of file");
7443 tok_str_add_tok(&func_str
);
7448 } else if (t
== '}') {
7450 if (block_level
== 0)
7454 tok_str_add(&func_str
, -1);
7455 tok_str_add(&func_str
, 0);
7457 save_parse_state(&saved_parse_state
);
7459 macro_ptr
= func_str
.str
;
7464 /* compute text section */
7465 cur_text_section
= ad
.section
;
7466 if (!cur_text_section
)
7467 cur_text_section
= text_section
;
7468 ind
= cur_text_section
->data_offset
;
7469 funcname
= get_tok_str(v
, NULL
);
7472 /* if symbol is already defined, then put complete type */
7475 /* put function symbol */
7476 sym
= global_identifier_push(v
, type
.t
, 0);
7477 sym
->type
.ref
= type
.ref
;
7479 /* NOTE: we patch the symbol size later */
7480 put_extern_sym(sym
, cur_text_section
, ind
, 0);
7482 sym
->r
= VT_SYM
| VT_CONST
;
7483 /* put debug symbol */
7485 put_func_debug(sym
);
7486 /* push a dummy symbol to enable local sym storage */
7487 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
7488 gfunc_prolog(&type
);
7491 #ifdef CONFIG_REG_VARS
7492 macro_ptr
= func_str
.str
;
7495 block(NULL
, NULL
, NULL
, NULL
, 0);
7498 cur_text_section
->data_offset
= ind
;
7499 /* look if any labels are undefined. Define symbols if
7500 '&&label' was used. */
7503 for(s
= label_stack
; s
!= NULL
; s
= s1
) {
7505 if (s
->r
& LABEL_FORWARD
) {
7506 error("label '%s' used but not defined",
7507 get_tok_str(s
->v
, NULL
));
7510 /* define corresponding symbol. A size of
7512 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
7515 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= NULL
;
7520 sym_pop(&local_stack
, NULL
); /* reset local stack */
7521 /* end of function */
7522 /* patch symbol size */
7523 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
7526 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
7528 funcname
= ""; /* for safety */
7529 func_vt
.t
= VT_VOID
; /* for safety */
7530 ind
= 0; /* for safety */
7532 #ifdef CONFIG_REG_VARS
7533 tok_str_free(func_str
.str
);
7534 restore_parse_state(&saved_parse_state
);
7538 if (btype
.t
& VT_TYPEDEF
) {
7539 /* save typedefed type */
7540 /* XXX: test storage specifiers ? */
7541 sym
= sym_push(v
, &type
, 0, 0);
7542 sym
->type
.t
|= VT_TYPEDEF
;
7543 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
7544 /* external function definition */
7545 external_sym(v
, &type
, 0);
7547 /* not lvalue if array */
7549 if (!(type
.t
& VT_ARRAY
))
7550 r
|= lvalue_type(type
.t
);
7551 if (btype
.t
& VT_EXTERN
) {
7552 /* external variable */
7553 external_sym(v
, &type
, r
);
7555 if (type
.t
& VT_STATIC
)
7559 has_init
= (tok
== '=');
7562 decl_initializer_alloc(&type
, &ad
, r
,
7576 /* compile the C file opened in 'file'. Return non zero if errors. */
7577 static int tcc_compile(TCCState
*s1
)
7581 volatile int section_sym
;
7584 printf("%s: **** new file\n", file
->filename
);
7587 s1
->include_stack_ptr
= s1
->include_stack
;
7588 /* XXX: move that before to avoid having to initialize
7589 file->ifdef_stack_ptr ? */
7590 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
7591 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
7593 /* XXX: not ANSI compliant: bound checking says error */
7595 anon_sym
= SYM_FIRST_ANOM
;
7597 /* file info: full path + filename */
7598 section_sym
= 0; /* avoid warning */
7600 section_sym
= put_elf_sym(symtab_section
, 0, 0,
7601 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
7602 text_section
->sh_num
, NULL
);
7603 getcwd(buf
, sizeof(buf
));
7604 pstrcat(buf
, sizeof(buf
), "/");
7605 put_stabs_r(buf
, N_SO
, 0, 0,
7606 text_section
->data_offset
, text_section
, section_sym
);
7607 put_stabs_r(file
->filename
, N_SO
, 0, 0,
7608 text_section
->data_offset
, text_section
, section_sym
);
7610 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
7611 symbols can be safely used */
7612 put_elf_sym(symtab_section
, 0, 0,
7613 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
7614 SHN_ABS
, file
->filename
);
7616 /* define some often used types */
7617 int_type
.t
= VT_INT
;
7619 char_pointer_type
.t
= VT_BYTE
;
7620 mk_pointer(&char_pointer_type
);
7622 func_old_type
.t
= VT_FUNC
;
7623 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
7626 /* define 'void *alloca(unsigned int)' builtin function */
7631 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
7632 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
7635 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
7639 define_start
= define_stack
;
7641 if (setjmp(s1
->error_jmp_buf
) == 0) {
7643 s1
->error_set_jmp_enabled
= 1;
7645 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7649 expect("declaration");
7651 /* end of translation unit info */
7653 put_stabs_r(NULL
, N_SO
, 0, 0,
7654 text_section
->data_offset
, text_section
, section_sym
);
7657 s1
->error_set_jmp_enabled
= 0;
7659 /* reset define stack, but leave -Dsymbols (may be incorrect if
7660 they are undefined) */
7661 free_defines(define_start
);
7663 sym_pop(&global_stack
, NULL
);
7665 return s1
->nb_errors
!= 0 ? -1 : 0;
7669 int tcc_compile_string(TCCState
*s
, const char *str
)
7671 BufferedFile bf1
, *bf
= &bf1
;
7675 /* init file structure */
7677 /* XXX: avoid copying */
7679 buf
= tcc_malloc(len
+ 1);
7684 bf
->buf_end
= buf
+ len
;
7685 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
7689 ret
= tcc_compile(s
);
7693 /* currently, no need to close */
7698 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
7699 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
7701 BufferedFile bf1
, *bf
= &bf1
;
7703 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
7704 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
7708 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
7710 /* init file structure */
7712 bf
->buf_ptr
= bf
->buffer
;
7713 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
7714 *bf
->buf_end
= CH_EOB
;
7715 bf
->filename
[0] = '\0';
7719 s1
->include_stack_ptr
= s1
->include_stack
;
7721 /* parse with define parser */
7722 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7728 /* undefine a preprocessor symbol */
7729 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
7733 ts
= tok_alloc(sym
, strlen(sym
));
7734 s
= define_find(ts
->tok
);
7735 /* undefine symbol by putting an invalid name */
7742 /* print the position in the source file of PC value 'pc' by reading
7743 the stabs debug information */
7744 static void rt_printline(unsigned long wanted_pc
)
7746 Stab_Sym
*sym
, *sym_end
;
7747 char func_name
[128], last_func_name
[128];
7748 unsigned long func_addr
, last_pc
, pc
;
7749 const char *incl_files
[INCLUDE_STACK_SIZE
];
7750 int incl_index
, len
, last_line_num
, i
;
7751 const char *str
, *p
;
7753 fprintf(stderr
, "0x%08lx:", wanted_pc
);
7755 func_name
[0] = '\0';
7758 last_func_name
[0] = '\0';
7759 last_pc
= 0xffffffff;
7761 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
7762 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
7763 while (sym
< sym_end
) {
7764 switch(sym
->n_type
) {
7765 /* function start or end */
7767 if (sym
->n_strx
== 0) {
7768 /* we test if between last line and end of function */
7769 pc
= sym
->n_value
+ func_addr
;
7770 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7772 func_name
[0] = '\0';
7775 str
= stabstr_section
->data
+ sym
->n_strx
;
7776 p
= strchr(str
, ':');
7778 pstrcpy(func_name
, sizeof(func_name
), str
);
7781 if (len
> sizeof(func_name
) - 1)
7782 len
= sizeof(func_name
) - 1;
7783 memcpy(func_name
, str
, len
);
7784 func_name
[len
] = '\0';
7786 func_addr
= sym
->n_value
;
7789 /* line number info */
7791 pc
= sym
->n_value
+ func_addr
;
7792 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7795 last_line_num
= sym
->n_desc
;
7797 strcpy(last_func_name
, func_name
);
7801 str
= stabstr_section
->data
+ sym
->n_strx
;
7803 if (incl_index
< INCLUDE_STACK_SIZE
) {
7804 incl_files
[incl_index
++] = str
;
7812 if (sym
->n_strx
== 0) {
7813 incl_index
= 0; /* end of translation unit */
7815 str
= stabstr_section
->data
+ sym
->n_strx
;
7816 /* do not add path */
7818 if (len
> 0 && str
[len
- 1] != '/')
7826 /* second pass: we try symtab symbols (no line number info) */
7829 Elf32_Sym
*sym
, *sym_end
;
7832 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
7833 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
7836 type
= ELF32_ST_TYPE(sym
->st_info
);
7837 if (type
== STT_FUNC
) {
7838 if (wanted_pc
>= sym
->st_value
&&
7839 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
7840 pstrcpy(last_func_name
, sizeof(last_func_name
),
7841 strtab_section
->data
+ sym
->st_name
);
7847 /* did not find any info: */
7848 fprintf(stderr
, " ???\n");
7851 if (last_func_name
[0] != '\0') {
7852 fprintf(stderr
, " %s()", last_func_name
);
7854 if (incl_index
> 0) {
7855 fprintf(stderr
, " (%s:%d",
7856 incl_files
[incl_index
- 1], last_line_num
);
7857 for(i
= incl_index
- 2; i
>= 0; i
--)
7858 fprintf(stderr
, ", included from %s", incl_files
[i
]);
7859 fprintf(stderr
, ")");
7861 fprintf(stderr
, "\n");
7873 /* return the PC at frame level 'level'. Return non zero if not found */
7874 static int rt_get_caller_pc(unsigned long *paddr
,
7875 struct ucontext
*uc
, int level
)
7881 *paddr
= uc
->uc_mcontext
.gregs
[EIP
];
7884 fp
= uc
->uc_mcontext
.gregs
[EBP
];
7885 for(i
=1;i
<level
;i
++) {
7886 /* XXX: check address validity with program info */
7887 if (fp
<= 0x1000 || fp
>= 0xc0000000)
7889 fp
= ((unsigned long *)fp
)[0];
7891 *paddr
= ((unsigned long *)fp
)[1];
7896 #error add arch specific rt_get_caller_pc()
7899 /* emit a run time error at position 'pc' */
7900 void rt_error(struct ucontext
*uc
, const char *fmt
, ...)
7907 fprintf(stderr
, "Runtime error: ");
7908 vfprintf(stderr
, fmt
, ap
);
7909 fprintf(stderr
, "\n");
7910 for(i
=0;i
<num_callers
;i
++) {
7911 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
7914 fprintf(stderr
, "at ");
7916 fprintf(stderr
, "by ");
7923 /* signal handler for fatal errors */
7924 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
7926 struct ucontext
*uc
= puc
;
7930 switch(siginf
->si_code
) {
7933 rt_error(uc
, "division by zero");
7936 rt_error(uc
, "floating point exception");
7942 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
7943 rt_error(uc
, *rt_bound_error_msg
);
7945 rt_error(uc
, "dereferencing invalid pointer");
7948 rt_error(uc
, "illegal instruction");
7951 rt_error(uc
, "abort() called");
7954 rt_error(uc
, "caught signal %d", signum
);
7961 /* do all relocations (needed before using tcc_get_symbol()) */
7962 int tcc_relocate(TCCState
*s1
)
7969 tcc_add_runtime(s1
);
7971 relocate_common_syms();
7973 /* compute relocation address : section are relocated in place. We
7974 also alloc the bss space */
7975 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7976 s
= s1
->sections
[i
];
7977 if (s
->sh_flags
& SHF_ALLOC
) {
7978 if (s
->sh_type
== SHT_NOBITS
)
7979 s
->data
= tcc_mallocz(s
->data_offset
);
7980 s
->sh_addr
= (unsigned long)s
->data
;
7984 relocate_syms(s1
, 1);
7986 if (s1
->nb_errors
!= 0)
7989 /* relocate each section */
7990 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7991 s
= s1
->sections
[i
];
7993 relocate_section(s1
, s
);
7998 /* launch the compiled program with the given arguments */
7999 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
8001 int (*prog_main
)(int, char **);
8003 if (tcc_relocate(s1
) < 0)
8006 prog_main
= tcc_get_symbol(s1
, "main");
8010 error("debug mode currently not available for Windows");
8012 struct sigaction sigact
;
8013 /* install TCC signal handlers to print debug info on fatal
8015 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
8016 sigact
.sa_sigaction
= sig_error
;
8017 sigemptyset(&sigact
.sa_mask
);
8018 sigaction(SIGFPE
, &sigact
, NULL
);
8019 sigaction(SIGILL
, &sigact
, NULL
);
8020 sigaction(SIGSEGV
, &sigact
, NULL
);
8021 sigaction(SIGBUS
, &sigact
, NULL
);
8022 sigaction(SIGABRT
, &sigact
, NULL
);
8026 #ifdef CONFIG_TCC_BCHECK
8027 if (do_bounds_check
) {
8028 void (*bound_init
)(void);
8030 /* set error function */
8031 rt_bound_error_msg
= (void *)tcc_get_symbol(s1
, "__bound_error_msg");
8033 /* XXX: use .init section so that it also work in binary ? */
8034 bound_init
= (void *)tcc_get_symbol(s1
, "__bound_init");
8038 return (*prog_main
)(argc
, argv
);
8041 TCCState
*tcc_new(void)
8046 s
= tcc_mallocz(sizeof(TCCState
));
8050 s
->output_type
= TCC_OUTPUT_MEMORY
;
8052 /* default include paths */
8053 tcc_add_sysinclude_path(s
, "/usr/local/include");
8054 tcc_add_sysinclude_path(s
, "/usr/include");
8055 tcc_add_sysinclude_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
8057 /* add all tokens */
8059 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
8061 tok_ident
= TOK_IDENT
;
8066 tok_alloc(p
, r
- p
- 1);
8070 /* we add dummy defines for some special macros to speed up tests
8071 and to have working defined() */
8072 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
8073 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
8074 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
8075 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
8077 /* standard defines */
8078 tcc_define_symbol(s
, "__STDC__", NULL
);
8079 #if defined(TCC_TARGET_I386)
8080 tcc_define_symbol(s
, "__i386__", NULL
);
8083 tcc_define_symbol(s
, "linux", NULL
);
8085 /* tiny C specific defines */
8086 tcc_define_symbol(s
, "__TINYC__", NULL
);
8088 /* default library paths */
8089 tcc_add_library_path(s
, "/usr/local/lib");
8090 tcc_add_library_path(s
, "/usr/lib");
8091 tcc_add_library_path(s
, "/lib");
8093 /* no section zero */
8094 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
8096 /* create standard sections */
8097 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
8098 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
8099 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
8101 /* symbols are always generated for linking stage */
8102 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
8104 ".hashtab", SHF_PRIVATE
);
8105 strtab_section
= symtab_section
->link
;
8107 /* private symbol table for dynamic symbols */
8108 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
8110 ".dynhashtab", SHF_PRIVATE
);
8114 void tcc_delete(TCCState
*s1
)
8118 /* free -D defines */
8122 n
= tok_ident
- TOK_IDENT
;
8123 for(i
= 0; i
< n
; i
++)
8124 tcc_free(table_ident
[i
]);
8125 tcc_free(table_ident
);
8127 /* free all sections */
8129 free_section(symtab_section
->hash
);
8131 free_section(s1
->dynsymtab_section
->hash
);
8132 free_section(s1
->dynsymtab_section
->link
);
8133 free_section(s1
->dynsymtab_section
);
8135 for(i
= 1; i
< s1
->nb_sections
; i
++)
8136 free_section(s1
->sections
[i
]);
8137 tcc_free(s1
->sections
);
8139 /* free loaded dlls array */
8140 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
8141 tcc_free(s1
->loaded_dlls
[i
]);
8142 tcc_free(s1
->loaded_dlls
);
8145 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
8146 tcc_free(s1
->library_paths
[i
]);
8147 tcc_free(s1
->library_paths
);
8149 /* cached includes */
8150 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
8151 tcc_free(s1
->cached_includes
[i
]);
8152 tcc_free(s1
->cached_includes
);
8154 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
8155 tcc_free(s1
->include_paths
[i
]);
8156 tcc_free(s1
->include_paths
);
8158 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
8159 tcc_free(s1
->sysinclude_paths
[i
]);
8160 tcc_free(s1
->sysinclude_paths
);
8165 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
8169 pathname1
= tcc_strdup(pathname
);
8170 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
8174 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
8178 pathname1
= tcc_strdup(pathname
);
8179 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
8183 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
8188 BufferedFile
*saved_file
;
8190 /* find source file type with extension */
8191 ext
= strrchr(filename
, '.');
8197 file
= tcc_open(s1
, filename
);
8199 if (flags
& AFF_PRINT_ERROR
) {
8200 error_noabort("file '%s' not found", filename
);
8206 if (!ext
|| !strcmp(ext
, "c")) {
8207 /* C file assumed */
8208 ret
= tcc_compile(s1
);
8211 /* assume executable format: auto guess file type */
8212 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
)) {
8213 error_noabort("could not read header");
8216 lseek(fd
, 0, SEEK_SET
);
8218 if (ehdr
.e_ident
[0] == ELFMAG0
&&
8219 ehdr
.e_ident
[1] == ELFMAG1
&&
8220 ehdr
.e_ident
[2] == ELFMAG2
&&
8221 ehdr
.e_ident
[3] == ELFMAG3
) {
8222 file
->line_num
= 0; /* do not display line number if error */
8223 if (ehdr
.e_type
== ET_REL
) {
8224 ret
= tcc_load_object_file(s1
, fd
, 0);
8225 } else if (ehdr
.e_type
== ET_DYN
) {
8226 ret
= tcc_load_dll(s1
, fd
, filename
,
8227 (flags
& AFF_REFERENCED_DLL
) != 0);
8229 error_noabort("unrecognized ELF file");
8232 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
8233 file
->line_num
= 0; /* do not display line number if error */
8234 ret
= tcc_load_archive(s1
, fd
);
8236 /* as GNU ld, consider it is an ld script if not recognized */
8237 ret
= tcc_load_ldscript(s1
);
8239 error_noabort("unrecognized file type");
8254 int tcc_add_file(TCCState
*s
, const char *filename
)
8256 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
8259 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
8263 pathname1
= tcc_strdup(pathname
);
8264 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
8268 /* find and load a dll. Return non zero if not found */
8269 /* XXX: add '-rpath' option support ? */
8270 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
8275 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
8276 snprintf(buf
, sizeof(buf
), "%s/%s",
8277 s
->library_paths
[i
], filename
);
8278 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
8284 /* the library name is the same as the argument of the '-l' option */
8285 int tcc_add_library(TCCState
*s
, const char *libraryname
)
8291 /* first we look for the dynamic library if not static linking */
8292 if (!s
->static_link
) {
8293 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8294 /* if we output to memory, then we simply we dlopen(). */
8295 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
8296 /* Since the libc is already loaded, we don't need to load it again */
8297 if (!strcmp(libraryname
, "c"))
8299 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
8303 if (tcc_add_dll(s
, buf
, 0) == 0)
8308 /* then we look for the static library */
8309 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
8310 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
8311 s
->library_paths
[i
], libraryname
);
8312 if (tcc_add_file_internal(s
, buf
, 0) == 0)
8318 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
8320 add_elf_sym(symtab_section
, val
, 0,
8321 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
8326 int tcc_set_output_type(TCCState
*s
, int output_type
)
8328 s
->output_type
= output_type
;
8330 /* if bound checking, then add corresponding sections */
8331 #ifdef CONFIG_TCC_BCHECK
8332 if (do_bounds_check
) {
8334 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
8335 /* create bounds sections */
8336 bounds_section
= new_section(s
, ".bounds",
8337 SHT_PROGBITS
, SHF_ALLOC
);
8338 lbounds_section
= new_section(s
, ".lbounds",
8339 SHT_PROGBITS
, SHF_ALLOC
);
8343 /* add debug sections */
8346 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
8347 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
8348 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
8349 put_elf_str(stabstr_section
, "");
8350 stab_section
->link
= stabstr_section
;
8351 /* put first entry */
8352 put_stabs("", 0, 0, 0, 0);
8355 /* add libc crt1/crti objects */
8356 if (output_type
== TCC_OUTPUT_EXE
||
8357 output_type
== TCC_OUTPUT_DLL
) {
8358 if (output_type
!= TCC_OUTPUT_DLL
)
8359 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
8360 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
8365 #if !defined(LIBTCC)
8367 static int64_t getclock_us(void)
8372 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
8375 gettimeofday(&tv
, NULL
);
8376 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
8382 printf("tcc version 0.9.13 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8383 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8384 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
8385 " [--] infile1 [infile2... --] [infile_args...]\n"
8387 "General options:\n"
8388 " -c compile only - generate an object file\n"
8389 " -o outfile set output filename\n"
8390 " -- allows multiples input files if no -o option given. Also\n"
8391 " separate input files from runtime arguments\n"
8392 " -Bdir set tcc internal library path\n"
8393 " -bench output compilation statistics\n"
8394 "Preprocessor options:\n"
8395 " -Idir add include path 'dir'\n"
8396 " -Dsym[=val] define 'sym' with value 'val'\n"
8397 " -Usym undefine 'sym'\n"
8399 " -Ldir add library path 'dir'\n"
8400 " -llib link with dynamic or static library 'lib'\n"
8401 " -shared generate a shared library\n"
8402 " -static static linking\n"
8403 " -r relocatable output\n"
8404 "Debugger options:\n"
8405 " -g generate runtime debug info\n"
8406 #ifdef CONFIG_TCC_BCHECK
8407 " -b compile with built-in memory and bounds checker (implies -g)\n"
8409 " -bt N show N callers in stack traces\n"
8413 int main(int argc
, char **argv
)
8416 int optind
, output_type
, multiple_files
, i
, reloc_output
;
8419 int nb_files
, nb_libraries
, nb_objfiles
, dminus
, ret
;
8420 char objfilename
[1024];
8421 int64_t start_time
= 0;
8424 output_type
= TCC_OUTPUT_MEMORY
;
8435 if (optind
>= argc
) {
8443 /* add a new file */
8444 dynarray_add((void ***)&files
, &nb_files
, r
);
8445 if (!multiple_files
) {
8447 /* argv[0] will be this file */
8450 } else if (r
[1] == '-') {
8451 /* '--' enables multiple files input and also ends several file input */
8452 if (dminus
&& multiple_files
) {
8453 optind
--; /* argv[0] will be '--' */
8458 } else if (r
[1] == 'h' || r
[1] == '?') {
8462 } else if (r
[1] == 'I') {
8463 if (tcc_add_include_path(s
, r
+ 2) < 0)
8464 error("too many include paths");
8465 } else if (r
[1] == 'D') {
8468 value
= strchr(sym
, '=');
8473 tcc_define_symbol(s
, sym
, value
);
8474 } else if (r
[1] == 'U') {
8475 tcc_undefine_symbol(s
, r
+ 2);
8476 } else if (r
[1] == 'L') {
8477 tcc_add_library_path(s
, r
+ 2);
8478 } else if (r
[1] == 'B') {
8479 /* set tcc utilities path (mainly for tcc development) */
8480 tcc_lib_path
= r
+ 2;
8481 } else if (r
[1] == 'l') {
8482 dynarray_add((void ***)&files
, &nb_files
, r
);
8484 } else if (!strcmp(r
+ 1, "bench")) {
8486 } else if (!strcmp(r
+ 1, "bt")) {
8487 num_callers
= atoi(argv
[optind
++]);
8489 #ifdef CONFIG_TCC_BCHECK
8491 do_bounds_check
= 1;
8497 } else if (r
[1] == 'c') {
8499 output_type
= TCC_OUTPUT_OBJ
;
8500 } else if (!strcmp(r
+ 1, "static")) {
8502 } else if (!strcmp(r
+ 1, "shared")) {
8503 output_type
= TCC_OUTPUT_DLL
;
8504 } else if (r
[1] == 'o') {
8508 outfile
= argv
[optind
++];
8509 } else if (r
[1] == 'r') {
8510 /* generate a .o merging several output files */
8512 output_type
= TCC_OUTPUT_OBJ
;
8513 } else if (r
[1] == 'W' || r
[1] == 'O' || r
[1] == 'm' || r
[1] == 'f') {
8514 /* ignore those options to be a drop-in replacement for gcc */
8516 error("invalid option -- '%s'", r
);
8520 nb_objfiles
= nb_files
- nb_libraries
;
8522 /* if outfile provided without other options, we output an
8524 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
8525 output_type
= TCC_OUTPUT_EXE
;
8527 /* check -c consistency : only single file handled. XXX: checks file type */
8528 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
8529 /* accepts only a single input file */
8530 if (nb_objfiles
!= 1)
8531 error("cannot specify multiple files with -c");
8532 if (nb_libraries
!= 0)
8533 error("cannot specify libraries with -c");
8536 /* compute default outfile name */
8537 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
8538 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
8540 /* add .o extension */
8541 pstrcpy(objfilename
, sizeof(objfilename
) - 1, files
[0]);
8542 ext
= strrchr(objfilename
, '.');
8544 goto default_outfile
;
8545 strcpy(ext
+ 1, "o");
8548 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
8550 outfile
= objfilename
;
8554 start_time
= getclock_us();
8557 tcc_set_output_type(s
, output_type
);
8559 /* compile or add each files or library */
8560 for(i
= 0;i
< nb_files
; i
++) {
8561 const char *filename
;
8563 filename
= files
[i
];
8564 if (filename
[0] == '-') {
8565 if (tcc_add_library(s
, filename
+ 2) < 0)
8566 error("cannot find %s", filename
);
8568 if (tcc_add_file(s
, filename
) < 0) {
8575 /* free all files */
8580 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
8581 if (total_time
< 0.001)
8583 if (total_bytes
< 1)
8585 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
8586 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
8587 total_time
, (int)(total_lines
/ total_time
),
8588 total_bytes
/ total_time
/ 1000000.0);
8591 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
8592 tcc_output_file(s
, outfile
);
8595 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
8598 /* XXX: cannot do it with bound checking because of the malloc hooks */
8599 if (!do_bounds_check
)
8604 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);