[PATCH][GIMPLE FE] Split out parser into separate file

Richard Biener rguenther@suse.de
Tue Oct 25 13:33:00 GMT 2016


Hi,

so I did the massaging to split out the GIMPLE parsing routines out
to a separate file (quite tricky to get the gengtype issues correctly
so I thought to help out here and get things started).

Tested on x86_64-unknown-linux-gnu, bootstrap is still in progress.

Will push to gimplefe soon.

I think it shows that the GIMPLE FE should maybe not use
c_parser_cast_expression or c_token_starts_typename or
c_parser_next_token_starts_declspecs.  But maybe it's not
100% avoidable as we want to re-use C parsing for local
declarations (of types and decls) as well (eventually even
local statics with initializers which remain GENERIC).

Richard.

commit f2dc45b7d1cbd3122944a26f449d7fd233994f50
Author: Richard Guenther <rguenther@suse.de>
Date:   Tue Oct 25 15:20:42 2016 +0200

    2016-10-25  Richard Biener  <rguenther@suse.de>
    
    	c/
    	* Make-lang.in (C_AND_OBJC_OBJS): Add gimple-parser.o.
    	* config-lang.in (gtfiles): Add c/c-parser.h.
    	* c-lang.c: Include c-pragma.h and c-parser.h.
    	* c-parser.c (enum c_id_kind, struct c_token,
    	struct c_parser, c_parser_next_token_is,
    	c_parser_next_token_is_not,
    	c_parser_next_token_is_keyword,
    	enum c_lookahead_kind, enum c_dtr_syn, enum c_parser_prec):
    	Split out to ...
    	* c-parser.h: ... new header.
    	* c-parser.c (c_parser_peek_token, c_parser_peek_2nd_token,
    	c_token_starts_typename, c_parser_next_token_starts_declspecs,
    	c_parser_next_tokens_start_declaration, c_parser_consume_token,
    	c_parser_error, c_parser_require, c_parser_skip_until_found,
    	c_parser_declspecs, c_parser_declarator,
    	c_parser_cast_expression): Export.
    	* c-parser.h (c_parser_peek_token, c_parser_peek_2nd_token,
    	c_token_starts_typename, c_parser_next_token_starts_declspecs,
    	c_parser_next_tokens_start_declaration, c_parser_consume_token,
    	c_parser_error, c_parser_require, c_parser_skip_until_found,
    	c_parser_declspecs, c_parser_declarator,
    	c_parser_cast_expression): Declare.
    	* gimple-parser.c: Moved from c-parser.c.
    	* gimple-parser.h (c_parser_parse_gimple_body): Declare.
    	(c_parser_gimple_pass_list): Likewise.
    
    	obj-c/
    	* config-lang.in (gtfiles): Add c/c-parser.h.

diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in
index 72c9ae7..cd7108b 100644
--- a/gcc/c/Make-lang.in
+++ b/gcc/c/Make-lang.in
@@ -51,7 +51,8 @@ CFLAGS-c/gccspec.o += $(DRIVER_DEFINES)
 # Language-specific object files for C and Objective C.
 C_AND_OBJC_OBJS = attribs.o c/c-errors.o c/c-decl.o c/c-typeck.o \
   c/c-convert.o c/c-aux-info.o c/c-objc-common.o c/c-parser.o \
-  c/c-array-notation.o c/c-fold.o $(C_COMMON_OBJS) $(C_TARGET_OBJS)
+  c/c-array-notation.o c/c-fold.o c/gimple-parser.o \
+  $(C_COMMON_OBJS) $(C_TARGET_OBJS)
 
 # Language-specific object files for C.
 C_OBJS = c/c-lang.o c-family/stub-objc.o $(C_AND_OBJC_OBJS)
diff --git a/gcc/c/c-lang.c b/gcc/c/c-lang.c
index b4096d0..a2dd768 100644
--- a/gcc/c/c-lang.c
+++ b/gcc/c/c-lang.c
@@ -25,6 +25,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "langhooks-def.h"
 #include "c-objc-common.h"
+#include "c-family/c-pragma.h"
+#include "c-parser.h"
 
 enum c_language_kind c_language = clk_c;
 
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 639d94f..9b51c48 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -59,18 +59,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-expr.h"
 #include "context.h"
 #include "gcc-rich-location.h"
-#include "tree-vrp.h"
-#include "tree-pass.h"
-#include "tree-pretty-print.h"
-#include "tree.h"
-#include "basic-block.h"
-#include "gimple.h"
-#include "gimple-pretty-print.h"
-#include "tree-ssa.h"
-#include "pass_manager.h"
-#include "tree-ssanames.h"
-#include "gimple-ssa.h"
-#include "tree-dfa.h"
+#include "c-parser.h"
+#include "gimple-parser.h"
 
 /* We need to walk over decls with incomplete struct/union/enum types
    after parsing the whole translation unit.
@@ -162,116 +152,6 @@ c_parse_init (void)
     }
 }
 
-/* The C lexer intermediates between the lexer in cpplib and c-lex.c
-   and the C parser.  Unlike the C++ lexer, the parser structure
-   stores the lexer information instead of using a separate structure.
-   Identifiers are separated into ordinary identifiers, type names,
-   keywords and some other Objective-C types of identifiers, and some
-   look-ahead is maintained.
-
-   ??? It might be a good idea to lex the whole file up front (as for
-   C++).  It would then be possible to share more of the C and C++
-   lexer code, if desired.  */
-
-/* More information about the type of a CPP_NAME token.  */
-enum c_id_kind {
-  /* An ordinary identifier.  */
-  C_ID_ID,
-  /* An identifier declared as a typedef name.  */
-  C_ID_TYPENAME,
-  /* An identifier declared as an Objective-C class name.  */
-  C_ID_CLASSNAME,
-  /* An address space identifier.  */
-  C_ID_ADDRSPACE,
-  /* Not an identifier.  */
-  C_ID_NONE
-};
-
-/* A single C token after string literal concatenation and conversion
-   of preprocessing tokens to tokens.  */
-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
-     declared as some kind of type.  Otherwise, it is C_ID_NONE.  */
-  ENUM_BITFIELD (c_id_kind) id_kind : 8;
-  /* If this token is a keyword, this value indicates which keyword.
-     Otherwise, this value is RID_MAX.  */
-  ENUM_BITFIELD (rid) keyword : 8;
-  /* If this token is a CPP_PRAGMA, this indicates the pragma that
-     was seen.  Otherwise it is PRAGMA_NONE.  */
-  ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
-  /* The location at which this token was found.  */
-  location_t location;
-  /* The value associated with this token, if any.  */
-  tree value;
-  /* Token flags.  */
-  unsigned char flags;
-
-  source_range get_range () const
-  {
-    return get_range_from_loc (line_table, location);
-  }
-
-  location_t get_finish () const
-  {
-    return get_range ().m_finish;
-  }
-};
-
-/* 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.  */
-struct GTY(()) c_parser {
-  /* The look-ahead tokens.  */
-  c_token * GTY((skip)) tokens;
-  /* Buffer for look-ahead tokens.  */
-  c_token tokens_buf[4];
-  /* How many look-ahead tokens are available (0 - 4, or
-     more if parsing from pre-lexed tokens).  */
-  unsigned int tokens_avail;
-  /* True if a syntax error is being recovered from; false otherwise.
-     c_parser_error sets this flag.  It should clear this flag when
-     enough tokens have been consumed to recover from the error.  */
-  BOOL_BITFIELD error : 1;
-  /* 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.  */
-
-  /* True if we are in a context where the Objective-C "PQ" keywords
-     are considered keywords.  */
-  BOOL_BITFIELD objc_pq_context : 1;
-  /* True if we are parsing a (potential) Objective-C foreach
-     statement.  This is set to true after we parsed 'for (' and while
-     we wait for 'in' or ';' to decide if it's a standard C for loop or an
-     Objective-C foreach loop.  */
-  BOOL_BITFIELD objc_could_be_foreach_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;
-  /* Nonzero if we're processing a __transaction statement.  The value
-     is 1 | TM_STMT_ATTR_*.  */
-  unsigned int in_transaction : 4;
-  /* True if we are in a context where the Objective-C "Property attribute"
-     keywords are valid.  */
-  BOOL_BITFIELD objc_property_attr_context : 1;
-
-  /* Cilk Plus specific parser/lexer information.  */
-
-  /* Buffer to hold all the tokens from parsing the vector attribute for the
-     SIMD-enabled functions (formerly known as elemental functions).  */
-  vec <c_token, va_gc> *cilk_simd_fn_tokens;
-};
-
-
 /* The actual parser and external interface.  ??? Does this need to be
    garbage-collected?  */
 
@@ -466,7 +346,7 @@ c_lex_one_token (c_parser *parser, c_token *token)
 /* Return a pointer to the next token from PARSER, reading it in if
    necessary.  */
 
-static inline c_token *
+c_token *
 c_parser_peek_token (c_parser *parser)
 {
   if (parser->tokens_avail == 0)
@@ -477,37 +357,10 @@ c_parser_peek_token (c_parser *parser)
   return &parser->tokens[0];
 }
 
-/* Return true if the next token from PARSER has the indicated
-   TYPE.  */
-
-static inline bool
-c_parser_next_token_is (c_parser *parser, enum cpp_ttype type)
-{
-  return c_parser_peek_token (parser)->type == type;
-}
-
-/* Return true if the next token from PARSER does not have the
-   indicated TYPE.  */
-
-static inline bool
-c_parser_next_token_is_not (c_parser *parser, enum cpp_ttype type)
-{
-  return !c_parser_next_token_is (parser, type);
-}
-
-/* Return true if the next token from PARSER is the indicated
-   KEYWORD.  */
-
-static inline bool
-c_parser_next_token_is_keyword (c_parser *parser, enum rid keyword)
-{
-  return c_parser_peek_token (parser)->keyword == keyword;
-}
-
 /* Return a pointer to the next-but-one token from PARSER, reading it
    in if necessary.  The next token is already read in.  */
 
-static c_token *
+c_token *
 c_parser_peek_2nd_token (c_parser *parser)
 {
   if (parser->tokens_avail >= 2)
@@ -582,7 +435,7 @@ c_keyword_starts_typename (enum rid keyword)
 
 /* Return true if TOKEN can start a type name,
    false otherwise.  */
-static bool
+bool
 c_token_starts_typename (c_token *token)
 {
   switch (token->type)
@@ -613,18 +466,6 @@ c_token_starts_typename (c_token *token)
     }
 }
 
-enum c_lookahead_kind {
-  /* Always treat unknown identifiers as typenames.  */
-  cla_prefer_type,
-
-  /* Could be parsing a nonabstract declarator.  Only treat an identifier
-     as a typename if followed by another identifier or a star.  */
-  cla_nonabstract_decl,
-
-  /* Never treat identifiers as typenames.  */
-  cla_prefer_id
-};
-
 /* Return true if the next token from PARSER can start a type name,
    false otherwise.  LA specifies how to do lookahead in order to
    detect unknown type names.  If unsure, pick CLA_PREFER_ID.  */
@@ -791,7 +632,7 @@ c_token_starts_declaration (c_token *token)
 
 /* Return true if the next token from PARSER can start declaration
    specifiers, false otherwise.  */
-static inline bool
+bool
 c_parser_next_token_starts_declspecs (c_parser *parser)
 {
   c_token *token = c_parser_peek_token (parser);
@@ -813,7 +654,7 @@ c_parser_next_token_starts_declspecs (c_parser *parser)
 
 /* Return true if the next tokens from PARSER can start declaration
    specifiers or a static assertion, false otherwise.  */
-static inline bool
+bool
 c_parser_next_tokens_start_declaration (c_parser *parser)
 {
   c_token *token = c_parser_peek_token (parser);
@@ -841,7 +682,7 @@ c_parser_next_tokens_start_declaration (c_parser *parser)
 
 /* Consume the next token from PARSER.  */
 
-static void
+void
 c_parser_consume_token (c_parser *parser)
 {
   gcc_assert (parser->tokens_avail >= 1);
@@ -934,7 +775,7 @@ c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
    this way is not i18n-friendly and some other approach should be
    used.  */
 
-static void
+void
 c_parser_error (c_parser *parser, const char *gmsgid)
 {
   c_token *token = c_parser_peek_token (parser);
@@ -977,7 +818,7 @@ c_parser_error (c_parser *parser, const char *gmsgid)
    been produced and no message will be produced this time.  Returns
    true if found, false otherwise.  */
 
-static bool
+bool
 c_parser_require (c_parser *parser,
 		  enum cpp_ttype type,
 		  const char *msgid)
@@ -1020,7 +861,7 @@ c_parser_require_keyword (c_parser *parser,
    already been produced and no message will be produced this
    time.  */
 
-static void
+void
 c_parser_skip_until_found (c_parser *parser,
 			   enum cpp_ttype type,
 			   const char *msgid)
@@ -1255,42 +1096,6 @@ restore_extension_diagnostics (int flags)
   warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
 }
 
-/* Possibly kinds of declarator to parse.  */
-enum c_dtr_syn {
-  /* A normal declarator with an identifier.  */
-  C_DTR_NORMAL,
-  /* An abstract declarator (maybe empty).  */
-  C_DTR_ABSTRACT,
-  /* A parameter declarator: may be either, but after a type name does
-     not redeclare a typedef name as an identifier if it can
-     alternatively be interpreted as a typedef name; see DR#009,
-     applied in C90 TC1, omitted from C99 and reapplied in C99 TC2
-     following DR#249.  For example, given a typedef T, "int T" and
-     "int *T" are valid parameter declarations redeclaring T, while
-     "int (T)" and "int * (T)" and "int (T[])" and "int (T (int))" are
-     abstract declarators rather than involving redundant parentheses;
-     the same applies with attributes inside the parentheses before
-     "T".  */
-  C_DTR_PARM
-};
-
-/* The binary operation precedence levels, where 0 is a dummy lowest level
-   used for the bottom of the stack.  */
-enum c_parser_prec {
-  PREC_NONE,
-  PREC_LOGOR,
-  PREC_LOGAND,
-  PREC_BITOR,
-  PREC_BITXOR,
-  PREC_BITAND,
-  PREC_EQ,
-  PREC_REL,
-  PREC_SHIFT,
-  PREC_ADD,
-  PREC_MULT,
-  NUM_PRECS
-};
-
 /* Helper data structure for parsing #pragma acc routine.  */
 struct oacc_routine_data {
   bool error_seen; /* Set if error has been reported.  */
@@ -1307,15 +1112,11 @@ static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
 					   bool * = NULL);
 static void c_parser_static_assert_declaration_no_semi (c_parser *);
 static void c_parser_static_assert_declaration (c_parser *);
-static void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool,
-				bool, bool, bool, enum c_lookahead_kind);
 static struct c_typespec c_parser_enum_specifier (c_parser *);
 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
 static tree c_parser_struct_declaration (c_parser *);
 static struct c_typespec c_parser_typeof_specifier (c_parser *);
 static tree c_parser_alignas_specifier (c_parser *);
-static struct c_declarator *c_parser_declarator (c_parser *, bool, c_dtr_syn,
-						 bool *);
 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
 							c_dtr_syn, bool *);
 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
@@ -1355,7 +1156,6 @@ static struct c_expr c_parser_conditional_expression (c_parser *,
 						      struct c_expr *, tree);
 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
 						 tree);
-static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
 static struct c_expr c_parser_unary_expression (c_parser *);
 static struct c_expr c_parser_sizeof_expression (c_parser *);
 static struct c_expr c_parser_alignof_expression (c_parser *);
@@ -1433,30 +1233,6 @@ static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
 static tree c_parser_cilk_clause_vectorlength (c_parser *, tree, bool);
 static void c_parser_cilk_grainsize (c_parser *, bool *);
 
-/* Gimple parsing functions.  */
-static void c_parser_parse_gimple_body (c_parser *);
-static bool c_parser_gimple_compound_statement (c_parser *, gimple_seq *);
-static void c_parser_gimple_label (c_parser *, gimple_seq *);
-static void c_parser_gimple_expression (c_parser *, gimple_seq *);
-static struct c_expr c_parser_gimple_binary_expression (c_parser *, enum tree_code *);
-static struct c_expr c_parser_gimple_unary_expression (c_parser *);
-static struct c_expr c_parser_gimple_postfix_expression (c_parser *);
-static struct c_expr c_parser_gimple_postfix_expression_after_primary (c_parser *,
-								       location_t,
-								       struct c_expr);
-static void c_parser_gimple_pass_list (c_parser *, opt_pass **, bool *);
-static opt_pass *c_parser_gimple_pass_list_params (c_parser *, opt_pass **);
-static void c_parser_gimple_declaration (c_parser *);
-static void c_parser_gimple_goto_stmt (location_t, tree, gimple_seq *);
-static void c_parser_gimple_if_stmt (c_parser *, gimple_seq *);
-static void c_parser_gimple_switch_stmt (c_parser *, gimple_seq *);
-static void c_parser_gimple_return_stmt (c_parser *, gimple_seq *);
-static void c_finish_gimple_return (location_t, tree);
-static c_expr c_parser_parse_ssa_names (c_parser *);
-static tree c_parser_gimple_paren_condition (c_parser *);
-static vec<tree, va_gc> *c_parser_gimple_expr_list (c_parser *,
-		    vec<tree, va_gc> **, vec<location_t> *);
-
 /* Parse a translation unit (C90 6.7, C99 6.9).
 
    translation-unit:
@@ -2496,7 +2272,7 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser)
      objc-protocol-refs
 */
 
-static void
+void
 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
 		    bool scspec_ok, bool typespec_ok, bool start_attr_ok,
 		    bool alignspec_ok, bool auto_type_ok,
@@ -3495,7 +3271,7 @@ c_parser_alignas_specifier (c_parser * parser)
    This function also accepts an omitted abstract declarator as being
    an abstract declarator, although not part of the formal syntax.  */
 
-static struct c_declarator *
+struct c_declarator *
 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
 		     bool *seen_id)
 {
@@ -6946,7 +6722,7 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after,
      ( type-name ) unary-expression
 */
 
-static struct c_expr
+struct c_expr
 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
 {
   location_t cast_loc = c_parser_peek_token (parser)->location;
@@ -18393,1309 +18169,4 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index,
   return value_tree;
 }
 
-/* Parse the body of a function declaration marked with "__GIMPLE".  */
-
-void
-c_parser_parse_gimple_body (c_parser *parser)
-{
-  gimple_seq seq = NULL;
-  gimple_seq body = NULL;
-  tree stmt = push_stmt_list ();
-  push_scope ();
-  location_t loc1 = c_parser_peek_token (parser)->location;
-
-  init_tree_ssa (cfun);
-
-  if (! c_parser_gimple_compound_statement (parser, &seq))
-    {
-      gimple *ret = gimple_build_return (NULL);
-      gimple_seq_add_stmt (&seq, ret);
-    }
-
-  tree block = pop_scope ();
-  stmt = pop_stmt_list (stmt);
-  stmt = c_build_bind_expr (loc1, block, stmt);
-
-  block = DECL_INITIAL (current_function_decl);
-  BLOCK_SUBBLOCKS (block) = NULL_TREE;
-  BLOCK_CHAIN (block) = NULL_TREE;
-  TREE_ASM_WRITTEN (block) = 1;
-
-  gbind *bind_stmt = gimple_build_bind (BIND_EXPR_VARS (stmt), NULL,
-					BIND_EXPR_BLOCK (stmt));
-  gimple_bind_set_body (bind_stmt, seq);
-  gimple_seq_add_stmt (&body, bind_stmt);
-  gimple_set_body (current_function_decl, body);
-  cfun->curr_properties = PROP_gimple_any;
-
-  return;
-}
-
-/* Parse a compound statement in gimple function body.
-
-   gimple-statement:
-     gimple-statement
-     gimple-declaration-statement
-     gimple-if-statement
-     gimple-switch-statement
-     gimple-labeled-statement
-     gimple-expression-statement
-     gimple-goto-statement
-     gimple-phi-statement
-     gimple-return-statement
-*/
-
-static bool
-c_parser_gimple_compound_statement (c_parser *parser, gimple_seq *seq)
-{
-  bool return_p = false;
-
-  if (! c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
-    return false;
-
-  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
-    {
-      c_parser_consume_token (parser);
-      return false;
-    }
-
-  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
-    {
-      c_parser_error (parser, "expected declaration or statement");
-      c_parser_consume_token (parser);
-      return false;
-    }
-
-  while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
-    {
-      if (parser->error)
-	{
-	  c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
-	  return return_p;
-	}
-
-      if (c_parser_next_token_is (parser, CPP_NAME)
-	  && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
-	c_parser_gimple_label (parser, seq);
-
-      else if (c_parser_next_tokens_start_declaration (parser))
-	c_parser_gimple_declaration (parser);
-
-      else if (c_parser_next_token_is (parser, CPP_EOF))
-	{
-	  c_parser_error (parser, "expected declaration or statement");
-	  return return_p;
-	}
-
-      else
-	{
-	  switch (c_parser_peek_token (parser)->type)
-	    {
-	    case CPP_KEYWORD:
-	      switch (c_parser_peek_token (parser)->keyword)
-		{
-		case RID_IF:
-		  c_parser_gimple_if_stmt (parser, seq);
-		  break;
-		case RID_SWITCH:
-		  c_parser_gimple_switch_stmt (parser, seq);
-		  break;
-		case RID_GOTO:
-		    {
-		      location_t loc = c_parser_peek_token (parser)->location;
-		      c_parser_consume_token (parser);
-		      if (c_parser_next_token_is (parser, CPP_NAME))
-			{
-			  c_parser_gimple_goto_stmt (loc,
-						     c_parser_peek_token
-						       (parser)->value,
-						     seq);
-			  c_parser_consume_token (parser);
-			  if (! c_parser_require (parser, CPP_SEMICOLON,
-						  "expected %<;%>"))
-			    return return_p;
-			}
-		    }
-		  break;
-		case RID_RETURN:
-		  return_p = true;
-		  c_parser_gimple_return_stmt (parser, seq);
-		  if (! c_parser_require (parser, CPP_SEMICOLON,
-					  "expected %<;%>"))
-		    return return_p;
-		  break;
-		default:
-		  goto expr_stmt;
-		}
-	      break;
-	    case CPP_SEMICOLON:
-	      c_parser_consume_token (parser);
-	      break;
-	    default:
-	    expr_stmt:
-	      c_parser_gimple_expression (parser, seq);
-	      if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
-		return return_p;
-	    }
-	}
-    }
-  c_parser_consume_token (parser);
-  return return_p; 
-}
-
-/* Parse a gimple expression.
-
-   gimple-expression:
-     gimple-unary-expression
-     gimple-call-statement
-     gimple-binary-expression
-     gimple-assign-expression
-     gimple-cast-expression
-
-*/
-
-static void
-c_parser_gimple_expression (c_parser *parser, gimple_seq *seq)
-{
-  struct c_expr lhs, rhs;
-  gimple *assign = NULL;
-  enum tree_code subcode = NOP_EXPR;
-  location_t loc;
-  tree arg = NULL_TREE;
-  auto_vec<tree> vargs;
-
-  lhs = c_parser_gimple_unary_expression (parser);
-  rhs.value = error_mark_node;
-
-  if (c_parser_next_token_is (parser, CPP_EQ))
-    c_parser_consume_token (parser);
-
-  loc = EXPR_LOCATION (lhs.value);
-
-  /* GIMPLE call expression.  */
-  if (c_parser_next_token_is (parser, CPP_SEMICOLON)
-      && TREE_CODE (lhs.value) == CALL_EXPR)
-    {
-      gimple *call;
-      call = gimple_build_call_from_tree (lhs.value);
-      gimple_seq_add_stmt (seq, call);
-      gimple_set_location (call, loc);
-      return;
-    }
-
-  /* Cast expression.  */
-  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
-      && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
-    {
-      /* TODO: have a gimple_cast_expr function.  */
-      rhs = c_parser_cast_expression (parser, NULL);
-      if (lhs.value != error_mark_node &&
-	  rhs.value != error_mark_node)
-	{
-	  assign = gimple_build_assign (lhs.value, rhs.value);
-	  gimple_seq_add_stmt (seq, assign);
-	  gimple_set_location (assign, loc);
-	  return;
-	}
-    }
-
-  if (POINTER_TYPE_P (TREE_TYPE (lhs.value)))
-    {
-      STRIP_USELESS_TYPE_CONVERSION (rhs.value);
-      if (! useless_type_conversion_p (TREE_TYPE (lhs.value),
-				       TREE_TYPE (rhs.value)))
-	rhs.value = fold_convert_loc (loc, TREE_TYPE (lhs.value), rhs.value);
-    }
-
-  /* Pointer expression.  */
-  if (TREE_CODE (lhs.value) == INDIRECT_REF)
-    {
-      tree save_expr = lhs.value;
-      bool volatilep = TREE_THIS_VOLATILE (lhs.value);
-      bool notrap = TREE_THIS_NOTRAP (lhs.value);
-      tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (lhs.value, 0));
-
-      lhs.value = fold_indirect_ref_loc (loc, lhs.value);
-      if (lhs.value == save_expr)
-	{
-	  lhs.value = fold_build2_loc (input_location, MEM_REF,
-				       TREE_TYPE (lhs.value),
-				       TREE_OPERAND (lhs.value, 0),
-				       build_int_cst (saved_ptr_type, 0));
-	  TREE_THIS_VOLATILE (lhs.value) = volatilep;
-	  TREE_THIS_NOTRAP (lhs.value) = notrap;
-	}
-    }
-
-  if (c_parser_next_token_is (parser, CPP_AND)
-      || c_parser_next_token_is (parser, CPP_MULT)
-      || c_parser_next_token_is (parser, CPP_PLUS)
-      || c_parser_next_token_is (parser, CPP_MINUS)
-      || c_parser_next_token_is (parser, CPP_COMPL)
-      || c_parser_next_token_is (parser, CPP_NOT))
-    {
-      rhs = c_parser_gimple_unary_expression (parser);
-      assign = gimple_build_assign (lhs.value, rhs.value);
-      gimple_set_location (assign, loc);
-      gimple_seq_add_stmt (seq, assign);
-      return;
-    }
-
-  /* GIMPLE PHI expression.  */
-  if (c_parser_next_token_is_keyword (parser, RID_PHI))
-    {
-      c_parser_consume_token (parser);
-
-      if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
-	return;
-
-      if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
-	c_parser_consume_token (parser);
-
-      while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
-	{
-	  if (c_parser_next_token_is (parser, CPP_NAME)
-	      && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
-	    {
-	      arg = lookup_label_for_goto (loc,
-					   c_parser_peek_token (parser)->value);
-	      c_parser_consume_token (parser);
-
-	      if (c_parser_next_token_is (parser, CPP_COLON))
-		c_parser_consume_token (parser);
-	      vargs.safe_push (arg);
-	    }
-	  else if (c_parser_next_token_is (parser, CPP_COMMA))
-	    c_parser_consume_token (parser);
-	  else
-	    {
-	      arg = c_parser_parse_ssa_names (parser).value;
-	      vargs.safe_push (arg);
-	    }
-	}
-
-      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
-				 "expected %<)%>");
-
-      /* Build internal function for PHI.  */
-      gcall *call_stmt = gimple_build_call_internal_vec (IFN_PHI, vargs);
-      gimple_call_set_lhs (call_stmt, lhs.value);
-      gimple_set_location (call_stmt, UNKNOWN_LOCATION);
-      gimple_seq_add_stmt (seq, call_stmt);
-      return;
-    }
-
-  /* GIMPLE call with lhs.  */
-  if (c_parser_next_token_is (parser, CPP_NAME)
-      && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN
-      && lookup_name (c_parser_peek_token (parser)->value))
-    {
-      rhs = c_parser_gimple_unary_expression (parser);
-      gimple *call = gimple_build_call_from_tree (rhs.value);
-      gimple_call_set_lhs (call, lhs.value);
-      gimple_seq_add_stmt (seq, call);
-      gimple_set_location (call, loc);
-      return;
-    }
-
-  rhs = c_parser_gimple_binary_expression (parser, &subcode);
-
-  if (lhs.value != error_mark_node
-      && rhs.value != error_mark_node)
-    {
-      if (subcode == NOP_EXPR)
-	assign = gimple_build_assign (lhs.value, rhs.value);
-      else
-	assign = gimple_build_assign (lhs.value, subcode,
-				      TREE_OPERAND (rhs.value, 0),
-				      TREE_OPERAND (rhs.value, 1));
-      gimple_seq_add_stmt (seq, assign);
-      gimple_set_location (assign, loc);
-    }
-  return;
-}
-
-/* Parse gimple binary expr.
-
-   gimple-multiplicative-expression:
-     gimple-unary-expression * gimple-unary-expression
-     gimple-unary-expression / gimple-unary-expression
-     gimple-unary-expression % gimple-unary-expression
-
-   gimple-additive-expression:
-     gimple-unary-expression + gimple-unary-expression
-     gimple-unary-expression - gimple-unary-expression
-
-   gimple-shift-expression:
-     gimple-unary-expression << gimple-unary-expression
-     gimple-unary-expression >> gimple-unary-expression
-
-   gimple-relational-expression:
-     gimple-unary-expression < gimple-unary-expression
-     gimple-unary-expression > gimple-unary-expression
-     gimple-unary-expression <= gimple-unary-expression
-     gimple-unary-expression >= gimple-unary-expression
-
-   gimple-equality-expression:
-     gimple-unary-expression == gimple-unary-expression
-     gimple-unary-expression != gimple-unary-expression
-
-   gimple-AND-expression:
-     gimple-unary-expression & gimple-unary-expression
-
-   gimple-exclusive-OR-expression:
-     gimple-unary-expression ^ gimple-unary-expression
-
-   gimple-inclusive-OR-expression:
-     gimple-unary-expression | gimple-unary-expression
-
-   gimple-logical-AND-expression:
-     gimple-unary-expression && gimple-unary-expression
-
-   gimple-logical-OR-expression:
-     gimple-unary-expression || gimple-unary-expression
-
-*/
-
-static c_expr
-c_parser_gimple_binary_expression (c_parser *parser, enum tree_code *subcode)
-{
-  struct {
-    /* The expression at this stack level.  */
-    struct c_expr expr;
-    /* The operation on its left.  */
-    enum tree_code op;
-    /* The source location of this operation.  */
-    location_t loc;
-  } stack[2];
-  int sp;
-  /* Location of the binary operator.  */
-  location_t binary_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
-#define POP								      \
-  do {									      \
-    if (sp == 1								      \
-	&& c_parser_peek_token (parser)->type == CPP_SEMICOLON		      \
-	&& (((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND)      \
-	       | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT)))     \
-	&& stack[sp].op != TRUNC_MOD_EXPR				      \
-	&& stack[0].expr.value != error_mark_node			      \
-	&& stack[1].expr.value != error_mark_node)			      \
-      stack[0].expr.value						      \
-	= build2 (stack[1].op, TREE_TYPE (stack[0].expr.value),		      \
-		  stack[0].expr.value, stack[1].expr.value);		      \
-    else								      \
-      stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc,	      \
-						   stack[sp].op,	      \
-						   stack[sp - 1].expr,	      \
-						   stack[sp].expr);	      \
-    sp--;								      \
-  } while (0)
-  stack[0].loc = c_parser_peek_token (parser)->location;
-  stack[0].expr = c_parser_gimple_unary_expression (parser);
-  sp = 0;
-  source_range src_range;
-  if (parser->error)
-    goto out;
-  switch (c_parser_peek_token (parser)->type)
-    {
-    case CPP_MULT:
-      *subcode = MULT_EXPR;
-      break;
-    case CPP_DIV:
-      *subcode = TRUNC_DIV_EXPR;
-      break;
-    case CPP_MOD:
-      *subcode = TRUNC_MOD_EXPR;
-      break;
-    case CPP_PLUS:
-      *subcode = PLUS_EXPR;
-      break;
-    case CPP_MINUS:
-      *subcode = MINUS_EXPR;
-      break;
-    case CPP_LSHIFT:
-      *subcode = LSHIFT_EXPR;
-      break;
-    case CPP_RSHIFT:
-      *subcode = RSHIFT_EXPR;
-      break;
-    case CPP_LESS:
-      *subcode = LT_EXPR;
-      break;
-    case CPP_GREATER:
-      *subcode = GT_EXPR;
-      break;
-    case CPP_LESS_EQ:
-      *subcode = LE_EXPR;
-      break;
-    case CPP_GREATER_EQ:
-      *subcode = GE_EXPR;
-      break;
-    case CPP_EQ_EQ:
-      *subcode = EQ_EXPR;
-      break;
-    case CPP_NOT_EQ:
-      *subcode = NE_EXPR;
-      break;
-    case CPP_AND:
-      *subcode = BIT_AND_EXPR;
-      break;
-    case CPP_XOR:
-      *subcode = BIT_XOR_EXPR;
-      break;
-    case CPP_OR:
-      *subcode = BIT_IOR_EXPR;
-      break;
-    case CPP_AND_AND:
-      *subcode = TRUTH_ANDIF_EXPR;
-      break;
-    case CPP_OR_OR:
-      *subcode = TRUTH_ORIF_EXPR;
-      break;
-    default:
-      /* Not a binary operator, so end of the binary expression.  */
-      *subcode = NOP_EXPR;
-      goto out;
-    }
-  binary_loc = c_parser_peek_token (parser)->location;
-  c_parser_consume_token (parser);
-  switch (*subcode)
-    {
-    case TRUTH_ANDIF_EXPR:
-      src_range = stack[sp].expr.src_range;
-      stack[sp].expr.value = c_objc_common_truthvalue_conversion
-	(stack[sp].loc, default_conversion (stack[sp].expr.value));
-      set_c_expr_source_range (&stack[sp].expr, src_range);
-      break;
-    case TRUTH_ORIF_EXPR:
-      src_range = stack[sp].expr.src_range;
-      stack[sp].expr.value = c_objc_common_truthvalue_conversion
-	(stack[sp].loc, default_conversion (stack[sp].expr.value));
-      set_c_expr_source_range (&stack[sp].expr, src_range);
-      break;
-    default:
-      break;
-    }
-  sp++;
-  stack[sp].loc = binary_loc;
-  stack[sp].expr = c_parser_gimple_unary_expression (parser);
-  stack[sp].op = *subcode;
-out:
-  while (sp > 0)
-    POP;
-  return stack[0].expr;
-#undef POP
-}
-
-/* Parse gimple unary expression.
-
-   gimple-unary-expression:
-     gimple-postfix-expression
-     unary-operator cast-expression
-
-   unary-operator: one of
-     & * + - ~ !
-*/
-
-static c_expr
-c_parser_gimple_unary_expression (c_parser *parser)
-{
-  struct c_expr ret, op;
-  if (c_parser_peek_token (parser)->value
-      && TREE_CODE (c_parser_peek_token (parser)->value) == IDENTIFIER_NODE
-      && ! lookup_name (c_parser_peek_token (parser)->value))
-    return c_parser_parse_ssa_names (parser);
-
-  location_t op_loc = c_parser_peek_token (parser)->location;
-  location_t finish;
-  ret.original_code = ERROR_MARK;
-  ret.original_type = NULL;
-  switch (c_parser_peek_token (parser)->type)
-    {
-    case CPP_AND:
-      c_parser_consume_token (parser);
-      op = c_parser_cast_expression (parser, NULL);
-      mark_exp_read (op.value);
-      return parser_build_unary_op (op_loc, ADDR_EXPR, op);
-    case CPP_MULT:
-      {
-	c_parser_consume_token (parser);
-	op = c_parser_cast_expression (parser, NULL);
-	finish = op.get_finish ();
-	location_t combined_loc = make_location (op_loc, op_loc, finish);
-	ret.value = build_indirect_ref (combined_loc, op.value,
-					RO_UNARY_STAR);
-	ret.src_range.m_start = op_loc;
-	ret.src_range.m_finish = finish;
-	return ret;
-      }
-    case CPP_PLUS:
-      c_parser_consume_token (parser);
-      op = c_parser_cast_expression (parser, NULL);
-      return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
-    case CPP_MINUS:
-      c_parser_consume_token (parser);
-      op = c_parser_cast_expression (parser, NULL);
-      return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
-    case CPP_COMPL:
-      c_parser_consume_token (parser);
-      op = c_parser_cast_expression (parser, NULL);
-      return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
-    case CPP_NOT:
-      c_parser_consume_token (parser);
-      op = c_parser_cast_expression (parser, NULL);
-      return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
-    default:
-      return c_parser_gimple_postfix_expression (parser);
-    }
-}
-
-/* Parse gimple ssa names.  */
-
-static c_expr
-c_parser_parse_ssa_names (c_parser *parser)
-{
-  tree id = NULL_TREE;
-  c_expr ret;
-  char *var_name = NULL, *var_version = NULL, *token = NULL;
-  ret.original_code = ERROR_MARK;
-  ret.original_type = NULL;
-
-  /* SSA token string.  */
-  const char *ssa_token
-    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
-  token = new char [strlen (ssa_token) + 1];
-  strcpy (token, ssa_token);
-
-  /* Separate var name and version.  */
-  var_version = strrchr (token, '_');
-  if (var_version)
-    {
-      var_name = new char[var_version - token + 1];
-      memcpy (var_name, token, var_version - token);
-      var_name[var_version - token] = '\0';
-      id = get_identifier (var_name);
-
-      /* lookup for parent decl.  */
-      if (lookup_name (id))
-	{
-	  var_version++;
-	  unsigned int version;
-	  version = atoi (var_version);
-	  if (var_version && version)
-	    {
-	      ret.value = NULL_TREE;
-	      if (version < num_ssa_names)
-		ret.value = ssa_name (version);
-	      if (! ret.value)
-		ret.value = make_ssa_name_fn (cfun, lookup_name (id),
-					      gimple_build_nop (), version);
-	      c_parser_consume_token (parser);
-	    }
-	}
-    }
-
-  /* For default definition SSA names.  */
-  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
-    {
-      c_parser_consume_token (parser);
-      ssa_token = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
-      if (! strcmp ("D", ssa_token))
-	{
-	  set_ssa_default_def (cfun, lookup_name (id), ret.value);
-	  c_parser_consume_token (parser);
-	}
-      if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
-	goto out;
-    }
-
-  out:
-  free (var_name);
-  free (token);
-  return ret;
-}
-
-/* Parse gimple postfix expression.
-
-   gimple-postfix-expression:
-     gimple-primary-expression
-     gimple-primary-xpression [ gimple-primary-expression ]
-     gimple-primary-expression ( gimple-argument-expression-list[opt] )
-
-   gimple-argument-expression-list:
-     gimple-unary-expression
-     gimple-argument-expression-list , gimple-unary-expression
-
-   gimple-primary-expression:
-     identifier
-     constant
-     string-literal
-
-*/
-
-static struct c_expr
-c_parser_gimple_postfix_expression (c_parser *parser)
-{
-  struct c_expr expr;
-  location_t loc = c_parser_peek_token (parser)->location;
-  source_range tok_range = c_parser_peek_token (parser)->get_range ();
-  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;
-      set_c_expr_source_range (&expr, tok_range);
-      loc = c_parser_peek_token (parser)->location;
-      c_parser_consume_token (parser);
-      break;
-    case CPP_CHAR:
-    case CPP_CHAR16:
-    case CPP_CHAR32:
-    case CPP_WCHAR:
-      expr.value = c_parser_peek_token (parser)->value;
-      set_c_expr_source_range (&expr, tok_range);
-      c_parser_consume_token (parser);
-      break;
-    case CPP_STRING:
-    case CPP_STRING16:
-    case CPP_STRING32:
-    case CPP_WSTRING:
-    case CPP_UTF8STRING:
-      expr.value = c_parser_peek_token (parser)->value;
-      set_c_expr_source_range (&expr, tok_range);
-      expr.original_code = STRING_CST;
-      c_parser_consume_token (parser);
-      break;
-    case CPP_NAME:
-      if (c_parser_peek_token (parser)->id_kind == C_ID_ID)
-	{
-	  tree id = c_parser_peek_token (parser)->value;
-	  c_parser_consume_token (parser);
-	  expr.value = build_external_ref (loc, id,
-					   (c_parser_peek_token (parser)->type
-					    == CPP_OPEN_PAREN),
-					   &expr.original_type);
-	  set_c_expr_source_range (&expr, tok_range);
-	  break;
-	}
-      else
-	{
-	  c_parser_error (parser, "expected expression");
-	  expr.set_error ();
-	  break;
-	}
-      break;
-    default:
-      c_parser_error (parser, "expected expression");
-      expr.set_error ();
-      break;
-    }
-  return c_parser_gimple_postfix_expression_after_primary
-    (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
-}
-
-/* Parse a gimple postfix expression after the initial primary or compound
-   literal.  */
-
-static struct c_expr
-c_parser_gimple_postfix_expression_after_primary (c_parser *parser,
-						  location_t expr_loc,
-						  struct c_expr expr)
-{
-  struct c_expr orig_expr;
-  vec<tree, va_gc> *exprlist;
-  vec<tree, va_gc> *origtypes = NULL;
-  vec<location_t> arg_loc = vNULL;
-  location_t start;
-  location_t finish;
-
-  location_t op_loc = c_parser_peek_token (parser)->location;
-
-  switch (c_parser_peek_token (parser)->type)
-    {
-    case CPP_OPEN_SQUARE:
-      {
-	c_parser_consume_token (parser);
-	tree idx = c_parser_gimple_unary_expression (parser).value;
-
-	if (! c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>"))
-	  break;
-
-	start = expr.get_start ();
-	finish = parser->tokens_buf[0].location;
-	expr.value = build_array_ref (op_loc, expr.value, idx);
-	set_c_expr_source_range (&expr, start, finish);
-
-	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;
-	else
-	  exprlist = c_parser_gimple_expr_list (parser, &origtypes,
-						&arg_loc);
-	c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
-				   "expected %<)%>");
-	orig_expr = expr;
-	start = expr.get_start ();
-	finish = parser->tokens_buf[0].get_finish ();
-	expr.value = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
-						exprlist, origtypes);
-	set_c_expr_source_range (&expr, start, finish);
-
-	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)
-	  {
-	    release_tree_vector (exprlist);
-	    release_tree_vector (origtypes);
-	  }
-	arg_loc.release ();
-	break;
-      default:
-	return expr;
-      }
-    }
-  return expr;
-}
-
-/* Parse expression list.
-
-   gimple-expr-list:
-     gimple-unary-expression
-     gimple-expr-list , gimple-unary-expression
-
- */
-
-static vec<tree, va_gc> *
-c_parser_gimple_expr_list (c_parser *parser, vec<tree, va_gc> **p_orig_types,
-			   vec<location_t> *locations)
-{
-  vec<tree, va_gc> *ret;
-  vec<tree, va_gc> *orig_types;
-  struct c_expr expr;
-  location_t loc = c_parser_peek_token (parser)->location;
-
-  ret = make_tree_vector ();
-  if (p_orig_types == NULL)
-    orig_types = NULL;
-  else
-    orig_types = make_tree_vector ();
-
-  expr = c_parser_gimple_unary_expression (parser);
-  vec_safe_push (ret, expr.value);
-  if (orig_types)
-    vec_safe_push (orig_types, expr.original_type);
-  if (locations)
-    locations->safe_push (loc);
-  while (c_parser_next_token_is (parser, CPP_COMMA))
-    {
-      c_parser_consume_token (parser);
-      loc = c_parser_peek_token (parser)->location;
-      expr = c_parser_gimple_unary_expression (parser);
-      vec_safe_push (ret, expr.value);
-      if (orig_types)
-	vec_safe_push (orig_types, expr.original_type);
-      if (locations)
-	locations->safe_push (loc);
-    }
-  if (orig_types)
-    *p_orig_types = orig_types;
-  return ret;
-}
-
-/* Parse gimple label.
-
-   gimple-label:
-     identifier :
-     case constant-expression :
-     default :
-
-*/
-
-static void
-c_parser_gimple_label (c_parser *parser, gimple_seq *seq)
-{
-  tree name = c_parser_peek_token (parser)->value;
-  location_t loc1 = 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));
-  c_parser_consume_token (parser);
-  tree label = define_label (loc1, name);
-  gimple_seq_add_stmt (seq, gimple_build_label (label));
-  return;
-}
-
-/* Parse gimple pass list.
-
-   gimple-pass-list:
-     startwith("pass-name")
- */
-
-static void
-c_parser_gimple_pass_list (c_parser *parser, opt_pass **pass,
-			   bool *startwith_p)
-{
-  if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
-    return;
-
-  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
-    return;
-
-  if (c_parser_next_token_is (parser, CPP_NAME))
-    {
-      const char *op = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
-      c_parser_consume_token (parser);
-      if (! strcmp (op, "startwith"))
-	{
-	  *pass = c_parser_gimple_pass_list_params (parser, pass);
-	  if (! *pass)
-	    return;
-
-	  *startwith_p = true;
-	  if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
-	    return;
-	}
-      else
-	{
-	  error_at (c_parser_peek_token (parser)->location,
-		    "invalid operation");
-	  return;
-	}
-    }
-  else if (c_parser_next_token_is (parser, CPP_EOF))
-    {
-      c_parser_error (parser, "expected parameters");
-      return;
-    }
-
-  return;
-}
-
-/* Support function for c_parser_gimple_pass_list.  */
-
-static opt_pass *
-c_parser_gimple_pass_list_params (c_parser *parser, opt_pass **pass)
-{
-  opt_pass *pass_start = NULL, *new_pass;
-  if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
-    return NULL;
-
-  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
-    return NULL;
-
-  while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
-    {
-      if (c_parser_next_token_is (parser, CPP_EOF))
-	{
-	  error_at (c_parser_peek_token (parser)->location,
-		    "expected pass names");
-	  return NULL;
-	}
-
-      if (c_parser_next_token_is (parser, CPP_STRING))
-	{
-	  const char *name = NULL;
-	  name = TREE_STRING_POINTER (c_parser_peek_token (parser)->value);
-	  c_parser_consume_token (parser);
-	  new_pass = g->get_passes ()->get_pass_by_name (name);
-
-	  if (! new_pass)
-	    {
-	      error_at (c_parser_peek_token (parser)->location,
-			"invalid pass name");
-	      parser->error = true;
-	      c_parser_consume_token (parser);
-	      return NULL;
-	    }
-	  if (*pass)
-	    {
-	      (*pass)->next = new_pass;
-	      (*pass) = (*pass)->next;
-	    }
-	  else
-	    {
-	      *pass = new_pass;
-	      pass_start = *pass;
-	    }
-	}
-      else if (c_parser_next_token_is (parser, CPP_COMMA))
-	c_parser_consume_token (parser);
-      else
-	{
-	  error_at (c_parser_peek_token (parser)->location,
-		    "invalid pass name");
-	  c_parser_consume_token (parser);
-	  return NULL;
-	}
-    }
-  return pass_start;
-}
-
-/* Parse gimple local declaration.
-
-   declaration-specifiers:
-     storage-class-specifier declaration-specifiers[opt]
-     type-specifier declaration-specifiers[opt]
-     type-qualifier declaration-specifiers[opt]
-     function-specifier declaration-specifiers[opt]
-     alignment-specifier declaration-specifiers[opt]
-
-   storage-class-specifier:
-     typedef
-     extern
-     static
-     auto
-     register
-
-   type-specifier:
-     void
-     char
-     short
-     int
-     long
-     float
-     double
-     signed
-     unsigned
-     _Bool
-     _Complex
-
-   type-qualifier:
-     const
-     restrict
-     volatile
-     address-space-qualifier
-     _Atomic
-
- */
-
-static void
-c_parser_gimple_declaration (c_parser *parser)
-{
-  struct c_declarator *declarator;
-  struct c_declspecs *specs = build_null_declspecs ();
-  c_parser_declspecs (parser, specs, true, true, true,
-		      true, true, cla_nonabstract_decl);
-  finish_declspecs (specs);
-
-  /* Provide better error recovery.  Note that a type name here is usually
-     better diagnosed as a redeclaration.  */
-  if (c_parser_next_token_starts_declspecs (parser)
-      && ! c_parser_next_token_is (parser, CPP_NAME))
-    {
-      c_parser_error (parser, "expected %<;%>");
-      parser->error = false;
-      return;
-    }
-
-  bool dummy = false;
-  declarator = c_parser_declarator (parser,
-				    specs->typespec_kind != ctsk_none,
-				    C_DTR_NORMAL, &dummy);
-
-  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
-    {
-      tree postfix_attrs = NULL_TREE;
-      tree all_prefix_attrs = specs->attrs;
-      specs->attrs = NULL;
-      tree decl = start_decl (declarator, specs, false,
-			 chainon (postfix_attrs, all_prefix_attrs));
-      if (decl)
-	finish_decl (decl, UNKNOWN_LOCATION, NULL_TREE, NULL_TREE, NULL_TREE);
-    }
-  else
-    {
-      c_parser_error (parser, "expected %<;%>");
-      return;
-    }
-}
-
-/* Parse gimple goto statement.  */
-
-static void
-c_parser_gimple_goto_stmt (location_t loc, tree label, gimple_seq *seq)
-{
-  tree decl = lookup_label_for_goto (loc, label);
-  gimple_seq_add_stmt (seq, gimple_build_goto (decl));
-  return;
-}
-
-/* Parse a parenthesized condition.
-   gimple-condition:
-     ( gimple-binary-expression )    */
-
-static tree
-c_parser_gimple_paren_condition (c_parser *parser)
-{
-  enum tree_code subcode = NOP_EXPR;
-  location_t loc = c_parser_peek_token (parser)->location;
-  if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
-    return error_mark_node;
-  tree cond = c_parser_gimple_binary_expression (parser, &subcode).value;
-  cond = c_objc_common_truthvalue_conversion (loc, cond);
-  if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
-    return error_mark_node;
-  return cond;
-}
-
-/* Parse gimple if-else statement.
-
-   if-statement:
-     if ( gimple-binary-expression ) gimple-goto-statement
-     if ( gimple-binary-expression ) gimple-goto-statement \
-					else gimple-goto-statement
- */
-
-static void
-c_parser_gimple_if_stmt (c_parser *parser, gimple_seq *seq)
-{
-  tree t_label, f_label, label;
-  location_t loc;
-  c_parser_consume_token (parser);
-  tree cond = c_parser_gimple_paren_condition (parser);
-
-  if (c_parser_next_token_is_keyword (parser, RID_GOTO))
-    {
-      loc = c_parser_peek_token (parser)->location;
-      c_parser_consume_token (parser);
-      label = c_parser_peek_token (parser)->value;
-      t_label = lookup_label_for_goto (loc, label);
-      c_parser_consume_token (parser);
-      if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
-	return;
-    }
-  else
-    {
-      c_parser_error (parser, "expected goto expression");
-      return;
-    }
-
-  if (c_parser_next_token_is_keyword (parser, RID_ELSE))
-    c_parser_consume_token (parser);
-  else
-    {
-      c_parser_error (parser, "expected else statement");
-      return;
-    }
-
-  if (c_parser_next_token_is_keyword (parser, RID_GOTO))
-    {
-      loc = c_parser_peek_token (parser)->location;
-      c_parser_consume_token (parser);
-      label = c_parser_peek_token (parser)->value;
-      f_label = lookup_label_for_goto (loc, label);
-      c_parser_consume_token (parser);
-      if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
-	return;
-    }
-  else
-    {
-      c_parser_error (parser, "expected goto expression");
-      return;
-    }
-
-  gimple_seq_add_stmt (seq, gimple_build_cond_from_tree (cond, t_label,
-							 f_label));
-}
-
-/* Parse gimple switch-statement.
-
-   gimple-switch-statement:
-     switch (gimple-unary-expression) gimple-case-statement
-
-   gimple-case-statement:
-     gimple-case-statement
-     gimple-label-statement : gimple-goto-statment
-*/
-
-static void
-c_parser_gimple_switch_stmt (c_parser *parser, gimple_seq *seq)
-{
-  c_expr cond_expr;
-  tree case_label, label;
-  auto_vec<tree> labels;
-  tree default_label = NULL_TREE;
-  gimple_seq switch_body = NULL;
-  location_t loc;
-  c_parser_consume_token (parser);
-
-  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
-    {
-      cond_expr = c_parser_gimple_unary_expression (parser);
-      if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
-	return;
-    }
-
-  if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
-    {
-      while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
-	{
-	  if (c_parser_next_token_is (parser, CPP_EOF))
-	    {
-	      c_parser_error (parser, "expected statement");
-	      return;
-	    }
-
-	  switch (c_parser_peek_token (parser)->keyword)
-	    {
-	    case RID_CASE:
-	      {
-		c_expr exp1;
-		loc = c_parser_peek_token (parser)->location;
-		c_parser_consume_token (parser);
-
-		if (c_parser_next_token_is (parser, CPP_NAME)
-		    || c_parser_peek_token (parser)->type == CPP_NUMBER)
-		  exp1 = c_parser_gimple_unary_expression (parser);
-		else
-		  c_parser_error (parser, "expected expression");
-
-		if (c_parser_next_token_is (parser, CPP_COLON))
-		  {
-		    c_parser_consume_token (parser);
-		    label = create_artificial_label (loc);
-		    case_label = build_case_label (exp1.value, NULL_TREE,
-						   label);
-		    labels.safe_push (case_label);
-		    gimple_seq_add_stmt (&switch_body,
-					 gimple_build_label
-					 (CASE_LABEL (case_label)));
-		  }
-		else if (! c_parser_require (parser, CPP_SEMICOLON,
-					    "expected %<:%>"))
-		  return;
-		break;
-	      }
-	    case RID_DEFAULT:
-	      {
-		c_parser_consume_token (parser);
-		if (c_parser_next_token_is (parser, CPP_COLON))
-		  {
-		    c_parser_consume_token (parser);
-		    default_label = build_case_label (NULL_TREE, NULL_TREE,
-						      create_artificial_label
-						      (UNKNOWN_LOCATION));
-		    gimple_seq_add_stmt (&switch_body,
-					 gimple_build_label
-					 (CASE_LABEL (default_label)));
-		  }
-		else if (! c_parser_require (parser, CPP_SEMICOLON,
-					    "expected %<:%>"))
-		  return;
-		break;
-	      }
-	    case RID_GOTO:
-	      {
-		loc = c_parser_peek_token (parser)->location;
-		c_parser_consume_token (parser);
-		if (c_parser_next_token_is (parser, CPP_NAME))
-		  {
-		    c_parser_gimple_goto_stmt (loc,
-					       c_parser_peek_token
-					         (parser)->value,
-					       &switch_body);
-		    c_parser_consume_token (parser);
-		    if (c_parser_next_token_is (parser, CPP_SEMICOLON))
-		      c_parser_consume_token (parser);
-		    else
-		      {
-			c_parser_error (parser, "expected semicolon");
-			return;
-		      }
-		  }
-		else if (! c_parser_require (parser, CPP_NAME,
-					    "expected label"))
-		  return;
-		break;
-	      }
-	    default:
-	      c_parser_error (parser, "expected case label or goto statement");
-	      return;
-	    }
-
-	}
-    }
-  if (! c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
-    return;
-  gimple_seq_add_stmt (seq, gimple_build_switch (cond_expr.value,
-						 default_label, labels));
-  gimple_seq_add_seq (seq, switch_body);
-  labels.release();
-}
-
-/* Parse gimple return statement.  */
-
-static void
-c_parser_gimple_return_stmt (c_parser *parser, gimple_seq *seq)
-{
-  location_t loc = c_parser_peek_token (parser)->location;
-  gimple *ret = NULL;
-  c_parser_consume_token (parser);
-  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
-    {
-      c_finish_gimple_return (loc, NULL_TREE);
-      ret = gimple_build_return (NULL);
-      gimple_seq_add_stmt (seq, ret);
-    }
-  else
-    {
-      location_t xloc = c_parser_peek_token (parser)->location;
-      c_expr expr = c_parser_gimple_unary_expression (parser);
-      c_finish_gimple_return (xloc, expr.value);
-      ret = gimple_build_return (expr.value);
-      gimple_seq_add_stmt (seq, ret);
-    }
-}
-
-/* Support function for c_parser_gimple_return_stmt.  */
-
-static void
-c_finish_gimple_return (location_t loc, tree retval)
-{
-  tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
-
-  /* Use the expansion point to handle cases such as returning NULL
-     in a function returning void.  */
-  source_location xloc = expansion_point_location_if_in_system_header (loc);
-
-  if (TREE_THIS_VOLATILE (current_function_decl))
-    warning_at (xloc, 0,
-		"function declared %<noreturn%> has a %<return%> statement");
-
-  if (! retval)
-    current_function_returns_null = 1;
-  else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
-    {
-      current_function_returns_null = 1;
-      if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
-	{
-	  error_at
-	    (xloc, "%<return%> with a value, in function returning void");
-	  inform (DECL_SOURCE_LOCATION (current_function_decl),
-		  "declared here");
-	}
-    }
-  else if (TREE_CODE (valtype) != TREE_CODE (TREE_TYPE (retval)))
-    {
-      error_at
-	(xloc, "invalid conversion in return statement");
-      inform (DECL_SOURCE_LOCATION (current_function_decl),
-	      "declared here");
-    }
-  return;
-}
-
 #include "gt-c-c-parser.h"
diff --git a/gcc/c/c-parser.h b/gcc/c/c-parser.h
new file mode 100644
index 0000000..d178254
--- /dev/null
+++ b/gcc/c/c-parser.h
@@ -0,0 +1,230 @@
+/* Declarations for the parser for C and Objective-C.
+   Copyright (C) 1987-2016 Free Software Foundation, Inc.
+
+   Parser actions based on the old Bison parser; structure somewhat
+   influenced by and fragments based on the C++ parser.
+
+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 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+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 COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_C_PARSER_H
+#define GCC_C_PARSER_H
+
+/* The C lexer intermediates between the lexer in cpplib and c-lex.c
+   and the C parser.  Unlike the C++ lexer, the parser structure
+   stores the lexer information instead of using a separate structure.
+   Identifiers are separated into ordinary identifiers, type names,
+   keywords and some other Objective-C types of identifiers, and some
+   look-ahead is maintained.
+
+   ??? It might be a good idea to lex the whole file up front (as for
+   C++).  It would then be possible to share more of the C and C++
+   lexer code, if desired.  */
+
+/* More information about the type of a CPP_NAME token.  */
+enum c_id_kind {
+  /* An ordinary identifier.  */
+  C_ID_ID,
+  /* An identifier declared as a typedef name.  */
+  C_ID_TYPENAME,
+  /* An identifier declared as an Objective-C class name.  */
+  C_ID_CLASSNAME,
+  /* An address space identifier.  */
+  C_ID_ADDRSPACE,
+  /* Not an identifier.  */
+  C_ID_NONE
+};
+
+/* A single C token after string literal concatenation and conversion
+   of preprocessing tokens to tokens.  */
+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
+     declared as some kind of type.  Otherwise, it is C_ID_NONE.  */
+  ENUM_BITFIELD (c_id_kind) id_kind : 8;
+  /* If this token is a keyword, this value indicates which keyword.
+     Otherwise, this value is RID_MAX.  */
+  ENUM_BITFIELD (rid) keyword : 8;
+  /* If this token is a CPP_PRAGMA, this indicates the pragma that
+     was seen.  Otherwise it is PRAGMA_NONE.  */
+  ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
+  /* The location at which this token was found.  */
+  location_t location;
+  /* The value associated with this token, if any.  */
+  tree value;
+  /* Token flags.  */
+  unsigned char flags;
+
+  source_range get_range () const
+  {
+    return get_range_from_loc (line_table, location);
+  }
+
+  location_t get_finish () const
+  {
+    return get_range ().m_finish;
+  }
+} c_token_;
+
+/* 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.  */
+struct GTY(()) c_parser {
+  /* The look-ahead tokens.  */
+  struct c_token * GTY((skip)) tokens;
+  /* Buffer for look-ahead tokens.  */
+  struct c_token GTY(()) tokens_buf[4];
+  /* How many look-ahead tokens are available (0 - 4, or
+     more if parsing from pre-lexed tokens).  */
+  unsigned int tokens_avail;
+  /* True if a syntax error is being recovered from; false otherwise.
+     c_parser_error sets this flag.  It should clear this flag when
+     enough tokens have been consumed to recover from the error.  */
+  BOOL_BITFIELD error : 1;
+  /* 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.  */
+
+  /* True if we are in a context where the Objective-C "PQ" keywords
+     are considered keywords.  */
+  BOOL_BITFIELD objc_pq_context : 1;
+  /* True if we are parsing a (potential) Objective-C foreach
+     statement.  This is set to true after we parsed 'for (' and while
+     we wait for 'in' or ';' to decide if it's a standard C for loop or an
+     Objective-C foreach loop.  */
+  BOOL_BITFIELD objc_could_be_foreach_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;
+  /* Nonzero if we're processing a __transaction statement.  The value
+     is 1 | TM_STMT_ATTR_*.  */
+  unsigned int in_transaction : 4;
+  /* True if we are in a context where the Objective-C "Property attribute"
+     keywords are valid.  */
+  BOOL_BITFIELD objc_property_attr_context : 1;
+
+  /* Cilk Plus specific parser/lexer information.  */
+
+  /* Buffer to hold all the tokens from parsing the vector attribute for the
+     SIMD-enabled functions (formerly known as elemental functions).  */
+  vec <c_token_, va_gc> *cilk_simd_fn_tokens;
+};
+
+/* Possibly kinds of declarator to parse.  */
+enum c_dtr_syn {
+  /* A normal declarator with an identifier.  */
+  C_DTR_NORMAL,
+  /* An abstract declarator (maybe empty).  */
+  C_DTR_ABSTRACT,
+  /* A parameter declarator: may be either, but after a type name does
+     not redeclare a typedef name as an identifier if it can
+     alternatively be interpreted as a typedef name; see DR#009,
+     applied in C90 TC1, omitted from C99 and reapplied in C99 TC2
+     following DR#249.  For example, given a typedef T, "int T" and
+     "int *T" are valid parameter declarations redeclaring T, while
+     "int (T)" and "int * (T)" and "int (T[])" and "int (T (int))" are
+     abstract declarators rather than involving redundant parentheses;
+     the same applies with attributes inside the parentheses before
+     "T".  */
+  C_DTR_PARM
+};
+
+/* The binary operation precedence levels, where 0 is a dummy lowest level
+   used for the bottom of the stack.  */
+enum c_parser_prec {
+  PREC_NONE,
+  PREC_LOGOR,
+  PREC_LOGAND,
+  PREC_BITOR,
+  PREC_BITXOR,
+  PREC_BITAND,
+  PREC_EQ,
+  PREC_REL,
+  PREC_SHIFT,
+  PREC_ADD,
+  PREC_MULT,
+  NUM_PRECS
+};
+
+enum c_lookahead_kind {
+  /* Always treat unknown identifiers as typenames.  */
+  cla_prefer_type,
+
+  /* Could be parsing a nonabstract declarator.  Only treat an identifier
+     as a typename if followed by another identifier or a star.  */
+  cla_nonabstract_decl,
+
+  /* Never treat identifiers as typenames.  */
+  cla_prefer_id
+};
+
+
+extern c_token * c_parser_peek_token (c_parser *parser);
+extern bool c_parser_require (c_parser *parser, enum cpp_ttype type,
+			      const char *msgid);
+extern void c_parser_error (c_parser *parser, const char *gmsgid);
+extern void c_parser_consume_token (c_parser *parser);
+extern void c_parser_skip_until_found (c_parser *parser, enum cpp_ttype type,
+				       const char *msgid);
+extern bool c_parser_next_token_starts_declspecs (c_parser *parser);
+extern c_token * c_parser_peek_2nd_token (c_parser *parser);
+bool c_parser_next_tokens_start_declaration (c_parser *parser);
+bool c_token_starts_typename (c_token *token);
+
+/* Return true if the next token from PARSER has the indicated
+   TYPE.  */
+
+static inline bool
+c_parser_next_token_is (c_parser *parser, enum cpp_ttype type)
+{
+  return c_parser_peek_token (parser)->type == type;
+}
+
+/* Return true if the next token from PARSER does not have the
+   indicated TYPE.  */
+
+static inline bool
+c_parser_next_token_is_not (c_parser *parser, enum cpp_ttype type)
+{
+  return !c_parser_next_token_is (parser, type);
+}
+
+/* Return true if the next token from PARSER is the indicated
+   KEYWORD.  */
+
+static inline bool
+c_parser_next_token_is_keyword (c_parser *parser, enum rid keyword)
+{
+  return c_parser_peek_token (parser)->keyword == keyword;
+}
+
+extern struct c_declarator *
+c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
+		     bool *seen_id);
+extern void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool,
+				bool, bool, bool, enum c_lookahead_kind);
+extern struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
+
+#endif
diff --git a/gcc/c/config-lang.in b/gcc/c/config-lang.in
index b9cdc8e..51fbb53 100644
--- a/gcc/c/config-lang.in
+++ b/gcc/c/config-lang.in
@@ -29,4 +29,4 @@ compilers="cc1\$(exeext)"
 
 target_libs=
 
-gtfiles="\$(srcdir)/c/c-lang.c \$(srcdir)/c/c-tree.h \$(srcdir)/c/c-decl.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/c-family/c-cppbuiltin.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/c/c-objc-common.c \$(srcdir)/c/c-parser.c \$(srcdir)/c/c-lang.h"
+gtfiles="\$(srcdir)/c/c-lang.c \$(srcdir)/c/c-tree.h \$(srcdir)/c/c-decl.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/c-family/c-cppbuiltin.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/c/c-objc-common.c \$(srcdir)/c/c-parser.h \$(srcdir)/c/c-parser.c \$(srcdir)/c/c-lang.h"
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
new file mode 100644
index 0000000..30e8d88
--- /dev/null
+++ b/gcc/c/gimple-parser.c
@@ -0,0 +1,1385 @@
+/* Parser for GIMPLE.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+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 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+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 COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "function.h"
+#include "c-tree.h"
+#include "timevar.h"
+#include "stringpool.h"
+#include "cgraph.h"
+#include "attribs.h"
+#include "stor-layout.h"
+#include "varasm.h"
+#include "trans-mem.h"
+#include "c-family/c-pragma.h"
+#include "c-lang.h"
+#include "c-family/c-objc.h"
+#include "plugin.h"
+#include "omp-low.h"
+#include "builtins.h"
+#include "gomp-constants.h"
+#include "c-family/c-indentation.h"
+#include "gimple-expr.h"
+#include "context.h"
+#include "gcc-rich-location.h"
+#include "c-parser.h"
+#include "tree-vrp.h"
+#include "tree-pass.h"
+#include "tree-pretty-print.h"
+#include "tree.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "gimple-pretty-print.h"
+#include "tree-ssa.h"
+#include "pass_manager.h"
+#include "tree-ssanames.h"
+#include "gimple-ssa.h"
+#include "tree-dfa.h"
+
+
+/* Gimple parsing functions.  */
+static bool c_parser_gimple_compound_statement (c_parser *, gimple_seq *);
+static void c_parser_gimple_label (c_parser *, gimple_seq *);
+static void c_parser_gimple_expression (c_parser *, gimple_seq *);
+static struct c_expr c_parser_gimple_binary_expression (c_parser *, enum tree_code *);
+static struct c_expr c_parser_gimple_unary_expression (c_parser *);
+static struct c_expr c_parser_gimple_postfix_expression (c_parser *);
+static struct c_expr c_parser_gimple_postfix_expression_after_primary (c_parser *,
+								       location_t,
+								       struct c_expr);
+static opt_pass *c_parser_gimple_pass_list_params (c_parser *, opt_pass **);
+static void c_parser_gimple_declaration (c_parser *);
+static void c_parser_gimple_goto_stmt (location_t, tree, gimple_seq *);
+static void c_parser_gimple_if_stmt (c_parser *, gimple_seq *);
+static void c_parser_gimple_switch_stmt (c_parser *, gimple_seq *);
+static void c_parser_gimple_return_stmt (c_parser *, gimple_seq *);
+static void c_finish_gimple_return (location_t, tree);
+static c_expr c_parser_parse_ssa_names (c_parser *);
+static tree c_parser_gimple_paren_condition (c_parser *);
+static vec<tree, va_gc> *c_parser_gimple_expr_list (c_parser *,
+		    vec<tree, va_gc> **, vec<location_t> *);
+
+
+/* Parse the body of a function declaration marked with "__GIMPLE".  */
+
+void
+c_parser_parse_gimple_body (c_parser *parser)
+{
+  gimple_seq seq = NULL;
+  gimple_seq body = NULL;
+  tree stmt = push_stmt_list ();
+  push_scope ();
+  location_t loc1 = c_parser_peek_token (parser)->location;
+
+  init_tree_ssa (cfun);
+
+  if (! c_parser_gimple_compound_statement (parser, &seq))
+    {
+      gimple *ret = gimple_build_return (NULL);
+      gimple_seq_add_stmt (&seq, ret);
+    }
+
+  tree block = pop_scope ();
+  stmt = pop_stmt_list (stmt);
+  stmt = c_build_bind_expr (loc1, block, stmt);
+
+  block = DECL_INITIAL (current_function_decl);
+  BLOCK_SUBBLOCKS (block) = NULL_TREE;
+  BLOCK_CHAIN (block) = NULL_TREE;
+  TREE_ASM_WRITTEN (block) = 1;
+
+  gbind *bind_stmt = gimple_build_bind (BIND_EXPR_VARS (stmt), NULL,
+					BIND_EXPR_BLOCK (stmt));
+  gimple_bind_set_body (bind_stmt, seq);
+  gimple_seq_add_stmt (&body, bind_stmt);
+  gimple_set_body (current_function_decl, body);
+  cfun->curr_properties = PROP_gimple_any;
+
+  return;
+}
+
+/* Parse a compound statement in gimple function body.
+
+   gimple-statement:
+     gimple-statement
+     gimple-declaration-statement
+     gimple-if-statement
+     gimple-switch-statement
+     gimple-labeled-statement
+     gimple-expression-statement
+     gimple-goto-statement
+     gimple-phi-statement
+     gimple-return-statement
+*/
+
+static bool
+c_parser_gimple_compound_statement (c_parser *parser, gimple_seq *seq)
+{
+  bool return_p = false;
+
+  if (! c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
+    return false;
+
+  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
+    {
+      c_parser_consume_token (parser);
+      return false;
+    }
+
+  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
+    {
+      c_parser_error (parser, "expected declaration or statement");
+      c_parser_consume_token (parser);
+      return false;
+    }
+
+  while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
+    {
+      if (parser->error)
+	{
+	  c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
+	  return return_p;
+	}
+
+      if (c_parser_next_token_is (parser, CPP_NAME)
+	  && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
+	c_parser_gimple_label (parser, seq);
+
+      else if (c_parser_next_tokens_start_declaration (parser))
+	c_parser_gimple_declaration (parser);
+
+      else if (c_parser_next_token_is (parser, CPP_EOF))
+	{
+	  c_parser_error (parser, "expected declaration or statement");
+	  return return_p;
+	}
+
+      else
+	{
+	  switch (c_parser_peek_token (parser)->type)
+	    {
+	    case CPP_KEYWORD:
+	      switch (c_parser_peek_token (parser)->keyword)
+		{
+		case RID_IF:
+		  c_parser_gimple_if_stmt (parser, seq);
+		  break;
+		case RID_SWITCH:
+		  c_parser_gimple_switch_stmt (parser, seq);
+		  break;
+		case RID_GOTO:
+		    {
+		      location_t loc = c_parser_peek_token (parser)->location;
+		      c_parser_consume_token (parser);
+		      if (c_parser_next_token_is (parser, CPP_NAME))
+			{
+			  c_parser_gimple_goto_stmt (loc,
+						     c_parser_peek_token
+						       (parser)->value,
+						     seq);
+			  c_parser_consume_token (parser);
+			  if (! c_parser_require (parser, CPP_SEMICOLON,
+						  "expected %<;%>"))
+			    return return_p;
+			}
+		    }
+		  break;
+		case RID_RETURN:
+		  return_p = true;
+		  c_parser_gimple_return_stmt (parser, seq);
+		  if (! c_parser_require (parser, CPP_SEMICOLON,
+					  "expected %<;%>"))
+		    return return_p;
+		  break;
+		default:
+		  goto expr_stmt;
+		}
+	      break;
+	    case CPP_SEMICOLON:
+	      c_parser_consume_token (parser);
+	      break;
+	    default:
+	    expr_stmt:
+	      c_parser_gimple_expression (parser, seq);
+	      if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
+		return return_p;
+	    }
+	}
+    }
+  c_parser_consume_token (parser);
+  return return_p; 
+}
+
+/* Parse a gimple expression.
+
+   gimple-expression:
+     gimple-unary-expression
+     gimple-call-statement
+     gimple-binary-expression
+     gimple-assign-expression
+     gimple-cast-expression
+
+*/
+
+static void
+c_parser_gimple_expression (c_parser *parser, gimple_seq *seq)
+{
+  struct c_expr lhs, rhs;
+  gimple *assign = NULL;
+  enum tree_code subcode = NOP_EXPR;
+  location_t loc;
+  tree arg = NULL_TREE;
+  auto_vec<tree> vargs;
+
+  lhs = c_parser_gimple_unary_expression (parser);
+  rhs.value = error_mark_node;
+
+  if (c_parser_next_token_is (parser, CPP_EQ))
+    c_parser_consume_token (parser);
+
+  loc = EXPR_LOCATION (lhs.value);
+
+  /* GIMPLE call expression.  */
+  if (c_parser_next_token_is (parser, CPP_SEMICOLON)
+      && TREE_CODE (lhs.value) == CALL_EXPR)
+    {
+      gimple *call;
+      call = gimple_build_call_from_tree (lhs.value);
+      gimple_seq_add_stmt (seq, call);
+      gimple_set_location (call, loc);
+      return;
+    }
+
+  /* Cast expression.  */
+  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
+      && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
+    {
+      /* TODO: have a gimple_cast_expr function.  */
+      rhs = c_parser_cast_expression (parser, NULL);
+      if (lhs.value != error_mark_node &&
+	  rhs.value != error_mark_node)
+	{
+	  assign = gimple_build_assign (lhs.value, rhs.value);
+	  gimple_seq_add_stmt (seq, assign);
+	  gimple_set_location (assign, loc);
+	  return;
+	}
+    }
+
+  if (POINTER_TYPE_P (TREE_TYPE (lhs.value)))
+    {
+      STRIP_USELESS_TYPE_CONVERSION (rhs.value);
+      if (! useless_type_conversion_p (TREE_TYPE (lhs.value),
+				       TREE_TYPE (rhs.value)))
+	rhs.value = fold_convert_loc (loc, TREE_TYPE (lhs.value), rhs.value);
+    }
+
+  /* Pointer expression.  */
+  if (TREE_CODE (lhs.value) == INDIRECT_REF)
+    {
+      tree save_expr = lhs.value;
+      bool volatilep = TREE_THIS_VOLATILE (lhs.value);
+      bool notrap = TREE_THIS_NOTRAP (lhs.value);
+      tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (lhs.value, 0));
+
+      lhs.value = fold_indirect_ref_loc (loc, lhs.value);
+      if (lhs.value == save_expr)
+	{
+	  lhs.value = fold_build2_loc (input_location, MEM_REF,
+				       TREE_TYPE (lhs.value),
+				       TREE_OPERAND (lhs.value, 0),
+				       build_int_cst (saved_ptr_type, 0));
+	  TREE_THIS_VOLATILE (lhs.value) = volatilep;
+	  TREE_THIS_NOTRAP (lhs.value) = notrap;
+	}
+    }
+
+  if (c_parser_next_token_is (parser, CPP_AND)
+      || c_parser_next_token_is (parser, CPP_MULT)
+      || c_parser_next_token_is (parser, CPP_PLUS)
+      || c_parser_next_token_is (parser, CPP_MINUS)
+      || c_parser_next_token_is (parser, CPP_COMPL)
+      || c_parser_next_token_is (parser, CPP_NOT))
+    {
+      rhs = c_parser_gimple_unary_expression (parser);
+      assign = gimple_build_assign (lhs.value, rhs.value);
+      gimple_set_location (assign, loc);
+      gimple_seq_add_stmt (seq, assign);
+      return;
+    }
+
+  /* GIMPLE PHI expression.  */
+  if (c_parser_next_token_is_keyword (parser, RID_PHI))
+    {
+      c_parser_consume_token (parser);
+
+      if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+	return;
+
+      if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+	c_parser_consume_token (parser);
+
+      while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
+	{
+	  if (c_parser_next_token_is (parser, CPP_NAME)
+	      && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
+	    {
+	      arg = lookup_label_for_goto (loc,
+					   c_parser_peek_token (parser)->value);
+	      c_parser_consume_token (parser);
+
+	      if (c_parser_next_token_is (parser, CPP_COLON))
+		c_parser_consume_token (parser);
+	      vargs.safe_push (arg);
+	    }
+	  else if (c_parser_next_token_is (parser, CPP_COMMA))
+	    c_parser_consume_token (parser);
+	  else
+	    {
+	      arg = c_parser_parse_ssa_names (parser).value;
+	      vargs.safe_push (arg);
+	    }
+	}
+
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
+				 "expected %<)%>");
+
+      /* Build internal function for PHI.  */
+      gcall *call_stmt = gimple_build_call_internal_vec (IFN_PHI, vargs);
+      gimple_call_set_lhs (call_stmt, lhs.value);
+      gimple_set_location (call_stmt, UNKNOWN_LOCATION);
+      gimple_seq_add_stmt (seq, call_stmt);
+      return;
+    }
+
+  /* GIMPLE call with lhs.  */
+  if (c_parser_next_token_is (parser, CPP_NAME)
+      && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN
+      && lookup_name (c_parser_peek_token (parser)->value))
+    {
+      rhs = c_parser_gimple_unary_expression (parser);
+      gimple *call = gimple_build_call_from_tree (rhs.value);
+      gimple_call_set_lhs (call, lhs.value);
+      gimple_seq_add_stmt (seq, call);
+      gimple_set_location (call, loc);
+      return;
+    }
+
+  rhs = c_parser_gimple_binary_expression (parser, &subcode);
+
+  if (lhs.value != error_mark_node
+      && rhs.value != error_mark_node)
+    {
+      if (subcode == NOP_EXPR)
+	assign = gimple_build_assign (lhs.value, rhs.value);
+      else
+	assign = gimple_build_assign (lhs.value, subcode,
+				      TREE_OPERAND (rhs.value, 0),
+				      TREE_OPERAND (rhs.value, 1));
+      gimple_seq_add_stmt (seq, assign);
+      gimple_set_location (assign, loc);
+    }
+  return;
+}
+
+/* Parse gimple binary expr.
+
+   gimple-multiplicative-expression:
+     gimple-unary-expression * gimple-unary-expression
+     gimple-unary-expression / gimple-unary-expression
+     gimple-unary-expression % gimple-unary-expression
+
+   gimple-additive-expression:
+     gimple-unary-expression + gimple-unary-expression
+     gimple-unary-expression - gimple-unary-expression
+
+   gimple-shift-expression:
+     gimple-unary-expression << gimple-unary-expression
+     gimple-unary-expression >> gimple-unary-expression
+
+   gimple-relational-expression:
+     gimple-unary-expression < gimple-unary-expression
+     gimple-unary-expression > gimple-unary-expression
+     gimple-unary-expression <= gimple-unary-expression
+     gimple-unary-expression >= gimple-unary-expression
+
+   gimple-equality-expression:
+     gimple-unary-expression == gimple-unary-expression
+     gimple-unary-expression != gimple-unary-expression
+
+   gimple-AND-expression:
+     gimple-unary-expression & gimple-unary-expression
+
+   gimple-exclusive-OR-expression:
+     gimple-unary-expression ^ gimple-unary-expression
+
+   gimple-inclusive-OR-expression:
+     gimple-unary-expression | gimple-unary-expression
+
+   gimple-logical-AND-expression:
+     gimple-unary-expression && gimple-unary-expression
+
+   gimple-logical-OR-expression:
+     gimple-unary-expression || gimple-unary-expression
+
+*/
+
+static c_expr
+c_parser_gimple_binary_expression (c_parser *parser, enum tree_code *subcode)
+{
+  struct {
+    /* The expression at this stack level.  */
+    struct c_expr expr;
+    /* The operation on its left.  */
+    enum tree_code op;
+    /* The source location of this operation.  */
+    location_t loc;
+  } stack[2];
+  int sp;
+  /* Location of the binary operator.  */
+  location_t binary_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
+#define POP								      \
+  do {									      \
+    if (sp == 1								      \
+	&& c_parser_peek_token (parser)->type == CPP_SEMICOLON		      \
+	&& (((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND)      \
+	       | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT)))     \
+	&& stack[sp].op != TRUNC_MOD_EXPR				      \
+	&& stack[0].expr.value != error_mark_node			      \
+	&& stack[1].expr.value != error_mark_node)			      \
+      stack[0].expr.value						      \
+	= build2 (stack[1].op, TREE_TYPE (stack[0].expr.value),		      \
+		  stack[0].expr.value, stack[1].expr.value);		      \
+    else								      \
+      stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc,	      \
+						   stack[sp].op,	      \
+						   stack[sp - 1].expr,	      \
+						   stack[sp].expr);	      \
+    sp--;								      \
+  } while (0)
+  stack[0].loc = c_parser_peek_token (parser)->location;
+  stack[0].expr = c_parser_gimple_unary_expression (parser);
+  sp = 0;
+  source_range src_range;
+  if (parser->error)
+    goto out;
+  switch (c_parser_peek_token (parser)->type)
+    {
+    case CPP_MULT:
+      *subcode = MULT_EXPR;
+      break;
+    case CPP_DIV:
+      *subcode = TRUNC_DIV_EXPR;
+      break;
+    case CPP_MOD:
+      *subcode = TRUNC_MOD_EXPR;
+      break;
+    case CPP_PLUS:
+      *subcode = PLUS_EXPR;
+      break;
+    case CPP_MINUS:
+      *subcode = MINUS_EXPR;
+      break;
+    case CPP_LSHIFT:
+      *subcode = LSHIFT_EXPR;
+      break;
+    case CPP_RSHIFT:
+      *subcode = RSHIFT_EXPR;
+      break;
+    case CPP_LESS:
+      *subcode = LT_EXPR;
+      break;
+    case CPP_GREATER:
+      *subcode = GT_EXPR;
+      break;
+    case CPP_LESS_EQ:
+      *subcode = LE_EXPR;
+      break;
+    case CPP_GREATER_EQ:
+      *subcode = GE_EXPR;
+      break;
+    case CPP_EQ_EQ:
+      *subcode = EQ_EXPR;
+      break;
+    case CPP_NOT_EQ:
+      *subcode = NE_EXPR;
+      break;
+    case CPP_AND:
+      *subcode = BIT_AND_EXPR;
+      break;
+    case CPP_XOR:
+      *subcode = BIT_XOR_EXPR;
+      break;
+    case CPP_OR:
+      *subcode = BIT_IOR_EXPR;
+      break;
+    case CPP_AND_AND:
+      *subcode = TRUTH_ANDIF_EXPR;
+      break;
+    case CPP_OR_OR:
+      *subcode = TRUTH_ORIF_EXPR;
+      break;
+    default:
+      /* Not a binary operator, so end of the binary expression.  */
+      *subcode = NOP_EXPR;
+      goto out;
+    }
+  binary_loc = c_parser_peek_token (parser)->location;
+  c_parser_consume_token (parser);
+  switch (*subcode)
+    {
+    case TRUTH_ANDIF_EXPR:
+      src_range = stack[sp].expr.src_range;
+      stack[sp].expr.value = c_objc_common_truthvalue_conversion
+	(stack[sp].loc, default_conversion (stack[sp].expr.value));
+      set_c_expr_source_range (&stack[sp].expr, src_range);
+      break;
+    case TRUTH_ORIF_EXPR:
+      src_range = stack[sp].expr.src_range;
+      stack[sp].expr.value = c_objc_common_truthvalue_conversion
+	(stack[sp].loc, default_conversion (stack[sp].expr.value));
+      set_c_expr_source_range (&stack[sp].expr, src_range);
+      break;
+    default:
+      break;
+    }
+  sp++;
+  stack[sp].loc = binary_loc;
+  stack[sp].expr = c_parser_gimple_unary_expression (parser);
+  stack[sp].op = *subcode;
+out:
+  while (sp > 0)
+    POP;
+  return stack[0].expr;
+#undef POP
+}
+
+/* Parse gimple unary expression.
+
+   gimple-unary-expression:
+     gimple-postfix-expression
+     unary-operator cast-expression
+
+   unary-operator: one of
+     & * + - ~ !
+*/
+
+static c_expr
+c_parser_gimple_unary_expression (c_parser *parser)
+{
+  struct c_expr ret, op;
+  if (c_parser_peek_token (parser)->value
+      && TREE_CODE (c_parser_peek_token (parser)->value) == IDENTIFIER_NODE
+      && ! lookup_name (c_parser_peek_token (parser)->value))
+    return c_parser_parse_ssa_names (parser);
+
+  location_t op_loc = c_parser_peek_token (parser)->location;
+  location_t finish;
+  ret.original_code = ERROR_MARK;
+  ret.original_type = NULL;
+  switch (c_parser_peek_token (parser)->type)
+    {
+    case CPP_AND:
+      c_parser_consume_token (parser);
+      op = c_parser_cast_expression (parser, NULL);
+      mark_exp_read (op.value);
+      return parser_build_unary_op (op_loc, ADDR_EXPR, op);
+    case CPP_MULT:
+      {
+	c_parser_consume_token (parser);
+	op = c_parser_cast_expression (parser, NULL);
+	finish = op.get_finish ();
+	location_t combined_loc = make_location (op_loc, op_loc, finish);
+	ret.value = build_indirect_ref (combined_loc, op.value,
+					RO_UNARY_STAR);
+	ret.src_range.m_start = op_loc;
+	ret.src_range.m_finish = finish;
+	return ret;
+      }
+    case CPP_PLUS:
+      c_parser_consume_token (parser);
+      op = c_parser_cast_expression (parser, NULL);
+      return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
+    case CPP_MINUS:
+      c_parser_consume_token (parser);
+      op = c_parser_cast_expression (parser, NULL);
+      return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
+    case CPP_COMPL:
+      c_parser_consume_token (parser);
+      op = c_parser_cast_expression (parser, NULL);
+      return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
+    case CPP_NOT:
+      c_parser_consume_token (parser);
+      op = c_parser_cast_expression (parser, NULL);
+      return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
+    default:
+      return c_parser_gimple_postfix_expression (parser);
+    }
+}
+
+/* Parse gimple ssa names.  */
+
+static c_expr
+c_parser_parse_ssa_names (c_parser *parser)
+{
+  tree id = NULL_TREE;
+  c_expr ret;
+  char *var_name = NULL, *var_version = NULL, *token = NULL;
+  ret.original_code = ERROR_MARK;
+  ret.original_type = NULL;
+
+  /* SSA token string.  */
+  const char *ssa_token
+    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+  token = new char [strlen (ssa_token) + 1];
+  strcpy (token, ssa_token);
+
+  /* Separate var name and version.  */
+  var_version = strrchr (token, '_');
+  if (var_version)
+    {
+      var_name = new char[var_version - token + 1];
+      memcpy (var_name, token, var_version - token);
+      var_name[var_version - token] = '\0';
+      id = get_identifier (var_name);
+
+      /* lookup for parent decl.  */
+      if (lookup_name (id))
+	{
+	  var_version++;
+	  unsigned int version;
+	  version = atoi (var_version);
+	  if (var_version && version)
+	    {
+	      ret.value = NULL_TREE;
+	      if (version < num_ssa_names)
+		ret.value = ssa_name (version);
+	      if (! ret.value)
+		ret.value = make_ssa_name_fn (cfun, lookup_name (id),
+					      gimple_build_nop (), version);
+	      c_parser_consume_token (parser);
+	    }
+	}
+    }
+
+  /* For default definition SSA names.  */
+  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    {
+      c_parser_consume_token (parser);
+      ssa_token = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+      if (! strcmp ("D", ssa_token))
+	{
+	  set_ssa_default_def (cfun, lookup_name (id), ret.value);
+	  c_parser_consume_token (parser);
+	}
+      if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
+	goto out;
+    }
+
+  out:
+  free (var_name);
+  free (token);
+  return ret;
+}
+
+/* Parse gimple postfix expression.
+
+   gimple-postfix-expression:
+     gimple-primary-expression
+     gimple-primary-xpression [ gimple-primary-expression ]
+     gimple-primary-expression ( gimple-argument-expression-list[opt] )
+
+   gimple-argument-expression-list:
+     gimple-unary-expression
+     gimple-argument-expression-list , gimple-unary-expression
+
+   gimple-primary-expression:
+     identifier
+     constant
+     string-literal
+
+*/
+
+static struct c_expr
+c_parser_gimple_postfix_expression (c_parser *parser)
+{
+  struct c_expr expr;
+  location_t loc = c_parser_peek_token (parser)->location;
+  source_range tok_range = c_parser_peek_token (parser)->get_range ();
+  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;
+      set_c_expr_source_range (&expr, tok_range);
+      loc = c_parser_peek_token (parser)->location;
+      c_parser_consume_token (parser);
+      break;
+    case CPP_CHAR:
+    case CPP_CHAR16:
+    case CPP_CHAR32:
+    case CPP_WCHAR:
+      expr.value = c_parser_peek_token (parser)->value;
+      set_c_expr_source_range (&expr, tok_range);
+      c_parser_consume_token (parser);
+      break;
+    case CPP_STRING:
+    case CPP_STRING16:
+    case CPP_STRING32:
+    case CPP_WSTRING:
+    case CPP_UTF8STRING:
+      expr.value = c_parser_peek_token (parser)->value;
+      set_c_expr_source_range (&expr, tok_range);
+      expr.original_code = STRING_CST;
+      c_parser_consume_token (parser);
+      break;
+    case CPP_NAME:
+      if (c_parser_peek_token (parser)->id_kind == C_ID_ID)
+	{
+	  tree id = c_parser_peek_token (parser)->value;
+	  c_parser_consume_token (parser);
+	  expr.value = build_external_ref (loc, id,
+					   (c_parser_peek_token (parser)->type
+					    == CPP_OPEN_PAREN),
+					   &expr.original_type);
+	  set_c_expr_source_range (&expr, tok_range);
+	  break;
+	}
+      else
+	{
+	  c_parser_error (parser, "expected expression");
+	  expr.set_error ();
+	  break;
+	}
+      break;
+    default:
+      c_parser_error (parser, "expected expression");
+      expr.set_error ();
+      break;
+    }
+  return c_parser_gimple_postfix_expression_after_primary
+    (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
+}
+
+/* Parse a gimple postfix expression after the initial primary or compound
+   literal.  */
+
+static struct c_expr
+c_parser_gimple_postfix_expression_after_primary (c_parser *parser,
+						  location_t expr_loc,
+						  struct c_expr expr)
+{
+  struct c_expr orig_expr;
+  vec<tree, va_gc> *exprlist;
+  vec<tree, va_gc> *origtypes = NULL;
+  vec<location_t> arg_loc = vNULL;
+  location_t start;
+  location_t finish;
+
+  location_t op_loc = c_parser_peek_token (parser)->location;
+
+  switch (c_parser_peek_token (parser)->type)
+    {
+    case CPP_OPEN_SQUARE:
+      {
+	c_parser_consume_token (parser);
+	tree idx = c_parser_gimple_unary_expression (parser).value;
+
+	if (! c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>"))
+	  break;
+
+	start = expr.get_start ();
+	finish = parser->tokens_buf[0].location;
+	expr.value = build_array_ref (op_loc, expr.value, idx);
+	set_c_expr_source_range (&expr, start, finish);
+
+	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;
+	else
+	  exprlist = c_parser_gimple_expr_list (parser, &origtypes,
+						&arg_loc);
+	c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
+				   "expected %<)%>");
+	orig_expr = expr;
+	start = expr.get_start ();
+	finish = parser->tokens_buf[0].get_finish ();
+	expr.value = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
+						exprlist, origtypes);
+	set_c_expr_source_range (&expr, start, finish);
+
+	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)
+	  {
+	    release_tree_vector (exprlist);
+	    release_tree_vector (origtypes);
+	  }
+	arg_loc.release ();
+	break;
+      default:
+	return expr;
+      }
+    }
+  return expr;
+}
+
+/* Parse expression list.
+
+   gimple-expr-list:
+     gimple-unary-expression
+     gimple-expr-list , gimple-unary-expression
+
+ */
+
+static vec<tree, va_gc> *
+c_parser_gimple_expr_list (c_parser *parser, vec<tree, va_gc> **p_orig_types,
+			   vec<location_t> *locations)
+{
+  vec<tree, va_gc> *ret;
+  vec<tree, va_gc> *orig_types;
+  struct c_expr expr;
+  location_t loc = c_parser_peek_token (parser)->location;
+
+  ret = make_tree_vector ();
+  if (p_orig_types == NULL)
+    orig_types = NULL;
+  else
+    orig_types = make_tree_vector ();
+
+  expr = c_parser_gimple_unary_expression (parser);
+  vec_safe_push (ret, expr.value);
+  if (orig_types)
+    vec_safe_push (orig_types, expr.original_type);
+  if (locations)
+    locations->safe_push (loc);
+  while (c_parser_next_token_is (parser, CPP_COMMA))
+    {
+      c_parser_consume_token (parser);
+      loc = c_parser_peek_token (parser)->location;
+      expr = c_parser_gimple_unary_expression (parser);
+      vec_safe_push (ret, expr.value);
+      if (orig_types)
+	vec_safe_push (orig_types, expr.original_type);
+      if (locations)
+	locations->safe_push (loc);
+    }
+  if (orig_types)
+    *p_orig_types = orig_types;
+  return ret;
+}
+
+/* Parse gimple label.
+
+   gimple-label:
+     identifier :
+     case constant-expression :
+     default :
+
+*/
+
+static void
+c_parser_gimple_label (c_parser *parser, gimple_seq *seq)
+{
+  tree name = c_parser_peek_token (parser)->value;
+  location_t loc1 = 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));
+  c_parser_consume_token (parser);
+  tree label = define_label (loc1, name);
+  gimple_seq_add_stmt (seq, gimple_build_label (label));
+  return;
+}
+
+/* Parse gimple pass list.
+
+   gimple-pass-list:
+     startwith("pass-name")
+ */
+
+void
+c_parser_gimple_pass_list (c_parser *parser, opt_pass **pass,
+			   bool *startwith_p)
+{
+  if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    return;
+
+  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+    return;
+
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *op = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+      c_parser_consume_token (parser);
+      if (! strcmp (op, "startwith"))
+	{
+	  *pass = c_parser_gimple_pass_list_params (parser, pass);
+	  if (! *pass)
+	    return;
+
+	  *startwith_p = true;
+	  if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
+	    return;
+	}
+      else
+	{
+	  error_at (c_parser_peek_token (parser)->location,
+		    "invalid operation");
+	  return;
+	}
+    }
+  else if (c_parser_next_token_is (parser, CPP_EOF))
+    {
+      c_parser_error (parser, "expected parameters");
+      return;
+    }
+
+  return;
+}
+
+/* Support function for c_parser_gimple_pass_list.  */
+
+static opt_pass *
+c_parser_gimple_pass_list_params (c_parser *parser, opt_pass **pass)
+{
+  opt_pass *pass_start = NULL, *new_pass;
+  if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    return NULL;
+
+  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+    return NULL;
+
+  while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
+    {
+      if (c_parser_next_token_is (parser, CPP_EOF))
+	{
+	  error_at (c_parser_peek_token (parser)->location,
+		    "expected pass names");
+	  return NULL;
+	}
+
+      if (c_parser_next_token_is (parser, CPP_STRING))
+	{
+	  const char *name = NULL;
+	  name = TREE_STRING_POINTER (c_parser_peek_token (parser)->value);
+	  c_parser_consume_token (parser);
+	  new_pass = g->get_passes ()->get_pass_by_name (name);
+
+	  if (! new_pass)
+	    {
+	      error_at (c_parser_peek_token (parser)->location,
+			"invalid pass name");
+	      parser->error = true;
+	      c_parser_consume_token (parser);
+	      return NULL;
+	    }
+	  if (*pass)
+	    {
+	      (*pass)->next = new_pass;
+	      (*pass) = (*pass)->next;
+	    }
+	  else
+	    {
+	      *pass = new_pass;
+	      pass_start = *pass;
+	    }
+	}
+      else if (c_parser_next_token_is (parser, CPP_COMMA))
+	c_parser_consume_token (parser);
+      else
+	{
+	  error_at (c_parser_peek_token (parser)->location,
+		    "invalid pass name");
+	  c_parser_consume_token (parser);
+	  return NULL;
+	}
+    }
+  return pass_start;
+}
+
+/* Parse gimple local declaration.
+
+   declaration-specifiers:
+     storage-class-specifier declaration-specifiers[opt]
+     type-specifier declaration-specifiers[opt]
+     type-qualifier declaration-specifiers[opt]
+     function-specifier declaration-specifiers[opt]
+     alignment-specifier declaration-specifiers[opt]
+
+   storage-class-specifier:
+     typedef
+     extern
+     static
+     auto
+     register
+
+   type-specifier:
+     void
+     char
+     short
+     int
+     long
+     float
+     double
+     signed
+     unsigned
+     _Bool
+     _Complex
+
+   type-qualifier:
+     const
+     restrict
+     volatile
+     address-space-qualifier
+     _Atomic
+
+ */
+
+static void
+c_parser_gimple_declaration (c_parser *parser)
+{
+  struct c_declarator *declarator;
+  struct c_declspecs *specs = build_null_declspecs ();
+  c_parser_declspecs (parser, specs, true, true, true,
+		      true, true, cla_nonabstract_decl);
+  finish_declspecs (specs);
+
+  /* Provide better error recovery.  Note that a type name here is usually
+     better diagnosed as a redeclaration.  */
+  if (c_parser_next_token_starts_declspecs (parser)
+      && ! c_parser_next_token_is (parser, CPP_NAME))
+    {
+      c_parser_error (parser, "expected %<;%>");
+      parser->error = false;
+      return;
+    }
+
+  bool dummy = false;
+  declarator = c_parser_declarator (parser,
+				    specs->typespec_kind != ctsk_none,
+				    C_DTR_NORMAL, &dummy);
+
+  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
+    {
+      tree postfix_attrs = NULL_TREE;
+      tree all_prefix_attrs = specs->attrs;
+      specs->attrs = NULL;
+      tree decl = start_decl (declarator, specs, false,
+			 chainon (postfix_attrs, all_prefix_attrs));
+      if (decl)
+	finish_decl (decl, UNKNOWN_LOCATION, NULL_TREE, NULL_TREE, NULL_TREE);
+    }
+  else
+    {
+      c_parser_error (parser, "expected %<;%>");
+      return;
+    }
+}
+
+/* Parse gimple goto statement.  */
+
+static void
+c_parser_gimple_goto_stmt (location_t loc, tree label, gimple_seq *seq)
+{
+  tree decl = lookup_label_for_goto (loc, label);
+  gimple_seq_add_stmt (seq, gimple_build_goto (decl));
+  return;
+}
+
+/* Parse a parenthesized condition.
+   gimple-condition:
+     ( gimple-binary-expression )    */
+
+static tree
+c_parser_gimple_paren_condition (c_parser *parser)
+{
+  enum tree_code subcode = NOP_EXPR;
+  location_t loc = c_parser_peek_token (parser)->location;
+  if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    return error_mark_node;
+  tree cond = c_parser_gimple_binary_expression (parser, &subcode).value;
+  cond = c_objc_common_truthvalue_conversion (loc, cond);
+  if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
+    return error_mark_node;
+  return cond;
+}
+
+/* Parse gimple if-else statement.
+
+   if-statement:
+     if ( gimple-binary-expression ) gimple-goto-statement
+     if ( gimple-binary-expression ) gimple-goto-statement \
+					else gimple-goto-statement
+ */
+
+static void
+c_parser_gimple_if_stmt (c_parser *parser, gimple_seq *seq)
+{
+  tree t_label, f_label, label;
+  location_t loc;
+  c_parser_consume_token (parser);
+  tree cond = c_parser_gimple_paren_condition (parser);
+
+  if (c_parser_next_token_is_keyword (parser, RID_GOTO))
+    {
+      loc = c_parser_peek_token (parser)->location;
+      c_parser_consume_token (parser);
+      label = c_parser_peek_token (parser)->value;
+      t_label = lookup_label_for_goto (loc, label);
+      c_parser_consume_token (parser);
+      if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
+	return;
+    }
+  else
+    {
+      c_parser_error (parser, "expected goto expression");
+      return;
+    }
+
+  if (c_parser_next_token_is_keyword (parser, RID_ELSE))
+    c_parser_consume_token (parser);
+  else
+    {
+      c_parser_error (parser, "expected else statement");
+      return;
+    }
+
+  if (c_parser_next_token_is_keyword (parser, RID_GOTO))
+    {
+      loc = c_parser_peek_token (parser)->location;
+      c_parser_consume_token (parser);
+      label = c_parser_peek_token (parser)->value;
+      f_label = lookup_label_for_goto (loc, label);
+      c_parser_consume_token (parser);
+      if (! c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
+	return;
+    }
+  else
+    {
+      c_parser_error (parser, "expected goto expression");
+      return;
+    }
+
+  gimple_seq_add_stmt (seq, gimple_build_cond_from_tree (cond, t_label,
+							 f_label));
+}
+
+/* Parse gimple switch-statement.
+
+   gimple-switch-statement:
+     switch (gimple-unary-expression) gimple-case-statement
+
+   gimple-case-statement:
+     gimple-case-statement
+     gimple-label-statement : gimple-goto-statment
+*/
+
+static void
+c_parser_gimple_switch_stmt (c_parser *parser, gimple_seq *seq)
+{
+  c_expr cond_expr;
+  tree case_label, label;
+  auto_vec<tree> labels;
+  tree default_label = NULL_TREE;
+  gimple_seq switch_body = NULL;
+  location_t loc;
+  c_parser_consume_token (parser);
+
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    {
+      cond_expr = c_parser_gimple_unary_expression (parser);
+      if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
+	return;
+    }
+
+  if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
+    {
+      while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
+	{
+	  if (c_parser_next_token_is (parser, CPP_EOF))
+	    {
+	      c_parser_error (parser, "expected statement");
+	      return;
+	    }
+
+	  switch (c_parser_peek_token (parser)->keyword)
+	    {
+	    case RID_CASE:
+	      {
+		c_expr exp1;
+		loc = c_parser_peek_token (parser)->location;
+		c_parser_consume_token (parser);
+
+		if (c_parser_next_token_is (parser, CPP_NAME)
+		    || c_parser_peek_token (parser)->type == CPP_NUMBER)
+		  exp1 = c_parser_gimple_unary_expression (parser);
+		else
+		  c_parser_error (parser, "expected expression");
+
+		if (c_parser_next_token_is (parser, CPP_COLON))
+		  {
+		    c_parser_consume_token (parser);
+		    label = create_artificial_label (loc);
+		    case_label = build_case_label (exp1.value, NULL_TREE,
+						   label);
+		    labels.safe_push (case_label);
+		    gimple_seq_add_stmt (&switch_body,
+					 gimple_build_label
+					 (CASE_LABEL (case_label)));
+		  }
+		else if (! c_parser_require (parser, CPP_SEMICOLON,
+					    "expected %<:%>"))
+		  return;
+		break;
+	      }
+	    case RID_DEFAULT:
+	      {
+		c_parser_consume_token (parser);
+		if (c_parser_next_token_is (parser, CPP_COLON))
+		  {
+		    c_parser_consume_token (parser);
+		    default_label = build_case_label (NULL_TREE, NULL_TREE,
+						      create_artificial_label
+						      (UNKNOWN_LOCATION));
+		    gimple_seq_add_stmt (&switch_body,
+					 gimple_build_label
+					 (CASE_LABEL (default_label)));
+		  }
+		else if (! c_parser_require (parser, CPP_SEMICOLON,
+					    "expected %<:%>"))
+		  return;
+		break;
+	      }
+	    case RID_GOTO:
+	      {
+		loc = c_parser_peek_token (parser)->location;
+		c_parser_consume_token (parser);
+		if (c_parser_next_token_is (parser, CPP_NAME))
+		  {
+		    c_parser_gimple_goto_stmt (loc,
+					       c_parser_peek_token
+					         (parser)->value,
+					       &switch_body);
+		    c_parser_consume_token (parser);
+		    if (c_parser_next_token_is (parser, CPP_SEMICOLON))
+		      c_parser_consume_token (parser);
+		    else
+		      {
+			c_parser_error (parser, "expected semicolon");
+			return;
+		      }
+		  }
+		else if (! c_parser_require (parser, CPP_NAME,
+					    "expected label"))
+		  return;
+		break;
+	      }
+	    default:
+	      c_parser_error (parser, "expected case label or goto statement");
+	      return;
+	    }
+
+	}
+    }
+  if (! c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
+    return;
+  gimple_seq_add_stmt (seq, gimple_build_switch (cond_expr.value,
+						 default_label, labels));
+  gimple_seq_add_seq (seq, switch_body);
+  labels.release();
+}
+
+/* Parse gimple return statement.  */
+
+static void
+c_parser_gimple_return_stmt (c_parser *parser, gimple_seq *seq)
+{
+  location_t loc = c_parser_peek_token (parser)->location;
+  gimple *ret = NULL;
+  c_parser_consume_token (parser);
+  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
+    {
+      c_finish_gimple_return (loc, NULL_TREE);
+      ret = gimple_build_return (NULL);
+      gimple_seq_add_stmt (seq, ret);
+    }
+  else
+    {
+      location_t xloc = c_parser_peek_token (parser)->location;
+      c_expr expr = c_parser_gimple_unary_expression (parser);
+      c_finish_gimple_return (xloc, expr.value);
+      ret = gimple_build_return (expr.value);
+      gimple_seq_add_stmt (seq, ret);
+    }
+}
+
+/* Support function for c_parser_gimple_return_stmt.  */
+
+static void
+c_finish_gimple_return (location_t loc, tree retval)
+{
+  tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
+
+  /* Use the expansion point to handle cases such as returning NULL
+     in a function returning void.  */
+  source_location xloc = expansion_point_location_if_in_system_header (loc);
+
+  if (TREE_THIS_VOLATILE (current_function_decl))
+    warning_at (xloc, 0,
+		"function declared %<noreturn%> has a %<return%> statement");
+
+  if (! retval)
+    current_function_returns_null = 1;
+  else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
+    {
+      current_function_returns_null = 1;
+      if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
+	{
+	  error_at
+	    (xloc, "%<return%> with a value, in function returning void");
+	  inform (DECL_SOURCE_LOCATION (current_function_decl),
+		  "declared here");
+	}
+    }
+  else if (TREE_CODE (valtype) != TREE_CODE (TREE_TYPE (retval)))
+    {
+      error_at
+	(xloc, "invalid conversion in return statement");
+      inform (DECL_SOURCE_LOCATION (current_function_decl),
+	      "declared here");
+    }
+  return;
+}
diff --git a/gcc/c/gimple-parser.h b/gcc/c/gimple-parser.h
new file mode 100644
index 0000000..d88d9e5
--- /dev/null
+++ b/gcc/c/gimple-parser.h
@@ -0,0 +1,27 @@
+/* Declarations for the parser for GIMPLE.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+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 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+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 COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_GIMPLE_PARSER_H
+#define GCC_GIMPLE_PARSER_H
+
+/* Gimple parsing functions.  */
+extern void c_parser_parse_gimple_body (c_parser *);
+extern void c_parser_gimple_pass_list (c_parser *, opt_pass **, bool *);
+
+#endif
diff --git a/gcc/objc/config-lang.in b/gcc/objc/config-lang.in
index f5a74a7..912af22 100644
--- a/gcc/objc/config-lang.in
+++ b/gcc/objc/config-lang.in
@@ -35,4 +35,4 @@ lang_requires="c"
 # Order is important.  If you change this list, make sure you test
 # building without C++ as well; that is, remove the gcc/cp directory,
 # and build with --enable-languages=c,objc.
-gtfiles="\$(srcdir)/objc/objc-map.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/objc/objc-act.h \$(srcdir)/objc/objc-act.c \$(srcdir)/objc/objc-runtime-shared-support.c \$(srcdir)/objc/objc-gnu-runtime-abi-01.c \$(srcdir)/objc/objc-next-runtime-abi-01.c \$(srcdir)/objc/objc-next-runtime-abi-02.c \$(srcdir)/c/c-parser.c \$(srcdir)/c/c-tree.h \$(srcdir)/c/c-decl.c \$(srcdir)/c/c-lang.h \$(srcdir)/c/c-objc-common.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-cppbuiltin.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c"
+gtfiles="\$(srcdir)/objc/objc-map.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/objc/objc-act.h \$(srcdir)/objc/objc-act.c \$(srcdir)/objc/objc-runtime-shared-support.c \$(srcdir)/objc/objc-gnu-runtime-abi-01.c \$(srcdir)/objc/objc-next-runtime-abi-01.c \$(srcdir)/objc/objc-next-runtime-abi-02.c \$(srcdir)/c/c-parser.h \$(srcdir)/c/c-parser.c \$(srcdir)/c/c-tree.h \$(srcdir)/c/c-decl.c \$(srcdir)/c/c-lang.h \$(srcdir)/c/c-objc-common.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-cppbuiltin.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c"



More information about the Gcc-patches mailing list