aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Booth <NeilB@earthling.net>2000-09-23 21:41:41 +0000
committerNeil Booth <NeilB@earthling.net>2000-09-23 21:41:41 +0000
commit0fd10014150c06d46f32e57111d05e33b949e5b5 (patch)
treeed10891b3898c3d5117b135bd865e1653390160c
parent8e6e74f4f49110309248bacda6c6fb2783d25f97 (diff)
* cpphash.h (CPP_RESERVE, CPP_PUTS_Q, CPP_PUTS, CPP_PUTC_Q,
CPP_PUTC, DUMMY_TOKEN, NO_DUMMY_TOKEN): Delete. * cpplex.c (_cpp_expand_token_space, _cpp_init_toklist, _cpp_free_toklist): No need to worry about extra dummy token at the start of token lists any more. (trigraph_ok): Only warn outside comments. (skip_block_comment): Set and clear lexing_comment. (skip_line_comment): Take a cpp_reader not cpp_buffer. Set and clear lexing_comment. (parse_number): Handle leading '.' indicated by pfile->seen_dot. (check_long_token): Delete. (lex_percent, lex_dot): New subroutines of lex_token to handle lexing of '.' and '%' without lookback. (lex_token): Use lex_dot and lex_percent. (lex_line): Don't check for LIST_OFFSET. (_cpp_init_input_buffer): Update for new _cpp_init_toklist. * cpplib.c (_cpp_parse_assertion): Similarly. (cpp_push_buffer): Initialize extra_char. * cpplib.h (LIST_OFFSET): Delete. (struct cpp_buffer): New member extra_char. (struct lexer_state): New members lexing_comment and seen_dot. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@36582 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/cpphash.h20
-rw-r--r--gcc/cpplex.c227
-rw-r--r--gcc/cpplib.c4
-rw-r--r--gcc/cpplib.h14
5 files changed, 159 insertions, 130 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index efe588a7ad7..6b29754e911 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+Sat 23-Sep-2000 22:39:18 BST Neil Booth <NeilB@earthling.net>
+
+ * cpphash.h (CPP_RESERVE, CPP_PUTS_Q, CPP_PUTS, CPP_PUTC_Q,
+ CPP_PUTC, DUMMY_TOKEN, NO_DUMMY_TOKEN): Delete.
+ * cpplex.c (_cpp_expand_token_space, _cpp_init_toklist,
+ _cpp_free_toklist): No need to worry about extra dummy token
+ at the start of token lists any more.
+ (trigraph_ok): Only warn outside comments.
+ (skip_block_comment): Set and clear lexing_comment.
+ (skip_line_comment): Take a cpp_reader not cpp_buffer.
+ Set and clear lexing_comment.
+ (parse_number): Handle leading '.' indicated by pfile->seen_dot.
+ (check_long_token): Delete.
+ (lex_percent, lex_dot): New subroutines of lex_token to
+ handle lexing of '.' and '%' without lookback.
+ (lex_token): Use lex_dot and lex_percent.
+ (lex_line): Don't check for LIST_OFFSET.
+ (_cpp_init_input_buffer): Update for new _cpp_init_toklist.
+ * cpplib.c (_cpp_parse_assertion): Similarly.
+ (cpp_push_buffer): Initialize extra_char.
+ * cpplib.h (LIST_OFFSET): Delete.
+ (struct cpp_buffer): New member extra_char.
+ (struct lexer_state): New members lexing_comment and seen_dot.
+
2000-09-23 Jason Merrill <jason@redhat.com>
* config/rs6000/x-aix41 (CLIB): Define here.
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index 08d3209d7bc..8f569e7404d 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -183,22 +183,6 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1];
/* Macros. */
-/* Make sure PFILE->token_buffer has space for at least N more characters. */
-#define CPP_RESERVE(PFILE, N) \
- (CPP_WRITTEN (PFILE) + (size_t)(N) > (PFILE)->token_buffer_size \
- && (_cpp_grow_token_buffer (PFILE, N), 0))
-
-/* Append string STR (of length N) to PFILE's output buffer.
- Assume there is enough space. */
-#define CPP_PUTS_Q(PFILE, STR, N) \
- (memcpy ((PFILE)->limit, STR, (N)), (PFILE)->limit += (N))
-/* Append string STR (of length N) to PFILE's output buffer. Make space. */
-#define CPP_PUTS(PFILE, STR, N) CPP_RESERVE(PFILE, N), CPP_PUTS_Q(PFILE, STR,N)
-/* Append character CH to PFILE's output buffer. Assume sufficient space. */
-#define CPP_PUTC_Q(PFILE, CH) (*(PFILE)->limit++ = (CH))
-/* Append character CH to PFILE's output buffer. Make space if need be. */
-#define CPP_PUTC(PFILE, CH) (CPP_RESERVE (PFILE, 1), CPP_PUTC_Q (PFILE, CH))
-
#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
#define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps)
#define CPP_IN_SYSTEM_HEADER(PFILE) \
@@ -213,10 +197,6 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1];
parse_name. */
#define HASHSTEP(r, c) ((r) * 67 + (c - 113));
-/* Flags for _cpp_init_toklist. */
-#define DUMMY_TOKEN 0
-#define NO_DUMMY_TOKEN 1
-
/* In cpperror.c */
enum error_type { WARNING = 0, PEDWARN, ERROR, FATAL, ICE };
extern int _cpp_begin_message PARAMS ((cpp_reader *, enum error_type,
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index c0bf875aaff..a7a6f99098c 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -103,7 +103,7 @@ static cppchar_t skip_escaped_newlines PARAMS ((cpp_buffer *, cppchar_t));
static cppchar_t get_effective_char PARAMS ((cpp_buffer *));
static int skip_block_comment PARAMS ((cpp_reader *));
-static int skip_line_comment PARAMS ((cpp_buffer *));
+static int skip_line_comment PARAMS ((cpp_reader *));
static void adjust_column PARAMS ((cpp_reader *));
static void skip_whitespace PARAMS ((cpp_reader *, cppchar_t));
static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *, cppchar_t));
@@ -112,11 +112,9 @@ static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t));
static void unterminated PARAMS ((cpp_reader *, unsigned int, int));
static int trigraph_ok PARAMS ((cpp_reader *, cppchar_t));
static void save_comment PARAMS ((cpp_reader *, cpp_token *, const U_CHAR *));
+static void lex_percent PARAMS ((cpp_buffer *, cpp_token *));
+static void lex_dot PARAMS ((cpp_reader *, cpp_token *));
static void lex_line PARAMS ((cpp_reader *, cpp_toklist *));
-static void check_long_token PARAMS ((cpp_buffer *,
- cpp_token *,
- cppchar_t,
- enum cpp_ttype));
static void lex_token PARAMS ((cpp_reader *, cpp_token *));
static int lex_next PARAMS ((cpp_reader *, int));
@@ -453,50 +451,35 @@ _cpp_expand_token_space (list, count)
cpp_toklist *list;
unsigned int count;
{
- unsigned int n;
-
list->tokens_cap += count;
- n = list->tokens_cap;
- if (list->flags & LIST_OFFSET)
- list->tokens--, n++;
list->tokens = (cpp_token *)
- xrealloc (list->tokens, n * sizeof (cpp_token));
- if (list->flags & LIST_OFFSET)
- list->tokens++; /* Skip the dummy. */
+ xrealloc (list->tokens, list->tokens_cap * sizeof (cpp_token));
}
-/* Initialize a token list. If flags is DUMMY_TOKEN, we allocate
- an extra token in front of the token list, as this allows the lexer
- to always peek at the previous token without worrying about
- underflowing the list, and some initial space. Otherwise, no
- token- or name-space is allocated, and there is no dummy token. */
+/* Initialize a token list. If EMPTY is false, some token and name
+ space is provided. */
void
-_cpp_init_toklist (list, flags)
+_cpp_init_toklist (list, empty)
cpp_toklist *list;
- int flags;
+ int empty;
{
- if (flags == NO_DUMMY_TOKEN)
+ if (empty)
{
list->tokens_cap = 0;
list->tokens = 0;
list->name_cap = 0;
list->namebuf = 0;
- list->flags = 0;
}
else
{
- /* Initialize token space. Put a dummy token before the start
- that will fail matches. */
+ /* Initialize token space. */
list->tokens_cap = 256; /* 4K's worth. */
list->tokens = (cpp_token *)
xmalloc ((list->tokens_cap + 1) * sizeof (cpp_token));
- list->tokens[0].type = CPP_EOF;
- list->tokens++;
/* Initialize name space. */
list->name_cap = 1024;
list->namebuf = (unsigned char *) xmalloc (list->name_cap);
- list->flags = LIST_OFFSET;
}
_cpp_clear_toklist (list);
@@ -512,7 +495,7 @@ _cpp_clear_toklist (list)
list->directive = 0;
list->paramc = 0;
list->params_len = 0;
- list->flags &= LIST_OFFSET; /* clear all but that one */
+ list->flags = 0;
}
/* Free a token list. Does not free the list itself, which may be
@@ -521,10 +504,7 @@ void
_cpp_free_toklist (list)
const cpp_toklist *list;
{
- if (list->flags & LIST_OFFSET)
- free (list->tokens - 1); /* Backup over dummy token. */
- else
- free (list->tokens);
+ free (list->tokens);
free (list->namebuf);
}
@@ -633,7 +613,8 @@ trigraph_ok (pfile, from_char)
{
int accept = CPP_OPTION (pfile, trigraphs);
- if (CPP_OPTION (pfile, warn_trigraphs))
+ /* Don't warn about trigraphs in comments. */
+ if (CPP_OPTION (pfile, warn_trigraphs) && !pfile->state.lexing_comment)
{
cpp_buffer *buffer = pfile->buffer;
if (accept)
@@ -768,6 +749,7 @@ skip_block_comment (pfile)
cpp_buffer *buffer = pfile->buffer;
cppchar_t c = EOF, prevc;
+ pfile->state.lexing_comment = 1;
while (buffer->cur != buffer->rlimit)
{
prevc = c, c = *buffer->cur++;
@@ -812,6 +794,7 @@ skip_block_comment (pfile)
adjust_column (pfile);
}
+ pfile->state.lexing_comment = 0;
buffer->read_ahead = EOF;
return c != '/' || prevc != '*';
}
@@ -820,12 +803,14 @@ skip_block_comment (pfile)
non-zero if a multiline comment. The following new line, if any,
is left in buffer->read_ahead. */
static int
-skip_line_comment (buffer)
- cpp_buffer *buffer;
+skip_line_comment (pfile)
+ cpp_reader *pfile;
{
+ cpp_buffer *buffer = pfile->buffer;
unsigned int orig_lineno = buffer->lineno;
cppchar_t c;
+ pfile->state.lexing_comment = 1;
do
{
c = EOF;
@@ -838,6 +823,7 @@ skip_line_comment (buffer)
}
while (!is_vspace (c));
+ pfile->state.lexing_comment = 0;
buffer->read_ahead = c; /* Leave any newline for caller. */
return orig_lineno != buffer->lineno;
}
@@ -966,11 +952,15 @@ parse_number (pfile, number, c)
cpp_buffer *buffer = pfile->buffer;
unsigned int orig_used = pfile->token_list.name_used;
+ /* Reserve space for a leading period. */
+ if (pfile->state.seen_dot)
+ pfile->token_list.name_used++;
+
do
{
do
{
- if (pfile->token_list.name_used == pfile->token_list.name_cap)
+ if (pfile->token_list.name_used >= pfile->token_list.name_cap)
_cpp_expand_name_space (&pfile->token_list,
pfile->token_list.name_used + 256);
pfile->token_list.namebuf[pfile->token_list.name_used++] = c;
@@ -991,6 +981,10 @@ parse_number (pfile, number, c)
}
while (is_numchar (c) || c == '.' || VALID_SIGN (c, prevc));
+ /* Put any leading period in place, now we have the room. */
+ if (pfile->state.seen_dot)
+ pfile->token_list.namebuf[orig_used] = '.';
+
/* Remember the next character. */
buffer->read_ahead = c;
@@ -1144,27 +1138,99 @@ save_comment (pfile, token, from)
memcpy (buffer, from, len - COMMENT_START_LEN);
}
-/* A helper routine for lex_token. With some long tokens, we need
- to read ahead to see if that is the token we have, but back-track
- if not. */
+/* Subroutine of lex_token to handle '%'. A little tricky, since we
+ want to avoid stepping back when lexing %:%X. */
static void
-check_long_token (buffer, result, wanted, type)
+lex_percent (buffer, result)
cpp_buffer *buffer;
cpp_token *result;
- cppchar_t wanted;
- enum cpp_ttype type;
{
- const unsigned char *saved_cur;
- cppchar_t c = buffer->read_ahead;
+ cppchar_t c;
+
+ result->type = CPP_MOD;
+ /* Parsing %:%X could leave an extra character. */
+ if (buffer->extra_char == EOF)
+ c = get_effective_char (buffer);
+ else
+ {
+ c = buffer->read_ahead = buffer->extra_char;
+ buffer->extra_char = EOF;
+ }
+
+ if (c == '=')
+ ACCEPT_CHAR (CPP_MOD_EQ);
+ else if (CPP_OPTION (buffer->pfile, digraphs))
+ {
+ if (c == ':')
+ {
+ result->flags |= DIGRAPH;
+ ACCEPT_CHAR (CPP_HASH);
+ if (get_effective_char (buffer) == '%')
+ {
+ buffer->extra_char = get_effective_char (buffer);
+ if (buffer->extra_char == ':')
+ {
+ buffer->extra_char = EOF;
+ ACCEPT_CHAR (CPP_PASTE);
+ }
+ else
+ /* We'll catch the extra_char when we're called back. */
+ buffer->read_ahead = '%';
+ }
+ }
+ else if (c == '>')
+ {
+ result->flags |= DIGRAPH;
+ ACCEPT_CHAR (CPP_CLOSE_BRACE);
+ }
+ }
+}
+
+/* Subroutine of lex_token to handle '.'. This is tricky, since we
+ want to avoid stepping back when lexing '...' or '.123'. In the
+ latter case we should also set a flag for parse_number. */
+static void
+lex_dot (pfile, result)
+ cpp_reader *pfile;
+ cpp_token *result;
+{
+ cpp_buffer *buffer = pfile->buffer;
+ cppchar_t c;
+
+ /* Parsing ..X could leave an extra character. */
+ if (buffer->extra_char == EOF)
+ c = get_effective_char (buffer);
+ else
+ {
+ c = buffer->read_ahead = buffer->extra_char;
+ buffer->extra_char = EOF;
+ }
- SAVE_STATE ();
- if (get_effective_char (buffer) == wanted)
- ACCEPT_CHAR (type);
+ /* All known character sets have 0...9 contiguous. */
+ if (c >= '0' && c <= '9')
+ {
+ result->type = CPP_NUMBER;
+ buffer->pfile->state.seen_dot = 1;
+ parse_number (pfile, &result->val.str, c);
+ buffer->pfile->state.seen_dot = 0;
+ }
else
{
- /* Restore state. */
- RESTORE_STATE ();
- buffer->read_ahead = c;
+ result->type = CPP_DOT;
+ if (c == '.')
+ {
+ buffer->extra_char = get_effective_char (buffer);
+ if (buffer->extra_char == '.')
+ {
+ buffer->extra_char = EOF;
+ ACCEPT_CHAR (CPP_ELLIPSIS);
+ }
+ else
+ /* We'll catch the extra_char when we're called back. */
+ buffer->read_ahead = '.';
+ }
+ else if (c == '*' && CPP_OPTION (pfile, cplusplus))
+ ACCEPT_CHAR (CPP_DOT_STAR);
}
}
@@ -1245,7 +1311,6 @@ lex_token (pfile, result)
}
break;
- make_number:
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
result->type = CPP_NUMBER;
@@ -1342,7 +1407,7 @@ lex_token (pfile, result)
comment_start = buffer->cur;
/* Skip_line_comment updates buffer->read_ahead. */
- if (skip_line_comment (buffer))
+ if (skip_line_comment (pfile))
cpp_warning_with_line (pfile, result->line, result->col,
"multi-line comment");
@@ -1413,57 +1478,12 @@ lex_token (pfile, result)
}
break;
- case '.':
- {
- const unsigned char *saved_cur;
- cppchar_t c1;
-
- /* Save state to avoid needing to pass 2 chars to parse_number. */
- SAVE_STATE ();
- c1 = get_effective_char (buffer);
- /* All known character sets have 0...9 contiguous. */
- if (c1 >= '0' && c1 <= '9')
- {
- RESTORE_STATE ();
- goto make_number;
- }
-
- result->type = CPP_DOT;
- if (c1 == '.')
- {
- if (get_effective_char (buffer) == '.')
- ACCEPT_CHAR (CPP_ELLIPSIS);
- else
- {
- buffer->read_ahead = EOF;
- RESTORE_STATE ();
- }
- }
- else if (c1 == '*' && CPP_OPTION (pfile, cplusplus))
- ACCEPT_CHAR (CPP_DOT_STAR);
- }
+ case '%':
+ lex_percent (buffer, result);
break;
- case '%':
- result->type = CPP_MOD;
- c = get_effective_char (buffer);
- if (c == '=')
- ACCEPT_CHAR (CPP_MOD_EQ);
- else if (CPP_OPTION (pfile, digraphs))
- {
- if (c == ':')
- {
- result->flags |= DIGRAPH;
- ACCEPT_CHAR (CPP_HASH);
- if (get_effective_char (buffer) == '%')
- check_long_token (buffer, result, ':', CPP_PASTE);
- }
- else if (c == '>')
- {
- result->flags |= DIGRAPH;
- ACCEPT_CHAR (CPP_CLOSE_BRACE);
- }
- }
+ case '.':
+ lex_dot (pfile, result);
break;
case '+':
@@ -1610,9 +1630,6 @@ lex_line (pfile, list)
cpp_token *cur_token, *first;
cpp_buffer *buffer = pfile->buffer;
- if (!(list->flags & LIST_OFFSET))
- (abort) ();
-
pfile->state.in_lex_line = 1;
if (pfile->buffer->cur == pfile->buffer->buf)
list->flags |= BEG_OF_FILE;
@@ -3397,7 +3414,7 @@ _cpp_init_input_buffer (pfile)
{
cpp_context *base;
- _cpp_init_toklist (&pfile->token_list, DUMMY_TOKEN);
+ _cpp_init_toklist (&pfile->token_list, 0);
pfile->no_expand_level = UINT_MAX;
pfile->context_cap = 20;
pfile->cur_context = 0;
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index 31064863cac..8c61ab0c222 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -1247,7 +1247,7 @@ _cpp_parse_assertion (pfile, answerp)
/* Allocate a struct answer, and copy the answer to it. */
answer = (struct answer *) xmalloc (sizeof (struct answer));
list = &answer->list;
- _cpp_init_toklist (list, NO_DUMMY_TOKEN);
+ _cpp_init_toklist (list, 1); /* Empty. */
for (;;)
{
@@ -1516,7 +1516,9 @@ cpp_push_buffer (pfile, buffer, length)
new->rlimit = buffer + length;
new->prev = buf;
new->pfile = pfile;
+ /* No read ahead or extra char initially. */
new->read_ahead = EOF;
+ new->extra_char = EOF;
CPP_BUFFER (pfile) = new;
return new;
diff --git a/gcc/cpplib.h b/gcc/cpplib.h
index 75115375664..15c30abc67d 100644
--- a/gcc/cpplib.h
+++ b/gcc/cpplib.h
@@ -182,9 +182,8 @@ struct cpp_token
};
/* cpp_toklist flags. */
-#define LIST_OFFSET (1 << 0)
-#define VAR_ARGS (1 << 1)
-#define BEG_OF_FILE (1 << 2)
+#define VAR_ARGS (1 << 0)
+#define BEG_OF_FILE (1 << 1)
struct directive; /* These are deliberately incomplete. */
struct answer;
@@ -225,6 +224,7 @@ struct cpp_buffer
const unsigned char *rlimit; /* end of valid data */
const unsigned char *line_base; /* start of current line */
cppchar_t read_ahead; /* read ahead character */
+ cppchar_t extra_char; /* extra read-ahead for long tokens. */
struct cpp_reader *pfile; /* Owns this buffer. */
struct cpp_buffer *prev;
@@ -460,8 +460,14 @@ struct lexer_state
/* Nonzero to get force the lexer to skip newlines. */
unsigned char skip_newlines;
- /* If we're in the subroutine lex_line. */
+ /* Nonzero if we're in the subroutine lex_line. */
unsigned char in_lex_line;
+
+ /* Nonzero if we're mid-comment. */
+ unsigned char lexing_comment;
+
+ /* Tells parse_number we saw a leading period. */
+ unsigned char seen_dot;
};
#define IN_DIRECTIVE(pfile) (pfile->state.in_directive)
#define KNOWN_DIRECTIVE(list) (list->directive != 0)