aboutsummaryrefslogtreecommitdiff
path: root/tcc.c
diff options
context:
space:
mode:
authorbellard <bellard>2002-11-22 22:16:30 +0000
committerbellard <bellard>2002-11-22 22:16:30 +0000
commitcdcfed9737c6cd20a36833b540c030f6601fea03 (patch)
tree3266b27608b8f33117f005665ed33cad7bafba54 /tcc.c
parent2956bd85cde6a01db1bfc527e1380c9d8817484c (diff)
downloadtinycc-cdcfed9737c6cd20a36833b540c030f6601fea03.tar.gz
tinycc-cdcfed9737c6cd20a36833b540c030f6601fea03.tar.bz2
restored include file optimization - added static on all globals
Diffstat (limited to 'tcc.c')
-rw-r--r--tcc.c268
1 files changed, 134 insertions, 134 deletions
diff --git a/tcc.c b/tcc.c
index c8637e2..bf84795 100644
--- a/tcc.c
+++ b/tcc.c
@@ -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)