cppmain.c (scan_translation_unit): Don't worry about putting a space after hashes.
* cppmain.c (scan_translation_unit): Don't worry about putting a space after hashes. * cpplib.c (directive_diagnostics): New. (_cpp_handle_directive): Update to use directive_diagnostics. (run_directive): Don't toggle prevent_expansion. (do_line): Backup in case of the line extension. * cpplib.h (cpp_lexer_pos): Remove. * cppmacro.c (_cpp_create_definition): Precede a leading # with whitespace. * gcc.dg/cpp/line5.c: New testcase. From-SVN: r45645
This commit is contained in:
parent
27553bf325
commit
18a9d8ff7f
7 changed files with 144 additions and 114 deletions
|
@ -1,3 +1,15 @@
|
|||
2001-09-16 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* cppmain.c (scan_translation_unit): Don't worry about
|
||||
putting a space after hashes.
|
||||
* cpplib.c (directive_diagnostics): New.
|
||||
(_cpp_handle_directive): Update to use directive_diagnostics.
|
||||
(run_directive): Don't toggle prevent_expansion.
|
||||
(do_line): Backup in case of the line extension.
|
||||
* cpplib.h (cpp_lexer_pos): Remove.
|
||||
* cppmacro.c (_cpp_create_definition): Precede a leading #
|
||||
with whitespace.
|
||||
|
||||
2001-09-15 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* c-typeck.c (comptypes): Handle zero-length arrays properly.
|
||||
|
|
204
gcc/cpplib.c
204
gcc/cpplib.c
|
@ -82,6 +82,8 @@ static void skip_rest_of_line PARAMS ((cpp_reader *));
|
|||
static void check_eol PARAMS ((cpp_reader *));
|
||||
static void start_directive PARAMS ((cpp_reader *));
|
||||
static void end_directive PARAMS ((cpp_reader *, int));
|
||||
static void directive_diagnostics
|
||||
PARAMS ((cpp_reader *, const directive *, int));
|
||||
static void run_directive PARAMS ((cpp_reader *, int,
|
||||
const char *, size_t));
|
||||
static int glue_header_name PARAMS ((cpp_reader *, cpp_token *));
|
||||
|
@ -248,8 +250,57 @@ end_directive (pfile, skip_line)
|
|||
pfile->directive = 0;
|
||||
}
|
||||
|
||||
/* Check if a token's name matches that of a known directive. Put in
|
||||
this file to save exporting dtable and other unneeded information. */
|
||||
/* Output diagnostics for a directive DIR. INDENTED is non-zero if
|
||||
the '#' was indented. */
|
||||
|
||||
static void
|
||||
directive_diagnostics (pfile, dir, indented)
|
||||
cpp_reader *pfile;
|
||||
const directive *dir;
|
||||
int indented;
|
||||
{
|
||||
if (pfile->state.line_extension)
|
||||
{
|
||||
if (CPP_PEDANTIC (pfile)
|
||||
&& ! pfile->state.skipping)
|
||||
cpp_pedwarn (pfile, "style of line directive is a GCC extension");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Issue -pedantic warnings for extensions. */
|
||||
if (CPP_PEDANTIC (pfile)
|
||||
&& ! pfile->state.skipping
|
||||
&& dir->origin == EXTENSION)
|
||||
cpp_pedwarn (pfile, "#%s is a GCC extension", dir->name);
|
||||
|
||||
/* Traditionally, a directive is ignored unless its # is in
|
||||
column 1. Therefore in code intended to work with K+R
|
||||
compilers, directives added by C89 must have their #
|
||||
indented, and directives present in traditional C must not.
|
||||
This is true even of directives in skipped conditional
|
||||
blocks. */
|
||||
if (CPP_WTRADITIONAL (pfile))
|
||||
{
|
||||
if (dir == &dtable[T_ELIF])
|
||||
cpp_warning (pfile, "suggest not using #elif in traditional C");
|
||||
else if (indented && dir->origin == KANDR)
|
||||
cpp_warning (pfile,
|
||||
"traditional C ignores #%s with the # indented",
|
||||
dir->name);
|
||||
else if (!indented && dir->origin != KANDR)
|
||||
cpp_warning (pfile,
|
||||
"suggest hiding #%s from traditional C with an indented #",
|
||||
dir->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we have a known directive. INDENTED is non-zero if the
|
||||
'#' of the directive was indented. This function is in this file
|
||||
to save unnecessarily exporting dtable etc. to cpplex.c. Returns
|
||||
non-zero if the line of tokens has been handled, zero if we should
|
||||
continue processing the line. */
|
||||
|
||||
int
|
||||
_cpp_handle_directive (pfile, indented)
|
||||
cpp_reader *pfile;
|
||||
|
@ -260,125 +311,80 @@ _cpp_handle_directive (pfile, indented)
|
|||
int skip = 1;
|
||||
|
||||
start_directive (pfile);
|
||||
|
||||
/* Lex the directive name directly. */
|
||||
_cpp_lex_token (pfile, &dname);
|
||||
|
||||
if (dname.type == CPP_NAME)
|
||||
{
|
||||
unsigned int index = dname.val.node->directive_index;
|
||||
if (index)
|
||||
dir = &dtable[index - 1];
|
||||
if (dname.val.node->directive_index)
|
||||
dir = &dtable[dname.val.node->directive_index - 1];
|
||||
}
|
||||
else if (dname.type == CPP_NUMBER)
|
||||
/* We do not recognise the # followed by a number extension in
|
||||
assembler code. */
|
||||
else if (dname.type == CPP_NUMBER && CPP_OPTION (pfile, lang) != CLK_ASM)
|
||||
{
|
||||
/* # followed by a number is equivalent to #line. Do not
|
||||
recognize this form in assembly language source files or
|
||||
skipped conditional groups. Complain about this form if
|
||||
we're being pedantic, but not if this is regurgitated input
|
||||
(preprocessed or fed back in by the C++ frontend). */
|
||||
if (! pfile->state.skipping && CPP_OPTION (pfile, lang) != CLK_ASM)
|
||||
{
|
||||
dir = &dtable[T_LINE];
|
||||
pfile->state.line_extension = 1;
|
||||
_cpp_backup_tokens (pfile, 1);
|
||||
if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed))
|
||||
cpp_pedwarn (pfile, "# followed by integer");
|
||||
}
|
||||
dir = &dtable[T_LINE];
|
||||
pfile->state.line_extension = 1;
|
||||
}
|
||||
|
||||
pfile->directive = dir;
|
||||
if (dir)
|
||||
{
|
||||
/* Make sure we lex headers correctly, whether skipping or not. */
|
||||
pfile->state.angled_headers = dir->flags & INCL;
|
||||
/* If we have a directive that is not an opening conditional,
|
||||
invalidate any control macro. */
|
||||
if (! (dir->flags & IF_COND))
|
||||
pfile->mi_valid = false;
|
||||
|
||||
/* If we are rescanning preprocessed input, only directives tagged
|
||||
with IN_I are honored, and the warnings below are suppressed. */
|
||||
if (CPP_OPTION (pfile, preprocessed))
|
||||
/* Kluge alert. In order to be sure that code like this
|
||||
|
||||
#define HASH #
|
||||
HASH define foo bar
|
||||
|
||||
does not cause '#define foo bar' to get executed when
|
||||
compiled with -save-temps, we recognize directives in
|
||||
-fpreprocessed mode only if the # is in column 1. cppmacro.c
|
||||
puts a space in fron of any '#' at the start of a macro. */
|
||||
if (CPP_OPTION (pfile, preprocessed)
|
||||
&& (indented || !(dir->flags & IN_I)))
|
||||
{
|
||||
/* Kluge alert. In order to be sure that code like this
|
||||
#define HASH #
|
||||
HASH define foo bar
|
||||
does not cause '#define foo bar' to get executed when
|
||||
compiled with -save-temps, we recognize directives in
|
||||
-fpreprocessed mode only if the # is in column 1 and the
|
||||
directive name starts in column 2. This output can only
|
||||
be generated by the directive callbacks in cppmain.c (see
|
||||
also the special case in scan_buffer). */
|
||||
if (dir->flags & IN_I && !indented && !(dname.flags & PREV_WHITE))
|
||||
(*dir->handler) (pfile);
|
||||
/* That check misses '# 123' linemarkers. Let them through too. */
|
||||
else if (dname.type == CPP_NUMBER)
|
||||
(*dir->handler) (pfile);
|
||||
else
|
||||
{
|
||||
/* We don't want to process this directive. Put back the
|
||||
tokens so caller will see them (and issue an error,
|
||||
probably). */
|
||||
_cpp_backup_tokens (pfile, 1);
|
||||
skip = 0;
|
||||
}
|
||||
skip = 0;
|
||||
dir = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Traditionally, a directive is ignored unless its # is in
|
||||
column 1. Therefore in code intended to work with K+R
|
||||
compilers, directives added by C89 must have their #
|
||||
indented, and directives present in traditional C must
|
||||
not. This is true even of directives in skipped
|
||||
conditional blocks. */
|
||||
if (CPP_WTRADITIONAL (pfile))
|
||||
{
|
||||
if (dir == &dtable[T_ELIF])
|
||||
cpp_warning (pfile,
|
||||
"suggest not using #elif in traditional C");
|
||||
else if (indented && dir->origin == KANDR)
|
||||
cpp_warning (pfile,
|
||||
"traditional C ignores #%s with the # indented",
|
||||
dir->name);
|
||||
else if (!indented && dir->origin != KANDR)
|
||||
cpp_warning (pfile,
|
||||
"suggest hiding #%s from traditional C with an indented #",
|
||||
dir->name);
|
||||
}
|
||||
|
||||
/* If we are skipping a failed conditional group, all
|
||||
non-conditional directives are ignored. */
|
||||
if (! pfile->state.skipping || (dir->flags & COND))
|
||||
{
|
||||
/* Issue -pedantic warnings for extensions. */
|
||||
if (CPP_PEDANTIC (pfile) && dir->origin == EXTENSION)
|
||||
cpp_pedwarn (pfile, "#%s is a GCC extension", dir->name);
|
||||
|
||||
/* If we have a directive that is not an opening
|
||||
conditional, invalidate any control macro. */
|
||||
if (! (dir->flags & IF_COND))
|
||||
pfile->mi_valid = false;
|
||||
|
||||
(*dir->handler) (pfile);
|
||||
}
|
||||
/* In failed conditional groups, all non-conditional
|
||||
directives are ignored. Before doing that, whether
|
||||
skipping or not, we should lex angle-bracketed headers
|
||||
correctly, and maybe output some diagnostics. */
|
||||
pfile->state.angled_headers = dir->flags & INCL;
|
||||
if (! CPP_OPTION (pfile, preprocessed))
|
||||
directive_diagnostics (pfile, dir, indented);
|
||||
if (pfile->state.skipping && !(dir->flags & COND))
|
||||
dir = 0;
|
||||
}
|
||||
}
|
||||
else if (dname.type != CPP_EOF && ! pfile->state.skipping)
|
||||
else if (dname.type == CPP_EOF)
|
||||
; /* CPP_EOF is the "null directive". */
|
||||
else
|
||||
{
|
||||
/* An unknown directive. Don't complain about it in assembly
|
||||
source: we don't know where the comments are, and # may
|
||||
introduce assembler pseudo-ops. Don't complain about invalid
|
||||
directives in skipped conditional groups (6.10 p4). */
|
||||
if (CPP_OPTION (pfile, lang) == CLK_ASM)
|
||||
{
|
||||
/* Output the # and this token for the assembler. */
|
||||
_cpp_backup_tokens (pfile, 1);
|
||||
skip = 0;
|
||||
}
|
||||
else
|
||||
skip = 0;
|
||||
else if (!pfile->state.skipping)
|
||||
cpp_error (pfile, "invalid preprocessing directive #%s",
|
||||
cpp_token_as_text (pfile, &dname));
|
||||
}
|
||||
|
||||
if (pfile->state.in_directive)
|
||||
end_directive (pfile, skip);
|
||||
if (dir)
|
||||
{
|
||||
pfile->directive = dir;
|
||||
(*pfile->directive->handler) (pfile);
|
||||
}
|
||||
else if (skip == 0)
|
||||
_cpp_backup_tokens (pfile, 1);
|
||||
|
||||
end_directive (pfile, skip);
|
||||
return skip;
|
||||
}
|
||||
|
||||
|
@ -394,11 +400,10 @@ run_directive (pfile, dir_no, buf, count)
|
|||
cpp_push_buffer (pfile, (const U_CHAR *) buf, count,
|
||||
/* from_stage3 */ true, 1);
|
||||
start_directive (pfile);
|
||||
pfile->buffer->saved_flags = 0; /* We don't want to recognise directives. */
|
||||
pfile->state.prevent_expansion++;
|
||||
/* We don't want a leading # to be interpreted as a directive. */
|
||||
pfile->buffer->saved_flags = 0;
|
||||
pfile->directive = &dtable[dir_no];
|
||||
(void) (*pfile->directive->handler) (pfile);
|
||||
pfile->state.prevent_expansion--;
|
||||
end_directive (pfile, 1);
|
||||
_cpp_pop_buffer (pfile);
|
||||
}
|
||||
|
@ -708,6 +713,11 @@ do_line (pfile)
|
|||
/* C99 raised the minimum limit on #line numbers. */
|
||||
cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
|
||||
|
||||
/* Putting this in _cpp_handle_directive risks two calls to
|
||||
_cpp_backup_tokens in some circumstances, which can segfault. */
|
||||
if (pfile->state.line_extension)
|
||||
_cpp_backup_tokens (pfile, 1);
|
||||
|
||||
/* #line commands expand macros. */
|
||||
cpp_get_token (pfile, &token);
|
||||
if (token.type != CPP_NUMBER
|
||||
|
|
|
@ -41,7 +41,6 @@ typedef struct cpp_token cpp_token;
|
|||
typedef struct cpp_string cpp_string;
|
||||
typedef struct cpp_hashnode cpp_hashnode;
|
||||
typedef struct cpp_macro cpp_macro;
|
||||
typedef struct cpp_lexer_pos cpp_lexer_pos;
|
||||
typedef struct cpp_callbacks cpp_callbacks;
|
||||
|
||||
struct answer;
|
||||
|
@ -186,13 +185,6 @@ struct cpp_token
|
|||
} val;
|
||||
};
|
||||
|
||||
/* The position of a token in the current file. */
|
||||
struct cpp_lexer_pos
|
||||
{
|
||||
unsigned int line;
|
||||
unsigned short col;
|
||||
};
|
||||
|
||||
/* A standalone character. We may want to make it unsigned for the
|
||||
same reason we use unsigned char - to avoid signedness issues. */
|
||||
typedef int cppchar_t;
|
||||
|
|
|
@ -1321,8 +1321,12 @@ _cpp_create_definition (pfile, node)
|
|||
/* Don't count the CPP_EOF. */
|
||||
macro->count--;
|
||||
|
||||
/* Clear the whitespace flag from the leading token. */
|
||||
macro->expansion[0].flags &= ~PREV_WHITE;
|
||||
/* Clear the whitespace flag from the leading token, but put a space
|
||||
in front of a leading # which might be used to fake a directive. */
|
||||
if (macro->expansion[0].type == CPP_HASH)
|
||||
macro->expansion[0].flags |= PREV_WHITE;
|
||||
else
|
||||
macro->expansion[0].flags &= ~PREV_WHITE;
|
||||
|
||||
/* Implement the macro-defined-to-itself optimisation. */
|
||||
macro->disabled = (macro->count == 1 && !macro->fun_like
|
||||
|
|
|
@ -233,13 +233,6 @@ scan_translation_unit (pfile)
|
|||
if ((token->flags & (PREV_WHITE | AVOID_LPASTE | BOL)) == AVOID_LPASTE
|
||||
&& cpp_avoid_paste (pfile, &tokens[1 - index], token))
|
||||
token->flags |= PREV_WHITE;
|
||||
/* Special case '# <directive name>': insert a space between
|
||||
the # and the token. This will prevent it from being
|
||||
treated as a directive when this code is re-preprocessed.
|
||||
XXX Should do this only at the beginning of a line, but how? */
|
||||
else if (token->type == CPP_NAME && token->val.node->directive_index
|
||||
&& tokens[1 - index].type == CPP_HASH)
|
||||
token->flags |= PREV_WHITE;
|
||||
|
||||
cpp_output_token (token, print.outf);
|
||||
if (token->type == CPP_STRING || token->type == CPP_WSTRING
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2001-09-16 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* gcc.dg/cpp/line5.c: New testcase.
|
||||
|
||||
2001-09-15 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* gcc.dg/cpp/macro9.c: New test.
|
||||
|
|
15
gcc/testsuite/gcc.dg/cpp/line5.c
Normal file
15
gcc/testsuite/gcc.dg/cpp/line5.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* Copyright (C) 2001 Free Software Foundation, Inc. */
|
||||
|
||||
/* { dg-do preprocess } */
|
||||
/* { dg-options "-fpreprocessed" } */
|
||||
|
||||
/* Source: Neil Booth, 16 Sep 2001.
|
||||
|
||||
This file, with an indented line marker, is not possible without
|
||||
user editing of preprocessed output, or the user using
|
||||
-fpreprocessed on raw source. Nevertheless, we should not
|
||||
segfault. This is a test that we don't back up two tokens in
|
||||
cpplib.c - one to back up over the number, and one when we
|
||||
recognise that it's not a valid directive in preprocessed input. */
|
||||
|
||||
# 1 "foo.c"
|
Loading…
Add table
Reference in a new issue