Subversion Repositories Kolibri OS

Rev

Rev 145 | Blame | Last modification | View Log | Download | RSS feed

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