Commit fe6c2db9 by Neil Booth Committed by Neil Booth

cpplib.c (start_directive, [...]): New functions.

        * cpplib.c (start_directive, end_directive): New functions.
        (_cpp_handle_directive, run_directive): Use them.
        (_cpp_handle_directive): Don't -Wtraditional on indented
        null directives.
        (_cpp_push_buffer): Don't re-clear was_skipping.
        * cpplib.h (struct cpp_reader): New member la_saved.
        * cppmacro.c (cpp_get_token): Don't interpret _Pragma in
        directives.

From-SVN: r37487
parent cbc2c182
2000-11-15 Neil Booth <neilb@earthling.net>
* cpplib.c (start_directive, end_directive): New functions.
(_cpp_handle_directive, run_directive): Use them.
(_cpp_handle_directive): Don't -Wtraditional on indented
null directives.
(_cpp_push_buffer): Don't re-clear was_skipping.
* cpplib.h (struct cpp_reader): New member la_saved.
* cppmacro.c (cpp_get_token): Don't interpret _Pragma in
directives.
gcc.dg/cpp/_Pragma1.c: Update.
gcc.dg/cpp/_Pragma2.c: New test.
2000-11-15 Mark Mitchell <mark@codesourcery.com> 2000-11-15 Mark Mitchell <mark@codesourcery.com>
* toplev.c (wrapup_global_declarations): Don't write out * toplev.c (wrapup_global_declarations): Don't write out
......
...@@ -81,6 +81,8 @@ struct directive ...@@ -81,6 +81,8 @@ struct directive
static void skip_rest_of_line PARAMS ((cpp_reader *)); 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 end_directive PARAMS ((cpp_reader *, 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,
const char *)); const char *));
...@@ -214,18 +216,12 @@ check_eol (pfile) ...@@ -214,18 +216,12 @@ check_eol (pfile)
} }
} }
/* Check if a token's name matches that of a known directive. Put in /* Called when entering a directive, _Pragma or command-line directive. */
this file to save exporting dtable and other unneeded information. */ static void
int start_directive (pfile)
_cpp_handle_directive (pfile, indented)
cpp_reader *pfile; cpp_reader *pfile;
int indented;
{ {
struct cpp_lookahead *la_saved;
cpp_buffer *buffer = pfile->buffer; cpp_buffer *buffer = pfile->buffer;
const directive *dir = 0;
cpp_token dname;
int not_asm = 1;
/* Setup in-directive state. */ /* Setup in-directive state. */
pfile->state.in_directive = 1; pfile->state.in_directive = 1;
...@@ -235,9 +231,52 @@ _cpp_handle_directive (pfile, indented) ...@@ -235,9 +231,52 @@ _cpp_handle_directive (pfile, indented)
pfile->directive_pos = pfile->lexer_pos; pfile->directive_pos = pfile->lexer_pos;
/* Don't save directive tokens for external clients. */ /* Don't save directive tokens for external clients. */
la_saved = pfile->la_write; pfile->la_saved = pfile->la_write;
pfile->la_write = 0; pfile->la_write = 0;
/* Turn off skipping. */
buffer->was_skipping = pfile->skipping;
pfile->skipping = 0;
}
/* Called when leaving a directive, _Pragma or command-line directive. */
static void
end_directive (pfile, skip_line)
cpp_reader *pfile;
int skip_line;
{
cpp_buffer *buffer = pfile->buffer;
/* Restore pfile->skipping before skip_rest_of_line. This avoids
warning about poisoned identifiers in skipped #error lines. */
pfile->skipping = buffer->was_skipping;
/* We don't skip for an assembler #. */
if (skip_line)
skip_rest_of_line (pfile);
/* Restore state. */
pfile->la_write = pfile->la_saved;
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
pfile->state.in_directive = 0;
pfile->state.angled_headers = 0;
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. */
int
_cpp_handle_directive (pfile, indented)
cpp_reader *pfile;
int indented;
{
cpp_buffer *buffer = pfile->buffer;
const directive *dir = 0;
cpp_token dname;
int skip = 1;
start_directive (pfile);
/* Lex the directive name directly. */ /* Lex the directive name directly. */
_cpp_lex_token (pfile, &dname); _cpp_lex_token (pfile, &dname);
...@@ -254,7 +293,7 @@ _cpp_handle_directive (pfile, indented) ...@@ -254,7 +293,7 @@ _cpp_handle_directive (pfile, indented)
skipped conditional groups. Complain about this form if skipped conditional groups. Complain about this form if
we're being pedantic, but not if this is regurgitated input we're being pedantic, but not if this is regurgitated input
(preprocessed or fed back in by the C++ frontend). */ (preprocessed or fed back in by the C++ frontend). */
if (! pfile->skipping && !CPP_OPTION (pfile, lang_asm)) if (! buffer->was_skipping && !CPP_OPTION (pfile, lang_asm))
{ {
dir = &dtable[T_LINE]; dir = &dtable[T_LINE];
_cpp_push_token (pfile, &dname, &pfile->directive_pos); _cpp_push_token (pfile, &dname, &pfile->directive_pos);
...@@ -294,7 +333,7 @@ _cpp_handle_directive (pfile, indented) ...@@ -294,7 +333,7 @@ _cpp_handle_directive (pfile, indented)
/* If we are skipping a failed conditional group, all /* If we are skipping a failed conditional group, all
non-conditional directives are ignored. */ non-conditional directives are ignored. */
if (! pfile->skipping || (dir->flags & COND)) if (! buffer->was_skipping || (dir->flags & COND))
{ {
/* Issue -pedantic warnings for extensions. */ /* Issue -pedantic warnings for extensions. */
if (CPP_PEDANTIC (pfile) && dir->origin == EXTENSION) if (CPP_PEDANTIC (pfile) && dir->origin == EXTENSION)
...@@ -305,20 +344,11 @@ _cpp_handle_directive (pfile, indented) ...@@ -305,20 +344,11 @@ _cpp_handle_directive (pfile, indented)
if (! (dir->flags & IF_COND)) if (! (dir->flags & IF_COND))
pfile->mi_state = MI_FAILED; pfile->mi_state = MI_FAILED;
buffer->was_skipping = pfile->skipping;
pfile->skipping = 0;
(*dir->handler) (pfile); (*dir->handler) (pfile);
pfile->skipping = buffer->was_skipping;
} }
} }
} }
else if (dname.type == CPP_EOF) else if (dname.type != CPP_EOF && ! pfile->skipping)
{
/* The null directive. */
if (indented && CPP_WTRADITIONAL (pfile))
cpp_warning (pfile, "traditional C ignores #\\n with the # indented");
}
else if (!pfile->skipping)
{ {
/* 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
...@@ -327,26 +357,16 @@ _cpp_handle_directive (pfile, indented) ...@@ -327,26 +357,16 @@ _cpp_handle_directive (pfile, indented)
if (CPP_OPTION (pfile, lang_asm)) if (CPP_OPTION (pfile, lang_asm))
{ {
/* Output the # and lookahead token for the assembler. */ /* Output the # and lookahead token for the assembler. */
not_asm = 0;
_cpp_push_token (pfile, &dname, &pfile->directive_pos); _cpp_push_token (pfile, &dname, &pfile->directive_pos);
skip = 0;
} }
else 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));
} }
/* Save the lookahead token for assembler. */ end_directive (pfile, skip);
if (not_asm) return skip;
skip_rest_of_line (pfile);
/* Restore state. */
pfile->la_write = la_saved;
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
pfile->state.in_directive = 0;
pfile->state.angled_headers = 0;
pfile->directive = 0;
return not_asm;
} }
/* Directive handler wrapper used by the command line option /* Directive handler wrapper used by the command line option
...@@ -360,41 +380,37 @@ run_directive (pfile, dir_no, buf, count, name) ...@@ -360,41 +380,37 @@ run_directive (pfile, dir_no, buf, count, name)
const char *name; const char *name;
{ {
unsigned int output_line = pfile->lexer_pos.output_line; unsigned int output_line = pfile->lexer_pos.output_line;
cpp_buffer *buffer = cpp_push_buffer (pfile, (const U_CHAR *) buf, count);
if (cpp_push_buffer (pfile, (const U_CHAR *) buf, count) != NULL) if (buffer)
{ {
const struct directive *dir = &dtable[dir_no], *orig_dir; const struct directive *dir = &dtable[dir_no];
unsigned char orig_in_directive;
if (name) if (name)
CPP_BUFFER (pfile)->nominal_fname = name; buffer->nominal_fname = name;
else else
CPP_BUFFER (pfile)->nominal_fname = _("<command line>"); buffer->nominal_fname = _("<command line>");
/* A kludge to avoid line markers for _Pragma. */
if (dir_no == T_PRAGMA)
pfile->lexer_pos.output_line = output_line;
/* Save any in-process directive; _Pragma can appear in one. */
orig_dir = pfile->directive;
orig_in_directive = pfile->state.in_directive;
/* For _Pragma, the text is passed through preprocessing stage 3 /* For _Pragma, the text is passed through preprocessing stage 3
only, i.e. no trigraphs, no escaped newline removal, and no only, i.e. no trigraphs, no escaped newline removal, and no
macro expansion. Do the same for command-line directives. */ macro expansion. Do the same for command-line directives. */
pfile->buffer->from_stage3 = 1; buffer->from_stage3 = 1;
pfile->state.in_directive = 1;
pfile->directive = dir; if (dir_no == T_PRAGMA)
{
/* A kludge to avoid line markers for _Pragma. */
pfile->lexer_pos.output_line = output_line;
/* Avoid interpretation of directives in a _Pragma string. */
pfile->state.next_bol = 0;
}
start_directive (pfile);
pfile->state.prevent_expansion++; pfile->state.prevent_expansion++;
(void) (*dir->handler) (pfile); (void) (*dir->handler) (pfile);
pfile->state.prevent_expansion--; pfile->state.prevent_expansion--;
pfile->directive = orig_dir; check_eol (pfile);
pfile->state.in_directive = orig_in_directive; end_directive (pfile, 1);
skip_rest_of_line (pfile);
if (pfile->buffer->cur != pfile->buffer->rlimit)
cpp_error (pfile, "extra text after end of #%s directive",
dtable[dir_no].name);
cpp_pop_buffer (pfile); cpp_pop_buffer (pfile);
} }
} }
...@@ -1713,7 +1729,6 @@ cpp_push_buffer (pfile, buffer, length) ...@@ -1713,7 +1729,6 @@ cpp_push_buffer (pfile, buffer, length)
new->rlimit = buffer + length; new->rlimit = buffer + length;
new->prev = buf; new->prev = buf;
new->pfile = pfile; new->pfile = pfile;
new->was_skipping = 0;
/* Preprocessed files don't do trigraph and escaped newline processing. */ /* Preprocessed files don't do trigraph and escaped newline processing. */
new->from_stage3 = CPP_OPTION (pfile, preprocessed); new->from_stage3 = CPP_OPTION (pfile, preprocessed);
/* No read ahead or extra char initially. */ /* No read ahead or extra char initially. */
......
...@@ -562,6 +562,7 @@ struct cpp_reader ...@@ -562,6 +562,7 @@ struct cpp_reader
struct cpp_lookahead *la_read; /* Read from this lookahead. */ struct cpp_lookahead *la_read; /* Read from this lookahead. */
struct cpp_lookahead *la_write; /* Write to this lookahead. */ struct cpp_lookahead *la_write; /* Write to this lookahead. */
struct cpp_lookahead *la_unused; /* Free store. */ struct cpp_lookahead *la_unused; /* Free store. */
struct cpp_lookahead *la_saved; /* Backup when entering directive. */
/* Error counter for exit code. */ /* Error counter for exit code. */
unsigned int errors; unsigned int errors;
......
...@@ -959,7 +959,10 @@ cpp_get_token (pfile, token) ...@@ -959,7 +959,10 @@ cpp_get_token (pfile, token)
continue; continue;
} }
if (token->val.node != pfile->spec_nodes.n__Pragma) /* Don't interpret _Pragma within directives. The standard is
not clear on this, but to me this makes most sense. */
if (token->val.node != pfile->spec_nodes.n__Pragma
|| pfile->state.in_directive)
break; break;
/* Handle it, and loop back for another token. MI is cleared /* Handle it, and loop back for another token. MI is cleared
......
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