mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-24 03:40:09 +08:00
tccpp: tcc_warning("extra tokens after directive")
with stuff like #endif int x; Also fix /* */ #else Also: - search_cached_include(): search for file->true_filename - tccasm.c: avoid crash with .file
This commit is contained in:
parent
6b78e561c8
commit
08a4c52de3
6
tcc.h
6
tcc.h
@ -502,7 +502,7 @@ typedef union CValue {
|
||||
float f;
|
||||
uint64_t i;
|
||||
struct {
|
||||
const void *data;
|
||||
char *data;
|
||||
int size;
|
||||
} str;
|
||||
int tab[LDOUBLE_SIZE/4];
|
||||
@ -1390,6 +1390,7 @@ ST_FUNC void define_undef(Sym *s);
|
||||
ST_INLN Sym *define_find(int v);
|
||||
ST_FUNC void free_defines(Sym *b);
|
||||
ST_FUNC void parse_define(void);
|
||||
ST_FUNC void skip_to_eol(int warn);
|
||||
ST_FUNC void preprocess(int is_bof);
|
||||
ST_FUNC void next(void);
|
||||
ST_INLN void unget_tok(int last_tok);
|
||||
@ -1397,6 +1398,7 @@ ST_FUNC void preprocess_start(TCCState *s1, int filetype);
|
||||
ST_FUNC void preprocess_end(TCCState *s1);
|
||||
ST_FUNC void tccpp_new(TCCState *s);
|
||||
ST_FUNC void tccpp_delete(TCCState *s);
|
||||
ST_FUNC void tccpp_putfile(const char *filename);
|
||||
ST_FUNC int tcc_preprocess(TCCState *s1);
|
||||
ST_FUNC void skip(int c);
|
||||
ST_FUNC NORETURN void expect(const char *msg);
|
||||
@ -1822,7 +1824,7 @@ ST_FUNC void tcc_debug_start(TCCState *s1);
|
||||
ST_FUNC void tcc_debug_end(TCCState *s1);
|
||||
ST_FUNC void tcc_debug_bincl(TCCState *s1);
|
||||
ST_FUNC void tcc_debug_eincl(TCCState *s1);
|
||||
ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename);
|
||||
ST_FUNC void tcc_debug_newfile(TCCState *s1);
|
||||
|
||||
ST_FUNC void tcc_debug_line(TCCState *s1);
|
||||
ST_FUNC void tcc_add_debug_info(TCCState *s1, int param, Sym *s, Sym *e);
|
||||
|
30
tccasm.c
30
tccasm.c
@ -728,7 +728,7 @@ static void asm_parse_directive(TCCState *s1, int global)
|
||||
case TOK_ASMDIR_ascii:
|
||||
case TOK_ASMDIR_asciz:
|
||||
{
|
||||
const uint8_t *p;
|
||||
const char *p;
|
||||
int i, size, t;
|
||||
|
||||
t = tok;
|
||||
@ -772,15 +772,21 @@ static void asm_parse_directive(TCCState *s1, int global)
|
||||
break;
|
||||
case TOK_ASMDIR_file:
|
||||
{
|
||||
char filename[512];
|
||||
|
||||
filename[0] = '\0';
|
||||
const char *p;
|
||||
parse_flags &= ~PARSE_FLAG_TOK_STR;
|
||||
next();
|
||||
if (tok == TOK_STR)
|
||||
pstrcat(filename, sizeof(filename), tokc.str.data);
|
||||
else
|
||||
pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
|
||||
tcc_warning_c(warn_unsupported)("ignoring .file %s", filename);
|
||||
if (tok == TOK_PPNUM)
|
||||
next();
|
||||
if (tok == TOK_PPSTR && tokc.str.data[0] == '"') {
|
||||
tokc.str.data[tokc.str.size - 2] = 0;
|
||||
p = tokc.str.data + 1;
|
||||
} else if (tok >= TOK_IDENT) {
|
||||
p = get_tok_str(tok, &tokc);
|
||||
} else {
|
||||
skip_to_eol(0);
|
||||
break;
|
||||
}
|
||||
tccpp_putfile(p);
|
||||
next();
|
||||
}
|
||||
break;
|
||||
@ -968,6 +974,7 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
|
||||
next();
|
||||
if (tok == TOK_EOF)
|
||||
break;
|
||||
tcc_debug_line(s1);
|
||||
parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
|
||||
redo:
|
||||
if (tok == '#') {
|
||||
@ -1033,9 +1040,8 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
|
||||
/* GCC inline asm support */
|
||||
|
||||
/* assemble the string 'str' in the current C compilation unit without
|
||||
C preprocessing. NOTE: str is modified by modifying the '\0' at the
|
||||
end */
|
||||
static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global)
|
||||
C preprocessing. */
|
||||
static void tcc_assemble_inline(TCCState *s1, const char *str, int len, int global)
|
||||
{
|
||||
const int *saved_macro_ptr = macro_ptr;
|
||||
int dotid = set_idnum('.', IS_ID);
|
||||
|
5
tccdbg.c
5
tccdbg.c
@ -1048,11 +1048,8 @@ static BufferedFile* put_new_file(TCCState *s1)
|
||||
}
|
||||
|
||||
/* put alternative filename */
|
||||
ST_FUNC void tcc_debug_putfile(TCCState *s1, const char *filename)
|
||||
ST_FUNC void tcc_debug_newfile(TCCState *s1)
|
||||
{
|
||||
if (0 == strcmp(file->filename, filename))
|
||||
return;
|
||||
pstrcpy(file->filename, sizeof(file->filename), filename);
|
||||
if (!s1->do_debug)
|
||||
return;
|
||||
if (s1->dwarf)
|
||||
|
2
tccgen.c
2
tccgen.c
@ -8387,7 +8387,7 @@ static void gen_inline_functions(TCCState *s)
|
||||
/* the function was used or forced (and then not internal):
|
||||
generate its code and convert it to a normal function */
|
||||
fn->sym = NULL;
|
||||
tcc_debug_putfile(s, fn->filename);
|
||||
tccpp_putfile(fn->filename);
|
||||
begin_macro(fn->func_str, 1);
|
||||
next();
|
||||
cur_text_section = text_section;
|
||||
|
129
tccpp.c
129
tccpp.c
@ -53,6 +53,8 @@ static int pp_debug_tok, pp_debug_symv;
|
||||
static int pp_counter;
|
||||
static void tok_print(const int *str, const char *msg, ...);
|
||||
static void next_nomacro(void);
|
||||
static void parse_number(const char *p);
|
||||
static void parse_string(const char *p, int len);
|
||||
|
||||
static struct TinyAlloc *toksym_alloc;
|
||||
static struct TinyAlloc *tokstr_alloc;
|
||||
@ -884,7 +886,6 @@ redo_start:
|
||||
start_of_line = 1;
|
||||
in_warn_or_error = 0;
|
||||
for(;;) {
|
||||
redo_no_start:
|
||||
c = *p;
|
||||
switch(c) {
|
||||
case ' ':
|
||||
@ -893,7 +894,7 @@ redo_start:
|
||||
case '\v':
|
||||
case '\r':
|
||||
p++;
|
||||
goto redo_no_start;
|
||||
continue;
|
||||
case '\n':
|
||||
file->line_num++;
|
||||
p++;
|
||||
@ -904,7 +905,7 @@ redo_start:
|
||||
expect("#endif");
|
||||
if (c == '\\')
|
||||
++p;
|
||||
goto redo_no_start;
|
||||
continue;
|
||||
/* skip strings */
|
||||
case '\"':
|
||||
case '\'':
|
||||
@ -924,7 +925,7 @@ redo_start:
|
||||
} else if (c == '/') {
|
||||
p = parse_line_comment(p);
|
||||
}
|
||||
break;
|
||||
continue;
|
||||
case '#':
|
||||
p++;
|
||||
if (start_of_line) {
|
||||
@ -1209,7 +1210,7 @@ static inline void tok_get(int *t, const int **pp, CValue *cv)
|
||||
case TOK_PPNUM:
|
||||
case TOK_PPSTR:
|
||||
cv->str.size = *p++;
|
||||
cv->str.data = p;
|
||||
cv->str.data = (char*)p;
|
||||
p += (cv->str.size + sizeof(int) - 1) / sizeof(int);
|
||||
break;
|
||||
case TOK_CDOUBLE:
|
||||
@ -1331,6 +1332,16 @@ static void maybe_run_test(TCCState *s)
|
||||
define_push(tok, MACRO_OBJ, NULL, NULL);
|
||||
}
|
||||
|
||||
ST_FUNC void skip_to_eol(int warn)
|
||||
{
|
||||
if (tok == TOK_LINEFEED)
|
||||
return;
|
||||
if (warn)
|
||||
tcc_warning("extra tokens after directive");
|
||||
file->buf_ptr = parse_line_comment(file->buf_ptr - 1);
|
||||
tok = TOK_LINEFEED;
|
||||
}
|
||||
|
||||
static CachedInclude *
|
||||
search_cached_include(TCCState *s1, const char *filename, int add);
|
||||
|
||||
@ -1370,6 +1381,9 @@ static int parse_include(TCCState *s1, int do_next, int test)
|
||||
memmove(p, p + 1, i - 1), p[i - 1] = 0;
|
||||
}
|
||||
|
||||
if (!test)
|
||||
skip_to_eol(1);
|
||||
|
||||
i = do_next ? file->include_next_index : -1;
|
||||
for (;;) {
|
||||
++i;
|
||||
@ -1658,7 +1672,7 @@ static CachedInclude *search_cached_include(TCCState *s1, const char *filename,
|
||||
return e;
|
||||
}
|
||||
|
||||
static void pragma_parse(TCCState *s1)
|
||||
static int pragma_parse(TCCState *s1)
|
||||
{
|
||||
next_nomacro();
|
||||
if (tok == TOK_push_macro || tok == TOK_pop_macro) {
|
||||
@ -1690,7 +1704,7 @@ static void pragma_parse(TCCState *s1)
|
||||
pp_debug_tok = t, pp_debug_symv = v;
|
||||
|
||||
} else if (tok == TOK_once) {
|
||||
search_cached_include(s1, file->filename, 1)->once = 1;
|
||||
search_cached_include(s1, file->true_filename, 1)->once = 1;
|
||||
|
||||
} else if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
|
||||
/* tcc -E: keep pragmas below unchanged */
|
||||
@ -1698,6 +1712,7 @@ static void pragma_parse(TCCState *s1)
|
||||
unget_tok(TOK_PRAGMA);
|
||||
unget_tok('#');
|
||||
unget_tok(TOK_LINEFEED);
|
||||
return 1;
|
||||
|
||||
} else if (tok == TOK_pack) {
|
||||
/* This may be:
|
||||
@ -1749,7 +1764,7 @@ static void pragma_parse(TCCState *s1)
|
||||
skip(',');
|
||||
if (tok != TOK_STR)
|
||||
goto pragma_err;
|
||||
p = tcc_strdup((char *)tokc.str.data);
|
||||
p = tcc_strdup(tokc.str.data);
|
||||
next();
|
||||
if (tok != ')')
|
||||
goto pragma_err;
|
||||
@ -1761,13 +1776,37 @@ static void pragma_parse(TCCState *s1)
|
||||
tcc_free(p);
|
||||
}
|
||||
|
||||
} else
|
||||
tcc_warning_c(warn_unsupported)("#pragma %s ignored", get_tok_str(tok, &tokc));
|
||||
return;
|
||||
|
||||
} else {
|
||||
tcc_warning_c(warn_all)("#pragma %s ignored", get_tok_str(tok, &tokc));
|
||||
return 0;
|
||||
}
|
||||
next();
|
||||
return 1;
|
||||
pragma_err:
|
||||
tcc_error("malformed #pragma directive");
|
||||
return;
|
||||
}
|
||||
|
||||
/* put alternative filename */
|
||||
ST_FUNC void tccpp_putfile(const char *filename)
|
||||
{
|
||||
char buf[1024];
|
||||
buf[0] = 0;
|
||||
if (!IS_ABSPATH(filename)) {
|
||||
/* prepend directory from real file */
|
||||
pstrcpy(buf, sizeof buf, file->true_filename);
|
||||
*tcc_basename(buf) = 0;
|
||||
}
|
||||
pstrcat(buf, sizeof buf, filename);
|
||||
#ifdef _WIN32
|
||||
normalize_slashes(buf);
|
||||
#endif
|
||||
if (0 == strcmp(file->filename, buf))
|
||||
return;
|
||||
//printf("new file '%s'\n", buf);
|
||||
if (file->true_filename == file->filename)
|
||||
file->true_filename = tcc_strdup(file->filename);
|
||||
pstrcpy(file->filename, sizeof file->filename, buf);
|
||||
tcc_debug_newfile(tcc_state);
|
||||
}
|
||||
|
||||
/* is_bof is true if first non space token at beginning of file */
|
||||
@ -1803,6 +1842,7 @@ ST_FUNC void preprocess(int is_bof)
|
||||
/* undefine symbol by putting an invalid name */
|
||||
if (s)
|
||||
define_undef(s);
|
||||
next_nomacro();
|
||||
break;
|
||||
case TOK_INCLUDE:
|
||||
case TOK_INCLUDE_NEXT:
|
||||
@ -1832,12 +1872,14 @@ ST_FUNC void preprocess(int is_bof)
|
||||
|| tok == TOK___HAS_INCLUDE
|
||||
|| tok == TOK___HAS_INCLUDE_NEXT)
|
||||
c ^= 1;
|
||||
next_nomacro();
|
||||
do_if:
|
||||
if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
|
||||
tcc_error("memory full (ifdef)");
|
||||
*s1->ifdef_stack_ptr++ = c;
|
||||
goto test_skip;
|
||||
case TOK_ELSE:
|
||||
next_nomacro();
|
||||
if (s1->ifdef_stack_ptr == s1->ifdef_stack)
|
||||
tcc_error("#else without matching #if");
|
||||
if (s1->ifdef_stack_ptr[-1] & 2)
|
||||
@ -1852,6 +1894,7 @@ ST_FUNC void preprocess(int is_bof)
|
||||
tcc_error("#elif after #else");
|
||||
/* last #if/#elif expression was true: we skip */
|
||||
if (c == 1) {
|
||||
skip_to_eol(0);
|
||||
c = 0;
|
||||
} else {
|
||||
c = expr_preprocess(s1);
|
||||
@ -1862,12 +1905,14 @@ ST_FUNC void preprocess(int is_bof)
|
||||
file->ifndef_macro = 0;
|
||||
test_skip:
|
||||
if (!(c & 1)) {
|
||||
skip_to_eol(1);
|
||||
preprocess_skip();
|
||||
is_bof = 0;
|
||||
goto redo;
|
||||
}
|
||||
break;
|
||||
case TOK_ENDIF:
|
||||
next_nomacro();
|
||||
if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
|
||||
tcc_error("#endif without matching #if");
|
||||
s1->ifdef_stack_ptr--;
|
||||
@ -1879,41 +1924,27 @@ ST_FUNC void preprocess(int is_bof)
|
||||
/* 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;
|
||||
}
|
||||
break;
|
||||
case TOK_PPNUM:
|
||||
n = strtoul((char*)tokc.str.data, &q, 10);
|
||||
goto _line_num;
|
||||
case TOK_LINE:
|
||||
next();
|
||||
if (tok != TOK_CINT)
|
||||
next_nomacro();
|
||||
if (tok != TOK_PPNUM)
|
||||
_line_err:
|
||||
tcc_error("wrong #line format");
|
||||
case TOK_PPNUM:
|
||||
parse_number(tokc.str.data);
|
||||
n = tokc.i;
|
||||
_line_num:
|
||||
next();
|
||||
next_nomacro();
|
||||
if (tok != TOK_LINEFEED) {
|
||||
if (tok == TOK_STR) {
|
||||
if (file->true_filename == file->filename)
|
||||
file->true_filename = tcc_strdup(file->filename);
|
||||
q = (char *)tokc.str.data;
|
||||
buf[0] = 0;
|
||||
if (!IS_ABSPATH(q)) {
|
||||
/* prepend directory from real file */
|
||||
pstrcpy(buf, sizeof buf, file->true_filename);
|
||||
*tcc_basename(buf) = 0;
|
||||
}
|
||||
pstrcat(buf, sizeof buf, q);
|
||||
tcc_debug_putfile(s1, buf);
|
||||
if (tok == TOK_PPSTR && tokc.str.data[0] == '"') {
|
||||
tokc.str.data[tokc.str.size - 2] = 0;
|
||||
tccpp_putfile(tokc.str.data + 1);
|
||||
} else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
||||
break;
|
||||
goto ignore;
|
||||
else
|
||||
goto _line_err;
|
||||
--n;
|
||||
next_nomacro();
|
||||
}
|
||||
if (file->fd > 0)
|
||||
total_lines += file->line_num - n;
|
||||
@ -1922,6 +1953,7 @@ ST_FUNC void preprocess(int is_bof)
|
||||
|
||||
case TOK_ERROR:
|
||||
case TOK_WARNING:
|
||||
{
|
||||
q = buf;
|
||||
c = skip_spaces();
|
||||
while (c != '\n' && c != CH_EOF) {
|
||||
@ -1934,9 +1966,12 @@ ST_FUNC void preprocess(int is_bof)
|
||||
tcc_error("#error %s", buf);
|
||||
else
|
||||
tcc_warning("#warning %s", buf);
|
||||
next_nomacro();
|
||||
break;
|
||||
}
|
||||
case TOK_PRAGMA:
|
||||
pragma_parse(s1);
|
||||
if (!pragma_parse(s1))
|
||||
goto ignore;
|
||||
break;
|
||||
case TOK_LINEFEED:
|
||||
goto the_end;
|
||||
@ -1945,16 +1980,14 @@ ST_FUNC void preprocess(int is_bof)
|
||||
if (saved_parse_flags & PARSE_FLAG_ASM_FILE)
|
||||
goto ignore;
|
||||
if (tok == '!' && is_bof)
|
||||
/* '!' is ignored at beginning to allow C scripts. */
|
||||
/* '#!' is ignored at beginning to allow C scripts. */
|
||||
goto ignore;
|
||||
tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
|
||||
ignore:
|
||||
file->buf_ptr = parse_line_comment(file->buf_ptr - 1);
|
||||
break;
|
||||
skip_to_eol(0);
|
||||
goto the_end;
|
||||
}
|
||||
/* ignore other preprocess commands or #! for C scripts */
|
||||
while (tok != TOK_LINEFEED)
|
||||
next_nomacro();
|
||||
skip_to_eol(1);
|
||||
the_end:
|
||||
parse_flags = saved_parse_flags;
|
||||
}
|
||||
@ -2006,7 +2039,7 @@ static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long
|
||||
c = c - 'A' + 10;
|
||||
else if (isnum(c))
|
||||
c = c - '0';
|
||||
else if (i > 0)
|
||||
else if (i >= 0)
|
||||
expect("more hex digits in universal-character-name");
|
||||
else
|
||||
goto add_hex_or_ucn;
|
||||
@ -2564,7 +2597,7 @@ static void next_nomacro(void)
|
||||
#ifdef INC_DEBUG
|
||||
printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
|
||||
#endif
|
||||
search_cached_include(s1, file->filename, 1)
|
||||
search_cached_include(s1, file->true_filename, 1)
|
||||
->ifndef_macro = file->ifndef_macro_saved;
|
||||
tok_flags &= ~TOK_FLAG_ENDIF;
|
||||
}
|
||||
@ -3481,10 +3514,10 @@ convert:
|
||||
/* convert preprocessor tokens into C tokens */
|
||||
if (t == TOK_PPNUM) {
|
||||
if (parse_flags & PARSE_FLAG_TOK_NUM)
|
||||
parse_number((char *)tokc.str.data);
|
||||
parse_number(tokc.str.data);
|
||||
} else if (t == TOK_PPSTR) {
|
||||
if (parse_flags & PARSE_FLAG_TOK_STR)
|
||||
parse_string((char *)tokc.str.data, tokc.str.size - 1);
|
||||
parse_string(tokc.str.data, tokc.str.size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user