summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/cpphash.h1
-rw-r--r--gcc/cpplib.c17
-rw-r--r--gcc/cppmain.c19
-rw-r--r--gcc/cpptrad.c116
5 files changed, 105 insertions, 66 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7c08d424ea8..d5270c8fbf7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+2002-06-13 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cpphash.h (_cpp_lex_identifier_trad): Remove.
+ * cpplib.c (end_directive): Don't skip, always remove overlay
+ apart from #define.
+ (prepare_directive_trad): Handle NULL pfile->directive.
+ (_cpp_handle_directive): Always call prepare_directive_trad
+ if traditional.
+ * cppmain.c (check_multiline_token): Rename account_for_newlines,
+ generalize inputs.
+ (scan_translation_unit_trad): Use it.
+ * cpptrad.c (skip_comment): Rename copy_comment, copy comment to
+ output, get escaped newline in comment close correct.
+ (check_output_buffer, skip_whitespace): Update.
+ (_cpp_lex_identifier_trad): Remove.
+ (scan_out_logical_line): Handle -C and comments in directives
+ properly.
+
Thu Jun 13 20:18:38 2002 J"orn Rennecke <joern.rennecke@superh.com>
* config.gcc: Add support for sh[234]*-*-elf*, sh[2346lbe]*-*-linux*.
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index ae6a4f2301d..24b5ef7fccc 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -522,7 +522,6 @@ extern bool _cpp_read_logical_line_trad PARAMS ((cpp_reader *));
extern void _cpp_overlay_buffer PARAMS ((cpp_reader *pfile, const uchar *,
size_t));
extern void _cpp_remove_overlay PARAMS ((cpp_reader *));
-extern cpp_hashnode *_cpp_lex_identifier_trad PARAMS ((cpp_reader *));
extern void _cpp_set_trad_context PARAMS ((cpp_reader *));
extern bool _cpp_create_trad_definition PARAMS ((cpp_reader *, cpp_macro *));
extern bool _cpp_expansions_different_trad PARAMS ((const cpp_macro *,
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index acc71e7120a..aecfbaf0edd 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -256,14 +256,11 @@ end_directive (pfile, skip_line)
{
if (CPP_OPTION (pfile, traditional))
{
- if (!pfile->directive || pfile->directive == &dtable[T_DEFINE])
- skip_line = false;
- else
+ if (pfile->directive != &dtable[T_DEFINE])
_cpp_remove_overlay (pfile);
}
-
/* We don't skip for an assembler #. */
- if (skip_line)
+ else if (skip_line)
{
skip_rest_of_line (pfile);
if (!pfile->keep_tokens)
@@ -289,7 +286,8 @@ prepare_directive_trad (pfile)
CUR (pfile->context) = pfile->buffer->cur;
else
{
- bool no_expand = ! (pfile->directive->flags & EXPAND);
+ bool no_expand = (pfile->directive
+ && ! (pfile->directive->flags & EXPAND));
bool was_skipping = pfile->state.skipping;
pfile->state.skipping = false;
@@ -382,6 +380,10 @@ _cpp_handle_directive (pfile, indented)
"style of line directive is a GCC extension");
}
+ pfile->directive = dir;
+ if (CPP_OPTION (pfile, traditional))
+ prepare_directive_trad (pfile);
+
if (dir)
{
/* If we have a directive that is not an opening conditional,
@@ -441,9 +443,6 @@ _cpp_handle_directive (pfile, indented)
pfile->state.save_comments =
! CPP_OPTION (pfile, discard_comments_in_macro_exp);
- pfile->directive = dir;
- if (CPP_OPTION (pfile, traditional))
- prepare_directive_trad (pfile);
(*pfile->directive->handler) (pfile);
}
else if (skip == 0)
diff --git a/gcc/cppmain.c b/gcc/cppmain.c
index 0edc3d2b25b..7ebc1ad2c5a 100644
--- a/gcc/cppmain.c
+++ b/gcc/cppmain.c
@@ -43,7 +43,7 @@ static void setup_callbacks PARAMS ((cpp_reader *));
/* General output routines. */
static void scan_translation_unit PARAMS ((cpp_reader *));
static void scan_translation_unit_trad PARAMS ((cpp_reader *));
-static void check_multiline_token PARAMS ((const cpp_string *));
+static void account_for_newlines PARAMS ((const uchar *, size_t));
static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
static void print_line PARAMS ((const struct line_map *, unsigned int,
@@ -208,19 +208,18 @@ scan_translation_unit (pfile)
cpp_output_token (token, print.outf);
if (token->type == CPP_COMMENT)
- check_multiline_token (&token->val.str);
+ account_for_newlines (token->val.str.text, token->val.str.len);
}
}
-/* Adjust print.line for newlines embedded in tokens. */
+/* Adjust print.line for newlines embedded in output. */
static void
-check_multiline_token (str)
- const cpp_string *str;
+account_for_newlines (str, len)
+ const uchar *str;
+ size_t len;
{
- unsigned int i;
-
- for (i = 0; i < str->len; i++)
- if (str->text[i] == '\n')
+ while (len--)
+ if (*str++ == '\n')
print.line++;
}
@@ -239,6 +238,8 @@ scan_translation_unit_trad (pfile)
maybe_print_line (print.map, pfile->out.first_line);
fwrite (pfile->out.base, 1, len, print.outf);
print.printed = 1;
+ if (!CPP_OPTION (pfile, discard_comments))
+ account_for_newlines (pfile->out.base, len);
}
}
diff --git a/gcc/cpptrad.c b/gcc/cpptrad.c
index 03ee0e893a6..4765be2273a 100644
--- a/gcc/cpptrad.c
+++ b/gcc/cpptrad.c
@@ -22,17 +22,13 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "cpphash.h"
/* The replacement text of a function-like macro is stored as a
- contiguous sequence of aligned blocks. Each block represents the
- portion of text from the start of the previous block (or the start
- of the macro replacement text in the case of the first block) to
- the next parameter, or the end of the replacement list if there
- are none left.
-
- Each block consists of an unsigned int, which is the length of text
- contained in the third part, an unsigned short, which is the
+ contiguous sequence of aligned blocks, each representing the text
+ between subsequent parameters in that text.
+
+ Each block comprises the length of text contained therein, the
one-based index of the argument that immediately follows that text,
and the text itself. The final block in the macro expansion is
- recognizable as it has an argument index of zero. */
+ easily recognizable as it has an argument index of zero. */
struct block
{
@@ -67,17 +63,16 @@ struct fun_macro
unsigned int argc;
};
-/* Lexing TODO: Handle -C, maybe -CC, and space in escaped newlines.
- Stop cpplex.c from recognizing comments and directives during its
- lexing pass. Get rid of line_base usage - seems pointless? Do we
- get escaped newline at EOF correct? */
+/* Lexing TODO: Maybe handle -CC and space in escaped newlines. Stop
+ cpplex.c from recognizing comments and directives during its lexing
+ pass. Get rid of line_base usage - seems pointless? */
static const uchar *handle_newline PARAMS ((cpp_reader *, const uchar *));
static const uchar *skip_escaped_newlines PARAMS ((cpp_reader *,
const uchar *));
static const uchar *skip_whitespace PARAMS ((cpp_reader *, const uchar *));
static cpp_hashnode *lex_identifier PARAMS ((cpp_reader *, const uchar *));
-static const uchar *skip_comment PARAMS ((cpp_reader *, const uchar *));
+static const uchar *copy_comment PARAMS ((cpp_reader *, const uchar *));
static void scan_out_logical_line PARAMS ((cpp_reader *pfile, cpp_macro *));
static void check_output_buffer PARAMS ((cpp_reader *, size_t));
static void push_replacement_text PARAMS ((cpp_reader *, cpp_hashnode *));
@@ -99,6 +94,10 @@ check_output_buffer (pfile, n)
cpp_reader *pfile;
size_t n;
{
+ /* We might need two bytes to terminate an unterminated comment, and
+ one more to terminate with a NUL. */
+ n += 2 + 1;
+
if (n > (size_t) (pfile->out.limit - pfile->out.cur))
{
size_t size = pfile->out.cur - pfile->out.base;
@@ -134,45 +133,70 @@ skip_escaped_newlines (pfile, cur)
cpp_reader *pfile;
const uchar *cur;
{
- while (*cur == '\\' && is_vspace (cur[1]))
- cur = handle_newline (pfile, cur + 1);
+ if (*cur == '\\' && is_vspace (cur[1]))
+ {
+ do
+ cur = handle_newline (pfile, cur + 1);
+ while (*cur == '\\' && is_vspace (cur[1]));
+
+ if (cur == RLIMIT (pfile->context))
+ cpp_error (pfile, DL_PEDWARN,
+ "backslash-newline at end of file");
+ }
return cur;
}
/* CUR points to the character after the asterisk introducing a
- comment. Returns the position after the comment. */
+ comment in the input buffer. The remaining comment is copied to
+ the buffer pointed to by pfile->out.cur, which must be of
+ sufficient size, and pfile->out.cur is updated. Unterminated
+ comments are diagnosed, and correctly terminated in the output.
+
+ Returns a pointer to the first character after the comment in the
+ input buffer. */
static const uchar *
-skip_comment (pfile, cur)
+copy_comment (pfile, cur)
cpp_reader *pfile;
const uchar *cur;
{
unsigned int from_line = pfile->line;
- unsigned int c = 0, prevc = 0;
const uchar *limit = RLIMIT (pfile->context);
+ uchar *out = pfile->out.cur;
while (cur < limit)
{
- prevc = c;
- c = *cur++;
+ unsigned int c = *cur++;
+ *out++ = c;
if (c == '/')
{
- if (prevc == '*')
- break;
+ /* An immediate slash does not terminate the comment. */
+ if (out[-2] == '*' && out > pfile->out.cur + 1)
+ goto done;
+
if (*cur == '*' && cur[1] != '/'
&& CPP_OPTION (pfile, warn_comments))
cpp_error_with_line (pfile, DL_WARNING, pfile->line, 0,
"\"/*\" within comment");
}
else if (is_vspace (c))
- cur = handle_newline (pfile, cur - 1);
+ {
+ cur = handle_newline (pfile, cur - 1);
+ /* Canonicalize newline sequences and skip escaped ones. */
+ if (out[-2] == '\\')
+ out -= 2;
+ else
+ out[-1] = '\n';
+ }
}
- if (c != '/' || prevc != '*')
- cpp_error_with_line (pfile, DL_ERROR, from_line, 0,
- "unterminated comment");
+ cpp_error_with_line (pfile, DL_ERROR, from_line, 0, "unterminated comment");
+ *out++ = '*';
+ *out++ = '/';
+ done:
+ pfile->out.cur = out;
return cur;
}
@@ -206,7 +230,7 @@ skip_whitespace (pfile, cur)
tmp = skip_escaped_newlines (pfile, cur + 1);
if (*tmp == '*')
{
- cur = skip_comment (pfile, tmp + 1);
+ cur = copy_comment (pfile, tmp + 1);
continue;
}
}
@@ -246,23 +270,6 @@ lex_identifier (pfile, cur)
return result;
}
-/* Reads an identifier, returning its hashnode. If the next token is
- not an identifier, returns NULL. */
-cpp_hashnode *
-_cpp_lex_identifier_trad (pfile)
- cpp_reader *pfile;
-{
- const uchar *cur = skip_whitespace (pfile, CUR (pfile->context));
-
- if (!is_idstart (*cur))
- {
- CUR (pfile->context) = cur;
- return NULL;
- }
-
- return lex_identifier (pfile, cur);
-}
-
/* Overlays the true file buffer temporarily with text of length LEN
starting at START. The true buffer is restored upon calling
restore_buff(). */
@@ -381,7 +388,7 @@ scan_out_logical_line (pfile, macro)
{
cpp_context *context;
const uchar *cur;
- unsigned int c, paren_depth, quote = 0;
+ unsigned int c, paren_depth = 0, quote = 0;
uchar *out;
struct fun_macro fmacro;
@@ -466,7 +473,22 @@ scan_out_logical_line (pfile, macro)
{
cur = skip_escaped_newlines (pfile, cur);
if (*cur == '*')
- out--, cur = skip_comment (pfile, cur + 1);
+ {
+ *out = '*';
+ pfile->out.cur = out + 1;
+ cur = copy_comment (pfile, cur + 1);
+
+ /* Comments in directives become spaces so that
+ tokens are properly separated when the ISO
+ preprocessor re-lexes the line. The exception
+ is #define. */
+ if (pfile->state.in_directive && !macro)
+ out[-1] = ' ';
+ else if (CPP_OPTION (pfile, discard_comments))
+ out -= 1;
+ else
+ out = pfile->out.cur;
+ }
}
break;
OpenPOWER on IntegriCloud