Commit 0c5e4866 by Nathan Sidwell Committed by Nathan Sidwell

parser.c (cp_token_position): New typedef.

	* parser.c (cp_token_position): New typedef. Define VEC thereof.
	(struct cp_lexer): Allow buffer and buffer_end to be NULL. Make
	next_token and last_token cp_token_position. Make saved_tokens a
	VEC(cp_token_position).
	(eof_token): New static variable.
	(CP_SAVED_TOKENS_SIZE): Rename to ...
	(CP_SAVED_TOKEN_STACK): ... here.
	(cp_lexer_new_main): Adjust main lexer creation and buffer
	filling.
	(cp_lexer_new_from_tokens): Do not copy the tokens, merely point
	to the parent buffer.  Do not append eof token.
	(cp_lexer_destroy): Only free buffer if non-NULL. Free token
	stack.
	(cp_lexer_next_token, cp_lexer_prev_token): Remove.
	(cp_lexer_token_position, cp_lexer_token_at): New.
	(cp_lexer_saving_tokens): Adjust. Make inline.
	(cp_lexer_advance_token, cp_lexer_token_difference): Remove.
	(cp_lexer_peek_token_emit_debug_info): Fold into ...
	(cp_lexer_peek_token): ... here.
	(cp_lexer_peek_nth_token): Don't peek past EOF.
	(cp_lexer_consume_token): Set next_token to eof_token, if reaching
	EOF.
	(cp_lexer_purge_token): Adjust eof setting.
	(cp_lexer_purge_tokens_after): Likewise.
	(cp_lexer_save_tokens): Push next_token directly.
	(cp_lexer_commit_tokens): Adjust.
	(cp_lexer_rollback_tokens): Pop next_token directly.
	(cp_parser_check_for_invalid_template_id): Adjust token purging.
	(cp_parser_translation_unit): Do not consume the EOF.
	(cp_parser_nested_name_specifier_opt): Adjust token purging.
	(cp_parser_template_id, cp_parser_template_name): Likewise.

From-SVN: r89320
parent 242b11bd
2004-10-20 Nathan Sidwell <nathan@codesourcery.com>
* parser.c (cp_token_position): New typedef. Define VEC thereof.
(struct cp_lexer): Allow buffer and buffer_end to be NULL. Make
next_token and last_token cp_token_position. Make saved_tokens a
VEC(cp_token_position).
(eof_token): New static variable.
(CP_SAVED_TOKENS_SIZE): Rename to ...
(CP_SAVED_TOKEN_STACK): ... here.
(cp_lexer_new_main): Adjust main lexer creation and buffer
filling.
(cp_lexer_new_from_tokens): Do not copy the tokens, merely point
to the parent buffer. Do not append eof token.
(cp_lexer_destroy): Only free buffer if non-NULL. Free token
stack.
(cp_lexer_next_token, cp_lexer_prev_token): Remove.
(cp_lexer_token_position, cp_lexer_token_at): New.
(cp_lexer_saving_tokens): Adjust. Make inline.
(cp_lexer_advance_token, cp_lexer_token_difference): Remove.
(cp_lexer_peek_token_emit_debug_info): Fold into ...
(cp_lexer_peek_token): ... here.
(cp_lexer_peek_nth_token): Don't peek past EOF.
(cp_lexer_consume_token): Set next_token to eof_token, if reaching
EOF.
(cp_lexer_purge_token): Adjust eof setting.
(cp_lexer_purge_tokens_after): Likewise.
(cp_lexer_save_tokens): Push next_token directly.
(cp_lexer_commit_tokens): Adjust.
(cp_lexer_rollback_tokens): Pop next_token directly.
(cp_parser_check_for_invalid_template_id): Adjust token purging.
(cp_parser_translation_unit): Do not consume the EOF.
(cp_parser_nested_name_specifier_opt): Adjust token purging.
(cp_parser_template_id, cp_parser_template_name): Likewise.
2004-10-19 Mark Mitchell <mark@codesourcery.com> 2004-10-19 Mark Mitchell <mark@codesourcery.com>
PR c++/14035 PR c++/14035
......
...@@ -63,6 +63,12 @@ typedef struct cp_token GTY (()) ...@@ -63,6 +63,12 @@ typedef struct cp_token GTY (())
location_t location; location_t location;
} cp_token; } cp_token;
/* We use a stack of token pointer for saving token sets. */
typedef struct cp_token *cp_token_position;
DEF_VEC_MALLOC_P (cp_token_position);
static cp_token eof_token = {CPP_EOF, 0, 0, 0, 0, NULL_TREE, {0, 0}};
/* The cp_lexer structure represents the C++ lexer. It is responsible /* The cp_lexer structure represents the C++ lexer. It is responsible
for managing the token stream from the preprocessor and supplying for managing the token stream from the preprocessor and supplying
it to the parser. Tokens are never added to the cp_lexer after it to the parser. Tokens are never added to the cp_lexer after
...@@ -70,24 +76,26 @@ typedef struct cp_token GTY (()) ...@@ -70,24 +76,26 @@ typedef struct cp_token GTY (())
typedef struct cp_lexer GTY (()) typedef struct cp_lexer GTY (())
{ {
/* The memory allocated for the buffer. Never NULL. */ /* The memory allocated for the buffer. NULL if this lexer does not
own the token buffer. */
cp_token * GTY ((length ("(%h.buffer_end - %h.buffer)"))) buffer; cp_token * GTY ((length ("(%h.buffer_end - %h.buffer)"))) buffer;
/* A pointer just past the end of the memory allocated for the buffer. */ /* If non-null, a pointer just past the end of the memory allocated
for the buffer. */
cp_token * GTY ((skip)) buffer_end; cp_token * GTY ((skip)) buffer_end;
/* A pointer just past the last available token. The tokens /* A pointer just past the last available token. The tokens
in this lexer are [buffer, last_token). */ in this lexer are [buffer, last_token). */
cp_token * GTY ((skip)) last_token; cp_token_position GTY ((skip)) last_token;
/* The next available token. If NEXT_TOKEN is NULL, then there are /* The next available token. If NEXT_TOKEN is &eof_token, then there are
no more available tokens. */ no more available tokens. */
cp_token * GTY ((skip)) next_token; cp_token_position GTY ((skip)) next_token;
/* A stack indicating positions at which cp_lexer_save_tokens was /* A stack indicating positions at which cp_lexer_save_tokens was
called. The top entry is the most recent position at which we called. The top entry is the most recent position at which we
began saving tokens. The entries are differences in token began saving tokens. If the stack is non-empty, we are saving
position between BUFFER and the first saved token. tokens. */
If the stack is non-empty, we are saving tokens. */ VEC (cp_token_position) *GTY ((skip)) saved_tokens;
varray_type saved_tokens;
/* True if we should output debugging information. */ /* True if we should output debugging information. */
bool debugging_p; bool debugging_p;
...@@ -121,12 +129,10 @@ static void cp_lexer_destroy ...@@ -121,12 +129,10 @@ static void cp_lexer_destroy
(cp_lexer *); (cp_lexer *);
static int cp_lexer_saving_tokens static int cp_lexer_saving_tokens
(const cp_lexer *); (const cp_lexer *);
static cp_token *cp_lexer_next_token static cp_token_position cp_lexer_token_position
(cp_lexer *, cp_token *); (cp_lexer *, bool);
static cp_token *cp_lexer_prev_token static cp_token *cp_lexer_token_at
(cp_lexer *, cp_token *); (cp_lexer *, cp_token_position);
static ptrdiff_t cp_lexer_token_difference
(cp_lexer *, cp_token *, cp_token *);
static void cp_lexer_grow_buffer static void cp_lexer_grow_buffer
(cp_lexer *); (cp_lexer *);
static void cp_lexer_get_preprocessor_token static void cp_lexer_get_preprocessor_token
...@@ -146,7 +152,7 @@ static cp_token *cp_lexer_consume_token ...@@ -146,7 +152,7 @@ static cp_token *cp_lexer_consume_token
static void cp_lexer_purge_token static void cp_lexer_purge_token
(cp_lexer *); (cp_lexer *);
static void cp_lexer_purge_tokens_after static void cp_lexer_purge_tokens_after
(cp_lexer *, cp_token *); (cp_lexer *, cp_token_position);
static void cp_lexer_handle_pragma static void cp_lexer_handle_pragma
(cp_lexer *); (cp_lexer *);
static void cp_lexer_save_tokens static void cp_lexer_save_tokens
...@@ -164,8 +170,6 @@ static void cp_lexer_start_debugging ...@@ -164,8 +170,6 @@ static void cp_lexer_start_debugging
(cp_lexer *) ATTRIBUTE_UNUSED; (cp_lexer *) ATTRIBUTE_UNUSED;
static void cp_lexer_stop_debugging static void cp_lexer_stop_debugging
(cp_lexer *) ATTRIBUTE_UNUSED; (cp_lexer *) ATTRIBUTE_UNUSED;
static void cp_lexer_peek_token_emit_debug_info
(cp_lexer *, cp_token *);
#else #else
/* If we define cp_lexer_debug_stream to NULL it will provoke warnings /* If we define cp_lexer_debug_stream to NULL it will provoke warnings
about passing NULL to functions that require non-NULL arguments about passing NULL to functions that require non-NULL arguments
...@@ -174,16 +178,14 @@ static void cp_lexer_peek_token_emit_debug_info ...@@ -174,16 +178,14 @@ static void cp_lexer_peek_token_emit_debug_info
#define cp_lexer_debug_stream stdout #define cp_lexer_debug_stream stdout
#define cp_lexer_print_token(str, tok) (void) 0 #define cp_lexer_print_token(str, tok) (void) 0
#define cp_lexer_debugging_p(lexer) 0 #define cp_lexer_debugging_p(lexer) 0
#define cp_lexer_peek_token_emit_debug_info(lexer, tok) (void) 0
#endif /* ENABLE_CHECKING */ #endif /* ENABLE_CHECKING */
static cp_token_cache *cp_token_cache_new static cp_token_cache *cp_token_cache_new
(cp_token *, cp_token *); (cp_token *, cp_token *);
/* Manifest constants. */ /* Manifest constants. */
#define CP_LEXER_BUFFER_SIZE 10000 #define CP_LEXER_BUFFER_SIZE 10000
#define CP_SAVED_TOKENS_SIZE 5 #define CP_SAVED_TOKEN_STACK 5
/* A token type for keywords, as opposed to ordinary identifiers. */ /* A token type for keywords, as opposed to ordinary identifiers. */
#define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1)) #define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
...@@ -245,12 +247,11 @@ cp_lexer_new_main (void) ...@@ -245,12 +247,11 @@ cp_lexer_new_main (void)
lexer->buffer_end = lexer->buffer + CP_LEXER_BUFFER_SIZE; lexer->buffer_end = lexer->buffer + CP_LEXER_BUFFER_SIZE;
/* There is one token in the buffer. */ /* There is one token in the buffer. */
lexer->last_token = lexer->buffer + 1; lexer->last_token = lexer->buffer;
lexer->next_token = lexer->buffer; lexer->next_token = lexer->buffer;
*lexer->next_token = first_token; *lexer->next_token = first_token;
/* Create the SAVED_TOKENS stack. */ lexer->saved_tokens = VEC_alloc (cp_token_position, CP_SAVED_TOKEN_STACK);
VARRAY_INT_INIT (lexer->saved_tokens, CP_SAVED_TOKENS_SIZE, "saved_tokens");
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
/* Initially we are not debugging. */ /* Initially we are not debugging. */
...@@ -258,11 +259,12 @@ cp_lexer_new_main (void) ...@@ -258,11 +259,12 @@ cp_lexer_new_main (void)
#endif /* ENABLE_CHECKING */ #endif /* ENABLE_CHECKING */
/* Get the rest of the tokens from the preprocessor. */ /* Get the rest of the tokens from the preprocessor. */
while (lexer->last_token[-1].type != CPP_EOF) while (lexer->last_token->type != CPP_EOF)
{ {
lexer->last_token++;
if (lexer->last_token == lexer->buffer_end) if (lexer->last_token == lexer->buffer_end)
cp_lexer_grow_buffer (lexer); cp_lexer_grow_buffer (lexer);
cp_lexer_get_preprocessor_token (lexer, lexer->last_token++); cp_lexer_get_preprocessor_token (lexer, lexer->last_token);
} }
/* Pragma processing (via cpp_handle_deferred_pragma) may result in /* Pragma processing (via cpp_handle_deferred_pragma) may result in
...@@ -283,26 +285,13 @@ cp_lexer_new_from_tokens (cp_token_cache *cache) ...@@ -283,26 +285,13 @@ cp_lexer_new_from_tokens (cp_token_cache *cache)
cp_token *first = cache->first; cp_token *first = cache->first;
cp_token *last = cache->last; cp_token *last = cache->last;
cp_lexer *lexer = GGC_CNEW (cp_lexer); cp_lexer *lexer = GGC_CNEW (cp_lexer);
cp_token *eof;
/* Allocate a new buffer. The reason we do this is to make sure
there's a CPP_EOF token at the end. An alternative would be to
modify cp_lexer_peek_token so that it checks for end-of-buffer
and returns a CPP_EOF when appropriate. */
lexer->buffer = GGC_NEWVEC (cp_token, (last - first) + 1);
memcpy (lexer->buffer, first, sizeof (cp_token) * (last - first));
lexer->next_token = lexer->buffer;
lexer->buffer_end = lexer->last_token = lexer->buffer + (last - first);
eof = lexer->buffer + (last - first); /* We do not own the buffer. */
eof->type = CPP_EOF; lexer->buffer = lexer->buffer_end = NULL;
eof->location = UNKNOWN_LOCATION; lexer->next_token = first == last ? &eof_token : first;
eof->value = NULL_TREE; lexer->last_token = last;
eof->keyword = RID_MAX;
lexer->saved_tokens = VEC_alloc (cp_token_position, CP_SAVED_TOKEN_STACK);
/* Create the SAVED_TOKENS stack. */
VARRAY_INT_INIT (lexer->saved_tokens, CP_SAVED_TOKENS_SIZE, "saved_tokens");
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
/* Initially we are not debugging. */ /* Initially we are not debugging. */
...@@ -318,7 +307,9 @@ cp_lexer_new_from_tokens (cp_token_cache *cache) ...@@ -318,7 +307,9 @@ cp_lexer_new_from_tokens (cp_token_cache *cache)
static void static void
cp_lexer_destroy (cp_lexer *lexer) cp_lexer_destroy (cp_lexer *lexer)
{ {
ggc_free (lexer->buffer); if (lexer->buffer)
ggc_free (lexer->buffer);
VEC_free (cp_token_position, lexer->saved_tokens);
ggc_free (lexer); ggc_free (lexer);
} }
...@@ -334,51 +325,26 @@ cp_lexer_debugging_p (cp_lexer *lexer) ...@@ -334,51 +325,26 @@ cp_lexer_debugging_p (cp_lexer *lexer)
#endif /* ENABLE_CHECKING */ #endif /* ENABLE_CHECKING */
/* TOKEN points into the circular token buffer. Return a pointer to static inline cp_token_position
the next token in the buffer. */ cp_lexer_token_position (cp_lexer *lexer, bool previous_p)
static inline cp_token *
cp_lexer_next_token (cp_lexer* lexer ATTRIBUTE_UNUSED, cp_token* token)
{ {
token++; gcc_assert (!previous_p || lexer->next_token != &eof_token);
return token;
return lexer->next_token - previous_p;
} }
/* TOKEN points into the circular token buffer. Return a pointer to
the previous token in the buffer. */
static inline cp_token * static inline cp_token *
cp_lexer_prev_token (cp_lexer* lexer ATTRIBUTE_UNUSED, cp_token* token) cp_lexer_token_at (cp_lexer *lexer ATTRIBUTE_UNUSED, cp_token_position pos)
{ {
return token - 1; return pos;
} }
/* nonzero if we are presently saving tokens. */ /* nonzero if we are presently saving tokens. */
static int static inline int
cp_lexer_saving_tokens (const cp_lexer* lexer) cp_lexer_saving_tokens (const cp_lexer* lexer)
{ {
return VARRAY_ACTIVE_SIZE (lexer->saved_tokens) != 0; return VEC_length (cp_token_position, lexer->saved_tokens) != 0;
}
/* Return a pointer to the token that is N tokens beyond TOKEN in the
buffer. */
static inline cp_token *
cp_lexer_advance_token (cp_lexer *lexer ATTRIBUTE_UNUSED,
cp_token *token, ptrdiff_t n)
{
return token + n;
}
/* Returns the number of times that START would have to be incremented
to reach FINISH. If START and FINISH are the same, returns zero. */
static inline ptrdiff_t
cp_lexer_token_difference (cp_lexer* lexer ATTRIBUTE_UNUSED,
cp_token* start, cp_token* finish)
{
return finish - start;
} }
/* If the buffer is full, make it bigger. */ /* If the buffer is full, make it bigger. */
...@@ -491,25 +457,14 @@ static inline cp_token * ...@@ -491,25 +457,14 @@ static inline cp_token *
cp_lexer_peek_token (cp_lexer *lexer) cp_lexer_peek_token (cp_lexer *lexer)
{ {
if (cp_lexer_debugging_p (lexer)) if (cp_lexer_debugging_p (lexer))
cp_lexer_peek_token_emit_debug_info (lexer, lexer->next_token); {
fputs ("cp_lexer: peeking at token: ", cp_lexer_debug_stream);
cp_lexer_print_token (cp_lexer_debug_stream, lexer->next_token);
putc ('\n', cp_lexer_debug_stream);
}
return lexer->next_token; return lexer->next_token;
} }
#ifdef ENABLE_CHECKING
/* Emit debug output for cp_lexer_peek_token. Split out into a
separate function so that cp_lexer_peek_token can be small and
inlinable. */
static void
cp_lexer_peek_token_emit_debug_info (cp_lexer *lexer ATTRIBUTE_UNUSED,
cp_token *token ATTRIBUTE_UNUSED)
{
fputs ("cp_lexer: peeking at token: ", cp_lexer_debug_stream);
cp_lexer_print_token (cp_lexer_debug_stream, token);
putc ('\n', cp_lexer_debug_stream);
}
#endif
/* Return true if the next token has the indicated TYPE. */ /* Return true if the next token has the indicated TYPE. */
static inline bool static inline bool
...@@ -551,7 +506,7 @@ cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n) ...@@ -551,7 +506,7 @@ cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n)
cp_token *token; cp_token *token;
/* N is 1-based, not zero-based. */ /* N is 1-based, not zero-based. */
gcc_assert (n > 0); gcc_assert (n > 0 && lexer->next_token != &eof_token);
if (cp_lexer_debugging_p (lexer)) if (cp_lexer_debugging_p (lexer))
fprintf (cp_lexer_debug_stream, fprintf (cp_lexer_debug_stream,
...@@ -562,6 +517,12 @@ cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n) ...@@ -562,6 +517,12 @@ cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n)
while (n != 0) while (n != 0)
{ {
++token; ++token;
if (token == lexer->last_token)
{
token = &eof_token;
break;
}
if (token->type != CPP_PURGED) if (token->type != CPP_PURGED)
--n; --n;
} }
...@@ -583,12 +544,22 @@ cp_lexer_consume_token (cp_lexer* lexer) ...@@ -583,12 +544,22 @@ cp_lexer_consume_token (cp_lexer* lexer)
{ {
cp_token *token = lexer->next_token; cp_token *token = lexer->next_token;
gcc_assert (token != &eof_token);
do do
++lexer->next_token; {
lexer->next_token++;
if (lexer->next_token == lexer->last_token)
{
lexer->next_token = &eof_token;
break;
}
}
while (lexer->next_token->type == CPP_PURGED); while (lexer->next_token->type == CPP_PURGED);
cp_lexer_set_source_position_from_token (token); cp_lexer_set_source_position_from_token (token);
/* Provide debugging output. */ /* Provide debugging output. */
if (cp_lexer_debugging_p (lexer)) if (cp_lexer_debugging_p (lexer))
{ {
...@@ -596,7 +567,7 @@ cp_lexer_consume_token (cp_lexer* lexer) ...@@ -596,7 +567,7 @@ cp_lexer_consume_token (cp_lexer* lexer)
cp_lexer_print_token (cp_lexer_debug_stream, token); cp_lexer_print_token (cp_lexer_debug_stream, token);
putc ('\n', cp_lexer_debug_stream); putc ('\n', cp_lexer_debug_stream);
} }
return token; return token;
} }
...@@ -608,14 +579,24 @@ static void ...@@ -608,14 +579,24 @@ static void
cp_lexer_purge_token (cp_lexer *lexer) cp_lexer_purge_token (cp_lexer *lexer)
{ {
cp_token *tok = lexer->next_token; cp_token *tok = lexer->next_token;
gcc_assert (tok != &eof_token);
tok->type = CPP_PURGED; tok->type = CPP_PURGED;
tok->location = UNKNOWN_LOCATION; tok->location = UNKNOWN_LOCATION;
tok->value = NULL_TREE; tok->value = NULL_TREE;
tok->keyword = RID_MAX; tok->keyword = RID_MAX;
do do
++lexer->next_token; {
while (lexer->next_token->type == CPP_PURGED); tok++;
if (tok == lexer->last_token)
{
tok = &eof_token;
break;
}
}
while (tok->type == CPP_PURGED);
lexer->next_token = tok;
} }
/* Permanently remove all tokens after TOK, up to, but not /* Permanently remove all tokens after TOK, up to, but not
...@@ -625,9 +606,11 @@ cp_lexer_purge_token (cp_lexer *lexer) ...@@ -625,9 +606,11 @@ cp_lexer_purge_token (cp_lexer *lexer)
static void static void
cp_lexer_purge_tokens_after (cp_lexer *lexer, cp_token *tok) cp_lexer_purge_tokens_after (cp_lexer *lexer, cp_token *tok)
{ {
cp_token *peek; cp_token *peek = lexer->next_token;
peek = cp_lexer_peek_token (lexer); if (peek == &eof_token)
peek = lexer->last_token;
gcc_assert (tok < peek); gcc_assert (tok < peek);
for ( tok += 1; tok != peek; tok += 1) for ( tok += 1; tok != peek; tok += 1)
...@@ -668,10 +651,7 @@ cp_lexer_save_tokens (cp_lexer* lexer) ...@@ -668,10 +651,7 @@ cp_lexer_save_tokens (cp_lexer* lexer)
if (cp_lexer_debugging_p (lexer)) if (cp_lexer_debugging_p (lexer))
fprintf (cp_lexer_debug_stream, "cp_lexer: saving tokens\n"); fprintf (cp_lexer_debug_stream, "cp_lexer: saving tokens\n");
VARRAY_PUSH_INT (lexer->saved_tokens, VEC_safe_push (cp_token_position, lexer->saved_tokens, lexer->next_token);
cp_lexer_token_difference (lexer,
lexer->buffer,
lexer->next_token));
} }
/* Commit to the portion of the token stream most recently saved. */ /* Commit to the portion of the token stream most recently saved. */
...@@ -683,7 +663,7 @@ cp_lexer_commit_tokens (cp_lexer* lexer) ...@@ -683,7 +663,7 @@ cp_lexer_commit_tokens (cp_lexer* lexer)
if (cp_lexer_debugging_p (lexer)) if (cp_lexer_debugging_p (lexer))
fprintf (cp_lexer_debug_stream, "cp_lexer: committing tokens\n"); fprintf (cp_lexer_debug_stream, "cp_lexer: committing tokens\n");
VARRAY_POP (lexer->saved_tokens); VEC_pop (cp_token_position, lexer->saved_tokens);
} }
/* Return all tokens saved since the last call to cp_lexer_save_tokens /* Return all tokens saved since the last call to cp_lexer_save_tokens
...@@ -692,20 +672,11 @@ cp_lexer_commit_tokens (cp_lexer* lexer) ...@@ -692,20 +672,11 @@ cp_lexer_commit_tokens (cp_lexer* lexer)
static void static void
cp_lexer_rollback_tokens (cp_lexer* lexer) cp_lexer_rollback_tokens (cp_lexer* lexer)
{ {
size_t delta;
/* Provide debugging output. */ /* Provide debugging output. */
if (cp_lexer_debugging_p (lexer)) if (cp_lexer_debugging_p (lexer))
fprintf (cp_lexer_debug_stream, "cp_lexer: restoring tokens\n"); fprintf (cp_lexer_debug_stream, "cp_lexer: restoring tokens\n");
/* Find the token that was the NEXT_TOKEN when we started saving lexer->next_token = VEC_pop (cp_token_position, lexer->saved_tokens);
tokens. */
delta = VARRAY_TOP_INT(lexer->saved_tokens);
/* Make it the next token again now. */
lexer->next_token = cp_lexer_advance_token (lexer, lexer->buffer, delta);
/* Stop saving tokens. */
VARRAY_POP (lexer->saved_tokens);
} }
/* Print a representation of the TOKEN on the STREAM. */ /* Print a representation of the TOKEN on the STREAM. */
...@@ -1956,8 +1927,7 @@ static void ...@@ -1956,8 +1927,7 @@ static void
cp_parser_check_for_invalid_template_id (cp_parser* parser, cp_parser_check_for_invalid_template_id (cp_parser* parser,
tree type) tree type)
{ {
ptrdiff_t start; cp_token_position start = 0;
cp_token *token;
if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
{ {
...@@ -1970,28 +1940,15 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser, ...@@ -1970,28 +1940,15 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser,
/* Remember the location of the invalid "<". */ /* Remember the location of the invalid "<". */
if (cp_parser_parsing_tentatively (parser) if (cp_parser_parsing_tentatively (parser)
&& !cp_parser_committed_to_tentative_parse (parser)) && !cp_parser_committed_to_tentative_parse (parser))
{ start = cp_lexer_token_position (parser->lexer, true);
token = cp_lexer_peek_token (parser->lexer);
token = cp_lexer_prev_token (parser->lexer, token);
start = cp_lexer_token_difference (parser->lexer,
parser->lexer->buffer,
token);
}
else
start = -1;
/* Consume the "<". */ /* Consume the "<". */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
/* Parse the template arguments. */ /* Parse the template arguments. */
cp_parser_enclosed_template_argument_list (parser); cp_parser_enclosed_template_argument_list (parser);
/* Permanently remove the invalid template arguments so that /* Permanently remove the invalid template arguments so that
this error message is not issued again. */ this error message is not issued again. */
if (start >= 0) if (start)
{ cp_lexer_purge_tokens_after (parser->lexer, start);
token = cp_lexer_advance_token (parser->lexer,
parser->lexer->buffer,
start);
cp_lexer_purge_tokens_after (parser->lexer, token);
}
} }
} }
...@@ -2634,9 +2591,6 @@ cp_parser_translation_unit (cp_parser* parser) ...@@ -2634,9 +2591,6 @@ cp_parser_translation_unit (cp_parser* parser)
/* If there are no tokens left then all went well. */ /* If there are no tokens left then all went well. */
if (cp_lexer_next_token_is (parser->lexer, CPP_EOF)) if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
{ {
/* Consume the EOF token. */
cp_parser_require (parser, CPP_EOF, "end-of-file");
/* Get rid of the token array; we don't need it any more. */ /* Get rid of the token array; we don't need it any more. */
cp_lexer_destroy (parser->lexer); cp_lexer_destroy (parser->lexer);
parser->lexer = NULL; parser->lexer = NULL;
...@@ -3382,8 +3336,8 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, ...@@ -3382,8 +3336,8 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
{ {
bool success = false; bool success = false;
tree access_check = NULL_TREE; tree access_check = NULL_TREE;
ptrdiff_t start; cp_token_position start = 0;
cp_token* token; cp_token *token;
/* If the next token corresponds to a nested name specifier, there /* If the next token corresponds to a nested name specifier, there
is no need to reparse it. However, if CHECK_DEPENDENCY_P is is no need to reparse it. However, if CHECK_DEPENDENCY_P is
...@@ -3402,14 +3356,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, ...@@ -3402,14 +3356,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
/* Remember where the nested-name-specifier starts. */ /* Remember where the nested-name-specifier starts. */
if (cp_parser_parsing_tentatively (parser) if (cp_parser_parsing_tentatively (parser)
&& !cp_parser_committed_to_tentative_parse (parser)) && !cp_parser_committed_to_tentative_parse (parser))
{ start = cp_lexer_token_position (parser->lexer, false);
token = cp_lexer_peek_token (parser->lexer);
start = cp_lexer_token_difference (parser->lexer,
parser->lexer->buffer,
token);
}
else
start = -1;
push_deferring_access_checks (dk_deferred); push_deferring_access_checks (dk_deferred);
...@@ -3570,21 +3517,18 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, ...@@ -3570,21 +3517,18 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
token. That way, should we re-parse the token stream, we will token. That way, should we re-parse the token stream, we will
not have to repeat the effort required to do the parse, nor will not have to repeat the effort required to do the parse, nor will
we issue duplicate error messages. */ we issue duplicate error messages. */
if (success && start >= 0) if (success && start)
{ {
/* Find the token that corresponds to the start of the cp_token *token = cp_lexer_token_at (parser->lexer, start);
template-id. */
token = cp_lexer_advance_token (parser->lexer,
parser->lexer->buffer,
start);
/* Reset the contents of the START token. */ /* Reset the contents of the START token. */
token->type = CPP_NESTED_NAME_SPECIFIER; token->type = CPP_NESTED_NAME_SPECIFIER;
token->value = build_tree_list (access_check, parser->scope); token->value = build_tree_list (access_check, parser->scope);
TREE_TYPE (token->value) = parser->qualifying_scope; TREE_TYPE (token->value) = parser->qualifying_scope;
token->keyword = RID_MAX; token->keyword = RID_MAX;
/* Purge all subsequent tokens. */ /* Purge all subsequent tokens. */
cp_lexer_purge_tokens_after (parser->lexer, token); cp_lexer_purge_tokens_after (parser->lexer, start);
} }
pop_deferring_access_checks (); pop_deferring_access_checks ();
...@@ -8358,7 +8302,7 @@ cp_parser_template_id (cp_parser *parser, ...@@ -8358,7 +8302,7 @@ cp_parser_template_id (cp_parser *parser,
tree template; tree template;
tree arguments; tree arguments;
tree template_id; tree template_id;
ptrdiff_t start_of_id; cp_token_position start_of_id = 0;
tree access_check = NULL_TREE; tree access_check = NULL_TREE;
cp_token *next_token, *next_token_2; cp_token *next_token, *next_token_2;
bool is_identifier; bool is_identifier;
...@@ -8395,14 +8339,7 @@ cp_parser_template_id (cp_parser *parser, ...@@ -8395,14 +8339,7 @@ cp_parser_template_id (cp_parser *parser,
/* Remember where the template-id starts. */ /* Remember where the template-id starts. */
if (cp_parser_parsing_tentatively (parser) if (cp_parser_parsing_tentatively (parser)
&& !cp_parser_committed_to_tentative_parse (parser)) && !cp_parser_committed_to_tentative_parse (parser))
{ start_of_id = cp_lexer_token_position (parser->lexer, false);
next_token = cp_lexer_peek_token (parser->lexer);
start_of_id = cp_lexer_token_difference (parser->lexer,
parser->lexer->buffer,
next_token);
}
else
start_of_id = -1;
push_deferring_access_checks (dk_deferred); push_deferring_access_checks (dk_deferred);
...@@ -8503,22 +8440,17 @@ cp_parser_template_id (cp_parser *parser, ...@@ -8503,22 +8440,17 @@ cp_parser_template_id (cp_parser *parser,
the effort required to do the parse, nor will we issue duplicate the effort required to do the parse, nor will we issue duplicate
error messages about problems during instantiation of the error messages about problems during instantiation of the
template. */ template. */
if (start_of_id >= 0) if (start_of_id)
{ {
cp_token *token; cp_token *token = cp_lexer_token_at (parser->lexer, start_of_id);
/* Find the token that corresponds to the start of the
template-id. */
token = cp_lexer_advance_token (parser->lexer,
parser->lexer->buffer,
start_of_id);
/* Reset the contents of the START_OF_ID token. */ /* Reset the contents of the START_OF_ID token. */
token->type = CPP_TEMPLATE_ID; token->type = CPP_TEMPLATE_ID;
token->value = build_tree_list (access_check, template_id); token->value = build_tree_list (access_check, template_id);
token->keyword = RID_MAX; token->keyword = RID_MAX;
/* Purge all subsequent tokens. */ /* Purge all subsequent tokens. */
cp_lexer_purge_tokens_after (parser->lexer, token); cp_lexer_purge_tokens_after (parser->lexer, start_of_id);
} }
pop_deferring_access_checks (); pop_deferring_access_checks ();
...@@ -8628,8 +8560,8 @@ cp_parser_template_name (cp_parser* parser, ...@@ -8628,8 +8560,8 @@ cp_parser_template_name (cp_parser* parser,
need the template keyword before their name. */ need the template keyword before their name. */
&& !constructor_name_p (identifier, parser->scope)) && !constructor_name_p (identifier, parser->scope))
{ {
ptrdiff_t start; cp_token_position start = 0;
cp_token* token;
/* Explain what went wrong. */ /* Explain what went wrong. */
error ("non-template %qD used as template", identifier); error ("non-template %qD used as template", identifier);
inform ("use %<%T::template %D%> to indicate that it is a template", inform ("use %<%T::template %D%> to indicate that it is a template",
...@@ -8640,14 +8572,8 @@ cp_parser_template_name (cp_parser* parser, ...@@ -8640,14 +8572,8 @@ cp_parser_template_name (cp_parser* parser,
&& !cp_parser_committed_to_tentative_parse (parser)) && !cp_parser_committed_to_tentative_parse (parser))
{ {
cp_parser_simulate_error (parser); cp_parser_simulate_error (parser);
token = cp_lexer_peek_token (parser->lexer); start = cp_lexer_token_position (parser->lexer, true);
token = cp_lexer_prev_token (parser->lexer, token);
start = cp_lexer_token_difference (parser->lexer,
parser->lexer->buffer,
token);
} }
else
start = -1;
/* Parse the template arguments so that we can issue error /* Parse the template arguments so that we can issue error
messages about them. */ messages about them. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
...@@ -8662,13 +8588,8 @@ cp_parser_template_name (cp_parser* parser, ...@@ -8662,13 +8588,8 @@ cp_parser_template_name (cp_parser* parser,
template argument list. That will prevent duplicate template argument list. That will prevent duplicate
error messages from being issued about the missing error messages from being issued about the missing
"template" keyword. */ "template" keyword. */
if (start >= 0) if (start)
{ cp_lexer_purge_tokens_after (parser->lexer, start);
token = cp_lexer_advance_token (parser->lexer,
parser->lexer->buffer,
start);
cp_lexer_purge_tokens_after (parser->lexer, token);
}
if (is_identifier) if (is_identifier)
*is_identifier = true; *is_identifier = true;
return identifier; return identifier;
......
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