Commit 18a9d8ff by Neil Booth Committed by Neil Booth

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
parent 27553bf3
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> 2001-09-15 Richard Henderson <rth@redhat.com>
* c-typeck.c (comptypes): Handle zero-length arrays properly. * c-typeck.c (comptypes): Handle zero-length arrays properly.
......
...@@ -82,6 +82,8 @@ static void skip_rest_of_line PARAMS ((cpp_reader *)); ...@@ -82,6 +82,8 @@ static void skip_rest_of_line PARAMS ((cpp_reader *));
static void check_eol PARAMS ((cpp_reader *)); static void check_eol PARAMS ((cpp_reader *));
static void start_directive PARAMS ((cpp_reader *)); static void start_directive PARAMS ((cpp_reader *));
static void end_directive PARAMS ((cpp_reader *, int)); 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, static void run_directive PARAMS ((cpp_reader *, int,
const char *, size_t)); const char *, size_t));
static int glue_header_name PARAMS ((cpp_reader *, cpp_token *)); static int glue_header_name PARAMS ((cpp_reader *, cpp_token *));
...@@ -248,8 +250,57 @@ end_directive (pfile, skip_line) ...@@ -248,8 +250,57 @@ end_directive (pfile, skip_line)
pfile->directive = 0; pfile->directive = 0;
} }
/* Check if a token's name matches that of a known directive. Put in /* Output diagnostics for a directive DIR. INDENTED is non-zero if
this file to save exporting dtable and other unneeded information. */ 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 int
_cpp_handle_directive (pfile, indented) _cpp_handle_directive (pfile, indented)
cpp_reader *pfile; cpp_reader *pfile;
...@@ -260,124 +311,79 @@ _cpp_handle_directive (pfile, indented) ...@@ -260,124 +311,79 @@ _cpp_handle_directive (pfile, indented)
int skip = 1; int skip = 1;
start_directive (pfile); start_directive (pfile);
/* Lex the directive name directly. */
_cpp_lex_token (pfile, &dname); _cpp_lex_token (pfile, &dname);
if (dname.type == CPP_NAME) if (dname.type == CPP_NAME)
{ {
unsigned int index = dname.val.node->directive_index; if (dname.val.node->directive_index)
if (index) dir = &dtable[dname.val.node->directive_index - 1];
dir = &dtable[index - 1];
} }
else if (dname.type == CPP_NUMBER) /* We do not recognise the # followed by a number extension in
{ assembler code. */
/* # followed by a number is equivalent to #line. Do not else if (dname.type == CPP_NUMBER && CPP_OPTION (pfile, lang) != CLK_ASM)
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]; dir = &dtable[T_LINE];
pfile->state.line_extension = 1; pfile->state.line_extension = 1;
_cpp_backup_tokens (pfile, 1);
if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed))
cpp_pedwarn (pfile, "# followed by integer");
}
} }
pfile->directive = dir;
if (dir) if (dir)
{ {
/* Make sure we lex headers correctly, whether skipping or not. */ /* If we have a directive that is not an opening conditional,
pfile->state.angled_headers = dir->flags & INCL; 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 /* Kluge alert. In order to be sure that code like this
#define HASH # #define HASH #
HASH define foo bar HASH define foo bar
does not cause '#define foo bar' to get executed when does not cause '#define foo bar' to get executed when
compiled with -save-temps, we recognize directives in compiled with -save-temps, we recognize directives in
-fpreprocessed mode only if the # is in column 1 and the -fpreprocessed mode only if the # is in column 1. cppmacro.c
directive name starts in column 2. This output can only puts a space in fron of any '#' at the start of a macro. */
be generated by the directive callbacks in cppmain.c (see if (CPP_OPTION (pfile, preprocessed)
also the special case in scan_buffer). */ && (indented || !(dir->flags & IN_I)))
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 else
{ {
/* Traditionally, a directive is ignored unless its # is in /* In failed conditional groups, all non-conditional
column 1. Therefore in code intended to work with K+R directives are ignored. Before doing that, whether
compilers, directives added by C89 must have their # skipping or not, we should lex angle-bracketed headers
indented, and directives present in traditional C must correctly, and maybe output some diagnostics. */
not. This is true even of directives in skipped pfile->state.angled_headers = dir->flags & INCL;
conditional blocks. */ if (! CPP_OPTION (pfile, preprocessed))
if (CPP_WTRADITIONAL (pfile)) directive_diagnostics (pfile, dir, indented);
{ if (pfile->state.skipping && !(dir->flags & COND))
if (dir == &dtable[T_ELIF]) dir = 0;
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);
}
} }
} }
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 /* An unknown directive. Don't complain about it in assembly
source: we don't know where the comments are, and # may source: we don't know where the comments are, and # may
introduce assembler pseudo-ops. Don't complain about invalid introduce assembler pseudo-ops. Don't complain about invalid
directives in skipped conditional groups (6.10 p4). */ directives in skipped conditional groups (6.10 p4). */
if (CPP_OPTION (pfile, lang) == CLK_ASM) if (CPP_OPTION (pfile, lang) == CLK_ASM)
{
/* Output the # and this token for the assembler. */
_cpp_backup_tokens (pfile, 1);
skip = 0; skip = 0;
} else if (!pfile->state.skipping)
else
cpp_error (pfile, "invalid preprocessing directive #%s", cpp_error (pfile, "invalid preprocessing directive #%s",
cpp_token_as_text (pfile, &dname)); cpp_token_as_text (pfile, &dname));
} }
if (pfile->state.in_directive) if (dir)
{
pfile->directive = dir;
(*pfile->directive->handler) (pfile);
}
else if (skip == 0)
_cpp_backup_tokens (pfile, 1);
end_directive (pfile, skip); end_directive (pfile, skip);
return skip; return skip;
} }
...@@ -394,11 +400,10 @@ run_directive (pfile, dir_no, buf, count) ...@@ -394,11 +400,10 @@ run_directive (pfile, dir_no, buf, count)
cpp_push_buffer (pfile, (const U_CHAR *) buf, count, cpp_push_buffer (pfile, (const U_CHAR *) buf, count,
/* from_stage3 */ true, 1); /* from_stage3 */ true, 1);
start_directive (pfile); start_directive (pfile);
pfile->buffer->saved_flags = 0; /* We don't want to recognise directives. */ /* We don't want a leading # to be interpreted as a directive. */
pfile->state.prevent_expansion++; pfile->buffer->saved_flags = 0;
pfile->directive = &dtable[dir_no]; pfile->directive = &dtable[dir_no];
(void) (*pfile->directive->handler) (pfile); (void) (*pfile->directive->handler) (pfile);
pfile->state.prevent_expansion--;
end_directive (pfile, 1); end_directive (pfile, 1);
_cpp_pop_buffer (pfile); _cpp_pop_buffer (pfile);
} }
...@@ -708,6 +713,11 @@ do_line (pfile) ...@@ -708,6 +713,11 @@ do_line (pfile)
/* C99 raised the minimum limit on #line numbers. */ /* C99 raised the minimum limit on #line numbers. */
cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767; 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. */ /* #line commands expand macros. */
cpp_get_token (pfile, &token); cpp_get_token (pfile, &token);
if (token.type != CPP_NUMBER if (token.type != CPP_NUMBER
......
...@@ -41,7 +41,6 @@ typedef struct cpp_token cpp_token; ...@@ -41,7 +41,6 @@ typedef struct cpp_token cpp_token;
typedef struct cpp_string cpp_string; typedef struct cpp_string cpp_string;
typedef struct cpp_hashnode cpp_hashnode; typedef struct cpp_hashnode cpp_hashnode;
typedef struct cpp_macro cpp_macro; typedef struct cpp_macro cpp_macro;
typedef struct cpp_lexer_pos cpp_lexer_pos;
typedef struct cpp_callbacks cpp_callbacks; typedef struct cpp_callbacks cpp_callbacks;
struct answer; struct answer;
...@@ -186,13 +185,6 @@ struct cpp_token ...@@ -186,13 +185,6 @@ struct cpp_token
} val; } 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 /* A standalone character. We may want to make it unsigned for the
same reason we use unsigned char - to avoid signedness issues. */ same reason we use unsigned char - to avoid signedness issues. */
typedef int cppchar_t; typedef int cppchar_t;
......
...@@ -1321,7 +1321,11 @@ _cpp_create_definition (pfile, node) ...@@ -1321,7 +1321,11 @@ _cpp_create_definition (pfile, node)
/* Don't count the CPP_EOF. */ /* Don't count the CPP_EOF. */
macro->count--; macro->count--;
/* Clear the whitespace flag from the leading token. */ /* 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; macro->expansion[0].flags &= ~PREV_WHITE;
/* Implement the macro-defined-to-itself optimisation. */ /* Implement the macro-defined-to-itself optimisation. */
......
...@@ -233,13 +233,6 @@ scan_translation_unit (pfile) ...@@ -233,13 +233,6 @@ scan_translation_unit (pfile)
if ((token->flags & (PREV_WHITE | AVOID_LPASTE | BOL)) == AVOID_LPASTE if ((token->flags & (PREV_WHITE | AVOID_LPASTE | BOL)) == AVOID_LPASTE
&& cpp_avoid_paste (pfile, &tokens[1 - index], token)) && cpp_avoid_paste (pfile, &tokens[1 - index], token))
token->flags |= PREV_WHITE; 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); cpp_output_token (token, print.outf);
if (token->type == CPP_STRING || token->type == CPP_WSTRING if (token->type == CPP_STRING || token->type == CPP_WSTRING
......
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> 2001-09-15 Neil Booth <neil@daikokuya.demon.co.uk>
* gcc.dg/cpp/macro9.c: New test. * gcc.dg/cpp/macro9.c: New test.
......
/* 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"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment