aboutsummaryrefslogtreecommitdiff
path: root/tccpp.c
diff options
context:
space:
mode:
authorjiang <30155751@qq.com>2014-05-04 13:18:31 +0800
committerjiang <30155751@qq.com>2014-05-04 13:18:31 +0800
commit5e56fb635a23484d8fda8b54a40900d0a54b0ba1 (patch)
tree6f7491150cfe01700c9863946906203adad0de13 /tccpp.c
parent089dea355a28da44376ce4f5195baa4b4e0b217d (diff)
downloadtinycc-5e56fb635a23484d8fda8b54a40900d0a54b0ba1.tar.gz
tinycc-5e56fb635a23484d8fda8b54a40900d0a54b0ba1.tar.bz2
Return to: e20c1eb99e1003c1e59522c136dbb15c52d7cc7c
1: The new patch for the other machines still have the problem. 2: libcrt Rename (what if gcc had libcrt as well) 3: parse_number exact problem 4: VT_VLS is to allow tcc Compile the following int b = 9; struct st { int a; int b [b] }; struct st st1; st1.b [8] = 9; printf ("% d \ n", st1.b [8]); tcc a problem. Due to problems in front, and now can not be improved 5: they commit much, bug difficult to lock, you can not let other people help develop. 6: ('\ t') too Thanks to Michael and Ray Their criticism I have benefited!
Diffstat (limited to 'tccpp.c')
-rw-r--r--tccpp.c302
1 files changed, 99 insertions, 203 deletions
diff --git a/tccpp.c b/tccpp.c
index 538f671..732c5ea 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -233,10 +233,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
ts = tcc_malloc(sizeof(TokenSym) + len);
table_ident[i] = ts;
ts->tok = tok_ident++;
- ts->sym_define.data = tcc_malloc(sizeof(Sym**));
- ts->sym_define.off = 0;
- ts->sym_define.data[0] = NULL;
- ts->sym_define.size = 1;
+ ts->sym_define = NULL;
ts->sym_label = NULL;
ts->sym_struct = NULL;
ts->sym_identifier = NULL;
@@ -1055,62 +1052,52 @@ static int macro_is_equal(const int *a, const int *b)
ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
{
Sym *s;
- CSym *def;
+
s = define_find(v);
if (s && !macro_is_equal(s->d, str))
tcc_warning("%s redefined", get_tok_str(v, NULL));
+
s = sym_push2(&define_stack, v, macro_type, 0);
s->d = str;
s->next = first_arg;
- def = &table_ident[v - TOK_IDENT]->sym_define;
- def->data[def->off] = s;
+ table_ident[v - TOK_IDENT]->sym_define = s;
}
/* undefined a define symbol. Its name is just set to zero */
ST_FUNC void define_undef(Sym *s)
{
int v;
- CSym *def;
- v = s->v - TOK_IDENT;
- if ((unsigned)v < (unsigned)(tok_ident - TOK_IDENT)){
- def = &table_ident[v]->sym_define;
- def->data[def->off] = NULL;
- }
+ v = s->v;
+ if (v >= TOK_IDENT && v < tok_ident)
+ table_ident[v - TOK_IDENT]->sym_define = NULL;
+ s->v = 0;
}
ST_INLN Sym *define_find(int v)
{
- CSym *def;
v -= TOK_IDENT;
if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
return NULL;
- def = &table_ident[v]->sym_define;
- return def->data[def->off];
+ return table_ident[v]->sym_define;
}
/* free define stack until top reaches 'b' */
ST_FUNC void free_defines(Sym *b)
{
- Sym *top, *tmp;
+ Sym *top, *top1;
int v;
- CSym *def;
top = define_stack;
while (top != b) {
- tmp = top->prev;
+ top1 = top->prev;
/* do not free args or predefined defines */
if (top->d)
tok_str_free(top->d);
- v = top->v - TOK_IDENT;
- if ((unsigned)v < (unsigned)(tok_ident - TOK_IDENT)){
- def = &table_ident[v]->sym_define;
- if(def->off)
- def->off = 0;
- if(def->data[0])
- def->data[0] = NULL;
- }
+ v = top->v;
+ if (v >= TOK_IDENT && v < tok_ident)
+ table_ident[v - TOK_IDENT]->sym_define = NULL;
sym_free(top);
- top = tmp;
+ top = top1;
}
define_stack = b;
}
@@ -1351,18 +1338,66 @@ static inline void add_cached_include(TCCState *s1, const char *filename, int if
s1->cached_includes_hash[h] = s1->nb_cached_includes;
}
+static void pragma_parse(TCCState *s1)
+{
+ int val;
+
+ next();
+ if (tok == TOK_pack) {
+ /*
+ This may be:
+ #pragma pack(1) // set
+ #pragma pack() // reset to default
+ #pragma pack(push,1) // push & set
+ #pragma pack(pop) // restore previous
+ */
+ next();
+ skip('(');
+ if (tok == TOK_ASM_pop) {
+ next();
+ if (s1->pack_stack_ptr <= s1->pack_stack) {
+ stk_error:
+ tcc_error("out of pack stack");
+ }
+ s1->pack_stack_ptr--;
+ } else {
+ val = 0;
+ if (tok != ')') {
+ if (tok == TOK_ASM_push) {
+ next();
+ if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
+ goto stk_error;
+ s1->pack_stack_ptr++;
+ skip(',');
+ }
+ if (tok != TOK_CINT) {
+ pack_error:
+ tcc_error("invalid pack pragma");
+ }
+ val = tokc.i;
+ if (val < 1 || val > 16 || (val & (val - 1)) != 0)
+ goto pack_error;
+ next();
+ }
+ *s1->pack_stack_ptr = val;
+ skip(')');
+ }
+ }
+}
+
/* is_bof is true if first non space token at beginning of file */
ST_FUNC void preprocess(int is_bof)
{
TCCState *s1 = tcc_state;
int i, c, n, saved_parse_flags;
- uint8_t buf[1024], *p;
+ char buf[1024], *q;
Sym *s;
saved_parse_flags = parse_flags;
- parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_LINEFEED;
+ parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
+ PARSE_FLAG_LINEFEED;
next_nomacro();
-redo:
+ redo:
switch(tok) {
case TOK_DEFINE:
next_nomacro();
@@ -1385,21 +1420,19 @@ redo:
goto read_name;
} else if (ch == '\"') {
c = ch;
-read_name:
+ read_name:
inp();
- p = buf;
+ q = buf;
while (ch != c && ch != '\n' && ch != CH_EOF) {
- if ((p - buf) < sizeof(buf) - 1)
- *p++ = ch;
+ if ((q - buf) < sizeof(buf) - 1)
+ *q++ = ch;
if (ch == '\\') {
if (handle_stray_noerror() == 0)
- --p;
+ --q;
} else
inp();
}
- if (ch != c)
- goto include_syntax;
- *p = '\0';
+ *q = '\0';
minp();
#if 0
/* eat all spaces and comments after include */
@@ -1437,8 +1470,6 @@ read_name:
c = '>';
}
}
- if(!buf[0])
- tcc_error(" empty filename in #include");
if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
tcc_error("#include recursion too deep");
@@ -1505,7 +1536,8 @@ include_trynext:
printf("%s: including %s\n", file->prev->filename, file->filename);
#endif
/* update target deps */
- dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps, tcc_strdup(buf1));
+ dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
+ tcc_strdup(buf1));
/* push current file in stack */
++s1->include_stack_ptr;
/* add include file debug info */
@@ -1538,7 +1570,7 @@ include_done:
file->ifndef_macro = tok;
}
}
- c = !!define_find(tok) ^ c;
+ c = (define_find(tok) != 0) ^ c;
do_if:
if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
tcc_error("memory full (ifdef)");
@@ -1562,12 +1594,12 @@ include_done:
goto skip;
c = expr_preprocess();
s1->ifdef_stack_ptr[-1] = c;
-test_else:
+ test_else:
if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1)
file->ifndef_macro = 0;
-test_skip:
+ test_skip:
if (!(c & 1)) {
-skip:
+ skip:
preprocess_skip();
is_bof = 0;
goto redo;
@@ -1585,11 +1617,11 @@ skip:
/* 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();
tok_flags |= TOK_FLAG_ENDIF;
+ goto the_end;
}
- next_nomacro();
- if (tok != TOK_LINEFEED)
- tcc_warning("Ignoring: %s", get_tok_str(tok, &tokc));
break;
case TOK_LINE:
next();
@@ -1600,7 +1632,8 @@ skip:
if (tok != TOK_LINEFEED) {
if (tok != TOK_STR)
tcc_error("#line");
- pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.cstr->data);
+ pstrcpy(file->filename, sizeof(file->filename),
+ (char *)tokc.cstr->data);
}
break;
case TOK_ERROR:
@@ -1608,161 +1641,24 @@ skip:
c = tok;
ch = file->buf_ptr[0];
skip_spaces();
- p = buf;
+ q = buf;
while (ch != '\n' && ch != CH_EOF) {
- if ((p - buf) < sizeof(buf) - 1)
- *p++ = ch;
+ if ((q - buf) < sizeof(buf) - 1)
+ *q++ = ch;
if (ch == '\\') {
if (handle_stray_noerror() == 0)
- --p;
+ --q;
} else
inp();
}
- *p = '\0';
+ *q = '\0';
if (c == TOK_ERROR)
tcc_error("#error %s", buf);
else
tcc_warning("#warning %s", buf);
break;
case TOK_PRAGMA:
- next();
- if (tok == TOK_pack && parse_flags & PARSE_FLAG_PACK) {
- /*
- This may be:
- #pragma pack(1) // set
- #pragma pack() // reset to default
- #pragma pack(push,1) // push & set
- #pragma pack(pop) // restore previous
- */
- next();
- skip('(');
- if (tok == TOK_ASM_pop) {
- next();
- if (s1->pack_stack_ptr <= s1->pack_stack) {
-stk_error:
- tcc_error("out of pack stack");
- }
- s1->pack_stack_ptr--;
- } else {
- int val = 0;
- if (tok != ')') {
- if (tok == TOK_ASM_push) {
- next();
- s1->pack_stack_ptr++;
- if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE)
- goto stk_error;
- skip(',');
- }
- if (tok != TOK_CINT) {
-pack_error:
- tcc_error("invalid pack pragma");
- }
- val = tokc.i;
- if (val < 1 || val > 16)
- goto pack_error;
- if (val < 1 || val > 16)
- tcc_error("Value must be greater than 1 is less than or equal to 16");
- if ((val & (val - 1)) != 0)
- tcc_error("Value must be a power of 2 curtain");
- next();
- }
- *s1->pack_stack_ptr = val;
- skip(')');
- }
- }else if (tok == TOK_PUSH_MACRO || tok == TOK_POP_MACRO) {
- TokenSym *ts;
- CSym *def;
- uint8_t *p1;
- int len, t;
- t = tok;
- ch = file->buf_ptr[0];
- skip_spaces();
- if (ch != '(')
- goto macro_xxx_syntax;
- /* XXX: incorrect if comments : use next_nomacro with a special mode */
- inp();
- skip_spaces();
- if (ch == '\"'){
- inp();
- p = buf;
- while (ch != '\"' && ch != '\n' && ch != CH_EOF) {
- if ((p - buf) < sizeof(buf) - 1)
- *p++ = ch;
- if (ch == CH_EOB) {
- --p;
- handle_stray();
- }else
- inp();
- }
- if(ch != '\"')
- goto macro_xxx_syntax;
- *p = '\0';
- minp();
- next();
- }else{
- /* computed #pragma macro_xxx for #define xxx */
- next();
- buf[0] = '\0';
- while (tok != ')') {
- if (tok != TOK_STR) {
- macro_xxx_syntax:
- tcc_error("'macro_xxx' expects (\"NAME\")");
- }
- pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
- next();
- }
- }
- skip (')');
- if(!buf[0])
- tcc_error(" empty string in #pragma");
- /* find TokenSym */
- p = buf;
- while (is_space(*p))
- p++;
- p1 = p;
- for(;;){
- if (!isidnum_table[p[0] - CH_EOF])
- break;
- ++p;
- }
- len = p - p1;
- while (is_space(*p))
- p++;
- if(!p) //'\0'
- tcc_error("unrecognized string: %s", buf);
- ts = tok_alloc(p1, len);
- if(ts){
- def = &ts->sym_define;
- if(t == TOK_PUSH_MACRO){
- void *tmp = def->data[def->off];
- if(tmp){
- def->off++;
- if(def->off >= def->size){
- int size = def->size;
- size *= 2;
- if (size >= MACRO_STACK_SIZE)
- tcc_error("stack full");
- def->data = tcc_realloc(def->data, size*sizeof(Sym**));
- def->size = size;
- }
- def->data[def->off] = tmp;
- }
- }else{
- if(def->off){
- --def->off;
- }else{
- tcc_warning("stack empty");
- }
- }
- }
- }else{
- fputs("#pragma ", s1->ppfp);
- while (tok != TOK_LINEFEED){
- fputs(get_tok_str(tok, &tokc), s1->ppfp);
- next();
- }
- goto the_end;
- }
+ pragma_parse(s1);
break;
default:
if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_PPNUM) {
@@ -1782,7 +1678,7 @@ pack_error:
/* ignore other preprocess commands or #! for C scripts */
while (tok != TOK_LINEFEED)
next_nomacro();
-the_end:
+ the_end:
parse_flags = saved_parse_flags;
}
@@ -3134,13 +3030,12 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
ch = file->buf_ptr[0];
tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS |
- PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES;
+ PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES;
token_seen = 0;
line_ref = 0;
file_ref = NULL;
iptr = s1->include_stack_ptr;
- tok = TOK_LINEFEED; /* print line */
- goto print_line;
+
for (;;) {
next();
if (tok == TOK_EOF) {
@@ -3148,11 +3043,11 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
} else if (file != file_ref) {
goto print_line;
} else if (tok == TOK_LINEFEED) {
- if (token_seen)
+ if (!token_seen)
continue;
++line_ref;
- token_seen = 1;
- } else if (token_seen) {
+ token_seen = 0;
+ } else if (!token_seen) {
d = file->line_num - line_ref;
if (file != file_ref || d < 0 || d >= 8) {
print_line:
@@ -3160,7 +3055,8 @@ print_line:
s = iptr_new > iptr ? " 1"
: iptr_new < iptr ? " 2"
: iptr_new > s1->include_stack ? " 3"
- : "";
+ : ""
+ ;
iptr = iptr_new;
fprintf(s1->ppfp, "# %d \"%s\"%s\n", file->line_num, file->filename, s);
} else {
@@ -3168,8 +3064,8 @@ print_line:
fputs("\n", s1->ppfp), --d;
}
line_ref = (file_ref = file)->line_num;
- token_seen = tok == TOK_LINEFEED;
- if (token_seen)
+ token_seen = tok != TOK_LINEFEED;
+ if (!token_seen)
continue;
}
fputs(get_tok_str(tok, &tokc), s1->ppfp);