aboutsummaryrefslogtreecommitdiff
path: root/gcc/cpplex.c
diff options
context:
space:
mode:
authorZack Weinberg <zack@gcc.gnu.org>2003-10-13 18:53:28 +0000
committerZack Weinberg <zack@gcc.gnu.org>2003-10-13 18:53:28 +0000
commitd08dcf87c3cd30fc6d3029bed71ed06237c840ba (patch)
treec72adc0c25b99cd7a460fe815b5e09afa77b4622 /gcc/cpplex.c
parentb1ef58c8faace79193bb064f8034b422beb7fb46 (diff)
downloadgcc-d08dcf87c3cd30fc6d3029bed71ed06237c840ba.zip
gcc-d08dcf87c3cd30fc6d3029bed71ed06237c840ba.tar.gz
gcc-d08dcf87c3cd30fc6d3029bed71ed06237c840ba.tar.bz2
cpplex.c (_cpp_clean_line): In the common case of a line with no trigraphs and no \-newline...
* cpplex.c (_cpp_clean_line): In the common case of a line with no trigraphs and no \-newline, avoid writing to memory. (_cpp_skip_block_comment): Use a local 'cur' pointer instead of the buffer member. Make c an uchar to avoid unnecessary sign extensions. From-SVN: r72437
Diffstat (limited to 'gcc/cpplex.c')
-rw-r--r--gcc/cpplex.c83
1 files changed, 70 insertions, 13 deletions
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index 45cf574..3701415 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -114,7 +114,57 @@ _cpp_clean_line (cpp_reader *pfile)
if (!buffer->from_stage3)
{
- d = (uchar *) s;
+ /* Short circuit for the common case of an un-escaped line with
+ no trigraphs. The primary win here is by not writing any
+ data back to memory until we have to. */
+ for (;;)
+ {
+ c = *++s;
+ if (c == '\n' || c == '\r')
+ {
+ d = (uchar *) s;
+
+ if (s == buffer->rlimit)
+ goto done;
+
+ /* DOS line ending? */
+ if (c == '\r' && s[1] == '\n')
+ s++;
+
+ if (s == buffer->rlimit)
+ goto done;
+
+ /* check for escaped newline */
+ p = d;
+ while (p != buffer->next_line && is_nvspace (p[-1]))
+ p--;
+ if (p == buffer->next_line || p[-1] != '\\')
+ goto done;
+
+ /* Have an escaped newline; process it and proceed to
+ the slow path. */
+ add_line_note (buffer, p - 1, p != d ? ' ' : '\\');
+ d = p - 2;
+ buffer->next_line = p - 1;
+ break;
+ }
+ if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]])
+ {
+ /* Have a trigraph. We may or may not have to convert
+ it. Add a line note regardless, for -Wtrigraphs. */
+ add_line_note (buffer, s, s[2]);
+ if (CPP_OPTION (pfile, trigraphs))
+ {
+ /* We do, and that means we have to switch to the
+ slow path. */
+ d = (uchar *) s;
+ *d = _cpp_trigraph_map[s[2]];
+ s += 2;
+ break;
+ }
+ }
+ }
+
for (;;)
{
@@ -164,6 +214,7 @@ _cpp_clean_line (cpp_reader *pfile)
s++;
}
+ done:
*d = '\n';
/* A sentinel note that should never be processed. */
add_line_note (buffer, d + 1, '\n');
@@ -266,43 +317,49 @@ bool
_cpp_skip_block_comment (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
- cppchar_t c;
+ const uchar *cur = buffer->cur;
+ uchar c;
- buffer->cur++;
- if (*buffer->cur == '/')
- buffer->cur++;
+ cur++;
+ if (*cur == '/')
+ cur++;
for (;;)
{
- c = *buffer->cur++;
-
/* People like decorating comments with '*', so check for '/'
instead for efficiency. */
+ c = *cur++;
+
if (c == '/')
{
- if (buffer->cur[-2] == '*')
+ if (cur[-2] == '*')
break;
/* Warn about potential nested comments, but not if the '/'
comes immediately before the true comment delimiter.
Don't bother to get it right across escaped newlines. */
if (CPP_OPTION (pfile, warn_comments)
- && buffer->cur[0] == '*' && buffer->cur[1] != '/')
- cpp_error_with_line (pfile, DL_WARNING,
- pfile->line, CPP_BUF_COL (buffer),
- "\"/*\" within comment");
+ && cur[0] == '*' && cur[1] != '/')
+ {
+ buffer->cur = cur;
+ cpp_error_with_line (pfile, DL_WARNING,
+ pfile->line, CPP_BUF_COL (buffer),
+ "\"/*\" within comment");
+ }
}
else if (c == '\n')
{
- buffer->cur--;
+ buffer->cur = cur - 1;
_cpp_process_line_notes (pfile, true);
if (buffer->next_line >= buffer->rlimit)
return true;
_cpp_clean_line (pfile);
pfile->line++;
+ cur = buffer->cur;
}
}
+ buffer->cur = cur;
_cpp_process_line_notes (pfile, true);
return false;
}