diff options
Diffstat (limited to 'libtcc.c')
| -rw-r--r-- | libtcc.c | 732 |
1 files changed, 108 insertions, 624 deletions
@@ -23,344 +23,70 @@ /********************************************************/ /* global variables */ -/* display benchmark infos */ -int total_lines; -int total_bytes; - -/* parser */ -static struct BufferedFile *file; -static int ch, tok; -static CValue tokc; -static CString tokcstr; /* current parsed string, if any */ -/* additional informations about token */ -static int tok_flags; -#define TOK_FLAG_BOL 0x0001 /* beginning of line before */ -#define TOK_FLAG_BOF 0x0002 /* beginning of file before */ -#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */ -#define TOK_FLAG_EOF 0x0008 /* end of file */ - -static int *macro_ptr, *macro_ptr_allocated; -static int *unget_saved_macro_ptr; -static int unget_saved_buffer[TOK_MAX_SIZE + 1]; -static int unget_buffer_enabled; -static int parse_flags; -#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */ -#define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */ -#define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a - token. line feed is also - returned at eof */ -#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */ -#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */ - -static Section *text_section, *data_section, *bss_section; /* predefined sections */ -static Section *cur_text_section; /* current section where function code is - generated */ -#ifdef CONFIG_TCC_ASM -static Section *last_text_section; /* to handle .previous asm directive */ -#endif - -#ifdef CONFIG_TCC_BCHECK -/* bound check related sections */ -static Section *bounds_section; /* contains global data bound description */ -static Section *lbounds_section; /* contains local data bound description */ -#endif - -/* symbol sections */ -static Section *symtab_section, *strtab_section; - -/* debug sections */ -static Section *stab_section, *stabstr_section; - -/* loc : local variable index - ind : output code index - rsym: return symbol - anon_sym: anonymous symbol index -*/ -static int rsym, anon_sym, ind, loc; -/* expression generation modifiers */ -static int const_wanted; /* true if constant wanted */ -static int nocode_wanted; /* true if no code generation wanted for an expression */ -static int global_expr; /* true if compound literals must be allocated - globally (used during initializers parsing */ -static CType func_vt; /* current function return type (used by return - instruction) */ -static int func_vc; -static int last_line_num, last_ind, func_ind; /* debug last line number and pc */ -static int tok_ident; -static TokenSym **table_ident; -static TokenSym *hash_ident[TOK_HASH_SIZE]; -static char token_buf[STRING_MAX_SIZE + 1]; -static char *funcname; -static Sym *global_stack, *local_stack; -static Sym *define_stack; -static Sym *global_label_stack, *local_label_stack; -/* symbol allocator */ -#define SYM_POOL_NB (8192 / sizeof(Sym)) -static Sym *sym_free_first; -static void **sym_pools; -static int nb_sym_pools; - -static SValue vstack[VSTACK_SIZE], *vtop; -/* some predefined types */ -static CType char_pointer_type, func_old_type, int_type; - /* use GNU C extensions */ -static int gnu_ext = 1; - -/* use Tiny C extensions */ -static int tcc_ext = 1; +ST_DATA int gnu_ext = 1; -/* max number of callers shown if error */ -#ifdef CONFIG_TCC_BACKTRACE -int num_callers = 6; -void *rt_prog_main; -const char **rt_bound_error_msg; -#endif +/* use TinyCC extensions */ +ST_DATA int tcc_ext = 1; /* XXX: get rid of this ASAP */ -static struct TCCState *tcc_state; - -/********************************************************/ -/* function prototypes */ - -/* tccpp.c */ -static void next(void); -char *get_tok_str(int v, CValue *cv); - -/* tccgen.c */ -static void parse_expr_type(CType *type); -static void expr_type(CType *type); -static void unary_type(CType *type); -static void block(int *bsym, int *csym, int *case_sym, int *def_sym, - int case_reg, int is_expr); -static int expr_const(void); -static void expr_eq(void); -static void gexpr(void); -static void gen_inline_functions(void); -static void decl(int l); -static void decl_initializer(CType *type, Section *sec, unsigned long c, - int first, int size_only); -static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, - int has_init, int v, int scope); -int gv(int rc); -void gv2(int rc1, int rc2); -void move_reg(int r, int s); -void save_regs(int n); -void save_reg(int r); -void vpop(void); -void vswap(void); -void vdup(void); -int get_reg(int rc); -int get_reg_ex(int rc,int rc2); - -void gen_op(int op); -void force_charshort_cast(int t); -static void gen_cast(CType *type); -void vstore(void); -static Sym *sym_find(int v); -static Sym *sym_push(int v, CType *type, int r, int c); - -/* type handling */ -static int type_size(CType *type, int *a); -static inline CType *pointed_type(CType *type); -static int pointed_size(CType *type); -static int lvalue_type(int t); -static int parse_btype(CType *type, AttributeDef *ad); -static void type_decl(CType *type, AttributeDef *ad, int *v, int td); -static int compare_types(CType *type1, CType *type2, int unqualified); -static int is_compatible_types(CType *type1, CType *type2); -static int is_compatible_parameter_types(CType *type1, CType *type2); - -int ieee_finite(double d); -void vpushi(int v); -void vpushll(long long v); -void vrott(int n); -void vnrott(int n); -void lexpand_nr(void); -static void vpush_global_sym(CType *type, int v); -void vset(CType *type, int r, int v); -void type_to_str(char *buf, int buf_size, - CType *type, const char *varstr); -static Sym *get_sym_ref(CType *type, Section *sec, - unsigned long offset, unsigned long size); -static Sym *external_global_sym(int v, CType *type, int r); - -/* section generation */ -static void section_realloc(Section *sec, unsigned long new_size); -static void *section_ptr_add(Section *sec, unsigned long size); -static void put_extern_sym(Sym *sym, Section *section, - unsigned long value, unsigned long size); -static void greloc(Section *s, Sym *sym, unsigned long addr, int type); -static int put_elf_str(Section *s, const char *sym); -static int put_elf_sym(Section *s, - unsigned long value, unsigned long size, - int info, int other, int shndx, const char *name); -static int add_elf_sym(Section *s, uplong value, unsigned long size, - int info, int other, int sh_num, const char *name); -static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, - int type, int symbol); -static void put_stabs(const char *str, int type, int other, int desc, - unsigned long value); -static void put_stabs_r(const char *str, int type, int other, int desc, - unsigned long value, Section *sec, int sym_index); -static void put_stabn(int type, int other, int desc, int value); -static void put_stabd(int type, int other, int desc); -static int tcc_add_dll(TCCState *s, const char *filename, int flags); - -#define AFF_PRINT_ERROR 0x0001 /* print error if file not found */ -#define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */ -#define AFF_PREPROCESS 0x0004 /* preprocess file */ -static int tcc_add_file_internal(TCCState *s, const char *filename, int flags); - -/* tcccoff.c */ -int tcc_output_coff(TCCState *s1, FILE *f); - -/* tccpe.c */ -int pe_load_file(struct TCCState *s1, const char *filename, int fd); -int pe_output_file(struct TCCState *s1, const char *filename); -int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv)); - -/* tccasm.c */ -#ifdef CONFIG_TCC_ASM -static void asm_expr(TCCState *s1, ExprValue *pe); -static int asm_int_expr(TCCState *s1); -static int find_constraint(ASMOperand *operands, int nb_operands, - const char *name, const char **pp); +ST_DATA struct TCCState *tcc_state; -static int tcc_assemble(TCCState *s1, int do_preprocess); +#ifdef CONFIG_TCC_BACKTRACE +ST_DATA int num_callers = 6; +ST_DATA const char **rt_bound_error_msg; +ST_DATA void *rt_prog_main; #endif -static void asm_instr(void); -static void asm_global_instr(void); - -/********************************************************/ -/* libtcc.c */ - -static Sym *__sym_malloc(void); -static inline Sym *sym_malloc(void); -static inline void sym_free(Sym *sym); -Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags); -static void free_section(Section *s); -static void section_realloc(Section *sec, unsigned long new_size); -static void *section_ptr_add(Section *sec, unsigned long size); -Section *find_section(TCCState *s1, const char *name); -static void put_extern_sym2( - Sym *sym, Section *section, - unsigned long value, unsigned long size, int can_add_underscore); -static void put_extern_sym( - Sym *sym, Section *section, - unsigned long value, unsigned long size); -static void greloc(Section *s, Sym *sym, unsigned long offset, int type); - -static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap); -static void strcat_printf(char *buf, int buf_size, const char *fmt, ...); - -/* CString handling */ -static void cstr_realloc(CString *cstr, int new_size); -static inline void cstr_ccat(CString *cstr, int ch); -static void cstr_cat(CString *cstr, const char *str); -static void cstr_wccat(CString *cstr, int ch); -static void cstr_new(CString *cstr); -static void cstr_free(CString *cstr); -#define cstr_reset(cstr) cstr_free(cstr) -static void add_char(CString *cstr, int c); - -static Sym *sym_push2(Sym **ps, int v, int t, long c); -static Sym *sym_find2(Sym *s, int v); -static inline Sym *struct_find(int v); -static inline Sym *sym_find(int v); -static Sym *sym_push(int v, CType *type, int r, int c); -static Sym *global_identifier_push(int v, int t, int c); -static void sym_pop(Sym **ptop, Sym *b); - -BufferedFile *tcc_open(TCCState *s1, const char *filename); -void tcc_close(BufferedFile *bf); -static int tcc_compile(TCCState *s1); - -void expect(const char *msg); -void skip(int c); -static void test_lvalue(void); -void *resolve_sym(TCCState *s1, const char *sym); - -static inline int isid(int c) -{ - return (c >= 'a' && c <= 'z') - || (c >= 'A' && c <= 'Z') - || c == '_'; -} - -static inline int isnum(int c) -{ - return c >= '0' && c <= '9'; -} - -static inline int isoct(int c) -{ - return c >= '0' && c <= '7'; -} - -static inline int toup(int c) -{ - if (c >= 'a' && c <= 'z') - return c - 'a' + 'A'; - else - return c; -} - /********************************************************/ +#ifndef NOTALLINONE +#include "tccpp.c" +#include "tccgen.c" +#include "tccelf.c" +#include "tccrun.c" #ifdef TCC_TARGET_I386 #include "i386-gen.c" #endif - #ifdef TCC_TARGET_ARM #include "arm-gen.c" #endif - #ifdef TCC_TARGET_C67 #include "c67-gen.c" #endif - #ifdef TCC_TARGET_X86_64 #include "x86_64-gen.c" #endif - -#include "tccpp.c" -#include "tccgen.c" - #ifdef CONFIG_TCC_ASM - +#include "tccasm.c" #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 #include "i386-asm.c" #endif - -#include "tccasm.c" -#else -static void asm_instr(void) -{ - error("inline asm() not supported"); -} -static void asm_global_instr(void) -{ - error("inline asm() not supported"); -} #endif - -#include "tccelf.c" - #ifdef TCC_TARGET_COFF #include "tcccoff.c" #endif - #ifdef TCC_TARGET_PE #include "tccpe.c" #endif +#endif /* ALL_IN_ONE */ -#include "tccrun.c" +/********************************************************/ +#ifndef CONFIG_TCC_ASM +ST_FUNC void asm_instr(void) +{ + error("inline asm() not supported"); +} +ST_FUNC void asm_global_instr(void) +{ + error("inline asm() not supported"); +} +#endif /********************************************************/ + #ifdef _WIN32 -char *normalize_slashes(char *path) +static char *normalize_slashes(char *path) { char *p; for (p = path; *p; ++p) @@ -369,10 +95,10 @@ char *normalize_slashes(char *path) return path; } -HMODULE tcc_module; +static HMODULE tcc_module; /* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */ -void tcc_set_lib_path_w32(TCCState *s) +static void tcc_set_lib_path_w32(TCCState *s) { char path[1024], *p; GetModuleFileNameA(tcc_module, path, sizeof path); @@ -396,18 +122,8 @@ BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) #endif /********************************************************/ - -/* we use our own 'finite' function to avoid potential problems with - non standard math libs */ -/* XXX: endianness dependent */ -int ieee_finite(double d) -{ - int *p = (int *)&d; - return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; -} - /* copy a string and truncate it. */ -char *pstrcpy(char *buf, int buf_size, const char *s) +PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s) { char *q, *q_end; int c; @@ -427,7 +143,7 @@ char *pstrcpy(char *buf, int buf_size, const char *s) } /* strcat and truncate. */ -char *pstrcat(char *buf, int buf_size, const char *s) +PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s) { int len; len = strlen(buf); @@ -437,7 +153,7 @@ char *pstrcat(char *buf, int buf_size, const char *s) } /* extract the basename of a file */ -char *tcc_basename(const char *name) +PUB_FUNC char *tcc_basename(const char *name) { char *p = strchr(name, 0); while (p > name && !IS_PATHSEP(p[-1])) @@ -445,21 +161,27 @@ char *tcc_basename(const char *name) return p; } -char *tcc_fileextension (const char *name) +PUB_FUNC char *tcc_fileextension (const char *name) { char *b = tcc_basename(name); char *e = strrchr(b, '.'); return e ? e : strchr(b, 0); } +/********************************************************/ /* memory management */ + +#undef free +#undef malloc +#undef realloc + #ifdef MEM_DEBUG int mem_cur_size; int mem_max_size; unsigned malloc_usable_size(void*); #endif -void tcc_free(void *ptr) +PUB_FUNC void tcc_free(void *ptr) { #ifdef MEM_DEBUG mem_cur_size -= malloc_usable_size(ptr); @@ -467,7 +189,7 @@ void tcc_free(void *ptr) free(ptr); } -void *tcc_malloc(unsigned long size) +PUB_FUNC void *tcc_malloc(unsigned long size) { void *ptr; ptr = malloc(size); @@ -481,7 +203,7 @@ void *tcc_malloc(unsigned long size) return ptr; } -void *tcc_mallocz(unsigned long size) +PUB_FUNC void *tcc_mallocz(unsigned long size) { void *ptr; ptr = tcc_malloc(size); @@ -489,7 +211,7 @@ void *tcc_mallocz(unsigned long size) return ptr; } -void *tcc_realloc(void *ptr, unsigned long size) +PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size) { void *ptr1; #ifdef MEM_DEBUG @@ -505,7 +227,7 @@ void *tcc_realloc(void *ptr, unsigned long size) return ptr1; } -char *tcc_strdup(const char *str) +PUB_FUNC char *tcc_strdup(const char *str) { char *ptr; ptr = tcc_malloc(strlen(str) + 1); @@ -513,7 +235,7 @@ char *tcc_strdup(const char *str) return ptr; } -void tcc_memstats(void) +PUB_FUNC void tcc_memstats(void) { #ifdef MEM_DEBUG printf("memory in use: %d\n", mem_cur_size); @@ -524,7 +246,10 @@ void tcc_memstats(void) #define malloc(s) use_tcc_malloc(s) #define realloc(p, s) use_tcc_realloc(p, s) -void dynarray_add(void ***ptab, int *nb_ptr, void *data) +/********************************************************/ +/* dynarrays */ + +PUB_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data) { int nb, nb_alloc; void **pp; @@ -546,7 +271,7 @@ void dynarray_add(void ***ptab, int *nb_ptr, void *data) *nb_ptr = nb; } -void dynarray_reset(void *pp, int *n) +PUB_FUNC void dynarray_reset(void *pp, int *n) { void **p; for (p = *(void***)pp; *n; ++p, --*n) @@ -556,43 +281,18 @@ void dynarray_reset(void *pp, int *n) *(void**)pp = NULL; } -/* symbol allocator */ -static Sym *__sym_malloc(void) -{ - Sym *sym_pool, *sym, *last_sym; - int i; - - sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym)); - dynarray_add(&sym_pools, &nb_sym_pools, sym_pool); - - last_sym = sym_free_first; - sym = sym_pool; - for(i = 0; i < SYM_POOL_NB; i++) { - sym->next = last_sym; - last_sym = sym; - sym++; - } - sym_free_first = last_sym; - return last_sym; -} - -static inline Sym *sym_malloc(void) +/* we use our own 'finite' function to avoid potential problems with + non standard math libs */ +/* XXX: endianness dependent */ +ST_FUNC int ieee_finite(double d) { - Sym *sym; - sym = sym_free_first; - if (!sym) - sym = __sym_malloc(); - sym_free_first = sym->next; - return sym; + int *p = (int *)&d; + return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; } -static inline void sym_free(Sym *sym) -{ - sym->next = sym_free_first; - sym_free_first = sym; -} +/********************************************************/ -Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) +ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) { Section *sec; @@ -633,7 +333,7 @@ static void free_section(Section *s) } /* realloc section and set its content to zero */ -static void section_realloc(Section *sec, unsigned long new_size) +ST_FUNC void section_realloc(Section *sec, unsigned long new_size) { unsigned long size; unsigned char *data; @@ -653,7 +353,7 @@ static void section_realloc(Section *sec, unsigned long new_size) /* reserve at least 'size' bytes in section 'sec' from sec->data_offset. */ -static void *section_ptr_add(Section *sec, unsigned long size) +ST_FUNC void *section_ptr_add(Section *sec, unsigned long size) { unsigned long offset, offset1; @@ -667,7 +367,7 @@ static void *section_ptr_add(Section *sec, unsigned long size) /* return a reference to a section, and create it if it does not exists */ -Section *find_section(TCCState *s1, const char *name) +ST_FUNC Section *find_section(TCCState *s1, const char *name) { Section *sec; int i; @@ -682,7 +382,7 @@ Section *find_section(TCCState *s1, const char *name) /* update sym->c so that it points to an external symbol in section 'section' with value 'value' */ -static void put_extern_sym2(Sym *sym, Section *section, +ST_FUNC void put_extern_sym2(Sym *sym, Section *section, unsigned long value, unsigned long size, int can_add_underscore) { @@ -779,14 +479,14 @@ static void put_extern_sym2(Sym *sym, Section *section, } } -static void put_extern_sym(Sym *sym, Section *section, +ST_FUNC void put_extern_sym(Sym *sym, Section *section, unsigned long value, unsigned long size) { put_extern_sym2(sym, section, value, size, 1); } /* add a new relocation entry to symbol 'sym' in section 's' */ -static void greloc(Section *s, Sym *sym, unsigned long offset, int type) +ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type) { int c = 0; if (sym) { @@ -798,6 +498,8 @@ static void greloc(Section *s, Sym *sym, unsigned long offset, int type) put_elf_reloc(symtab_section, s, offset, type, c); } +/********************************************************/ + static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap) { int len; @@ -813,7 +515,7 @@ static void strcat_printf(char *buf, int buf_size, const char *fmt, ...) va_end(ap); } -void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) +static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) { char buf[2048]; BufferedFile **f; @@ -850,7 +552,7 @@ void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) s1->nb_errors++; } -void tcc_set_error_func(TCCState *s, void *error_opaque, +LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, void (*error_func)(void *opaque, const char *msg)) { s->error_opaque = error_opaque; @@ -858,7 +560,7 @@ void tcc_set_error_func(TCCState *s, void *error_opaque, } /* error without aborting current compilation */ -void error_noabort(const char *fmt, ...) +PUB_FUNC void error_noabort(const char *fmt, ...) { TCCState *s1 = tcc_state; va_list ap; @@ -868,7 +570,7 @@ void error_noabort(const char *fmt, ...) va_end(ap); } -void error(const char *fmt, ...) +PUB_FUNC void error(const char *fmt, ...) { TCCState *s1 = tcc_state; va_list ap; @@ -885,12 +587,12 @@ void error(const char *fmt, ...) } } -void expect(const char *msg) +PUB_FUNC void expect(const char *msg) { error("%s expected", msg); } -void warning(const char *fmt, ...) +PUB_FUNC void warning(const char *fmt, ...) { TCCState *s1 = tcc_state; va_list ap; @@ -903,233 +605,10 @@ void warning(const char *fmt, ...) va_end(ap); } -void skip(int c) -{ - if (tok != c) - error("'%c' expected", c); - next(); -} - -static void test_lvalue(void) -{ - if (!(vtop->r & VT_LVAL)) - expect("lvalue"); -} - -/* CString handling */ - -static void cstr_realloc(CString *cstr, int new_size) -{ - int size; - void *data; - - size = cstr->size_allocated; - if (size == 0) - size = 8; /* no need to allocate a too small first string */ - while (size < new_size) - size = size * 2; - data = tcc_realloc(cstr->data_allocated, size); - if (!data) - error("memory full"); - cstr->data_allocated = data; - cstr->size_allocated = size; - cstr->data = data; -} - -/* add a byte */ -static inline void cstr_ccat(CString *cstr, int ch) -{ - int size; - size = cstr->size + 1; - if (size > cstr->size_allocated) - cstr_realloc(cstr, size); - ((unsigned char *)cstr->data)[size - 1] = ch; - cstr->size = size; -} - -static void cstr_cat(CString *cstr, const char *str) -{ - int c; - for(;;) { - c = *str; - if (c == '\0') - break; - cstr_ccat(cstr, c); - str++; - } -} - -/* add a wide char */ -static void cstr_wccat(CString *cstr, int ch) -{ - int size; - size = cstr->size + sizeof(nwchar_t); - if (size > cstr->size_allocated) - cstr_realloc(cstr, size); - *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch; - cstr->size = size; -} - -static void cstr_new(CString *cstr) -{ - memset(cstr, 0, sizeof(CString)); -} - -/* free string and reset it to NULL */ -static void cstr_free(CString *cstr) -{ - tcc_free(cstr->data_allocated); - cstr_new(cstr); -} - -#define cstr_reset(cstr) cstr_free(cstr) - -/* XXX: unicode ? */ -static void add_char(CString *cstr, int c) -{ - if (c == '\'' || c == '\"' || c == '\\') { - /* XXX: could be more precise if char or string */ - cstr_ccat(cstr, '\\'); - } - if (c >= 32 && c <= 126) { - cstr_ccat(cstr, c); - } else { - cstr_ccat(cstr, '\\'); - if (c == '\n') { - cstr_ccat(cstr, 'n'); - } else { - cstr_ccat(cstr, '0' + ((c >> 6) & 7)); - cstr_ccat(cstr, '0' + ((c >> 3) & 7)); - cstr_ccat(cstr, '0' + (c & 7)); - } - } -} - -/* push, without hashing */ -static Sym *sym_push2(Sym **ps, int v, int t, long c) -{ - Sym *s; - s = sym_malloc(); - s->v = v; - s->type.t = t; - s->type.ref = NULL; -#ifdef _WIN64 - s->d = NULL; -#endif - s->c = c; - s->next = NULL; - /* add in stack */ - s->prev = *ps; - *ps = s; - return s; -} - -/* find a symbol and return its associated structure. 's' is the top - of the symbol stack */ -static Sym *sym_find2(Sym *s, int v) -{ - while (s) { - if (s->v == v) - return s; - s = s->prev; - } - return NULL; -} - -/* structure lookup */ -static inline Sym *struct_find(int v) -{ - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) - return NULL; - return table_ident[v]->sym_struct; -} - -/* find an identifier */ -static inline Sym *sym_find(int v) -{ - v -= TOK_IDENT; - if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) - return NULL; - return table_ident[v]->sym_identifier; -} - -/* push a given symbol on the symbol stack */ -static Sym *sym_push(int v, CType *type, int r, int c) -{ - Sym *s, **ps; - TokenSym *ts; - - if (local_stack) - ps = &local_stack; - else - ps = &global_stack; - s = sym_push2(ps, v, type->t, c); - s->type.ref = type->ref; - s->r = r; - /* don't record fields or anonymous symbols */ - /* XXX: simplify */ - if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { - /* record symbol in token array */ - ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT]; - if (v & SYM_STRUCT) - ps = &ts->sym_struct; - else - ps = &ts->sym_identifier; - s->prev_tok = *ps; - *ps = s; - } - return s; -} - -/* push a global identifier */ -static Sym *global_identifier_push(int v, int t, int c) -{ - Sym *s, **ps; - s = sym_push2(&global_stack, v, t, c); - /* don't record anonymous symbol */ - if (v < SYM_FIRST_ANOM) { - ps = &table_ident[v - TOK_IDENT]->sym_identifier; - /* modify the top most local identifier, so that - sym_identifier will point to 's' when popped */ - while (*ps != NULL) - ps = &(*ps)->prev_tok; - s->prev_tok = NULL; - *ps = s; - } - return s; -} - -/* pop symbols until top reaches 'b' */ -static void sym_pop(Sym **ptop, Sym *b) -{ - Sym *s, *ss, **ps; - TokenSym *ts; - int v; - - s = *ptop; - while(s != b) { - ss = s->prev; - v = s->v; - /* remove symbol in token array */ - /* XXX: simplify */ - if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { - ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT]; - if (v & SYM_STRUCT) - ps = &ts->sym_struct; - else - ps = &ts->sym_identifier; - *ps = s->prev_tok; - } - sym_free(s); - s = ss; - } - *ptop = b; -} - +/********************************************************/ /* I/O layer */ -BufferedFile *tcc_open(TCCState *s1, const char *filename) +ST_FUNC BufferedFile *tcc_open(TCCState *s1, const char *filename) { int fd; BufferedFile *bf; @@ -1159,7 +638,7 @@ BufferedFile *tcc_open(TCCState *s1, const char *filename) return bf; } -void tcc_close(BufferedFile *bf) +ST_FUNC void tcc_close(BufferedFile *bf) { total_lines += bf->line_num; close(bf->fd); @@ -1272,7 +751,7 @@ static int tcc_compile(TCCState *s1) return s1->nb_errors != 0 ? -1 : 0; } -int tcc_compile_string(TCCState *s, const char *str) +LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str) { BufferedFile bf1, *bf = &bf1; int ret, len; @@ -1301,7 +780,7 @@ int tcc_compile_string(TCCState *s, const char *str) } /* define a preprocessor symbol. A value can also be provided with the '=' operator */ -void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) +LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) { BufferedFile bf1, *bf = &bf1; @@ -1331,7 +810,7 @@ void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) } /* undefine a preprocessor symbol */ -void tcc_undefine_symbol(TCCState *s1, const char *sym) +LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym) { TokenSym *ts; Sym *s; @@ -1369,7 +848,7 @@ static void tcc_cleanup(void) macro_ptr = NULL; } -TCCState *tcc_new(void) +LIBTCCAPI TCCState *tcc_new(void) { TCCState *s; char buffer[100]; @@ -1477,6 +956,7 @@ TCCState *tcc_new(void) ".dynstrtab", ".dynhashtab", SHF_PRIVATE); s->alacarte_link = 1; + s->nocommon = 1; #ifdef CHAR_IS_UNSIGNED s->char_is_unsigned = 1; @@ -1485,17 +965,15 @@ TCCState *tcc_new(void) /* XXX: currently the PE linker is not ready to support that */ s->leading_underscore = 1; #endif - if (s->section_align == 0) s->section_align = ELF_PAGE_SIZE; - #ifdef TCC_TARGET_I386 s->seg_size = 32; #endif return s; } -void tcc_delete(TCCState *s1) +LIBTCCAPI void tcc_delete(TCCState *s1) { int i; @@ -1533,7 +1011,7 @@ void tcc_delete(TCCState *s1) tcc_free(s1); } -int tcc_add_include_path(TCCState *s1, const char *pathname) +LIBTCCAPI int tcc_add_include_path(TCCState *s1, const char *pathname) { char *pathname1; @@ -1542,7 +1020,7 @@ int tcc_add_include_path(TCCState *s1, const char *pathname) return 0; } -int tcc_add_sysinclude_path(TCCState *s1, const char *pathname) +LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s1, const char *pathname) { char *pathname1; @@ -1668,7 +1146,7 @@ the_end: return ret; } -int tcc_add_file(TCCState *s, const char *filename) +LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) { if (s->output_type == TCC_OUTPUT_PREPROCESS) return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS); @@ -1676,7 +1154,7 @@ int tcc_add_file(TCCState *s, const char *filename) return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR); } -int tcc_add_library_path(TCCState *s, const char *pathname) +LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) { char *pathname1; @@ -1687,7 +1165,7 @@ int tcc_add_library_path(TCCState *s, const char *pathname) /* find and load a dll. Return non zero if not found */ /* XXX: add '-rpath' option support ? */ -static int tcc_add_dll(TCCState *s, const char *filename, int flags) +ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) { char buf[1024]; int i; @@ -1702,7 +1180,7 @@ static int tcc_add_dll(TCCState *s, const char *filename, int flags) } /* the library name is the same as the argument of the '-l' option */ -int tcc_add_library(TCCState *s, const char *libraryname) +LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) { char buf[1024]; int i; @@ -1728,7 +1206,7 @@ int tcc_add_library(TCCState *s, const char *libraryname) return -1; } -int tcc_add_symbol(TCCState *s, const char *name, void *val) +LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, void *val) { add_elf_sym(symtab_section, (uplong)val, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, @@ -1736,7 +1214,7 @@ int tcc_add_symbol(TCCState *s, const char *name, void *val) return 0; } -int tcc_set_output_type(TCCState *s, int output_type) +LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) { char buf[1024]; @@ -1825,7 +1303,7 @@ static const FlagDef warning_defs[] = { "implicit-function-declaration" }, }; -static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, +ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, const char *name, int value) { int i; @@ -1849,9 +1327,8 @@ static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, return 0; } - /* set/reset a warning */ -int tcc_set_warning(TCCState *s, const char *warning_name, int value) +LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value) { int i; const FlagDef *p; @@ -1876,20 +1353,13 @@ static const FlagDef flag_defs[] = { }; /* set/reset a flag */ -int tcc_set_flag(TCCState *s, const char *flag_name, int value) +PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value) { return set_flag(s, flag_defs, countof(flag_defs), flag_name, value); } -/* set CONFIG_TCCDIR at runtime */ -void tcc_set_lib_path(TCCState *s, const char *path) -{ - tcc_free(s->tcc_lib_path); - s->tcc_lib_path = tcc_strdup(path); -} - -void tcc_print_stats(TCCState *s, int64_t total_time) +PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time) { double tt; tt = (double)total_time / 1000000.0; @@ -1902,3 +1372,17 @@ void tcc_print_stats(TCCState *s, int64_t total_time) tt, (int)(total_lines / tt), total_bytes / tt / 1000000.0); } + +/* set CONFIG_TCCDIR at runtime */ +LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path) +{ + tcc_free(s->tcc_lib_path); + s->tcc_lib_path = tcc_strdup(path); +} + +PUB_FUNC void set_num_callers(int n) +{ +#ifdef CONFIG_TCC_BACKTRACE + num_callers = n; +#endif +} |
