diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-04-27 12:45:13 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-04-27 12:45:13 +0000 |
commit | 268b9e9e95f56a59a8817b28ad59b53f40fc668d (patch) | |
tree | 5e9529982daf11d5b3ab800d4c58bc3fbee99d28 /gcc/c-parser.c | |
parent | e1910362719612f58bd1ea5050fa7a5175036abc (diff) | |
download | gcc-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.c | 294 |
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 %<;%>"); |