aboutsummaryrefslogtreecommitdiff
path: root/libtcc.c
diff options
context:
space:
mode:
authorgrischka <grischka>2009-12-20 01:53:49 +0100
committergrischka <grischka>2009-12-20 01:53:49 +0100
commit88a3ccab9f3c877e2ffb8fecc3303006e0640907 (patch)
tree47092d8442f4d7f1e4714643acf25787556d1e10 /libtcc.c
parent7fa712e00c5221d9373e8f8fa073e9e6fa064da1 (diff)
downloadtinycc-88a3ccab9f3c877e2ffb8fecc3303006e0640907.tar.gz
tinycc-88a3ccab9f3c877e2ffb8fecc3303006e0640907.tar.bz2
allow tcc be build from separate objects
If you want that, run: make NOTALLINONE=1
Diffstat (limited to 'libtcc.c')
-rw-r--r--libtcc.c732
1 files changed, 108 insertions, 624 deletions
diff --git a/libtcc.c b/libtcc.c
index 7ef1f0b..9be8c1c 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -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
+}