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
47 /* preprocessor debug */
49 /* include file debug */
54 /* target selection */
55 //#define TCC_TARGET_I386 /* i386 code generator */
56 //#define TCC_TARGET_IL /* .NET CLI generator */
58 /* default target is I386 */
59 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_IL)
60 #define TCC_TARGET_I386
63 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_IL)
64 #define CONFIG_TCC_BCHECK /* enable bound checking code */
67 #ifndef CONFIG_TCC_PREFIX
68 #define CONFIG_TCC_PREFIX "/usr/local"
71 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
72 executables or dlls */
73 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
75 #define INCLUDE_STACK_SIZE 32
76 #define IFDEF_STACK_SIZE 64
77 #define VSTACK_SIZE 64
78 #define STRING_MAX_SIZE 1024
80 #define TOK_HASH_SIZE 2048 /* must be a power of two */
81 #define TOK_ALLOC_INCR 512 /* must be a power of two */
83 /* token symbol management */
84 typedef struct TokenSym
{
85 struct TokenSym
*hash_next
;
86 struct Sym
*sym_define
; /* direct pointer to define */
87 struct Sym
*sym_label
; /* direct pointer to label */
88 struct Sym
*sym_struct
; /* direct pointer to structure */
89 struct Sym
*sym_identifier
; /* direct pointer to identifier */
90 int tok
; /* token number */
95 typedef struct CString
{
96 int size
; /* size in bytes */
97 void *data
; /* either 'char *' or 'int *' */
99 void *data_allocated
; /* if non NULL, data has been malloced */
102 /* type definition */
103 typedef struct CType
{
109 typedef union CValue
{
115 unsigned int ul
; /* address (should be unsigned long on 64 bit cpu) */
117 unsigned long long ull
;
118 struct CString
*cstr
;
124 typedef struct SValue
{
125 CType type
; /* type */
126 unsigned short r
; /* register + flags */
127 unsigned short r2
; /* second register, used for 'long long'
128 type. If not used, set to VT_CONST */
129 CValue c
; /* constant, if VT_CONST */
130 struct Sym
*sym
; /* symbol, if (VT_SYM | VT_CONST) */
133 /* symbol management */
135 int v
; /* symbol token */
136 int r
; /* associated register */
137 int c
; /* associated number */
138 CType type
; /* associated type */
139 struct Sym
*next
; /* next related symbol */
140 struct Sym
*prev
; /* prev symbol in stack */
141 struct Sym
*prev_tok
; /* previous symbol for this token */
144 /* section definition */
145 /* XXX: use directly ELF structure for parameters ? */
146 /* special flag to indicate that the section should not be linked to
148 #define SHF_PRIVATE 0x80000000
150 typedef struct Section
{
151 unsigned long data_offset
; /* current data offset */
152 unsigned char *data
; /* section data */
153 unsigned long data_allocated
; /* used for realloc() handling */
154 int sh_name
; /* elf section name (only used during output) */
155 int sh_num
; /* elf section number */
156 int sh_type
; /* elf section type */
157 int sh_flags
; /* elf section flags */
158 int sh_info
; /* elf section info */
159 int sh_addralign
; /* elf section alignment */
160 int sh_entsize
; /* elf entry size */
161 unsigned long sh_size
; /* section size (only used during output) */
162 unsigned long sh_addr
; /* address at which the section is relocated */
163 unsigned long sh_offset
; /* address at which the section is relocated */
164 int nb_hashed_syms
; /* used to resize the hash table */
165 struct Section
*link
; /* link to another section */
166 struct Section
*reloc
; /* corresponding section for relocation, if any */
167 struct Section
*hash
; /* hash table for symbols */
168 struct Section
*next
;
169 char name
[64]; /* section name */
172 typedef struct DLLReference
{
177 /* GNUC attribute definition */
178 typedef struct AttributeDef
{
181 unsigned char func_call
; /* FUNC_CDECL or FUNC_STDCALL */
184 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
185 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */
186 #define SYM_FIRST_ANOM (1 << (31 - VT_STRUCT_SHIFT)) /* first anonymous sym */
188 /* stored in 'Sym.c' field */
189 #define FUNC_NEW 1 /* ansi function prototype */
190 #define FUNC_OLD 2 /* old function prototype */
191 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */
193 /* stored in 'Sym.r' field */
194 #define FUNC_CDECL 0 /* standard c call */
195 #define FUNC_STDCALL 1 /* pascal c call */
197 /* field 'Sym.t' for macros */
198 #define MACRO_OBJ 0 /* object like macro */
199 #define MACRO_FUNC 1 /* function like macro */
201 /* field 'Sym.r' for labels */
202 #define LABEL_FORWARD 1 /* label is forward defined */
204 /* type_decl() types */
205 #define TYPE_ABSTRACT 1 /* type without variable */
206 #define TYPE_DIRECT 2 /* type with variable */
208 #define IO_BUF_SIZE 8192
210 typedef struct BufferedFile
{
211 unsigned char *buf_ptr
;
212 unsigned char *buf_end
;
214 int line_num
; /* current line number - here to simply code */
215 int ifndef_macro
; /*'#ifndef macro \n #define macro' search */
216 int *ifdef_stack_ptr
; /* ifdef_stack value at the start of the file */
217 char inc_type
; /* type of include */
218 char inc_filename
[512]; /* filename specified by the user */
219 char filename
[1024]; /* current filename - here to simplify code */
220 unsigned char buffer
[IO_BUF_SIZE
+ 1]; /* extra size for CH_EOB char */
223 #define CH_EOB 0 /* end of buffer or '\0' char in file */
224 #define CH_EOF (-1) /* end of file */
226 /* parsing state (used to save parser state to reparse part of the
227 source several times) */
228 typedef struct ParseState
{
235 /* used to record tokens */
236 typedef struct TokenString
{
242 /* include file cache, used to find files faster and also to eliminate
243 inclusion if the include file is protected by #ifndef ... #endif */
244 typedef struct CachedInclude
{
246 char type
; /* '"' or '>' to give include type */
247 char filename
[1]; /* path specified in #include */
251 struct BufferedFile
*file
;
252 int ch
, ch1
, tok
, tok1
;
254 CString tokcstr
; /* current parsed string, if any */
255 /* if true, line feed is returned as a token. line feed is also
258 /* set to TRUE if eof was reached */
260 Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
261 Section
*cur_text_section
; /* current section where function code is
263 /* bound check related sections */
264 Section
*bounds_section
; /* contains global data bound description */
265 Section
*lbounds_section
; /* contains local data bound description */
266 /* symbol sections */
267 Section
*symtab_section
, *strtab_section
;
270 Section
*stab_section
, *stabstr_section
;
272 /* loc : local variable index
273 ind : output code index
275 anon_sym: anonymous symbol index
279 /* expression generation modifiers */
280 int const_wanted
; /* true if constant wanted */
281 int nocode_wanted
; /* true if no code generation wanted for an expression */
282 int global_expr
; /* true if compound literals must be allocated
283 globally (used during initializers parsing */
284 CType func_vt
; /* current function return type (used by return
287 int last_line_num
, last_ind
, func_ind
; /* debug last line number and pc */
289 TokenSym
**table_ident
;
290 TokenSym
*hash_ident
[TOK_HASH_SIZE
];
291 char token_buf
[STRING_MAX_SIZE
+ 1];
293 Sym
*global_stack
, *local_stack
;
297 SValue vstack
[VSTACK_SIZE
], *vtop
;
298 int *macro_ptr
, *macro_ptr_allocated
;
299 /* some predefined types */
300 CType char_pointer_type
, func_old_type
, int_type
;
302 /* compile with debug symbol (and use them if error during execution) */
305 /* compile with built-in memory and bounds checker */
306 int do_bounds_check
= 0;
308 /* display benchmark infos */
313 /* use GNU C extensions */
316 /* use Tiny C extensions */
319 /* max number of callers shown if error */
320 static int num_callers
= 6;
321 static const char **rt_bound_error_msg
;
323 /* XXX: suppress that ASAP */
324 static struct TCCState
*tcc_state
;
326 /* give the path of the tcc libraries */
327 static const char *tcc_lib_path
= CONFIG_TCC_PREFIX
"/lib/tcc";
332 BufferedFile
**include_stack_ptr
;
333 int *ifdef_stack_ptr
;
335 /* include file handling */
336 char **include_paths
;
337 int nb_include_paths
;
338 char **sysinclude_paths
;
339 int nb_sysinclude_paths
;
340 CachedInclude
**cached_includes
;
341 int nb_cached_includes
;
343 char **library_paths
;
344 int nb_library_paths
;
346 /* array of all loaded dlls (including those referenced by loaded
348 DLLReference
**loaded_dlls
;
353 int nb_sections
; /* number of sections, including first dummy section */
357 unsigned long *got_offsets
;
360 /* give the correspondance from symtab indexes to dynsym indexes */
361 int *symtab_to_dynsym
;
363 /* temporary dynamic symbol sections (for dll loading) */
364 Section
*dynsymtab_section
;
365 /* exported dynamic symbol section */
368 /* if true, static linking is performed */
373 void (*error_func
)(void *opaque
, const char *msg
);
374 int error_set_jmp_enabled
;
375 jmp_buf error_jmp_buf
;
378 /* see include_stack_ptr */
379 BufferedFile
*include_stack
[INCLUDE_STACK_SIZE
];
381 /* see ifdef_stack_ptr */
382 int ifdef_stack
[IFDEF_STACK_SIZE
];
385 /* The current value can be: */
386 #define VT_VALMASK 0x00ff
387 #define VT_CONST 0x00f0 /* constant in vc
388 (must be first non register value) */
389 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */
390 #define VT_LOCAL 0x00f2 /* offset on stack */
391 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */
392 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */
393 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */
394 #define VT_LVAL 0x0100 /* var is an lvalue */
395 #define VT_SYM 0x0200 /* a symbol value is added */
396 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
397 char/short stored in integer registers) */
398 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before
399 dereferencing value */
400 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the
401 bounding function call point is in vc */
402 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
403 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
404 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
405 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
408 #define VT_STRUCT_SHIFT 12 /* structure/enum name shift (20 bits left) */
410 #define VT_INT 0 /* integer type */
411 #define VT_BYTE 1 /* signed byte type */
412 #define VT_SHORT 2 /* short type */
413 #define VT_VOID 3 /* void type */
414 #define VT_PTR 4 /* pointer */
415 #define VT_ENUM 5 /* enum definition */
416 #define VT_FUNC 6 /* function type */
417 #define VT_STRUCT 7 /* struct/union definition */
418 #define VT_FLOAT 8 /* IEEE float */
419 #define VT_DOUBLE 9 /* IEEE double */
420 #define VT_LDOUBLE 10 /* IEEE long double */
421 #define VT_BOOL 11 /* ISOC99 boolean type */
422 #define VT_LLONG 12 /* 64 bit integer */
423 #define VT_LONG 13 /* long integer (NEVER USED as type, only
425 #define VT_BTYPE 0x000f /* mask for basic type */
426 #define VT_UNSIGNED 0x0010 /* unsigned type */
427 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */
428 #define VT_BITFIELD 0x0040 /* bitfield modifier */
431 #define VT_EXTERN 0x00000080 /* extern definition */
432 #define VT_STATIC 0x00000100 /* static variable */
433 #define VT_TYPEDEF 0x00000200 /* typedef definition */
435 /* type mask (except storage) */
436 #define VT_TYPE (~(VT_EXTERN | VT_STATIC | VT_TYPEDEF))
440 /* warning: the following compare tokens depend on i386 asm code */
452 #define TOK_LAND 0xa0
456 #define TOK_MID 0xa3 /* inc/dec, to void constant */
458 #define TOK_UDIV 0xb0 /* unsigned division */
459 #define TOK_UMOD 0xb1 /* unsigned modulo */
460 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */
461 #define TOK_CINT 0xb3 /* number in tokc */
462 #define TOK_CCHAR 0xb4 /* char constant in tokc */
463 #define TOK_STR 0xb5 /* pointer to string in tokc */
464 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
465 #define TOK_LCHAR 0xb7
466 #define TOK_LSTR 0xb8
467 #define TOK_CFLOAT 0xb9 /* float constant */
468 #define TOK_LINENUM 0xba /* line number info */
469 #define TOK_CDOUBLE 0xc0 /* double constant */
470 #define TOK_CLDOUBLE 0xc1 /* long double constant */
471 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
472 #define TOK_ADDC1 0xc3 /* add with carry generation */
473 #define TOK_ADDC2 0xc4 /* add with carry use */
474 #define TOK_SUBC1 0xc5 /* add with carry generation */
475 #define TOK_SUBC2 0xc6 /* add with carry use */
476 #define TOK_CUINT 0xc8 /* unsigned int constant */
477 #define TOK_CLLONG 0xc9 /* long long constant */
478 #define TOK_CULLONG 0xca /* unsigned long long constant */
479 #define TOK_ARROW 0xcb
480 #define TOK_DOTS 0xcc /* three dots */
481 #define TOK_SHR 0xcd /* unsigned shift right */
482 #define TOK_PPNUM 0xce /* preprocessor number */
484 #define TOK_SHL 0x01 /* shift left */
485 #define TOK_SAR 0x02 /* signed shift right */
487 /* assignement operators : normal operator or 0x80 */
488 #define TOK_A_MOD 0xa5
489 #define TOK_A_AND 0xa6
490 #define TOK_A_MUL 0xaa
491 #define TOK_A_ADD 0xab
492 #define TOK_A_SUB 0xad
493 #define TOK_A_DIV 0xaf
494 #define TOK_A_XOR 0xde
495 #define TOK_A_OR 0xfc
496 #define TOK_A_SHL 0x81
497 #define TOK_A_SAR 0x82
499 /* WARNING: the content of this string encodes token numbers */
500 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";
502 #define TOK_EOF (-1) /* end of file */
503 #define TOK_LINEFEED 10 /* line feed */
505 /* all identificators and strings have token above that */
506 #define TOK_IDENT 256
509 TOK_LAST
= TOK_IDENT
- 1,
510 #define DEF(id, str) id,
515 static const char *tcc_keywords
=
516 #define DEF(id, str) str "\0"
521 #define TOK_UIDENT TOK_DEFINE
524 #define snprintf _snprintf
525 #define vsnprintf _vsnprintf
528 #if defined(WIN32) || defined(TCC_UCLIBC)
529 /* currently incorrect */
530 long double strtold(const char *nptr
, char **endptr
)
532 return (long double)strtod(nptr
, endptr
);
534 float strtof(const char *nptr
, char **endptr
)
536 return (float)strtod(nptr
, endptr
);
539 /* XXX: need to define this to use them in non ISOC99 context */
540 extern float strtof (const char *__nptr
, char **__endptr
);
541 extern long double strtold (const char *__nptr
, char **__endptr
);
544 static char *pstrcpy(char *buf
, int buf_size
, const char *s
);
545 static char *pstrcat(char *buf
, int buf_size
, const char *s
);
547 static void sum(int l
);
548 static void next(void);
549 static void next_nomacro(void);
550 static void parse_expr_type(CType
*type
);
551 static void expr_type(CType
*type
);
552 static void unary_type(CType
*type
);
553 static int expr_const(void);
554 static void expr_eq(void);
555 static void gexpr(void);
556 static void decl(int l
);
557 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
558 int first
, int size_only
);
559 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
560 int has_init
, int v
, int scope
);
562 void gv2(int rc1
, int rc2
);
563 void move_reg(int r
, int s
);
564 void save_regs(int n
);
565 void save_reg(int r
);
571 static void macro_subst(TokenString
*tok_str
,
572 Sym
**nested_list
, int *macro_str
);
573 int save_reg_forced(int r
);
575 void force_charshort_cast(int t
);
576 static void gen_cast(CType
*type
);
578 static Sym
*sym_find(int v
);
579 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
);
582 int type_size(CType
*type
, int *a
);
583 static inline CType
*pointed_type(CType
*type
);
584 static int pointed_size(CType
*type
);
585 static int lvalue_type(int t
);
586 static int is_compatible_types(CType
*type1
, CType
*type2
);
587 static int parse_btype(CType
*type
, AttributeDef
*ad
);
588 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
);
590 void error(const char *fmt
, ...);
592 void vset(CType
*type
, int r
, int v
);
593 void type_to_str(char *buf
, int buf_size
,
594 CType
*type
, const char *varstr
);
595 char *get_tok_str(int v
, CValue
*cv
);
596 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
597 unsigned long offset
, unsigned long size
);
598 static Sym
*external_global_sym(int v
, CType
*type
, int r
);
600 /* section generation */
601 static void section_realloc(Section
*sec
, unsigned long new_size
);
602 static void *section_ptr_add(Section
*sec
, unsigned long size
);
603 static void put_extern_sym(Sym
*sym
, Section
*section
,
604 unsigned long value
, unsigned long size
);
605 static void greloc(Section
*s
, Sym
*sym
, unsigned long addr
, int type
);
606 static int put_elf_str(Section
*s
, const char *sym
);
607 static int put_elf_sym(Section
*s
,
608 unsigned long value
, unsigned long size
,
609 int info
, int other
, int shndx
, const char *name
);
610 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
611 int info
, int sh_num
, const char *name
);
612 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
613 int type
, int symbol
);
614 static void put_stabs(const char *str
, int type
, int other
, int desc
,
615 unsigned long value
);
616 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
617 unsigned long value
, Section
*sec
, int sym_index
);
618 static void put_stabn(int type
, int other
, int desc
, int value
);
619 static void put_stabd(int type
, int other
, int desc
);
620 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
);
622 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
623 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
624 static int tcc_add_file_internal(TCCState
*s
, const char *filename
, int flags
);
626 /* true if float/double/long double type */
627 static inline int is_float(int t
)
631 return bt
== VT_LDOUBLE
|| bt
== VT_DOUBLE
|| bt
== VT_FLOAT
;
634 #ifdef TCC_TARGET_I386
635 #include "i386-gen.c"
641 #ifdef CONFIG_TCC_STATIC
643 #define RTLD_LAZY 0x001
644 #define RTLD_NOW 0x002
645 #define RTLD_GLOBAL 0x100
646 #define RTLD_DEFAULT NULL
648 /* dummy function for profiling */
649 void *dlopen(const char *filename
, int flag
)
654 const char *dlerror(void)
659 typedef struct TCCSyms
{
664 #define TCCSYM(a) { #a, &a, },
666 /* add the symbol you want here if no dynamic linking is done */
667 static TCCSyms tcc_syms
[] = {
675 void *dlsym(void *handle
, const char *symbol
)
679 while (p
->str
!= NULL
) {
680 if (!strcmp(p
->str
, symbol
))
689 /********************************************************/
691 /* we use our own 'finite' function to avoid potential problems with
692 non standard math libs */
693 /* XXX: endianness dependant */
694 int ieee_finite(double d
)
697 return ((unsigned)((p
[1] | 0x800fffff) + 1)) >> 31;
700 /* copy a string and truncate it. */
701 static char *pstrcpy(char *buf
, int buf_size
, const char *s
)
708 q_end
= buf
+ buf_size
- 1;
720 /* strcat and truncate. */
721 static char *pstrcat(char *buf
, int buf_size
, const char *s
)
726 pstrcpy(buf
+ len
, buf_size
- len
, s
);
730 /* memory management */
736 static inline void tcc_free(void *ptr
)
739 mem_cur_size
-= malloc_usable_size(ptr
);
744 static void *tcc_malloc(unsigned long size
)
749 error("memory full");
751 mem_cur_size
+= malloc_usable_size(ptr
);
752 if (mem_cur_size
> mem_max_size
)
753 mem_max_size
= mem_cur_size
;
758 static void *tcc_mallocz(unsigned long size
)
761 ptr
= tcc_malloc(size
);
762 memset(ptr
, 0, size
);
766 static inline void *tcc_realloc(void *ptr
, unsigned long size
)
770 mem_cur_size
-= malloc_usable_size(ptr
);
772 ptr1
= realloc(ptr
, size
);
774 /* NOTE: count not correct if alloc error, but not critical */
775 mem_cur_size
+= malloc_usable_size(ptr1
);
776 if (mem_cur_size
> mem_max_size
)
777 mem_max_size
= mem_cur_size
;
782 static char *tcc_strdup(const char *str
)
785 ptr
= tcc_malloc(strlen(str
) + 1);
790 #define free(p) use_tcc_free(p)
791 #define malloc(s) use_tcc_malloc(s)
792 #define realloc(p, s) use_tcc_realloc(p, s)
794 static void dynarray_add(void ***ptab
, int *nb_ptr
, void *data
)
801 /* every power of two we double array size */
802 if ((nb
& (nb
- 1)) == 0) {
807 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
809 error("memory full");
816 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
820 sec
= tcc_mallocz(sizeof(Section
));
821 pstrcpy(sec
->name
, sizeof(sec
->name
), name
);
822 sec
->sh_type
= sh_type
;
823 sec
->sh_flags
= sh_flags
;
830 sec
->sh_addralign
= 4;
833 sec
->sh_addralign
= 1;
836 sec
->sh_addralign
= 32; /* default conservative alignment */
840 /* only add section if not private */
841 if (!(sh_flags
& SHF_PRIVATE
)) {
842 sec
->sh_num
= s1
->nb_sections
;
843 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
848 static void free_section(Section
*s
)
854 /* realloc section and set its content to zero */
855 static void section_realloc(Section
*sec
, unsigned long new_size
)
860 size
= sec
->data_allocated
;
863 while (size
< new_size
)
865 data
= tcc_realloc(sec
->data
, size
);
867 error("memory full");
868 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
870 sec
->data_allocated
= size
;
873 /* reserve at least 'size' bytes in section 'sec' from
875 static void *section_ptr_add(Section
*sec
, unsigned long size
)
877 unsigned long offset
, offset1
;
879 offset
= sec
->data_offset
;
880 offset1
= offset
+ size
;
881 if (offset1
> sec
->data_allocated
)
882 section_realloc(sec
, offset1
);
883 sec
->data_offset
= offset1
;
884 return sec
->data
+ offset
;
887 /* return a reference to a section, and create it if it does not
889 Section
*find_section(TCCState
*s1
, const char *name
)
893 for(i
= 1; i
< s1
->nb_sections
; i
++) {
894 sec
= s1
->sections
[i
];
895 if (!strcmp(name
, sec
->name
))
898 /* sections are created as PROGBITS */
899 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
902 /* update sym->c so that it points to an external symbol in section
903 'section' with value 'value' */
904 static void put_extern_sym(Sym
*sym
, Section
*section
,
905 unsigned long value
, unsigned long size
)
907 int sym_type
, sym_bind
, sh_num
, info
;
912 sh_num
= section
->sh_num
;
916 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
)
919 sym_type
= STT_OBJECT
;
920 if (sym
->type
.t
& VT_STATIC
)
921 sym_bind
= STB_LOCAL
;
923 sym_bind
= STB_GLOBAL
;
925 name
= get_tok_str(sym
->v
, NULL
);
926 #ifdef CONFIG_TCC_BCHECK
927 if (do_bounds_check
) {
930 /* XXX: avoid doing that for statics ? */
931 /* if bound checking is activated, we change some function
932 names by adding the "__bound" prefix */
935 /* XXX: we rely only on malloc hooks */
947 strcpy(buf
, "__bound_");
954 info
= ELF32_ST_INFO(sym_bind
, sym_type
);
955 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, sh_num
, name
);
957 esym
= &((Elf32_Sym
*)symtab_section
->data
)[sym
->c
];
958 esym
->st_value
= value
;
959 esym
->st_size
= size
;
960 esym
->st_shndx
= sh_num
;
964 /* add a new relocation entry to symbol 'sym' in section 's' */
965 static void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
968 put_extern_sym(sym
, NULL
, 0, 0);
969 /* now we can add ELF relocation info */
970 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
973 static inline int isid(int c
)
975 return (c
>= 'a' && c
<= 'z') ||
976 (c
>= 'A' && c
<= 'Z') ||
980 static inline int isnum(int c
)
982 return c
>= '0' && c
<= '9';
985 static inline int isoct(int c
)
987 return c
>= '0' && c
<= '7';
990 static inline int toup(int c
)
992 if (c
>= 'a' && c
<= 'z')
993 return c
- 'a' + 'A';
998 static void strcat_vprintf(char *buf
, int buf_size
, const char *fmt
, va_list ap
)
1002 vsnprintf(buf
+ len
, buf_size
- len
, fmt
, ap
);
1005 static void strcat_printf(char *buf
, int buf_size
, const char *fmt
, ...)
1009 strcat_vprintf(buf
, buf_size
, fmt
, ap
);
1013 void error1(TCCState
*s1
, int is_warning
, const char *fmt
, va_list ap
)
1020 for(f
= s1
->include_stack
; f
< s1
->include_stack_ptr
; f
++)
1021 strcat_printf(buf
, sizeof(buf
), "In file included from %s:%d:\n",
1022 (*f
)->filename
, (*f
)->line_num
);
1023 if (file
->line_num
> 0) {
1024 strcat_printf(buf
, sizeof(buf
),
1025 "%s:%d: ", file
->filename
, file
->line_num
);
1027 strcat_printf(buf
, sizeof(buf
),
1028 "%s: ", file
->filename
);
1031 strcat_printf(buf
, sizeof(buf
),
1035 strcat_printf(buf
, sizeof(buf
), "warning: ");
1036 strcat_vprintf(buf
, sizeof(buf
), fmt
, ap
);
1038 if (!s1
->error_func
) {
1039 /* default case: stderr */
1040 fprintf(stderr
, "%s\n", buf
);
1042 s1
->error_func(s1
->error_opaque
, buf
);
1049 void tcc_set_error_func(TCCState
*s
, void *error_opaque
,
1050 void (*error_func
)(void *opaque
, const char *msg
))
1052 s
->error_opaque
= error_opaque
;
1053 s
->error_func
= error_func
;
1057 /* error without aborting current compilation */
1058 void error_noabort(const char *fmt
, ...)
1060 TCCState
*s1
= tcc_state
;
1064 error1(s1
, 0, fmt
, ap
);
1068 void error(const char *fmt
, ...)
1070 TCCState
*s1
= tcc_state
;
1074 error1(s1
, 0, fmt
, ap
);
1076 /* better than nothing: in some cases, we accept to handle errors */
1077 if (s1
->error_set_jmp_enabled
) {
1078 longjmp(s1
->error_jmp_buf
, 1);
1080 /* XXX: suppress it someday */
1085 void expect(const char *msg
)
1087 error("%s expected", msg
);
1090 void warning(const char *fmt
, ...)
1092 TCCState
*s1
= tcc_state
;
1096 error1(s1
, 1, fmt
, ap
);
1103 error("'%c' expected", c
);
1107 void test_lvalue(void)
1109 if (!(vtop
->r
& VT_LVAL
))
1113 TokenSym
*tok_alloc(const char *str
, int len
)
1115 TokenSym
*ts
, **pts
, **ptable
;
1120 h
= (h
* 263 + ((unsigned char *)str
)[i
]) & (TOK_HASH_SIZE
- 1);
1122 pts
= &hash_ident
[h
];
1127 if (ts
->len
== len
&& !memcmp(ts
->str
, str
, len
))
1129 pts
= &(ts
->hash_next
);
1132 if (tok_ident
>= SYM_FIRST_ANOM
)
1133 error("memory full");
1135 /* expand token table if needed */
1136 i
= tok_ident
- TOK_IDENT
;
1137 if ((i
% TOK_ALLOC_INCR
) == 0) {
1138 ptable
= tcc_realloc(table_ident
, (i
+ TOK_ALLOC_INCR
) * sizeof(TokenSym
*));
1140 error("memory full");
1141 table_ident
= ptable
;
1144 ts
= tcc_malloc(sizeof(TokenSym
) + len
);
1145 table_ident
[i
] = ts
;
1146 ts
->tok
= tok_ident
++;
1147 ts
->sym_define
= NULL
;
1148 ts
->sym_label
= NULL
;
1149 ts
->sym_struct
= NULL
;
1150 ts
->sym_identifier
= NULL
;
1152 ts
->hash_next
= NULL
;
1153 memcpy(ts
->str
, str
, len
+ 1);
1158 /* CString handling */
1160 static void cstr_realloc(CString
*cstr
, int new_size
)
1165 size
= cstr
->size_allocated
;
1167 size
= 8; /* no need to allocate a too small first string */
1168 while (size
< new_size
)
1170 data
= tcc_realloc(cstr
->data_allocated
, size
);
1172 error("memory full");
1173 cstr
->data_allocated
= data
;
1174 cstr
->size_allocated
= size
;
1179 static void cstr_ccat(CString
*cstr
, int ch
)
1182 size
= cstr
->size
+ 1;
1183 if (size
> cstr
->size_allocated
)
1184 cstr_realloc(cstr
, size
);
1185 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1189 static void cstr_cat(CString
*cstr
, const char *str
)
1201 /* add a wide char */
1202 static void cstr_wccat(CString
*cstr
, int ch
)
1205 size
= cstr
->size
+ sizeof(int);
1206 if (size
> cstr
->size_allocated
)
1207 cstr_realloc(cstr
, size
);
1208 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1212 static void cstr_new(CString
*cstr
)
1214 memset(cstr
, 0, sizeof(CString
));
1217 /* free string and reset it to NULL */
1218 static void cstr_free(CString
*cstr
)
1220 tcc_free(cstr
->data_allocated
);
1224 #define cstr_reset(cstr) cstr_free(cstr)
1226 /* XXX: unicode ? */
1227 static void add_char(CString
*cstr
, int c
)
1229 if (c
== '\'' || c
== '\"' || c
== '\\') {
1230 /* XXX: could be more precise if char or string */
1231 cstr_ccat(cstr
, '\\');
1233 if (c
>= 32 && c
<= 126) {
1236 cstr_ccat(cstr
, '\\');
1238 cstr_ccat(cstr
, 'n');
1240 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1241 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1242 cstr_ccat(cstr
, '0' + (c
& 7));
1247 /* XXX: buffer overflow */
1248 /* XXX: float tokens */
1249 char *get_tok_str(int v
, CValue
*cv
)
1251 static char buf
[STRING_MAX_SIZE
+ 1];
1252 static CString cstr_buf
;
1258 /* NOTE: to go faster, we give a fixed buffer for small strings */
1259 cstr_reset(&cstr_buf
);
1260 cstr_buf
.data
= buf
;
1261 cstr_buf
.size_allocated
= sizeof(buf
);
1267 /* XXX: not quite exact, but only useful for testing */
1268 sprintf(p
, "%u", cv
->ui
);
1272 /* XXX: not quite exact, but only useful for testing */
1273 sprintf(p
, "%Lu", cv
->ull
);
1277 cstr_ccat(&cstr_buf
, '\'');
1278 add_char(&cstr_buf
, cv
->i
);
1279 cstr_ccat(&cstr_buf
, '\'');
1280 cstr_ccat(&cstr_buf
, '\0');
1284 len
= cstr
->size
- 1;
1286 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1287 cstr_ccat(&cstr_buf
, '\0');
1292 cstr_ccat(&cstr_buf
, '\"');
1294 len
= cstr
->size
- 1;
1296 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1298 len
= (cstr
->size
/ sizeof(int)) - 1;
1300 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1302 cstr_ccat(&cstr_buf
, '\"');
1303 cstr_ccat(&cstr_buf
, '\0');
1312 return strcpy(p
, "<<=");
1314 return strcpy(p
, ">>=");
1316 if (v
< TOK_IDENT
) {
1317 /* search in two bytes table */
1331 } else if (v
< tok_ident
) {
1332 return table_ident
[v
- TOK_IDENT
]->str
;
1333 } else if (v
>= SYM_FIRST_ANOM
) {
1334 /* special name for anonymous symbol */
1335 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1337 /* should never happen */
1342 return cstr_buf
.data
;
1345 /* push, without hashing */
1346 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1349 s
= tcc_malloc(sizeof(Sym
));
1360 /* find a symbol and return its associated structure. 's' is the top
1361 of the symbol stack */
1362 static Sym
*sym_find2(Sym
*s
, int v
)
1372 /* structure lookup */
1373 static Sym
*struct_find(int v
)
1376 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1378 return table_ident
[v
]->sym_struct
;
1381 /* find an identifier */
1382 static inline Sym
*sym_find(int v
)
1385 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1387 return table_ident
[v
]->sym_identifier
;
1390 /* push a given symbol on the symbol stack */
1391 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1400 s
= sym_push2(ps
, v
, type
->t
, c
);
1401 s
->type
.ref
= type
->ref
;
1403 /* don't record fields or anonymous symbols */
1405 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1406 /* record symbol in token array */
1407 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1409 ps
= &ts
->sym_struct
;
1411 ps
= &ts
->sym_identifier
;
1418 /* push a global identifier */
1419 static Sym
*global_identifier_push(int v
, int t
, int c
)
1422 s
= sym_push2(&global_stack
, v
, t
, c
);
1423 /* don't record anonymous symbol */
1424 if (v
< SYM_FIRST_ANOM
) {
1425 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1426 /* modify the top most local identifier, so that
1427 sym_identifier will point to 's' when popped */
1429 ps
= &(*ps
)->prev_tok
;
1436 /* pop symbols until top reaches 'b' */
1437 static void sym_pop(Sym
**ptop
, Sym
*b
)
1447 /* remove symbol in token array */
1449 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1450 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1452 ps
= &ts
->sym_struct
;
1454 ps
= &ts
->sym_identifier
;
1465 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1470 fd
= open(filename
, O_RDONLY
);
1473 bf
= tcc_malloc(sizeof(BufferedFile
));
1479 bf
->buf_ptr
= bf
->buffer
;
1480 bf
->buf_end
= bf
->buffer
;
1481 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1482 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1484 bf
->ifndef_macro
= 0;
1485 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1486 // printf("opening '%s'\n", filename);
1490 void tcc_close(BufferedFile
*bf
)
1492 total_lines
+= bf
->line_num
;
1497 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1498 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1500 /* fill input buffer and return next char */
1501 int tcc_getc_slow(BufferedFile
*bf
)
1504 /* only tries to read if really end of buffer */
1505 if (bf
->buf_ptr
>= bf
->buf_end
) {
1507 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1514 bf
->buf_ptr
= bf
->buffer
;
1515 bf
->buf_end
= bf
->buffer
+ len
;
1516 *bf
->buf_end
= CH_EOB
;
1518 if (bf
->buf_ptr
< bf
->buf_end
) {
1519 return *bf
->buf_ptr
++;
1521 bf
->buf_ptr
= bf
->buf_end
;
1526 /* no need to put that inline */
1527 void handle_eob(void)
1529 TCCState
*s1
= tcc_state
;
1531 ch1
= tcc_getc_slow(file
);
1535 if (return_linefeed
) {
1539 if (s1
->include_stack_ptr
== s1
->include_stack
)
1541 /* add end of include file debug info */
1543 put_stabd(N_EINCL
, 0, 0);
1545 /* pop include stack */
1547 s1
->include_stack_ptr
--;
1548 file
= *s1
->include_stack_ptr
;
1552 /* read next char from current input file */
1553 static inline void inp(void)
1555 ch1
= TCC_GETC(file
);
1556 /* end of buffer/file handling */
1561 // printf("ch1=%c 0x%x\n", ch1, ch1);
1564 /* handle '\\n' and '\\r\n' */
1565 static void handle_stray(void)
1570 } else if (ch1
== '\r') {
1573 error("invalid character after '\\'");
1580 } while (ch
== '\\');
1583 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1585 static inline void minp(void)
1594 /* same as minp, but also skip comments */
1595 static void cinp(void)
1602 /* single line C++ comments */
1604 while (ch1
!= '\n' && ch1
!= CH_EOF
)
1606 ch
= ' '; /* return space */
1607 } else if (ch1
== '*') {
1610 while (ch1
!= CH_EOF
) {
1613 if (c
== '*' && ch1
== '/') {
1615 ch
= ' '; /* return space */
1627 /* space exlcuding newline */
1628 static inline int is_space(int ch
)
1630 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1633 static inline void skip_spaces(void)
1635 while (is_space(ch
))
1639 /* skip block of text until #else, #elif or #endif. skip also pairs of
1641 void preprocess_skip(void)
1646 while (ch
!= '\n') {
1657 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1659 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1661 else if (tok
== TOK_ENDIF
)
1667 /* ParseState handling */
1669 /* XXX: currently, no include file info is stored. Thus, we cannot display
1670 accurate messages if the function or data definition spans multiple
1673 /* save current parse state in 's' */
1674 void save_parse_state(ParseState
*s
)
1676 s
->line_num
= file
->line_num
;
1677 s
->macro_ptr
= macro_ptr
;
1682 /* restore parse state from 's' */
1683 void restore_parse_state(ParseState
*s
)
1685 file
->line_num
= s
->line_num
;
1686 macro_ptr
= s
->macro_ptr
;
1691 /* return the number of additionnal 'ints' necessary to store the
1693 static inline int tok_ext_size(int t
)
1712 return LDOUBLE_SIZE
/ 4;
1718 /* token string handling */
1720 static inline void tok_str_new(TokenString
*s
)
1724 s
->last_line_num
= -1;
1727 static void tok_str_free(int *str
)
1738 if (t
== TOK_STR
|| t
== TOK_LSTR
|| t
== TOK_PPNUM
) {
1739 /* XXX: use a macro to be portable on 64 bit ? */
1740 cstr
= (CString
*)(*p
++);
1744 p
+= tok_ext_size(t
);
1750 static void tok_str_add(TokenString
*s
, int t
)
1756 if ((len
& 63) == 0) {
1757 str
= tcc_realloc(str
, (len
+ 64) * sizeof(int));
1766 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1769 CString
*cstr
, *cstr1
;
1773 if (t
== TOK_STR
|| t
== TOK_LSTR
|| t
== TOK_PPNUM
) {
1774 /* special case: need to duplicate string */
1776 cstr
= tcc_malloc(sizeof(CString
));
1779 cstr
->size_allocated
= size
;
1780 cstr
->data_allocated
= tcc_malloc(size
);
1781 cstr
->data
= cstr
->data_allocated
;
1782 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1784 tok_str_add(s
, cv1
.tab
[0]);
1786 n
= tok_ext_size(t
);
1788 tok_str_add(s
, cv
->tab
[i
]);
1792 /* add the current parse token in token string 's' */
1793 static void tok_str_add_tok(TokenString
*s
)
1797 /* save line number info */
1798 if (file
->line_num
!= s
->last_line_num
) {
1799 s
->last_line_num
= file
->line_num
;
1800 cval
.i
= s
->last_line_num
;
1801 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1803 tok_str_add2(s
, tok
, &tokc
);
1806 /* get a token from an integer array and increment pointer accordingly */
1807 static int tok_get(int **tok_str
, CValue
*cv
)
1813 n
= tok_ext_size(t
);
1820 /* defines handling */
1821 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
1825 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
1826 s
->next
= first_arg
;
1827 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
1830 /* undefined a define symbol. Its name is just set to zero */
1831 static void define_undef(Sym
*s
)
1835 if (v
>= TOK_IDENT
&& v
< tok_ident
)
1836 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
1840 static inline Sym
*define_find(int v
)
1843 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1845 return table_ident
[v
]->sym_define
;
1848 /* free define stack until top reaches 'b' */
1849 static void free_defines(Sym
*b
)
1857 /* do not free args or predefined defines */
1859 tok_str_free((int *)top
->c
);
1861 if (v
>= TOK_IDENT
&& v
< tok_ident
)
1862 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
1870 static Sym
*label_find(int v
)
1873 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1875 return table_ident
[v
]->sym_label
;
1878 static Sym
*label_push(int v
, int flags
)
1881 s
= sym_push2(&label_stack
, v
, 0, 0);
1883 table_ident
[v
- TOK_IDENT
]->sym_label
= s
;
1887 /* eval an expression for #if/#elif */
1888 int expr_preprocess(void)
1894 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1895 next(); /* do macro subst */
1896 if (tok
== TOK_DEFINED
) {
1901 c
= define_find(tok
) != 0;
1906 } else if (tok
>= TOK_IDENT
) {
1907 /* if undefined macro */
1911 tok_str_add_tok(&str
);
1913 tok_str_add(&str
, -1); /* simulate end of file */
1914 tok_str_add(&str
, 0);
1915 /* now evaluate C constant expression */
1916 macro_ptr
= str
.str
;
1920 tok_str_free(str
.str
);
1924 #if defined(DEBUG) || defined(PP_DEBUG)
1925 void tok_print(int *str
)
1931 t
= tok_get(&str
, &cval
);
1934 printf(" %s", get_tok_str(t
, &cval
));
1940 /* parse after #define */
1941 void parse_define(void)
1943 Sym
*s
, *first
, **ps
;
1944 int v
, t
, varg
, is_vaargs
;
1949 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
1950 /* XXX: should check if same macro (ANSI) */
1953 /* '(' must be just after macro definition for MACRO_FUNC */
1958 while (tok
!= ')') {
1962 if (varg
== TOK_DOTS
) {
1963 varg
= TOK___VA_ARGS__
;
1965 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1969 if (varg
< TOK_IDENT
)
1970 error("badly punctuated parameter list");
1971 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1982 /* EOF testing necessary for '-D' handling */
1983 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1984 tok_str_add2(&str
, tok
, &tokc
);
1987 tok_str_add(&str
, 0);
1989 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1992 define_push(v
, t
, str
.str
, first
);
1995 /* XXX: use a token or a hash table to accelerate matching ? */
1996 static CachedInclude
*search_cached_include(TCCState
*s1
,
1997 int type
, const char *filename
)
2002 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
2003 e
= s1
->cached_includes
[i
];
2004 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2010 static inline void add_cached_include(TCCState
*s1
, int type
,
2011 const char *filename
, int ifndef_macro
)
2015 if (search_cached_include(s1
, type
, filename
))
2018 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2020 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2024 strcpy(e
->filename
, filename
);
2025 e
->ifndef_macro
= ifndef_macro
;
2026 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2031 INCLUDE_STATE_NONE
= 0,
2032 INCLUDE_STATE_SEEK_IFNDEF
,
2035 void preprocess(void)
2037 TCCState
*s1
= tcc_state
;
2038 int size
, i
, c
, n
, line_num
;
2039 enum IncludeState state
;
2040 char buf
[1024], *q
, *p
;
2046 return_linefeed
= 1; /* linefeed will be returned as a
2047 token. EOF is also returned as line feed */
2048 state
= INCLUDE_STATE_NONE
;
2061 s
= define_find(tok
);
2062 /* undefine symbol by putting an invalid name */
2071 } else if (ch
== '\"') {
2076 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2077 if ((q
- buf
) < sizeof(buf
) - 1)
2082 /* eat all spaces and comments after include */
2083 /* XXX: slightly incorrect */
2084 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2087 /* computed #include : either we have only strings or
2088 we have anything enclosed in '<>' */
2091 if (tok
== TOK_STR
) {
2092 while (tok
!= TOK_LINEFEED
) {
2093 if (tok
!= TOK_STR
) {
2095 error("'#include' expects \"FILENAME\" or <FILENAME>");
2097 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2103 while (tok
!= TOK_LINEFEED
) {
2104 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2108 /* check syntax and remove '<>' */
2109 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2110 goto include_syntax
;
2111 memmove(buf
, buf
+ 1, len
- 2);
2112 buf
[len
- 2] = '\0';
2118 e
= search_cached_include(s1
, c
, buf
);
2119 if (e
&& define_find(e
->ifndef_macro
)) {
2120 /* no need to parse the include because the 'ifndef macro'
2123 printf("%s: skipping %s\n", file
->filename
, buf
);
2127 /* first search in current dir if "header.h" */
2129 p
= strrchr(file
->filename
, '/');
2131 size
= p
+ 1 - file
->filename
;
2132 if (size
> sizeof(buf1
) - 1)
2133 size
= sizeof(buf1
) - 1;
2134 memcpy(buf1
, file
->filename
, size
);
2136 pstrcat(buf1
, sizeof(buf1
), buf
);
2137 f
= tcc_open(s1
, buf1
);
2141 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2142 error("#include recursion too deep");
2143 /* now search in all the include paths */
2144 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2145 for(i
= 0; i
< n
; i
++) {
2147 if (i
< s1
->nb_include_paths
)
2148 path
= s1
->include_paths
[i
];
2150 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2151 pstrcpy(buf1
, sizeof(buf1
), path
);
2152 pstrcat(buf1
, sizeof(buf1
), "/");
2153 pstrcat(buf1
, sizeof(buf1
), buf
);
2154 f
= tcc_open(s1
, buf1
);
2158 error("include file '%s' not found", buf
);
2162 printf("%s: including %s\n", file
->filename
, buf1
);
2165 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2166 /* push current file in stack */
2167 /* XXX: fix current line init */
2168 *s1
->include_stack_ptr
++ = file
;
2170 /* add include file debug info */
2172 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2174 /* we check for the construct: #ifndef IDENT \n #define IDENT */
2176 /* get first non space char */
2177 while (is_space(ch
) || ch
== '\n')
2181 state
= INCLUDE_STATE_SEEK_IFNDEF
;
2189 c
= expr_preprocess();
2195 if (tok
< TOK_IDENT
)
2196 error("invalid argument for '#if%sdef'", c
? "n" : "");
2197 if (state
== INCLUDE_STATE_SEEK_IFNDEF
) {
2199 file
->ifndef_macro
= tok
;
2201 state
= INCLUDE_STATE_NONE
;
2203 c
= (define_find(tok
) != 0) ^ c
;
2205 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2206 error("memory full");
2207 *s1
->ifdef_stack_ptr
++ = c
;
2210 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2211 error("#else without matching #if");
2212 if (s1
->ifdef_stack_ptr
[-1] & 2)
2213 error("#else after #else");
2214 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2217 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2218 error("#elif without matching #if");
2219 c
= s1
->ifdef_stack_ptr
[-1];
2221 error("#elif after #else");
2222 /* last #if/#elif expression was true: we skip */
2225 c
= expr_preprocess();
2226 s1
->ifdef_stack_ptr
[-1] = c
;
2231 state
= INCLUDE_STATE_NONE
;
2236 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2237 error("#endif without matching #if");
2238 if (file
->ifndef_macro
&&
2239 s1
->ifdef_stack_ptr
== (file
->ifdef_stack_ptr
+ 1)) {
2240 /* '#ifndef macro \n #define macro' was at the start of
2241 file. Now we check if an '#endif' is exactly at the end
2243 while (tok
!= TOK_LINEFEED
)
2245 /* XXX: should also skip comments, but it is more complicated */
2247 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
2248 file
->ifndef_macro
);
2250 /* if not end of file, we must desactivate the ifndef
2252 file
->ifndef_macro
= 0;
2255 s1
->ifdef_stack_ptr
--;
2259 if (tok
!= TOK_CINT
)
2263 if (tok
!= TOK_LINEFEED
) {
2266 pstrcpy(file
->filename
, sizeof(file
->filename
),
2267 (char *)tokc
.cstr
->data
);
2269 /* NOTE: we do it there to avoid problems with linefeed */
2270 file
->line_num
= line_num
;
2277 while (ch
!= '\n' && ch
!= CH_EOF
) {
2278 if ((q
- buf
) < sizeof(buf
) - 1)
2284 error("#error %s", buf
);
2286 warning("#warning %s", buf
);
2289 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
2290 /* '!' is ignored to allow C scripts. numbers are ignored
2291 to emulate cpp behaviour */
2293 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
2297 /* ignore other preprocess commands or #! for C scripts */
2298 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
)
2301 return_linefeed
= 0;
2304 /* read a number in base b */
2305 static int getn(int b
)
2310 if (ch
>= 'a' && ch
<= 'f')
2312 else if (ch
>= 'A' && ch
<= 'F')
2318 if (t
< 0 || t
>= b
)
2326 /* read a character for string or char constant and eval escape codes */
2327 static int getq(void)
2335 /* at most three octal digits */
2339 c
= c
* 8 + ch
- '0';
2342 c
= c
* 8 + ch
- '0';
2347 } else if (ch
== 'x') {
2365 else if (ch
== 'e' && gnu_ext
)
2367 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
2370 error("invalid escaped char");
2373 } else if (c
== '\r' && ch
== '\n') {
2380 /* we use 64 bit numbers */
2383 /* bn = (bn << shift) | or_val */
2384 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2388 for(i
=0;i
<BN_SIZE
;i
++) {
2390 bn
[i
] = (v
<< shift
) | or_val
;
2391 or_val
= v
>> (32 - shift
);
2395 void bn_zero(unsigned int *bn
)
2398 for(i
=0;i
<BN_SIZE
;i
++) {
2403 /* parse number in null terminated string 'p' and return it in the
2405 void parse_number(const char *p
)
2407 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
2409 unsigned int bn
[BN_SIZE
];
2420 goto float_frac_parse
;
2421 } else if (t
== '0') {
2422 if (ch
== 'x' || ch
== 'X') {
2426 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2432 /* parse all digits. cannot check octal numbers at this stage
2433 because of floating point constants */
2435 if (ch
>= 'a' && ch
<= 'f')
2437 else if (ch
>= 'A' && ch
<= 'F')
2445 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2447 error("number too long");
2453 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2454 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2456 /* NOTE: strtox should support that for hexa numbers, but
2457 non ISOC99 libcs do not support it, so we prefer to do
2459 /* hexadecimal or binary floats */
2460 /* XXX: handle overflows */
2472 } else if (t
>= 'a') {
2474 } else if (t
>= 'A') {
2479 bn_lshift(bn
, shift
, t
);
2486 if (t
>= 'a' && t
<= 'f') {
2488 } else if (t
>= 'A' && t
<= 'F') {
2490 } else if (t
>= '0' && t
<= '9') {
2496 error("invalid digit");
2497 bn_lshift(bn
, shift
, t
);
2502 if (ch
!= 'p' && ch
!= 'P')
2503 error("exponent expected");
2509 } else if (ch
== '-') {
2513 if (ch
< '0' || ch
> '9')
2514 error("exponent digits expected");
2515 while (ch
>= '0' && ch
<= '9') {
2516 exp_val
= exp_val
* 10 + ch
- '0';
2519 exp_val
= exp_val
* s
;
2521 /* now we can generate the number */
2522 /* XXX: should patch directly float number */
2523 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
2524 d
= ldexp(d
, exp_val
- frac_bits
);
2529 /* float : should handle overflow */
2531 } else if (t
== 'L') {
2534 /* XXX: not large enough */
2535 tokc
.ld
= (long double)d
;
2541 /* decimal floats */
2543 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2548 while (ch
>= '0' && ch
<= '9') {
2549 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2555 if (ch
== 'e' || ch
== 'E') {
2556 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2560 if (ch
== '-' || ch
== '+') {
2561 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2566 if (ch
< '0' || ch
> '9')
2567 error("exponent digits expected");
2568 while (ch
>= '0' && ch
<= '9') {
2569 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2581 tokc
.f
= strtof(token_buf
, NULL
);
2582 } else if (t
== 'L') {
2585 tokc
.ld
= strtold(token_buf
, NULL
);
2588 tokc
.d
= strtod(token_buf
, NULL
);
2592 unsigned long long n
, n1
;
2595 /* integer number */
2598 if (b
== 10 && *q
== '0') {
2605 /* no need for checks except for base 10 / 8 errors */
2608 } else if (t
>= 'a') {
2610 } else if (t
>= 'A') {
2615 error("invalid digit");
2619 /* detect overflow */
2620 /* XXX: this test is not reliable */
2622 error("integer constant overflow");
2625 /* XXX: not exactly ANSI compliant */
2626 if ((n
& 0xffffffff00000000LL
) != 0) {
2631 } else if (n
> 0x7fffffff) {
2642 error("three 'l's in integer constant");
2645 if (tok
== TOK_CINT
)
2647 else if (tok
== TOK_CUINT
)
2651 } else if (t
== 'U') {
2653 error("two 'u's in integer constant");
2655 if (tok
== TOK_CINT
)
2657 else if (tok
== TOK_CLLONG
)
2664 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2671 /* return next token without macro substitution */
2672 static inline void next_nomacro1(void)
2689 if (return_linefeed
) {
2690 /* XXX: should eat token ? */
2696 /* preprocessor command if # at start of line after
2708 if (start_of_line
) {
2716 tok
= TOK_TWOSHARPS
;
2721 case 'a': case 'b': case 'c': case 'd':
2722 case 'e': case 'f': case 'g': case 'h':
2723 case 'i': case 'j': case 'k': case 'l':
2724 case 'm': case 'n': case 'o': case 'p':
2725 case 'q': case 'r': case 's': case 't':
2726 case 'u': case 'v': case 'w': case 'x':
2728 case 'A': case 'B': case 'C': case 'D':
2729 case 'E': case 'F': case 'G': case 'H':
2730 case 'I': case 'J': case 'K':
2731 case 'M': case 'N': case 'O': case 'P':
2732 case 'Q': case 'R': case 'S': case 'T':
2733 case 'U': case 'V': case 'W': case 'X':
2740 while (isid(ch
) || isnum(ch
)) {
2741 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2742 error("ident too long");
2747 ts
= tok_alloc(token_buf
, q
- token_buf
);
2764 case '0': case '1': case '2': case '3':
2765 case '4': case '5': case '6': case '7':
2768 cstr_reset(&tokcstr
);
2769 /* after the first digit, accept digits, alpha, '.' or sign if
2770 prefixed by 'eEpP' */
2774 cstr_ccat(&tokcstr
, ch
);
2776 if (!(isnum(ch
) || isid(ch
) || ch
== '.' ||
2777 ((ch
== '+' || ch
== '-') &&
2778 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
2781 /* We add a trailing '\0' to ease parsing */
2782 cstr_ccat(&tokcstr
, '\0');
2783 tokc
.cstr
= &tokcstr
;
2787 /* special dot handling because it can also start a number */
2790 cstr_reset(&tokcstr
);
2791 cstr_ccat(&tokcstr
, '.');
2809 /* this cast is needed if >= 128 */
2810 if (tok
== TOK_CCHAR
)
2821 cstr_reset(&tokcstr
);
2822 while (ch
!= '\"') {
2825 error("unterminated string");
2827 cstr_ccat(&tokcstr
, b
);
2829 cstr_wccat(&tokcstr
, b
);
2832 cstr_ccat(&tokcstr
, '\0');
2834 cstr_wccat(&tokcstr
, '\0');
2835 tokc
.cstr
= &tokcstr
;
2844 } else if (ch
== '<') {
2862 } else if (ch
== '>') {
2899 } else if (ch
== '=') {
2911 } else if (ch
== '=') {
2923 } else if (ch
== '=') {
2935 } else if (ch
== '=') {
2938 } else if (ch
== '>') {
2971 /* comments or operator */
2980 else if (ch
== '/' || ch
== '*') {
3006 error("unrecognized character \\x%02x", ch
);
3011 /* return next token without macro substitution. Can read input from
3013 static void next_nomacro(void)
3019 tok
= tok_get(¯o_ptr
, &tokc
);
3020 if (tok
== TOK_LINENUM
) {
3021 file
->line_num
= tokc
.i
;
3030 /* substitute args in macro_str and return allocated string */
3031 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
3033 int *st
, last_tok
, t
, notfirst
;
3042 t
= tok_get(¯o_str
, &cval
);
3047 t
= tok_get(¯o_str
, &cval
);
3050 s
= sym_find2(args
, t
);
3057 cstr_ccat(&cstr
, ' ');
3058 t
= tok_get(&st
, &cval
);
3059 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
3062 cstr_ccat(&cstr
, '\0');
3064 printf("stringize: %s\n", (char *)cstr
.data
);
3068 tok_str_add2(&str
, TOK_STR
, &cval
);
3071 tok_str_add2(&str
, t
, &cval
);
3073 } else if (t
>= TOK_IDENT
) {
3074 s
= sym_find2(args
, t
);
3077 /* if '##' is present before or after, no arg substitution */
3078 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
3079 /* special case for var arg macros : ## eats the
3080 ',' if empty VA_ARGS variable. */
3081 /* XXX: test of the ',' is not 100%
3082 reliable. should fix it to avoid security
3084 if (gnu_ext
&& s
->type
.t
&&
3085 last_tok
== TOK_TWOSHARPS
&&
3086 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
3088 /* suppress ',' '##' */
3091 /* suppress '##' and add variable */
3099 t1
= tok_get(&st
, &cval
);
3102 tok_str_add2(&str
, t1
, &cval
);
3106 macro_subst(&str
, nested_list
, st
);
3109 tok_str_add(&str
, t
);
3112 tok_str_add2(&str
, t
, &cval
);
3116 tok_str_add(&str
, 0);
3120 /* handle the '##' operator */
3121 static int *macro_twosharps(void)
3126 const char *p1
, *p2
;
3128 TokenString macro_str1
;
3132 tok_str_new(¯o_str1
);
3138 while (*macro_ptr
== TOK_TWOSHARPS
) {
3140 macro_ptr1
= macro_ptr
;
3143 t
= tok_get(¯o_ptr
, &cval
);
3145 /* We concatenate the two tokens if we have an
3146 identifier or a preprocessing number */
3148 p1
= get_tok_str(tok
, &tokc
);
3149 cstr_cat(&cstr
, p1
);
3150 p2
= get_tok_str(t
, &cval
);
3151 cstr_cat(&cstr
, p2
);
3152 cstr_ccat(&cstr
, '\0');
3154 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
3155 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
3156 if (tok
== TOK_PPNUM
) {
3157 /* if number, then create a number token */
3158 /* NOTE: no need to allocate because
3159 tok_str_add2() does it */
3162 /* if identifier, we must do a test to
3163 validate we have a correct identifier */
3164 if (t
== TOK_PPNUM
) {
3174 if (!isnum(c
) && !isid(c
))
3178 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
3179 tok
= ts
->tok
; /* modify current token */
3182 const char *str
= cstr
.data
;
3183 const unsigned char *q
;
3185 /* we look for a valid token */
3186 /* XXX: do more extensive checks */
3187 if (!strcmp(str
, ">>=")) {
3189 } else if (!strcmp(str
, "<<=")) {
3191 } else if (strlen(str
) == 2) {
3192 /* search in two bytes table */
3197 if (q
[0] == str
[0] && q
[1] == str
[1])
3204 /* NOTE: because get_tok_str use a static buffer,
3207 p1
= get_tok_str(tok
, &tokc
);
3208 cstr_cat(&cstr
, p1
);
3209 cstr_ccat(&cstr
, '\0');
3210 p2
= get_tok_str(t
, &cval
);
3211 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
3212 /* cannot merge tokens: just add them separately */
3213 tok_str_add2(¯o_str1
, tok
, &tokc
);
3214 /* XXX: free associated memory ? */
3221 tok_str_add2(¯o_str1
, tok
, &tokc
);
3224 tok_str_add(¯o_str1
, 0);
3225 return macro_str1
.str
;
3229 /* do macro substitution of current token with macro 's' and add
3230 result to (tok_str,tok_len). 'nested_list' is the list of all
3231 macros we got inside to avoid recursing. Return non zero if no
3232 substitution needs to be done */
3233 static int macro_subst_tok(TokenString
*tok_str
,
3234 Sym
**nested_list
, Sym
*s
)
3236 Sym
*args
, *sa
, *sa1
;
3237 int mstr_allocated
, parlevel
, *mstr
, t
;
3243 /* if symbol is a macro, prepare substitution */
3244 /* if nested substitution, do nothing */
3245 if (sym_find2(*nested_list
, tok
))
3248 /* special macros */
3249 if (tok
== TOK___LINE__
) {
3250 cval
.i
= file
->line_num
;
3251 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
3252 } else if (tok
== TOK___FILE__
) {
3253 cstrval
= file
->filename
;
3255 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3256 } else if (tok
== TOK___DATE__
) {
3257 cstrval
= "Jan 1 2002";
3259 } else if (tok
== TOK___TIME__
) {
3260 cstrval
= "00:00:00";
3263 cstr_cat(&cstr
, cstrval
);
3264 cstr_ccat(&cstr
, '\0');
3266 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3271 if (s
->type
.t
== MACRO_FUNC
) {
3272 /* NOTE: we do not use next_nomacro to avoid eating the
3273 next token. XXX: find better solution */
3277 while (is_space(ch
) || ch
== '\n')
3281 if (t
!= '(') /* no macro subst */
3284 /* argument macro */
3289 /* NOTE: empty args are allowed, except if no args */
3291 /* handle '()' case */
3292 if (!args
&& tok
== ')')
3295 error("macro '%s' used with too many args",
3296 get_tok_str(s
->v
, 0));
3299 /* NOTE: non zero sa->t indicates VA_ARGS */
3300 while ((parlevel
> 0 ||
3302 (tok
!= ',' || sa
->type
.t
))) &&
3306 else if (tok
== ')')
3308 tok_str_add2(&str
, tok
, &tokc
);
3311 tok_str_add(&str
, 0);
3312 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
3315 /* special case for gcc var args: add an empty
3316 var arg argument if it is omitted */
3317 if (sa
&& sa
->type
.t
&& gnu_ext
)
3327 error("macro '%s' used with too few args",
3328 get_tok_str(s
->v
, 0));
3331 /* now subst each arg */
3332 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3337 tok_str_free((int *)sa
->c
);
3343 sym_push2(nested_list
, s
->v
, 0, 0);
3344 macro_subst(tok_str
, nested_list
, mstr
);
3345 /* pop nested defined symbol */
3347 *nested_list
= sa1
->prev
;
3355 /* do macro substitution of macro_str and add result to
3356 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3357 inside to avoid recursing. */
3358 static void macro_subst(TokenString
*tok_str
,
3359 Sym
**nested_list
, int *macro_str
)
3362 int *saved_macro_ptr
;
3365 saved_macro_ptr
= macro_ptr
;
3366 macro_ptr
= macro_str
;
3367 /* first scan for '##' operator handling */
3368 macro_str1
= macro_twosharps();
3369 macro_ptr
= macro_str1
;
3375 s
= define_find(tok
);
3377 if (macro_subst_tok(tok_str
, nested_list
, s
) != 0)
3381 tok_str_add2(tok_str
, tok
, &tokc
);
3384 macro_ptr
= saved_macro_ptr
;
3385 tok_str_free(macro_str1
);
3388 /* return next token with macro substitution */
3389 static void next(void)
3391 Sym
*nested_list
, *s
;
3394 /* special 'ungettok' case for label parsing */
3403 /* if not reading from macro substituted string, then try
3404 to substitute macros */
3405 if (tok
>= TOK_IDENT
) {
3406 s
= define_find(tok
);
3408 /* we have a macro: we try to substitute */
3411 if (macro_subst_tok(&str
, &nested_list
, s
) == 0) {
3412 /* substitution done, NOTE: maybe empty */
3413 tok_str_add(&str
, 0);
3414 macro_ptr
= str
.str
;
3415 macro_ptr_allocated
= str
.str
;
3422 /* end of macro string: free it */
3423 tok_str_free(macro_ptr_allocated
);
3429 /* convert preprocessor tokens into C tokens */
3430 if (tok
== TOK_PPNUM
) {
3431 parse_number((char *)tokc
.cstr
->data
);
3435 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3439 void swap(int *p
, int *q
)
3447 void vsetc(CType
*type
, int r
, CValue
*vc
)
3451 if (vtop
>= vstack
+ VSTACK_SIZE
)
3452 error("memory full");
3453 /* cannot let cpu flags if other instruction are generated. Also
3454 avoid leaving VT_JMP anywhere except on the top of the stack
3455 because it would complicate the code generator. */
3456 if (vtop
>= vstack
) {
3457 v
= vtop
->r
& VT_VALMASK
;
3458 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
3464 vtop
->r2
= VT_CONST
;
3468 /* push integer constant */
3473 vsetc(&int_type
, VT_CONST
, &cval
);
3476 /* Return a static symbol pointing to a section */
3477 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
3478 unsigned long offset
, unsigned long size
)
3484 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
3485 sym
->type
.ref
= type
->ref
;
3486 sym
->r
= VT_CONST
| VT_SYM
;
3487 put_extern_sym(sym
, sec
, offset
, size
);
3491 /* push a reference to a section offset by adding a dummy symbol */
3492 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
3497 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
3498 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
3501 /* define a new external reference to a symbol 'v' of type 'u' */
3502 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
3508 /* push forward reference */
3509 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
3510 s
->type
.ref
= type
->ref
;
3511 s
->r
= r
| VT_CONST
| VT_SYM
;
3516 /* define a new external reference to a symbol 'v' of type 'u' */
3517 static Sym
*external_sym(int v
, CType
*type
, int r
)
3523 /* push forward reference */
3524 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
3525 s
->type
.t
|= VT_EXTERN
;
3530 /* push a reference to global symbol v */
3531 static void vpush_global_sym(CType
*type
, int v
)
3536 sym
= external_global_sym(v
, type
, 0);
3538 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
3542 void vset(CType
*type
, int r
, int v
)
3547 vsetc(type
, r
, &cval
);
3550 void vseti(int r
, int v
)
3566 void vpushv(SValue
*v
)
3568 if (vtop
>= vstack
+ VSTACK_SIZE
)
3569 error("memory full");
3579 /* save r to the memory stack, and mark it as being free */
3580 void save_reg(int r
)
3582 int l
, saved
, size
, align
;
3586 /* modify all stack values */
3589 for(p
=vstack
;p
<=vtop
;p
++) {
3590 if ((p
->r
& VT_VALMASK
) == r
||
3591 (p
->r2
& VT_VALMASK
) == r
) {
3592 /* must save value on stack if not already done */
3594 /* NOTE: must reload 'r' because r might be equal to r2 */
3595 r
= p
->r
& VT_VALMASK
;
3596 /* store register in the stack */
3598 if ((p
->r
& VT_LVAL
) ||
3599 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
3601 size
= type_size(type
, &align
);
3602 loc
= (loc
- size
) & -align
;
3603 sv
.type
.t
= type
->t
;
3604 sv
.r
= VT_LOCAL
| VT_LVAL
;
3607 #ifdef TCC_TARGET_I386
3608 /* x86 specific: need to pop fp register ST0 if saved */
3610 o(0xd9dd); /* fstp %st(1) */
3613 /* special long long case */
3614 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
3621 /* mark that stack entry as being saved on the stack */
3622 if (p
->r
& VT_LVAL
) {
3623 /* also suppress the bounded flag because the
3624 relocation address of the function was stored in
3626 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
3628 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
3636 /* find a free register of class 'rc'. If none, save one register */
3642 /* find a free register */
3643 for(r
=0;r
<NB_REGS
;r
++) {
3644 if (reg_classes
[r
] & rc
) {
3645 for(p
=vstack
;p
<=vtop
;p
++) {
3646 if ((p
->r
& VT_VALMASK
) == r
||
3647 (p
->r2
& VT_VALMASK
) == r
)
3655 /* no register left : free the first one on the stack (VERY
3656 IMPORTANT to start from the bottom to ensure that we don't
3657 spill registers used in gen_opi()) */
3658 for(p
=vstack
;p
<=vtop
;p
++) {
3659 r
= p
->r
& VT_VALMASK
;
3660 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
3662 /* also look at second register (if long long) */
3663 r
= p
->r2
& VT_VALMASK
;
3664 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
3670 /* Should never comes here */
3674 /* save registers up to (vtop - n) stack entry */
3675 void save_regs(int n
)
3680 for(p
= vstack
;p
<= p1
; p
++) {
3681 r
= p
->r
& VT_VALMASK
;
3688 /* move register 's' to 'r', and flush previous value of r to memory
3690 void move_reg(int r
, int s
)
3703 /* get address of vtop (vtop MUST BE an lvalue) */
3706 vtop
->r
&= ~VT_LVAL
;
3707 /* tricky: if saved lvalue, then we can go back to lvalue */
3708 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
3709 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
3712 #ifdef CONFIG_TCC_BCHECK
3713 /* generate lvalue bound code */
3719 vtop
->r
&= ~VT_MUSTBOUND
;
3720 /* if lvalue, then use checking code before dereferencing */
3721 if (vtop
->r
& VT_LVAL
) {
3722 /* if not VT_BOUNDED value, then make one */
3723 if (!(vtop
->r
& VT_BOUNDED
)) {
3724 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
3725 /* must save type because we must set it to int to get pointer */
3727 vtop
->type
.t
= VT_INT
;
3730 gen_bounded_ptr_add();
3731 vtop
->r
|= lval_type
;
3734 /* then check for dereferencing */
3735 gen_bounded_ptr_deref();
3740 /* store vtop a register belonging to class 'rc'. lvalues are
3741 converted to values. Cannot be used if cannot be converted to
3742 register value (such as structures). */
3745 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
3746 unsigned long long ll
;
3748 /* NOTE: get_reg can modify vstack[] */
3749 if (vtop
->type
.t
& VT_BITFIELD
) {
3750 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
3751 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3752 /* remove bit field info to avoid loops */
3753 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3754 /* generate shifts */
3755 vpushi(32 - (bit_pos
+ bit_size
));
3757 vpushi(32 - bit_size
);
3758 /* NOTE: transformed to SHR if unsigned */
3762 if (is_float(vtop
->type
.t
) &&
3763 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3766 unsigned long offset
;
3768 /* XXX: unify with initializers handling ? */
3769 /* CPUs usually cannot use float constants, so we store them
3770 generically in data segment */
3771 size
= type_size(&vtop
->type
, &align
);
3772 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
3773 data_section
->data_offset
= offset
;
3774 /* XXX: not portable yet */
3775 ptr
= section_ptr_add(data_section
, size
);
3778 ptr
[i
] = vtop
->c
.tab
[i
];
3779 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
3780 vtop
->r
|= VT_LVAL
| VT_SYM
;
3784 #ifdef CONFIG_TCC_BCHECK
3785 if (vtop
->r
& VT_MUSTBOUND
)
3789 r
= vtop
->r
& VT_VALMASK
;
3790 /* need to reload if:
3792 - lvalue (need to dereference pointer)
3793 - already a register, but not in the right class */
3794 if (r
>= VT_CONST
||
3795 (vtop
->r
& VT_LVAL
) ||
3796 !(reg_classes
[r
] & rc
) ||
3797 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
3798 !(reg_classes
[vtop
->r2
] & rc
))) {
3800 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
3801 /* two register type load : expand to two words
3803 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3806 vtop
->c
.ui
= ll
; /* first word */
3808 vtop
->r
= r
; /* save register value */
3809 vpushi(ll
>> 32); /* second word */
3810 } else if (r
>= VT_CONST
||
3811 (vtop
->r
& VT_LVAL
)) {
3812 /* load from memory */
3815 vtop
[-1].r
= r
; /* save register value */
3816 /* increment pointer to get second word */
3817 vtop
->type
.t
= VT_INT
;
3823 /* move registers */
3826 vtop
[-1].r
= r
; /* save register value */
3827 vtop
->r
= vtop
[-1].r2
;
3829 /* allocate second register */
3836 /* write second register */
3838 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
3840 /* lvalue of scalar type : need to use lvalue type
3841 because of possible cast */
3844 /* compute memory access type */
3845 if (vtop
->r
& VT_LVAL_BYTE
)
3847 else if (vtop
->r
& VT_LVAL_SHORT
)
3849 if (vtop
->r
& VT_LVAL_UNSIGNED
)
3853 /* restore wanted type */
3856 /* one register type load */
3865 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3866 void gv2(int rc1
, int rc2
)
3870 /* generate more generic register first. But VT_JMP or VT_CMP
3871 values must be generated first in all cases to avoid possible
3873 v
= vtop
[0].r
& VT_VALMASK
;
3874 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
3879 /* test if reload is needed for first register */
3880 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
3890 /* test if reload is needed for first register */
3891 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
3897 /* expand long long on stack in two int registers */
3902 u
= vtop
->type
.t
& VT_UNSIGNED
;
3905 vtop
[0].r
= vtop
[-1].r2
;
3906 vtop
[0].r2
= VT_CONST
;
3907 vtop
[-1].r2
= VT_CONST
;
3908 vtop
[0].type
.t
= VT_INT
| u
;
3909 vtop
[-1].type
.t
= VT_INT
| u
;
3912 /* build a long long from two ints */
3915 gv2(RC_INT
, RC_INT
);
3916 vtop
[-1].r2
= vtop
[0].r
;
3917 vtop
[-1].type
.t
= t
;
3921 /* rotate n first stack elements to the bottom */
3928 for(i
=-n
+1;i
!=0;i
++)
3929 vtop
[i
] = vtop
[i
+1];
3933 /* pop stack value */
3937 v
= vtop
->r
& VT_VALMASK
;
3938 #ifdef TCC_TARGET_I386
3939 /* for x86, we need to pop the FP stack */
3940 if (v
== REG_ST0
&& !nocode_wanted
) {
3941 o(0xd9dd); /* fstp %st(1) */
3944 if (v
== VT_JMP
|| v
== VT_JMPI
) {
3945 /* need to put correct jump if && or || without test */
3951 /* convert stack entry to register and duplicate its value in another
3959 if ((t
& VT_BTYPE
) == VT_LLONG
) {
3966 /* stack: H L L1 H1 */
3974 /* duplicate value */
3985 load(r1
, &sv
); /* move r to r1 */
3987 /* duplicates value */
3992 /* generate CPU independent (unsigned) long long operations */
3993 void gen_opl(int op
)
3995 int t
, a
, b
, op1
, c
, i
;
4003 func
= TOK___divdi3
;
4006 func
= TOK___udivdi3
;
4009 func
= TOK___moddi3
;
4012 func
= TOK___umoddi3
;
4014 /* call generic long long function */
4015 gfunc_start(&gf
, FUNC_CDECL
);
4018 vpush_global_sym(&func_old_type
, func
);
4022 vtop
->r2
= REG_LRET
;
4035 /* stack: L1 H1 L2 H2 */
4040 vtop
[-2] = vtop
[-3];
4043 /* stack: H1 H2 L1 L2 */
4049 /* stack: H1 H2 L1 L2 ML MH */
4052 /* stack: ML MH H1 H2 L1 L2 */
4056 /* stack: ML MH H1 L2 H2 L1 */
4061 /* stack: ML MH M1 M2 */
4064 } else if (op
== '+' || op
== '-') {
4065 /* XXX: add non carry method too (for MIPS or alpha) */
4071 /* stack: H1 H2 (L1 op L2) */
4074 gen_op(op1
+ 1); /* TOK_xxxC2 */
4077 /* stack: H1 H2 (L1 op L2) */
4080 /* stack: (L1 op L2) H1 H2 */
4082 /* stack: (L1 op L2) (H1 op H2) */
4090 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4091 t
= vtop
[-1].type
.t
;
4095 /* stack: L H shift */
4097 /* constant: simpler */
4098 /* NOTE: all comments are for SHL. the other cases are
4099 done by swaping words */
4110 if (op
!= TOK_SAR
) {
4143 /* XXX: should provide a faster fallback on x86 ? */
4146 func
= TOK___sardi3
;
4149 func
= TOK___shrdi3
;
4152 func
= TOK___shldi3
;
4158 /* compare operations */
4164 /* stack: L1 H1 L2 H2 */
4166 vtop
[-1] = vtop
[-2];
4168 /* stack: L1 L2 H1 H2 */
4171 /* when values are equal, we need to compare low words. since
4172 the jump is inverted, we invert the test too. */
4175 else if (op1
== TOK_GT
)
4177 else if (op1
== TOK_ULT
)
4179 else if (op1
== TOK_UGT
)
4184 if (op1
!= TOK_NE
) {
4188 /* generate non equal test */
4189 /* XXX: NOT PORTABLE yet */
4193 #ifdef TCC_TARGET_I386
4194 b
= psym(0x850f, 0);
4196 error("not implemented");
4209 /* handle integer constant optimizations and various machine
4211 void gen_opic(int op
)
4218 /* currently, we cannot do computations with forward symbols */
4219 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4220 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4224 case '+': v1
->c
.i
+= fc
; break;
4225 case '-': v1
->c
.i
-= fc
; break;
4226 case '&': v1
->c
.i
&= fc
; break;
4227 case '^': v1
->c
.i
^= fc
; break;
4228 case '|': v1
->c
.i
|= fc
; break;
4229 case '*': v1
->c
.i
*= fc
; break;
4236 /* if division by zero, generate explicit division */
4239 error("division by zero in constant");
4243 default: v1
->c
.i
/= fc
; break;
4244 case '%': v1
->c
.i
%= fc
; break;
4245 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
4246 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
4249 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
4250 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
4251 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
4253 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
4254 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
4255 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
4256 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
4257 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
4258 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
4259 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
4260 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
4261 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
4262 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
4264 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
4265 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
4271 /* if commutative ops, put c2 as constant */
4272 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
4273 op
== '|' || op
== '*')) {
4278 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
4281 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
4282 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
4288 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
4289 /* try to use shifts instead of muls or divs */
4290 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
4299 else if (op
== TOK_PDIV
)
4305 } else if (c2
&& (op
== '+' || op
== '-') &&
4306 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
4307 (VT_CONST
| VT_SYM
)) {
4308 /* symbol + constant case */
4315 if (!nocode_wanted
) {
4316 /* call low level op generator */
4325 /* generate a floating point operation with constant propagation */
4326 void gen_opif(int op
)
4334 /* currently, we cannot do computations with forward symbols */
4335 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4336 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4338 if (v1
->type
.t
== VT_FLOAT
) {
4341 } else if (v1
->type
.t
== VT_DOUBLE
) {
4349 /* NOTE: we only do constant propagation if finite number (not
4350 NaN or infinity) (ANSI spec) */
4351 if (!ieee_finite(f1
) || !ieee_finite(f2
))
4355 case '+': f1
+= f2
; break;
4356 case '-': f1
-= f2
; break;
4357 case '*': f1
*= f2
; break;
4361 error("division by zero in constant");
4366 /* XXX: also handles tests ? */
4370 /* XXX: overflow test ? */
4371 if (v1
->type
.t
== VT_FLOAT
) {
4373 } else if (v1
->type
.t
== VT_DOUBLE
) {
4381 if (!nocode_wanted
) {
4389 static int pointed_size(CType
*type
)
4392 return type_size(pointed_type(type
), &align
);
4396 void check_pointer_types(SValue
*p1
, SValue
*p2
)
4398 char buf1
[256], buf2
[256];
4402 if (!is_compatible_types(t1
, t2
)) {
4403 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
4404 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
4405 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
4410 /* generic gen_op: handles types problems */
4413 int u
, t1
, t2
, bt1
, bt2
, t
;
4416 t1
= vtop
[-1].type
.t
;
4417 t2
= vtop
[0].type
.t
;
4418 bt1
= t1
& VT_BTYPE
;
4419 bt2
= t2
& VT_BTYPE
;
4421 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
4422 /* at least one operand is a pointer */
4423 /* relationnal op: must be both pointers */
4424 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4425 // check_pointer_types(vtop, vtop - 1);
4426 /* pointers are handled are unsigned */
4427 t
= VT_INT
| VT_UNSIGNED
;
4430 /* if both pointers, then it must be the '-' op */
4431 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
4433 error("cannot use pointers here");
4434 // check_pointer_types(vtop - 1, vtop);
4435 /* XXX: check that types are compatible */
4436 u
= pointed_size(&vtop
[-1].type
);
4438 /* set to integer type */
4439 vtop
->type
.t
= VT_INT
;
4443 /* exactly one pointer : must be '+' or '-'. */
4444 if (op
!= '-' && op
!= '+')
4445 error("cannot use pointers here");
4446 /* Put pointer as first operand */
4447 if (bt2
== VT_PTR
) {
4451 type1
= vtop
[-1].type
;
4452 /* XXX: cast to int ? (long long case) */
4453 vpushi(pointed_size(&vtop
[-1].type
));
4455 #ifdef CONFIG_TCC_BCHECK
4456 /* if evaluating constant expression, no code should be
4457 generated, so no bound check */
4458 if (do_bounds_check
&& !const_wanted
) {
4459 /* if bounded pointers, we generate a special code to
4466 gen_bounded_ptr_add();
4472 /* put again type if gen_opic() swaped operands */
4475 } else if (is_float(bt1
) || is_float(bt2
)) {
4476 /* compute bigger type and do implicit casts */
4477 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
4479 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
4484 /* floats can only be used for a few operations */
4485 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
4486 (op
< TOK_ULT
|| op
> TOK_GT
))
4487 error("invalid operands for binary operation");
4489 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
4490 /* cast to biggest op */
4492 /* convert to unsigned if it does not fit in a long long */
4493 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4494 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4498 /* integer operations */
4500 /* convert to unsigned if it does not fit in an integer */
4501 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4502 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4505 /* XXX: currently, some unsigned operations are explicit, so
4506 we modify them here */
4507 if (t
& VT_UNSIGNED
) {
4514 else if (op
== TOK_LT
)
4516 else if (op
== TOK_GT
)
4518 else if (op
== TOK_LE
)
4520 else if (op
== TOK_GE
)
4527 /* special case for shifts and long long: we keep the shift as
4529 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
4534 else if ((t
& VT_BTYPE
) == VT_LLONG
)
4538 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4539 /* relationnal op: the result is an int */
4540 vtop
->type
.t
= VT_INT
;
4547 /* generic itof for unsigned long long case */
4548 void gen_cvt_itof1(int t
)
4552 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
4553 (VT_LLONG
| VT_UNSIGNED
)) {
4555 gfunc_start(&gf
, FUNC_CDECL
);
4558 vpush_global_sym(&func_old_type
, TOK___ulltof
);
4559 else if (t
== VT_DOUBLE
)
4560 vpush_global_sym(&func_old_type
, TOK___ulltod
);
4562 vpush_global_sym(&func_old_type
, TOK___ulltold
);
4571 /* generic ftoi for unsigned long long case */
4572 void gen_cvt_ftoi1(int t
)
4577 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
4578 /* not handled natively */
4579 gfunc_start(&gf
, FUNC_CDECL
);
4580 st
= vtop
->type
.t
& VT_BTYPE
;
4583 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
4584 else if (st
== VT_DOUBLE
)
4585 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
4587 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
4591 vtop
->r2
= REG_LRET
;
4597 /* force char or short cast */
4598 void force_charshort_cast(int t
)
4602 /* XXX: add optimization if lvalue : just change type and offset */
4607 if (t
& VT_UNSIGNED
) {
4608 vpushi((1 << bits
) - 1);
4619 /* cast 'vtop' to 'type' */
4620 static void gen_cast(CType
*type
)
4622 int sbt
, dbt
, sf
, df
, c
;
4624 /* special delayed cast for char/short */
4625 /* XXX: in some cases (multiple cascaded casts), it may still
4627 if (vtop
->r
& VT_MUSTCAST
) {
4628 vtop
->r
&= ~VT_MUSTCAST
;
4629 force_charshort_cast(vtop
->type
.t
);
4632 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
4633 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
4635 if (sbt
!= dbt
&& !nocode_wanted
) {
4638 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4640 /* convert from fp to fp */
4642 /* constant case: we can do it now */
4643 /* XXX: in ISOC, cannot do it if error in convert */
4644 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
4645 vtop
->c
.f
= (float)vtop
->c
.d
;
4646 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
4647 vtop
->c
.f
= (float)vtop
->c
.ld
;
4648 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
4649 vtop
->c
.d
= (double)vtop
->c
.f
;
4650 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
4651 vtop
->c
.d
= (double)vtop
->c
.ld
;
4652 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
4653 vtop
->c
.ld
= (long double)vtop
->c
.f
;
4654 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
4655 vtop
->c
.ld
= (long double)vtop
->c
.d
;
4657 /* non constant case: generate code */
4661 /* convert int to fp */
4664 case VT_LLONG
| VT_UNSIGNED
:
4666 /* XXX: add const cases for long long */
4668 case VT_INT
| VT_UNSIGNED
:
4670 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
4671 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
4672 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
4677 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
4678 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
4679 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
4688 /* convert fp to int */
4689 /* we handle char/short/etc... with generic code */
4690 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
4691 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
4696 case VT_LLONG
| VT_UNSIGNED
:
4698 /* XXX: add const cases for long long */
4700 case VT_INT
| VT_UNSIGNED
:
4702 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4703 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4704 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4710 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4711 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4712 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4720 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
4721 /* additionnal cast for char/short/bool... */
4725 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
4726 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
4727 /* scalar to long long */
4729 if (sbt
== (VT_INT
| VT_UNSIGNED
))
4730 vtop
->c
.ll
= vtop
->c
.ui
;
4732 vtop
->c
.ll
= vtop
->c
.i
;
4734 /* machine independant conversion */
4736 /* generate high word */
4737 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
4745 /* patch second register */
4746 vtop
[-1].r2
= vtop
->r
;
4750 } else if (dbt
== VT_BOOL
) {
4751 /* scalar to bool */
4754 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
4755 (dbt
& VT_BTYPE
) == VT_SHORT
) {
4756 force_charshort_cast(dbt
);
4757 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
4759 if (sbt
== VT_LLONG
) {
4760 /* from long long: just take low order word */
4764 /* if lvalue and single word type, nothing to do because
4765 the lvalue already contains the real type size (see
4766 VT_LVAL_xxx constants) */
4772 /* return type size. Put alignment at 'a' */
4773 int type_size(CType
*type
, int *a
)
4778 bt
= type
->t
& VT_BTYPE
;
4779 if (bt
== VT_STRUCT
) {
4782 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
4784 } else if (bt
== VT_PTR
) {
4785 if (type
->t
& VT_ARRAY
) {
4787 return type_size(&s
->type
, a
) * s
->c
;
4792 } else if (bt
== VT_LDOUBLE
) {
4794 return LDOUBLE_SIZE
;
4795 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
4798 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
4801 } else if (bt
== VT_SHORT
) {
4805 /* char, void, function, _Bool */
4811 /* return the pointed type of t */
4812 static inline CType
*pointed_type(CType
*type
)
4814 return &type
->ref
->type
;
4817 /* modify type so that its it is a pointer to type. */
4818 static void mk_pointer(CType
*type
)
4821 s
= sym_push(SYM_FIELD
, type
, 0, -1);
4822 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
4826 static int is_compatible_types(CType
*type1
, CType
*type2
)
4829 int bt1
, bt2
, t1
, t2
;
4831 t1
= type1
->t
& VT_TYPE
;
4832 t2
= type2
->t
& VT_TYPE
;
4833 bt1
= t1
& VT_BTYPE
;
4834 bt2
= t2
& VT_BTYPE
;
4835 if (bt1
== VT_PTR
) {
4836 type1
= pointed_type(type1
);
4837 /* if function, then convert implicitely to function pointer */
4838 if (bt2
!= VT_FUNC
) {
4841 type2
= pointed_type(type2
);
4843 /* void matches everything */
4844 /* XXX: not fully compliant */
4845 if ((type1
->t
& VT_TYPE
) == VT_VOID
|| (type2
->t
& VT_TYPE
) == VT_VOID
)
4847 return is_compatible_types(type1
, type2
);
4848 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4850 } else if (bt1
== VT_FUNC
) {
4855 if (!is_compatible_types(&s1
->type
, &s2
->type
))
4857 /* XXX: not complete */
4858 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
4862 while (s1
!= NULL
) {
4865 if (!is_compatible_types(&s1
->type
, &s2
->type
))
4874 /* XXX: not complete */
4879 /* print a type. If 'varstr' is not NULL, then the variable is also
4880 printed in the type */
4882 /* XXX: add array and function pointers */
4883 void type_to_str(char *buf
, int buf_size
,
4884 CType
*type
, const char *varstr
)
4891 t
= type
->t
& VT_TYPE
;
4894 if (t
& VT_UNSIGNED
)
4895 pstrcat(buf
, buf_size
, "unsigned ");
4925 tstr
= "long double";
4927 pstrcat(buf
, buf_size
, tstr
);
4931 if (bt
== VT_STRUCT
)
4935 pstrcat(buf
, buf_size
, tstr
);
4937 if (v
>= SYM_FIRST_ANOM
)
4938 pstrcat(buf
, buf_size
, "<anonymous>");
4940 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
4944 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
4945 pstrcat(buf
, buf_size
, "(");
4947 while (sa
!= NULL
) {
4948 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
4949 pstrcat(buf
, buf_size
, buf1
);
4952 pstrcat(buf
, buf_size
, ", ");
4954 pstrcat(buf
, buf_size
, ")");
4958 pstrcpy(buf1
, sizeof(buf1
), "*");
4960 pstrcat(buf1
, sizeof(buf1
), varstr
);
4961 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
4965 pstrcat(buf
, buf_size
, " ");
4966 pstrcat(buf
, buf_size
, varstr
);
4971 /* verify type compatibility to store vtop in 'dt' type, and generate
4973 void gen_assign_cast(CType
*dt
)
4976 char buf1
[256], buf2
[256];
4978 st
= &vtop
->type
; /* source type */
4979 if ((dt
->t
& VT_BTYPE
) == VT_PTR
) {
4980 /* special cases for pointers */
4981 /* a function is implicitely a function pointer */
4982 if ((st
->t
& VT_BTYPE
) == VT_FUNC
) {
4983 if (!is_compatible_types(pointed_type(dt
), st
))
4988 /* '0' can also be a pointer */
4989 if ((st
->t
& VT_BTYPE
) == VT_INT
&&
4990 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
4994 if (!is_compatible_types(dt
, st
)) {
4996 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
4997 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
4998 error("cannot cast '%s' to '%s'", buf1
, buf2
);
5004 /* store vtop in lvalue pushed on stack */
5007 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
5010 ft
= vtop
[-1].type
.t
;
5011 sbt
= vtop
->type
.t
& VT_BTYPE
;
5012 dbt
= ft
& VT_BTYPE
;
5013 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
5014 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
5015 /* optimize char/short casts */
5016 delayed_cast
= VT_MUSTCAST
;
5017 vtop
->type
.t
= ft
& VT_TYPE
;
5020 gen_assign_cast(&vtop
[-1].type
);
5023 if (sbt
== VT_STRUCT
) {
5024 /* if structure, only generate pointer */
5025 /* structure assignment : generate memcpy */
5026 /* XXX: optimize if small size */
5027 if (!nocode_wanted
) {
5029 gfunc_start(&gf
, FUNC_CDECL
);
5031 size
= type_size(&vtop
->type
, &align
);
5035 vtop
->type
.t
= VT_INT
;
5040 vtop
->type
.t
= VT_INT
;
5045 vpush_global_sym(&func_old_type
, TOK_memcpy
);
5051 /* leave source on stack */
5052 } else if (ft
& VT_BITFIELD
) {
5053 /* bitfield store handling */
5054 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
5055 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
5056 /* remove bit field info to avoid loops */
5057 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
5059 /* duplicate destination */
5061 vtop
[-1] = vtop
[-2];
5063 /* mask and shift source */
5064 vpushi((1 << bit_size
) - 1);
5068 /* load destination, mask and or with source */
5070 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
5076 #ifdef CONFIG_TCC_BCHECK
5077 /* bound check case */
5078 if (vtop
[-1].r
& VT_MUSTBOUND
) {
5084 if (!nocode_wanted
) {
5088 r
= gv(rc
); /* generate value */
5089 /* if lvalue was saved on stack, must read it */
5090 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
5092 t
= get_reg(RC_INT
);
5094 sv
.r
= VT_LOCAL
| VT_LVAL
;
5095 sv
.c
.ul
= vtop
[-1].c
.ul
;
5097 vtop
[-1].r
= t
| VT_LVAL
;
5100 /* two word case handling : store second register at word + 4 */
5101 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
5103 /* convert to int to increment easily */
5104 vtop
->type
.t
= VT_INT
;
5110 /* XXX: it works because r2 is spilled last ! */
5111 store(vtop
->r2
, vtop
- 1);
5115 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5116 vtop
->r
|= delayed_cast
;
5120 /* post defines POST/PRE add. c is the token ++ or -- */
5121 void inc(int post
, int c
)
5124 vdup(); /* save lvalue */
5126 gv_dup(); /* duplicate value */
5131 vpushi(c
- TOK_MID
);
5133 vstore(); /* store value */
5135 vpop(); /* if post op, return saved value */
5138 /* Parse GNUC __attribute__ extension. Currently, the following
5139 extensions are recognized:
5140 - aligned(n) : set data/function alignment.
5141 - section(x) : generate data/code in this section.
5142 - unused : currently ignored, but may be used someday.
5144 void parse_attribute(AttributeDef
*ad
)
5151 while (tok
!= ')') {
5152 if (tok
< TOK_IDENT
)
5153 expect("attribute name");
5158 case TOK___SECTION__
:
5161 expect("section name");
5162 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
5167 case TOK___ALIGNED__
:
5170 if (n
<= 0 || (n
& (n
- 1)) != 0)
5171 error("alignment must be a positive power of two");
5176 case TOK___UNUSED__
:
5177 /* currently, no need to handle it because tcc does not
5178 track unused objects */
5181 case TOK___NORETURN__
:
5182 /* currently, no need to handle it because tcc does not
5183 track unused objects */
5188 ad
->func_call
= FUNC_CDECL
;
5192 case TOK___STDCALL__
:
5193 ad
->func_call
= FUNC_STDCALL
;
5196 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
5197 /* skip parameters */
5198 /* XXX: skip parenthesis too */
5201 while (tok
!= ')' && tok
!= -1)
5215 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5216 static void struct_decl(CType
*type
, int u
)
5218 int a
, v
, size
, align
, maxalign
, c
, offset
;
5219 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
5224 a
= tok
; /* save decl type */
5229 /* struct already defined ? return it */
5230 /* XXX: check consistency */
5234 error("invalid type");
5241 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, 0);
5242 /* put struct/union/enum name in type */
5250 error("struct/union/enum already defined");
5251 /* cannot be empty */
5258 if (a
== TOK_ENUM
) {
5265 /* enum symbols have static storage */
5266 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
5267 ss
->type
.t
|= VT_STATIC
;
5272 parse_btype(&btype
, &ad
);
5278 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
);
5279 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
5280 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
5281 error("invalid type for '%s'",
5282 get_tok_str(v
, NULL
));
5286 bit_size
= expr_const();
5287 /* XXX: handle v = 0 case for messages */
5289 error("negative width in bit-field '%s'",
5290 get_tok_str(v
, NULL
));
5291 if (v
&& bit_size
== 0)
5292 error("zero width for bit-field '%s'",
5293 get_tok_str(v
, NULL
));
5295 size
= type_size(&type1
, &align
);
5297 if (bit_size
>= 0) {
5298 bt
= type1
.t
& VT_BTYPE
;
5302 error("bitfields must have scalar type");
5304 if (bit_size
> bsize
) {
5305 error("width of '%s' exceeds its type",
5306 get_tok_str(v
, NULL
));
5307 } else if (bit_size
== bsize
) {
5308 /* no need for bit fields */
5310 } else if (bit_size
== 0) {
5311 /* XXX: what to do if only padding in a
5313 /* zero size: means to pad */
5317 /* we do not have enough room ? */
5318 if ((bit_pos
+ bit_size
) > bsize
)
5321 /* XXX: handle LSB first */
5322 type1
.t
|= VT_BITFIELD
|
5323 (bit_pos
<< VT_STRUCT_SHIFT
) |
5324 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
5325 bit_pos
+= bit_size
;
5331 /* add new memory data only if starting
5333 if (lbit_pos
== 0) {
5334 if (a
== TOK_STRUCT
) {
5335 c
= (c
+ align
- 1) & -align
;
5343 if (align
> maxalign
)
5347 printf("add field %s offset=%d",
5348 get_tok_str(v
, NULL
), offset
);
5349 if (type1
.t
& VT_BITFIELD
) {
5350 printf(" pos=%d size=%d",
5351 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
5352 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
5356 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
5360 if (tok
== ';' || tok
== -1)
5370 /* size for struct/union, dummy for enum */
5371 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
5375 /* return 0 if no type declaration. otherwise, return the basic type
5378 static int parse_btype(CType
*type
, AttributeDef
*ad
)
5380 int t
, u
, type_found
;
5384 memset(ad
, 0, sizeof(AttributeDef
));
5395 if ((t
& VT_BTYPE
) != 0)
5396 error("too many basic types");
5410 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
5411 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5412 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
5413 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
5427 if ((t
& VT_BTYPE
) == VT_LONG
) {
5428 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5435 struct_decl(&type1
, VT_ENUM
);
5438 type
->ref
= type1
.ref
;
5442 struct_decl(&type1
, VT_STRUCT
);
5445 /* type modifiers */
5450 case TOK___SIGNED__
:
5453 case TOK___INLINE__
:
5475 /* GNUC attribute */
5476 case TOK___ATTRIBUTE__
:
5477 parse_attribute(ad
);
5482 parse_expr_type(&type1
);
5486 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
5488 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
5489 type
->ref
= s
->type
.ref
;
5496 /* long is never used as type */
5497 if ((t
& VT_BTYPE
) == VT_LONG
)
5498 t
= (t
& ~VT_BTYPE
) | VT_INT
;
5503 static void post_type(CType
*type
, AttributeDef
*ad
)
5506 Sym
**plast
, *s
, *first
;
5511 /* function declaration */
5516 while (tok
!= ')') {
5517 /* read param name and compute offset */
5518 if (l
!= FUNC_OLD
) {
5519 if (!parse_btype(&pt
, &ad1
)) {
5521 error("invalid type");
5528 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5530 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
5531 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
5532 error("parameter declared as void");
5539 /* array must be transformed to pointer according to ANSI C */
5541 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
5546 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5553 /* if no parameters, then old type prototype */
5557 t1
= type
->t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5558 type
->t
&= ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5559 post_type(type
, ad
);
5560 /* we push a anonymous symbol which will contain the function prototype */
5561 s
= sym_push(SYM_FIELD
, type
, ad
->func_call
, l
);
5563 type
->t
= t1
| VT_FUNC
;
5565 } else if (tok
== '[') {
5566 /* array definition */
5572 error("invalid array size");
5575 /* parse next post type */
5576 t1
= type
->t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5577 type
->t
&= ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5578 post_type(type
, ad
);
5580 /* we push a anonymous symbol which will contain the array
5582 s
= sym_push(SYM_FIELD
, type
, 0, n
);
5583 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
5588 /* Parse a type declaration (except basic type), and return the type
5589 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5590 expected. 'type' should contain the basic type. 'ad' is the
5591 attribute definition of the basic type. It can be modified by
5594 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
5597 CType type1
, *type2
;
5599 while (tok
== '*') {
5601 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
5606 /* recursive type */
5607 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5608 type1
.t
= 0; /* XXX: same as int */
5611 /* XXX: this is not correct to modify 'ad' at this point, but
5612 the syntax is not clear */
5613 if (tok
== TOK___ATTRIBUTE__
)
5614 parse_attribute(ad
);
5615 type_decl(&type1
, ad
, v
, td
);
5618 /* type identifier */
5619 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
5623 if (!(td
& TYPE_ABSTRACT
))
5624 expect("identifier");
5628 post_type(type
, ad
);
5629 if (tok
== TOK___ATTRIBUTE__
)
5630 parse_attribute(ad
);
5633 /* append type at the end of type1 */
5646 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5647 static int lvalue_type(int t
)
5654 else if (bt
== VT_SHORT
)
5658 if (t
& VT_UNSIGNED
)
5659 r
|= VT_LVAL_UNSIGNED
;
5663 /* indirection with full error checking and bound check */
5664 static void indir(void)
5666 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
5668 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
5670 vtop
->type
= *pointed_type(&vtop
->type
);
5671 /* an array is never an lvalue */
5672 if (!(vtop
->type
.t
& VT_ARRAY
)) {
5673 vtop
->r
|= lvalue_type(vtop
->type
.t
);
5674 /* if bound checking, the referenced pointer must be checked */
5675 if (do_bounds_check
)
5676 vtop
->r
|= VT_MUSTBOUND
;
5680 /* pass a parameter to a function and do type checking and casting */
5681 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
5686 func_type
= func
->c
;
5687 if (func_type
== FUNC_OLD
||
5688 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5689 /* default casting : only need to convert float to double */
5690 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
5694 } else if (arg
== NULL
) {
5695 error("too many arguments to function");
5697 gen_assign_cast(&arg
->type
);
5699 if (!nocode_wanted
) {
5706 /* parse an expression of the form '(type)' or '(expr)' and return its
5708 static void parse_expr_type(CType
*type
)
5714 if (parse_btype(type
, &ad
)) {
5715 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
5722 static void vpush_tokc(int t
)
5726 vsetc(&type
, VT_CONST
, &tokc
);
5729 static void unary(void)
5731 int n
, t
, align
, size
, r
;
5737 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
5740 } else if (tok
== TOK_CUINT
) {
5741 vpush_tokc(VT_INT
| VT_UNSIGNED
);
5743 } else if (tok
== TOK_CLLONG
) {
5744 vpush_tokc(VT_LLONG
);
5746 } else if (tok
== TOK_CULLONG
) {
5747 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
5749 } else if (tok
== TOK_CFLOAT
) {
5750 vpush_tokc(VT_FLOAT
);
5752 } else if (tok
== TOK_CDOUBLE
) {
5753 vpush_tokc(VT_DOUBLE
);
5755 } else if (tok
== TOK_CLDOUBLE
) {
5756 vpush_tokc(VT_LDOUBLE
);
5758 } else if (tok
== TOK___FUNC__
|| (tok
== TOK___FUNCTION__
&& gnu_ext
)) {
5761 /* special function name identifier */
5763 len
= strlen(funcname
) + 1;
5764 /* generate char[len] type */
5769 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
5770 ptr
= section_ptr_add(data_section
, len
);
5771 memcpy(ptr
, funcname
, len
);
5773 } else if (tok
== TOK_LSTR
) {
5776 } else if (tok
== TOK_STR
) {
5777 /* string parsing */
5783 memset(&ad
, 0, sizeof(AttributeDef
));
5784 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
5790 if (parse_btype(&type
, &ad
)) {
5791 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
5793 /* check ISOC99 compound literal */
5795 /* data is allocated locally by default */
5800 /* all except arrays are lvalues */
5801 if (!(type
.t
& VT_ARRAY
))
5802 r
|= lvalue_type(type
.t
);
5803 memset(&ad
, 0, sizeof(AttributeDef
));
5804 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
5813 } else if (t
== '*') {
5816 } else if (t
== '&') {
5818 /* functions names must be treated as function pointers,
5819 except for unary '&' and sizeof. Since we consider that
5820 functions are not lvalues, we only have to handle it
5821 there and in function calls. */
5822 /* arrays can also be used although they are not lvalues */
5823 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
5824 !(vtop
->type
.t
& VT_ARRAY
))
5826 mk_pointer(&vtop
->type
);
5828 } else if (t
== '!') {
5830 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
5831 vtop
->c
.i
= !vtop
->c
.i
;
5832 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
5833 vtop
->c
.i
= vtop
->c
.i
^ 1;
5835 vseti(VT_JMP
, gtst(1, 0));
5836 } else if (t
== '~') {
5840 } else if (t
== '+') {
5841 /* in order to force cast, we add zero */
5843 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
5844 error("pointer not accepted for unary plus");
5847 } else if (t
== TOK_SIZEOF
|| t
== TOK_ALIGNOF
) {
5849 parse_expr_type(&type
);
5853 size
= type_size(&type
, &align
);
5854 if (t
== TOK_SIZEOF
)
5858 } else if (t
== TOK_INC
|| t
== TOK_DEC
) {
5861 } else if (t
== '-') {
5865 } else if (t
== TOK_LAND
&& gnu_ext
) {
5866 /* allow to take the address of a label */
5867 if (tok
< TOK_UIDENT
)
5868 expect("label identifier");
5869 s
= label_find(tok
);
5871 s
= label_push(tok
, LABEL_FORWARD
);
5874 s
->type
.t
= VT_VOID
;
5875 mk_pointer(&s
->type
);
5876 s
->type
.t
|= VT_STATIC
;
5878 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
5883 expect("identifier");
5887 error("'%s' undeclared", get_tok_str(t
, NULL
));
5888 /* for simple function calls, we tolerate undeclared
5889 external reference to int() function */
5890 s
= external_global_sym(t
, &func_old_type
, 0);
5892 vset(&s
->type
, s
->r
, s
->c
);
5893 /* if forward reference, we must point to s */
5894 if (vtop
->r
& VT_SYM
) {
5901 /* post operations */
5903 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
5906 } else if (tok
== '.' || tok
== TOK_ARROW
) {
5908 if (tok
== TOK_ARROW
)
5913 /* expect pointer on structure */
5914 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
5915 expect("struct or union");
5919 while ((s
= s
->next
) != NULL
) {
5924 error("field not found");
5925 /* add field offset to pointer */
5926 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
5929 /* change type to field type, and set to lvalue */
5930 vtop
->type
= s
->type
;
5931 /* an array is never an lvalue */
5932 if (!(vtop
->type
.t
& VT_ARRAY
)) {
5933 vtop
->r
|= lvalue_type(vtop
->type
.t
);
5934 /* if bound checking, the referenced pointer must be checked */
5935 if (do_bounds_check
)
5936 vtop
->r
|= VT_MUSTBOUND
;
5939 } else if (tok
== '[') {
5945 } else if (tok
== '(') {
5950 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
5951 /* pointer test (no array accepted) */
5952 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
5953 vtop
->type
= *pointed_type(&vtop
->type
);
5954 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
5958 expect("function pointer");
5961 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
5963 /* get return type */
5965 if (!nocode_wanted
) {
5966 save_regs(0); /* save used temporary registers */
5967 gfunc_start(&gf
, s
->r
);
5970 sa
= s
->next
; /* first parameter */
5971 #ifdef INVERT_FUNC_PARAMS
5975 ParseState saved_parse_state
;
5978 /* read each argument and store it on a stack */
5984 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
5988 else if (tok
== ')')
5990 tok_str_add_tok(&str
);
5993 tok_str_add(&str
, -1); /* end of file added */
5994 tok_str_add(&str
, 0);
5995 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
5996 s1
->next
= sa
; /* add reference to argument */
6005 /* now generate code in reverse order by reading the stack */
6006 save_parse_state(&saved_parse_state
);
6008 macro_ptr
= (int *)args
->c
;
6012 expect("',' or ')'");
6013 gfunc_param_typed(&gf
, s
, args
->next
);
6015 tok_str_free((int *)args
->c
);
6019 restore_parse_state(&saved_parse_state
);
6022 /* compute first implicit argument if a structure is returned */
6023 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
6024 /* get some space for the returned structure */
6025 size
= type_size(&s
->type
, &align
);
6026 loc
= (loc
- size
) & -align
;
6028 ret
.r
= VT_LOCAL
| VT_LVAL
;
6029 /* pass it as 'int' to avoid structure arg passing
6031 vseti(VT_LOCAL
, loc
);
6040 /* return in register */
6041 if (is_float(ret
.type
.t
)) {
6044 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
6050 #ifndef INVERT_FUNC_PARAMS
6054 gfunc_param_typed(&gf
, s
, sa
);
6064 error("too few arguments to function");
6071 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
6079 static void uneq(void)
6085 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
6086 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
6087 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
6102 static void sum(int l
)
6110 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
6111 (l
== 1 && (tok
== '+' || tok
== '-')) ||
6112 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
6113 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
6114 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
6115 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
6116 (l
== 5 && tok
== '&') ||
6117 (l
== 6 && tok
== '^') ||
6118 (l
== 7 && tok
== '|') ||
6119 (l
== 8 && tok
== TOK_LAND
) ||
6120 (l
== 9 && tok
== TOK_LOR
)) {
6129 /* only used if non constant */
6130 static void eand(void)
6137 if (tok
!= TOK_LAND
) {
6150 static void eor(void)
6157 if (tok
!= TOK_LOR
) {
6170 /* XXX: better constant handling */
6171 static void expr_eq(void)
6173 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
6175 CType type
, type1
, type2
;
6196 save_regs(1); /* we need to save all registers here except
6197 at the top because it is a branch point */
6201 sv
= *vtop
; /* save value to handle it later */
6202 vtop
--; /* no vpop so that FP stack is not flushed */
6211 bt1
= t1
& VT_BTYPE
;
6213 bt2
= t2
& VT_BTYPE
;
6214 /* cast operands to correct type according to ISOC rules */
6215 if (is_float(bt1
) || is_float(bt2
)) {
6216 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
6217 type
.t
= VT_LDOUBLE
;
6218 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
6223 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
6224 /* cast to biggest op */
6226 /* convert to unsigned if it does not fit in a long long */
6227 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
6228 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
6229 type
.t
|= VT_UNSIGNED
;
6230 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
6231 /* XXX: test pointer compatibility */
6233 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
6234 /* XXX: test structure compatibility */
6236 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
6237 /* NOTE: as an extension, we accept void on only one side */
6240 /* integer operations */
6242 /* convert to unsigned if it does not fit in an integer */
6243 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
6244 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
6245 type
.t
|= VT_UNSIGNED
;
6248 /* now we convert second operand */
6251 if (is_float(type
.t
)) {
6253 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
6254 /* for long longs, we use fixed registers to avoid having
6255 to handle a complicated move */
6259 /* this is horrible, but we must also convert first
6263 /* put again first value and cast it */
6274 static void gexpr(void)
6285 /* parse an expression and return its type without any side effect. */
6286 static void expr_type(CType
*type
)
6298 /* parse a unary expression and return its type without any side
6300 static void unary_type(CType
*type
)
6312 /* parse a constant expression and return value in vtop. */
6313 static void expr_const1(void)
6322 /* parse an integer constant and return its value. */
6323 static int expr_const(void)
6327 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
6328 expect("constant expression");
6334 /* return the label token if current token is a label, otherwise
6336 static int is_label(void)
6341 /* fast test first */
6342 if (tok
< TOK_UIDENT
)
6344 /* no need to save tokc since we expect an identifier */
6352 /* XXX: may not work in all cases (macros ?) */
6361 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
6366 /* generate line number info */
6368 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
6369 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
6371 last_line_num
= file
->line_num
;
6374 if (tok
== TOK_IF
) {
6381 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6383 if (c
== TOK_ELSE
) {
6387 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6388 gsym(d
); /* patch else jmp */
6391 } else if (tok
== TOK_WHILE
) {
6399 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6403 } else if (tok
== '{') {
6407 while (tok
!= '}') {
6410 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6412 /* pop locally defined symbols */
6413 sym_pop(&local_stack
, s
);
6415 } else if (tok
== TOK_RETURN
) {
6419 gen_assign_cast(&func_vt
);
6420 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
6422 /* if returning structure, must copy it to implicit
6423 first pointer arg location */
6426 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
6429 /* copy structure value to pointer */
6431 } else if (is_float(func_vt
.t
)) {
6436 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6439 rsym
= gjmp(rsym
); /* jmp */
6440 } else if (tok
== TOK_BREAK
) {
6443 error("cannot break");
6444 *bsym
= gjmp(*bsym
);
6447 } else if (tok
== TOK_CONTINUE
) {
6450 error("cannot continue");
6451 *csym
= gjmp(*csym
);
6454 } else if (tok
== TOK_FOR
) {
6481 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6486 if (tok
== TOK_DO
) {
6491 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6502 if (tok
== TOK_SWITCH
) {
6506 /* XXX: other types than integer */
6507 case_reg
= gv(RC_INT
);
6511 b
= gjmp(0); /* jump to first case */
6513 block(&a
, csym
, &b
, &c
, case_reg
);
6514 /* if no default, jmp after switch */
6522 if (tok
== TOK_CASE
) {
6529 if (gnu_ext
&& tok
== TOK_DOTS
) {
6533 warning("empty case range");
6535 /* since a case is like a label, we must skip it with a jmp */
6542 *case_sym
= gtst(1, 0);
6545 *case_sym
= gtst(1, 0);
6549 *case_sym
= gtst(1, *case_sym
);
6553 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6555 if (tok
== TOK_DEFAULT
) {
6561 error("too many 'default'");
6563 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6565 if (tok
== TOK_GOTO
) {
6567 if (tok
== '*' && gnu_ext
) {
6571 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
6574 } else if (tok
>= TOK_UIDENT
) {
6575 s
= label_find(tok
);
6576 /* put forward definition if needed */
6578 s
= label_push(tok
, LABEL_FORWARD
);
6580 /* label already defined */
6581 if (s
->r
& LABEL_FORWARD
)
6582 s
->next
= (void *)gjmp((long)s
->next
);
6584 gjmp_addr((long)s
->next
);
6587 expect("label identifier");
6596 if (!(s
->r
& LABEL_FORWARD
))
6597 error("multiple defined label");
6598 gsym((long)s
->next
);
6600 s
= label_push(b
, 0);
6602 s
->next
= (void *)ind
;
6604 /* we accept this, but it is a mistake */
6606 warning("deprecated use of label at end of compound statement");
6608 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6610 /* expression case */
6620 /* t is the array or struct type. c is the array or struct
6621 address. cur_index/cur_field is the pointer to the current
6622 value. 'size_only' is true if only size info is needed (only used
6624 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
6625 int *cur_index
, Sym
**cur_field
,
6629 int notfirst
, index
, align
, l
;
6633 if (gnu_ext
&& (l
= is_label()) != 0)
6636 while (tok
== '[' || tok
== '.') {
6638 if (!(type
->t
& VT_ARRAY
))
6639 expect("array type");
6642 index
= expr_const();
6643 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
6644 expect("invalid index");
6648 type
= pointed_type(type
);
6649 c
+= index
* type_size(type
, &align
);
6655 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
6656 expect("struct/union type");
6669 /* XXX: suppress this mess by using explicit storage field */
6671 type1
.t
|= (type
->t
& ~VT_TYPE
);
6685 if (type
->t
& VT_ARRAY
) {
6687 type
= pointed_type(type
);
6688 c
+= index
* type_size(type
, &align
);
6692 error("too many field init");
6693 /* XXX: suppress this mess by using explicit storage field */
6695 type1
.t
|= (type
->t
& ~VT_TYPE
);
6700 decl_initializer(type
, sec
, c
, 0, size_only
);
6704 #define EXPR_CONST 1
6707 /* store a value or an expression directly in global data or in local array */
6708 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
6709 int v
, int expr_type
)
6711 int saved_global_expr
, bt
;
6719 /* compound literals must be allocated globally in this case */
6720 saved_global_expr
= global_expr
;
6723 global_expr
= saved_global_expr
;
6724 /* NOTE: symbols are accepted */
6725 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
6726 error("initializer element is not constant");
6734 /* XXX: not portable */
6735 /* XXX: generate error if incorrect relocation */
6736 gen_assign_cast(type
);
6737 bt
= type
->t
& VT_BTYPE
;
6738 ptr
= sec
->data
+ c
;
6739 if ((vtop
->r
& VT_SYM
) &&
6745 error("initializer element is not computable at load time");
6748 *(char *)ptr
= vtop
->c
.i
;
6751 *(short *)ptr
= vtop
->c
.i
;
6754 *(double *)ptr
= vtop
->c
.d
;
6757 *(long double *)ptr
= vtop
->c
.ld
;
6760 *(long long *)ptr
= vtop
->c
.ll
;
6763 if (vtop
->r
& VT_SYM
) {
6764 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
6766 *(int *)ptr
= vtop
->c
.i
;
6771 vset(type
, VT_LOCAL
, c
);
6778 /* put zeros for variable based init */
6779 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
6784 /* nothing to do because globals are already set to zero */
6786 gfunc_start(&gf
, FUNC_CDECL
);
6793 vpush_global_sym(&func_old_type
, TOK_memset
);
6798 /* 't' contains the type and storage info. 'c' is the offset of the
6799 object in section 'sec'. If 'sec' is NULL, it means stack based
6800 allocation. 'first' is true if array '{' must be read (multi
6801 dimension implicit array init handling). 'size_only' is true if
6802 size only evaluation is wanted (only for arrays). */
6803 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
6804 int first
, int size_only
)
6806 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
6807 int size1
, align1
, expr_type
;
6811 if (type
->t
& VT_ARRAY
) {
6815 t1
= pointed_type(type
);
6816 size1
= type_size(t1
, &align1
);
6819 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
6825 /* only parse strings here if correct type (otherwise: handle
6826 them as ((w)char *) expressions */
6827 if ((tok
== TOK_LSTR
&&
6828 (t1
->t
& VT_BTYPE
) == VT_INT
) ||
6830 (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
6831 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6836 /* compute maximum number of chars wanted */
6838 cstr_len
= cstr
->size
;
6840 cstr_len
= cstr
->size
/ sizeof(int);
6843 if (n
>= 0 && nb
> (n
- array_length
))
6844 nb
= n
- array_length
;
6847 warning("initializer-string for array is too long");
6848 /* in order to go faster for common case (char
6849 string in global variable, we handle it
6851 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
6852 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
6856 ch
= ((unsigned char *)cstr
->data
)[i
];
6858 ch
= ((int *)cstr
->data
)[i
];
6859 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
6867 /* only add trailing zero if enough storage (no
6868 warning in this case since it is standard) */
6869 if (n
< 0 || array_length
< n
) {
6871 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
6877 while (tok
!= '}') {
6878 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
6879 if (n
>= 0 && index
>= n
)
6880 error("index too large");
6881 /* must put zero in holes (note that doing it that way
6882 ensures that it even works with designators) */
6883 if (!size_only
&& array_length
< index
) {
6884 init_putz(t1
, sec
, c
+ array_length
* size1
,
6885 (index
- array_length
) * size1
);
6888 if (index
> array_length
)
6889 array_length
= index
;
6890 /* special test for multi dimensional arrays (may not
6891 be strictly correct if designators are used at the
6893 if (index
>= n
&& no_oblock
)
6902 /* put zeros at the end */
6903 if (!size_only
&& n
>= 0 && array_length
< n
) {
6904 init_putz(t1
, sec
, c
+ array_length
* size1
,
6905 (n
- array_length
) * size1
);
6907 /* patch type size if needed */
6909 s
->c
= array_length
;
6910 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
6911 /* XXX: union needs only one init */
6918 while (tok
!= '}') {
6919 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
6920 /* fill with zero between fields */
6922 if (!size_only
&& array_length
< index
) {
6923 init_putz(type
, sec
, c
+ array_length
,
6924 index
- array_length
);
6926 index
= index
+ type_size(&f
->type
, &align1
);
6927 if (index
> array_length
)
6928 array_length
= index
;
6934 /* put zeros at the end */
6935 if (!size_only
&& array_length
< n
) {
6936 init_putz(type
, sec
, c
+ array_length
,
6940 } else if (tok
== '{') {
6942 decl_initializer(type
, sec
, c
, first
, size_only
);
6944 } else if (size_only
) {
6945 /* just skip expression */
6947 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
6951 else if (tok
== ')')
6956 /* currently, we always use constant expression for globals
6957 (may change for scripting case) */
6958 expr_type
= EXPR_CONST
;
6960 expr_type
= EXPR_ANY
;
6961 init_putv(type
, sec
, c
, 0, expr_type
);
6965 /* parse an initializer for type 't' if 'has_init' is non zero, and
6966 allocate space in local or global data space ('r' is either
6967 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6968 variable 'v' of scope 'scope' is declared before initializers are
6969 parsed. If 'v' is zero, then a reference to the new object is put
6970 in the value stack. If 'has_init' is 2, a special parsing is done
6971 to handle string constants. */
6972 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
6973 int has_init
, int v
, int scope
)
6975 int size
, align
, addr
, data_offset
;
6977 ParseState saved_parse_state
;
6978 TokenString init_str
;
6981 size
= type_size(type
, &align
);
6982 /* If unknown size, we must evaluate it before
6983 evaluating initializers because
6984 initializers can generate global data too
6985 (e.g. string pointers or ISOC99 compound
6986 literals). It also simplifies local
6987 initializers handling */
6988 tok_str_new(&init_str
);
6991 error("unknown type size");
6992 /* get all init string */
6993 if (has_init
== 2) {
6994 /* only get strings */
6995 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6996 tok_str_add_tok(&init_str
);
7001 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
7003 error("unexpected end of file in initializer");
7004 tok_str_add_tok(&init_str
);
7007 else if (tok
== '}') {
7015 tok_str_add(&init_str
, -1);
7016 tok_str_add(&init_str
, 0);
7019 save_parse_state(&saved_parse_state
);
7021 macro_ptr
= init_str
.str
;
7023 decl_initializer(type
, NULL
, 0, 1, 1);
7024 /* prepare second initializer parsing */
7025 macro_ptr
= init_str
.str
;
7028 /* if still unknown size, error */
7029 size
= type_size(type
, &align
);
7031 error("unknown type size");
7033 /* take into account specified alignment if bigger */
7034 if (ad
->aligned
> align
)
7035 align
= ad
->aligned
;
7036 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
7038 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
7040 #ifdef TCC_TARGET_IL
7041 /* XXX: ugly patch to allocate local variables for IL, just
7046 loc
= (loc
- size
) & -align
;
7049 /* handles bounds */
7050 /* XXX: currently, since we do only one pass, we cannot track
7051 '&' operators, so we add only arrays */
7052 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
7053 unsigned long *bounds_ptr
;
7054 /* add padding between regions */
7056 /* then add local bound info */
7057 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
7058 bounds_ptr
[0] = addr
;
7059 bounds_ptr
[1] = size
;
7062 /* compute section */
7070 data_offset
= sec
->data_offset
;
7071 data_offset
= (data_offset
+ align
- 1) & -align
;
7073 /* very important to increment global pointer at this time
7074 because initializers themselves can create new initializers */
7075 data_offset
+= size
;
7076 /* add padding if bound check */
7077 if (do_bounds_check
)
7079 sec
->data_offset
= data_offset
;
7080 /* allocate section space to put the data */
7081 if (sec
->sh_type
!= SHT_NOBITS
&&
7082 data_offset
> sec
->data_allocated
)
7083 section_realloc(sec
, data_offset
);
7087 /* local variable */
7088 sym_push(v
, type
, r
, addr
);
7090 /* push local reference */
7091 vset(type
, r
, addr
);
7097 if (scope
== VT_CONST
) {
7098 /* global scope: see if already defined */
7102 if (!is_compatible_types(&sym
->type
, type
))
7103 error("incompatible types for redefinition of '%s'",
7104 get_tok_str(v
, NULL
));
7105 if (!(sym
->type
.t
& VT_EXTERN
))
7106 error("redefinition of '%s'", get_tok_str(v
, NULL
));
7107 sym
->type
.t
&= ~VT_EXTERN
;
7110 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
7112 put_extern_sym(sym
, sec
, addr
, size
);
7116 /* push global reference */
7117 sym
= get_sym_ref(type
, sec
, addr
, size
);
7119 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
7123 /* handles bounds now because the symbol must be defined
7124 before for the relocation */
7125 if (do_bounds_check
) {
7126 unsigned long *bounds_ptr
;
7128 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
7129 /* then add global bound info */
7130 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
7131 bounds_ptr
[0] = 0; /* relocated */
7132 bounds_ptr
[1] = size
;
7136 decl_initializer(type
, sec
, addr
, 1, 0);
7137 /* restore parse state if needed */
7139 tok_str_free(init_str
.str
);
7140 restore_parse_state(&saved_parse_state
);
7145 void put_func_debug(Sym
*sym
)
7150 /* XXX: we put here a dummy type */
7151 snprintf(buf
, sizeof(buf
), "%s:%c1",
7152 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
7153 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
7154 cur_text_section
, sym
->c
);
7159 /* not finished : try to put some local vars in registers */
7160 //#define CONFIG_REG_VARS
7162 #ifdef CONFIG_REG_VARS
7163 void add_var_ref(int t
)
7165 printf("%s:%d: &%s\n",
7166 file
->filename
, file
->line_num
,
7167 get_tok_str(t
, NULL
));
7170 /* first pass on a function with heuristic to extract variable usage
7171 and pointer references to local variables for register allocation */
7172 void analyse_function(void)
7179 /* any symbol coming after '&' is considered as being a
7180 variable whose reference is taken. It is highly unaccurate
7181 but it is difficult to do better without a complete parse */
7184 /* if '& number', then no need to examine next tokens */
7185 if (tok
== TOK_CINT
||
7187 tok
== TOK_CLLONG
||
7188 tok
== TOK_CULLONG
) {
7190 } else if (tok
>= TOK_UIDENT
) {
7191 /* if '& ident [' or '& ident ->', then ident address
7195 if (tok
!= '[' && tok
!= TOK_ARROW
)
7199 while (tok
!= '}' && tok
!= ';' &&
7200 !((tok
== ',' || tok
== ')') && level
== 0)) {
7201 if (tok
>= TOK_UIDENT
) {
7203 } else if (tok
== '(') {
7205 } else if (tok
== ')') {
7218 /* parse an old style function declaration list */
7219 /* XXX: check multiple parameter */
7220 static void func_decl_list(Sym
*func_sym
)
7227 /* parse each declaration */
7228 while (tok
!= '{' && tok
!= ';' && tok
!= TOK_EOF
) {
7229 if (!parse_btype(&btype
, &ad
))
7230 expect("declaration list");
7231 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
7232 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
7234 /* we accept no variable after */
7238 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
7239 /* find parameter in function parameter list */
7242 if ((s
->v
& ~SYM_FIELD
) == v
)
7246 error("declaration for parameter '%s' but no such parameter",
7247 get_tok_str(v
, NULL
));
7249 /* check that no storage specifier except 'register' was given */
7250 if (type
.t
& (VT_EXTERN
| VT_STATIC
| VT_TYPEDEF
))
7251 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
7252 /* we can add the type (NOTE: it could be local to the function) */
7254 /* accept other parameters */
7265 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
7266 static void decl(int l
)
7274 if (!parse_btype(&btype
, &ad
)) {
7275 /* skip redundant ';' */
7276 /* XXX: find more elegant solution */
7281 /* special test for old K&R protos without explicit int
7282 type. Only accepted when defining global data */
7283 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
7287 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
7288 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
7290 /* we accept no variable after */
7294 while (1) { /* iterate thru each declaration */
7296 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
7300 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
7301 printf("type = '%s'\n", buf
);
7304 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
7305 /* if old style function prototype, we accept a
7308 if (sym
->c
== FUNC_OLD
)
7309 func_decl_list(sym
);
7313 #ifdef CONFIG_REG_VARS
7314 TokenString func_str
;
7315 ParseState saved_parse_state
;
7320 error("cannot use local functions");
7321 if (!(type
.t
& VT_FUNC
))
7322 expect("function definition");
7324 #ifdef CONFIG_REG_VARS
7325 /* parse all function code and record it */
7327 tok_str_new(&func_str
);
7333 error("unexpected end of file");
7334 tok_str_add_tok(&func_str
);
7339 } else if (t
== '}') {
7341 if (block_level
== 0)
7345 tok_str_add(&func_str
, -1);
7346 tok_str_add(&func_str
, 0);
7348 save_parse_state(&saved_parse_state
);
7350 macro_ptr
= func_str
.str
;
7355 /* compute text section */
7356 cur_text_section
= ad
.section
;
7357 if (!cur_text_section
)
7358 cur_text_section
= text_section
;
7359 ind
= cur_text_section
->data_offset
;
7360 funcname
= get_tok_str(v
, NULL
);
7363 /* if symbol is already defined, then put complete type */
7366 /* put function symbol */
7367 sym
= global_identifier_push(v
, type
.t
, 0);
7368 sym
->type
.ref
= type
.ref
;
7370 /* NOTE: we patch the symbol size later */
7371 put_extern_sym(sym
, cur_text_section
, ind
, 0);
7373 sym
->r
= VT_SYM
| VT_CONST
;
7374 /* put debug symbol */
7376 put_func_debug(sym
);
7377 /* push a dummy symbol to enable local sym storage */
7378 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
7379 gfunc_prolog(&type
);
7382 #ifdef CONFIG_REG_VARS
7383 macro_ptr
= func_str
.str
;
7386 block(NULL
, NULL
, NULL
, NULL
, 0);
7389 cur_text_section
->data_offset
= ind
;
7390 /* look if any labels are undefined. Define symbols if
7391 '&&label' was used. */
7394 for(s
= label_stack
; s
!= NULL
; s
= s1
) {
7396 if (s
->r
& LABEL_FORWARD
) {
7397 error("label '%s' used but not defined",
7398 get_tok_str(s
->v
, NULL
));
7401 /* define corresponding symbol. A size of
7403 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
7406 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= NULL
;
7411 sym_pop(&local_stack
, NULL
); /* reset local stack */
7412 /* end of function */
7413 /* patch symbol size */
7414 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
7417 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
7419 funcname
= ""; /* for safety */
7420 func_vt
.t
= VT_VOID
; /* for safety */
7421 ind
= 0; /* for safety */
7423 #ifdef CONFIG_REG_VARS
7424 tok_str_free(func_str
.str
);
7425 restore_parse_state(&saved_parse_state
);
7429 if (btype
.t
& VT_TYPEDEF
) {
7430 /* save typedefed type */
7431 /* XXX: test storage specifiers ? */
7432 sym
= sym_push(v
, &type
, 0, 0);
7433 sym
->type
.t
|= VT_TYPEDEF
;
7434 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
7435 /* external function definition */
7436 external_sym(v
, &type
, 0);
7438 /* not lvalue if array */
7440 if (!(type
.t
& VT_ARRAY
))
7441 r
|= lvalue_type(type
.t
);
7442 if (btype
.t
& VT_EXTERN
) {
7443 /* external variable */
7444 external_sym(v
, &type
, r
);
7446 if (type
.t
& VT_STATIC
)
7450 has_init
= (tok
== '=');
7453 decl_initializer_alloc(&type
, &ad
, r
,
7467 /* compile the C file opened in 'file'. Return non zero if errors. */
7468 static int tcc_compile(TCCState
*s1
)
7472 volatile int section_sym
;
7475 printf("%s: **** new file\n", file
->filename
);
7478 s1
->include_stack_ptr
= s1
->include_stack
;
7479 /* XXX: move that before to avoid having to initialize
7480 file->ifdef_stack_ptr ? */
7481 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
7482 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
7484 /* XXX: not ANSI compliant: bound checking says error */
7486 anon_sym
= SYM_FIRST_ANOM
;
7488 /* file info: full path + filename */
7489 section_sym
= 0; /* avoid warning */
7491 section_sym
= put_elf_sym(symtab_section
, 0, 0,
7492 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
7493 text_section
->sh_num
, NULL
);
7494 getcwd(buf
, sizeof(buf
));
7495 pstrcat(buf
, sizeof(buf
), "/");
7496 put_stabs_r(buf
, N_SO
, 0, 0,
7497 text_section
->data_offset
, text_section
, section_sym
);
7498 put_stabs_r(file
->filename
, N_SO
, 0, 0,
7499 text_section
->data_offset
, text_section
, section_sym
);
7501 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
7502 symbols can be safely used */
7503 put_elf_sym(symtab_section
, 0, 0,
7504 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
7505 SHN_ABS
, file
->filename
);
7507 /* define some often used types */
7508 int_type
.t
= VT_INT
;
7510 char_pointer_type
.t
= VT_BYTE
;
7511 mk_pointer(&char_pointer_type
);
7513 func_old_type
.t
= VT_FUNC
;
7514 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
7517 /* define 'void *alloca(unsigned int)' builtin function */
7522 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
7523 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
7526 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
7530 define_start
= define_stack
;
7532 if (setjmp(s1
->error_jmp_buf
) == 0) {
7534 s1
->error_set_jmp_enabled
= 1;
7537 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7541 expect("declaration");
7543 /* end of translation unit info */
7545 put_stabs_r(NULL
, N_SO
, 0, 0,
7546 text_section
->data_offset
, text_section
, section_sym
);
7549 s1
->error_set_jmp_enabled
= 0;
7551 /* reset define stack, but leave -Dsymbols (may be incorrect if
7552 they are undefined) */
7553 free_defines(define_start
);
7555 sym_pop(&global_stack
, NULL
);
7557 return s1
->nb_errors
!= 0 ? -1 : 0;
7560 int tcc_compile_string(TCCState
*s
, const char *str
)
7562 BufferedFile bf1
, *bf
= &bf1
;
7565 /* init file structure */
7567 bf
->buf_ptr
= (char *)str
;
7568 bf
->buf_end
= (char *)str
+ strlen(bf
->buffer
);
7569 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
7573 ret
= tcc_compile(s
);
7575 /* currently, no need to close */
7579 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
7580 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
7582 BufferedFile bf1
, *bf
= &bf1
;
7584 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
7585 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
7589 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
7591 /* init file structure */
7593 bf
->buf_ptr
= bf
->buffer
;
7594 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
7595 bf
->filename
[0] = '\0';
7599 s1
->include_stack_ptr
= s1
->include_stack
;
7601 /* parse with define parser */
7603 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7609 /* undefine a preprocessor symbol */
7610 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
7614 ts
= tok_alloc(sym
, strlen(sym
));
7615 s
= define_find(ts
->tok
);
7616 /* undefine symbol by putting an invalid name */
7623 /* print the position in the source file of PC value 'pc' by reading
7624 the stabs debug information */
7625 static void rt_printline(unsigned long wanted_pc
)
7627 Stab_Sym
*sym
, *sym_end
;
7628 char func_name
[128], last_func_name
[128];
7629 unsigned long func_addr
, last_pc
, pc
;
7630 const char *incl_files
[INCLUDE_STACK_SIZE
];
7631 int incl_index
, len
, last_line_num
, i
;
7632 const char *str
, *p
;
7634 fprintf(stderr
, "0x%08lx:", wanted_pc
);
7636 func_name
[0] = '\0';
7639 last_func_name
[0] = '\0';
7640 last_pc
= 0xffffffff;
7642 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
7643 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
7644 while (sym
< sym_end
) {
7645 switch(sym
->n_type
) {
7646 /* function start or end */
7648 if (sym
->n_strx
== 0) {
7649 /* we test if between last line and end of function */
7650 pc
= sym
->n_value
+ func_addr
;
7651 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7653 func_name
[0] = '\0';
7656 str
= stabstr_section
->data
+ sym
->n_strx
;
7657 p
= strchr(str
, ':');
7659 pstrcpy(func_name
, sizeof(func_name
), str
);
7662 if (len
> sizeof(func_name
) - 1)
7663 len
= sizeof(func_name
) - 1;
7664 memcpy(func_name
, str
, len
);
7665 func_name
[len
] = '\0';
7667 func_addr
= sym
->n_value
;
7670 /* line number info */
7672 pc
= sym
->n_value
+ func_addr
;
7673 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7676 last_line_num
= sym
->n_desc
;
7678 strcpy(last_func_name
, func_name
);
7682 str
= stabstr_section
->data
+ sym
->n_strx
;
7684 if (incl_index
< INCLUDE_STACK_SIZE
) {
7685 incl_files
[incl_index
++] = str
;
7693 if (sym
->n_strx
== 0) {
7694 incl_index
= 0; /* end of translation unit */
7696 str
= stabstr_section
->data
+ sym
->n_strx
;
7697 /* do not add path */
7699 if (len
> 0 && str
[len
- 1] != '/')
7707 /* second pass: we try symtab symbols (no line number info) */
7710 Elf32_Sym
*sym
, *sym_end
;
7713 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
7714 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
7717 type
= ELF32_ST_TYPE(sym
->st_info
);
7718 if (type
== STT_FUNC
) {
7719 if (wanted_pc
>= sym
->st_value
&&
7720 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
7721 pstrcpy(last_func_name
, sizeof(last_func_name
),
7722 strtab_section
->data
+ sym
->st_name
);
7728 /* did not find any info: */
7729 fprintf(stderr
, " ???\n");
7732 if (last_func_name
[0] != '\0') {
7733 fprintf(stderr
, " %s()", last_func_name
);
7735 if (incl_index
> 0) {
7736 fprintf(stderr
, " (%s:%d",
7737 incl_files
[incl_index
- 1], last_line_num
);
7738 for(i
= incl_index
- 2; i
>= 0; i
--)
7739 fprintf(stderr
, ", included from %s", incl_files
[i
]);
7740 fprintf(stderr
, ")");
7742 fprintf(stderr
, "\n");
7754 /* return the PC at frame level 'level'. Return non zero if not found */
7755 static int rt_get_caller_pc(unsigned long *paddr
,
7756 struct ucontext
*uc
, int level
)
7762 *paddr
= uc
->uc_mcontext
.gregs
[EIP
];
7765 fp
= uc
->uc_mcontext
.gregs
[EBP
];
7766 for(i
=1;i
<level
;i
++) {
7767 /* XXX: check address validity with program info */
7768 if (fp
<= 0x1000 || fp
>= 0xc0000000)
7770 fp
= ((unsigned long *)fp
)[0];
7772 *paddr
= ((unsigned long *)fp
)[1];
7777 #error add arch specific rt_get_caller_pc()
7780 /* emit a run time error at position 'pc' */
7781 void rt_error(struct ucontext
*uc
, const char *fmt
, ...)
7788 fprintf(stderr
, "Runtime error: ");
7789 vfprintf(stderr
, fmt
, ap
);
7790 fprintf(stderr
, "\n");
7791 for(i
=0;i
<num_callers
;i
++) {
7792 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
7795 fprintf(stderr
, "at ");
7797 fprintf(stderr
, "by ");
7804 /* signal handler for fatal errors */
7805 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
7807 struct ucontext
*uc
= puc
;
7811 switch(siginf
->si_code
) {
7814 rt_error(uc
, "division by zero");
7817 rt_error(uc
, "floating point exception");
7823 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
7824 rt_error(uc
, *rt_bound_error_msg
);
7826 rt_error(uc
, "dereferencing invalid pointer");
7829 rt_error(uc
, "illegal instruction");
7832 rt_error(uc
, "abort() called");
7835 rt_error(uc
, "caught signal %d", signum
);
7842 /* do all relocations (needed before using tcc_get_symbol()) */
7843 int tcc_relocate(TCCState
*s1
)
7850 tcc_add_runtime(s1
);
7852 relocate_common_syms();
7854 /* compute relocation address : section are relocated in place. We
7855 also alloc the bss space */
7856 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7857 s
= s1
->sections
[i
];
7858 if (s
->sh_flags
& SHF_ALLOC
) {
7859 if (s
->sh_type
== SHT_NOBITS
)
7860 s
->data
= tcc_mallocz(s
->data_offset
);
7861 s
->sh_addr
= (unsigned long)s
->data
;
7865 relocate_syms(s1
, 1);
7867 if (s1
->nb_errors
!= 0)
7870 /* relocate each section */
7871 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7872 s
= s1
->sections
[i
];
7874 relocate_section(s1
, s
);
7879 /* launch the compiled program with the given arguments */
7880 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
7882 int (*prog_main
)(int, char **);
7884 if (tcc_relocate(s1
) < 0)
7887 prog_main
= tcc_get_symbol(s1
, "main");
7891 error("debug mode currently not available for Windows");
7893 struct sigaction sigact
;
7894 /* install TCC signal handlers to print debug info on fatal
7896 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
7897 sigact
.sa_sigaction
= sig_error
;
7898 sigemptyset(&sigact
.sa_mask
);
7899 sigaction(SIGFPE
, &sigact
, NULL
);
7900 sigaction(SIGILL
, &sigact
, NULL
);
7901 sigaction(SIGSEGV
, &sigact
, NULL
);
7902 sigaction(SIGBUS
, &sigact
, NULL
);
7903 sigaction(SIGABRT
, &sigact
, NULL
);
7907 #ifdef CONFIG_TCC_BCHECK
7908 if (do_bounds_check
) {
7909 void (*bound_init
)(void);
7911 /* set error function */
7912 rt_bound_error_msg
= (void *)tcc_get_symbol(s1
, "__bound_error_msg");
7914 /* XXX: use .init section so that it also work in binary ? */
7915 bound_init
= (void *)tcc_get_symbol(s1
, "__bound_init");
7919 return (*prog_main
)(argc
, argv
);
7922 TCCState
*tcc_new(void)
7927 s
= tcc_mallocz(sizeof(TCCState
));
7931 s
->output_type
= TCC_OUTPUT_MEMORY
;
7933 /* default include paths */
7934 tcc_add_sysinclude_path(s
, "/usr/local/include");
7935 tcc_add_sysinclude_path(s
, "/usr/include");
7936 tcc_add_sysinclude_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
7938 /* add all tokens */
7940 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
7942 tok_ident
= TOK_IDENT
;
7947 tok_alloc(p
, r
- p
- 1);
7951 /* we add dummy defines for some special macros to speed up tests
7952 and to have working defined() */
7953 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
7954 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
7955 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
7956 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
7958 /* standard defines */
7959 tcc_define_symbol(s
, "__STDC__", NULL
);
7960 #if defined(TCC_TARGET_I386)
7961 tcc_define_symbol(s
, "__i386__", NULL
);
7964 tcc_define_symbol(s
, "linux", NULL
);
7966 /* tiny C specific defines */
7967 tcc_define_symbol(s
, "__TINYC__", NULL
);
7969 /* default library paths */
7970 tcc_add_library_path(s
, "/usr/local/lib");
7971 tcc_add_library_path(s
, "/usr/lib");
7972 tcc_add_library_path(s
, "/lib");
7974 /* no section zero */
7975 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
7977 /* create standard sections */
7978 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
7979 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
7980 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
7982 /* symbols are always generated for linking stage */
7983 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
7985 ".hashtab", SHF_PRIVATE
);
7986 strtab_section
= symtab_section
->link
;
7988 /* private symbol table for dynamic symbols */
7989 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
7991 ".dynhashtab", SHF_PRIVATE
);
7995 void tcc_delete(TCCState
*s1
)
7999 /* free -D defines */
8003 n
= tok_ident
- TOK_IDENT
;
8004 for(i
= 0; i
< n
; i
++)
8005 tcc_free(table_ident
[i
]);
8006 tcc_free(table_ident
);
8008 /* free all sections */
8010 free_section(symtab_section
->hash
);
8012 free_section(s1
->dynsymtab_section
->hash
);
8013 free_section(s1
->dynsymtab_section
->link
);
8014 free_section(s1
->dynsymtab_section
);
8016 for(i
= 1; i
< s1
->nb_sections
; i
++)
8017 free_section(s1
->sections
[i
]);
8018 tcc_free(s1
->sections
);
8020 /* free loaded dlls array */
8021 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
8022 tcc_free(s1
->loaded_dlls
[i
]);
8023 tcc_free(s1
->loaded_dlls
);
8026 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
8027 tcc_free(s1
->library_paths
[i
]);
8028 tcc_free(s1
->library_paths
);
8030 /* cached includes */
8031 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
8032 tcc_free(s1
->cached_includes
[i
]);
8033 tcc_free(s1
->cached_includes
);
8035 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
8036 tcc_free(s1
->include_paths
[i
]);
8037 tcc_free(s1
->include_paths
);
8039 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
8040 tcc_free(s1
->sysinclude_paths
[i
]);
8041 tcc_free(s1
->sysinclude_paths
);
8046 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
8050 pathname1
= tcc_strdup(pathname
);
8051 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
8055 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
8059 pathname1
= tcc_strdup(pathname
);
8060 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
8064 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
8069 BufferedFile
*saved_file
;
8071 /* find source file type with extension */
8072 ext
= strrchr(filename
, '.');
8078 file
= tcc_open(s1
, filename
);
8080 if (flags
& AFF_PRINT_ERROR
) {
8081 error_noabort("file '%s' not found", filename
);
8087 if (!ext
|| !strcmp(ext
, "c")) {
8088 /* C file assumed */
8089 ret
= tcc_compile(s1
);
8092 /* assume executable format: auto guess file type */
8093 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
)) {
8094 error_noabort("could not read header");
8097 lseek(fd
, 0, SEEK_SET
);
8099 if (ehdr
.e_ident
[0] == ELFMAG0
&&
8100 ehdr
.e_ident
[1] == ELFMAG1
&&
8101 ehdr
.e_ident
[2] == ELFMAG2
&&
8102 ehdr
.e_ident
[3] == ELFMAG3
) {
8103 file
->line_num
= 0; /* do not display line number if error */
8104 if (ehdr
.e_type
== ET_REL
) {
8105 ret
= tcc_load_object_file(s1
, fd
, 0);
8106 } else if (ehdr
.e_type
== ET_DYN
) {
8107 ret
= tcc_load_dll(s1
, fd
, filename
,
8108 (flags
& AFF_REFERENCED_DLL
) != 0);
8110 error_noabort("unrecognized ELF file");
8113 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
8114 file
->line_num
= 0; /* do not display line number if error */
8115 ret
= tcc_load_archive(s1
, fd
);
8117 /* as GNU ld, consider it is an ld script if not recognized */
8118 ret
= tcc_load_ldscript(s1
);
8120 error_noabort("unrecognized file type");
8135 int tcc_add_file(TCCState
*s
, const char *filename
)
8137 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
8140 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
8144 pathname1
= tcc_strdup(pathname
);
8145 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
8149 /* find and load a dll. Return non zero if not found */
8150 /* XXX: add '-rpath' option support ? */
8151 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
8156 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
8157 snprintf(buf
, sizeof(buf
), "%s/%s",
8158 s
->library_paths
[i
], filename
);
8159 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
8165 /* the library name is the same as the argument of the '-l' option */
8166 int tcc_add_library(TCCState
*s
, const char *libraryname
)
8172 /* first we look for the dynamic library if not static linking */
8173 if (!s
->static_link
) {
8174 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8175 /* if we output to memory, then we simply we dlopen(). */
8176 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
8177 /* Since the libc is already loaded, we don't need to load it again */
8178 if (!strcmp(libraryname
, "c"))
8180 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
8184 if (tcc_add_dll(s
, buf
, 0) == 0)
8189 /* then we look for the static library */
8190 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
8191 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
8192 s
->library_paths
[i
], libraryname
);
8193 if (tcc_add_file_internal(s
, buf
, 0) == 0)
8199 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
8201 add_elf_sym(symtab_section
, val
, 0,
8202 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
8207 int tcc_set_output_type(TCCState
*s
, int output_type
)
8209 s
->output_type
= output_type
;
8211 /* if bound checking, then add corresponding sections */
8212 #ifdef CONFIG_TCC_BCHECK
8213 if (do_bounds_check
) {
8215 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
8216 /* create bounds sections */
8217 bounds_section
= new_section(s
, ".bounds",
8218 SHT_PROGBITS
, SHF_ALLOC
);
8219 lbounds_section
= new_section(s
, ".lbounds",
8220 SHT_PROGBITS
, SHF_ALLOC
);
8224 /* add debug sections */
8227 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
8228 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
8229 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
8230 put_elf_str(stabstr_section
, "");
8231 stab_section
->link
= stabstr_section
;
8232 /* put first entry */
8233 put_stabs("", 0, 0, 0, 0);
8236 /* add libc crt1/crti objects */
8237 if (output_type
== TCC_OUTPUT_EXE
||
8238 output_type
== TCC_OUTPUT_DLL
) {
8239 if (output_type
!= TCC_OUTPUT_DLL
)
8240 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
8241 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
8246 #if !defined(LIBTCC)
8248 static int64_t getclock_us(void)
8253 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
8256 gettimeofday(&tv
, NULL
);
8257 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
8263 printf("tcc version 0.9.13 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8264 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8265 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
8266 " [--] infile1 [infile2... --] [infile_args...]\n"
8268 "General options:\n"
8269 " -c compile only - generate an object file\n"
8270 " -o outfile set output filename\n"
8271 " -- allows multiples input files if no -o option given. Also\n"
8272 " separate input files from runtime arguments\n"
8273 " -Bdir set tcc internal library path\n"
8274 " -bench output compilation statistics\n"
8275 "Preprocessor options:\n"
8276 " -Idir add include path 'dir'\n"
8277 " -Dsym[=val] define 'sym' with value 'val'\n"
8278 " -Usym undefine 'sym'\n"
8280 " -Ldir add library path 'dir'\n"
8281 " -llib link with dynamic or static library 'lib'\n"
8282 " -shared generate a shared library\n"
8283 " -static static linking\n"
8284 " -r relocatable output\n"
8285 "Debugger options:\n"
8286 " -g generate runtime debug info\n"
8287 #ifdef CONFIG_TCC_BCHECK
8288 " -b compile with built-in memory and bounds checker (implies -g)\n"
8290 " -bt N show N callers in stack traces\n"
8294 int main(int argc
, char **argv
)
8297 int optind
, output_type
, multiple_files
, i
, reloc_output
;
8300 int nb_files
, nb_libraries
, nb_objfiles
, dminus
, ret
;
8301 char objfilename
[1024];
8302 int64_t start_time
= 0;
8305 output_type
= TCC_OUTPUT_MEMORY
;
8316 if (optind
>= argc
) {
8324 /* add a new file */
8325 dynarray_add((void ***)&files
, &nb_files
, r
);
8326 if (!multiple_files
) {
8328 /* argv[0] will be this file */
8331 } else if (r
[1] == '-') {
8332 /* '--' enables multiple files input and also ends several file input */
8333 if (dminus
&& multiple_files
) {
8334 optind
--; /* argv[0] will be '--' */
8339 } else if (r
[1] == 'h' || r
[1] == '?') {
8343 } else if (r
[1] == 'I') {
8344 if (tcc_add_include_path(s
, r
+ 2) < 0)
8345 error("too many include paths");
8346 } else if (r
[1] == 'D') {
8349 value
= strchr(sym
, '=');
8354 tcc_define_symbol(s
, sym
, value
);
8355 } else if (r
[1] == 'U') {
8356 tcc_undefine_symbol(s
, r
+ 2);
8357 } else if (r
[1] == 'L') {
8358 tcc_add_library_path(s
, r
+ 2);
8359 } else if (r
[1] == 'B') {
8360 /* set tcc utilities path (mainly for tcc development) */
8361 tcc_lib_path
= r
+ 2;
8362 } else if (r
[1] == 'l') {
8363 dynarray_add((void ***)&files
, &nb_files
, r
);
8365 } else if (!strcmp(r
+ 1, "bench")) {
8367 } else if (!strcmp(r
+ 1, "bt")) {
8368 num_callers
= atoi(argv
[optind
++]);
8370 #ifdef CONFIG_TCC_BCHECK
8372 do_bounds_check
= 1;
8378 } else if (r
[1] == 'c') {
8380 output_type
= TCC_OUTPUT_OBJ
;
8381 } else if (!strcmp(r
+ 1, "static")) {
8383 } else if (!strcmp(r
+ 1, "shared")) {
8384 output_type
= TCC_OUTPUT_DLL
;
8385 } else if (r
[1] == 'o') {
8389 outfile
= argv
[optind
++];
8390 } else if (r
[1] == 'r') {
8391 /* generate a .o merging several output files */
8393 output_type
= TCC_OUTPUT_OBJ
;
8394 } else if (r
[1] == 'W' || r
[1] == 'O' || r
[1] == 'm' || r
[1] == 'f') {
8395 /* ignore those options to be a drop-in replacement for gcc */
8397 error("invalid option -- '%s'", r
);
8401 nb_objfiles
= nb_files
- nb_libraries
;
8403 /* if outfile provided without other options, we output an
8405 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
8406 output_type
= TCC_OUTPUT_EXE
;
8408 /* check -c consistency : only single file handled. XXX: checks file type */
8409 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
8410 /* accepts only a single input file */
8411 if (nb_objfiles
!= 1)
8412 error("cannot specify multiple files with -c");
8413 if (nb_libraries
!= 0)
8414 error("cannot specify libraries with -c");
8417 /* compute default outfile name */
8418 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
8419 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
8421 /* add .o extension */
8422 pstrcpy(objfilename
, sizeof(objfilename
) - 1, files
[0]);
8423 ext
= strrchr(objfilename
, '.');
8425 goto default_outfile
;
8426 strcpy(ext
+ 1, "o");
8429 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
8431 outfile
= objfilename
;
8435 start_time
= getclock_us();
8438 tcc_set_output_type(s
, output_type
);
8440 /* compile or add each files or library */
8441 for(i
= 0;i
< nb_files
; i
++) {
8442 const char *filename
;
8444 filename
= files
[i
];
8445 if (filename
[0] == '-') {
8446 if (tcc_add_library(s
, filename
+ 2) < 0)
8447 error("cannot find %s", filename
);
8449 if (tcc_add_file(s
, filename
) < 0) {
8456 /* free all files */
8461 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
8462 if (total_time
< 0.001)
8464 if (total_bytes
< 1)
8466 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
8467 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
8468 total_time
, (int)(total_lines
/ total_time
),
8469 total_bytes
/ total_time
/ 1000000.0);
8472 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
8473 tcc_output_file(s
, outfile
);
8476 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
8479 /* XXX: cannot do it with bound checking because of the malloc hooks */
8480 if (!do_bounds_check
)
8485 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);