summaryrefslogtreecommitdiff
path: root/gcc/c-parser.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-04-27 12:45:13 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-04-27 12:45:13 +0000
commit268b9e9e95f56a59a8817b28ad59b53f40fc668d (patch)
tree5e9529982daf11d5b3ab800d4c58bc3fbee99d28 /gcc/c-parser.c
parente1910362719612f58bd1ea5050fa7a5175036abc (diff)
downloadgcc-268b9e9e95f56a59a8817b28ad59b53f40fc668d.tar.gz
2009-04-27 Basile Starynkevitch <basile@starynkevitch.net>
MERGED WITH TRUNK r146824:: * gcc/basilys.h: all GTY goes before the identifiers. * gcc/basilys.c: removed errors.h include. * gcc/run-basilys.h: ditto. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@146839 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-parser.c')
-rw-r--r--gcc/c-parser.c294
1 files changed, 212 insertions, 82 deletions
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 1be2ae5a5bc..7fe7fae1cda 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -57,6 +57,7 @@ along with GCC; see the file COPYING3. If not see
#include "vec.h"
#include "target.h"
#include "cgraph.h"
+#include "plugin.h"
/* Initialization routine for this file. */
@@ -136,8 +137,7 @@ typedef enum c_id_kind {
/* A single C token after string literal concatenation and conversion
of preprocessing tokens to tokens. */
-typedef struct c_token GTY (())
-{
+typedef struct GTY (()) c_token {
/* The kind of token. */
ENUM_BITFIELD (cpp_ttype) type : 8;
/* If this token is a CPP_NAME, this value indicates whether also
@@ -158,8 +158,7 @@ typedef struct c_token GTY (())
/* A parser structure recording information about the state and
context of parsing. Includes lexer information with up to two
tokens of look-ahead; more are not needed for C. */
-typedef struct c_parser GTY(())
-{
+typedef struct GTY(()) c_parser {
/* The look-ahead tokens. */
c_token tokens[2];
/* How many look-ahead tokens are available (0, 1 or 2). */
@@ -572,7 +571,11 @@ c_parser_error (c_parser *parser, const char *gmsgid)
CPP_KEYWORD, keywords are treated like
identifiers. */
(token->type == CPP_KEYWORD ? CPP_NAME : token->type),
- token->value);
+ /* ??? The C parser does not save the cpp flags of a
+ token, we need to pass 0 here and we will not get
+ the source spelling of some tokens but rather the
+ canonical spelling. */
+ token->value, /*flags=*/0);
}
/* If the next token is of the indicated TYPE, consume it. Otherwise,
@@ -817,14 +820,12 @@ disable_extension_diagnostics (void)
| (warn_pointer_arith << 1)
| (warn_traditional << 2)
| (flag_iso << 3)
- | (warn_long_long << 4)
- | (cpp_opts->warn_long_long << 5));
+ | (warn_long_long << 4));
cpp_opts->pedantic = pedantic = 0;
warn_pointer_arith = 0;
cpp_opts->warn_traditional = warn_traditional = 0;
flag_iso = 0;
- warn_long_long = 0;
- cpp_opts->warn_long_long = 0;
+ cpp_opts->warn_long_long = warn_long_long = 0;
return ret;
}
@@ -838,8 +839,7 @@ restore_extension_diagnostics (int flags)
warn_pointer_arith = (flags >> 1) & 1;
cpp_opts->warn_traditional = warn_traditional = (flags >> 2) & 1;
flag_iso = (flags >> 3) & 1;
- warn_long_long = (flags >> 4) & 1;
- cpp_opts->warn_long_long = (flags >> 5) & 1;
+ cpp_opts->warn_long_long = warn_long_long = (flags >> 4) & 1;
}
/* Possibly kinds of declarator to parse. */
@@ -915,7 +915,10 @@ static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
struct c_expr);
static struct c_expr c_parser_expression (c_parser *);
static struct c_expr c_parser_expression_conv (c_parser *);
-static tree c_parser_expr_list (c_parser *, bool, bool);
+static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool,
+ VEC(tree,gc) **);
+static void c_parser_release_expr_list (VEC(tree,gc) *);
+static tree c_parser_vec_to_tree_list (VEC(tree,gc) *);
static void c_parser_omp_construct (c_parser *);
static void c_parser_omp_threadprivate (c_parser *);
static void c_parser_omp_barrier (c_parser *);
@@ -1229,7 +1232,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
if (d != error_mark_node)
{
maybe_warn_string_init (TREE_TYPE (d), init);
- finish_decl (d, init.value, asm_name);
+ finish_decl (d, init.value, init.original_type, asm_name);
}
}
else
@@ -1238,7 +1241,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
chainon (postfix_attrs,
all_prefix_attrs));
if (d)
- finish_decl (d, NULL_TREE, asm_name);
+ finish_decl (d, NULL_TREE, NULL_TREE, asm_name);
}
if (c_parser_next_token_is (parser, CPP_COMMA))
{
@@ -1552,6 +1555,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
attrs_ok = true;
seen_type = true;
t = c_parser_struct_or_union_specifier (parser);
+ invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
declspecs_add_type (specs, t);
break;
case RID_TYPEOF:
@@ -2784,6 +2788,7 @@ c_parser_attributes (c_parser *parser)
|| c_parser_next_token_is (parser, CPP_KEYWORD))
{
tree attr, attr_name, attr_args;
+ VEC(tree,gc) *expr_list;
if (c_parser_next_token_is (parser, CPP_COMMA))
{
c_parser_consume_token (parser);
@@ -2862,10 +2867,12 @@ c_parser_attributes (c_parser *parser)
attr_args = build_tree_list (NULL_TREE, arg1);
else
{
+ tree tree_list;
c_parser_consume_token (parser);
- attr_args = tree_cons (NULL_TREE, arg1,
- c_parser_expr_list (parser, false,
- true));
+ expr_list = c_parser_expr_list (parser, false, true, NULL);
+ tree_list = c_parser_vec_to_tree_list (expr_list);
+ attr_args = tree_cons (NULL_TREE, arg1, tree_list);
+ c_parser_release_expr_list (expr_list);
}
}
else
@@ -2873,7 +2880,11 @@ c_parser_attributes (c_parser *parser)
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
attr_args = NULL_TREE;
else
- attr_args = c_parser_expr_list (parser, false, true);
+ {
+ expr_list = c_parser_expr_list (parser, false, true, NULL);
+ attr_args = c_parser_vec_to_tree_list (expr_list);
+ c_parser_release_expr_list (expr_list);
+ }
}
attr = build_tree_list (attr_name, attr_args);
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
@@ -3042,6 +3053,7 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p)
struct c_expr ret;
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, "expected %<}%>");
pop_init_level (0);
return ret;
@@ -3098,6 +3110,7 @@ c_parser_initelt (c_parser *parser)
struct c_expr init;
init.value = error_mark_node;
init.original_code = ERROR_MARK;
+ init.original_type = NULL;
c_parser_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_COMMA, NULL);
process_init_element (init, false);
@@ -3172,6 +3185,7 @@ c_parser_initelt (c_parser *parser)
mexpr.value
= objc_build_message_expr (build_tree_list (rec, args));
mexpr.original_code = ERROR_MARK;
+ mexpr.original_type = NULL;
/* Now parse and process the remainder of the
initializer, starting with this message
expression as a primary-expression. */
@@ -3221,6 +3235,7 @@ c_parser_initelt (c_parser *parser)
struct c_expr init;
init.value = error_mark_node;
init.original_code = ERROR_MARK;
+ init.original_type = NULL;
c_parser_error (parser, "expected %<=%>");
c_parser_skip_until_found (parser, CPP_COMMA, NULL);
process_init_element (init, false);
@@ -3733,12 +3748,13 @@ c_parser_statement_after_labels (c_parser *parser)
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- stmt = c_finish_return (NULL_TREE);
+ stmt = c_finish_return (NULL_TREE, NULL_TREE);
c_parser_consume_token (parser);
}
else
{
- stmt = c_finish_return (c_parser_expression_conv (parser).value);
+ struct c_expr expr = c_parser_expression_conv (parser);
+ stmt = c_finish_return (expr.value, expr.original_type);
goto expect_semicolon;
}
break;
@@ -3821,7 +3837,6 @@ c_parser_condition (c_parser *parser)
cond = c_parser_expression_conv (parser).value;
cond = c_objc_common_truthvalue_conversion (loc, cond);
cond = c_fully_fold (cond, false, NULL);
- protected_set_expr_location (cond, loc);
if (warn_sequence_point)
verify_sequence_points (cond);
return cond;
@@ -4428,7 +4443,8 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
c_parser_consume_token (parser);
rhs = c_parser_expr_no_commas (parser, NULL);
rhs = default_function_array_conversion (rhs);
- ret.value = build_modify_expr (op_location, lhs.value, code, rhs.value);
+ ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
+ code, rhs.value, rhs.original_type);
if (code == NOP_EXPR)
ret.original_code = MODIFY_EXPR;
else
@@ -4436,6 +4452,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
TREE_NO_WARNING (ret.value) = 1;
ret.original_code = ERROR_MARK;
}
+ ret.original_type = NULL;
return ret;
}
@@ -4463,7 +4480,6 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
cond_loc = c_parser_peek_token (parser)->location;
cond = c_parser_binary_expression (parser, after);
- protected_set_expr_location (cond.value, cond_loc);
if (c_parser_next_token_is_not (parser, CPP_QUERY))
return cond;
@@ -4483,6 +4499,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
exp1.value = c_save_expr (default_conversion (cond.value));
if (eptype)
exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
+ exp1.original_type = NULL;
cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
skip_evaluation += cond.value == truthvalue_true_node;
}
@@ -4501,6 +4518,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
skip_evaluation -= cond.value == truthvalue_true_node;
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
exp2 = c_parser_conditional_expression (parser, NULL);
@@ -4510,6 +4528,24 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
cond.original_code == C_MAYBE_CONST_EXPR,
exp1.value, exp2.value);
ret.original_code = ERROR_MARK;
+ if (exp1.value == error_mark_node || exp2.value == error_mark_node)
+ ret.original_type = NULL;
+ else
+ {
+ tree t1, t2;
+
+ /* If both sides are enum type, the default conversion will have
+ made the type of the result be an integer type. We want to
+ remember the enum types we started with. */
+ t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
+ t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
+ ret.original_type = ((t1 != error_mark_node
+ && t2 != error_mark_node
+ && (TYPE_MAIN_VARIANT (t1)
+ == TYPE_MAIN_VARIANT (t2)))
+ ? t1
+ : NULL);
+ }
return ret;
}
@@ -4615,6 +4651,8 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
enum prec prec;
/* The operation on its left. */
enum tree_code op;
+ /* The source location of this operation. */
+ location_t loc;
} stack[NUM_PRECS];
int sp;
/* Location of the binary operator. */
@@ -4636,13 +4674,14 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
= default_function_array_conversion (stack[sp - 1].expr); \
stack[sp].expr \
= default_function_array_conversion (stack[sp].expr); \
- stack[sp - 1].expr = parser_build_binary_op (binary_loc, \
+ stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
stack[sp].op, \
stack[sp - 1].expr, \
stack[sp].expr); \
sp--; \
} while (0)
gcc_assert (!after || c_dialect_objc ());
+ stack[0].loc = c_parser_peek_token (parser)->location;
stack[0].expr = c_parser_cast_expression (parser, after);
stack[0].prec = PREC_NONE;
sp = 0;
@@ -4741,20 +4780,21 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
stack[sp].expr
= default_function_array_conversion (stack[sp].expr);
stack[sp].expr.value = c_objc_common_truthvalue_conversion
- (binary_loc, default_conversion (stack[sp].expr.value));
+ (stack[sp].loc, default_conversion (stack[sp].expr.value));
skip_evaluation += stack[sp].expr.value == truthvalue_false_node;
break;
case TRUTH_ORIF_EXPR:
stack[sp].expr
= default_function_array_conversion (stack[sp].expr);
stack[sp].expr.value = c_objc_common_truthvalue_conversion
- (binary_loc, default_conversion (stack[sp].expr.value));
+ (stack[sp].loc, default_conversion (stack[sp].expr.value));
skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
break;
default:
break;
}
sp++;
+ stack[sp].loc = binary_loc;
stack[sp].expr = c_parser_cast_expression (parser, NULL);
stack[sp].prec = oprec;
stack[sp].op = ocode;
@@ -4798,6 +4838,7 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
{
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
@@ -4811,6 +4852,7 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
expr = default_function_array_conversion (expr);
ret.value = c_cast_expr (type_name, expr.value);
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
else
@@ -4850,6 +4892,8 @@ c_parser_unary_expression (c_parser *parser)
int ext;
struct c_expr ret, op;
location_t loc = c_parser_peek_token (parser)->location;
+ ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
switch (c_parser_peek_token (parser)->type)
{
case CPP_PLUS_PLUS:
@@ -4872,7 +4916,6 @@ c_parser_unary_expression (c_parser *parser)
op = c_parser_cast_expression (parser, NULL);
op = default_function_array_conversion (op);
ret.value = build_indirect_ref (loc, op.value, "unary *");
- ret.original_code = ERROR_MARK;
return ret;
case CPP_PLUS:
if (!c_dialect_objc () && !in_system_header)
@@ -4912,7 +4955,6 @@ c_parser_unary_expression (c_parser *parser)
c_parser_error (parser, "expected identifier");
ret.value = error_mark_node;
}
- ret.original_code = ERROR_MARK;
return ret;
case CPP_KEYWORD:
switch (c_parser_peek_token (parser)->keyword)
@@ -4973,6 +5015,7 @@ c_parser_sizeof_expression (c_parser *parser)
in_sizeof--;
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
@@ -5027,6 +5070,7 @@ c_parser_alignof_expression (c_parser *parser)
in_alignof--;
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
@@ -5040,6 +5084,7 @@ c_parser_alignof_expression (c_parser *parser)
in_alignof--;
ret.value = c_alignof (groktypename (type_name, NULL, NULL));
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
else
@@ -5051,6 +5096,7 @@ c_parser_alignof_expression (c_parser *parser)
in_alignof--;
ret.value = c_alignof_expr (expr.value);
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
}
@@ -5114,11 +5160,12 @@ c_parser_postfix_expression (c_parser *parser)
struct c_expr expr, e1, e2, e3;
struct c_type_name *t1, *t2;
location_t loc;
+ expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
switch (c_parser_peek_token (parser)->type)
{
case CPP_NUMBER:
expr.value = c_parser_peek_token (parser)->value;
- expr.original_code = ERROR_MARK;
loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
if (TREE_CODE (expr.value) == FIXED_CST
@@ -5133,7 +5180,6 @@ c_parser_postfix_expression (c_parser *parser)
case CPP_CHAR32:
case CPP_WCHAR:
expr.value = c_parser_peek_token (parser)->value;
- expr.original_code = ERROR_MARK;
c_parser_consume_token (parser);
break;
case CPP_STRING:
@@ -5148,7 +5194,6 @@ c_parser_postfix_expression (c_parser *parser)
gcc_assert (c_dialect_objc ());
expr.value
= objc_build_string_object (c_parser_peek_token (parser)->value);
- expr.original_code = ERROR_MARK;
c_parser_consume_token (parser);
break;
case CPP_NAME:
@@ -5156,7 +5201,6 @@ c_parser_postfix_expression (c_parser *parser)
{
c_parser_error (parser, "expected expression");
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
{
@@ -5165,8 +5209,8 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
expr.value = build_external_ref (id,
(c_parser_peek_token (parser)->type
- == CPP_OPEN_PAREN), loc);
- expr.original_code = ERROR_MARK;
+ == CPP_OPEN_PAREN), loc,
+ &expr.original_type);
}
break;
case CPP_OPEN_PAREN:
@@ -5187,7 +5231,6 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
stmt = c_begin_stmt_expr ();
@@ -5197,7 +5240,6 @@ c_parser_postfix_expression (c_parser *parser)
pedwarn (here, OPT_pedantic,
"ISO C forbids braced-groups within expressions");
expr.value = c_finish_stmt_expr (stmt);
- expr.original_code = ERROR_MARK;
}
else if (c_token_starts_typename (c_parser_peek_2nd_token (parser)))
{
@@ -5213,7 +5255,6 @@ c_parser_postfix_expression (c_parser *parser)
if (type_name == NULL)
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
}
else
expr = c_parser_postfix_expression_after_paren_type (parser,
@@ -5228,6 +5269,7 @@ c_parser_postfix_expression (c_parser *parser)
TREE_NO_WARNING (expr.value) = 1;
if (expr.original_code != C_MAYBE_CONST_EXPR)
expr.original_code = ERROR_MARK;
+ /* Don't change EXPR.ORIGINAL_TYPE. */
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
}
@@ -5241,7 +5283,6 @@ c_parser_postfix_expression (c_parser *parser)
expr.value = fname_decl (c_parser_peek_token (parser)->location,
c_parser_peek_token (parser)->keyword,
c_parser_peek_token (parser)->value);
- expr.original_code = ERROR_MARK;
c_parser_consume_token (parser);
break;
case RID_VA_ARG:
@@ -5249,7 +5290,6 @@ c_parser_postfix_expression (c_parser *parser)
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
e1 = c_parser_expr_no_commas (parser, NULL);
@@ -5258,7 +5298,6 @@ c_parser_postfix_expression (c_parser *parser)
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
t1 = c_parser_type_name (parser);
@@ -5267,7 +5306,6 @@ c_parser_postfix_expression (c_parser *parser)
if (t1 == NULL)
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
}
else
{
@@ -5282,7 +5320,6 @@ c_parser_postfix_expression (c_parser *parser)
expr.value);
C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
}
- expr.original_code = ERROR_MARK;
}
break;
case RID_OFFSETOF:
@@ -5290,21 +5327,18 @@ c_parser_postfix_expression (c_parser *parser)
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
t1 = c_parser_type_name (parser);
if (t1 == NULL)
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
{
@@ -5369,7 +5403,6 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
expr.value = fold_offsetof (offsetof_ref, NULL_TREE);
- expr.original_code = ERROR_MARK;
}
break;
case RID_CHOOSE_EXPR:
@@ -5377,7 +5410,6 @@ c_parser_postfix_expression (c_parser *parser)
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
loc = c_parser_peek_token (parser)->location;
@@ -5386,7 +5418,6 @@ c_parser_postfix_expression (c_parser *parser)
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
e2 = c_parser_expr_no_commas (parser, NULL);
@@ -5394,7 +5425,6 @@ c_parser_postfix_expression (c_parser *parser)
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
e3 = c_parser_expr_no_commas (parser, NULL);
@@ -5403,7 +5433,7 @@ c_parser_postfix_expression (c_parser *parser)
{
tree c;
- c = fold (e1.value);
+ c = e1.value;
if (TREE_CODE (c) != INTEGER_CST
|| !INTEGRAL_TYPE_P (TREE_TYPE (c)))
error_at (loc,
@@ -5418,28 +5448,24 @@ c_parser_postfix_expression (c_parser *parser)
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
t1 = c_parser_type_name (parser);
if (t1 == NULL)
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
t2 = c_parser_type_name (parser);
if (t2 == NULL)
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
@@ -5453,7 +5479,6 @@ c_parser_postfix_expression (c_parser *parser)
expr.value = comptypes (e1, e2)
? build_int_cst (NULL_TREE, 1)
: build_int_cst (NULL_TREE, 0);
- expr.original_code = ERROR_MARK;
}
break;
case RID_AT_SELECTOR:
@@ -5462,7 +5487,6 @@ c_parser_postfix_expression (c_parser *parser)
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
{
@@ -5470,7 +5494,6 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
expr.value = objc_build_selector_expr (sel);
- expr.original_code = ERROR_MARK;
}
break;
case RID_AT_PROTOCOL:
@@ -5479,7 +5502,6 @@ c_parser_postfix_expression (c_parser *parser)
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
if (c_parser_next_token_is_not (parser, CPP_NAME))
@@ -5487,7 +5509,6 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
{
@@ -5496,7 +5517,6 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
expr.value = objc_build_protocol_expr (id);
- expr.original_code = ERROR_MARK;
}
break;
case RID_AT_ENCODE:
@@ -5506,14 +5526,12 @@ c_parser_postfix_expression (c_parser *parser)
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
t1 = c_parser_type_name (parser);
if (t1 == NULL)
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
break;
}
@@ -5522,13 +5540,11 @@ c_parser_postfix_expression (c_parser *parser)
{
tree type = groktypename (t1, NULL, NULL);
expr.value = objc_build_encode_expr (type);
- expr.original_code = ERROR_MARK;
}
break;
default:
c_parser_error (parser, "expected expression");
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
break;
@@ -5543,14 +5559,12 @@ c_parser_postfix_expression (c_parser *parser)
"expected %<]%>");
expr.value = objc_build_message_expr (build_tree_list (receiver,
args));
- expr.original_code = ERROR_MARK;
break;
}
/* Else fall through to report error. */
default:
c_parser_error (parser, "expected expression");
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
return c_parser_postfix_expression_after_primary (parser, expr);
@@ -5595,6 +5609,7 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
non_const |= !type_expr_const;
expr.value = build_compound_literal (type, init.value, non_const);
expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
if (type_expr)
{
if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
@@ -5620,7 +5635,9 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
struct c_expr expr)
{
struct c_expr orig_expr;
- tree ident, idx, exprlist;
+ tree ident, idx;
+ VEC(tree,gc) *exprlist;
+ VEC(tree,gc) *origtypes;
location_t loc = c_parser_peek_token (parser)->location;
while (true)
{
@@ -5635,24 +5652,32 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
"expected %<]%>");
expr.value = build_array_ref (expr.value, idx, loc);
expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
break;
case CPP_OPEN_PAREN:
/* Function call. */
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- exprlist = NULL_TREE;
+ exprlist = NULL;
else
- exprlist = c_parser_expr_list (parser, true, false);
+ exprlist = c_parser_expr_list (parser, true, false, &origtypes);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
orig_expr = expr;
- expr.value = build_function_call (expr.value, exprlist);
+ expr.value = build_function_call_vec (expr.value, exprlist,
+ origtypes);
expr.original_code = ERROR_MARK;
if (TREE_CODE (expr.value) == INTEGER_CST
&& TREE_CODE (orig_expr.value) == FUNCTION_DECL
&& DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL
&& DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
expr.original_code = C_MAYBE_CONST_EXPR;
+ expr.original_type = NULL;
+ if (exprlist != NULL)
+ {
+ c_parser_release_expr_list (exprlist);
+ c_parser_release_expr_list (origtypes);
+ }
break;
case CPP_DOT:
/* Structure element reference. */
@@ -5665,11 +5690,23 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
c_parser_error (parser, "expected identifier");
expr.value = error_mark_node;
expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
return expr;
}
c_parser_consume_token (parser);
expr.value = build_component_ref (expr.value, ident);
expr.original_code = ERROR_MARK;
+ if (TREE_CODE (expr.value) != COMPONENT_REF)
+ expr.original_type = NULL;
+ else
+ {
+ /* Remember the original type of a bitfield. */
+ tree field = TREE_OPERAND (expr.value, 1);
+ if (TREE_CODE (field) != FIELD_DECL)
+ expr.original_type = NULL;
+ else
+ expr.original_type = DECL_BIT_FIELD_TYPE (field);
+ }
break;
case CPP_DEREF:
/* Structure element reference. */
@@ -5682,6 +5719,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
c_parser_error (parser, "expected identifier");
expr.value = error_mark_node;
expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
return expr;
}
c_parser_consume_token (parser);
@@ -5690,6 +5728,17 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
"->"),
ident);
expr.original_code = ERROR_MARK;
+ if (TREE_CODE (expr.value) != COMPONENT_REF)
+ expr.original_type = NULL;
+ else
+ {
+ /* Remember the original type of a bitfield. */
+ tree field = TREE_OPERAND (expr.value, 1);
+ if (TREE_CODE (field) != FIELD_DECL)
+ expr.original_type = NULL;
+ else
+ expr.original_type = DECL_BIT_FIELD_TYPE (field);
+ }
break;
case CPP_PLUS_PLUS:
/* Postincrement. */
@@ -5698,6 +5747,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
expr.value = build_unary_op (loc,
POSTINCREMENT_EXPR, expr.value, 0);
expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
break;
case CPP_MINUS_MINUS:
/* Postdecrement. */
@@ -5706,6 +5756,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
expr.value = build_unary_op (loc,
POSTDECREMENT_EXPR, expr.value, 0);
expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
break;
default:
return expr;
@@ -5733,6 +5784,7 @@ c_parser_expression (c_parser *parser)
next = default_function_array_conversion (next);
expr.value = build_compound_expr (expr.value, next.value);
expr.original_code = COMPOUND_EXPR;
+ expr.original_type = NULL;
}
return expr;
}
@@ -5757,17 +5809,55 @@ c_parser_expression_conv (c_parser *parser)
nonempty-expr-list , assignment-expression
*/
-static tree
-c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p)
+/* We cache two vectors, to save most allocation and deallocation. */
+static GTY((deletable)) VEC(tree,gc) *cached_expr_list_1;
+static GTY((deletable)) VEC(tree,gc) *cached_expr_list_2;
+
+static VEC(tree,gc) *
+c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
+ VEC(tree,gc) **p_orig_types)
{
+ VEC(tree,gc) *ret;
+ VEC(tree,gc) *orig_types;
struct c_expr expr;
- tree ret, cur;
+
+ if (cached_expr_list_1 != NULL)
+ {
+ ret = cached_expr_list_1;
+ cached_expr_list_1 = NULL;
+ VEC_truncate (tree, ret, 0);
+ }
+ else if (cached_expr_list_2 != NULL)
+ {
+ ret = cached_expr_list_2;
+ cached_expr_list_2 = NULL;
+ VEC_truncate (tree, ret, 0);
+ }
+ else
+ ret = VEC_alloc (tree, gc, 16);
+
+ if (p_orig_types == NULL)
+ orig_types = NULL;
+ else
+ {
+ if (cached_expr_list_2 != NULL)
+ {
+ orig_types = cached_expr_list_2;
+ cached_expr_list_2 = NULL;
+ VEC_truncate (tree, orig_types, 0);
+ }
+ else
+ orig_types = VEC_alloc (tree, gc, 16);
+ }
+
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
expr = default_function_array_conversion (expr);
if (fold_p)
expr.value = c_fully_fold (expr.value, false, NULL);
- ret = cur = build_tree_list (NULL_TREE, expr.value);
+ VEC_quick_push (tree, ret, expr.value);
+ if (orig_types != NULL)
+ VEC_quick_push (tree, orig_types, expr.original_type);
while (c_parser_next_token_is (parser, CPP_COMMA))
{
c_parser_consume_token (parser);
@@ -5776,11 +5866,45 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p)
expr = default_function_array_conversion (expr);
if (fold_p)
expr.value = c_fully_fold (expr.value, false, NULL);
- cur = TREE_CHAIN (cur) = build_tree_list (NULL_TREE, expr.value);
+ VEC_safe_push (tree, gc, ret, expr.value);
+ if (orig_types != NULL)
+ VEC_safe_push (tree, gc, orig_types, expr.original_type);
}
+ if (orig_types != NULL)
+ *p_orig_types = orig_types;
return ret;
}
+/* Release a vector returned by c_parser_expr_list. */
+
+static void
+c_parser_release_expr_list (VEC(tree,gc) *vec)
+{
+ if (cached_expr_list_1 == NULL)
+ cached_expr_list_1 = vec;
+ else if (cached_expr_list_2 == NULL)
+ cached_expr_list_2 = vec;
+ else
+ VEC_free (tree, gc, vec);
+}
+
+/* Convert a vector, as returned by c_parser_expr_list, to a
+ tree_list. */
+
+static tree
+c_parser_vec_to_tree_list (VEC(tree,gc) *vec)
+{
+ tree ret = NULL_TREE;
+ tree *pp = &ret;
+ unsigned int i;
+ tree t;
+ for (i = 0; VEC_iterate (tree, vec, i, t); ++i)
+ {
+ *pp = build_tree_list (NULL, t);
+ pp = &TREE_CHAIN (*pp);
+ }
+ return ret;
+}
/* Parse Objective-C-specific constructs. */
@@ -6651,18 +6775,21 @@ c_parser_objc_message_args (c_parser *parser)
static tree
c_parser_objc_keywordexpr (c_parser *parser)
{
- tree list = c_parser_expr_list (parser, true, true);
- if (TREE_CHAIN (list) == NULL_TREE)
+ tree ret;
+ VEC(tree,gc) *expr_list = c_parser_expr_list (parser, true, true, NULL);
+ if (VEC_length (tree, expr_list) == 1)
{
/* Just return the expression, remove a level of
indirection. */
- return TREE_VALUE (list);
+ ret = VEC_index (tree, expr_list, 0);
}
else
{
/* We have a comma expression, we will collapse later. */
- return list;
+ ret = c_parser_vec_to_tree_list (expr_list);
}
+ c_parser_release_expr_list (expr_list);
+ return ret;
}
@@ -7696,18 +7823,21 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
else if (c_parser_next_token_is (parser, CPP_NAME)
&& c_parser_peek_2nd_token (parser)->type == CPP_EQ)
{
+ struct c_expr decl_exp;
struct c_expr init_exp;
location_t init_loc;
- decl = c_parser_postfix_expression (parser).value;
+ decl_exp = c_parser_postfix_expression (parser);
+ decl = decl_exp.value;
c_parser_require (parser, CPP_EQ, "expected %<=%>");
init_loc = c_parser_peek_token (parser)->location;
init_exp = c_parser_expr_no_commas (parser, NULL);
init_exp = default_function_array_conversion (init_exp);
- init = build_modify_expr (init_loc,
- decl, NOP_EXPR, init_exp.value);
+ init = build_modify_expr (init_loc, decl, decl_exp.original_type,
+ NOP_EXPR, init_exp.value,
+ init_exp.original_type);
init = c_process_expr_stmt (init);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");