X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-parser.c;h=c2e5435af2627ec78e1277084524da04de4919ad;hb=25c54918978537122a535d8ca782cc7983494410;hp=852025392833ceb813663d00f0978fd16a8b96c1;hpb=5c3667a19751f3f0b11b07c3712b152a70c650ba;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 85202539283..c2e5435af26 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -1,6 +1,6 @@ /* Parser for C and Objective-C. Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. Parser actions based on the old Bison parser; structure somewhat influenced by and fragments based on the C++ parser. @@ -9,7 +9,7 @@ This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -18,9 +18,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ /* TODO: @@ -59,25 +58,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "cgraph.h" -/* Miscellaneous data and functions needed for the parser. */ - -int yydebug; - -/* Objective-C specific parser/lexer information. */ - -static int objc_pq_context = 0; - -/* The following flag is needed to contextualize Objective-C lexical - analysis. In some cases (e.g., 'int NSObject;'), it is undesirable - to bind an identifier to an Objective-C class, even if a class with - that name exists. */ -static int objc_need_raw_identifier = 0; -#define OBJC_NEED_RAW_IDENTIFIER(VAL) \ - do { \ - if (c_dialect_objc ()) \ - objc_need_raw_identifier = VAL; \ - } while (0) - /* The reserved keyword table. */ struct resword { @@ -100,6 +80,9 @@ static const struct resword reswords[] = { "_Decimal32", RID_DFLOAT32, D_EXT }, { "_Decimal64", RID_DFLOAT64, D_EXT }, { "_Decimal128", RID_DFLOAT128, D_EXT }, + { "_Fract", RID_FRACT, D_EXT }, + { "_Accum", RID_ACCUM, D_EXT }, + { "_Sat", RID_SAT, D_EXT }, { "__FUNCTION__", RID_FUNCTION_NAME, 0 }, { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 }, { "__alignof", RID_ALIGNOF, 0 }, @@ -200,26 +183,6 @@ static const struct resword reswords[] = }; #define N_reswords (sizeof reswords / sizeof (struct resword)) -/* All OpenMP clauses. OpenMP 2.5. */ -typedef enum pragma_omp_clause { - PRAGMA_OMP_CLAUSE_NONE = 0, - - PRAGMA_OMP_CLAUSE_COPYIN, - PRAGMA_OMP_CLAUSE_COPYPRIVATE, - PRAGMA_OMP_CLAUSE_DEFAULT, - PRAGMA_OMP_CLAUSE_FIRSTPRIVATE, - PRAGMA_OMP_CLAUSE_IF, - PRAGMA_OMP_CLAUSE_LASTPRIVATE, - PRAGMA_OMP_CLAUSE_NOWAIT, - PRAGMA_OMP_CLAUSE_NUM_THREADS, - PRAGMA_OMP_CLAUSE_ORDERED, - PRAGMA_OMP_CLAUSE_PRIVATE, - PRAGMA_OMP_CLAUSE_REDUCTION, - PRAGMA_OMP_CLAUSE_SCHEDULE, - PRAGMA_OMP_CLAUSE_SHARED -} pragma_omp_clause; - - /* Initialization routine for this file. */ void @@ -317,6 +280,17 @@ typedef struct c_parser GTY(()) /* True if we're processing a pragma, and shouldn't automatically consume CPP_PRAGMA_EOL. */ BOOL_BITFIELD in_pragma : 1; + /* True if we're parsing the outermost block of an if statement. */ + BOOL_BITFIELD in_if_block : 1; + /* True if we want to lex an untranslated string. */ + BOOL_BITFIELD lex_untranslated_string : 1; + /* Objective-C specific parser/lexer information. */ + BOOL_BITFIELD objc_pq_context : 1; + /* The following flag is needed to contextualize Objective-C lexical + analysis. In some cases (e.g., 'int NSObject;'), it is + undesirable to bind an identifier to an Objective-C class, even + if a class with that name exists. */ + BOOL_BITFIELD objc_need_raw_identifier : 1; } c_parser; @@ -329,11 +303,13 @@ static GTY (()) c_parser *the_parser; /* Read in and lex a single token, storing it in *TOKEN. */ static void -c_lex_one_token (c_token *token) +c_lex_one_token (c_parser *parser, c_token *token) { timevar_push (TV_LEX); - token->type = c_lex_with_flags (&token->value, &token->location, NULL); + token->type = c_lex_with_flags (&token->value, &token->location, NULL, + (parser->lex_untranslated_string + ? C_LEX_STRING_NO_TRANSLATE : 0)); token->id_kind = C_ID_NONE; token->keyword = RID_MAX; token->pragma_kind = PRAGMA_NONE; @@ -345,8 +321,9 @@ c_lex_one_token (c_token *token) { tree decl; - int objc_force_identifier = objc_need_raw_identifier; - OBJC_NEED_RAW_IDENTIFIER (0); + bool objc_force_identifier = parser->objc_need_raw_identifier; + if (c_dialect_objc ()) + parser->objc_need_raw_identifier = false; if (C_IS_RESERVED_WORD (token->value)) { @@ -355,7 +332,8 @@ c_lex_one_token (c_token *token) if (c_dialect_objc ()) { if (!OBJC_IS_AT_KEYWORD (rid_code) - && (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context)) + && (!OBJC_IS_PQ_KEYWORD (rid_code) + || parser->objc_pq_context)) { /* Return the canonical spelling for this keyword. */ token->value = ridpointers[(int) rid_code]; @@ -412,7 +390,8 @@ c_lex_one_token (c_token *token) case CPP_SEMICOLON: /* These tokens may affect the interpretation of any identifiers following, if doing Objective-C. */ - OBJC_NEED_RAW_IDENTIFIER (0); + if (c_dialect_objc ()) + parser->objc_need_raw_identifier = false; break; case CPP_PRAGMA: /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */ @@ -433,7 +412,7 @@ c_parser_peek_token (c_parser *parser) { if (parser->tokens_avail == 0) { - c_lex_one_token (&parser->tokens[0]); + c_lex_one_token (parser, &parser->tokens[0]); parser->tokens_avail = 1; } return &parser->tokens[0]; @@ -516,6 +495,9 @@ c_token_starts_typename (c_token *token) case RID_VOLATILE: case RID_RESTRICT: case RID_ATTRIBUTE: + case RID_FRACT: + case RID_ACCUM: + case RID_SAT: return true; default: return false; @@ -590,6 +572,9 @@ c_token_starts_declspecs (c_token *token) case RID_VOLATILE: case RID_RESTRICT: case RID_ATTRIBUTE: + case RID_FRACT: + case RID_ACCUM: + case RID_SAT: return true; default: return false; @@ -623,7 +608,7 @@ c_parser_peek_2nd_token (c_parser *parser) gcc_assert (parser->tokens_avail == 1); gcc_assert (parser->tokens[0].type != CPP_EOF); gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL); - c_lex_one_token (&parser->tokens[1]); + c_lex_one_token (parser, &parser->tokens[1]); parser->tokens_avail = 2; return &parser->tokens[1]; } @@ -1084,7 +1069,8 @@ c_parser_translation_unit (c_parser *parser) if (c_parser_next_token_is (parser, CPP_EOF)) { if (pedantic) - pedwarn ("ISO C forbids an empty source file"); + pedwarn ("%HISO C forbids an empty source file", + &c_parser_peek_token (parser)->location); } else { @@ -1169,7 +1155,8 @@ c_parser_external_declaration (c_parser *parser) break; case CPP_SEMICOLON: if (pedantic) - pedwarn ("ISO C does not allow extra %<;%> outside of a function"); + pedwarn ("%HISO C does not allow extra %<;%> outside of a function", + &c_parser_peek_token (parser)->location); c_parser_consume_token (parser); break; case CPP_PRAGMA: @@ -1260,6 +1247,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok, tree prefix_attrs; tree all_prefix_attrs; bool diagnosed_no_specs = false; + location_t here = c_parser_peek_token (parser)->location; specs = build_null_declspecs (); c_parser_declspecs (parser, specs, true, true, start_attr_ok); @@ -1282,7 +1270,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok, else { shadow_tag_warned (specs, 1); - pedwarn ("empty declaration"); + pedwarn ("%Hempty declaration", &here); } c_parser_consume_token (parser); return; @@ -1318,7 +1306,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok, if (!diagnosed_no_specs && !specs->declspecs_seen_p) { diagnosed_no_specs = true; - pedwarn ("data definition has no type or storage class"); + pedwarn ("%Hdata definition has no type or storage class", + &here); } /* Having seen a data definition, there cannot now be a function definition. */ @@ -1388,7 +1377,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok, if (nested) { if (pedantic) - pedwarn ("ISO C forbids nested functions"); + pedwarn ("%HISO C forbids nested functions", &here); push_function_context (); } if (!start_function (specs, declarator, all_prefix_attrs)) @@ -1523,6 +1512,12 @@ c_parser_asm_definition (c_parser *parser) _Decimal32 _Decimal64 _Decimal128 + _Fract + _Accum + _Sat + + (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037: + http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf) Objective-C: @@ -1625,11 +1620,15 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, case RID_DFLOAT64: case RID_DFLOAT128: case RID_BOOL: + case RID_FRACT: + case RID_ACCUM: + case RID_SAT: if (!typespec_ok) goto out; attrs_ok = true; seen_type = true; - OBJC_NEED_RAW_IDENTIFIER (1); + if (c_dialect_objc ()) + parser->objc_need_raw_identifier = true; t.kind = ctsk_resword; t.spec = c_parser_peek_token (parser)->value; declspecs_add_type (specs, t); @@ -1711,18 +1710,23 @@ c_parser_enum_specifier (c_parser *parser) struct c_typespec ret; tree attrs; tree ident = NULL_TREE; + location_t ident_loc; gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM)); c_parser_consume_token (parser); attrs = c_parser_attributes (parser); + /* Set the location in case we create a decl now. */ + c_parser_set_source_position_from_token (c_parser_peek_token (parser)); if (c_parser_next_token_is (parser, CPP_NAME)) { ident = c_parser_peek_token (parser)->value; + ident_loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); } if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) { /* Parse an enum definition. */ - tree type = start_enum (ident); + struct c_enum_contents the_enum; + tree type = start_enum (&the_enum, ident); tree postfix_attrs; /* We chain the enumerators in reverse order, then put them in forward order at the end. */ @@ -1734,6 +1738,8 @@ c_parser_enum_specifier (c_parser *parser) tree enum_value; tree enum_decl; bool seen_comma; + c_token *token; + location_t comma_loc; if (c_parser_next_token_is_not (parser, CPP_NAME)) { c_parser_error (parser, "expected identifier"); @@ -1741,7 +1747,10 @@ c_parser_enum_specifier (c_parser *parser) values = error_mark_node; break; } - enum_id = c_parser_peek_token (parser)->value; + token = c_parser_peek_token (parser); + enum_id = token->value; + /* Set the location in case we create a decl now. */ + c_parser_set_source_position_from_token (token); c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_EQ)) { @@ -1750,19 +1759,20 @@ c_parser_enum_specifier (c_parser *parser) } else enum_value = NULL_TREE; - enum_decl = build_enumerator (enum_id, enum_value); + enum_decl = build_enumerator (&the_enum, enum_id, enum_value); TREE_CHAIN (enum_decl) = values; values = enum_decl; seen_comma = false; if (c_parser_next_token_is (parser, CPP_COMMA)) { + comma_loc = c_parser_peek_token (parser)->location; seen_comma = true; c_parser_consume_token (parser); } if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) { if (seen_comma && pedantic && !flag_isoc99) - pedwarn ("comma at end of enumerator list"); + pedwarn ("%Hcomma at end of enumerator list", &comma_loc); c_parser_consume_token (parser); break; } @@ -1791,7 +1801,11 @@ c_parser_enum_specifier (c_parser *parser) /* In ISO C, enumerated types can be referred to only if already defined. */ if (pedantic && !COMPLETE_TYPE_P (ret.spec)) - pedwarn ("ISO C forbids forward references to % types"); + { + gcc_assert (ident); + pedwarn ("%HISO C forbids forward references to % types", + &ident_loc); + } return ret; } @@ -1854,6 +1868,8 @@ c_parser_struct_or_union_specifier (c_parser *parser) } c_parser_consume_token (parser); attrs = c_parser_attributes (parser); + /* Set the location in case we create a decl now. */ + c_parser_set_source_position_from_token (c_parser_peek_token (parser)); if (c_parser_next_token_is (parser, CPP_NAME)) { ident = c_parser_peek_token (parser)->value; @@ -1913,7 +1929,8 @@ c_parser_struct_or_union_specifier (c_parser *parser) if (c_parser_next_token_is (parser, CPP_SEMICOLON)) { if (pedantic) - pedwarn ("extra semicolon in struct or union specified"); + pedwarn ("%Hextra semicolon in struct or union specified", + &c_parser_peek_token (parser)->location); c_parser_consume_token (parser); continue; } @@ -1941,7 +1958,8 @@ c_parser_struct_or_union_specifier (c_parser *parser) else { if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) - pedwarn ("no semicolon at end of struct or union"); + pedwarn ("%Hno semicolon at end of struct or union", + &c_parser_peek_token (parser)->location); else { c_parser_error (parser, "expected %<;%>"); @@ -2005,6 +2023,7 @@ c_parser_struct_declaration (c_parser *parser) tree prefix_attrs; tree all_prefix_attrs; tree decls; + location_t decl_loc; if (c_parser_next_token_is_keyword (parser, RID_EXTENSION)) { int ext; @@ -2016,6 +2035,7 @@ c_parser_struct_declaration (c_parser *parser) return decl; } specs = build_null_declspecs (); + decl_loc = c_parser_peek_token (parser)->location; c_parser_declspecs (parser, specs, false, true, true); if (parser->error) return NULL_TREE; @@ -2031,7 +2051,8 @@ c_parser_struct_declaration (c_parser *parser) if (!specs->type_seen_p) { if (pedantic) - pedwarn ("ISO C forbids member declarations with no members"); + pedwarn ("%HISO C forbids member declarations with no members", + &decl_loc); shadow_tag_warned (specs, pedantic); ret = NULL_TREE; } @@ -2040,7 +2061,11 @@ c_parser_struct_declaration (c_parser *parser) /* Support for unnamed structs or unions as members of structs or unions (which is [a] useful and [b] supports MS P-SDK). */ - ret = grokfield (build_id_declarator (NULL_TREE), specs, NULL_TREE); + tree attrs = NULL; + ret = grokfield (build_id_declarator (NULL_TREE), specs, + NULL_TREE, &attrs); + if (ret) + decl_attributes (&ret, attrs, 0); } return ret; } @@ -2080,7 +2105,7 @@ c_parser_struct_declaration (c_parser *parser) } if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) postfix_attrs = c_parser_attributes (parser); - d = grokfield (declarator, specs, width); + d = grokfield (declarator, specs, width, &all_prefix_attrs); decl_attributes (&d, chainon (postfix_attrs, all_prefix_attrs), 0); TREE_CHAIN (d) = decls; @@ -2152,12 +2177,13 @@ c_parser_typeof_specifier (c_parser *parser) else { bool was_vm; + location_t here = c_parser_peek_token (parser)->location; struct c_expr expr = c_parser_expression (parser); skip_evaluation--; in_typeof--; if (TREE_CODE (expr.value) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) - error ("% applied to a bit-field"); + error ("%H% applied to a bit-field", &here); ret.spec = TREE_TYPE (expr.value); was_vm = variably_modified_type_p (ret.spec, NULL_TREE); /* This should be returned with the type so that when the type @@ -2172,7 +2198,7 @@ c_parser_typeof_specifier (c_parser *parser) if (DECL_P (e) || CONSTANT_CLASS_P (e)) e = build1 (NOP_EXPR, void_type_node, e); - if (EXPR_P (e)) + if (CAN_HAVE_LOCATION_P (e)) SET_EXPR_LOCATION (e, input_location); add_stmt (e); @@ -2475,7 +2501,7 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present, star_seen); if (declarator == NULL) return NULL; - inner = set_array_declarator_inner (declarator, inner, !id_present); + inner = set_array_declarator_inner (declarator, inner); return c_parser_direct_declarator_inner (parser, id_present, inner); } else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) @@ -2595,7 +2621,8 @@ c_parser_parms_list_declarator (c_parser *parser, tree attrs) ret->had_vla_unspec = 0; /* Suppress -Wold-style-definition for this case. */ ret->types = error_mark_node; - error ("ISO C requires a named argument before %<...%>"); + error ("%HISO C requires a named argument before %<...%>", + &c_parser_peek_token (parser)->location); c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) { @@ -2737,8 +2764,8 @@ c_parser_parameter_declaration (c_parser *parser, tree attrs) string-literal ??? At present, following the old parser, the caller needs to have - set c_lex_string_translate to 0. It would be better to follow the - C++ parser rather than using the c_lex_string_translate kludge. */ + set lex_untranslated_string to 1. It would be better to follow the + C++ parser rather than using this kludge. */ static tree c_parser_asm_string_literal (c_parser *parser) @@ -2751,7 +2778,8 @@ c_parser_asm_string_literal (c_parser *parser) } else if (c_parser_next_token_is (parser, CPP_WSTRING)) { - error ("wide string literal in %"); + error ("%Hwide string literal in %", + &c_parser_peek_token (parser)->location); str = build_string (1, ""); c_parser_consume_token (parser); } @@ -2777,16 +2805,16 @@ c_parser_simple_asm_expr (c_parser *parser) tree str; gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM)); /* ??? Follow the C++ parser rather than using the - c_lex_string_translate kludge. */ - c_lex_string_translate = 0; + lex_untranslated_string kludge. */ + parser->lex_untranslated_string = true; c_parser_consume_token (parser); if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; return NULL_TREE; } str = c_parser_asm_string_literal (parser); - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) { c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); @@ -2829,17 +2857,17 @@ c_parser_attributes (c_parser *parser) while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) { /* ??? Follow the C++ parser rather than using the - c_lex_string_translate kludge. */ - c_lex_string_translate = 0; + lex_untranslated_string kludge. */ + parser->lex_untranslated_string = true; c_parser_consume_token (parser); if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; return attrs; } if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); return attrs; } @@ -2885,6 +2913,9 @@ c_parser_attributes (c_parser *parser) case RID_DFLOAT64: case RID_DFLOAT128: case RID_BOOL: + case RID_FRACT: + case RID_ACCUM: + case RID_SAT: ok = true; break; default: @@ -2936,7 +2967,7 @@ c_parser_attributes (c_parser *parser) c_parser_consume_token (parser); else { - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); return attrs; @@ -2947,7 +2978,7 @@ c_parser_attributes (c_parser *parser) c_parser_consume_token (parser); else { - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); return attrs; @@ -2956,12 +2987,12 @@ c_parser_attributes (c_parser *parser) c_parser_consume_token (parser); else { - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); return attrs; } - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; } return attrs; } @@ -3065,6 +3096,7 @@ c_parser_initializer (c_parser *parser) static struct c_expr c_parser_braced_init (c_parser *parser, tree type, bool nested_p) { + location_t brace_loc = c_parser_peek_token (parser)->location; gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); c_parser_consume_token (parser); if (nested_p) @@ -3074,7 +3106,7 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p) if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) { if (pedantic) - pedwarn ("ISO C forbids empty initializer braces"); + pedwarn ("%HISO C forbids empty initializer braces", &brace_loc); } else { @@ -3119,7 +3151,11 @@ c_parser_initelt (c_parser *parser) /* Old-style structure member designator. */ set_init_label (c_parser_peek_token (parser)->value); if (pedantic) - pedwarn ("obsolete use of designated initializer with %<:%>"); + { + /* Use the colon as the error location. */ + pedwarn ("%Hobsolete use of designated initializer with %<:%>", + &c_parser_peek_2nd_token (parser)->location); + } c_parser_consume_token (parser); c_parser_consume_token (parser); } @@ -3128,10 +3164,14 @@ c_parser_initelt (c_parser *parser) /* des_seen is 0 if there have been no designators, 1 if there has been a single array designator and 2 otherwise. */ int des_seen = 0; + /* Location of a designator. */ + location_t des_loc; while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE) || c_parser_next_token_is (parser, CPP_DOT)) { int des_prev = des_seen; + if (!des_seen) + des_loc = c_parser_peek_token (parser)->location; if (des_seen < 2) des_seen++; if (c_parser_next_token_is (parser, CPP_DOT)) @@ -3157,6 +3197,7 @@ c_parser_initelt (c_parser *parser) else { tree first, second; + location_t ellipsis_loc; /* ??? Following the old parser, [ objc-receiver objc-message-args ] is accepted as an initializer, being distinguished from a designator by what follows @@ -3232,6 +3273,7 @@ c_parser_initelt (c_parser *parser) array_desig_after_first: if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) { + ellipsis_loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); second = c_parser_expr_no_commas (parser, NULL).value; } @@ -3242,8 +3284,8 @@ c_parser_initelt (c_parser *parser) c_parser_consume_token (parser); set_init_index (first, second); if (pedantic && second) - pedwarn ("ISO C forbids specifying range of " - "elements to initialize"); + pedwarn ("%HISO C forbids specifying range of " + "elements to initialize", &ellipsis_loc); } else c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, @@ -3255,7 +3297,8 @@ c_parser_initelt (c_parser *parser) if (c_parser_next_token_is (parser, CPP_EQ)) { if (pedantic && !flag_isoc99) - pedwarn ("ISO C90 forbids specifying subobject to initialize"); + pedwarn ("%HISO C90 forbids specifying subobject " + "to initialize", &des_loc); c_parser_consume_token (parser); } else @@ -3263,8 +3306,9 @@ c_parser_initelt (c_parser *parser) if (des_seen == 1) { if (pedantic) - pedwarn ("obsolete use of designated initializer " - "without %<=%>"); + pedwarn ("%Hobsolete use of designated initializer " + "without %<=%>", + &c_parser_peek_token (parser)->location); } else { @@ -3379,6 +3423,7 @@ c_parser_compound_statement_nostart (c_parser *parser) { bool last_stmt = false; bool last_label = false; + location_t label_loc; if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) { c_parser_consume_token (parser); @@ -3386,6 +3431,7 @@ c_parser_compound_statement_nostart (c_parser *parser) } if (c_parser_next_token_is_keyword (parser, RID_LABEL)) { + location_t err_loc = c_parser_peek_token (parser)->location; /* Read zero or more forward-declarations for labels that nested functions can jump to. */ while (c_parser_next_token_is_keyword (parser, RID_LABEL)) @@ -3413,11 +3459,8 @@ c_parser_compound_statement_nostart (c_parser *parser) } c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); } - /* ??? Locating this diagnostic on the token after the - declarations end follows the old parser, but it might be - better to locate it where the declarations start instead. */ if (pedantic) - pedwarn ("ISO C forbids label declarations"); + pedwarn ("%HISO C forbids label declarations", &err_loc); } /* We must now have at least one statement, label or declaration. */ if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) @@ -3434,6 +3477,10 @@ c_parser_compound_statement_nostart (c_parser *parser) || (c_parser_next_token_is (parser, CPP_NAME) && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) { + if (c_parser_next_token_is_keyword (parser, RID_CASE)) + label_loc = c_parser_peek_2nd_token (parser)->location; + else + label_loc = c_parser_peek_token (parser)->location; last_label = true; last_stmt = false; c_parser_label (parser); @@ -3496,6 +3543,20 @@ c_parser_compound_statement_nostart (c_parser *parser) c_parser_error (parser, "expected declaration or statement"); return; } + else if (c_parser_next_token_is_keyword (parser, RID_ELSE)) + { + if (parser->in_if_block) + { + error ("%H""expected %<}%> before %", &loc); + return; + } + else + { + error ("%H% without a previous %", &loc); + c_parser_consume_token (parser); + continue; + } + } else { statement: @@ -3507,7 +3568,7 @@ c_parser_compound_statement_nostart (c_parser *parser) parser->error = false; } if (last_label) - error ("label at end of compound statement"); + error ("%Hlabel at end of compound statement", &label_loc); c_parser_consume_token (parser); } @@ -3562,12 +3623,11 @@ c_parser_label (c_parser *parser) { tree name = c_parser_peek_token (parser)->value; tree tlab; - location_t loc2; tree attrs; + location_t loc2 = c_parser_peek_token (parser)->location; gcc_assert (c_parser_next_token_is (parser, CPP_NAME)); c_parser_consume_token (parser); gcc_assert (c_parser_next_token_is (parser, CPP_COLON)); - loc2 = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); attrs = c_parser_attributes (parser); tlab = define_label (loc2, name); @@ -3578,7 +3638,20 @@ c_parser_label (c_parser *parser) } } if (label) - SET_EXPR_LOCATION (label, loc1); + { + SET_EXPR_LOCATION (label, loc1); + if (c_parser_next_token_starts_declspecs (parser) + && !(c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) + { + error ("%Ha label can only be part of a statement and " + "a declaration is not a statement", + &c_parser_peek_token (parser)->location); + c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false, + /*nested*/ true, /*empty_ok*/ false, + /*start_attr_ok*/ true); + } + } } /* Parse a statement (C90 6.6, C99 6.8). @@ -3696,6 +3769,8 @@ c_parser_statement_after_labels (c_parser *parser) { location_t loc = c_parser_peek_token (parser)->location; tree stmt = NULL_TREE; + bool in_if_block = parser->in_if_block; + parser->in_if_block = false; switch (c_parser_peek_token (parser)->type) { case CPP_OPEN_BRACE: @@ -3817,8 +3892,10 @@ c_parser_statement_after_labels (c_parser *parser) (recursively) all of the component statements should already have line numbers assigned. ??? Can we discard no-op statements earlier? */ - if (stmt && EXPR_P (stmt)) + if (stmt && CAN_HAVE_LOCATION_P (stmt)) SET_EXPR_LOCATION (stmt, loc); + + parser->in_if_block = in_if_block; } /* Parse a parenthesized condition from an if, do or while statement. @@ -3836,7 +3913,7 @@ c_parser_paren_condition (c_parser *parser) loc = c_parser_peek_token (parser)->location; cond = c_objc_common_truthvalue_conversion (c_parser_expression_conv (parser).value); - if (EXPR_P (cond)) + if (CAN_HAVE_LOCATION_P (cond)) SET_EXPR_LOCATION (cond, loc); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); return cond; @@ -3852,11 +3929,13 @@ c_parser_c99_block_statement (c_parser *parser) return c_end_compound_stmt (block, flag_isoc99); } -/* Parse the body of an if statement or the else half thereof. This - is just parsing a statement but (a) it is a block in C99, (b) we - track whether the body is an if statement for the sake of - -Wparentheses warnings, (c) we handle an empty body specially for - the sake of -Wextra warnings. */ +/* Parse the body of an if statement. This is just parsing a + statement but (a) it is a block in C99, (b) we track whether the + body is an if statement for the sake of -Wparentheses warnings, (c) + we handle an empty body specially for the sake of -Wempty-body + warnings, and (d) we call parser_compound_statement directly + because c_parser_statement_after_labels resets + parser->in_if_block. */ static tree c_parser_if_body (c_parser *parser, bool *if_p) @@ -3868,9 +3947,38 @@ c_parser_if_body (c_parser *parser, bool *if_p) && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) c_parser_label (parser); *if_p = c_parser_next_token_is_keyword (parser, RID_IF); - if (extra_warnings && c_parser_next_token_is (parser, CPP_SEMICOLON)) - add_stmt (build_empty_stmt ()); - c_parser_statement_after_labels (parser); + if (c_parser_next_token_is (parser, CPP_SEMICOLON)) + { + add_stmt (build_empty_stmt ()); + c_parser_consume_token (parser); + } + else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) + add_stmt (c_parser_compound_statement (parser)); + else + c_parser_statement_after_labels (parser); + return c_end_compound_stmt (block, flag_isoc99); +} + +/* Parse the else body of an if statement. This is just parsing a + statement but (a) it is a block in C99, (b) we handle an empty body + specially for the sake of -Wempty-body warnings. */ + +static tree +c_parser_else_body (c_parser *parser) +{ + tree block = c_begin_compound_stmt (flag_isoc99); + while (c_parser_next_token_is_keyword (parser, RID_CASE) + || c_parser_next_token_is_keyword (parser, RID_DEFAULT) + || (c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) + c_parser_label (parser); + if (c_parser_next_token_is (parser, CPP_SEMICOLON)) + { + add_stmt (build_empty_stmt ()); + c_parser_consume_token (parser); + } + else + c_parser_statement_after_labels (parser); return c_end_compound_stmt (block, flag_isoc99); } @@ -3887,18 +3995,23 @@ c_parser_if_statement (c_parser *parser) tree block; location_t loc; tree cond; - bool first_if = false, second_if = false; + bool first_if = false; tree first_body, second_body; + bool in_if_block; + gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF)); c_parser_consume_token (parser); block = c_begin_compound_stmt (flag_isoc99); loc = c_parser_peek_token (parser)->location; cond = c_parser_paren_condition (parser); + in_if_block = parser->in_if_block; + parser->in_if_block = true; first_body = c_parser_if_body (parser, &first_if); + parser->in_if_block = in_if_block; if (c_parser_next_token_is_keyword (parser, RID_ELSE)) { c_parser_consume_token (parser); - second_body = c_parser_if_body (parser, &second_if); + second_body = c_parser_else_body (parser); } else second_body = NULL_TREE; @@ -3977,6 +4090,10 @@ c_parser_do_statement (c_parser *parser) location_t loc; gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO)); c_parser_consume_token (parser); + if (c_parser_next_token_is (parser, CPP_SEMICOLON)) + warning (OPT_Wempty_body, + "%Hsuggest braces around empty body in % statement", + &c_parser_peek_token (parser)->location); block = c_begin_compound_stmt (flag_isoc99); loc = c_parser_peek_token (parser)->location; save_break = c_break_label; @@ -4073,7 +4190,7 @@ c_parser_for_statement (c_parser *parser) { tree ocond = c_parser_expression_conv (parser).value; cond = c_objc_common_truthvalue_conversion (ocond); - if (EXPR_P (cond)) + if (CAN_HAVE_LOCATION_P (cond)) SET_EXPR_LOCATION (cond, loc); c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); } @@ -4131,7 +4248,8 @@ c_parser_asm_statement (c_parser *parser) else if (c_parser_next_token_is_keyword (parser, RID_CONST) || c_parser_next_token_is_keyword (parser, RID_RESTRICT)) { - warning (0, "%E qualifier ignored on asm", + warning (0, "%H%E qualifier ignored on asm", + &c_parser_peek_token (parser)->location, c_parser_peek_token (parser)->value); quals = NULL_TREE; c_parser_consume_token (parser); @@ -4139,11 +4257,11 @@ c_parser_asm_statement (c_parser *parser) else quals = NULL_TREE; /* ??? Follow the C++ parser rather than using the - c_lex_string_translate kludge. */ - c_lex_string_translate = 0; + lex_untranslated_string kludge. */ + parser->lex_untranslated_string = true; if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; return NULL_TREE; } str = c_parser_asm_string_literal (parser); @@ -4157,7 +4275,7 @@ c_parser_asm_statement (c_parser *parser) } if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>")) { - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); return NULL_TREE; } @@ -4176,7 +4294,7 @@ c_parser_asm_statement (c_parser *parser) } if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>")) { - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); return NULL_TREE; } @@ -4193,14 +4311,14 @@ c_parser_asm_statement (c_parser *parser) } if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>")) { - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); return NULL_TREE; } /* Parse clobbers. */ clobbers = c_parser_asm_clobbers (parser); done_asm: - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) { c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); @@ -4258,16 +4376,16 @@ c_parser_asm_operands (c_parser *parser, bool convert_p) str = c_parser_asm_string_literal (parser); if (str == NULL_TREE) return NULL_TREE; - c_lex_string_translate = 1; + parser->lex_untranslated_string = false; if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { - c_lex_string_translate = 0; + parser->lex_untranslated_string = true; return NULL_TREE; } expr = c_parser_expression (parser); if (convert_p) expr = default_function_array_conversion (expr); - c_lex_string_translate = 0; + parser->lex_untranslated_string = true; if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) { c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); @@ -4411,7 +4529,8 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after) if (c_parser_next_token_is (parser, CPP_COLON)) { if (pedantic) - pedwarn ("ISO C forbids omitting the middle term of a ?: expression"); + pedwarn ("%HISO C forbids omitting the middle term of a ?: expression", + &c_parser_peek_token (parser)->location); /* Make sure first operand is calculated only once. */ exp1.value = save_expr (default_conversion (cond.value)); cond.value = c_objc_common_truthvalue_conversion (exp1.value); @@ -4798,10 +4917,11 @@ c_parser_unary_expression (c_parser *parser) ret.original_code = ERROR_MARK; return ret; case CPP_PLUS: - c_parser_consume_token (parser); if (!c_dialect_objc () && !in_system_header) warning (OPT_Wtraditional, - "traditional C rejects the unary plus operator"); + "%Htraditional C rejects the unary plus operator", + &c_parser_peek_token (parser)->location); + c_parser_consume_token (parser); op = c_parser_cast_expression (parser, NULL); op = default_function_array_conversion (op); return parser_build_unary_op (CONVERT_EXPR, op); @@ -4873,6 +4993,7 @@ static struct c_expr c_parser_sizeof_expression (c_parser *parser) { struct c_expr expr; + location_t expr_loc; gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF)); c_parser_consume_token (parser); skip_evaluation++; @@ -4884,6 +5005,7 @@ c_parser_sizeof_expression (c_parser *parser) starting with a compound literal. */ struct c_type_name *type_name; c_parser_consume_token (parser); + expr_loc = c_parser_peek_token (parser)->location; type_name = c_parser_type_name (parser); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); if (type_name == NULL) @@ -4908,19 +5030,21 @@ c_parser_sizeof_expression (c_parser *parser) && type_name->declarator->u.array.vla_unspec_p) { /* C99 6.7.5.2p4 */ - error ("%<[*]%> not allowed in other than a declaration"); + error ("%H%<[*]%> not allowed in other than a declaration", + &expr_loc); } return c_expr_sizeof_type (type_name); } else { + expr_loc = c_parser_peek_token (parser)->location; expr = c_parser_unary_expression (parser); sizeof_expr: skip_evaluation--; in_sizeof--; if (TREE_CODE (expr.value) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) - error ("% applied to a bit-field"); + error ("%H% applied to a bit-field", &expr_loc); return c_expr_sizeof_expr (expr); } } @@ -5038,6 +5162,7 @@ c_parser_postfix_expression (c_parser *parser) { struct c_expr expr, e1, e2, e3; struct c_type_name *t1, *t2; + location_t loc; switch (c_parser_peek_token (parser)->type) { case CPP_NUMBER: @@ -5085,12 +5210,13 @@ c_parser_postfix_expression (c_parser *parser) { /* A statement expression. */ tree stmt; + location_t here = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); c_parser_consume_token (parser); if (cur_stmt_list == NULL) { - error ("braced-group within expression allowed " - "only inside a function"); + error ("%Hbraced-group within expression allowed " + "only inside a function", &here); parser->error = true; c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); @@ -5103,7 +5229,8 @@ c_parser_postfix_expression (c_parser *parser) c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); if (pedantic) - pedwarn ("ISO C forbids braced-groups within expressions"); + pedwarn ("%HISO C forbids braced-groups within expressions", + &here); expr.value = c_finish_stmt_expr (stmt); expr.original_code = ERROR_MARK; } @@ -5262,6 +5389,7 @@ c_parser_postfix_expression (c_parser *parser) expr.original_code = ERROR_MARK; break; } + loc = c_parser_peek_token (parser)->location; e1 = c_parser_expr_no_commas (parser, NULL); if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) { @@ -5286,8 +5414,8 @@ c_parser_postfix_expression (c_parser *parser) c = fold (e1.value); if (TREE_CODE (c) != INTEGER_CST) - error ("first argument to %<__builtin_choose_expr%> not" - " a constant"); + error ("%Hfirst argument to %<__builtin_choose_expr%> not" + " a constant", &loc); expr = integer_zerop (c) ? e3 : e2; } break; @@ -5449,11 +5577,13 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser, tree type; struct c_expr init; struct c_expr expr; + location_t start_loc; start_init (NULL_TREE, NULL, 0); type = groktypename (type_name); + start_loc = c_parser_peek_token (parser)->location; if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type)) { - error ("compound literal has variable size"); + error ("%Hcompound literal has variable size", &start_loc); type = error_mark_node; } init = c_parser_braced_init (parser, type, false); @@ -5461,7 +5591,7 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser, maybe_warn_string_init (type, init); if (pedantic && !flag_isoc99) - pedwarn ("ISO C90 forbids compound literals"); + pedwarn ("%HISO C90 forbids compound literals", &start_loc); expr.value = build_compound_literal (type, init.value); expr.original_code = ERROR_MARK; return c_parser_postfix_expression_after_primary (parser, expr); @@ -5761,7 +5891,8 @@ c_parser_objc_class_instance_variables (c_parser *parser) if (c_parser_next_token_is (parser, CPP_SEMICOLON)) { if (pedantic) - pedwarn ("extra semicolon in struct or union specified"); + pedwarn ("%Hextra semicolon in struct or union specified", + &c_parser_peek_token (parser)->location); c_parser_consume_token (parser); continue; } @@ -5928,11 +6059,11 @@ c_parser_objc_protocol_definition (c_parser *parser) c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_LESS)) proto = c_parser_objc_protocol_refs (parser); - objc_pq_context = 1; + parser->objc_pq_context = true; objc_start_protocol (id, proto); c_parser_objc_methodprotolist (parser); c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); - objc_pq_context = 0; + parser->objc_pq_context = false; objc_finish_interface (); } } @@ -5972,20 +6103,21 @@ c_parser_objc_method_definition (c_parser *parser) enum tree_code type = c_parser_objc_method_type (parser); tree decl; objc_set_method_type (type); - objc_pq_context = 1; + parser->objc_pq_context = true; decl = c_parser_objc_method_decl (parser); if (c_parser_next_token_is (parser, CPP_SEMICOLON)) { c_parser_consume_token (parser); if (pedantic) - pedwarn ("extra semicolon in method definition specified"); + pedwarn ("%Hextra semicolon in method definition specified", + &c_parser_peek_token (parser)->location); } if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE)) { c_parser_error (parser, "expected %<{%>"); return; } - objc_pq_context = 0; + parser->objc_pq_context = false; objc_start_method_definition (decl); add_stmt (c_parser_compound_statement (parser)); objc_finish_method_definition (current_function_decl); @@ -6015,7 +6147,9 @@ c_parser_objc_methodprotolist (c_parser *parser) { case CPP_SEMICOLON: if (pedantic) - pedwarn ("ISO C does not allow extra %<;%> outside of a function"); + pedwarn ("%HISO C does not allow extra %<;%> " + "outside of a function", + &c_parser_peek_token (parser)->location); c_parser_consume_token (parser); break; case CPP_PLUS: @@ -6049,10 +6183,10 @@ c_parser_objc_methodproto (c_parser *parser) tree decl; objc_set_method_type (type); /* Remember protocol qualifiers in prototypes. */ - objc_pq_context = 1; + parser->objc_pq_context = true; decl = c_parser_objc_method_decl (parser); /* Forget protocol qualifiers here. */ - objc_pq_context = 0; + parser->objc_pq_context = false; objc_add_method_declaration (decl); c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); } @@ -6545,8 +6679,9 @@ c_parser_pragma (c_parser *parser, enum pragma_context context) return false; case PRAGMA_OMP_SECTION: - error ("%<#pragma omp section%> may only be used in " - "%<#pragma omp sections%> construct"); + error ("%H%<#pragma omp section%> may only be used in " + "%<#pragma omp sections%> construct", + &c_parser_peek_token (parser)->location); c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); return false; @@ -6907,6 +7042,7 @@ c_parser_omp_clause_num_threads (c_parser *parser, tree list) { if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { + location_t expr_loc = c_parser_peek_token (parser)->location; tree c, t = c_parser_expression (parser).value; c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -6922,7 +7058,7 @@ c_parser_omp_clause_num_threads (c_parser *parser, tree list) build_int_cst (TREE_TYPE (t), 0)); if (c == boolean_true_node) { - warning (0, "% value must be positive"); + warning (0, "%H% value must be positive", &expr_loc); t = integer_one_node; } @@ -7078,13 +7214,15 @@ c_parser_omp_clause_schedule (c_parser *parser, tree list) c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_COMMA)) { + location_t here; c_parser_consume_token (parser); + here = c_parser_peek_token (parser)->location; t = c_parser_expr_no_commas (parser, NULL).value; if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME) - error ("schedule % does not take " - "a % parameter"); + error ("%Hschedule % does not take " + "a % parameter", &here); else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE) OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t; else @@ -7127,6 +7265,7 @@ c_parser_omp_all_clauses (c_parser *parser, unsigned int mask, while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) { + location_t here = c_parser_peek_token (parser)->location; const pragma_omp_clause c_kind = c_parser_omp_clause_name (parser); const char *c_name; tree prev = clauses; @@ -7195,7 +7334,7 @@ c_parser_omp_all_clauses (c_parser *parser, unsigned int mask, /* Remove the invalid clause(s) from the list to avoid confusing the rest of the compiler. */ clauses = prev; - error ("%qs is not valid for %qs", c_name, where); + error ("%H%qs is not valid for %qs", &here, c_name, where); } } @@ -7424,7 +7563,7 @@ c_parser_omp_for_loop (c_parser *parser) { cond = c_parser_expression_conv (parser).value; cond = c_objc_common_truthvalue_conversion (cond); - if (EXPR_P (cond)) + if (CAN_HAVE_LOCATION_P (cond)) SET_EXPR_LOCATION (cond, input_location); } c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); @@ -7583,7 +7722,8 @@ c_parser_omp_sections_scope (c_parser *parser) } else if (!error_suppress) { - error ("expected %<#pragma omp section%> or %<}%>"); + error ("%Hexpected %<#pragma omp section%> or %<}%>", + &loc); error_suppress = true; } @@ -7755,6 +7895,12 @@ c_parser_omp_construct (c_parser *parser) p_kind = c_parser_peek_token (parser)->pragma_kind; c_parser_consume_pragma (parser); + /* For all constructs below except #pragma omp atomic + MUST_NOT_THROW catch handlers are needed when exceptions + are enabled. */ + if (p_kind != PRAGMA_OMP_ATOMIC) + c_maybe_initialize_eh (); + switch (p_kind) { case PRAGMA_OMP_ATOMIC: @@ -7801,9 +7947,6 @@ c_parser_omp_threadprivate (c_parser *parser) c_parser_consume_pragma (parser); vars = c_parser_omp_var_list_parens (parser, 0, NULL); - if (!targetm.have_tls) - sorry ("threadprivate variables not supported in this target"); - /* Mark every variable in VARS to be assigned thread local storage. */ for (t = vars; t; t = TREE_CHAIN (t)) {