restored include file optimization - added static on all globals

tcc-xref
bellard 2002-11-22 22:16:30 +00:00
parent 2956bd85cd
commit cdcfed9737
1 changed files with 134 additions and 134 deletions

268
tcc.c
View File

@ -213,7 +213,8 @@ typedef struct BufferedFile {
unsigned char *buf_end;
int fd;
int line_num; /* current line number - here to simply code */
int ifndef_macro; /*'#ifndef macro \n #define macro' search */
int ifndef_macro; /* #ifndef macro / #endif search */
int ifndef_macro_saved; /* saved ifndef_macro */
int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
char inc_type; /* type of include */
char inc_filename[512]; /* filename specified by the user */
@ -249,73 +250,76 @@ typedef struct CachedInclude {
} CachedInclude;
/* parser */
struct BufferedFile *file;
int ch, tok, tok1;
CValue tokc, tok1c;
CString tokcstr; /* current parsed string, if any */
static struct BufferedFile *file;
static int ch, tok, tok1;
static CValue tokc, tok1c;
static CString tokcstr; /* current parsed string, if any */
/* additionnal 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 */
/* if true, line feed is returned as a token. line feed is also
returned at eof */
int return_linefeed;
/* set to TRUE if eof was reached */
int eof_seen;
Section *text_section, *data_section, *bss_section; /* predefined sections */
Section *cur_text_section; /* current section where function code is
static int return_linefeed;
static Section *text_section, *data_section, *bss_section; /* predefined sections */
static Section *cur_text_section; /* current section where function code is
generated */
/* bound check related sections */
Section *bounds_section; /* contains global data bound description */
Section *lbounds_section; /* contains local data bound description */
static Section *bounds_section; /* contains global data bound description */
static Section *lbounds_section; /* contains local data bound description */
/* symbol sections */
Section *symtab_section, *strtab_section;
static Section *symtab_section, *strtab_section;
/* debug sections */
Section *stab_section, *stabstr_section;
static Section *stab_section, *stabstr_section;
/* loc : local variable index
ind : output code index
rsym: return symbol
anon_sym: anonymous symbol index
*/
int rsym, anon_sym,
prog, ind, loc;
static int rsym, anon_sym, ind, loc;
/* expression generation modifiers */
int const_wanted; /* true if constant wanted */
int nocode_wanted; /* true if no code generation wanted for an expression */
int global_expr; /* true if compound literals must be allocated
globally (used during initializers parsing */
CType func_vt; /* current function return type (used by return
instruction) */
int func_vc;
int last_line_num, last_ind, func_ind; /* debug last line number and pc */
int tok_ident;
TokenSym **table_ident;
TokenSym *hash_ident[TOK_HASH_SIZE];
char token_buf[STRING_MAX_SIZE + 1];
char *funcname;
Sym *global_stack, *local_stack;
Sym *define_stack;
Sym *label_stack;
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 *label_stack;
SValue vstack[VSTACK_SIZE], *vtop;
int *macro_ptr, *macro_ptr_allocated;
static SValue vstack[VSTACK_SIZE], *vtop;
static int *macro_ptr, *macro_ptr_allocated;
/* some predefined types */
CType char_pointer_type, func_old_type, int_type;
static CType char_pointer_type, func_old_type, int_type;
/* compile with debug symbol (and use them if error during execution) */
int do_debug = 0;
static int do_debug = 0;
/* compile with built-in memory and bounds checker */
int do_bounds_check = 0;
static int do_bounds_check = 0;
/* display benchmark infos */
int do_bench = 0;
int total_lines;
int total_bytes;
static int do_bench = 0;
static int total_lines;
static int total_bytes;
/* use GNU C extensions */
int gnu_ext = 1;
static int gnu_ext = 1;
/* use Tiny C extensions */
int tcc_ext = 1;
static int tcc_ext = 1;
/* max number of callers shown if error */
static int num_callers = 6;
@ -1225,6 +1229,21 @@ static void cstr_free(CString *cstr)
#define cstr_reset(cstr) cstr_free(cstr)
static CString *cstr_dup(CString *cstr1)
{
CString *cstr;
int size;
cstr = tcc_malloc(sizeof(CString));
size = cstr1->size;
cstr->size = size;
cstr->size_allocated = size;
cstr->data_allocated = tcc_malloc(size);
cstr->data = cstr->data_allocated;
memcpy(cstr->data_allocated, cstr1->data_allocated, size);
return cstr;
}
/* XXX: unicode ? */
static void add_char(CString *cstr, int c)
{
@ -1525,32 +1544,10 @@ int tcc_getc_slow(BufferedFile *bf)
/* no need to put that inline */
void handle_eob(void)
{
TCCState *s1 = tcc_state;
/* no need to do anything if not at EOB */
if (file->buf_ptr <= file->buf_end)
return;
for(;;) {
ch = tcc_getc_slow(file);
if (ch != CH_EOF)
return;
eof_seen = 1;
if (return_linefeed) {
ch = '\n';
return;
}
if (s1->include_stack_ptr == s1->include_stack)
return;
/* add end of include file debug info */
if (do_debug) {
put_stabd(N_EINCL, 0, 0);
}
/* pop include stack */
tcc_close(file);
s1->include_stack_ptr--;
file = *s1->include_stack_ptr;
}
ch = tcc_getc_slow(file);
}
/* read next char from current input file and handle end of input buffer */
@ -1668,7 +1665,8 @@ void preprocess_skip(void)
start_of_line = 1;
a = 0;
while (1) {
for(;;) {
redo_no_start:
switch(ch) {
case ' ':
case '\t':
@ -1676,19 +1674,18 @@ void preprocess_skip(void)
case '\v':
case '\r':
inp();
break;
goto redo_no_start;
case '\n':
start_of_line = 1;
file->line_num++;
inp();
break;
goto redo_no_start;
case '\\':
handle_stray();
break;
goto redo_no_start;
/* skip strings */
case '\"':
case '\'':
start_of_line = 0;
sep = ch;
inp();
while (ch != sep) {
@ -1714,8 +1711,6 @@ void preprocess_skip(void)
parse_comment();
} else if (ch == '/') {
parse_line_comment();
} else {
start_of_line = 0;
}
break;
@ -1731,16 +1726,15 @@ void preprocess_skip(void)
else if (tok == TOK_ENDIF)
a--;
}
start_of_line = 0;
break;
case CH_EOF:
expect("#endif");
break;
default:
inp();
start_of_line = 0;
break;
}
start_of_line = 0;
}
the_end: ;
}
@ -1846,22 +1840,13 @@ static void tok_str_add(TokenString *s, int t)
static void tok_str_add2(TokenString *s, int t, CValue *cv)
{
int n, i, size;
CString *cstr, *cstr1;
int n, i;
CValue cv1;
tok_str_add(s, t);
if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) {
/* special case: need to duplicate string */
cstr1 = cv->cstr;
cstr = tcc_malloc(sizeof(CString));
size = cstr1->size;
cstr->size = size;
cstr->size_allocated = size;
cstr->data_allocated = tcc_malloc(size);
cstr->data = cstr->data_allocated;
memcpy(cstr->data_allocated, cstr1->data_allocated, size);
cv1.cstr = cstr;
cv1.cstr = cstr_dup(cv->cstr);
tok_str_add(s, cv1.tab[0]);
} else {
n = tok_ext_size(t);
@ -2107,17 +2092,11 @@ static inline void add_cached_include(TCCState *s1, int type,
dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
}
enum IncludeState {
INCLUDE_STATE_NONE = 0,
INCLUDE_STATE_SEEK_IFNDEF,
};
void preprocess(void)
/* is_bof is true if first non space token at beginning of file */
static void preprocess(int is_bof)
{
TCCState *s1 = tcc_state;
int size, i, c, n, line_num;
enum IncludeState state;
char buf[1024], *q, *p;
char buf1[1024];
BufferedFile *f;
@ -2126,9 +2105,6 @@ void preprocess(void)
return_linefeed = 1; /* linefeed will be returned as a
token. EOF is also returned as line feed */
state = INCLUDE_STATE_NONE;
eof_seen = 0;
redo1:
next_nomacro();
redo:
switch(tok) {
@ -2253,16 +2229,8 @@ void preprocess(void)
if (do_debug) {
put_stabs(file->filename, N_BINCL, 0, 0, 0);
}
/* we check for the construct: #ifndef IDENT \n #define IDENT */
inp();
/* get first non space char */
while (is_space(ch) || ch == '\n')
cinp();
if (ch != '#')
goto the_end;
state = INCLUDE_STATE_SEEK_IFNDEF;
cinp();
goto redo1;
tok_flags |= TOK_FLAG_BOF;
goto the_end;
}
break;
case TOK_IFNDEF:
@ -2277,11 +2245,13 @@ void preprocess(void)
next_nomacro();
if (tok < TOK_IDENT)
error("invalid argument for '#if%sdef'", c ? "n" : "");
if (state == INCLUDE_STATE_SEEK_IFNDEF) {
if (is_bof) {
if (c) {
#ifdef INC_DEBUG
printf("#ifndef %s\n", get_tok_str(tok, NULL));
#endif
file->ifndef_macro = tok;
}
state = INCLUDE_STATE_NONE;
}
c = (define_find(tok) != 0) ^ c;
do_if:
@ -2311,31 +2281,27 @@ void preprocess(void)
if (!(c & 1)) {
skip:
preprocess_skip();
state = INCLUDE_STATE_NONE;
is_bof = 0;
goto redo;
}
break;
case TOK_ENDIF:
if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
error("#endif without matching #if");
s1->ifdef_stack_ptr--;
/* '#ifndef macro' was at the start of file. Now we check if
an '#endif' is exactly at the end of file */
if (file->ifndef_macro &&
s1->ifdef_stack_ptr == (file->ifdef_stack_ptr + 1)) {
/* '#ifndef macro \n #define macro' was at the start of
file. Now we check if an '#endif' is exactly at the end
of file */
s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
file->ifndef_macro_saved = file->ifndef_macro;
/* need to set to zero to avoid false matches if another
#ifndef at middle of file */
file->ifndef_macro = 0;
while (tok != TOK_LINEFEED)
next_nomacro();
/* XXX: should also skip comments, but it is more complicated */
if (eof_seen) {
add_cached_include(s1, file->inc_type, file->inc_filename,
file->ifndef_macro);
} else {
/* if not end of file, we must desactivate the ifndef
macro search */
file->ifndef_macro = 0;
}
tok_flags |= TOK_FLAG_ENDIF;
goto the_end;
}
s1->ifdef_stack_ptr--;
break;
case TOK_LINE:
next();
@ -2378,7 +2344,7 @@ void preprocess(void)
break;
}
/* ignore other preprocess commands or #! for C scripts */
while (tok != TOK_LINEFEED && tok != TOK_EOF)
while (tok != TOK_LINEFEED)
next_nomacro();
the_end:
return_linefeed = 0;
@ -2780,11 +2746,10 @@ void parse_number(const char *p)
/* return next token without macro substitution */
static inline void next_nomacro1(void)
{
int b, t, start_of_line;
int b, t;
char *q;
TokenSym *ts;
start_of_line = 0;
redo_no_start:
switch(ch) {
case ' ':
@ -2799,13 +2764,48 @@ static inline void next_nomacro1(void)
handle_stray();
goto redo_no_start;
case CH_EOF:
{
TCCState *s1 = tcc_state;
if (return_linefeed) {
tok = TOK_LINEFEED;
} else if (s1->include_stack_ptr == s1->include_stack) {
/* no include left : end of file */
tok = TOK_EOF;
} else {
/* pop include file */
/* test if previous '#endif' was after a #ifdef at
start of file */
if (tok_flags & TOK_FLAG_ENDIF) {
#ifdef INC_DEBUG
printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
#endif
add_cached_include(s1, file->inc_type, file->inc_filename,
file->ifndef_macro_saved);
}
/* add end of include file debug info */
if (do_debug) {
put_stabd(N_EINCL, 0, 0);
}
/* pop include stack */
tcc_close(file);
s1->include_stack_ptr--;
file = *s1->include_stack_ptr;
inp();
goto redo_no_start;
}
}
break;
case '\n':
file->line_num++;
if (return_linefeed) {
/* XXX: should eat token ? */
tok = TOK_LINEFEED;
} else {
start_of_line = 1;
tok_flags |= TOK_FLAG_BOL;
inp();
goto redo_no_start;
}
@ -2813,8 +2813,8 @@ static inline void next_nomacro1(void)
case '#':
minp();
if (start_of_line) {
preprocess();
if (tok_flags & TOK_FLAG_BOL) {
preprocess(tok_flags & TOK_FLAG_BOF);
goto redo_no_start;
} else {
if (ch == '#') {
@ -3108,13 +3108,11 @@ static inline void next_nomacro1(void)
tok = ch;
cinp();
break;
case CH_EOF:
tok = TOK_EOF;
break;
default:
error("unrecognized character \\x%02x", ch);
break;
}
tok_flags = 0;
#if defined(PARSE_DEBUG)
printf("token = %s\n", get_tok_str(tok, &tokc));
#endif
@ -3386,6 +3384,7 @@ static int macro_subst_tok(TokenString *tok_str,
if (macro_ptr) {
t = *macro_ptr;
} else {
/* XXX: incorrect with comments */
while (is_space(ch) || ch == '\n')
cinp();
t = ch;
@ -7642,7 +7641,8 @@ static int tcc_compile(TCCState *s1)
s1->nb_errors = 0;
s1->error_set_jmp_enabled = 1;
ch = '\n'; /* needed to parse correctly first preprocessor command */
ch = '\n'; /* XXX: suppress that*/
tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
next();
decl(VT_CONST);
if (tok != -1)