bool,
struct c_declarator *);
static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree);
-static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree);
+static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
+ tree);
static struct c_parm *c_parser_parameter_declaration (c_parser *, tree);
static tree c_parser_simple_asm_expr (c_parser *);
static tree c_parser_attributes (c_parser *);
static void c_parser_objc_method_definition (c_parser *);
static void c_parser_objc_methodprotolist (c_parser *);
static void c_parser_objc_methodproto (c_parser *);
-static tree c_parser_objc_method_decl (c_parser *, bool, tree *);
+static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
static tree c_parser_objc_type_name (c_parser *);
static tree c_parser_objc_protocol_refs (c_parser *);
static void c_parser_objc_try_catch_finally_statement (c_parser *);
{
struct c_declarator *declarator;
bool dummy = false;
+ timevar_id_t tv;
tree fnbody;
/* Declaring either one or more declarators (in which case we
should diagnose if there were no declaration specifiers) or a
c_pop_function_context ();
break;
}
+
+ if (DECL_DECLARED_INLINE_P (current_function_decl))
+ tv = TV_PARSE_INLINE;
+ else
+ tv = TV_PARSE_FUNC;
+ timevar_push (tv);
+
/* Parse old-style parameter declarations. ??? Attributes are
not allowed to start declaration specifiers here because of a
syntax conflict between a function declaration with attribute
add_stmt (fnbody);
finish_function ();
}
+
+ timevar_pop (tv);
break;
}
}
{
/* Parse an enum definition. */
struct c_enum_contents the_enum;
- tree type = start_enum (enum_loc, &the_enum, ident);
+ tree type;
tree postfix_attrs;
/* We chain the enumerators in reverse order, then put them in
forward order at the end. */
- tree values = NULL_TREE;
+ tree values;
+ timevar_push (TV_PARSE_ENUM);
+ type = start_enum (enum_loc, &the_enum, ident);
+ values = NULL_TREE;
c_parser_consume_token (parser);
while (true)
{
ret.kind = ctsk_tagdef;
ret.expr = NULL_TREE;
ret.expr_const_operands = true;
+ timevar_pop (TV_PARSE_ENUM);
return ret;
}
else if (!ident)
semicolon separated fields than comma separated fields, and
so we'll be minimizing the number of node traversals required
by chainon. */
- tree contents = NULL_TREE;
+ tree contents;
+ timevar_push (TV_PARSE_STRUCT);
+ contents = NULL_TREE;
c_parser_consume_token (parser);
/* Handle the Objective-C @defs construct,
e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
ret.kind = ctsk_tagdef;
ret.expr = NULL_TREE;
ret.expr_const_operands = true;
+ timevar_pop (TV_PARSE_STRUCT);
return ret;
}
else if (!ident)
}
else
{
- struct c_arg_info *ret = c_parser_parms_list_declarator (parser, attrs);
+ struct c_arg_info *ret = c_parser_parms_list_declarator (parser, attrs,
+ NULL);
pop_scope ();
return ret;
}
/* Parse a parameter list (possibly empty), including the closing
parenthesis but not the opening one. ATTRS are the attributes at
- the start of the list. */
+ the start of the list. EXPR is NULL or an expression that needs to
+ be evaluated for the side effects of array size expressions in the
+ parameters. */
static struct c_arg_info *
-c_parser_parms_list_declarator (c_parser *parser, tree attrs)
+c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr)
{
bool bad_parm = false;
+
/* ??? Following the old parser, forward parameter declarations may
use abstract declarators, and if no real parameter declarations
follow the forward declarations then this is not diagnosed. Also
if (parm == NULL)
bad_parm = true;
else
- push_parm_decl (parm);
+ push_parm_decl (parm, &expr);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
tree new_attrs;
c_parser_consume_token (parser);
mark_forward_parm_decls ();
new_attrs = c_parser_attributes (parser);
- return c_parser_parms_list_declarator (parser, new_attrs);
+ return c_parser_parms_list_declarator (parser, new_attrs, expr);
}
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
{
c_parser_consume_token (parser);
if (bad_parm)
- {
- get_pending_sizes ();
- return NULL;
- }
+ return NULL;
else
- return get_parm_info (false);
+ return get_parm_info (false, expr);
}
if (!c_parser_require (parser, CPP_COMMA,
"expected %<;%>, %<,%> or %<)%>"))
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- get_pending_sizes ();
return NULL;
}
if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
{
c_parser_consume_token (parser);
if (bad_parm)
- {
- get_pending_sizes ();
- return NULL;
- }
+ return NULL;
else
- return get_parm_info (true);
+ return get_parm_info (true, expr);
}
else
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
- get_pending_sizes ();
return NULL;
}
}
c_parser_consume_token (parser);
brace_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
- if (cur_stmt_list == NULL)
+ if (!building_stmt_list_p ())
{
error_at (loc, "braced-group within expression allowed "
"only inside a function");
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
- "extra semicolon in struct or union specified");
+ "extra semicolon");
c_parser_consume_token (parser);
continue;
}
/* Parse some comma-separated declarations. */
decls = c_parser_struct_declaration (parser);
- {
- /* Comma-separated instance variables are chained together in
- reverse order; add them one by one. */
- tree ivar = nreverse (decls);
- for (; ivar; ivar = DECL_CHAIN (ivar))
- objc_add_instance_variable (copy_node (ivar));
- }
+ if (decls == NULL)
+ {
+ /* There is a syntax error. We want to skip the offending
+ tokens up to the next ';' (included) or '}'
+ (excluded). */
+
+ /* First, skip manually a ')' or ']'. This is because they
+ reduce the nesting level, so c_parser_skip_until_found()
+ wouldn't be able to skip past them. */
+ c_token *token = c_parser_peek_token (parser);
+ if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
+ c_parser_consume_token (parser);
+
+ /* Then, do the standard skipping. */
+ c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
+
+ /* We hopefully recovered. Start normal parsing again. */
+ parser->error = false;
+ continue;
+ }
+ else
+ {
+ /* Comma-separated instance variables are chained together
+ in reverse order; add them one by one. */
+ tree ivar = nreverse (decls);
+ for (; ivar; ivar = DECL_CHAIN (ivar))
+ objc_add_instance_variable (copy_node (ivar));
+ }
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
}
if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
|| c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
{
- tree list = NULL_TREE;
/* Any identifiers, including those declared as type names, are
OK here. */
while (true)
break;
}
id = c_parser_peek_token (parser)->value;
- list = chainon (list, build_tree_list (NULL_TREE, id));
+ objc_declare_protocol (id, attributes);
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_COMMA))
c_parser_consume_token (parser);
break;
}
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
- objc_declare_protocols (list, attributes);
}
else
{
c_parser_objc_method_definition (c_parser *parser)
{
bool is_class_method = c_parser_objc_method_type (parser);
- tree decl, attributes = NULL_TREE;
+ tree decl, attributes = NULL_TREE, expr = NULL_TREE;
parser->objc_pq_context = true;
- decl = c_parser_objc_method_decl (parser, is_class_method, &attributes);
+ decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
+ &expr);
if (decl == error_mark_node)
return; /* Bail here. */
}
parser->objc_pq_context = false;
- if (objc_start_method_definition (is_class_method, decl, attributes))
+ if (objc_start_method_definition (is_class_method, decl, attributes, expr))
{
add_stmt (c_parser_compound_statement (parser));
objc_finish_method_definition (current_function_decl);
/* Remember protocol qualifiers in prototypes. */
parser->objc_pq_context = true;
- decl = c_parser_objc_method_decl (parser, is_class_method, &attributes);
+ decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
+ NULL);
/* Forget protocol qualifiers now. */
parser->objc_pq_context = false;
*/
static tree
-c_parser_objc_method_decl (c_parser *parser, bool is_class_method, tree *attributes)
+c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
+ tree *attributes, tree *expr)
{
tree type = NULL_TREE;
tree sel;
if (parm == NULL)
break;
parms = chainon (parms,
- build_tree_list (NULL_TREE, grokparm (parm)));
+ build_tree_list (NULL_TREE, grokparm (parm, expr)));
}
sel = list;
}
if (parm == NULL)
parameter_declaration = error_mark_node;
else
- parameter_declaration = grokparm (parm);
+ parameter_declaration = grokparm (parm, NULL);
}
if (seen_open_paren)
c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");