OSDN Git Service

2007-08-04 Paul Thomas <pault@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / c-parser.c
index a5fa523..a1f8b85 100644 (file)
@@ -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
+<http://www.gnu.org/licenses/>.  */
 
 /* TODO:
 
@@ -59,25 +58,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "cgraph.h"
 
 \f
-/* 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
 {
@@ -200,26 +180,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 +277,13 @@ 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;
+  /* 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,7 +296,7 @@ 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);
 
@@ -345,8 +312,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 +323,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 +381,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 +403,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];
@@ -623,7 +593,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];
 }
@@ -829,50 +799,6 @@ c_parser_skip_to_end_of_parameter (c_parser *parser)
   parser->error = false;
 }
 
-/* Skip tokens until we have consumed an entire block, or until we
-   have consumed a non-nested ';'.  */
-
-static void
-c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
-{
-  unsigned nesting_depth = 0;
-
-  while (true)
-    {
-      c_token *token;
-
-      /* Peek at the next token.  */
-      token = c_parser_peek_token (parser);
-      /* If we've run out of tokens, stop.  */
-      if (token->type == CPP_EOF)
-       return;
-      if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
-       return;
-      /* If the next token is a ';', we have reached the end of the
-        statement.  */
-      if (token->type == CPP_SEMICOLON && !nesting_depth)
-       {
-         /* Consume the ';'.  */
-         c_parser_consume_token (parser);
-         break;
-       }
-      /* If the next token is a non-nested '}', then we have reached
-        the end of the current block.  */
-      if (token->type == CPP_CLOSE_BRACE
-         && (nesting_depth == 0 || --nesting_depth == 0))
-       {
-         c_parser_consume_token (parser);
-         break;
-       }
-      /* If it the next token is a '{', then we are entering a new
-        block.  Consume the entire block.  */
-      if (token->type == CPP_OPEN_BRACE)
-       ++nesting_depth;
-      c_parser_consume_token (parser);
-    }
-  parser->error = false;
-}
-
 /* Expect to be at the end of the pragma directive and consume an
    end of line marker.  */
 
@@ -899,6 +825,82 @@ c_parser_skip_to_pragma_eol (c_parser *parser)
   parser->error = false;
 }
 
+/* Skip tokens until we have consumed an entire block, or until we
+   have consumed a non-nested ';'.  */
+
+static void
+c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
+{
+  unsigned nesting_depth = 0;
+  bool save_error = parser->error;
+
+  while (true)
+    {
+      c_token *token;
+
+      /* Peek at the next token.  */
+      token = c_parser_peek_token (parser);
+
+      switch (token->type)
+       {
+       case CPP_EOF:
+         return;
+
+       case CPP_PRAGMA_EOL:
+         if (parser->in_pragma)
+           return;
+         break;
+
+       case CPP_SEMICOLON:
+         /* If the next token is a ';', we have reached the
+            end of the statement.  */
+         if (!nesting_depth)
+           {
+             /* Consume the ';'.  */
+             c_parser_consume_token (parser);
+             goto finished;
+           }
+         break;
+
+       case CPP_CLOSE_BRACE:
+         /* If the next token is a non-nested '}', then we have
+            reached the end of the current block.  */
+         if (nesting_depth == 0 || --nesting_depth == 0)
+           {
+             c_parser_consume_token (parser);
+             goto finished;
+           }
+         break;
+
+       case CPP_OPEN_BRACE:
+         /* If it the next token is a '{', then we are entering a new
+            block.  Consume the entire block.  */
+         ++nesting_depth;
+         break;
+
+       case CPP_PRAGMA:
+         /* If we see a pragma, consume the whole thing at once.  We
+            have some safeguards against consuming pragmas willy-nilly.
+            Normally, we'd expect to be here with parser->error set,
+            which disables these safeguards.  But it's possible to get
+            here for secondary error recovery, after parser->error has
+            been cleared.  */
+         c_parser_consume_pragma (parser);
+         c_parser_skip_to_pragma_eol (parser);
+         parser->error = save_error;
+         continue;
+
+       default:
+         break;
+       }
+
+      c_parser_consume_token (parser);
+    }
+
+ finished:
+  parser->error = false;
+}
+
 /* Save the warning flags which are controlled by __extension__.  */
 
 static inline int
@@ -1597,7 +1599,8 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
            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);
@@ -1690,7 +1693,8 @@ c_parser_enum_specifier (c_parser *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.  */
@@ -1718,7 +1722,7 @@ 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;
@@ -2119,6 +2123,7 @@ c_parser_typeof_specifier (c_parser *parser)
     }
   else
     {
+      bool was_vm;
       struct c_expr expr = c_parser_expression (parser);
       skip_evaluation--;
       in_typeof--;
@@ -2126,7 +2131,25 @@ c_parser_typeof_specifier (c_parser *parser)
          && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
        error ("%<typeof%> applied to a bit-field");
       ret.spec = TREE_TYPE (expr.value);
-      pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
+      was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
+      /* This should be returned with the type so that when the type
+        is evaluated, this can be evaluated.  For now, we avoid
+        evaluation when the context might.  */
+      if (!skip_evaluation && was_vm)
+       {
+         tree e = expr.value;
+
+         /* If the expression is not of a type to which we cannot assign a line
+            number, wrap the thing in a no-op NOP_EXPR.  */
+         if (DECL_P (e) || CONSTANT_CLASS_P (e))
+           e = build1 (NOP_EXPR, void_type_node, e);
+
+         if (CAN_HAVE_LOCATION_P (e))
+           SET_EXPR_LOCATION (e, input_location);
+
+         add_stmt (e);
+       }
+      pop_maybe_used (was_vm);
     }
   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
   return ret;
@@ -2193,7 +2216,7 @@ c_parser_typeof_specifier (c_parser *parser)
                         parameter-type-list[opt] )
 
    direct-abstract-declarator:
-     direct-abstract-declarator[opt] ( parameter-forward-declarations 
+     direct-abstract-declarator[opt] ( parameter-forward-declarations
                                       parameter-type-list[opt] )
 
    parameter-forward-declarations:
@@ -2422,6 +2445,8 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
        }
       declarator = build_array_declarator (dimen, quals_attrs, static_seen,
                                           star_seen);
+      if (declarator == NULL)
+       return NULL;
       inner = set_array_declarator_inner (declarator, inner, !id_present);
       return c_parser_direct_declarator_inner (parser, id_present, inner);
     }
@@ -2484,6 +2509,8 @@ c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs)
          ret->tags = 0;
          ret->types = list;
          ret->others = 0;
+         ret->pending_sizes = 0;
+         ret->had_vla_unspec = 0;
          c_parser_consume_token (parser);
          pop_scope ();
          return ret;
@@ -2525,6 +2552,8 @@ c_parser_parms_list_declarator (c_parser *parser, tree attrs)
       ret->tags = 0;
       ret->types = 0;
       ret->others = 0;
+      ret->pending_sizes = 0;
+      ret->had_vla_unspec = 0;
       c_parser_consume_token (parser);
       return ret;
     }
@@ -2534,6 +2563,8 @@ c_parser_parms_list_declarator (c_parser *parser, tree attrs)
       ret->parms = 0;
       ret->tags = 0;
       ret->others = 0;
+      ret->pending_sizes = 0;
+      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 %<...%>");
@@ -2584,6 +2615,8 @@ c_parser_parms_list_declarator (c_parser *parser, tree attrs)
              ret->tags = 0;
              ret->types = 0;
              ret->others = 0;
+             ret->pending_sizes = 0;
+             ret->had_vla_unspec = 0;
              return ret;
            }
        }
@@ -2609,6 +2642,8 @@ c_parser_parms_list_declarator (c_parser *parser, tree attrs)
                  ret->tags = 0;
                  ret->types = 0;
                  ret->others = 0;
+                 ret->pending_sizes = 0;
+                 ret->had_vla_unspec = 0;
                  return ret;
                }
            }
@@ -3440,6 +3475,8 @@ c_parser_compound_statement_nostart (c_parser *parser)
          last_stmt = true;
          c_parser_statement_after_labels (parser);
        }
+
+      parser->error = false;
     }
   if (last_label)
     error ("label at end of compound statement");
@@ -3752,7 +3789,7 @@ 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);
 }
 
@@ -3771,7 +3808,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;
@@ -3791,7 +3828,7 @@ c_parser_c99_block_statement (c_parser *parser)
    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.  */
+   the sake of -Wempty-body warnings.  */
 
 static tree
 c_parser_if_body (c_parser *parser, bool *if_p)
@@ -3803,7 +3840,7 @@ 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))
+  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
     add_stmt (build_empty_stmt ());
   c_parser_statement_after_labels (parser);
   return c_end_compound_stmt (block, flag_isoc99);
@@ -3912,6 +3949,9 @@ 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,
+             "suggest braces around empty body in %<do%> statement");
   block = c_begin_compound_stmt (flag_isoc99);
   loc = c_parser_peek_token (parser)->location;
   save_break = c_break_label;
@@ -4008,7 +4048,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 %<;%>");
        }
@@ -4660,6 +4700,10 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
          ret.original_code = ERROR_MARK;
          return ret;
        }
+
+      /* Save casted types in the function's used types hash table.  */
+      used_types_insert (type_name->specs->type);
+
       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
        return c_parser_postfix_expression_after_paren_type (parser,
                                                             type_name);
@@ -4835,6 +4879,12 @@ c_parser_sizeof_expression (c_parser *parser)
       /* sizeof ( type-name ).  */
       skip_evaluation--;
       in_sizeof--;
+      if (type_name->declarator->kind == cdk_array
+         && type_name->declarator->u.array.vla_unspec_p)
+       {
+         /* C99 6.7.5.2p4 */
+         error ("%<[*]%> not allowed in other than a declaration");
+       }
       return c_expr_sizeof_type (type_name);
     }
   else
@@ -5133,7 +5183,7 @@ c_parser_postfix_expression (c_parser *parser)
            if (type == error_mark_node)
              offsetof_ref = error_mark_node;
            else
-             offsetof_ref = build1 (INDIRECT_REF, type, NULL);
+             offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
            /* Parse the second argument to __builtin_offsetof.  We
               must have one identifier, and beyond that we want to
               accept sub structure and sub array references.  */
@@ -5175,7 +5225,7 @@ c_parser_postfix_expression (c_parser *parser)
              c_parser_error (parser, "expected identifier");
            c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
                                       "expected %<)%>");
-           expr.value = fold_offsetof (offsetof_ref);
+           expr.value = fold_offsetof (offsetof_ref, NULL_TREE);
            expr.original_code = ERROR_MARK;
          }
          break;
@@ -5376,7 +5426,7 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
   struct c_expr expr;
   start_init (NULL_TREE, NULL, 0);
   type = groktypename (type_name);
-  if (C_TYPE_VARIABLE_SIZE (type))
+  if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
     {
       error ("compound literal has variable size");
       type = error_mark_node;
@@ -5853,11 +5903,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 ();
     }
 }
@@ -5897,7 +5947,7 @@ 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))
     {
@@ -5910,7 +5960,7 @@ c_parser_objc_method_definition (c_parser *parser)
       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);
@@ -5974,10 +6024,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 %<;%>");
 }
@@ -6625,7 +6675,7 @@ check_no_duplicate_clause (tree clauses, enum tree_code code, const char *name)
   tree c;
 
   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
-    if (TREE_CODE (c) == code)
+    if (OMP_CLAUSE_CODE (c) == code)
       {
        error ("too many %qs clauses", name);
        break;
@@ -6644,7 +6694,8 @@ check_no_duplicate_clause (tree clauses, enum tree_code code, const char *name)
    return the list created.  */
 
 static tree
-c_parser_omp_variable_list (c_parser *parser, enum tree_code kind, tree list)
+c_parser_omp_variable_list (c_parser *parser, enum omp_clause_code kind,
+                            tree list)
 {
   if (c_parser_next_token_is_not (parser, CPP_NAME)
       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
@@ -6662,7 +6713,7 @@ c_parser_omp_variable_list (c_parser *parser, enum tree_code kind, tree list)
        ;
       else if (kind != 0)
        {
-         tree u = make_node (kind);
+         tree u = build_omp_clause (kind);
          OMP_CLAUSE_DECL (u) = t;
          OMP_CLAUSE_CHAIN (u) = list;
          list = u;
@@ -6759,7 +6810,7 @@ c_parser_omp_clause_default (c_parser *parser, tree list)
     return list;
 
   check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
-  c = make_node (OMP_CLAUSE_DEFAULT);
+  c = build_omp_clause (OMP_CLAUSE_DEFAULT);
   OMP_CLAUSE_CHAIN (c) = list;
   OMP_CLAUSE_DEFAULT_KIND (c) = kind;
 
@@ -6788,7 +6839,7 @@ c_parser_omp_clause_if (c_parser *parser, tree list)
 
       check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if");
 
-      c = make_node (OMP_CLAUSE_IF);
+      c = build_omp_clause (OMP_CLAUSE_IF);
       OMP_CLAUSE_IF_EXPR (c) = t;
       OMP_CLAUSE_CHAIN (c) = list;
       list = c;
@@ -6818,7 +6869,7 @@ c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
 
   check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
 
-  c = make_node (OMP_CLAUSE_NOWAIT);
+  c = build_omp_clause (OMP_CLAUSE_NOWAIT);
   OMP_CLAUSE_CHAIN (c) = list;
   return c;
 }
@@ -6852,7 +6903,7 @@ c_parser_omp_clause_num_threads (c_parser *parser, tree list)
 
       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
 
-      c = make_node (OMP_CLAUSE_NUM_THREADS);
+      c = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
       OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
       OMP_CLAUSE_CHAIN (c) = list;
       list = c;
@@ -6871,7 +6922,7 @@ c_parser_omp_clause_ordered (c_parser *parser ATTRIBUTE_UNUSED, tree list)
 
   check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
 
-  c = make_node (OMP_CLAUSE_ORDERED);
+  c = build_omp_clause (OMP_CLAUSE_ORDERED);
   OMP_CLAUSE_CHAIN (c) = list;
   return c;
 }
@@ -6963,7 +7014,7 @@ c_parser_omp_clause_schedule (c_parser *parser, tree list)
   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
     return list;
 
-  c = make_node (OMP_CLAUSE_SCHEDULE);
+  c = build_omp_clause (OMP_CLAUSE_SCHEDULE);
 
   if (c_parser_next_token_is (parser, CPP_NAME))
     {
@@ -7160,6 +7211,7 @@ static void
 c_parser_omp_atomic (c_parser *parser)
 {
   tree lhs, rhs;
+  tree stmt;
   enum tree_code code;
 
   c_parser_skip_to_pragma_eol (parser);
@@ -7226,7 +7278,9 @@ c_parser_omp_atomic (c_parser *parser)
       rhs = c_parser_expression (parser).value;
       break;
     }
-  c_finish_omp_atomic (code, lhs, rhs);
+  stmt = c_finish_omp_atomic (code, lhs, rhs);
+  if (stmt != error_mark_node)
+    add_stmt (stmt);
   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
 }
 
@@ -7345,7 +7399,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 %<;%>");
@@ -7373,7 +7427,7 @@ c_parser_omp_for_loop (c_parser *parser)
 
   /* Only bother calling c_finish_omp_for if we havn't already generated
      an error from the initialization parsing.  */
-  if (decl != NULL)
+  if (decl != NULL && decl != error_mark_node && init != error_mark_node)
     return c_finish_omp_for (loc, decl, init, cond, incr, body, NULL);
   return NULL;
 
@@ -7617,6 +7671,7 @@ c_parser_omp_parallel (c_parser *parser)
       if (stmt)
        OMP_FOR_CLAUSES (stmt) = ws_clause;
       stmt = c_finish_omp_parallel (par_clause, block);
+      OMP_PARALLEL_COMBINED (stmt) = 1;
       break;
 
     case PRAGMA_OMP_PARALLEL_SECTIONS:
@@ -7626,6 +7681,7 @@ c_parser_omp_parallel (c_parser *parser)
       if (stmt)
        OMP_SECTIONS_CLAUSES (stmt) = ws_clause;
       stmt = c_finish_omp_parallel (par_clause, block);
+      OMP_PARALLEL_COMBINED (stmt) = 1;
       break;
 
     default:
@@ -7674,6 +7730,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:
@@ -7720,9 +7782,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))
     {