Subversion Repositories Kolibri OS

Rev

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