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 '\\' /* 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
);
1154 ts
->str
[len
] = '\0';
1159 /* CString handling */
1161 static void cstr_realloc(CString
*cstr
, int new_size
)
1166 size
= cstr
->size_allocated
;
1168 size
= 8; /* no need to allocate a too small first string */
1169 while (size
< new_size
)
1171 data
= tcc_realloc(cstr
->data_allocated
, size
);
1173 error("memory full");
1174 cstr
->data_allocated
= data
;
1175 cstr
->size_allocated
= size
;
1180 static void cstr_ccat(CString
*cstr
, int ch
)
1183 size
= cstr
->size
+ 1;
1184 if (size
> cstr
->size_allocated
)
1185 cstr_realloc(cstr
, size
);
1186 ((unsigned char *)cstr
->data
)[size
- 1] = ch
;
1190 static void cstr_cat(CString
*cstr
, const char *str
)
1202 /* add a wide char */
1203 static void cstr_wccat(CString
*cstr
, int ch
)
1206 size
= cstr
->size
+ sizeof(int);
1207 if (size
> cstr
->size_allocated
)
1208 cstr_realloc(cstr
, size
);
1209 *(int *)(((unsigned char *)cstr
->data
) + size
- sizeof(int)) = ch
;
1213 static void cstr_new(CString
*cstr
)
1215 memset(cstr
, 0, sizeof(CString
));
1218 /* free string and reset it to NULL */
1219 static void cstr_free(CString
*cstr
)
1221 tcc_free(cstr
->data_allocated
);
1225 #define cstr_reset(cstr) cstr_free(cstr)
1227 /* XXX: unicode ? */
1228 static void add_char(CString
*cstr
, int c
)
1230 if (c
== '\'' || c
== '\"' || c
== '\\') {
1231 /* XXX: could be more precise if char or string */
1232 cstr_ccat(cstr
, '\\');
1234 if (c
>= 32 && c
<= 126) {
1237 cstr_ccat(cstr
, '\\');
1239 cstr_ccat(cstr
, 'n');
1241 cstr_ccat(cstr
, '0' + ((c
>> 6) & 7));
1242 cstr_ccat(cstr
, '0' + ((c
>> 3) & 7));
1243 cstr_ccat(cstr
, '0' + (c
& 7));
1248 /* XXX: buffer overflow */
1249 /* XXX: float tokens */
1250 char *get_tok_str(int v
, CValue
*cv
)
1252 static char buf
[STRING_MAX_SIZE
+ 1];
1253 static CString cstr_buf
;
1259 /* NOTE: to go faster, we give a fixed buffer for small strings */
1260 cstr_reset(&cstr_buf
);
1261 cstr_buf
.data
= buf
;
1262 cstr_buf
.size_allocated
= sizeof(buf
);
1268 /* XXX: not quite exact, but only useful for testing */
1269 sprintf(p
, "%u", cv
->ui
);
1273 /* XXX: not quite exact, but only useful for testing */
1274 sprintf(p
, "%Lu", cv
->ull
);
1278 cstr_ccat(&cstr_buf
, '\'');
1279 add_char(&cstr_buf
, cv
->i
);
1280 cstr_ccat(&cstr_buf
, '\'');
1281 cstr_ccat(&cstr_buf
, '\0');
1285 len
= cstr
->size
- 1;
1287 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1288 cstr_ccat(&cstr_buf
, '\0');
1293 cstr_ccat(&cstr_buf
, '\"');
1295 len
= cstr
->size
- 1;
1297 add_char(&cstr_buf
, ((unsigned char *)cstr
->data
)[i
]);
1299 len
= (cstr
->size
/ sizeof(int)) - 1;
1301 add_char(&cstr_buf
, ((int *)cstr
->data
)[i
]);
1303 cstr_ccat(&cstr_buf
, '\"');
1304 cstr_ccat(&cstr_buf
, '\0');
1313 return strcpy(p
, "<<=");
1315 return strcpy(p
, ">>=");
1317 if (v
< TOK_IDENT
) {
1318 /* search in two bytes table */
1332 } else if (v
< tok_ident
) {
1333 return table_ident
[v
- TOK_IDENT
]->str
;
1334 } else if (v
>= SYM_FIRST_ANOM
) {
1335 /* special name for anonymous symbol */
1336 sprintf(p
, "L.%u", v
- SYM_FIRST_ANOM
);
1338 /* should never happen */
1343 return cstr_buf
.data
;
1346 /* push, without hashing */
1347 static Sym
*sym_push2(Sym
**ps
, int v
, int t
, int c
)
1350 s
= tcc_malloc(sizeof(Sym
));
1361 /* find a symbol and return its associated structure. 's' is the top
1362 of the symbol stack */
1363 static Sym
*sym_find2(Sym
*s
, int v
)
1373 /* structure lookup */
1374 static Sym
*struct_find(int v
)
1377 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1379 return table_ident
[v
]->sym_struct
;
1382 /* find an identifier */
1383 static inline Sym
*sym_find(int v
)
1386 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1388 return table_ident
[v
]->sym_identifier
;
1391 /* push a given symbol on the symbol stack */
1392 static Sym
*sym_push(int v
, CType
*type
, int r
, int c
)
1401 s
= sym_push2(ps
, v
, type
->t
, c
);
1402 s
->type
.ref
= type
->ref
;
1404 /* don't record fields or anonymous symbols */
1406 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1407 /* record symbol in token array */
1408 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1410 ps
= &ts
->sym_struct
;
1412 ps
= &ts
->sym_identifier
;
1419 /* push a global identifier */
1420 static Sym
*global_identifier_push(int v
, int t
, int c
)
1423 s
= sym_push2(&global_stack
, v
, t
, c
);
1424 /* don't record anonymous symbol */
1425 if (v
< SYM_FIRST_ANOM
) {
1426 ps
= &table_ident
[v
- TOK_IDENT
]->sym_identifier
;
1427 /* modify the top most local identifier, so that
1428 sym_identifier will point to 's' when popped */
1430 ps
= &(*ps
)->prev_tok
;
1437 /* pop symbols until top reaches 'b' */
1438 static void sym_pop(Sym
**ptop
, Sym
*b
)
1448 /* remove symbol in token array */
1450 if (!(v
& SYM_FIELD
) && (v
& ~SYM_STRUCT
) < SYM_FIRST_ANOM
) {
1451 ts
= table_ident
[(v
& ~SYM_STRUCT
) - TOK_IDENT
];
1453 ps
= &ts
->sym_struct
;
1455 ps
= &ts
->sym_identifier
;
1466 BufferedFile
*tcc_open(TCCState
*s1
, const char *filename
)
1471 fd
= open(filename
, O_RDONLY
);
1474 bf
= tcc_malloc(sizeof(BufferedFile
));
1480 bf
->buf_ptr
= bf
->buffer
;
1481 bf
->buf_end
= bf
->buffer
;
1482 bf
->buffer
[0] = CH_EOB
; /* put eob symbol */
1483 pstrcpy(bf
->filename
, sizeof(bf
->filename
), filename
);
1485 bf
->ifndef_macro
= 0;
1486 bf
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
1487 // printf("opening '%s'\n", filename);
1491 void tcc_close(BufferedFile
*bf
)
1493 total_lines
+= bf
->line_num
;
1498 /* read one char. MUST call tcc_fillbuf if CH_EOB is read */
1499 #define TCC_GETC(bf) (*(bf)->buf_ptr++)
1501 /* fill input buffer and return next char */
1502 int tcc_getc_slow(BufferedFile
*bf
)
1505 /* only tries to read if really end of buffer */
1506 if (bf
->buf_ptr
>= bf
->buf_end
) {
1508 len
= read(bf
->fd
, bf
->buffer
, IO_BUF_SIZE
);
1515 bf
->buf_ptr
= bf
->buffer
;
1516 bf
->buf_end
= bf
->buffer
+ len
;
1517 *bf
->buf_end
= CH_EOB
;
1519 if (bf
->buf_ptr
< bf
->buf_end
) {
1520 return *bf
->buf_ptr
++;
1522 bf
->buf_ptr
= bf
->buf_end
;
1527 /* no need to put that inline */
1528 void handle_eob(void)
1530 TCCState
*s1
= tcc_state
;
1532 /* no need to do anything if not at EOB */
1533 if (file
->buf_ptr
<= file
->buf_end
)
1537 ch1
= tcc_getc_slow(file
);
1541 if (return_linefeed
) {
1545 if (s1
->include_stack_ptr
== s1
->include_stack
)
1547 /* add end of include file debug info */
1549 put_stabd(N_EINCL
, 0, 0);
1551 /* pop include stack */
1553 s1
->include_stack_ptr
--;
1554 file
= *s1
->include_stack_ptr
;
1558 /* read next char from current input file */
1559 static inline void inp(void)
1561 ch1
= TCC_GETC(file
);
1562 /* end of buffer/file handling */
1567 // printf("ch1=%c 0x%x\n", ch1, ch1);
1570 /* handle '\\n' and '\\r\n' */
1571 static void handle_stray(void)
1576 } else if (ch1
== '\r') {
1579 error("invalid character after '\\'");
1586 } while (ch
== '\\');
1589 /* input with '\\n' handling. Also supports '\\r\n' for horrible MSDOS
1591 static inline void minp(void)
1600 /* same as minp, but also skip comments */
1601 static void cinp(void)
1608 /* single line C++ comments */
1610 while (ch1
!= '\n' && ch1
!= CH_EOF
)
1612 ch
= ' '; /* return space */
1613 } else if (ch1
== '*') {
1616 while (ch1
!= CH_EOF
) {
1619 if (c
== '*' && ch1
== '/') {
1621 ch
= ' '; /* return space */
1633 /* space exlcuding newline */
1634 static inline int is_space(int ch
)
1636 return ch
== ' ' || ch
== '\t' || ch
== '\v' || ch
== '\f' || ch
== '\r';
1639 static inline void skip_spaces(void)
1641 while (is_space(ch
))
1645 /* skip block of text until #else, #elif or #endif. skip also pairs of
1647 void preprocess_skip(void)
1652 while (ch
!= '\n') {
1663 (tok
== TOK_ELSE
|| tok
== TOK_ELIF
|| tok
== TOK_ENDIF
))
1665 if (tok
== TOK_IF
|| tok
== TOK_IFDEF
|| tok
== TOK_IFNDEF
)
1667 else if (tok
== TOK_ENDIF
)
1673 /* ParseState handling */
1675 /* XXX: currently, no include file info is stored. Thus, we cannot display
1676 accurate messages if the function or data definition spans multiple
1679 /* save current parse state in 's' */
1680 void save_parse_state(ParseState
*s
)
1682 s
->line_num
= file
->line_num
;
1683 s
->macro_ptr
= macro_ptr
;
1688 /* restore parse state from 's' */
1689 void restore_parse_state(ParseState
*s
)
1691 file
->line_num
= s
->line_num
;
1692 macro_ptr
= s
->macro_ptr
;
1697 /* return the number of additionnal 'ints' necessary to store the
1699 static inline int tok_ext_size(int t
)
1718 return LDOUBLE_SIZE
/ 4;
1724 /* token string handling */
1726 static inline void tok_str_new(TokenString
*s
)
1730 s
->last_line_num
= -1;
1733 static void tok_str_free(int *str
)
1744 if (t
== TOK_STR
|| t
== TOK_LSTR
|| t
== TOK_PPNUM
) {
1745 /* XXX: use a macro to be portable on 64 bit ? */
1746 cstr
= (CString
*)(*p
++);
1750 p
+= tok_ext_size(t
);
1756 static void tok_str_add(TokenString
*s
, int t
)
1762 if ((len
& 63) == 0) {
1763 str
= tcc_realloc(str
, (len
+ 64) * sizeof(int));
1772 static void tok_str_add2(TokenString
*s
, int t
, CValue
*cv
)
1775 CString
*cstr
, *cstr1
;
1779 if (t
== TOK_STR
|| t
== TOK_LSTR
|| t
== TOK_PPNUM
) {
1780 /* special case: need to duplicate string */
1782 cstr
= tcc_malloc(sizeof(CString
));
1785 cstr
->size_allocated
= size
;
1786 cstr
->data_allocated
= tcc_malloc(size
);
1787 cstr
->data
= cstr
->data_allocated
;
1788 memcpy(cstr
->data_allocated
, cstr1
->data_allocated
, size
);
1790 tok_str_add(s
, cv1
.tab
[0]);
1792 n
= tok_ext_size(t
);
1794 tok_str_add(s
, cv
->tab
[i
]);
1798 /* add the current parse token in token string 's' */
1799 static void tok_str_add_tok(TokenString
*s
)
1803 /* save line number info */
1804 if (file
->line_num
!= s
->last_line_num
) {
1805 s
->last_line_num
= file
->line_num
;
1806 cval
.i
= s
->last_line_num
;
1807 tok_str_add2(s
, TOK_LINENUM
, &cval
);
1809 tok_str_add2(s
, tok
, &tokc
);
1812 /* get a token from an integer array and increment pointer accordingly */
1813 static int tok_get(int **tok_str
, CValue
*cv
)
1819 n
= tok_ext_size(t
);
1826 /* defines handling */
1827 static inline void define_push(int v
, int macro_type
, int *str
, Sym
*first_arg
)
1831 s
= sym_push2(&define_stack
, v
, macro_type
, (int)str
);
1832 s
->next
= first_arg
;
1833 table_ident
[v
- TOK_IDENT
]->sym_define
= s
;
1836 /* undefined a define symbol. Its name is just set to zero */
1837 static void define_undef(Sym
*s
)
1841 if (v
>= TOK_IDENT
&& v
< tok_ident
)
1842 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
1846 static inline Sym
*define_find(int v
)
1849 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1851 return table_ident
[v
]->sym_define
;
1854 /* free define stack until top reaches 'b' */
1855 static void free_defines(Sym
*b
)
1863 /* do not free args or predefined defines */
1865 tok_str_free((int *)top
->c
);
1867 if (v
>= TOK_IDENT
&& v
< tok_ident
)
1868 table_ident
[v
- TOK_IDENT
]->sym_define
= NULL
;
1876 static Sym
*label_find(int v
)
1879 if ((unsigned)v
>= (unsigned)(tok_ident
- TOK_IDENT
))
1881 return table_ident
[v
]->sym_label
;
1884 static Sym
*label_push(int v
, int flags
)
1887 s
= sym_push2(&label_stack
, v
, 0, 0);
1889 table_ident
[v
- TOK_IDENT
]->sym_label
= s
;
1893 /* eval an expression for #if/#elif */
1894 int expr_preprocess(void)
1900 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1901 next(); /* do macro subst */
1902 if (tok
== TOK_DEFINED
) {
1907 c
= define_find(tok
) != 0;
1912 } else if (tok
>= TOK_IDENT
) {
1913 /* if undefined macro */
1917 tok_str_add_tok(&str
);
1919 tok_str_add(&str
, -1); /* simulate end of file */
1920 tok_str_add(&str
, 0);
1921 /* now evaluate C constant expression */
1922 macro_ptr
= str
.str
;
1926 tok_str_free(str
.str
);
1930 #if defined(DEBUG) || defined(PP_DEBUG)
1931 void tok_print(int *str
)
1937 t
= tok_get(&str
, &cval
);
1940 printf(" %s", get_tok_str(t
, &cval
));
1946 /* parse after #define */
1947 void parse_define(void)
1949 Sym
*s
, *first
, **ps
;
1950 int v
, t
, varg
, is_vaargs
;
1955 error("invalid macro name '%s'", get_tok_str(tok
, &tokc
));
1956 /* XXX: should check if same macro (ANSI) */
1959 /* '(' must be just after macro definition for MACRO_FUNC */
1964 while (tok
!= ')') {
1968 if (varg
== TOK_DOTS
) {
1969 varg
= TOK___VA_ARGS__
;
1971 } else if (tok
== TOK_DOTS
&& gnu_ext
) {
1975 if (varg
< TOK_IDENT
)
1976 error("badly punctuated parameter list");
1977 s
= sym_push2(&define_stack
, varg
| SYM_FIELD
, is_vaargs
, 0);
1988 /* EOF testing necessary for '-D' handling */
1989 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
) {
1990 tok_str_add2(&str
, tok
, &tokc
);
1993 tok_str_add(&str
, 0);
1995 printf("define %s %d: ", get_tok_str(v
, NULL
), t
);
1998 define_push(v
, t
, str
.str
, first
);
2001 /* XXX: use a token or a hash table to accelerate matching ? */
2002 static CachedInclude
*search_cached_include(TCCState
*s1
,
2003 int type
, const char *filename
)
2008 for(i
= 0;i
< s1
->nb_cached_includes
; i
++) {
2009 e
= s1
->cached_includes
[i
];
2010 if (e
->type
== type
&& !strcmp(e
->filename
, filename
))
2016 static inline void add_cached_include(TCCState
*s1
, int type
,
2017 const char *filename
, int ifndef_macro
)
2021 if (search_cached_include(s1
, type
, filename
))
2024 printf("adding cached '%s' %s\n", filename
, get_tok_str(ifndef_macro
, NULL
));
2026 e
= tcc_malloc(sizeof(CachedInclude
) + strlen(filename
));
2030 strcpy(e
->filename
, filename
);
2031 e
->ifndef_macro
= ifndef_macro
;
2032 dynarray_add((void ***)&s1
->cached_includes
, &s1
->nb_cached_includes
, e
);
2037 INCLUDE_STATE_NONE
= 0,
2038 INCLUDE_STATE_SEEK_IFNDEF
,
2041 void preprocess(void)
2043 TCCState
*s1
= tcc_state
;
2044 int size
, i
, c
, n
, line_num
;
2045 enum IncludeState state
;
2046 char buf
[1024], *q
, *p
;
2052 return_linefeed
= 1; /* linefeed will be returned as a
2053 token. EOF is also returned as line feed */
2054 state
= INCLUDE_STATE_NONE
;
2067 s
= define_find(tok
);
2068 /* undefine symbol by putting an invalid name */
2077 } else if (ch
== '\"') {
2082 while (ch
!= c
&& ch
!= '\n' && ch
!= CH_EOF
) {
2083 if ((q
- buf
) < sizeof(buf
) - 1)
2088 /* eat all spaces and comments after include */
2089 /* XXX: slightly incorrect */
2090 while (ch1
!= '\n' && ch1
!= CH_EOF
)
2093 /* computed #include : either we have only strings or
2094 we have anything enclosed in '<>' */
2097 if (tok
== TOK_STR
) {
2098 while (tok
!= TOK_LINEFEED
) {
2099 if (tok
!= TOK_STR
) {
2101 error("'#include' expects \"FILENAME\" or <FILENAME>");
2103 pstrcat(buf
, sizeof(buf
), (char *)tokc
.cstr
->data
);
2109 while (tok
!= TOK_LINEFEED
) {
2110 pstrcat(buf
, sizeof(buf
), get_tok_str(tok
, &tokc
));
2114 /* check syntax and remove '<>' */
2115 if (len
< 2 || buf
[0] != '<' || buf
[len
- 1] != '>')
2116 goto include_syntax
;
2117 memmove(buf
, buf
+ 1, len
- 2);
2118 buf
[len
- 2] = '\0';
2124 e
= search_cached_include(s1
, c
, buf
);
2125 if (e
&& define_find(e
->ifndef_macro
)) {
2126 /* no need to parse the include because the 'ifndef macro'
2129 printf("%s: skipping %s\n", file
->filename
, buf
);
2133 /* first search in current dir if "header.h" */
2135 p
= strrchr(file
->filename
, '/');
2137 size
= p
+ 1 - file
->filename
;
2138 if (size
> sizeof(buf1
) - 1)
2139 size
= sizeof(buf1
) - 1;
2140 memcpy(buf1
, file
->filename
, size
);
2142 pstrcat(buf1
, sizeof(buf1
), buf
);
2143 f
= tcc_open(s1
, buf1
);
2147 if (s1
->include_stack_ptr
>= s1
->include_stack
+ INCLUDE_STACK_SIZE
)
2148 error("#include recursion too deep");
2149 /* now search in all the include paths */
2150 n
= s1
->nb_include_paths
+ s1
->nb_sysinclude_paths
;
2151 for(i
= 0; i
< n
; i
++) {
2153 if (i
< s1
->nb_include_paths
)
2154 path
= s1
->include_paths
[i
];
2156 path
= s1
->sysinclude_paths
[i
- s1
->nb_include_paths
];
2157 pstrcpy(buf1
, sizeof(buf1
), path
);
2158 pstrcat(buf1
, sizeof(buf1
), "/");
2159 pstrcat(buf1
, sizeof(buf1
), buf
);
2160 f
= tcc_open(s1
, buf1
);
2164 error("include file '%s' not found", buf
);
2168 printf("%s: including %s\n", file
->filename
, buf1
);
2171 pstrcpy(f
->inc_filename
, sizeof(f
->inc_filename
), buf
);
2172 /* push current file in stack */
2173 /* XXX: fix current line init */
2174 *s1
->include_stack_ptr
++ = file
;
2176 /* add include file debug info */
2178 put_stabs(file
->filename
, N_BINCL
, 0, 0, 0);
2180 /* we check for the construct: #ifndef IDENT \n #define IDENT */
2182 /* get first non space char */
2183 while (is_space(ch
) || ch
== '\n')
2187 state
= INCLUDE_STATE_SEEK_IFNDEF
;
2195 c
= expr_preprocess();
2201 if (tok
< TOK_IDENT
)
2202 error("invalid argument for '#if%sdef'", c
? "n" : "");
2203 if (state
== INCLUDE_STATE_SEEK_IFNDEF
) {
2205 file
->ifndef_macro
= tok
;
2207 state
= INCLUDE_STATE_NONE
;
2209 c
= (define_find(tok
) != 0) ^ c
;
2211 if (s1
->ifdef_stack_ptr
>= s1
->ifdef_stack
+ IFDEF_STACK_SIZE
)
2212 error("memory full");
2213 *s1
->ifdef_stack_ptr
++ = c
;
2216 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2217 error("#else without matching #if");
2218 if (s1
->ifdef_stack_ptr
[-1] & 2)
2219 error("#else after #else");
2220 c
= (s1
->ifdef_stack_ptr
[-1] ^= 3);
2223 if (s1
->ifdef_stack_ptr
== s1
->ifdef_stack
)
2224 error("#elif without matching #if");
2225 c
= s1
->ifdef_stack_ptr
[-1];
2227 error("#elif after #else");
2228 /* last #if/#elif expression was true: we skip */
2231 c
= expr_preprocess();
2232 s1
->ifdef_stack_ptr
[-1] = c
;
2237 state
= INCLUDE_STATE_NONE
;
2242 if (s1
->ifdef_stack_ptr
<= file
->ifdef_stack_ptr
)
2243 error("#endif without matching #if");
2244 if (file
->ifndef_macro
&&
2245 s1
->ifdef_stack_ptr
== (file
->ifdef_stack_ptr
+ 1)) {
2246 /* '#ifndef macro \n #define macro' was at the start of
2247 file. Now we check if an '#endif' is exactly at the end
2249 while (tok
!= TOK_LINEFEED
)
2251 /* XXX: should also skip comments, but it is more complicated */
2253 add_cached_include(s1
, file
->inc_type
, file
->inc_filename
,
2254 file
->ifndef_macro
);
2256 /* if not end of file, we must desactivate the ifndef
2258 file
->ifndef_macro
= 0;
2261 s1
->ifdef_stack_ptr
--;
2265 if (tok
!= TOK_CINT
)
2269 if (tok
!= TOK_LINEFEED
) {
2272 pstrcpy(file
->filename
, sizeof(file
->filename
),
2273 (char *)tokc
.cstr
->data
);
2275 /* NOTE: we do it there to avoid problems with linefeed */
2276 file
->line_num
= line_num
;
2283 while (ch
!= '\n' && ch
!= CH_EOF
) {
2284 if ((q
- buf
) < sizeof(buf
) - 1)
2290 error("#error %s", buf
);
2292 warning("#warning %s", buf
);
2295 if (tok
== TOK_LINEFEED
|| tok
== '!' || tok
== TOK_CINT
) {
2296 /* '!' is ignored to allow C scripts. numbers are ignored
2297 to emulate cpp behaviour */
2299 error("invalid preprocessing directive #%s", get_tok_str(tok
, &tokc
));
2303 /* ignore other preprocess commands or #! for C scripts */
2304 while (tok
!= TOK_LINEFEED
&& tok
!= TOK_EOF
)
2307 return_linefeed
= 0;
2310 /* read a number in base b */
2311 static int getn(int b
)
2316 if (ch
>= 'a' && ch
<= 'f')
2318 else if (ch
>= 'A' && ch
<= 'F')
2324 if (t
< 0 || t
>= b
)
2332 /* read a character for string or char constant and eval escape codes */
2333 static int getq(void)
2341 /* at most three octal digits */
2345 c
= c
* 8 + ch
- '0';
2348 c
= c
* 8 + ch
- '0';
2353 } else if (ch
== 'x') {
2371 else if (ch
== 'e' && gnu_ext
)
2373 else if (ch
== '\'' || ch
== '\"' || ch
== '\\' || ch
== '?')
2376 error("invalid escaped char");
2379 } else if (c
== '\r' && ch
== '\n') {
2386 /* we use 64 bit numbers */
2389 /* bn = (bn << shift) | or_val */
2390 void bn_lshift(unsigned int *bn
, int shift
, int or_val
)
2394 for(i
=0;i
<BN_SIZE
;i
++) {
2396 bn
[i
] = (v
<< shift
) | or_val
;
2397 or_val
= v
>> (32 - shift
);
2401 void bn_zero(unsigned int *bn
)
2404 for(i
=0;i
<BN_SIZE
;i
++) {
2409 /* parse number in null terminated string 'p' and return it in the
2411 void parse_number(const char *p
)
2413 int b
, t
, shift
, frac_bits
, s
, exp_val
, ch
;
2415 unsigned int bn
[BN_SIZE
];
2426 goto float_frac_parse
;
2427 } else if (t
== '0') {
2428 if (ch
== 'x' || ch
== 'X') {
2432 } else if (tcc_ext
&& (ch
== 'b' || ch
== 'B')) {
2438 /* parse all digits. cannot check octal numbers at this stage
2439 because of floating point constants */
2441 if (ch
>= 'a' && ch
<= 'f')
2443 else if (ch
>= 'A' && ch
<= 'F')
2451 if (q
>= token_buf
+ STRING_MAX_SIZE
) {
2453 error("number too long");
2459 ((ch
== 'e' || ch
== 'E') && b
== 10) ||
2460 ((ch
== 'p' || ch
== 'P') && (b
== 16 || b
== 2))) {
2462 /* NOTE: strtox should support that for hexa numbers, but
2463 non ISOC99 libcs do not support it, so we prefer to do
2465 /* hexadecimal or binary floats */
2466 /* XXX: handle overflows */
2478 } else if (t
>= 'a') {
2480 } else if (t
>= 'A') {
2485 bn_lshift(bn
, shift
, t
);
2492 if (t
>= 'a' && t
<= 'f') {
2494 } else if (t
>= 'A' && t
<= 'F') {
2496 } else if (t
>= '0' && t
<= '9') {
2502 error("invalid digit");
2503 bn_lshift(bn
, shift
, t
);
2508 if (ch
!= 'p' && ch
!= 'P')
2515 } else if (ch
== '-') {
2519 if (ch
< '0' || ch
> '9')
2520 expect("exponent digits");
2521 while (ch
>= '0' && ch
<= '9') {
2522 exp_val
= exp_val
* 10 + ch
- '0';
2525 exp_val
= exp_val
* s
;
2527 /* now we can generate the number */
2528 /* XXX: should patch directly float number */
2529 d
= (double)bn
[1] * 4294967296.0 + (double)bn
[0];
2530 d
= ldexp(d
, exp_val
- frac_bits
);
2535 /* float : should handle overflow */
2537 } else if (t
== 'L') {
2540 /* XXX: not large enough */
2541 tokc
.ld
= (long double)d
;
2547 /* decimal floats */
2549 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2554 while (ch
>= '0' && ch
<= '9') {
2555 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2561 if (ch
== 'e' || ch
== 'E') {
2562 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2566 if (ch
== '-' || ch
== '+') {
2567 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2572 if (ch
< '0' || ch
> '9')
2573 expect("exponent digits");
2574 while (ch
>= '0' && ch
<= '9') {
2575 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2587 tokc
.f
= strtof(token_buf
, NULL
);
2588 } else if (t
== 'L') {
2591 tokc
.ld
= strtold(token_buf
, NULL
);
2594 tokc
.d
= strtod(token_buf
, NULL
);
2598 unsigned long long n
, n1
;
2601 /* integer number */
2604 if (b
== 10 && *q
== '0') {
2611 /* no need for checks except for base 10 / 8 errors */
2614 } else if (t
>= 'a') {
2616 } else if (t
>= 'A') {
2621 error("invalid digit");
2625 /* detect overflow */
2626 /* XXX: this test is not reliable */
2628 error("integer constant overflow");
2631 /* XXX: not exactly ANSI compliant */
2632 if ((n
& 0xffffffff00000000LL
) != 0) {
2637 } else if (n
> 0x7fffffff) {
2648 error("three 'l's in integer constant");
2651 if (tok
== TOK_CINT
)
2653 else if (tok
== TOK_CUINT
)
2657 } else if (t
== 'U') {
2659 error("two 'u's in integer constant");
2661 if (tok
== TOK_CINT
)
2663 else if (tok
== TOK_CLLONG
)
2670 if (tok
== TOK_CINT
|| tok
== TOK_CUINT
)
2677 /* return next token without macro substitution */
2678 static inline void next_nomacro1(void)
2695 if (return_linefeed
) {
2696 /* XXX: should eat token ? */
2702 /* preprocessor command if # at start of line after
2714 if (start_of_line
) {
2722 tok
= TOK_TWOSHARPS
;
2727 case 'a': case 'b': case 'c': case 'd':
2728 case 'e': case 'f': case 'g': case 'h':
2729 case 'i': case 'j': case 'k': case 'l':
2730 case 'm': case 'n': case 'o': case 'p':
2731 case 'q': case 'r': case 's': case 't':
2732 case 'u': case 'v': case 'w': case 'x':
2734 case 'A': case 'B': case 'C': case 'D':
2735 case 'E': case 'F': case 'G': case 'H':
2736 case 'I': case 'J': case 'K':
2737 case 'M': case 'N': case 'O': case 'P':
2738 case 'Q': case 'R': case 'S': case 'T':
2739 case 'U': case 'V': case 'W': case 'X':
2746 while (isid(ch
) || isnum(ch
)) {
2747 if (q
>= token_buf
+ STRING_MAX_SIZE
)
2748 error("ident too long");
2753 ts
= tok_alloc(token_buf
, q
- token_buf
);
2770 case '0': case '1': case '2': case '3':
2771 case '4': case '5': case '6': case '7':
2774 cstr_reset(&tokcstr
);
2775 /* after the first digit, accept digits, alpha, '.' or sign if
2776 prefixed by 'eEpP' */
2780 cstr_ccat(&tokcstr
, ch
);
2782 if (!(isnum(ch
) || isid(ch
) || ch
== '.' ||
2783 ((ch
== '+' || ch
== '-') &&
2784 (t
== 'e' || t
== 'E' || t
== 'p' || t
== 'P'))))
2787 /* We add a trailing '\0' to ease parsing */
2788 cstr_ccat(&tokcstr
, '\0');
2789 tokc
.cstr
= &tokcstr
;
2793 /* special dot handling because it can also start a number */
2796 cstr_reset(&tokcstr
);
2797 cstr_ccat(&tokcstr
, '.');
2815 /* this cast is needed if >= 128 */
2816 if (tok
== TOK_CCHAR
)
2820 error("unterminated character constant");
2827 cstr_reset(&tokcstr
);
2828 while (ch
!= '\"') {
2831 error("unterminated string");
2833 cstr_ccat(&tokcstr
, b
);
2835 cstr_wccat(&tokcstr
, b
);
2838 cstr_ccat(&tokcstr
, '\0');
2840 cstr_wccat(&tokcstr
, '\0');
2841 tokc
.cstr
= &tokcstr
;
2850 } else if (ch
== '<') {
2868 } else if (ch
== '>') {
2905 } else if (ch
== '=') {
2917 } else if (ch
== '=') {
2929 } else if (ch
== '=') {
2941 } else if (ch
== '=') {
2944 } else if (ch
== '>') {
2977 /* comments or operator */
2986 else if (ch
== '/' || ch
== '*') {
3012 error("unrecognized character \\x%02x", ch
);
3017 /* return next token without macro substitution. Can read input from
3019 static void next_nomacro(void)
3025 tok
= tok_get(¯o_ptr
, &tokc
);
3026 if (tok
== TOK_LINENUM
) {
3027 file
->line_num
= tokc
.i
;
3036 /* substitute args in macro_str and return allocated string */
3037 static int *macro_arg_subst(Sym
**nested_list
, int *macro_str
, Sym
*args
)
3039 int *st
, last_tok
, t
, notfirst
;
3048 t
= tok_get(¯o_str
, &cval
);
3053 t
= tok_get(¯o_str
, &cval
);
3056 s
= sym_find2(args
, t
);
3063 cstr_ccat(&cstr
, ' ');
3064 t
= tok_get(&st
, &cval
);
3065 cstr_cat(&cstr
, get_tok_str(t
, &cval
));
3068 cstr_ccat(&cstr
, '\0');
3070 printf("stringize: %s\n", (char *)cstr
.data
);
3074 tok_str_add2(&str
, TOK_STR
, &cval
);
3077 tok_str_add2(&str
, t
, &cval
);
3079 } else if (t
>= TOK_IDENT
) {
3080 s
= sym_find2(args
, t
);
3083 /* if '##' is present before or after, no arg substitution */
3084 if (*macro_str
== TOK_TWOSHARPS
|| last_tok
== TOK_TWOSHARPS
) {
3085 /* special case for var arg macros : ## eats the
3086 ',' if empty VA_ARGS variable. */
3087 /* XXX: test of the ',' is not 100%
3088 reliable. should fix it to avoid security
3090 if (gnu_ext
&& s
->type
.t
&&
3091 last_tok
== TOK_TWOSHARPS
&&
3092 str
.len
>= 2 && str
.str
[str
.len
- 2] == ',') {
3094 /* suppress ',' '##' */
3097 /* suppress '##' and add variable */
3105 t1
= tok_get(&st
, &cval
);
3108 tok_str_add2(&str
, t1
, &cval
);
3112 macro_subst(&str
, nested_list
, st
);
3115 tok_str_add(&str
, t
);
3118 tok_str_add2(&str
, t
, &cval
);
3122 tok_str_add(&str
, 0);
3126 /* handle the '##' operator */
3127 static int *macro_twosharps(void)
3132 const char *p1
, *p2
;
3134 TokenString macro_str1
;
3138 tok_str_new(¯o_str1
);
3144 while (*macro_ptr
== TOK_TWOSHARPS
) {
3146 macro_ptr1
= macro_ptr
;
3149 t
= tok_get(¯o_ptr
, &cval
);
3151 /* We concatenate the two tokens if we have an
3152 identifier or a preprocessing number */
3154 p1
= get_tok_str(tok
, &tokc
);
3155 cstr_cat(&cstr
, p1
);
3156 p2
= get_tok_str(t
, &cval
);
3157 cstr_cat(&cstr
, p2
);
3158 cstr_ccat(&cstr
, '\0');
3160 if ((tok
>= TOK_IDENT
|| tok
== TOK_PPNUM
) &&
3161 (t
>= TOK_IDENT
|| t
== TOK_PPNUM
)) {
3162 if (tok
== TOK_PPNUM
) {
3163 /* if number, then create a number token */
3164 /* NOTE: no need to allocate because
3165 tok_str_add2() does it */
3168 /* if identifier, we must do a test to
3169 validate we have a correct identifier */
3170 if (t
== TOK_PPNUM
) {
3180 if (!isnum(c
) && !isid(c
))
3184 ts
= tok_alloc(cstr
.data
, strlen(cstr
.data
));
3185 tok
= ts
->tok
; /* modify current token */
3188 const char *str
= cstr
.data
;
3189 const unsigned char *q
;
3191 /* we look for a valid token */
3192 /* XXX: do more extensive checks */
3193 if (!strcmp(str
, ">>=")) {
3195 } else if (!strcmp(str
, "<<=")) {
3197 } else if (strlen(str
) == 2) {
3198 /* search in two bytes table */
3203 if (q
[0] == str
[0] && q
[1] == str
[1])
3210 /* NOTE: because get_tok_str use a static buffer,
3213 p1
= get_tok_str(tok
, &tokc
);
3214 cstr_cat(&cstr
, p1
);
3215 cstr_ccat(&cstr
, '\0');
3216 p2
= get_tok_str(t
, &cval
);
3217 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr
.data
, p2
);
3218 /* cannot merge tokens: just add them separately */
3219 tok_str_add2(¯o_str1
, tok
, &tokc
);
3220 /* XXX: free associated memory ? */
3227 tok_str_add2(¯o_str1
, tok
, &tokc
);
3230 tok_str_add(¯o_str1
, 0);
3231 return macro_str1
.str
;
3235 /* do macro substitution of current token with macro 's' and add
3236 result to (tok_str,tok_len). 'nested_list' is the list of all
3237 macros we got inside to avoid recursing. Return non zero if no
3238 substitution needs to be done */
3239 static int macro_subst_tok(TokenString
*tok_str
,
3240 Sym
**nested_list
, Sym
*s
)
3242 Sym
*args
, *sa
, *sa1
;
3243 int mstr_allocated
, parlevel
, *mstr
, t
;
3249 /* if symbol is a macro, prepare substitution */
3250 /* if nested substitution, do nothing */
3251 if (sym_find2(*nested_list
, tok
))
3254 /* special macros */
3255 if (tok
== TOK___LINE__
) {
3256 cval
.i
= file
->line_num
;
3257 tok_str_add2(tok_str
, TOK_CINT
, &cval
);
3258 } else if (tok
== TOK___FILE__
) {
3259 cstrval
= file
->filename
;
3261 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3262 } else if (tok
== TOK___DATE__
) {
3263 cstrval
= "Jan 1 2002";
3265 } else if (tok
== TOK___TIME__
) {
3266 cstrval
= "00:00:00";
3269 cstr_cat(&cstr
, cstrval
);
3270 cstr_ccat(&cstr
, '\0');
3272 tok_str_add2(tok_str
, TOK_STR
, &cval
);
3277 if (s
->type
.t
== MACRO_FUNC
) {
3278 /* NOTE: we do not use next_nomacro to avoid eating the
3279 next token. XXX: find better solution */
3283 while (is_space(ch
) || ch
== '\n')
3287 if (t
!= '(') /* no macro subst */
3290 /* argument macro */
3295 /* NOTE: empty args are allowed, except if no args */
3297 /* handle '()' case */
3298 if (!args
&& tok
== ')')
3301 error("macro '%s' used with too many args",
3302 get_tok_str(s
->v
, 0));
3305 /* NOTE: non zero sa->t indicates VA_ARGS */
3306 while ((parlevel
> 0 ||
3308 (tok
!= ',' || sa
->type
.t
))) &&
3312 else if (tok
== ')')
3314 tok_str_add2(&str
, tok
, &tokc
);
3317 tok_str_add(&str
, 0);
3318 sym_push2(&args
, sa
->v
& ~SYM_FIELD
, sa
->type
.t
, (int)str
.str
);
3321 /* special case for gcc var args: add an empty
3322 var arg argument if it is omitted */
3323 if (sa
&& sa
->type
.t
&& gnu_ext
)
3333 error("macro '%s' used with too few args",
3334 get_tok_str(s
->v
, 0));
3337 /* now subst each arg */
3338 mstr
= macro_arg_subst(nested_list
, mstr
, args
);
3343 tok_str_free((int *)sa
->c
);
3349 sym_push2(nested_list
, s
->v
, 0, 0);
3350 macro_subst(tok_str
, nested_list
, mstr
);
3351 /* pop nested defined symbol */
3353 *nested_list
= sa1
->prev
;
3361 /* do macro substitution of macro_str and add result to
3362 (tok_str,tok_len). 'nested_list' is the list of all macros we got
3363 inside to avoid recursing. */
3364 static void macro_subst(TokenString
*tok_str
,
3365 Sym
**nested_list
, int *macro_str
)
3368 int *saved_macro_ptr
;
3371 saved_macro_ptr
= macro_ptr
;
3372 macro_ptr
= macro_str
;
3373 /* first scan for '##' operator handling */
3374 macro_str1
= macro_twosharps();
3375 macro_ptr
= macro_str1
;
3381 s
= define_find(tok
);
3383 if (macro_subst_tok(tok_str
, nested_list
, s
) != 0)
3387 tok_str_add2(tok_str
, tok
, &tokc
);
3390 macro_ptr
= saved_macro_ptr
;
3391 tok_str_free(macro_str1
);
3394 /* return next token with macro substitution */
3395 static void next(void)
3397 Sym
*nested_list
, *s
;
3400 /* special 'ungettok' case for label parsing */
3409 /* if not reading from macro substituted string, then try
3410 to substitute macros */
3411 if (tok
>= TOK_IDENT
) {
3412 s
= define_find(tok
);
3414 /* we have a macro: we try to substitute */
3417 if (macro_subst_tok(&str
, &nested_list
, s
) == 0) {
3418 /* substitution done, NOTE: maybe empty */
3419 tok_str_add(&str
, 0);
3420 macro_ptr
= str
.str
;
3421 macro_ptr_allocated
= str
.str
;
3428 /* end of macro string: free it */
3429 tok_str_free(macro_ptr_allocated
);
3435 /* convert preprocessor tokens into C tokens */
3436 if (tok
== TOK_PPNUM
) {
3437 parse_number((char *)tokc
.cstr
->data
);
3441 printf("token = %s\n", get_tok_str(tok
, &tokc
));
3445 void swap(int *p
, int *q
)
3453 void vsetc(CType
*type
, int r
, CValue
*vc
)
3457 if (vtop
>= vstack
+ VSTACK_SIZE
)
3458 error("memory full");
3459 /* cannot let cpu flags if other instruction are generated. Also
3460 avoid leaving VT_JMP anywhere except on the top of the stack
3461 because it would complicate the code generator. */
3462 if (vtop
>= vstack
) {
3463 v
= vtop
->r
& VT_VALMASK
;
3464 if (v
== VT_CMP
|| (v
& ~1) == VT_JMP
)
3470 vtop
->r2
= VT_CONST
;
3474 /* push integer constant */
3479 vsetc(&int_type
, VT_CONST
, &cval
);
3482 /* Return a static symbol pointing to a section */
3483 static Sym
*get_sym_ref(CType
*type
, Section
*sec
,
3484 unsigned long offset
, unsigned long size
)
3490 sym
= global_identifier_push(v
, type
->t
| VT_STATIC
, 0);
3491 sym
->type
.ref
= type
->ref
;
3492 sym
->r
= VT_CONST
| VT_SYM
;
3493 put_extern_sym(sym
, sec
, offset
, size
);
3497 /* push a reference to a section offset by adding a dummy symbol */
3498 static void vpush_ref(CType
*type
, Section
*sec
, unsigned long offset
, unsigned long size
)
3503 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
3504 vtop
->sym
= get_sym_ref(type
, sec
, offset
, size
);
3507 /* define a new external reference to a symbol 'v' of type 'u' */
3508 static Sym
*external_global_sym(int v
, CType
*type
, int r
)
3514 /* push forward reference */
3515 s
= global_identifier_push(v
, type
->t
| VT_EXTERN
, 0);
3516 s
->type
.ref
= type
->ref
;
3517 s
->r
= r
| VT_CONST
| VT_SYM
;
3522 /* define a new external reference to a symbol 'v' of type 'u' */
3523 static Sym
*external_sym(int v
, CType
*type
, int r
)
3529 /* push forward reference */
3530 s
= sym_push(v
, type
, r
| VT_CONST
| VT_SYM
, 0);
3531 s
->type
.t
|= VT_EXTERN
;
3536 /* push a reference to global symbol v */
3537 static void vpush_global_sym(CType
*type
, int v
)
3542 sym
= external_global_sym(v
, type
, 0);
3544 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
3548 void vset(CType
*type
, int r
, int v
)
3553 vsetc(type
, r
, &cval
);
3556 void vseti(int r
, int v
)
3572 void vpushv(SValue
*v
)
3574 if (vtop
>= vstack
+ VSTACK_SIZE
)
3575 error("memory full");
3585 /* save r to the memory stack, and mark it as being free */
3586 void save_reg(int r
)
3588 int l
, saved
, size
, align
;
3592 /* modify all stack values */
3595 for(p
=vstack
;p
<=vtop
;p
++) {
3596 if ((p
->r
& VT_VALMASK
) == r
||
3597 (p
->r2
& VT_VALMASK
) == r
) {
3598 /* must save value on stack if not already done */
3600 /* NOTE: must reload 'r' because r might be equal to r2 */
3601 r
= p
->r
& VT_VALMASK
;
3602 /* store register in the stack */
3604 if ((p
->r
& VT_LVAL
) ||
3605 (!is_float(type
->t
) && (type
->t
& VT_BTYPE
) != VT_LLONG
))
3607 size
= type_size(type
, &align
);
3608 loc
= (loc
- size
) & -align
;
3609 sv
.type
.t
= type
->t
;
3610 sv
.r
= VT_LOCAL
| VT_LVAL
;
3613 #ifdef TCC_TARGET_I386
3614 /* x86 specific: need to pop fp register ST0 if saved */
3616 o(0xd9dd); /* fstp %st(1) */
3619 /* special long long case */
3620 if ((type
->t
& VT_BTYPE
) == VT_LLONG
) {
3627 /* mark that stack entry as being saved on the stack */
3628 if (p
->r
& VT_LVAL
) {
3629 /* also suppress the bounded flag because the
3630 relocation address of the function was stored in
3632 p
->r
= (p
->r
& ~(VT_VALMASK
| VT_BOUNDED
)) | VT_LLOCAL
;
3634 p
->r
= lvalue_type(p
->type
.t
) | VT_LOCAL
;
3642 /* find a free register of class 'rc'. If none, save one register */
3648 /* find a free register */
3649 for(r
=0;r
<NB_REGS
;r
++) {
3650 if (reg_classes
[r
] & rc
) {
3651 for(p
=vstack
;p
<=vtop
;p
++) {
3652 if ((p
->r
& VT_VALMASK
) == r
||
3653 (p
->r2
& VT_VALMASK
) == r
)
3661 /* no register left : free the first one on the stack (VERY
3662 IMPORTANT to start from the bottom to ensure that we don't
3663 spill registers used in gen_opi()) */
3664 for(p
=vstack
;p
<=vtop
;p
++) {
3665 r
= p
->r
& VT_VALMASK
;
3666 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
))
3668 /* also look at second register (if long long) */
3669 r
= p
->r2
& VT_VALMASK
;
3670 if (r
< VT_CONST
&& (reg_classes
[r
] & rc
)) {
3676 /* Should never comes here */
3680 /* save registers up to (vtop - n) stack entry */
3681 void save_regs(int n
)
3686 for(p
= vstack
;p
<= p1
; p
++) {
3687 r
= p
->r
& VT_VALMASK
;
3694 /* move register 's' to 'r', and flush previous value of r to memory
3696 void move_reg(int r
, int s
)
3709 /* get address of vtop (vtop MUST BE an lvalue) */
3712 vtop
->r
&= ~VT_LVAL
;
3713 /* tricky: if saved lvalue, then we can go back to lvalue */
3714 if ((vtop
->r
& VT_VALMASK
) == VT_LLOCAL
)
3715 vtop
->r
= (vtop
->r
& ~(VT_VALMASK
| VT_LVAL_TYPE
)) | VT_LOCAL
| VT_LVAL
;
3718 #ifdef CONFIG_TCC_BCHECK
3719 /* generate lvalue bound code */
3725 vtop
->r
&= ~VT_MUSTBOUND
;
3726 /* if lvalue, then use checking code before dereferencing */
3727 if (vtop
->r
& VT_LVAL
) {
3728 /* if not VT_BOUNDED value, then make one */
3729 if (!(vtop
->r
& VT_BOUNDED
)) {
3730 lval_type
= vtop
->r
& (VT_LVAL_TYPE
| VT_LVAL
);
3731 /* must save type because we must set it to int to get pointer */
3733 vtop
->type
.t
= VT_INT
;
3736 gen_bounded_ptr_add();
3737 vtop
->r
|= lval_type
;
3740 /* then check for dereferencing */
3741 gen_bounded_ptr_deref();
3746 /* store vtop a register belonging to class 'rc'. lvalues are
3747 converted to values. Cannot be used if cannot be converted to
3748 register value (such as structures). */
3751 int r
, r2
, rc2
, bit_pos
, bit_size
, size
, align
, i
;
3752 unsigned long long ll
;
3754 /* NOTE: get_reg can modify vstack[] */
3755 if (vtop
->type
.t
& VT_BITFIELD
) {
3756 bit_pos
= (vtop
->type
.t
>> VT_STRUCT_SHIFT
) & 0x3f;
3757 bit_size
= (vtop
->type
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
3758 /* remove bit field info to avoid loops */
3759 vtop
->type
.t
&= ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
3760 /* generate shifts */
3761 vpushi(32 - (bit_pos
+ bit_size
));
3763 vpushi(32 - bit_size
);
3764 /* NOTE: transformed to SHR if unsigned */
3768 if (is_float(vtop
->type
.t
) &&
3769 (vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3772 unsigned long offset
;
3774 /* XXX: unify with initializers handling ? */
3775 /* CPUs usually cannot use float constants, so we store them
3776 generically in data segment */
3777 size
= type_size(&vtop
->type
, &align
);
3778 offset
= (data_section
->data_offset
+ align
- 1) & -align
;
3779 data_section
->data_offset
= offset
;
3780 /* XXX: not portable yet */
3781 ptr
= section_ptr_add(data_section
, size
);
3784 ptr
[i
] = vtop
->c
.tab
[i
];
3785 sym
= get_sym_ref(&vtop
->type
, data_section
, offset
, size
<< 2);
3786 vtop
->r
|= VT_LVAL
| VT_SYM
;
3790 #ifdef CONFIG_TCC_BCHECK
3791 if (vtop
->r
& VT_MUSTBOUND
)
3795 r
= vtop
->r
& VT_VALMASK
;
3796 /* need to reload if:
3798 - lvalue (need to dereference pointer)
3799 - already a register, but not in the right class */
3800 if (r
>= VT_CONST
||
3801 (vtop
->r
& VT_LVAL
) ||
3802 !(reg_classes
[r
] & rc
) ||
3803 ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
&&
3804 !(reg_classes
[vtop
->r2
] & rc
))) {
3806 if ((vtop
->type
.t
& VT_BTYPE
) == VT_LLONG
) {
3807 /* two register type load : expand to two words
3809 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) == VT_CONST
) {
3812 vtop
->c
.ui
= ll
; /* first word */
3814 vtop
->r
= r
; /* save register value */
3815 vpushi(ll
>> 32); /* second word */
3816 } else if (r
>= VT_CONST
||
3817 (vtop
->r
& VT_LVAL
)) {
3818 /* load from memory */
3821 vtop
[-1].r
= r
; /* save register value */
3822 /* increment pointer to get second word */
3823 vtop
->type
.t
= VT_INT
;
3829 /* move registers */
3832 vtop
[-1].r
= r
; /* save register value */
3833 vtop
->r
= vtop
[-1].r2
;
3835 /* allocate second register */
3842 /* write second register */
3844 } else if ((vtop
->r
& VT_LVAL
) && !is_float(vtop
->type
.t
)) {
3846 /* lvalue of scalar type : need to use lvalue type
3847 because of possible cast */
3850 /* compute memory access type */
3851 if (vtop
->r
& VT_LVAL_BYTE
)
3853 else if (vtop
->r
& VT_LVAL_SHORT
)
3855 if (vtop
->r
& VT_LVAL_UNSIGNED
)
3859 /* restore wanted type */
3862 /* one register type load */
3871 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
3872 void gv2(int rc1
, int rc2
)
3876 /* generate more generic register first. But VT_JMP or VT_CMP
3877 values must be generated first in all cases to avoid possible
3879 v
= vtop
[0].r
& VT_VALMASK
;
3880 if (v
!= VT_CMP
&& (v
& ~1) != VT_JMP
&& rc1
<= rc2
) {
3885 /* test if reload is needed for first register */
3886 if ((vtop
[-1].r
& VT_VALMASK
) >= VT_CONST
) {
3896 /* test if reload is needed for first register */
3897 if ((vtop
[0].r
& VT_VALMASK
) >= VT_CONST
) {
3903 /* expand long long on stack in two int registers */
3908 u
= vtop
->type
.t
& VT_UNSIGNED
;
3911 vtop
[0].r
= vtop
[-1].r2
;
3912 vtop
[0].r2
= VT_CONST
;
3913 vtop
[-1].r2
= VT_CONST
;
3914 vtop
[0].type
.t
= VT_INT
| u
;
3915 vtop
[-1].type
.t
= VT_INT
| u
;
3918 /* build a long long from two ints */
3921 gv2(RC_INT
, RC_INT
);
3922 vtop
[-1].r2
= vtop
[0].r
;
3923 vtop
[-1].type
.t
= t
;
3927 /* rotate n first stack elements to the bottom */
3934 for(i
=-n
+1;i
!=0;i
++)
3935 vtop
[i
] = vtop
[i
+1];
3939 /* pop stack value */
3943 v
= vtop
->r
& VT_VALMASK
;
3944 #ifdef TCC_TARGET_I386
3945 /* for x86, we need to pop the FP stack */
3946 if (v
== REG_ST0
&& !nocode_wanted
) {
3947 o(0xd9dd); /* fstp %st(1) */
3950 if (v
== VT_JMP
|| v
== VT_JMPI
) {
3951 /* need to put correct jump if && or || without test */
3957 /* convert stack entry to register and duplicate its value in another
3965 if ((t
& VT_BTYPE
) == VT_LLONG
) {
3972 /* stack: H L L1 H1 */
3980 /* duplicate value */
3991 load(r1
, &sv
); /* move r to r1 */
3993 /* duplicates value */
3998 /* generate CPU independent (unsigned) long long operations */
3999 void gen_opl(int op
)
4001 int t
, a
, b
, op1
, c
, i
;
4009 func
= TOK___divdi3
;
4012 func
= TOK___udivdi3
;
4015 func
= TOK___moddi3
;
4018 func
= TOK___umoddi3
;
4020 /* call generic long long function */
4021 gfunc_start(&gf
, FUNC_CDECL
);
4024 vpush_global_sym(&func_old_type
, func
);
4028 vtop
->r2
= REG_LRET
;
4041 /* stack: L1 H1 L2 H2 */
4046 vtop
[-2] = vtop
[-3];
4049 /* stack: H1 H2 L1 L2 */
4055 /* stack: H1 H2 L1 L2 ML MH */
4058 /* stack: ML MH H1 H2 L1 L2 */
4062 /* stack: ML MH H1 L2 H2 L1 */
4067 /* stack: ML MH M1 M2 */
4070 } else if (op
== '+' || op
== '-') {
4071 /* XXX: add non carry method too (for MIPS or alpha) */
4077 /* stack: H1 H2 (L1 op L2) */
4080 gen_op(op1
+ 1); /* TOK_xxxC2 */
4083 /* stack: H1 H2 (L1 op L2) */
4086 /* stack: (L1 op L2) H1 H2 */
4088 /* stack: (L1 op L2) (H1 op H2) */
4096 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) {
4097 t
= vtop
[-1].type
.t
;
4101 /* stack: L H shift */
4103 /* constant: simpler */
4104 /* NOTE: all comments are for SHL. the other cases are
4105 done by swaping words */
4116 if (op
!= TOK_SAR
) {
4149 /* XXX: should provide a faster fallback on x86 ? */
4152 func
= TOK___sardi3
;
4155 func
= TOK___shrdi3
;
4158 func
= TOK___shldi3
;
4164 /* compare operations */
4170 /* stack: L1 H1 L2 H2 */
4172 vtop
[-1] = vtop
[-2];
4174 /* stack: L1 L2 H1 H2 */
4177 /* when values are equal, we need to compare low words. since
4178 the jump is inverted, we invert the test too. */
4181 else if (op1
== TOK_GT
)
4183 else if (op1
== TOK_ULT
)
4185 else if (op1
== TOK_UGT
)
4190 if (op1
!= TOK_NE
) {
4194 /* generate non equal test */
4195 /* XXX: NOT PORTABLE yet */
4199 #ifdef TCC_TARGET_I386
4200 b
= psym(0x850f, 0);
4202 error("not implemented");
4215 /* handle integer constant optimizations and various machine
4217 void gen_opic(int op
)
4224 /* currently, we cannot do computations with forward symbols */
4225 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4226 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4230 case '+': v1
->c
.i
+= fc
; break;
4231 case '-': v1
->c
.i
-= fc
; break;
4232 case '&': v1
->c
.i
&= fc
; break;
4233 case '^': v1
->c
.i
^= fc
; break;
4234 case '|': v1
->c
.i
|= fc
; break;
4235 case '*': v1
->c
.i
*= fc
; break;
4242 /* if division by zero, generate explicit division */
4245 error("division by zero in constant");
4249 default: v1
->c
.i
/= fc
; break;
4250 case '%': v1
->c
.i
%= fc
; break;
4251 case TOK_UDIV
: v1
->c
.i
= (unsigned)v1
->c
.i
/ fc
; break;
4252 case TOK_UMOD
: v1
->c
.i
= (unsigned)v1
->c
.i
% fc
; break;
4255 case TOK_SHL
: v1
->c
.i
<<= fc
; break;
4256 case TOK_SHR
: v1
->c
.i
= (unsigned)v1
->c
.i
>> fc
; break;
4257 case TOK_SAR
: v1
->c
.i
>>= fc
; break;
4259 case TOK_ULT
: v1
->c
.i
= (unsigned)v1
->c
.i
< (unsigned)fc
; break;
4260 case TOK_UGE
: v1
->c
.i
= (unsigned)v1
->c
.i
>= (unsigned)fc
; break;
4261 case TOK_EQ
: v1
->c
.i
= v1
->c
.i
== fc
; break;
4262 case TOK_NE
: v1
->c
.i
= v1
->c
.i
!= fc
; break;
4263 case TOK_ULE
: v1
->c
.i
= (unsigned)v1
->c
.i
<= (unsigned)fc
; break;
4264 case TOK_UGT
: v1
->c
.i
= (unsigned)v1
->c
.i
> (unsigned)fc
; break;
4265 case TOK_LT
: v1
->c
.i
= v1
->c
.i
< fc
; break;
4266 case TOK_GE
: v1
->c
.i
= v1
->c
.i
>= fc
; break;
4267 case TOK_LE
: v1
->c
.i
= v1
->c
.i
<= fc
; break;
4268 case TOK_GT
: v1
->c
.i
= v1
->c
.i
> fc
; break;
4270 case TOK_LAND
: v1
->c
.i
= v1
->c
.i
&& fc
; break;
4271 case TOK_LOR
: v1
->c
.i
= v1
->c
.i
|| fc
; break;
4277 /* if commutative ops, put c2 as constant */
4278 if (c1
&& (op
== '+' || op
== '&' || op
== '^' ||
4279 op
== '|' || op
== '*')) {
4284 if (c2
&& (((op
== '*' || op
== '/' || op
== TOK_UDIV
||
4287 ((op
== '+' || op
== '-' || op
== '|' || op
== '^' ||
4288 op
== TOK_SHL
|| op
== TOK_SHR
|| op
== TOK_SAR
) &&
4294 } else if (c2
&& (op
== '*' || op
== TOK_PDIV
|| op
== TOK_UDIV
)) {
4295 /* try to use shifts instead of muls or divs */
4296 if (fc
> 0 && (fc
& (fc
- 1)) == 0) {
4305 else if (op
== TOK_PDIV
)
4311 } else if (c2
&& (op
== '+' || op
== '-') &&
4312 (vtop
[-1].r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) ==
4313 (VT_CONST
| VT_SYM
)) {
4314 /* symbol + constant case */
4321 if (!nocode_wanted
) {
4322 /* call low level op generator */
4331 /* generate a floating point operation with constant propagation */
4332 void gen_opif(int op
)
4340 /* currently, we cannot do computations with forward symbols */
4341 c1
= (v1
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4342 c2
= (v2
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4344 if (v1
->type
.t
== VT_FLOAT
) {
4347 } else if (v1
->type
.t
== VT_DOUBLE
) {
4355 /* NOTE: we only do constant propagation if finite number (not
4356 NaN or infinity) (ANSI spec) */
4357 if (!ieee_finite(f1
) || !ieee_finite(f2
))
4361 case '+': f1
+= f2
; break;
4362 case '-': f1
-= f2
; break;
4363 case '*': f1
*= f2
; break;
4367 error("division by zero in constant");
4372 /* XXX: also handles tests ? */
4376 /* XXX: overflow test ? */
4377 if (v1
->type
.t
== VT_FLOAT
) {
4379 } else if (v1
->type
.t
== VT_DOUBLE
) {
4387 if (!nocode_wanted
) {
4395 static int pointed_size(CType
*type
)
4398 return type_size(pointed_type(type
), &align
);
4402 void check_pointer_types(SValue
*p1
, SValue
*p2
)
4404 char buf1
[256], buf2
[256];
4408 if (!is_compatible_types(t1
, t2
)) {
4409 type_to_str(buf1
, sizeof(buf1
), t1
, NULL
);
4410 type_to_str(buf2
, sizeof(buf2
), t2
, NULL
);
4411 error("incompatible pointers '%s' and '%s'", buf1
, buf2
);
4416 /* generic gen_op: handles types problems */
4419 int u
, t1
, t2
, bt1
, bt2
, t
;
4422 t1
= vtop
[-1].type
.t
;
4423 t2
= vtop
[0].type
.t
;
4424 bt1
= t1
& VT_BTYPE
;
4425 bt2
= t2
& VT_BTYPE
;
4427 if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
4428 /* at least one operand is a pointer */
4429 /* relationnal op: must be both pointers */
4430 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4431 // check_pointer_types(vtop, vtop - 1);
4432 /* pointers are handled are unsigned */
4433 t
= VT_INT
| VT_UNSIGNED
;
4436 /* if both pointers, then it must be the '-' op */
4437 if (bt1
== VT_PTR
&& bt2
== VT_PTR
) {
4439 error("cannot use pointers here");
4440 // check_pointer_types(vtop - 1, vtop);
4441 /* XXX: check that types are compatible */
4442 u
= pointed_size(&vtop
[-1].type
);
4444 /* set to integer type */
4445 vtop
->type
.t
= VT_INT
;
4449 /* exactly one pointer : must be '+' or '-'. */
4450 if (op
!= '-' && op
!= '+')
4451 error("cannot use pointers here");
4452 /* Put pointer as first operand */
4453 if (bt2
== VT_PTR
) {
4457 type1
= vtop
[-1].type
;
4458 /* XXX: cast to int ? (long long case) */
4459 vpushi(pointed_size(&vtop
[-1].type
));
4461 #ifdef CONFIG_TCC_BCHECK
4462 /* if evaluating constant expression, no code should be
4463 generated, so no bound check */
4464 if (do_bounds_check
&& !const_wanted
) {
4465 /* if bounded pointers, we generate a special code to
4472 gen_bounded_ptr_add();
4478 /* put again type if gen_opic() swaped operands */
4481 } else if (is_float(bt1
) || is_float(bt2
)) {
4482 /* compute bigger type and do implicit casts */
4483 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
4485 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
4490 /* floats can only be used for a few operations */
4491 if (op
!= '+' && op
!= '-' && op
!= '*' && op
!= '/' &&
4492 (op
< TOK_ULT
|| op
> TOK_GT
))
4493 error("invalid operands for binary operation");
4495 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
4496 /* cast to biggest op */
4498 /* convert to unsigned if it does not fit in a long long */
4499 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
4500 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
4504 /* integer operations */
4506 /* convert to unsigned if it does not fit in an integer */
4507 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
4508 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
4511 /* XXX: currently, some unsigned operations are explicit, so
4512 we modify them here */
4513 if (t
& VT_UNSIGNED
) {
4520 else if (op
== TOK_LT
)
4522 else if (op
== TOK_GT
)
4524 else if (op
== TOK_LE
)
4526 else if (op
== TOK_GE
)
4533 /* special case for shifts and long long: we keep the shift as
4535 if (op
== TOK_SHR
|| op
== TOK_SAR
|| op
== TOK_SHL
)
4540 else if ((t
& VT_BTYPE
) == VT_LLONG
)
4544 if (op
>= TOK_ULT
&& op
<= TOK_GT
) {
4545 /* relationnal op: the result is an int */
4546 vtop
->type
.t
= VT_INT
;
4553 /* generic itof for unsigned long long case */
4554 void gen_cvt_itof1(int t
)
4558 if ((vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
)) ==
4559 (VT_LLONG
| VT_UNSIGNED
)) {
4561 gfunc_start(&gf
, FUNC_CDECL
);
4564 vpush_global_sym(&func_old_type
, TOK___ulltof
);
4565 else if (t
== VT_DOUBLE
)
4566 vpush_global_sym(&func_old_type
, TOK___ulltod
);
4568 vpush_global_sym(&func_old_type
, TOK___ulltold
);
4577 /* generic ftoi for unsigned long long case */
4578 void gen_cvt_ftoi1(int t
)
4583 if (t
== (VT_LLONG
| VT_UNSIGNED
)) {
4584 /* not handled natively */
4585 gfunc_start(&gf
, FUNC_CDECL
);
4586 st
= vtop
->type
.t
& VT_BTYPE
;
4589 vpush_global_sym(&func_old_type
, TOK___fixunssfdi
);
4590 else if (st
== VT_DOUBLE
)
4591 vpush_global_sym(&func_old_type
, TOK___fixunsdfdi
);
4593 vpush_global_sym(&func_old_type
, TOK___fixunsxfdi
);
4597 vtop
->r2
= REG_LRET
;
4603 /* force char or short cast */
4604 void force_charshort_cast(int t
)
4608 /* XXX: add optimization if lvalue : just change type and offset */
4613 if (t
& VT_UNSIGNED
) {
4614 vpushi((1 << bits
) - 1);
4625 /* cast 'vtop' to 'type' */
4626 static void gen_cast(CType
*type
)
4628 int sbt
, dbt
, sf
, df
, c
;
4630 /* special delayed cast for char/short */
4631 /* XXX: in some cases (multiple cascaded casts), it may still
4633 if (vtop
->r
& VT_MUSTCAST
) {
4634 vtop
->r
&= ~VT_MUSTCAST
;
4635 force_charshort_cast(vtop
->type
.t
);
4638 dbt
= type
->t
& (VT_BTYPE
| VT_UNSIGNED
);
4639 sbt
= vtop
->type
.t
& (VT_BTYPE
| VT_UNSIGNED
);
4641 if (sbt
!= dbt
&& !nocode_wanted
) {
4644 c
= (vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
;
4646 /* convert from fp to fp */
4648 /* constant case: we can do it now */
4649 /* XXX: in ISOC, cannot do it if error in convert */
4650 if (dbt
== VT_FLOAT
&& sbt
== VT_DOUBLE
)
4651 vtop
->c
.f
= (float)vtop
->c
.d
;
4652 else if (dbt
== VT_FLOAT
&& sbt
== VT_LDOUBLE
)
4653 vtop
->c
.f
= (float)vtop
->c
.ld
;
4654 else if (dbt
== VT_DOUBLE
&& sbt
== VT_FLOAT
)
4655 vtop
->c
.d
= (double)vtop
->c
.f
;
4656 else if (dbt
== VT_DOUBLE
&& sbt
== VT_LDOUBLE
)
4657 vtop
->c
.d
= (double)vtop
->c
.ld
;
4658 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_FLOAT
)
4659 vtop
->c
.ld
= (long double)vtop
->c
.f
;
4660 else if (dbt
== VT_LDOUBLE
&& sbt
== VT_DOUBLE
)
4661 vtop
->c
.ld
= (long double)vtop
->c
.d
;
4663 /* non constant case: generate code */
4667 /* convert int to fp */
4670 case VT_LLONG
| VT_UNSIGNED
:
4672 /* XXX: add const cases for long long */
4674 case VT_INT
| VT_UNSIGNED
:
4676 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.ui
; break;
4677 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.ui
; break;
4678 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.ui
; break;
4683 case VT_FLOAT
: vtop
->c
.f
= (float)vtop
->c
.i
; break;
4684 case VT_DOUBLE
: vtop
->c
.d
= (double)vtop
->c
.i
; break;
4685 case VT_LDOUBLE
: vtop
->c
.ld
= (long double)vtop
->c
.i
; break;
4694 /* convert fp to int */
4695 /* we handle char/short/etc... with generic code */
4696 if (dbt
!= (VT_INT
| VT_UNSIGNED
) &&
4697 dbt
!= (VT_LLONG
| VT_UNSIGNED
) &&
4702 case VT_LLONG
| VT_UNSIGNED
:
4704 /* XXX: add const cases for long long */
4706 case VT_INT
| VT_UNSIGNED
:
4708 case VT_FLOAT
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4709 case VT_DOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4710 case VT_LDOUBLE
: vtop
->c
.ui
= (unsigned int)vtop
->c
.d
; break;
4716 case VT_FLOAT
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4717 case VT_DOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4718 case VT_LDOUBLE
: vtop
->c
.i
= (int)vtop
->c
.d
; break;
4726 if (dbt
== VT_INT
&& (type
->t
& (VT_BTYPE
| VT_UNSIGNED
)) != dbt
) {
4727 /* additionnal cast for char/short/bool... */
4731 } else if ((dbt
& VT_BTYPE
) == VT_LLONG
) {
4732 if ((sbt
& VT_BTYPE
) != VT_LLONG
) {
4733 /* scalar to long long */
4735 if (sbt
== (VT_INT
| VT_UNSIGNED
))
4736 vtop
->c
.ll
= vtop
->c
.ui
;
4738 vtop
->c
.ll
= vtop
->c
.i
;
4740 /* machine independant conversion */
4742 /* generate high word */
4743 if (sbt
== (VT_INT
| VT_UNSIGNED
)) {
4751 /* patch second register */
4752 vtop
[-1].r2
= vtop
->r
;
4756 } else if (dbt
== VT_BOOL
) {
4757 /* scalar to bool */
4760 } else if ((dbt
& VT_BTYPE
) == VT_BYTE
||
4761 (dbt
& VT_BTYPE
) == VT_SHORT
) {
4762 force_charshort_cast(dbt
);
4763 } else if ((dbt
& VT_BTYPE
) == VT_INT
) {
4765 if (sbt
== VT_LLONG
) {
4766 /* from long long: just take low order word */
4770 /* if lvalue and single word type, nothing to do because
4771 the lvalue already contains the real type size (see
4772 VT_LVAL_xxx constants) */
4778 /* return type size. Put alignment at 'a' */
4779 int type_size(CType
*type
, int *a
)
4784 bt
= type
->t
& VT_BTYPE
;
4785 if (bt
== VT_STRUCT
) {
4788 *a
= 4; /* XXX: cannot store it yet. Doing that is safe */
4790 } else if (bt
== VT_PTR
) {
4791 if (type
->t
& VT_ARRAY
) {
4793 return type_size(&s
->type
, a
) * s
->c
;
4798 } else if (bt
== VT_LDOUBLE
) {
4800 return LDOUBLE_SIZE
;
4801 } else if (bt
== VT_DOUBLE
|| bt
== VT_LLONG
) {
4804 } else if (bt
== VT_INT
|| bt
== VT_ENUM
|| bt
== VT_FLOAT
) {
4807 } else if (bt
== VT_SHORT
) {
4811 /* char, void, function, _Bool */
4817 /* return the pointed type of t */
4818 static inline CType
*pointed_type(CType
*type
)
4820 return &type
->ref
->type
;
4823 /* modify type so that its it is a pointer to type. */
4824 static void mk_pointer(CType
*type
)
4827 s
= sym_push(SYM_FIELD
, type
, 0, -1);
4828 type
->t
= VT_PTR
| (type
->t
& ~VT_TYPE
);
4832 static int is_compatible_types(CType
*type1
, CType
*type2
)
4835 int bt1
, bt2
, t1
, t2
;
4837 t1
= type1
->t
& VT_TYPE
;
4838 t2
= type2
->t
& VT_TYPE
;
4839 bt1
= t1
& VT_BTYPE
;
4840 bt2
= t2
& VT_BTYPE
;
4841 if (bt1
== VT_PTR
) {
4842 type1
= pointed_type(type1
);
4843 /* if function, then convert implicitely to function pointer */
4844 if (bt2
!= VT_FUNC
) {
4847 type2
= pointed_type(type2
);
4849 /* void matches everything */
4850 /* XXX: not fully compliant */
4851 if ((type1
->t
& VT_TYPE
) == VT_VOID
|| (type2
->t
& VT_TYPE
) == VT_VOID
)
4853 return is_compatible_types(type1
, type2
);
4854 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
4856 } else if (bt1
== VT_FUNC
) {
4861 if (!is_compatible_types(&s1
->type
, &s2
->type
))
4863 /* XXX: not complete */
4864 if (s1
->c
== FUNC_OLD
|| s2
->c
== FUNC_OLD
)
4868 while (s1
!= NULL
) {
4871 if (!is_compatible_types(&s1
->type
, &s2
->type
))
4880 /* XXX: not complete */
4885 /* print a type. If 'varstr' is not NULL, then the variable is also
4886 printed in the type */
4888 /* XXX: add array and function pointers */
4889 void type_to_str(char *buf
, int buf_size
,
4890 CType
*type
, const char *varstr
)
4897 t
= type
->t
& VT_TYPE
;
4900 if (t
& VT_UNSIGNED
)
4901 pstrcat(buf
, buf_size
, "unsigned ");
4931 tstr
= "long double";
4933 pstrcat(buf
, buf_size
, tstr
);
4937 if (bt
== VT_STRUCT
)
4941 pstrcat(buf
, buf_size
, tstr
);
4943 if (v
>= SYM_FIRST_ANOM
)
4944 pstrcat(buf
, buf_size
, "<anonymous>");
4946 pstrcat(buf
, buf_size
, get_tok_str(v
, NULL
));
4950 type_to_str(buf
, buf_size
, &s
->type
, varstr
);
4951 pstrcat(buf
, buf_size
, "(");
4953 while (sa
!= NULL
) {
4954 type_to_str(buf1
, sizeof(buf1
), &sa
->type
, NULL
);
4955 pstrcat(buf
, buf_size
, buf1
);
4958 pstrcat(buf
, buf_size
, ", ");
4960 pstrcat(buf
, buf_size
, ")");
4964 pstrcpy(buf1
, sizeof(buf1
), "*");
4966 pstrcat(buf1
, sizeof(buf1
), varstr
);
4967 type_to_str(buf
, buf_size
, &s
->type
, buf1
);
4971 pstrcat(buf
, buf_size
, " ");
4972 pstrcat(buf
, buf_size
, varstr
);
4977 /* verify type compatibility to store vtop in 'dt' type, and generate
4979 void gen_assign_cast(CType
*dt
)
4982 char buf1
[256], buf2
[256];
4984 st
= &vtop
->type
; /* source type */
4985 if ((dt
->t
& VT_BTYPE
) == VT_PTR
) {
4986 /* special cases for pointers */
4987 /* a function is implicitely a function pointer */
4988 if ((st
->t
& VT_BTYPE
) == VT_FUNC
) {
4989 if (!is_compatible_types(pointed_type(dt
), st
))
4994 /* '0' can also be a pointer */
4995 if ((st
->t
& VT_BTYPE
) == VT_INT
&&
4996 ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
) &&
5000 if (!is_compatible_types(dt
, st
)) {
5002 type_to_str(buf1
, sizeof(buf1
), st
, NULL
);
5003 type_to_str(buf2
, sizeof(buf2
), dt
, NULL
);
5004 error("cannot cast '%s' to '%s'", buf1
, buf2
);
5010 /* store vtop in lvalue pushed on stack */
5013 int sbt
, dbt
, ft
, r
, t
, size
, align
, bit_size
, bit_pos
, rc
, delayed_cast
;
5016 ft
= vtop
[-1].type
.t
;
5017 sbt
= vtop
->type
.t
& VT_BTYPE
;
5018 dbt
= ft
& VT_BTYPE
;
5019 if (((sbt
== VT_INT
|| sbt
== VT_SHORT
) && dbt
== VT_BYTE
) ||
5020 (sbt
== VT_INT
&& dbt
== VT_SHORT
)) {
5021 /* optimize char/short casts */
5022 delayed_cast
= VT_MUSTCAST
;
5023 vtop
->type
.t
= ft
& VT_TYPE
;
5026 gen_assign_cast(&vtop
[-1].type
);
5029 if (sbt
== VT_STRUCT
) {
5030 /* if structure, only generate pointer */
5031 /* structure assignment : generate memcpy */
5032 /* XXX: optimize if small size */
5033 if (!nocode_wanted
) {
5035 gfunc_start(&gf
, FUNC_CDECL
);
5037 size
= type_size(&vtop
->type
, &align
);
5041 vtop
->type
.t
= VT_INT
;
5046 vtop
->type
.t
= VT_INT
;
5051 vpush_global_sym(&func_old_type
, TOK_memcpy
);
5057 /* leave source on stack */
5058 } else if (ft
& VT_BITFIELD
) {
5059 /* bitfield store handling */
5060 bit_pos
= (ft
>> VT_STRUCT_SHIFT
) & 0x3f;
5061 bit_size
= (ft
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f;
5062 /* remove bit field info to avoid loops */
5063 vtop
[-1].type
.t
= ft
& ~(VT_BITFIELD
| (-1 << VT_STRUCT_SHIFT
));
5065 /* duplicate destination */
5067 vtop
[-1] = vtop
[-2];
5069 /* mask and shift source */
5070 vpushi((1 << bit_size
) - 1);
5074 /* load destination, mask and or with source */
5076 vpushi(~(((1 << bit_size
) - 1) << bit_pos
));
5082 #ifdef CONFIG_TCC_BCHECK
5083 /* bound check case */
5084 if (vtop
[-1].r
& VT_MUSTBOUND
) {
5090 if (!nocode_wanted
) {
5094 r
= gv(rc
); /* generate value */
5095 /* if lvalue was saved on stack, must read it */
5096 if ((vtop
[-1].r
& VT_VALMASK
) == VT_LLOCAL
) {
5098 t
= get_reg(RC_INT
);
5100 sv
.r
= VT_LOCAL
| VT_LVAL
;
5101 sv
.c
.ul
= vtop
[-1].c
.ul
;
5103 vtop
[-1].r
= t
| VT_LVAL
;
5106 /* two word case handling : store second register at word + 4 */
5107 if ((ft
& VT_BTYPE
) == VT_LLONG
) {
5109 /* convert to int to increment easily */
5110 vtop
->type
.t
= VT_INT
;
5116 /* XXX: it works because r2 is spilled last ! */
5117 store(vtop
->r2
, vtop
- 1);
5121 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
5122 vtop
->r
|= delayed_cast
;
5126 /* post defines POST/PRE add. c is the token ++ or -- */
5127 void inc(int post
, int c
)
5130 vdup(); /* save lvalue */
5132 gv_dup(); /* duplicate value */
5137 vpushi(c
- TOK_MID
);
5139 vstore(); /* store value */
5141 vpop(); /* if post op, return saved value */
5144 /* Parse GNUC __attribute__ extension. Currently, the following
5145 extensions are recognized:
5146 - aligned(n) : set data/function alignment.
5147 - section(x) : generate data/code in this section.
5148 - unused : currently ignored, but may be used someday.
5150 void parse_attribute(AttributeDef
*ad
)
5157 while (tok
!= ')') {
5158 if (tok
< TOK_IDENT
)
5159 expect("attribute name");
5164 case TOK___SECTION__
:
5167 expect("section name");
5168 ad
->section
= find_section(tcc_state
, (char *)tokc
.cstr
->data
);
5173 case TOK___ALIGNED__
:
5176 if (n
<= 0 || (n
& (n
- 1)) != 0)
5177 error("alignment must be a positive power of two");
5182 case TOK___UNUSED__
:
5183 /* currently, no need to handle it because tcc does not
5184 track unused objects */
5187 case TOK___NORETURN__
:
5188 /* currently, no need to handle it because tcc does not
5189 track unused objects */
5194 ad
->func_call
= FUNC_CDECL
;
5198 case TOK___STDCALL__
:
5199 ad
->func_call
= FUNC_STDCALL
;
5202 warning("'%s' attribute ignored", get_tok_str(t
, NULL
));
5203 /* skip parameters */
5204 /* XXX: skip parenthesis too */
5207 while (tok
!= ')' && tok
!= -1)
5221 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
5222 static void struct_decl(CType
*type
, int u
)
5224 int a
, v
, size
, align
, maxalign
, c
, offset
;
5225 int bit_size
, bit_pos
, bsize
, bt
, lbit_pos
;
5230 a
= tok
; /* save decl type */
5235 /* struct already defined ? return it */
5236 /* XXX: check consistency */
5240 error("invalid type");
5247 s
= sym_push(v
| SYM_STRUCT
, &type1
, 0, 0);
5248 /* put struct/union/enum name in type */
5256 error("struct/union/enum already defined");
5257 /* cannot be empty */
5264 if (a
== TOK_ENUM
) {
5271 /* enum symbols have static storage */
5272 ss
= sym_push(v
, &int_type
, VT_CONST
, c
);
5273 ss
->type
.t
|= VT_STATIC
;
5278 parse_btype(&btype
, &ad
);
5284 type_decl(&type1
, &ad
, &v
, TYPE_DIRECT
);
5285 if ((type1
.t
& VT_BTYPE
) == VT_FUNC
||
5286 (type1
.t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
)))
5287 error("invalid type for '%s'",
5288 get_tok_str(v
, NULL
));
5292 bit_size
= expr_const();
5293 /* XXX: handle v = 0 case for messages */
5295 error("negative width in bit-field '%s'",
5296 get_tok_str(v
, NULL
));
5297 if (v
&& bit_size
== 0)
5298 error("zero width for bit-field '%s'",
5299 get_tok_str(v
, NULL
));
5301 size
= type_size(&type1
, &align
);
5303 if (bit_size
>= 0) {
5304 bt
= type1
.t
& VT_BTYPE
;
5308 error("bitfields must have scalar type");
5310 if (bit_size
> bsize
) {
5311 error("width of '%s' exceeds its type",
5312 get_tok_str(v
, NULL
));
5313 } else if (bit_size
== bsize
) {
5314 /* no need for bit fields */
5316 } else if (bit_size
== 0) {
5317 /* XXX: what to do if only padding in a
5319 /* zero size: means to pad */
5323 /* we do not have enough room ? */
5324 if ((bit_pos
+ bit_size
) > bsize
)
5327 /* XXX: handle LSB first */
5328 type1
.t
|= VT_BITFIELD
|
5329 (bit_pos
<< VT_STRUCT_SHIFT
) |
5330 (bit_size
<< (VT_STRUCT_SHIFT
+ 6));
5331 bit_pos
+= bit_size
;
5337 /* add new memory data only if starting
5339 if (lbit_pos
== 0) {
5340 if (a
== TOK_STRUCT
) {
5341 c
= (c
+ align
- 1) & -align
;
5349 if (align
> maxalign
)
5353 printf("add field %s offset=%d",
5354 get_tok_str(v
, NULL
), offset
);
5355 if (type1
.t
& VT_BITFIELD
) {
5356 printf(" pos=%d size=%d",
5357 (type1
.t
>> VT_STRUCT_SHIFT
) & 0x3f,
5358 (type1
.t
>> (VT_STRUCT_SHIFT
+ 6)) & 0x3f);
5362 ss
= sym_push(v
| SYM_FIELD
, &type1
, 0, offset
);
5366 if (tok
== ';' || tok
== -1)
5376 /* size for struct/union, dummy for enum */
5377 s
->c
= (c
+ maxalign
- 1) & -maxalign
;
5381 /* return 0 if no type declaration. otherwise, return the basic type
5384 static int parse_btype(CType
*type
, AttributeDef
*ad
)
5386 int t
, u
, type_found
;
5390 memset(ad
, 0, sizeof(AttributeDef
));
5401 if ((t
& VT_BTYPE
) != 0)
5402 error("too many basic types");
5416 if ((t
& VT_BTYPE
) == VT_DOUBLE
) {
5417 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5418 } else if ((t
& VT_BTYPE
) == VT_LONG
) {
5419 t
= (t
& ~VT_BTYPE
) | VT_LLONG
;
5433 if ((t
& VT_BTYPE
) == VT_LONG
) {
5434 t
= (t
& ~VT_BTYPE
) | VT_LDOUBLE
;
5441 struct_decl(&type1
, VT_ENUM
);
5444 type
->ref
= type1
.ref
;
5448 struct_decl(&type1
, VT_STRUCT
);
5451 /* type modifiers */
5456 case TOK___SIGNED__
:
5459 case TOK___INLINE__
:
5481 /* GNUC attribute */
5482 case TOK___ATTRIBUTE__
:
5483 parse_attribute(ad
);
5488 parse_expr_type(&type1
);
5492 if (!s
|| !(s
->type
.t
& VT_TYPEDEF
))
5494 t
|= (s
->type
.t
& ~VT_TYPEDEF
);
5495 type
->ref
= s
->type
.ref
;
5502 /* long is never used as type */
5503 if ((t
& VT_BTYPE
) == VT_LONG
)
5504 t
= (t
& ~VT_BTYPE
) | VT_INT
;
5509 static void post_type(CType
*type
, AttributeDef
*ad
)
5512 Sym
**plast
, *s
, *first
;
5517 /* function declaration */
5522 while (tok
!= ')') {
5523 /* read param name and compute offset */
5524 if (l
!= FUNC_OLD
) {
5525 if (!parse_btype(&pt
, &ad1
)) {
5527 error("invalid type");
5534 if ((pt
.t
& VT_BTYPE
) == VT_VOID
&& tok
== ')')
5536 type_decl(&pt
, &ad1
, &n
, TYPE_DIRECT
| TYPE_ABSTRACT
);
5537 if ((pt
.t
& VT_BTYPE
) == VT_VOID
)
5538 error("parameter declared as void");
5545 /* array must be transformed to pointer according to ANSI C */
5547 s
= sym_push(n
| SYM_FIELD
, &pt
, 0, 0);
5552 if (l
== FUNC_NEW
&& tok
== TOK_DOTS
) {
5559 /* if no parameters, then old type prototype */
5563 t1
= type
->t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5564 type
->t
&= ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5565 post_type(type
, ad
);
5566 /* we push a anonymous symbol which will contain the function prototype */
5567 s
= sym_push(SYM_FIELD
, type
, ad
->func_call
, l
);
5569 type
->t
= t1
| VT_FUNC
;
5571 } else if (tok
== '[') {
5572 /* array definition */
5578 error("invalid array size");
5581 /* parse next post type */
5582 t1
= type
->t
& (VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5583 type
->t
&= ~(VT_TYPEDEF
| VT_STATIC
| VT_EXTERN
);
5584 post_type(type
, ad
);
5586 /* we push a anonymous symbol which will contain the array
5588 s
= sym_push(SYM_FIELD
, type
, 0, n
);
5589 type
->t
= t1
| VT_ARRAY
| VT_PTR
;
5594 /* Parse a type declaration (except basic type), and return the type
5595 in 'type'. 'td' is a bitmask indicating which kind of type decl is
5596 expected. 'type' should contain the basic type. 'ad' is the
5597 attribute definition of the basic type. It can be modified by
5600 static void type_decl(CType
*type
, AttributeDef
*ad
, int *v
, int td
)
5603 CType type1
, *type2
;
5605 while (tok
== '*') {
5607 while (tok
== TOK_CONST
|| tok
== TOK_VOLATILE
|| tok
== TOK_RESTRICT
)
5612 /* recursive type */
5613 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
5614 type1
.t
= 0; /* XXX: same as int */
5617 /* XXX: this is not correct to modify 'ad' at this point, but
5618 the syntax is not clear */
5619 if (tok
== TOK___ATTRIBUTE__
)
5620 parse_attribute(ad
);
5621 type_decl(&type1
, ad
, v
, td
);
5624 /* type identifier */
5625 if (tok
>= TOK_IDENT
&& (td
& TYPE_DIRECT
)) {
5629 if (!(td
& TYPE_ABSTRACT
))
5630 expect("identifier");
5634 post_type(type
, ad
);
5635 if (tok
== TOK___ATTRIBUTE__
)
5636 parse_attribute(ad
);
5639 /* append type at the end of type1 */
5652 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
5653 static int lvalue_type(int t
)
5660 else if (bt
== VT_SHORT
)
5664 if (t
& VT_UNSIGNED
)
5665 r
|= VT_LVAL_UNSIGNED
;
5669 /* indirection with full error checking and bound check */
5670 static void indir(void)
5672 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
5674 if ((vtop
->r
& VT_LVAL
) && !nocode_wanted
)
5676 vtop
->type
= *pointed_type(&vtop
->type
);
5677 /* an array is never an lvalue */
5678 if (!(vtop
->type
.t
& VT_ARRAY
)) {
5679 vtop
->r
|= lvalue_type(vtop
->type
.t
);
5680 /* if bound checking, the referenced pointer must be checked */
5681 if (do_bounds_check
)
5682 vtop
->r
|= VT_MUSTBOUND
;
5686 /* pass a parameter to a function and do type checking and casting */
5687 void gfunc_param_typed(GFuncContext
*gf
, Sym
*func
, Sym
*arg
)
5692 func_type
= func
->c
;
5693 if (func_type
== FUNC_OLD
||
5694 (func_type
== FUNC_ELLIPSIS
&& arg
== NULL
)) {
5695 /* default casting : only need to convert float to double */
5696 if ((vtop
->type
.t
& VT_BTYPE
) == VT_FLOAT
) {
5700 } else if (arg
== NULL
) {
5701 error("too many arguments to function");
5703 gen_assign_cast(&arg
->type
);
5705 if (!nocode_wanted
) {
5712 /* parse an expression of the form '(type)' or '(expr)' and return its
5714 static void parse_expr_type(CType
*type
)
5720 if (parse_btype(type
, &ad
)) {
5721 type_decl(type
, &ad
, &n
, TYPE_ABSTRACT
);
5728 static void vpush_tokc(int t
)
5732 vsetc(&type
, VT_CONST
, &tokc
);
5735 static void unary(void)
5737 int n
, t
, align
, size
, r
;
5743 if (tok
== TOK_CINT
|| tok
== TOK_CCHAR
|| tok
== TOK_LCHAR
) {
5746 } else if (tok
== TOK_CUINT
) {
5747 vpush_tokc(VT_INT
| VT_UNSIGNED
);
5749 } else if (tok
== TOK_CLLONG
) {
5750 vpush_tokc(VT_LLONG
);
5752 } else if (tok
== TOK_CULLONG
) {
5753 vpush_tokc(VT_LLONG
| VT_UNSIGNED
);
5755 } else if (tok
== TOK_CFLOAT
) {
5756 vpush_tokc(VT_FLOAT
);
5758 } else if (tok
== TOK_CDOUBLE
) {
5759 vpush_tokc(VT_DOUBLE
);
5761 } else if (tok
== TOK_CLDOUBLE
) {
5762 vpush_tokc(VT_LDOUBLE
);
5764 } else if (tok
== TOK___FUNC__
|| (tok
== TOK___FUNCTION__
&& gnu_ext
)) {
5767 /* special function name identifier */
5769 len
= strlen(funcname
) + 1;
5770 /* generate char[len] type */
5775 vpush_ref(&type
, data_section
, data_section
->data_offset
, len
);
5776 ptr
= section_ptr_add(data_section
, len
);
5777 memcpy(ptr
, funcname
, len
);
5779 } else if (tok
== TOK_LSTR
) {
5782 } else if (tok
== TOK_STR
) {
5783 /* string parsing */
5789 memset(&ad
, 0, sizeof(AttributeDef
));
5790 decl_initializer_alloc(&type
, &ad
, VT_CONST
, 2, 0, 0);
5796 if (parse_btype(&type
, &ad
)) {
5797 type_decl(&type
, &ad
, &n
, TYPE_ABSTRACT
);
5799 /* check ISOC99 compound literal */
5801 /* data is allocated locally by default */
5806 /* all except arrays are lvalues */
5807 if (!(type
.t
& VT_ARRAY
))
5808 r
|= lvalue_type(type
.t
);
5809 memset(&ad
, 0, sizeof(AttributeDef
));
5810 decl_initializer_alloc(&type
, &ad
, r
, 1, 0, 0);
5819 } else if (t
== '*') {
5822 } else if (t
== '&') {
5824 /* functions names must be treated as function pointers,
5825 except for unary '&' and sizeof. Since we consider that
5826 functions are not lvalues, we only have to handle it
5827 there and in function calls. */
5828 /* arrays can also be used although they are not lvalues */
5829 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
&&
5830 !(vtop
->type
.t
& VT_ARRAY
))
5832 mk_pointer(&vtop
->type
);
5834 } else if (t
== '!') {
5836 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) == VT_CONST
)
5837 vtop
->c
.i
= !vtop
->c
.i
;
5838 else if ((vtop
->r
& VT_VALMASK
) == VT_CMP
)
5839 vtop
->c
.i
= vtop
->c
.i
^ 1;
5841 vseti(VT_JMP
, gtst(1, 0));
5842 } else if (t
== '~') {
5846 } else if (t
== '+') {
5847 /* in order to force cast, we add zero */
5849 if ((vtop
->type
.t
& VT_BTYPE
) == VT_PTR
)
5850 error("pointer not accepted for unary plus");
5853 } else if (t
== TOK_SIZEOF
|| t
== TOK_ALIGNOF
) {
5855 parse_expr_type(&type
);
5859 size
= type_size(&type
, &align
);
5860 if (t
== TOK_SIZEOF
)
5864 } else if (t
== TOK_INC
|| t
== TOK_DEC
) {
5867 } else if (t
== '-') {
5871 } else if (t
== TOK_LAND
&& gnu_ext
) {
5872 /* allow to take the address of a label */
5873 if (tok
< TOK_UIDENT
)
5874 expect("label identifier");
5875 s
= label_find(tok
);
5877 s
= label_push(tok
, LABEL_FORWARD
);
5880 s
->type
.t
= VT_VOID
;
5881 mk_pointer(&s
->type
);
5882 s
->type
.t
|= VT_STATIC
;
5884 vset(&s
->type
, VT_CONST
| VT_SYM
, 0);
5889 expect("identifier");
5893 error("'%s' undeclared", get_tok_str(t
, NULL
));
5894 /* for simple function calls, we tolerate undeclared
5895 external reference to int() function */
5896 s
= external_global_sym(t
, &func_old_type
, 0);
5898 vset(&s
->type
, s
->r
, s
->c
);
5899 /* if forward reference, we must point to s */
5900 if (vtop
->r
& VT_SYM
) {
5907 /* post operations */
5909 if (tok
== TOK_INC
|| tok
== TOK_DEC
) {
5912 } else if (tok
== '.' || tok
== TOK_ARROW
) {
5914 if (tok
== TOK_ARROW
)
5919 /* expect pointer on structure */
5920 if ((vtop
->type
.t
& VT_BTYPE
) != VT_STRUCT
)
5921 expect("struct or union");
5925 while ((s
= s
->next
) != NULL
) {
5930 error("field not found");
5931 /* add field offset to pointer */
5932 vtop
->type
= char_pointer_type
; /* change type to 'char *' */
5935 /* change type to field type, and set to lvalue */
5936 vtop
->type
= s
->type
;
5937 /* an array is never an lvalue */
5938 if (!(vtop
->type
.t
& VT_ARRAY
)) {
5939 vtop
->r
|= lvalue_type(vtop
->type
.t
);
5940 /* if bound checking, the referenced pointer must be checked */
5941 if (do_bounds_check
)
5942 vtop
->r
|= VT_MUSTBOUND
;
5945 } else if (tok
== '[') {
5951 } else if (tok
== '(') {
5956 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
) {
5957 /* pointer test (no array accepted) */
5958 if ((vtop
->type
.t
& (VT_BTYPE
| VT_ARRAY
)) == VT_PTR
) {
5959 vtop
->type
= *pointed_type(&vtop
->type
);
5960 if ((vtop
->type
.t
& VT_BTYPE
) != VT_FUNC
)
5964 expect("function pointer");
5967 vtop
->r
&= ~VT_LVAL
; /* no lvalue */
5969 /* get return type */
5971 if (!nocode_wanted
) {
5972 save_regs(0); /* save used temporary registers */
5973 gfunc_start(&gf
, s
->r
);
5976 sa
= s
->next
; /* first parameter */
5977 #ifdef INVERT_FUNC_PARAMS
5981 ParseState saved_parse_state
;
5984 /* read each argument and store it on a stack */
5990 while ((parlevel
> 0 || (tok
!= ')' && tok
!= ',')) &&
5994 else if (tok
== ')')
5996 tok_str_add_tok(&str
);
5999 tok_str_add(&str
, -1); /* end of file added */
6000 tok_str_add(&str
, 0);
6001 s1
= sym_push2(&args
, 0, 0, (int)str
.str
);
6002 s1
->next
= sa
; /* add reference to argument */
6011 /* now generate code in reverse order by reading the stack */
6012 save_parse_state(&saved_parse_state
);
6014 macro_ptr
= (int *)args
->c
;
6018 expect("',' or ')'");
6019 gfunc_param_typed(&gf
, s
, args
->next
);
6021 tok_str_free((int *)args
->c
);
6025 restore_parse_state(&saved_parse_state
);
6028 /* compute first implicit argument if a structure is returned */
6029 if ((s
->type
.t
& VT_BTYPE
) == VT_STRUCT
) {
6030 /* get some space for the returned structure */
6031 size
= type_size(&s
->type
, &align
);
6032 loc
= (loc
- size
) & -align
;
6034 ret
.r
= VT_LOCAL
| VT_LVAL
;
6035 /* pass it as 'int' to avoid structure arg passing
6037 vseti(VT_LOCAL
, loc
);
6046 /* return in register */
6047 if (is_float(ret
.type
.t
)) {
6050 if ((ret
.type
.t
& VT_BTYPE
) == VT_LLONG
)
6056 #ifndef INVERT_FUNC_PARAMS
6060 gfunc_param_typed(&gf
, s
, sa
);
6070 error("too few arguments to function");
6077 vsetc(&ret
.type
, ret
.r
, &ret
.c
);
6085 static void uneq(void)
6091 (tok
>= TOK_A_MOD
&& tok
<= TOK_A_DIV
) ||
6092 tok
== TOK_A_XOR
|| tok
== TOK_A_OR
||
6093 tok
== TOK_A_SHL
|| tok
== TOK_A_SAR
) {
6108 static void sum(int l
)
6116 while ((l
== 0 && (tok
== '*' || tok
== '/' || tok
== '%')) ||
6117 (l
== 1 && (tok
== '+' || tok
== '-')) ||
6118 (l
== 2 && (tok
== TOK_SHL
|| tok
== TOK_SAR
)) ||
6119 (l
== 3 && ((tok
>= TOK_ULE
&& tok
<= TOK_GT
) ||
6120 tok
== TOK_ULT
|| tok
== TOK_UGE
)) ||
6121 (l
== 4 && (tok
== TOK_EQ
|| tok
== TOK_NE
)) ||
6122 (l
== 5 && tok
== '&') ||
6123 (l
== 6 && tok
== '^') ||
6124 (l
== 7 && tok
== '|') ||
6125 (l
== 8 && tok
== TOK_LAND
) ||
6126 (l
== 9 && tok
== TOK_LOR
)) {
6135 /* only used if non constant */
6136 static void eand(void)
6143 if (tok
!= TOK_LAND
) {
6156 static void eor(void)
6163 if (tok
!= TOK_LOR
) {
6176 /* XXX: better constant handling */
6177 static void expr_eq(void)
6179 int tt
, u
, r1
, r2
, rc
, t1
, t2
, bt1
, bt2
;
6181 CType type
, type1
, type2
;
6202 save_regs(1); /* we need to save all registers here except
6203 at the top because it is a branch point */
6207 sv
= *vtop
; /* save value to handle it later */
6208 vtop
--; /* no vpop so that FP stack is not flushed */
6217 bt1
= t1
& VT_BTYPE
;
6219 bt2
= t2
& VT_BTYPE
;
6220 /* cast operands to correct type according to ISOC rules */
6221 if (is_float(bt1
) || is_float(bt2
)) {
6222 if (bt1
== VT_LDOUBLE
|| bt2
== VT_LDOUBLE
) {
6223 type
.t
= VT_LDOUBLE
;
6224 } else if (bt1
== VT_DOUBLE
|| bt2
== VT_DOUBLE
) {
6229 } else if (bt1
== VT_LLONG
|| bt2
== VT_LLONG
) {
6230 /* cast to biggest op */
6232 /* convert to unsigned if it does not fit in a long long */
6233 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
) ||
6234 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_LLONG
| VT_UNSIGNED
))
6235 type
.t
|= VT_UNSIGNED
;
6236 } else if (bt1
== VT_PTR
|| bt2
== VT_PTR
) {
6237 /* XXX: test pointer compatibility */
6239 } else if (bt1
== VT_STRUCT
|| bt2
== VT_STRUCT
) {
6240 /* XXX: test structure compatibility */
6242 } else if (bt1
== VT_VOID
|| bt2
== VT_VOID
) {
6243 /* NOTE: as an extension, we accept void on only one side */
6246 /* integer operations */
6248 /* convert to unsigned if it does not fit in an integer */
6249 if ((t1
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
) ||
6250 (t2
& (VT_BTYPE
| VT_UNSIGNED
)) == (VT_INT
| VT_UNSIGNED
))
6251 type
.t
|= VT_UNSIGNED
;
6254 /* now we convert second operand */
6257 if (is_float(type
.t
)) {
6259 } else if ((type
.t
& VT_BTYPE
) == VT_LLONG
) {
6260 /* for long longs, we use fixed registers to avoid having
6261 to handle a complicated move */
6265 /* this is horrible, but we must also convert first
6269 /* put again first value and cast it */
6280 static void gexpr(void)
6291 /* parse an expression and return its type without any side effect. */
6292 static void expr_type(CType
*type
)
6304 /* parse a unary expression and return its type without any side
6306 static void unary_type(CType
*type
)
6318 /* parse a constant expression and return value in vtop. */
6319 static void expr_const1(void)
6328 /* parse an integer constant and return its value. */
6329 static int expr_const(void)
6333 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
| VT_SYM
)) != VT_CONST
)
6334 expect("constant expression");
6340 /* return the label token if current token is a label, otherwise
6342 static int is_label(void)
6347 /* fast test first */
6348 if (tok
< TOK_UIDENT
)
6350 /* no need to save tokc since we expect an identifier */
6358 /* XXX: may not work in all cases (macros ?) */
6367 static void block(int *bsym
, int *csym
, int *case_sym
, int *def_sym
, int case_reg
)
6372 /* generate line number info */
6374 (last_line_num
!= file
->line_num
|| last_ind
!= ind
)) {
6375 put_stabn(N_SLINE
, 0, file
->line_num
, ind
- func_ind
);
6377 last_line_num
= file
->line_num
;
6380 if (tok
== TOK_IF
) {
6387 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6389 if (c
== TOK_ELSE
) {
6393 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6394 gsym(d
); /* patch else jmp */
6397 } else if (tok
== TOK_WHILE
) {
6405 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6409 } else if (tok
== '{') {
6413 while (tok
!= '}') {
6416 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6418 /* pop locally defined symbols */
6419 sym_pop(&local_stack
, s
);
6421 } else if (tok
== TOK_RETURN
) {
6425 gen_assign_cast(&func_vt
);
6426 if ((func_vt
.t
& VT_BTYPE
) == VT_STRUCT
) {
6428 /* if returning structure, must copy it to implicit
6429 first pointer arg location */
6432 vset(&type
, VT_LOCAL
| VT_LVAL
, func_vc
);
6435 /* copy structure value to pointer */
6437 } else if (is_float(func_vt
.t
)) {
6442 vtop
--; /* NOT vpop() because on x86 it would flush the fp stack */
6445 rsym
= gjmp(rsym
); /* jmp */
6446 } else if (tok
== TOK_BREAK
) {
6449 error("cannot break");
6450 *bsym
= gjmp(*bsym
);
6453 } else if (tok
== TOK_CONTINUE
) {
6456 error("cannot continue");
6457 *csym
= gjmp(*csym
);
6460 } else if (tok
== TOK_FOR
) {
6487 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6492 if (tok
== TOK_DO
) {
6497 block(&a
, &b
, case_sym
, def_sym
, case_reg
);
6508 if (tok
== TOK_SWITCH
) {
6512 /* XXX: other types than integer */
6513 case_reg
= gv(RC_INT
);
6517 b
= gjmp(0); /* jump to first case */
6519 block(&a
, csym
, &b
, &c
, case_reg
);
6520 /* if no default, jmp after switch */
6528 if (tok
== TOK_CASE
) {
6535 if (gnu_ext
&& tok
== TOK_DOTS
) {
6539 warning("empty case range");
6541 /* since a case is like a label, we must skip it with a jmp */
6548 *case_sym
= gtst(1, 0);
6551 *case_sym
= gtst(1, 0);
6555 *case_sym
= gtst(1, *case_sym
);
6559 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6561 if (tok
== TOK_DEFAULT
) {
6567 error("too many 'default'");
6569 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6571 if (tok
== TOK_GOTO
) {
6573 if (tok
== '*' && gnu_ext
) {
6577 if ((vtop
->type
.t
& VT_BTYPE
) != VT_PTR
)
6580 } else if (tok
>= TOK_UIDENT
) {
6581 s
= label_find(tok
);
6582 /* put forward definition if needed */
6584 s
= label_push(tok
, LABEL_FORWARD
);
6586 /* label already defined */
6587 if (s
->r
& LABEL_FORWARD
)
6588 s
->next
= (void *)gjmp((long)s
->next
);
6590 gjmp_addr((long)s
->next
);
6593 expect("label identifier");
6602 if (!(s
->r
& LABEL_FORWARD
))
6603 error("multiple defined label");
6604 gsym((long)s
->next
);
6606 s
= label_push(b
, 0);
6608 s
->next
= (void *)ind
;
6610 /* we accept this, but it is a mistake */
6612 warning("deprecated use of label at end of compound statement");
6614 block(bsym
, csym
, case_sym
, def_sym
, case_reg
);
6616 /* expression case */
6626 /* t is the array or struct type. c is the array or struct
6627 address. cur_index/cur_field is the pointer to the current
6628 value. 'size_only' is true if only size info is needed (only used
6630 static void decl_designator(CType
*type
, Section
*sec
, unsigned long c
,
6631 int *cur_index
, Sym
**cur_field
,
6635 int notfirst
, index
, align
, l
;
6639 if (gnu_ext
&& (l
= is_label()) != 0)
6642 while (tok
== '[' || tok
== '.') {
6644 if (!(type
->t
& VT_ARRAY
))
6645 expect("array type");
6648 index
= expr_const();
6649 if (index
< 0 || (s
->c
>= 0 && index
>= s
->c
))
6650 expect("invalid index");
6654 type
= pointed_type(type
);
6655 c
+= index
* type_size(type
, &align
);
6661 if ((type
->t
& VT_BTYPE
) != VT_STRUCT
)
6662 expect("struct/union type");
6675 /* XXX: suppress this mess by using explicit storage field */
6677 type1
.t
|= (type
->t
& ~VT_TYPE
);
6691 if (type
->t
& VT_ARRAY
) {
6693 type
= pointed_type(type
);
6694 c
+= index
* type_size(type
, &align
);
6698 error("too many field init");
6699 /* XXX: suppress this mess by using explicit storage field */
6701 type1
.t
|= (type
->t
& ~VT_TYPE
);
6706 decl_initializer(type
, sec
, c
, 0, size_only
);
6710 #define EXPR_CONST 1
6713 /* store a value or an expression directly in global data or in local array */
6714 static void init_putv(CType
*type
, Section
*sec
, unsigned long c
,
6715 int v
, int expr_type
)
6717 int saved_global_expr
, bt
;
6725 /* compound literals must be allocated globally in this case */
6726 saved_global_expr
= global_expr
;
6729 global_expr
= saved_global_expr
;
6730 /* NOTE: symbols are accepted */
6731 if ((vtop
->r
& (VT_VALMASK
| VT_LVAL
)) != VT_CONST
)
6732 error("initializer element is not constant");
6740 /* XXX: not portable */
6741 /* XXX: generate error if incorrect relocation */
6742 gen_assign_cast(type
);
6743 bt
= type
->t
& VT_BTYPE
;
6744 ptr
= sec
->data
+ c
;
6745 if ((vtop
->r
& VT_SYM
) &&
6751 error("initializer element is not computable at load time");
6754 *(char *)ptr
= vtop
->c
.i
;
6757 *(short *)ptr
= vtop
->c
.i
;
6760 *(double *)ptr
= vtop
->c
.d
;
6763 *(long double *)ptr
= vtop
->c
.ld
;
6766 *(long long *)ptr
= vtop
->c
.ll
;
6769 if (vtop
->r
& VT_SYM
) {
6770 greloc(sec
, vtop
->sym
, c
, R_DATA_32
);
6772 *(int *)ptr
= vtop
->c
.i
;
6777 vset(type
, VT_LOCAL
, c
);
6784 /* put zeros for variable based init */
6785 static void init_putz(CType
*t
, Section
*sec
, unsigned long c
, int size
)
6790 /* nothing to do because globals are already set to zero */
6792 gfunc_start(&gf
, FUNC_CDECL
);
6799 vpush_global_sym(&func_old_type
, TOK_memset
);
6804 /* 't' contains the type and storage info. 'c' is the offset of the
6805 object in section 'sec'. If 'sec' is NULL, it means stack based
6806 allocation. 'first' is true if array '{' must be read (multi
6807 dimension implicit array init handling). 'size_only' is true if
6808 size only evaluation is wanted (only for arrays). */
6809 static void decl_initializer(CType
*type
, Section
*sec
, unsigned long c
,
6810 int first
, int size_only
)
6812 int index
, array_length
, n
, no_oblock
, nb
, parlevel
, i
;
6813 int size1
, align1
, expr_type
;
6817 if (type
->t
& VT_ARRAY
) {
6821 t1
= pointed_type(type
);
6822 size1
= type_size(t1
, &align1
);
6825 if ((first
&& tok
!= TOK_LSTR
&& tok
!= TOK_STR
) ||
6831 /* only parse strings here if correct type (otherwise: handle
6832 them as ((w)char *) expressions */
6833 if ((tok
== TOK_LSTR
&&
6834 (t1
->t
& VT_BTYPE
) == VT_INT
) ||
6836 (t1
->t
& VT_BTYPE
) == VT_BYTE
)) {
6837 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
6842 /* compute maximum number of chars wanted */
6844 cstr_len
= cstr
->size
;
6846 cstr_len
= cstr
->size
/ sizeof(int);
6849 if (n
>= 0 && nb
> (n
- array_length
))
6850 nb
= n
- array_length
;
6853 warning("initializer-string for array is too long");
6854 /* in order to go faster for common case (char
6855 string in global variable, we handle it
6857 if (sec
&& tok
== TOK_STR
&& size1
== 1) {
6858 memcpy(sec
->data
+ c
+ array_length
, cstr
->data
, nb
);
6862 ch
= ((unsigned char *)cstr
->data
)[i
];
6864 ch
= ((int *)cstr
->data
)[i
];
6865 init_putv(t1
, sec
, c
+ (array_length
+ i
) * size1
,
6873 /* only add trailing zero if enough storage (no
6874 warning in this case since it is standard) */
6875 if (n
< 0 || array_length
< n
) {
6877 init_putv(t1
, sec
, c
+ (array_length
* size1
), 0, EXPR_VAL
);
6883 while (tok
!= '}') {
6884 decl_designator(type
, sec
, c
, &index
, NULL
, size_only
);
6885 if (n
>= 0 && index
>= n
)
6886 error("index too large");
6887 /* must put zero in holes (note that doing it that way
6888 ensures that it even works with designators) */
6889 if (!size_only
&& array_length
< index
) {
6890 init_putz(t1
, sec
, c
+ array_length
* size1
,
6891 (index
- array_length
) * size1
);
6894 if (index
> array_length
)
6895 array_length
= index
;
6896 /* special test for multi dimensional arrays (may not
6897 be strictly correct if designators are used at the
6899 if (index
>= n
&& no_oblock
)
6908 /* put zeros at the end */
6909 if (!size_only
&& n
>= 0 && array_length
< n
) {
6910 init_putz(t1
, sec
, c
+ array_length
* size1
,
6911 (n
- array_length
) * size1
);
6913 /* patch type size if needed */
6915 s
->c
= array_length
;
6916 } else if ((type
->t
& VT_BTYPE
) == VT_STRUCT
&& tok
== '{') {
6917 /* XXX: union needs only one init */
6924 while (tok
!= '}') {
6925 decl_designator(type
, sec
, c
, NULL
, &f
, size_only
);
6926 /* fill with zero between fields */
6928 if (!size_only
&& array_length
< index
) {
6929 init_putz(type
, sec
, c
+ array_length
,
6930 index
- array_length
);
6932 index
= index
+ type_size(&f
->type
, &align1
);
6933 if (index
> array_length
)
6934 array_length
= index
;
6940 /* put zeros at the end */
6941 if (!size_only
&& array_length
< n
) {
6942 init_putz(type
, sec
, c
+ array_length
,
6946 } else if (tok
== '{') {
6948 decl_initializer(type
, sec
, c
, first
, size_only
);
6950 } else if (size_only
) {
6951 /* just skip expression */
6953 while ((parlevel
> 0 || (tok
!= '}' && tok
!= ',')) &&
6957 else if (tok
== ')')
6962 /* currently, we always use constant expression for globals
6963 (may change for scripting case) */
6964 expr_type
= EXPR_CONST
;
6966 expr_type
= EXPR_ANY
;
6967 init_putv(type
, sec
, c
, 0, expr_type
);
6971 /* parse an initializer for type 't' if 'has_init' is non zero, and
6972 allocate space in local or global data space ('r' is either
6973 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
6974 variable 'v' of scope 'scope' is declared before initializers are
6975 parsed. If 'v' is zero, then a reference to the new object is put
6976 in the value stack. If 'has_init' is 2, a special parsing is done
6977 to handle string constants. */
6978 static void decl_initializer_alloc(CType
*type
, AttributeDef
*ad
, int r
,
6979 int has_init
, int v
, int scope
)
6981 int size
, align
, addr
, data_offset
;
6983 ParseState saved_parse_state
;
6984 TokenString init_str
;
6987 size
= type_size(type
, &align
);
6988 /* If unknown size, we must evaluate it before
6989 evaluating initializers because
6990 initializers can generate global data too
6991 (e.g. string pointers or ISOC99 compound
6992 literals). It also simplifies local
6993 initializers handling */
6994 tok_str_new(&init_str
);
6997 error("unknown type size");
6998 /* get all init string */
6999 if (has_init
== 2) {
7000 /* only get strings */
7001 while (tok
== TOK_STR
|| tok
== TOK_LSTR
) {
7002 tok_str_add_tok(&init_str
);
7007 while (level
> 0 || (tok
!= ',' && tok
!= ';')) {
7009 error("unexpected end of file in initializer");
7010 tok_str_add_tok(&init_str
);
7013 else if (tok
== '}') {
7021 tok_str_add(&init_str
, -1);
7022 tok_str_add(&init_str
, 0);
7025 save_parse_state(&saved_parse_state
);
7027 macro_ptr
= init_str
.str
;
7029 decl_initializer(type
, NULL
, 0, 1, 1);
7030 /* prepare second initializer parsing */
7031 macro_ptr
= init_str
.str
;
7034 /* if still unknown size, error */
7035 size
= type_size(type
, &align
);
7037 error("unknown type size");
7039 /* take into account specified alignment if bigger */
7040 if (ad
->aligned
> align
)
7041 align
= ad
->aligned
;
7042 if ((r
& VT_VALMASK
) == VT_LOCAL
) {
7044 if (do_bounds_check
&& (type
->t
& VT_ARRAY
))
7046 #ifdef TCC_TARGET_IL
7047 /* XXX: ugly patch to allocate local variables for IL, just
7052 loc
= (loc
- size
) & -align
;
7055 /* handles bounds */
7056 /* XXX: currently, since we do only one pass, we cannot track
7057 '&' operators, so we add only arrays */
7058 if (do_bounds_check
&& (type
->t
& VT_ARRAY
)) {
7059 unsigned long *bounds_ptr
;
7060 /* add padding between regions */
7062 /* then add local bound info */
7063 bounds_ptr
= section_ptr_add(lbounds_section
, 2 * sizeof(unsigned long));
7064 bounds_ptr
[0] = addr
;
7065 bounds_ptr
[1] = size
;
7068 /* compute section */
7076 data_offset
= sec
->data_offset
;
7077 data_offset
= (data_offset
+ align
- 1) & -align
;
7079 /* very important to increment global pointer at this time
7080 because initializers themselves can create new initializers */
7081 data_offset
+= size
;
7082 /* add padding if bound check */
7083 if (do_bounds_check
)
7085 sec
->data_offset
= data_offset
;
7086 /* allocate section space to put the data */
7087 if (sec
->sh_type
!= SHT_NOBITS
&&
7088 data_offset
> sec
->data_allocated
)
7089 section_realloc(sec
, data_offset
);
7093 /* local variable */
7094 sym_push(v
, type
, r
, addr
);
7096 /* push local reference */
7097 vset(type
, r
, addr
);
7103 if (scope
== VT_CONST
) {
7104 /* global scope: see if already defined */
7108 if (!is_compatible_types(&sym
->type
, type
))
7109 error("incompatible types for redefinition of '%s'",
7110 get_tok_str(v
, NULL
));
7111 if (!(sym
->type
.t
& VT_EXTERN
))
7112 error("redefinition of '%s'", get_tok_str(v
, NULL
));
7113 sym
->type
.t
&= ~VT_EXTERN
;
7116 sym
= sym_push(v
, type
, r
| VT_SYM
, 0);
7118 put_extern_sym(sym
, sec
, addr
, size
);
7122 /* push global reference */
7123 sym
= get_sym_ref(type
, sec
, addr
, size
);
7125 vsetc(type
, VT_CONST
| VT_SYM
, &cval
);
7129 /* handles bounds now because the symbol must be defined
7130 before for the relocation */
7131 if (do_bounds_check
) {
7132 unsigned long *bounds_ptr
;
7134 greloc(bounds_section
, sym
, bounds_section
->data_offset
, R_DATA_32
);
7135 /* then add global bound info */
7136 bounds_ptr
= section_ptr_add(bounds_section
, 2 * sizeof(long));
7137 bounds_ptr
[0] = 0; /* relocated */
7138 bounds_ptr
[1] = size
;
7142 decl_initializer(type
, sec
, addr
, 1, 0);
7143 /* restore parse state if needed */
7145 tok_str_free(init_str
.str
);
7146 restore_parse_state(&saved_parse_state
);
7151 void put_func_debug(Sym
*sym
)
7156 /* XXX: we put here a dummy type */
7157 snprintf(buf
, sizeof(buf
), "%s:%c1",
7158 funcname
, sym
->type
.t
& VT_STATIC
? 'f' : 'F');
7159 put_stabs_r(buf
, N_FUN
, 0, file
->line_num
, 0,
7160 cur_text_section
, sym
->c
);
7165 /* not finished : try to put some local vars in registers */
7166 //#define CONFIG_REG_VARS
7168 #ifdef CONFIG_REG_VARS
7169 void add_var_ref(int t
)
7171 printf("%s:%d: &%s\n",
7172 file
->filename
, file
->line_num
,
7173 get_tok_str(t
, NULL
));
7176 /* first pass on a function with heuristic to extract variable usage
7177 and pointer references to local variables for register allocation */
7178 void analyse_function(void)
7185 /* any symbol coming after '&' is considered as being a
7186 variable whose reference is taken. It is highly unaccurate
7187 but it is difficult to do better without a complete parse */
7190 /* if '& number', then no need to examine next tokens */
7191 if (tok
== TOK_CINT
||
7193 tok
== TOK_CLLONG
||
7194 tok
== TOK_CULLONG
) {
7196 } else if (tok
>= TOK_UIDENT
) {
7197 /* if '& ident [' or '& ident ->', then ident address
7201 if (tok
!= '[' && tok
!= TOK_ARROW
)
7205 while (tok
!= '}' && tok
!= ';' &&
7206 !((tok
== ',' || tok
== ')') && level
== 0)) {
7207 if (tok
>= TOK_UIDENT
) {
7209 } else if (tok
== '(') {
7211 } else if (tok
== ')') {
7224 /* parse an old style function declaration list */
7225 /* XXX: check multiple parameter */
7226 static void func_decl_list(Sym
*func_sym
)
7233 /* parse each declaration */
7234 while (tok
!= '{' && tok
!= ';' && tok
!= TOK_EOF
) {
7235 if (!parse_btype(&btype
, &ad
))
7236 expect("declaration list");
7237 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
7238 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
7240 /* we accept no variable after */
7244 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
7245 /* find parameter in function parameter list */
7248 if ((s
->v
& ~SYM_FIELD
) == v
)
7252 error("declaration for parameter '%s' but no such parameter",
7253 get_tok_str(v
, NULL
));
7255 /* check that no storage specifier except 'register' was given */
7256 if (type
.t
& (VT_EXTERN
| VT_STATIC
| VT_TYPEDEF
))
7257 error("storage class specified for '%s'", get_tok_str(v
, NULL
));
7258 /* we can add the type (NOTE: it could be local to the function) */
7260 /* accept other parameters */
7271 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
7272 static void decl(int l
)
7280 if (!parse_btype(&btype
, &ad
)) {
7281 /* skip redundant ';' */
7282 /* XXX: find more elegant solution */
7287 /* special test for old K&R protos without explicit int
7288 type. Only accepted when defining global data */
7289 if (l
== VT_LOCAL
|| tok
< TOK_DEFINE
)
7293 if (((btype
.t
& VT_BTYPE
) == VT_ENUM
||
7294 (btype
.t
& VT_BTYPE
) == VT_STRUCT
) &&
7296 /* we accept no variable after */
7300 while (1) { /* iterate thru each declaration */
7302 type_decl(&type
, &ad
, &v
, TYPE_DIRECT
);
7306 type_to_str(buf
, sizeof(buf
), t
, get_tok_str(v
, NULL
));
7307 printf("type = '%s'\n", buf
);
7310 if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
7311 /* if old style function prototype, we accept a
7314 if (sym
->c
== FUNC_OLD
)
7315 func_decl_list(sym
);
7319 #ifdef CONFIG_REG_VARS
7320 TokenString func_str
;
7321 ParseState saved_parse_state
;
7326 error("cannot use local functions");
7327 if (!(type
.t
& VT_FUNC
))
7328 expect("function definition");
7330 #ifdef CONFIG_REG_VARS
7331 /* parse all function code and record it */
7333 tok_str_new(&func_str
);
7339 error("unexpected end of file");
7340 tok_str_add_tok(&func_str
);
7345 } else if (t
== '}') {
7347 if (block_level
== 0)
7351 tok_str_add(&func_str
, -1);
7352 tok_str_add(&func_str
, 0);
7354 save_parse_state(&saved_parse_state
);
7356 macro_ptr
= func_str
.str
;
7361 /* compute text section */
7362 cur_text_section
= ad
.section
;
7363 if (!cur_text_section
)
7364 cur_text_section
= text_section
;
7365 ind
= cur_text_section
->data_offset
;
7366 funcname
= get_tok_str(v
, NULL
);
7369 /* if symbol is already defined, then put complete type */
7372 /* put function symbol */
7373 sym
= global_identifier_push(v
, type
.t
, 0);
7374 sym
->type
.ref
= type
.ref
;
7376 /* NOTE: we patch the symbol size later */
7377 put_extern_sym(sym
, cur_text_section
, ind
, 0);
7379 sym
->r
= VT_SYM
| VT_CONST
;
7380 /* put debug symbol */
7382 put_func_debug(sym
);
7383 /* push a dummy symbol to enable local sym storage */
7384 sym_push2(&local_stack
, SYM_FIELD
, 0, 0);
7385 gfunc_prolog(&type
);
7388 #ifdef CONFIG_REG_VARS
7389 macro_ptr
= func_str
.str
;
7392 block(NULL
, NULL
, NULL
, NULL
, 0);
7395 cur_text_section
->data_offset
= ind
;
7396 /* look if any labels are undefined. Define symbols if
7397 '&&label' was used. */
7400 for(s
= label_stack
; s
!= NULL
; s
= s1
) {
7402 if (s
->r
& LABEL_FORWARD
) {
7403 error("label '%s' used but not defined",
7404 get_tok_str(s
->v
, NULL
));
7407 /* define corresponding symbol. A size of
7409 put_extern_sym(s
, cur_text_section
, (long)s
->next
, 1);
7412 table_ident
[s
->v
- TOK_IDENT
]->sym_label
= NULL
;
7417 sym_pop(&local_stack
, NULL
); /* reset local stack */
7418 /* end of function */
7419 /* patch symbol size */
7420 ((Elf32_Sym
*)symtab_section
->data
)[sym
->c
].st_size
=
7423 put_stabn(N_FUN
, 0, 0, ind
- func_ind
);
7425 funcname
= ""; /* for safety */
7426 func_vt
.t
= VT_VOID
; /* for safety */
7427 ind
= 0; /* for safety */
7429 #ifdef CONFIG_REG_VARS
7430 tok_str_free(func_str
.str
);
7431 restore_parse_state(&saved_parse_state
);
7435 if (btype
.t
& VT_TYPEDEF
) {
7436 /* save typedefed type */
7437 /* XXX: test storage specifiers ? */
7438 sym
= sym_push(v
, &type
, 0, 0);
7439 sym
->type
.t
|= VT_TYPEDEF
;
7440 } else if ((type
.t
& VT_BTYPE
) == VT_FUNC
) {
7441 /* external function definition */
7442 external_sym(v
, &type
, 0);
7444 /* not lvalue if array */
7446 if (!(type
.t
& VT_ARRAY
))
7447 r
|= lvalue_type(type
.t
);
7448 if (btype
.t
& VT_EXTERN
) {
7449 /* external variable */
7450 external_sym(v
, &type
, r
);
7452 if (type
.t
& VT_STATIC
)
7456 has_init
= (tok
== '=');
7459 decl_initializer_alloc(&type
, &ad
, r
,
7473 /* compile the C file opened in 'file'. Return non zero if errors. */
7474 static int tcc_compile(TCCState
*s1
)
7478 volatile int section_sym
;
7481 printf("%s: **** new file\n", file
->filename
);
7484 s1
->include_stack_ptr
= s1
->include_stack
;
7485 /* XXX: move that before to avoid having to initialize
7486 file->ifdef_stack_ptr ? */
7487 s1
->ifdef_stack_ptr
= s1
->ifdef_stack
;
7488 file
->ifdef_stack_ptr
= s1
->ifdef_stack_ptr
;
7490 /* XXX: not ANSI compliant: bound checking says error */
7492 anon_sym
= SYM_FIRST_ANOM
;
7494 /* file info: full path + filename */
7495 section_sym
= 0; /* avoid warning */
7497 section_sym
= put_elf_sym(symtab_section
, 0, 0,
7498 ELF32_ST_INFO(STB_LOCAL
, STT_SECTION
), 0,
7499 text_section
->sh_num
, NULL
);
7500 getcwd(buf
, sizeof(buf
));
7501 pstrcat(buf
, sizeof(buf
), "/");
7502 put_stabs_r(buf
, N_SO
, 0, 0,
7503 text_section
->data_offset
, text_section
, section_sym
);
7504 put_stabs_r(file
->filename
, N_SO
, 0, 0,
7505 text_section
->data_offset
, text_section
, section_sym
);
7507 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
7508 symbols can be safely used */
7509 put_elf_sym(symtab_section
, 0, 0,
7510 ELF32_ST_INFO(STB_LOCAL
, STT_FILE
), 0,
7511 SHN_ABS
, file
->filename
);
7513 /* define some often used types */
7514 int_type
.t
= VT_INT
;
7516 char_pointer_type
.t
= VT_BYTE
;
7517 mk_pointer(&char_pointer_type
);
7519 func_old_type
.t
= VT_FUNC
;
7520 func_old_type
.ref
= sym_push(SYM_FIELD
, &int_type
, FUNC_CDECL
, FUNC_OLD
);
7523 /* define 'void *alloca(unsigned int)' builtin function */
7528 sym
= sym_push(p
, mk_pointer(VT_VOID
), FUNC_CDECL
, FUNC_NEW
);
7529 s1
= sym_push(SYM_FIELD
, VT_UNSIGNED
| VT_INT
, 0, 0);
7532 sym_push(TOK_alloca
, VT_FUNC
| (p
<< VT_STRUCT_SHIFT
), VT_CONST
, 0);
7536 define_start
= define_stack
;
7538 if (setjmp(s1
->error_jmp_buf
) == 0) {
7540 s1
->error_set_jmp_enabled
= 1;
7543 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7547 expect("declaration");
7549 /* end of translation unit info */
7551 put_stabs_r(NULL
, N_SO
, 0, 0,
7552 text_section
->data_offset
, text_section
, section_sym
);
7555 s1
->error_set_jmp_enabled
= 0;
7557 /* reset define stack, but leave -Dsymbols (may be incorrect if
7558 they are undefined) */
7559 free_defines(define_start
);
7561 sym_pop(&global_stack
, NULL
);
7563 return s1
->nb_errors
!= 0 ? -1 : 0;
7567 int tcc_compile_string(TCCState
*s
, const char *str
)
7569 BufferedFile bf1
, *bf
= &bf1
;
7573 /* init file structure */
7575 /* XXX: avoid copying */
7577 buf
= tcc_malloc(len
+ 1);
7582 bf
->buf_end
= buf
+ len
;
7583 pstrcpy(bf
->filename
, sizeof(bf
->filename
), "<string>");
7587 ret
= tcc_compile(s
);
7591 /* currently, no need to close */
7596 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
7597 void tcc_define_symbol(TCCState
*s1
, const char *sym
, const char *value
)
7599 BufferedFile bf1
, *bf
= &bf1
;
7601 pstrcpy(bf
->buffer
, IO_BUF_SIZE
, sym
);
7602 pstrcat(bf
->buffer
, IO_BUF_SIZE
, " ");
7606 pstrcat(bf
->buffer
, IO_BUF_SIZE
, value
);
7608 /* init file structure */
7610 bf
->buf_ptr
= bf
->buffer
;
7611 bf
->buf_end
= bf
->buffer
+ strlen(bf
->buffer
);
7612 *bf
->buf_end
= CH_EOB
;
7613 bf
->filename
[0] = '\0';
7617 s1
->include_stack_ptr
= s1
->include_stack
;
7619 /* parse with define parser */
7621 ch
= '\n'; /* needed to parse correctly first preprocessor command */
7627 /* undefine a preprocessor symbol */
7628 void tcc_undefine_symbol(TCCState
*s1
, const char *sym
)
7632 ts
= tok_alloc(sym
, strlen(sym
));
7633 s
= define_find(ts
->tok
);
7634 /* undefine symbol by putting an invalid name */
7641 /* print the position in the source file of PC value 'pc' by reading
7642 the stabs debug information */
7643 static void rt_printline(unsigned long wanted_pc
)
7645 Stab_Sym
*sym
, *sym_end
;
7646 char func_name
[128], last_func_name
[128];
7647 unsigned long func_addr
, last_pc
, pc
;
7648 const char *incl_files
[INCLUDE_STACK_SIZE
];
7649 int incl_index
, len
, last_line_num
, i
;
7650 const char *str
, *p
;
7652 fprintf(stderr
, "0x%08lx:", wanted_pc
);
7654 func_name
[0] = '\0';
7657 last_func_name
[0] = '\0';
7658 last_pc
= 0xffffffff;
7660 sym
= (Stab_Sym
*)stab_section
->data
+ 1;
7661 sym_end
= (Stab_Sym
*)(stab_section
->data
+ stab_section
->data_offset
);
7662 while (sym
< sym_end
) {
7663 switch(sym
->n_type
) {
7664 /* function start or end */
7666 if (sym
->n_strx
== 0) {
7667 /* we test if between last line and end of function */
7668 pc
= sym
->n_value
+ func_addr
;
7669 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7671 func_name
[0] = '\0';
7674 str
= stabstr_section
->data
+ sym
->n_strx
;
7675 p
= strchr(str
, ':');
7677 pstrcpy(func_name
, sizeof(func_name
), str
);
7680 if (len
> sizeof(func_name
) - 1)
7681 len
= sizeof(func_name
) - 1;
7682 memcpy(func_name
, str
, len
);
7683 func_name
[len
] = '\0';
7685 func_addr
= sym
->n_value
;
7688 /* line number info */
7690 pc
= sym
->n_value
+ func_addr
;
7691 if (wanted_pc
>= last_pc
&& wanted_pc
< pc
)
7694 last_line_num
= sym
->n_desc
;
7696 strcpy(last_func_name
, func_name
);
7700 str
= stabstr_section
->data
+ sym
->n_strx
;
7702 if (incl_index
< INCLUDE_STACK_SIZE
) {
7703 incl_files
[incl_index
++] = str
;
7711 if (sym
->n_strx
== 0) {
7712 incl_index
= 0; /* end of translation unit */
7714 str
= stabstr_section
->data
+ sym
->n_strx
;
7715 /* do not add path */
7717 if (len
> 0 && str
[len
- 1] != '/')
7725 /* second pass: we try symtab symbols (no line number info) */
7728 Elf32_Sym
*sym
, *sym_end
;
7731 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
7732 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
7735 type
= ELF32_ST_TYPE(sym
->st_info
);
7736 if (type
== STT_FUNC
) {
7737 if (wanted_pc
>= sym
->st_value
&&
7738 wanted_pc
< sym
->st_value
+ sym
->st_size
) {
7739 pstrcpy(last_func_name
, sizeof(last_func_name
),
7740 strtab_section
->data
+ sym
->st_name
);
7746 /* did not find any info: */
7747 fprintf(stderr
, " ???\n");
7750 if (last_func_name
[0] != '\0') {
7751 fprintf(stderr
, " %s()", last_func_name
);
7753 if (incl_index
> 0) {
7754 fprintf(stderr
, " (%s:%d",
7755 incl_files
[incl_index
- 1], last_line_num
);
7756 for(i
= incl_index
- 2; i
>= 0; i
--)
7757 fprintf(stderr
, ", included from %s", incl_files
[i
]);
7758 fprintf(stderr
, ")");
7760 fprintf(stderr
, "\n");
7772 /* return the PC at frame level 'level'. Return non zero if not found */
7773 static int rt_get_caller_pc(unsigned long *paddr
,
7774 struct ucontext
*uc
, int level
)
7780 *paddr
= uc
->uc_mcontext
.gregs
[EIP
];
7783 fp
= uc
->uc_mcontext
.gregs
[EBP
];
7784 for(i
=1;i
<level
;i
++) {
7785 /* XXX: check address validity with program info */
7786 if (fp
<= 0x1000 || fp
>= 0xc0000000)
7788 fp
= ((unsigned long *)fp
)[0];
7790 *paddr
= ((unsigned long *)fp
)[1];
7795 #error add arch specific rt_get_caller_pc()
7798 /* emit a run time error at position 'pc' */
7799 void rt_error(struct ucontext
*uc
, const char *fmt
, ...)
7806 fprintf(stderr
, "Runtime error: ");
7807 vfprintf(stderr
, fmt
, ap
);
7808 fprintf(stderr
, "\n");
7809 for(i
=0;i
<num_callers
;i
++) {
7810 if (rt_get_caller_pc(&pc
, uc
, i
) < 0)
7813 fprintf(stderr
, "at ");
7815 fprintf(stderr
, "by ");
7822 /* signal handler for fatal errors */
7823 static void sig_error(int signum
, siginfo_t
*siginf
, void *puc
)
7825 struct ucontext
*uc
= puc
;
7829 switch(siginf
->si_code
) {
7832 rt_error(uc
, "division by zero");
7835 rt_error(uc
, "floating point exception");
7841 if (rt_bound_error_msg
&& *rt_bound_error_msg
)
7842 rt_error(uc
, *rt_bound_error_msg
);
7844 rt_error(uc
, "dereferencing invalid pointer");
7847 rt_error(uc
, "illegal instruction");
7850 rt_error(uc
, "abort() called");
7853 rt_error(uc
, "caught signal %d", signum
);
7860 /* do all relocations (needed before using tcc_get_symbol()) */
7861 int tcc_relocate(TCCState
*s1
)
7868 tcc_add_runtime(s1
);
7870 relocate_common_syms();
7872 /* compute relocation address : section are relocated in place. We
7873 also alloc the bss space */
7874 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7875 s
= s1
->sections
[i
];
7876 if (s
->sh_flags
& SHF_ALLOC
) {
7877 if (s
->sh_type
== SHT_NOBITS
)
7878 s
->data
= tcc_mallocz(s
->data_offset
);
7879 s
->sh_addr
= (unsigned long)s
->data
;
7883 relocate_syms(s1
, 1);
7885 if (s1
->nb_errors
!= 0)
7888 /* relocate each section */
7889 for(i
= 1; i
< s1
->nb_sections
; i
++) {
7890 s
= s1
->sections
[i
];
7892 relocate_section(s1
, s
);
7897 /* launch the compiled program with the given arguments */
7898 int tcc_run(TCCState
*s1
, int argc
, char **argv
)
7900 int (*prog_main
)(int, char **);
7902 if (tcc_relocate(s1
) < 0)
7905 prog_main
= tcc_get_symbol(s1
, "main");
7909 error("debug mode currently not available for Windows");
7911 struct sigaction sigact
;
7912 /* install TCC signal handlers to print debug info on fatal
7914 sigact
.sa_flags
= SA_SIGINFO
| SA_ONESHOT
;
7915 sigact
.sa_sigaction
= sig_error
;
7916 sigemptyset(&sigact
.sa_mask
);
7917 sigaction(SIGFPE
, &sigact
, NULL
);
7918 sigaction(SIGILL
, &sigact
, NULL
);
7919 sigaction(SIGSEGV
, &sigact
, NULL
);
7920 sigaction(SIGBUS
, &sigact
, NULL
);
7921 sigaction(SIGABRT
, &sigact
, NULL
);
7925 #ifdef CONFIG_TCC_BCHECK
7926 if (do_bounds_check
) {
7927 void (*bound_init
)(void);
7929 /* set error function */
7930 rt_bound_error_msg
= (void *)tcc_get_symbol(s1
, "__bound_error_msg");
7932 /* XXX: use .init section so that it also work in binary ? */
7933 bound_init
= (void *)tcc_get_symbol(s1
, "__bound_init");
7937 return (*prog_main
)(argc
, argv
);
7940 TCCState
*tcc_new(void)
7945 s
= tcc_mallocz(sizeof(TCCState
));
7949 s
->output_type
= TCC_OUTPUT_MEMORY
;
7951 /* default include paths */
7952 tcc_add_sysinclude_path(s
, "/usr/local/include");
7953 tcc_add_sysinclude_path(s
, "/usr/include");
7954 tcc_add_sysinclude_path(s
, CONFIG_TCC_PREFIX
"/lib/tcc/include");
7956 /* add all tokens */
7958 memset(hash_ident
, 0, TOK_HASH_SIZE
* sizeof(TokenSym
*));
7960 tok_ident
= TOK_IDENT
;
7965 tok_alloc(p
, r
- p
- 1);
7969 /* we add dummy defines for some special macros to speed up tests
7970 and to have working defined() */
7971 define_push(TOK___LINE__
, MACRO_OBJ
, NULL
, NULL
);
7972 define_push(TOK___FILE__
, MACRO_OBJ
, NULL
, NULL
);
7973 define_push(TOK___DATE__
, MACRO_OBJ
, NULL
, NULL
);
7974 define_push(TOK___TIME__
, MACRO_OBJ
, NULL
, NULL
);
7976 /* standard defines */
7977 tcc_define_symbol(s
, "__STDC__", NULL
);
7978 #if defined(TCC_TARGET_I386)
7979 tcc_define_symbol(s
, "__i386__", NULL
);
7982 tcc_define_symbol(s
, "linux", NULL
);
7984 /* tiny C specific defines */
7985 tcc_define_symbol(s
, "__TINYC__", NULL
);
7987 /* default library paths */
7988 tcc_add_library_path(s
, "/usr/local/lib");
7989 tcc_add_library_path(s
, "/usr/lib");
7990 tcc_add_library_path(s
, "/lib");
7992 /* no section zero */
7993 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
7995 /* create standard sections */
7996 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
7997 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
7998 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
8000 /* symbols are always generated for linking stage */
8001 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
8003 ".hashtab", SHF_PRIVATE
);
8004 strtab_section
= symtab_section
->link
;
8006 /* private symbol table for dynamic symbols */
8007 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
8009 ".dynhashtab", SHF_PRIVATE
);
8013 void tcc_delete(TCCState
*s1
)
8017 /* free -D defines */
8021 n
= tok_ident
- TOK_IDENT
;
8022 for(i
= 0; i
< n
; i
++)
8023 tcc_free(table_ident
[i
]);
8024 tcc_free(table_ident
);
8026 /* free all sections */
8028 free_section(symtab_section
->hash
);
8030 free_section(s1
->dynsymtab_section
->hash
);
8031 free_section(s1
->dynsymtab_section
->link
);
8032 free_section(s1
->dynsymtab_section
);
8034 for(i
= 1; i
< s1
->nb_sections
; i
++)
8035 free_section(s1
->sections
[i
]);
8036 tcc_free(s1
->sections
);
8038 /* free loaded dlls array */
8039 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
8040 tcc_free(s1
->loaded_dlls
[i
]);
8041 tcc_free(s1
->loaded_dlls
);
8044 for(i
= 0; i
< s1
->nb_library_paths
; i
++)
8045 tcc_free(s1
->library_paths
[i
]);
8046 tcc_free(s1
->library_paths
);
8048 /* cached includes */
8049 for(i
= 0; i
< s1
->nb_cached_includes
; i
++)
8050 tcc_free(s1
->cached_includes
[i
]);
8051 tcc_free(s1
->cached_includes
);
8053 for(i
= 0; i
< s1
->nb_include_paths
; i
++)
8054 tcc_free(s1
->include_paths
[i
]);
8055 tcc_free(s1
->include_paths
);
8057 for(i
= 0; i
< s1
->nb_sysinclude_paths
; i
++)
8058 tcc_free(s1
->sysinclude_paths
[i
]);
8059 tcc_free(s1
->sysinclude_paths
);
8064 int tcc_add_include_path(TCCState
*s1
, const char *pathname
)
8068 pathname1
= tcc_strdup(pathname
);
8069 dynarray_add((void ***)&s1
->include_paths
, &s1
->nb_include_paths
, pathname1
);
8073 int tcc_add_sysinclude_path(TCCState
*s1
, const char *pathname
)
8077 pathname1
= tcc_strdup(pathname
);
8078 dynarray_add((void ***)&s1
->sysinclude_paths
, &s1
->nb_sysinclude_paths
, pathname1
);
8082 static int tcc_add_file_internal(TCCState
*s1
, const char *filename
, int flags
)
8087 BufferedFile
*saved_file
;
8089 /* find source file type with extension */
8090 ext
= strrchr(filename
, '.');
8096 file
= tcc_open(s1
, filename
);
8098 if (flags
& AFF_PRINT_ERROR
) {
8099 error_noabort("file '%s' not found", filename
);
8105 if (!ext
|| !strcmp(ext
, "c")) {
8106 /* C file assumed */
8107 ret
= tcc_compile(s1
);
8110 /* assume executable format: auto guess file type */
8111 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
)) {
8112 error_noabort("could not read header");
8115 lseek(fd
, 0, SEEK_SET
);
8117 if (ehdr
.e_ident
[0] == ELFMAG0
&&
8118 ehdr
.e_ident
[1] == ELFMAG1
&&
8119 ehdr
.e_ident
[2] == ELFMAG2
&&
8120 ehdr
.e_ident
[3] == ELFMAG3
) {
8121 file
->line_num
= 0; /* do not display line number if error */
8122 if (ehdr
.e_type
== ET_REL
) {
8123 ret
= tcc_load_object_file(s1
, fd
, 0);
8124 } else if (ehdr
.e_type
== ET_DYN
) {
8125 ret
= tcc_load_dll(s1
, fd
, filename
,
8126 (flags
& AFF_REFERENCED_DLL
) != 0);
8128 error_noabort("unrecognized ELF file");
8131 } else if (memcmp((char *)&ehdr
, ARMAG
, 8) == 0) {
8132 file
->line_num
= 0; /* do not display line number if error */
8133 ret
= tcc_load_archive(s1
, fd
);
8135 /* as GNU ld, consider it is an ld script if not recognized */
8136 ret
= tcc_load_ldscript(s1
);
8138 error_noabort("unrecognized file type");
8153 int tcc_add_file(TCCState
*s
, const char *filename
)
8155 return tcc_add_file_internal(s
, filename
, AFF_PRINT_ERROR
);
8158 int tcc_add_library_path(TCCState
*s
, const char *pathname
)
8162 pathname1
= tcc_strdup(pathname
);
8163 dynarray_add((void ***)&s
->library_paths
, &s
->nb_library_paths
, pathname1
);
8167 /* find and load a dll. Return non zero if not found */
8168 /* XXX: add '-rpath' option support ? */
8169 static int tcc_add_dll(TCCState
*s
, const char *filename
, int flags
)
8174 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
8175 snprintf(buf
, sizeof(buf
), "%s/%s",
8176 s
->library_paths
[i
], filename
);
8177 if (tcc_add_file_internal(s
, buf
, flags
) == 0)
8183 /* the library name is the same as the argument of the '-l' option */
8184 int tcc_add_library(TCCState
*s
, const char *libraryname
)
8190 /* first we look for the dynamic library if not static linking */
8191 if (!s
->static_link
) {
8192 snprintf(buf
, sizeof(buf
), "lib%s.so", libraryname
);
8193 /* if we output to memory, then we simply we dlopen(). */
8194 if (s
->output_type
== TCC_OUTPUT_MEMORY
) {
8195 /* Since the libc is already loaded, we don't need to load it again */
8196 if (!strcmp(libraryname
, "c"))
8198 h
= dlopen(buf
, RTLD_GLOBAL
| RTLD_LAZY
);
8202 if (tcc_add_dll(s
, buf
, 0) == 0)
8207 /* then we look for the static library */
8208 for(i
= 0; i
< s
->nb_library_paths
; i
++) {
8209 snprintf(buf
, sizeof(buf
), "%s/lib%s.a",
8210 s
->library_paths
[i
], libraryname
);
8211 if (tcc_add_file_internal(s
, buf
, 0) == 0)
8217 int tcc_add_symbol(TCCState
*s
, const char *name
, unsigned long val
)
8219 add_elf_sym(symtab_section
, val
, 0,
8220 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
8225 int tcc_set_output_type(TCCState
*s
, int output_type
)
8227 s
->output_type
= output_type
;
8229 /* if bound checking, then add corresponding sections */
8230 #ifdef CONFIG_TCC_BCHECK
8231 if (do_bounds_check
) {
8233 tcc_define_symbol(s
, "__BOUNDS_CHECKING_ON", NULL
);
8234 /* create bounds sections */
8235 bounds_section
= new_section(s
, ".bounds",
8236 SHT_PROGBITS
, SHF_ALLOC
);
8237 lbounds_section
= new_section(s
, ".lbounds",
8238 SHT_PROGBITS
, SHF_ALLOC
);
8242 /* add debug sections */
8245 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
8246 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
8247 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
8248 put_elf_str(stabstr_section
, "");
8249 stab_section
->link
= stabstr_section
;
8250 /* put first entry */
8251 put_stabs("", 0, 0, 0, 0);
8254 /* add libc crt1/crti objects */
8255 if (output_type
== TCC_OUTPUT_EXE
||
8256 output_type
== TCC_OUTPUT_DLL
) {
8257 if (output_type
!= TCC_OUTPUT_DLL
)
8258 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crt1.o");
8259 tcc_add_file(s
, CONFIG_TCC_CRT_PREFIX
"/crti.o");
8264 #if !defined(LIBTCC)
8266 static int64_t getclock_us(void)
8271 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
8274 gettimeofday(&tv
, NULL
);
8275 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
8281 printf("tcc version 0.9.13 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n"
8282 "usage: tcc [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
8283 " [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
8284 " [--] infile1 [infile2... --] [infile_args...]\n"
8286 "General options:\n"
8287 " -c compile only - generate an object file\n"
8288 " -o outfile set output filename\n"
8289 " -- allows multiples input files if no -o option given. Also\n"
8290 " separate input files from runtime arguments\n"
8291 " -Bdir set tcc internal library path\n"
8292 " -bench output compilation statistics\n"
8293 "Preprocessor options:\n"
8294 " -Idir add include path 'dir'\n"
8295 " -Dsym[=val] define 'sym' with value 'val'\n"
8296 " -Usym undefine 'sym'\n"
8298 " -Ldir add library path 'dir'\n"
8299 " -llib link with dynamic or static library 'lib'\n"
8300 " -shared generate a shared library\n"
8301 " -static static linking\n"
8302 " -r relocatable output\n"
8303 "Debugger options:\n"
8304 " -g generate runtime debug info\n"
8305 #ifdef CONFIG_TCC_BCHECK
8306 " -b compile with built-in memory and bounds checker (implies -g)\n"
8308 " -bt N show N callers in stack traces\n"
8312 int main(int argc
, char **argv
)
8315 int optind
, output_type
, multiple_files
, i
, reloc_output
;
8318 int nb_files
, nb_libraries
, nb_objfiles
, dminus
, ret
;
8319 char objfilename
[1024];
8320 int64_t start_time
= 0;
8323 output_type
= TCC_OUTPUT_MEMORY
;
8334 if (optind
>= argc
) {
8342 /* add a new file */
8343 dynarray_add((void ***)&files
, &nb_files
, r
);
8344 if (!multiple_files
) {
8346 /* argv[0] will be this file */
8349 } else if (r
[1] == '-') {
8350 /* '--' enables multiple files input and also ends several file input */
8351 if (dminus
&& multiple_files
) {
8352 optind
--; /* argv[0] will be '--' */
8357 } else if (r
[1] == 'h' || r
[1] == '?') {
8361 } else if (r
[1] == 'I') {
8362 if (tcc_add_include_path(s
, r
+ 2) < 0)
8363 error("too many include paths");
8364 } else if (r
[1] == 'D') {
8367 value
= strchr(sym
, '=');
8372 tcc_define_symbol(s
, sym
, value
);
8373 } else if (r
[1] == 'U') {
8374 tcc_undefine_symbol(s
, r
+ 2);
8375 } else if (r
[1] == 'L') {
8376 tcc_add_library_path(s
, r
+ 2);
8377 } else if (r
[1] == 'B') {
8378 /* set tcc utilities path (mainly for tcc development) */
8379 tcc_lib_path
= r
+ 2;
8380 } else if (r
[1] == 'l') {
8381 dynarray_add((void ***)&files
, &nb_files
, r
);
8383 } else if (!strcmp(r
+ 1, "bench")) {
8385 } else if (!strcmp(r
+ 1, "bt")) {
8386 num_callers
= atoi(argv
[optind
++]);
8388 #ifdef CONFIG_TCC_BCHECK
8390 do_bounds_check
= 1;
8396 } else if (r
[1] == 'c') {
8398 output_type
= TCC_OUTPUT_OBJ
;
8399 } else if (!strcmp(r
+ 1, "static")) {
8401 } else if (!strcmp(r
+ 1, "shared")) {
8402 output_type
= TCC_OUTPUT_DLL
;
8403 } else if (r
[1] == 'o') {
8407 outfile
= argv
[optind
++];
8408 } else if (r
[1] == 'r') {
8409 /* generate a .o merging several output files */
8411 output_type
= TCC_OUTPUT_OBJ
;
8412 } else if (r
[1] == 'W' || r
[1] == 'O' || r
[1] == 'm' || r
[1] == 'f') {
8413 /* ignore those options to be a drop-in replacement for gcc */
8415 error("invalid option -- '%s'", r
);
8419 nb_objfiles
= nb_files
- nb_libraries
;
8421 /* if outfile provided without other options, we output an
8423 if (outfile
&& output_type
== TCC_OUTPUT_MEMORY
)
8424 output_type
= TCC_OUTPUT_EXE
;
8426 /* check -c consistency : only single file handled. XXX: checks file type */
8427 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
8428 /* accepts only a single input file */
8429 if (nb_objfiles
!= 1)
8430 error("cannot specify multiple files with -c");
8431 if (nb_libraries
!= 0)
8432 error("cannot specify libraries with -c");
8435 /* compute default outfile name */
8436 if (output_type
!= TCC_OUTPUT_MEMORY
&& !outfile
) {
8437 if (output_type
== TCC_OUTPUT_OBJ
&& !reloc_output
) {
8439 /* add .o extension */
8440 pstrcpy(objfilename
, sizeof(objfilename
) - 1, files
[0]);
8441 ext
= strrchr(objfilename
, '.');
8443 goto default_outfile
;
8444 strcpy(ext
+ 1, "o");
8447 pstrcpy(objfilename
, sizeof(objfilename
), "a.out");
8449 outfile
= objfilename
;
8453 start_time
= getclock_us();
8456 tcc_set_output_type(s
, output_type
);
8458 /* compile or add each files or library */
8459 for(i
= 0;i
< nb_files
; i
++) {
8460 const char *filename
;
8462 filename
= files
[i
];
8463 if (filename
[0] == '-') {
8464 if (tcc_add_library(s
, filename
+ 2) < 0)
8465 error("cannot find %s", filename
);
8467 if (tcc_add_file(s
, filename
) < 0) {
8474 /* free all files */
8479 total_time
= (double)(getclock_us() - start_time
) / 1000000.0;
8480 if (total_time
< 0.001)
8482 if (total_bytes
< 1)
8484 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
8485 tok_ident
- TOK_IDENT
, total_lines
, total_bytes
,
8486 total_time
, (int)(total_lines
/ total_time
),
8487 total_bytes
/ total_time
/ 1000000.0);
8490 if (s
->output_type
!= TCC_OUTPUT_MEMORY
) {
8491 tcc_output_file(s
, outfile
);
8494 ret
= tcc_run(s
, argc
- optind
, argv
+ optind
);
8497 /* XXX: cannot do it with bound checking because of the malloc hooks */
8498 if (!do_bounds_check
)
8503 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size
, mem_max_size
);