Commit e5976695 by Mark Mitchell Committed by Mark Mitchell

parser.c (cp_parser_context_free_list): New variable.

	* parser.c (cp_parser_context_free_list): New variable.
	(cp_parser_context_new): Use it.
	(cp_parser_error): Check return code from
	cp_parser_simulate_error.
	(cp_parser_simulate_error): Return a value.
	(cp_parser_id_expression): Optimize common case.
	(cp_parser_class_name): Likewise.
	(cp_parser_class_specifier): Adjust call to
	cp_parser_late_parsing_default_args.
	(cp_parser_lookup_name): Optimize common case.
	(cp_parser_late_parsing_for_member): Adjust call to
	cp_parser_late_parsing_default_args.
	(cp_parser_late_parsing_default_args): Add scope parameter.
	(cp_parser_require): Avoid creating the error message unless it's
	needed.
	(cp_parser_parse_definitely): Place free'd contexts on the free
	list.

From-SVN: r60665
parent 9f1cf235
2002-12-30 Mark Mitchell <mark@codesourcery.com> 2002-12-30 Mark Mitchell <mark@codesourcery.com>
* parser.c (cp_parser_context_free_list): New variable.
(cp_parser_context_new): Use it.
(cp_parser_error): Check return code from
cp_parser_simulate_error.
(cp_parser_simulate_error): Return a value.
(cp_parser_id_expression): Optimize common case.
(cp_parser_class_name): Likewise.
(cp_parser_class_specifier): Adjust call to
cp_parser_late_parsing_default_args.
(cp_parser_lookup_name): Optimize common case.
(cp_parser_late_parsing_for_member): Adjust call to
cp_parser_late_parsing_default_args.
(cp_parser_late_parsing_default_args): Add scope parameter.
(cp_parser_require): Avoid creating the error message unless it's
needed.
(cp_parser_parse_definitely): Place free'd contexts on the free
list.
* parser.c (cp_parser_declaration_seq_opt): Handle pending_lang_change. * parser.c (cp_parser_declaration_seq_opt): Handle pending_lang_change.
2002-12-30 David Edelsohn <edelsohn@gnu.org> 2002-12-30 David Edelsohn <edelsohn@gnu.org>
......
...@@ -1196,6 +1196,10 @@ typedef struct cp_parser_context GTY (()) ...@@ -1196,6 +1196,10 @@ typedef struct cp_parser_context GTY (())
static cp_parser_context *cp_parser_context_new static cp_parser_context *cp_parser_context_new
PARAMS ((cp_parser_context *)); PARAMS ((cp_parser_context *));
/* Class variables. */
static GTY(()) cp_parser_context* cp_parser_context_free_list;
/* Constructors and destructors. */ /* Constructors and destructors. */
/* Construct a new context. The context below this one on the stack /* Construct a new context. The context below this one on the stack
...@@ -1208,8 +1212,16 @@ cp_parser_context_new (next) ...@@ -1208,8 +1212,16 @@ cp_parser_context_new (next)
cp_parser_context *context; cp_parser_context *context;
/* Allocate the storage. */ /* Allocate the storage. */
context = ((cp_parser_context *) if (cp_parser_context_free_list != NULL)
ggc_alloc_cleared (sizeof (cp_parser_context))); {
/* Pull the first entry from the free list. */
context = cp_parser_context_free_list;
cp_parser_context_free_list = context->next;
memset ((char *)context, 0, sizeof (*context));
}
else
context = ((cp_parser_context *)
ggc_alloc_cleared (sizeof (cp_parser_context)));
/* No errors have occurred yet in this context. */ /* No errors have occurred yet in this context. */
context->status = CP_PARSER_STATUS_KIND_NO_ERROR; context->status = CP_PARSER_STATUS_KIND_NO_ERROR;
/* If this is not the bottomost context, copy information that we /* If this is not the bottomost context, copy information that we
...@@ -1704,7 +1716,7 @@ static tree cp_parser_functional_cast ...@@ -1704,7 +1716,7 @@ static tree cp_parser_functional_cast
static void cp_parser_late_parsing_for_member static void cp_parser_late_parsing_for_member
PARAMS ((cp_parser *, tree)); PARAMS ((cp_parser *, tree));
static void cp_parser_late_parsing_default_args static void cp_parser_late_parsing_default_args
PARAMS ((cp_parser *, tree)); (cp_parser *, tree, tree);
static tree cp_parser_sizeof_operand static tree cp_parser_sizeof_operand
PARAMS ((cp_parser *, enum rid)); PARAMS ((cp_parser *, enum rid));
static bool cp_parser_declares_only_class_p static bool cp_parser_declares_only_class_p
...@@ -1741,7 +1753,7 @@ static bool cp_parser_committed_to_tentative_parse ...@@ -1741,7 +1753,7 @@ static bool cp_parser_committed_to_tentative_parse
PARAMS ((cp_parser *)); PARAMS ((cp_parser *));
static void cp_parser_error static void cp_parser_error
PARAMS ((cp_parser *, const char *)); PARAMS ((cp_parser *, const char *));
static void cp_parser_simulate_error static bool cp_parser_simulate_error
PARAMS ((cp_parser *)); PARAMS ((cp_parser *));
static void cp_parser_check_type_definition static void cp_parser_check_type_definition
PARAMS ((cp_parser *)); PARAMS ((cp_parser *));
...@@ -2213,24 +2225,26 @@ cp_parser_error (parser, message) ...@@ -2213,24 +2225,26 @@ cp_parser_error (parser, message)
cp_parser *parser; cp_parser *parser;
const char *message; const char *message;
{ {
/* Remember that we have issued an error. */
cp_parser_simulate_error (parser);
/* Output the MESSAGE -- unless we're parsing tentatively. */ /* Output the MESSAGE -- unless we're parsing tentatively. */
if (!cp_parser_parsing_tentatively (parser) if (!cp_parser_simulate_error (parser))
|| cp_parser_committed_to_tentative_parse (parser))
error (message); error (message);
} }
/* If we are parsing tentatively, remember that an error has occurred /* If we are parsing tentatively, remember that an error has occurred
during this tentative parse. */ during this tentative parse. Returns true if the error was
simulated; false if a messgae should be issued by the caller. */
static void static bool
cp_parser_simulate_error (parser) cp_parser_simulate_error (parser)
cp_parser *parser; cp_parser *parser;
{ {
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))
parser->context->status = CP_PARSER_STATUS_KIND_ERROR; {
parser->context->status = CP_PARSER_STATUS_KIND_ERROR;
return true;
}
return false;
} }
/* This function is called when a type is defined. If type /* This function is called when a type is defined. If type
...@@ -3117,8 +3131,16 @@ cp_parser_id_expression (cp_parser *parser, ...@@ -3117,8 +3131,16 @@ cp_parser_id_expression (cp_parser *parser,
cp_token *token; cp_token *token;
tree id; tree id;
/* We don't know yet whether or not this will be a /* Peek at the next token. */
template-id. */ token = cp_lexer_peek_token (parser->lexer);
/* If it's an identifier, and the next token is not a "<", then
we can avoid the template-id case. This is an optimization
for this common case. */
if (token->type == CPP_NAME
&& cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_LESS)
return cp_parser_identifier (parser);
cp_parser_parse_tentatively (parser); cp_parser_parse_tentatively (parser);
/* Try a template-id. */ /* Try a template-id. */
id = cp_parser_template_id (parser, id = cp_parser_template_id (parser,
...@@ -3128,7 +3150,8 @@ cp_parser_id_expression (cp_parser *parser, ...@@ -3128,7 +3150,8 @@ cp_parser_id_expression (cp_parser *parser,
if (cp_parser_parse_definitely (parser)) if (cp_parser_parse_definitely (parser))
return id; return id;
/* Peek at the next token. */ /* Peek at the next token. (Changes in the token buffer may
have invalidated the pointer obtained above.) */
token = cp_lexer_peek_token (parser->lexer); token = cp_lexer_peek_token (parser->lexer);
switch (token->type) switch (token->type)
...@@ -11331,7 +11354,16 @@ cp_parser_class_name (cp_parser *parser, ...@@ -11331,7 +11354,16 @@ cp_parser_class_name (cp_parser *parser,
tree decl; tree decl;
tree scope; tree scope;
bool typename_p; bool typename_p;
cp_token *token;
/* All class-names start with an identifier. */
token = cp_lexer_peek_token (parser->lexer);
if (token->type != CPP_NAME && token->type != CPP_TEMPLATE_ID)
{
cp_parser_error (parser, "expected class-name");
return error_mark_node;
}
/* PARSER->SCOPE can be cleared when parsing the template-arguments /* PARSER->SCOPE can be cleared when parsing the template-arguments
to a template-id, so we save it here. */ to a template-id, so we save it here. */
scope = parser->scope; scope = parser->scope;
...@@ -11339,21 +11371,11 @@ cp_parser_class_name (cp_parser *parser, ...@@ -11339,21 +11371,11 @@ cp_parser_class_name (cp_parser *parser,
in a qualified name where the enclosing scope is type-dependent. */ in a qualified name where the enclosing scope is type-dependent. */
typename_p = (typename_keyword_p && scope && TYPE_P (scope) typename_p = (typename_keyword_p && scope && TYPE_P (scope)
&& cp_parser_dependent_type_p (scope)); && cp_parser_dependent_type_p (scope));
/* Handle the common case (an identifier, but not a template-id)
/* We don't know whether what comes next is a template-id or efficiently. */
not. */ if (token->type == CPP_NAME
cp_parser_parse_tentatively (parser); && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_LESS)
/* Try a template-id. */
decl = cp_parser_template_id (parser, template_keyword_p,
check_dependency_p);
if (cp_parser_parse_definitely (parser))
{
if (decl == error_mark_node)
return error_mark_node;
}
else
{ {
/* If it wasn't a template-id, try a simple identifier. */
tree identifier; tree identifier;
/* Look for the identifier. */ /* Look for the identifier. */
...@@ -11385,6 +11407,14 @@ cp_parser_class_name (cp_parser *parser, ...@@ -11385,6 +11407,14 @@ cp_parser_class_name (cp_parser *parser,
check_dependency_p); check_dependency_p);
} }
} }
else
{
/* Try a template-id. */
decl = cp_parser_template_id (parser, template_keyword_p,
check_dependency_p);
if (decl == error_mark_node)
return error_mark_node;
}
decl = cp_parser_maybe_treat_template_as_class (decl, class_head_p); decl = cp_parser_maybe_treat_template_as_class (decl, class_head_p);
...@@ -11515,7 +11545,7 @@ cp_parser_class_specifier (parser) ...@@ -11515,7 +11545,7 @@ cp_parser_class_specifier (parser)
parser->default_arg_types; parser->default_arg_types;
parser->default_arg_types = TREE_CHAIN (parser->default_arg_types)) parser->default_arg_types = TREE_CHAIN (parser->default_arg_types))
cp_parser_late_parsing_default_args cp_parser_late_parsing_default_args
(parser, TREE_PURPOSE (parser->default_arg_types)); (parser, TREE_PURPOSE (parser->default_arg_types), NULL_TREE);
/* Reverse the queue, so that we process it in the order the /* Reverse the queue, so that we process it in the order the
functions were declared. */ functions were declared. */
...@@ -13392,9 +13422,7 @@ cp_parser_lookup_name (parser, name, check_access, is_type, ...@@ -13392,9 +13422,7 @@ cp_parser_lookup_name (parser, name, check_access, is_type,
{ {
/* The error message we have to print is too complicated for /* The error message we have to print is too complicated for
cp_parser_error, so we incorporate its actions directly. */ cp_parser_error, so we incorporate its actions directly. */
cp_parser_simulate_error (parser); if (!cp_parser_simulate_error (parser))
if (!cp_parser_parsing_tentatively (parser)
|| cp_parser_committed_to_tentative_parse (parser))
{ {
error ("reference to `%D' is ambiguous", name); error ("reference to `%D' is ambiguous", name);
print_candidates (decl); print_candidates (decl);
...@@ -14216,11 +14244,10 @@ cp_parser_late_parsing_for_member (parser, member_function) ...@@ -14216,11 +14244,10 @@ cp_parser_late_parsing_for_member (parser, member_function)
/* If there are default arguments that have not yet been processed, /* If there are default arguments that have not yet been processed,
take care of them now. */ take care of them now. */
if (DECL_FUNCTION_MEMBER_P (member_function)) cp_parser_late_parsing_default_args (parser, TREE_TYPE (member_function),
push_nested_class (DECL_CONTEXT (member_function), 1); DECL_FUNCTION_MEMBER_P (member_function)
cp_parser_late_parsing_default_args (parser, TREE_TYPE (member_function)); ? DECL_CONTEXT (member_function)
if (DECL_FUNCTION_MEMBER_P (member_function)) : NULL_TREE);
pop_nested_class ();
/* If the body of the function has not yet been parsed, parse it /* If the body of the function has not yet been parsed, parse it
now. */ now. */
...@@ -14276,12 +14303,12 @@ cp_parser_late_parsing_for_member (parser, member_function) ...@@ -14276,12 +14303,12 @@ cp_parser_late_parsing_for_member (parser, member_function)
} }
/* TYPE is a FUNCTION_TYPE or METHOD_TYPE which contains a parameter /* TYPE is a FUNCTION_TYPE or METHOD_TYPE which contains a parameter
with an unparsed DEFAULT_ARG. Parse those default args now. */ with an unparsed DEFAULT_ARG. If non-NULL, SCOPE is the class in
whose context name lookups in the default argument should occur.
Parse the default args now. */
static void static void
cp_parser_late_parsing_default_args (parser, type) cp_parser_late_parsing_default_args (cp_parser *parser, tree type, tree scope)
cp_parser *parser;
tree type;
{ {
cp_lexer *saved_lexer; cp_lexer *saved_lexer;
cp_token_cache *tokens; cp_token_cache *tokens;
...@@ -14312,7 +14339,11 @@ cp_parser_late_parsing_default_args (parser, type) ...@@ -14312,7 +14339,11 @@ cp_parser_late_parsing_default_args (parser, type)
saved_local_variables_forbidden_p = parser->local_variables_forbidden_p; saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
parser->local_variables_forbidden_p = true; parser->local_variables_forbidden_p = true;
/* Parse the assignment-expression. */ /* Parse the assignment-expression. */
if (scope)
push_nested_class (scope, 1);
TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser); TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser);
if (scope)
pop_nested_class ();
/* Restore saved state. */ /* Restore saved state. */
parser->lexer = saved_lexer; parser->lexer = saved_lexer;
...@@ -14450,14 +14481,9 @@ cp_parser_require (parser, type, token_desc) ...@@ -14450,14 +14481,9 @@ cp_parser_require (parser, type, token_desc)
return cp_lexer_consume_token (parser->lexer); return cp_lexer_consume_token (parser->lexer);
else else
{ {
dyn_string_t error_msg; /* Output the MESSAGE -- unless we're parsing tentatively. */
if (!cp_parser_simulate_error (parser))
/* Format the error message. */ error ("expected %s", token_desc);
error_msg = dyn_string_new (0);
dyn_string_append_cstr (error_msg, "expected ");
dyn_string_append_cstr (error_msg, token_desc);
cp_parser_error (parser, error_msg->s);
dyn_string_delete (error_msg);
return NULL; return NULL;
} }
} }
...@@ -14759,15 +14785,16 @@ cp_parser_parse_definitely (parser) ...@@ -14759,15 +14785,16 @@ cp_parser_parse_definitely (parser)
parser->context->deferred_access_checks parser->context->deferred_access_checks
= chainon (parser->context->deferred_access_checks, = chainon (parser->context->deferred_access_checks,
context->deferred_access_checks); context->deferred_access_checks);
return true;
} }
/* Otherwise, if errors occurred, roll back our state so that things /* Otherwise, if errors occurred, roll back our state so that things
are just as they were before we began the tentative parse. */ are just as they were before we began the tentative parse. */
else else
{ cp_lexer_rollback_tokens (parser->lexer);
cp_lexer_rollback_tokens (parser->lexer); /* Add the context to the front of the free list. */
return false; context->next = cp_parser_context_free_list;
} cp_parser_context_free_list = context;
return !error_occurred;
} }
/* Returns non-zero if we are parsing tentatively. */ /* Returns non-zero if we are parsing tentatively. */
......
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