Subversion Repositories Kolibri OS

Rev

Rev 609 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
145 halyavin 1
/*
2
 *  TCC - Tiny C Compiler
3
 *
4
 *  Copyright (c) 2001-2004 Fabrice Bellard
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library 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 GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
#define _GNU_SOURCE
21
#include "config.h"
22
 
23
#ifdef CONFIG_TCCBOOT
24
 
25
#include "tccboot.h"
26
#define CONFIG_TCC_STATIC
27
 
28
#else
29
 
30
#include 
31
#include 
32
#include 
33
#include 
34
#include 
35
#include 
36
#include 
37
#include 
38
#include 
39
#include 
40
#include 
41
#ifdef WIN32
42
#include 
43
#endif
44
#ifndef WIN32
45
#include 
46
#include 
47
#endif
48
 
49
#endif /* !CONFIG_TCCBOOT */
50
 
51
#include "elf.h"
52
#include "stab.h"
53
 
54
#ifndef O_BINARY
55
#define O_BINARY 0
56
#endif
57
 
58
#include "libtcc.h"
59
 
60
/* parser debug */
61
//#define PARSE_DEBUG
62
/* preprocessor debug */
63
//#define PP_DEBUG
64
/* include file debug */
65
//#define INC_DEBUG
66
 
67
//#define MEM_DEBUG
68
 
69
/* assembler debug */
70
//#define ASM_DEBUG
71
 
72
/* target selection */
73
//#define TCC_TARGET_I386   /* i386 code generator */
74
//#define TCC_TARGET_ARM    /* ARMv4 code generator */
75
//#define TCC_TARGET_C67    /* TMS320C67xx code generator */
76
 
77
/* default target is I386 */
78
#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
79
    !defined(TCC_TARGET_C67)
80
#define TCC_TARGET_I386
81
#endif
82
 
83
#if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
84
    !defined(TCC_TARGET_C67)
85
#define CONFIG_TCC_BCHECK /* enable bound checking code */
86
#endif
87
 
88
#if defined(WIN32) && !defined(TCC_TARGET_PE) && !defined(TCC_TARGET_MEOS)
89
#define CONFIG_TCC_STATIC
90
#endif
91
 
92
/* define it to include assembler support */
93
#if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
94
#define CONFIG_TCC_ASM
95
#endif
96
 
97
/* object format selection */
98
#if defined(TCC_TARGET_C67)
99
#define TCC_TARGET_COFF
100
#endif
101
 
102
#define FALSE 0
103
#define false 0
104
#define TRUE 1
105
#define true 1
106
typedef int BOOL;
107
 
108
/* path to find crt1.o, crti.o and crtn.o. Only needed when generating
109
   executables or dlls */
110
#define CONFIG_TCC_CRT_PREFIX "/usr/lib"
111
 
112
#define INCLUDE_STACK_SIZE  32
113
#define IFDEF_STACK_SIZE    64
114
#define VSTACK_SIZE         256
115
#define STRING_MAX_SIZE     1024
116
#define PACK_STACK_SIZE     8
117
 
118
#define TOK_HASH_SIZE       8192 /* must be a power of two */
119
#define TOK_ALLOC_INCR      512  /* must be a power of two */
120
#define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */
121
 
122
/* token symbol management */
123
typedef struct TokenSym {
124
    struct TokenSym *hash_next;
125
    struct Sym *sym_define; /* direct pointer to define */
126
    struct Sym *sym_label; /* direct pointer to label */
127
    struct Sym *sym_struct; /* direct pointer to structure */
128
    struct Sym *sym_identifier; /* direct pointer to identifier */
129
    int tok; /* token number */
130
    int len;
131
    char str[1];
132
} TokenSym;
133
 
134
typedef struct CString {
135
    int size; /* size in bytes */
136
    void *data; /* either 'char *' or 'int *' */
137
    int size_allocated;
138
    void *data_allocated; /* if non NULL, data has been malloced */
139
} CString;
140
 
141
/* type definition */
142
typedef struct CType {
143
    int t;
144
    struct Sym *ref;
145
} CType;
146
 
147
/* constant value */
148
typedef union CValue {
149
    long double ld;
150
    double d;
151
    float f;
152
    int i;
153
    unsigned int ui;
154
    unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
155
    long long ll;
156
    unsigned long long ull;
157
    struct CString *cstr;
158
    void *ptr;
159
    int tab[1];
160
} CValue;
161
 
162
/* value on stack */
163
typedef struct SValue {
164
    CType type;      /* type */
165
    unsigned short r;      /* register + flags */
166
    unsigned short r2;     /* second register, used for 'long long'
167
                              type. If not used, set to VT_CONST */
168
    CValue c;              /* constant, if VT_CONST */
169
    struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST) */
170
} SValue;
171
 
172
/* symbol management */
173
typedef struct Sym {
174
    int v;    /* symbol token */
175
    int r;    /* associated register */
176
    int c;    /* associated number */
177
    CType type;    /* associated type */
178
    struct Sym *next; /* next related symbol */
179
    struct Sym *prev; /* prev symbol in stack */
180
    struct Sym *prev_tok; /* previous symbol for this token */
181
} Sym;
182
 
183
/* section definition */
184
/* XXX: use directly ELF structure for parameters ? */
185
/* special flag to indicate that the section should not be linked to
186
   the other ones */
187
#define SHF_PRIVATE 0x80000000
188
 
189
typedef struct Section {
190
    unsigned long data_offset; /* current data offset */
191
    unsigned char *data;       /* section data */
192
    unsigned long data_allocated; /* used for realloc() handling */
193
    int sh_name;             /* elf section name (only used during output) */
194
    int sh_num;              /* elf section number */
195
    int sh_type;             /* elf section type */
196
    int sh_flags;            /* elf section flags */
197
    int sh_info;             /* elf section info */
198
    int sh_addralign;        /* elf section alignment */
199
    int sh_entsize;          /* elf entry size */
200
    unsigned long sh_size;   /* section size (only used during output) */
201
    unsigned long sh_addr;      /* address at which the section is relocated */
202
    unsigned long sh_offset;      /* address at which the section is relocated */
203
    int nb_hashed_syms;      /* used to resize the hash table */
204
    struct Section *link;    /* link to another section */
205
    struct Section *reloc;   /* corresponding section for relocation, if any */
206
    struct Section *hash;     /* hash table for symbols */
207
    struct Section *next;
208
    char name[1];           /* section name */
209
} Section;
210
 
211
typedef struct DLLReference {
212
    int level;
213
    char name[1];
214
} DLLReference;
215
 
216
/* GNUC attribute definition */
217
typedef struct AttributeDef {
218
    int aligned;
219
    int packed;
220
    Section *section;
221
    unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */
222
    unsigned char dllexport;
223
} AttributeDef;
224
 
225
#define SYM_STRUCT     0x40000000 /* struct/union/enum symbol space */
226
#define SYM_FIELD      0x20000000 /* struct/union field symbol space */
227
#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
228
 
229
/* stored in 'Sym.c' field */
230
#define FUNC_NEW       1 /* ansi function prototype */
231
#define FUNC_OLD       2 /* old function prototype */
232
#define FUNC_ELLIPSIS  3 /* ansi function prototype with ... */
233
 
234
/* stored in 'Sym.r' field */
235
#define FUNC_CDECL     0 /* standard c call */
236
#define FUNC_STDCALL   1 /* pascal c call */
237
#define FUNC_FASTCALL1 2 /* first param in %eax */
238
#define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
239
#define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
240
 
241
/* field 'Sym.t' for macros */
242
#define MACRO_OBJ      0 /* object like macro */
243
#define MACRO_FUNC     1 /* function like macro */
244
 
245
/* field 'Sym.r' for C labels */
246
#define LABEL_DEFINED  0 /* label is defined */
247
#define LABEL_FORWARD  1 /* label is forward defined */
248
#define LABEL_DECLARED 2 /* label is declared but never used */
249
 
250
/* type_decl() types */
251
#define TYPE_ABSTRACT  1 /* type without variable */
252
#define TYPE_DIRECT    2 /* type with variable */
253
 
254
#define IO_BUF_SIZE 8192
255
 
256
typedef struct BufferedFile {
257
    uint8_t *buf_ptr;
258
    uint8_t *buf_end;
259
    int fd;
260
    int line_num;    /* current line number - here to simplify code */
261
    int ifndef_macro;  /* #ifndef macro / #endif search */
262
    int ifndef_macro_saved; /* saved ifndef_macro */
263
    int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
264
    char inc_type;          /* type of include */
265
    char inc_filename[512]; /* filename specified by the user */
266
    char filename[1024];    /* current filename - here to simplify code */
267
    unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
268
} BufferedFile;
269
 
270
#define CH_EOB   '\\'       /* end of buffer or '\0' char in file */
271
#define CH_EOF   (-1)   /* end of file */
272
 
273
/* parsing state (used to save parser state to reparse part of the
274
   source several times) */
275
typedef struct ParseState {
276
    int *macro_ptr;
277
    int line_num;
278
    int tok;
279
    CValue tokc;
280
} ParseState;
281
 
282
/* used to record tokens */
283
typedef struct TokenString {
284
    int *str;
285
    int len;
286
    int allocated_len;
287
    int last_line_num;
288
} TokenString;
289
 
290
/* include file cache, used to find files faster and also to eliminate
291
   inclusion if the include file is protected by #ifndef ... #endif */
292
typedef struct CachedInclude {
293
    int ifndef_macro;
294
    int hash_next; /* -1 if none */
295
    char type; /* '"' or '>' to give include type */
296
    char filename[1]; /* path specified in #include */
297
} CachedInclude;
298
 
299
#define CACHED_INCLUDES_HASH_SIZE 512
300
 
301
/* parser */
302
static struct BufferedFile *file;
303
static int ch, tok;
304
static CValue tokc;
305
static CString tokcstr; /* current parsed string, if any */
306
/* additional informations about token */
307
static int tok_flags;
308
#define TOK_FLAG_BOL   0x0001 /* beginning of line before */
309
#define TOK_FLAG_BOF   0x0002 /* beginning of file before */
310
#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
311
 
312
static int *macro_ptr, *macro_ptr_allocated;
313
static int *unget_saved_macro_ptr;
314
static int unget_saved_buffer[TOK_MAX_SIZE + 1];
315
static int unget_buffer_enabled;
316
static int parse_flags;
317
#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
318
#define PARSE_FLAG_TOK_NUM    0x0002 /* return numbers instead of TOK_PPNUM */
319
#define PARSE_FLAG_LINEFEED   0x0004 /* line feed is returned as a
320
                                        token. line feed is also
321
                                        returned at eof */
322
#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
323
 
324
static Section *text_section, *data_section, *bss_section; /* predefined sections */
325
static Section *cur_text_section; /* current section where function code is
326
                              generated */
327
#ifdef CONFIG_TCC_ASM
328
static Section *last_text_section; /* to handle .previous asm directive */
329
#endif
330
/* bound check related sections */
331
static Section *bounds_section; /* contains global data bound description */
332
static Section *lbounds_section; /* contains local data bound description */
333
/* symbol sections */
334
static Section *symtab_section, *strtab_section;
335
 
336
/* debug sections */
337
static Section *stab_section, *stabstr_section;
338
 
339
/* loc : local variable index
340
   ind : output code index
341
   rsym: return symbol
342
   anon_sym: anonymous symbol index
343
*/
344
static int rsym, anon_sym, ind, loc;
345
/* expression generation modifiers */
346
static int const_wanted; /* true if constant wanted */
347
static int nocode_wanted; /* true if no code generation wanted for an expression */
348
static int global_expr;  /* true if compound literals must be allocated
349
                            globally (used during initializers parsing */
350
static CType func_vt; /* current function return type (used by return
351
                         instruction) */
352
static int func_vc;
353
static int last_line_num, last_ind, func_ind; /* debug last line number and pc */
354
static int tok_ident;
355
static TokenSym **table_ident;
356
static TokenSym *hash_ident[TOK_HASH_SIZE];
357
static char token_buf[STRING_MAX_SIZE + 1];
358
static char *funcname;
359
static Sym *global_stack, *local_stack;
360
static Sym *define_stack;
361
static Sym *global_label_stack, *local_label_stack;
362
/* symbol allocator */
363
#define SYM_POOL_NB (8192 / sizeof(Sym))
364
static Sym *sym_free_first;
365
 
366
static SValue vstack[VSTACK_SIZE], *vtop;
367
/* some predefined types */
368
static CType char_pointer_type, func_old_type, int_type;
369
/* true if isid(c) || isnum(c) */
370
static unsigned char isidnum_table[256];
371
 
372
/* compile with debug symbol (and use them if error during execution) */
373
static int do_debug = 0;
374
 
375
/* compile with built-in memory and bounds checker */
376
static int do_bounds_check = 0;
377
 
378
/* display benchmark infos */
379
#if !defined(LIBTCC)
380
static int do_bench = 0;
381
#endif
382
static int total_lines;
383
static int total_bytes;
384
 
385
/* use GNU C extensions */
386
static int gnu_ext = 1;
387
 
388
/* use Tiny C extensions */
389
static int tcc_ext = 1;
390
 
391
/* max number of callers shown if error */
392
static int num_callers = 6;
393
static const char **rt_bound_error_msg;
394
 
395
/* XXX: get rid of this ASAP */
396
static struct TCCState *tcc_state;
397
 
398
/* give the path of the tcc libraries */
399
static const char *tcc_lib_path = CONFIG_TCCDIR;
400
 
401
struct TCCState {
402
    int output_type;
403
 
404
    BufferedFile **include_stack_ptr;
405
    int *ifdef_stack_ptr;
406
 
407
    /* include file handling */
408
    char **include_paths;
409
    int nb_include_paths;
410
    char **sysinclude_paths;
411
    int nb_sysinclude_paths;
412
    CachedInclude **cached_includes;
413
    int nb_cached_includes;
414
 
415
    char **library_paths;
416
    int nb_library_paths;
417
 
418
    /* array of all loaded dlls (including those referenced by loaded
419
       dlls) */
420
    DLLReference **loaded_dlls;
421
    int nb_loaded_dlls;
422
 
423
    /* sections */
424
    Section **sections;
425
    int nb_sections; /* number of sections, including first dummy section */
426
 
427
    /* got handling */
428
    Section *got;
429
    Section *plt;
430
    unsigned long *got_offsets;
431
    int nb_got_offsets;
432
    /* give the correspondance from symtab indexes to dynsym indexes */
433
    int *symtab_to_dynsym;
434
 
435
    /* temporary dynamic symbol sections (for dll loading) */
436
    Section *dynsymtab_section;
437
    /* exported dynamic symbol section */
438
    Section *dynsym;
439
 
440
    int nostdinc; /* if true, no standard headers are added */
441
    int nostdlib; /* if true, no standard libraries are added */
442
 
443
    int nocommon; /* if true, do not use common symbols for .bss data */
444
 
445
    /* if true, static linking is performed */
446
    int static_link;
447
 
448
    /* if true, all symbols are exported */
449
    int rdynamic;
450
 
451
    /* if true, only link in referenced objects from archive */
452
    int alacarte_link;
453
 
454
    /* address of text section */
455
    unsigned long text_addr;
456
    int has_text_addr;
457
 
458
    /* output format, see TCC_OUTPUT_FORMAT_xxx */
459
    int output_format;
460
 
461
    /* C language options */
462
    int char_is_unsigned;
463
    int leading_underscore;
464
 
465
    /* warning switches */
466
    int warn_write_strings;
467
    int warn_unsupported;
468
    int warn_error;
469
    int warn_none;
470
    int warn_implicit_function_declaration;
471
 
472
    /* error handling */
473
    void *error_opaque;
474
    void (*error_func)(void *opaque, const char *msg);
475
    int error_set_jmp_enabled;
476
    jmp_buf error_jmp_buf;
477
    int nb_errors;
478
 
479
    /* tiny assembler state */
480
    Sym *asm_labels;
481
 
482
    /* see include_stack_ptr */
483
    BufferedFile *include_stack[INCLUDE_STACK_SIZE];
484
 
485
    /* see ifdef_stack_ptr */
486
    int ifdef_stack[IFDEF_STACK_SIZE];
487
 
488
    /* see cached_includes */
489
    int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE];
490
 
491
    /* pack stack */
492
    int pack_stack[PACK_STACK_SIZE];
493
    int *pack_stack_ptr;
494
};
495
 
496
/* The current value can be: */
497
#define VT_VALMASK   0x00ff
498
#define VT_CONST     0x00f0  /* constant in vc
499
                              (must be first non register value) */
500
#define VT_LLOCAL    0x00f1  /* lvalue, offset on stack */
501
#define VT_LOCAL     0x00f2  /* offset on stack */
502
#define VT_CMP       0x00f3  /* the value is stored in processor flags (in vc) */
503
#define VT_JMP       0x00f4  /* value is the consequence of jmp true (even) */
504
#define VT_JMPI      0x00f5  /* value is the consequence of jmp false (odd) */
505
#define VT_LVAL      0x0100  /* var is an lvalue */
506
#define VT_SYM       0x0200  /* a symbol value is added */
507
#define VT_MUSTCAST  0x0400  /* value must be casted to be correct (used for
508
                                char/short stored in integer registers) */
509
#define VT_MUSTBOUND 0x0800  /* bound checking must be done before
510
                                dereferencing value */
511
#define VT_BOUNDED   0x8000  /* value is bounded. The address of the
512
                                bounding function call point is in vc */
513
#define VT_LVAL_BYTE     0x1000  /* lvalue is a byte */
514
#define VT_LVAL_SHORT    0x2000  /* lvalue is a short */
515
#define VT_LVAL_UNSIGNED 0x4000  /* lvalue is unsigned */
516
#define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
517
 
518
/* types */
519
#define VT_INT        0  /* integer type */
520
#define VT_BYTE       1  /* signed byte type */
521
#define VT_SHORT      2  /* short type */
522
#define VT_VOID       3  /* void type */
523
#define VT_PTR        4  /* pointer */
524
#define VT_ENUM       5  /* enum definition */
525
#define VT_FUNC       6  /* function type */
526
#define VT_STRUCT     7  /* struct/union definition */
527
#define VT_FLOAT      8  /* IEEE float */
528
#define VT_DOUBLE     9  /* IEEE double */
529
#define VT_LDOUBLE   10  /* IEEE long double */
530
#define VT_BOOL      11  /* ISOC99 boolean type */
531
#define VT_LLONG     12  /* 64 bit integer */
532
#define VT_LONG      13  /* long integer (NEVER USED as type, only
533
                            during parsing) */
534
#define VT_BTYPE      0x000f /* mask for basic type */
535
#define VT_UNSIGNED   0x0010  /* unsigned type */
536
#define VT_ARRAY      0x0020  /* array type (also has VT_PTR) */
537
#define VT_BITFIELD   0x0040  /* bitfield modifier */
538
#define VT_CONSTANT   0x0800  /* const modifier */
539
#define VT_VOLATILE   0x1000  /* volatile modifier */
540
#define VT_SIGNED     0x2000  /* signed type */
541
 
542
/* storage */
543
#define VT_EXTERN  0x00000080  /* extern definition */
544
#define VT_STATIC  0x00000100  /* static variable */
545
#define VT_TYPEDEF 0x00000200  /* typedef definition */
546
#define VT_INLINE  0x00000400  /* inline definition */
547
 
548
#define VT_STRUCT_SHIFT 16   /* shift for bitfield shift values */
549
 
550
/* type mask (except storage) */
551
#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
552
#define VT_TYPE    (~(VT_STORAGE))
553
 
554
/* token values */
555
 
556
/* warning: the following compare tokens depend on i386 asm code */
557
#define TOK_ULT 0x92
558
#define TOK_UGE 0x93
559
#define TOK_EQ  0x94
560
#define TOK_NE  0x95
561
#define TOK_ULE 0x96
562
#define TOK_UGT 0x97
563
#define TOK_LT  0x9c
564
#define TOK_GE  0x9d
565
#define TOK_LE  0x9e
566
#define TOK_GT  0x9f
567
 
568
#define TOK_LAND  0xa0
569
#define TOK_LOR   0xa1
570
 
571
#define TOK_DEC   0xa2
572
#define TOK_MID   0xa3 /* inc/dec, to void constant */
573
#define TOK_INC   0xa4
574
#define TOK_UDIV  0xb0 /* unsigned division */
575
#define TOK_UMOD  0xb1 /* unsigned modulo */
576
#define TOK_PDIV  0xb2 /* fast division with undefined rounding for pointers */
577
#define TOK_CINT   0xb3 /* number in tokc */
578
#define TOK_CCHAR 0xb4 /* char constant in tokc */
579
#define TOK_STR   0xb5 /* pointer to string in tokc */
580
#define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
581
#define TOK_LCHAR    0xb7
582
#define TOK_LSTR     0xb8
583
#define TOK_CFLOAT   0xb9 /* float constant */
584
#define TOK_LINENUM  0xba /* line number info */
585
#define TOK_CDOUBLE  0xc0 /* double constant */
586
#define TOK_CLDOUBLE 0xc1 /* long double constant */
587
#define TOK_UMULL    0xc2 /* unsigned 32x32 -> 64 mul */
588
#define TOK_ADDC1    0xc3 /* add with carry generation */
589
#define TOK_ADDC2    0xc4 /* add with carry use */
590
#define TOK_SUBC1    0xc5 /* add with carry generation */
591
#define TOK_SUBC2    0xc6 /* add with carry use */
592
#define TOK_CUINT    0xc8 /* unsigned int constant */
593
#define TOK_CLLONG   0xc9 /* long long constant */
594
#define TOK_CULLONG  0xca /* unsigned long long constant */
595
#define TOK_ARROW    0xcb
596
#define TOK_DOTS     0xcc /* three dots */
597
#define TOK_SHR      0xcd /* unsigned shift right */
598
#define TOK_PPNUM    0xce /* preprocessor number */
599
 
600
#define TOK_SHL   0x01 /* shift left */
601
#define TOK_SAR   0x02 /* signed shift right */
602
 
603
/* assignement operators : normal operator or 0x80 */
604
#define TOK_A_MOD 0xa5
605
#define TOK_A_AND 0xa6
606
#define TOK_A_MUL 0xaa
607
#define TOK_A_ADD 0xab
608
#define TOK_A_SUB 0xad
609
#define TOK_A_DIV 0xaf
610
#define TOK_A_XOR 0xde
611
#define TOK_A_OR  0xfc
612
#define TOK_A_SHL 0x81
613
#define TOK_A_SAR 0x82
614
 
615
#ifndef offsetof
616
#define offsetof(type, field) ((size_t) &((type *)0)->field)
617
#endif
618
 
619
#ifndef countof
620
#define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
621
#endif
622
 
623
/* WARNING: the content of this string encodes token numbers */
624
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";
625
 
626
#define TOK_EOF       (-1)  /* end of file */
627
#define TOK_LINEFEED  10    /* line feed */
628
 
629
/* all identificators and strings have token above that */
630
#define TOK_IDENT 256
631
 
632
/* only used for i386 asm opcodes definitions */
633
#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
634
 
635
#define DEF_BWL(x) \
636
 DEF(TOK_ASM_ ## x ## b, #x "b") \
637
 DEF(TOK_ASM_ ## x ## w, #x "w") \
638
 DEF(TOK_ASM_ ## x ## l, #x "l") \
639
 DEF(TOK_ASM_ ## x, #x)
640
 
641
#define DEF_WL(x) \
642
 DEF(TOK_ASM_ ## x ## w, #x "w") \
643
 DEF(TOK_ASM_ ## x ## l, #x "l") \
644
 DEF(TOK_ASM_ ## x, #x)
645
 
646
#define DEF_FP1(x) \
647
 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
648
 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
649
 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
650
 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
651
 
652
#define DEF_FP(x) \
653
 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
654
 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
655
 DEF_FP1(x)
656
 
657
#define DEF_ASMTEST(x) \
658
 DEF_ASM(x ## o) \
659
 DEF_ASM(x ## no) \
660
 DEF_ASM(x ## b) \
661
 DEF_ASM(x ## c) \
662
 DEF_ASM(x ## nae) \
663
 DEF_ASM(x ## nb) \
664
 DEF_ASM(x ## nc) \
665
 DEF_ASM(x ## ae) \
666
 DEF_ASM(x ## e) \
667
 DEF_ASM(x ## z) \
668
 DEF_ASM(x ## ne) \
669
 DEF_ASM(x ## nz) \
670
 DEF_ASM(x ## be) \
671
 DEF_ASM(x ## na) \
672
 DEF_ASM(x ## nbe) \
673
 DEF_ASM(x ## a) \
674
 DEF_ASM(x ## s) \
675
 DEF_ASM(x ## ns) \
676
 DEF_ASM(x ## p) \
677
 DEF_ASM(x ## pe) \
678
 DEF_ASM(x ## np) \
679
 DEF_ASM(x ## po) \
680
 DEF_ASM(x ## l) \
681
 DEF_ASM(x ## nge) \
682
 DEF_ASM(x ## nl) \
683
 DEF_ASM(x ## ge) \
684
 DEF_ASM(x ## le) \
685
 DEF_ASM(x ## ng) \
686
 DEF_ASM(x ## nle) \
687
 DEF_ASM(x ## g)
688
 
689
#define TOK_ASM_int TOK_INT
690
 
691
enum tcc_token {
692
    TOK_LAST = TOK_IDENT - 1,
693
#define DEF(id, str) id,
694
#include "tcctok.h"
695
#undef DEF
696
};
697
 
698
static const char tcc_keywords[] =
699
#define DEF(id, str) str "\0"
700
#include "tcctok.h"
701
#undef DEF
702
;
703
 
704
#define TOK_UIDENT TOK_DEFINE
705
 
706
#ifdef WIN32
707
int __stdcall GetModuleFileNameA(void *, char *, int);
708
void *__stdcall GetProcAddress(void *, const char *);
709
void *__stdcall GetModuleHandleA(const char *);
710
void *__stdcall LoadLibraryA(const char *);
711
int __stdcall FreeConsole(void);
712
 
713
#define snprintf _snprintf
714
#define vsnprintf _vsnprintf
715
#ifndef __GNUC__
716
  #define strtold (long double)strtod
717
  #define strtof (float)strtod
718
  #define strtoll (long long)strtol
719
#endif
720
#elif defined(TCC_UCLIBC) || defined(__FreeBSD__)
721
/* currently incorrect */
722
long double strtold(const char *nptr, char **endptr)
723
{
724
    return (long double)strtod(nptr, endptr);
725
}
726
float strtof(const char *nptr, char **endptr)
727
{
728
    return (float)strtod(nptr, endptr);
729
}
730
#else
731
/* XXX: need to define this to use them in non ISOC99 context */
732
extern float strtof (const char *__nptr, char **__endptr);
733
extern long double strtold (const char *__nptr, char **__endptr);
734
#endif
735
 
736
static char *pstrcpy(char *buf, int buf_size, const char *s);
737
static char *pstrcat(char *buf, int buf_size, const char *s);
738
static const char *tcc_basename(const char *name);
739
 
740
static void next(void);
741
static void next_nomacro(void);
742
static void parse_expr_type(CType *type);
743
static void expr_type(CType *type);
744
static void unary_type(CType *type);
745
static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
746
                  int case_reg, int is_expr);
747
static int expr_const(void);
748
static void expr_eq(void);
749
static void gexpr(void);
750
static void gen_inline_functions(void);
751
static void decl(int l);
752
static void decl_initializer(CType *type, Section *sec, unsigned long c,
753
                             int first, int size_only);
754
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
755
                                   int has_init, int v, int scope);
756
int gv(int rc);
757
void gv2(int rc1, int rc2);
758
void move_reg(int r, int s);
759
void save_regs(int n);
760
void save_reg(int r);
761
void vpop(void);
762
void vswap(void);
763
void vdup(void);
764
int get_reg(int rc);
765
int get_reg_ex(int rc,int rc2);
766
 
767
struct macro_level {
768
    struct macro_level *prev;
769
    int *p;
770
};
771
 
772
static void macro_subst(TokenString *tok_str, Sym **nested_list,
773
                        const int *macro_str, struct macro_level **can_read_stream);
774
void gen_op(int op);
775
void force_charshort_cast(int t);
776
static void gen_cast(CType *type);
777
void vstore(void);
778
static Sym *sym_find(int v);
779
static Sym *sym_push(int v, CType *type, int r, int c);
780
 
781
/* type handling */
782
static int type_size(CType *type, int *a);
783
static inline CType *pointed_type(CType *type);
784
static int pointed_size(CType *type);
785
static int lvalue_type(int t);
786
static int parse_btype(CType *type, AttributeDef *ad);
787
static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
788
static int is_compatible_types(CType *type1, CType *type2);
789
 
790
int ieee_finite(double d);
791
void error(const char *fmt, ...);
792
void vpushi(int v);
793
void vrott(int n);
794
void vnrott(int n);
795
void lexpand_nr(void);
796
static void vpush_global_sym(CType *type, int v);
797
void vset(CType *type, int r, int v);
798
void type_to_str(char *buf, int buf_size,
799
                 CType *type, const char *varstr);
800
char *get_tok_str(int v, CValue *cv);
801
static Sym *get_sym_ref(CType *type, Section *sec,
802
                        unsigned long offset, unsigned long size);
803
static Sym *external_global_sym(int v, CType *type, int r);
804
 
805
/* section generation */
806
static void section_realloc(Section *sec, unsigned long new_size);
807
static void *section_ptr_add(Section *sec, unsigned long size);
808
static void put_extern_sym(Sym *sym, Section *section,
809
                           unsigned long value, unsigned long size);
810
static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
811
static int put_elf_str(Section *s, const char *sym);
812
static int put_elf_sym(Section *s,
813
                       unsigned long value, unsigned long size,
814
                       int info, int other, int shndx, const char *name);
815
static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
816
                       int info, int other, int sh_num, const char *name);
817
static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
818
                          int type, int symbol);
819
static void put_stabs(const char *str, int type, int other, int desc,
820
                      unsigned long value);
821
static void put_stabs_r(const char *str, int type, int other, int desc,
822
                        unsigned long value, Section *sec, int sym_index);
823
static void put_stabn(int type, int other, int desc, int value);
824
static void put_stabd(int type, int other, int desc);
825
static int tcc_add_dll(TCCState *s, const char *filename, int flags);
826
 
827
#define AFF_PRINT_ERROR     0x0001 /* print error if file not found */
828
#define AFF_REFERENCED_DLL  0x0002 /* load a referenced dll from another dll */
829
static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
830
 
831
/* tcccoff.c */
832
int tcc_output_coff(TCCState *s1, FILE *f);
833
 
834
/* tccpe.c */
835
void *resolve_sym(TCCState *s1, const char *sym, int type);
836
int pe_load_def_file(struct TCCState *s1, FILE *fp);
837
void pe_setup_paths(struct TCCState *s1, int *p_output_type, const char **p_outfile, char *first_file);
838
unsigned long pe_add_runtime(struct TCCState *s1);
839
int tcc_output_pe(struct TCCState *s1, const char *filename);
840
 
841
/* tccasm.c */
842
 
843
#ifdef CONFIG_TCC_ASM
844
 
845
typedef struct ExprValue {
846
    uint32_t v;
847
    Sym *sym;
848
} ExprValue;
849
 
850
#define MAX_ASM_OPERANDS 30
851
 
852
typedef struct ASMOperand {
853
    int id; /* GCC 3 optionnal identifier (0 if number only supported */
854
    char *constraint;
855
    char asm_str[16]; /* computed asm string for operand */
856
    SValue *vt; /* C value of the expression */
857
    int ref_index; /* if >= 0, gives reference to a output constraint */
858
    int input_index; /* if >= 0, gives reference to an input constraint */
859
    int priority; /* priority, used to assign registers */
860
    int reg; /* if >= 0, register number used for this operand */
861
    int is_llong; /* true if double register value */
862
    int is_memory; /* true if memory operand */
863
    int is_rw;     /* for '+' modifier */
864
} ASMOperand;
865
 
866
static void asm_expr(TCCState *s1, ExprValue *pe);
867
static int asm_int_expr(TCCState *s1);
868
static int find_constraint(ASMOperand *operands, int nb_operands,
869
                           const char *name, const char **pp);
870
 
871
static int tcc_assemble(TCCState *s1, int do_preprocess);
872
 
873
#endif
874
 
875
static void asm_instr(void);
876
static void asm_global_instr(void);
877
 
878
/* true if float/double/long double type */
879
static inline int is_float(int t)
880
{
881
    int bt;
882
    bt = t & VT_BTYPE;
883
    return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
884
}
885
 
886
#ifdef TCC_TARGET_I386
887
#include "i386-gen.c"
888
#endif
889
 
890
#ifdef TCC_TARGET_ARM
891
#include "arm-gen.c"
892
#endif
893
 
894
#ifdef TCC_TARGET_C67
895
#include "c67-gen.c"
896
#endif
897
 
898
#ifdef CONFIG_TCC_STATIC
899
 
900
#define RTLD_LAZY       0x001
901
#define RTLD_NOW        0x002
902
#define RTLD_GLOBAL     0x100
903
#define RTLD_DEFAULT    NULL
904
 
905
/* dummy function for profiling */
906
void *dlopen(const char *filename, int flag)
907
{
908
    return NULL;
909
}
910
 
911
const char *dlerror(void)
912
{
913
    return "error";
914
}
915
 
916
typedef struct TCCSyms {
917
    char *str;
918
    void *ptr;
919
} TCCSyms;
920
 
921
#define TCCSYM(a) { #a, &a, },
922
 
923
/* add the symbol you want here if no dynamic linking is done */
924
static TCCSyms tcc_syms[] = {
925
#if !defined(CONFIG_TCCBOOT)
926
    TCCSYM(printf)
927
    TCCSYM(fprintf)
928
    TCCSYM(fopen)
929
    TCCSYM(fclose)
930
#endif
931
    { NULL, NULL },
932
};
933
 
934
void *resolve_sym(TCCState *s1, const char *symbol, int type)
935
{
936
    TCCSyms *p;
937
    p = tcc_syms;
938
    while (p->str != NULL) {
939
        if (!strcmp(p->str, symbol))
940
            return p->ptr;
941
        p++;
942
    }
943
    return NULL;
944
}
945
 
946
#elif !defined(WIN32)
947
 
948
#include 
949
 
950
void *resolve_sym(TCCState *s1, const char *sym, int type)
951
{
952
    return dlsym(RTLD_DEFAULT, sym);
953
}
954
 
955
#endif
956
 
957
/********************************************************/
958
 
959
/* we use our own 'finite' function to avoid potential problems with
960
   non standard math libs */
961
/* XXX: endianness dependent */
962
int ieee_finite(double d)
963
{
964
    int *p = (int *)&d;
965
    return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
966
}
967
 
968
/* copy a string and truncate it. */
969
static char *pstrcpy(char *buf, int buf_size, const char *s)
970
{
971
    char *q, *q_end;
972
    int c;
973
 
974
    if (buf_size > 0) {
975
        q = buf;
976
        q_end = buf + buf_size - 1;
977
        while (q < q_end) {
978
            c = *s++;
979
            if (c == '\0')
980
                break;
981
            *q++ = c;
982
        }
983
        *q = '\0';
984
    }
985
    return buf;
986
}
987
 
988
/* strcat and truncate. */
989
static char *pstrcat(char *buf, int buf_size, const char *s)
990
{
991
    int len;
992
    len = strlen(buf);
993
    if (len < buf_size)
994
        pstrcpy(buf + len, buf_size - len, s);
995
    return buf;
996
}
997
 
998
static int strstart(const char *str, const char *val, const char **ptr)
999
{
1000
    const char *p, *q;
1001
    p = str;
1002
    q = val;
1003
    while (*q != '\0') {
1004
        if (*p != *q)
1005
            return 0;
1006
        p++;
1007
        q++;
1008
    }
1009
    if (ptr)
1010
        *ptr = p;
1011
    return 1;
1012
}
1013
 
1014
/* memory management */
1015
#ifdef MEM_DEBUG
1016
int mem_cur_size;
1017
int mem_max_size;
1018
#endif
1019
 
1020
static inline void tcc_free(void *ptr)
1021
{
1022
#ifdef MEM_DEBUG
1023
    mem_cur_size -= malloc_usable_size(ptr);
1024
#endif
1025
    free(ptr);
1026
}
1027
 
1028
static void *tcc_malloc(unsigned long size)
1029
{
1030
    void *ptr;
1031
    ptr = malloc(size);
1032
    if (!ptr && size)
1033
        error("memory full");
1034
#ifdef MEM_DEBUG
1035
    mem_cur_size += malloc_usable_size(ptr);
1036
    if (mem_cur_size > mem_max_size)
1037
        mem_max_size = mem_cur_size;
1038
#endif
1039
    return ptr;
1040
}
1041
 
1042
static void *tcc_mallocz(unsigned long size)
1043
{
1044
    void *ptr;
1045
    ptr = tcc_malloc(size);
1046
    memset(ptr, 0, size);
1047
    return ptr;
1048
}
1049
 
1050
static inline void *tcc_realloc(void *ptr, unsigned long size)
1051
{
1052
    void *ptr1;
1053
#ifdef MEM_DEBUG
1054
    mem_cur_size -= malloc_usable_size(ptr);
1055
#endif
1056
    ptr1 = realloc(ptr, size);
1057
#ifdef MEM_DEBUG
1058
    /* NOTE: count not correct if alloc error, but not critical */
1059
    mem_cur_size += malloc_usable_size(ptr1);
1060
    if (mem_cur_size > mem_max_size)
1061
        mem_max_size = mem_cur_size;
1062
#endif
1063
    return ptr1;
1064
}
1065
 
1066
static char *tcc_strdup(const char *str)
1067
{
1068
    char *ptr;
1069
    ptr = tcc_malloc(strlen(str) + 1);
1070
    strcpy(ptr, str);
1071
    return ptr;
1072
}
1073
 
1074
#define free(p) use_tcc_free(p)
1075
#define malloc(s) use_tcc_malloc(s)
1076
#define realloc(p, s) use_tcc_realloc(p, s)
1077
 
1078
static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
1079
{
1080
    int nb, nb_alloc;
1081
    void **pp;
1082
 
1083
    nb = *nb_ptr;
1084
    pp = *ptab;
1085
    /* every power of two we double array size */
1086
    if ((nb & (nb - 1)) == 0) {
1087
        if (!nb)
1088
            nb_alloc = 1;
1089
        else
1090
            nb_alloc = nb * 2;
1091
        pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
1092
        if (!pp)
1093
            error("memory full");
1094
        *ptab = pp;
1095
    }
1096
    pp[nb++] = data;
1097
    *nb_ptr = nb;
1098
}
1099
 
1100
/* symbol allocator */
1101
static Sym *__sym_malloc(void)
1102
{
1103
    Sym *sym_pool, *sym, *last_sym;
1104
    int i;
1105
 
1106
    sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
1107
 
1108
    last_sym = sym_free_first;
1109
    sym = sym_pool;
1110
    for(i = 0; i < SYM_POOL_NB; i++) {
1111
        sym->next = last_sym;
1112
        last_sym = sym;
1113
        sym++;
1114
    }
1115
    sym_free_first = last_sym;
1116
    return last_sym;
1117
}
1118
 
1119
static inline Sym *sym_malloc(void)
1120
{
1121
    Sym *sym;
1122
    sym = sym_free_first;
1123
    if (!sym)
1124
        sym = __sym_malloc();
1125
    sym_free_first = sym->next;
1126
    return sym;
1127
}
1128
 
1129
static inline void sym_free(Sym *sym)
1130
{
1131
    sym->next = sym_free_first;
1132
    sym_free_first = sym;
1133
}
1134
 
1135
Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
1136
{
1137
    Section *sec;
1138
 
1139
    sec = tcc_mallocz(sizeof(Section) + strlen(name));
1140
    strcpy(sec->name, name);
1141
    sec->sh_type = sh_type;
1142
    sec->sh_flags = sh_flags;
1143
    switch(sh_type) {
1144
    case SHT_HASH:
1145
    case SHT_REL:
1146
    case SHT_DYNSYM:
1147
    case SHT_SYMTAB:
1148
    case SHT_DYNAMIC:
1149
        sec->sh_addralign = 4;
1150
        break;
1151
    case SHT_STRTAB:
1152
        sec->sh_addralign = 1;
1153
        break;
1154
    default:
1155
        sec->sh_addralign = 32; /* default conservative alignment */
1156
        break;
1157
    }
1158
 
1159
    /* only add section if not private */
1160
    if (!(sh_flags & SHF_PRIVATE)) {
1161
        sec->sh_num = s1->nb_sections;
1162
        dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
1163
    }
1164
    return sec;
1165
}
1166
 
1167
static void free_section(Section *s)
1168
{
1169
    tcc_free(s->data);
1170
    tcc_free(s);
1171
}
1172
 
1173
/* realloc section and set its content to zero */
1174
static void section_realloc(Section *sec, unsigned long new_size)
1175
{
1176
    unsigned long size;
1177
    unsigned char *data;
1178
 
1179
    size = sec->data_allocated;
1180
    if (size == 0)
1181
        size = 1;
1182
    while (size < new_size)
1183
        size = size * 2;
1184
    data = tcc_realloc(sec->data, size);
1185
    if (!data)
1186
        error("memory full");
1187
    memset(data + sec->data_allocated, 0, size - sec->data_allocated);
1188
    sec->data = data;
1189
    sec->data_allocated = size;
1190
}
1191
 
1192
/* reserve at least 'size' bytes in section 'sec' from
1193
   sec->data_offset. */
1194
static void *section_ptr_add(Section *sec, unsigned long size)
1195
{
1196
    unsigned long offset, offset1;
1197
 
1198
    offset = sec->data_offset;
1199
    offset1 = offset + size;
1200
    if (offset1 > sec->data_allocated)
1201
        section_realloc(sec, offset1);
1202
    sec->data_offset = offset1;
1203
    return sec->data + offset;
1204
}
1205
 
1206
/* return a reference to a section, and create it if it does not
1207
   exists */
1208
Section *find_section(TCCState *s1, const char *name)
1209
{
1210
    Section *sec;
1211
    int i;
1212
    for(i = 1; i < s1->nb_sections; i++) {
1213
        sec = s1->sections[i];
1214
        if (!strcmp(name, sec->name))
1215
            return sec;
1216
    }
1217
    /* sections are created as PROGBITS */
1218
    return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
1219
}
1220
 
1221
#define SECTION_ABS ((void *)1)
1222
 
1223
/* update sym->c so that it points to an external symbol in section
1224
   'section' with value 'value' */
1225
static void put_extern_sym2(Sym *sym, Section *section,
1226
                            unsigned long value, unsigned long size,
1227
                            int can_add_underscore)
1228
{
1229
    int sym_type, sym_bind, sh_num, info;
1230
    Elf32_Sym *esym;
1231
    const char *name;
1232
    char buf1[256];
1233
 
1234
    if (section == NULL)
1235
        sh_num = SHN_UNDEF;
1236
    else if (section == SECTION_ABS)
1237
        sh_num = SHN_ABS;
1238
    else
1239
        sh_num = section->sh_num;
1240
    if (!sym->c) {
1241
        if ((sym->type.t & VT_BTYPE) == VT_FUNC)
1242
            sym_type = STT_FUNC;
1243
        else
1244
            sym_type = STT_OBJECT;
1245
        if (sym->type.t & VT_STATIC)
1246
            sym_bind = STB_LOCAL;
1247
        else
1248
            sym_bind = STB_GLOBAL;
1249
 
1250
        name = get_tok_str(sym->v, NULL);
1251
#ifdef CONFIG_TCC_BCHECK
1252
        if (do_bounds_check) {
1253
            char buf[32];
1254
 
1255
            /* XXX: avoid doing that for statics ? */
1256
            /* if bound checking is activated, we change some function
1257
               names by adding the "__bound" prefix */
1258
            switch(sym->v) {
1259
#if 0
1260
            /* XXX: we rely only on malloc hooks */
1261
            case TOK_malloc:
1262
            case TOK_free:
1263
            case TOK_realloc:
1264
            case TOK_memalign:
1265
            case TOK_calloc:
1266
#endif
1267
            case TOK_memcpy:
1268
            case TOK_memmove:
1269
            case TOK_memset:
1270
            case TOK_strlen:
1271
            case TOK_strcpy:
1272
                strcpy(buf, "__bound_");
1273
                strcat(buf, name);
1274
                name = buf;
1275
                break;
1276
            }
1277
        }
1278
#endif
1279
        if (tcc_state->leading_underscore && can_add_underscore) {
1280
            buf1[0] = '_';
1281
            pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
1282
            name = buf1;
1283
        }
1284
        info = ELF32_ST_INFO(sym_bind, sym_type);
1285
        sym->c = add_elf_sym(symtab_section, value, size, info, 0, sh_num, name);
1286
    } else {
1287
        esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
1288
        esym->st_value = value;
1289
        esym->st_size = size;
1290
        esym->st_shndx = sh_num;
1291
    }
1292
}
1293
 
1294
static void put_extern_sym(Sym *sym, Section *section,
1295
                           unsigned long value, unsigned long size)
1296
{
1297
    put_extern_sym2(sym, section, value, size, 1);
1298
}
1299
 
1300
/* add a new relocation entry to symbol 'sym' in section 's' */
1301
static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
1302
{
1303
    if (!sym->c)
1304
        put_extern_sym(sym, NULL, 0, 0);
1305
    /* now we can add ELF relocation info */
1306
    put_elf_reloc(symtab_section, s, offset, type, sym->c);
1307
}
1308
 
1309
static inline int isid(int c)
1310
{
1311
    return (c >= 'a' && c <= 'z') ||
1312
        (c >= 'A' && c <= 'Z') ||
1313
        c == '_';
1314
}
1315
 
1316
static inline int isnum(int c)
1317
{
1318
    return c >= '0' && c <= '9';
1319
}
1320
 
1321
static inline int isoct(int c)
1322
{
1323
    return c >= '0' && c <= '7';
1324
}
1325
 
1326
static inline int toup(int c)
1327
{
1328
    if (c >= 'a' && c <= 'z')
1329
        return c - 'a' + 'A';
1330
    else
1331
        return c;
1332
}
1333
 
1334
static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
1335
{
1336
    int len;
1337
    len = strlen(buf);
1338
    vsnprintf(buf + len, buf_size - len, fmt, ap);
1339
}
1340
 
1341
static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
1342
{
1343
    va_list ap;
1344
    va_start(ap, fmt);
1345
    strcat_vprintf(buf, buf_size, fmt, ap);
1346
    va_end(ap);
1347
}
1348
 
1349
void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
1350
{
1351
    char buf[2048];
1352
    BufferedFile **f;
1353
 
1354
    buf[0] = '\0';
1355
    if (file) {
1356
        for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
1357
            strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
1358
                          (*f)->filename, (*f)->line_num);
1359
        if (file->line_num > 0) {
1360
            strcat_printf(buf, sizeof(buf),
1361
                          "%s:%d: ", file->filename, file->line_num);
1362
        } else {
1363
            strcat_printf(buf, sizeof(buf),
1364
                          "%s: ", file->filename);
1365
        }
1366
    } else {
1367
        strcat_printf(buf, sizeof(buf),
1368
                      "tcc: ");
1369
    }
1370
    if (is_warning)
1371
        strcat_printf(buf, sizeof(buf), "warning: ");
1372
    strcat_vprintf(buf, sizeof(buf), fmt, ap);
1373
 
1374
    if (!s1->error_func) {
1375
        /* default case: stderr */
1376
        fprintf(stderr, "%s\n", buf);
1377
    } else {
1378
        s1->error_func(s1->error_opaque, buf);
1379
    }
1380
    if (!is_warning || s1->warn_error)
1381
        s1->nb_errors++;
1382
}
1383
 
1384
#ifdef LIBTCC
1385
void tcc_set_error_func(TCCState *s, void *error_opaque,
1386
                        void (*error_func)(void *opaque, const char *msg))
1387
{
1388
    s->error_opaque = error_opaque;
1389
    s->error_func = error_func;
1390
}
1391
#endif
1392
 
1393
/* error without aborting current compilation */
1394
void error_noabort(const char *fmt, ...)
1395
{
1396
    TCCState *s1 = tcc_state;
1397
    va_list ap;
1398
 
1399
    va_start(ap, fmt);
1400
    error1(s1, 0, fmt, ap);
1401
    va_end(ap);
1402
}
1403
 
1404
void error(const char *fmt, ...)
1405
{
1406
    TCCState *s1 = tcc_state;
1407
    va_list ap;
1408
 
1409
    va_start(ap, fmt);
1410
    error1(s1, 0, fmt, ap);
1411
    va_end(ap);
1412
    /* better than nothing: in some cases, we accept to handle errors */
1413
    if (s1->error_set_jmp_enabled) {
1414
        longjmp(s1->error_jmp_buf, 1);
1415
    } else {
1416
        /* XXX: eliminate this someday */
1417
        exit(1);
1418
    }
1419
}
1420
 
1421
void expect(const char *msg)
1422
{
1423
    error("%s expected", msg);
1424
}
1425
 
1426
void warning(const char *fmt, ...)
1427
{
1428
    TCCState *s1 = tcc_state;
1429
    va_list ap;
1430
 
1431
    if (s1->warn_none)
1432
        return;
1433
 
1434
    va_start(ap, fmt);
1435
    error1(s1, 1, fmt, ap);
1436
    va_end(ap);
1437
}
1438
 
1439
void skip(int c)
1440
{
1441
    if (tok != c)
1442
        error("'%c' expected", c);
1443
    next();
1444
}
1445
 
1446
static void test_lvalue(void)
1447
{
1448
    if (!(vtop->r & VT_LVAL))
1449
        expect("lvalue");
1450
}
1451
 
1452
/* allocate a new token */
1453
static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
1454
{
1455
    TokenSym *ts, **ptable;
1456
    int i;
1457
 
1458
    if (tok_ident >= SYM_FIRST_ANOM)
1459
        error("memory full");
1460
 
1461
    /* expand token table if needed */
1462
    i = tok_ident - TOK_IDENT;
1463
    if ((i % TOK_ALLOC_INCR) == 0) {
1464
        ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
1465
        if (!ptable)
1466
            error("memory full");
1467
        table_ident = ptable;
1468
    }
1469
 
1470
    ts = tcc_malloc(sizeof(TokenSym) + len);
1471
    table_ident[i] = ts;
1472
    ts->tok = tok_ident++;
1473
    ts->sym_define = NULL;
1474
    ts->sym_label = NULL;
1475
    ts->sym_struct = NULL;
1476
    ts->sym_identifier = NULL;
1477
    ts->len = len;
1478
    ts->hash_next = NULL;
1479
    memcpy(ts->str, str, len);
1480
    ts->str[len] = '\0';
1481
    *pts = ts;
1482
    return ts;
1483
}
1484
 
1485
#define TOK_HASH_INIT 1
1486
#define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
1487
 
1488
/* find a token and add it if not found */
1489
static TokenSym *tok_alloc(const char *str, int len)
1490
{
1491
    TokenSym *ts, **pts;
1492
    int i;
1493
    unsigned int h;
1494
 
1495
    h = TOK_HASH_INIT;
1496
    for(i=0;i
1497
        h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
1498
    h &= (TOK_HASH_SIZE - 1);
1499
 
1500
    pts = &hash_ident[h];
1501
    for(;;) {
1502
        ts = *pts;
1503
        if (!ts)
1504
            break;
1505
        if (ts->len == len && !memcmp(ts->str, str, len))
1506
            return ts;
1507
        pts = &(ts->hash_next);
1508
    }
1509
    return tok_alloc_new(pts, str, len);
1510
}
1511
 
1512
/* CString handling */
1513
 
1514
static void cstr_realloc(CString *cstr, int new_size)
1515
{
1516
    int size;
1517
    void *data;
1518
 
1519
    size = cstr->size_allocated;
1520
    if (size == 0)
1521
        size = 8; /* no need to allocate a too small first string */
1522
    while (size < new_size)
1523
        size = size * 2;
1524
    data = tcc_realloc(cstr->data_allocated, size);
1525
    if (!data)
1526
        error("memory full");
1527
    cstr->data_allocated = data;
1528
    cstr->size_allocated = size;
1529
    cstr->data = data;
1530
}
1531
 
1532
/* add a byte */
1533
static inline void cstr_ccat(CString *cstr, int ch)
1534
{
1535
    int size;
1536
    size = cstr->size + 1;
1537
    if (size > cstr->size_allocated)
1538
        cstr_realloc(cstr, size);
1539
    ((unsigned char *)cstr->data)[size - 1] = ch;
1540
    cstr->size = size;
1541
}
1542
 
1543
static void cstr_cat(CString *cstr, const char *str)
1544
{
1545
    int c;
1546
    for(;;) {
1547
        c = *str;
1548
        if (c == '\0')
1549
            break;
1550
        cstr_ccat(cstr, c);
1551
        str++;
1552
    }
1553
}
1554
 
1555
/* add a wide char */
1556
static void cstr_wccat(CString *cstr, int ch)
1557
{
1558
    int size;
1559
    size = cstr->size + sizeof(int);
1560
    if (size > cstr->size_allocated)
1561
        cstr_realloc(cstr, size);
1562
    *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
1563
    cstr->size = size;
1564
}
1565
 
1566
static void cstr_new(CString *cstr)
1567
{
1568
    memset(cstr, 0, sizeof(CString));
1569
}
1570
 
1571
/* free string and reset it to NULL */
1572
static void cstr_free(CString *cstr)
1573
{
1574
    tcc_free(cstr->data_allocated);
1575
    cstr_new(cstr);
1576
}
1577
 
1578
#define cstr_reset(cstr) cstr_free(cstr)
1579
 
1580
/* XXX: unicode ? */
1581
static void add_char(CString *cstr, int c)
1582
{
1583
    if (c == '\'' || c == '\"' || c == '\\') {
1584
        /* XXX: could be more precise if char or string */
1585
        cstr_ccat(cstr, '\\');
1586
    }
1587
    if (c >= 32 && c <= 126) {
1588
        cstr_ccat(cstr, c);
1589
    } else {
1590
        cstr_ccat(cstr, '\\');
1591
        if (c == '\n') {
1592
            cstr_ccat(cstr, 'n');
1593
        } else {
1594
            cstr_ccat(cstr, '0' + ((c >> 6) & 7));
1595
            cstr_ccat(cstr, '0' + ((c >> 3) & 7));
1596
            cstr_ccat(cstr, '0' + (c & 7));
1597
        }
1598
    }
1599
}
1600
 
1601
/* XXX: buffer overflow */
1602
/* XXX: float tokens */
1603
char *get_tok_str(int v, CValue *cv)
1604
{
1605
    static char buf[STRING_MAX_SIZE + 1];
1606
    static CString cstr_buf;
1607
    CString *cstr;
1608
    unsigned char *q;
1609
    char *p;
1610
    int i, len;
1611
 
1612
    /* NOTE: to go faster, we give a fixed buffer for small strings */
1613
    cstr_reset(&cstr_buf);
1614
    cstr_buf.data = buf;
1615
    cstr_buf.size_allocated = sizeof(buf);
1616
    p = buf;
1617
 
1618
    switch(v) {
1619
    case TOK_CINT:
1620
    case TOK_CUINT:
1621
        /* XXX: not quite exact, but only useful for testing */
1622
        sprintf(p, "%u", cv->ui);
1623
        break;
1624
    case TOK_CLLONG:
1625
    case TOK_CULLONG:
1626
        /* XXX: not quite exact, but only useful for testing  */
1627
        sprintf(p, "%Lu", cv->ull);
1628
        break;
1629
    case TOK_CCHAR:
1630
    case TOK_LCHAR:
1631
        cstr_ccat(&cstr_buf, '\'');
1632
        add_char(&cstr_buf, cv->i);
1633
        cstr_ccat(&cstr_buf, '\'');
1634
        cstr_ccat(&cstr_buf, '\0');
1635
        break;
1636
    case TOK_PPNUM:
1637
        cstr = cv->cstr;
1638
        len = cstr->size - 1;
1639
        for(i=0;i
1640
            add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1641
        cstr_ccat(&cstr_buf, '\0');
1642
        break;
1643
    case TOK_STR:
1644
    case TOK_LSTR:
1645
        cstr = cv->cstr;
1646
        cstr_ccat(&cstr_buf, '\"');
1647
        if (v == TOK_STR) {
1648
            len = cstr->size - 1;
1649
            for(i=0;i
1650
                add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
1651
        } else {
1652
            len = (cstr->size / sizeof(int)) - 1;
1653
            for(i=0;i
1654
                add_char(&cstr_buf, ((int *)cstr->data)[i]);
1655
        }
1656
        cstr_ccat(&cstr_buf, '\"');
1657
        cstr_ccat(&cstr_buf, '\0');
1658
        break;
1659
    case TOK_LT:
1660
        v = '<';
1661
        goto addv;
1662
    case TOK_GT:
1663
        v = '>';
1664
        goto addv;
1665
    case TOK_A_SHL:
1666
        return strcpy(p, "<<=");
1667
    case TOK_A_SAR:
1668
        return strcpy(p, ">>=");
1669
    default:
1670
        if (v < TOK_IDENT) {
1671
            /* search in two bytes table */
1672
            q = tok_two_chars;
1673
            while (*q) {
1674
                if (q[2] == v) {
1675
                    *p++ = q[0];
1676
                    *p++ = q[1];
1677
                    *p = '\0';
1678
                    return buf;
1679
                }
1680
                q += 3;
1681
            }
1682
        addv:
1683
            *p++ = v;
1684
            *p = '\0';
1685
        } else if (v < tok_ident) {
1686
            return table_ident[v - TOK_IDENT]->str;
1687
        } else if (v >= SYM_FIRST_ANOM) {
1688
            /* special name for anonymous symbol */
1689
            sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
1690
        } else {
1691
            /* should never happen */
1692
            return NULL;
1693
        }
1694
        break;
1695
    }
1696
    return cstr_buf.data;
1697
}
1698
 
1699
/* push, without hashing */
1700
static Sym *sym_push2(Sym **ps, int v, int t, int c)
1701
{
1702
    Sym *s;
1703
    s = sym_malloc();
1704
    s->v = v;
1705
    s->type.t = t;
1706
    s->c = c;
1707
    s->next = NULL;
1708
    /* add in stack */
1709
    s->prev = *ps;
1710
    *ps = s;
1711
    return s;
1712
}
1713
 
1714
/* find a symbol and return its associated structure. 's' is the top
1715
   of the symbol stack */
1716
static Sym *sym_find2(Sym *s, int v)
1717
{
1718
    while (s) {
1719
        if (s->v == v)
1720
            return s;
1721
        s = s->prev;
1722
    }
1723
    return NULL;
1724
}
1725
 
1726
/* structure lookup */
1727
static inline Sym *struct_find(int v)
1728
{
1729
    v -= TOK_IDENT;
1730
    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1731
        return NULL;
1732
    return table_ident[v]->sym_struct;
1733
}
1734
 
1735
/* find an identifier */
1736
static inline Sym *sym_find(int v)
1737
{
1738
    v -= TOK_IDENT;
1739
    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
1740
        return NULL;
1741
    return table_ident[v]->sym_identifier;
1742
}
1743
 
1744
/* push a given symbol on the symbol stack */
1745
static Sym *sym_push(int v, CType *type, int r, int c)
1746
{
1747
    Sym *s, **ps;
1748
    TokenSym *ts;
1749
 
1750
    if (local_stack)
1751
        ps = &local_stack;
1752
    else
1753
        ps = &global_stack;
1754
    s = sym_push2(ps, v, type->t, c);
1755
    s->type.ref = type->ref;
1756
    s->r = r;
1757
    /* don't record fields or anonymous symbols */
1758
    /* XXX: simplify */
1759
    if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1760
        /* record symbol in token array */
1761
        ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1762
        if (v & SYM_STRUCT)
1763
            ps = &ts->sym_struct;
1764
        else
1765
            ps = &ts->sym_identifier;
1766
        s->prev_tok = *ps;
1767
        *ps = s;
1768
    }
1769
    return s;
1770
}
1771
 
1772
/* push a global identifier */
1773
static Sym *global_identifier_push(int v, int t, int c)
1774
{
1775
    Sym *s, **ps;
1776
    s = sym_push2(&global_stack, v, t, c);
1777
    /* don't record anonymous symbol */
1778
    if (v < SYM_FIRST_ANOM) {
1779
        ps = &table_ident[v - TOK_IDENT]->sym_identifier;
1780
        /* modify the top most local identifier, so that
1781
           sym_identifier will point to 's' when popped */
1782
        while (*ps != NULL)
1783
            ps = &(*ps)->prev_tok;
1784
        s->prev_tok = NULL;
1785
        *ps = s;
1786
    }
1787
    return s;
1788
}
1789
 
1790
/* pop symbols until top reaches 'b' */
1791
static void sym_pop(Sym **ptop, Sym *b)
1792
{
1793
    Sym *s, *ss, **ps;
1794
    TokenSym *ts;
1795
    int v;
1796
 
1797
    s = *ptop;
1798
    while(s != b) {
1799
        ss = s->prev;
1800
        v = s->v;
1801
        /* remove symbol in token array */
1802
        /* XXX: simplify */
1803
        if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
1804
            ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
1805
            if (v & SYM_STRUCT)
1806
                ps = &ts->sym_struct;
1807
            else
1808
                ps = &ts->sym_identifier;
1809
            *ps = s->prev_tok;
1810
        }
1811
        sym_free(s);
1812
        s = ss;
1813
    }
1814
    *ptop = b;
1815
}
1816
 
1817
/* I/O layer */
1818
 
1819
BufferedFile *tcc_open(TCCState *s1, const char *filename)
1820
{
1821
    int fd;
1822
    BufferedFile *bf;
1823
 
1824
    fd = open(filename, O_RDONLY | O_BINARY);
1825
    if (fd < 0)
1826
        return NULL;
1827
    bf = tcc_malloc(sizeof(BufferedFile));
1828
    if (!bf) {
1829
        close(fd);
1830
        return NULL;
1831
    }
1832
    bf->fd = fd;
1833
    bf->buf_ptr = bf->buffer;
1834
    bf->buf_end = bf->buffer;
1835
    bf->buffer[0] = CH_EOB; /* put eob symbol */
1836
    pstrcpy(bf->filename, sizeof(bf->filename), filename);
1837
    bf->line_num = 1;
1838
    bf->ifndef_macro = 0;
1839
    bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
1840
    //    printf("opening '%s'\n", filename);
1841
    return bf;
1842
}
1843
 
1844
void tcc_close(BufferedFile *bf)
1845
{
1846
    total_lines += bf->line_num;
1847
    close(bf->fd);
1848
    tcc_free(bf);
1849
}
1850
 
1851
/* fill input buffer and peek next char */
1852
static int tcc_peekc_slow(BufferedFile *bf)
1853
{
1854
    int len;
1855
    /* only tries to read if really end of buffer */
1856
    if (bf->buf_ptr >= bf->buf_end) {
1857
        if (bf->fd != -1) {
1858
#if defined(PARSE_DEBUG)
1859
            len = 8;
1860
#else
1861
            len = IO_BUF_SIZE;
1862
#endif
1863
            len = read(bf->fd, bf->buffer, len);
1864
            if (len < 0)
1865
                len = 0;
1866
        } else {
1867
            len = 0;
1868
        }
1869
        total_bytes += len;
1870
        bf->buf_ptr = bf->buffer;
1871
        bf->buf_end = bf->buffer + len;
1872
        *bf->buf_end = CH_EOB;
1873
    }
1874
    if (bf->buf_ptr < bf->buf_end) {
1875
        return bf->buf_ptr[0];
1876
    } else {
1877
        bf->buf_ptr = bf->buf_end;
1878
        return CH_EOF;
1879
    }
1880
}
1881
 
1882
/* return the current character, handling end of block if necessary
1883
   (but not stray) */
1884
static int handle_eob(void)
1885
{
1886
    return tcc_peekc_slow(file);
1887
}
1888
 
1889
/* read next char from current input file and handle end of input buffer */
1890
static inline void inp(void)
1891
{
1892
    ch = *(++(file->buf_ptr));
1893
    /* end of buffer/file handling */
1894
    if (ch == CH_EOB)
1895
        ch = handle_eob();
1896
}
1897
 
1898
/* handle '\[\r]\n' */
1899
static void handle_stray(void)
1900
{
1901
    while (ch == '\\') {
1902
        inp();
1903
        if (ch == '\n') {
1904
            file->line_num++;
1905
            inp();
1906
        } else if (ch == '\r') {
1907
            inp();
1908
            if (ch != '\n')
1909
                goto fail;
1910
            file->line_num++;
1911
            inp();
1912
        } else {
1913
        fail:
1914
            error("stray '\\' in program");
1915
        }
1916
    }
1917
}
1918
 
1919
/* skip the stray and handle the \\n case. Output an error if
1920
   incorrect char after the stray */
1921
static int handle_stray1(uint8_t *p)
1922
{
1923
    int c;
1924
 
1925
    if (p >= file->buf_end) {
1926
        file->buf_ptr = p;
1927
        c = handle_eob();
1928
        p = file->buf_ptr;
1929
        if (c == '\\')
1930
            goto parse_stray;
1931
    } else {
1932
    parse_stray:
1933
        file->buf_ptr = p;
1934
        ch = *p;
1935
        handle_stray();
1936
        p = file->buf_ptr;
1937
        c = *p;
1938
    }
1939
    return c;
1940
}
1941
 
1942
/* handle just the EOB case, but not stray */
1943
#define PEEKC_EOB(c, p)\
1944
{\
1945
    p++;\
1946
    c = *p;\
1947
    if (c == '\\') {\
1948
        file->buf_ptr = p;\
1949
        c = handle_eob();\
1950
        p = file->buf_ptr;\
1951
    }\
1952
}
1953
 
1954
/* handle the complicated stray case */
1955
#define PEEKC(c, p)\
1956
{\
1957
    p++;\
1958
    c = *p;\
1959
    if (c == '\\') {\
1960
        c = handle_stray1(p);\
1961
        p = file->buf_ptr;\
1962
    }\
1963
}
1964
 
1965
/* input with '\[\r]\n' handling. Note that this function cannot
1966
   handle other characters after '\', so you cannot call it inside
1967
   strings or comments */
1968
static void minp(void)
1969
{
1970
    inp();
1971
    if (ch == '\\')
1972
        handle_stray();
1973
}
1974
 
1975
 
1976
/* single line C++ comments */
1977
static uint8_t *parse_line_comment(uint8_t *p)
1978
{
1979
    int c;
1980
 
1981
    p++;
1982
    for(;;) {
1983
        c = *p;
1984
    redo:
1985
        if (c == '\n' || c == CH_EOF) {
1986
            break;
1987
        } else if (c == '\\') {
1988
            file->buf_ptr = p;
1989
            c = handle_eob();
1990
            p = file->buf_ptr;
1991
            if (c == '\\') {
1992
                PEEKC_EOB(c, p);
1993
                if (c == '\n') {
1994
                    file->line_num++;
1995
                    PEEKC_EOB(c, p);
1996
                } else if (c == '\r') {
1997
                    PEEKC_EOB(c, p);
1998
                    if (c == '\n') {
1999
                        file->line_num++;
2000
                        PEEKC_EOB(c, p);
2001
                    }
2002
                }
2003
            } else {
2004
                goto redo;
2005
            }
2006
        } else {
2007
            p++;
2008
        }
2009
    }
2010
    return p;
2011
}
2012
 
2013
/* C comments */
2014
static uint8_t *parse_comment(uint8_t *p)
2015
{
2016
    int c;
2017
 
2018
    p++;
2019
    for(;;) {
2020
        /* fast skip loop */
2021
        for(;;) {
2022
            c = *p;
2023
            if (c == '\n' || c == '*' || c == '\\')
2024
                break;
2025
            p++;
2026
            c = *p;
2027
            if (c == '\n' || c == '*' || c == '\\')
2028
                break;
2029
            p++;
2030
        }
2031
        /* now we can handle all the cases */
2032
        if (c == '\n') {
2033
            file->line_num++;
2034
            p++;
2035
        } else if (c == '*') {
2036
            p++;
2037
            for(;;) {
2038
                c = *p;
2039
                if (c == '*') {
2040
                    p++;
2041
                } else if (c == '/') {
2042
                    goto end_of_comment;
2043
                } else if (c == '\\') {
2044
                    file->buf_ptr = p;
2045
                    c = handle_eob();
2046
                    p = file->buf_ptr;
2047
                    if (c == '\\') {
2048
                        /* skip '\[\r]\n', otherwise just skip the stray */
2049
                        while (c == '\\') {
2050
                            PEEKC_EOB(c, p);
2051
                            if (c == '\n') {
2052
                                file->line_num++;
2053
                                PEEKC_EOB(c, p);
2054
                            } else if (c == '\r') {
2055
                                PEEKC_EOB(c, p);
2056
                                if (c == '\n') {
2057
                                    file->line_num++;
2058
                                    PEEKC_EOB(c, p);
2059
                                }
2060
                            } else {
2061
                                goto after_star;
2062
                            }
2063
                        }
2064
                    }
2065
                } else {
2066
                    break;
2067
                }
2068
            }
2069
        after_star: ;
2070
        } else {
2071
            /* stray, eob or eof */
2072
            file->buf_ptr = p;
2073
            c = handle_eob();
2074
            p = file->buf_ptr;
2075
            if (c == CH_EOF) {
2076
                error("unexpected end of file in comment");
2077
            } else if (c == '\\') {
2078
                p++;
2079
            }
2080
        }
2081
    }
2082
 end_of_comment:
2083
    p++;
2084
    return p;
2085
}
2086
 
2087
#define cinp minp
2088
 
2089
/* space excluding newline */
2090
static inline int is_space(int ch)
2091
{
2092
    return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
2093
}
2094
 
2095
static inline void skip_spaces(void)
2096
{
2097
    while (is_space(ch))
2098
        cinp();
2099
}
2100
 
2101
/* parse a string without interpreting escapes */
2102
static uint8_t *parse_pp_string(uint8_t *p,
2103
                                int sep, CString *str)
2104
{
2105
    int c;
2106
    p++;
2107
    for(;;) {
2108
        c = *p;
2109
        if (c == sep) {
2110
            break;
2111
        } else if (c == '\\') {
2112
            file->buf_ptr = p;
2113
            c = handle_eob();
2114
            p = file->buf_ptr;
2115
            if (c == CH_EOF) {
2116
            unterminated_string:
2117
                /* XXX: indicate line number of start of string */
2118
                error("missing terminating %c character", sep);
2119
            } else if (c == '\\') {
2120
                /* escape : just skip \[\r]\n */
2121
                PEEKC_EOB(c, p);
2122
                if (c == '\n') {
2123
                    file->line_num++;
2124
                    p++;
2125
                } else if (c == '\r') {
2126
                    PEEKC_EOB(c, p);
2127
                    if (c != '\n')
2128
                        expect("'\n' after '\r'");
2129
                    file->line_num++;
2130
                    p++;
2131
                } else if (c == CH_EOF) {
2132
                    goto unterminated_string;
2133
                } else {
2134
                    if (str) {
2135
                        cstr_ccat(str, '\\');
2136
                        cstr_ccat(str, c);
2137
                    }
2138
                    p++;
2139
                }
2140
            }
2141
        } else if (c == '\n') {
2142
            file->line_num++;
2143
            goto add_char;
2144
        } else if (c == '\r') {
2145
            PEEKC_EOB(c, p);
2146
            if (c != '\n') {
2147
                if (str)
2148
                    cstr_ccat(str, '\r');
2149
            } else {
2150
                file->line_num++;
2151
                goto add_char;
2152
            }
2153
        } else {
2154
        add_char:
2155
            if (str)
2156
                cstr_ccat(str, c);
2157
            p++;
2158
        }
2159
    }
2160
    p++;
2161
    return p;
2162
}
2163
 
2164
/* skip block of text until #else, #elif or #endif. skip also pairs of
2165
   #if/#endif */
2166
void preprocess_skip(void)
2167
{
2168
    int a, start_of_line, c;
2169
    uint8_t *p;
2170
 
2171
    p = file->buf_ptr;
2172
    start_of_line = 1;
2173
    a = 0;
2174
    for(;;) {
2175
    redo_no_start:
2176
        c = *p;
2177
        switch(c) {
2178
        case ' ':
2179
        case '\t':
2180
        case '\f':
2181
        case '\v':
2182
        case '\r':
2183
            p++;
2184
            goto redo_no_start;
2185
        case '\n':
2186
            start_of_line = 1;
2187
            file->line_num++;
2188
            p++;
2189
            goto redo_no_start;
2190
        case '\\':
2191
            file->buf_ptr = p;
2192
            c = handle_eob();
2193
            if (c == CH_EOF) {
2194
                expect("#endif");
2195
            } else if (c == '\\') {
2196
                /* XXX: incorrect: should not give an error */
2197
                ch = file->buf_ptr[0];
2198
                handle_stray();
2199
            }
2200
            p = file->buf_ptr;
2201
            goto redo_no_start;
2202
            /* skip strings */
2203
        case '\"':
2204
        case '\'':
2205
            p = parse_pp_string(p, c, NULL);
2206
            break;
2207
            /* skip comments */
2208
        case '/':
2209
            file->buf_ptr = p;
2210
            ch = *p;
2211
            minp();
2212
            p = file->buf_ptr;
2213
            if (ch == '*') {
2214
                p = parse_comment(p);
2215
            } else if (ch == '/') {
2216
                p = parse_line_comment(p);
2217
            }
2218
            break;
2219
 
2220
        case '#':
2221
            p++;
2222
            if (start_of_line) {
2223
                file->buf_ptr = p;
2224
                next_nomacro();
2225
                p = file->buf_ptr;
2226
                if (a == 0 &&
2227
                    (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
2228
                    goto the_end;
2229
                if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
2230
                    a++;
2231
                else if (tok == TOK_ENDIF)
2232
                    a--;
2233
            }
2234
            break;
2235
        default:
2236
            p++;
2237
            break;
2238
        }
2239
        start_of_line = 0;
2240
    }
2241
 the_end: ;
2242
    file->buf_ptr = p;
2243
}
2244
 
2245
/* ParseState handling */
2246
 
2247
/* XXX: currently, no include file info is stored. Thus, we cannot display
2248
   accurate messages if the function or data definition spans multiple
2249
   files */
2250
 
2251
/* save current parse state in 's' */
2252
void save_parse_state(ParseState *s)
2253
{
2254
    s->line_num = file->line_num;
2255
    s->macro_ptr = macro_ptr;
2256
    s->tok = tok;
2257
    s->tokc = tokc;
2258
}
2259
 
2260
/* restore parse state from 's' */
2261
void restore_parse_state(ParseState *s)
2262
{
2263
    file->line_num = s->line_num;
2264
    macro_ptr = s->macro_ptr;
2265
    tok = s->tok;
2266
    tokc = s->tokc;
2267
}
2268
 
2269
/* return the number of additional 'ints' necessary to store the
2270
   token */
2271
static inline int tok_ext_size(int t)
2272
{
2273
    switch(t) {
2274
        /* 4 bytes */
2275
    case TOK_CINT:
2276
    case TOK_CUINT:
2277
    case TOK_CCHAR:
2278
    case TOK_LCHAR:
2279
    case TOK_CFLOAT:
2280
    case TOK_LINENUM:
2281
        return 1;
2282
    case TOK_STR:
2283
    case TOK_LSTR:
2284
    case TOK_PPNUM:
2285
        error("unsupported token");
2286
        return 1;
2287
    case TOK_CDOUBLE:
2288
    case TOK_CLLONG:
2289
    case TOK_CULLONG:
2290
        return 2;
2291
    case TOK_CLDOUBLE:
2292
        return LDOUBLE_SIZE / 4;
2293
    default:
2294
        return 0;
2295
    }
2296
}
2297
 
2298
/* token string handling */
2299
 
2300
static inline void tok_str_new(TokenString *s)
2301
{
2302
    s->str = NULL;
2303
    s->len = 0;
2304
    s->allocated_len = 0;
2305
    s->last_line_num = -1;
2306
}
2307
 
2308
static void tok_str_free(int *str)
2309
{
2310
    tcc_free(str);
2311
}
2312
 
2313
static int *tok_str_realloc(TokenString *s)
2314
{
2315
    int *str, len;
2316
 
2317
    if (s->allocated_len == 0) {
2318
        len = 8;
2319
    } else {
2320
        len = s->allocated_len * 2;
2321
    }
2322
    str = tcc_realloc(s->str, len * sizeof(int));
2323
    if (!str)
2324
        error("memory full");
2325
    s->allocated_len = len;
2326
    s->str = str;
2327
    return str;
2328
}
2329
 
2330
static void tok_str_add(TokenString *s, int t)
2331
{
2332
    int len, *str;
2333
 
2334
    len = s->len;
2335
    str = s->str;
2336
    if (len >= s->allocated_len)
2337
        str = tok_str_realloc(s);
2338
    str[len++] = t;
2339
    s->len = len;
2340
}
2341
 
2342
static void tok_str_add2(TokenString *s, int t, CValue *cv)
2343
{
2344
    int len, *str;
2345
 
2346
    len = s->len;
2347
    str = s->str;
2348
 
2349
    /* allocate space for worst case */
2350
    if (len + TOK_MAX_SIZE > s->allocated_len)
2351
        str = tok_str_realloc(s);
2352
    str[len++] = t;
2353
    switch(t) {
2354
    case TOK_CINT:
2355
    case TOK_CUINT:
2356
    case TOK_CCHAR:
2357
    case TOK_LCHAR:
2358
    case TOK_CFLOAT:
2359
    case TOK_LINENUM:
2360
        str[len++] = cv->tab[0];
2361
        break;
2362
    case TOK_PPNUM:
2363
    case TOK_STR:
2364
    case TOK_LSTR:
2365
        {
2366
            int nb_words;
2367
            CString *cstr;
2368
 
2369
            nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2;
2370
            while ((len + nb_words) > s->allocated_len)
2371
                str = tok_str_realloc(s);
2372
            cstr = (CString *)(str + len);
2373
            cstr->data = NULL;
2374
            cstr->size = cv->cstr->size;
2375
            cstr->data_allocated = NULL;
2376
            cstr->size_allocated = cstr->size;
2377
            memcpy((char *)cstr + sizeof(CString),
2378
                   cv->cstr->data, cstr->size);
2379
            len += nb_words;
2380
        }
2381
        break;
2382
    case TOK_CDOUBLE:
2383
    case TOK_CLLONG:
2384
    case TOK_CULLONG:
2385
#if LDOUBLE_SIZE == 8
2386
    case TOK_CLDOUBLE:
2387
#endif
2388
        str[len++] = cv->tab[0];
2389
        str[len++] = cv->tab[1];
2390
        break;
2391
#if LDOUBLE_SIZE == 12
2392
    case TOK_CLDOUBLE:
2393
        str[len++] = cv->tab[0];
2394
        str[len++] = cv->tab[1];
2395
        str[len++] = cv->tab[2];
2396
#elif LDOUBLE_SIZE != 8
2397
#error add long double size support
2398
#endif
2399
        break;
2400
    default:
2401
        break;
2402
    }
2403
    s->len = len;
2404
}
2405
 
2406
/* add the current parse token in token string 's' */
2407
static void tok_str_add_tok(TokenString *s)
2408
{
2409
    CValue cval;
2410
 
2411
    /* save line number info */
2412
    if (file->line_num != s->last_line_num) {
2413
        s->last_line_num = file->line_num;
2414
        cval.i = s->last_line_num;
2415
        tok_str_add2(s, TOK_LINENUM, &cval);
2416
    }
2417
    tok_str_add2(s, tok, &tokc);
2418
}
2419
 
2420
#if LDOUBLE_SIZE == 12
2421
#define LDOUBLE_GET(p, cv)                      \
2422
        cv.tab[0] = p[0];                       \
2423
        cv.tab[1] = p[1];                       \
2424
        cv.tab[2] = p[2];
2425
#elif LDOUBLE_SIZE == 8
2426
#define LDOUBLE_GET(p, cv)                      \
2427
        cv.tab[0] = p[0];                       \
2428
        cv.tab[1] = p[1];
2429
#else
2430
#error add long double size support
2431
#endif
2432
 
2433
 
2434
/* get a token from an integer array and increment pointer
2435
   accordingly. we code it as a macro to avoid pointer aliasing. */
2436
#define TOK_GET(t, p, cv)                       \
2437
{                                               \
2438
    t = *p++;                                   \
2439
    switch(t) {                                 \
2440
    case TOK_CINT:                              \
2441
    case TOK_CUINT:                             \
2442
    case TOK_CCHAR:                             \
2443
    case TOK_LCHAR:                             \
2444
    case TOK_CFLOAT:                            \
2445
    case TOK_LINENUM:                           \
2446
        cv.tab[0] = *p++;                       \
2447
        break;                                  \
2448
    case TOK_STR:                               \
2449
    case TOK_LSTR:                              \
2450
    case TOK_PPNUM:                             \
2451
        cv.cstr = (CString *)p;                 \
2452
        cv.cstr->data = (char *)p + sizeof(CString);\
2453
        p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\
2454
        break;                                  \
2455
    case TOK_CDOUBLE:                           \
2456
    case TOK_CLLONG:                            \
2457
    case TOK_CULLONG:                           \
2458
        cv.tab[0] = p[0];                       \
2459
        cv.tab[1] = p[1];                       \
2460
        p += 2;                                 \
2461
        break;                                  \
2462
    case TOK_CLDOUBLE:                          \
2463
        LDOUBLE_GET(p, cv);                     \
2464
        p += LDOUBLE_SIZE / 4;                  \
2465
        break;                                  \
2466
    default:                                    \
2467
        break;                                  \
2468
    }                                           \
2469
}
2470
 
2471
/* defines handling */
2472
static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
2473
{
2474
    Sym *s;
2475
 
2476
    s = sym_push2(&define_stack, v, macro_type, (int)str);
2477
    s->next = first_arg;
2478
    table_ident[v - TOK_IDENT]->sym_define = s;
2479
}
2480
 
2481
/* undefined a define symbol. Its name is just set to zero */
2482
static void define_undef(Sym *s)
2483
{
2484
    int v;
2485
    v = s->v;
2486
    if (v >= TOK_IDENT && v < tok_ident)
2487
        table_ident[v - TOK_IDENT]->sym_define = NULL;
2488
    s->v = 0;
2489
}
2490
 
2491
static inline Sym *define_find(int v)
2492
{
2493
    v -= TOK_IDENT;
2494
    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2495
        return NULL;
2496
    return table_ident[v]->sym_define;
2497
}
2498
 
2499
/* free define stack until top reaches 'b' */
2500
static void free_defines(Sym *b)
2501
{
2502
    Sym *top, *top1;
2503
    int v;
2504
 
2505
    top = define_stack;
2506
    while (top != b) {
2507
        top1 = top->prev;
2508
        /* do not free args or predefined defines */
2509
        if (top->c)
2510
            tok_str_free((int *)top->c);
2511
        v = top->v;
2512
        if (v >= TOK_IDENT && v < tok_ident)
2513
            table_ident[v - TOK_IDENT]->sym_define = NULL;
2514
        sym_free(top);
2515
        top = top1;
2516
    }
2517
    define_stack = b;
2518
}
2519
 
2520
/* label lookup */
2521
static Sym *label_find(int v)
2522
{
2523
    v -= TOK_IDENT;
2524
    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
2525
        return NULL;
2526
    return table_ident[v]->sym_label;
2527
}
2528
 
2529
static Sym *label_push(Sym **ptop, int v, int flags)
2530
{
2531
    Sym *s, **ps;
2532
    s = sym_push2(ptop, v, 0, 0);
2533
    s->r = flags;
2534
    ps = &table_ident[v - TOK_IDENT]->sym_label;
2535
    if (ptop == &global_label_stack) {
2536
        /* modify the top most local identifier, so that
2537
           sym_identifier will point to 's' when popped */
2538
        while (*ps != NULL)
2539
            ps = &(*ps)->prev_tok;
2540
    }
2541
    s->prev_tok = *ps;
2542
    *ps = s;
2543
    return s;
2544
}
2545
 
2546
/* pop labels until element last is reached. Look if any labels are
2547
   undefined. Define symbols if '&&label' was used. */
2548
static void label_pop(Sym **ptop, Sym *slast)
2549
{
2550
    Sym *s, *s1;
2551
    for(s = *ptop; s != slast; s = s1) {
2552
        s1 = s->prev;
2553
        if (s->r == LABEL_DECLARED) {
2554
            warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
2555
        } else if (s->r == LABEL_FORWARD) {
2556
                error("label '%s' used but not defined",
2557
                      get_tok_str(s->v, NULL));
2558
        } else {
2559
            if (s->c) {
2560
                /* define corresponding symbol. A size of
2561
                   1 is put. */
2562
                put_extern_sym(s, cur_text_section, (long)s->next, 1);
2563
            }
2564
        }
2565
        /* remove label */
2566
        table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
2567
        sym_free(s);
2568
    }
2569
    *ptop = slast;
2570
}
2571
 
2572
/* eval an expression for #if/#elif */
2573
static int expr_preprocess(void)
2574
{
2575
    int c, t;
2576
    TokenString str;
2577
 
2578
    tok_str_new(&str);
2579
    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2580
        next(); /* do macro subst */
2581
        if (tok == TOK_DEFINED) {
2582
            next_nomacro();
2583
            t = tok;
2584
            if (t == '(')
2585
                next_nomacro();
2586
            c = define_find(tok) != 0;
2587
            if (t == '(')
2588
                next_nomacro();
2589
            tok = TOK_CINT;
2590
            tokc.i = c;
2591
        } else if (tok >= TOK_IDENT) {
2592
            /* if undefined macro */
2593
            tok = TOK_CINT;
2594
            tokc.i = 0;
2595
        }
2596
        tok_str_add_tok(&str);
2597
    }
2598
    tok_str_add(&str, -1); /* simulate end of file */
2599
    tok_str_add(&str, 0);
2600
    /* now evaluate C constant expression */
2601
    macro_ptr = str.str;
2602
    next();
2603
    c = expr_const();
2604
    macro_ptr = NULL;
2605
    tok_str_free(str.str);
2606
    return c != 0;
2607
}
2608
 
2609
#if defined(PARSE_DEBUG) || defined(PP_DEBUG)
2610
static void tok_print(int *str)
2611
{
2612
    int t;
2613
    CValue cval;
2614
 
2615
    while (1) {
2616
        TOK_GET(t, str, cval);
2617
        if (!t)
2618
            break;
2619
        printf(" %s", get_tok_str(t, &cval));
2620
    }
2621
    printf("\n");
2622
}
2623
#endif
2624
 
2625
/* parse after #define */
2626
static void parse_define(void)
2627
{
2628
    Sym *s, *first, **ps;
2629
    int v, t, varg, is_vaargs, c;
2630
    TokenString str;
2631
 
2632
    v = tok;
2633
    if (v < TOK_IDENT)
2634
        error("invalid macro name '%s'", get_tok_str(tok, &tokc));
2635
    /* XXX: should check if same macro (ANSI) */
2636
    first = NULL;
2637
    t = MACRO_OBJ;
2638
    /* '(' must be just after macro definition for MACRO_FUNC */
2639
    c = file->buf_ptr[0];
2640
    if (c == '\\')
2641
        c = handle_stray1(file->buf_ptr);
2642
    if (c == '(') {
2643
        next_nomacro();
2644
        next_nomacro();
2645
        ps = &first;
2646
        while (tok != ')') {
2647
            varg = tok;
2648
            next_nomacro();
2649
            is_vaargs = 0;
2650
            if (varg == TOK_DOTS) {
2651
                varg = TOK___VA_ARGS__;
2652
                is_vaargs = 1;
2653
            } else if (tok == TOK_DOTS && gnu_ext) {
2654
                is_vaargs = 1;
2655
                next_nomacro();
2656
            }
2657
            if (varg < TOK_IDENT)
2658
                error("badly punctuated parameter list");
2659
            s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
2660
            *ps = s;
2661
            ps = &s->next;
2662
            if (tok != ',')
2663
                break;
2664
            next_nomacro();
2665
        }
2666
        t = MACRO_FUNC;
2667
    }
2668
    tok_str_new(&str);
2669
    next_nomacro();
2670
    /* EOF testing necessary for '-D' handling */
2671
    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2672
        tok_str_add2(&str, tok, &tokc);
2673
        next_nomacro();
2674
    }
2675
    tok_str_add(&str, 0);
2676
#ifdef PP_DEBUG
2677
    printf("define %s %d: ", get_tok_str(v, NULL), t);
2678
    tok_print(str.str);
2679
#endif
2680
    define_push(v, t, str.str, first);
2681
}
2682
 
2683
static inline int hash_cached_include(int type, const char *filename)
2684
{
2685
    const unsigned char *s;
2686
    unsigned int h;
2687
 
2688
    h = TOK_HASH_INIT;
2689
    h = TOK_HASH_FUNC(h, type);
2690
    s = filename;
2691
    while (*s) {
2692
        h = TOK_HASH_FUNC(h, *s);
2693
        s++;
2694
    }
2695
    h &= (CACHED_INCLUDES_HASH_SIZE - 1);
2696
    return h;
2697
}
2698
 
2699
/* XXX: use a token or a hash table to accelerate matching ? */
2700
static CachedInclude *search_cached_include(TCCState *s1,
2701
                                            int type, const char *filename)
2702
{
2703
    CachedInclude *e;
2704
    int i, h;
2705
    h = hash_cached_include(type, filename);
2706
    i = s1->cached_includes_hash[h];
2707
    for(;;) {
2708
        if (i == 0)
2709
            break;
2710
        e = s1->cached_includes[i - 1];
2711
        if (e->type == type && !strcmp(e->filename, filename))
2712
            return e;
2713
        i = e->hash_next;
2714
    }
2715
    return NULL;
2716
}
2717
 
2718
static inline void add_cached_include(TCCState *s1, int type,
2719
                                      const char *filename, int ifndef_macro)
2720
{
2721
    CachedInclude *e;
2722
    int h;
2723
 
2724
    if (search_cached_include(s1, type, filename))
2725
        return;
2726
#ifdef INC_DEBUG
2727
    printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
2728
#endif
2729
    e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
2730
    if (!e)
2731
        return;
2732
    e->type = type;
2733
    strcpy(e->filename, filename);
2734
    e->ifndef_macro = ifndef_macro;
2735
    dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
2736
    /* add in hash table */
2737
    h = hash_cached_include(type, filename);
2738
    e->hash_next = s1->cached_includes_hash[h];
2739
    s1->cached_includes_hash[h] = s1->nb_cached_includes;
2740
}
2741
 
2742
static void pragma_parse(TCCState *s1)
2743
{
2744
    int val;
2745
 
2746
    next();
2747
    if (tok == TOK_pack) {
2748
        /*
2749
          This may be:
2750
          #pragma pack(1) // set
2751
          #pragma pack() // reset to default
2752
          #pragma pack(push,1) // push & set
2753
          #pragma pack(pop) // restore previous
2754
        */
2755
        next();
2756
        skip('(');
2757
        if (tok == TOK_ASM_pop) {
2758
            next();
2759
            if (s1->pack_stack_ptr <= s1->pack_stack) {
2760
            stk_error:
2761
                error("out of pack stack");
2762
            }
2763
            s1->pack_stack_ptr--;
2764
        } else {
2765
            val = 0;
2766
            if (tok != ')') {
2767
                if (tok == TOK_ASM_push) {
2768
                    next();
2769
                    if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
2770
                        goto stk_error;
2771
                    s1->pack_stack_ptr++;
2772
                    skip(',');
2773
                }
2774
                if (tok != TOK_CINT) {
2775
                pack_error:
2776
                    error("invalid pack pragma");
2777
                }
2778
                val = tokc.i;
2779
                if (val < 1 || val > 16 || (val & (val - 1)) != 0)
2780
                    goto pack_error;
2781
                next();
2782
            }
2783
            *s1->pack_stack_ptr = val;
2784
            skip(')');
2785
        }
2786
    }
2787
}
2788
 
2789
/* is_bof is true if first non space token at beginning of file */
2790
static void preprocess(int is_bof)
2791
{
2792
    TCCState *s1 = tcc_state;
2793
    int size, i, c, n, saved_parse_flags;
2794
    char buf[1024], *q, *p;
2795
    char buf1[1024];
2796
    BufferedFile *f;
2797
    Sym *s;
2798
    CachedInclude *e;
2799
 
2800
    saved_parse_flags = parse_flags;
2801
    parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
2802
        PARSE_FLAG_LINEFEED;
2803
    next_nomacro();
2804
 redo:
2805
    switch(tok) {
2806
    case TOK_DEFINE:
2807
        next_nomacro();
2808
        parse_define();
2809
        break;
2810
    case TOK_UNDEF:
2811
        next_nomacro();
2812
        s = define_find(tok);
2813
        /* undefine symbol by putting an invalid name */
2814
        if (s)
2815
            define_undef(s);
2816
        break;
2817
    case TOK_INCLUDE:
2818
    case TOK_INCLUDE_NEXT:
2819
        ch = file->buf_ptr[0];
2820
        /* XXX: incorrect if comments : use next_nomacro with a special mode */
2821
        skip_spaces();
2822
        if (ch == '<') {
2823
            c = '>';
2824
            goto read_name;
2825
        } else if (ch == '\"') {
2826
            c = ch;
2827
        read_name:
2828
            /* XXX: better stray handling */
2829
            minp();
2830
            q = buf;
2831
            while (ch != c && ch != '\n' && ch != CH_EOF) {
2832
                if ((q - buf) < sizeof(buf) - 1)
2833
                    *q++ = ch;
2834
                minp();
2835
            }
2836
            *q = '\0';
2837
            minp();
2838
#if 0
2839
            /* eat all spaces and comments after include */
2840
            /* XXX: slightly incorrect */
2841
            while (ch1 != '\n' && ch1 != CH_EOF)
2842
                inp();
2843
#endif
2844
        } else {
2845
            /* computed #include : either we have only strings or
2846
               we have anything enclosed in '<>' */
2847
            next();
2848
            buf[0] = '\0';
2849
            if (tok == TOK_STR) {
2850
                while (tok != TOK_LINEFEED) {
2851
                    if (tok != TOK_STR) {
2852
                    include_syntax:
2853
                        error("'#include' expects \"FILENAME\" or ");
2854
                    }
2855
                    pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
2856
                    next();
2857
                }
2858
                c = '\"';
2859
            } else {
2860
                int len;
2861
                while (tok != TOK_LINEFEED) {
2862
                    pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
2863
                    next();
2864
                }
2865
                len = strlen(buf);
2866
                /* check syntax and remove '<>' */
2867
                if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
2868
                    goto include_syntax;
2869
                memmove(buf, buf + 1, len - 2);
2870
                buf[len - 2] = '\0';
2871
                c = '>';
2872
            }
2873
        }
2874
 
2875
        e = search_cached_include(s1, c, buf);
2876
        if (e && define_find(e->ifndef_macro)) {
2877
            /* no need to parse the include because the 'ifndef macro'
2878
               is defined */
2879
#ifdef INC_DEBUG
2880
            printf("%s: skipping %s\n", file->filename, buf);
2881
#endif
2882
        } else {
2883
            if (c == '\"') {
2884
                /* first search in current dir if "header.h" */
2885
                size = 0;
2886
                p = strrchr(file->filename, '/');
2887
                if (p)
2888
                    size = p + 1 - file->filename;
2889
                if (size > sizeof(buf1) - 1)
2890
                    size = sizeof(buf1) - 1;
2891
                memcpy(buf1, file->filename, size);
2892
                buf1[size] = '\0';
2893
                pstrcat(buf1, sizeof(buf1), buf);
2894
                f = tcc_open(s1, buf1);
2895
                if (f) {
2896
                    if (tok == TOK_INCLUDE_NEXT)
2897
                        tok = TOK_INCLUDE;
2898
                    else
2899
                        goto found;
2900
                }
2901
            }
2902
            if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
2903
                error("#include recursion too deep");
2904
            /* now search in all the include paths */
2905
            n = s1->nb_include_paths + s1->nb_sysinclude_paths;
2906
            for(i = 0; i < n; i++) {
2907
                const char *path;
2908
                if (i < s1->nb_include_paths)
2909
                    path = s1->include_paths[i];
2910
                else
2911
                    path = s1->sysinclude_paths[i - s1->nb_include_paths];
2912
                pstrcpy(buf1, sizeof(buf1), path);
2913
                pstrcat(buf1, sizeof(buf1), "/");
2914
                pstrcat(buf1, sizeof(buf1), buf);
2915
                f = tcc_open(s1, buf1);
2916
                if (f) {
2917
                    if (tok == TOK_INCLUDE_NEXT)
2918
                        tok = TOK_INCLUDE;
2919
                    else
2920
                        goto found;
2921
                }
2922
            }
2923
            error("include file '%s' not found", buf);
2924
            f = NULL;
2925
        found:
2926
#ifdef INC_DEBUG
2927
            printf("%s: including %s\n", file->filename, buf1);
2928
#endif
2929
            f->inc_type = c;
2930
            pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
2931
            /* push current file in stack */
2932
            /* XXX: fix current line init */
2933
            *s1->include_stack_ptr++ = file;
2934
            file = f;
2935
            /* add include file debug info */
2936
            if (do_debug) {
2937
                put_stabs(file->filename, N_BINCL, 0, 0, 0);
2938
            }
2939
            tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
2940
            ch = file->buf_ptr[0];
2941
            goto the_end;
2942
        }
2943
        break;
2944
    case TOK_IFNDEF:
2945
        c = 1;
2946
        goto do_ifdef;
2947
    case TOK_IF:
2948
        c = expr_preprocess();
2949
        goto do_if;
2950
    case TOK_IFDEF:
2951
        c = 0;
2952
    do_ifdef:
2953
        next_nomacro();
2954
        if (tok < TOK_IDENT)
2955
            error("invalid argument for '#if%sdef'", c ? "n" : "");
2956
        if (is_bof) {
2957
            if (c) {
2958
#ifdef INC_DEBUG
2959
                printf("#ifndef %s\n", get_tok_str(tok, NULL));
2960
#endif
2961
                file->ifndef_macro = tok;
2962
            }
2963
        }
2964
        c = (define_find(tok) != 0) ^ c;
2965
    do_if:
2966
        if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
2967
            error("memory full");
2968
        *s1->ifdef_stack_ptr++ = c;
2969
        goto test_skip;
2970
    case TOK_ELSE:
2971
        if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2972
            error("#else without matching #if");
2973
        if (s1->ifdef_stack_ptr[-1] & 2)
2974
            error("#else after #else");
2975
        c = (s1->ifdef_stack_ptr[-1] ^= 3);
2976
        goto test_skip;
2977
    case TOK_ELIF:
2978
        if (s1->ifdef_stack_ptr == s1->ifdef_stack)
2979
            error("#elif without matching #if");
2980
        c = s1->ifdef_stack_ptr[-1];
2981
        if (c > 1)
2982
            error("#elif after #else");
2983
        /* last #if/#elif expression was true: we skip */
2984
        if (c == 1)
2985
            goto skip;
2986
        c = expr_preprocess();
2987
        s1->ifdef_stack_ptr[-1] = c;
2988
    test_skip:
2989
        if (!(c & 1)) {
2990
        skip:
2991
            preprocess_skip();
2992
            is_bof = 0;
2993
            goto redo;
2994
        }
2995
        break;
2996
    case TOK_ENDIF:
2997
        if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
2998
            error("#endif without matching #if");
2999
        s1->ifdef_stack_ptr--;
3000
        /* '#ifndef macro' was at the start of file. Now we check if
3001
           an '#endif' is exactly at the end of file */
3002
        if (file->ifndef_macro &&
3003
            s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
3004
            file->ifndef_macro_saved = file->ifndef_macro;
3005
            /* need to set to zero to avoid false matches if another
3006
               #ifndef at middle of file */
3007
            file->ifndef_macro = 0;
3008
            while (tok != TOK_LINEFEED)
3009
                next_nomacro();
3010
            tok_flags |= TOK_FLAG_ENDIF;
3011
            goto the_end;
3012
        }
3013
        break;
3014
    case TOK_LINE:
3015
        next();
3016
        if (tok != TOK_CINT)
3017
            error("#line");
3018
        file->line_num = tokc.i - 1; /* the line number will be incremented after */
3019
        next();
3020
        if (tok != TOK_LINEFEED) {
3021
            if (tok != TOK_STR)
3022
                error("#line");
3023
            pstrcpy(file->filename, sizeof(file->filename),
3024
                    (char *)tokc.cstr->data);
3025
        }
3026
        break;
3027
    case TOK_ERROR:
3028
    case TOK_WARNING:
3029
        c = tok;
3030
        ch = file->buf_ptr[0];
3031
        skip_spaces();
3032
        q = buf;
3033
        while (ch != '\n' && ch != CH_EOF) {
3034
            if ((q - buf) < sizeof(buf) - 1)
3035
                *q++ = ch;
3036
            minp();
3037
        }
3038
        *q = '\0';
3039
        if (c == TOK_ERROR)
3040
            error("#error %s", buf);
3041
        else
3042
            warning("#warning %s", buf);
3043
        break;
3044
    case TOK_PRAGMA:
3045
        pragma_parse(s1);
3046
        break;
3047
    default:
3048
        if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
3049
            /* '!' is ignored to allow C scripts. numbers are ignored
3050
               to emulate cpp behaviour */
3051
        } else {
3052
            if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS))
3053
                error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
3054
        }
3055
        break;
3056
    }
3057
    /* ignore other preprocess commands or #! for C scripts */
3058
    while (tok != TOK_LINEFEED)
3059
        next_nomacro();
3060
 the_end:
3061
    parse_flags = saved_parse_flags;
3062
}
3063
 
3064
/* evaluate escape codes in a string. */
3065
static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
3066
{
3067
    int c, n;
3068
    const uint8_t *p;
3069
 
3070
    p = buf;
3071
    for(;;) {
3072
        c = *p;
3073
        if (c == '\0')
3074
            break;
3075
        if (c == '\\') {
3076
            p++;
3077
            /* escape */
3078
            c = *p;
3079
            switch(c) {
3080
            case '0': case '1': case '2': case '3':
3081
            case '4': case '5': case '6': case '7':
3082
                /* at most three octal digits */
3083
                n = c - '0';
3084
                p++;
3085
                c = *p;
3086
                if (isoct(c)) {
3087
                    n = n * 8 + c - '0';
3088
                    p++;
3089
                    c = *p;
3090
                    if (isoct(c)) {
3091
                        n = n * 8 + c - '0';
3092
                        p++;
3093
                    }
3094
                }
3095
                c = n;
3096
                goto add_char_nonext;
3097
            case 'x':
3098
                p++;
3099
                n = 0;
3100
                for(;;) {
3101
                    c = *p;
3102
                    if (c >= 'a' && c <= 'f')
3103
                        c = c - 'a' + 10;
3104
                    else if (c >= 'A' && c <= 'F')
3105
                        c = c - 'A' + 10;
3106
                    else if (isnum(c))
3107
                        c = c - '0';
3108
                    else
3109
                        break;
3110
                    n = n * 16 + c;
3111
                    p++;
3112
                }
3113
                c = n;
3114
                goto add_char_nonext;
3115
            case 'a':
3116
                c = '\a';
3117
                break;
3118
            case 'b':
3119
                c = '\b';
3120
                break;
3121
            case 'f':
3122
                c = '\f';
3123
                break;
3124
            case 'n':
3125
                c = '\n';
3126
                break;
3127
            case 'r':
3128
                c = '\r';
3129
                break;
3130
            case 't':
3131
                c = '\t';
3132
                break;
3133
            case 'v':
3134
                c = '\v';
3135
                break;
3136
            case 'e':
3137
                if (!gnu_ext)
3138
                    goto invalid_escape;
3139
                c = 27;
3140
                break;
3141
            case '\'':
3142
            case '\"':
3143
            case '\\':
3144
            case '?':
3145
                break;
3146
            default:
3147
            invalid_escape:
3148
                if (c >= '!' && c <= '~')
3149
                    warning("unknown escape sequence: \'\\%c\'", c);
3150
                else
3151
                    warning("unknown escape sequence: \'\\x%x\'", c);
3152
                break;
3153
            }
3154
        }
3155
        p++;
3156
    add_char_nonext:
3157
        if (!is_long)
3158
            cstr_ccat(outstr, c);
3159
        else
3160
            cstr_wccat(outstr, c);
3161
    }
3162
    /* add a trailing '\0' */
3163
    if (!is_long)
3164
        cstr_ccat(outstr, '\0');
3165
    else
3166
        cstr_wccat(outstr, '\0');
3167
}
3168
 
3169
/* we use 64 bit numbers */
3170
#define BN_SIZE 2
3171
 
3172
/* bn = (bn << shift) | or_val */
3173
void bn_lshift(unsigned int *bn, int shift, int or_val)
3174
{
3175
    int i;
3176
    unsigned int v;
3177
    for(i=0;i
3178
        v = bn[i];
3179
        bn[i] = (v << shift) | or_val;
3180
        or_val = v >> (32 - shift);
3181
    }
3182
}
3183
 
3184
void bn_zero(unsigned int *bn)
3185
{
3186
    int i;
3187
    for(i=0;i
3188
        bn[i] = 0;
3189
    }
3190
}
3191
 
3192
/* parse number in null terminated string 'p' and return it in the
3193
   current token */
3194
void parse_number(const char *p)
3195
{
3196
    int b, t, shift, frac_bits, s, exp_val, ch;
3197
    char *q;
3198
    unsigned int bn[BN_SIZE];
3199
    double d;
3200
 
3201
    /* number */
3202
    q = token_buf;
3203
    ch = *p++;
3204
    t = ch;
3205
    ch = *p++;
3206
    *q++ = t;
3207
    b = 10;
3208
    if (t == '.') {
3209
        goto float_frac_parse;
3210
    } else if (t == '0') {
3211
        if (ch == 'x' || ch == 'X') {
3212
            q--;
3213
            ch = *p++;
3214
            b = 16;
3215
        } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
3216
            q--;
3217
            ch = *p++;
3218
            b = 2;
3219
        }
3220
    }
3221
    /* parse all digits. cannot check octal numbers at this stage
3222
       because of floating point constants */
3223
    while (1) {
3224
        if (ch >= 'a' && ch <= 'f')
3225
            t = ch - 'a' + 10;
3226
        else if (ch >= 'A' && ch <= 'F')
3227
            t = ch - 'A' + 10;
3228
        else if (isnum(ch))
3229
            t = ch - '0';
3230
        else
3231
            break;
3232
        if (t >= b)
3233
            break;
3234
        if (q >= token_buf + STRING_MAX_SIZE) {
3235
        num_too_long:
3236
            error("number too long");
3237
        }
3238
        *q++ = ch;
3239
        ch = *p++;
3240
    }
3241
    if (ch == '.' ||
3242
        ((ch == 'e' || ch == 'E') && b == 10) ||
3243
        ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
3244
        if (b != 10) {
3245
            /* NOTE: strtox should support that for hexa numbers, but
3246
               non ISOC99 libcs do not support it, so we prefer to do
3247
               it by hand */
3248
            /* hexadecimal or binary floats */
3249
            /* XXX: handle overflows */
3250
            *q = '\0';
3251
            if (b == 16)
3252
                shift = 4;
3253
            else
3254
                shift = 2;
3255
            bn_zero(bn);
3256
            q = token_buf;
3257
            while (1) {
3258
                t = *q++;
3259
                if (t == '\0') {
3260
                    break;
3261
                } else if (t >= 'a') {
3262
                    t = t - 'a' + 10;
3263
                } else if (t >= 'A') {
3264
                    t = t - 'A' + 10;
3265
                } else {
3266
                    t = t - '0';
3267
                }
3268
                bn_lshift(bn, shift, t);
3269
            }
3270
            frac_bits = 0;
3271
            if (ch == '.') {
3272
                ch = *p++;
3273
                while (1) {
3274
                    t = ch;
3275
                    if (t >= 'a' && t <= 'f') {
3276
                        t = t - 'a' + 10;
3277
                    } else if (t >= 'A' && t <= 'F') {
3278
                        t = t - 'A' + 10;
3279
                    } else if (t >= '0' && t <= '9') {
3280
                        t = t - '0';
3281
                    } else {
3282
                        break;
3283
                    }
3284
                    if (t >= b)
3285
                        error("invalid digit");
3286
                    bn_lshift(bn, shift, t);
3287
                    frac_bits += shift;
3288
                    ch = *p++;
3289
                }
3290
            }
3291
            if (ch != 'p' && ch != 'P')
3292
                expect("exponent");
3293
            ch = *p++;
3294
            s = 1;
3295
            exp_val = 0;
3296
            if (ch == '+') {
3297
                ch = *p++;
3298
            } else if (ch == '-') {
3299
                s = -1;
3300
                ch = *p++;
3301
            }
3302
            if (ch < '0' || ch > '9')
3303
                expect("exponent digits");
3304
            while (ch >= '0' && ch <= '9') {
3305
                exp_val = exp_val * 10 + ch - '0';
3306
                ch = *p++;
3307
            }
3308
            exp_val = exp_val * s;
3309
 
3310
            /* now we can generate the number */
3311
            /* XXX: should patch directly float number */
3312
            d = (double)bn[1] * 4294967296.0 + (double)bn[0];
3313
            d = ldexp(d, exp_val - frac_bits);
3314
            t = toup(ch);
3315
            if (t == 'F') {
3316
                ch = *p++;
3317
                tok = TOK_CFLOAT;
3318
                /* float : should handle overflow */
3319
                tokc.f = (float)d;
3320
            } else if (t == 'L') {
3321
                ch = *p++;
3322
                tok = TOK_CLDOUBLE;
3323
                /* XXX: not large enough */
3324
                tokc.ld = (long double)d;
3325
            } else {
3326
                tok = TOK_CDOUBLE;
3327
                tokc.d = d;
3328
            }
3329
        } else {
3330
            /* decimal floats */
3331
            if (ch == '.') {
3332
                if (q >= token_buf + STRING_MAX_SIZE)
3333
                    goto num_too_long;
3334
                *q++ = ch;
3335
                ch = *p++;
3336
            float_frac_parse:
3337
                while (ch >= '0' && ch <= '9') {
3338
                    if (q >= token_buf + STRING_MAX_SIZE)
3339
                        goto num_too_long;
3340
                    *q++ = ch;
3341
                    ch = *p++;
3342
                }
3343
            }
3344
            if (ch == 'e' || ch == 'E') {
3345
                if (q >= token_buf + STRING_MAX_SIZE)
3346
                    goto num_too_long;
3347
                *q++ = ch;
3348
                ch = *p++;
3349
                if (ch == '-' || ch == '+') {
3350
                    if (q >= token_buf + STRING_MAX_SIZE)
3351
                        goto num_too_long;
3352
                    *q++ = ch;
3353
                    ch = *p++;
3354
                }
3355
                if (ch < '0' || ch > '9')
3356
                    expect("exponent digits");
3357
                while (ch >= '0' && ch <= '9') {
3358
                    if (q >= token_buf + STRING_MAX_SIZE)
3359
                        goto num_too_long;
3360
                    *q++ = ch;
3361
                    ch = *p++;
3362
                }
3363
            }
3364
            *q = '\0';
3365
            t = toup(ch);
3366
            errno = 0;
3367
            if (t == 'F') {
3368
                ch = *p++;
3369
                tok = TOK_CFLOAT;
3370
                tokc.f = strtof(token_buf, NULL);
3371
            } else if (t == 'L') {
3372
                ch = *p++;
3373
                tok = TOK_CLDOUBLE;
3374
                tokc.ld = strtold(token_buf, NULL);
3375
            } else {
3376
                tok = TOK_CDOUBLE;
3377
                tokc.d = strtod(token_buf, NULL);
3378
            }
3379
        }
3380
    } else {
3381
        unsigned long long n, n1;
3382
        int lcount, ucount;
3383
 
3384
        /* integer number */
3385
        *q = '\0';
3386
        q = token_buf;
3387
        if (b == 10 && *q == '0') {
3388
            b = 8;
3389
            q++;
3390
        }
3391
        n = 0;
3392
        while(1) {
3393
            t = *q++;
3394
            /* no need for checks except for base 10 / 8 errors */
3395
            if (t == '\0') {
3396
                break;
3397
            } else if (t >= 'a') {
3398
                t = t - 'a' + 10;
3399
            } else if (t >= 'A') {
3400
                t = t - 'A' + 10;
3401
            } else {
3402
                t = t - '0';
3403
                if (t >= b)
3404
                    error("invalid digit");
3405
            }
3406
            n1 = n;
3407
            n = n * b + t;
3408
            /* detect overflow */
3409
            /* XXX: this test is not reliable */
3410
            if (n < n1)
3411
                error("integer constant overflow");
3412
        }
3413
 
3414
        /* XXX: not exactly ANSI compliant */
3415
        if ((n & 0xffffffff00000000LL) != 0) {
3416
            if ((n >> 63) != 0)
3417
                tok = TOK_CULLONG;
3418
            else
3419
                tok = TOK_CLLONG;
3420
        } else if (n > 0x7fffffff) {
3421
            tok = TOK_CUINT;
3422
        } else {
3423
            tok = TOK_CINT;
3424
        }
3425
        lcount = 0;
3426
        ucount = 0;
3427
        for(;;) {
3428
            t = toup(ch);
3429
            if (t == 'L') {
3430
                if (lcount >= 2)
3431
                    error("three 'l's in integer constant");
3432
                lcount++;
3433
                if (lcount == 2) {
3434
                    if (tok == TOK_CINT)
3435
                        tok = TOK_CLLONG;
3436
                    else if (tok == TOK_CUINT)
3437
                        tok = TOK_CULLONG;
3438
                }
3439
                ch = *p++;
3440
            } else if (t == 'U') {
3441
                if (ucount >= 1)
3442
                    error("two 'u's in integer constant");
3443
                ucount++;
3444
                if (tok == TOK_CINT)
3445
                    tok = TOK_CUINT;
3446
                else if (tok == TOK_CLLONG)
3447
                    tok = TOK_CULLONG;
3448
                ch = *p++;
3449
            } else {
3450
                break;
3451
            }
3452
        }
3453
        if (tok == TOK_CINT || tok == TOK_CUINT)
3454
            tokc.ui = n;
3455
        else
3456
            tokc.ull = n;
3457
    }
3458
}
3459
 
3460
 
3461
#define PARSE2(c1, tok1, c2, tok2)              \
3462
    case c1:                                    \
3463
        PEEKC(c, p);                            \
3464
        if (c == c2) {                          \
3465
            p++;                                \
3466
            tok = tok2;                         \
3467
        } else {                                \
3468
            tok = tok1;                         \
3469
        }                                       \
3470
        break;
3471
 
3472
/* return next token without macro substitution */
3473
static inline void next_nomacro1(void)
3474
{
3475
    int t, c, is_long;
3476
    TokenSym *ts;
3477
    uint8_t *p, *p1;
3478
    unsigned int h;
3479
 
3480
    p = file->buf_ptr;
3481
 redo_no_start:
3482
    c = *p;
3483
    switch(c) {
3484
    case ' ':
3485
    case '\t':
3486
    case '\f':
3487
    case '\v':
3488
    case '\r':
3489
        p++;
3490
        goto redo_no_start;
3491
 
3492
    case '\\':
3493
        /* first look if it is in fact an end of buffer */
3494
        if (p >= file->buf_end) {
3495
            file->buf_ptr = p;
3496
            handle_eob();
3497
            p = file->buf_ptr;
3498
            if (p >= file->buf_end)
3499
                goto parse_eof;
3500
            else
3501
                goto redo_no_start;
3502
        } else {
3503
            file->buf_ptr = p;
3504
            ch = *p;
3505
            handle_stray();
3506
            p = file->buf_ptr;
3507
            goto redo_no_start;
3508
        }
3509
    parse_eof:
3510
        {
3511
            TCCState *s1 = tcc_state;
3512
            if (parse_flags & PARSE_FLAG_LINEFEED) {
3513
                tok = TOK_LINEFEED;
3514
            } else if (s1->include_stack_ptr == s1->include_stack ||
3515
                       !(parse_flags & PARSE_FLAG_PREPROCESS)) {
3516
                /* no include left : end of file. */
3517
                tok = TOK_EOF;
3518
            } else {
3519
                /* pop include file */
3520
 
3521
                /* test if previous '#endif' was after a #ifdef at
3522
                   start of file */
3523
                if (tok_flags & TOK_FLAG_ENDIF) {
3524
#ifdef INC_DEBUG
3525
                    printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
3526
#endif
3527
                    add_cached_include(s1, file->inc_type, file->inc_filename,
3528
                                       file->ifndef_macro_saved);
3529
                }
3530
 
3531
                /* add end of include file debug info */
3532
                if (do_debug) {
3533
                    put_stabd(N_EINCL, 0, 0);
3534
                }
3535
                /* pop include stack */
3536
                tcc_close(file);
3537
                s1->include_stack_ptr--;
3538
                file = *s1->include_stack_ptr;
3539
                p = file->buf_ptr;
3540
                goto redo_no_start;
3541
            }
3542
        }
3543
        break;
3544
 
3545
    case '\n':
3546
        if (parse_flags & PARSE_FLAG_LINEFEED) {
3547
            tok = TOK_LINEFEED;
3548
        } else {
3549
            file->line_num++;
3550
            tok_flags |= TOK_FLAG_BOL;
3551
            p++;
3552
            goto redo_no_start;
3553
        }
3554
        break;
3555
 
3556
    case '#':
3557
        /* XXX: simplify */
3558
        PEEKC(c, p);
3559
        if ((tok_flags & TOK_FLAG_BOL) &&
3560
            (parse_flags & PARSE_FLAG_PREPROCESS)) {
3561
            file->buf_ptr = p;
3562
            preprocess(tok_flags & TOK_FLAG_BOF);
3563
            p = file->buf_ptr;
3564
            goto redo_no_start;
3565
        } else {
3566
            if (c == '#') {
3567
                p++;
3568
                tok = TOK_TWOSHARPS;
3569
            } else {
3570
                if (parse_flags & PARSE_FLAG_ASM_COMMENTS) {
3571
                    p = parse_line_comment(p - 1);
3572
                    goto redo_no_start;
3573
                } else {
3574
                    tok = '#';
3575
                }
3576
            }
3577
        }
3578
        break;
3579
 
3580
    case 'a': case 'b': case 'c': case 'd':
3581
    case 'e': case 'f': case 'g': case 'h':
3582
    case 'i': case 'j': case 'k': case 'l':
3583
    case 'm': case 'n': case 'o': case 'p':
3584
    case 'q': case 'r': case 's': case 't':
3585
    case 'u': case 'v': case 'w': case 'x':
3586
    case 'y': case 'z':
3587
    case 'A': case 'B': case 'C': case 'D':
3588
    case 'E': case 'F': case 'G': case 'H':
3589
    case 'I': case 'J': case 'K':
3590
    case 'M': case 'N': case 'O': case 'P':
3591
    case 'Q': case 'R': case 'S': case 'T':
3592
    case 'U': case 'V': case 'W': case 'X':
3593
    case 'Y': case 'Z':
3594
    case '_':
3595
    parse_ident_fast:
3596
        p1 = p;
3597
        h = TOK_HASH_INIT;
3598
        h = TOK_HASH_FUNC(h, c);
3599
        p++;
3600
        for(;;) {
3601
            c = *p;
3602
            if (!isidnum_table[c])
3603
                break;
3604
            h = TOK_HASH_FUNC(h, c);
3605
            p++;
3606
        }
3607
        if (c != '\\') {
3608
            TokenSym **pts;
3609
            int len;
3610
 
3611
            /* fast case : no stray found, so we have the full token
3612
               and we have already hashed it */
3613
            len = p - p1;
3614
            h &= (TOK_HASH_SIZE - 1);
3615
            pts = &hash_ident[h];
3616
            for(;;) {
3617
                ts = *pts;
3618
                if (!ts)
3619
                    break;
3620
                if (ts->len == len && !memcmp(ts->str, p1, len))
3621
                    goto token_found;
3622
                pts = &(ts->hash_next);
3623
            }
3624
            ts = tok_alloc_new(pts, p1, len);
3625
        token_found: ;
3626
        } else {
3627
            /* slower case */
3628
            cstr_reset(&tokcstr);
3629
 
3630
            while (p1 < p) {
3631
                cstr_ccat(&tokcstr, *p1);
3632
                p1++;
3633
            }
3634
            p--;
3635
            PEEKC(c, p);
3636
        parse_ident_slow:
3637
            while (isidnum_table[c]) {
3638
                cstr_ccat(&tokcstr, c);
3639
                PEEKC(c, p);
3640
            }
3641
            ts = tok_alloc(tokcstr.data, tokcstr.size);
3642
        }
3643
        tok = ts->tok;
3644
        break;
3645
    case 'L':
3646
        t = p[1];
3647
        if (t != '\\' && t != '\'' && t != '\"') {
3648
            /* fast case */
3649
            goto parse_ident_fast;
3650
        } else {
3651
            PEEKC(c, p);
3652
            if (c == '\'' || c == '\"') {
3653
                is_long = 1;
3654
                goto str_const;
3655
            } else {
3656
                cstr_reset(&tokcstr);
3657
                cstr_ccat(&tokcstr, 'L');
3658
                goto parse_ident_slow;
3659
            }
3660
        }
3661
        break;
3662
    case '0': case '1': case '2': case '3':
3663
    case '4': case '5': case '6': case '7':
3664
    case '8': case '9':
3665
 
3666
        cstr_reset(&tokcstr);
3667
        /* after the first digit, accept digits, alpha, '.' or sign if
3668
           prefixed by 'eEpP' */
3669
    parse_num:
3670
        for(;;) {
3671
            t = c;
3672
            cstr_ccat(&tokcstr, c);
3673
            PEEKC(c, p);
3674
            if (!(isnum(c) || isid(c) || c == '.' ||
3675
                  ((c == '+' || c == '-') &&
3676
                   (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
3677
                break;
3678
        }
3679
        /* We add a trailing '\0' to ease parsing */
3680
        cstr_ccat(&tokcstr, '\0');
3681
        tokc.cstr = &tokcstr;
3682
        tok = TOK_PPNUM;
3683
        break;
3684
    case '.':
3685
        /* special dot handling because it can also start a number */
3686
        PEEKC(c, p);
3687
        if (isnum(c)) {
3688
            cstr_reset(&tokcstr);
3689
            cstr_ccat(&tokcstr, '.');
3690
            goto parse_num;
3691
        } else if (c == '.') {
3692
            PEEKC(c, p);
3693
            if (c != '.')
3694
                expect("'.'");
3695
            PEEKC(c, p);
3696
            tok = TOK_DOTS;
3697
        } else {
3698
            tok = '.';
3699
        }
3700
        break;
3701
    case '\'':
3702
    case '\"':
3703
        is_long = 0;
3704
    str_const:
3705
        {
3706
            CString str;
3707
            int sep;
3708
 
3709
            sep = c;
3710
 
3711
            /* parse the string */
3712
            cstr_new(&str);
3713
            p = parse_pp_string(p, sep, &str);
3714
            cstr_ccat(&str, '\0');
3715
 
3716
            /* eval the escape (should be done as TOK_PPNUM) */
3717
            cstr_reset(&tokcstr);
3718
            parse_escape_string(&tokcstr, str.data, is_long);
3719
            cstr_free(&str);
3720
 
3721
            if (sep == '\'') {
3722
                int char_size;
3723
                /* XXX: make it portable */
3724
                if (!is_long)
3725
                    char_size = 1;
3726
                else
3727
                    char_size = sizeof(int);
3728
                if (tokcstr.size <= char_size)
3729
                    error("empty character constant");
3730
                if (tokcstr.size > 2 * char_size)
3731
                    warning("multi-character character constant");
3732
                if (!is_long) {
3733
                    tokc.i = *(int8_t *)tokcstr.data;
3734
                    tok = TOK_CCHAR;
3735
                } else {
3736
                    tokc.i = *(int *)tokcstr.data;
3737
                    tok = TOK_LCHAR;
3738
                }
3739
            } else {
3740
                tokc.cstr = &tokcstr;
3741
                if (!is_long)
3742
                    tok = TOK_STR;
3743
                else
3744
                    tok = TOK_LSTR;
3745
            }
3746
        }
3747
        break;
3748
 
3749
    case '<':
3750
        PEEKC(c, p);
3751
        if (c == '=') {
3752
            p++;
3753
            tok = TOK_LE;
3754
        } else if (c == '<') {
3755
            PEEKC(c, p);
3756
            if (c == '=') {
3757
                p++;
3758
                tok = TOK_A_SHL;
3759
            } else {
3760
                tok = TOK_SHL;
3761
            }
3762
        } else {
3763
            tok = TOK_LT;
3764
        }
3765
        break;
3766
 
3767
    case '>':
3768
        PEEKC(c, p);
3769
        if (c == '=') {
3770
            p++;
3771
            tok = TOK_GE;
3772
        } else if (c == '>') {
3773
            PEEKC(c, p);
3774
            if (c == '=') {
3775
                p++;
3776
                tok = TOK_A_SAR;
3777
            } else {
3778
                tok = TOK_SAR;
3779
            }
3780
        } else {
3781
            tok = TOK_GT;
3782
        }
3783
        break;
3784
 
3785
    case '&':
3786
        PEEKC(c, p);
3787
        if (c == '&') {
3788
            p++;
3789
            tok = TOK_LAND;
3790
        } else if (c == '=') {
3791
            p++;
3792
            tok = TOK_A_AND;
3793
        } else {
3794
            tok = '&';
3795
        }
3796
        break;
3797
 
3798
    case '|':
3799
        PEEKC(c, p);
3800
        if (c == '|') {
3801
            p++;
3802
            tok = TOK_LOR;
3803
        } else if (c == '=') {
3804
            p++;
3805
            tok = TOK_A_OR;
3806
        } else {
3807
            tok = '|';
3808
        }
3809
        break;
3810
 
3811
    case '+':
3812
        PEEKC(c, p);
3813
        if (c == '+') {
3814
            p++;
3815
            tok = TOK_INC;
3816
        } else if (c == '=') {
3817
            p++;
3818
            tok = TOK_A_ADD;
3819
        } else {
3820
            tok = '+';
3821
        }
3822
        break;
3823
 
3824
    case '-':
3825
        PEEKC(c, p);
3826
        if (c == '-') {
3827
            p++;
3828
            tok = TOK_DEC;
3829
        } else if (c == '=') {
3830
            p++;
3831
            tok = TOK_A_SUB;
3832
        } else if (c == '>') {
3833
            p++;
3834
            tok = TOK_ARROW;
3835
        } else {
3836
            tok = '-';
3837
        }
3838
        break;
3839
 
3840
    PARSE2('!', '!', '=', TOK_NE)
3841
    PARSE2('=', '=', '=', TOK_EQ)
3842
    PARSE2('*', '*', '=', TOK_A_MUL)
3843
    PARSE2('%', '%', '=', TOK_A_MOD)
3844
    PARSE2('^', '^', '=', TOK_A_XOR)
3845
 
3846
        /* comments or operator */
3847
    case '/':
3848
        PEEKC(c, p);
3849
        if (c == '*') {
3850
            p = parse_comment(p);
3851
            goto redo_no_start;
3852
        } else if (c == '/') {
3853
            p = parse_line_comment(p);
3854
            goto redo_no_start;
3855
        } else if (c == '=') {
3856
            p++;
3857
            tok = TOK_A_DIV;
3858
        } else {
3859
            tok = '/';
3860
        }
3861
        break;
3862
 
3863
        /* simple tokens */
3864
    case '(':
3865
    case ')':
3866
    case '[':
3867
    case ']':
3868
    case '{':
3869
    case '}':
3870
    case ',':
3871
    case ';':
3872
    case ':':
3873
    case '?':
3874
    case '~':
3875
    case '$': /* only used in assembler */
3876
    case '@': /* dito */
3877
        tok = c;
3878
        p++;
3879
        break;
3880
    default:
3881
        error("unrecognized character \\x%02x", c);
3882
        break;
3883
    }
3884
    file->buf_ptr = p;
3885
    tok_flags = 0;
3886
#if defined(PARSE_DEBUG)
3887
    printf("token = %s\n", get_tok_str(tok, &tokc));
3888
#endif
3889
}
3890
 
3891
/* return next token without macro substitution. Can read input from
3892
   macro_ptr buffer */
3893
static void next_nomacro(void)
3894
{
3895
    if (macro_ptr) {
3896
    redo:
3897
        tok = *macro_ptr;
3898
        if (tok) {
3899
            TOK_GET(tok, macro_ptr, tokc);
3900
            if (tok == TOK_LINENUM) {
3901
                file->line_num = tokc.i;
3902
                goto redo;
3903
            }
3904
        }
3905
    } else {
3906
        next_nomacro1();
3907
    }
3908
}
3909
 
3910
/* substitute args in macro_str and return allocated string */
3911
static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
3912
{
3913
    int *st, last_tok, t, notfirst;
3914
    Sym *s;
3915
    CValue cval;
3916
    TokenString str;
3917
    CString cstr;
3918
 
3919
    tok_str_new(&str);
3920
    last_tok = 0;
3921
    while(1) {
3922
        TOK_GET(t, macro_str, cval);
3923
        if (!t)
3924
            break;
3925
        if (t == '#') {
3926
            /* stringize */
3927
            TOK_GET(t, macro_str, cval);
3928
            if (!t)
3929
                break;
3930
            s = sym_find2(args, t);
3931
            if (s) {
3932
                cstr_new(&cstr);
3933
                st = (int *)s->c;
3934
                notfirst = 0;
3935
                while (*st) {
3936
                    if (notfirst)
3937
                        cstr_ccat(&cstr, ' ');
3938
                    TOK_GET(t, st, cval);
3939
                    cstr_cat(&cstr, get_tok_str(t, &cval));
3940
                    notfirst = 1;
3941
                }
3942
                cstr_ccat(&cstr, '\0');
3943
#ifdef PP_DEBUG
3944
                printf("stringize: %s\n", (char *)cstr.data);
3945
#endif
3946
                /* add string */
3947
                cval.cstr = &cstr;
3948
                tok_str_add2(&str, TOK_STR, &cval);
3949
                cstr_free(&cstr);
3950
            } else {
3951
                tok_str_add2(&str, t, &cval);
3952
            }
3953
        } else if (t >= TOK_IDENT) {
3954
            s = sym_find2(args, t);
3955
            if (s) {
3956
                st = (int *)s->c;
3957
                /* if '##' is present before or after, no arg substitution */
3958
                if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
3959
                    /* special case for var arg macros : ## eats the
3960
                       ',' if empty VA_ARGS variable. */
3961
                    /* XXX: test of the ',' is not 100%
3962
                       reliable. should fix it to avoid security
3963
                       problems */
3964
                    if (gnu_ext && s->type.t &&
3965
                        last_tok == TOK_TWOSHARPS &&
3966
                        str.len >= 2 && str.str[str.len - 2] == ',') {
3967
                        if (*st == 0) {
3968
                            /* suppress ',' '##' */
3969
                            str.len -= 2;
3970
                        } else {
3971
                            /* suppress '##' and add variable */
3972
                            str.len--;
3973
                            goto add_var;
3974
                        }
3975
                    } else {
3976
                        int t1;
3977
                    add_var:
3978
                        for(;;) {
3979
                            TOK_GET(t1, st, cval);
3980
                            if (!t1)
3981
                                break;
3982
                            tok_str_add2(&str, t1, &cval);
3983
                        }
3984
                    }
3985
                } else {
3986
                    /* NOTE: the stream cannot be read when macro
3987
                       substituing an argument */
3988
                    macro_subst(&str, nested_list, st, NULL);
3989
                }
3990
            } else {
3991
                tok_str_add(&str, t);
3992
            }
3993
        } else {
3994
            tok_str_add2(&str, t, &cval);
3995
        }
3996
        last_tok = t;
3997
    }
3998
    tok_str_add(&str, 0);
3999
    return str.str;
4000
}
4001
 
4002
static char const ab_month_name[12][4] =
4003
{
4004
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
4005
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
4006
};
4007
 
4008
/* do macro substitution of current token with macro 's' and add
4009
   result to (tok_str,tok_len). 'nested_list' is the list of all
4010
   macros we got inside to avoid recursing. Return non zero if no
4011
   substitution needs to be done */
4012
static int macro_subst_tok(TokenString *tok_str,
4013
                           Sym **nested_list, Sym *s, struct macro_level **can_read_stream)
4014
{
4015
    Sym *args, *sa, *sa1;
4016
    int mstr_allocated, parlevel, *mstr, t, t1;
4017
    TokenString str;
4018
    char *cstrval;
4019
    CValue cval;
4020
    CString cstr;
4021
    char buf[32];
4022
 
4023
    /* if symbol is a macro, prepare substitution */
4024
    /* special macros */
4025
    if (tok == TOK___LINE__) {
4026
        snprintf(buf, sizeof(buf), "%d", file->line_num);
4027
        cstrval = buf;
4028
        t1 = TOK_PPNUM;
4029
        goto add_cstr1;
4030
    } else if (tok == TOK___FILE__) {
4031
        cstrval = file->filename;
4032
        goto add_cstr;
4033
    } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
4034
        time_t ti;
4035
        struct tm *tm;
4036
 
4037
        time(&ti);
4038
        tm = localtime(&ti);
4039
        if (tok == TOK___DATE__) {
4040
            snprintf(buf, sizeof(buf), "%s %2d %d",
4041
                     ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
4042
        } else {
4043
            snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
4044
                     tm->tm_hour, tm->tm_min, tm->tm_sec);
4045
        }
4046
        cstrval = buf;
4047
    add_cstr:
4048
        t1 = TOK_STR;
4049
    add_cstr1:
4050
        cstr_new(&cstr);
4051
        cstr_cat(&cstr, cstrval);
4052
        cstr_ccat(&cstr, '\0');
4053
        cval.cstr = &cstr;
4054
        tok_str_add2(tok_str, t1, &cval);
4055
        cstr_free(&cstr);
4056
    } else {
4057
        mstr = (int *)s->c;
4058
        mstr_allocated = 0;
4059
        if (s->type.t == MACRO_FUNC) {
4060
            /* NOTE: we do not use next_nomacro to avoid eating the
4061
               next token. XXX: find better solution */
4062
        redo:
4063
            if (macro_ptr) {
4064
                t = *macro_ptr;
4065
                if (t == 0 && can_read_stream) {
4066
                    /* end of macro stream: we must look at the token
4067
                       after in the file */
4068
                    struct macro_level *ml = *can_read_stream;
4069
                    macro_ptr = NULL;
4070
                    if (ml)
4071
                    {
4072
                        macro_ptr = ml->p;
4073
                        ml->p = NULL;
4074
                        *can_read_stream = ml -> prev;
4075
                    }
4076
                    goto redo;
4077
                }
4078
            } else {
4079
                /* XXX: incorrect with comments */
4080
                ch = file->buf_ptr[0];
4081
                while (is_space(ch) || ch == '\n')
4082
                    cinp();
4083
                t = ch;
4084
            }
4085
            if (t != '(') /* no macro subst */
4086
                return -1;
4087
 
4088
            /* argument macro */
4089
            next_nomacro();
4090
            next_nomacro();
4091
            args = NULL;
4092
            sa = s->next;
4093
            /* NOTE: empty args are allowed, except if no args */
4094
            for(;;) {
4095
                /* handle '()' case */
4096
                if (!args && !sa && tok == ')')
4097
                    break;
4098
                if (!sa)
4099
                    error("macro '%s' used with too many args",
4100
                          get_tok_str(s->v, 0));
4101
                tok_str_new(&str);
4102
                parlevel = 0;
4103
                /* NOTE: non zero sa->t indicates VA_ARGS */
4104
                while ((parlevel > 0 ||
4105
                        (tok != ')' &&
4106
                         (tok != ',' || sa->type.t))) &&
4107
                       tok != -1) {
4108
                    if (tok == '(')
4109
                        parlevel++;
4110
                    else if (tok == ')')
4111
                        parlevel--;
4112
                    tok_str_add2(&str, tok, &tokc);
4113
                    next_nomacro();
4114
                }
4115
                tok_str_add(&str, 0);
4116
                sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (int)str.str);
4117
                sa = sa->next;
4118
                if (tok == ')') {
4119
                    /* special case for gcc var args: add an empty
4120
                       var arg argument if it is omitted */
4121
                    if (sa && sa->type.t && gnu_ext)
4122
                        continue;
4123
                    else
4124
                        break;
4125
                }
4126
                if (tok != ',')
4127
                    expect(",");
4128
                next_nomacro();
4129
            }
4130
            if (sa) {
4131
                error("macro '%s' used with too few args",
4132
                      get_tok_str(s->v, 0));
4133
            }
4134
 
4135
            /* now subst each arg */
4136
            mstr = macro_arg_subst(nested_list, mstr, args);
4137
            /* free memory */
4138
            sa = args;
4139
            while (sa) {
4140
                sa1 = sa->prev;
4141
                tok_str_free((int *)sa->c);
4142
                sym_free(sa);
4143
                sa = sa1;
4144
            }
4145
            mstr_allocated = 1;
4146
        }
4147
        sym_push2(nested_list, s->v, 0, 0);
4148
        macro_subst(tok_str, nested_list, mstr, can_read_stream);
4149
        /* pop nested defined symbol */
4150
        sa1 = *nested_list;
4151
        *nested_list = sa1->prev;
4152
        sym_free(sa1);
4153
        if (mstr_allocated)
4154
            tok_str_free(mstr);
4155
    }
4156
    return 0;
4157
}
4158
 
4159
/* handle the '##' operator. Return NULL if no '##' seen. Otherwise
4160
   return the resulting string (which must be freed). */
4161
static inline int *macro_twosharps(const int *macro_str)
4162
{
4163
    TokenSym *ts;
4164
    const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr;
4165
    int t;
4166
    const char *p1, *p2;
4167
    CValue cval;
4168
    TokenString macro_str1;
4169
    CString cstr;
4170
 
4171
    start_macro_ptr = macro_str;
4172
    /* we search the first '##' */
4173
    for(;;) {
4174
        macro_ptr1 = macro_str;
4175
        TOK_GET(t, macro_str, cval);
4176
        /* nothing more to do if end of string */
4177
        if (t == 0)
4178
            return NULL;
4179
        if (*macro_str == TOK_TWOSHARPS)
4180
            break;
4181
    }
4182
 
4183
    /* we saw '##', so we need more processing to handle it */
4184
    cstr_new(&cstr);
4185
    tok_str_new(¯o_str1);
4186
    tok = t;
4187
    tokc = cval;
4188
 
4189
    /* add all tokens seen so far */
4190
    for(ptr = start_macro_ptr; ptr < macro_ptr1;) {
4191
        TOK_GET(t, ptr, cval);
4192
        tok_str_add2(¯o_str1, t, &cval);
4193
    }
4194
    saved_macro_ptr = macro_ptr;
4195
    /* XXX: get rid of the use of macro_ptr here */
4196
    macro_ptr = (int *)macro_str;
4197
    for(;;) {
4198
        while (*macro_ptr == TOK_TWOSHARPS) {
4199
            macro_ptr++;
4200
            macro_ptr1 = macro_ptr;
4201
            t = *macro_ptr;
4202
            if (t) {
4203
                TOK_GET(t, macro_ptr, cval);
4204
                /* We concatenate the two tokens if we have an
4205
                   identifier or a preprocessing number */
4206
                cstr_reset(&cstr);
4207
                p1 = get_tok_str(tok, &tokc);
4208
                cstr_cat(&cstr, p1);
4209
                p2 = get_tok_str(t, &cval);
4210
                cstr_cat(&cstr, p2);
4211
                cstr_ccat(&cstr, '\0');
4212
 
4213
                if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
4214
                    (t >= TOK_IDENT || t == TOK_PPNUM)) {
4215
                    if (tok == TOK_PPNUM) {
4216
                        /* if number, then create a number token */
4217
                        /* NOTE: no need to allocate because
4218
                           tok_str_add2() does it */
4219
                        tokc.cstr = &cstr;
4220
                    } else {
4221
                        /* if identifier, we must do a test to
4222
                           validate we have a correct identifier */
4223
                        if (t == TOK_PPNUM) {
4224
                            const char *p;
4225
                            int c;
4226
 
4227
                            p = p2;
4228
                            for(;;) {
4229
                                c = *p;
4230
                                if (c == '\0')
4231
                                    break;
4232
                                p++;
4233
                                if (!isnum(c) && !isid(c))
4234
                                    goto error_pasting;
4235
                            }
4236
                        }
4237
                        ts = tok_alloc(cstr.data, strlen(cstr.data));
4238
                        tok = ts->tok; /* modify current token */
4239
                    }
4240
                } else {
4241
                    const char *str = cstr.data;
4242
                    const unsigned char *q;
4243
 
4244
                    /* we look for a valid token */
4245
                    /* XXX: do more extensive checks */
4246
                    if (!strcmp(str, ">>=")) {
4247
                        tok = TOK_A_SAR;
4248
                    } else if (!strcmp(str, "<<=")) {
4249
                        tok = TOK_A_SHL;
4250
                    } else if (strlen(str) == 2) {
4251
                        /* search in two bytes table */
4252
                        q = tok_two_chars;
4253
                        for(;;) {
4254
                            if (!*q)
4255
                                goto error_pasting;
4256
                            if (q[0] == str[0] && q[1] == str[1])
4257
                                break;
4258
                            q += 3;
4259
                        }
4260
                        tok = q[2];
4261
                    } else {
4262
                    error_pasting:
4263
                        /* NOTE: because get_tok_str use a static buffer,
4264
                           we must save it */
4265
                        cstr_reset(&cstr);
4266
                        p1 = get_tok_str(tok, &tokc);
4267
                        cstr_cat(&cstr, p1);
4268
                        cstr_ccat(&cstr, '\0');
4269
                        p2 = get_tok_str(t, &cval);
4270
                        warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
4271
                        /* cannot merge tokens: just add them separately */
4272
                        tok_str_add2(¯o_str1, tok, &tokc);
4273
                        /* XXX: free associated memory ? */
4274
                        tok = t;
4275
                        tokc = cval;
4276
                    }
4277
                }
4278
            }
4279
        }
4280
        tok_str_add2(¯o_str1, tok, &tokc);
4281
        next_nomacro();
4282
        if (tok == 0)
4283
            break;
4284
    }
4285
    macro_ptr = (int *)saved_macro_ptr;
4286
    cstr_free(&cstr);
4287
    tok_str_add(¯o_str1, 0);
4288
    return macro_str1.str;
4289
}
4290
 
4291
 
4292
/* do macro substitution of macro_str and add result to
4293
   (tok_str,tok_len). 'nested_list' is the list of all macros we got
4294
   inside to avoid recursing. */
4295
static void macro_subst(TokenString *tok_str, Sym **nested_list,
4296
                        const int *macro_str, struct macro_level ** can_read_stream)
4297
{
4298
    Sym *s;
4299
    int *macro_str1;
4300
    const int *ptr;
4301
    int t, ret;
4302
    CValue cval;
4303
    struct macro_level ml;
4304
 
4305
    /* first scan for '##' operator handling */
4306
    ptr = macro_str;
4307
    macro_str1 = macro_twosharps(ptr);
4308
    if (macro_str1)
4309
        ptr = macro_str1;
4310
    while (1) {
4311
        /* NOTE: ptr == NULL can only happen if tokens are read from
4312
           file stream due to a macro function call */
4313
        if (ptr == NULL)
4314
            break;
4315
        TOK_GET(t, ptr, cval);
4316
        if (t == 0)
4317
            break;
4318
        s = define_find(t);
4319
        if (s != NULL) {
4320
            /* if nested substitution, do nothing */
4321
            if (sym_find2(*nested_list, t))
4322
                goto no_subst;
4323
            ml.p = macro_ptr;
4324
            if (can_read_stream)
4325
                ml.prev = *can_read_stream, *can_read_stream = &ml;
4326
            macro_ptr = (int *)ptr;
4327
            tok = t;
4328
            ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream);
4329
            ptr = (int *)macro_ptr;
4330
            macro_ptr = ml.p;
4331
            if (can_read_stream && *can_read_stream == &ml)
4332
                    *can_read_stream = ml.prev;
4333
            if (ret != 0)
4334
                goto no_subst;
4335
        } else {
4336
        no_subst:
4337
            tok_str_add2(tok_str, t, &cval);
4338
        }
4339
    }
4340
    if (macro_str1)
4341
        tok_str_free(macro_str1);
4342
}
4343
 
4344
/* return next token with macro substitution */
4345
static void next(void)
4346
{
4347
    Sym *nested_list, *s;
4348
    TokenString str;
4349
    struct macro_level *ml;
4350
 
4351
 redo:
4352
    next_nomacro();
4353
    if (!macro_ptr) {
4354
        /* if not reading from macro substituted string, then try
4355
           to substitute macros */
4356
        if (tok >= TOK_IDENT &&
4357
            (parse_flags & PARSE_FLAG_PREPROCESS)) {
4358
            s = define_find(tok);
4359
            if (s) {
4360
                /* we have a macro: we try to substitute */
4361
                tok_str_new(&str);
4362
                nested_list = NULL;
4363
                ml = NULL;
4364
                if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) {
4365
                    /* substitution done, NOTE: maybe empty */
4366
                    tok_str_add(&str, 0);
4367
                    macro_ptr = str.str;
4368
                    macro_ptr_allocated = str.str;
4369
                    goto redo;
4370
                }
4371
            }
4372
        }
4373
    } else {
4374
        if (tok == 0) {
4375
            /* end of macro or end of unget buffer */
4376
            if (unget_buffer_enabled) {
4377
                macro_ptr = unget_saved_macro_ptr;
4378
                unget_buffer_enabled = 0;
4379
            } else {
4380
                /* end of macro string: free it */
4381
                tok_str_free(macro_ptr_allocated);
4382
                macro_ptr = NULL;
4383
            }
4384
            goto redo;
4385
        }
4386
    }
4387
 
4388
    /* convert preprocessor tokens into C tokens */
4389
    if (tok == TOK_PPNUM &&
4390
        (parse_flags & PARSE_FLAG_TOK_NUM)) {
4391
        parse_number((char *)tokc.cstr->data);
4392
    }
4393
}
4394
 
4395
/* push back current token and set current token to 'last_tok'. Only
4396
   identifier case handled for labels. */
4397
static inline void unget_tok(int last_tok)
4398
{
4399
    int i, n;
4400
    int *q;
4401
    unget_saved_macro_ptr = macro_ptr;
4402
    unget_buffer_enabled = 1;
4403
    q = unget_saved_buffer;
4404
    macro_ptr = q;
4405
    *q++ = tok;
4406
    n = tok_ext_size(tok) - 1;
4407
    for(i=0;i
4408
        *q++ = tokc.tab[i];
4409
    *q = 0; /* end of token string */
4410
    tok = last_tok;
4411
}
4412
 
4413
 
4414
void swap(int *p, int *q)
4415
{
4416
    int t;
4417
    t = *p;
4418
    *p = *q;
4419
    *q = t;
4420
}
4421
 
4422
void vsetc(CType *type, int r, CValue *vc)
4423
{
4424
    int v;
4425
 
4426
    if (vtop >= vstack + (VSTACK_SIZE - 1))
4427
        error("memory full");
4428
    /* cannot let cpu flags if other instruction are generated. Also
4429
       avoid leaving VT_JMP anywhere except on the top of the stack
4430
       because it would complicate the code generator. */
4431
    if (vtop >= vstack) {
4432
        v = vtop->r & VT_VALMASK;
4433
        if (v == VT_CMP || (v & ~1) == VT_JMP)
4434
            gv(RC_INT);
4435
    }
4436
    vtop++;
4437
    vtop->type = *type;
4438
    vtop->r = r;
4439
    vtop->r2 = VT_CONST;
4440
    vtop->c = *vc;
4441
}
4442
 
4443
/* push integer constant */
4444
void vpushi(int v)
4445
{
4446
    CValue cval;
4447
    cval.i = v;
4448
    vsetc(&int_type, VT_CONST, &cval);
4449
}
4450
 
4451
/* Return a static symbol pointing to a section */
4452
static Sym *get_sym_ref(CType *type, Section *sec,
4453
                        unsigned long offset, unsigned long size)
4454
{
4455
    int v;
4456
    Sym *sym;
4457
 
4458
    v = anon_sym++;
4459
    sym = global_identifier_push(v, type->t | VT_STATIC, 0);
4460
    sym->type.ref = type->ref;
4461
    sym->r = VT_CONST | VT_SYM;
4462
    put_extern_sym(sym, sec, offset, size);
4463
    return sym;
4464
}
4465
 
4466
/* push a reference to a section offset by adding a dummy symbol */
4467
static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
4468
{
4469
    CValue cval;
4470
 
4471
    cval.ul = 0;
4472
    vsetc(type, VT_CONST | VT_SYM, &cval);
4473
    vtop->sym = get_sym_ref(type, sec, offset, size);
4474
}
4475
 
4476
/* define a new external reference to a symbol 'v' of type 'u' */
4477
static Sym *external_global_sym(int v, CType *type, int r)
4478
{
4479
    Sym *s;
4480
 
4481
    s = sym_find(v);
4482
    if (!s) {
4483
        /* push forward reference */
4484
        s = global_identifier_push(v, type->t | VT_EXTERN, 0);
4485
        s->type.ref = type->ref;
4486
        s->r = r | VT_CONST | VT_SYM;
4487
    }
4488
    return s;
4489
}
4490
 
4491
/* define a new external reference to a symbol 'v' of type 'u' */
4492
static Sym *external_sym(int v, CType *type, int r)
4493
{
4494
    Sym *s;
4495
 
4496
    s = sym_find(v);
4497
    if (!s) {
4498
        /* push forward reference */
4499
        s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
4500
        s->type.t |= VT_EXTERN;
4501
    } else {
4502
        if (!is_compatible_types(&s->type, type))
4503
            error("incompatible types for redefinition of '%s'",
4504
                  get_tok_str(v, NULL));
4505
    }
4506
    return s;
4507
}
4508
 
4509
/* push a reference to global symbol v */
4510
static void vpush_global_sym(CType *type, int v)
4511
{
4512
    Sym *sym;
4513
    CValue cval;
4514
 
4515
    sym = external_global_sym(v, type, 0);
4516
    cval.ul = 0;
4517
    vsetc(type, VT_CONST | VT_SYM, &cval);
4518
    vtop->sym = sym;
4519
}
4520
 
4521
void vset(CType *type, int r, int v)
4522
{
4523
    CValue cval;
4524
 
4525
    cval.i = v;
4526
    vsetc(type, r, &cval);
4527
}
4528
 
4529
void vseti(int r, int v)
4530
{
4531
    CType type;
4532
    type.t = VT_INT;
4533
    vset(&type, r, v);
4534
}
4535
 
4536
void vswap(void)
4537
{
4538
    SValue tmp;
4539
 
4540
    tmp = vtop[0];
4541
    vtop[0] = vtop[-1];
4542
    vtop[-1] = tmp;
4543
}
4544
 
4545
void vpushv(SValue *v)
4546
{
4547
    if (vtop >= vstack + (VSTACK_SIZE - 1))
4548
        error("memory full");
4549
    vtop++;
4550
    *vtop = *v;
4551
}
4552
 
4553
void vdup(void)
4554
{
4555
    vpushv(vtop);
4556
}
4557
 
4558
/* save r to the memory stack, and mark it as being free */
4559
void save_reg(int r)
4560
{
4561
    int l, saved, size, align;
4562
    SValue *p, sv;
4563
    CType *type;
4564
 
4565
    /* modify all stack values */
4566
    saved = 0;
4567
    l = 0;
4568
    for(p=vstack;p<=vtop;p++) {
4569
        if ((p->r & VT_VALMASK) == r ||
4570
            (p->r2 & VT_VALMASK) == r) {
4571
            /* must save value on stack if not already done */
4572
            if (!saved) {
4573
                /* NOTE: must reload 'r' because r might be equal to r2 */
4574
                r = p->r & VT_VALMASK;
4575
                /* store register in the stack */
4576
                type = &p->type;
4577
                if ((p->r & VT_LVAL) ||
4578
                    (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
4579
                    type = &int_type;
4580
                size = type_size(type, &align);
4581
                loc = (loc - size) & -align;
4582
                sv.type.t = type->t;
4583
                sv.r = VT_LOCAL | VT_LVAL;
4584
                sv.c.ul = loc;
4585
                store(r, &sv);
4586
#ifdef TCC_TARGET_I386
4587
                /* x86 specific: need to pop fp register ST0 if saved */
4588
                if (r == TREG_ST0) {
4589
                    o(0xd9dd); /* fstp %st(1) */
4590
                }
4591
#endif
4592
                /* special long long case */
4593
                if ((type->t & VT_BTYPE) == VT_LLONG) {
4594
                    sv.c.ul += 4;
4595
                    store(p->r2, &sv);
4596
                }
4597
                l = loc;
4598
                saved = 1;
4599
            }
4600
            /* mark that stack entry as being saved on the stack */
4601
            if (p->r & VT_LVAL) {
4602
                /* also clear the bounded flag because the
4603
                   relocation address of the function was stored in
4604
                   p->c.ul */
4605
                p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
4606
            } else {
4607
                p->r = lvalue_type(p->type.t) | VT_LOCAL;
4608
            }
4609
            p->r2 = VT_CONST;
4610
            p->c.ul = l;
4611
        }
4612
    }
4613
}
4614
 
4615
/* find a register of class 'rc2' with at most one reference on stack.
4616
 * If none, call get_reg(rc) */
4617
int get_reg_ex(int rc, int rc2)
4618
{
4619
    int r;
4620
    SValue *p;
4621
 
4622
    for(r=0;r
4623
        if (reg_classes[r] & rc2) {
4624
            int n;
4625
            n=0;
4626
            for(p = vstack; p <= vtop; p++) {
4627
                if ((p->r & VT_VALMASK) == r ||
4628
                    (p->r2 & VT_VALMASK) == r)
4629
                    n++;
4630
            }
4631
            if (n <= 1)
4632
                return r;
4633
        }
4634
    }
4635
    return get_reg(rc);
4636
}
4637
 
4638
/* find a free register of class 'rc'. If none, save one register */
4639
int get_reg(int rc)
4640
{
4641
    int r;
4642
    SValue *p;
4643
 
4644
    /* find a free register */
4645
    for(r=0;r
4646
        if (reg_classes[r] & rc) {
4647
            for(p=vstack;p<=vtop;p++) {
4648
                if ((p->r & VT_VALMASK) == r ||
4649
                    (p->r2 & VT_VALMASK) == r)
4650
                    goto notfound;
4651
            }
4652
            return r;
4653
        }
4654
    notfound: ;
4655
    }
4656
 
4657
    /* no register left : free the first one on the stack (VERY
4658
       IMPORTANT to start from the bottom to ensure that we don't
4659
       spill registers used in gen_opi()) */
4660
    for(p=vstack;p<=vtop;p++) {
4661
        r = p->r & VT_VALMASK;
4662
        if (r < VT_CONST && (reg_classes[r] & rc))
4663
            goto save_found;
4664
        /* also look at second register (if long long) */
4665
        r = p->r2 & VT_VALMASK;
4666
        if (r < VT_CONST && (reg_classes[r] & rc)) {
4667
        save_found:
4668
            save_reg(r);
4669
            return r;
4670
        }
4671
    }
4672
    /* Should never comes here */
4673
    return -1;
4674
}
4675
 
4676
/* save registers up to (vtop - n) stack entry */
4677
void save_regs(int n)
4678
{
4679
    int r;
4680
    SValue *p, *p1;
4681
    p1 = vtop - n;
4682
    for(p = vstack;p <= p1; p++) {
4683
        r = p->r & VT_VALMASK;
4684
        if (r < VT_CONST) {
4685
            save_reg(r);
4686
        }
4687
    }
4688
}
4689
 
4690
/* move register 's' to 'r', and flush previous value of r to memory
4691
   if needed */
4692
void move_reg(int r, int s)
4693
{
4694
    SValue sv;
4695
 
4696
    if (r != s) {
4697
        save_reg(r);
4698
        sv.type.t = VT_INT;
4699
        sv.r = s;
4700
        sv.c.ul = 0;
4701
        load(r, &sv);
4702
    }
4703
}
4704
 
4705
/* get address of vtop (vtop MUST BE an lvalue) */
4706
void gaddrof(void)
4707
{
4708
    vtop->r &= ~VT_LVAL;
4709
    /* tricky: if saved lvalue, then we can go back to lvalue */
4710
    if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
4711
        vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
4712
}
4713
 
4714
#ifdef CONFIG_TCC_BCHECK
4715
/* generate lvalue bound code */
4716
void gbound(void)
4717
{
4718
    int lval_type;
4719
    CType type1;
4720
 
4721
    vtop->r &= ~VT_MUSTBOUND;
4722
    /* if lvalue, then use checking code before dereferencing */
4723
    if (vtop->r & VT_LVAL) {
4724
        /* if not VT_BOUNDED value, then make one */
4725
        if (!(vtop->r & VT_BOUNDED)) {
4726
            lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
4727
            /* must save type because we must set it to int to get pointer */
4728
            type1 = vtop->type;
4729
            vtop->type.t = VT_INT;
4730
            gaddrof();
4731
            vpushi(0);
4732
            gen_bounded_ptr_add();
4733
            vtop->r |= lval_type;
4734
            vtop->type = type1;
4735
        }
4736
        /* then check for dereferencing */
4737
        gen_bounded_ptr_deref();
4738
    }
4739
}
4740
#endif
4741
 
4742
/* store vtop a register belonging to class 'rc'. lvalues are
4743
   converted to values. Cannot be used if cannot be converted to
4744
   register value (such as structures). */
4745
int gv(int rc)
4746
{
4747
    int r, r2, rc2, bit_pos, bit_size, size, align, i;
4748
    unsigned long long ll;
4749
 
4750
    /* NOTE: get_reg can modify vstack[] */
4751
    if (vtop->type.t & VT_BITFIELD) {
4752
        bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
4753
        bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
4754
        /* remove bit field info to avoid loops */
4755
        vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
4756
        /* generate shifts */
4757
        vpushi(32 - (bit_pos + bit_size));
4758
        gen_op(TOK_SHL);
4759
        vpushi(32 - bit_size);
4760
        /* NOTE: transformed to SHR if unsigned */
4761
        gen_op(TOK_SAR);
4762
        r = gv(rc);
4763
    } else {
4764
        if (is_float(vtop->type.t) &&
4765
            (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4766
            Sym *sym;
4767
            int *ptr;
4768
            unsigned long offset;
4769
 
4770
            /* XXX: unify with initializers handling ? */
4771
            /* CPUs usually cannot use float constants, so we store them
4772
               generically in data segment */
4773
            size = type_size(&vtop->type, &align);
4774
            offset = (data_section->data_offset + align - 1) & -align;
4775
            data_section->data_offset = offset;
4776
            /* XXX: not portable yet */
4777
            ptr = section_ptr_add(data_section, size);
4778
            size = size >> 2;
4779
            for(i=0;i
4780
                ptr[i] = vtop->c.tab[i];
4781
            sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
4782
            vtop->r |= VT_LVAL | VT_SYM;
4783
            vtop->sym = sym;
4784
            vtop->c.ul = 0;
4785
        }
4786
#ifdef CONFIG_TCC_BCHECK
4787
        if (vtop->r & VT_MUSTBOUND)
4788
            gbound();
4789
#endif
4790
 
4791
        r = vtop->r & VT_VALMASK;
4792
        /* need to reload if:
4793
           - constant
4794
           - lvalue (need to dereference pointer)
4795
           - already a register, but not in the right class */
4796
        if (r >= VT_CONST ||
4797
            (vtop->r & VT_LVAL) ||
4798
            !(reg_classes[r] & rc) ||
4799
            ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
4800
             !(reg_classes[vtop->r2] & rc))) {
4801
            r = get_reg(rc);
4802
            if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
4803
                /* two register type load : expand to two words
4804
                   temporarily */
4805
                if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
4806
                    /* load constant */
4807
                    ll = vtop->c.ull;
4808
                    vtop->c.ui = ll; /* first word */
4809
                    load(r, vtop);
4810
                    vtop->r = r; /* save register value */
4811
                    vpushi(ll >> 32); /* second word */
4812
                } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
4813
                           (vtop->r & VT_LVAL)) {
4814
                    /* We do not want to modifier the long long
4815
                       pointer here, so the safest (and less
4816
                       efficient) is to save all the other registers
4817
                       in the stack. XXX: totally inefficient. */
4818
                    save_regs(1);
4819
                    /* load from memory */
4820
                    load(r, vtop);
4821
                    vdup();
4822
                    vtop[-1].r = r; /* save register value */
4823
                    /* increment pointer to get second word */
4824
                    vtop->type.t = VT_INT;
4825
                    gaddrof();
4826
                    vpushi(4);
4827
                    gen_op('+');
4828
                    vtop->r |= VT_LVAL;
4829
                } else {
4830
                    /* move registers */
4831
                    load(r, vtop);
4832
                    vdup();
4833
                    vtop[-1].r = r; /* save register value */
4834
                    vtop->r = vtop[-1].r2;
4835
                }
4836
                /* allocate second register */
4837
                rc2 = RC_INT;
4838
                if (rc == RC_IRET)
4839
                    rc2 = RC_LRET;
4840
                r2 = get_reg(rc2);
4841
                load(r2, vtop);
4842
                vpop();
4843
                /* write second register */
4844
                vtop->r2 = r2;
4845
            } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
4846
                int t1, t;
4847
                /* lvalue of scalar type : need to use lvalue type
4848
                   because of possible cast */
4849
                t = vtop->type.t;
4850
                t1 = t;
4851
                /* compute memory access type */
4852
                if (vtop->r & VT_LVAL_BYTE)
4853
                    t = VT_BYTE;
4854
                else if (vtop->r & VT_LVAL_SHORT)
4855
                    t = VT_SHORT;
4856
                if (vtop->r & VT_LVAL_UNSIGNED)
4857
                    t |= VT_UNSIGNED;
4858
                vtop->type.t = t;
4859
                load(r, vtop);
4860
                /* restore wanted type */
4861
                vtop->type.t = t1;
4862
            } else {
4863
                /* one register type load */
4864
                load(r, vtop);
4865
            }
4866
        }
4867
        vtop->r = r;
4868
#ifdef TCC_TARGET_C67
4869
        /* uses register pairs for doubles */
4870
        if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
4871
            vtop->r2 = r+1;
4872
#endif
4873
    }
4874
    return r;
4875
}
4876
 
4877
/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
4878
void gv2(int rc1, int rc2)
4879
{
4880
    int v;
4881
 
4882
    /* generate more generic register first. But VT_JMP or VT_CMP
4883
       values must be generated first in all cases to avoid possible
4884
       reload errors */
4885
    v = vtop[0].r & VT_VALMASK;
4886
    if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
4887
        vswap();
4888
        gv(rc1);
4889
        vswap();
4890
        gv(rc2);
4891
        /* test if reload is needed for first register */
4892
        if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
4893
            vswap();
4894
            gv(rc1);
4895
            vswap();
4896
        }
4897
    } else {
4898
        gv(rc2);
4899
        vswap();
4900
        gv(rc1);
4901
        vswap();
4902
        /* test if reload is needed for first register */
4903
        if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
4904
            gv(rc2);
4905
        }
4906
    }
4907
}
4908
 
4909
/* expand long long on stack in two int registers */
4910
void lexpand(void)
4911
{
4912
    int u;
4913
 
4914
    u = vtop->type.t & VT_UNSIGNED;
4915
    gv(RC_INT);
4916
    vdup();
4917
    vtop[0].r = vtop[-1].r2;
4918
    vtop[0].r2 = VT_CONST;
4919
    vtop[-1].r2 = VT_CONST;
4920
    vtop[0].type.t = VT_INT | u;
4921
    vtop[-1].type.t = VT_INT | u;
4922
}
4923
 
4924
#ifdef TCC_TARGET_ARM
4925
/* expand long long on stack */
4926
void lexpand_nr(void)
4927
{
4928
    int u,v;
4929
 
4930
    u = vtop->type.t & VT_UNSIGNED;
4931
    vdup();
4932
    vtop->r2 = VT_CONST;
4933
    vtop->type.t = VT_INT | u;
4934
    v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
4935
    if (v == VT_CONST) {
4936
      vtop[-1].c.ui = vtop->c.ull;
4937
      vtop->c.ui = vtop->c.ull >> 32;
4938
      vtop->r = VT_CONST;
4939
    } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
4940
      vtop->c.ui += 4;
4941
      vtop->r = vtop[-1].r;
4942
    } else if (v > VT_CONST) {
4943
      vtop--;
4944
      lexpand();
4945
    } else
4946
      vtop->r = vtop[-1].r2;
4947
    vtop[-1].r2 = VT_CONST;
4948
    vtop[-1].type.t = VT_INT | u;
4949
}
4950
#endif
4951
 
4952
/* build a long long from two ints */
4953
void lbuild(int t)
4954
{
4955
    gv2(RC_INT, RC_INT);
4956
    vtop[-1].r2 = vtop[0].r;
4957
    vtop[-1].type.t = t;
4958
    vpop();
4959
}
4960
 
4961
/* rotate n first stack elements to the bottom
4962
   I1 ... In -> I2 ... In I1 [top is right]
4963
*/
4964
void vrotb(int n)
4965
{
4966
    int i;
4967
    SValue tmp;
4968
 
4969
    tmp = vtop[-n + 1];
4970
    for(i=-n+1;i!=0;i++)
4971
        vtop[i] = vtop[i+1];
4972
    vtop[0] = tmp;
4973
}
4974
 
4975
/* rotate n first stack elements to the top
4976
   I1 ... In -> In I1 ... I(n-1)  [top is right]
4977
 */
4978
void vrott(int n)
4979
{
4980
    int i;
4981
    SValue tmp;
4982
 
4983
    tmp = vtop[0];
4984
    for(i = 0;i < n - 1; i++)
4985
        vtop[-i] = vtop[-i - 1];
4986
    vtop[-n + 1] = tmp;
4987
}
4988
 
4989
#ifdef TCC_TARGET_ARM
4990
/* like vrott but in other direction
4991
   In ... I1 -> I(n-1) ... I1 In  [top is right]
4992
 */
4993
void vnrott(int n)
4994
{
4995
    int i;
4996
    SValue tmp;
4997
 
4998
    tmp = vtop[-n + 1];
4999
    for(i = n - 1; i > 0; i--)
5000
        vtop[-i] = vtop[-i + 1];
5001
    vtop[0] = tmp;
5002
}
5003
#endif
5004
 
5005
/* pop stack value */
5006
void vpop(void)
5007
{
5008
    int v;
5009
    v = vtop->r & VT_VALMASK;
5010
#ifdef TCC_TARGET_I386
5011
    /* for x86, we need to pop the FP stack */
5012
    if (v == TREG_ST0 && !nocode_wanted) {
5013
        o(0xd9dd); /* fstp %st(1) */
5014
    } else
5015
#endif
5016
    if (v == VT_JMP || v == VT_JMPI) {
5017
        /* need to put correct jump if && or || without test */
5018
        gsym(vtop->c.ul);
5019
    }
5020
    vtop--;
5021
}
5022
 
5023
/* convert stack entry to register and duplicate its value in another
5024
   register */
5025
void gv_dup(void)
5026
{
5027
    int rc, t, r, r1;
5028
    SValue sv;
5029
 
5030
    t = vtop->type.t;
5031
    if ((t & VT_BTYPE) == VT_LLONG) {
5032
        lexpand();
5033
        gv_dup();
5034
        vswap();
5035
        vrotb(3);
5036
        gv_dup();
5037
        vrotb(4);
5038
        /* stack: H L L1 H1 */
5039
        lbuild(t);
5040
        vrotb(3);
5041
        vrotb(3);
5042
        vswap();
5043
        lbuild(t);
5044
        vswap();
5045
    } else {
5046
        /* duplicate value */
5047
        rc = RC_INT;
5048
        sv.type.t = VT_INT;
5049
        if (is_float(t)) {
5050
            rc = RC_FLOAT;
5051
            sv.type.t = t;
5052
        }
5053
        r = gv(rc);
5054
        r1 = get_reg(rc);
5055
        sv.r = r;
5056
        sv.c.ul = 0;
5057
        load(r1, &sv); /* move r to r1 */
5058
        vdup();
5059
        /* duplicates value */
5060
        vtop->r = r1;
5061
    }
5062
}
5063
 
5064
/* generate CPU independent (unsigned) long long operations */
5065
void gen_opl(int op)
5066
{
5067
    int t, a, b, op1, c, i;
5068
    int func;
5069
    SValue tmp;
5070
 
5071
    switch(op) {
5072
    case '/':
5073
    case TOK_PDIV:
5074
        func = TOK___divdi3;
5075
        goto gen_func;
5076
    case TOK_UDIV:
5077
        func = TOK___udivdi3;
5078
        goto gen_func;
5079
    case '%':
5080
        func = TOK___moddi3;
5081
        goto gen_func;
5082
    case TOK_UMOD:
5083
        func = TOK___umoddi3;
5084
    gen_func:
5085
        /* call generic long long function */
5086
        vpush_global_sym(&func_old_type, func);
5087
        vrott(3);
5088
        gfunc_call(2);
5089
        vpushi(0);
5090
        vtop->r = REG_IRET;
5091
        vtop->r2 = REG_LRET;
5092
        break;
5093
    case '^':
5094
    case '&':
5095
    case '|':
5096
    case '*':
5097
    case '+':
5098
    case '-':
5099
        t = vtop->type.t;
5100
        vswap();
5101
        lexpand();
5102
        vrotb(3);
5103
        lexpand();
5104
        /* stack: L1 H1 L2 H2 */
5105
        tmp = vtop[0];
5106
        vtop[0] = vtop[-3];
5107
        vtop[-3] = tmp;
5108
        tmp = vtop[-2];
5109
        vtop[-2] = vtop[-3];
5110
        vtop[-3] = tmp;
5111
        vswap();
5112
        /* stack: H1 H2 L1 L2 */
5113
        if (op == '*') {
5114
            vpushv(vtop - 1);
5115
            vpushv(vtop - 1);
5116
            gen_op(TOK_UMULL);
5117
            lexpand();
5118
            /* stack: H1 H2 L1 L2 ML MH */
5119
            for(i=0;i<4;i++)
5120
                vrotb(6);
5121
            /* stack: ML MH H1 H2 L1 L2 */
5122
            tmp = vtop[0];
5123
            vtop[0] = vtop[-2];
5124
            vtop[-2] = tmp;
5125
            /* stack: ML MH H1 L2 H2 L1 */
5126
            gen_op('*');
5127
            vrotb(3);
5128
            vrotb(3);
5129
            gen_op('*');
5130
            /* stack: ML MH M1 M2 */
5131
            gen_op('+');
5132
            gen_op('+');
5133
        } else if (op == '+' || op == '-') {
5134
            /* XXX: add non carry method too (for MIPS or alpha) */
5135
            if (op == '+')
5136
                op1 = TOK_ADDC1;
5137
            else
5138
                op1 = TOK_SUBC1;
5139
            gen_op(op1);
5140
            /* stack: H1 H2 (L1 op L2) */
5141
            vrotb(3);
5142
            vrotb(3);
5143
            gen_op(op1 + 1); /* TOK_xxxC2 */
5144
        } else {
5145
            gen_op(op);
5146
            /* stack: H1 H2 (L1 op L2) */
5147
            vrotb(3);
5148
            vrotb(3);
5149
            /* stack: (L1 op L2) H1 H2 */
5150
            gen_op(op);
5151
            /* stack: (L1 op L2) (H1 op H2) */
5152
        }
5153
        /* stack: L H */
5154
        lbuild(t);
5155
        break;
5156
    case TOK_SAR:
5157
    case TOK_SHR:
5158
    case TOK_SHL:
5159
        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
5160
            t = vtop[-1].type.t;
5161
            vswap();
5162
            lexpand();
5163
            vrotb(3);
5164
            /* stack: L H shift */
5165
            c = (int)vtop->c.i;
5166
            /* constant: simpler */
5167
            /* NOTE: all comments are for SHL. the other cases are
5168
               done by swaping words */
5169
            vpop();
5170
            if (op != TOK_SHL)
5171
                vswap();
5172
            if (c >= 32) {
5173
                /* stack: L H */
5174
                vpop();
5175
                if (c > 32) {
5176
                    vpushi(c - 32);
5177
                    gen_op(op);
5178
                }
5179
                if (op != TOK_SAR) {
5180
                    vpushi(0);
5181
                } else {
5182
                    gv_dup();
5183
                    vpushi(31);
5184
                    gen_op(TOK_SAR);
5185
                }
5186
                vswap();
5187
            } else {
5188
                vswap();
5189
                gv_dup();
5190
                /* stack: H L L */
5191
                vpushi(c);
5192
                gen_op(op);
5193
                vswap();
5194
                vpushi(32 - c);
5195
                if (op == TOK_SHL)
5196
                    gen_op(TOK_SHR);
5197
                else
5198
                    gen_op(TOK_SHL);
5199
                vrotb(3);
5200
                /* stack: L L H */
5201
                vpushi(c);
5202
                if (op == TOK_SHL)
5203
                    gen_op(TOK_SHL);
5204
                else
5205
                    gen_op(TOK_SHR);
5206
                gen_op('|');
5207
            }
5208
            if (op != TOK_SHL)
5209
                vswap();
5210
            lbuild(t);
5211
        } else {
5212
            /* XXX: should provide a faster fallback on x86 ? */
5213
            switch(op) {
5214
            case TOK_SAR:
5215
                func = TOK___sardi3;
5216
                goto gen_func;
5217
            case TOK_SHR:
5218
                func = TOK___shrdi3;
5219
                goto gen_func;
5220
            case TOK_SHL:
5221
                func = TOK___shldi3;
5222
                goto gen_func;
5223
            }
5224
        }
5225
        break;
5226
    default:
5227
        /* compare operations */
5228
        t = vtop->type.t;
5229
        vswap();
5230
        lexpand();
5231
        vrotb(3);
5232
        lexpand();
5233
        /* stack: L1 H1 L2 H2 */
5234
        tmp = vtop[-1];
5235
        vtop[-1] = vtop[-2];
5236
        vtop[-2] = tmp;
5237
        /* stack: L1 L2 H1 H2 */
5238
        /* compare high */
5239
        op1 = op;
5240
        /* when values are equal, we need to compare low words. since
5241
           the jump is inverted, we invert the test too. */
5242
        if (op1 == TOK_LT)
5243
            op1 = TOK_LE;
5244
        else if (op1 == TOK_GT)
5245
            op1 = TOK_GE;
5246
        else if (op1 == TOK_ULT)
5247
            op1 = TOK_ULE;
5248
        else if (op1 == TOK_UGT)
5249
            op1 = TOK_UGE;
5250
        a = 0;
5251
        b = 0;
5252
        gen_op(op1);
5253
        if (op1 != TOK_NE) {
5254
            a = gtst(1, 0);
5255
        }
5256
        if (op != TOK_EQ) {
5257
            /* generate non equal test */
5258
            /* XXX: NOT PORTABLE yet */
5259
            if (a == 0) {
5260
                b = gtst(0, 0);
5261
            } else {
5262
#if defined(TCC_TARGET_I386)
5263
                b = psym(0x850f, 0);
5264
#elif defined(TCC_TARGET_ARM)
5265
		b = ind;
5266
		o(0x1A000000 | encbranch(ind, 0, 1));
5267
#elif defined(TCC_TARGET_C67)
5268
                error("not implemented");
5269
#else
5270
#error not supported
5271
#endif
5272
            }
5273
        }
5274
        /* compare low. Always unsigned */
5275
        op1 = op;
5276
        if (op1 == TOK_LT)
5277
            op1 = TOK_ULT;
5278
        else if (op1 == TOK_LE)
5279
            op1 = TOK_ULE;
5280
        else if (op1 == TOK_GT)
5281
            op1 = TOK_UGT;
5282
        else if (op1 == TOK_GE)
5283
            op1 = TOK_UGE;
5284
        gen_op(op1);
5285
        a = gtst(1, a);
5286
        gsym(b);
5287
        vseti(VT_JMPI, a);
5288
        break;
5289
    }
5290
}
5291
 
5292
/* handle integer constant optimizations and various machine
5293
   independent opt */
5294
void gen_opic(int op)
5295
{
5296
    int fc, c1, c2, n;
5297
    SValue *v1, *v2;
5298
 
5299
    v1 = vtop - 1;
5300
    v2 = vtop;
5301
    /* currently, we cannot do computations with forward symbols */
5302
    c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5303
    c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5304
    if (c1 && c2) {
5305
        fc = v2->c.i;
5306
        switch(op) {
5307
        case '+': v1->c.i += fc; break;
5308
        case '-': v1->c.i -= fc; break;
5309
        case '&': v1->c.i &= fc; break;
5310
        case '^': v1->c.i ^= fc; break;
5311
        case '|': v1->c.i |= fc; break;
5312
        case '*': v1->c.i *= fc; break;
5313
 
5314
        case TOK_PDIV:
5315
        case '/':
5316
        case '%':
5317
        case TOK_UDIV:
5318
        case TOK_UMOD:
5319
            /* if division by zero, generate explicit division */
5320
            if (fc == 0) {
5321
                if (const_wanted)
5322
                    error("division by zero in constant");
5323
                goto general_case;
5324
            }
5325
            switch(op) {
5326
            default: v1->c.i /= fc; break;
5327
            case '%': v1->c.i %= fc; break;
5328
            case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
5329
            case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
5330
            }
5331
            break;
5332
        case TOK_SHL: v1->c.i <<= fc; break;
5333
        case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
5334
        case TOK_SAR: v1->c.i >>= fc; break;
5335
            /* tests */
5336
        case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
5337
        case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
5338
        case TOK_EQ: v1->c.i = v1->c.i == fc; break;
5339
        case TOK_NE: v1->c.i = v1->c.i != fc; break;
5340
        case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
5341
        case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
5342
        case TOK_LT: v1->c.i = v1->c.i < fc; break;
5343
        case TOK_GE: v1->c.i = v1->c.i >= fc; break;
5344
        case TOK_LE: v1->c.i = v1->c.i <= fc; break;
5345
        case TOK_GT: v1->c.i = v1->c.i > fc; break;
5346
            /* logical */
5347
        case TOK_LAND: v1->c.i = v1->c.i && fc; break;
5348
        case TOK_LOR: v1->c.i = v1->c.i || fc; break;
5349
        default:
5350
            goto general_case;
5351
        }
5352
        vtop--;
5353
    } else {
5354
        /* if commutative ops, put c2 as constant */
5355
        if (c1 && (op == '+' || op == '&' || op == '^' ||
5356
                   op == '|' || op == '*')) {
5357
            vswap();
5358
            swap(&c1, &c2);
5359
        }
5360
        fc = vtop->c.i;
5361
        if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
5362
                     op == TOK_PDIV) &&
5363
                    fc == 1) ||
5364
                   ((op == '+' || op == '-' || op == '|' || op == '^' ||
5365
                     op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
5366
                    fc == 0) ||
5367
                   (op == '&' &&
5368
                    fc == -1))) {
5369
            /* nothing to do */
5370
            vtop--;
5371
        } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
5372
            /* try to use shifts instead of muls or divs */
5373
            if (fc > 0 && (fc & (fc - 1)) == 0) {
5374
                n = -1;
5375
                while (fc) {
5376
                    fc >>= 1;
5377
                    n++;
5378
                }
5379
                vtop->c.i = n;
5380
                if (op == '*')
5381
                    op = TOK_SHL;
5382
                else if (op == TOK_PDIV)
5383
                    op = TOK_SAR;
5384
                else
5385
                    op = TOK_SHR;
5386
            }
5387
            goto general_case;
5388
        } else if (c2 && (op == '+' || op == '-') &&
5389
                   (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
5390
                   (VT_CONST | VT_SYM)) {
5391
            /* symbol + constant case */
5392
            if (op == '-')
5393
                fc = -fc;
5394
            vtop--;
5395
            vtop->c.i += fc;
5396
        } else {
5397
        general_case:
5398
            if (!nocode_wanted) {
5399
                /* call low level op generator */
5400
                gen_opi(op);
5401
            } else {
5402
                vtop--;
5403
            }
5404
        }
5405
    }
5406
}
5407
 
5408
/* generate a floating point operation with constant propagation */
5409
void gen_opif(int op)
5410
{
5411
    int c1, c2;
5412
    SValue *v1, *v2;
5413
    long double f1, f2;
5414
 
5415
    v1 = vtop - 1;
5416
    v2 = vtop;
5417
    /* currently, we cannot do computations with forward symbols */
5418
    c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5419
    c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5420
    if (c1 && c2) {
5421
        if (v1->type.t == VT_FLOAT) {
5422
            f1 = v1->c.f;
5423
            f2 = v2->c.f;
5424
        } else if (v1->type.t == VT_DOUBLE) {
5425
            f1 = v1->c.d;
5426
            f2 = v2->c.d;
5427
        } else {
5428
            f1 = v1->c.ld;
5429
            f2 = v2->c.ld;
5430
        }
5431
 
5432
        /* NOTE: we only do constant propagation if finite number (not
5433
           NaN or infinity) (ANSI spec) */
5434
        if (!ieee_finite(f1) || !ieee_finite(f2))
5435
            goto general_case;
5436
 
5437
        switch(op) {
5438
        case '+': f1 += f2; break;
5439
        case '-': f1 -= f2; break;
5440
        case '*': f1 *= f2; break;
5441
        case '/':
5442
            if (f2 == 0.0) {
5443
                if (const_wanted)
5444
                    error("division by zero in constant");
5445
                goto general_case;
5446
            }
5447
            f1 /= f2;
5448
            break;
5449
            /* XXX: also handles tests ? */
5450
        default:
5451
            goto general_case;
5452
        }
5453
        /* XXX: overflow test ? */
5454
        if (v1->type.t == VT_FLOAT) {
5455
            v1->c.f = f1;
5456
        } else if (v1->type.t == VT_DOUBLE) {
5457
            v1->c.d = f1;
5458
        } else {
5459
            v1->c.ld = f1;
5460
        }
5461
        vtop--;
5462
    } else {
5463
    general_case:
5464
        if (!nocode_wanted) {
5465
            gen_opf(op);
5466
        } else {
5467
            vtop--;
5468
        }
5469
    }
5470
}
5471
 
5472
static int pointed_size(CType *type)
5473
{
5474
    int align;
5475
    return type_size(pointed_type(type), &align);
5476
}
5477
 
5478
static inline int is_null_pointer(SValue *p)
5479
{
5480
    if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
5481
        return 0;
5482
    return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
5483
        ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
5484
}
5485
 
5486
static inline int is_integer_btype(int bt)
5487
{
5488
    return (bt == VT_BYTE || bt == VT_SHORT ||
5489
            bt == VT_INT || bt == VT_LLONG);
5490
}
5491
 
5492
/* check types for comparison or substraction of pointers */
5493
static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
5494
{
5495
    CType *type1, *type2, tmp_type1, tmp_type2;
5496
    int bt1, bt2;
5497
 
5498
    /* null pointers are accepted for all comparisons as gcc */
5499
    if (is_null_pointer(p1) || is_null_pointer(p2))
5500
        return;
5501
    type1 = &p1->type;
5502
    type2 = &p2->type;
5503
    bt1 = type1->t & VT_BTYPE;
5504
    bt2 = type2->t & VT_BTYPE;
5505
    /* accept comparison between pointer and integer with a warning */
5506
    if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
5507
        warning("comparison between pointer and integer");
5508
        return;
5509
    }
5510
 
5511
    /* both must be pointers or implicit function pointers */
5512
    if (bt1 == VT_PTR) {
5513
        type1 = pointed_type(type1);
5514
    } else if (bt1 != VT_FUNC)
5515
        goto invalid_operands;
5516
 
5517
    if (bt2 == VT_PTR) {
5518
        type2 = pointed_type(type2);
5519
    } else if (bt2 != VT_FUNC) {
5520
    invalid_operands:
5521
        error("invalid operands to binary %s", get_tok_str(op, NULL));
5522
    }
5523
    if ((type1->t & VT_BTYPE) == VT_VOID ||
5524
        (type2->t & VT_BTYPE) == VT_VOID)
5525
        return;
5526
    tmp_type1 = *type1;
5527
    tmp_type2 = *type2;
5528
    tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
5529
    tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
5530
    if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
5531
        /* gcc-like error if '-' is used */
5532
        if (op == '-')
5533
            goto invalid_operands;
5534
        else
5535
            warning("comparison of distinct pointer types lacks a cast");
5536
    }
5537
}
5538
 
5539
/* generic gen_op: handles types problems */
5540
void gen_op(int op)
5541
{
5542
    int u, t1, t2, bt1, bt2, t;
5543
    CType type1;
5544
 
5545
    t1 = vtop[-1].type.t;
5546
    t2 = vtop[0].type.t;
5547
    bt1 = t1 & VT_BTYPE;
5548
    bt2 = t2 & VT_BTYPE;
5549
 
5550
    if (bt1 == VT_PTR || bt2 == VT_PTR) {
5551
        /* at least one operand is a pointer */
5552
        /* relationnal op: must be both pointers */
5553
        if (op >= TOK_ULT && op <= TOK_GT) {
5554
            check_comparison_pointer_types(vtop - 1, vtop, op);
5555
            /* pointers are handled are unsigned */
5556
            t = VT_INT | VT_UNSIGNED;
5557
            goto std_op;
5558
        }
5559
        /* if both pointers, then it must be the '-' op */
5560
        if (bt1 == VT_PTR && bt2 == VT_PTR) {
5561
            if (op != '-')
5562
                error("cannot use pointers here");
5563
            check_comparison_pointer_types(vtop - 1, vtop, op);
5564
            /* XXX: check that types are compatible */
5565
            u = pointed_size(&vtop[-1].type);
5566
            gen_opic(op);
5567
            /* set to integer type */
5568
            vtop->type.t = VT_INT;
5569
            vpushi(u);
5570
            gen_op(TOK_PDIV);
5571
        } else {
5572
            /* exactly one pointer : must be '+' or '-'. */
5573
            if (op != '-' && op != '+')
5574
                error("cannot use pointers here");
5575
            /* Put pointer as first operand */
5576
            if (bt2 == VT_PTR) {
5577
                vswap();
5578
                swap(&t1, &t2);
5579
            }
5580
            type1 = vtop[-1].type;
5581
            /* XXX: cast to int ? (long long case) */
5582
            vpushi(pointed_size(&vtop[-1].type));
5583
            gen_op('*');
5584
#ifdef CONFIG_TCC_BCHECK
5585
            /* if evaluating constant expression, no code should be
5586
               generated, so no bound check */
5587
            if (do_bounds_check && !const_wanted) {
5588
                /* if bounded pointers, we generate a special code to
5589
                   test bounds */
5590
                if (op == '-') {
5591
                    vpushi(0);
5592
                    vswap();
5593
                    gen_op('-');
5594
                }
5595
                gen_bounded_ptr_add();
5596
            } else
5597
#endif
5598
            {
5599
                gen_opic(op);
5600
            }
5601
            /* put again type if gen_opic() swaped operands */
5602
            vtop->type = type1;
5603
        }
5604
    } else if (is_float(bt1) || is_float(bt2)) {
5605
        /* compute bigger type and do implicit casts */
5606
        if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
5607
            t = VT_LDOUBLE;
5608
        } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
5609
            t = VT_DOUBLE;
5610
        } else {
5611
            t = VT_FLOAT;
5612
        }
5613
        /* floats can only be used for a few operations */
5614
        if (op != '+' && op != '-' && op != '*' && op != '/' &&
5615
            (op < TOK_ULT || op > TOK_GT))
5616
            error("invalid operands for binary operation");
5617
        goto std_op;
5618
    } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
5619
        /* cast to biggest op */
5620
        t = VT_LLONG;
5621
        /* convert to unsigned if it does not fit in a long long */
5622
        if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
5623
            (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
5624
            t |= VT_UNSIGNED;
5625
        goto std_op;
5626
    } else {
5627
        /* integer operations */
5628
        t = VT_INT;
5629
        /* convert to unsigned if it does not fit in an integer */
5630
        if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
5631
            (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
5632
            t |= VT_UNSIGNED;
5633
    std_op:
5634
        /* XXX: currently, some unsigned operations are explicit, so
5635
           we modify them here */
5636
        if (t & VT_UNSIGNED) {
5637
            if (op == TOK_SAR)
5638
                op = TOK_SHR;
5639
            else if (op == '/')
5640
                op = TOK_UDIV;
5641
            else if (op == '%')
5642
                op = TOK_UMOD;
5643
            else if (op == TOK_LT)
5644
                op = TOK_ULT;
5645
            else if (op == TOK_GT)
5646
                op = TOK_UGT;
5647
            else if (op == TOK_LE)
5648
                op = TOK_ULE;
5649
            else if (op == TOK_GE)
5650
                op = TOK_UGE;
5651
        }
5652
        vswap();
5653
        type1.t = t;
5654
        gen_cast(&type1);
5655
        vswap();
5656
        /* special case for shifts and long long: we keep the shift as
5657
           an integer */
5658
        if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
5659
            type1.t = VT_INT;
5660
        gen_cast(&type1);
5661
        if (is_float(t))
5662
            gen_opif(op);
5663
        else if ((t & VT_BTYPE) == VT_LLONG)
5664
            gen_opl(op);
5665
        else
5666
            gen_opic(op);
5667
        if (op >= TOK_ULT && op <= TOK_GT) {
5668
            /* relationnal op: the result is an int */
5669
            vtop->type.t = VT_INT;
5670
        } else {
5671
            vtop->type.t = t;
5672
        }
5673
    }
5674
}
5675
 
5676
/* generic itof for unsigned long long case */
5677
void gen_cvt_itof1(int t)
5678
{
5679
    if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
5680
        (VT_LLONG | VT_UNSIGNED)) {
5681
 
5682
        if (t == VT_FLOAT)
5683
            vpush_global_sym(&func_old_type, TOK___ulltof);
5684
        else if (t == VT_DOUBLE)
5685
            vpush_global_sym(&func_old_type, TOK___ulltod);
5686
        else
5687
            vpush_global_sym(&func_old_type, TOK___ulltold);
5688
        vrott(2);
5689
        gfunc_call(1);
5690
        vpushi(0);
5691
        vtop->r = REG_FRET;
5692
    } else {
5693
        gen_cvt_itof(t);
5694
    }
5695
}
5696
 
5697
/* generic ftoi for unsigned long long case */
5698
void gen_cvt_ftoi1(int t)
5699
{
5700
    int st;
5701
 
5702
    if (t == (VT_LLONG | VT_UNSIGNED)) {
5703
        /* not handled natively */
5704
        st = vtop->type.t & VT_BTYPE;
5705
        if (st == VT_FLOAT)
5706
            vpush_global_sym(&func_old_type, TOK___fixunssfdi);
5707
        else if (st == VT_DOUBLE)
5708
            vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
5709
        else
5710
            vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
5711
        vrott(2);
5712
        gfunc_call(1);
5713
        vpushi(0);
5714
        vtop->r = REG_IRET;
5715
        vtop->r2 = REG_LRET;
5716
    } else {
5717
        gen_cvt_ftoi(t);
5718
    }
5719
}
5720
 
5721
/* force char or short cast */
5722
void force_charshort_cast(int t)
5723
{
5724
    int bits, dbt;
5725
    dbt = t & VT_BTYPE;
5726
    /* XXX: add optimization if lvalue : just change type and offset */
5727
    if (dbt == VT_BYTE)
5728
        bits = 8;
5729
    else
5730
        bits = 16;
5731
    if (t & VT_UNSIGNED) {
5732
        vpushi((1 << bits) - 1);
5733
        gen_op('&');
5734
    } else {
5735
        bits = 32 - bits;
5736
        vpushi(bits);
5737
        gen_op(TOK_SHL);
5738
        vpushi(bits);
5739
        gen_op(TOK_SAR);
5740
    }
5741
}
5742
 
5743
/* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
5744
static void gen_cast(CType *type)
5745
{
5746
    int sbt, dbt, sf, df, c;
5747
 
5748
    /* special delayed cast for char/short */
5749
    /* XXX: in some cases (multiple cascaded casts), it may still
5750
       be incorrect */
5751
    if (vtop->r & VT_MUSTCAST) {
5752
        vtop->r &= ~VT_MUSTCAST;
5753
        force_charshort_cast(vtop->type.t);
5754
    }
5755
 
5756
    /* bitfields first get cast to ints */
5757
    if (vtop->type.t & VT_BITFIELD) {
5758
        gv(RC_INT);
5759
    }
5760
 
5761
    dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
5762
    sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
5763
 
5764
    if (sbt != dbt && !nocode_wanted) {
5765
        sf = is_float(sbt);
5766
        df = is_float(dbt);
5767
        c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
5768
        if (sf && df) {
5769
            /* convert from fp to fp */
5770
            if (c) {
5771
                /* constant case: we can do it now */
5772
                /* XXX: in ISOC, cannot do it if error in convert */
5773
                if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
5774
                    vtop->c.f = (float)vtop->c.d;
5775
                else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
5776
                    vtop->c.f = (float)vtop->c.ld;
5777
                else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
5778
                    vtop->c.d = (double)vtop->c.f;
5779
                else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
5780
                    vtop->c.d = (double)vtop->c.ld;
5781
                else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
5782
                    vtop->c.ld = (long double)vtop->c.f;
5783
                else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
5784
                    vtop->c.ld = (long double)vtop->c.d;
5785
            } else {
5786
                /* non constant case: generate code */
5787
                gen_cvt_ftof(dbt);
5788
            }
5789
        } else if (df) {
5790
            /* convert int to fp */
5791
            if (c) {
5792
                switch(sbt) {
5793
                case VT_LLONG | VT_UNSIGNED:
5794
                case VT_LLONG:
5795
                    /* XXX: add const cases for long long */
5796
                    goto do_itof;
5797
                case VT_INT | VT_UNSIGNED:
5798
                    switch(dbt) {
5799
                    case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
5800
                    case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
5801
                    case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
5802
                    }
5803
                    break;
5804
                default:
5805
                    switch(dbt) {
5806
                    case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
5807
                    case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
5808
                    case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
5809
                    }
5810
                    break;
5811
                }
5812
            } else {
5813
            do_itof:
5814
#if !defined(TCC_TARGET_ARM)
5815
                gen_cvt_itof1(dbt);
5816
#else
5817
                gen_cvt_itof(dbt);
5818
#endif
5819
            }
5820
        } else if (sf) {
5821
            /* convert fp to int */
5822
            /* we handle char/short/etc... with generic code */
5823
            if (dbt != (VT_INT | VT_UNSIGNED) &&
5824
                dbt != (VT_LLONG | VT_UNSIGNED) &&
5825
                dbt != VT_LLONG)
5826
                dbt = VT_INT;
5827
            if (c) {
5828
                switch(dbt) {
5829
                case VT_LLONG | VT_UNSIGNED:
5830
                case VT_LLONG:
5831
                    /* XXX: add const cases for long long */
5832
                    goto do_ftoi;
5833
                case VT_INT | VT_UNSIGNED:
5834
                    switch(sbt) {
5835
                    case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
5836
                    case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5837
                    case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
5838
                    }
5839
                    break;
5840
                default:
5841
                    /* int case */
5842
                    switch(sbt) {
5843
                    case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
5844
                    case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
5845
                    case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
5846
                    }
5847
                    break;
5848
                }
5849
            } else {
5850
            do_ftoi:
5851
                gen_cvt_ftoi1(dbt);
5852
            }
5853
            if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
5854
                /* additional cast for char/short/bool... */
5855
                vtop->type.t = dbt;
5856
                gen_cast(type);
5857
            }
5858
        } else if ((dbt & VT_BTYPE) == VT_LLONG) {
5859
            if ((sbt & VT_BTYPE) != VT_LLONG) {
5860
                /* scalar to long long */
5861
                if (c) {
5862
                    if (sbt == (VT_INT | VT_UNSIGNED))
5863
                        vtop->c.ll = vtop->c.ui;
5864
                    else
5865
                        vtop->c.ll = vtop->c.i;
5866
                } else {
5867
                    /* machine independent conversion */
5868
                    gv(RC_INT);
5869
                    /* generate high word */
5870
                    if (sbt == (VT_INT | VT_UNSIGNED)) {
5871
                        vpushi(0);
5872
                        gv(RC_INT);
5873
                    } else {
5874
                        gv_dup();
5875
                        vpushi(31);
5876
                        gen_op(TOK_SAR);
5877
                    }
5878
                    /* patch second register */
5879
                    vtop[-1].r2 = vtop->r;
5880
                    vpop();
5881
                }
5882
            }
5883
        } else if (dbt == VT_BOOL) {
5884
            /* scalar to bool */
5885
            vpushi(0);
5886
            gen_op(TOK_NE);
5887
        } else if ((dbt & VT_BTYPE) == VT_BYTE ||
5888
                   (dbt & VT_BTYPE) == VT_SHORT) {
5889
            force_charshort_cast(dbt);
5890
        } else if ((dbt & VT_BTYPE) == VT_INT) {
5891
            /* scalar to int */
5892
            if (sbt == VT_LLONG) {
5893
                /* from long long: just take low order word */
5894
                lexpand();
5895
                vpop();
5896
            }
5897
            /* if lvalue and single word type, nothing to do because
5898
               the lvalue already contains the real type size (see
5899
               VT_LVAL_xxx constants) */
5900
        }
5901
    }
5902
    vtop->type = *type;
5903
}
5904
 
5905
/* return type size. Put alignment at 'a' */
5906
static int type_size(CType *type, int *a)
5907
{
5908
    Sym *s;
5909
    int bt;
5910
 
5911
    bt = type->t & VT_BTYPE;
5912
    if (bt == VT_STRUCT) {
5913
        /* struct/union */
5914
        s = type->ref;
5915
        *a = s->r;
5916
        return s->c;
5917
    } else if (bt == VT_PTR) {
5918
        if (type->t & VT_ARRAY) {
5919
            s = type->ref;
5920
            return type_size(&s->type, a) * s->c;
5921
        } else {
5922
            *a = PTR_SIZE;
5923
            return PTR_SIZE;
5924
        }
5925
    } else if (bt == VT_LDOUBLE) {
5926
        *a = LDOUBLE_ALIGN;
5927
        return LDOUBLE_SIZE;
5928
    } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
5929
#ifdef TCC_TARGET_I386
5930
        *a = 4;
5931
#else
5932
        *a = 8;
5933
#endif
5934
        return 8;
5935
    } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
5936
        *a = 4;
5937
        return 4;
5938
    } else if (bt == VT_SHORT) {
5939
        *a = 2;
5940
        return 2;
5941
    } else {
5942
        /* char, void, function, _Bool */
5943
        *a = 1;
5944
        return 1;
5945
    }
5946
}
5947
 
5948
/* return the pointed type of t */
5949
static inline CType *pointed_type(CType *type)
5950
{
5951
    return &type->ref->type;
5952
}
5953
 
5954
/* modify type so that its it is a pointer to type. */
5955
static void mk_pointer(CType *type)
5956
{
5957
    Sym *s;
5958
    s = sym_push(SYM_FIELD, type, 0, -1);
5959
    type->t = VT_PTR | (type->t & ~VT_TYPE);
5960
    type->ref = s;
5961
}
5962
 
5963
/* compare function types. OLD functions match any new functions */
5964
static int is_compatible_func(CType *type1, CType *type2)
5965
{
5966
    Sym *s1, *s2;
5967
 
5968
    s1 = type1->ref;
5969
    s2 = type2->ref;
5970
    if (!is_compatible_types(&s1->type, &s2->type))
5971
        return 0;
5972
    /* check func_call */
5973
    if (s1->r != s2->r)
5974
        return 0;
5975
    /* XXX: not complete */
5976
    if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
5977
        return 1;
5978
    if (s1->c != s2->c)
5979
        return 0;
5980
    while (s1 != NULL) {
5981
        if (s2 == NULL)
5982
            return 0;
5983
        if (!is_compatible_types(&s1->type, &s2->type))
5984
            return 0;
5985
        s1 = s1->next;
5986
        s2 = s2->next;
5987
    }
5988
    if (s2)
5989
        return 0;
5990
    return 1;
5991
}
5992
 
5993
/* return true if type1 and type2 are exactly the same (including
5994
   qualifiers).
5995
 
5996
   - enums are not checked as gcc __builtin_types_compatible_p ()
5997
 */
5998
static int is_compatible_types(CType *type1, CType *type2)
5999
{
6000
    int bt1, t1, t2;
6001
 
6002
    t1 = type1->t & VT_TYPE;
6003
    t2 = type2->t & VT_TYPE;
6004
    /* XXX: bitfields ? */
6005
    if (t1 != t2)
6006
        return 0;
6007
    /* test more complicated cases */
6008
    bt1 = t1 & VT_BTYPE;
6009
    if (bt1 == VT_PTR) {
6010
        type1 = pointed_type(type1);
6011
        type2 = pointed_type(type2);
6012
        return is_compatible_types(type1, type2);
6013
    } else if (bt1 == VT_STRUCT) {
6014
        return (type1->ref == type2->ref);
6015
    } else if (bt1 == VT_FUNC) {
6016
        return is_compatible_func(type1, type2);
6017
    } else {
6018
        return 1;
6019
    }
6020
}
6021
 
6022
/* print a type. If 'varstr' is not NULL, then the variable is also
6023
   printed in the type */
6024
/* XXX: union */
6025
/* XXX: add array and function pointers */
6026
void type_to_str(char *buf, int buf_size,
6027
                 CType *type, const char *varstr)
6028
{
6029
    int bt, v, t;
6030
    Sym *s, *sa;
6031
    char buf1[256];
6032
    const char *tstr;
6033
 
6034
    t = type->t & VT_TYPE;
6035
    bt = t & VT_BTYPE;
6036
    buf[0] = '\0';
6037
    if (t & VT_CONSTANT)
6038
        pstrcat(buf, buf_size, "const ");
6039
    if (t & VT_VOLATILE)
6040
        pstrcat(buf, buf_size, "volatile ");
6041
    if (t & VT_UNSIGNED)
6042
        pstrcat(buf, buf_size, "unsigned ");
6043
    switch(bt) {
6044
    case VT_VOID:
6045
        tstr = "void";
6046
        goto add_tstr;
6047
    case VT_BOOL:
6048
        tstr = "_Bool";
6049
        goto add_tstr;
6050
    case VT_BYTE:
6051
        tstr = "char";
6052
        goto add_tstr;
6053
    case VT_SHORT:
6054
        tstr = "short";
6055
        goto add_tstr;
6056
    case VT_INT:
6057
        tstr = "int";
6058
        goto add_tstr;
6059
    case VT_LONG:
6060
        tstr = "long";
6061
        goto add_tstr;
6062
    case VT_LLONG:
6063
        tstr = "long long";
6064
        goto add_tstr;
6065
    case VT_FLOAT:
6066
        tstr = "float";
6067
        goto add_tstr;
6068
    case VT_DOUBLE:
6069
        tstr = "double";
6070
        goto add_tstr;
6071
    case VT_LDOUBLE:
6072
        tstr = "long double";
6073
    add_tstr:
6074
        pstrcat(buf, buf_size, tstr);
6075
        break;
6076
    case VT_ENUM:
6077
    case VT_STRUCT:
6078
        if (bt == VT_STRUCT)
6079
            tstr = "struct ";
6080
        else
6081
            tstr = "enum ";
6082
        pstrcat(buf, buf_size, tstr);
6083
        v = type->ref->v & ~SYM_STRUCT;
6084
        if (v >= SYM_FIRST_ANOM)
6085
            pstrcat(buf, buf_size, "");
6086
        else
6087
            pstrcat(buf, buf_size, get_tok_str(v, NULL));
6088
        break;
6089
    case VT_FUNC:
6090
        s = type->ref;
6091
        type_to_str(buf, buf_size, &s->type, varstr);
6092
        pstrcat(buf, buf_size, "(");
6093
        sa = s->next;
6094
        while (sa != NULL) {
6095
            type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
6096
            pstrcat(buf, buf_size, buf1);
6097
            sa = sa->next;
6098
            if (sa)
6099
                pstrcat(buf, buf_size, ", ");
6100
        }
6101
        pstrcat(buf, buf_size, ")");
6102
        goto no_var;
6103
    case VT_PTR:
6104
        s = type->ref;
6105
        pstrcpy(buf1, sizeof(buf1), "*");
6106
        if (varstr)
6107
            pstrcat(buf1, sizeof(buf1), varstr);
6108
        type_to_str(buf, buf_size, &s->type, buf1);
6109
        goto no_var;
6110
    }
6111
    if (varstr) {
6112
        pstrcat(buf, buf_size, " ");
6113
        pstrcat(buf, buf_size, varstr);
6114
    }
6115
 no_var: ;
6116
}
6117
 
6118
/* verify type compatibility to store vtop in 'dt' type, and generate
6119
   casts if needed. */
6120
static void gen_assign_cast(CType *dt)
6121
{
6122
    CType *st, *type1, *type2, tmp_type1, tmp_type2;
6123
    char buf1[256], buf2[256];
6124
    int dbt, sbt;
6125
 
6126
    st = &vtop->type; /* source type */
6127
    dbt = dt->t & VT_BTYPE;
6128
    sbt = st->t & VT_BTYPE;
6129
    if (dt->t & VT_CONSTANT)
6130
        warning("assignment of read-only location");
6131
    switch(dbt) {
6132
    case VT_PTR:
6133
        /* special cases for pointers */
6134
        /* '0' can also be a pointer */
6135
        if (is_null_pointer(vtop))
6136
            goto type_ok;
6137
        /* accept implicit pointer to integer cast with warning */
6138
        if (is_integer_btype(sbt)) {
6139
            warning("assignment makes pointer from integer without a cast");
6140
            goto type_ok;
6141
        }
6142
        type1 = pointed_type(dt);
6143
        /* a function is implicitely a function pointer */
6144
        if (sbt == VT_FUNC) {
6145
            if ((type1->t & VT_BTYPE) != VT_VOID &&
6146
                !is_compatible_types(pointed_type(dt), st))
6147
                goto error;
6148
            else
6149
                goto type_ok;
6150
        }
6151
        if (sbt != VT_PTR)
6152
            goto error;
6153
        type2 = pointed_type(st);
6154
        if ((type1->t & VT_BTYPE) == VT_VOID ||
6155
            (type2->t & VT_BTYPE) == VT_VOID) {
6156
            /* void * can match anything */
6157
        } else {
6158
            /* exact type match, except for unsigned */
6159
            tmp_type1 = *type1;
6160
            tmp_type2 = *type2;
6161
            tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
6162
            tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
6163
            if (!is_compatible_types(&tmp_type1, &tmp_type2))
6164
                goto error;
6165
        }
6166
        /* check const and volatile */
6167
        if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
6168
            (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
6169
            warning("assignment discards qualifiers from pointer target type");
6170
        break;
6171
    case VT_BYTE:
6172
    case VT_SHORT:
6173
    case VT_INT:
6174
    case VT_LLONG:
6175
        if (sbt == VT_PTR || sbt == VT_FUNC) {
6176
            warning("assignment makes integer from pointer without a cast");
6177
        }
6178
        /* XXX: more tests */
6179
        break;
6180
    case VT_STRUCT:
6181
        tmp_type1 = *dt;
6182
        tmp_type2 = *st;
6183
        tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
6184
        tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
6185
        if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
6186
        error:
6187
            type_to_str(buf1, sizeof(buf1), st, NULL);
6188
            type_to_str(buf2, sizeof(buf2), dt, NULL);
6189
            error("cannot cast '%s' to '%s'", buf1, buf2);
6190
        }
6191
        break;
6192
    }
6193
 type_ok:
6194
    gen_cast(dt);
6195
}
6196
 
6197
/* store vtop in lvalue pushed on stack */
6198
void vstore(void)
6199
{
6200
    int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
6201
 
6202
    ft = vtop[-1].type.t;
6203
    sbt = vtop->type.t & VT_BTYPE;
6204
    dbt = ft & VT_BTYPE;
6205
    if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
6206
        (sbt == VT_INT && dbt == VT_SHORT)) {
6207
        /* optimize char/short casts */
6208
        delayed_cast = VT_MUSTCAST;
6209
        vtop->type.t = ft & VT_TYPE;
6210
        /* XXX: factorize */
6211
        if (ft & VT_CONSTANT)
6212
            warning("assignment of read-only location");
6213
    } else {
6214
        delayed_cast = 0;
6215
        if (!(ft & VT_BITFIELD))
6216
            gen_assign_cast(&vtop[-1].type);
6217
    }
6218
 
6219
    if (sbt == VT_STRUCT) {
6220
        /* if structure, only generate pointer */
6221
        /* structure assignment : generate memcpy */
6222
        /* XXX: optimize if small size */
6223
        if (!nocode_wanted) {
6224
            size = type_size(&vtop->type, &align);
6225
 
6226
            vpush_global_sym(&func_old_type, TOK_memcpy);
6227
 
6228
            /* destination */
6229
            vpushv(vtop - 2);
6230
            vtop->type.t = VT_INT;
6231
            gaddrof();
6232
            /* source */
6233
            vpushv(vtop - 2);
6234
            vtop->type.t = VT_INT;
6235
            gaddrof();
6236
            /* type size */
6237
            vpushi(size);
6238
            gfunc_call(3);
6239
 
6240
            vswap();
6241
            vpop();
6242
        } else {
6243
            vswap();
6244
            vpop();
6245
        }
6246
        /* leave source on stack */
6247
    } else if (ft & VT_BITFIELD) {
6248
        /* bitfield store handling */
6249
        bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
6250
        bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
6251
        /* remove bit field info to avoid loops */
6252
        vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
6253
 
6254
        /* duplicate destination */
6255
        vdup();
6256
        vtop[-1] = vtop[-2];
6257
 
6258
        /* mask and shift source */
6259
        vpushi((1 << bit_size) - 1);
6260
        gen_op('&');
6261
        vpushi(bit_pos);
6262
        gen_op(TOK_SHL);
6263
        /* load destination, mask and or with source */
6264
        vswap();
6265
        vpushi(~(((1 << bit_size) - 1) << bit_pos));
6266
        gen_op('&');
6267
        gen_op('|');
6268
        /* store result */
6269
        vstore();
6270
    } else {
6271
#ifdef CONFIG_TCC_BCHECK
6272
        /* bound check case */
6273
        if (vtop[-1].r & VT_MUSTBOUND) {
6274
            vswap();
6275
            gbound();
6276
            vswap();
6277
        }
6278
#endif
6279
        if (!nocode_wanted) {
6280
            rc = RC_INT;
6281
            if (is_float(ft))
6282
                rc = RC_FLOAT;
6283
            r = gv(rc);  /* generate value */
6284
            /* if lvalue was saved on stack, must read it */
6285
            if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
6286
                SValue sv;
6287
                t = get_reg(RC_INT);
6288
                sv.type.t = VT_INT;
6289
                sv.r = VT_LOCAL | VT_LVAL;
6290
                sv.c.ul = vtop[-1].c.ul;
6291
                load(t, &sv);
6292
                vtop[-1].r = t | VT_LVAL;
6293
            }
6294
            store(r, vtop - 1);
6295
            /* two word case handling : store second register at word + 4 */
6296
            if ((ft & VT_BTYPE) == VT_LLONG) {
6297
                vswap();
6298
                /* convert to int to increment easily */
6299
                vtop->type.t = VT_INT;
6300
                gaddrof();
6301
                vpushi(4);
6302
                gen_op('+');
6303
                vtop->r |= VT_LVAL;
6304
                vswap();
6305
                /* XXX: it works because r2 is spilled last ! */
6306
                store(vtop->r2, vtop - 1);
6307
            }
6308
        }
6309
        vswap();
6310
        vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
6311
        vtop->r |= delayed_cast;
6312
    }
6313
}
6314
 
6315
/* post defines POST/PRE add. c is the token ++ or -- */
6316
void inc(int post, int c)
6317
{
6318
    test_lvalue();
6319
    vdup(); /* save lvalue */
6320
    if (post) {
6321
        gv_dup(); /* duplicate value */
6322
        vrotb(3);
6323
        vrotb(3);
6324
    }
6325
    /* add constant */
6326
    vpushi(c - TOK_MID);
6327
    gen_op('+');
6328
    vstore(); /* store value */
6329
    if (post)
6330
        vpop(); /* if post op, return saved value */
6331
}
6332
 
6333
/* Parse GNUC __attribute__ extension. Currently, the following
6334
   extensions are recognized:
6335
   - aligned(n) : set data/function alignment.
6336
   - packed : force data alignment to 1
6337
   - section(x) : generate data/code in this section.
6338
   - unused : currently ignored, but may be used someday.
6339
   - regparm(n) : pass function parameters in registers (i386 only)
6340
 */
6341
static void parse_attribute(AttributeDef *ad)
6342
{
6343
    int t, n;
6344
 
6345
    while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
6346
    next();
6347
    skip('(');
6348
    skip('(');
6349
    while (tok != ')') {
6350
        if (tok < TOK_IDENT)
6351
            expect("attribute name");
6352
        t = tok;
6353
        next();
6354
        switch(t) {
6355
        case TOK_SECTION1:
6356
        case TOK_SECTION2:
6357
            skip('(');
6358
            if (tok != TOK_STR)
6359
                expect("section name");
6360
            ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
6361
            next();
6362
            skip(')');
6363
            break;
6364
        case TOK_ALIGNED1:
6365
        case TOK_ALIGNED2:
6366
            if (tok == '(') {
6367
                next();
6368
                n = expr_const();
6369
                if (n <= 0 || (n & (n - 1)) != 0)
6370
                    error("alignment must be a positive power of two");
6371
                skip(')');
6372
            } else {
6373
                n = MAX_ALIGN;
6374
            }
6375
            ad->aligned = n;
6376
            break;
6377
        case TOK_PACKED1:
6378
        case TOK_PACKED2:
6379
            ad->packed = 1;
6380
            break;
6381
        case TOK_UNUSED1:
6382
        case TOK_UNUSED2:
6383
            /* currently, no need to handle it because tcc does not
6384
               track unused objects */
6385
            break;
6386
        case TOK_NORETURN1:
6387
        case TOK_NORETURN2:
6388
            /* currently, no need to handle it because tcc does not
6389
               track unused objects */
6390
            break;
6391
        case TOK_CDECL1:
6392
        case TOK_CDECL2:
6393
        case TOK_CDECL3:
6394
            ad->func_call = FUNC_CDECL;
6395
            break;
6396
        case TOK_STDCALL1:
6397
        case TOK_STDCALL2:
6398
        case TOK_STDCALL3:
6399
            ad->func_call = FUNC_STDCALL;
6400
            break;
6401
#ifdef TCC_TARGET_I386
6402
        case TOK_REGPARM1:
6403
        case TOK_REGPARM2:
6404
            skip('(');
6405
            n = expr_const();
6406
            if (n > 3)
6407
                n = 3;
6408
            else if (n < 0)
6409
                n = 0;
6410
            if (n > 0)
6411
                ad->func_call = FUNC_FASTCALL1 + n - 1;
6412
            skip(')');
6413
            break;
6414
#endif
6415
        case TOK_DLLEXPORT:
6416
            ad->dllexport = 1;
6417
            break;
6418
        default:
6419
            if (tcc_state->warn_unsupported)
6420
                warning("'%s' attribute ignored", get_tok_str(t, NULL));
6421
            /* skip parameters */
6422
            /* XXX: skip parenthesis too */
6423
            if (tok == '(') {
6424
                next();
6425
                while (tok != ')' && tok != -1)
6426
                    next();
6427
                next();
6428
            }
6429
            break;
6430
        }
6431
        if (tok != ',')
6432
            break;
6433
        next();
6434
    }
6435
    skip(')');
6436
    skip(')');
6437
    }
6438
}
6439
 
6440
/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
6441
static void struct_decl(CType *type, int u)
6442
{
6443
    int a, v, size, align, maxalign, c, offset;
6444
    int bit_size, bit_pos, bsize, bt, lbit_pos;
6445
    Sym *s, *ss, **ps;
6446
    AttributeDef ad;
6447
    CType type1, btype;
6448
 
6449
    a = tok; /* save decl type */
6450
    next();
6451
    if (tok != '{') {
6452
        v = tok;
6453
        next();
6454
        /* struct already defined ? return it */
6455
        if (v < TOK_IDENT)
6456
            expect("struct/union/enum name");
6457
        s = struct_find(v);
6458
        if (s) {
6459
            if (s->type.t != a)
6460
                error("invalid type");
6461
            goto do_decl;
6462
        }
6463
    } else {
6464
        v = anon_sym++;
6465
    }
6466
    type1.t = a;
6467
    /* we put an undefined size for struct/union */
6468
    s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
6469
    s->r = 0; /* default alignment is zero as gcc */
6470
    /* put struct/union/enum name in type */
6471
 do_decl:
6472
    type->t = u;
6473
    type->ref = s;
6474
 
6475
    if (tok == '{') {
6476
        next();
6477
        if (s->c != -1)
6478
            error("struct/union/enum already defined");
6479
        /* cannot be empty */
6480
        c = 0;
6481
        /* non empty enums are not allowed */
6482
        if (a == TOK_ENUM) {
6483
            for(;;) {
6484
                v = tok;
6485
                if (v < TOK_UIDENT)
6486
                    expect("identifier");
6487
                next();
6488
                if (tok == '=') {
6489
                    next();
6490
                    c = expr_const();
6491
                }
6492
                /* enum symbols have static storage */
6493
                ss = sym_push(v, &int_type, VT_CONST, c);
6494
                ss->type.t |= VT_STATIC;
6495
                if (tok != ',')
6496
                    break;
6497
                next();
6498
                c++;
6499
                /* NOTE: we accept a trailing comma */
6500
                if (tok == '}')
6501
                    break;
6502
            }
6503
            skip('}');
6504
        } else {
6505
            maxalign = 1;
6506
            ps = &s->next;
6507
            bit_pos = 0;
6508
            offset = 0;
6509
            while (tok != '}') {
6510
                parse_btype(&btype, &ad);
6511
                while (1) {
6512
                    bit_size = -1;
6513
                    v = 0;
6514
                    type1 = btype;
6515
                    if (tok != ':') {
6516
                        type_decl(&type1, &ad, &v, TYPE_DIRECT);
6517
                        if ((type1.t & VT_BTYPE) == VT_FUNC ||
6518
                            (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
6519
                            error("invalid type for '%s'",
6520
                                  get_tok_str(v, NULL));
6521
                    }
6522
                    if (tok == ':') {
6523
                        next();
6524
                        bit_size = expr_const();
6525
                        /* XXX: handle v = 0 case for messages */
6526
                        if (bit_size < 0)
6527
                            error("negative width in bit-field '%s'",
6528
                                  get_tok_str(v, NULL));
6529
                        if (v && bit_size == 0)
6530
                            error("zero width for bit-field '%s'",
6531
                                  get_tok_str(v, NULL));
6532
                    }
6533
                    size = type_size(&type1, &align);
6534
                    if (ad.aligned) {
6535
                        if (align < ad.aligned)
6536
                            align = ad.aligned;
6537
                    } else if (ad.packed) {
6538
                        align = 1;
6539
                    } else if (*tcc_state->pack_stack_ptr) {
6540
                        if (align > *tcc_state->pack_stack_ptr)
6541
                            align = *tcc_state->pack_stack_ptr;
6542
                    }
6543
                    lbit_pos = 0;
6544
                    if (bit_size >= 0) {
6545
                        bt = type1.t & VT_BTYPE;
6546
                        if (bt != VT_INT &&
6547
                            bt != VT_BYTE &&
6548
                            bt != VT_SHORT &&
6549
                            bt != VT_BOOL &&
6550
                            bt != VT_ENUM)
6551
                            error("bitfields must have scalar type");
6552
                        bsize = size * 8;
6553
                        if (bit_size > bsize) {
6554
                            error("width of '%s' exceeds its type",
6555
                                  get_tok_str(v, NULL));
6556
                        } else if (bit_size == bsize) {
6557
                            /* no need for bit fields */
6558
                            bit_pos = 0;
6559
                        } else if (bit_size == 0) {
6560
                            /* XXX: what to do if only padding in a
6561
                               structure ? */
6562
                            /* zero size: means to pad */
6563
                            if (bit_pos > 0)
6564
                                bit_pos = bsize;
6565
                        } else {
6566
                            /* we do not have enough room ? */
6567
                            if ((bit_pos + bit_size) > bsize)
6568
                                bit_pos = 0;
6569
                            lbit_pos = bit_pos;
6570
                            /* XXX: handle LSB first */
6571
                            type1.t |= VT_BITFIELD |
6572
                                (bit_pos << VT_STRUCT_SHIFT) |
6573
                                (bit_size << (VT_STRUCT_SHIFT + 6));
6574
                            bit_pos += bit_size;
6575
                        }
6576
                    } else {
6577
                        bit_pos = 0;
6578
                    }
6579
                    if (v) {
6580
                        /* add new memory data only if starting
6581
                           bit field */
6582
                        if (lbit_pos == 0) {
6583
                            if (a == TOK_STRUCT) {
6584
                                c = (c + align - 1) & -align;
6585
                                offset = c;
6586
                                c += size;
6587
                            } else {
6588
                                offset = 0;
6589
                                if (size > c)
6590
                                    c = size;
6591
                            }
6592
                            if (align > maxalign)
6593
                                maxalign = align;
6594
                        }
6595
#if 0
6596
                        printf("add field %s offset=%d",
6597
                               get_tok_str(v, NULL), offset);
6598
                        if (type1.t & VT_BITFIELD) {
6599
                            printf(" pos=%d size=%d",
6600
                                   (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
6601
                                   (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
6602
                        }
6603
                        printf("\n");
6604
#endif
6605
                        ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
6606
                        *ps = ss;
6607
                        ps = &ss->next;
6608
                    }
6609
                    if (tok == ';' || tok == TOK_EOF)
6610
                        break;
6611
                    skip(',');
6612
                }
6613
                skip(';');
6614
            }
6615
            skip('}');
6616
            /* store size and alignment */
6617
            s->c = (c + maxalign - 1) & -maxalign;
6618
            s->r = maxalign;
6619
        }
6620
    }
6621
}
6622
 
6623
/* return 0 if no type declaration. otherwise, return the basic type
6624
   and skip it.
6625
 */
6626
static int parse_btype(CType *type, AttributeDef *ad)
6627
{
6628
    int t, u, type_found, typespec_found;
6629
    Sym *s;
6630
    CType type1;
6631
 
6632
    memset(ad, 0, sizeof(AttributeDef));
6633
    type_found = 0;
6634
    typespec_found = 0;
6635
    t = 0;
6636
    while(1) {
6637
        switch(tok) {
6638
        case TOK_EXTENSION:
6639
            /* currently, we really ignore extension */
6640
            next();
6641
            continue;
6642
 
6643
            /* basic types */
6644
        case TOK_CHAR:
6645
            u = VT_BYTE;
6646
        basic_type:
6647
            next();
6648
        basic_type1:
6649
            if ((t & VT_BTYPE) != 0)
6650
                error("too many basic types");
6651
            t |= u;
6652
            typespec_found = 1;
6653
            break;
6654
        case TOK_VOID:
6655
            u = VT_VOID;
6656
            goto basic_type;
6657
        case TOK_SHORT:
6658
            u = VT_SHORT;
6659
            goto basic_type;
6660
        case TOK_INT:
6661
            next();
6662
            typespec_found = 1;
6663
            break;
6664
        case TOK_LONG:
6665
            next();
6666
            if ((t & VT_BTYPE) == VT_DOUBLE) {
6667
                t = (t & ~VT_BTYPE) | VT_LDOUBLE;
6668
            } else if ((t & VT_BTYPE) == VT_LONG) {
6669
                t = (t & ~VT_BTYPE) | VT_LLONG;
6670
            } else {
6671
                u = VT_LONG;
6672
                goto basic_type1;
6673
            }
6674
            break;
6675
        case TOK_BOOL:
6676
            u = VT_BOOL;
6677
            goto basic_type;
6678
        case TOK_FLOAT:
6679
            u = VT_FLOAT;
6680
            goto basic_type;
6681
        case TOK_DOUBLE:
6682
            next();
6683
            if ((t & VT_BTYPE) == VT_LONG) {
6684
                t = (t & ~VT_BTYPE) | VT_LDOUBLE;
6685
            } else {
6686
                u = VT_DOUBLE;
6687
                goto basic_type1;
6688
            }
6689
            break;
6690
        case TOK_ENUM:
6691
            struct_decl(&type1, VT_ENUM);
6692
        basic_type2:
6693
            u = type1.t;
6694
            type->ref = type1.ref;
6695
            goto basic_type1;
6696
        case TOK_STRUCT:
6697
        case TOK_UNION:
6698
            struct_decl(&type1, VT_STRUCT);
6699
            goto basic_type2;
6700
 
6701
            /* type modifiers */
6702
        case TOK_CONST1:
6703
        case TOK_CONST2:
6704
        case TOK_CONST3:
6705
            t |= VT_CONSTANT;
6706
            next();
6707
            break;
6708
        case TOK_VOLATILE1:
6709
        case TOK_VOLATILE2:
6710
        case TOK_VOLATILE3:
6711
            t |= VT_VOLATILE;
6712
            next();
6713
            break;
6714
        case TOK_SIGNED1:
6715
        case TOK_SIGNED2:
6716
        case TOK_SIGNED3:
6717
            typespec_found = 1;
6718
	    t |= VT_SIGNED;
6719
	    next();
6720
	    break;
6721
        case TOK_REGISTER:
6722
        case TOK_AUTO:
6723
        case TOK_RESTRICT1:
6724
        case TOK_RESTRICT2:
6725
        case TOK_RESTRICT3:
6726
            next();
6727
            break;
6728
        case TOK_UNSIGNED:
6729
            t |= VT_UNSIGNED;
6730
            next();
6731
            typespec_found = 1;
6732
            break;
6733
 
6734
            /* storage */
6735
        case TOK_EXTERN:
6736
            t |= VT_EXTERN;
6737
            next();
6738
            break;
6739
        case TOK_STATIC:
6740
            t |= VT_STATIC;
6741
            next();
6742
            break;
6743
        case TOK_TYPEDEF:
6744
            t |= VT_TYPEDEF;
6745
            next();
6746
            break;
6747
        case TOK_INLINE1:
6748
        case TOK_INLINE2:
6749
        case TOK_INLINE3:
6750
            t |= VT_INLINE;
6751
            next();
6752
            break;
6753
 
6754
            /* GNUC attribute */
6755
        case TOK_ATTRIBUTE1:
6756
        case TOK_ATTRIBUTE2:
6757
            parse_attribute(ad);
6758
            break;
6759
            /* GNUC typeof */
6760
        case TOK_TYPEOF1:
6761
        case TOK_TYPEOF2:
6762
        case TOK_TYPEOF3:
6763
            next();
6764
            parse_expr_type(&type1);
6765
            goto basic_type2;
6766
        default:
6767
            if (typespec_found)
6768
                goto the_end;
6769
            s = sym_find(tok);
6770
            if (!s || !(s->type.t & VT_TYPEDEF))
6771
                goto the_end;
6772
            t |= (s->type.t & ~VT_TYPEDEF);
6773
            type->ref = s->type.ref;
6774
            next();
6775
            break;
6776
        }
6777
        type_found = 1;
6778
    }
6779
the_end:
6780
    if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
6781
      error("signed and unsigned modifier");
6782
    if (tcc_state->char_is_unsigned) {
6783
        if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
6784
            t |= VT_UNSIGNED;
6785
    }
6786
    t &= ~VT_SIGNED;
6787
 
6788
    /* long is never used as type */
6789
    if ((t & VT_BTYPE) == VT_LONG)
6790
        t = (t & ~VT_BTYPE) | VT_INT;
6791
    type->t = t;
6792
    return type_found;
6793
}
6794
 
6795
/* convert a function parameter type (array to pointer and function to
6796
   function pointer) */
6797
static inline void convert_parameter_type(CType *pt)
6798
{
6799
    /* remove const and volatile qualifiers (XXX: const could be used
6800
       to indicate a const function parameter */
6801
    pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
6802
    /* array must be transformed to pointer according to ANSI C */
6803
    pt->t &= ~VT_ARRAY;
6804
    if ((pt->t & VT_BTYPE) == VT_FUNC) {
6805
        mk_pointer(pt);
6806
    }
6807
}
6808
 
6809
static void post_type(CType *type, AttributeDef *ad)
6810
{
6811
    int n, l, t1;
6812
    Sym **plast, *s, *first;
6813
    AttributeDef ad1;
6814
    CType pt;
6815
 
6816
    if (tok == '(') {
6817
        /* function declaration */
6818
        next();
6819
        l = 0;
6820
        first = NULL;
6821
        plast = &first;
6822
        while (tok != ')') {
6823
            /* read param name and compute offset */
6824
            if (l != FUNC_OLD) {
6825
                if (!parse_btype(&pt, &ad1)) {
6826
                    if (l) {
6827
                        error("invalid type");
6828
                    } else {
6829
                        l = FUNC_OLD;
6830
                        goto old_proto;
6831
                    }
6832
                }
6833
                l = FUNC_NEW;
6834
                if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
6835
                    break;
6836
                type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
6837
                if ((pt.t & VT_BTYPE) == VT_VOID)
6838
                    error("parameter declared as void");
6839
            } else {
6840
            old_proto:
6841
                n = tok;
6842
                pt.t = VT_INT;
6843
                next();
6844
            }
6845
            convert_parameter_type(&pt);
6846
            s = sym_push(n | SYM_FIELD, &pt, 0, 0);
6847
            *plast = s;
6848
            plast = &s->next;
6849
            if (tok == ',') {
6850
                next();
6851
                if (l == FUNC_NEW && tok == TOK_DOTS) {
6852
                    l = FUNC_ELLIPSIS;
6853
                    next();
6854
                    break;
6855
                }
6856
            }
6857
        }
6858
        /* if no parameters, then old type prototype */
6859
        if (l == 0)
6860
            l = FUNC_OLD;
6861
        skip(')');
6862
        t1 = type->t & VT_STORAGE;
6863
        /* NOTE: const is ignored in returned type as it has a special
6864
           meaning in gcc / C++ */
6865
        type->t &= ~(VT_STORAGE | VT_CONSTANT);
6866
        post_type(type, ad);
6867
        /* we push a anonymous symbol which will contain the function prototype */
6868
        s = sym_push(SYM_FIELD, type, ad->func_call, l);
6869
        s->next = first;
6870
        type->t = t1 | VT_FUNC;
6871
        type->ref = s;
6872
    } else if (tok == '[') {
6873
        /* array definition */
6874
        next();
6875
        n = -1;
6876
        if (tok != ']') {
6877
            n = expr_const();
6878
            if (n < 0)
6879
                error("invalid array size");
6880
        }
6881
        skip(']');
6882
        /* parse next post type */
6883
        t1 = type->t & VT_STORAGE;
6884
        type->t &= ~VT_STORAGE;
6885
        post_type(type, ad);
6886
 
6887
        /* we push a anonymous symbol which will contain the array
6888
           element type */
6889
        s = sym_push(SYM_FIELD, type, 0, n);
6890
        type->t = t1 | VT_ARRAY | VT_PTR;
6891
        type->ref = s;
6892
    }
6893
}
6894
 
6895
/* Parse a type declaration (except basic type), and return the type
6896
   in 'type'. 'td' is a bitmask indicating which kind of type decl is
6897
   expected. 'type' should contain the basic type. 'ad' is the
6898
   attribute definition of the basic type. It can be modified by
6899
   type_decl().
6900
 */
6901
static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
6902
{
6903
    Sym *s;
6904
    CType type1, *type2;
6905
    int qualifiers;
6906
 
6907
    while (tok == '*') {
6908
        qualifiers = 0;
6909
    redo:
6910
        next();
6911
        switch(tok) {
6912
        case TOK_CONST1:
6913
        case TOK_CONST2:
6914
        case TOK_CONST3:
6915
            qualifiers |= VT_CONSTANT;
6916
            goto redo;
6917
        case TOK_VOLATILE1:
6918
        case TOK_VOLATILE2:
6919
        case TOK_VOLATILE3:
6920
            qualifiers |= VT_VOLATILE;
6921
            goto redo;
6922
        case TOK_RESTRICT1:
6923
        case TOK_RESTRICT2:
6924
        case TOK_RESTRICT3:
6925
            goto redo;
6926
        }
6927
        mk_pointer(type);
6928
        type->t |= qualifiers;
6929
    }
6930
 
6931
    /* XXX: clarify attribute handling */
6932
    if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6933
        parse_attribute(ad);
6934
 
6935
    /* recursive type */
6936
    /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
6937
    type1.t = 0; /* XXX: same as int */
6938
    if (tok == '(') {
6939
        next();
6940
        /* XXX: this is not correct to modify 'ad' at this point, but
6941
           the syntax is not clear */
6942
        if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6943
            parse_attribute(ad);
6944
        type_decl(&type1, ad, v, td);
6945
        skip(')');
6946
    } else {
6947
        /* type identifier */
6948
        if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
6949
            *v = tok;
6950
            next();
6951
        } else {
6952
            if (!(td & TYPE_ABSTRACT))
6953
                expect("identifier");
6954
            *v = 0;
6955
        }
6956
    }
6957
    post_type(type, ad);
6958
    if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
6959
        parse_attribute(ad);
6960
    if (!type1.t)
6961
        return;
6962
    /* append type at the end of type1 */
6963
    type2 = &type1;
6964
    for(;;) {
6965
        s = type2->ref;
6966
        type2 = &s->type;
6967
        if (!type2->t) {
6968
            *type2 = *type;
6969
            break;
6970
        }
6971
    }
6972
    *type = type1;
6973
}
6974
 
6975
/* compute the lvalue VT_LVAL_xxx needed to match type t. */
6976
static int lvalue_type(int t)
6977
{
6978
    int bt, r;
6979
    r = VT_LVAL;
6980
    bt = t & VT_BTYPE;
6981
    if (bt == VT_BYTE || bt == VT_BOOL)
6982
        r |= VT_LVAL_BYTE;
6983
    else if (bt == VT_SHORT)
6984
        r |= VT_LVAL_SHORT;
6985
    else
6986
        return r;
6987
    if (t & VT_UNSIGNED)
6988
        r |= VT_LVAL_UNSIGNED;
6989
    return r;
6990
}
6991
 
6992
/* indirection with full error checking and bound check */
6993
static void indir(void)
6994
{
6995
    if ((vtop->type.t & VT_BTYPE) != VT_PTR)
6996
        expect("pointer");
6997
    if ((vtop->r & VT_LVAL) && !nocode_wanted)
6998
        gv(RC_INT);
6999
    vtop->type = *pointed_type(&vtop->type);
7000
    /* an array is never an lvalue */
7001
    if (!(vtop->type.t & VT_ARRAY)) {
7002
        vtop->r |= lvalue_type(vtop->type.t);
7003
        /* if bound checking, the referenced pointer must be checked */
7004
        if (do_bounds_check)
7005
            vtop->r |= VT_MUSTBOUND;
7006
    }
7007
}
7008
 
7009
/* pass a parameter to a function and do type checking and casting */
7010
static void gfunc_param_typed(Sym *func, Sym *arg)
7011
{
7012
    int func_type;
7013
    CType type;
7014
 
7015
    func_type = func->c;
7016
    if (func_type == FUNC_OLD ||
7017
        (func_type == FUNC_ELLIPSIS && arg == NULL)) {
7018
        /* default casting : only need to convert float to double */
7019
        if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
7020
            type.t = VT_DOUBLE;
7021
            gen_cast(&type);
7022
        }
7023
    } else if (arg == NULL) {
7024
        error("too many arguments to function");
7025
    } else {
7026
        type = arg->type;
7027
        type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
7028
        gen_assign_cast(&type);
7029
    }
7030
}
7031
 
7032
/* parse an expression of the form '(type)' or '(expr)' and return its
7033
   type */
7034
static void parse_expr_type(CType *type)
7035
{
7036
    int n;
7037
    AttributeDef ad;
7038
 
7039
    skip('(');
7040
    if (parse_btype(type, &ad)) {
7041
        type_decl(type, &ad, &n, TYPE_ABSTRACT);
7042
    } else {
7043
        expr_type(type);
7044
    }
7045
    skip(')');
7046
}
7047
 
7048
static void parse_type(CType *type)
7049
{
7050
    AttributeDef ad;
7051
    int n;
7052
 
7053
    if (!parse_btype(type, &ad)) {
7054
        expect("type");
7055
    }
7056
    type_decl(type, &ad, &n, TYPE_ABSTRACT);
7057
}
7058
 
7059
static void vpush_tokc(int t)
7060
{
7061
    CType type;
7062
    type.t = t;
7063
    vsetc(&type, VT_CONST, &tokc);
7064
}
7065
 
7066
static void unary(void)
7067
{
7068
    int n, t, align, size, r;
7069
    CType type;
7070
    Sym *s;
7071
    AttributeDef ad;
7072
 
7073
    /* XXX: GCC 2.95.3 does not generate a table although it should be
7074
       better here */
7075
 tok_next:
7076
    switch(tok) {
7077
    case TOK_EXTENSION:
7078
        next();
7079
        goto tok_next;
7080
    case TOK_CINT:
7081
    case TOK_CCHAR:
7082
    case TOK_LCHAR:
7083
        vpushi(tokc.i);
7084
        next();
7085
        break;
7086
    case TOK_CUINT:
7087
        vpush_tokc(VT_INT | VT_UNSIGNED);
7088
        next();
7089
        break;
7090
    case TOK_CLLONG:
7091
        vpush_tokc(VT_LLONG);
7092
        next();
7093
        break;
7094
    case TOK_CULLONG:
7095
        vpush_tokc(VT_LLONG | VT_UNSIGNED);
7096
        next();
7097
        break;
7098
    case TOK_CFLOAT:
7099
        vpush_tokc(VT_FLOAT);
7100
        next();
7101
        break;
7102
    case TOK_CDOUBLE:
7103
        vpush_tokc(VT_DOUBLE);
7104
        next();
7105
        break;
7106
    case TOK_CLDOUBLE:
7107
        vpush_tokc(VT_LDOUBLE);
7108
        next();
7109
        break;
7110
    case TOK___FUNCTION__:
7111
        if (!gnu_ext)
7112
            goto tok_identifier;
7113
        /* fall thru */
7114
    case TOK___FUNC__:
7115
        {
7116
            void *ptr;
7117
            int len;
7118
            /* special function name identifier */
7119
            len = strlen(funcname) + 1;
7120
            /* generate char[len] type */
7121
            type.t = VT_BYTE;
7122
            mk_pointer(&type);
7123
            type.t |= VT_ARRAY;
7124
            type.ref->c = len;
7125
            vpush_ref(&type, data_section, data_section->data_offset, len);
7126
            ptr = section_ptr_add(data_section, len);
7127
            memcpy(ptr, funcname, len);
7128
            next();
7129
        }
7130
        break;
7131
    case TOK_LSTR:
7132
        t = VT_INT;
7133
        goto str_init;
7134
    case TOK_STR:
7135
        /* string parsing */
7136
        t = VT_BYTE;
7137
    str_init:
7138
        if (tcc_state->warn_write_strings)
7139
            t |= VT_CONSTANT;
7140
        type.t = t;
7141
        mk_pointer(&type);
7142
        type.t |= VT_ARRAY;
7143
        memset(&ad, 0, sizeof(AttributeDef));
7144
        decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
7145
        break;
7146
    case '(':
7147
        next();
7148
        /* cast ? */
7149
        if (parse_btype(&type, &ad)) {
7150
            type_decl(&type, &ad, &n, TYPE_ABSTRACT);
7151
            skip(')');
7152
            /* check ISOC99 compound literal */
7153
            if (tok == '{') {
7154
                    /* data is allocated locally by default */
7155
                if (global_expr)
7156
                    r = VT_CONST;
7157
                else
7158
                    r = VT_LOCAL;
7159
                /* all except arrays are lvalues */
7160
                if (!(type.t & VT_ARRAY))
7161
                    r |= lvalue_type(type.t);
7162
                memset(&ad, 0, sizeof(AttributeDef));
7163
                decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
7164
            } else {
7165
                unary();
7166
                gen_cast(&type);
7167
            }
7168
        } else if (tok == '{') {
7169
            /* save all registers */
7170
            save_regs(0);
7171
            /* statement expression : we do not accept break/continue
7172
               inside as GCC does */
7173
            block(NULL, NULL, NULL, NULL, 0, 1);
7174
            skip(')');
7175
        } else {
7176
            gexpr();
7177
            skip(')');
7178
        }
7179
        break;
7180
    case '*':
7181
        next();
7182
        unary();
7183
        indir();
7184
        break;
7185
    case '&':
7186
        next();
7187
        unary();
7188
        /* functions names must be treated as function pointers,
7189
           except for unary '&' and sizeof. Since we consider that
7190
           functions are not lvalues, we only have to handle it
7191
           there and in function calls. */
7192
        /* arrays can also be used although they are not lvalues */
7193
        if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
7194
            !(vtop->type.t & VT_ARRAY))
7195
            test_lvalue();
7196
        mk_pointer(&vtop->type);
7197
        gaddrof();
7198
        break;
7199
    case '!':
7200
        next();
7201
        unary();
7202
        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
7203
            vtop->c.i = !vtop->c.i;
7204
        else if ((vtop->r & VT_VALMASK) == VT_CMP)
7205
            vtop->c.i = vtop->c.i ^ 1;
7206
        else
7207
            vseti(VT_JMP, gtst(1, 0));
7208
        break;
7209
    case '~':
7210
        next();
7211
        unary();
7212
        vpushi(-1);
7213
        gen_op('^');
7214
        break;
7215
    case '+':
7216
        next();
7217
        /* in order to force cast, we add zero */
7218
        unary();
7219
        if ((vtop->type.t & VT_BTYPE) == VT_PTR)
7220
            error("pointer not accepted for unary plus");
7221
        vpushi(0);
7222
        gen_op('+');
7223
        break;
7224
    case TOK_SIZEOF:
7225
    case TOK_ALIGNOF1:
7226
    case TOK_ALIGNOF2:
7227
        t = tok;
7228
        next();
7229
        if (tok == '(') {
7230
            parse_expr_type(&type);
7231
        } else {
7232
            unary_type(&type);
7233
        }
7234
        size = type_size(&type, &align);
7235
        if (t == TOK_SIZEOF) {
7236
            if (size < 0)
7237
                error("sizeof applied to an incomplete type");
7238
            vpushi(size);
7239
        } else {
7240
            vpushi(align);
7241
        }
7242
        break;
7243
 
7244
    case TOK_builtin_types_compatible_p:
7245
        {
7246
            CType type1, type2;
7247
            next();
7248
            skip('(');
7249
            parse_type(&type1);
7250
            skip(',');
7251
            parse_type(&type2);
7252
            skip(')');
7253
            type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
7254
            type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
7255
            vpushi(is_compatible_types(&type1, &type2));
7256
        }
7257
        break;
7258
    case TOK_builtin_constant_p:
7259
        {
7260
            int saved_nocode_wanted, res;
7261
            next();
7262
            skip('(');
7263
            saved_nocode_wanted = nocode_wanted;
7264
            nocode_wanted = 1;
7265
            gexpr();
7266
            res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
7267
            vpop();
7268
            nocode_wanted = saved_nocode_wanted;
7269
            skip(')');
7270
            vpushi(res);
7271
        }
7272
        break;
7273
    case TOK_INC:
7274
    case TOK_DEC:
7275
        t = tok;
7276
        next();
7277
        unary();
7278
        inc(0, t);
7279
        break;
7280
    case '-':
7281
        next();
7282
        vpushi(0);
7283
        unary();
7284
        gen_op('-');
7285
        break;
7286
    case TOK_LAND:
7287
        if (!gnu_ext)
7288
            goto tok_identifier;
7289
        next();
7290
        /* allow to take the address of a label */
7291
        if (tok < TOK_UIDENT)
7292
            expect("label identifier");
7293
        s = label_find(tok);
7294
        if (!s) {
7295
            s = label_push(&global_label_stack, tok, LABEL_FORWARD);
7296
        } else {
7297
            if (s->r == LABEL_DECLARED)
7298
                s->r = LABEL_FORWARD;
7299
        }
7300
        if (!s->type.t) {
7301
            s->type.t = VT_VOID;
7302
            mk_pointer(&s->type);
7303
            s->type.t |= VT_STATIC;
7304
        }
7305
        vset(&s->type, VT_CONST | VT_SYM, 0);
7306
        vtop->sym = s;
7307
        next();
7308
        break;
7309
    default:
7310
    tok_identifier:
7311
        t = tok;
7312
        next();
7313
        if (t < TOK_UIDENT)
7314
            expect("identifier");
7315
        s = sym_find(t);
7316
        if (!s) {
7317
            if (tok != '(')
7318
                error("'%s' undeclared", get_tok_str(t, NULL));
7319
            /* for simple function calls, we tolerate undeclared
7320
               external reference to int() function */
7321
            if (tcc_state->warn_implicit_function_declaration)
7322
                warning("implicit declaration of function '%s'",
7323
                        get_tok_str(t, NULL));
7324
            s = external_global_sym(t, &func_old_type, 0);
7325
        }
7326
        if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
7327
            (VT_STATIC | VT_INLINE | VT_FUNC)) {
7328
            /* if referencing an inline function, then we generate a
7329
               symbol to it if not already done. It will have the
7330
               effect to generate code for it at the end of the
7331
               compilation unit. Inline function as always
7332
               generated in the text section. */
7333
            if (!s->c)
7334
                put_extern_sym(s, text_section, 0, 0);
7335
            r = VT_SYM | VT_CONST;
7336
        } else {
7337
            r = s->r;
7338
        }
7339
        vset(&s->type, r, s->c);
7340
        /* if forward reference, we must point to s */
7341
        if (vtop->r & VT_SYM) {
7342
            vtop->sym = s;
7343
            vtop->c.ul = 0;
7344
        }
7345
        break;
7346
    }
7347
 
7348
    /* post operations */
7349
    while (1) {
7350
        if (tok == TOK_INC || tok == TOK_DEC) {
7351
            inc(1, tok);
7352
            next();
7353
        } else if (tok == '.' || tok == TOK_ARROW) {
7354
            /* field */
7355
            if (tok == TOK_ARROW)
7356
                indir();
7357
            test_lvalue();
7358
            gaddrof();
7359
            next();
7360
            /* expect pointer on structure */
7361
            if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
7362
                expect("struct or union");
7363
            s = vtop->type.ref;
7364
            /* find field */
7365
            tok |= SYM_FIELD;
7366
            while ((s = s->next) != NULL) {
7367
                if (s->v == tok)
7368
                    break;
7369
            }
7370
            if (!s)
7371
                error("field not found");
7372
            /* add field offset to pointer */
7373
            vtop->type = char_pointer_type; /* change type to 'char *' */
7374
            vpushi(s->c);
7375
            gen_op('+');
7376
            /* change type to field type, and set to lvalue */
7377
            vtop->type = s->type;
7378
            /* an array is never an lvalue */
7379
            if (!(vtop->type.t & VT_ARRAY)) {
7380
                vtop->r |= lvalue_type(vtop->type.t);
7381
                /* if bound checking, the referenced pointer must be checked */
7382
                if (do_bounds_check)
7383
                    vtop->r |= VT_MUSTBOUND;
7384
            }
7385
            next();
7386
        } else if (tok == '[') {
7387
            next();
7388
            gexpr();
7389
            gen_op('+');
7390
            indir();
7391
            skip(']');
7392
        } else if (tok == '(') {
7393
            SValue ret;
7394
            Sym *sa;
7395
            int nb_args;
7396
 
7397
            /* function call  */
7398
            if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
7399
                /* pointer test (no array accepted) */
7400
                if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
7401
                    vtop->type = *pointed_type(&vtop->type);
7402
                    if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
7403
                        goto error_func;
7404
                } else {
7405
                error_func:
7406
                    expect("function pointer");
7407
                }
7408
            } else {
7409
                vtop->r &= ~VT_LVAL; /* no lvalue */
7410
            }
7411
            /* get return type */
7412
            s = vtop->type.ref;
7413
            next();
7414
            sa = s->next; /* first parameter */
7415
            nb_args = 0;
7416
            /* compute first implicit argument if a structure is returned */
7417
            if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
7418
                /* get some space for the returned structure */
7419
                size = type_size(&s->type, &align);
7420
                loc = (loc - size) & -align;
7421
                ret.type = s->type;
7422
                ret.r = VT_LOCAL | VT_LVAL;
7423
                /* pass it as 'int' to avoid structure arg passing
7424
                   problems */
7425
                vseti(VT_LOCAL, loc);
7426
                ret.c = vtop->c;
7427
                nb_args++;
7428
            } else {
7429
                ret.type = s->type;
7430
                ret.r2 = VT_CONST;
7431
                /* return in register */
7432
                if (is_float(ret.type.t)) {
7433
                    ret.r = REG_FRET;
7434
                } else {
7435
                    if ((ret.type.t & VT_BTYPE) == VT_LLONG)
7436
                        ret.r2 = REG_LRET;
7437
                    ret.r = REG_IRET;
7438
                }
7439
                ret.c.i = 0;
7440
            }
7441
            if (tok != ')') {
7442
                for(;;) {
7443
                    expr_eq();
7444
                    gfunc_param_typed(s, sa);
7445
                    nb_args++;
7446
                    if (sa)
7447
                        sa = sa->next;
7448
                    if (tok == ')')
7449
                        break;
7450
                    skip(',');
7451
                }
7452
            }
7453
            if (sa)
7454
                error("too few arguments to function");
7455
            skip(')');
7456
            if (!nocode_wanted) {
7457
                gfunc_call(nb_args);
7458
            } else {
7459
                vtop -= (nb_args + 1);
7460
            }
7461
            /* return value */
7462
            vsetc(&ret.type, ret.r, &ret.c);
7463
            vtop->r2 = ret.r2;
7464
        } else {
7465
            break;
7466
        }
7467
    }
7468
}
7469
 
7470
static void uneq(void)
7471
{
7472
    int t;
7473
 
7474
    unary();
7475
    if (tok == '=' ||
7476
        (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
7477
        tok == TOK_A_XOR || tok == TOK_A_OR ||
7478
        tok == TOK_A_SHL || tok == TOK_A_SAR) {
7479
        test_lvalue();
7480
        t = tok;
7481
        next();
7482
        if (t == '=') {
7483
            expr_eq();
7484
        } else {
7485
            vdup();
7486
            expr_eq();
7487
            gen_op(t & 0x7f);
7488
        }
7489
        vstore();
7490
    }
7491
}
7492
 
7493
static void expr_prod(void)
7494
{
7495
    int t;
7496
 
7497
    uneq();
7498
    while (tok == '*' || tok == '/' || tok == '%') {
7499
        t = tok;
7500
        next();
7501
        uneq();
7502
        gen_op(t);
7503
    }
7504
}
7505
 
7506
static void expr_sum(void)
7507
{
7508
    int t;
7509
 
7510
    expr_prod();
7511
    while (tok == '+' || tok == '-') {
7512
        t = tok;
7513
        next();
7514
        expr_prod();
7515
        gen_op(t);
7516
    }
7517
}
7518
 
7519
static void expr_shift(void)
7520
{
7521
    int t;
7522
 
7523
    expr_sum();
7524
    while (tok == TOK_SHL || tok == TOK_SAR) {
7525
        t = tok;
7526
        next();
7527
        expr_sum();
7528
        gen_op(t);
7529
    }
7530
}
7531
 
7532
static void expr_cmp(void)
7533
{
7534
    int t;
7535
 
7536
    expr_shift();
7537
    while ((tok >= TOK_ULE && tok <= TOK_GT) ||
7538
           tok == TOK_ULT || tok == TOK_UGE) {
7539
        t = tok;
7540
        next();
7541
        expr_shift();
7542
        gen_op(t);
7543
    }
7544
}
7545
 
7546
static void expr_cmpeq(void)
7547
{
7548
    int t;
7549
 
7550
    expr_cmp();
7551
    while (tok == TOK_EQ || tok == TOK_NE) {
7552
        t = tok;
7553
        next();
7554
        expr_cmp();
7555
        gen_op(t);
7556
    }
7557
}
7558
 
7559
static void expr_and(void)
7560
{
7561
    expr_cmpeq();
7562
    while (tok == '&') {
7563
        next();
7564
        expr_cmpeq();
7565
        gen_op('&');
7566
    }
7567
}
7568
 
7569
static void expr_xor(void)
7570
{
7571
    expr_and();
7572
    while (tok == '^') {
7573
        next();
7574
        expr_and();
7575
        gen_op('^');
7576
    }
7577
}
7578
 
7579
static void expr_or(void)
7580
{
7581
    expr_xor();
7582
    while (tok == '|') {
7583
        next();
7584
        expr_xor();
7585
        gen_op('|');
7586
    }
7587
}
7588
 
7589
/* XXX: fix this mess */
7590
static void expr_land_const(void)
7591
{
7592
    expr_or();
7593
    while (tok == TOK_LAND) {
7594
        next();
7595
        expr_or();
7596
        gen_op(TOK_LAND);
7597
    }
7598
}
7599
 
7600
/* XXX: fix this mess */
7601
static void expr_lor_const(void)
7602
{
7603
    expr_land_const();
7604
    while (tok == TOK_LOR) {
7605
        next();
7606
        expr_land_const();
7607
        gen_op(TOK_LOR);
7608
    }
7609
}
7610
 
7611
/* only used if non constant */
7612
static void expr_land(void)
7613
{
7614
    int t;
7615
 
7616
    expr_or();
7617
    if (tok == TOK_LAND) {
7618
        t = 0;
7619
        for(;;) {
7620
            t = gtst(1, t);
7621
            if (tok != TOK_LAND) {
7622
                vseti(VT_JMPI, t);
7623
                break;
7624
            }
7625
            next();
7626
            expr_or();
7627
        }
7628
    }
7629
}
7630
 
7631
static void expr_lor(void)
7632
{
7633
    int t;
7634
 
7635
    expr_land();
7636
    if (tok == TOK_LOR) {
7637
        t = 0;
7638
        for(;;) {
7639
            t = gtst(0, t);
7640
            if (tok != TOK_LOR) {
7641
                vseti(VT_JMP, t);
7642
                break;
7643
            }
7644
            next();
7645
            expr_land();
7646
        }
7647
    }
7648
}
7649
 
7650
/* XXX: better constant handling */
7651
static void expr_eq(void)
7652
{
7653
    int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
7654
    SValue sv;
7655
    CType type, type1, type2;
7656
 
7657
    if (const_wanted) {
7658
        int c1, c;
7659
        expr_lor_const();
7660
        if (tok == '?') {
7661
            c = vtop->c.i;
7662
            vpop();
7663
            next();
7664
            if (tok == ':' && gnu_ext) {
7665
                c1 = c;
7666
            } else {
7667
                gexpr();
7668
                c1 = vtop->c.i;
7669
                vpop();
7670
            }
7671
            skip(':');
7672
            expr_eq();
7673
            if (c)
7674
                vtop->c.i = c1;
7675
        }
7676
    } else {
7677
        expr_lor();
7678
        if (tok == '?') {
7679
            next();
7680
            if (vtop != vstack) {
7681
                /* needed to avoid having different registers saved in
7682
                   each branch */
7683
                if (is_float(vtop->type.t))
7684
                    rc = RC_FLOAT;
7685
                else
7686
                    rc = RC_INT;
7687
                    gv(rc);
7688
                    save_regs(1);
7689
            }
7690
            if (tok == ':' && gnu_ext) {
7691
                gv_dup();
7692
                tt = gtst(1, 0);
7693
            } else {
7694
                tt = gtst(1, 0);
7695
                gexpr();
7696
            }
7697
            type1 = vtop->type;
7698
            sv = *vtop; /* save value to handle it later */
7699
            vtop--; /* no vpop so that FP stack is not flushed */
7700
            skip(':');
7701
            u = gjmp(0);
7702
            gsym(tt);
7703
            expr_eq();
7704
            type2 = vtop->type;
7705
 
7706
            t1 = type1.t;
7707
            bt1 = t1 & VT_BTYPE;
7708
            t2 = type2.t;
7709
            bt2 = t2 & VT_BTYPE;
7710
            /* cast operands to correct type according to ISOC rules */
7711
            if (is_float(bt1) || is_float(bt2)) {
7712
                if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
7713
                    type.t = VT_LDOUBLE;
7714
                } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
7715
                    type.t = VT_DOUBLE;
7716
                } else {
7717
                    type.t = VT_FLOAT;
7718
                }
7719
            } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
7720
                /* cast to biggest op */
7721
                type.t = VT_LLONG;
7722
                /* convert to unsigned if it does not fit in a long long */
7723
                if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
7724
                    (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
7725
                    type.t |= VT_UNSIGNED;
7726
            } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
7727
                /* XXX: test pointer compatibility */
7728
                type = type1;
7729
            } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
7730
                /* XXX: test structure compatibility */
7731
                type = type1;
7732
            } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
7733
                /* NOTE: as an extension, we accept void on only one side */
7734
                type.t = VT_VOID;
7735
            } else {
7736
                /* integer operations */
7737
                type.t = VT_INT;
7738
                /* convert to unsigned if it does not fit in an integer */
7739
                if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
7740
                    (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
7741
                    type.t |= VT_UNSIGNED;
7742
            }
7743
 
7744
            /* now we convert second operand */
7745
            gen_cast(&type);
7746
            rc = RC_INT;
7747
            if (is_float(type.t)) {
7748
                rc = RC_FLOAT;
7749
            } else if ((type.t & VT_BTYPE) == VT_LLONG) {
7750
                /* for long longs, we use fixed registers to avoid having
7751
                   to handle a complicated move */
7752
                rc = RC_IRET;
7753
            }
7754
 
7755
            r2 = gv(rc);
7756
            /* this is horrible, but we must also convert first
7757
               operand */
7758
            tt = gjmp(0);
7759
            gsym(u);
7760
            /* put again first value and cast it */
7761
            *vtop = sv;
7762
            gen_cast(&type);
7763
            r1 = gv(rc);
7764
            move_reg(r2, r1);
7765
            vtop->r = r2;
7766
            gsym(tt);
7767
        }
7768
    }
7769
}
7770
 
7771
static void gexpr(void)
7772
{
7773
    while (1) {
7774
        expr_eq();
7775
        if (tok != ',')
7776
            break;
7777
        vpop();
7778
        next();
7779
    }
7780
}
7781
 
7782
/* parse an expression and return its type without any side effect. */
7783
static void expr_type(CType *type)
7784
{
7785
    int saved_nocode_wanted;
7786
 
7787
    saved_nocode_wanted = nocode_wanted;
7788
    nocode_wanted = 1;
7789
    gexpr();
7790
    *type = vtop->type;
7791
    vpop();
7792
    nocode_wanted = saved_nocode_wanted;
7793
}
7794
 
7795
/* parse a unary expression and return its type without any side
7796
   effect. */
7797
static void unary_type(CType *type)
7798
{
7799
    int a;
7800
 
7801
    a = nocode_wanted;
7802
    nocode_wanted = 1;
7803
    unary();
7804
    *type = vtop->type;
7805
    vpop();
7806
    nocode_wanted = a;
7807
}
7808
 
7809
/* parse a constant expression and return value in vtop.  */
7810
static void expr_const1(void)
7811
{
7812
    int a;
7813
    a = const_wanted;
7814
    const_wanted = 1;
7815
    expr_eq();
7816
    const_wanted = a;
7817
}
7818
 
7819
/* parse an integer constant and return its value. */
7820
static int expr_const(void)
7821
{
7822
    int c;
7823
    expr_const1();
7824
    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
7825
        expect("constant expression");
7826
    c = vtop->c.i;
7827
    vpop();
7828
    return c;
7829
}
7830
 
7831
/* return the label token if current token is a label, otherwise
7832
   return zero */
7833
static int is_label(void)
7834
{
7835
    int last_tok;
7836
 
7837
    /* fast test first */
7838
    if (tok < TOK_UIDENT)
7839
        return 0;
7840
    /* no need to save tokc because tok is an identifier */
7841
    last_tok = tok;
7842
    next();
7843
    if (tok == ':') {
7844
        next();
7845
        return last_tok;
7846
    } else {
7847
        unget_tok(last_tok);
7848
        return 0;
7849
    }
7850
}
7851
 
7852
static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
7853
                  int case_reg, int is_expr)
7854
{
7855
    int a, b, c, d;
7856
    Sym *s;
7857
 
7858
    /* generate line number info */
7859
    if (do_debug &&
7860
        (last_line_num != file->line_num || last_ind != ind)) {
7861
        put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
7862
        last_ind = ind;
7863
        last_line_num = file->line_num;
7864
    }
7865
 
7866
    if (is_expr) {
7867
        /* default return value is (void) */
7868
        vpushi(0);
7869
        vtop->type.t = VT_VOID;
7870
    }
7871
 
7872
    if (tok == TOK_IF) {
7873
        /* if test */
7874
        next();
7875
        skip('(');
7876
        gexpr();
7877
        skip(')');
7878
        a = gtst(1, 0);
7879
        block(bsym, csym, case_sym, def_sym, case_reg, 0);
7880
        c = tok;
7881
        if (c == TOK_ELSE) {
7882
            next();
7883
            d = gjmp(0);
7884
            gsym(a);
7885
            block(bsym, csym, case_sym, def_sym, case_reg, 0);
7886
            gsym(d); /* patch else jmp */
7887
        } else
7888
            gsym(a);
7889
    } else if (tok == TOK_WHILE) {
7890
        next();
7891
        d = ind;
7892
        skip('(');
7893
        gexpr();
7894
        skip(')');
7895
        a = gtst(1, 0);
7896
        b = 0;
7897
        block(&a, &b, case_sym, def_sym, case_reg, 0);
7898
        gjmp_addr(d);
7899
        gsym(a);
7900
        gsym_addr(b, d);
7901
    } else if (tok == '{') {
7902
        Sym *llabel;
7903
 
7904
        next();
7905
        /* record local declaration stack position */
7906
        s = local_stack;
7907
        llabel = local_label_stack;
7908
        /* handle local labels declarations */
7909
        if (tok == TOK_LABEL) {
7910
            next();
7911
            for(;;) {
7912
                if (tok < TOK_UIDENT)
7913
                    expect("label identifier");
7914
                label_push(&local_label_stack, tok, LABEL_DECLARED);
7915
                next();
7916
                if (tok == ',') {
7917
                    next();
7918
                } else {
7919
                    skip(';');
7920
                    break;
7921
                }
7922
            }
7923
        }
7924
        while (tok != '}') {
7925
            decl(VT_LOCAL);
7926
            if (tok != '}') {
7927
                if (is_expr)
7928
                    vpop();
7929
                block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
7930
            }
7931
        }
7932
        /* pop locally defined labels */
7933
        label_pop(&local_label_stack, llabel);
7934
        /* pop locally defined symbols */
7935
        sym_pop(&local_stack, s);
7936
        next();
7937
    } else if (tok == TOK_RETURN) {
7938
        next();
7939
        if (tok != ';') {
7940
            gexpr();
7941
            gen_assign_cast(&func_vt);
7942
            if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
7943
                CType type;
7944
                /* if returning structure, must copy it to implicit
7945
                   first pointer arg location */
7946
                type = func_vt;
7947
                mk_pointer(&type);
7948
                vset(&type, VT_LOCAL | VT_LVAL, func_vc);
7949
                indir();
7950
                vswap();
7951
                /* copy structure value to pointer */
7952
                vstore();
7953
            } else if (is_float(func_vt.t)) {
7954
                gv(RC_FRET);
7955
            } else {
7956
                gv(RC_IRET);
7957
            }
7958
            vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
7959
        }
7960
        skip(';');
7961
        rsym = gjmp(rsym); /* jmp */
7962
    } else if (tok == TOK_BREAK) {
7963
        /* compute jump */
7964
        if (!bsym)
7965
            error("cannot break");
7966
        *bsym = gjmp(*bsym);
7967
        next();
7968
        skip(';');
7969
    } else if (tok == TOK_CONTINUE) {
7970
        /* compute jump */
7971
        if (!csym)
7972
            error("cannot continue");
7973
        *csym = gjmp(*csym);
7974
        next();
7975
        skip(';');
7976
    } else if (tok == TOK_FOR) {
7977
        int e;
7978
        next();
7979
        skip('(');
7980
        if (tok != ';') {
7981
            gexpr();
7982
            vpop();
7983
        }
7984
        skip(';');
7985
        d = ind;
7986
        c = ind;
7987
        a = 0;
7988
        b = 0;
7989
        if (tok != ';') {
7990
            gexpr();
7991
            a = gtst(1, 0);
7992
        }
7993
        skip(';');
7994
        if (tok != ')') {
7995
            e = gjmp(0);
7996
            c = ind;
7997
            gexpr();
7998
            vpop();
7999
            gjmp_addr(d);
8000
            gsym(e);
8001
        }
8002
        skip(')');
8003
        block(&a, &b, case_sym, def_sym, case_reg, 0);
8004
        gjmp_addr(c);
8005
        gsym(a);
8006
        gsym_addr(b, c);
8007
    } else
8008
    if (tok == TOK_DO) {
8009
        next();
8010
        a = 0;
8011
        b = 0;
8012
        d = ind;
8013
        block(&a, &b, case_sym, def_sym, case_reg, 0);
8014
        skip(TOK_WHILE);
8015
        skip('(');
8016
        gsym(b);
8017
        gexpr();
8018
        c = gtst(0, 0);
8019
        gsym_addr(c, d);
8020
        skip(')');
8021
        gsym(a);
8022
        skip(';');
8023
    } else
8024
    if (tok == TOK_SWITCH) {
8025
        next();
8026
        skip('(');
8027
        gexpr();
8028
        /* XXX: other types than integer */
8029
        case_reg = gv(RC_INT);
8030
        vpop();
8031
        skip(')');
8032
        a = 0;
8033
        b = gjmp(0); /* jump to first case */
8034
        c = 0;
8035
        block(&a, csym, &b, &c, case_reg, 0);
8036
        /* if no default, jmp after switch */
8037
        if (c == 0)
8038
            c = ind;
8039
        /* default label */
8040
        gsym_addr(b, c);
8041
        /* break label */
8042
        gsym(a);
8043
    } else
8044
    if (tok == TOK_CASE) {
8045
        int v1, v2;
8046
        if (!case_sym)
8047
            expect("switch");
8048
        next();
8049
        v1 = expr_const();
8050
        v2 = v1;
8051
        if (gnu_ext && tok == TOK_DOTS) {
8052
            next();
8053
            v2 = expr_const();
8054
            if (v2 < v1)
8055
                warning("empty case range");
8056
        }
8057
        /* since a case is like a label, we must skip it with a jmp */
8058
        b = gjmp(0);
8059
        gsym(*case_sym);
8060
        vseti(case_reg, 0);
8061
        vpushi(v1);
8062
        if (v1 == v2) {
8063
            gen_op(TOK_EQ);
8064
            *case_sym = gtst(1, 0);
8065
        } else {
8066
            gen_op(TOK_GE);
8067
            *case_sym = gtst(1, 0);
8068
            vseti(case_reg, 0);
8069
            vpushi(v2);
8070
            gen_op(TOK_LE);
8071
            *case_sym = gtst(1, *case_sym);
8072
        }
8073
        gsym(b);
8074
        skip(':');
8075
        is_expr = 0;
8076
        goto block_after_label;
8077
    } else
8078
    if (tok == TOK_DEFAULT) {
8079
        next();
8080
        skip(':');
8081
        if (!def_sym)
8082
            expect("switch");
8083
        if (*def_sym)
8084
            error("too many 'default'");
8085
        *def_sym = ind;
8086
        is_expr = 0;
8087
        goto block_after_label;
8088
    } else
8089
    if (tok == TOK_GOTO) {
8090
        next();
8091
        if (tok == '*' && gnu_ext) {
8092
            /* computed goto */
8093
            next();
8094
            gexpr();
8095
            if ((vtop->type.t & VT_BTYPE) != VT_PTR)
8096
                expect("pointer");
8097
            ggoto();
8098
        } else if (tok >= TOK_UIDENT) {
8099
            s = label_find(tok);
8100
            /* put forward definition if needed */
8101
            if (!s) {
8102
                s = label_push(&global_label_stack, tok, LABEL_FORWARD);
8103
            } else {
8104
                if (s->r == LABEL_DECLARED)
8105
                    s->r = LABEL_FORWARD;
8106
            }
8107
            /* label already defined */
8108
            if (s->r & LABEL_FORWARD)
8109
                s->next = (void *)gjmp((long)s->next);
8110
            else
8111
                gjmp_addr((long)s->next);
8112
            next();
8113
        } else {
8114
            expect("label identifier");
8115
        }
8116
        skip(';');
8117
    } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
8118
        asm_instr();
8119
    } else {
8120
        b = is_label();
8121
        if (b) {
8122
            /* label case */
8123
            s = label_find(b);
8124
            if (s) {
8125
                if (s->r == LABEL_DEFINED)
8126
                    error("duplicate label '%s'", get_tok_str(s->v, NULL));
8127
                gsym((long)s->next);
8128
                s->r = LABEL_DEFINED;
8129
            } else {
8130
                s = label_push(&global_label_stack, b, LABEL_DEFINED);
8131
            }
8132
            s->next = (void *)ind;
8133
            /* we accept this, but it is a mistake */
8134
        block_after_label:
8135
            if (tok == '}') {
8136
                warning("deprecated use of label at end of compound statement");
8137
            } else {
8138
                if (is_expr)
8139
                    vpop();
8140
                block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
8141
            }
8142
        } else {
8143
            /* expression case */
8144
            if (tok != ';') {
8145
                if (is_expr) {
8146
                    vpop();
8147
                    gexpr();
8148
                } else {
8149
                    gexpr();
8150
                    vpop();
8151
                }
8152
            }
8153
            skip(';');
8154
        }
8155
    }
8156
}
8157
 
8158
/* t is the array or struct type. c is the array or struct
8159
   address. cur_index/cur_field is the pointer to the current
8160
   value. 'size_only' is true if only size info is needed (only used
8161
   in arrays) */
8162
static void decl_designator(CType *type, Section *sec, unsigned long c,
8163
                            int *cur_index, Sym **cur_field,
8164
                            int size_only)
8165
{
8166
    Sym *s, *f;
8167
    int notfirst, index, index_last, align, l, nb_elems, elem_size;
8168
    CType type1;
8169
 
8170
    notfirst = 0;
8171
    elem_size = 0;
8172
    nb_elems = 1;
8173
    if (gnu_ext && (l = is_label()) != 0)
8174
        goto struct_field;
8175
    while (tok == '[' || tok == '.') {
8176
        if (tok == '[') {
8177
            if (!(type->t & VT_ARRAY))
8178
                expect("array type");
8179
            s = type->ref;
8180
            next();
8181
            index = expr_const();
8182
            if (index < 0 || (s->c >= 0 && index >= s->c))
8183
                expect("invalid index");
8184
            if (tok == TOK_DOTS && gnu_ext) {
8185
                next();
8186
                index_last = expr_const();
8187
                if (index_last < 0 ||
8188
                    (s->c >= 0 && index_last >= s->c) ||
8189
                    index_last < index)
8190
                    expect("invalid index");
8191
            } else {
8192
                index_last = index;
8193
            }
8194
            skip(']');
8195
            if (!notfirst)
8196
                *cur_index = index_last;
8197
            type = pointed_type(type);
8198
            elem_size = type_size(type, &align);
8199
            c += index * elem_size;
8200
            /* NOTE: we only support ranges for last designator */
8201
            nb_elems = index_last - index + 1;
8202
            if (nb_elems != 1) {
8203
                notfirst = 1;
8204
                break;
8205
            }
8206
        } else {
8207
            next();
8208
            l = tok;
8209
            next();
8210
        struct_field:
8211
            if ((type->t & VT_BTYPE) != VT_STRUCT)
8212
                expect("struct/union type");
8213
            s = type->ref;
8214
            l |= SYM_FIELD;
8215
            f = s->next;
8216
            while (f) {
8217
                if (f->v == l)
8218
                    break;
8219
                f = f->next;
8220
            }
8221
            if (!f)
8222
                expect("field");
8223
            if (!notfirst)
8224
                *cur_field = f;
8225
            /* XXX: fix this mess by using explicit storage field */
8226
            type1 = f->type;
8227
            type1.t |= (type->t & ~VT_TYPE);
8228
            type = &type1;
8229
            c += f->c;
8230
        }
8231
        notfirst = 1;
8232
    }
8233
    if (notfirst) {
8234
        if (tok == '=') {
8235
            next();
8236
        } else {
8237
            if (!gnu_ext)
8238
                expect("=");
8239
        }
8240
    } else {
8241
        if (type->t & VT_ARRAY) {
8242
            index = *cur_index;
8243
            type = pointed_type(type);
8244
            c += index * type_size(type, &align);
8245
        } else {
8246
            f = *cur_field;
8247
            if (!f)
8248
                error("too many field init");
8249
            /* XXX: fix this mess by using explicit storage field */
8250
            type1 = f->type;
8251
            type1.t |= (type->t & ~VT_TYPE);
8252
            type = &type1;
8253
            c += f->c;
8254
        }
8255
    }
8256
    decl_initializer(type, sec, c, 0, size_only);
8257
 
8258
    /* XXX: make it more general */
8259
    if (!size_only && nb_elems > 1) {
8260
        unsigned long c_end;
8261
        uint8_t *src, *dst;
8262
        int i;
8263
 
8264
        if (!sec)
8265
            error("range init not supported yet for dynamic storage");
8266
        c_end = c + nb_elems * elem_size;
8267
        if (c_end > sec->data_allocated)
8268
            section_realloc(sec, c_end);
8269
        src = sec->data + c;
8270
        dst = src;
8271
        for(i = 1; i < nb_elems; i++) {
8272
            dst += elem_size;
8273
            memcpy(dst, src, elem_size);
8274
        }
8275
    }
8276
}
8277
 
8278
#define EXPR_VAL   0
8279
#define EXPR_CONST 1
8280
#define EXPR_ANY   2
8281
 
8282
/* store a value or an expression directly in global data or in local array */
8283
static void init_putv(CType *type, Section *sec, unsigned long c,
8284
                      int v, int expr_type)
8285
{
8286
    int saved_global_expr, bt, bit_pos, bit_size;
8287
    void *ptr;
8288
    unsigned long long bit_mask;
8289
    CType dtype;
8290
 
8291
    switch(expr_type) {
8292
    case EXPR_VAL:
8293
        vpushi(v);
8294
        break;
8295
    case EXPR_CONST:
8296
        /* compound literals must be allocated globally in this case */
8297
        saved_global_expr = global_expr;
8298
        global_expr = 1;
8299
        expr_const1();
8300
        global_expr = saved_global_expr;
8301
        /* NOTE: symbols are accepted */
8302
        if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
8303
            error("initializer element is not constant");
8304
        break;
8305
    case EXPR_ANY:
8306
        expr_eq();
8307
        break;
8308
    }
8309
 
8310
    dtype = *type;
8311
    dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
8312
 
8313
    if (sec) {
8314
        /* XXX: not portable */
8315
        /* XXX: generate error if incorrect relocation */
8316
        gen_assign_cast(&dtype);
8317
        bt = type->t & VT_BTYPE;
8318
        ptr = sec->data + c;
8319
        /* XXX: make code faster ? */
8320
        if (!(type->t & VT_BITFIELD)) {
8321
            bit_pos = 0;
8322
            bit_size = 32;
8323
            bit_mask = -1LL;
8324
        } else {
8325
            bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
8326
            bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
8327
            bit_mask = (1LL << bit_size) - 1;
8328
        }
8329
        if ((vtop->r & VT_SYM) &&
8330
            (bt == VT_BYTE ||
8331
             bt == VT_SHORT ||
8332
             bt == VT_DOUBLE ||
8333
             bt == VT_LDOUBLE ||
8334
             bt == VT_LLONG ||
8335
             (bt == VT_INT && bit_size != 32)))
8336
            error("initializer element is not computable at load time");
8337
        switch(bt) {
8338
        case VT_BYTE:
8339
            *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
8340
            break;
8341
        case VT_SHORT:
8342
            *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
8343
            break;
8344
        case VT_DOUBLE:
8345
            *(double *)ptr = vtop->c.d;
8346
            break;
8347
        case VT_LDOUBLE:
8348
            *(long double *)ptr = vtop->c.ld;
8349
            break;
8350
        case VT_LLONG:
8351
            *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
8352
            break;
8353
        default:
8354
            if (vtop->r & VT_SYM) {
8355
                greloc(sec, vtop->sym, c, R_DATA_32);
8356
            }
8357
            *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
8358
            break;
8359
        }
8360
        vtop--;
8361
    } else {
8362
        vset(&dtype, VT_LOCAL, c);
8363
        vswap();
8364
        vstore();
8365
        vpop();
8366
    }
8367
}
8368
 
8369
/* put zeros for variable based init */
8370
static void init_putz(CType *t, Section *sec, unsigned long c, int size)
8371
{
8372
    if (sec) {
8373
        /* nothing to do because globals are already set to zero */
8374
    } else {
8375
        vpush_global_sym(&func_old_type, TOK_memset);
8376
        vseti(VT_LOCAL, c);
8377
        vpushi(0);
8378
        vpushi(size);
8379
        gfunc_call(3);
8380
    }
8381
}
8382
 
8383
/* 't' contains the type and storage info. 'c' is the offset of the
8384
   object in section 'sec'. If 'sec' is NULL, it means stack based
8385
   allocation. 'first' is true if array '{' must be read (multi
8386
   dimension implicit array init handling). 'size_only' is true if
8387
   size only evaluation is wanted (only for arrays). */
8388
static void decl_initializer(CType *type, Section *sec, unsigned long c,
8389
                             int first, int size_only)
8390
{
8391
    int index, array_length, n, no_oblock, nb, parlevel, i;
8392
    int size1, align1, expr_type;
8393
    Sym *s, *f;
8394
    CType *t1;
8395
 
8396
    if (type->t & VT_ARRAY) {
8397
        s = type->ref;
8398
        n = s->c;
8399
        array_length = 0;
8400
        t1 = pointed_type(type);
8401
        size1 = type_size(t1, &align1);
8402
 
8403
        no_oblock = 1;
8404
        if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
8405
            tok == '{') {
8406
            skip('{');
8407
            no_oblock = 0;
8408
        }
8409
 
8410
        /* only parse strings here if correct type (otherwise: handle
8411
           them as ((w)char *) expressions */
8412
        if ((tok == TOK_LSTR &&
8413
             (t1->t & VT_BTYPE) == VT_INT) ||
8414
            (tok == TOK_STR &&
8415
             (t1->t & VT_BTYPE) == VT_BYTE)) {
8416
            while (tok == TOK_STR || tok == TOK_LSTR) {
8417
                int cstr_len, ch;
8418
                CString *cstr;
8419
 
8420
                cstr = tokc.cstr;
8421
                /* compute maximum number of chars wanted */
8422
                if (tok == TOK_STR)
8423
                    cstr_len = cstr->size;
8424
                else
8425
                    cstr_len = cstr->size / sizeof(int);
8426
                cstr_len--;
8427
                nb = cstr_len;
8428
                if (n >= 0 && nb > (n - array_length))
8429
                    nb = n - array_length;
8430
                if (!size_only) {
8431
                    if (cstr_len > nb)
8432
                        warning("initializer-string for array is too long");
8433
                    /* in order to go faster for common case (char
8434
                       string in global variable, we handle it
8435
                       specifically */
8436
                    if (sec && tok == TOK_STR && size1 == 1) {
8437
                        memcpy(sec->data + c + array_length, cstr->data, nb);
8438
                    } else {
8439
                        for(i=0;i
8440
                            if (tok == TOK_STR)
8441
                                ch = ((unsigned char *)cstr->data)[i];
8442
                            else
8443
                                ch = ((int *)cstr->data)[i];
8444
                            init_putv(t1, sec, c + (array_length + i) * size1,
8445
                                      ch, EXPR_VAL);
8446
                        }
8447
                    }
8448
                }
8449
                array_length += nb;
8450
                next();
8451
            }
8452
            /* only add trailing zero if enough storage (no
8453
               warning in this case since it is standard) */
8454
            if (n < 0 || array_length < n) {
8455
                if (!size_only) {
8456
                    init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
8457
                }
8458
                array_length++;
8459
            }
8460
        } else {
8461
            index = 0;
8462
            while (tok != '}') {
8463
                decl_designator(type, sec, c, &index, NULL, size_only);
8464
                if (n >= 0 && index >= n)
8465
                    error("index too large");
8466
                /* must put zero in holes (note that doing it that way
8467
                   ensures that it even works with designators) */
8468
                if (!size_only && array_length < index) {
8469
                    init_putz(t1, sec, c + array_length * size1,
8470
                              (index - array_length) * size1);
8471
                }
8472
                index++;
8473
                if (index > array_length)
8474
                    array_length = index;
8475
                /* special test for multi dimensional arrays (may not
8476
                   be strictly correct if designators are used at the
8477
                   same time) */
8478
                if (index >= n && no_oblock)
8479
                    break;
8480
                if (tok == '}')
8481
                    break;
8482
                skip(',');
8483
            }
8484
        }
8485
        if (!no_oblock)
8486
            skip('}');
8487
        /* put zeros at the end */
8488
        if (!size_only && n >= 0 && array_length < n) {
8489
            init_putz(t1, sec, c + array_length * size1,
8490
                      (n - array_length) * size1);
8491
        }
8492
        /* patch type size if needed */
8493
        if (n < 0)
8494
            s->c = array_length;
8495
    } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
8496
               (sec || !first || tok == '{')) {
8497
        int par_count;
8498
 
8499
        /* NOTE: the previous test is a specific case for automatic
8500
           struct/union init */
8501
        /* XXX: union needs only one init */
8502
 
8503
        /* XXX: this test is incorrect for local initializers
8504
           beginning with ( without {. It would be much more difficult
8505
           to do it correctly (ideally, the expression parser should
8506
           be used in all cases) */
8507
        par_count = 0;
8508
        if (tok == '(') {
8509
            AttributeDef ad1;
8510
            CType type1;
8511
            next();
8512
            while (tok == '(') {
8513
                par_count++;
8514
                next();
8515
            }
8516
            if (!parse_btype(&type1, &ad1))
8517
                expect("cast");
8518
            type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
8519
#if 0
8520
            if (!is_assignable_types(type, &type1))
8521
                error("invalid type for cast");
8522
#endif
8523
            skip(')');
8524
        }
8525
        no_oblock = 1;
8526
        if (first || tok == '{') {
8527
            skip('{');
8528
            no_oblock = 0;
8529
        }
8530
        s = type->ref;
8531
        f = s->next;
8532
        array_length = 0;
8533
        index = 0;
8534
        n = s->c;
8535
        while (tok != '}') {
8536
            decl_designator(type, sec, c, NULL, &f, size_only);
8537
            index = f->c;
8538
            if (!size_only && array_length < index) {
8539
                init_putz(type, sec, c + array_length,
8540
                          index - array_length);
8541
            }
8542
            index = index + type_size(&f->type, &align1);
8543
            if (index > array_length)
8544
                array_length = index;
8545
            f = f->next;
8546
            if (no_oblock && f == NULL)
8547
                break;
8548
            if (tok == '}')
8549
                break;
8550
            skip(',');
8551
        }
8552
        /* put zeros at the end */
8553
        if (!size_only && array_length < n) {
8554
            init_putz(type, sec, c + array_length,
8555
                      n - array_length);
8556
        }
8557
        if (!no_oblock)
8558
            skip('}');
8559
        while (par_count) {
8560
            skip(')');
8561
            par_count--;
8562
        }
8563
    } else if (tok == '{') {
8564
        next();
8565
        decl_initializer(type, sec, c, first, size_only);
8566
        skip('}');
8567
    } else if (size_only) {
8568
        /* just skip expression */
8569
        parlevel = 0;
8570
        while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
8571
               tok != -1) {
8572
            if (tok == '(')
8573
                parlevel++;
8574
            else if (tok == ')')
8575
                parlevel--;
8576
            next();
8577
        }
8578
    } else {
8579
        /* currently, we always use constant expression for globals
8580
           (may change for scripting case) */
8581
        expr_type = EXPR_CONST;
8582
        if (!sec)
8583
            expr_type = EXPR_ANY;
8584
        init_putv(type, sec, c, 0, expr_type);
8585
    }
8586
}
8587
 
8588
/* parse an initializer for type 't' if 'has_init' is non zero, and
8589
   allocate space in local or global data space ('r' is either
8590
   VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
8591
   variable 'v' of scope 'scope' is declared before initializers are
8592
   parsed. If 'v' is zero, then a reference to the new object is put
8593
   in the value stack. If 'has_init' is 2, a special parsing is done
8594
   to handle string constants. */
8595
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
8596
                                   int has_init, int v, int scope)
8597
{
8598
    int size, align, addr, data_offset;
8599
    int level;
8600
    ParseState saved_parse_state;
8601
    TokenString init_str;
8602
    Section *sec;
8603
 
8604
    size = type_size(type, &align);
8605
    /* If unknown size, we must evaluate it before
8606
       evaluating initializers because
8607
       initializers can generate global data too
8608
       (e.g. string pointers or ISOC99 compound
8609
       literals). It also simplifies local
8610
       initializers handling */
8611
    tok_str_new(&init_str);
8612
    if (size < 0) {
8613
        if (!has_init)
8614
            error("unknown type size");
8615
        /* get all init string */
8616
        if (has_init == 2) {
8617
            /* only get strings */
8618
            while (tok == TOK_STR || tok == TOK_LSTR) {
8619
                tok_str_add_tok(&init_str);
8620
                next();
8621
            }
8622
        } else {
8623
            level = 0;
8624
            while (level > 0 || (tok != ',' && tok != ';')) {
8625
                if (tok < 0)
8626
                    error("unexpected end of file in initializer");
8627
                tok_str_add_tok(&init_str);
8628
                if (tok == '{')
8629
                    level++;
8630
                else if (tok == '}') {
8631
                    if (level == 0)
8632
                        break;
8633
                    level--;
8634
                }
8635
                next();
8636
            }
8637
        }
8638
        tok_str_add(&init_str, -1);
8639
        tok_str_add(&init_str, 0);
8640
 
8641
        /* compute size */
8642
        save_parse_state(&saved_parse_state);
8643
 
8644
        macro_ptr = init_str.str;
8645
        next();
8646
        decl_initializer(type, NULL, 0, 1, 1);
8647
        /* prepare second initializer parsing */
8648
        macro_ptr = init_str.str;
8649
        next();
8650
 
8651
        /* if still unknown size, error */
8652
        size = type_size(type, &align);
8653
        if (size < 0)
8654
            error("unknown type size");
8655
    }
8656
    /* take into account specified alignment if bigger */
8657
    if (ad->aligned) {
8658
        if (ad->aligned > align)
8659
            align = ad->aligned;
8660
    } else if (ad->packed) {
8661
        align = 1;
8662
    }
8663
    if ((r & VT_VALMASK) == VT_LOCAL) {
8664
        sec = NULL;
8665
        if (do_bounds_check && (type->t & VT_ARRAY))
8666
            loc--;
8667
        loc = (loc - size) & -align;
8668
        addr = loc;
8669
        /* handles bounds */
8670
        /* XXX: currently, since we do only one pass, we cannot track
8671
           '&' operators, so we add only arrays */
8672
        if (do_bounds_check && (type->t & VT_ARRAY)) {
8673
            unsigned long *bounds_ptr;
8674
            /* add padding between regions */
8675
            loc--;
8676
            /* then add local bound info */
8677
            bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
8678
            bounds_ptr[0] = addr;
8679
            bounds_ptr[1] = size;
8680
        }
8681
        if (v) {
8682
            /* local variable */
8683
            sym_push(v, type, r, addr);
8684
        } else {
8685
            /* push local reference */
8686
            vset(type, r, addr);
8687
        }
8688
    } else {
8689
        Sym *sym;
8690
 
8691
        sym = NULL;
8692
        if (v && scope == VT_CONST) {
8693
            /* see if the symbol was already defined */
8694
            sym = sym_find(v);
8695
            if (sym) {
8696
                if (!is_compatible_types(&sym->type, type))
8697
                    error("incompatible types for redefinition of '%s'",
8698
                          get_tok_str(v, NULL));
8699
                if (sym->type.t & VT_EXTERN) {
8700
                    /* if the variable is extern, it was not allocated */
8701
                    sym->type.t &= ~VT_EXTERN;
8702
                    /* set array size if it was ommited in extern
8703
                       declaration */
8704
                    if ((sym->type.t & VT_ARRAY) &&
8705
                        sym->type.ref->c < 0 &&
8706
                        type->ref->c >= 0)
8707
                        sym->type.ref->c = type->ref->c;
8708
                } else {
8709
                    /* we accept several definitions of the same
8710
                       global variable. this is tricky, because we
8711
                       must play with the SHN_COMMON type of the symbol */
8712
                    /* XXX: should check if the variable was already
8713
                       initialized. It is incorrect to initialized it
8714
                       twice */
8715
                    /* no init data, we won't add more to the symbol */
8716
                    if (!has_init)
8717
                        goto no_alloc;
8718
                }
8719
            }
8720
        }
8721
 
8722
        /* allocate symbol in corresponding section */
8723
        sec = ad->section;
8724
        if (!sec) {
8725
            if (has_init)
8726
                sec = data_section;
8727
            else if (tcc_state->nocommon)
8728
                sec = bss_section;
8729
        }
8730
        if (sec) {
8731
            data_offset = sec->data_offset;
8732
            data_offset = (data_offset + align - 1) & -align;
8733
            addr = data_offset;
8734
            /* very important to increment global pointer at this time
8735
               because initializers themselves can create new initializers */
8736
            data_offset += size;
8737
            /* add padding if bound check */
8738
            if (do_bounds_check)
8739
                data_offset++;
8740
            sec->data_offset = data_offset;
8741
            /* allocate section space to put the data */
8742
            if (sec->sh_type != SHT_NOBITS &&
8743
                data_offset > sec->data_allocated)
8744
                section_realloc(sec, data_offset);
8745
            /* align section if needed */
8746
            if (align > sec->sh_addralign)
8747
                sec->sh_addralign = align;
8748
        } else {
8749
            addr = 0; /* avoid warning */
8750
        }
8751
 
8752
        if (v) {
8753
            if (scope == VT_CONST) {
8754
                if (!sym)
8755
                    goto do_def;
8756
            } else {
8757
            do_def:
8758
                sym = sym_push(v, type, r | VT_SYM, 0);
8759
            }
8760
            /* update symbol definition */
8761
            if (sec) {
8762
                put_extern_sym(sym, sec, addr, size);
8763
            } else {
8764
                Elf32_Sym *esym;
8765
                /* put a common area */
8766
                put_extern_sym(sym, NULL, align, size);
8767
                /* XXX: find a nicer way */
8768
                esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
8769
                esym->st_shndx = SHN_COMMON;
8770
            }
8771
        } else {
8772
            CValue cval;
8773
 
8774
            /* push global reference */
8775
            sym = get_sym_ref(type, sec, addr, size);
8776
            cval.ul = 0;
8777
            vsetc(type, VT_CONST | VT_SYM, &cval);
8778
            vtop->sym = sym;
8779
        }
8780
 
8781
        /* handles bounds now because the symbol must be defined
8782
           before for the relocation */
8783
        if (do_bounds_check) {
8784
            unsigned long *bounds_ptr;
8785
 
8786
            greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
8787
            /* then add global bound info */
8788
            bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
8789
            bounds_ptr[0] = 0; /* relocated */
8790
            bounds_ptr[1] = size;
8791
        }
8792
    }
8793
    if (has_init) {
8794
        decl_initializer(type, sec, addr, 1, 0);
8795
        /* restore parse state if needed */
8796
        if (init_str.str) {
8797
            tok_str_free(init_str.str);
8798
            restore_parse_state(&saved_parse_state);
8799
        }
8800
    }
8801
 no_alloc: ;
8802
}
8803
 
8804
void put_func_debug(Sym *sym)
8805
{
8806
    char buf[512];
8807
 
8808
    /* stabs info */
8809
    /* XXX: we put here a dummy type */
8810
    snprintf(buf, sizeof(buf), "%s:%c1",
8811
             funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
8812
    put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
8813
                cur_text_section, sym->c);
8814
    last_ind = 0;
8815
    last_line_num = 0;
8816
}
8817
 
8818
/* parse an old style function declaration list */
8819
/* XXX: check multiple parameter */
8820
static void func_decl_list(Sym *func_sym)
8821
{
8822
    AttributeDef ad;
8823
    int v;
8824
    Sym *s;
8825
    CType btype, type;
8826
 
8827
    /* parse each declaration */
8828
    while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
8829
        if (!parse_btype(&btype, &ad))
8830
            expect("declaration list");
8831
        if (((btype.t & VT_BTYPE) == VT_ENUM ||
8832
             (btype.t & VT_BTYPE) == VT_STRUCT) &&
8833
            tok == ';') {
8834
            /* we accept no variable after */
8835
        } else {
8836
            for(;;) {
8837
                type = btype;
8838
                type_decl(&type, &ad, &v, TYPE_DIRECT);
8839
                /* find parameter in function parameter list */
8840
                s = func_sym->next;
8841
                while (s != NULL) {
8842
                    if ((s->v & ~SYM_FIELD) == v)
8843
                        goto found;
8844
                    s = s->next;
8845
                }
8846
                error("declaration for parameter '%s' but no such parameter",
8847
                      get_tok_str(v, NULL));
8848
            found:
8849
                /* check that no storage specifier except 'register' was given */
8850
                if (type.t & VT_STORAGE)
8851
                    error("storage class specified for '%s'", get_tok_str(v, NULL));
8852
                convert_parameter_type(&type);
8853
                /* we can add the type (NOTE: it could be local to the function) */
8854
                s->type = type;
8855
                /* accept other parameters */
8856
                if (tok == ',')
8857
                    next();
8858
                else
8859
                    break;
8860
            }
8861
        }
8862
        skip(';');
8863
    }
8864
}
8865
 
8866
/* parse a function defined by symbol 'sym' and generate its code in
8867
   'cur_text_section' */
8868
static void gen_function(Sym *sym)
8869
{
8870
    ind = cur_text_section->data_offset;
8871
    /* NOTE: we patch the symbol size later */
8872
    put_extern_sym(sym, cur_text_section, ind, 0);
8873
    funcname = get_tok_str(sym->v, NULL);
8874
    func_ind = ind;
8875
    /* put debug symbol */
8876
    if (do_debug)
8877
        put_func_debug(sym);
8878
    /* push a dummy symbol to enable local sym storage */
8879
    sym_push2(&local_stack, SYM_FIELD, 0, 0);
8880
    gfunc_prolog(&sym->type);
8881
    rsym = 0;
8882
    block(NULL, NULL, NULL, NULL, 0, 0);
8883
    gsym(rsym);
8884
    gfunc_epilog();
8885
    cur_text_section->data_offset = ind;
8886
    label_pop(&global_label_stack, NULL);
8887
    sym_pop(&local_stack, NULL); /* reset local stack */
8888
    /* end of function */
8889
    /* patch symbol size */
8890
    ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
8891
        ind - func_ind;
8892
    if (do_debug) {
8893
        put_stabn(N_FUN, 0, 0, ind - func_ind);
8894
    }
8895
    funcname = ""; /* for safety */
8896
    func_vt.t = VT_VOID; /* for safety */
8897
    ind = 0; /* for safety */
8898
}
8899
 
8900
static void gen_inline_functions(void)
8901
{
8902
    Sym *sym;
8903
    CType *type;
8904
    int *str, inline_generated;
8905
 
8906
    /* iterate while inline function are referenced */
8907
    for(;;) {
8908
        inline_generated = 0;
8909
        for(sym = global_stack; sym != NULL; sym = sym->prev) {
8910
            type = &sym->type;
8911
            if (((type->t & VT_BTYPE) == VT_FUNC) &&
8912
                (type->t & (VT_STATIC | VT_INLINE)) ==
8913
                (VT_STATIC | VT_INLINE) &&
8914
                sym->c != 0) {
8915
                /* the function was used: generate its code and
8916
                   convert it to a normal function */
8917
                str = (int *)sym->r;
8918
                sym->r = VT_SYM | VT_CONST;
8919
                type->t &= ~VT_INLINE;
8920
 
8921
                macro_ptr = str;
8922
                next();
8923
                cur_text_section = text_section;
8924
                gen_function(sym);
8925
                macro_ptr = NULL; /* fail safe */
8926
 
8927
                tok_str_free(str);
8928
                inline_generated = 1;
8929
            }
8930
        }
8931
        if (!inline_generated)
8932
            break;
8933
    }
8934
 
8935
    /* free all remaining inline function tokens */
8936
    for(sym = global_stack; sym != NULL; sym = sym->prev) {
8937
        type = &sym->type;
8938
        if (((type->t & VT_BTYPE) == VT_FUNC) &&
8939
            (type->t & (VT_STATIC | VT_INLINE)) ==
8940
            (VT_STATIC | VT_INLINE)) {
8941
            str = (int *)sym->r;
8942
            tok_str_free(str);
8943
            sym->r = 0; /* fail safe */
8944
        }
8945
    }
8946
}
8947
 
8948
/* 'l' is VT_LOCAL or VT_CONST to define default storage type */
8949
static void decl(int l)
8950
{
8951
    int v, has_init, r;
8952
    CType type, btype;
8953
    Sym *sym;
8954
    AttributeDef ad;
8955
 
8956
    while (1) {
8957
        if (!parse_btype(&btype, &ad)) {
8958
            /* skip redundant ';' */
8959
            /* XXX: find more elegant solution */
8960
            if (tok == ';') {
8961
                next();
8962
                continue;
8963
            }
8964
            if (l == VT_CONST &&
8965
                (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
8966
                /* global asm block */
8967
                asm_global_instr();
8968
                continue;
8969
            }
8970
            /* special test for old K&R protos without explicit int
8971
               type. Only accepted when defining global data */
8972
            if (l == VT_LOCAL || tok < TOK_DEFINE)
8973
                break;
8974
            btype.t = VT_INT;
8975
        }
8976
        if (((btype.t & VT_BTYPE) == VT_ENUM ||
8977
             (btype.t & VT_BTYPE) == VT_STRUCT) &&
8978
            tok == ';') {
8979
            /* we accept no variable after */
8980
            next();
8981
            continue;
8982
        }
8983
        while (1) { /* iterate thru each declaration */
8984
            type = btype;
8985
            type_decl(&type, &ad, &v, TYPE_DIRECT);
8986
#if 0
8987
            {
8988
                char buf[500];
8989
                type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
8990
                printf("type = '%s'\n", buf);
8991
            }
8992
#endif
8993
            if ((type.t & VT_BTYPE) == VT_FUNC) {
8994
                /* if old style function prototype, we accept a
8995
                   declaration list */
8996
                sym = type.ref;
8997
                if (sym->c == FUNC_OLD)
8998
                    func_decl_list(sym);
8999
            }
9000
 
9001
            if (tok == '{') {
9002
                if (l == VT_LOCAL)
9003
                    error("cannot use local functions");
9004
                if (!(type.t & VT_FUNC))
9005
                    expect("function definition");
9006
 
9007
                /* reject abstract declarators in function definition */
9008
                sym = type.ref;
9009
                while ((sym = sym->next) != NULL)
9010
                    if (!(sym->v & ~SYM_FIELD))
9011
                       expect("identifier");
9012
 
9013
                /* XXX: cannot do better now: convert extern line to static inline */
9014
                if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
9015
                    type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
9016
 
9017
                sym = sym_find(v);
9018
                if (sym) {
9019
                    if ((sym->type.t & VT_BTYPE) != VT_FUNC)
9020
                        goto func_error1;
9021
                    /* specific case: if not func_call defined, we put
9022
                       the one of the prototype */
9023
                    /* XXX: should have default value */
9024
                    if (sym->type.ref->r != FUNC_CDECL &&
9025
                        type.ref->r == FUNC_CDECL)
9026
                        type.ref->r = sym->type.ref->r;
9027
                    if (!is_compatible_types(&sym->type, &type)) {
9028
                    func_error1:
9029
                        error("incompatible types for redefinition of '%s'",
9030
                              get_tok_str(v, NULL));
9031
                    }
9032
                    /* if symbol is already defined, then put complete type */
9033
                    sym->type = type;
9034
                } else {
9035
                    /* put function symbol */
9036
                    sym = global_identifier_push(v, type.t, 0);
9037
                    sym->type.ref = type.ref;
9038
                }
9039
 
9040
                /* static inline functions are just recorded as a kind
9041
                   of macro. Their code will be emitted at the end of
9042
                   the compilation unit only if they are used */
9043
                if ((type.t & (VT_INLINE | VT_STATIC)) ==
9044
                    (VT_INLINE | VT_STATIC)) {
9045
                    TokenString func_str;
9046
                    int block_level;
9047
 
9048
                    tok_str_new(&func_str);
9049
 
9050
                    block_level = 0;
9051
                    for(;;) {
9052
                        int t;
9053
                        if (tok == TOK_EOF)
9054
                            error("unexpected end of file");
9055
                        tok_str_add_tok(&func_str);
9056
                        t = tok;
9057
                        next();
9058
                        if (t == '{') {
9059
                            block_level++;
9060
                        } else if (t == '}') {
9061
                            block_level--;
9062
                            if (block_level == 0)
9063
                                break;
9064
                        }
9065
                    }
9066
                    tok_str_add(&func_str, -1);
9067
                    tok_str_add(&func_str, 0);
9068
                    sym->r = (int)func_str.str;
9069
                } else {
9070
                    /* compute text section */
9071
                    cur_text_section = ad.section;
9072
                    if (!cur_text_section)
9073
                        cur_text_section = text_section;
9074
                    sym->r = VT_SYM | VT_CONST;
9075
                    gen_function(sym);
9076
#ifdef TCC_TARGET_PE
9077
                    if (ad.dllexport) {
9078
                        ((Elf32_Sym *)symtab_section->data)[sym->c].st_other |= 1;
9079
                    }
9080
#endif
9081
                }
9082
                break;
9083
            } else {
9084
                if (btype.t & VT_TYPEDEF) {
9085
                    /* save typedefed type  */
9086
                    /* XXX: test storage specifiers ? */
9087
                    sym = sym_push(v, &type, 0, 0);
9088
                    sym->type.t |= VT_TYPEDEF;
9089
                } else if ((type.t & VT_BTYPE) == VT_FUNC) {
9090
                    /* external function definition */
9091
                    /* specific case for func_call attribute */
9092
                    if (ad.func_call)
9093
                        type.ref->r = ad.func_call;
9094
                    external_sym(v, &type, 0);
9095
                } else {
9096
                    /* not lvalue if array */
9097
                    r = 0;
9098
                    if (!(type.t & VT_ARRAY))
9099
                        r |= lvalue_type(type.t);
9100
                    has_init = (tok == '=');
9101
                    if ((btype.t & VT_EXTERN) ||
9102
                        ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
9103
                         !has_init && l == VT_CONST && type.ref->c < 0)) {
9104
                        /* external variable */
9105
                        /* NOTE: as GCC, uninitialized global static
9106
                           arrays of null size are considered as
9107
                           extern */
9108
                        external_sym(v, &type, r);
9109
                    } else {
9110
                        if (type.t & VT_STATIC)
9111
                            r |= VT_CONST;
9112
                        else
9113
                            r |= l;
9114
                        if (has_init)
9115
                            next();
9116
                        decl_initializer_alloc(&type, &ad, r,
9117
                                               has_init, v, l);
9118
                    }
9119
                }
9120
                if (tok != ',') {
9121
                    skip(';');
9122
                    break;
9123
                }
9124
                next();
9125
            }
9126
        }
9127
    }
9128
}
9129
 
9130
/* better than nothing, but needs extension to handle '-E' option
9131
   correctly too */
9132
static void preprocess_init(TCCState *s1)
9133
{
9134
    s1->include_stack_ptr = s1->include_stack;
9135
    /* XXX: move that before to avoid having to initialize
9136
       file->ifdef_stack_ptr ? */
9137
    s1->ifdef_stack_ptr = s1->ifdef_stack;
9138
    file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
9139
 
9140
    /* XXX: not ANSI compliant: bound checking says error */
9141
    vtop = vstack - 1;
9142
    s1->pack_stack[0] = 0;
9143
    s1->pack_stack_ptr = s1->pack_stack;
9144
}
9145
 
9146
/* compile the C file opened in 'file'. Return non zero if errors. */
9147
static int tcc_compile(TCCState *s1)
9148
{
9149
    Sym *define_start;
9150
    char buf[512];
9151
    volatile int section_sym;
9152
 
9153
#ifdef INC_DEBUG
9154
    printf("%s: **** new file\n", file->filename);
9155
#endif
9156
    preprocess_init(s1);
9157
 
9158
    funcname = "";
9159
    anon_sym = SYM_FIRST_ANOM;
9160
 
9161
    /* file info: full path + filename */
9162
    section_sym = 0; /* avoid warning */
9163
    if (do_debug) {
9164
        section_sym = put_elf_sym(symtab_section, 0, 0,
9165
                                  ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
9166
                                  text_section->sh_num, NULL);
9167
        getcwd(buf, sizeof(buf));
9168
        pstrcat(buf, sizeof(buf), "/");
9169
        put_stabs_r(buf, N_SO, 0, 0,
9170
                    text_section->data_offset, text_section, section_sym);
9171
        put_stabs_r(file->filename, N_SO, 0, 0,
9172
                    text_section->data_offset, text_section, section_sym);
9173
    }
9174
    /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
9175
       symbols can be safely used */
9176
    put_elf_sym(symtab_section, 0, 0,
9177
                ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
9178
                SHN_ABS, file->filename);
9179
 
9180
    /* define some often used types */
9181
    int_type.t = VT_INT;
9182
 
9183
    char_pointer_type.t = VT_BYTE;
9184
    mk_pointer(&char_pointer_type);
9185
 
9186
    func_old_type.t = VT_FUNC;
9187
    func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
9188
 
9189
#if 0
9190
    /* define 'void *alloca(unsigned int)' builtin function */
9191
    {
9192
        Sym *s1;
9193
 
9194
        p = anon_sym++;
9195
        sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
9196
        s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
9197
        s1->next = NULL;
9198
        sym->next = s1;
9199
        sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
9200
    }
9201
#endif
9202
 
9203
    define_start = define_stack;
9204
 
9205
    if (setjmp(s1->error_jmp_buf) == 0) {
9206
        s1->nb_errors = 0;
9207
        s1->error_set_jmp_enabled = 1;
9208
 
9209
        ch = file->buf_ptr[0];
9210
        tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
9211
        parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
9212
        next();
9213
        decl(VT_CONST);
9214
        if (tok != TOK_EOF)
9215
            expect("declaration");
9216
 
9217
        /* end of translation unit info */
9218
        if (do_debug) {
9219
            put_stabs_r(NULL, N_SO, 0, 0,
9220
                        text_section->data_offset, text_section, section_sym);
9221
        }
9222
    }
9223
    s1->error_set_jmp_enabled = 0;
9224
 
9225
    /* reset define stack, but leave -Dsymbols (may be incorrect if
9226
       they are undefined) */
9227
    free_defines(define_start);
9228
 
9229
    gen_inline_functions();
9230
 
9231
    sym_pop(&global_stack, NULL);
9232
 
9233
    return s1->nb_errors != 0 ? -1 : 0;
9234
}
9235
 
9236
#ifdef LIBTCC
9237
int tcc_compile_string(TCCState *s, const char *str)
9238
{
9239
    BufferedFile bf1, *bf = &bf1;
9240
    int ret, len;
9241
    char *buf;
9242
 
9243
    /* init file structure */
9244
    bf->fd = -1;
9245
    /* XXX: avoid copying */
9246
    len = strlen(str);
9247
    buf = tcc_malloc(len + 1);
9248
    if (!buf)
9249
        return -1;
9250
    memcpy(buf, str, len);
9251
    buf[len] = CH_EOB;
9252
    bf->buf_ptr = buf;
9253
    bf->buf_end = buf + len;
9254
    pstrcpy(bf->filename, sizeof(bf->filename), "");
9255
    bf->line_num = 1;
9256
    file = bf;
9257
 
9258
    ret = tcc_compile(s);
9259
 
9260
    tcc_free(buf);
9261
 
9262
    /* currently, no need to close */
9263
    return ret;
9264
}
9265
#endif
9266
 
9267
/* define a preprocessor symbol. A value can also be provided with the '=' operator */
9268
void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
9269
{
9270
    BufferedFile bf1, *bf = &bf1;
9271
 
9272
    pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
9273
    pstrcat(bf->buffer, IO_BUF_SIZE, " ");
9274
    /* default value */
9275
    if (!value)
9276
        value = "1";
9277
    pstrcat(bf->buffer, IO_BUF_SIZE, value);
9278
 
9279
    /* init file structure */
9280
    bf->fd = -1;
9281
    bf->buf_ptr = bf->buffer;
9282
    bf->buf_end = bf->buffer + strlen(bf->buffer);
9283
    *bf->buf_end = CH_EOB;
9284
    bf->filename[0] = '\0';
9285
    bf->line_num = 1;
9286
    file = bf;
9287
 
9288
    s1->include_stack_ptr = s1->include_stack;
9289
 
9290
    /* parse with define parser */
9291
    ch = file->buf_ptr[0];
9292
    next_nomacro();
9293
    parse_define();
9294
    file = NULL;
9295
}
9296
 
9297
/* undefine a preprocessor symbol */
9298
void tcc_undefine_symbol(TCCState *s1, const char *sym)
9299
{
9300
    TokenSym *ts;
9301
    Sym *s;
9302
    ts = tok_alloc(sym, strlen(sym));
9303
    s = define_find(ts->tok);
9304
    /* undefine symbol by putting an invalid name */
9305
    if (s)
9306
        define_undef(s);
9307
}
9308
 
9309
#ifdef CONFIG_TCC_ASM
9310
 
9311
#ifdef TCC_TARGET_I386
9312
#include "i386-asm.c"
9313
#endif
9314
#include "tccasm.c"
9315
 
9316
#else
9317
static void asm_instr(void)
9318
{
9319
    error("inline asm() not supported");
9320
}
9321
static void asm_global_instr(void)
9322
{
9323
    error("inline asm() not supported");
9324
}
9325
#endif
9326
 
9327
#include "tccelf.c"
9328
 
9329
#ifdef TCC_TARGET_COFF
9330
#include "tcccoff.c"
9331
#endif
9332
 
9333
#if defined(TCC_TARGET_PE) || defined(TCC_TARGET_MEOS)
9334
#include "tccpe.c"
9335
#endif
9336
 
9337
#ifdef TCC_TARGET_MEOS
9338
#include "tccmeos.c"
9339
#endif
9340
 
9341
/* print the position in the source file of PC value 'pc' by reading
9342
   the stabs debug information */
9343
static void rt_printline(unsigned long wanted_pc)
9344
{
9345
    Stab_Sym *sym, *sym_end;
9346
    char func_name[128], last_func_name[128];
9347
    unsigned long func_addr, last_pc, pc;
9348
    const char *incl_files[INCLUDE_STACK_SIZE];
9349
    int incl_index, len, last_line_num, i;
9350
    const char *str, *p;
9351
 
9352
    fprintf(stderr, "0x%08lx:", wanted_pc);
9353
 
9354
    func_name[0] = '\0';
9355
    func_addr = 0;
9356
    incl_index = 0;
9357
    last_func_name[0] = '\0';
9358
    last_pc = 0xffffffff;
9359
    last_line_num = 1;
9360
    sym = (Stab_Sym *)stab_section->data + 1;
9361
    sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
9362
    while (sym < sym_end) {
9363
        switch(sym->n_type) {
9364
            /* function start or end */
9365
        case N_FUN:
9366
            if (sym->n_strx == 0) {
9367
                /* we test if between last line and end of function */
9368
                pc = sym->n_value + func_addr;
9369
                if (wanted_pc >= last_pc && wanted_pc < pc)
9370
                    goto found;
9371
                func_name[0] = '\0';
9372
                func_addr = 0;
9373
            } else {
9374
                str = stabstr_section->data + sym->n_strx;
9375
                p = strchr(str, ':');
9376
                if (!p) {
9377
                    pstrcpy(func_name, sizeof(func_name), str);
9378
                } else {
9379
                    len = p - str;
9380
                    if (len > sizeof(func_name) - 1)
9381
                        len = sizeof(func_name) - 1;
9382
                    memcpy(func_name, str, len);
9383
                    func_name[len] = '\0';
9384
                }
9385
                func_addr = sym->n_value;
9386
            }
9387
            break;
9388
            /* line number info */
9389
        case N_SLINE:
9390
            pc = sym->n_value + func_addr;
9391
            if (wanted_pc >= last_pc && wanted_pc < pc)
9392
                goto found;
9393
            last_pc = pc;
9394
            last_line_num = sym->n_desc;
9395
            /* XXX: slow! */
9396
            strcpy(last_func_name, func_name);
9397
            break;
9398
            /* include files */
9399
        case N_BINCL:
9400
            str = stabstr_section->data + sym->n_strx;
9401
        add_incl:
9402
            if (incl_index < INCLUDE_STACK_SIZE) {
9403
                incl_files[incl_index++] = str;
9404
            }
9405
            break;
9406
        case N_EINCL:
9407
            if (incl_index > 1)
9408
                incl_index--;
9409
            break;
9410
        case N_SO:
9411
            if (sym->n_strx == 0) {
9412
                incl_index = 0; /* end of translation unit */
9413
            } else {
9414
                str = stabstr_section->data + sym->n_strx;
9415
                /* do not add path */
9416
                len = strlen(str);
9417
                if (len > 0 && str[len - 1] != '/')
9418
                    goto add_incl;
9419
            }
9420
            break;
9421
        }
9422
        sym++;
9423
    }
9424
 
9425
    /* second pass: we try symtab symbols (no line number info) */
9426
    incl_index = 0;
9427
    {
9428
        Elf32_Sym *sym, *sym_end;
9429
        int type;
9430
 
9431
        sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
9432
        for(sym = (Elf32_Sym *)symtab_section->data + 1;
9433
            sym < sym_end;
9434
            sym++) {
9435
            type = ELF32_ST_TYPE(sym->st_info);
9436
            if (type == STT_FUNC) {
9437
                if (wanted_pc >= sym->st_value &&
9438
                    wanted_pc < sym->st_value + sym->st_size) {
9439
                    pstrcpy(last_func_name, sizeof(last_func_name),
9440
                            strtab_section->data + sym->st_name);
9441
                    goto found;
9442
                }
9443
            }
9444
        }
9445
    }
9446
    /* did not find any info: */
9447
    fprintf(stderr, " ???\n");
9448
    return;
9449
 found:
9450
    if (last_func_name[0] != '\0') {
9451
        fprintf(stderr, " %s()", last_func_name);
9452
    }
9453
    if (incl_index > 0) {
9454
        fprintf(stderr, " (%s:%d",
9455
                incl_files[incl_index - 1], last_line_num);
9456
        for(i = incl_index - 2; i >= 0; i--)
9457
            fprintf(stderr, ", included from %s", incl_files[i]);
9458
        fprintf(stderr, ")");
9459
    }
9460
    fprintf(stderr, "\n");
9461
}
9462
 
9463
#if !defined(WIN32) && !defined(CONFIG_TCCBOOT)
9464
 
9465
#ifdef __i386__
9466
 
9467
/* fix for glibc 2.1 */
9468
#ifndef REG_EIP
9469
#define REG_EIP EIP
9470
#define REG_EBP EBP
9471
#endif
9472
 
9473
/* return the PC at frame level 'level'. Return non zero if not found */
9474
static int rt_get_caller_pc(unsigned long *paddr,
9475
                            ucontext_t *uc, int level)
9476
{
9477
    unsigned long fp;
9478
    int i;
9479
 
9480
    if (level == 0) {
9481
#if defined(__FreeBSD__)
9482
        *paddr = uc->uc_mcontext.mc_eip;
9483
#elif defined(__dietlibc__)
9484
        *paddr = uc->uc_mcontext.eip;
9485
#else
9486
        *paddr = uc->uc_mcontext.gregs[REG_EIP];
9487
#endif
9488
        return 0;
9489
    } else {
9490
#if defined(__FreeBSD__)
9491
        fp = uc->uc_mcontext.mc_ebp;
9492
#elif defined(__dietlibc__)
9493
        fp = uc->uc_mcontext.ebp;
9494
#else
9495
        fp = uc->uc_mcontext.gregs[REG_EBP];
9496
#endif
9497
        for(i=1;i
9498
            /* XXX: check address validity with program info */
9499
            if (fp <= 0x1000 || fp >= 0xc0000000)
9500
                return -1;
9501
            fp = ((unsigned long *)fp)[0];
9502
        }
9503
        *paddr = ((unsigned long *)fp)[1];
9504
        return 0;
9505
    }
9506
}
9507
#else
9508
 
9509
#warning add arch specific rt_get_caller_pc()
9510
 
9511
static int rt_get_caller_pc(unsigned long *paddr,
9512
                            ucontext_t *uc, int level)
9513
{
9514
    return -1;
9515
}
9516
#endif
9517
 
9518
/* emit a run time error at position 'pc' */
9519
void rt_error(ucontext_t *uc, const char *fmt, ...)
9520
{
9521
    va_list ap;
9522
    unsigned long pc;
9523
    int i;
9524
 
9525
    va_start(ap, fmt);
9526
    fprintf(stderr, "Runtime error: ");
9527
    vfprintf(stderr, fmt, ap);
9528
    fprintf(stderr, "\n");
9529
    for(i=0;i
9530
        if (rt_get_caller_pc(&pc, uc, i) < 0)
9531
            break;
9532
        if (i == 0)
9533
            fprintf(stderr, "at ");
9534
        else
9535
            fprintf(stderr, "by ");
9536
        rt_printline(pc);
9537
    }
9538
    exit(255);
9539
    va_end(ap);
9540
}
9541
 
9542
/* signal handler for fatal errors */
9543
static void sig_error(int signum, siginfo_t *siginf, void *puc)
9544
{
9545
    ucontext_t *uc = puc;
9546
 
9547
    switch(signum) {
9548
    case SIGFPE:
9549
        switch(siginf->si_code) {
9550
        case FPE_INTDIV:
9551
        case FPE_FLTDIV:
9552
            rt_error(uc, "division by zero");
9553
            break;
9554
        default:
9555
            rt_error(uc, "floating point exception");
9556
            break;
9557
        }
9558
        break;
9559
    case SIGBUS:
9560
    case SIGSEGV:
9561
        if (rt_bound_error_msg && *rt_bound_error_msg)
9562
            rt_error(uc, *rt_bound_error_msg);
9563
        else
9564
            rt_error(uc, "dereferencing invalid pointer");
9565
        break;
9566
    case SIGILL:
9567
        rt_error(uc, "illegal instruction");
9568
        break;
9569
    case SIGABRT:
9570
        rt_error(uc, "abort() called");
9571
        break;
9572
    default:
9573
        rt_error(uc, "caught signal %d", signum);
9574
        break;
9575
    }
9576
    exit(255);
9577
}
9578
#endif
9579
 
9580
/* do all relocations (needed before using tcc_get_symbol()) */
9581
int tcc_relocate(TCCState *s1)
9582
{
9583
    Section *s;
9584
    int i;
9585
 
9586
    s1->nb_errors = 0;
9587
 
9588
#if defined(TCC_TARGET_PE) || defined(TCC_TARGET_MEOS)
9589
    pe_add_runtime(s1);
9590
#else
9591
    tcc_add_runtime(s1);
9592
#endif
9593
 
9594
    relocate_common_syms();
9595
 
9596
    tcc_add_linker_symbols(s1);
9597
 
9598
    build_got_entries(s1);
9599
 
9600
    /* compute relocation address : section are relocated in place. We
9601
       also alloc the bss space */
9602
    for(i = 1; i < s1->nb_sections; i++) {
9603
        s = s1->sections[i];
9604
        if (s->sh_flags & SHF_ALLOC) {
9605
            if (s->sh_type == SHT_NOBITS)
9606
                s->data = tcc_mallocz(s->data_offset);
9607
            s->sh_addr = (unsigned long)s->data;
9608
        }
9609
    }
9610
 
9611
    relocate_syms(s1, 1);
9612
 
9613
    if (s1->nb_errors != 0)
9614
        return -1;
9615
 
9616
    /* relocate each section */
9617
    for(i = 1; i < s1->nb_sections; i++) {
9618
        s = s1->sections[i];
9619
        if (s->reloc)
9620
            relocate_section(s1, s);
9621
    }
9622
    return 0;
9623
}
9624
 
9625
/* launch the compiled program with the given arguments */
9626
int tcc_run(TCCState *s1, int argc, char **argv)
9627
{
9628
    int (*prog_main)(int, char **);
9629
 
9630
    if (tcc_relocate(s1) < 0)
9631
        return -1;
9632
 
9633
    prog_main = tcc_get_symbol_err(s1, "main");
9634
 
9635
    if (do_debug) {
9636
#if defined(WIN32) || defined(CONFIG_TCCBOOT)
9637
        error("debug mode currently not available for Windows");
9638
#else
9639
        struct sigaction sigact;
9640
        /* install TCC signal handlers to print debug info on fatal
9641
           runtime errors */
9642
        sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
9643
        sigact.sa_sigaction = sig_error;
9644
        sigemptyset(&sigact.sa_mask);
9645
        sigaction(SIGFPE, &sigact, NULL);
9646
        sigaction(SIGILL, &sigact, NULL);
9647
        sigaction(SIGSEGV, &sigact, NULL);
9648
        sigaction(SIGBUS, &sigact, NULL);
9649
        sigaction(SIGABRT, &sigact, NULL);
9650
#endif
9651
    }
9652
 
9653
#ifdef CONFIG_TCC_BCHECK
9654
    if (do_bounds_check) {
9655
        void (*bound_init)(void);
9656
 
9657
        /* set error function */
9658
        rt_bound_error_msg = (void *)tcc_get_symbol_err(s1,
9659
                                                        "__bound_error_msg");
9660
 
9661
        /* XXX: use .init section so that it also work in binary ? */
9662
        bound_init = (void *)tcc_get_symbol_err(s1, "__bound_init");
9663
        bound_init();
9664
    }
9665
#endif
9666
    return (*prog_main)(argc, argv);
9667
}
9668
 
9669
TCCState *tcc_new(void)
9670
{
9671
    const char *p, *r;
9672
    TCCState *s;
9673
    TokenSym *ts;
9674
    int i, c;
9675
 
9676
    s = tcc_mallocz(sizeof(TCCState));
9677
    if (!s)
9678
        return NULL;
9679
    tcc_state = s;
9680
    s->output_type = TCC_OUTPUT_MEMORY;
9681
 
9682
    /* init isid table */
9683
    for(i=0;i<256;i++)
9684
        isidnum_table[i] = isid(i) || isnum(i);
9685
 
9686
    /* add all tokens */
9687
    table_ident = NULL;
9688
    memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
9689
 
9690
    tok_ident = TOK_IDENT;
9691
    p = tcc_keywords;
9692
    while (*p) {
9693
        r = p;
9694
        for(;;) {
9695
            c = *r++;
9696
            if (c == '\0')
9697
                break;
9698
        }
9699
        ts = tok_alloc(p, r - p - 1);
9700
        p = r;
9701
    }
9702
 
9703
    /* we add dummy defines for some special macros to speed up tests
9704
       and to have working defined() */
9705
    define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
9706
    define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
9707
    define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
9708
    define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
9709
 
9710
    /* standard defines */
9711
    tcc_define_symbol(s, "__STDC__", NULL);
9712
#if defined(TCC_TARGET_I386)
9713
    tcc_define_symbol(s, "__i386__", NULL);
9714
#endif
9715
#if defined(TCC_TARGET_ARM)
9716
    tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
9717
    tcc_define_symbol(s, "__arm_elf__", NULL);
9718
    tcc_define_symbol(s, "__arm_elf", NULL);
9719
    tcc_define_symbol(s, "arm_elf", NULL);
9720
    tcc_define_symbol(s, "__arm__", NULL);
9721
    tcc_define_symbol(s, "__arm", NULL);
9722
    tcc_define_symbol(s, "arm", NULL);
9723
    tcc_define_symbol(s, "__APCS_32__", NULL);
9724
#endif
9725
#if defined(linux)
9726
    tcc_define_symbol(s, "__linux__", NULL);
9727
    tcc_define_symbol(s, "linux", NULL);
9728
#endif
9729
    /* tiny C specific defines */
9730
    tcc_define_symbol(s, "__TINYC__", NULL);
9731
 
9732
    /* tiny C & gcc defines */
9733
    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
9734
    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
9735
    tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
9736
 
9737
    /* default library paths */
9738
#ifdef TCC_TARGET_PE
9739
    {
9740
        char buf[1024];
9741
        snprintf(buf, sizeof(buf), "%s/lib", tcc_lib_path);
9742
        tcc_add_library_path(s, buf);
9743
    }
9744
#else
9745
#ifdef TCC_TARGET_MEOS
9746
#else
9747
    tcc_add_library_path(s, "/usr/local/lib");
9748
    tcc_add_library_path(s, "/usr/lib");
9749
    tcc_add_library_path(s, "/lib");
9750
#endif
9751
#endif
9752
 
9753
    /* no section zero */
9754
    dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
9755
 
9756
    /* create standard sections */
9757
    text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
9758
    data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
9759
    bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
9760
 
9761
    /* symbols are always generated for linking stage */
9762
    symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
9763
                                ".strtab",
9764
                                ".hashtab", SHF_PRIVATE);
9765
    strtab_section = symtab_section->link;
9766
 
9767
    /* private symbol table for dynamic symbols */
9768
    s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
9769
                                      ".dynstrtab",
9770
                                      ".dynhashtab", SHF_PRIVATE);
9771
    s->alacarte_link = 1;
9772
 
9773
#ifdef CHAR_IS_UNSIGNED
9774
    s->char_is_unsigned = 1;
9775
#endif
9776
#if defined(TCC_TARGET_PE) && 0
9777
    /* XXX: currently the PE linker is not ready to support that */
9778
    s->leading_underscore = 1;
9779
#endif
9780
    return s;
9781
}
9782
 
9783
void tcc_delete(TCCState *s1)
9784
{
9785
    int i, n;
9786
 
9787
    /* free -D defines */
9788
    free_defines(NULL);
9789
 
9790
    /* free tokens */
9791
    n = tok_ident - TOK_IDENT;
9792
    for(i = 0; i < n; i++)
9793
        tcc_free(table_ident[i]);
9794
    tcc_free(table_ident);
9795
 
9796
    /* free all sections */
9797
 
9798
    free_section(symtab_section->hash);
9799
 
9800
    free_section(s1->dynsymtab_section->hash);
9801
    free_section(s1->dynsymtab_section->link);
9802
    free_section(s1->dynsymtab_section);
9803
 
9804
    for(i = 1; i < s1->nb_sections; i++)
9805
        free_section(s1->sections[i]);
9806
    tcc_free(s1->sections);
9807
 
9808
    /* free loaded dlls array */
9809
    for(i = 0; i < s1->nb_loaded_dlls; i++)
9810
        tcc_free(s1->loaded_dlls[i]);
9811
    tcc_free(s1->loaded_dlls);
9812
 
9813
    /* library paths */
9814
    for(i = 0; i < s1->nb_library_paths; i++)
9815
        tcc_free(s1->library_paths[i]);
9816
    tcc_free(s1->library_paths);
9817
 
9818
    /* cached includes */
9819
    for(i = 0; i < s1->nb_cached_includes; i++)
9820
        tcc_free(s1->cached_includes[i]);
9821
    tcc_free(s1->cached_includes);
9822
 
9823
    for(i = 0; i < s1->nb_include_paths; i++)
9824
        tcc_free(s1->include_paths[i]);
9825
    tcc_free(s1->include_paths);
9826
 
9827
    for(i = 0; i < s1->nb_sysinclude_paths; i++)
9828
        tcc_free(s1->sysinclude_paths[i]);
9829
    tcc_free(s1->sysinclude_paths);
9830
 
9831
    tcc_free(s1);
9832
}
9833
 
9834
int tcc_add_include_path(TCCState *s1, const char *pathname)
9835
{
9836
    char *pathname1;
9837
 
9838
    pathname1 = tcc_strdup(pathname);
9839
    dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
9840
    return 0;
9841
}
9842
 
9843
int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
9844
{
9845
    char *pathname1;
9846
 
9847
    pathname1 = tcc_strdup(pathname);
9848
    dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
9849
    return 0;
9850
}
9851
 
9852
static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
9853
{
9854
    const char *ext, *filename1;
9855
    Elf32_Ehdr ehdr;
9856
    int fd, ret;
9857
    BufferedFile *saved_file;
9858
 
9859
    /* find source file type with extension */
9860
    filename1 = strrchr(filename, '/');
9861
    if (filename1)
9862
        filename1++;
9863
    else
9864
        filename1 = filename;
9865
    ext = strrchr(filename1, '.');
9866
    if (ext)
9867
        ext++;
9868
 
9869
    /* open the file */
9870
    saved_file = file;
9871
    file = tcc_open(s1, filename);
9872
    if (!file) {
9873
        if (flags & AFF_PRINT_ERROR) {
9874
            error_noabort("file '%s' not found", filename);
9875
        }
9876
        ret = -1;
9877
        goto fail1;
9878
    }
9879
 
9880
    if (!ext || !strcmp(ext, "c")) {
9881
        /* C file assumed */
9882
        ret = tcc_compile(s1);
9883
    } else
9884
#ifdef CONFIG_TCC_ASM
9885
    if (!strcmp(ext, "S")) {
9886
        /* preprocessed assembler */
9887
        ret = tcc_assemble(s1, 1);
9888
    } else if (!strcmp(ext, "s")) {
9889
        /* non preprocessed assembler */
9890
        ret = tcc_assemble(s1, 0);
9891
    } else
9892
#endif
9893
#ifdef TCC_TARGET_PE
9894
    if (!strcmp(ext, "def")) {
9895
        ret = pe_load_def_file(s1, fdopen(file->fd, "rb"));
9896
    } else
9897
#endif
9898
    {
9899
        fd = file->fd;
9900
        /* assume executable format: auto guess file type */
9901
        ret = read(fd, &ehdr, sizeof(ehdr));
9902
        lseek(fd, 0, SEEK_SET);
9903
        if (ret <= 0) {
9904
            error_noabort("could not read header");
9905
            goto fail;
9906
        } else if (ret != sizeof(ehdr)) {
9907
            goto try_load_script;
9908
        }
9909
 
9910
        if (ehdr.e_ident[0] == ELFMAG0 &&
9911
            ehdr.e_ident[1] == ELFMAG1 &&
9912
            ehdr.e_ident[2] == ELFMAG2 &&
9913
            ehdr.e_ident[3] == ELFMAG3) {
9914
            file->line_num = 0; /* do not display line number if error */
9915
            if (ehdr.e_type == ET_REL) {
9916
                ret = tcc_load_object_file(s1, fd, 0);
9917
            } else if (ehdr.e_type == ET_DYN) {
9918
                if (s1->output_type == TCC_OUTPUT_MEMORY) {
9919
#if defined(TCC_TARGET_PE) || defined(TCC_TARGET_MEOS)
9920
                    ret = -1;
9921
#else
9922
                    void *h;
9923
                    h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
9924
                    if (h)
9925
                        ret = 0;
9926
                    else
9927
                        ret = -1;
9928
#endif
9929
                } else {
9930
                    ret = tcc_load_dll(s1, fd, filename,
9931
                                       (flags & AFF_REFERENCED_DLL) != 0);
9932
                }
9933
            } else {
9934
                error_noabort("unrecognized ELF file");
9935
                goto fail;
9936
            }
9937
        } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
9938
            file->line_num = 0; /* do not display line number if error */
9939
            ret = tcc_load_archive(s1, fd);
9940
        } else
9941
#ifdef TCC_TARGET_COFF
9942
        if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
9943
            ret = tcc_load_coff(s1, fd);
9944
        } else
9945
#endif
9946
        {
9947
            /* as GNU ld, consider it is an ld script if not recognized */
9948
        try_load_script:
9949
            ret = tcc_load_ldscript(s1);
9950
            if (ret < 0) {
9951
                error_noabort("unrecognized file type");
9952
                goto fail;
9953
            }
9954
        }
9955
    }
9956
 the_end:
9957
    tcc_close(file);
9958
 fail1:
9959
    file = saved_file;
9960
    return ret;
9961
 fail:
9962
    ret = -1;
9963
    goto the_end;
9964
}
9965
 
9966
int tcc_add_file(TCCState *s, const char *filename)
9967
{
9968
    return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
9969
}
9970
 
9971
int tcc_add_library_path(TCCState *s, const char *pathname)
9972
{
9973
    char *pathname1;
9974
 
9975
    pathname1 = tcc_strdup(pathname);
9976
    dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
9977
    return 0;
9978
}
9979
 
9980
/* find and load a dll. Return non zero if not found */
9981
/* XXX: add '-rpath' option support ? */
9982
static int tcc_add_dll(TCCState *s, const char *filename, int flags)
9983
{
9984
    char buf[1024];
9985
    int i;
9986
 
9987
    for(i = 0; i < s->nb_library_paths; i++) {
9988
        snprintf(buf, sizeof(buf), "%s/%s",
9989
                 s->library_paths[i], filename);
9990
        if (tcc_add_file_internal(s, buf, flags) == 0)
9991
            return 0;
9992
    }
9993
    return -1;
9994
}
9995
 
9996
/* the library name is the same as the argument of the '-l' option */
9997
int tcc_add_library(TCCState *s, const char *libraryname)
9998
{
9999
    char buf[1024];
10000
    int i;
10001
 
10002
    /* first we look for the dynamic library if not static linking */
10003
    if (!s->static_link) {
10004
#ifdef TCC_TARGET_PE
10005
        snprintf(buf, sizeof(buf), "%s.def", libraryname);
10006
#else
10007
        snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
10008
#endif
10009
        if (tcc_add_dll(s, buf, 0) == 0)
10010
            return 0;
10011
    }
10012
 
10013
    /* then we look for the static library */
10014
    for(i = 0; i < s->nb_library_paths; i++) {
10015
        snprintf(buf, sizeof(buf), "%s/lib%s.a",
10016
                 s->library_paths[i], libraryname);
10017
        if (tcc_add_file_internal(s, buf, 0) == 0)
10018
            return 0;
10019
    }
10020
    return -1;
10021
}
10022
 
10023
int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
10024
{
10025
    add_elf_sym(symtab_section, val, 0,
10026
                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
10027
                SHN_ABS, name);
10028
    return 0;
10029
}
10030
 
10031
int tcc_set_output_type(TCCState *s, int output_type)
10032
{
10033
    s->output_type = output_type;
10034
 
10035
    if (!s->nostdinc) {
10036
        char buf[1024];
10037
 
10038
        /* default include paths */
10039
        /* XXX: reverse order needed if -isystem support */
10040
#if !defined(TCC_TARGET_PE) && !defined(TCC_TARGET_MEOS)
10041
        tcc_add_sysinclude_path(s, "/usr/local/include");
10042
        tcc_add_sysinclude_path(s, "/usr/include");
10043
#endif
10044
        snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path);
10045
        tcc_add_sysinclude_path(s, buf);
10046
#ifdef TCC_TARGET_PE
10047
        snprintf(buf, sizeof(buf), "%s/include/winapi", tcc_lib_path);
10048
        tcc_add_sysinclude_path(s, buf);
10049
#endif
10050
    }
10051
 
10052
    /* if bound checking, then add corresponding sections */
10053
#ifdef CONFIG_TCC_BCHECK
10054
    if (do_bounds_check) {
10055
        /* define symbol */
10056
        tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
10057
        /* create bounds sections */
10058
        bounds_section = new_section(s, ".bounds",
10059
                                     SHT_PROGBITS, SHF_ALLOC);
10060
        lbounds_section = new_section(s, ".lbounds",
10061
                                      SHT_PROGBITS, SHF_ALLOC);
10062
    }
10063
#endif
10064
 
10065
    if (s->char_is_unsigned) {
10066
        tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
10067
    }
10068
 
10069
    /* add debug sections */
10070
    if (do_debug) {
10071
        /* stab symbols */
10072
        stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
10073
        stab_section->sh_entsize = sizeof(Stab_Sym);
10074
        stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
10075
        put_elf_str(stabstr_section, "");
10076
        stab_section->link = stabstr_section;
10077
        /* put first entry */
10078
        put_stabs("", 0, 0, 0, 0);
10079
    }
10080
 
10081
    /* add libc crt1/crti objects */
10082
#if !defined(TCC_TARGET_PE) && !defined(TCC_TARGET_MEOS)
10083
    if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
10084
        !s->nostdlib) {
10085
        if (output_type != TCC_OUTPUT_DLL)
10086
            tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
10087
        tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
10088
    }
10089
#endif
10090
#if defined(TCC_TARGET_MEOS)
10091
    if (s->output_type != TCC_OUTPUT_OBJ)
10092
        tcc_add_file(s,".\\start.o");
10093
#endif
10094
    return 0;
10095
}
10096
 
10097
#define WD_ALL    0x0001 /* warning is activated when using -Wall */
10098
#define FD_INVERT 0x0002 /* invert value before storing */
10099
 
10100
typedef struct FlagDef {
10101
    uint16_t offset;
10102
    uint16_t flags;
10103
    const char *name;
10104
} FlagDef;
10105
 
10106
static const FlagDef warning_defs[] = {
10107
    { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
10108
    { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
10109
    { offsetof(TCCState, warn_error), 0, "error" },
10110
    { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
10111
      "implicit-function-declaration" },
10112
};
10113
 
10114
static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
10115
                    const char *name, int value)
10116
{
10117
    int i;
10118
    const FlagDef *p;
10119
    const char *r;
10120
 
10121
    r = name;
10122
    if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {
10123
        r += 3;
10124
        value = !value;
10125
    }
10126
    for(i = 0, p = flags; i < nb_flags; i++, p++) {
10127
        if (!strcmp(r, p->name))
10128
            goto found;
10129
    }
10130
    return -1;
10131
 found:
10132
    if (p->flags & FD_INVERT)
10133
        value = !value;
10134
    *(int *)((uint8_t *)s + p->offset) = value;
10135
    return 0;
10136
}
10137
 
10138
 
10139
/* set/reset a warning */
10140
int tcc_set_warning(TCCState *s, const char *warning_name, int value)
10141
{
10142
    int i;
10143
    const FlagDef *p;
10144
 
10145
    if (!strcmp(warning_name, "all")) {
10146
        for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
10147
            if (p->flags & WD_ALL)
10148
                *(int *)((uint8_t *)s + p->offset) = 1;
10149
        }
10150
        return 0;
10151
    } else {
10152
        return set_flag(s, warning_defs, countof(warning_defs),
10153
                        warning_name, value);
10154
    }
10155
}
10156
 
10157
static const FlagDef flag_defs[] = {
10158
    { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
10159
    { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
10160
    { offsetof(TCCState, nocommon), FD_INVERT, "common" },
10161
    { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
10162
};
10163
 
10164
/* set/reset a flag */
10165
int tcc_set_flag(TCCState *s, const char *flag_name, int value)
10166
{
10167
    return set_flag(s, flag_defs, countof(flag_defs),
10168
                    flag_name, value);
10169
}
10170
 
10171
#if !defined(LIBTCC)
10172
 
10173
/* extract the basename of a file */
10174
static const char *tcc_basename(const char *name)
10175
{
10176
    const char *p;
10177
    p = strrchr(name, '/');
10178
#ifdef WIN32
10179
    if (!p)
10180
        p = strrchr(name, '\\');
10181
#endif
10182
    if (!p)
10183
        p = name;
10184
    else
10185
        p++;
10186
    return p;
10187
}
10188
 
10189
static int64_t getclock_us(void)
10190
{
10191
#ifdef WIN32
10192
    struct _timeb tb;
10193
    _ftime(&tb);
10194
    return (tb.time * 1000LL + tb.millitm) * 1000LL;
10195
#else
10196
    struct timeval tv;
10197
    gettimeofday(&tv, NULL);
10198
    return tv.tv_sec * 1000000LL + tv.tv_usec;
10199
#endif
10200
}
10201
 
10202
void help(void)
10203
{
10204
    printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2005 Fabrice Bellard\n"
10205
           "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
10206
           "           [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
10207
           "           [infile1 infile2...] [-run infile args...]\n"
10208
           "\n"
10209
           "General options:\n"
10210
           "  -v          display current version\n"
10211
           "  -c          compile only - generate an object file\n"
10212
           "  -o outfile  set output filename\n"
10213
           "  -Bdir       set tcc internal library path\n"
10214
           "  -bench      output compilation statistics\n"
10215
 	   "  -run        run compiled source\n"
10216
           "  -fflag      set or reset (with 'no-' prefix) 'flag' (see man page)\n"
10217
           "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see man page)\n"
10218
           "  -w          disable all warnings\n"
10219
           "Preprocessor options:\n"
10220
           "  -Idir       add include path 'dir'\n"
10221
           "  -Dsym[=val] define 'sym' with value 'val'\n"
10222
           "  -Usym       undefine 'sym'\n"
10223
           "Linker options:\n"
10224
           "  -Ldir       add library path 'dir'\n"
10225
           "  -llib       link with dynamic or static library 'lib'\n"
10226
           "  -shared     generate a shared library\n"
10227
           "  -static     static linking\n"
10228
           "  -rdynamic   export all global symbols to dynamic linker\n"
10229
           "  -r          relocatable output\n"
10230
           "Debugger options:\n"
10231
           "  -g          generate runtime debug info\n"
10232
#ifdef CONFIG_TCC_BCHECK
10233
           "  -b          compile with built-in memory and bounds checker (implies -g)\n"
10234
#endif
10235
           "  -bt N       show N callers in stack traces\n"
10236
           );
10237
}
10238
 
10239
#define TCC_OPTION_HAS_ARG 0x0001
10240
#define TCC_OPTION_NOSEP   0x0002 /* cannot have space before option and arg */
10241
 
10242
typedef struct TCCOption {
10243
    const char *name;
10244
    uint16_t index;
10245
    uint16_t flags;
10246
} TCCOption;
10247
 
10248
enum {
10249
    TCC_OPTION_HELP,
10250
    TCC_OPTION_I,
10251
    TCC_OPTION_D,
10252
    TCC_OPTION_U,
10253
    TCC_OPTION_L,
10254
    TCC_OPTION_B,
10255
    TCC_OPTION_l,
10256
    TCC_OPTION_bench,
10257
    TCC_OPTION_bt,
10258
    TCC_OPTION_b,
10259
    TCC_OPTION_g,
10260
    TCC_OPTION_c,
10261
    TCC_OPTION_static,
10262
    TCC_OPTION_shared,
10263
    TCC_OPTION_o,
10264
    TCC_OPTION_r,
10265
    TCC_OPTION_Wl,
10266
    TCC_OPTION_W,
10267
    TCC_OPTION_O,
10268
    TCC_OPTION_m,
10269
    TCC_OPTION_f,
10270
    TCC_OPTION_nostdinc,
10271
    TCC_OPTION_nostdlib,
10272
    TCC_OPTION_print_search_dirs,
10273
    TCC_OPTION_rdynamic,
10274
    TCC_OPTION_run,
10275
    TCC_OPTION_v,
10276
    TCC_OPTION_w,
10277
    TCC_OPTION_pipe,
10278
};
10279
 
10280
static const TCCOption tcc_options[] = {
10281
    { "h", TCC_OPTION_HELP, 0 },
10282
    { "?", TCC_OPTION_HELP, 0 },
10283
    { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
10284
    { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
10285
    { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
10286
    { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
10287
    { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
10288
    { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
10289
    { "bench", TCC_OPTION_bench, 0 },
10290
    { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
10291
#ifdef CONFIG_TCC_BCHECK
10292
    { "b", TCC_OPTION_b, 0 },
10293
#endif
10294
    { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
10295
    { "c", TCC_OPTION_c, 0 },
10296
    { "static", TCC_OPTION_static, 0 },
10297
    { "shared", TCC_OPTION_shared, 0 },
10298
    { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
10299
    { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
10300
    { "rdynamic", TCC_OPTION_rdynamic, 0 },
10301
    { "r", TCC_OPTION_r, 0 },
10302
    { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
10303
    { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
10304
    { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
10305
    { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
10306
    { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
10307
    { "nostdinc", TCC_OPTION_nostdinc, 0 },
10308
    { "nostdlib", TCC_OPTION_nostdlib, 0 },
10309
    { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
10310
    { "v", TCC_OPTION_v, 0 },
10311
    { "w", TCC_OPTION_w, 0 },
10312
    { "pipe", TCC_OPTION_pipe, 0},
10313
    { NULL },
10314
};
10315
 
10316
/* convert 'str' into an array of space separated strings */
10317
static int expand_args(char ***pargv, const char *str)
10318
{
10319
    const char *s1;
10320
    char **argv, *arg;
10321
    int argc, len;
10322
 
10323
    argc = 0;
10324
    argv = NULL;
10325
    for(;;) {
10326
        while (is_space(*str))
10327
            str++;
10328
        if (*str == '\0')
10329
            break;
10330
        s1 = str;
10331
        while (*str != '\0' && !is_space(*str))
10332
            str++;
10333
        len = str - s1;
10334
        arg = tcc_malloc(len + 1);
10335
        memcpy(arg, s1, len);
10336
        arg[len] = '\0';
10337
        dynarray_add((void ***)&argv, &argc, arg);
10338
    }
10339
    *pargv = argv;
10340
    return argc;
10341
}
10342
 
10343
static char **files;
10344
static int nb_files, nb_libraries;
10345
static int multiple_files;
10346
static int print_search_dirs;
10347
static int output_type;
10348
static int reloc_output;
10349
static const char *outfile;
10350
 
10351
int parse_args(TCCState *s, int argc, char **argv)
10352
{
10353
    int optind;
10354
    const TCCOption *popt;
10355
    const char *optarg, *p1, *r1;
10356
    char *r;
10357
 
10358
    optind = 0;
10359
    while (1) {
10360
        if (optind >= argc) {
10361
            if (nb_files == 0 && !print_search_dirs)
10362
                goto show_help;
10363
            else
10364
                break;
10365
        }
10366
        r = argv[optind++];
10367
        if (r[0] != '-') {
10368
            /* add a new file */
10369
            dynarray_add((void ***)&files, &nb_files, r);
10370
            if (!multiple_files) {
10371
                optind--;
10372
                /* argv[0] will be this file */
10373
                break;
10374
            }
10375
        } else {
10376
            /* find option in table (match only the first chars */
10377
            popt = tcc_options;
10378
            for(;;) {
10379
                p1 = popt->name;
10380
                if (p1 == NULL)
10381
                    error("invalid option -- '%s'", r);
10382
                r1 = r + 1;
10383
                for(;;) {
10384
                    if (*p1 == '\0')
10385
                        goto option_found;
10386
                    if (*r1 != *p1)
10387
                        break;
10388
                    p1++;
10389
                    r1++;
10390
                }
10391
                popt++;
10392
            }
10393
        option_found:
10394
            if (popt->flags & TCC_OPTION_HAS_ARG) {
10395
                if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) {
10396
                    optarg = r1;
10397
                } else {
10398
                    if (optind >= argc)
10399
                        error("argument to '%s' is missing", r);
10400
                    optarg = argv[optind++];
10401
                }
10402
            } else {
10403
                if (*r1 != '\0')
10404
                    goto show_help;
10405
                optarg = NULL;
10406
            }
10407
 
10408
            switch(popt->index) {
10409
            case TCC_OPTION_HELP:
10410
            show_help:
10411
                help();
10412
                exit(1);
10413
            case TCC_OPTION_I:
10414
                if (tcc_add_include_path(s, optarg) < 0)
10415
                    error("too many include paths");
10416
                break;
10417
            case TCC_OPTION_D:
10418
                {
10419
                    char *sym, *value;
10420
                    sym = (char *)optarg;
10421
                    value = strchr(sym, '=');
10422
                    if (value) {
10423
                        *value = '\0';
10424
                        value++;
10425
                    }
10426
                    tcc_define_symbol(s, sym, value);
10427
                }
10428
                break;
10429
            case TCC_OPTION_U:
10430
                tcc_undefine_symbol(s, optarg);
10431
                break;
10432
            case TCC_OPTION_L:
10433
                tcc_add_library_path(s, optarg);
10434
                break;
10435
            case TCC_OPTION_B:
10436
                /* set tcc utilities path (mainly for tcc development) */
10437
                tcc_lib_path = optarg;
10438
                break;
10439
            case TCC_OPTION_l:
10440
                dynarray_add((void ***)&files, &nb_files, r);
10441
                nb_libraries++;
10442
                break;
10443
            case TCC_OPTION_bench:
10444
                do_bench = 1;
10445
                break;
10446
            case TCC_OPTION_bt:
10447
                num_callers = atoi(optarg);
10448
                break;
10449
#ifdef CONFIG_TCC_BCHECK
10450
            case TCC_OPTION_b:
10451
                do_bounds_check = 1;
10452
                do_debug = 1;
10453
                break;
10454
#endif
10455
            case TCC_OPTION_g:
10456
                do_debug = 1;
10457
                break;
10458
            case TCC_OPTION_c:
10459
                multiple_files = 1;
10460
                output_type = TCC_OUTPUT_OBJ;
10461
                break;
10462
            case TCC_OPTION_static:
10463
                s->static_link = 1;
10464
                break;
10465
            case TCC_OPTION_shared:
10466
                output_type = TCC_OUTPUT_DLL;
10467
                break;
10468
            case TCC_OPTION_o:
10469
                multiple_files = 1;
10470
                outfile = optarg;
10471
                break;
10472
            case TCC_OPTION_r:
10473
                /* generate a .o merging several output files */
10474
                reloc_output = 1;
10475
                output_type = TCC_OUTPUT_OBJ;
10476
                break;
10477
            case TCC_OPTION_nostdinc:
10478
                s->nostdinc = 1;
10479
                break;
10480
            case TCC_OPTION_nostdlib:
10481
                s->nostdlib = 1;
10482
                break;
10483
            case TCC_OPTION_print_search_dirs:
10484
                print_search_dirs = 1;
10485
                break;
10486
            case TCC_OPTION_run:
10487
                {
10488
                    int argc1;
10489
                    char **argv1;
10490
                    argc1 = expand_args(&argv1, optarg);
10491
                    if (argc1 > 0) {
10492
                        parse_args(s, argc1, argv1);
10493
                    }
10494
                    multiple_files = 0;
10495
                    output_type = TCC_OUTPUT_MEMORY;
10496
                }
10497
                break;
10498
            case TCC_OPTION_v:
10499
                printf("tcc version %s\n", TCC_VERSION);
10500
                exit(0);
10501
            case TCC_OPTION_f:
10502
                if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported)
10503
                    goto unsupported_option;
10504
                break;
10505
            case TCC_OPTION_W:
10506
                if (tcc_set_warning(s, optarg, 1) < 0 &&
10507
                    s->warn_unsupported)
10508
                    goto unsupported_option;
10509
                break;
10510
            case TCC_OPTION_w:
10511
                s->warn_none = 1;
10512
                break;
10513
            case TCC_OPTION_rdynamic:
10514
                s->rdynamic = 1;
10515
                break;
10516
            case TCC_OPTION_Wl:
10517
                {
10518
                    const char *p;
10519
                    if (strstart(optarg, "-Ttext,", &p)) {
10520
                        s->text_addr = strtoul(p, NULL, 16);
10521
                        s->has_text_addr = 1;
10522
                    } else if (strstart(optarg, "--oformat,", &p)) {
10523
                        if (strstart(p, "elf32-", NULL)) {
10524
                            s->output_format = TCC_OUTPUT_FORMAT_ELF;
10525
                        } else if (!strcmp(p, "binary")) {
10526
                            s->output_format = TCC_OUTPUT_FORMAT_BINARY;
10527
                        } else
10528
#ifdef TCC_TARGET_COFF
10529
                        if (!strcmp(p, "coff")) {
10530
                            s->output_format = TCC_OUTPUT_FORMAT_COFF;
10531
                        } else
10532
#endif
10533
                        {
10534
                            error("target %s not found", p);
10535
                        }
10536
                    } else {
10537
                        error("unsupported linker option '%s'", optarg);
10538
                    }
10539
                }
10540
                break;
10541
            default:
10542
                if (s->warn_unsupported) {
10543
                unsupported_option:
10544
                    warning("unsupported option '%s'", r);
10545
                }
10546
                break;
10547
            }
10548
        }
10549
    }
10550
    return optind;
10551
}
10552
 
10553
int main(int argc, char **argv)
10554
{
10555
    int i;
10556
    TCCState *s;
10557
    int nb_objfiles, ret, optind;
10558
    char objfilename[1024];
10559
    int64_t start_time = 0;
10560
 
10561
#ifdef WIN32
10562
    /* on win32, we suppose the lib and includes are at the location
10563
       of 'tcc.exe' */
10564
    {
10565
        static char path[1024];
10566
        char *p, *d;
10567
 
10568
        GetModuleFileNameA(NULL, path, sizeof path);
10569
        p = d = strlwr(path);
10570
        while (*d)
10571
        {
10572
            if (*d == '\\') *d = '/', p = d;
10573
            ++d;
10574
        }
10575
        *p = '\0';
10576
        tcc_lib_path = path;
10577
    }
10578
#endif
10579
 
10580
    s = tcc_new();
10581
    output_type = TCC_OUTPUT_EXE;
10582
    outfile = NULL;
10583
    multiple_files = 1;
10584
    files = NULL;
10585
    nb_files = 0;
10586
    nb_libraries = 0;
10587
    reloc_output = 0;
10588
    print_search_dirs = 0;
10589
 
10590
    optind = parse_args(s, argc - 1, argv + 1) + 1;
10591
 
10592
    if (print_search_dirs) {
10593
        /* enough for Linux kernel */
10594
        printf("install: %s/\n", tcc_lib_path);
10595
        return 0;
10596
    }
10597
 
10598
    nb_objfiles = nb_files - nb_libraries;
10599
 
10600
    /* if outfile provided without other options, we output an
10601
       executable */
10602
    if (outfile && output_type == TCC_OUTPUT_MEMORY)
10603
        output_type = TCC_OUTPUT_EXE;
10604
 
10605
    /* check -c consistency : only single file handled. XXX: checks file type */
10606
    if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
10607
        /* accepts only a single input file */
10608
        if (nb_objfiles != 1)
10609
            error("cannot specify multiple files with -c");
10610
        if (nb_libraries != 0)
10611
            error("cannot specify libraries with -c");
10612
    }
10613
 
10614
    if (output_type != TCC_OUTPUT_MEMORY) {
10615
        if (!outfile) {
10616
    /* compute default outfile name */
10617
            pstrcpy(objfilename, sizeof(objfilename) - 1,
10618
                    /* strip path */
10619
                    tcc_basename(files[0]));
10620
#ifdef TCC_TARGET_PE
10621
            pe_guess_outfile(objfilename, output_type);
10622
#else
10623
            if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
10624
                char *ext = strrchr(objfilename, '.');
10625
            if (!ext)
10626
                goto default_outfile;
10627
                /* add .o extension */
10628
            strcpy(ext + 1, "o");
10629
        } else {
10630
        default_outfile:
10631
            pstrcpy(objfilename, sizeof(objfilename), "a.out");
10632
        }
10633
#endif
10634
        outfile = objfilename;
10635
        }
10636
    }
10637
 
10638
    if (do_bench) {
10639
        start_time = getclock_us();
10640
    }
10641
 
10642
    tcc_set_output_type(s, output_type);
10643
 
10644
    /* compile or add each files or library */
10645
    for(i = 0;i < nb_files; i++) {
10646
        const char *filename;
10647
 
10648
        filename = files[i];
10649
        if (filename[0] == '-') {
10650
            if (tcc_add_library(s, filename + 2) < 0)
10651
                error("cannot find %s", filename);
10652
        } else {
10653
            if (tcc_add_file(s, filename) < 0) {
10654
                ret = 1;
10655
                goto the_end;
10656
            }
10657
        }
10658
    }
10659
 
10660
    /* free all files */
10661
    tcc_free(files);
10662
 
10663
    if (do_bench) {
10664
        double total_time;
10665
        total_time = (double)(getclock_us() - start_time) / 1000000.0;
10666
        if (total_time < 0.001)
10667
            total_time = 0.001;
10668
        if (total_bytes < 1)
10669
            total_bytes = 1;
10670
        printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
10671
               tok_ident - TOK_IDENT, total_lines, total_bytes,
10672
               total_time, (int)(total_lines / total_time),
10673
               total_bytes / total_time / 1000000.0);
10674
    }
10675
 
10676
    if (s->output_type == TCC_OUTPUT_MEMORY) {
10677
        ret = tcc_run(s, argc - optind, argv + optind);
10678
    } else
10679
#ifdef TCC_TARGET_PE
10680
    if (s->output_type != TCC_OUTPUT_OBJ) {
10681
        ret = tcc_output_pe(s, outfile);
10682
    } else
10683
#else
10684
#ifdef TCC_TARGET_MEOS
10685
    if (s->output_type != TCC_OUTPUT_OBJ) {
10686
        ret = tcc_output_me(s, outfile);
10687
    } else
10688
#endif
10689
#endif
10690
 
10691
    {
10692
        tcc_output_file(s, outfile);
10693
        ret = 0;
10694
    }
10695
 the_end:
10696
    /* XXX: cannot do it with bound checking because of the malloc hooks */
10697
    if (!do_bounds_check)
10698
        tcc_delete(s);
10699
 
10700
#ifdef MEM_DEBUG
10701
    if (do_bench) {
10702
        printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
10703
    }
10704
#endif
10705
    return ret;
10706
}
10707
 
10708
#endif