xref: /dragonfly/contrib/gcc-4.7/gcc/c-parser.c (revision e4b17023)
1*e4b17023SJohn Marino /* Parser for C and Objective-C.
2*e4b17023SJohn Marino    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3*e4b17023SJohn Marino    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011,
4*e4b17023SJohn Marino    2012 Free Software Foundation, Inc.
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino    Parser actions based on the old Bison parser; structure somewhat
7*e4b17023SJohn Marino    influenced by and fragments based on the C++ parser.
8*e4b17023SJohn Marino 
9*e4b17023SJohn Marino This file is part of GCC.
10*e4b17023SJohn Marino 
11*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
12*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
13*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
14*e4b17023SJohn Marino version.
15*e4b17023SJohn Marino 
16*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
18*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19*e4b17023SJohn Marino for more details.
20*e4b17023SJohn Marino 
21*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
22*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
23*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
24*e4b17023SJohn Marino 
25*e4b17023SJohn Marino /* TODO:
26*e4b17023SJohn Marino 
27*e4b17023SJohn Marino    Make sure all relevant comments, and all relevant code from all
28*e4b17023SJohn Marino    actions, brought over from old parser.  Verify exact correspondence
29*e4b17023SJohn Marino    of syntax accepted.
30*e4b17023SJohn Marino 
31*e4b17023SJohn Marino    Add testcases covering every input symbol in every state in old and
32*e4b17023SJohn Marino    new parsers.
33*e4b17023SJohn Marino 
34*e4b17023SJohn Marino    Include full syntax for GNU C, including erroneous cases accepted
35*e4b17023SJohn Marino    with error messages, in syntax productions in comments.
36*e4b17023SJohn Marino 
37*e4b17023SJohn Marino    Make more diagnostics in the front end generally take an explicit
38*e4b17023SJohn Marino    location rather than implicitly using input_location.  */
39*e4b17023SJohn Marino 
40*e4b17023SJohn Marino #include "config.h"
41*e4b17023SJohn Marino #include "system.h"
42*e4b17023SJohn Marino #include "coretypes.h"
43*e4b17023SJohn Marino #include "tm.h"			/* For rtl.h: needs enum reg_class.  */
44*e4b17023SJohn Marino #include "tree.h"
45*e4b17023SJohn Marino #include "langhooks.h"
46*e4b17023SJohn Marino #include "input.h"
47*e4b17023SJohn Marino #include "cpplib.h"
48*e4b17023SJohn Marino #include "timevar.h"
49*e4b17023SJohn Marino #include "c-family/c-pragma.h"
50*e4b17023SJohn Marino #include "c-tree.h"
51*e4b17023SJohn Marino #include "flags.h"
52*e4b17023SJohn Marino #include "output.h"
53*e4b17023SJohn Marino #include "ggc.h"
54*e4b17023SJohn Marino #include "c-family/c-common.h"
55*e4b17023SJohn Marino #include "c-family/c-objc.h"
56*e4b17023SJohn Marino #include "vec.h"
57*e4b17023SJohn Marino #include "target.h"
58*e4b17023SJohn Marino #include "cgraph.h"
59*e4b17023SJohn Marino #include "plugin.h"
60*e4b17023SJohn Marino 
61*e4b17023SJohn Marino 
62*e4b17023SJohn Marino /* Initialization routine for this file.  */
63*e4b17023SJohn Marino 
64*e4b17023SJohn Marino void
c_parse_init(void)65*e4b17023SJohn Marino c_parse_init (void)
66*e4b17023SJohn Marino {
67*e4b17023SJohn Marino   /* The only initialization required is of the reserved word
68*e4b17023SJohn Marino      identifiers.  */
69*e4b17023SJohn Marino   unsigned int i;
70*e4b17023SJohn Marino   tree id;
71*e4b17023SJohn Marino   int mask = 0;
72*e4b17023SJohn Marino 
73*e4b17023SJohn Marino   /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
74*e4b17023SJohn Marino      the c_token structure.  */
75*e4b17023SJohn Marino   gcc_assert (RID_MAX <= 255);
76*e4b17023SJohn Marino 
77*e4b17023SJohn Marino   mask |= D_CXXONLY;
78*e4b17023SJohn Marino   if (!flag_isoc99)
79*e4b17023SJohn Marino     mask |= D_C99;
80*e4b17023SJohn Marino   if (flag_no_asm)
81*e4b17023SJohn Marino     {
82*e4b17023SJohn Marino       mask |= D_ASM | D_EXT;
83*e4b17023SJohn Marino       if (!flag_isoc99)
84*e4b17023SJohn Marino 	mask |= D_EXT89;
85*e4b17023SJohn Marino     }
86*e4b17023SJohn Marino   if (!c_dialect_objc ())
87*e4b17023SJohn Marino     mask |= D_OBJC | D_CXX_OBJC;
88*e4b17023SJohn Marino 
89*e4b17023SJohn Marino   ridpointers = ggc_alloc_cleared_vec_tree ((int) RID_MAX);
90*e4b17023SJohn Marino   for (i = 0; i < num_c_common_reswords; i++)
91*e4b17023SJohn Marino     {
92*e4b17023SJohn Marino       /* If a keyword is disabled, do not enter it into the table
93*e4b17023SJohn Marino 	 and so create a canonical spelling that isn't a keyword.  */
94*e4b17023SJohn Marino       if (c_common_reswords[i].disable & mask)
95*e4b17023SJohn Marino 	{
96*e4b17023SJohn Marino 	  if (warn_cxx_compat
97*e4b17023SJohn Marino 	      && (c_common_reswords[i].disable & D_CXXWARN))
98*e4b17023SJohn Marino 	    {
99*e4b17023SJohn Marino 	      id = get_identifier (c_common_reswords[i].word);
100*e4b17023SJohn Marino 	      C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
101*e4b17023SJohn Marino 	      C_IS_RESERVED_WORD (id) = 1;
102*e4b17023SJohn Marino 	    }
103*e4b17023SJohn Marino 	  continue;
104*e4b17023SJohn Marino 	}
105*e4b17023SJohn Marino 
106*e4b17023SJohn Marino       id = get_identifier (c_common_reswords[i].word);
107*e4b17023SJohn Marino       C_SET_RID_CODE (id, c_common_reswords[i].rid);
108*e4b17023SJohn Marino       C_IS_RESERVED_WORD (id) = 1;
109*e4b17023SJohn Marino       ridpointers [(int) c_common_reswords[i].rid] = id;
110*e4b17023SJohn Marino     }
111*e4b17023SJohn Marino }
112*e4b17023SJohn Marino 
113*e4b17023SJohn Marino /* The C lexer intermediates between the lexer in cpplib and c-lex.c
114*e4b17023SJohn Marino    and the C parser.  Unlike the C++ lexer, the parser structure
115*e4b17023SJohn Marino    stores the lexer information instead of using a separate structure.
116*e4b17023SJohn Marino    Identifiers are separated into ordinary identifiers, type names,
117*e4b17023SJohn Marino    keywords and some other Objective-C types of identifiers, and some
118*e4b17023SJohn Marino    look-ahead is maintained.
119*e4b17023SJohn Marino 
120*e4b17023SJohn Marino    ??? It might be a good idea to lex the whole file up front (as for
121*e4b17023SJohn Marino    C++).  It would then be possible to share more of the C and C++
122*e4b17023SJohn Marino    lexer code, if desired.  */
123*e4b17023SJohn Marino 
124*e4b17023SJohn Marino /* The following local token type is used.  */
125*e4b17023SJohn Marino 
126*e4b17023SJohn Marino /* A keyword.  */
127*e4b17023SJohn Marino #define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
128*e4b17023SJohn Marino 
129*e4b17023SJohn Marino /* More information about the type of a CPP_NAME token.  */
130*e4b17023SJohn Marino typedef enum c_id_kind {
131*e4b17023SJohn Marino   /* An ordinary identifier.  */
132*e4b17023SJohn Marino   C_ID_ID,
133*e4b17023SJohn Marino   /* An identifier declared as a typedef name.  */
134*e4b17023SJohn Marino   C_ID_TYPENAME,
135*e4b17023SJohn Marino   /* An identifier declared as an Objective-C class name.  */
136*e4b17023SJohn Marino   C_ID_CLASSNAME,
137*e4b17023SJohn Marino   /* An address space identifier.  */
138*e4b17023SJohn Marino   C_ID_ADDRSPACE,
139*e4b17023SJohn Marino   /* Not an identifier.  */
140*e4b17023SJohn Marino   C_ID_NONE
141*e4b17023SJohn Marino } c_id_kind;
142*e4b17023SJohn Marino 
143*e4b17023SJohn Marino /* A single C token after string literal concatenation and conversion
144*e4b17023SJohn Marino    of preprocessing tokens to tokens.  */
145*e4b17023SJohn Marino typedef struct GTY (()) c_token {
146*e4b17023SJohn Marino   /* The kind of token.  */
147*e4b17023SJohn Marino   ENUM_BITFIELD (cpp_ttype) type : 8;
148*e4b17023SJohn Marino   /* If this token is a CPP_NAME, this value indicates whether also
149*e4b17023SJohn Marino      declared as some kind of type.  Otherwise, it is C_ID_NONE.  */
150*e4b17023SJohn Marino   ENUM_BITFIELD (c_id_kind) id_kind : 8;
151*e4b17023SJohn Marino   /* If this token is a keyword, this value indicates which keyword.
152*e4b17023SJohn Marino      Otherwise, this value is RID_MAX.  */
153*e4b17023SJohn Marino   ENUM_BITFIELD (rid) keyword : 8;
154*e4b17023SJohn Marino   /* If this token is a CPP_PRAGMA, this indicates the pragma that
155*e4b17023SJohn Marino      was seen.  Otherwise it is PRAGMA_NONE.  */
156*e4b17023SJohn Marino   ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
157*e4b17023SJohn Marino   /* The location at which this token was found.  */
158*e4b17023SJohn Marino   location_t location;
159*e4b17023SJohn Marino   /* The value associated with this token, if any.  */
160*e4b17023SJohn Marino   tree value;
161*e4b17023SJohn Marino } c_token;
162*e4b17023SJohn Marino 
163*e4b17023SJohn Marino /* A parser structure recording information about the state and
164*e4b17023SJohn Marino    context of parsing.  Includes lexer information with up to two
165*e4b17023SJohn Marino    tokens of look-ahead; more are not needed for C.  */
166*e4b17023SJohn Marino typedef struct GTY(()) c_parser {
167*e4b17023SJohn Marino   /* The look-ahead tokens.  */
168*e4b17023SJohn Marino   c_token tokens[2];
169*e4b17023SJohn Marino   /* How many look-ahead tokens are available (0, 1 or 2).  */
170*e4b17023SJohn Marino   short tokens_avail;
171*e4b17023SJohn Marino   /* True if a syntax error is being recovered from; false otherwise.
172*e4b17023SJohn Marino      c_parser_error sets this flag.  It should clear this flag when
173*e4b17023SJohn Marino      enough tokens have been consumed to recover from the error.  */
174*e4b17023SJohn Marino   BOOL_BITFIELD error : 1;
175*e4b17023SJohn Marino   /* True if we're processing a pragma, and shouldn't automatically
176*e4b17023SJohn Marino      consume CPP_PRAGMA_EOL.  */
177*e4b17023SJohn Marino   BOOL_BITFIELD in_pragma : 1;
178*e4b17023SJohn Marino   /* True if we're parsing the outermost block of an if statement.  */
179*e4b17023SJohn Marino   BOOL_BITFIELD in_if_block : 1;
180*e4b17023SJohn Marino   /* True if we want to lex an untranslated string.  */
181*e4b17023SJohn Marino   BOOL_BITFIELD lex_untranslated_string : 1;
182*e4b17023SJohn Marino 
183*e4b17023SJohn Marino   /* Objective-C specific parser/lexer information.  */
184*e4b17023SJohn Marino 
185*e4b17023SJohn Marino   /* True if we are in a context where the Objective-C "PQ" keywords
186*e4b17023SJohn Marino      are considered keywords.  */
187*e4b17023SJohn Marino   BOOL_BITFIELD objc_pq_context : 1;
188*e4b17023SJohn Marino   /* True if we are parsing a (potential) Objective-C foreach
189*e4b17023SJohn Marino      statement.  This is set to true after we parsed 'for (' and while
190*e4b17023SJohn Marino      we wait for 'in' or ';' to decide if it's a standard C for loop or an
191*e4b17023SJohn Marino      Objective-C foreach loop.  */
192*e4b17023SJohn Marino   BOOL_BITFIELD objc_could_be_foreach_context : 1;
193*e4b17023SJohn Marino   /* The following flag is needed to contextualize Objective-C lexical
194*e4b17023SJohn Marino      analysis.  In some cases (e.g., 'int NSObject;'), it is
195*e4b17023SJohn Marino      undesirable to bind an identifier to an Objective-C class, even
196*e4b17023SJohn Marino      if a class with that name exists.  */
197*e4b17023SJohn Marino   BOOL_BITFIELD objc_need_raw_identifier : 1;
198*e4b17023SJohn Marino   /* Nonzero if we're processing a __transaction statement.  The value
199*e4b17023SJohn Marino      is 1 | TM_STMT_ATTR_*.  */
200*e4b17023SJohn Marino   unsigned int in_transaction : 4;
201*e4b17023SJohn Marino   /* True if we are in a context where the Objective-C "Property attribute"
202*e4b17023SJohn Marino      keywords are valid.  */
203*e4b17023SJohn Marino   BOOL_BITFIELD objc_property_attr_context : 1;
204*e4b17023SJohn Marino } c_parser;
205*e4b17023SJohn Marino 
206*e4b17023SJohn Marino 
207*e4b17023SJohn Marino /* The actual parser and external interface.  ??? Does this need to be
208*e4b17023SJohn Marino    garbage-collected?  */
209*e4b17023SJohn Marino 
210*e4b17023SJohn Marino static GTY (()) c_parser *the_parser;
211*e4b17023SJohn Marino 
212*e4b17023SJohn Marino /* Read in and lex a single token, storing it in *TOKEN.  */
213*e4b17023SJohn Marino 
214*e4b17023SJohn Marino static void
c_lex_one_token(c_parser * parser,c_token * token)215*e4b17023SJohn Marino c_lex_one_token (c_parser *parser, c_token *token)
216*e4b17023SJohn Marino {
217*e4b17023SJohn Marino   timevar_push (TV_LEX);
218*e4b17023SJohn Marino 
219*e4b17023SJohn Marino   token->type = c_lex_with_flags (&token->value, &token->location, NULL,
220*e4b17023SJohn Marino 				  (parser->lex_untranslated_string
221*e4b17023SJohn Marino 				   ? C_LEX_STRING_NO_TRANSLATE : 0));
222*e4b17023SJohn Marino   token->id_kind = C_ID_NONE;
223*e4b17023SJohn Marino   token->keyword = RID_MAX;
224*e4b17023SJohn Marino   token->pragma_kind = PRAGMA_NONE;
225*e4b17023SJohn Marino 
226*e4b17023SJohn Marino   switch (token->type)
227*e4b17023SJohn Marino     {
228*e4b17023SJohn Marino     case CPP_NAME:
229*e4b17023SJohn Marino       {
230*e4b17023SJohn Marino 	tree decl;
231*e4b17023SJohn Marino 
232*e4b17023SJohn Marino 	bool objc_force_identifier = parser->objc_need_raw_identifier;
233*e4b17023SJohn Marino 	if (c_dialect_objc ())
234*e4b17023SJohn Marino 	  parser->objc_need_raw_identifier = false;
235*e4b17023SJohn Marino 
236*e4b17023SJohn Marino 	if (C_IS_RESERVED_WORD (token->value))
237*e4b17023SJohn Marino 	  {
238*e4b17023SJohn Marino 	    enum rid rid_code = C_RID_CODE (token->value);
239*e4b17023SJohn Marino 
240*e4b17023SJohn Marino 	    if (rid_code == RID_CXX_COMPAT_WARN)
241*e4b17023SJohn Marino 	      {
242*e4b17023SJohn Marino 		warning_at (token->location,
243*e4b17023SJohn Marino 			    OPT_Wc___compat,
244*e4b17023SJohn Marino 			    "identifier %qE conflicts with C++ keyword",
245*e4b17023SJohn Marino 			    token->value);
246*e4b17023SJohn Marino 	      }
247*e4b17023SJohn Marino 	    else if (rid_code >= RID_FIRST_ADDR_SPACE
248*e4b17023SJohn Marino 		     && rid_code <= RID_LAST_ADDR_SPACE)
249*e4b17023SJohn Marino 	      {
250*e4b17023SJohn Marino 		token->id_kind = C_ID_ADDRSPACE;
251*e4b17023SJohn Marino 		token->keyword = rid_code;
252*e4b17023SJohn Marino 		break;
253*e4b17023SJohn Marino 	      }
254*e4b17023SJohn Marino 	    else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
255*e4b17023SJohn Marino 	      {
256*e4b17023SJohn Marino 		/* We found an Objective-C "pq" keyword (in, out,
257*e4b17023SJohn Marino 		   inout, bycopy, byref, oneway).  They need special
258*e4b17023SJohn Marino 		   care because the interpretation depends on the
259*e4b17023SJohn Marino 		   context.  */
260*e4b17023SJohn Marino 		if (parser->objc_pq_context)
261*e4b17023SJohn Marino 		  {
262*e4b17023SJohn Marino 		    token->type = CPP_KEYWORD;
263*e4b17023SJohn Marino 		    token->keyword = rid_code;
264*e4b17023SJohn Marino 		    break;
265*e4b17023SJohn Marino 		  }
266*e4b17023SJohn Marino 		else if (parser->objc_could_be_foreach_context
267*e4b17023SJohn Marino 			 && rid_code == RID_IN)
268*e4b17023SJohn Marino 		  {
269*e4b17023SJohn Marino 		    /* We are in Objective-C, inside a (potential)
270*e4b17023SJohn Marino 		       foreach context (which means after having
271*e4b17023SJohn Marino 		       parsed 'for (', but before having parsed ';'),
272*e4b17023SJohn Marino 		       and we found 'in'.  We consider it the keyword
273*e4b17023SJohn Marino 		       which terminates the declaration at the
274*e4b17023SJohn Marino 		       beginning of a foreach-statement.  Note that
275*e4b17023SJohn Marino 		       this means you can't use 'in' for anything else
276*e4b17023SJohn Marino 		       in that context; in particular, in Objective-C
277*e4b17023SJohn Marino 		       you can't use 'in' as the name of the running
278*e4b17023SJohn Marino 		       variable in a C for loop.  We could potentially
279*e4b17023SJohn Marino 		       try to add code here to disambiguate, but it
280*e4b17023SJohn Marino 		       seems a reasonable limitation.  */
281*e4b17023SJohn Marino 		    token->type = CPP_KEYWORD;
282*e4b17023SJohn Marino 		    token->keyword = rid_code;
283*e4b17023SJohn Marino 		    break;
284*e4b17023SJohn Marino 		  }
285*e4b17023SJohn Marino 		/* Else, "pq" keywords outside of the "pq" context are
286*e4b17023SJohn Marino 		   not keywords, and we fall through to the code for
287*e4b17023SJohn Marino 		   normal tokens.  */
288*e4b17023SJohn Marino 	      }
289*e4b17023SJohn Marino 	    else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
290*e4b17023SJohn Marino 	      {
291*e4b17023SJohn Marino 		/* We found an Objective-C "property attribute"
292*e4b17023SJohn Marino 		   keyword (getter, setter, readonly, etc). These are
293*e4b17023SJohn Marino 		   only valid in the property context.  */
294*e4b17023SJohn Marino 		if (parser->objc_property_attr_context)
295*e4b17023SJohn Marino 		  {
296*e4b17023SJohn Marino 		    token->type = CPP_KEYWORD;
297*e4b17023SJohn Marino 		    token->keyword = rid_code;
298*e4b17023SJohn Marino 		    break;
299*e4b17023SJohn Marino 		  }
300*e4b17023SJohn Marino 		/* Else they are not special keywords.
301*e4b17023SJohn Marino 		*/
302*e4b17023SJohn Marino 	      }
303*e4b17023SJohn Marino 	    else if (c_dialect_objc ()
304*e4b17023SJohn Marino 		     && (OBJC_IS_AT_KEYWORD (rid_code)
305*e4b17023SJohn Marino 			 || OBJC_IS_CXX_KEYWORD (rid_code)))
306*e4b17023SJohn Marino 	      {
307*e4b17023SJohn Marino 		/* We found one of the Objective-C "@" keywords (defs,
308*e4b17023SJohn Marino 		   selector, synchronized, etc) or one of the
309*e4b17023SJohn Marino 		   Objective-C "cxx" keywords (class, private,
310*e4b17023SJohn Marino 		   protected, public, try, catch, throw) without a
311*e4b17023SJohn Marino 		   preceding '@' sign.  Do nothing and fall through to
312*e4b17023SJohn Marino 		   the code for normal tokens (in C++ we would still
313*e4b17023SJohn Marino 		   consider the CXX ones keywords, but not in C).  */
314*e4b17023SJohn Marino 		;
315*e4b17023SJohn Marino 	      }
316*e4b17023SJohn Marino 	    else
317*e4b17023SJohn Marino 	      {
318*e4b17023SJohn Marino 		token->type = CPP_KEYWORD;
319*e4b17023SJohn Marino 		token->keyword = rid_code;
320*e4b17023SJohn Marino 		break;
321*e4b17023SJohn Marino 	      }
322*e4b17023SJohn Marino 	  }
323*e4b17023SJohn Marino 
324*e4b17023SJohn Marino 	decl = lookup_name (token->value);
325*e4b17023SJohn Marino 	if (decl)
326*e4b17023SJohn Marino 	  {
327*e4b17023SJohn Marino 	    if (TREE_CODE (decl) == TYPE_DECL)
328*e4b17023SJohn Marino 	      {
329*e4b17023SJohn Marino 		token->id_kind = C_ID_TYPENAME;
330*e4b17023SJohn Marino 		break;
331*e4b17023SJohn Marino 	      }
332*e4b17023SJohn Marino 	  }
333*e4b17023SJohn Marino 	else if (c_dialect_objc ())
334*e4b17023SJohn Marino 	  {
335*e4b17023SJohn Marino 	    tree objc_interface_decl = objc_is_class_name (token->value);
336*e4b17023SJohn Marino 	    /* Objective-C class names are in the same namespace as
337*e4b17023SJohn Marino 	       variables and typedefs, and hence are shadowed by local
338*e4b17023SJohn Marino 	       declarations.  */
339*e4b17023SJohn Marino 	    if (objc_interface_decl
340*e4b17023SJohn Marino                 && (!objc_force_identifier || global_bindings_p ()))
341*e4b17023SJohn Marino 	      {
342*e4b17023SJohn Marino 		token->value = objc_interface_decl;
343*e4b17023SJohn Marino 		token->id_kind = C_ID_CLASSNAME;
344*e4b17023SJohn Marino 		break;
345*e4b17023SJohn Marino 	      }
346*e4b17023SJohn Marino 	  }
347*e4b17023SJohn Marino         token->id_kind = C_ID_ID;
348*e4b17023SJohn Marino       }
349*e4b17023SJohn Marino       break;
350*e4b17023SJohn Marino     case CPP_AT_NAME:
351*e4b17023SJohn Marino       /* This only happens in Objective-C; it must be a keyword.  */
352*e4b17023SJohn Marino       token->type = CPP_KEYWORD;
353*e4b17023SJohn Marino       switch (C_RID_CODE (token->value))
354*e4b17023SJohn Marino 	{
355*e4b17023SJohn Marino 	  /* Replace 'class' with '@class', 'private' with '@private',
356*e4b17023SJohn Marino 	     etc.  This prevents confusion with the C++ keyword
357*e4b17023SJohn Marino 	     'class', and makes the tokens consistent with other
358*e4b17023SJohn Marino 	     Objective-C 'AT' keywords.  For example '@class' is
359*e4b17023SJohn Marino 	     reported as RID_AT_CLASS which is consistent with
360*e4b17023SJohn Marino 	     '@synchronized', which is reported as
361*e4b17023SJohn Marino 	     RID_AT_SYNCHRONIZED.
362*e4b17023SJohn Marino 	  */
363*e4b17023SJohn Marino 	case RID_CLASS:     token->keyword = RID_AT_CLASS; break;
364*e4b17023SJohn Marino 	case RID_PRIVATE:   token->keyword = RID_AT_PRIVATE; break;
365*e4b17023SJohn Marino 	case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
366*e4b17023SJohn Marino 	case RID_PUBLIC:    token->keyword = RID_AT_PUBLIC; break;
367*e4b17023SJohn Marino 	case RID_THROW:     token->keyword = RID_AT_THROW; break;
368*e4b17023SJohn Marino 	case RID_TRY:       token->keyword = RID_AT_TRY; break;
369*e4b17023SJohn Marino 	case RID_CATCH:     token->keyword = RID_AT_CATCH; break;
370*e4b17023SJohn Marino 	default:            token->keyword = C_RID_CODE (token->value);
371*e4b17023SJohn Marino 	}
372*e4b17023SJohn Marino       break;
373*e4b17023SJohn Marino     case CPP_COLON:
374*e4b17023SJohn Marino     case CPP_COMMA:
375*e4b17023SJohn Marino     case CPP_CLOSE_PAREN:
376*e4b17023SJohn Marino     case CPP_SEMICOLON:
377*e4b17023SJohn Marino       /* These tokens may affect the interpretation of any identifiers
378*e4b17023SJohn Marino 	 following, if doing Objective-C.  */
379*e4b17023SJohn Marino       if (c_dialect_objc ())
380*e4b17023SJohn Marino 	parser->objc_need_raw_identifier = false;
381*e4b17023SJohn Marino       break;
382*e4b17023SJohn Marino     case CPP_PRAGMA:
383*e4b17023SJohn Marino       /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST.  */
384*e4b17023SJohn Marino       token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
385*e4b17023SJohn Marino       token->value = NULL;
386*e4b17023SJohn Marino       break;
387*e4b17023SJohn Marino     default:
388*e4b17023SJohn Marino       break;
389*e4b17023SJohn Marino     }
390*e4b17023SJohn Marino   timevar_pop (TV_LEX);
391*e4b17023SJohn Marino }
392*e4b17023SJohn Marino 
393*e4b17023SJohn Marino /* Return a pointer to the next token from PARSER, reading it in if
394*e4b17023SJohn Marino    necessary.  */
395*e4b17023SJohn Marino 
396*e4b17023SJohn Marino static inline c_token *
c_parser_peek_token(c_parser * parser)397*e4b17023SJohn Marino c_parser_peek_token (c_parser *parser)
398*e4b17023SJohn Marino {
399*e4b17023SJohn Marino   if (parser->tokens_avail == 0)
400*e4b17023SJohn Marino     {
401*e4b17023SJohn Marino       c_lex_one_token (parser, &parser->tokens[0]);
402*e4b17023SJohn Marino       parser->tokens_avail = 1;
403*e4b17023SJohn Marino     }
404*e4b17023SJohn Marino   return &parser->tokens[0];
405*e4b17023SJohn Marino }
406*e4b17023SJohn Marino 
407*e4b17023SJohn Marino /* Return true if the next token from PARSER has the indicated
408*e4b17023SJohn Marino    TYPE.  */
409*e4b17023SJohn Marino 
410*e4b17023SJohn Marino static inline bool
c_parser_next_token_is(c_parser * parser,enum cpp_ttype type)411*e4b17023SJohn Marino c_parser_next_token_is (c_parser *parser, enum cpp_ttype type)
412*e4b17023SJohn Marino {
413*e4b17023SJohn Marino   return c_parser_peek_token (parser)->type == type;
414*e4b17023SJohn Marino }
415*e4b17023SJohn Marino 
416*e4b17023SJohn Marino /* Return true if the next token from PARSER does not have the
417*e4b17023SJohn Marino    indicated TYPE.  */
418*e4b17023SJohn Marino 
419*e4b17023SJohn Marino static inline bool
c_parser_next_token_is_not(c_parser * parser,enum cpp_ttype type)420*e4b17023SJohn Marino c_parser_next_token_is_not (c_parser *parser, enum cpp_ttype type)
421*e4b17023SJohn Marino {
422*e4b17023SJohn Marino   return !c_parser_next_token_is (parser, type);
423*e4b17023SJohn Marino }
424*e4b17023SJohn Marino 
425*e4b17023SJohn Marino /* Return true if the next token from PARSER is the indicated
426*e4b17023SJohn Marino    KEYWORD.  */
427*e4b17023SJohn Marino 
428*e4b17023SJohn Marino static inline bool
c_parser_next_token_is_keyword(c_parser * parser,enum rid keyword)429*e4b17023SJohn Marino c_parser_next_token_is_keyword (c_parser *parser, enum rid keyword)
430*e4b17023SJohn Marino {
431*e4b17023SJohn Marino   return c_parser_peek_token (parser)->keyword == keyword;
432*e4b17023SJohn Marino }
433*e4b17023SJohn Marino 
434*e4b17023SJohn Marino /* Return a pointer to the next-but-one token from PARSER, reading it
435*e4b17023SJohn Marino    in if necessary.  The next token is already read in.  */
436*e4b17023SJohn Marino 
437*e4b17023SJohn Marino static c_token *
c_parser_peek_2nd_token(c_parser * parser)438*e4b17023SJohn Marino c_parser_peek_2nd_token (c_parser *parser)
439*e4b17023SJohn Marino {
440*e4b17023SJohn Marino   if (parser->tokens_avail >= 2)
441*e4b17023SJohn Marino     return &parser->tokens[1];
442*e4b17023SJohn Marino   gcc_assert (parser->tokens_avail == 1);
443*e4b17023SJohn Marino   gcc_assert (parser->tokens[0].type != CPP_EOF);
444*e4b17023SJohn Marino   gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
445*e4b17023SJohn Marino   c_lex_one_token (parser, &parser->tokens[1]);
446*e4b17023SJohn Marino   parser->tokens_avail = 2;
447*e4b17023SJohn Marino   return &parser->tokens[1];
448*e4b17023SJohn Marino }
449*e4b17023SJohn Marino 
450*e4b17023SJohn Marino /* Return true if TOKEN can start a type name,
451*e4b17023SJohn Marino    false otherwise.  */
452*e4b17023SJohn Marino static bool
c_token_starts_typename(c_token * token)453*e4b17023SJohn Marino c_token_starts_typename (c_token *token)
454*e4b17023SJohn Marino {
455*e4b17023SJohn Marino   switch (token->type)
456*e4b17023SJohn Marino     {
457*e4b17023SJohn Marino     case CPP_NAME:
458*e4b17023SJohn Marino       switch (token->id_kind)
459*e4b17023SJohn Marino 	{
460*e4b17023SJohn Marino 	case C_ID_ID:
461*e4b17023SJohn Marino 	  return false;
462*e4b17023SJohn Marino 	case C_ID_ADDRSPACE:
463*e4b17023SJohn Marino 	  return true;
464*e4b17023SJohn Marino 	case C_ID_TYPENAME:
465*e4b17023SJohn Marino 	  return true;
466*e4b17023SJohn Marino 	case C_ID_CLASSNAME:
467*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
468*e4b17023SJohn Marino 	  return true;
469*e4b17023SJohn Marino 	default:
470*e4b17023SJohn Marino 	  gcc_unreachable ();
471*e4b17023SJohn Marino 	}
472*e4b17023SJohn Marino     case CPP_KEYWORD:
473*e4b17023SJohn Marino       switch (token->keyword)
474*e4b17023SJohn Marino 	{
475*e4b17023SJohn Marino 	case RID_UNSIGNED:
476*e4b17023SJohn Marino 	case RID_LONG:
477*e4b17023SJohn Marino 	case RID_INT128:
478*e4b17023SJohn Marino 	case RID_SHORT:
479*e4b17023SJohn Marino 	case RID_SIGNED:
480*e4b17023SJohn Marino 	case RID_COMPLEX:
481*e4b17023SJohn Marino 	case RID_INT:
482*e4b17023SJohn Marino 	case RID_CHAR:
483*e4b17023SJohn Marino 	case RID_FLOAT:
484*e4b17023SJohn Marino 	case RID_DOUBLE:
485*e4b17023SJohn Marino 	case RID_VOID:
486*e4b17023SJohn Marino 	case RID_DFLOAT32:
487*e4b17023SJohn Marino 	case RID_DFLOAT64:
488*e4b17023SJohn Marino 	case RID_DFLOAT128:
489*e4b17023SJohn Marino 	case RID_BOOL:
490*e4b17023SJohn Marino 	case RID_ENUM:
491*e4b17023SJohn Marino 	case RID_STRUCT:
492*e4b17023SJohn Marino 	case RID_UNION:
493*e4b17023SJohn Marino 	case RID_TYPEOF:
494*e4b17023SJohn Marino 	case RID_CONST:
495*e4b17023SJohn Marino 	case RID_VOLATILE:
496*e4b17023SJohn Marino 	case RID_RESTRICT:
497*e4b17023SJohn Marino 	case RID_ATTRIBUTE:
498*e4b17023SJohn Marino 	case RID_FRACT:
499*e4b17023SJohn Marino 	case RID_ACCUM:
500*e4b17023SJohn Marino 	case RID_SAT:
501*e4b17023SJohn Marino 	  return true;
502*e4b17023SJohn Marino 	default:
503*e4b17023SJohn Marino 	  return false;
504*e4b17023SJohn Marino 	}
505*e4b17023SJohn Marino     case CPP_LESS:
506*e4b17023SJohn Marino       if (c_dialect_objc ())
507*e4b17023SJohn Marino 	return true;
508*e4b17023SJohn Marino       return false;
509*e4b17023SJohn Marino     default:
510*e4b17023SJohn Marino       return false;
511*e4b17023SJohn Marino     }
512*e4b17023SJohn Marino }
513*e4b17023SJohn Marino 
514*e4b17023SJohn Marino enum c_lookahead_kind {
515*e4b17023SJohn Marino   /* Always treat unknown identifiers as typenames.  */
516*e4b17023SJohn Marino   cla_prefer_type,
517*e4b17023SJohn Marino 
518*e4b17023SJohn Marino   /* Could be parsing a nonabstract declarator.  Only treat an identifier
519*e4b17023SJohn Marino      as a typename if followed by another identifier or a star.  */
520*e4b17023SJohn Marino   cla_nonabstract_decl,
521*e4b17023SJohn Marino 
522*e4b17023SJohn Marino   /* Never treat identifiers as typenames.  */
523*e4b17023SJohn Marino   cla_prefer_id
524*e4b17023SJohn Marino };
525*e4b17023SJohn Marino 
526*e4b17023SJohn Marino /* Return true if the next token from PARSER can start a type name,
527*e4b17023SJohn Marino    false otherwise.  LA specifies how to do lookahead in order to
528*e4b17023SJohn Marino    detect unknown type names.  If unsure, pick CLA_PREFER_ID.  */
529*e4b17023SJohn Marino 
530*e4b17023SJohn Marino static inline bool
c_parser_next_tokens_start_typename(c_parser * parser,enum c_lookahead_kind la)531*e4b17023SJohn Marino c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
532*e4b17023SJohn Marino {
533*e4b17023SJohn Marino   c_token *token = c_parser_peek_token (parser);
534*e4b17023SJohn Marino   if (c_token_starts_typename (token))
535*e4b17023SJohn Marino     return true;
536*e4b17023SJohn Marino 
537*e4b17023SJohn Marino   /* Try a bit harder to detect an unknown typename.  */
538*e4b17023SJohn Marino   if (la != cla_prefer_id
539*e4b17023SJohn Marino       && token->type == CPP_NAME
540*e4b17023SJohn Marino       && token->id_kind == C_ID_ID
541*e4b17023SJohn Marino 
542*e4b17023SJohn Marino       /* Do not try too hard when we could have "object in array".  */
543*e4b17023SJohn Marino       && !parser->objc_could_be_foreach_context
544*e4b17023SJohn Marino 
545*e4b17023SJohn Marino       && (la == cla_prefer_type
546*e4b17023SJohn Marino 	  || c_parser_peek_2nd_token (parser)->type == CPP_NAME
547*e4b17023SJohn Marino 	  || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
548*e4b17023SJohn Marino 
549*e4b17023SJohn Marino       /* Only unknown identifiers.  */
550*e4b17023SJohn Marino       && !lookup_name (token->value))
551*e4b17023SJohn Marino     return true;
552*e4b17023SJohn Marino 
553*e4b17023SJohn Marino   return false;
554*e4b17023SJohn Marino }
555*e4b17023SJohn Marino 
556*e4b17023SJohn Marino /* Return true if TOKEN is a type qualifier, false otherwise.  */
557*e4b17023SJohn Marino static bool
c_token_is_qualifier(c_token * token)558*e4b17023SJohn Marino c_token_is_qualifier (c_token *token)
559*e4b17023SJohn Marino {
560*e4b17023SJohn Marino   switch (token->type)
561*e4b17023SJohn Marino     {
562*e4b17023SJohn Marino     case CPP_NAME:
563*e4b17023SJohn Marino       switch (token->id_kind)
564*e4b17023SJohn Marino 	{
565*e4b17023SJohn Marino 	case C_ID_ADDRSPACE:
566*e4b17023SJohn Marino 	  return true;
567*e4b17023SJohn Marino 	default:
568*e4b17023SJohn Marino 	  return false;
569*e4b17023SJohn Marino 	}
570*e4b17023SJohn Marino     case CPP_KEYWORD:
571*e4b17023SJohn Marino       switch (token->keyword)
572*e4b17023SJohn Marino 	{
573*e4b17023SJohn Marino 	case RID_CONST:
574*e4b17023SJohn Marino 	case RID_VOLATILE:
575*e4b17023SJohn Marino 	case RID_RESTRICT:
576*e4b17023SJohn Marino 	case RID_ATTRIBUTE:
577*e4b17023SJohn Marino 	  return true;
578*e4b17023SJohn Marino 	default:
579*e4b17023SJohn Marino 	  return false;
580*e4b17023SJohn Marino 	}
581*e4b17023SJohn Marino     case CPP_LESS:
582*e4b17023SJohn Marino       return false;
583*e4b17023SJohn Marino     default:
584*e4b17023SJohn Marino       gcc_unreachable ();
585*e4b17023SJohn Marino     }
586*e4b17023SJohn Marino }
587*e4b17023SJohn Marino 
588*e4b17023SJohn Marino /* Return true if the next token from PARSER is a type qualifier,
589*e4b17023SJohn Marino    false otherwise.  */
590*e4b17023SJohn Marino static inline bool
c_parser_next_token_is_qualifier(c_parser * parser)591*e4b17023SJohn Marino c_parser_next_token_is_qualifier (c_parser *parser)
592*e4b17023SJohn Marino {
593*e4b17023SJohn Marino   c_token *token = c_parser_peek_token (parser);
594*e4b17023SJohn Marino   return c_token_is_qualifier (token);
595*e4b17023SJohn Marino }
596*e4b17023SJohn Marino 
597*e4b17023SJohn Marino /* Return true if TOKEN can start declaration specifiers, false
598*e4b17023SJohn Marino    otherwise.  */
599*e4b17023SJohn Marino static bool
c_token_starts_declspecs(c_token * token)600*e4b17023SJohn Marino c_token_starts_declspecs (c_token *token)
601*e4b17023SJohn Marino {
602*e4b17023SJohn Marino   switch (token->type)
603*e4b17023SJohn Marino     {
604*e4b17023SJohn Marino     case CPP_NAME:
605*e4b17023SJohn Marino       switch (token->id_kind)
606*e4b17023SJohn Marino 	{
607*e4b17023SJohn Marino 	case C_ID_ID:
608*e4b17023SJohn Marino 	  return false;
609*e4b17023SJohn Marino 	case C_ID_ADDRSPACE:
610*e4b17023SJohn Marino 	  return true;
611*e4b17023SJohn Marino 	case C_ID_TYPENAME:
612*e4b17023SJohn Marino 	  return true;
613*e4b17023SJohn Marino 	case C_ID_CLASSNAME:
614*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
615*e4b17023SJohn Marino 	  return true;
616*e4b17023SJohn Marino 	default:
617*e4b17023SJohn Marino 	  gcc_unreachable ();
618*e4b17023SJohn Marino 	}
619*e4b17023SJohn Marino     case CPP_KEYWORD:
620*e4b17023SJohn Marino       switch (token->keyword)
621*e4b17023SJohn Marino 	{
622*e4b17023SJohn Marino 	case RID_STATIC:
623*e4b17023SJohn Marino 	case RID_EXTERN:
624*e4b17023SJohn Marino 	case RID_REGISTER:
625*e4b17023SJohn Marino 	case RID_TYPEDEF:
626*e4b17023SJohn Marino 	case RID_INLINE:
627*e4b17023SJohn Marino 	case RID_NORETURN:
628*e4b17023SJohn Marino 	case RID_AUTO:
629*e4b17023SJohn Marino 	case RID_THREAD:
630*e4b17023SJohn Marino 	case RID_UNSIGNED:
631*e4b17023SJohn Marino 	case RID_LONG:
632*e4b17023SJohn Marino 	case RID_INT128:
633*e4b17023SJohn Marino 	case RID_SHORT:
634*e4b17023SJohn Marino 	case RID_SIGNED:
635*e4b17023SJohn Marino 	case RID_COMPLEX:
636*e4b17023SJohn Marino 	case RID_INT:
637*e4b17023SJohn Marino 	case RID_CHAR:
638*e4b17023SJohn Marino 	case RID_FLOAT:
639*e4b17023SJohn Marino 	case RID_DOUBLE:
640*e4b17023SJohn Marino 	case RID_VOID:
641*e4b17023SJohn Marino 	case RID_DFLOAT32:
642*e4b17023SJohn Marino 	case RID_DFLOAT64:
643*e4b17023SJohn Marino 	case RID_DFLOAT128:
644*e4b17023SJohn Marino 	case RID_BOOL:
645*e4b17023SJohn Marino 	case RID_ENUM:
646*e4b17023SJohn Marino 	case RID_STRUCT:
647*e4b17023SJohn Marino 	case RID_UNION:
648*e4b17023SJohn Marino 	case RID_TYPEOF:
649*e4b17023SJohn Marino 	case RID_CONST:
650*e4b17023SJohn Marino 	case RID_VOLATILE:
651*e4b17023SJohn Marino 	case RID_RESTRICT:
652*e4b17023SJohn Marino 	case RID_ATTRIBUTE:
653*e4b17023SJohn Marino 	case RID_FRACT:
654*e4b17023SJohn Marino 	case RID_ACCUM:
655*e4b17023SJohn Marino 	case RID_SAT:
656*e4b17023SJohn Marino 	case RID_ALIGNAS:
657*e4b17023SJohn Marino 	  return true;
658*e4b17023SJohn Marino 	default:
659*e4b17023SJohn Marino 	  return false;
660*e4b17023SJohn Marino 	}
661*e4b17023SJohn Marino     case CPP_LESS:
662*e4b17023SJohn Marino       if (c_dialect_objc ())
663*e4b17023SJohn Marino 	return true;
664*e4b17023SJohn Marino       return false;
665*e4b17023SJohn Marino     default:
666*e4b17023SJohn Marino       return false;
667*e4b17023SJohn Marino     }
668*e4b17023SJohn Marino }
669*e4b17023SJohn Marino 
670*e4b17023SJohn Marino 
671*e4b17023SJohn Marino /* Return true if TOKEN can start declaration specifiers or a static
672*e4b17023SJohn Marino    assertion, false otherwise.  */
673*e4b17023SJohn Marino static bool
c_token_starts_declaration(c_token * token)674*e4b17023SJohn Marino c_token_starts_declaration (c_token *token)
675*e4b17023SJohn Marino {
676*e4b17023SJohn Marino   if (c_token_starts_declspecs (token)
677*e4b17023SJohn Marino       || token->keyword == RID_STATIC_ASSERT)
678*e4b17023SJohn Marino     return true;
679*e4b17023SJohn Marino   else
680*e4b17023SJohn Marino     return false;
681*e4b17023SJohn Marino }
682*e4b17023SJohn Marino 
683*e4b17023SJohn Marino /* Return true if the next token from PARSER can start declaration
684*e4b17023SJohn Marino    specifiers, false otherwise.  */
685*e4b17023SJohn Marino static inline bool
c_parser_next_token_starts_declspecs(c_parser * parser)686*e4b17023SJohn Marino c_parser_next_token_starts_declspecs (c_parser *parser)
687*e4b17023SJohn Marino {
688*e4b17023SJohn Marino   c_token *token = c_parser_peek_token (parser);
689*e4b17023SJohn Marino 
690*e4b17023SJohn Marino   /* In Objective-C, a classname normally starts a declspecs unless it
691*e4b17023SJohn Marino      is immediately followed by a dot.  In that case, it is the
692*e4b17023SJohn Marino      Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
693*e4b17023SJohn Marino      setter/getter on the class.  c_token_starts_declspecs() can't
694*e4b17023SJohn Marino      differentiate between the two cases because it only checks the
695*e4b17023SJohn Marino      current token, so we have a special check here.  */
696*e4b17023SJohn Marino   if (c_dialect_objc ()
697*e4b17023SJohn Marino       && token->type == CPP_NAME
698*e4b17023SJohn Marino       && token->id_kind == C_ID_CLASSNAME
699*e4b17023SJohn Marino       && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
700*e4b17023SJohn Marino     return false;
701*e4b17023SJohn Marino 
702*e4b17023SJohn Marino   return c_token_starts_declspecs (token);
703*e4b17023SJohn Marino }
704*e4b17023SJohn Marino 
705*e4b17023SJohn Marino /* Return true if the next tokens from PARSER can start declaration
706*e4b17023SJohn Marino    specifiers or a static assertion, false otherwise.  */
707*e4b17023SJohn Marino static inline bool
c_parser_next_tokens_start_declaration(c_parser * parser)708*e4b17023SJohn Marino c_parser_next_tokens_start_declaration (c_parser *parser)
709*e4b17023SJohn Marino {
710*e4b17023SJohn Marino   c_token *token = c_parser_peek_token (parser);
711*e4b17023SJohn Marino 
712*e4b17023SJohn Marino   /* Same as above.  */
713*e4b17023SJohn Marino   if (c_dialect_objc ()
714*e4b17023SJohn Marino       && token->type == CPP_NAME
715*e4b17023SJohn Marino       && token->id_kind == C_ID_CLASSNAME
716*e4b17023SJohn Marino       && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
717*e4b17023SJohn Marino     return false;
718*e4b17023SJohn Marino 
719*e4b17023SJohn Marino   /* Labels do not start declarations.  */
720*e4b17023SJohn Marino   if (token->type == CPP_NAME
721*e4b17023SJohn Marino       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
722*e4b17023SJohn Marino     return false;
723*e4b17023SJohn Marino 
724*e4b17023SJohn Marino   if (c_token_starts_declaration (token))
725*e4b17023SJohn Marino     return true;
726*e4b17023SJohn Marino 
727*e4b17023SJohn Marino   if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
728*e4b17023SJohn Marino     return true;
729*e4b17023SJohn Marino 
730*e4b17023SJohn Marino   return false;
731*e4b17023SJohn Marino }
732*e4b17023SJohn Marino 
733*e4b17023SJohn Marino /* Consume the next token from PARSER.  */
734*e4b17023SJohn Marino 
735*e4b17023SJohn Marino static void
c_parser_consume_token(c_parser * parser)736*e4b17023SJohn Marino c_parser_consume_token (c_parser *parser)
737*e4b17023SJohn Marino {
738*e4b17023SJohn Marino   gcc_assert (parser->tokens_avail >= 1);
739*e4b17023SJohn Marino   gcc_assert (parser->tokens[0].type != CPP_EOF);
740*e4b17023SJohn Marino   gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
741*e4b17023SJohn Marino   gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
742*e4b17023SJohn Marino   if (parser->tokens_avail == 2)
743*e4b17023SJohn Marino     parser->tokens[0] = parser->tokens[1];
744*e4b17023SJohn Marino   parser->tokens_avail--;
745*e4b17023SJohn Marino }
746*e4b17023SJohn Marino 
747*e4b17023SJohn Marino /* Expect the current token to be a #pragma.  Consume it and remember
748*e4b17023SJohn Marino    that we've begun parsing a pragma.  */
749*e4b17023SJohn Marino 
750*e4b17023SJohn Marino static void
c_parser_consume_pragma(c_parser * parser)751*e4b17023SJohn Marino c_parser_consume_pragma (c_parser *parser)
752*e4b17023SJohn Marino {
753*e4b17023SJohn Marino   gcc_assert (!parser->in_pragma);
754*e4b17023SJohn Marino   gcc_assert (parser->tokens_avail >= 1);
755*e4b17023SJohn Marino   gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
756*e4b17023SJohn Marino   if (parser->tokens_avail == 2)
757*e4b17023SJohn Marino     parser->tokens[0] = parser->tokens[1];
758*e4b17023SJohn Marino   parser->tokens_avail--;
759*e4b17023SJohn Marino   parser->in_pragma = true;
760*e4b17023SJohn Marino }
761*e4b17023SJohn Marino 
762*e4b17023SJohn Marino /* Update the globals input_location and in_system_header from
763*e4b17023SJohn Marino    TOKEN.  */
764*e4b17023SJohn Marino static inline void
c_parser_set_source_position_from_token(c_token * token)765*e4b17023SJohn Marino c_parser_set_source_position_from_token (c_token *token)
766*e4b17023SJohn Marino {
767*e4b17023SJohn Marino   if (token->type != CPP_EOF)
768*e4b17023SJohn Marino     {
769*e4b17023SJohn Marino       input_location = token->location;
770*e4b17023SJohn Marino     }
771*e4b17023SJohn Marino }
772*e4b17023SJohn Marino 
773*e4b17023SJohn Marino /* Issue a diagnostic of the form
774*e4b17023SJohn Marino       FILE:LINE: MESSAGE before TOKEN
775*e4b17023SJohn Marino    where TOKEN is the next token in the input stream of PARSER.
776*e4b17023SJohn Marino    MESSAGE (specified by the caller) is usually of the form "expected
777*e4b17023SJohn Marino    OTHER-TOKEN".
778*e4b17023SJohn Marino 
779*e4b17023SJohn Marino    Do not issue a diagnostic if still recovering from an error.
780*e4b17023SJohn Marino 
781*e4b17023SJohn Marino    ??? This is taken from the C++ parser, but building up messages in
782*e4b17023SJohn Marino    this way is not i18n-friendly and some other approach should be
783*e4b17023SJohn Marino    used.  */
784*e4b17023SJohn Marino 
785*e4b17023SJohn Marino static void
c_parser_error(c_parser * parser,const char * gmsgid)786*e4b17023SJohn Marino c_parser_error (c_parser *parser, const char *gmsgid)
787*e4b17023SJohn Marino {
788*e4b17023SJohn Marino   c_token *token = c_parser_peek_token (parser);
789*e4b17023SJohn Marino   if (parser->error)
790*e4b17023SJohn Marino     return;
791*e4b17023SJohn Marino   parser->error = true;
792*e4b17023SJohn Marino   if (!gmsgid)
793*e4b17023SJohn Marino     return;
794*e4b17023SJohn Marino   /* This diagnostic makes more sense if it is tagged to the line of
795*e4b17023SJohn Marino      the token we just peeked at.  */
796*e4b17023SJohn Marino   c_parser_set_source_position_from_token (token);
797*e4b17023SJohn Marino   c_parse_error (gmsgid,
798*e4b17023SJohn Marino 		 /* Because c_parse_error does not understand
799*e4b17023SJohn Marino 		    CPP_KEYWORD, keywords are treated like
800*e4b17023SJohn Marino 		    identifiers.  */
801*e4b17023SJohn Marino 		 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
802*e4b17023SJohn Marino 		 /* ??? The C parser does not save the cpp flags of a
803*e4b17023SJohn Marino 		    token, we need to pass 0 here and we will not get
804*e4b17023SJohn Marino 		    the source spelling of some tokens but rather the
805*e4b17023SJohn Marino 		    canonical spelling.  */
806*e4b17023SJohn Marino 		 token->value, /*flags=*/0);
807*e4b17023SJohn Marino }
808*e4b17023SJohn Marino 
809*e4b17023SJohn Marino /* If the next token is of the indicated TYPE, consume it.  Otherwise,
810*e4b17023SJohn Marino    issue the error MSGID.  If MSGID is NULL then a message has already
811*e4b17023SJohn Marino    been produced and no message will be produced this time.  Returns
812*e4b17023SJohn Marino    true if found, false otherwise.  */
813*e4b17023SJohn Marino 
814*e4b17023SJohn Marino static bool
c_parser_require(c_parser * parser,enum cpp_ttype type,const char * msgid)815*e4b17023SJohn Marino c_parser_require (c_parser *parser,
816*e4b17023SJohn Marino 		  enum cpp_ttype type,
817*e4b17023SJohn Marino 		  const char *msgid)
818*e4b17023SJohn Marino {
819*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, type))
820*e4b17023SJohn Marino     {
821*e4b17023SJohn Marino       c_parser_consume_token (parser);
822*e4b17023SJohn Marino       return true;
823*e4b17023SJohn Marino     }
824*e4b17023SJohn Marino   else
825*e4b17023SJohn Marino     {
826*e4b17023SJohn Marino       c_parser_error (parser, msgid);
827*e4b17023SJohn Marino       return false;
828*e4b17023SJohn Marino     }
829*e4b17023SJohn Marino }
830*e4b17023SJohn Marino 
831*e4b17023SJohn Marino /* If the next token is the indicated keyword, consume it.  Otherwise,
832*e4b17023SJohn Marino    issue the error MSGID.  Returns true if found, false otherwise.  */
833*e4b17023SJohn Marino 
834*e4b17023SJohn Marino static bool
c_parser_require_keyword(c_parser * parser,enum rid keyword,const char * msgid)835*e4b17023SJohn Marino c_parser_require_keyword (c_parser *parser,
836*e4b17023SJohn Marino 			  enum rid keyword,
837*e4b17023SJohn Marino 			  const char *msgid)
838*e4b17023SJohn Marino {
839*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, keyword))
840*e4b17023SJohn Marino     {
841*e4b17023SJohn Marino       c_parser_consume_token (parser);
842*e4b17023SJohn Marino       return true;
843*e4b17023SJohn Marino     }
844*e4b17023SJohn Marino   else
845*e4b17023SJohn Marino     {
846*e4b17023SJohn Marino       c_parser_error (parser, msgid);
847*e4b17023SJohn Marino       return false;
848*e4b17023SJohn Marino     }
849*e4b17023SJohn Marino }
850*e4b17023SJohn Marino 
851*e4b17023SJohn Marino /* Like c_parser_require, except that tokens will be skipped until the
852*e4b17023SJohn Marino    desired token is found.  An error message is still produced if the
853*e4b17023SJohn Marino    next token is not as expected.  If MSGID is NULL then a message has
854*e4b17023SJohn Marino    already been produced and no message will be produced this
855*e4b17023SJohn Marino    time.  */
856*e4b17023SJohn Marino 
857*e4b17023SJohn Marino static void
c_parser_skip_until_found(c_parser * parser,enum cpp_ttype type,const char * msgid)858*e4b17023SJohn Marino c_parser_skip_until_found (c_parser *parser,
859*e4b17023SJohn Marino 			   enum cpp_ttype type,
860*e4b17023SJohn Marino 			   const char *msgid)
861*e4b17023SJohn Marino {
862*e4b17023SJohn Marino   unsigned nesting_depth = 0;
863*e4b17023SJohn Marino 
864*e4b17023SJohn Marino   if (c_parser_require (parser, type, msgid))
865*e4b17023SJohn Marino     return;
866*e4b17023SJohn Marino 
867*e4b17023SJohn Marino   /* Skip tokens until the desired token is found.  */
868*e4b17023SJohn Marino   while (true)
869*e4b17023SJohn Marino     {
870*e4b17023SJohn Marino       /* Peek at the next token.  */
871*e4b17023SJohn Marino       c_token *token = c_parser_peek_token (parser);
872*e4b17023SJohn Marino       /* If we've reached the token we want, consume it and stop.  */
873*e4b17023SJohn Marino       if (token->type == type && !nesting_depth)
874*e4b17023SJohn Marino 	{
875*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
876*e4b17023SJohn Marino 	  break;
877*e4b17023SJohn Marino 	}
878*e4b17023SJohn Marino 
879*e4b17023SJohn Marino       /* If we've run out of tokens, stop.  */
880*e4b17023SJohn Marino       if (token->type == CPP_EOF)
881*e4b17023SJohn Marino 	return;
882*e4b17023SJohn Marino       if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
883*e4b17023SJohn Marino 	return;
884*e4b17023SJohn Marino       if (token->type == CPP_OPEN_BRACE
885*e4b17023SJohn Marino 	  || token->type == CPP_OPEN_PAREN
886*e4b17023SJohn Marino 	  || token->type == CPP_OPEN_SQUARE)
887*e4b17023SJohn Marino 	++nesting_depth;
888*e4b17023SJohn Marino       else if (token->type == CPP_CLOSE_BRACE
889*e4b17023SJohn Marino 	       || token->type == CPP_CLOSE_PAREN
890*e4b17023SJohn Marino 	       || token->type == CPP_CLOSE_SQUARE)
891*e4b17023SJohn Marino 	{
892*e4b17023SJohn Marino 	  if (nesting_depth-- == 0)
893*e4b17023SJohn Marino 	    break;
894*e4b17023SJohn Marino 	}
895*e4b17023SJohn Marino       /* Consume this token.  */
896*e4b17023SJohn Marino       c_parser_consume_token (parser);
897*e4b17023SJohn Marino     }
898*e4b17023SJohn Marino   parser->error = false;
899*e4b17023SJohn Marino }
900*e4b17023SJohn Marino 
901*e4b17023SJohn Marino /* Skip tokens until the end of a parameter is found, but do not
902*e4b17023SJohn Marino    consume the comma, semicolon or closing delimiter.  */
903*e4b17023SJohn Marino 
904*e4b17023SJohn Marino static void
c_parser_skip_to_end_of_parameter(c_parser * parser)905*e4b17023SJohn Marino c_parser_skip_to_end_of_parameter (c_parser *parser)
906*e4b17023SJohn Marino {
907*e4b17023SJohn Marino   unsigned nesting_depth = 0;
908*e4b17023SJohn Marino 
909*e4b17023SJohn Marino   while (true)
910*e4b17023SJohn Marino     {
911*e4b17023SJohn Marino       c_token *token = c_parser_peek_token (parser);
912*e4b17023SJohn Marino       if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
913*e4b17023SJohn Marino 	  && !nesting_depth)
914*e4b17023SJohn Marino 	break;
915*e4b17023SJohn Marino       /* If we've run out of tokens, stop.  */
916*e4b17023SJohn Marino       if (token->type == CPP_EOF)
917*e4b17023SJohn Marino 	return;
918*e4b17023SJohn Marino       if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
919*e4b17023SJohn Marino 	return;
920*e4b17023SJohn Marino       if (token->type == CPP_OPEN_BRACE
921*e4b17023SJohn Marino 	  || token->type == CPP_OPEN_PAREN
922*e4b17023SJohn Marino 	  || token->type == CPP_OPEN_SQUARE)
923*e4b17023SJohn Marino 	++nesting_depth;
924*e4b17023SJohn Marino       else if (token->type == CPP_CLOSE_BRACE
925*e4b17023SJohn Marino 	       || token->type == CPP_CLOSE_PAREN
926*e4b17023SJohn Marino 	       || token->type == CPP_CLOSE_SQUARE)
927*e4b17023SJohn Marino 	{
928*e4b17023SJohn Marino 	  if (nesting_depth-- == 0)
929*e4b17023SJohn Marino 	    break;
930*e4b17023SJohn Marino 	}
931*e4b17023SJohn Marino       /* Consume this token.  */
932*e4b17023SJohn Marino       c_parser_consume_token (parser);
933*e4b17023SJohn Marino     }
934*e4b17023SJohn Marino   parser->error = false;
935*e4b17023SJohn Marino }
936*e4b17023SJohn Marino 
937*e4b17023SJohn Marino /* Expect to be at the end of the pragma directive and consume an
938*e4b17023SJohn Marino    end of line marker.  */
939*e4b17023SJohn Marino 
940*e4b17023SJohn Marino static void
c_parser_skip_to_pragma_eol(c_parser * parser)941*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (c_parser *parser)
942*e4b17023SJohn Marino {
943*e4b17023SJohn Marino   gcc_assert (parser->in_pragma);
944*e4b17023SJohn Marino   parser->in_pragma = false;
945*e4b17023SJohn Marino 
946*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_PRAGMA_EOL, "expected end of line"))
947*e4b17023SJohn Marino     while (true)
948*e4b17023SJohn Marino       {
949*e4b17023SJohn Marino 	c_token *token = c_parser_peek_token (parser);
950*e4b17023SJohn Marino 	if (token->type == CPP_EOF)
951*e4b17023SJohn Marino 	  break;
952*e4b17023SJohn Marino 	if (token->type == CPP_PRAGMA_EOL)
953*e4b17023SJohn Marino 	  {
954*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
955*e4b17023SJohn Marino 	    break;
956*e4b17023SJohn Marino 	  }
957*e4b17023SJohn Marino 	c_parser_consume_token (parser);
958*e4b17023SJohn Marino       }
959*e4b17023SJohn Marino 
960*e4b17023SJohn Marino   parser->error = false;
961*e4b17023SJohn Marino }
962*e4b17023SJohn Marino 
963*e4b17023SJohn Marino /* Skip tokens until we have consumed an entire block, or until we
964*e4b17023SJohn Marino    have consumed a non-nested ';'.  */
965*e4b17023SJohn Marino 
966*e4b17023SJohn Marino static void
c_parser_skip_to_end_of_block_or_statement(c_parser * parser)967*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
968*e4b17023SJohn Marino {
969*e4b17023SJohn Marino   unsigned nesting_depth = 0;
970*e4b17023SJohn Marino   bool save_error = parser->error;
971*e4b17023SJohn Marino 
972*e4b17023SJohn Marino   while (true)
973*e4b17023SJohn Marino     {
974*e4b17023SJohn Marino       c_token *token;
975*e4b17023SJohn Marino 
976*e4b17023SJohn Marino       /* Peek at the next token.  */
977*e4b17023SJohn Marino       token = c_parser_peek_token (parser);
978*e4b17023SJohn Marino 
979*e4b17023SJohn Marino       switch (token->type)
980*e4b17023SJohn Marino 	{
981*e4b17023SJohn Marino 	case CPP_EOF:
982*e4b17023SJohn Marino 	  return;
983*e4b17023SJohn Marino 
984*e4b17023SJohn Marino 	case CPP_PRAGMA_EOL:
985*e4b17023SJohn Marino 	  if (parser->in_pragma)
986*e4b17023SJohn Marino 	    return;
987*e4b17023SJohn Marino 	  break;
988*e4b17023SJohn Marino 
989*e4b17023SJohn Marino 	case CPP_SEMICOLON:
990*e4b17023SJohn Marino 	  /* If the next token is a ';', we have reached the
991*e4b17023SJohn Marino 	     end of the statement.  */
992*e4b17023SJohn Marino 	  if (!nesting_depth)
993*e4b17023SJohn Marino 	    {
994*e4b17023SJohn Marino 	      /* Consume the ';'.  */
995*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
996*e4b17023SJohn Marino 	      goto finished;
997*e4b17023SJohn Marino 	    }
998*e4b17023SJohn Marino 	  break;
999*e4b17023SJohn Marino 
1000*e4b17023SJohn Marino 	case CPP_CLOSE_BRACE:
1001*e4b17023SJohn Marino 	  /* If the next token is a non-nested '}', then we have
1002*e4b17023SJohn Marino 	     reached the end of the current block.  */
1003*e4b17023SJohn Marino 	  if (nesting_depth == 0 || --nesting_depth == 0)
1004*e4b17023SJohn Marino 	    {
1005*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
1006*e4b17023SJohn Marino 	      goto finished;
1007*e4b17023SJohn Marino 	    }
1008*e4b17023SJohn Marino 	  break;
1009*e4b17023SJohn Marino 
1010*e4b17023SJohn Marino 	case CPP_OPEN_BRACE:
1011*e4b17023SJohn Marino 	  /* If it the next token is a '{', then we are entering a new
1012*e4b17023SJohn Marino 	     block.  Consume the entire block.  */
1013*e4b17023SJohn Marino 	  ++nesting_depth;
1014*e4b17023SJohn Marino 	  break;
1015*e4b17023SJohn Marino 
1016*e4b17023SJohn Marino 	case CPP_PRAGMA:
1017*e4b17023SJohn Marino 	  /* If we see a pragma, consume the whole thing at once.  We
1018*e4b17023SJohn Marino 	     have some safeguards against consuming pragmas willy-nilly.
1019*e4b17023SJohn Marino 	     Normally, we'd expect to be here with parser->error set,
1020*e4b17023SJohn Marino 	     which disables these safeguards.  But it's possible to get
1021*e4b17023SJohn Marino 	     here for secondary error recovery, after parser->error has
1022*e4b17023SJohn Marino 	     been cleared.  */
1023*e4b17023SJohn Marino 	  c_parser_consume_pragma (parser);
1024*e4b17023SJohn Marino 	  c_parser_skip_to_pragma_eol (parser);
1025*e4b17023SJohn Marino 	  parser->error = save_error;
1026*e4b17023SJohn Marino 	  continue;
1027*e4b17023SJohn Marino 
1028*e4b17023SJohn Marino 	default:
1029*e4b17023SJohn Marino 	  break;
1030*e4b17023SJohn Marino 	}
1031*e4b17023SJohn Marino 
1032*e4b17023SJohn Marino       c_parser_consume_token (parser);
1033*e4b17023SJohn Marino     }
1034*e4b17023SJohn Marino 
1035*e4b17023SJohn Marino  finished:
1036*e4b17023SJohn Marino   parser->error = false;
1037*e4b17023SJohn Marino }
1038*e4b17023SJohn Marino 
1039*e4b17023SJohn Marino /* CPP's options (initialized by c-opts.c).  */
1040*e4b17023SJohn Marino extern cpp_options *cpp_opts;
1041*e4b17023SJohn Marino 
1042*e4b17023SJohn Marino /* Save the warning flags which are controlled by __extension__.  */
1043*e4b17023SJohn Marino 
1044*e4b17023SJohn Marino static inline int
disable_extension_diagnostics(void)1045*e4b17023SJohn Marino disable_extension_diagnostics (void)
1046*e4b17023SJohn Marino {
1047*e4b17023SJohn Marino   int ret = (pedantic
1048*e4b17023SJohn Marino 	     | (warn_pointer_arith << 1)
1049*e4b17023SJohn Marino 	     | (warn_traditional << 2)
1050*e4b17023SJohn Marino 	     | (flag_iso << 3)
1051*e4b17023SJohn Marino 	     | (warn_long_long << 4)
1052*e4b17023SJohn Marino 	     | (warn_cxx_compat << 5)
1053*e4b17023SJohn Marino 	     | (warn_overlength_strings << 6));
1054*e4b17023SJohn Marino   cpp_opts->cpp_pedantic = pedantic = 0;
1055*e4b17023SJohn Marino   warn_pointer_arith = 0;
1056*e4b17023SJohn Marino   cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1057*e4b17023SJohn Marino   flag_iso = 0;
1058*e4b17023SJohn Marino   cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1059*e4b17023SJohn Marino   warn_cxx_compat = 0;
1060*e4b17023SJohn Marino   warn_overlength_strings = 0;
1061*e4b17023SJohn Marino   return ret;
1062*e4b17023SJohn Marino }
1063*e4b17023SJohn Marino 
1064*e4b17023SJohn Marino /* Restore the warning flags which are controlled by __extension__.
1065*e4b17023SJohn Marino    FLAGS is the return value from disable_extension_diagnostics.  */
1066*e4b17023SJohn Marino 
1067*e4b17023SJohn Marino static inline void
restore_extension_diagnostics(int flags)1068*e4b17023SJohn Marino restore_extension_diagnostics (int flags)
1069*e4b17023SJohn Marino {
1070*e4b17023SJohn Marino   cpp_opts->cpp_pedantic = pedantic = flags & 1;
1071*e4b17023SJohn Marino   warn_pointer_arith = (flags >> 1) & 1;
1072*e4b17023SJohn Marino   cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1073*e4b17023SJohn Marino   flag_iso = (flags >> 3) & 1;
1074*e4b17023SJohn Marino   cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1075*e4b17023SJohn Marino   warn_cxx_compat = (flags >> 5) & 1;
1076*e4b17023SJohn Marino   warn_overlength_strings = (flags >> 6) & 1;
1077*e4b17023SJohn Marino }
1078*e4b17023SJohn Marino 
1079*e4b17023SJohn Marino /* Possibly kinds of declarator to parse.  */
1080*e4b17023SJohn Marino typedef enum c_dtr_syn {
1081*e4b17023SJohn Marino   /* A normal declarator with an identifier.  */
1082*e4b17023SJohn Marino   C_DTR_NORMAL,
1083*e4b17023SJohn Marino   /* An abstract declarator (maybe empty).  */
1084*e4b17023SJohn Marino   C_DTR_ABSTRACT,
1085*e4b17023SJohn Marino   /* A parameter declarator: may be either, but after a type name does
1086*e4b17023SJohn Marino      not redeclare a typedef name as an identifier if it can
1087*e4b17023SJohn Marino      alternatively be interpreted as a typedef name; see DR#009,
1088*e4b17023SJohn Marino      applied in C90 TC1, omitted from C99 and reapplied in C99 TC2
1089*e4b17023SJohn Marino      following DR#249.  For example, given a typedef T, "int T" and
1090*e4b17023SJohn Marino      "int *T" are valid parameter declarations redeclaring T, while
1091*e4b17023SJohn Marino      "int (T)" and "int * (T)" and "int (T[])" and "int (T (int))" are
1092*e4b17023SJohn Marino      abstract declarators rather than involving redundant parentheses;
1093*e4b17023SJohn Marino      the same applies with attributes inside the parentheses before
1094*e4b17023SJohn Marino      "T".  */
1095*e4b17023SJohn Marino   C_DTR_PARM
1096*e4b17023SJohn Marino } c_dtr_syn;
1097*e4b17023SJohn Marino 
1098*e4b17023SJohn Marino /* The binary operation precedence levels, where 0 is a dummy lowest level
1099*e4b17023SJohn Marino    used for the bottom of the stack.  */
1100*e4b17023SJohn Marino enum c_parser_prec {
1101*e4b17023SJohn Marino   PREC_NONE,
1102*e4b17023SJohn Marino   PREC_LOGOR,
1103*e4b17023SJohn Marino   PREC_LOGAND,
1104*e4b17023SJohn Marino   PREC_BITOR,
1105*e4b17023SJohn Marino   PREC_BITXOR,
1106*e4b17023SJohn Marino   PREC_BITAND,
1107*e4b17023SJohn Marino   PREC_EQ,
1108*e4b17023SJohn Marino   PREC_REL,
1109*e4b17023SJohn Marino   PREC_SHIFT,
1110*e4b17023SJohn Marino   PREC_ADD,
1111*e4b17023SJohn Marino   PREC_MULT,
1112*e4b17023SJohn Marino   NUM_PRECS
1113*e4b17023SJohn Marino };
1114*e4b17023SJohn Marino 
1115*e4b17023SJohn Marino static void c_parser_external_declaration (c_parser *);
1116*e4b17023SJohn Marino static void c_parser_asm_definition (c_parser *);
1117*e4b17023SJohn Marino static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1118*e4b17023SJohn Marino 					   bool, bool, tree *);
1119*e4b17023SJohn Marino static void c_parser_static_assert_declaration_no_semi (c_parser *);
1120*e4b17023SJohn Marino static void c_parser_static_assert_declaration (c_parser *);
1121*e4b17023SJohn Marino static void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool,
1122*e4b17023SJohn Marino 				bool, enum c_lookahead_kind);
1123*e4b17023SJohn Marino static struct c_typespec c_parser_enum_specifier (c_parser *);
1124*e4b17023SJohn Marino static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1125*e4b17023SJohn Marino static tree c_parser_struct_declaration (c_parser *);
1126*e4b17023SJohn Marino static struct c_typespec c_parser_typeof_specifier (c_parser *);
1127*e4b17023SJohn Marino static tree c_parser_alignas_specifier (c_parser *);
1128*e4b17023SJohn Marino static struct c_declarator *c_parser_declarator (c_parser *, bool, c_dtr_syn,
1129*e4b17023SJohn Marino 						 bool *);
1130*e4b17023SJohn Marino static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1131*e4b17023SJohn Marino 							c_dtr_syn, bool *);
1132*e4b17023SJohn Marino static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1133*e4b17023SJohn Marino 							      bool,
1134*e4b17023SJohn Marino 							      struct c_declarator *);
1135*e4b17023SJohn Marino static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree);
1136*e4b17023SJohn Marino static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1137*e4b17023SJohn Marino 							  tree);
1138*e4b17023SJohn Marino static struct c_parm *c_parser_parameter_declaration (c_parser *, tree);
1139*e4b17023SJohn Marino static tree c_parser_simple_asm_expr (c_parser *);
1140*e4b17023SJohn Marino static tree c_parser_attributes (c_parser *);
1141*e4b17023SJohn Marino static struct c_type_name *c_parser_type_name (c_parser *);
1142*e4b17023SJohn Marino static struct c_expr c_parser_initializer (c_parser *);
1143*e4b17023SJohn Marino static struct c_expr c_parser_braced_init (c_parser *, tree, bool);
1144*e4b17023SJohn Marino static void c_parser_initelt (c_parser *, struct obstack *);
1145*e4b17023SJohn Marino static void c_parser_initval (c_parser *, struct c_expr *,
1146*e4b17023SJohn Marino 			      struct obstack *);
1147*e4b17023SJohn Marino static tree c_parser_compound_statement (c_parser *);
1148*e4b17023SJohn Marino static void c_parser_compound_statement_nostart (c_parser *);
1149*e4b17023SJohn Marino static void c_parser_label (c_parser *);
1150*e4b17023SJohn Marino static void c_parser_statement (c_parser *);
1151*e4b17023SJohn Marino static void c_parser_statement_after_labels (c_parser *);
1152*e4b17023SJohn Marino static void c_parser_if_statement (c_parser *);
1153*e4b17023SJohn Marino static void c_parser_switch_statement (c_parser *);
1154*e4b17023SJohn Marino static void c_parser_while_statement (c_parser *);
1155*e4b17023SJohn Marino static void c_parser_do_statement (c_parser *);
1156*e4b17023SJohn Marino static void c_parser_for_statement (c_parser *);
1157*e4b17023SJohn Marino static tree c_parser_asm_statement (c_parser *);
1158*e4b17023SJohn Marino static tree c_parser_asm_operands (c_parser *, bool);
1159*e4b17023SJohn Marino static tree c_parser_asm_goto_operands (c_parser *);
1160*e4b17023SJohn Marino static tree c_parser_asm_clobbers (c_parser *);
1161*e4b17023SJohn Marino static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *);
1162*e4b17023SJohn Marino static struct c_expr c_parser_conditional_expression (c_parser *,
1163*e4b17023SJohn Marino 						      struct c_expr *);
1164*e4b17023SJohn Marino static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1165*e4b17023SJohn Marino 						 enum c_parser_prec);
1166*e4b17023SJohn Marino static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1167*e4b17023SJohn Marino static struct c_expr c_parser_unary_expression (c_parser *);
1168*e4b17023SJohn Marino static struct c_expr c_parser_sizeof_expression (c_parser *);
1169*e4b17023SJohn Marino static struct c_expr c_parser_alignof_expression (c_parser *);
1170*e4b17023SJohn Marino static struct c_expr c_parser_postfix_expression (c_parser *);
1171*e4b17023SJohn Marino static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1172*e4b17023SJohn Marino 								   struct c_type_name *,
1173*e4b17023SJohn Marino 								   location_t);
1174*e4b17023SJohn Marino static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1175*e4b17023SJohn Marino 								location_t loc,
1176*e4b17023SJohn Marino 								struct c_expr);
1177*e4b17023SJohn Marino static tree c_parser_transaction (c_parser *, enum rid);
1178*e4b17023SJohn Marino static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1179*e4b17023SJohn Marino static tree c_parser_transaction_cancel (c_parser *);
1180*e4b17023SJohn Marino static struct c_expr c_parser_expression (c_parser *);
1181*e4b17023SJohn Marino static struct c_expr c_parser_expression_conv (c_parser *);
1182*e4b17023SJohn Marino static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool,
1183*e4b17023SJohn Marino 					 VEC(tree,gc) **);
1184*e4b17023SJohn Marino static void c_parser_omp_construct (c_parser *);
1185*e4b17023SJohn Marino static void c_parser_omp_threadprivate (c_parser *);
1186*e4b17023SJohn Marino static void c_parser_omp_barrier (c_parser *);
1187*e4b17023SJohn Marino static void c_parser_omp_flush (c_parser *);
1188*e4b17023SJohn Marino static void c_parser_omp_taskwait (c_parser *);
1189*e4b17023SJohn Marino static void c_parser_omp_taskyield (c_parser *);
1190*e4b17023SJohn Marino 
1191*e4b17023SJohn Marino enum pragma_context { pragma_external, pragma_stmt, pragma_compound };
1192*e4b17023SJohn Marino static bool c_parser_pragma (c_parser *, enum pragma_context);
1193*e4b17023SJohn Marino 
1194*e4b17023SJohn Marino /* These Objective-C parser functions are only ever called when
1195*e4b17023SJohn Marino    compiling Objective-C.  */
1196*e4b17023SJohn Marino static void c_parser_objc_class_definition (c_parser *, tree);
1197*e4b17023SJohn Marino static void c_parser_objc_class_instance_variables (c_parser *);
1198*e4b17023SJohn Marino static void c_parser_objc_class_declaration (c_parser *);
1199*e4b17023SJohn Marino static void c_parser_objc_alias_declaration (c_parser *);
1200*e4b17023SJohn Marino static void c_parser_objc_protocol_definition (c_parser *, tree);
1201*e4b17023SJohn Marino static bool c_parser_objc_method_type (c_parser *);
1202*e4b17023SJohn Marino static void c_parser_objc_method_definition (c_parser *);
1203*e4b17023SJohn Marino static void c_parser_objc_methodprotolist (c_parser *);
1204*e4b17023SJohn Marino static void c_parser_objc_methodproto (c_parser *);
1205*e4b17023SJohn Marino static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1206*e4b17023SJohn Marino static tree c_parser_objc_type_name (c_parser *);
1207*e4b17023SJohn Marino static tree c_parser_objc_protocol_refs (c_parser *);
1208*e4b17023SJohn Marino static void c_parser_objc_try_catch_finally_statement (c_parser *);
1209*e4b17023SJohn Marino static void c_parser_objc_synchronized_statement (c_parser *);
1210*e4b17023SJohn Marino static tree c_parser_objc_selector (c_parser *);
1211*e4b17023SJohn Marino static tree c_parser_objc_selector_arg (c_parser *);
1212*e4b17023SJohn Marino static tree c_parser_objc_receiver (c_parser *);
1213*e4b17023SJohn Marino static tree c_parser_objc_message_args (c_parser *);
1214*e4b17023SJohn Marino static tree c_parser_objc_keywordexpr (c_parser *);
1215*e4b17023SJohn Marino static void c_parser_objc_at_property_declaration (c_parser *);
1216*e4b17023SJohn Marino static void c_parser_objc_at_synthesize_declaration (c_parser *);
1217*e4b17023SJohn Marino static void c_parser_objc_at_dynamic_declaration (c_parser *);
1218*e4b17023SJohn Marino static bool c_parser_objc_diagnose_bad_element_prefix
1219*e4b17023SJohn Marino   (c_parser *, struct c_declspecs *);
1220*e4b17023SJohn Marino 
1221*e4b17023SJohn Marino /* Parse a translation unit (C90 6.7, C99 6.9).
1222*e4b17023SJohn Marino 
1223*e4b17023SJohn Marino    translation-unit:
1224*e4b17023SJohn Marino      external-declarations
1225*e4b17023SJohn Marino 
1226*e4b17023SJohn Marino    external-declarations:
1227*e4b17023SJohn Marino      external-declaration
1228*e4b17023SJohn Marino      external-declarations external-declaration
1229*e4b17023SJohn Marino 
1230*e4b17023SJohn Marino    GNU extensions:
1231*e4b17023SJohn Marino 
1232*e4b17023SJohn Marino    translation-unit:
1233*e4b17023SJohn Marino      empty
1234*e4b17023SJohn Marino */
1235*e4b17023SJohn Marino 
1236*e4b17023SJohn Marino static void
c_parser_translation_unit(c_parser * parser)1237*e4b17023SJohn Marino c_parser_translation_unit (c_parser *parser)
1238*e4b17023SJohn Marino {
1239*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_EOF))
1240*e4b17023SJohn Marino     {
1241*e4b17023SJohn Marino       pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
1242*e4b17023SJohn Marino 	       "ISO C forbids an empty translation unit");
1243*e4b17023SJohn Marino     }
1244*e4b17023SJohn Marino   else
1245*e4b17023SJohn Marino     {
1246*e4b17023SJohn Marino       void *obstack_position = obstack_alloc (&parser_obstack, 0);
1247*e4b17023SJohn Marino       mark_valid_location_for_stdc_pragma (false);
1248*e4b17023SJohn Marino       do
1249*e4b17023SJohn Marino 	{
1250*e4b17023SJohn Marino 	  ggc_collect ();
1251*e4b17023SJohn Marino 	  c_parser_external_declaration (parser);
1252*e4b17023SJohn Marino 	  obstack_free (&parser_obstack, obstack_position);
1253*e4b17023SJohn Marino 	}
1254*e4b17023SJohn Marino       while (c_parser_next_token_is_not (parser, CPP_EOF));
1255*e4b17023SJohn Marino     }
1256*e4b17023SJohn Marino }
1257*e4b17023SJohn Marino 
1258*e4b17023SJohn Marino /* Parse an external declaration (C90 6.7, C99 6.9).
1259*e4b17023SJohn Marino 
1260*e4b17023SJohn Marino    external-declaration:
1261*e4b17023SJohn Marino      function-definition
1262*e4b17023SJohn Marino      declaration
1263*e4b17023SJohn Marino 
1264*e4b17023SJohn Marino    GNU extensions:
1265*e4b17023SJohn Marino 
1266*e4b17023SJohn Marino    external-declaration:
1267*e4b17023SJohn Marino      asm-definition
1268*e4b17023SJohn Marino      ;
1269*e4b17023SJohn Marino      __extension__ external-declaration
1270*e4b17023SJohn Marino 
1271*e4b17023SJohn Marino    Objective-C:
1272*e4b17023SJohn Marino 
1273*e4b17023SJohn Marino    external-declaration:
1274*e4b17023SJohn Marino      objc-class-definition
1275*e4b17023SJohn Marino      objc-class-declaration
1276*e4b17023SJohn Marino      objc-alias-declaration
1277*e4b17023SJohn Marino      objc-protocol-definition
1278*e4b17023SJohn Marino      objc-method-definition
1279*e4b17023SJohn Marino      @end
1280*e4b17023SJohn Marino */
1281*e4b17023SJohn Marino 
1282*e4b17023SJohn Marino static void
c_parser_external_declaration(c_parser * parser)1283*e4b17023SJohn Marino c_parser_external_declaration (c_parser *parser)
1284*e4b17023SJohn Marino {
1285*e4b17023SJohn Marino   int ext;
1286*e4b17023SJohn Marino   switch (c_parser_peek_token (parser)->type)
1287*e4b17023SJohn Marino     {
1288*e4b17023SJohn Marino     case CPP_KEYWORD:
1289*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->keyword)
1290*e4b17023SJohn Marino 	{
1291*e4b17023SJohn Marino 	case RID_EXTENSION:
1292*e4b17023SJohn Marino 	  ext = disable_extension_diagnostics ();
1293*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
1294*e4b17023SJohn Marino 	  c_parser_external_declaration (parser);
1295*e4b17023SJohn Marino 	  restore_extension_diagnostics (ext);
1296*e4b17023SJohn Marino 	  break;
1297*e4b17023SJohn Marino 	case RID_ASM:
1298*e4b17023SJohn Marino 	  c_parser_asm_definition (parser);
1299*e4b17023SJohn Marino 	  break;
1300*e4b17023SJohn Marino 	case RID_AT_INTERFACE:
1301*e4b17023SJohn Marino 	case RID_AT_IMPLEMENTATION:
1302*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
1303*e4b17023SJohn Marino 	  c_parser_objc_class_definition (parser, NULL_TREE);
1304*e4b17023SJohn Marino 	  break;
1305*e4b17023SJohn Marino 	case RID_AT_CLASS:
1306*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
1307*e4b17023SJohn Marino 	  c_parser_objc_class_declaration (parser);
1308*e4b17023SJohn Marino 	  break;
1309*e4b17023SJohn Marino 	case RID_AT_ALIAS:
1310*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
1311*e4b17023SJohn Marino 	  c_parser_objc_alias_declaration (parser);
1312*e4b17023SJohn Marino 	  break;
1313*e4b17023SJohn Marino 	case RID_AT_PROTOCOL:
1314*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
1315*e4b17023SJohn Marino 	  c_parser_objc_protocol_definition (parser, NULL_TREE);
1316*e4b17023SJohn Marino 	  break;
1317*e4b17023SJohn Marino 	case RID_AT_PROPERTY:
1318*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
1319*e4b17023SJohn Marino 	  c_parser_objc_at_property_declaration (parser);
1320*e4b17023SJohn Marino 	  break;
1321*e4b17023SJohn Marino 	case RID_AT_SYNTHESIZE:
1322*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
1323*e4b17023SJohn Marino 	  c_parser_objc_at_synthesize_declaration (parser);
1324*e4b17023SJohn Marino 	  break;
1325*e4b17023SJohn Marino 	case RID_AT_DYNAMIC:
1326*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
1327*e4b17023SJohn Marino 	  c_parser_objc_at_dynamic_declaration (parser);
1328*e4b17023SJohn Marino 	  break;
1329*e4b17023SJohn Marino 	case RID_AT_END:
1330*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
1331*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
1332*e4b17023SJohn Marino 	  objc_finish_implementation ();
1333*e4b17023SJohn Marino 	  break;
1334*e4b17023SJohn Marino 	default:
1335*e4b17023SJohn Marino 	  goto decl_or_fndef;
1336*e4b17023SJohn Marino 	}
1337*e4b17023SJohn Marino       break;
1338*e4b17023SJohn Marino     case CPP_SEMICOLON:
1339*e4b17023SJohn Marino       pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
1340*e4b17023SJohn Marino 	       "ISO C does not allow extra %<;%> outside of a function");
1341*e4b17023SJohn Marino       c_parser_consume_token (parser);
1342*e4b17023SJohn Marino       break;
1343*e4b17023SJohn Marino     case CPP_PRAGMA:
1344*e4b17023SJohn Marino       mark_valid_location_for_stdc_pragma (true);
1345*e4b17023SJohn Marino       c_parser_pragma (parser, pragma_external);
1346*e4b17023SJohn Marino       mark_valid_location_for_stdc_pragma (false);
1347*e4b17023SJohn Marino       break;
1348*e4b17023SJohn Marino     case CPP_PLUS:
1349*e4b17023SJohn Marino     case CPP_MINUS:
1350*e4b17023SJohn Marino       if (c_dialect_objc ())
1351*e4b17023SJohn Marino 	{
1352*e4b17023SJohn Marino 	  c_parser_objc_method_definition (parser);
1353*e4b17023SJohn Marino 	  break;
1354*e4b17023SJohn Marino 	}
1355*e4b17023SJohn Marino       /* Else fall through, and yield a syntax error trying to parse
1356*e4b17023SJohn Marino 	 as a declaration or function definition.  */
1357*e4b17023SJohn Marino     default:
1358*e4b17023SJohn Marino     decl_or_fndef:
1359*e4b17023SJohn Marino       /* A declaration or a function definition (or, in Objective-C,
1360*e4b17023SJohn Marino 	 an @interface or @protocol with prefix attributes).  We can
1361*e4b17023SJohn Marino 	 only tell which after parsing the declaration specifiers, if
1362*e4b17023SJohn Marino 	 any, and the first declarator.  */
1363*e4b17023SJohn Marino       c_parser_declaration_or_fndef (parser, true, true, true, false, true, NULL);
1364*e4b17023SJohn Marino       break;
1365*e4b17023SJohn Marino     }
1366*e4b17023SJohn Marino }
1367*e4b17023SJohn Marino 
1368*e4b17023SJohn Marino /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1369*e4b17023SJohn Marino    6.7, 6.9.1).  If FNDEF_OK is true, a function definition is
1370*e4b17023SJohn Marino    accepted; otherwise (old-style parameter declarations) only other
1371*e4b17023SJohn Marino    declarations are accepted.  If STATIC_ASSERT_OK is true, a static
1372*e4b17023SJohn Marino    assertion is accepted; otherwise (old-style parameter declarations)
1373*e4b17023SJohn Marino    it is not.  If NESTED is true, we are inside a function or parsing
1374*e4b17023SJohn Marino    old-style parameter declarations; any functions encountered are
1375*e4b17023SJohn Marino    nested functions and declaration specifiers are required; otherwise
1376*e4b17023SJohn Marino    we are at top level and functions are normal functions and
1377*e4b17023SJohn Marino    declaration specifiers may be optional.  If EMPTY_OK is true, empty
1378*e4b17023SJohn Marino    declarations are OK (subject to all other constraints); otherwise
1379*e4b17023SJohn Marino    (old-style parameter declarations) they are diagnosed.  If
1380*e4b17023SJohn Marino    START_ATTR_OK is true, the declaration specifiers may start with
1381*e4b17023SJohn Marino    attributes; otherwise they may not.
1382*e4b17023SJohn Marino    OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1383*e4b17023SJohn Marino    declaration when parsing an Objective-C foreach statement.
1384*e4b17023SJohn Marino 
1385*e4b17023SJohn Marino    declaration:
1386*e4b17023SJohn Marino      declaration-specifiers init-declarator-list[opt] ;
1387*e4b17023SJohn Marino      static_assert-declaration
1388*e4b17023SJohn Marino 
1389*e4b17023SJohn Marino    function-definition:
1390*e4b17023SJohn Marino      declaration-specifiers[opt] declarator declaration-list[opt]
1391*e4b17023SJohn Marino        compound-statement
1392*e4b17023SJohn Marino 
1393*e4b17023SJohn Marino    declaration-list:
1394*e4b17023SJohn Marino      declaration
1395*e4b17023SJohn Marino      declaration-list declaration
1396*e4b17023SJohn Marino 
1397*e4b17023SJohn Marino    init-declarator-list:
1398*e4b17023SJohn Marino      init-declarator
1399*e4b17023SJohn Marino      init-declarator-list , init-declarator
1400*e4b17023SJohn Marino 
1401*e4b17023SJohn Marino    init-declarator:
1402*e4b17023SJohn Marino      declarator simple-asm-expr[opt] attributes[opt]
1403*e4b17023SJohn Marino      declarator simple-asm-expr[opt] attributes[opt] = initializer
1404*e4b17023SJohn Marino 
1405*e4b17023SJohn Marino    GNU extensions:
1406*e4b17023SJohn Marino 
1407*e4b17023SJohn Marino    nested-function-definition:
1408*e4b17023SJohn Marino      declaration-specifiers declarator declaration-list[opt]
1409*e4b17023SJohn Marino        compound-statement
1410*e4b17023SJohn Marino 
1411*e4b17023SJohn Marino    Objective-C:
1412*e4b17023SJohn Marino      attributes objc-class-definition
1413*e4b17023SJohn Marino      attributes objc-category-definition
1414*e4b17023SJohn Marino      attributes objc-protocol-definition
1415*e4b17023SJohn Marino 
1416*e4b17023SJohn Marino    The simple-asm-expr and attributes are GNU extensions.
1417*e4b17023SJohn Marino 
1418*e4b17023SJohn Marino    This function does not handle __extension__; that is handled in its
1419*e4b17023SJohn Marino    callers.  ??? Following the old parser, __extension__ may start
1420*e4b17023SJohn Marino    external declarations, declarations in functions and declarations
1421*e4b17023SJohn Marino    at the start of "for" loops, but not old-style parameter
1422*e4b17023SJohn Marino    declarations.
1423*e4b17023SJohn Marino 
1424*e4b17023SJohn Marino    C99 requires declaration specifiers in a function definition; the
1425*e4b17023SJohn Marino    absence is diagnosed through the diagnosis of implicit int.  In GNU
1426*e4b17023SJohn Marino    C we also allow but diagnose declarations without declaration
1427*e4b17023SJohn Marino    specifiers, but only at top level (elsewhere they conflict with
1428*e4b17023SJohn Marino    other syntax).
1429*e4b17023SJohn Marino 
1430*e4b17023SJohn Marino    In Objective-C, declarations of the looping variable in a foreach
1431*e4b17023SJohn Marino    statement are exceptionally terminated by 'in' (for example, 'for
1432*e4b17023SJohn Marino    (NSObject *object in array) { ... }').
1433*e4b17023SJohn Marino 
1434*e4b17023SJohn Marino    OpenMP:
1435*e4b17023SJohn Marino 
1436*e4b17023SJohn Marino    declaration:
1437*e4b17023SJohn Marino      threadprivate-directive  */
1438*e4b17023SJohn Marino 
1439*e4b17023SJohn Marino static void
c_parser_declaration_or_fndef(c_parser * parser,bool fndef_ok,bool static_assert_ok,bool empty_ok,bool nested,bool start_attr_ok,tree * objc_foreach_object_declaration)1440*e4b17023SJohn Marino c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1441*e4b17023SJohn Marino 			       bool static_assert_ok, bool empty_ok,
1442*e4b17023SJohn Marino 			       bool nested, bool start_attr_ok,
1443*e4b17023SJohn Marino 			       tree *objc_foreach_object_declaration)
1444*e4b17023SJohn Marino {
1445*e4b17023SJohn Marino   struct c_declspecs *specs;
1446*e4b17023SJohn Marino   tree prefix_attrs;
1447*e4b17023SJohn Marino   tree all_prefix_attrs;
1448*e4b17023SJohn Marino   bool diagnosed_no_specs = false;
1449*e4b17023SJohn Marino   location_t here = c_parser_peek_token (parser)->location;
1450*e4b17023SJohn Marino 
1451*e4b17023SJohn Marino   if (static_assert_ok
1452*e4b17023SJohn Marino       && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1453*e4b17023SJohn Marino     {
1454*e4b17023SJohn Marino       c_parser_static_assert_declaration (parser);
1455*e4b17023SJohn Marino       return;
1456*e4b17023SJohn Marino     }
1457*e4b17023SJohn Marino   specs = build_null_declspecs ();
1458*e4b17023SJohn Marino 
1459*e4b17023SJohn Marino   /* Try to detect an unknown type name when we have "A B" or "A *B".  */
1460*e4b17023SJohn Marino   if (c_parser_peek_token (parser)->type == CPP_NAME
1461*e4b17023SJohn Marino       && c_parser_peek_token (parser)->id_kind == C_ID_ID
1462*e4b17023SJohn Marino       && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1463*e4b17023SJohn Marino           || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1464*e4b17023SJohn Marino       && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1465*e4b17023SJohn Marino     {
1466*e4b17023SJohn Marino       error_at (here, "unknown type name %qE",
1467*e4b17023SJohn Marino                 c_parser_peek_token (parser)->value);
1468*e4b17023SJohn Marino 
1469*e4b17023SJohn Marino       /* Parse declspecs normally to get a correct pointer type, but avoid
1470*e4b17023SJohn Marino          a further "fails to be a type name" error.  Refuse nested functions
1471*e4b17023SJohn Marino          since it is not how the user likely wants us to recover.  */
1472*e4b17023SJohn Marino       c_parser_peek_token (parser)->type = CPP_KEYWORD;
1473*e4b17023SJohn Marino       c_parser_peek_token (parser)->keyword = RID_VOID;
1474*e4b17023SJohn Marino       c_parser_peek_token (parser)->value = error_mark_node;
1475*e4b17023SJohn Marino       fndef_ok = !nested;
1476*e4b17023SJohn Marino     }
1477*e4b17023SJohn Marino 
1478*e4b17023SJohn Marino   c_parser_declspecs (parser, specs, true, true, start_attr_ok, cla_nonabstract_decl);
1479*e4b17023SJohn Marino   if (parser->error)
1480*e4b17023SJohn Marino     {
1481*e4b17023SJohn Marino       c_parser_skip_to_end_of_block_or_statement (parser);
1482*e4b17023SJohn Marino       return;
1483*e4b17023SJohn Marino     }
1484*e4b17023SJohn Marino   if (nested && !specs->declspecs_seen_p)
1485*e4b17023SJohn Marino     {
1486*e4b17023SJohn Marino       c_parser_error (parser, "expected declaration specifiers");
1487*e4b17023SJohn Marino       c_parser_skip_to_end_of_block_or_statement (parser);
1488*e4b17023SJohn Marino       return;
1489*e4b17023SJohn Marino     }
1490*e4b17023SJohn Marino   finish_declspecs (specs);
1491*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1492*e4b17023SJohn Marino     {
1493*e4b17023SJohn Marino       if (empty_ok)
1494*e4b17023SJohn Marino 	shadow_tag (specs);
1495*e4b17023SJohn Marino       else
1496*e4b17023SJohn Marino 	{
1497*e4b17023SJohn Marino 	  shadow_tag_warned (specs, 1);
1498*e4b17023SJohn Marino 	  pedwarn (here, 0, "empty declaration");
1499*e4b17023SJohn Marino 	}
1500*e4b17023SJohn Marino       c_parser_consume_token (parser);
1501*e4b17023SJohn Marino       return;
1502*e4b17023SJohn Marino     }
1503*e4b17023SJohn Marino 
1504*e4b17023SJohn Marino   /* Provide better error recovery.  Note that a type name here is usually
1505*e4b17023SJohn Marino      better diagnosed as a redeclaration.  */
1506*e4b17023SJohn Marino   if (empty_ok
1507*e4b17023SJohn Marino       && specs->typespec_kind == ctsk_tagdef
1508*e4b17023SJohn Marino       && c_parser_next_token_starts_declspecs (parser)
1509*e4b17023SJohn Marino       && !c_parser_next_token_is (parser, CPP_NAME))
1510*e4b17023SJohn Marino     {
1511*e4b17023SJohn Marino       c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
1512*e4b17023SJohn Marino       parser->error = false;
1513*e4b17023SJohn Marino       shadow_tag_warned (specs, 1);
1514*e4b17023SJohn Marino       return;
1515*e4b17023SJohn Marino     }
1516*e4b17023SJohn Marino   else if (c_dialect_objc ())
1517*e4b17023SJohn Marino     {
1518*e4b17023SJohn Marino       /* Prefix attributes are an error on method decls.  */
1519*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->type)
1520*e4b17023SJohn Marino 	{
1521*e4b17023SJohn Marino 	  case CPP_PLUS:
1522*e4b17023SJohn Marino 	  case CPP_MINUS:
1523*e4b17023SJohn Marino 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1524*e4b17023SJohn Marino 	      return;
1525*e4b17023SJohn Marino 	    if (specs->attrs)
1526*e4b17023SJohn Marino 	      {
1527*e4b17023SJohn Marino 		warning_at (c_parser_peek_token (parser)->location,
1528*e4b17023SJohn Marino 			    OPT_Wattributes,
1529*e4b17023SJohn Marino 	       		    "prefix attributes are ignored for methods");
1530*e4b17023SJohn Marino 		specs->attrs = NULL_TREE;
1531*e4b17023SJohn Marino 	      }
1532*e4b17023SJohn Marino 	    if (fndef_ok)
1533*e4b17023SJohn Marino 	      c_parser_objc_method_definition (parser);
1534*e4b17023SJohn Marino 	    else
1535*e4b17023SJohn Marino 	      c_parser_objc_methodproto (parser);
1536*e4b17023SJohn Marino 	    return;
1537*e4b17023SJohn Marino 	    break;
1538*e4b17023SJohn Marino 	  default:
1539*e4b17023SJohn Marino 	    break;
1540*e4b17023SJohn Marino 	}
1541*e4b17023SJohn Marino       /* This is where we parse 'attributes @interface ...',
1542*e4b17023SJohn Marino 	 'attributes @implementation ...', 'attributes @protocol ...'
1543*e4b17023SJohn Marino 	 (where attributes could be, for example, __attribute__
1544*e4b17023SJohn Marino 	 ((deprecated)).
1545*e4b17023SJohn Marino       */
1546*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->keyword)
1547*e4b17023SJohn Marino 	{
1548*e4b17023SJohn Marino 	case RID_AT_INTERFACE:
1549*e4b17023SJohn Marino 	  {
1550*e4b17023SJohn Marino 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1551*e4b17023SJohn Marino 	      return;
1552*e4b17023SJohn Marino 	    c_parser_objc_class_definition (parser, specs->attrs);
1553*e4b17023SJohn Marino 	    return;
1554*e4b17023SJohn Marino 	  }
1555*e4b17023SJohn Marino 	  break;
1556*e4b17023SJohn Marino 	case RID_AT_IMPLEMENTATION:
1557*e4b17023SJohn Marino 	  {
1558*e4b17023SJohn Marino 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1559*e4b17023SJohn Marino 	      return;
1560*e4b17023SJohn Marino 	    if (specs->attrs)
1561*e4b17023SJohn Marino 	      {
1562*e4b17023SJohn Marino 		warning_at (c_parser_peek_token (parser)->location,
1563*e4b17023SJohn Marino 			OPT_Wattributes,
1564*e4b17023SJohn Marino 			"prefix attributes are ignored for implementations");
1565*e4b17023SJohn Marino 		specs->attrs = NULL_TREE;
1566*e4b17023SJohn Marino 	      }
1567*e4b17023SJohn Marino 	    c_parser_objc_class_definition (parser, NULL_TREE);
1568*e4b17023SJohn Marino 	    return;
1569*e4b17023SJohn Marino 	  }
1570*e4b17023SJohn Marino 	  break;
1571*e4b17023SJohn Marino 	case RID_AT_PROTOCOL:
1572*e4b17023SJohn Marino 	  {
1573*e4b17023SJohn Marino 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1574*e4b17023SJohn Marino 	      return;
1575*e4b17023SJohn Marino 	    c_parser_objc_protocol_definition (parser, specs->attrs);
1576*e4b17023SJohn Marino 	    return;
1577*e4b17023SJohn Marino 	  }
1578*e4b17023SJohn Marino 	  break;
1579*e4b17023SJohn Marino 	case RID_AT_ALIAS:
1580*e4b17023SJohn Marino 	case RID_AT_CLASS:
1581*e4b17023SJohn Marino 	case RID_AT_END:
1582*e4b17023SJohn Marino 	case RID_AT_PROPERTY:
1583*e4b17023SJohn Marino 	  if (specs->attrs)
1584*e4b17023SJohn Marino 	    {
1585*e4b17023SJohn Marino 	      c_parser_error (parser, "unexpected attribute");
1586*e4b17023SJohn Marino 	      specs->attrs = NULL;
1587*e4b17023SJohn Marino 	    }
1588*e4b17023SJohn Marino 	  break;
1589*e4b17023SJohn Marino 	default:
1590*e4b17023SJohn Marino 	  break;
1591*e4b17023SJohn Marino 	}
1592*e4b17023SJohn Marino     }
1593*e4b17023SJohn Marino 
1594*e4b17023SJohn Marino   pending_xref_error ();
1595*e4b17023SJohn Marino   prefix_attrs = specs->attrs;
1596*e4b17023SJohn Marino   all_prefix_attrs = prefix_attrs;
1597*e4b17023SJohn Marino   specs->attrs = NULL_TREE;
1598*e4b17023SJohn Marino   while (true)
1599*e4b17023SJohn Marino     {
1600*e4b17023SJohn Marino       struct c_declarator *declarator;
1601*e4b17023SJohn Marino       bool dummy = false;
1602*e4b17023SJohn Marino       timevar_id_t tv;
1603*e4b17023SJohn Marino       tree fnbody;
1604*e4b17023SJohn Marino       /* Declaring either one or more declarators (in which case we
1605*e4b17023SJohn Marino 	 should diagnose if there were no declaration specifiers) or a
1606*e4b17023SJohn Marino 	 function definition (in which case the diagnostic for
1607*e4b17023SJohn Marino 	 implicit int suffices).  */
1608*e4b17023SJohn Marino       declarator = c_parser_declarator (parser,
1609*e4b17023SJohn Marino 					specs->typespec_kind != ctsk_none,
1610*e4b17023SJohn Marino 					C_DTR_NORMAL, &dummy);
1611*e4b17023SJohn Marino       if (declarator == NULL)
1612*e4b17023SJohn Marino 	{
1613*e4b17023SJohn Marino 	  c_parser_skip_to_end_of_block_or_statement (parser);
1614*e4b17023SJohn Marino 	  return;
1615*e4b17023SJohn Marino 	}
1616*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_EQ)
1617*e4b17023SJohn Marino 	  || c_parser_next_token_is (parser, CPP_COMMA)
1618*e4b17023SJohn Marino 	  || c_parser_next_token_is (parser, CPP_SEMICOLON)
1619*e4b17023SJohn Marino 	  || c_parser_next_token_is_keyword (parser, RID_ASM)
1620*e4b17023SJohn Marino 	  || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
1621*e4b17023SJohn Marino 	  || c_parser_next_token_is_keyword (parser, RID_IN))
1622*e4b17023SJohn Marino 	{
1623*e4b17023SJohn Marino 	  tree asm_name = NULL_TREE;
1624*e4b17023SJohn Marino 	  tree postfix_attrs = NULL_TREE;
1625*e4b17023SJohn Marino 	  if (!diagnosed_no_specs && !specs->declspecs_seen_p)
1626*e4b17023SJohn Marino 	    {
1627*e4b17023SJohn Marino 	      diagnosed_no_specs = true;
1628*e4b17023SJohn Marino 	      pedwarn (here, 0, "data definition has no type or storage class");
1629*e4b17023SJohn Marino 	    }
1630*e4b17023SJohn Marino 	  /* Having seen a data definition, there cannot now be a
1631*e4b17023SJohn Marino 	     function definition.  */
1632*e4b17023SJohn Marino 	  fndef_ok = false;
1633*e4b17023SJohn Marino 	  if (c_parser_next_token_is_keyword (parser, RID_ASM))
1634*e4b17023SJohn Marino 	    asm_name = c_parser_simple_asm_expr (parser);
1635*e4b17023SJohn Marino 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
1636*e4b17023SJohn Marino 	    postfix_attrs = c_parser_attributes (parser);
1637*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_EQ))
1638*e4b17023SJohn Marino 	    {
1639*e4b17023SJohn Marino 	      tree d;
1640*e4b17023SJohn Marino 	      struct c_expr init;
1641*e4b17023SJohn Marino 	      location_t init_loc;
1642*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
1643*e4b17023SJohn Marino 	      /* The declaration of the variable is in effect while
1644*e4b17023SJohn Marino 		 its initializer is parsed.  */
1645*e4b17023SJohn Marino 	      d = start_decl (declarator, specs, true,
1646*e4b17023SJohn Marino 			      chainon (postfix_attrs, all_prefix_attrs));
1647*e4b17023SJohn Marino 	      if (!d)
1648*e4b17023SJohn Marino 		d = error_mark_node;
1649*e4b17023SJohn Marino 	      start_init (d, asm_name, global_bindings_p ());
1650*e4b17023SJohn Marino 	      init_loc = c_parser_peek_token (parser)->location;
1651*e4b17023SJohn Marino 	      init = c_parser_initializer (parser);
1652*e4b17023SJohn Marino 	      finish_init ();
1653*e4b17023SJohn Marino 	      if (d != error_mark_node)
1654*e4b17023SJohn Marino 		{
1655*e4b17023SJohn Marino 		  maybe_warn_string_init (TREE_TYPE (d), init);
1656*e4b17023SJohn Marino 		  finish_decl (d, init_loc, init.value,
1657*e4b17023SJohn Marino 		      	       init.original_type, asm_name);
1658*e4b17023SJohn Marino 		}
1659*e4b17023SJohn Marino 	    }
1660*e4b17023SJohn Marino 	  else
1661*e4b17023SJohn Marino 	    {
1662*e4b17023SJohn Marino 	      tree d = start_decl (declarator, specs, false,
1663*e4b17023SJohn Marino 				   chainon (postfix_attrs,
1664*e4b17023SJohn Marino 					    all_prefix_attrs));
1665*e4b17023SJohn Marino 	      if (d)
1666*e4b17023SJohn Marino 		finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
1667*e4b17023SJohn Marino 			     NULL_TREE, asm_name);
1668*e4b17023SJohn Marino 
1669*e4b17023SJohn Marino 	      if (c_parser_next_token_is_keyword (parser, RID_IN))
1670*e4b17023SJohn Marino 		{
1671*e4b17023SJohn Marino 		  if (d)
1672*e4b17023SJohn Marino 		    *objc_foreach_object_declaration = d;
1673*e4b17023SJohn Marino 		  else
1674*e4b17023SJohn Marino 		    *objc_foreach_object_declaration = error_mark_node;
1675*e4b17023SJohn Marino 		}
1676*e4b17023SJohn Marino 	    }
1677*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_COMMA))
1678*e4b17023SJohn Marino 	    {
1679*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
1680*e4b17023SJohn Marino 	      if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
1681*e4b17023SJohn Marino 		all_prefix_attrs = chainon (c_parser_attributes (parser),
1682*e4b17023SJohn Marino 					    prefix_attrs);
1683*e4b17023SJohn Marino 	      else
1684*e4b17023SJohn Marino 		all_prefix_attrs = prefix_attrs;
1685*e4b17023SJohn Marino 	      continue;
1686*e4b17023SJohn Marino 	    }
1687*e4b17023SJohn Marino 	  else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1688*e4b17023SJohn Marino 	    {
1689*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
1690*e4b17023SJohn Marino 	      return;
1691*e4b17023SJohn Marino 	    }
1692*e4b17023SJohn Marino 	  else if (c_parser_next_token_is_keyword (parser, RID_IN))
1693*e4b17023SJohn Marino 	    {
1694*e4b17023SJohn Marino 	      /* This can only happen in Objective-C: we found the
1695*e4b17023SJohn Marino 		 'in' that terminates the declaration inside an
1696*e4b17023SJohn Marino 		 Objective-C foreach statement.  Do not consume the
1697*e4b17023SJohn Marino 		 token, so that the caller can use it to determine
1698*e4b17023SJohn Marino 		 that this indeed is a foreach context.  */
1699*e4b17023SJohn Marino 	      return;
1700*e4b17023SJohn Marino 	    }
1701*e4b17023SJohn Marino 	  else
1702*e4b17023SJohn Marino 	    {
1703*e4b17023SJohn Marino 	      c_parser_error (parser, "expected %<,%> or %<;%>");
1704*e4b17023SJohn Marino 	      c_parser_skip_to_end_of_block_or_statement (parser);
1705*e4b17023SJohn Marino 	      return;
1706*e4b17023SJohn Marino 	    }
1707*e4b17023SJohn Marino 	}
1708*e4b17023SJohn Marino       else if (!fndef_ok)
1709*e4b17023SJohn Marino 	{
1710*e4b17023SJohn Marino 	  c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
1711*e4b17023SJohn Marino 			  "%<asm%> or %<__attribute__%>");
1712*e4b17023SJohn Marino 	  c_parser_skip_to_end_of_block_or_statement (parser);
1713*e4b17023SJohn Marino 	  return;
1714*e4b17023SJohn Marino 	}
1715*e4b17023SJohn Marino       /* Function definition (nested or otherwise).  */
1716*e4b17023SJohn Marino       if (nested)
1717*e4b17023SJohn Marino 	{
1718*e4b17023SJohn Marino 	  pedwarn (here, OPT_pedantic, "ISO C forbids nested functions");
1719*e4b17023SJohn Marino 	  c_push_function_context ();
1720*e4b17023SJohn Marino 	}
1721*e4b17023SJohn Marino       if (!start_function (specs, declarator, all_prefix_attrs))
1722*e4b17023SJohn Marino 	{
1723*e4b17023SJohn Marino 	  /* This can appear in many cases looking nothing like a
1724*e4b17023SJohn Marino 	     function definition, so we don't give a more specific
1725*e4b17023SJohn Marino 	     error suggesting there was one.  */
1726*e4b17023SJohn Marino 	  c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
1727*e4b17023SJohn Marino 			  "or %<__attribute__%>");
1728*e4b17023SJohn Marino 	  if (nested)
1729*e4b17023SJohn Marino 	    c_pop_function_context ();
1730*e4b17023SJohn Marino 	  break;
1731*e4b17023SJohn Marino 	}
1732*e4b17023SJohn Marino 
1733*e4b17023SJohn Marino       if (DECL_DECLARED_INLINE_P (current_function_decl))
1734*e4b17023SJohn Marino         tv = TV_PARSE_INLINE;
1735*e4b17023SJohn Marino       else
1736*e4b17023SJohn Marino         tv = TV_PARSE_FUNC;
1737*e4b17023SJohn Marino       timevar_push (tv);
1738*e4b17023SJohn Marino 
1739*e4b17023SJohn Marino       /* Parse old-style parameter declarations.  ??? Attributes are
1740*e4b17023SJohn Marino 	 not allowed to start declaration specifiers here because of a
1741*e4b17023SJohn Marino 	 syntax conflict between a function declaration with attribute
1742*e4b17023SJohn Marino 	 suffix and a function definition with an attribute prefix on
1743*e4b17023SJohn Marino 	 first old-style parameter declaration.  Following the old
1744*e4b17023SJohn Marino 	 parser, they are not accepted on subsequent old-style
1745*e4b17023SJohn Marino 	 parameter declarations either.  However, there is no
1746*e4b17023SJohn Marino 	 ambiguity after the first declaration, nor indeed on the
1747*e4b17023SJohn Marino 	 first as long as we don't allow postfix attributes after a
1748*e4b17023SJohn Marino 	 declarator with a nonempty identifier list in a definition;
1749*e4b17023SJohn Marino 	 and postfix attributes have never been accepted here in
1750*e4b17023SJohn Marino 	 function definitions either.  */
1751*e4b17023SJohn Marino       while (c_parser_next_token_is_not (parser, CPP_EOF)
1752*e4b17023SJohn Marino 	     && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
1753*e4b17023SJohn Marino 	c_parser_declaration_or_fndef (parser, false, false, false,
1754*e4b17023SJohn Marino 				       true, false, NULL);
1755*e4b17023SJohn Marino       store_parm_decls ();
1756*e4b17023SJohn Marino       DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
1757*e4b17023SJohn Marino 	= c_parser_peek_token (parser)->location;
1758*e4b17023SJohn Marino       fnbody = c_parser_compound_statement (parser);
1759*e4b17023SJohn Marino       if (nested)
1760*e4b17023SJohn Marino 	{
1761*e4b17023SJohn Marino 	  tree decl = current_function_decl;
1762*e4b17023SJohn Marino 	  /* Mark nested functions as needing static-chain initially.
1763*e4b17023SJohn Marino 	     lower_nested_functions will recompute it but the
1764*e4b17023SJohn Marino 	     DECL_STATIC_CHAIN flag is also used before that happens,
1765*e4b17023SJohn Marino 	     by initializer_constant_valid_p.  See gcc.dg/nested-fn-2.c.  */
1766*e4b17023SJohn Marino 	  DECL_STATIC_CHAIN (decl) = 1;
1767*e4b17023SJohn Marino 	  add_stmt (fnbody);
1768*e4b17023SJohn Marino 	  finish_function ();
1769*e4b17023SJohn Marino 	  c_pop_function_context ();
1770*e4b17023SJohn Marino 	  add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
1771*e4b17023SJohn Marino 	}
1772*e4b17023SJohn Marino       else
1773*e4b17023SJohn Marino 	{
1774*e4b17023SJohn Marino 	  add_stmt (fnbody);
1775*e4b17023SJohn Marino 	  finish_function ();
1776*e4b17023SJohn Marino 	}
1777*e4b17023SJohn Marino 
1778*e4b17023SJohn Marino       timevar_pop (tv);
1779*e4b17023SJohn Marino       break;
1780*e4b17023SJohn Marino     }
1781*e4b17023SJohn Marino }
1782*e4b17023SJohn Marino 
1783*e4b17023SJohn Marino /* Parse an asm-definition (asm() outside a function body).  This is a
1784*e4b17023SJohn Marino    GNU extension.
1785*e4b17023SJohn Marino 
1786*e4b17023SJohn Marino    asm-definition:
1787*e4b17023SJohn Marino      simple-asm-expr ;
1788*e4b17023SJohn Marino */
1789*e4b17023SJohn Marino 
1790*e4b17023SJohn Marino static void
c_parser_asm_definition(c_parser * parser)1791*e4b17023SJohn Marino c_parser_asm_definition (c_parser *parser)
1792*e4b17023SJohn Marino {
1793*e4b17023SJohn Marino   tree asm_str = c_parser_simple_asm_expr (parser);
1794*e4b17023SJohn Marino   if (asm_str)
1795*e4b17023SJohn Marino     cgraph_add_asm_node (asm_str);
1796*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
1797*e4b17023SJohn Marino }
1798*e4b17023SJohn Marino 
1799*e4b17023SJohn Marino /* Parse a static assertion (C11 6.7.10).
1800*e4b17023SJohn Marino 
1801*e4b17023SJohn Marino    static_assert-declaration:
1802*e4b17023SJohn Marino      static_assert-declaration-no-semi ;
1803*e4b17023SJohn Marino */
1804*e4b17023SJohn Marino 
1805*e4b17023SJohn Marino static void
c_parser_static_assert_declaration(c_parser * parser)1806*e4b17023SJohn Marino c_parser_static_assert_declaration (c_parser *parser)
1807*e4b17023SJohn Marino {
1808*e4b17023SJohn Marino   c_parser_static_assert_declaration_no_semi (parser);
1809*e4b17023SJohn Marino   if (parser->error
1810*e4b17023SJohn Marino       || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
1811*e4b17023SJohn Marino     c_parser_skip_to_end_of_block_or_statement (parser);
1812*e4b17023SJohn Marino }
1813*e4b17023SJohn Marino 
1814*e4b17023SJohn Marino /* Parse a static assertion (C11 6.7.10), without the trailing
1815*e4b17023SJohn Marino    semicolon.
1816*e4b17023SJohn Marino 
1817*e4b17023SJohn Marino    static_assert-declaration-no-semi:
1818*e4b17023SJohn Marino      _Static_assert ( constant-expression , string-literal )
1819*e4b17023SJohn Marino */
1820*e4b17023SJohn Marino 
1821*e4b17023SJohn Marino static void
c_parser_static_assert_declaration_no_semi(c_parser * parser)1822*e4b17023SJohn Marino c_parser_static_assert_declaration_no_semi (c_parser *parser)
1823*e4b17023SJohn Marino {
1824*e4b17023SJohn Marino   location_t assert_loc, value_loc;
1825*e4b17023SJohn Marino   tree value;
1826*e4b17023SJohn Marino   tree string;
1827*e4b17023SJohn Marino 
1828*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
1829*e4b17023SJohn Marino   assert_loc = c_parser_peek_token (parser)->location;
1830*e4b17023SJohn Marino   if (!flag_isoc11)
1831*e4b17023SJohn Marino     {
1832*e4b17023SJohn Marino       if (flag_isoc99)
1833*e4b17023SJohn Marino 	pedwarn (assert_loc, OPT_pedantic,
1834*e4b17023SJohn Marino 		 "ISO C99 does not support %<_Static_assert%>");
1835*e4b17023SJohn Marino       else
1836*e4b17023SJohn Marino 	pedwarn (assert_loc, OPT_pedantic,
1837*e4b17023SJohn Marino 		 "ISO C90 does not support %<_Static_assert%>");
1838*e4b17023SJohn Marino     }
1839*e4b17023SJohn Marino   c_parser_consume_token (parser);
1840*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1841*e4b17023SJohn Marino     return;
1842*e4b17023SJohn Marino   value_loc = c_parser_peek_token (parser)->location;
1843*e4b17023SJohn Marino   value = c_parser_expr_no_commas (parser, NULL).value;
1844*e4b17023SJohn Marino   parser->lex_untranslated_string = true;
1845*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
1846*e4b17023SJohn Marino     {
1847*e4b17023SJohn Marino       parser->lex_untranslated_string = false;
1848*e4b17023SJohn Marino       return;
1849*e4b17023SJohn Marino     }
1850*e4b17023SJohn Marino   switch (c_parser_peek_token (parser)->type)
1851*e4b17023SJohn Marino     {
1852*e4b17023SJohn Marino     case CPP_STRING:
1853*e4b17023SJohn Marino     case CPP_STRING16:
1854*e4b17023SJohn Marino     case CPP_STRING32:
1855*e4b17023SJohn Marino     case CPP_WSTRING:
1856*e4b17023SJohn Marino     case CPP_UTF8STRING:
1857*e4b17023SJohn Marino       string = c_parser_peek_token (parser)->value;
1858*e4b17023SJohn Marino       c_parser_consume_token (parser);
1859*e4b17023SJohn Marino       parser->lex_untranslated_string = false;
1860*e4b17023SJohn Marino       break;
1861*e4b17023SJohn Marino     default:
1862*e4b17023SJohn Marino       c_parser_error (parser, "expected string literal");
1863*e4b17023SJohn Marino       parser->lex_untranslated_string = false;
1864*e4b17023SJohn Marino       return;
1865*e4b17023SJohn Marino     }
1866*e4b17023SJohn Marino   c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
1867*e4b17023SJohn Marino 
1868*e4b17023SJohn Marino   if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
1869*e4b17023SJohn Marino     {
1870*e4b17023SJohn Marino       error_at (value_loc, "expression in static assertion is not an integer");
1871*e4b17023SJohn Marino       return;
1872*e4b17023SJohn Marino     }
1873*e4b17023SJohn Marino   if (TREE_CODE (value) != INTEGER_CST)
1874*e4b17023SJohn Marino     {
1875*e4b17023SJohn Marino       value = c_fully_fold (value, false, NULL);
1876*e4b17023SJohn Marino       if (TREE_CODE (value) == INTEGER_CST)
1877*e4b17023SJohn Marino 	pedwarn (value_loc, OPT_pedantic, "expression in static assertion "
1878*e4b17023SJohn Marino 		 "is not an integer constant expression");
1879*e4b17023SJohn Marino     }
1880*e4b17023SJohn Marino   if (TREE_CODE (value) != INTEGER_CST)
1881*e4b17023SJohn Marino     {
1882*e4b17023SJohn Marino       error_at (value_loc, "expression in static assertion is not constant");
1883*e4b17023SJohn Marino       return;
1884*e4b17023SJohn Marino     }
1885*e4b17023SJohn Marino   constant_expression_warning (value);
1886*e4b17023SJohn Marino   if (integer_zerop (value))
1887*e4b17023SJohn Marino     error_at (assert_loc, "static assertion failed: %E", string);
1888*e4b17023SJohn Marino }
1889*e4b17023SJohn Marino 
1890*e4b17023SJohn Marino /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
1891*e4b17023SJohn Marino    6.7), adding them to SPECS (which may already include some).
1892*e4b17023SJohn Marino    Storage class specifiers are accepted iff SCSPEC_OK; type
1893*e4b17023SJohn Marino    specifiers are accepted iff TYPESPEC_OK; attributes are accepted at
1894*e4b17023SJohn Marino    the start iff START_ATTR_OK.
1895*e4b17023SJohn Marino 
1896*e4b17023SJohn Marino    declaration-specifiers:
1897*e4b17023SJohn Marino      storage-class-specifier declaration-specifiers[opt]
1898*e4b17023SJohn Marino      type-specifier declaration-specifiers[opt]
1899*e4b17023SJohn Marino      type-qualifier declaration-specifiers[opt]
1900*e4b17023SJohn Marino      function-specifier declaration-specifiers[opt]
1901*e4b17023SJohn Marino      alignment-specifier declaration-specifiers[opt]
1902*e4b17023SJohn Marino 
1903*e4b17023SJohn Marino    Function specifiers (inline) are from C99, and are currently
1904*e4b17023SJohn Marino    handled as storage class specifiers, as is __thread.  Alignment
1905*e4b17023SJohn Marino    specifiers are from C11.
1906*e4b17023SJohn Marino 
1907*e4b17023SJohn Marino    C90 6.5.1, C99 6.7.1:
1908*e4b17023SJohn Marino    storage-class-specifier:
1909*e4b17023SJohn Marino      typedef
1910*e4b17023SJohn Marino      extern
1911*e4b17023SJohn Marino      static
1912*e4b17023SJohn Marino      auto
1913*e4b17023SJohn Marino      register
1914*e4b17023SJohn Marino 
1915*e4b17023SJohn Marino    C99 6.7.4:
1916*e4b17023SJohn Marino    function-specifier:
1917*e4b17023SJohn Marino      inline
1918*e4b17023SJohn Marino      _Noreturn
1919*e4b17023SJohn Marino 
1920*e4b17023SJohn Marino    (_Noreturn is new in C11.)
1921*e4b17023SJohn Marino 
1922*e4b17023SJohn Marino    C90 6.5.2, C99 6.7.2:
1923*e4b17023SJohn Marino    type-specifier:
1924*e4b17023SJohn Marino      void
1925*e4b17023SJohn Marino      char
1926*e4b17023SJohn Marino      short
1927*e4b17023SJohn Marino      int
1928*e4b17023SJohn Marino      long
1929*e4b17023SJohn Marino      float
1930*e4b17023SJohn Marino      double
1931*e4b17023SJohn Marino      signed
1932*e4b17023SJohn Marino      unsigned
1933*e4b17023SJohn Marino      _Bool
1934*e4b17023SJohn Marino      _Complex
1935*e4b17023SJohn Marino      [_Imaginary removed in C99 TC2]
1936*e4b17023SJohn Marino      struct-or-union-specifier
1937*e4b17023SJohn Marino      enum-specifier
1938*e4b17023SJohn Marino      typedef-name
1939*e4b17023SJohn Marino 
1940*e4b17023SJohn Marino    (_Bool and _Complex are new in C99.)
1941*e4b17023SJohn Marino 
1942*e4b17023SJohn Marino    C90 6.5.3, C99 6.7.3:
1943*e4b17023SJohn Marino 
1944*e4b17023SJohn Marino    type-qualifier:
1945*e4b17023SJohn Marino      const
1946*e4b17023SJohn Marino      restrict
1947*e4b17023SJohn Marino      volatile
1948*e4b17023SJohn Marino      address-space-qualifier
1949*e4b17023SJohn Marino 
1950*e4b17023SJohn Marino    (restrict is new in C99.)
1951*e4b17023SJohn Marino 
1952*e4b17023SJohn Marino    GNU extensions:
1953*e4b17023SJohn Marino 
1954*e4b17023SJohn Marino    declaration-specifiers:
1955*e4b17023SJohn Marino      attributes declaration-specifiers[opt]
1956*e4b17023SJohn Marino 
1957*e4b17023SJohn Marino    type-qualifier:
1958*e4b17023SJohn Marino      address-space
1959*e4b17023SJohn Marino 
1960*e4b17023SJohn Marino    address-space:
1961*e4b17023SJohn Marino      identifier recognized by the target
1962*e4b17023SJohn Marino 
1963*e4b17023SJohn Marino    storage-class-specifier:
1964*e4b17023SJohn Marino      __thread
1965*e4b17023SJohn Marino 
1966*e4b17023SJohn Marino    type-specifier:
1967*e4b17023SJohn Marino      typeof-specifier
1968*e4b17023SJohn Marino      __int128
1969*e4b17023SJohn Marino      _Decimal32
1970*e4b17023SJohn Marino      _Decimal64
1971*e4b17023SJohn Marino      _Decimal128
1972*e4b17023SJohn Marino      _Fract
1973*e4b17023SJohn Marino      _Accum
1974*e4b17023SJohn Marino      _Sat
1975*e4b17023SJohn Marino 
1976*e4b17023SJohn Marino   (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
1977*e4b17023SJohn Marino    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
1978*e4b17023SJohn Marino 
1979*e4b17023SJohn Marino    Objective-C:
1980*e4b17023SJohn Marino 
1981*e4b17023SJohn Marino    type-specifier:
1982*e4b17023SJohn Marino      class-name objc-protocol-refs[opt]
1983*e4b17023SJohn Marino      typedef-name objc-protocol-refs
1984*e4b17023SJohn Marino      objc-protocol-refs
1985*e4b17023SJohn Marino */
1986*e4b17023SJohn Marino 
1987*e4b17023SJohn Marino static void
c_parser_declspecs(c_parser * parser,struct c_declspecs * specs,bool scspec_ok,bool typespec_ok,bool start_attr_ok,enum c_lookahead_kind la)1988*e4b17023SJohn Marino c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
1989*e4b17023SJohn Marino 		    bool scspec_ok, bool typespec_ok, bool start_attr_ok,
1990*e4b17023SJohn Marino 		    enum c_lookahead_kind la)
1991*e4b17023SJohn Marino {
1992*e4b17023SJohn Marino   bool attrs_ok = start_attr_ok;
1993*e4b17023SJohn Marino   bool seen_type = specs->typespec_kind != ctsk_none;
1994*e4b17023SJohn Marino 
1995*e4b17023SJohn Marino   if (!typespec_ok)
1996*e4b17023SJohn Marino     gcc_assert (la == cla_prefer_id);
1997*e4b17023SJohn Marino 
1998*e4b17023SJohn Marino   while (c_parser_next_token_is (parser, CPP_NAME)
1999*e4b17023SJohn Marino 	 || c_parser_next_token_is (parser, CPP_KEYWORD)
2000*e4b17023SJohn Marino 	 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2001*e4b17023SJohn Marino     {
2002*e4b17023SJohn Marino       struct c_typespec t;
2003*e4b17023SJohn Marino       tree attrs;
2004*e4b17023SJohn Marino       tree align;
2005*e4b17023SJohn Marino       location_t loc = c_parser_peek_token (parser)->location;
2006*e4b17023SJohn Marino 
2007*e4b17023SJohn Marino       /* If we cannot accept a type, exit if the next token must start
2008*e4b17023SJohn Marino 	 one.  Also, if we already have seen a tagged definition,
2009*e4b17023SJohn Marino 	 a typename would be an error anyway and likely the user
2010*e4b17023SJohn Marino 	 has simply forgotten a semicolon, so we exit.  */
2011*e4b17023SJohn Marino       if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2012*e4b17023SJohn Marino 	  && c_parser_next_tokens_start_typename (parser, la)
2013*e4b17023SJohn Marino 	  && !c_parser_next_token_is_qualifier (parser))
2014*e4b17023SJohn Marino 	break;
2015*e4b17023SJohn Marino 
2016*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_NAME))
2017*e4b17023SJohn Marino 	{
2018*e4b17023SJohn Marino 	  tree value = c_parser_peek_token (parser)->value;
2019*e4b17023SJohn Marino 	  c_id_kind kind = c_parser_peek_token (parser)->id_kind;
2020*e4b17023SJohn Marino 
2021*e4b17023SJohn Marino 	  if (kind == C_ID_ADDRSPACE)
2022*e4b17023SJohn Marino 	    {
2023*e4b17023SJohn Marino 	      addr_space_t as
2024*e4b17023SJohn Marino 		= c_parser_peek_token (parser)->keyword - RID_FIRST_ADDR_SPACE;
2025*e4b17023SJohn Marino 	      declspecs_add_addrspace (specs, as);
2026*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
2027*e4b17023SJohn Marino 	      attrs_ok = true;
2028*e4b17023SJohn Marino 	      continue;
2029*e4b17023SJohn Marino 	    }
2030*e4b17023SJohn Marino 
2031*e4b17023SJohn Marino 	  gcc_assert (!c_parser_next_token_is_qualifier (parser));
2032*e4b17023SJohn Marino 
2033*e4b17023SJohn Marino 	  /* If we cannot accept a type, and the next token must start one,
2034*e4b17023SJohn Marino 	     exit.  Do the same if we already have seen a tagged definition,
2035*e4b17023SJohn Marino 	     since it would be an error anyway and likely the user has simply
2036*e4b17023SJohn Marino 	     forgotten a semicolon.  */
2037*e4b17023SJohn Marino 	  if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2038*e4b17023SJohn Marino 	    break;
2039*e4b17023SJohn Marino 
2040*e4b17023SJohn Marino 	  /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2041*e4b17023SJohn Marino 	     a C_ID_CLASSNAME.  */
2042*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
2043*e4b17023SJohn Marino 	  seen_type = true;
2044*e4b17023SJohn Marino 	  attrs_ok = true;
2045*e4b17023SJohn Marino 	  if (kind == C_ID_ID)
2046*e4b17023SJohn Marino 	    {
2047*e4b17023SJohn Marino 	      error ("unknown type name %qE", value);
2048*e4b17023SJohn Marino 	      t.kind = ctsk_typedef;
2049*e4b17023SJohn Marino 	      t.spec = error_mark_node;
2050*e4b17023SJohn Marino 	    }
2051*e4b17023SJohn Marino 	  else if (kind == C_ID_TYPENAME
2052*e4b17023SJohn Marino 	           && (!c_dialect_objc ()
2053*e4b17023SJohn Marino 	               || c_parser_next_token_is_not (parser, CPP_LESS)))
2054*e4b17023SJohn Marino 	    {
2055*e4b17023SJohn Marino 	      t.kind = ctsk_typedef;
2056*e4b17023SJohn Marino 	      /* For a typedef name, record the meaning, not the name.
2057*e4b17023SJohn Marino 		 In case of 'foo foo, bar;'.  */
2058*e4b17023SJohn Marino 	      t.spec = lookup_name (value);
2059*e4b17023SJohn Marino 	    }
2060*e4b17023SJohn Marino 	  else
2061*e4b17023SJohn Marino 	    {
2062*e4b17023SJohn Marino 	      tree proto = NULL_TREE;
2063*e4b17023SJohn Marino 	      gcc_assert (c_dialect_objc ());
2064*e4b17023SJohn Marino 	      t.kind = ctsk_objc;
2065*e4b17023SJohn Marino 	      if (c_parser_next_token_is (parser, CPP_LESS))
2066*e4b17023SJohn Marino 		proto = c_parser_objc_protocol_refs (parser);
2067*e4b17023SJohn Marino 	      t.spec = objc_get_protocol_qualified_type (value, proto);
2068*e4b17023SJohn Marino 	    }
2069*e4b17023SJohn Marino 	  t.expr = NULL_TREE;
2070*e4b17023SJohn Marino 	  t.expr_const_operands = true;
2071*e4b17023SJohn Marino 	  declspecs_add_type (loc, specs, t);
2072*e4b17023SJohn Marino 	  continue;
2073*e4b17023SJohn Marino 	}
2074*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_LESS))
2075*e4b17023SJohn Marino 	{
2076*e4b17023SJohn Marino 	  /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2077*e4b17023SJohn Marino 	     nisse@lysator.liu.se.  */
2078*e4b17023SJohn Marino 	  tree proto;
2079*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
2080*e4b17023SJohn Marino 	  if (!typespec_ok || seen_type)
2081*e4b17023SJohn Marino 	    break;
2082*e4b17023SJohn Marino 	  proto = c_parser_objc_protocol_refs (parser);
2083*e4b17023SJohn Marino 	  t.kind = ctsk_objc;
2084*e4b17023SJohn Marino 	  t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2085*e4b17023SJohn Marino 	  t.expr = NULL_TREE;
2086*e4b17023SJohn Marino 	  t.expr_const_operands = true;
2087*e4b17023SJohn Marino 	  declspecs_add_type (loc, specs, t);
2088*e4b17023SJohn Marino 	  continue;
2089*e4b17023SJohn Marino 	}
2090*e4b17023SJohn Marino       gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2091*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->keyword)
2092*e4b17023SJohn Marino 	{
2093*e4b17023SJohn Marino 	case RID_STATIC:
2094*e4b17023SJohn Marino 	case RID_EXTERN:
2095*e4b17023SJohn Marino 	case RID_REGISTER:
2096*e4b17023SJohn Marino 	case RID_TYPEDEF:
2097*e4b17023SJohn Marino 	case RID_INLINE:
2098*e4b17023SJohn Marino 	case RID_NORETURN:
2099*e4b17023SJohn Marino 	case RID_AUTO:
2100*e4b17023SJohn Marino 	case RID_THREAD:
2101*e4b17023SJohn Marino 	  if (!scspec_ok)
2102*e4b17023SJohn Marino 	    goto out;
2103*e4b17023SJohn Marino 	  attrs_ok = true;
2104*e4b17023SJohn Marino 	  /* TODO: Distinguish between function specifiers (inline, noreturn)
2105*e4b17023SJohn Marino 	     and storage class specifiers, either here or in
2106*e4b17023SJohn Marino 	     declspecs_add_scspec.  */
2107*e4b17023SJohn Marino 	  declspecs_add_scspec (specs, c_parser_peek_token (parser)->value);
2108*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
2109*e4b17023SJohn Marino 	  break;
2110*e4b17023SJohn Marino 	case RID_UNSIGNED:
2111*e4b17023SJohn Marino 	case RID_LONG:
2112*e4b17023SJohn Marino 	case RID_INT128:
2113*e4b17023SJohn Marino 	case RID_SHORT:
2114*e4b17023SJohn Marino 	case RID_SIGNED:
2115*e4b17023SJohn Marino 	case RID_COMPLEX:
2116*e4b17023SJohn Marino 	case RID_INT:
2117*e4b17023SJohn Marino 	case RID_CHAR:
2118*e4b17023SJohn Marino 	case RID_FLOAT:
2119*e4b17023SJohn Marino 	case RID_DOUBLE:
2120*e4b17023SJohn Marino 	case RID_VOID:
2121*e4b17023SJohn Marino 	case RID_DFLOAT32:
2122*e4b17023SJohn Marino 	case RID_DFLOAT64:
2123*e4b17023SJohn Marino 	case RID_DFLOAT128:
2124*e4b17023SJohn Marino 	case RID_BOOL:
2125*e4b17023SJohn Marino 	case RID_FRACT:
2126*e4b17023SJohn Marino 	case RID_ACCUM:
2127*e4b17023SJohn Marino 	case RID_SAT:
2128*e4b17023SJohn Marino 	  if (!typespec_ok)
2129*e4b17023SJohn Marino 	    goto out;
2130*e4b17023SJohn Marino 	  attrs_ok = true;
2131*e4b17023SJohn Marino 	  seen_type = true;
2132*e4b17023SJohn Marino 	  if (c_dialect_objc ())
2133*e4b17023SJohn Marino 	    parser->objc_need_raw_identifier = true;
2134*e4b17023SJohn Marino 	  t.kind = ctsk_resword;
2135*e4b17023SJohn Marino 	  t.spec = c_parser_peek_token (parser)->value;
2136*e4b17023SJohn Marino 	  t.expr = NULL_TREE;
2137*e4b17023SJohn Marino 	  t.expr_const_operands = true;
2138*e4b17023SJohn Marino 	  declspecs_add_type (loc, specs, t);
2139*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
2140*e4b17023SJohn Marino 	  break;
2141*e4b17023SJohn Marino 	case RID_ENUM:
2142*e4b17023SJohn Marino 	  if (!typespec_ok)
2143*e4b17023SJohn Marino 	    goto out;
2144*e4b17023SJohn Marino 	  attrs_ok = true;
2145*e4b17023SJohn Marino 	  seen_type = true;
2146*e4b17023SJohn Marino 	  t = c_parser_enum_specifier (parser);
2147*e4b17023SJohn Marino 	  declspecs_add_type (loc, specs, t);
2148*e4b17023SJohn Marino 	  break;
2149*e4b17023SJohn Marino 	case RID_STRUCT:
2150*e4b17023SJohn Marino 	case RID_UNION:
2151*e4b17023SJohn Marino 	  if (!typespec_ok)
2152*e4b17023SJohn Marino 	    goto out;
2153*e4b17023SJohn Marino 	  attrs_ok = true;
2154*e4b17023SJohn Marino 	  seen_type = true;
2155*e4b17023SJohn Marino 	  t = c_parser_struct_or_union_specifier (parser);
2156*e4b17023SJohn Marino           invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2157*e4b17023SJohn Marino 	  declspecs_add_type (loc, specs, t);
2158*e4b17023SJohn Marino 	  break;
2159*e4b17023SJohn Marino 	case RID_TYPEOF:
2160*e4b17023SJohn Marino 	  /* ??? The old parser rejected typeof after other type
2161*e4b17023SJohn Marino 	     specifiers, but is a syntax error the best way of
2162*e4b17023SJohn Marino 	     handling this?  */
2163*e4b17023SJohn Marino 	  if (!typespec_ok || seen_type)
2164*e4b17023SJohn Marino 	    goto out;
2165*e4b17023SJohn Marino 	  attrs_ok = true;
2166*e4b17023SJohn Marino 	  seen_type = true;
2167*e4b17023SJohn Marino 	  t = c_parser_typeof_specifier (parser);
2168*e4b17023SJohn Marino 	  declspecs_add_type (loc, specs, t);
2169*e4b17023SJohn Marino 	  break;
2170*e4b17023SJohn Marino 	case RID_CONST:
2171*e4b17023SJohn Marino 	case RID_VOLATILE:
2172*e4b17023SJohn Marino 	case RID_RESTRICT:
2173*e4b17023SJohn Marino 	  attrs_ok = true;
2174*e4b17023SJohn Marino 	  declspecs_add_qual (specs, c_parser_peek_token (parser)->value);
2175*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
2176*e4b17023SJohn Marino 	  break;
2177*e4b17023SJohn Marino 	case RID_ATTRIBUTE:
2178*e4b17023SJohn Marino 	  if (!attrs_ok)
2179*e4b17023SJohn Marino 	    goto out;
2180*e4b17023SJohn Marino 	  attrs = c_parser_attributes (parser);
2181*e4b17023SJohn Marino 	  declspecs_add_attrs (specs, attrs);
2182*e4b17023SJohn Marino 	  break;
2183*e4b17023SJohn Marino 	case RID_ALIGNAS:
2184*e4b17023SJohn Marino 	  align = c_parser_alignas_specifier (parser);
2185*e4b17023SJohn Marino 	  declspecs_add_alignas (specs, align);
2186*e4b17023SJohn Marino 	  break;
2187*e4b17023SJohn Marino 	default:
2188*e4b17023SJohn Marino 	  goto out;
2189*e4b17023SJohn Marino 	}
2190*e4b17023SJohn Marino     }
2191*e4b17023SJohn Marino  out: ;
2192*e4b17023SJohn Marino }
2193*e4b17023SJohn Marino 
2194*e4b17023SJohn Marino /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2).
2195*e4b17023SJohn Marino 
2196*e4b17023SJohn Marino    enum-specifier:
2197*e4b17023SJohn Marino      enum attributes[opt] identifier[opt] { enumerator-list } attributes[opt]
2198*e4b17023SJohn Marino      enum attributes[opt] identifier[opt] { enumerator-list , } attributes[opt]
2199*e4b17023SJohn Marino      enum attributes[opt] identifier
2200*e4b17023SJohn Marino 
2201*e4b17023SJohn Marino    The form with trailing comma is new in C99.  The forms with
2202*e4b17023SJohn Marino    attributes are GNU extensions.  In GNU C, we accept any expression
2203*e4b17023SJohn Marino    without commas in the syntax (assignment expressions, not just
2204*e4b17023SJohn Marino    conditional expressions); assignment expressions will be diagnosed
2205*e4b17023SJohn Marino    as non-constant.
2206*e4b17023SJohn Marino 
2207*e4b17023SJohn Marino    enumerator-list:
2208*e4b17023SJohn Marino      enumerator
2209*e4b17023SJohn Marino      enumerator-list , enumerator
2210*e4b17023SJohn Marino 
2211*e4b17023SJohn Marino    enumerator:
2212*e4b17023SJohn Marino      enumeration-constant
2213*e4b17023SJohn Marino      enumeration-constant = constant-expression
2214*e4b17023SJohn Marino */
2215*e4b17023SJohn Marino 
2216*e4b17023SJohn Marino static struct c_typespec
c_parser_enum_specifier(c_parser * parser)2217*e4b17023SJohn Marino c_parser_enum_specifier (c_parser *parser)
2218*e4b17023SJohn Marino {
2219*e4b17023SJohn Marino   struct c_typespec ret;
2220*e4b17023SJohn Marino   tree attrs;
2221*e4b17023SJohn Marino   tree ident = NULL_TREE;
2222*e4b17023SJohn Marino   location_t enum_loc;
2223*e4b17023SJohn Marino   location_t ident_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
2224*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
2225*e4b17023SJohn Marino   enum_loc = c_parser_peek_token (parser)->location;
2226*e4b17023SJohn Marino   c_parser_consume_token (parser);
2227*e4b17023SJohn Marino   attrs = c_parser_attributes (parser);
2228*e4b17023SJohn Marino   enum_loc = c_parser_peek_token (parser)->location;
2229*e4b17023SJohn Marino   /* Set the location in case we create a decl now.  */
2230*e4b17023SJohn Marino   c_parser_set_source_position_from_token (c_parser_peek_token (parser));
2231*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_NAME))
2232*e4b17023SJohn Marino     {
2233*e4b17023SJohn Marino       ident = c_parser_peek_token (parser)->value;
2234*e4b17023SJohn Marino       ident_loc = c_parser_peek_token (parser)->location;
2235*e4b17023SJohn Marino       enum_loc = ident_loc;
2236*e4b17023SJohn Marino       c_parser_consume_token (parser);
2237*e4b17023SJohn Marino     }
2238*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2239*e4b17023SJohn Marino     {
2240*e4b17023SJohn Marino       /* Parse an enum definition.  */
2241*e4b17023SJohn Marino       struct c_enum_contents the_enum;
2242*e4b17023SJohn Marino       tree type;
2243*e4b17023SJohn Marino       tree postfix_attrs;
2244*e4b17023SJohn Marino       /* We chain the enumerators in reverse order, then put them in
2245*e4b17023SJohn Marino 	 forward order at the end.  */
2246*e4b17023SJohn Marino       tree values;
2247*e4b17023SJohn Marino       timevar_push (TV_PARSE_ENUM);
2248*e4b17023SJohn Marino       type = start_enum (enum_loc, &the_enum, ident);
2249*e4b17023SJohn Marino       values = NULL_TREE;
2250*e4b17023SJohn Marino       c_parser_consume_token (parser);
2251*e4b17023SJohn Marino       while (true)
2252*e4b17023SJohn Marino 	{
2253*e4b17023SJohn Marino 	  tree enum_id;
2254*e4b17023SJohn Marino 	  tree enum_value;
2255*e4b17023SJohn Marino 	  tree enum_decl;
2256*e4b17023SJohn Marino 	  bool seen_comma;
2257*e4b17023SJohn Marino 	  c_token *token;
2258*e4b17023SJohn Marino 	  location_t comma_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
2259*e4b17023SJohn Marino 	  location_t decl_loc, value_loc;
2260*e4b17023SJohn Marino 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
2261*e4b17023SJohn Marino 	    {
2262*e4b17023SJohn Marino 	      c_parser_error (parser, "expected identifier");
2263*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
2264*e4b17023SJohn Marino 	      values = error_mark_node;
2265*e4b17023SJohn Marino 	      break;
2266*e4b17023SJohn Marino 	    }
2267*e4b17023SJohn Marino 	  token = c_parser_peek_token (parser);
2268*e4b17023SJohn Marino 	  enum_id = token->value;
2269*e4b17023SJohn Marino 	  /* Set the location in case we create a decl now.  */
2270*e4b17023SJohn Marino 	  c_parser_set_source_position_from_token (token);
2271*e4b17023SJohn Marino 	  decl_loc = value_loc = token->location;
2272*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
2273*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_EQ))
2274*e4b17023SJohn Marino 	    {
2275*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
2276*e4b17023SJohn Marino 	      value_loc = c_parser_peek_token (parser)->location;
2277*e4b17023SJohn Marino 	      enum_value = c_parser_expr_no_commas (parser, NULL).value;
2278*e4b17023SJohn Marino 	    }
2279*e4b17023SJohn Marino 	  else
2280*e4b17023SJohn Marino 	    enum_value = NULL_TREE;
2281*e4b17023SJohn Marino 	  enum_decl = build_enumerator (decl_loc, value_loc,
2282*e4b17023SJohn Marino 	      				&the_enum, enum_id, enum_value);
2283*e4b17023SJohn Marino 	  TREE_CHAIN (enum_decl) = values;
2284*e4b17023SJohn Marino 	  values = enum_decl;
2285*e4b17023SJohn Marino 	  seen_comma = false;
2286*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_COMMA))
2287*e4b17023SJohn Marino 	    {
2288*e4b17023SJohn Marino 	      comma_loc = c_parser_peek_token (parser)->location;
2289*e4b17023SJohn Marino 	      seen_comma = true;
2290*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
2291*e4b17023SJohn Marino 	    }
2292*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2293*e4b17023SJohn Marino 	    {
2294*e4b17023SJohn Marino 	      if (seen_comma && !flag_isoc99)
2295*e4b17023SJohn Marino 		pedwarn (comma_loc, OPT_pedantic, "comma at end of enumerator list");
2296*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
2297*e4b17023SJohn Marino 	      break;
2298*e4b17023SJohn Marino 	    }
2299*e4b17023SJohn Marino 	  if (!seen_comma)
2300*e4b17023SJohn Marino 	    {
2301*e4b17023SJohn Marino 	      c_parser_error (parser, "expected %<,%> or %<}%>");
2302*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
2303*e4b17023SJohn Marino 	      values = error_mark_node;
2304*e4b17023SJohn Marino 	      break;
2305*e4b17023SJohn Marino 	    }
2306*e4b17023SJohn Marino 	}
2307*e4b17023SJohn Marino       postfix_attrs = c_parser_attributes (parser);
2308*e4b17023SJohn Marino       ret.spec = finish_enum (type, nreverse (values),
2309*e4b17023SJohn Marino 			      chainon (attrs, postfix_attrs));
2310*e4b17023SJohn Marino       ret.kind = ctsk_tagdef;
2311*e4b17023SJohn Marino       ret.expr = NULL_TREE;
2312*e4b17023SJohn Marino       ret.expr_const_operands = true;
2313*e4b17023SJohn Marino       timevar_pop (TV_PARSE_ENUM);
2314*e4b17023SJohn Marino       return ret;
2315*e4b17023SJohn Marino     }
2316*e4b17023SJohn Marino   else if (!ident)
2317*e4b17023SJohn Marino     {
2318*e4b17023SJohn Marino       c_parser_error (parser, "expected %<{%>");
2319*e4b17023SJohn Marino       ret.spec = error_mark_node;
2320*e4b17023SJohn Marino       ret.kind = ctsk_tagref;
2321*e4b17023SJohn Marino       ret.expr = NULL_TREE;
2322*e4b17023SJohn Marino       ret.expr_const_operands = true;
2323*e4b17023SJohn Marino       return ret;
2324*e4b17023SJohn Marino     }
2325*e4b17023SJohn Marino   ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident);
2326*e4b17023SJohn Marino   /* In ISO C, enumerated types can be referred to only if already
2327*e4b17023SJohn Marino      defined.  */
2328*e4b17023SJohn Marino   if (pedantic && !COMPLETE_TYPE_P (ret.spec))
2329*e4b17023SJohn Marino     {
2330*e4b17023SJohn Marino       gcc_assert (ident);
2331*e4b17023SJohn Marino       pedwarn (enum_loc, OPT_pedantic,
2332*e4b17023SJohn Marino 	       "ISO C forbids forward references to %<enum%> types");
2333*e4b17023SJohn Marino     }
2334*e4b17023SJohn Marino   return ret;
2335*e4b17023SJohn Marino }
2336*e4b17023SJohn Marino 
2337*e4b17023SJohn Marino /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1).
2338*e4b17023SJohn Marino 
2339*e4b17023SJohn Marino    struct-or-union-specifier:
2340*e4b17023SJohn Marino      struct-or-union attributes[opt] identifier[opt]
2341*e4b17023SJohn Marino        { struct-contents } attributes[opt]
2342*e4b17023SJohn Marino      struct-or-union attributes[opt] identifier
2343*e4b17023SJohn Marino 
2344*e4b17023SJohn Marino    struct-contents:
2345*e4b17023SJohn Marino      struct-declaration-list
2346*e4b17023SJohn Marino 
2347*e4b17023SJohn Marino    struct-declaration-list:
2348*e4b17023SJohn Marino      struct-declaration ;
2349*e4b17023SJohn Marino      struct-declaration-list struct-declaration ;
2350*e4b17023SJohn Marino 
2351*e4b17023SJohn Marino    GNU extensions:
2352*e4b17023SJohn Marino 
2353*e4b17023SJohn Marino    struct-contents:
2354*e4b17023SJohn Marino      empty
2355*e4b17023SJohn Marino      struct-declaration
2356*e4b17023SJohn Marino      struct-declaration-list struct-declaration
2357*e4b17023SJohn Marino 
2358*e4b17023SJohn Marino    struct-declaration-list:
2359*e4b17023SJohn Marino      struct-declaration-list ;
2360*e4b17023SJohn Marino      ;
2361*e4b17023SJohn Marino 
2362*e4b17023SJohn Marino    (Note that in the syntax here, unlike that in ISO C, the semicolons
2363*e4b17023SJohn Marino    are included here rather than in struct-declaration, in order to
2364*e4b17023SJohn Marino    describe the syntax with extra semicolons and missing semicolon at
2365*e4b17023SJohn Marino    end.)
2366*e4b17023SJohn Marino 
2367*e4b17023SJohn Marino    Objective-C:
2368*e4b17023SJohn Marino 
2369*e4b17023SJohn Marino    struct-declaration-list:
2370*e4b17023SJohn Marino      @defs ( class-name )
2371*e4b17023SJohn Marino 
2372*e4b17023SJohn Marino    (Note this does not include a trailing semicolon, but can be
2373*e4b17023SJohn Marino    followed by further declarations, and gets a pedwarn-if-pedantic
2374*e4b17023SJohn Marino    when followed by a semicolon.)  */
2375*e4b17023SJohn Marino 
2376*e4b17023SJohn Marino static struct c_typespec
c_parser_struct_or_union_specifier(c_parser * parser)2377*e4b17023SJohn Marino c_parser_struct_or_union_specifier (c_parser *parser)
2378*e4b17023SJohn Marino {
2379*e4b17023SJohn Marino   struct c_typespec ret;
2380*e4b17023SJohn Marino   tree attrs;
2381*e4b17023SJohn Marino   tree ident = NULL_TREE;
2382*e4b17023SJohn Marino   location_t struct_loc;
2383*e4b17023SJohn Marino   location_t ident_loc = UNKNOWN_LOCATION;
2384*e4b17023SJohn Marino   enum tree_code code;
2385*e4b17023SJohn Marino   switch (c_parser_peek_token (parser)->keyword)
2386*e4b17023SJohn Marino     {
2387*e4b17023SJohn Marino     case RID_STRUCT:
2388*e4b17023SJohn Marino       code = RECORD_TYPE;
2389*e4b17023SJohn Marino       break;
2390*e4b17023SJohn Marino     case RID_UNION:
2391*e4b17023SJohn Marino       code = UNION_TYPE;
2392*e4b17023SJohn Marino       break;
2393*e4b17023SJohn Marino     default:
2394*e4b17023SJohn Marino       gcc_unreachable ();
2395*e4b17023SJohn Marino     }
2396*e4b17023SJohn Marino   struct_loc = c_parser_peek_token (parser)->location;
2397*e4b17023SJohn Marino   c_parser_consume_token (parser);
2398*e4b17023SJohn Marino   attrs = c_parser_attributes (parser);
2399*e4b17023SJohn Marino 
2400*e4b17023SJohn Marino   /* Set the location in case we create a decl now.  */
2401*e4b17023SJohn Marino   c_parser_set_source_position_from_token (c_parser_peek_token (parser));
2402*e4b17023SJohn Marino 
2403*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_NAME))
2404*e4b17023SJohn Marino     {
2405*e4b17023SJohn Marino       ident = c_parser_peek_token (parser)->value;
2406*e4b17023SJohn Marino       ident_loc = c_parser_peek_token (parser)->location;
2407*e4b17023SJohn Marino       struct_loc = ident_loc;
2408*e4b17023SJohn Marino       c_parser_consume_token (parser);
2409*e4b17023SJohn Marino     }
2410*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2411*e4b17023SJohn Marino     {
2412*e4b17023SJohn Marino       /* Parse a struct or union definition.  Start the scope of the
2413*e4b17023SJohn Marino 	 tag before parsing components.  */
2414*e4b17023SJohn Marino       struct c_struct_parse_info *struct_info;
2415*e4b17023SJohn Marino       tree type = start_struct (struct_loc, code, ident, &struct_info);
2416*e4b17023SJohn Marino       tree postfix_attrs;
2417*e4b17023SJohn Marino       /* We chain the components in reverse order, then put them in
2418*e4b17023SJohn Marino 	 forward order at the end.  Each struct-declaration may
2419*e4b17023SJohn Marino 	 declare multiple components (comma-separated), so we must use
2420*e4b17023SJohn Marino 	 chainon to join them, although when parsing each
2421*e4b17023SJohn Marino 	 struct-declaration we can use TREE_CHAIN directly.
2422*e4b17023SJohn Marino 
2423*e4b17023SJohn Marino 	 The theory behind all this is that there will be more
2424*e4b17023SJohn Marino 	 semicolon separated fields than comma separated fields, and
2425*e4b17023SJohn Marino 	 so we'll be minimizing the number of node traversals required
2426*e4b17023SJohn Marino 	 by chainon.  */
2427*e4b17023SJohn Marino       tree contents;
2428*e4b17023SJohn Marino       timevar_push (TV_PARSE_STRUCT);
2429*e4b17023SJohn Marino       contents = NULL_TREE;
2430*e4b17023SJohn Marino       c_parser_consume_token (parser);
2431*e4b17023SJohn Marino       /* Handle the Objective-C @defs construct,
2432*e4b17023SJohn Marino 	 e.g. foo(sizeof(struct{ @defs(ClassName) }));.  */
2433*e4b17023SJohn Marino       if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
2434*e4b17023SJohn Marino 	{
2435*e4b17023SJohn Marino 	  tree name;
2436*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
2437*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
2438*e4b17023SJohn Marino 	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2439*e4b17023SJohn Marino 	    goto end_at_defs;
2440*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_NAME)
2441*e4b17023SJohn Marino 	      && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
2442*e4b17023SJohn Marino 	    {
2443*e4b17023SJohn Marino 	      name = c_parser_peek_token (parser)->value;
2444*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
2445*e4b17023SJohn Marino 	    }
2446*e4b17023SJohn Marino 	  else
2447*e4b17023SJohn Marino 	    {
2448*e4b17023SJohn Marino 	      c_parser_error (parser, "expected class name");
2449*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
2450*e4b17023SJohn Marino 	      goto end_at_defs;
2451*e4b17023SJohn Marino 	    }
2452*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
2453*e4b17023SJohn Marino 				     "expected %<)%>");
2454*e4b17023SJohn Marino 	  contents = nreverse (objc_get_class_ivars (name));
2455*e4b17023SJohn Marino 	}
2456*e4b17023SJohn Marino     end_at_defs:
2457*e4b17023SJohn Marino       /* Parse the struct-declarations and semicolons.  Problems with
2458*e4b17023SJohn Marino 	 semicolons are diagnosed here; empty structures are diagnosed
2459*e4b17023SJohn Marino 	 elsewhere.  */
2460*e4b17023SJohn Marino       while (true)
2461*e4b17023SJohn Marino 	{
2462*e4b17023SJohn Marino 	  tree decls;
2463*e4b17023SJohn Marino 	  /* Parse any stray semicolon.  */
2464*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2465*e4b17023SJohn Marino 	    {
2466*e4b17023SJohn Marino 	      pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
2467*e4b17023SJohn Marino 		       "extra semicolon in struct or union specified");
2468*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
2469*e4b17023SJohn Marino 	      continue;
2470*e4b17023SJohn Marino 	    }
2471*e4b17023SJohn Marino 	  /* Stop if at the end of the struct or union contents.  */
2472*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2473*e4b17023SJohn Marino 	    {
2474*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
2475*e4b17023SJohn Marino 	      break;
2476*e4b17023SJohn Marino 	    }
2477*e4b17023SJohn Marino 	  /* Accept #pragmas at struct scope.  */
2478*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_PRAGMA))
2479*e4b17023SJohn Marino 	    {
2480*e4b17023SJohn Marino 	      c_parser_pragma (parser, pragma_external);
2481*e4b17023SJohn Marino 	      continue;
2482*e4b17023SJohn Marino 	    }
2483*e4b17023SJohn Marino 	  /* Parse some comma-separated declarations, but not the
2484*e4b17023SJohn Marino 	     trailing semicolon if any.  */
2485*e4b17023SJohn Marino 	  decls = c_parser_struct_declaration (parser);
2486*e4b17023SJohn Marino 	  contents = chainon (decls, contents);
2487*e4b17023SJohn Marino 	  /* If no semicolon follows, either we have a parse error or
2488*e4b17023SJohn Marino 	     are at the end of the struct or union and should
2489*e4b17023SJohn Marino 	     pedwarn.  */
2490*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2491*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
2492*e4b17023SJohn Marino 	  else
2493*e4b17023SJohn Marino 	    {
2494*e4b17023SJohn Marino 	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2495*e4b17023SJohn Marino 		pedwarn (c_parser_peek_token (parser)->location, 0,
2496*e4b17023SJohn Marino 			 "no semicolon at end of struct or union");
2497*e4b17023SJohn Marino 	      else if (parser->error
2498*e4b17023SJohn Marino 		       || !c_parser_next_token_starts_declspecs (parser))
2499*e4b17023SJohn Marino 		{
2500*e4b17023SJohn Marino 		  c_parser_error (parser, "expected %<;%>");
2501*e4b17023SJohn Marino 		  c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
2502*e4b17023SJohn Marino 		  break;
2503*e4b17023SJohn Marino 		}
2504*e4b17023SJohn Marino 
2505*e4b17023SJohn Marino 	      /* If we come here, we have already emitted an error
2506*e4b17023SJohn Marino 		 for an expected `;', identifier or `(', and we also
2507*e4b17023SJohn Marino 	         recovered already.  Go on with the next field. */
2508*e4b17023SJohn Marino 	    }
2509*e4b17023SJohn Marino 	}
2510*e4b17023SJohn Marino       postfix_attrs = c_parser_attributes (parser);
2511*e4b17023SJohn Marino       ret.spec = finish_struct (struct_loc, type, nreverse (contents),
2512*e4b17023SJohn Marino 				chainon (attrs, postfix_attrs), struct_info);
2513*e4b17023SJohn Marino       ret.kind = ctsk_tagdef;
2514*e4b17023SJohn Marino       ret.expr = NULL_TREE;
2515*e4b17023SJohn Marino       ret.expr_const_operands = true;
2516*e4b17023SJohn Marino       timevar_pop (TV_PARSE_STRUCT);
2517*e4b17023SJohn Marino       return ret;
2518*e4b17023SJohn Marino     }
2519*e4b17023SJohn Marino   else if (!ident)
2520*e4b17023SJohn Marino     {
2521*e4b17023SJohn Marino       c_parser_error (parser, "expected %<{%>");
2522*e4b17023SJohn Marino       ret.spec = error_mark_node;
2523*e4b17023SJohn Marino       ret.kind = ctsk_tagref;
2524*e4b17023SJohn Marino       ret.expr = NULL_TREE;
2525*e4b17023SJohn Marino       ret.expr_const_operands = true;
2526*e4b17023SJohn Marino       return ret;
2527*e4b17023SJohn Marino     }
2528*e4b17023SJohn Marino   ret = parser_xref_tag (ident_loc, code, ident);
2529*e4b17023SJohn Marino   return ret;
2530*e4b17023SJohn Marino }
2531*e4b17023SJohn Marino 
2532*e4b17023SJohn Marino /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1), *without*
2533*e4b17023SJohn Marino    the trailing semicolon.
2534*e4b17023SJohn Marino 
2535*e4b17023SJohn Marino    struct-declaration:
2536*e4b17023SJohn Marino      specifier-qualifier-list struct-declarator-list
2537*e4b17023SJohn Marino      static_assert-declaration-no-semi
2538*e4b17023SJohn Marino 
2539*e4b17023SJohn Marino    specifier-qualifier-list:
2540*e4b17023SJohn Marino      type-specifier specifier-qualifier-list[opt]
2541*e4b17023SJohn Marino      type-qualifier specifier-qualifier-list[opt]
2542*e4b17023SJohn Marino      attributes specifier-qualifier-list[opt]
2543*e4b17023SJohn Marino 
2544*e4b17023SJohn Marino    struct-declarator-list:
2545*e4b17023SJohn Marino      struct-declarator
2546*e4b17023SJohn Marino      struct-declarator-list , attributes[opt] struct-declarator
2547*e4b17023SJohn Marino 
2548*e4b17023SJohn Marino    struct-declarator:
2549*e4b17023SJohn Marino      declarator attributes[opt]
2550*e4b17023SJohn Marino      declarator[opt] : constant-expression attributes[opt]
2551*e4b17023SJohn Marino 
2552*e4b17023SJohn Marino    GNU extensions:
2553*e4b17023SJohn Marino 
2554*e4b17023SJohn Marino    struct-declaration:
2555*e4b17023SJohn Marino      __extension__ struct-declaration
2556*e4b17023SJohn Marino      specifier-qualifier-list
2557*e4b17023SJohn Marino 
2558*e4b17023SJohn Marino    Unlike the ISO C syntax, semicolons are handled elsewhere.  The use
2559*e4b17023SJohn Marino    of attributes where shown is a GNU extension.  In GNU C, we accept
2560*e4b17023SJohn Marino    any expression without commas in the syntax (assignment
2561*e4b17023SJohn Marino    expressions, not just conditional expressions); assignment
2562*e4b17023SJohn Marino    expressions will be diagnosed as non-constant.  */
2563*e4b17023SJohn Marino 
2564*e4b17023SJohn Marino static tree
c_parser_struct_declaration(c_parser * parser)2565*e4b17023SJohn Marino c_parser_struct_declaration (c_parser *parser)
2566*e4b17023SJohn Marino {
2567*e4b17023SJohn Marino   struct c_declspecs *specs;
2568*e4b17023SJohn Marino   tree prefix_attrs;
2569*e4b17023SJohn Marino   tree all_prefix_attrs;
2570*e4b17023SJohn Marino   tree decls;
2571*e4b17023SJohn Marino   location_t decl_loc;
2572*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
2573*e4b17023SJohn Marino     {
2574*e4b17023SJohn Marino       int ext;
2575*e4b17023SJohn Marino       tree decl;
2576*e4b17023SJohn Marino       ext = disable_extension_diagnostics ();
2577*e4b17023SJohn Marino       c_parser_consume_token (parser);
2578*e4b17023SJohn Marino       decl = c_parser_struct_declaration (parser);
2579*e4b17023SJohn Marino       restore_extension_diagnostics (ext);
2580*e4b17023SJohn Marino       return decl;
2581*e4b17023SJohn Marino     }
2582*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
2583*e4b17023SJohn Marino     {
2584*e4b17023SJohn Marino       c_parser_static_assert_declaration_no_semi (parser);
2585*e4b17023SJohn Marino       return NULL_TREE;
2586*e4b17023SJohn Marino     }
2587*e4b17023SJohn Marino   specs = build_null_declspecs ();
2588*e4b17023SJohn Marino   decl_loc = c_parser_peek_token (parser)->location;
2589*e4b17023SJohn Marino   c_parser_declspecs (parser, specs, false, true, true, cla_nonabstract_decl);
2590*e4b17023SJohn Marino   if (parser->error)
2591*e4b17023SJohn Marino     return NULL_TREE;
2592*e4b17023SJohn Marino   if (!specs->declspecs_seen_p)
2593*e4b17023SJohn Marino     {
2594*e4b17023SJohn Marino       c_parser_error (parser, "expected specifier-qualifier-list");
2595*e4b17023SJohn Marino       return NULL_TREE;
2596*e4b17023SJohn Marino     }
2597*e4b17023SJohn Marino   finish_declspecs (specs);
2598*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_SEMICOLON)
2599*e4b17023SJohn Marino       || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2600*e4b17023SJohn Marino     {
2601*e4b17023SJohn Marino       tree ret;
2602*e4b17023SJohn Marino       if (specs->typespec_kind == ctsk_none)
2603*e4b17023SJohn Marino 	{
2604*e4b17023SJohn Marino 	  pedwarn (decl_loc, OPT_pedantic,
2605*e4b17023SJohn Marino 		   "ISO C forbids member declarations with no members");
2606*e4b17023SJohn Marino 	  shadow_tag_warned (specs, pedantic);
2607*e4b17023SJohn Marino 	  ret = NULL_TREE;
2608*e4b17023SJohn Marino 	}
2609*e4b17023SJohn Marino       else
2610*e4b17023SJohn Marino 	{
2611*e4b17023SJohn Marino 	  /* Support for unnamed structs or unions as members of
2612*e4b17023SJohn Marino 	     structs or unions (which is [a] useful and [b] supports
2613*e4b17023SJohn Marino 	     MS P-SDK).  */
2614*e4b17023SJohn Marino 	  tree attrs = NULL;
2615*e4b17023SJohn Marino 
2616*e4b17023SJohn Marino 	  ret = grokfield (c_parser_peek_token (parser)->location,
2617*e4b17023SJohn Marino 			   build_id_declarator (NULL_TREE), specs,
2618*e4b17023SJohn Marino 			   NULL_TREE, &attrs);
2619*e4b17023SJohn Marino 	  if (ret)
2620*e4b17023SJohn Marino 	    decl_attributes (&ret, attrs, 0);
2621*e4b17023SJohn Marino 	}
2622*e4b17023SJohn Marino       return ret;
2623*e4b17023SJohn Marino     }
2624*e4b17023SJohn Marino 
2625*e4b17023SJohn Marino   /* Provide better error recovery.  Note that a type name here is valid,
2626*e4b17023SJohn Marino      and will be treated as a field name.  */
2627*e4b17023SJohn Marino   if (specs->typespec_kind == ctsk_tagdef
2628*e4b17023SJohn Marino       && TREE_CODE (specs->type) != ENUMERAL_TYPE
2629*e4b17023SJohn Marino       && c_parser_next_token_starts_declspecs (parser)
2630*e4b17023SJohn Marino       && !c_parser_next_token_is (parser, CPP_NAME))
2631*e4b17023SJohn Marino     {
2632*e4b17023SJohn Marino       c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2633*e4b17023SJohn Marino       parser->error = false;
2634*e4b17023SJohn Marino       return NULL_TREE;
2635*e4b17023SJohn Marino     }
2636*e4b17023SJohn Marino 
2637*e4b17023SJohn Marino   pending_xref_error ();
2638*e4b17023SJohn Marino   prefix_attrs = specs->attrs;
2639*e4b17023SJohn Marino   all_prefix_attrs = prefix_attrs;
2640*e4b17023SJohn Marino   specs->attrs = NULL_TREE;
2641*e4b17023SJohn Marino   decls = NULL_TREE;
2642*e4b17023SJohn Marino   while (true)
2643*e4b17023SJohn Marino     {
2644*e4b17023SJohn Marino       /* Declaring one or more declarators or un-named bit-fields.  */
2645*e4b17023SJohn Marino       struct c_declarator *declarator;
2646*e4b17023SJohn Marino       bool dummy = false;
2647*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_COLON))
2648*e4b17023SJohn Marino 	declarator = build_id_declarator (NULL_TREE);
2649*e4b17023SJohn Marino       else
2650*e4b17023SJohn Marino 	declarator = c_parser_declarator (parser,
2651*e4b17023SJohn Marino 					  specs->typespec_kind != ctsk_none,
2652*e4b17023SJohn Marino 					  C_DTR_NORMAL, &dummy);
2653*e4b17023SJohn Marino       if (declarator == NULL)
2654*e4b17023SJohn Marino 	{
2655*e4b17023SJohn Marino 	  c_parser_skip_to_end_of_block_or_statement (parser);
2656*e4b17023SJohn Marino 	  break;
2657*e4b17023SJohn Marino 	}
2658*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_COLON)
2659*e4b17023SJohn Marino 	  || c_parser_next_token_is (parser, CPP_COMMA)
2660*e4b17023SJohn Marino 	  || c_parser_next_token_is (parser, CPP_SEMICOLON)
2661*e4b17023SJohn Marino 	  || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
2662*e4b17023SJohn Marino 	  || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2663*e4b17023SJohn Marino 	{
2664*e4b17023SJohn Marino 	  tree postfix_attrs = NULL_TREE;
2665*e4b17023SJohn Marino 	  tree width = NULL_TREE;
2666*e4b17023SJohn Marino 	  tree d;
2667*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_COLON))
2668*e4b17023SJohn Marino 	    {
2669*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
2670*e4b17023SJohn Marino 	      width = c_parser_expr_no_commas (parser, NULL).value;
2671*e4b17023SJohn Marino 	    }
2672*e4b17023SJohn Marino 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2673*e4b17023SJohn Marino 	    postfix_attrs = c_parser_attributes (parser);
2674*e4b17023SJohn Marino 	  d = grokfield (c_parser_peek_token (parser)->location,
2675*e4b17023SJohn Marino 			 declarator, specs, width, &all_prefix_attrs);
2676*e4b17023SJohn Marino 	  decl_attributes (&d, chainon (postfix_attrs,
2677*e4b17023SJohn Marino 					all_prefix_attrs), 0);
2678*e4b17023SJohn Marino 	  DECL_CHAIN (d) = decls;
2679*e4b17023SJohn Marino 	  decls = d;
2680*e4b17023SJohn Marino 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2681*e4b17023SJohn Marino 	    all_prefix_attrs = chainon (c_parser_attributes (parser),
2682*e4b17023SJohn Marino 					prefix_attrs);
2683*e4b17023SJohn Marino 	  else
2684*e4b17023SJohn Marino 	    all_prefix_attrs = prefix_attrs;
2685*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_COMMA))
2686*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
2687*e4b17023SJohn Marino 	  else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
2688*e4b17023SJohn Marino 		   || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2689*e4b17023SJohn Marino 	    {
2690*e4b17023SJohn Marino 	      /* Semicolon consumed in caller.  */
2691*e4b17023SJohn Marino 	      break;
2692*e4b17023SJohn Marino 	    }
2693*e4b17023SJohn Marino 	  else
2694*e4b17023SJohn Marino 	    {
2695*e4b17023SJohn Marino 	      c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
2696*e4b17023SJohn Marino 	      break;
2697*e4b17023SJohn Marino 	    }
2698*e4b17023SJohn Marino 	}
2699*e4b17023SJohn Marino       else
2700*e4b17023SJohn Marino 	{
2701*e4b17023SJohn Marino 	  c_parser_error (parser,
2702*e4b17023SJohn Marino 			  "expected %<:%>, %<,%>, %<;%>, %<}%> or "
2703*e4b17023SJohn Marino 			  "%<__attribute__%>");
2704*e4b17023SJohn Marino 	  break;
2705*e4b17023SJohn Marino 	}
2706*e4b17023SJohn Marino     }
2707*e4b17023SJohn Marino   return decls;
2708*e4b17023SJohn Marino }
2709*e4b17023SJohn Marino 
2710*e4b17023SJohn Marino /* Parse a typeof specifier (a GNU extension).
2711*e4b17023SJohn Marino 
2712*e4b17023SJohn Marino    typeof-specifier:
2713*e4b17023SJohn Marino      typeof ( expression )
2714*e4b17023SJohn Marino      typeof ( type-name )
2715*e4b17023SJohn Marino */
2716*e4b17023SJohn Marino 
2717*e4b17023SJohn Marino static struct c_typespec
c_parser_typeof_specifier(c_parser * parser)2718*e4b17023SJohn Marino c_parser_typeof_specifier (c_parser *parser)
2719*e4b17023SJohn Marino {
2720*e4b17023SJohn Marino   struct c_typespec ret;
2721*e4b17023SJohn Marino   ret.kind = ctsk_typeof;
2722*e4b17023SJohn Marino   ret.spec = error_mark_node;
2723*e4b17023SJohn Marino   ret.expr = NULL_TREE;
2724*e4b17023SJohn Marino   ret.expr_const_operands = true;
2725*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
2726*e4b17023SJohn Marino   c_parser_consume_token (parser);
2727*e4b17023SJohn Marino   c_inhibit_evaluation_warnings++;
2728*e4b17023SJohn Marino   in_typeof++;
2729*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2730*e4b17023SJohn Marino     {
2731*e4b17023SJohn Marino       c_inhibit_evaluation_warnings--;
2732*e4b17023SJohn Marino       in_typeof--;
2733*e4b17023SJohn Marino       return ret;
2734*e4b17023SJohn Marino     }
2735*e4b17023SJohn Marino   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
2736*e4b17023SJohn Marino     {
2737*e4b17023SJohn Marino       struct c_type_name *type = c_parser_type_name (parser);
2738*e4b17023SJohn Marino       c_inhibit_evaluation_warnings--;
2739*e4b17023SJohn Marino       in_typeof--;
2740*e4b17023SJohn Marino       if (type != NULL)
2741*e4b17023SJohn Marino 	{
2742*e4b17023SJohn Marino 	  ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
2743*e4b17023SJohn Marino 	  pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
2744*e4b17023SJohn Marino 	}
2745*e4b17023SJohn Marino     }
2746*e4b17023SJohn Marino   else
2747*e4b17023SJohn Marino     {
2748*e4b17023SJohn Marino       bool was_vm;
2749*e4b17023SJohn Marino       location_t here = c_parser_peek_token (parser)->location;
2750*e4b17023SJohn Marino       struct c_expr expr = c_parser_expression (parser);
2751*e4b17023SJohn Marino       c_inhibit_evaluation_warnings--;
2752*e4b17023SJohn Marino       in_typeof--;
2753*e4b17023SJohn Marino       if (TREE_CODE (expr.value) == COMPONENT_REF
2754*e4b17023SJohn Marino 	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
2755*e4b17023SJohn Marino 	error_at (here, "%<typeof%> applied to a bit-field");
2756*e4b17023SJohn Marino       mark_exp_read (expr.value);
2757*e4b17023SJohn Marino       ret.spec = TREE_TYPE (expr.value);
2758*e4b17023SJohn Marino       was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
2759*e4b17023SJohn Marino       /* This is returned with the type so that when the type is
2760*e4b17023SJohn Marino 	 evaluated, this can be evaluated.  */
2761*e4b17023SJohn Marino       if (was_vm)
2762*e4b17023SJohn Marino 	ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
2763*e4b17023SJohn Marino       pop_maybe_used (was_vm);
2764*e4b17023SJohn Marino     }
2765*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
2766*e4b17023SJohn Marino   return ret;
2767*e4b17023SJohn Marino }
2768*e4b17023SJohn Marino 
2769*e4b17023SJohn Marino /* Parse an alignment-specifier.
2770*e4b17023SJohn Marino 
2771*e4b17023SJohn Marino    C11 6.7.5:
2772*e4b17023SJohn Marino 
2773*e4b17023SJohn Marino    alignment-specifier:
2774*e4b17023SJohn Marino      _Alignas ( type-name )
2775*e4b17023SJohn Marino      _Alignas ( constant-expression )
2776*e4b17023SJohn Marino */
2777*e4b17023SJohn Marino 
2778*e4b17023SJohn Marino static tree
c_parser_alignas_specifier(c_parser * parser)2779*e4b17023SJohn Marino c_parser_alignas_specifier (c_parser * parser)
2780*e4b17023SJohn Marino {
2781*e4b17023SJohn Marino   tree ret = error_mark_node;
2782*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
2783*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
2784*e4b17023SJohn Marino   c_parser_consume_token (parser);
2785*e4b17023SJohn Marino   if (!flag_isoc11)
2786*e4b17023SJohn Marino     {
2787*e4b17023SJohn Marino       if (flag_isoc99)
2788*e4b17023SJohn Marino 	pedwarn (loc, OPT_pedantic,
2789*e4b17023SJohn Marino 		 "ISO C99 does not support %<_Alignas%>");
2790*e4b17023SJohn Marino       else
2791*e4b17023SJohn Marino 	pedwarn (loc, OPT_pedantic,
2792*e4b17023SJohn Marino 		 "ISO C90 does not support %<_Alignas%>");
2793*e4b17023SJohn Marino     }
2794*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2795*e4b17023SJohn Marino     return ret;
2796*e4b17023SJohn Marino   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
2797*e4b17023SJohn Marino     {
2798*e4b17023SJohn Marino       struct c_type_name *type = c_parser_type_name (parser);
2799*e4b17023SJohn Marino       if (type != NULL)
2800*e4b17023SJohn Marino 	ret = c_alignof (loc, groktypename (type, NULL, NULL));
2801*e4b17023SJohn Marino     }
2802*e4b17023SJohn Marino   else
2803*e4b17023SJohn Marino     ret = c_parser_expr_no_commas (parser, NULL).value;
2804*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
2805*e4b17023SJohn Marino   return ret;
2806*e4b17023SJohn Marino }
2807*e4b17023SJohn Marino 
2808*e4b17023SJohn Marino /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
2809*e4b17023SJohn Marino    6.5.5, C99 6.7.5, 6.7.6).  If TYPE_SEEN_P then a typedef name may
2810*e4b17023SJohn Marino    be redeclared; otherwise it may not.  KIND indicates which kind of
2811*e4b17023SJohn Marino    declarator is wanted.  Returns a valid declarator except in the
2812*e4b17023SJohn Marino    case of a syntax error in which case NULL is returned.  *SEEN_ID is
2813*e4b17023SJohn Marino    set to true if an identifier being declared is seen; this is used
2814*e4b17023SJohn Marino    to diagnose bad forms of abstract array declarators and to
2815*e4b17023SJohn Marino    determine whether an identifier list is syntactically permitted.
2816*e4b17023SJohn Marino 
2817*e4b17023SJohn Marino    declarator:
2818*e4b17023SJohn Marino      pointer[opt] direct-declarator
2819*e4b17023SJohn Marino 
2820*e4b17023SJohn Marino    direct-declarator:
2821*e4b17023SJohn Marino      identifier
2822*e4b17023SJohn Marino      ( attributes[opt] declarator )
2823*e4b17023SJohn Marino      direct-declarator array-declarator
2824*e4b17023SJohn Marino      direct-declarator ( parameter-type-list )
2825*e4b17023SJohn Marino      direct-declarator ( identifier-list[opt] )
2826*e4b17023SJohn Marino 
2827*e4b17023SJohn Marino    pointer:
2828*e4b17023SJohn Marino      * type-qualifier-list[opt]
2829*e4b17023SJohn Marino      * type-qualifier-list[opt] pointer
2830*e4b17023SJohn Marino 
2831*e4b17023SJohn Marino    type-qualifier-list:
2832*e4b17023SJohn Marino      type-qualifier
2833*e4b17023SJohn Marino      attributes
2834*e4b17023SJohn Marino      type-qualifier-list type-qualifier
2835*e4b17023SJohn Marino      type-qualifier-list attributes
2836*e4b17023SJohn Marino 
2837*e4b17023SJohn Marino    parameter-type-list:
2838*e4b17023SJohn Marino      parameter-list
2839*e4b17023SJohn Marino      parameter-list , ...
2840*e4b17023SJohn Marino 
2841*e4b17023SJohn Marino    parameter-list:
2842*e4b17023SJohn Marino      parameter-declaration
2843*e4b17023SJohn Marino      parameter-list , parameter-declaration
2844*e4b17023SJohn Marino 
2845*e4b17023SJohn Marino    parameter-declaration:
2846*e4b17023SJohn Marino      declaration-specifiers declarator attributes[opt]
2847*e4b17023SJohn Marino      declaration-specifiers abstract-declarator[opt] attributes[opt]
2848*e4b17023SJohn Marino 
2849*e4b17023SJohn Marino    identifier-list:
2850*e4b17023SJohn Marino      identifier
2851*e4b17023SJohn Marino      identifier-list , identifier
2852*e4b17023SJohn Marino 
2853*e4b17023SJohn Marino    abstract-declarator:
2854*e4b17023SJohn Marino      pointer
2855*e4b17023SJohn Marino      pointer[opt] direct-abstract-declarator
2856*e4b17023SJohn Marino 
2857*e4b17023SJohn Marino    direct-abstract-declarator:
2858*e4b17023SJohn Marino      ( attributes[opt] abstract-declarator )
2859*e4b17023SJohn Marino      direct-abstract-declarator[opt] array-declarator
2860*e4b17023SJohn Marino      direct-abstract-declarator[opt] ( parameter-type-list[opt] )
2861*e4b17023SJohn Marino 
2862*e4b17023SJohn Marino    GNU extensions:
2863*e4b17023SJohn Marino 
2864*e4b17023SJohn Marino    direct-declarator:
2865*e4b17023SJohn Marino      direct-declarator ( parameter-forward-declarations
2866*e4b17023SJohn Marino 			 parameter-type-list[opt] )
2867*e4b17023SJohn Marino 
2868*e4b17023SJohn Marino    direct-abstract-declarator:
2869*e4b17023SJohn Marino      direct-abstract-declarator[opt] ( parameter-forward-declarations
2870*e4b17023SJohn Marino 				       parameter-type-list[opt] )
2871*e4b17023SJohn Marino 
2872*e4b17023SJohn Marino    parameter-forward-declarations:
2873*e4b17023SJohn Marino      parameter-list ;
2874*e4b17023SJohn Marino      parameter-forward-declarations parameter-list ;
2875*e4b17023SJohn Marino 
2876*e4b17023SJohn Marino    The uses of attributes shown above are GNU extensions.
2877*e4b17023SJohn Marino 
2878*e4b17023SJohn Marino    Some forms of array declarator are not included in C99 in the
2879*e4b17023SJohn Marino    syntax for abstract declarators; these are disallowed elsewhere.
2880*e4b17023SJohn Marino    This may be a defect (DR#289).
2881*e4b17023SJohn Marino 
2882*e4b17023SJohn Marino    This function also accepts an omitted abstract declarator as being
2883*e4b17023SJohn Marino    an abstract declarator, although not part of the formal syntax.  */
2884*e4b17023SJohn Marino 
2885*e4b17023SJohn Marino static struct c_declarator *
c_parser_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)2886*e4b17023SJohn Marino c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
2887*e4b17023SJohn Marino 		     bool *seen_id)
2888*e4b17023SJohn Marino {
2889*e4b17023SJohn Marino   /* Parse any initial pointer part.  */
2890*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_MULT))
2891*e4b17023SJohn Marino     {
2892*e4b17023SJohn Marino       struct c_declspecs *quals_attrs = build_null_declspecs ();
2893*e4b17023SJohn Marino       struct c_declarator *inner;
2894*e4b17023SJohn Marino       c_parser_consume_token (parser);
2895*e4b17023SJohn Marino       c_parser_declspecs (parser, quals_attrs, false, false, true, cla_prefer_id);
2896*e4b17023SJohn Marino       inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
2897*e4b17023SJohn Marino       if (inner == NULL)
2898*e4b17023SJohn Marino 	return NULL;
2899*e4b17023SJohn Marino       else
2900*e4b17023SJohn Marino 	return make_pointer_declarator (quals_attrs, inner);
2901*e4b17023SJohn Marino     }
2902*e4b17023SJohn Marino   /* Now we have a direct declarator, direct abstract declarator or
2903*e4b17023SJohn Marino      nothing (which counts as a direct abstract declarator here).  */
2904*e4b17023SJohn Marino   return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
2905*e4b17023SJohn Marino }
2906*e4b17023SJohn Marino 
2907*e4b17023SJohn Marino /* Parse a direct declarator or direct abstract declarator; arguments
2908*e4b17023SJohn Marino    as c_parser_declarator.  */
2909*e4b17023SJohn Marino 
2910*e4b17023SJohn Marino static struct c_declarator *
c_parser_direct_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)2911*e4b17023SJohn Marino c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
2912*e4b17023SJohn Marino 			    bool *seen_id)
2913*e4b17023SJohn Marino {
2914*e4b17023SJohn Marino   /* The direct declarator must start with an identifier (possibly
2915*e4b17023SJohn Marino      omitted) or a parenthesized declarator (possibly abstract).  In
2916*e4b17023SJohn Marino      an ordinary declarator, initial parentheses must start a
2917*e4b17023SJohn Marino      parenthesized declarator.  In an abstract declarator or parameter
2918*e4b17023SJohn Marino      declarator, they could start a parenthesized declarator or a
2919*e4b17023SJohn Marino      parameter list.  To tell which, the open parenthesis and any
2920*e4b17023SJohn Marino      following attributes must be read.  If a declaration specifier
2921*e4b17023SJohn Marino      follows, then it is a parameter list; if the specifier is a
2922*e4b17023SJohn Marino      typedef name, there might be an ambiguity about redeclaring it,
2923*e4b17023SJohn Marino      which is resolved in the direction of treating it as a typedef
2924*e4b17023SJohn Marino      name.  If a close parenthesis follows, it is also an empty
2925*e4b17023SJohn Marino      parameter list, as the syntax does not permit empty abstract
2926*e4b17023SJohn Marino      declarators.  Otherwise, it is a parenthesized declarator (in
2927*e4b17023SJohn Marino      which case the analysis may be repeated inside it, recursively).
2928*e4b17023SJohn Marino 
2929*e4b17023SJohn Marino      ??? There is an ambiguity in a parameter declaration "int
2930*e4b17023SJohn Marino      (__attribute__((foo)) x)", where x is not a typedef name: it
2931*e4b17023SJohn Marino      could be an abstract declarator for a function, or declare x with
2932*e4b17023SJohn Marino      parentheses.  The proper resolution of this ambiguity needs
2933*e4b17023SJohn Marino      documenting.  At present we follow an accident of the old
2934*e4b17023SJohn Marino      parser's implementation, whereby the first parameter must have
2935*e4b17023SJohn Marino      some declaration specifiers other than just attributes.  Thus as
2936*e4b17023SJohn Marino      a parameter declaration it is treated as a parenthesized
2937*e4b17023SJohn Marino      parameter named x, and as an abstract declarator it is
2938*e4b17023SJohn Marino      rejected.
2939*e4b17023SJohn Marino 
2940*e4b17023SJohn Marino      ??? Also following the old parser, attributes inside an empty
2941*e4b17023SJohn Marino      parameter list are ignored, making it a list not yielding a
2942*e4b17023SJohn Marino      prototype, rather than giving an error or making it have one
2943*e4b17023SJohn Marino      parameter with implicit type int.
2944*e4b17023SJohn Marino 
2945*e4b17023SJohn Marino      ??? Also following the old parser, typedef names may be
2946*e4b17023SJohn Marino      redeclared in declarators, but not Objective-C class names.  */
2947*e4b17023SJohn Marino 
2948*e4b17023SJohn Marino   if (kind != C_DTR_ABSTRACT
2949*e4b17023SJohn Marino       && c_parser_next_token_is (parser, CPP_NAME)
2950*e4b17023SJohn Marino       && ((type_seen_p
2951*e4b17023SJohn Marino 	   && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
2952*e4b17023SJohn Marino 	       || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
2953*e4b17023SJohn Marino 	  || c_parser_peek_token (parser)->id_kind == C_ID_ID))
2954*e4b17023SJohn Marino     {
2955*e4b17023SJohn Marino       struct c_declarator *inner
2956*e4b17023SJohn Marino 	= build_id_declarator (c_parser_peek_token (parser)->value);
2957*e4b17023SJohn Marino       *seen_id = true;
2958*e4b17023SJohn Marino       inner->id_loc = c_parser_peek_token (parser)->location;
2959*e4b17023SJohn Marino       c_parser_consume_token (parser);
2960*e4b17023SJohn Marino       return c_parser_direct_declarator_inner (parser, *seen_id, inner);
2961*e4b17023SJohn Marino     }
2962*e4b17023SJohn Marino 
2963*e4b17023SJohn Marino   if (kind != C_DTR_NORMAL
2964*e4b17023SJohn Marino       && c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
2965*e4b17023SJohn Marino     {
2966*e4b17023SJohn Marino       struct c_declarator *inner = build_id_declarator (NULL_TREE);
2967*e4b17023SJohn Marino       return c_parser_direct_declarator_inner (parser, *seen_id, inner);
2968*e4b17023SJohn Marino     }
2969*e4b17023SJohn Marino 
2970*e4b17023SJohn Marino   /* Either we are at the end of an abstract declarator, or we have
2971*e4b17023SJohn Marino      parentheses.  */
2972*e4b17023SJohn Marino 
2973*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
2974*e4b17023SJohn Marino     {
2975*e4b17023SJohn Marino       tree attrs;
2976*e4b17023SJohn Marino       struct c_declarator *inner;
2977*e4b17023SJohn Marino       c_parser_consume_token (parser);
2978*e4b17023SJohn Marino       attrs = c_parser_attributes (parser);
2979*e4b17023SJohn Marino       if (kind != C_DTR_NORMAL
2980*e4b17023SJohn Marino 	  && (c_parser_next_token_starts_declspecs (parser)
2981*e4b17023SJohn Marino 	      || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
2982*e4b17023SJohn Marino 	{
2983*e4b17023SJohn Marino 	  struct c_arg_info *args
2984*e4b17023SJohn Marino 	    = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
2985*e4b17023SJohn Marino 					 attrs);
2986*e4b17023SJohn Marino 	  if (args == NULL)
2987*e4b17023SJohn Marino 	    return NULL;
2988*e4b17023SJohn Marino 	  else
2989*e4b17023SJohn Marino 	    {
2990*e4b17023SJohn Marino 	      inner
2991*e4b17023SJohn Marino 		= build_function_declarator (args,
2992*e4b17023SJohn Marino 					     build_id_declarator (NULL_TREE));
2993*e4b17023SJohn Marino 	      return c_parser_direct_declarator_inner (parser, *seen_id,
2994*e4b17023SJohn Marino 						       inner);
2995*e4b17023SJohn Marino 	    }
2996*e4b17023SJohn Marino 	}
2997*e4b17023SJohn Marino       /* A parenthesized declarator.  */
2998*e4b17023SJohn Marino       inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
2999*e4b17023SJohn Marino       if (inner != NULL && attrs != NULL)
3000*e4b17023SJohn Marino 	inner = build_attrs_declarator (attrs, inner);
3001*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3002*e4b17023SJohn Marino 	{
3003*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
3004*e4b17023SJohn Marino 	  if (inner == NULL)
3005*e4b17023SJohn Marino 	    return NULL;
3006*e4b17023SJohn Marino 	  else
3007*e4b17023SJohn Marino 	    return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3008*e4b17023SJohn Marino 	}
3009*e4b17023SJohn Marino       else
3010*e4b17023SJohn Marino 	{
3011*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3012*e4b17023SJohn Marino 				     "expected %<)%>");
3013*e4b17023SJohn Marino 	  return NULL;
3014*e4b17023SJohn Marino 	}
3015*e4b17023SJohn Marino     }
3016*e4b17023SJohn Marino   else
3017*e4b17023SJohn Marino     {
3018*e4b17023SJohn Marino       if (kind == C_DTR_NORMAL)
3019*e4b17023SJohn Marino 	{
3020*e4b17023SJohn Marino 	  c_parser_error (parser, "expected identifier or %<(%>");
3021*e4b17023SJohn Marino 	  return NULL;
3022*e4b17023SJohn Marino 	}
3023*e4b17023SJohn Marino       else
3024*e4b17023SJohn Marino 	return build_id_declarator (NULL_TREE);
3025*e4b17023SJohn Marino     }
3026*e4b17023SJohn Marino }
3027*e4b17023SJohn Marino 
3028*e4b17023SJohn Marino /* Parse part of a direct declarator or direct abstract declarator,
3029*e4b17023SJohn Marino    given that some (in INNER) has already been parsed; ID_PRESENT is
3030*e4b17023SJohn Marino    true if an identifier is present, false for an abstract
3031*e4b17023SJohn Marino    declarator.  */
3032*e4b17023SJohn Marino 
3033*e4b17023SJohn Marino static struct c_declarator *
c_parser_direct_declarator_inner(c_parser * parser,bool id_present,struct c_declarator * inner)3034*e4b17023SJohn Marino c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
3035*e4b17023SJohn Marino 				  struct c_declarator *inner)
3036*e4b17023SJohn Marino {
3037*e4b17023SJohn Marino   /* Parse a sequence of array declarators and parameter lists.  */
3038*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
3039*e4b17023SJohn Marino     {
3040*e4b17023SJohn Marino       location_t brace_loc = c_parser_peek_token (parser)->location;
3041*e4b17023SJohn Marino       struct c_declarator *declarator;
3042*e4b17023SJohn Marino       struct c_declspecs *quals_attrs = build_null_declspecs ();
3043*e4b17023SJohn Marino       bool static_seen;
3044*e4b17023SJohn Marino       bool star_seen;
3045*e4b17023SJohn Marino       tree dimen;
3046*e4b17023SJohn Marino       c_parser_consume_token (parser);
3047*e4b17023SJohn Marino       c_parser_declspecs (parser, quals_attrs, false, false, true, cla_prefer_id);
3048*e4b17023SJohn Marino       static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
3049*e4b17023SJohn Marino       if (static_seen)
3050*e4b17023SJohn Marino 	c_parser_consume_token (parser);
3051*e4b17023SJohn Marino       if (static_seen && !quals_attrs->declspecs_seen_p)
3052*e4b17023SJohn Marino 	c_parser_declspecs (parser, quals_attrs, false, false, true, cla_prefer_id);
3053*e4b17023SJohn Marino       if (!quals_attrs->declspecs_seen_p)
3054*e4b17023SJohn Marino 	quals_attrs = NULL;
3055*e4b17023SJohn Marino       /* If "static" is present, there must be an array dimension.
3056*e4b17023SJohn Marino 	 Otherwise, there may be a dimension, "*", or no
3057*e4b17023SJohn Marino 	 dimension.  */
3058*e4b17023SJohn Marino       if (static_seen)
3059*e4b17023SJohn Marino 	{
3060*e4b17023SJohn Marino 	  star_seen = false;
3061*e4b17023SJohn Marino 	  dimen = c_parser_expr_no_commas (parser, NULL).value;
3062*e4b17023SJohn Marino 	}
3063*e4b17023SJohn Marino       else
3064*e4b17023SJohn Marino 	{
3065*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3066*e4b17023SJohn Marino 	    {
3067*e4b17023SJohn Marino 	      dimen = NULL_TREE;
3068*e4b17023SJohn Marino 	      star_seen = false;
3069*e4b17023SJohn Marino 	    }
3070*e4b17023SJohn Marino 	  else if (c_parser_next_token_is (parser, CPP_MULT))
3071*e4b17023SJohn Marino 	    {
3072*e4b17023SJohn Marino 	      if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
3073*e4b17023SJohn Marino 		{
3074*e4b17023SJohn Marino 		  dimen = NULL_TREE;
3075*e4b17023SJohn Marino 		  star_seen = true;
3076*e4b17023SJohn Marino 		  c_parser_consume_token (parser);
3077*e4b17023SJohn Marino 		}
3078*e4b17023SJohn Marino 	      else
3079*e4b17023SJohn Marino 		{
3080*e4b17023SJohn Marino 		  star_seen = false;
3081*e4b17023SJohn Marino 		  dimen = c_parser_expr_no_commas (parser, NULL).value;
3082*e4b17023SJohn Marino 		}
3083*e4b17023SJohn Marino 	    }
3084*e4b17023SJohn Marino 	  else
3085*e4b17023SJohn Marino 	    {
3086*e4b17023SJohn Marino 	      star_seen = false;
3087*e4b17023SJohn Marino 	      dimen = c_parser_expr_no_commas (parser, NULL).value;
3088*e4b17023SJohn Marino 	    }
3089*e4b17023SJohn Marino 	}
3090*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3091*e4b17023SJohn Marino 	c_parser_consume_token (parser);
3092*e4b17023SJohn Marino       else
3093*e4b17023SJohn Marino 	{
3094*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
3095*e4b17023SJohn Marino 				     "expected %<]%>");
3096*e4b17023SJohn Marino 	  return NULL;
3097*e4b17023SJohn Marino 	}
3098*e4b17023SJohn Marino       if (dimen)
3099*e4b17023SJohn Marino 	mark_exp_read (dimen);
3100*e4b17023SJohn Marino       declarator = build_array_declarator (brace_loc, dimen, quals_attrs,
3101*e4b17023SJohn Marino 					   static_seen, star_seen);
3102*e4b17023SJohn Marino       if (declarator == NULL)
3103*e4b17023SJohn Marino 	return NULL;
3104*e4b17023SJohn Marino       inner = set_array_declarator_inner (declarator, inner);
3105*e4b17023SJohn Marino       return c_parser_direct_declarator_inner (parser, id_present, inner);
3106*e4b17023SJohn Marino     }
3107*e4b17023SJohn Marino   else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3108*e4b17023SJohn Marino     {
3109*e4b17023SJohn Marino       tree attrs;
3110*e4b17023SJohn Marino       struct c_arg_info *args;
3111*e4b17023SJohn Marino       c_parser_consume_token (parser);
3112*e4b17023SJohn Marino       attrs = c_parser_attributes (parser);
3113*e4b17023SJohn Marino       args = c_parser_parms_declarator (parser, id_present, attrs);
3114*e4b17023SJohn Marino       if (args == NULL)
3115*e4b17023SJohn Marino 	return NULL;
3116*e4b17023SJohn Marino       else
3117*e4b17023SJohn Marino 	{
3118*e4b17023SJohn Marino 	  inner = build_function_declarator (args, inner);
3119*e4b17023SJohn Marino 	  return c_parser_direct_declarator_inner (parser, id_present, inner);
3120*e4b17023SJohn Marino 	}
3121*e4b17023SJohn Marino     }
3122*e4b17023SJohn Marino   return inner;
3123*e4b17023SJohn Marino }
3124*e4b17023SJohn Marino 
3125*e4b17023SJohn Marino /* Parse a parameter list or identifier list, including the closing
3126*e4b17023SJohn Marino    parenthesis but not the opening one.  ATTRS are the attributes at
3127*e4b17023SJohn Marino    the start of the list.  ID_LIST_OK is true if an identifier list is
3128*e4b17023SJohn Marino    acceptable; such a list must not have attributes at the start.  */
3129*e4b17023SJohn Marino 
3130*e4b17023SJohn Marino static struct c_arg_info *
c_parser_parms_declarator(c_parser * parser,bool id_list_ok,tree attrs)3131*e4b17023SJohn Marino c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs)
3132*e4b17023SJohn Marino {
3133*e4b17023SJohn Marino   push_scope ();
3134*e4b17023SJohn Marino   declare_parm_level ();
3135*e4b17023SJohn Marino   /* If the list starts with an identifier, it is an identifier list.
3136*e4b17023SJohn Marino      Otherwise, it is either a prototype list or an empty list.  */
3137*e4b17023SJohn Marino   if (id_list_ok
3138*e4b17023SJohn Marino       && !attrs
3139*e4b17023SJohn Marino       && c_parser_next_token_is (parser, CPP_NAME)
3140*e4b17023SJohn Marino       && c_parser_peek_token (parser)->id_kind == C_ID_ID
3141*e4b17023SJohn Marino 
3142*e4b17023SJohn Marino       /* Look ahead to detect typos in type names.  */
3143*e4b17023SJohn Marino       && c_parser_peek_2nd_token (parser)->type != CPP_NAME
3144*e4b17023SJohn Marino       && c_parser_peek_2nd_token (parser)->type != CPP_MULT
3145*e4b17023SJohn Marino       && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
3146*e4b17023SJohn Marino       && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE)
3147*e4b17023SJohn Marino     {
3148*e4b17023SJohn Marino       tree list = NULL_TREE, *nextp = &list;
3149*e4b17023SJohn Marino       while (c_parser_next_token_is (parser, CPP_NAME)
3150*e4b17023SJohn Marino 	     && c_parser_peek_token (parser)->id_kind == C_ID_ID)
3151*e4b17023SJohn Marino 	{
3152*e4b17023SJohn Marino 	  *nextp = build_tree_list (NULL_TREE,
3153*e4b17023SJohn Marino 				    c_parser_peek_token (parser)->value);
3154*e4b17023SJohn Marino 	  nextp = & TREE_CHAIN (*nextp);
3155*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
3156*e4b17023SJohn Marino 	  if (c_parser_next_token_is_not (parser, CPP_COMMA))
3157*e4b17023SJohn Marino 	    break;
3158*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
3159*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3160*e4b17023SJohn Marino 	    {
3161*e4b17023SJohn Marino 	      c_parser_error (parser, "expected identifier");
3162*e4b17023SJohn Marino 	      break;
3163*e4b17023SJohn Marino 	    }
3164*e4b17023SJohn Marino 	}
3165*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3166*e4b17023SJohn Marino 	{
3167*e4b17023SJohn Marino 	  struct c_arg_info *ret = build_arg_info ();
3168*e4b17023SJohn Marino 	  ret->types = list;
3169*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
3170*e4b17023SJohn Marino 	  pop_scope ();
3171*e4b17023SJohn Marino 	  return ret;
3172*e4b17023SJohn Marino 	}
3173*e4b17023SJohn Marino       else
3174*e4b17023SJohn Marino 	{
3175*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3176*e4b17023SJohn Marino 				     "expected %<)%>");
3177*e4b17023SJohn Marino 	  pop_scope ();
3178*e4b17023SJohn Marino 	  return NULL;
3179*e4b17023SJohn Marino 	}
3180*e4b17023SJohn Marino     }
3181*e4b17023SJohn Marino   else
3182*e4b17023SJohn Marino     {
3183*e4b17023SJohn Marino       struct c_arg_info *ret = c_parser_parms_list_declarator (parser, attrs,
3184*e4b17023SJohn Marino 							       NULL);
3185*e4b17023SJohn Marino       pop_scope ();
3186*e4b17023SJohn Marino       return ret;
3187*e4b17023SJohn Marino     }
3188*e4b17023SJohn Marino }
3189*e4b17023SJohn Marino 
3190*e4b17023SJohn Marino /* Parse a parameter list (possibly empty), including the closing
3191*e4b17023SJohn Marino    parenthesis but not the opening one.  ATTRS are the attributes at
3192*e4b17023SJohn Marino    the start of the list.  EXPR is NULL or an expression that needs to
3193*e4b17023SJohn Marino    be evaluated for the side effects of array size expressions in the
3194*e4b17023SJohn Marino    parameters.  */
3195*e4b17023SJohn Marino 
3196*e4b17023SJohn Marino static struct c_arg_info *
c_parser_parms_list_declarator(c_parser * parser,tree attrs,tree expr)3197*e4b17023SJohn Marino c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr)
3198*e4b17023SJohn Marino {
3199*e4b17023SJohn Marino   bool bad_parm = false;
3200*e4b17023SJohn Marino 
3201*e4b17023SJohn Marino   /* ??? Following the old parser, forward parameter declarations may
3202*e4b17023SJohn Marino      use abstract declarators, and if no real parameter declarations
3203*e4b17023SJohn Marino      follow the forward declarations then this is not diagnosed.  Also
3204*e4b17023SJohn Marino      note as above that attributes are ignored as the only contents of
3205*e4b17023SJohn Marino      the parentheses, or as the only contents after forward
3206*e4b17023SJohn Marino      declarations.  */
3207*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3208*e4b17023SJohn Marino     {
3209*e4b17023SJohn Marino       struct c_arg_info *ret = build_arg_info ();
3210*e4b17023SJohn Marino       c_parser_consume_token (parser);
3211*e4b17023SJohn Marino       return ret;
3212*e4b17023SJohn Marino     }
3213*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
3214*e4b17023SJohn Marino     {
3215*e4b17023SJohn Marino       struct c_arg_info *ret = build_arg_info ();
3216*e4b17023SJohn Marino 
3217*e4b17023SJohn Marino       if (flag_allow_parameterless_variadic_functions)
3218*e4b17023SJohn Marino         {
3219*e4b17023SJohn Marino           /* F (...) is allowed.  */
3220*e4b17023SJohn Marino           ret->types = NULL_TREE;
3221*e4b17023SJohn Marino         }
3222*e4b17023SJohn Marino       else
3223*e4b17023SJohn Marino         {
3224*e4b17023SJohn Marino           /* Suppress -Wold-style-definition for this case.  */
3225*e4b17023SJohn Marino           ret->types = error_mark_node;
3226*e4b17023SJohn Marino           error_at (c_parser_peek_token (parser)->location,
3227*e4b17023SJohn Marino                     "ISO C requires a named argument before %<...%>");
3228*e4b17023SJohn Marino         }
3229*e4b17023SJohn Marino       c_parser_consume_token (parser);
3230*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3231*e4b17023SJohn Marino 	{
3232*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
3233*e4b17023SJohn Marino 	  return ret;
3234*e4b17023SJohn Marino 	}
3235*e4b17023SJohn Marino       else
3236*e4b17023SJohn Marino 	{
3237*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3238*e4b17023SJohn Marino 				     "expected %<)%>");
3239*e4b17023SJohn Marino 	  return NULL;
3240*e4b17023SJohn Marino 	}
3241*e4b17023SJohn Marino     }
3242*e4b17023SJohn Marino   /* Nonempty list of parameters, either terminated with semicolon
3243*e4b17023SJohn Marino      (forward declarations; recurse) or with close parenthesis (normal
3244*e4b17023SJohn Marino      function) or with ", ... )" (variadic function).  */
3245*e4b17023SJohn Marino   while (true)
3246*e4b17023SJohn Marino     {
3247*e4b17023SJohn Marino       /* Parse a parameter.  */
3248*e4b17023SJohn Marino       struct c_parm *parm = c_parser_parameter_declaration (parser, attrs);
3249*e4b17023SJohn Marino       attrs = NULL_TREE;
3250*e4b17023SJohn Marino       if (parm == NULL)
3251*e4b17023SJohn Marino 	bad_parm = true;
3252*e4b17023SJohn Marino       else
3253*e4b17023SJohn Marino 	push_parm_decl (parm, &expr);
3254*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3255*e4b17023SJohn Marino 	{
3256*e4b17023SJohn Marino 	  tree new_attrs;
3257*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
3258*e4b17023SJohn Marino 	  mark_forward_parm_decls ();
3259*e4b17023SJohn Marino 	  new_attrs = c_parser_attributes (parser);
3260*e4b17023SJohn Marino 	  return c_parser_parms_list_declarator (parser, new_attrs, expr);
3261*e4b17023SJohn Marino 	}
3262*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3263*e4b17023SJohn Marino 	{
3264*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
3265*e4b17023SJohn Marino 	  if (bad_parm)
3266*e4b17023SJohn Marino 	    return NULL;
3267*e4b17023SJohn Marino 	  else
3268*e4b17023SJohn Marino 	    return get_parm_info (false, expr);
3269*e4b17023SJohn Marino 	}
3270*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_COMMA,
3271*e4b17023SJohn Marino 			     "expected %<;%>, %<,%> or %<)%>"))
3272*e4b17023SJohn Marino 	{
3273*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3274*e4b17023SJohn Marino 	  return NULL;
3275*e4b17023SJohn Marino 	}
3276*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
3277*e4b17023SJohn Marino 	{
3278*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
3279*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3280*e4b17023SJohn Marino 	    {
3281*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
3282*e4b17023SJohn Marino 	      if (bad_parm)
3283*e4b17023SJohn Marino 		return NULL;
3284*e4b17023SJohn Marino 	      else
3285*e4b17023SJohn Marino 		return get_parm_info (true, expr);
3286*e4b17023SJohn Marino 	    }
3287*e4b17023SJohn Marino 	  else
3288*e4b17023SJohn Marino 	    {
3289*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3290*e4b17023SJohn Marino 					 "expected %<)%>");
3291*e4b17023SJohn Marino 	      return NULL;
3292*e4b17023SJohn Marino 	    }
3293*e4b17023SJohn Marino 	}
3294*e4b17023SJohn Marino     }
3295*e4b17023SJohn Marino }
3296*e4b17023SJohn Marino 
3297*e4b17023SJohn Marino /* Parse a parameter declaration.  ATTRS are the attributes at the
3298*e4b17023SJohn Marino    start of the declaration if it is the first parameter.  */
3299*e4b17023SJohn Marino 
3300*e4b17023SJohn Marino static struct c_parm *
c_parser_parameter_declaration(c_parser * parser,tree attrs)3301*e4b17023SJohn Marino c_parser_parameter_declaration (c_parser *parser, tree attrs)
3302*e4b17023SJohn Marino {
3303*e4b17023SJohn Marino   struct c_declspecs *specs;
3304*e4b17023SJohn Marino   struct c_declarator *declarator;
3305*e4b17023SJohn Marino   tree prefix_attrs;
3306*e4b17023SJohn Marino   tree postfix_attrs = NULL_TREE;
3307*e4b17023SJohn Marino   bool dummy = false;
3308*e4b17023SJohn Marino   if (!c_parser_next_token_starts_declspecs (parser))
3309*e4b17023SJohn Marino     {
3310*e4b17023SJohn Marino       c_token *token = c_parser_peek_token (parser);
3311*e4b17023SJohn Marino       if (parser->error)
3312*e4b17023SJohn Marino 	return NULL;
3313*e4b17023SJohn Marino       c_parser_set_source_position_from_token (token);
3314*e4b17023SJohn Marino       if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
3315*e4b17023SJohn Marino 	{
3316*e4b17023SJohn Marino 	  error ("unknown type name %qE", token->value);
3317*e4b17023SJohn Marino 	  parser->error = true;
3318*e4b17023SJohn Marino 	}
3319*e4b17023SJohn Marino       /* ??? In some Objective-C cases '...' isn't applicable so there
3320*e4b17023SJohn Marino 	 should be a different message.  */
3321*e4b17023SJohn Marino       else
3322*e4b17023SJohn Marino 	c_parser_error (parser,
3323*e4b17023SJohn Marino 			"expected declaration specifiers or %<...%>");
3324*e4b17023SJohn Marino       c_parser_skip_to_end_of_parameter (parser);
3325*e4b17023SJohn Marino       return NULL;
3326*e4b17023SJohn Marino     }
3327*e4b17023SJohn Marino   specs = build_null_declspecs ();
3328*e4b17023SJohn Marino   if (attrs)
3329*e4b17023SJohn Marino     {
3330*e4b17023SJohn Marino       declspecs_add_attrs (specs, attrs);
3331*e4b17023SJohn Marino       attrs = NULL_TREE;
3332*e4b17023SJohn Marino     }
3333*e4b17023SJohn Marino   c_parser_declspecs (parser, specs, true, true, true, cla_nonabstract_decl);
3334*e4b17023SJohn Marino   finish_declspecs (specs);
3335*e4b17023SJohn Marino   pending_xref_error ();
3336*e4b17023SJohn Marino   prefix_attrs = specs->attrs;
3337*e4b17023SJohn Marino   specs->attrs = NULL_TREE;
3338*e4b17023SJohn Marino   declarator = c_parser_declarator (parser,
3339*e4b17023SJohn Marino 				    specs->typespec_kind != ctsk_none,
3340*e4b17023SJohn Marino 				    C_DTR_PARM, &dummy);
3341*e4b17023SJohn Marino   if (declarator == NULL)
3342*e4b17023SJohn Marino     {
3343*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_COMMA, NULL);
3344*e4b17023SJohn Marino       return NULL;
3345*e4b17023SJohn Marino     }
3346*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3347*e4b17023SJohn Marino     postfix_attrs = c_parser_attributes (parser);
3348*e4b17023SJohn Marino   return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
3349*e4b17023SJohn Marino 		       declarator);
3350*e4b17023SJohn Marino }
3351*e4b17023SJohn Marino 
3352*e4b17023SJohn Marino /* Parse a string literal in an asm expression.  It should not be
3353*e4b17023SJohn Marino    translated, and wide string literals are an error although
3354*e4b17023SJohn Marino    permitted by the syntax.  This is a GNU extension.
3355*e4b17023SJohn Marino 
3356*e4b17023SJohn Marino    asm-string-literal:
3357*e4b17023SJohn Marino      string-literal
3358*e4b17023SJohn Marino 
3359*e4b17023SJohn Marino    ??? At present, following the old parser, the caller needs to have
3360*e4b17023SJohn Marino    set lex_untranslated_string to 1.  It would be better to follow the
3361*e4b17023SJohn Marino    C++ parser rather than using this kludge.  */
3362*e4b17023SJohn Marino 
3363*e4b17023SJohn Marino static tree
c_parser_asm_string_literal(c_parser * parser)3364*e4b17023SJohn Marino c_parser_asm_string_literal (c_parser *parser)
3365*e4b17023SJohn Marino {
3366*e4b17023SJohn Marino   tree str;
3367*e4b17023SJohn Marino   int save_flag = warn_overlength_strings;
3368*e4b17023SJohn Marino   warn_overlength_strings = 0;
3369*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_STRING))
3370*e4b17023SJohn Marino     {
3371*e4b17023SJohn Marino       str = c_parser_peek_token (parser)->value;
3372*e4b17023SJohn Marino       c_parser_consume_token (parser);
3373*e4b17023SJohn Marino     }
3374*e4b17023SJohn Marino   else if (c_parser_next_token_is (parser, CPP_WSTRING))
3375*e4b17023SJohn Marino     {
3376*e4b17023SJohn Marino       error_at (c_parser_peek_token (parser)->location,
3377*e4b17023SJohn Marino 		"wide string literal in %<asm%>");
3378*e4b17023SJohn Marino       str = build_string (1, "");
3379*e4b17023SJohn Marino       c_parser_consume_token (parser);
3380*e4b17023SJohn Marino     }
3381*e4b17023SJohn Marino   else
3382*e4b17023SJohn Marino     {
3383*e4b17023SJohn Marino       c_parser_error (parser, "expected string literal");
3384*e4b17023SJohn Marino       str = NULL_TREE;
3385*e4b17023SJohn Marino     }
3386*e4b17023SJohn Marino   warn_overlength_strings = save_flag;
3387*e4b17023SJohn Marino   return str;
3388*e4b17023SJohn Marino }
3389*e4b17023SJohn Marino 
3390*e4b17023SJohn Marino /* Parse a simple asm expression.  This is used in restricted
3391*e4b17023SJohn Marino    contexts, where a full expression with inputs and outputs does not
3392*e4b17023SJohn Marino    make sense.  This is a GNU extension.
3393*e4b17023SJohn Marino 
3394*e4b17023SJohn Marino    simple-asm-expr:
3395*e4b17023SJohn Marino      asm ( asm-string-literal )
3396*e4b17023SJohn Marino */
3397*e4b17023SJohn Marino 
3398*e4b17023SJohn Marino static tree
c_parser_simple_asm_expr(c_parser * parser)3399*e4b17023SJohn Marino c_parser_simple_asm_expr (c_parser *parser)
3400*e4b17023SJohn Marino {
3401*e4b17023SJohn Marino   tree str;
3402*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
3403*e4b17023SJohn Marino   /* ??? Follow the C++ parser rather than using the
3404*e4b17023SJohn Marino      lex_untranslated_string kludge.  */
3405*e4b17023SJohn Marino   parser->lex_untranslated_string = true;
3406*e4b17023SJohn Marino   c_parser_consume_token (parser);
3407*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
3408*e4b17023SJohn Marino     {
3409*e4b17023SJohn Marino       parser->lex_untranslated_string = false;
3410*e4b17023SJohn Marino       return NULL_TREE;
3411*e4b17023SJohn Marino     }
3412*e4b17023SJohn Marino   str = c_parser_asm_string_literal (parser);
3413*e4b17023SJohn Marino   parser->lex_untranslated_string = false;
3414*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
3415*e4b17023SJohn Marino     {
3416*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3417*e4b17023SJohn Marino       return NULL_TREE;
3418*e4b17023SJohn Marino     }
3419*e4b17023SJohn Marino   return str;
3420*e4b17023SJohn Marino }
3421*e4b17023SJohn Marino 
3422*e4b17023SJohn Marino static tree
c_parser_attribute_any_word(c_parser * parser)3423*e4b17023SJohn Marino c_parser_attribute_any_word (c_parser *parser)
3424*e4b17023SJohn Marino {
3425*e4b17023SJohn Marino   tree attr_name = NULL_TREE;
3426*e4b17023SJohn Marino 
3427*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_KEYWORD))
3428*e4b17023SJohn Marino     {
3429*e4b17023SJohn Marino       /* ??? See comment above about what keywords are accepted here.  */
3430*e4b17023SJohn Marino       bool ok;
3431*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->keyword)
3432*e4b17023SJohn Marino 	{
3433*e4b17023SJohn Marino 	case RID_STATIC:
3434*e4b17023SJohn Marino 	case RID_UNSIGNED:
3435*e4b17023SJohn Marino 	case RID_LONG:
3436*e4b17023SJohn Marino 	case RID_INT128:
3437*e4b17023SJohn Marino 	case RID_CONST:
3438*e4b17023SJohn Marino 	case RID_EXTERN:
3439*e4b17023SJohn Marino 	case RID_REGISTER:
3440*e4b17023SJohn Marino 	case RID_TYPEDEF:
3441*e4b17023SJohn Marino 	case RID_SHORT:
3442*e4b17023SJohn Marino 	case RID_INLINE:
3443*e4b17023SJohn Marino 	case RID_NORETURN:
3444*e4b17023SJohn Marino 	case RID_VOLATILE:
3445*e4b17023SJohn Marino 	case RID_SIGNED:
3446*e4b17023SJohn Marino 	case RID_AUTO:
3447*e4b17023SJohn Marino 	case RID_RESTRICT:
3448*e4b17023SJohn Marino 	case RID_COMPLEX:
3449*e4b17023SJohn Marino 	case RID_THREAD:
3450*e4b17023SJohn Marino 	case RID_INT:
3451*e4b17023SJohn Marino 	case RID_CHAR:
3452*e4b17023SJohn Marino 	case RID_FLOAT:
3453*e4b17023SJohn Marino 	case RID_DOUBLE:
3454*e4b17023SJohn Marino 	case RID_VOID:
3455*e4b17023SJohn Marino 	case RID_DFLOAT32:
3456*e4b17023SJohn Marino 	case RID_DFLOAT64:
3457*e4b17023SJohn Marino 	case RID_DFLOAT128:
3458*e4b17023SJohn Marino 	case RID_BOOL:
3459*e4b17023SJohn Marino 	case RID_FRACT:
3460*e4b17023SJohn Marino 	case RID_ACCUM:
3461*e4b17023SJohn Marino 	case RID_SAT:
3462*e4b17023SJohn Marino 	case RID_TRANSACTION_ATOMIC:
3463*e4b17023SJohn Marino 	case RID_TRANSACTION_CANCEL:
3464*e4b17023SJohn Marino 	  ok = true;
3465*e4b17023SJohn Marino 	  break;
3466*e4b17023SJohn Marino 	default:
3467*e4b17023SJohn Marino 	  ok = false;
3468*e4b17023SJohn Marino 	  break;
3469*e4b17023SJohn Marino 	}
3470*e4b17023SJohn Marino       if (!ok)
3471*e4b17023SJohn Marino 	return NULL_TREE;
3472*e4b17023SJohn Marino 
3473*e4b17023SJohn Marino       /* Accept __attribute__((__const)) as __attribute__((const)) etc.  */
3474*e4b17023SJohn Marino       attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
3475*e4b17023SJohn Marino     }
3476*e4b17023SJohn Marino   else if (c_parser_next_token_is (parser, CPP_NAME))
3477*e4b17023SJohn Marino     attr_name = c_parser_peek_token (parser)->value;
3478*e4b17023SJohn Marino 
3479*e4b17023SJohn Marino   return attr_name;
3480*e4b17023SJohn Marino }
3481*e4b17023SJohn Marino 
3482*e4b17023SJohn Marino /* Parse (possibly empty) attributes.  This is a GNU extension.
3483*e4b17023SJohn Marino 
3484*e4b17023SJohn Marino    attributes:
3485*e4b17023SJohn Marino      empty
3486*e4b17023SJohn Marino      attributes attribute
3487*e4b17023SJohn Marino 
3488*e4b17023SJohn Marino    attribute:
3489*e4b17023SJohn Marino      __attribute__ ( ( attribute-list ) )
3490*e4b17023SJohn Marino 
3491*e4b17023SJohn Marino    attribute-list:
3492*e4b17023SJohn Marino      attrib
3493*e4b17023SJohn Marino      attribute_list , attrib
3494*e4b17023SJohn Marino 
3495*e4b17023SJohn Marino    attrib:
3496*e4b17023SJohn Marino      empty
3497*e4b17023SJohn Marino      any-word
3498*e4b17023SJohn Marino      any-word ( identifier )
3499*e4b17023SJohn Marino      any-word ( identifier , nonempty-expr-list )
3500*e4b17023SJohn Marino      any-word ( expr-list )
3501*e4b17023SJohn Marino 
3502*e4b17023SJohn Marino    where the "identifier" must not be declared as a type, and
3503*e4b17023SJohn Marino    "any-word" may be any identifier (including one declared as a
3504*e4b17023SJohn Marino    type), a reserved word storage class specifier, type specifier or
3505*e4b17023SJohn Marino    type qualifier.  ??? This still leaves out most reserved keywords
3506*e4b17023SJohn Marino    (following the old parser), shouldn't we include them, and why not
3507*e4b17023SJohn Marino    allow identifiers declared as types to start the arguments?  */
3508*e4b17023SJohn Marino 
3509*e4b17023SJohn Marino static tree
c_parser_attributes(c_parser * parser)3510*e4b17023SJohn Marino c_parser_attributes (c_parser *parser)
3511*e4b17023SJohn Marino {
3512*e4b17023SJohn Marino   tree attrs = NULL_TREE;
3513*e4b17023SJohn Marino   while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3514*e4b17023SJohn Marino     {
3515*e4b17023SJohn Marino       /* ??? Follow the C++ parser rather than using the
3516*e4b17023SJohn Marino 	 lex_untranslated_string kludge.  */
3517*e4b17023SJohn Marino       parser->lex_untranslated_string = true;
3518*e4b17023SJohn Marino       c_parser_consume_token (parser);
3519*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
3520*e4b17023SJohn Marino 	{
3521*e4b17023SJohn Marino 	  parser->lex_untranslated_string = false;
3522*e4b17023SJohn Marino 	  return attrs;
3523*e4b17023SJohn Marino 	}
3524*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
3525*e4b17023SJohn Marino 	{
3526*e4b17023SJohn Marino 	  parser->lex_untranslated_string = false;
3527*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3528*e4b17023SJohn Marino 	  return attrs;
3529*e4b17023SJohn Marino 	}
3530*e4b17023SJohn Marino       /* Parse the attribute list.  */
3531*e4b17023SJohn Marino       while (c_parser_next_token_is (parser, CPP_COMMA)
3532*e4b17023SJohn Marino 	     || c_parser_next_token_is (parser, CPP_NAME)
3533*e4b17023SJohn Marino 	     || c_parser_next_token_is (parser, CPP_KEYWORD))
3534*e4b17023SJohn Marino 	{
3535*e4b17023SJohn Marino 	  tree attr, attr_name, attr_args;
3536*e4b17023SJohn Marino 	  VEC(tree,gc) *expr_list;
3537*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_COMMA))
3538*e4b17023SJohn Marino 	    {
3539*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
3540*e4b17023SJohn Marino 	      continue;
3541*e4b17023SJohn Marino 	    }
3542*e4b17023SJohn Marino 
3543*e4b17023SJohn Marino 	  attr_name = c_parser_attribute_any_word (parser);
3544*e4b17023SJohn Marino 	  if (attr_name == NULL)
3545*e4b17023SJohn Marino 	    break;
3546*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
3547*e4b17023SJohn Marino 	  if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
3548*e4b17023SJohn Marino 	    {
3549*e4b17023SJohn Marino 	      attr = build_tree_list (attr_name, NULL_TREE);
3550*e4b17023SJohn Marino 	      attrs = chainon (attrs, attr);
3551*e4b17023SJohn Marino 	      continue;
3552*e4b17023SJohn Marino 	    }
3553*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
3554*e4b17023SJohn Marino 	  /* Parse the attribute contents.  If they start with an
3555*e4b17023SJohn Marino 	     identifier which is followed by a comma or close
3556*e4b17023SJohn Marino 	     parenthesis, then the arguments start with that
3557*e4b17023SJohn Marino 	     identifier; otherwise they are an expression list.
3558*e4b17023SJohn Marino 	     In objective-c the identifier may be a classname.  */
3559*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_NAME)
3560*e4b17023SJohn Marino 	      && (c_parser_peek_token (parser)->id_kind == C_ID_ID
3561*e4b17023SJohn Marino 		  || (c_dialect_objc ()
3562*e4b17023SJohn Marino 		      && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3563*e4b17023SJohn Marino 	      && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
3564*e4b17023SJohn Marino 		  || (c_parser_peek_2nd_token (parser)->type
3565*e4b17023SJohn Marino 		      == CPP_CLOSE_PAREN)))
3566*e4b17023SJohn Marino 	    {
3567*e4b17023SJohn Marino 	      tree arg1 = c_parser_peek_token (parser)->value;
3568*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
3569*e4b17023SJohn Marino 	      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3570*e4b17023SJohn Marino 		attr_args = build_tree_list (NULL_TREE, arg1);
3571*e4b17023SJohn Marino 	      else
3572*e4b17023SJohn Marino 		{
3573*e4b17023SJohn Marino 		  tree tree_list;
3574*e4b17023SJohn Marino 		  c_parser_consume_token (parser);
3575*e4b17023SJohn Marino 		  expr_list = c_parser_expr_list (parser, false, true, NULL);
3576*e4b17023SJohn Marino 		  tree_list = build_tree_list_vec (expr_list);
3577*e4b17023SJohn Marino 		  attr_args = tree_cons (NULL_TREE, arg1, tree_list);
3578*e4b17023SJohn Marino 		  release_tree_vector (expr_list);
3579*e4b17023SJohn Marino 		}
3580*e4b17023SJohn Marino 	    }
3581*e4b17023SJohn Marino 	  else
3582*e4b17023SJohn Marino 	    {
3583*e4b17023SJohn Marino 	      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3584*e4b17023SJohn Marino 		attr_args = NULL_TREE;
3585*e4b17023SJohn Marino 	      else
3586*e4b17023SJohn Marino 		{
3587*e4b17023SJohn Marino 		  expr_list = c_parser_expr_list (parser, false, true, NULL);
3588*e4b17023SJohn Marino 		  attr_args = build_tree_list_vec (expr_list);
3589*e4b17023SJohn Marino 		  release_tree_vector (expr_list);
3590*e4b17023SJohn Marino 		}
3591*e4b17023SJohn Marino 	    }
3592*e4b17023SJohn Marino 	  attr = build_tree_list (attr_name, attr_args);
3593*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3594*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
3595*e4b17023SJohn Marino 	  else
3596*e4b17023SJohn Marino 	    {
3597*e4b17023SJohn Marino 	      parser->lex_untranslated_string = false;
3598*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3599*e4b17023SJohn Marino 					 "expected %<)%>");
3600*e4b17023SJohn Marino 	      return attrs;
3601*e4b17023SJohn Marino 	    }
3602*e4b17023SJohn Marino 	  attrs = chainon (attrs, attr);
3603*e4b17023SJohn Marino 	}
3604*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3605*e4b17023SJohn Marino 	c_parser_consume_token (parser);
3606*e4b17023SJohn Marino       else
3607*e4b17023SJohn Marino 	{
3608*e4b17023SJohn Marino 	  parser->lex_untranslated_string = false;
3609*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3610*e4b17023SJohn Marino 				     "expected %<)%>");
3611*e4b17023SJohn Marino 	  return attrs;
3612*e4b17023SJohn Marino 	}
3613*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3614*e4b17023SJohn Marino 	c_parser_consume_token (parser);
3615*e4b17023SJohn Marino       else
3616*e4b17023SJohn Marino 	{
3617*e4b17023SJohn Marino 	  parser->lex_untranslated_string = false;
3618*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3619*e4b17023SJohn Marino 				     "expected %<)%>");
3620*e4b17023SJohn Marino 	  return attrs;
3621*e4b17023SJohn Marino 	}
3622*e4b17023SJohn Marino       parser->lex_untranslated_string = false;
3623*e4b17023SJohn Marino     }
3624*e4b17023SJohn Marino   return attrs;
3625*e4b17023SJohn Marino }
3626*e4b17023SJohn Marino 
3627*e4b17023SJohn Marino /* Parse a type name (C90 6.5.5, C99 6.7.6).
3628*e4b17023SJohn Marino 
3629*e4b17023SJohn Marino    type-name:
3630*e4b17023SJohn Marino      specifier-qualifier-list abstract-declarator[opt]
3631*e4b17023SJohn Marino */
3632*e4b17023SJohn Marino 
3633*e4b17023SJohn Marino static struct c_type_name *
c_parser_type_name(c_parser * parser)3634*e4b17023SJohn Marino c_parser_type_name (c_parser *parser)
3635*e4b17023SJohn Marino {
3636*e4b17023SJohn Marino   struct c_declspecs *specs = build_null_declspecs ();
3637*e4b17023SJohn Marino   struct c_declarator *declarator;
3638*e4b17023SJohn Marino   struct c_type_name *ret;
3639*e4b17023SJohn Marino   bool dummy = false;
3640*e4b17023SJohn Marino   c_parser_declspecs (parser, specs, false, true, true, cla_prefer_type);
3641*e4b17023SJohn Marino   if (!specs->declspecs_seen_p)
3642*e4b17023SJohn Marino     {
3643*e4b17023SJohn Marino       c_parser_error (parser, "expected specifier-qualifier-list");
3644*e4b17023SJohn Marino       return NULL;
3645*e4b17023SJohn Marino     }
3646*e4b17023SJohn Marino   if (specs->type != error_mark_node)
3647*e4b17023SJohn Marino     {
3648*e4b17023SJohn Marino       pending_xref_error ();
3649*e4b17023SJohn Marino       finish_declspecs (specs);
3650*e4b17023SJohn Marino     }
3651*e4b17023SJohn Marino   declarator = c_parser_declarator (parser,
3652*e4b17023SJohn Marino 				    specs->typespec_kind != ctsk_none,
3653*e4b17023SJohn Marino 				    C_DTR_ABSTRACT, &dummy);
3654*e4b17023SJohn Marino   if (declarator == NULL)
3655*e4b17023SJohn Marino     return NULL;
3656*e4b17023SJohn Marino   ret = XOBNEW (&parser_obstack, struct c_type_name);
3657*e4b17023SJohn Marino   ret->specs = specs;
3658*e4b17023SJohn Marino   ret->declarator = declarator;
3659*e4b17023SJohn Marino   return ret;
3660*e4b17023SJohn Marino }
3661*e4b17023SJohn Marino 
3662*e4b17023SJohn Marino /* Parse an initializer (C90 6.5.7, C99 6.7.8).
3663*e4b17023SJohn Marino 
3664*e4b17023SJohn Marino    initializer:
3665*e4b17023SJohn Marino      assignment-expression
3666*e4b17023SJohn Marino      { initializer-list }
3667*e4b17023SJohn Marino      { initializer-list , }
3668*e4b17023SJohn Marino 
3669*e4b17023SJohn Marino    initializer-list:
3670*e4b17023SJohn Marino      designation[opt] initializer
3671*e4b17023SJohn Marino      initializer-list , designation[opt] initializer
3672*e4b17023SJohn Marino 
3673*e4b17023SJohn Marino    designation:
3674*e4b17023SJohn Marino      designator-list =
3675*e4b17023SJohn Marino 
3676*e4b17023SJohn Marino    designator-list:
3677*e4b17023SJohn Marino      designator
3678*e4b17023SJohn Marino      designator-list designator
3679*e4b17023SJohn Marino 
3680*e4b17023SJohn Marino    designator:
3681*e4b17023SJohn Marino      array-designator
3682*e4b17023SJohn Marino      . identifier
3683*e4b17023SJohn Marino 
3684*e4b17023SJohn Marino    array-designator:
3685*e4b17023SJohn Marino      [ constant-expression ]
3686*e4b17023SJohn Marino 
3687*e4b17023SJohn Marino    GNU extensions:
3688*e4b17023SJohn Marino 
3689*e4b17023SJohn Marino    initializer:
3690*e4b17023SJohn Marino      { }
3691*e4b17023SJohn Marino 
3692*e4b17023SJohn Marino    designation:
3693*e4b17023SJohn Marino      array-designator
3694*e4b17023SJohn Marino      identifier :
3695*e4b17023SJohn Marino 
3696*e4b17023SJohn Marino    array-designator:
3697*e4b17023SJohn Marino      [ constant-expression ... constant-expression ]
3698*e4b17023SJohn Marino 
3699*e4b17023SJohn Marino    Any expression without commas is accepted in the syntax for the
3700*e4b17023SJohn Marino    constant-expressions, with non-constant expressions rejected later.
3701*e4b17023SJohn Marino 
3702*e4b17023SJohn Marino    This function is only used for top-level initializers; for nested
3703*e4b17023SJohn Marino    ones, see c_parser_initval.  */
3704*e4b17023SJohn Marino 
3705*e4b17023SJohn Marino static struct c_expr
c_parser_initializer(c_parser * parser)3706*e4b17023SJohn Marino c_parser_initializer (c_parser *parser)
3707*e4b17023SJohn Marino {
3708*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3709*e4b17023SJohn Marino     return c_parser_braced_init (parser, NULL_TREE, false);
3710*e4b17023SJohn Marino   else
3711*e4b17023SJohn Marino     {
3712*e4b17023SJohn Marino       struct c_expr ret;
3713*e4b17023SJohn Marino       location_t loc = c_parser_peek_token (parser)->location;
3714*e4b17023SJohn Marino       ret = c_parser_expr_no_commas (parser, NULL);
3715*e4b17023SJohn Marino       if (TREE_CODE (ret.value) != STRING_CST
3716*e4b17023SJohn Marino 	  && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
3717*e4b17023SJohn Marino 	ret = default_function_array_read_conversion (loc, ret);
3718*e4b17023SJohn Marino       return ret;
3719*e4b17023SJohn Marino     }
3720*e4b17023SJohn Marino }
3721*e4b17023SJohn Marino 
3722*e4b17023SJohn Marino /* Parse a braced initializer list.  TYPE is the type specified for a
3723*e4b17023SJohn Marino    compound literal, and NULL_TREE for other initializers and for
3724*e4b17023SJohn Marino    nested braced lists.  NESTED_P is true for nested braced lists,
3725*e4b17023SJohn Marino    false for the list of a compound literal or the list that is the
3726*e4b17023SJohn Marino    top-level initializer in a declaration.  */
3727*e4b17023SJohn Marino 
3728*e4b17023SJohn Marino static struct c_expr
c_parser_braced_init(c_parser * parser,tree type,bool nested_p)3729*e4b17023SJohn Marino c_parser_braced_init (c_parser *parser, tree type, bool nested_p)
3730*e4b17023SJohn Marino {
3731*e4b17023SJohn Marino   struct c_expr ret;
3732*e4b17023SJohn Marino   struct obstack braced_init_obstack;
3733*e4b17023SJohn Marino   location_t brace_loc = c_parser_peek_token (parser)->location;
3734*e4b17023SJohn Marino   gcc_obstack_init (&braced_init_obstack);
3735*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
3736*e4b17023SJohn Marino   c_parser_consume_token (parser);
3737*e4b17023SJohn Marino   if (nested_p)
3738*e4b17023SJohn Marino     push_init_level (0, &braced_init_obstack);
3739*e4b17023SJohn Marino   else
3740*e4b17023SJohn Marino     really_start_incremental_init (type);
3741*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3742*e4b17023SJohn Marino     {
3743*e4b17023SJohn Marino       pedwarn (brace_loc, OPT_pedantic, "ISO C forbids empty initializer braces");
3744*e4b17023SJohn Marino     }
3745*e4b17023SJohn Marino   else
3746*e4b17023SJohn Marino     {
3747*e4b17023SJohn Marino       /* Parse a non-empty initializer list, possibly with a trailing
3748*e4b17023SJohn Marino 	 comma.  */
3749*e4b17023SJohn Marino       while (true)
3750*e4b17023SJohn Marino 	{
3751*e4b17023SJohn Marino 	  c_parser_initelt (parser, &braced_init_obstack);
3752*e4b17023SJohn Marino 	  if (parser->error)
3753*e4b17023SJohn Marino 	    break;
3754*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_COMMA))
3755*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
3756*e4b17023SJohn Marino 	  else
3757*e4b17023SJohn Marino 	    break;
3758*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3759*e4b17023SJohn Marino 	    break;
3760*e4b17023SJohn Marino 	}
3761*e4b17023SJohn Marino     }
3762*e4b17023SJohn Marino   if (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
3763*e4b17023SJohn Marino     {
3764*e4b17023SJohn Marino       ret.value = error_mark_node;
3765*e4b17023SJohn Marino       ret.original_code = ERROR_MARK;
3766*e4b17023SJohn Marino       ret.original_type = NULL;
3767*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, "expected %<}%>");
3768*e4b17023SJohn Marino       pop_init_level (0, &braced_init_obstack);
3769*e4b17023SJohn Marino       obstack_free (&braced_init_obstack, NULL);
3770*e4b17023SJohn Marino       return ret;
3771*e4b17023SJohn Marino     }
3772*e4b17023SJohn Marino   c_parser_consume_token (parser);
3773*e4b17023SJohn Marino   ret = pop_init_level (0, &braced_init_obstack);
3774*e4b17023SJohn Marino   obstack_free (&braced_init_obstack, NULL);
3775*e4b17023SJohn Marino   return ret;
3776*e4b17023SJohn Marino }
3777*e4b17023SJohn Marino 
3778*e4b17023SJohn Marino /* Parse a nested initializer, including designators.  */
3779*e4b17023SJohn Marino 
3780*e4b17023SJohn Marino static void
c_parser_initelt(c_parser * parser,struct obstack * braced_init_obstack)3781*e4b17023SJohn Marino c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
3782*e4b17023SJohn Marino {
3783*e4b17023SJohn Marino   /* Parse any designator or designator list.  A single array
3784*e4b17023SJohn Marino      designator may have the subsequent "=" omitted in GNU C, but a
3785*e4b17023SJohn Marino      longer list or a structure member designator may not.  */
3786*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_NAME)
3787*e4b17023SJohn Marino       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
3788*e4b17023SJohn Marino     {
3789*e4b17023SJohn Marino       /* Old-style structure member designator.  */
3790*e4b17023SJohn Marino       set_init_label (c_parser_peek_token (parser)->value,
3791*e4b17023SJohn Marino 		      braced_init_obstack);
3792*e4b17023SJohn Marino       /* Use the colon as the error location.  */
3793*e4b17023SJohn Marino       pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_pedantic,
3794*e4b17023SJohn Marino 	       "obsolete use of designated initializer with %<:%>");
3795*e4b17023SJohn Marino       c_parser_consume_token (parser);
3796*e4b17023SJohn Marino       c_parser_consume_token (parser);
3797*e4b17023SJohn Marino     }
3798*e4b17023SJohn Marino   else
3799*e4b17023SJohn Marino     {
3800*e4b17023SJohn Marino       /* des_seen is 0 if there have been no designators, 1 if there
3801*e4b17023SJohn Marino 	 has been a single array designator and 2 otherwise.  */
3802*e4b17023SJohn Marino       int des_seen = 0;
3803*e4b17023SJohn Marino       /* Location of a designator.  */
3804*e4b17023SJohn Marino       location_t des_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
3805*e4b17023SJohn Marino       while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3806*e4b17023SJohn Marino 	     || c_parser_next_token_is (parser, CPP_DOT))
3807*e4b17023SJohn Marino 	{
3808*e4b17023SJohn Marino 	  int des_prev = des_seen;
3809*e4b17023SJohn Marino 	  if (!des_seen)
3810*e4b17023SJohn Marino 	    des_loc = c_parser_peek_token (parser)->location;
3811*e4b17023SJohn Marino 	  if (des_seen < 2)
3812*e4b17023SJohn Marino 	    des_seen++;
3813*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_DOT))
3814*e4b17023SJohn Marino 	    {
3815*e4b17023SJohn Marino 	      des_seen = 2;
3816*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
3817*e4b17023SJohn Marino 	      if (c_parser_next_token_is (parser, CPP_NAME))
3818*e4b17023SJohn Marino 		{
3819*e4b17023SJohn Marino 		  set_init_label (c_parser_peek_token (parser)->value,
3820*e4b17023SJohn Marino 				  braced_init_obstack);
3821*e4b17023SJohn Marino 		  c_parser_consume_token (parser);
3822*e4b17023SJohn Marino 		}
3823*e4b17023SJohn Marino 	      else
3824*e4b17023SJohn Marino 		{
3825*e4b17023SJohn Marino 		  struct c_expr init;
3826*e4b17023SJohn Marino 		  init.value = error_mark_node;
3827*e4b17023SJohn Marino 		  init.original_code = ERROR_MARK;
3828*e4b17023SJohn Marino 		  init.original_type = NULL;
3829*e4b17023SJohn Marino 		  c_parser_error (parser, "expected identifier");
3830*e4b17023SJohn Marino 		  c_parser_skip_until_found (parser, CPP_COMMA, NULL);
3831*e4b17023SJohn Marino 		  process_init_element (init, false, braced_init_obstack);
3832*e4b17023SJohn Marino 		  return;
3833*e4b17023SJohn Marino 		}
3834*e4b17023SJohn Marino 	    }
3835*e4b17023SJohn Marino 	  else
3836*e4b17023SJohn Marino 	    {
3837*e4b17023SJohn Marino 	      tree first, second;
3838*e4b17023SJohn Marino 	      location_t ellipsis_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
3839*e4b17023SJohn Marino 	      /* ??? Following the old parser, [ objc-receiver
3840*e4b17023SJohn Marino 		 objc-message-args ] is accepted as an initializer,
3841*e4b17023SJohn Marino 		 being distinguished from a designator by what follows
3842*e4b17023SJohn Marino 		 the first assignment expression inside the square
3843*e4b17023SJohn Marino 		 brackets, but after a first array designator a
3844*e4b17023SJohn Marino 		 subsequent square bracket is for Objective-C taken to
3845*e4b17023SJohn Marino 		 start an expression, using the obsolete form of
3846*e4b17023SJohn Marino 		 designated initializer without '=', rather than
3847*e4b17023SJohn Marino 		 possibly being a second level of designation: in LALR
3848*e4b17023SJohn Marino 		 terms, the '[' is shifted rather than reducing
3849*e4b17023SJohn Marino 		 designator to designator-list.  */
3850*e4b17023SJohn Marino 	      if (des_prev == 1 && c_dialect_objc ())
3851*e4b17023SJohn Marino 		{
3852*e4b17023SJohn Marino 		  des_seen = des_prev;
3853*e4b17023SJohn Marino 		  break;
3854*e4b17023SJohn Marino 		}
3855*e4b17023SJohn Marino 	      if (des_prev == 0 && c_dialect_objc ())
3856*e4b17023SJohn Marino 		{
3857*e4b17023SJohn Marino 		  /* This might be an array designator or an
3858*e4b17023SJohn Marino 		     Objective-C message expression.  If the former,
3859*e4b17023SJohn Marino 		     continue parsing here; if the latter, parse the
3860*e4b17023SJohn Marino 		     remainder of the initializer given the starting
3861*e4b17023SJohn Marino 		     primary-expression.  ??? It might make sense to
3862*e4b17023SJohn Marino 		     distinguish when des_prev == 1 as well; see
3863*e4b17023SJohn Marino 		     previous comment.  */
3864*e4b17023SJohn Marino 		  tree rec, args;
3865*e4b17023SJohn Marino 		  struct c_expr mexpr;
3866*e4b17023SJohn Marino 		  c_parser_consume_token (parser);
3867*e4b17023SJohn Marino 		  if (c_parser_peek_token (parser)->type == CPP_NAME
3868*e4b17023SJohn Marino 		      && ((c_parser_peek_token (parser)->id_kind
3869*e4b17023SJohn Marino 			   == C_ID_TYPENAME)
3870*e4b17023SJohn Marino 			  || (c_parser_peek_token (parser)->id_kind
3871*e4b17023SJohn Marino 			      == C_ID_CLASSNAME)))
3872*e4b17023SJohn Marino 		    {
3873*e4b17023SJohn Marino 		      /* Type name receiver.  */
3874*e4b17023SJohn Marino 		      tree id = c_parser_peek_token (parser)->value;
3875*e4b17023SJohn Marino 		      c_parser_consume_token (parser);
3876*e4b17023SJohn Marino 		      rec = objc_get_class_reference (id);
3877*e4b17023SJohn Marino 		      goto parse_message_args;
3878*e4b17023SJohn Marino 		    }
3879*e4b17023SJohn Marino 		  first = c_parser_expr_no_commas (parser, NULL).value;
3880*e4b17023SJohn Marino 		  mark_exp_read (first);
3881*e4b17023SJohn Marino 		  if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
3882*e4b17023SJohn Marino 		      || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3883*e4b17023SJohn Marino 		    goto array_desig_after_first;
3884*e4b17023SJohn Marino 		  /* Expression receiver.  So far only one part
3885*e4b17023SJohn Marino 		     without commas has been parsed; there might be
3886*e4b17023SJohn Marino 		     more of the expression.  */
3887*e4b17023SJohn Marino 		  rec = first;
3888*e4b17023SJohn Marino 		  while (c_parser_next_token_is (parser, CPP_COMMA))
3889*e4b17023SJohn Marino 		    {
3890*e4b17023SJohn Marino 		      struct c_expr next;
3891*e4b17023SJohn Marino 		      location_t comma_loc, exp_loc;
3892*e4b17023SJohn Marino 		      comma_loc = c_parser_peek_token (parser)->location;
3893*e4b17023SJohn Marino 		      c_parser_consume_token (parser);
3894*e4b17023SJohn Marino 		      exp_loc = c_parser_peek_token (parser)->location;
3895*e4b17023SJohn Marino 		      next = c_parser_expr_no_commas (parser, NULL);
3896*e4b17023SJohn Marino 		      next = default_function_array_read_conversion (exp_loc,
3897*e4b17023SJohn Marino 								     next);
3898*e4b17023SJohn Marino 		      rec = build_compound_expr (comma_loc, rec, next.value);
3899*e4b17023SJohn Marino 		    }
3900*e4b17023SJohn Marino 		parse_message_args:
3901*e4b17023SJohn Marino 		  /* Now parse the objc-message-args.  */
3902*e4b17023SJohn Marino 		  args = c_parser_objc_message_args (parser);
3903*e4b17023SJohn Marino 		  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
3904*e4b17023SJohn Marino 					     "expected %<]%>");
3905*e4b17023SJohn Marino 		  mexpr.value
3906*e4b17023SJohn Marino 		    = objc_build_message_expr (rec, args);
3907*e4b17023SJohn Marino 		  mexpr.original_code = ERROR_MARK;
3908*e4b17023SJohn Marino 		  mexpr.original_type = NULL;
3909*e4b17023SJohn Marino 		  /* Now parse and process the remainder of the
3910*e4b17023SJohn Marino 		     initializer, starting with this message
3911*e4b17023SJohn Marino 		     expression as a primary-expression.  */
3912*e4b17023SJohn Marino 		  c_parser_initval (parser, &mexpr, braced_init_obstack);
3913*e4b17023SJohn Marino 		  return;
3914*e4b17023SJohn Marino 		}
3915*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
3916*e4b17023SJohn Marino 	      first = c_parser_expr_no_commas (parser, NULL).value;
3917*e4b17023SJohn Marino 	      mark_exp_read (first);
3918*e4b17023SJohn Marino 	    array_desig_after_first:
3919*e4b17023SJohn Marino 	      if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
3920*e4b17023SJohn Marino 		{
3921*e4b17023SJohn Marino 		  ellipsis_loc = c_parser_peek_token (parser)->location;
3922*e4b17023SJohn Marino 		  c_parser_consume_token (parser);
3923*e4b17023SJohn Marino 		  second = c_parser_expr_no_commas (parser, NULL).value;
3924*e4b17023SJohn Marino 		  mark_exp_read (second);
3925*e4b17023SJohn Marino 		}
3926*e4b17023SJohn Marino 	      else
3927*e4b17023SJohn Marino 		second = NULL_TREE;
3928*e4b17023SJohn Marino 	      if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3929*e4b17023SJohn Marino 		{
3930*e4b17023SJohn Marino 		  c_parser_consume_token (parser);
3931*e4b17023SJohn Marino 		  set_init_index (first, second, braced_init_obstack);
3932*e4b17023SJohn Marino 		  if (second)
3933*e4b17023SJohn Marino 		    pedwarn (ellipsis_loc, OPT_pedantic,
3934*e4b17023SJohn Marino 			     "ISO C forbids specifying range of elements to initialize");
3935*e4b17023SJohn Marino 		}
3936*e4b17023SJohn Marino 	      else
3937*e4b17023SJohn Marino 		c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
3938*e4b17023SJohn Marino 					   "expected %<]%>");
3939*e4b17023SJohn Marino 	    }
3940*e4b17023SJohn Marino 	}
3941*e4b17023SJohn Marino       if (des_seen >= 1)
3942*e4b17023SJohn Marino 	{
3943*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_EQ))
3944*e4b17023SJohn Marino 	    {
3945*e4b17023SJohn Marino 	      if (!flag_isoc99)
3946*e4b17023SJohn Marino 		pedwarn (des_loc, OPT_pedantic,
3947*e4b17023SJohn Marino 			 "ISO C90 forbids specifying subobject to initialize");
3948*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
3949*e4b17023SJohn Marino 	    }
3950*e4b17023SJohn Marino 	  else
3951*e4b17023SJohn Marino 	    {
3952*e4b17023SJohn Marino 	      if (des_seen == 1)
3953*e4b17023SJohn Marino 		pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
3954*e4b17023SJohn Marino 			 "obsolete use of designated initializer without %<=%>");
3955*e4b17023SJohn Marino 	      else
3956*e4b17023SJohn Marino 		{
3957*e4b17023SJohn Marino 		  struct c_expr init;
3958*e4b17023SJohn Marino 		  init.value = error_mark_node;
3959*e4b17023SJohn Marino 		  init.original_code = ERROR_MARK;
3960*e4b17023SJohn Marino 		  init.original_type = NULL;
3961*e4b17023SJohn Marino 		  c_parser_error (parser, "expected %<=%>");
3962*e4b17023SJohn Marino 		  c_parser_skip_until_found (parser, CPP_COMMA, NULL);
3963*e4b17023SJohn Marino 		  process_init_element (init, false, braced_init_obstack);
3964*e4b17023SJohn Marino 		  return;
3965*e4b17023SJohn Marino 		}
3966*e4b17023SJohn Marino 	    }
3967*e4b17023SJohn Marino 	}
3968*e4b17023SJohn Marino     }
3969*e4b17023SJohn Marino   c_parser_initval (parser, NULL, braced_init_obstack);
3970*e4b17023SJohn Marino }
3971*e4b17023SJohn Marino 
3972*e4b17023SJohn Marino /* Parse a nested initializer; as c_parser_initializer but parses
3973*e4b17023SJohn Marino    initializers within braced lists, after any designators have been
3974*e4b17023SJohn Marino    applied.  If AFTER is not NULL then it is an Objective-C message
3975*e4b17023SJohn Marino    expression which is the primary-expression starting the
3976*e4b17023SJohn Marino    initializer.  */
3977*e4b17023SJohn Marino 
3978*e4b17023SJohn Marino static void
c_parser_initval(c_parser * parser,struct c_expr * after,struct obstack * braced_init_obstack)3979*e4b17023SJohn Marino c_parser_initval (c_parser *parser, struct c_expr *after,
3980*e4b17023SJohn Marino 		  struct obstack * braced_init_obstack)
3981*e4b17023SJohn Marino {
3982*e4b17023SJohn Marino   struct c_expr init;
3983*e4b17023SJohn Marino   gcc_assert (!after || c_dialect_objc ());
3984*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
3985*e4b17023SJohn Marino     init = c_parser_braced_init (parser, NULL_TREE, true);
3986*e4b17023SJohn Marino   else
3987*e4b17023SJohn Marino     {
3988*e4b17023SJohn Marino       location_t loc = c_parser_peek_token (parser)->location;
3989*e4b17023SJohn Marino       init = c_parser_expr_no_commas (parser, after);
3990*e4b17023SJohn Marino       if (init.value != NULL_TREE
3991*e4b17023SJohn Marino 	  && TREE_CODE (init.value) != STRING_CST
3992*e4b17023SJohn Marino 	  && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
3993*e4b17023SJohn Marino 	init = default_function_array_read_conversion (loc, init);
3994*e4b17023SJohn Marino     }
3995*e4b17023SJohn Marino   process_init_element (init, false, braced_init_obstack);
3996*e4b17023SJohn Marino }
3997*e4b17023SJohn Marino 
3998*e4b17023SJohn Marino /* Parse a compound statement (possibly a function body) (C90 6.6.2,
3999*e4b17023SJohn Marino    C99 6.8.2).
4000*e4b17023SJohn Marino 
4001*e4b17023SJohn Marino    compound-statement:
4002*e4b17023SJohn Marino      { block-item-list[opt] }
4003*e4b17023SJohn Marino      { label-declarations block-item-list }
4004*e4b17023SJohn Marino 
4005*e4b17023SJohn Marino    block-item-list:
4006*e4b17023SJohn Marino      block-item
4007*e4b17023SJohn Marino      block-item-list block-item
4008*e4b17023SJohn Marino 
4009*e4b17023SJohn Marino    block-item:
4010*e4b17023SJohn Marino      nested-declaration
4011*e4b17023SJohn Marino      statement
4012*e4b17023SJohn Marino 
4013*e4b17023SJohn Marino    nested-declaration:
4014*e4b17023SJohn Marino      declaration
4015*e4b17023SJohn Marino 
4016*e4b17023SJohn Marino    GNU extensions:
4017*e4b17023SJohn Marino 
4018*e4b17023SJohn Marino    compound-statement:
4019*e4b17023SJohn Marino      { label-declarations block-item-list }
4020*e4b17023SJohn Marino 
4021*e4b17023SJohn Marino    nested-declaration:
4022*e4b17023SJohn Marino      __extension__ nested-declaration
4023*e4b17023SJohn Marino      nested-function-definition
4024*e4b17023SJohn Marino 
4025*e4b17023SJohn Marino    label-declarations:
4026*e4b17023SJohn Marino      label-declaration
4027*e4b17023SJohn Marino      label-declarations label-declaration
4028*e4b17023SJohn Marino 
4029*e4b17023SJohn Marino    label-declaration:
4030*e4b17023SJohn Marino      __label__ identifier-list ;
4031*e4b17023SJohn Marino 
4032*e4b17023SJohn Marino    Allowing the mixing of declarations and code is new in C99.  The
4033*e4b17023SJohn Marino    GNU syntax also permits (not shown above) labels at the end of
4034*e4b17023SJohn Marino    compound statements, which yield an error.  We don't allow labels
4035*e4b17023SJohn Marino    on declarations; this might seem like a natural extension, but
4036*e4b17023SJohn Marino    there would be a conflict between attributes on the label and
4037*e4b17023SJohn Marino    prefix attributes on the declaration.  ??? The syntax follows the
4038*e4b17023SJohn Marino    old parser in requiring something after label declarations.
4039*e4b17023SJohn Marino    Although they are erroneous if the labels declared aren't defined,
4040*e4b17023SJohn Marino    is it useful for the syntax to be this way?
4041*e4b17023SJohn Marino 
4042*e4b17023SJohn Marino    OpenMP:
4043*e4b17023SJohn Marino 
4044*e4b17023SJohn Marino    block-item:
4045*e4b17023SJohn Marino      openmp-directive
4046*e4b17023SJohn Marino 
4047*e4b17023SJohn Marino    openmp-directive:
4048*e4b17023SJohn Marino      barrier-directive
4049*e4b17023SJohn Marino      flush-directive  */
4050*e4b17023SJohn Marino 
4051*e4b17023SJohn Marino static tree
c_parser_compound_statement(c_parser * parser)4052*e4b17023SJohn Marino c_parser_compound_statement (c_parser *parser)
4053*e4b17023SJohn Marino {
4054*e4b17023SJohn Marino   tree stmt;
4055*e4b17023SJohn Marino   location_t brace_loc;
4056*e4b17023SJohn Marino   brace_loc = c_parser_peek_token (parser)->location;
4057*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
4058*e4b17023SJohn Marino     {
4059*e4b17023SJohn Marino       /* Ensure a scope is entered and left anyway to avoid confusion
4060*e4b17023SJohn Marino 	 if we have just prepared to enter a function body.  */
4061*e4b17023SJohn Marino       stmt = c_begin_compound_stmt (true);
4062*e4b17023SJohn Marino       c_end_compound_stmt (brace_loc, stmt, true);
4063*e4b17023SJohn Marino       return error_mark_node;
4064*e4b17023SJohn Marino     }
4065*e4b17023SJohn Marino   stmt = c_begin_compound_stmt (true);
4066*e4b17023SJohn Marino   c_parser_compound_statement_nostart (parser);
4067*e4b17023SJohn Marino   return c_end_compound_stmt (brace_loc, stmt, true);
4068*e4b17023SJohn Marino }
4069*e4b17023SJohn Marino 
4070*e4b17023SJohn Marino /* Parse a compound statement except for the opening brace.  This is
4071*e4b17023SJohn Marino    used for parsing both compound statements and statement expressions
4072*e4b17023SJohn Marino    (which follow different paths to handling the opening).  */
4073*e4b17023SJohn Marino 
4074*e4b17023SJohn Marino static void
c_parser_compound_statement_nostart(c_parser * parser)4075*e4b17023SJohn Marino c_parser_compound_statement_nostart (c_parser *parser)
4076*e4b17023SJohn Marino {
4077*e4b17023SJohn Marino   bool last_stmt = false;
4078*e4b17023SJohn Marino   bool last_label = false;
4079*e4b17023SJohn Marino   bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
4080*e4b17023SJohn Marino   location_t label_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
4081*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4082*e4b17023SJohn Marino     {
4083*e4b17023SJohn Marino       c_parser_consume_token (parser);
4084*e4b17023SJohn Marino       return;
4085*e4b17023SJohn Marino     }
4086*e4b17023SJohn Marino   mark_valid_location_for_stdc_pragma (true);
4087*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_LABEL))
4088*e4b17023SJohn Marino     {
4089*e4b17023SJohn Marino       /* Read zero or more forward-declarations for labels that nested
4090*e4b17023SJohn Marino 	 functions can jump to.  */
4091*e4b17023SJohn Marino       mark_valid_location_for_stdc_pragma (false);
4092*e4b17023SJohn Marino       while (c_parser_next_token_is_keyword (parser, RID_LABEL))
4093*e4b17023SJohn Marino 	{
4094*e4b17023SJohn Marino 	  label_loc = c_parser_peek_token (parser)->location;
4095*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
4096*e4b17023SJohn Marino 	  /* Any identifiers, including those declared as type names,
4097*e4b17023SJohn Marino 	     are OK here.  */
4098*e4b17023SJohn Marino 	  while (true)
4099*e4b17023SJohn Marino 	    {
4100*e4b17023SJohn Marino 	      tree label;
4101*e4b17023SJohn Marino 	      if (c_parser_next_token_is_not (parser, CPP_NAME))
4102*e4b17023SJohn Marino 		{
4103*e4b17023SJohn Marino 		  c_parser_error (parser, "expected identifier");
4104*e4b17023SJohn Marino 		  break;
4105*e4b17023SJohn Marino 		}
4106*e4b17023SJohn Marino 	      label
4107*e4b17023SJohn Marino 		= declare_label (c_parser_peek_token (parser)->value);
4108*e4b17023SJohn Marino 	      C_DECLARED_LABEL_FLAG (label) = 1;
4109*e4b17023SJohn Marino 	      add_stmt (build_stmt (label_loc, DECL_EXPR, label));
4110*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
4111*e4b17023SJohn Marino 	      if (c_parser_next_token_is (parser, CPP_COMMA))
4112*e4b17023SJohn Marino 		c_parser_consume_token (parser);
4113*e4b17023SJohn Marino 	      else
4114*e4b17023SJohn Marino 		break;
4115*e4b17023SJohn Marino 	    }
4116*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
4117*e4b17023SJohn Marino 	}
4118*e4b17023SJohn Marino       pedwarn (label_loc, OPT_pedantic, "ISO C forbids label declarations");
4119*e4b17023SJohn Marino     }
4120*e4b17023SJohn Marino   /* We must now have at least one statement, label or declaration.  */
4121*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4122*e4b17023SJohn Marino     {
4123*e4b17023SJohn Marino       mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
4124*e4b17023SJohn Marino       c_parser_error (parser, "expected declaration or statement");
4125*e4b17023SJohn Marino       c_parser_consume_token (parser);
4126*e4b17023SJohn Marino       return;
4127*e4b17023SJohn Marino     }
4128*e4b17023SJohn Marino   while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
4129*e4b17023SJohn Marino     {
4130*e4b17023SJohn Marino       location_t loc = c_parser_peek_token (parser)->location;
4131*e4b17023SJohn Marino       if (c_parser_next_token_is_keyword (parser, RID_CASE)
4132*e4b17023SJohn Marino 	  || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
4133*e4b17023SJohn Marino 	  || (c_parser_next_token_is (parser, CPP_NAME)
4134*e4b17023SJohn Marino 	      && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
4135*e4b17023SJohn Marino 	{
4136*e4b17023SJohn Marino 	  if (c_parser_next_token_is_keyword (parser, RID_CASE))
4137*e4b17023SJohn Marino 	    label_loc = c_parser_peek_2nd_token (parser)->location;
4138*e4b17023SJohn Marino 	  else
4139*e4b17023SJohn Marino 	    label_loc = c_parser_peek_token (parser)->location;
4140*e4b17023SJohn Marino 	  last_label = true;
4141*e4b17023SJohn Marino 	  last_stmt = false;
4142*e4b17023SJohn Marino 	  mark_valid_location_for_stdc_pragma (false);
4143*e4b17023SJohn Marino 	  c_parser_label (parser);
4144*e4b17023SJohn Marino 	}
4145*e4b17023SJohn Marino       else if (!last_label
4146*e4b17023SJohn Marino 	       && c_parser_next_tokens_start_declaration (parser))
4147*e4b17023SJohn Marino 	{
4148*e4b17023SJohn Marino 	  last_label = false;
4149*e4b17023SJohn Marino 	  mark_valid_location_for_stdc_pragma (false);
4150*e4b17023SJohn Marino 	  c_parser_declaration_or_fndef (parser, true, true, true, true, true, NULL);
4151*e4b17023SJohn Marino 	  if (last_stmt)
4152*e4b17023SJohn Marino 	    pedwarn_c90 (loc,
4153*e4b17023SJohn Marino 			 (pedantic && !flag_isoc99)
4154*e4b17023SJohn Marino 			 ? OPT_pedantic
4155*e4b17023SJohn Marino 			 : OPT_Wdeclaration_after_statement,
4156*e4b17023SJohn Marino 			 "ISO C90 forbids mixed declarations and code");
4157*e4b17023SJohn Marino 	  last_stmt = false;
4158*e4b17023SJohn Marino 	}
4159*e4b17023SJohn Marino       else if (!last_label
4160*e4b17023SJohn Marino 	       && c_parser_next_token_is_keyword (parser, RID_EXTENSION))
4161*e4b17023SJohn Marino 	{
4162*e4b17023SJohn Marino 	  /* __extension__ can start a declaration, but is also an
4163*e4b17023SJohn Marino 	     unary operator that can start an expression.  Consume all
4164*e4b17023SJohn Marino 	     but the last of a possible series of __extension__ to
4165*e4b17023SJohn Marino 	     determine which.  */
4166*e4b17023SJohn Marino 	  while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
4167*e4b17023SJohn Marino 		 && (c_parser_peek_2nd_token (parser)->keyword
4168*e4b17023SJohn Marino 		     == RID_EXTENSION))
4169*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
4170*e4b17023SJohn Marino 	  if (c_token_starts_declaration (c_parser_peek_2nd_token (parser)))
4171*e4b17023SJohn Marino 	    {
4172*e4b17023SJohn Marino 	      int ext;
4173*e4b17023SJohn Marino 	      ext = disable_extension_diagnostics ();
4174*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
4175*e4b17023SJohn Marino 	      last_label = false;
4176*e4b17023SJohn Marino 	      mark_valid_location_for_stdc_pragma (false);
4177*e4b17023SJohn Marino 	      c_parser_declaration_or_fndef (parser, true, true, true, true,
4178*e4b17023SJohn Marino 					     true, NULL);
4179*e4b17023SJohn Marino 	      /* Following the old parser, __extension__ does not
4180*e4b17023SJohn Marino 		 disable this diagnostic.  */
4181*e4b17023SJohn Marino 	      restore_extension_diagnostics (ext);
4182*e4b17023SJohn Marino 	      if (last_stmt)
4183*e4b17023SJohn Marino 		pedwarn_c90 (loc, (pedantic && !flag_isoc99)
4184*e4b17023SJohn Marino 			     ? OPT_pedantic
4185*e4b17023SJohn Marino 			     : OPT_Wdeclaration_after_statement,
4186*e4b17023SJohn Marino 			     "ISO C90 forbids mixed declarations and code");
4187*e4b17023SJohn Marino 	      last_stmt = false;
4188*e4b17023SJohn Marino 	    }
4189*e4b17023SJohn Marino 	  else
4190*e4b17023SJohn Marino 	    goto statement;
4191*e4b17023SJohn Marino 	}
4192*e4b17023SJohn Marino       else if (c_parser_next_token_is (parser, CPP_PRAGMA))
4193*e4b17023SJohn Marino 	{
4194*e4b17023SJohn Marino 	  /* External pragmas, and some omp pragmas, are not associated
4195*e4b17023SJohn Marino 	     with regular c code, and so are not to be considered statements
4196*e4b17023SJohn Marino 	     syntactically.  This ensures that the user doesn't put them
4197*e4b17023SJohn Marino 	     places that would turn into syntax errors if the directive
4198*e4b17023SJohn Marino 	     were ignored.  */
4199*e4b17023SJohn Marino 	  if (c_parser_pragma (parser, pragma_compound))
4200*e4b17023SJohn Marino 	    last_label = false, last_stmt = true;
4201*e4b17023SJohn Marino 	}
4202*e4b17023SJohn Marino       else if (c_parser_next_token_is (parser, CPP_EOF))
4203*e4b17023SJohn Marino 	{
4204*e4b17023SJohn Marino 	  mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
4205*e4b17023SJohn Marino 	  c_parser_error (parser, "expected declaration or statement");
4206*e4b17023SJohn Marino 	  return;
4207*e4b17023SJohn Marino 	}
4208*e4b17023SJohn Marino       else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
4209*e4b17023SJohn Marino         {
4210*e4b17023SJohn Marino           if (parser->in_if_block)
4211*e4b17023SJohn Marino             {
4212*e4b17023SJohn Marino 	      mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
4213*e4b17023SJohn Marino               error_at (loc, """expected %<}%> before %<else%>");
4214*e4b17023SJohn Marino               return;
4215*e4b17023SJohn Marino             }
4216*e4b17023SJohn Marino           else
4217*e4b17023SJohn Marino             {
4218*e4b17023SJohn Marino               error_at (loc, "%<else%> without a previous %<if%>");
4219*e4b17023SJohn Marino               c_parser_consume_token (parser);
4220*e4b17023SJohn Marino               continue;
4221*e4b17023SJohn Marino             }
4222*e4b17023SJohn Marino         }
4223*e4b17023SJohn Marino       else
4224*e4b17023SJohn Marino 	{
4225*e4b17023SJohn Marino 	statement:
4226*e4b17023SJohn Marino 	  last_label = false;
4227*e4b17023SJohn Marino 	  last_stmt = true;
4228*e4b17023SJohn Marino 	  mark_valid_location_for_stdc_pragma (false);
4229*e4b17023SJohn Marino 	  c_parser_statement_after_labels (parser);
4230*e4b17023SJohn Marino 	}
4231*e4b17023SJohn Marino 
4232*e4b17023SJohn Marino       parser->error = false;
4233*e4b17023SJohn Marino     }
4234*e4b17023SJohn Marino   if (last_label)
4235*e4b17023SJohn Marino     error_at (label_loc, "label at end of compound statement");
4236*e4b17023SJohn Marino   c_parser_consume_token (parser);
4237*e4b17023SJohn Marino   /* Restore the value we started with.  */
4238*e4b17023SJohn Marino   mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
4239*e4b17023SJohn Marino }
4240*e4b17023SJohn Marino 
4241*e4b17023SJohn Marino /* Parse a label (C90 6.6.1, C99 6.8.1).
4242*e4b17023SJohn Marino 
4243*e4b17023SJohn Marino    label:
4244*e4b17023SJohn Marino      identifier : attributes[opt]
4245*e4b17023SJohn Marino      case constant-expression :
4246*e4b17023SJohn Marino      default :
4247*e4b17023SJohn Marino 
4248*e4b17023SJohn Marino    GNU extensions:
4249*e4b17023SJohn Marino 
4250*e4b17023SJohn Marino    label:
4251*e4b17023SJohn Marino      case constant-expression ... constant-expression :
4252*e4b17023SJohn Marino 
4253*e4b17023SJohn Marino    The use of attributes on labels is a GNU extension.  The syntax in
4254*e4b17023SJohn Marino    GNU C accepts any expressions without commas, non-constant
4255*e4b17023SJohn Marino    expressions being rejected later.  */
4256*e4b17023SJohn Marino 
4257*e4b17023SJohn Marino static void
c_parser_label(c_parser * parser)4258*e4b17023SJohn Marino c_parser_label (c_parser *parser)
4259*e4b17023SJohn Marino {
4260*e4b17023SJohn Marino   location_t loc1 = c_parser_peek_token (parser)->location;
4261*e4b17023SJohn Marino   tree label = NULL_TREE;
4262*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_CASE))
4263*e4b17023SJohn Marino     {
4264*e4b17023SJohn Marino       tree exp1, exp2;
4265*e4b17023SJohn Marino       c_parser_consume_token (parser);
4266*e4b17023SJohn Marino       exp1 = c_parser_expr_no_commas (parser, NULL).value;
4267*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_COLON))
4268*e4b17023SJohn Marino 	{
4269*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
4270*e4b17023SJohn Marino 	  label = do_case (loc1, exp1, NULL_TREE);
4271*e4b17023SJohn Marino 	}
4272*e4b17023SJohn Marino       else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4273*e4b17023SJohn Marino 	{
4274*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
4275*e4b17023SJohn Marino 	  exp2 = c_parser_expr_no_commas (parser, NULL).value;
4276*e4b17023SJohn Marino 	  if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
4277*e4b17023SJohn Marino 	    label = do_case (loc1, exp1, exp2);
4278*e4b17023SJohn Marino 	}
4279*e4b17023SJohn Marino       else
4280*e4b17023SJohn Marino 	c_parser_error (parser, "expected %<:%> or %<...%>");
4281*e4b17023SJohn Marino     }
4282*e4b17023SJohn Marino   else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
4283*e4b17023SJohn Marino     {
4284*e4b17023SJohn Marino       c_parser_consume_token (parser);
4285*e4b17023SJohn Marino       if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
4286*e4b17023SJohn Marino 	label = do_case (loc1, NULL_TREE, NULL_TREE);
4287*e4b17023SJohn Marino     }
4288*e4b17023SJohn Marino   else
4289*e4b17023SJohn Marino     {
4290*e4b17023SJohn Marino       tree name = c_parser_peek_token (parser)->value;
4291*e4b17023SJohn Marino       tree tlab;
4292*e4b17023SJohn Marino       tree attrs;
4293*e4b17023SJohn Marino       location_t loc2 = c_parser_peek_token (parser)->location;
4294*e4b17023SJohn Marino       gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
4295*e4b17023SJohn Marino       c_parser_consume_token (parser);
4296*e4b17023SJohn Marino       gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
4297*e4b17023SJohn Marino       c_parser_consume_token (parser);
4298*e4b17023SJohn Marino       attrs = c_parser_attributes (parser);
4299*e4b17023SJohn Marino       tlab = define_label (loc2, name);
4300*e4b17023SJohn Marino       if (tlab)
4301*e4b17023SJohn Marino 	{
4302*e4b17023SJohn Marino 	  decl_attributes (&tlab, attrs, 0);
4303*e4b17023SJohn Marino 	  label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
4304*e4b17023SJohn Marino 	}
4305*e4b17023SJohn Marino     }
4306*e4b17023SJohn Marino   if (label)
4307*e4b17023SJohn Marino     {
4308*e4b17023SJohn Marino       if (c_parser_next_tokens_start_declaration (parser))
4309*e4b17023SJohn Marino 	{
4310*e4b17023SJohn Marino 	  error_at (c_parser_peek_token (parser)->location,
4311*e4b17023SJohn Marino 		    "a label can only be part of a statement and "
4312*e4b17023SJohn Marino 		    "a declaration is not a statement");
4313*e4b17023SJohn Marino 	  c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false,
4314*e4b17023SJohn Marino 					 /*static_assert_ok*/ true,
4315*e4b17023SJohn Marino 					 /*nested*/ true, /*empty_ok*/ false,
4316*e4b17023SJohn Marino 					 /*start_attr_ok*/ true, NULL);
4317*e4b17023SJohn Marino 	}
4318*e4b17023SJohn Marino     }
4319*e4b17023SJohn Marino }
4320*e4b17023SJohn Marino 
4321*e4b17023SJohn Marino /* Parse a statement (C90 6.6, C99 6.8).
4322*e4b17023SJohn Marino 
4323*e4b17023SJohn Marino    statement:
4324*e4b17023SJohn Marino      labeled-statement
4325*e4b17023SJohn Marino      compound-statement
4326*e4b17023SJohn Marino      expression-statement
4327*e4b17023SJohn Marino      selection-statement
4328*e4b17023SJohn Marino      iteration-statement
4329*e4b17023SJohn Marino      jump-statement
4330*e4b17023SJohn Marino 
4331*e4b17023SJohn Marino    labeled-statement:
4332*e4b17023SJohn Marino      label statement
4333*e4b17023SJohn Marino 
4334*e4b17023SJohn Marino    expression-statement:
4335*e4b17023SJohn Marino      expression[opt] ;
4336*e4b17023SJohn Marino 
4337*e4b17023SJohn Marino    selection-statement:
4338*e4b17023SJohn Marino      if-statement
4339*e4b17023SJohn Marino      switch-statement
4340*e4b17023SJohn Marino 
4341*e4b17023SJohn Marino    iteration-statement:
4342*e4b17023SJohn Marino      while-statement
4343*e4b17023SJohn Marino      do-statement
4344*e4b17023SJohn Marino      for-statement
4345*e4b17023SJohn Marino 
4346*e4b17023SJohn Marino    jump-statement:
4347*e4b17023SJohn Marino      goto identifier ;
4348*e4b17023SJohn Marino      continue ;
4349*e4b17023SJohn Marino      break ;
4350*e4b17023SJohn Marino      return expression[opt] ;
4351*e4b17023SJohn Marino 
4352*e4b17023SJohn Marino    GNU extensions:
4353*e4b17023SJohn Marino 
4354*e4b17023SJohn Marino    statement:
4355*e4b17023SJohn Marino      asm-statement
4356*e4b17023SJohn Marino 
4357*e4b17023SJohn Marino    jump-statement:
4358*e4b17023SJohn Marino      goto * expression ;
4359*e4b17023SJohn Marino 
4360*e4b17023SJohn Marino    Objective-C:
4361*e4b17023SJohn Marino 
4362*e4b17023SJohn Marino    statement:
4363*e4b17023SJohn Marino      objc-throw-statement
4364*e4b17023SJohn Marino      objc-try-catch-statement
4365*e4b17023SJohn Marino      objc-synchronized-statement
4366*e4b17023SJohn Marino 
4367*e4b17023SJohn Marino    objc-throw-statement:
4368*e4b17023SJohn Marino      @throw expression ;
4369*e4b17023SJohn Marino      @throw ;
4370*e4b17023SJohn Marino 
4371*e4b17023SJohn Marino    OpenMP:
4372*e4b17023SJohn Marino 
4373*e4b17023SJohn Marino    statement:
4374*e4b17023SJohn Marino      openmp-construct
4375*e4b17023SJohn Marino 
4376*e4b17023SJohn Marino    openmp-construct:
4377*e4b17023SJohn Marino      parallel-construct
4378*e4b17023SJohn Marino      for-construct
4379*e4b17023SJohn Marino      sections-construct
4380*e4b17023SJohn Marino      single-construct
4381*e4b17023SJohn Marino      parallel-for-construct
4382*e4b17023SJohn Marino      parallel-sections-construct
4383*e4b17023SJohn Marino      master-construct
4384*e4b17023SJohn Marino      critical-construct
4385*e4b17023SJohn Marino      atomic-construct
4386*e4b17023SJohn Marino      ordered-construct
4387*e4b17023SJohn Marino 
4388*e4b17023SJohn Marino    parallel-construct:
4389*e4b17023SJohn Marino      parallel-directive structured-block
4390*e4b17023SJohn Marino 
4391*e4b17023SJohn Marino    for-construct:
4392*e4b17023SJohn Marino      for-directive iteration-statement
4393*e4b17023SJohn Marino 
4394*e4b17023SJohn Marino    sections-construct:
4395*e4b17023SJohn Marino      sections-directive section-scope
4396*e4b17023SJohn Marino 
4397*e4b17023SJohn Marino    single-construct:
4398*e4b17023SJohn Marino      single-directive structured-block
4399*e4b17023SJohn Marino 
4400*e4b17023SJohn Marino    parallel-for-construct:
4401*e4b17023SJohn Marino      parallel-for-directive iteration-statement
4402*e4b17023SJohn Marino 
4403*e4b17023SJohn Marino    parallel-sections-construct:
4404*e4b17023SJohn Marino      parallel-sections-directive section-scope
4405*e4b17023SJohn Marino 
4406*e4b17023SJohn Marino    master-construct:
4407*e4b17023SJohn Marino      master-directive structured-block
4408*e4b17023SJohn Marino 
4409*e4b17023SJohn Marino    critical-construct:
4410*e4b17023SJohn Marino      critical-directive structured-block
4411*e4b17023SJohn Marino 
4412*e4b17023SJohn Marino    atomic-construct:
4413*e4b17023SJohn Marino      atomic-directive expression-statement
4414*e4b17023SJohn Marino 
4415*e4b17023SJohn Marino    ordered-construct:
4416*e4b17023SJohn Marino      ordered-directive structured-block
4417*e4b17023SJohn Marino 
4418*e4b17023SJohn Marino    Transactional Memory:
4419*e4b17023SJohn Marino 
4420*e4b17023SJohn Marino    statement:
4421*e4b17023SJohn Marino      transaction-statement
4422*e4b17023SJohn Marino      transaction-cancel-statement
4423*e4b17023SJohn Marino */
4424*e4b17023SJohn Marino 
4425*e4b17023SJohn Marino static void
c_parser_statement(c_parser * parser)4426*e4b17023SJohn Marino c_parser_statement (c_parser *parser)
4427*e4b17023SJohn Marino {
4428*e4b17023SJohn Marino   while (c_parser_next_token_is_keyword (parser, RID_CASE)
4429*e4b17023SJohn Marino 	 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
4430*e4b17023SJohn Marino 	 || (c_parser_next_token_is (parser, CPP_NAME)
4431*e4b17023SJohn Marino 	     && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
4432*e4b17023SJohn Marino     c_parser_label (parser);
4433*e4b17023SJohn Marino   c_parser_statement_after_labels (parser);
4434*e4b17023SJohn Marino }
4435*e4b17023SJohn Marino 
4436*e4b17023SJohn Marino /* Parse a statement, other than a labeled statement.  */
4437*e4b17023SJohn Marino 
4438*e4b17023SJohn Marino static void
c_parser_statement_after_labels(c_parser * parser)4439*e4b17023SJohn Marino c_parser_statement_after_labels (c_parser *parser)
4440*e4b17023SJohn Marino {
4441*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
4442*e4b17023SJohn Marino   tree stmt = NULL_TREE;
4443*e4b17023SJohn Marino   bool in_if_block = parser->in_if_block;
4444*e4b17023SJohn Marino   parser->in_if_block = false;
4445*e4b17023SJohn Marino   switch (c_parser_peek_token (parser)->type)
4446*e4b17023SJohn Marino     {
4447*e4b17023SJohn Marino     case CPP_OPEN_BRACE:
4448*e4b17023SJohn Marino       add_stmt (c_parser_compound_statement (parser));
4449*e4b17023SJohn Marino       break;
4450*e4b17023SJohn Marino     case CPP_KEYWORD:
4451*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->keyword)
4452*e4b17023SJohn Marino 	{
4453*e4b17023SJohn Marino 	case RID_IF:
4454*e4b17023SJohn Marino 	  c_parser_if_statement (parser);
4455*e4b17023SJohn Marino 	  break;
4456*e4b17023SJohn Marino 	case RID_SWITCH:
4457*e4b17023SJohn Marino 	  c_parser_switch_statement (parser);
4458*e4b17023SJohn Marino 	  break;
4459*e4b17023SJohn Marino 	case RID_WHILE:
4460*e4b17023SJohn Marino 	  c_parser_while_statement (parser);
4461*e4b17023SJohn Marino 	  break;
4462*e4b17023SJohn Marino 	case RID_DO:
4463*e4b17023SJohn Marino 	  c_parser_do_statement (parser);
4464*e4b17023SJohn Marino 	  break;
4465*e4b17023SJohn Marino 	case RID_FOR:
4466*e4b17023SJohn Marino 	  c_parser_for_statement (parser);
4467*e4b17023SJohn Marino 	  break;
4468*e4b17023SJohn Marino 	case RID_GOTO:
4469*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
4470*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_NAME))
4471*e4b17023SJohn Marino 	    {
4472*e4b17023SJohn Marino 	      stmt = c_finish_goto_label (loc,
4473*e4b17023SJohn Marino 					  c_parser_peek_token (parser)->value);
4474*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
4475*e4b17023SJohn Marino 	    }
4476*e4b17023SJohn Marino 	  else if (c_parser_next_token_is (parser, CPP_MULT))
4477*e4b17023SJohn Marino 	    {
4478*e4b17023SJohn Marino 	      tree val;
4479*e4b17023SJohn Marino 
4480*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
4481*e4b17023SJohn Marino 	      val = c_parser_expression (parser).value;
4482*e4b17023SJohn Marino 	      mark_exp_read (val);
4483*e4b17023SJohn Marino 	      stmt = c_finish_goto_ptr (loc, val);
4484*e4b17023SJohn Marino 	    }
4485*e4b17023SJohn Marino 	  else
4486*e4b17023SJohn Marino 	    c_parser_error (parser, "expected identifier or %<*%>");
4487*e4b17023SJohn Marino 	  goto expect_semicolon;
4488*e4b17023SJohn Marino 	case RID_CONTINUE:
4489*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
4490*e4b17023SJohn Marino 	  stmt = c_finish_bc_stmt (loc, &c_cont_label, false);
4491*e4b17023SJohn Marino 	  goto expect_semicolon;
4492*e4b17023SJohn Marino 	case RID_BREAK:
4493*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
4494*e4b17023SJohn Marino 	  stmt = c_finish_bc_stmt (loc, &c_break_label, true);
4495*e4b17023SJohn Marino 	  goto expect_semicolon;
4496*e4b17023SJohn Marino 	case RID_RETURN:
4497*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
4498*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4499*e4b17023SJohn Marino 	    {
4500*e4b17023SJohn Marino 	      stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
4501*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
4502*e4b17023SJohn Marino 	    }
4503*e4b17023SJohn Marino 	  else
4504*e4b17023SJohn Marino 	    {
4505*e4b17023SJohn Marino 	      struct c_expr expr = c_parser_expression_conv (parser);
4506*e4b17023SJohn Marino 	      mark_exp_read (expr.value);
4507*e4b17023SJohn Marino 	      stmt = c_finish_return (loc, expr.value, expr.original_type);
4508*e4b17023SJohn Marino 	      goto expect_semicolon;
4509*e4b17023SJohn Marino 	    }
4510*e4b17023SJohn Marino 	  break;
4511*e4b17023SJohn Marino 	case RID_ASM:
4512*e4b17023SJohn Marino 	  stmt = c_parser_asm_statement (parser);
4513*e4b17023SJohn Marino 	  break;
4514*e4b17023SJohn Marino 	case RID_TRANSACTION_ATOMIC:
4515*e4b17023SJohn Marino 	case RID_TRANSACTION_RELAXED:
4516*e4b17023SJohn Marino 	  stmt = c_parser_transaction (parser,
4517*e4b17023SJohn Marino 	      c_parser_peek_token (parser)->keyword);
4518*e4b17023SJohn Marino 	  break;
4519*e4b17023SJohn Marino 	case RID_TRANSACTION_CANCEL:
4520*e4b17023SJohn Marino 	  stmt = c_parser_transaction_cancel (parser);
4521*e4b17023SJohn Marino 	  goto expect_semicolon;
4522*e4b17023SJohn Marino 	case RID_AT_THROW:
4523*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
4524*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
4525*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4526*e4b17023SJohn Marino 	    {
4527*e4b17023SJohn Marino 	      stmt = objc_build_throw_stmt (loc, NULL_TREE);
4528*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
4529*e4b17023SJohn Marino 	    }
4530*e4b17023SJohn Marino 	  else
4531*e4b17023SJohn Marino 	    {
4532*e4b17023SJohn Marino 	      tree expr = c_parser_expression (parser).value;
4533*e4b17023SJohn Marino 	      expr = c_fully_fold (expr, false, NULL);
4534*e4b17023SJohn Marino 	      stmt = objc_build_throw_stmt (loc, expr);
4535*e4b17023SJohn Marino 	      goto expect_semicolon;
4536*e4b17023SJohn Marino 	    }
4537*e4b17023SJohn Marino 	  break;
4538*e4b17023SJohn Marino 	case RID_AT_TRY:
4539*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
4540*e4b17023SJohn Marino 	  c_parser_objc_try_catch_finally_statement (parser);
4541*e4b17023SJohn Marino 	  break;
4542*e4b17023SJohn Marino 	case RID_AT_SYNCHRONIZED:
4543*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
4544*e4b17023SJohn Marino 	  c_parser_objc_synchronized_statement (parser);
4545*e4b17023SJohn Marino 	  break;
4546*e4b17023SJohn Marino 	default:
4547*e4b17023SJohn Marino 	  goto expr_stmt;
4548*e4b17023SJohn Marino 	}
4549*e4b17023SJohn Marino       break;
4550*e4b17023SJohn Marino     case CPP_SEMICOLON:
4551*e4b17023SJohn Marino       c_parser_consume_token (parser);
4552*e4b17023SJohn Marino       break;
4553*e4b17023SJohn Marino     case CPP_CLOSE_PAREN:
4554*e4b17023SJohn Marino     case CPP_CLOSE_SQUARE:
4555*e4b17023SJohn Marino       /* Avoid infinite loop in error recovery:
4556*e4b17023SJohn Marino 	 c_parser_skip_until_found stops at a closing nesting
4557*e4b17023SJohn Marino 	 delimiter without consuming it, but here we need to consume
4558*e4b17023SJohn Marino 	 it to proceed further.  */
4559*e4b17023SJohn Marino       c_parser_error (parser, "expected statement");
4560*e4b17023SJohn Marino       c_parser_consume_token (parser);
4561*e4b17023SJohn Marino       break;
4562*e4b17023SJohn Marino     case CPP_PRAGMA:
4563*e4b17023SJohn Marino       c_parser_pragma (parser, pragma_stmt);
4564*e4b17023SJohn Marino       break;
4565*e4b17023SJohn Marino     default:
4566*e4b17023SJohn Marino     expr_stmt:
4567*e4b17023SJohn Marino       stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
4568*e4b17023SJohn Marino     expect_semicolon:
4569*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
4570*e4b17023SJohn Marino       break;
4571*e4b17023SJohn Marino     }
4572*e4b17023SJohn Marino   /* Two cases cannot and do not have line numbers associated: If stmt
4573*e4b17023SJohn Marino      is degenerate, such as "2;", then stmt is an INTEGER_CST, which
4574*e4b17023SJohn Marino      cannot hold line numbers.  But that's OK because the statement
4575*e4b17023SJohn Marino      will either be changed to a MODIFY_EXPR during gimplification of
4576*e4b17023SJohn Marino      the statement expr, or discarded.  If stmt was compound, but
4577*e4b17023SJohn Marino      without new variables, we will have skipped the creation of a
4578*e4b17023SJohn Marino      BIND and will have a bare STATEMENT_LIST.  But that's OK because
4579*e4b17023SJohn Marino      (recursively) all of the component statements should already have
4580*e4b17023SJohn Marino      line numbers assigned.  ??? Can we discard no-op statements
4581*e4b17023SJohn Marino      earlier?  */
4582*e4b17023SJohn Marino   if (CAN_HAVE_LOCATION_P (stmt)
4583*e4b17023SJohn Marino       && EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
4584*e4b17023SJohn Marino     SET_EXPR_LOCATION (stmt, loc);
4585*e4b17023SJohn Marino 
4586*e4b17023SJohn Marino   parser->in_if_block = in_if_block;
4587*e4b17023SJohn Marino }
4588*e4b17023SJohn Marino 
4589*e4b17023SJohn Marino /* Parse the condition from an if, do, while or for statements.  */
4590*e4b17023SJohn Marino 
4591*e4b17023SJohn Marino static tree
c_parser_condition(c_parser * parser)4592*e4b17023SJohn Marino c_parser_condition (c_parser *parser)
4593*e4b17023SJohn Marino {
4594*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
4595*e4b17023SJohn Marino   tree cond;
4596*e4b17023SJohn Marino   cond = c_parser_expression_conv (parser).value;
4597*e4b17023SJohn Marino   cond = c_objc_common_truthvalue_conversion (loc, cond);
4598*e4b17023SJohn Marino   cond = c_fully_fold (cond, false, NULL);
4599*e4b17023SJohn Marino   if (warn_sequence_point)
4600*e4b17023SJohn Marino     verify_sequence_points (cond);
4601*e4b17023SJohn Marino   return cond;
4602*e4b17023SJohn Marino }
4603*e4b17023SJohn Marino 
4604*e4b17023SJohn Marino /* Parse a parenthesized condition from an if, do or while statement.
4605*e4b17023SJohn Marino 
4606*e4b17023SJohn Marino    condition:
4607*e4b17023SJohn Marino      ( expression )
4608*e4b17023SJohn Marino */
4609*e4b17023SJohn Marino static tree
c_parser_paren_condition(c_parser * parser)4610*e4b17023SJohn Marino c_parser_paren_condition (c_parser *parser)
4611*e4b17023SJohn Marino {
4612*e4b17023SJohn Marino   tree cond;
4613*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4614*e4b17023SJohn Marino     return error_mark_node;
4615*e4b17023SJohn Marino   cond = c_parser_condition (parser);
4616*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
4617*e4b17023SJohn Marino   return cond;
4618*e4b17023SJohn Marino }
4619*e4b17023SJohn Marino 
4620*e4b17023SJohn Marino /* Parse a statement which is a block in C99.  */
4621*e4b17023SJohn Marino 
4622*e4b17023SJohn Marino static tree
c_parser_c99_block_statement(c_parser * parser)4623*e4b17023SJohn Marino c_parser_c99_block_statement (c_parser *parser)
4624*e4b17023SJohn Marino {
4625*e4b17023SJohn Marino   tree block = c_begin_compound_stmt (flag_isoc99);
4626*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
4627*e4b17023SJohn Marino   c_parser_statement (parser);
4628*e4b17023SJohn Marino   return c_end_compound_stmt (loc, block, flag_isoc99);
4629*e4b17023SJohn Marino }
4630*e4b17023SJohn Marino 
4631*e4b17023SJohn Marino /* Parse the body of an if statement.  This is just parsing a
4632*e4b17023SJohn Marino    statement but (a) it is a block in C99, (b) we track whether the
4633*e4b17023SJohn Marino    body is an if statement for the sake of -Wparentheses warnings, (c)
4634*e4b17023SJohn Marino    we handle an empty body specially for the sake of -Wempty-body
4635*e4b17023SJohn Marino    warnings, and (d) we call parser_compound_statement directly
4636*e4b17023SJohn Marino    because c_parser_statement_after_labels resets
4637*e4b17023SJohn Marino    parser->in_if_block.  */
4638*e4b17023SJohn Marino 
4639*e4b17023SJohn Marino static tree
c_parser_if_body(c_parser * parser,bool * if_p)4640*e4b17023SJohn Marino c_parser_if_body (c_parser *parser, bool *if_p)
4641*e4b17023SJohn Marino {
4642*e4b17023SJohn Marino   tree block = c_begin_compound_stmt (flag_isoc99);
4643*e4b17023SJohn Marino   location_t body_loc = c_parser_peek_token (parser)->location;
4644*e4b17023SJohn Marino   while (c_parser_next_token_is_keyword (parser, RID_CASE)
4645*e4b17023SJohn Marino 	 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
4646*e4b17023SJohn Marino 	 || (c_parser_next_token_is (parser, CPP_NAME)
4647*e4b17023SJohn Marino 	     && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
4648*e4b17023SJohn Marino     c_parser_label (parser);
4649*e4b17023SJohn Marino   *if_p = c_parser_next_token_is_keyword (parser, RID_IF);
4650*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4651*e4b17023SJohn Marino     {
4652*e4b17023SJohn Marino       location_t loc = c_parser_peek_token (parser)->location;
4653*e4b17023SJohn Marino       add_stmt (build_empty_stmt (loc));
4654*e4b17023SJohn Marino       c_parser_consume_token (parser);
4655*e4b17023SJohn Marino       if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
4656*e4b17023SJohn Marino 	warning_at (loc, OPT_Wempty_body,
4657*e4b17023SJohn Marino 		    "suggest braces around empty body in an %<if%> statement");
4658*e4b17023SJohn Marino     }
4659*e4b17023SJohn Marino   else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
4660*e4b17023SJohn Marino     add_stmt (c_parser_compound_statement (parser));
4661*e4b17023SJohn Marino   else
4662*e4b17023SJohn Marino     c_parser_statement_after_labels (parser);
4663*e4b17023SJohn Marino   return c_end_compound_stmt (body_loc, block, flag_isoc99);
4664*e4b17023SJohn Marino }
4665*e4b17023SJohn Marino 
4666*e4b17023SJohn Marino /* Parse the else body of an if statement.  This is just parsing a
4667*e4b17023SJohn Marino    statement but (a) it is a block in C99, (b) we handle an empty body
4668*e4b17023SJohn Marino    specially for the sake of -Wempty-body warnings.  */
4669*e4b17023SJohn Marino 
4670*e4b17023SJohn Marino static tree
c_parser_else_body(c_parser * parser)4671*e4b17023SJohn Marino c_parser_else_body (c_parser *parser)
4672*e4b17023SJohn Marino {
4673*e4b17023SJohn Marino   location_t else_loc = c_parser_peek_token (parser)->location;
4674*e4b17023SJohn Marino   tree block = c_begin_compound_stmt (flag_isoc99);
4675*e4b17023SJohn Marino   while (c_parser_next_token_is_keyword (parser, RID_CASE)
4676*e4b17023SJohn Marino 	 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
4677*e4b17023SJohn Marino 	 || (c_parser_next_token_is (parser, CPP_NAME)
4678*e4b17023SJohn Marino 	     && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
4679*e4b17023SJohn Marino     c_parser_label (parser);
4680*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4681*e4b17023SJohn Marino     {
4682*e4b17023SJohn Marino       location_t loc = c_parser_peek_token (parser)->location;
4683*e4b17023SJohn Marino       warning_at (loc,
4684*e4b17023SJohn Marino 		  OPT_Wempty_body,
4685*e4b17023SJohn Marino 	         "suggest braces around empty body in an %<else%> statement");
4686*e4b17023SJohn Marino       add_stmt (build_empty_stmt (loc));
4687*e4b17023SJohn Marino       c_parser_consume_token (parser);
4688*e4b17023SJohn Marino     }
4689*e4b17023SJohn Marino   else
4690*e4b17023SJohn Marino     c_parser_statement_after_labels (parser);
4691*e4b17023SJohn Marino   return c_end_compound_stmt (else_loc, block, flag_isoc99);
4692*e4b17023SJohn Marino }
4693*e4b17023SJohn Marino 
4694*e4b17023SJohn Marino /* Parse an if statement (C90 6.6.4, C99 6.8.4).
4695*e4b17023SJohn Marino 
4696*e4b17023SJohn Marino    if-statement:
4697*e4b17023SJohn Marino      if ( expression ) statement
4698*e4b17023SJohn Marino      if ( expression ) statement else statement
4699*e4b17023SJohn Marino */
4700*e4b17023SJohn Marino 
4701*e4b17023SJohn Marino static void
c_parser_if_statement(c_parser * parser)4702*e4b17023SJohn Marino c_parser_if_statement (c_parser *parser)
4703*e4b17023SJohn Marino {
4704*e4b17023SJohn Marino   tree block;
4705*e4b17023SJohn Marino   location_t loc;
4706*e4b17023SJohn Marino   tree cond;
4707*e4b17023SJohn Marino   bool first_if = false;
4708*e4b17023SJohn Marino   tree first_body, second_body;
4709*e4b17023SJohn Marino   bool in_if_block;
4710*e4b17023SJohn Marino 
4711*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
4712*e4b17023SJohn Marino   c_parser_consume_token (parser);
4713*e4b17023SJohn Marino   block = c_begin_compound_stmt (flag_isoc99);
4714*e4b17023SJohn Marino   loc = c_parser_peek_token (parser)->location;
4715*e4b17023SJohn Marino   cond = c_parser_paren_condition (parser);
4716*e4b17023SJohn Marino   in_if_block = parser->in_if_block;
4717*e4b17023SJohn Marino   parser->in_if_block = true;
4718*e4b17023SJohn Marino   first_body = c_parser_if_body (parser, &first_if);
4719*e4b17023SJohn Marino   parser->in_if_block = in_if_block;
4720*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_ELSE))
4721*e4b17023SJohn Marino     {
4722*e4b17023SJohn Marino       c_parser_consume_token (parser);
4723*e4b17023SJohn Marino       second_body = c_parser_else_body (parser);
4724*e4b17023SJohn Marino     }
4725*e4b17023SJohn Marino   else
4726*e4b17023SJohn Marino     second_body = NULL_TREE;
4727*e4b17023SJohn Marino   c_finish_if_stmt (loc, cond, first_body, second_body, first_if);
4728*e4b17023SJohn Marino   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
4729*e4b17023SJohn Marino }
4730*e4b17023SJohn Marino 
4731*e4b17023SJohn Marino /* Parse a switch statement (C90 6.6.4, C99 6.8.4).
4732*e4b17023SJohn Marino 
4733*e4b17023SJohn Marino    switch-statement:
4734*e4b17023SJohn Marino      switch (expression) statement
4735*e4b17023SJohn Marino */
4736*e4b17023SJohn Marino 
4737*e4b17023SJohn Marino static void
c_parser_switch_statement(c_parser * parser)4738*e4b17023SJohn Marino c_parser_switch_statement (c_parser *parser)
4739*e4b17023SJohn Marino {
4740*e4b17023SJohn Marino   tree block, expr, body, save_break;
4741*e4b17023SJohn Marino   location_t switch_loc = c_parser_peek_token (parser)->location;
4742*e4b17023SJohn Marino   location_t switch_cond_loc;
4743*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
4744*e4b17023SJohn Marino   c_parser_consume_token (parser);
4745*e4b17023SJohn Marino   block = c_begin_compound_stmt (flag_isoc99);
4746*e4b17023SJohn Marino   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4747*e4b17023SJohn Marino     {
4748*e4b17023SJohn Marino       switch_cond_loc = c_parser_peek_token (parser)->location;
4749*e4b17023SJohn Marino       expr = c_parser_expression (parser).value;
4750*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
4751*e4b17023SJohn Marino     }
4752*e4b17023SJohn Marino   else
4753*e4b17023SJohn Marino     {
4754*e4b17023SJohn Marino       switch_cond_loc = UNKNOWN_LOCATION;
4755*e4b17023SJohn Marino       expr = error_mark_node;
4756*e4b17023SJohn Marino     }
4757*e4b17023SJohn Marino   c_start_case (switch_loc, switch_cond_loc, expr);
4758*e4b17023SJohn Marino   save_break = c_break_label;
4759*e4b17023SJohn Marino   c_break_label = NULL_TREE;
4760*e4b17023SJohn Marino   body = c_parser_c99_block_statement (parser);
4761*e4b17023SJohn Marino   c_finish_case (body);
4762*e4b17023SJohn Marino   if (c_break_label)
4763*e4b17023SJohn Marino     {
4764*e4b17023SJohn Marino       location_t here = c_parser_peek_token (parser)->location;
4765*e4b17023SJohn Marino       tree t = build1 (LABEL_EXPR, void_type_node, c_break_label);
4766*e4b17023SJohn Marino       SET_EXPR_LOCATION (t, here);
4767*e4b17023SJohn Marino       add_stmt (t);
4768*e4b17023SJohn Marino     }
4769*e4b17023SJohn Marino   c_break_label = save_break;
4770*e4b17023SJohn Marino   add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
4771*e4b17023SJohn Marino }
4772*e4b17023SJohn Marino 
4773*e4b17023SJohn Marino /* Parse a while statement (C90 6.6.5, C99 6.8.5).
4774*e4b17023SJohn Marino 
4775*e4b17023SJohn Marino    while-statement:
4776*e4b17023SJohn Marino       while (expression) statement
4777*e4b17023SJohn Marino */
4778*e4b17023SJohn Marino 
4779*e4b17023SJohn Marino static void
c_parser_while_statement(c_parser * parser)4780*e4b17023SJohn Marino c_parser_while_statement (c_parser *parser)
4781*e4b17023SJohn Marino {
4782*e4b17023SJohn Marino   tree block, cond, body, save_break, save_cont;
4783*e4b17023SJohn Marino   location_t loc;
4784*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
4785*e4b17023SJohn Marino   c_parser_consume_token (parser);
4786*e4b17023SJohn Marino   block = c_begin_compound_stmt (flag_isoc99);
4787*e4b17023SJohn Marino   loc = c_parser_peek_token (parser)->location;
4788*e4b17023SJohn Marino   cond = c_parser_paren_condition (parser);
4789*e4b17023SJohn Marino   save_break = c_break_label;
4790*e4b17023SJohn Marino   c_break_label = NULL_TREE;
4791*e4b17023SJohn Marino   save_cont = c_cont_label;
4792*e4b17023SJohn Marino   c_cont_label = NULL_TREE;
4793*e4b17023SJohn Marino   body = c_parser_c99_block_statement (parser);
4794*e4b17023SJohn Marino   c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, true);
4795*e4b17023SJohn Marino   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
4796*e4b17023SJohn Marino   c_break_label = save_break;
4797*e4b17023SJohn Marino   c_cont_label = save_cont;
4798*e4b17023SJohn Marino }
4799*e4b17023SJohn Marino 
4800*e4b17023SJohn Marino /* Parse a do statement (C90 6.6.5, C99 6.8.5).
4801*e4b17023SJohn Marino 
4802*e4b17023SJohn Marino    do-statement:
4803*e4b17023SJohn Marino      do statement while ( expression ) ;
4804*e4b17023SJohn Marino */
4805*e4b17023SJohn Marino 
4806*e4b17023SJohn Marino static void
c_parser_do_statement(c_parser * parser)4807*e4b17023SJohn Marino c_parser_do_statement (c_parser *parser)
4808*e4b17023SJohn Marino {
4809*e4b17023SJohn Marino   tree block, cond, body, save_break, save_cont, new_break, new_cont;
4810*e4b17023SJohn Marino   location_t loc;
4811*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
4812*e4b17023SJohn Marino   c_parser_consume_token (parser);
4813*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4814*e4b17023SJohn Marino     warning_at (c_parser_peek_token (parser)->location,
4815*e4b17023SJohn Marino 		OPT_Wempty_body,
4816*e4b17023SJohn Marino 		"suggest braces around empty body in %<do%> statement");
4817*e4b17023SJohn Marino   block = c_begin_compound_stmt (flag_isoc99);
4818*e4b17023SJohn Marino   loc = c_parser_peek_token (parser)->location;
4819*e4b17023SJohn Marino   save_break = c_break_label;
4820*e4b17023SJohn Marino   c_break_label = NULL_TREE;
4821*e4b17023SJohn Marino   save_cont = c_cont_label;
4822*e4b17023SJohn Marino   c_cont_label = NULL_TREE;
4823*e4b17023SJohn Marino   body = c_parser_c99_block_statement (parser);
4824*e4b17023SJohn Marino   c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
4825*e4b17023SJohn Marino   new_break = c_break_label;
4826*e4b17023SJohn Marino   c_break_label = save_break;
4827*e4b17023SJohn Marino   new_cont = c_cont_label;
4828*e4b17023SJohn Marino   c_cont_label = save_cont;
4829*e4b17023SJohn Marino   cond = c_parser_paren_condition (parser);
4830*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
4831*e4b17023SJohn Marino     c_parser_skip_to_end_of_block_or_statement (parser);
4832*e4b17023SJohn Marino   c_finish_loop (loc, cond, NULL, body, new_break, new_cont, false);
4833*e4b17023SJohn Marino   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
4834*e4b17023SJohn Marino }
4835*e4b17023SJohn Marino 
4836*e4b17023SJohn Marino /* Parse a for statement (C90 6.6.5, C99 6.8.5).
4837*e4b17023SJohn Marino 
4838*e4b17023SJohn Marino    for-statement:
4839*e4b17023SJohn Marino      for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
4840*e4b17023SJohn Marino      for ( nested-declaration expression[opt] ; expression[opt] ) statement
4841*e4b17023SJohn Marino 
4842*e4b17023SJohn Marino    The form with a declaration is new in C99.
4843*e4b17023SJohn Marino 
4844*e4b17023SJohn Marino    ??? In accordance with the old parser, the declaration may be a
4845*e4b17023SJohn Marino    nested function, which is then rejected in check_for_loop_decls,
4846*e4b17023SJohn Marino    but does it make any sense for this to be included in the grammar?
4847*e4b17023SJohn Marino    Note in particular that the nested function does not include a
4848*e4b17023SJohn Marino    trailing ';', whereas the "declaration" production includes one.
4849*e4b17023SJohn Marino    Also, can we reject bad declarations earlier and cheaper than
4850*e4b17023SJohn Marino    check_for_loop_decls?
4851*e4b17023SJohn Marino 
4852*e4b17023SJohn Marino    In Objective-C, there are two additional variants:
4853*e4b17023SJohn Marino 
4854*e4b17023SJohn Marino    foreach-statement:
4855*e4b17023SJohn Marino      for ( expression in expresssion ) statement
4856*e4b17023SJohn Marino      for ( declaration in expression ) statement
4857*e4b17023SJohn Marino 
4858*e4b17023SJohn Marino    This is inconsistent with C, because the second variant is allowed
4859*e4b17023SJohn Marino    even if c99 is not enabled.
4860*e4b17023SJohn Marino 
4861*e4b17023SJohn Marino    The rest of the comment documents these Objective-C foreach-statement.
4862*e4b17023SJohn Marino 
4863*e4b17023SJohn Marino    Here is the canonical example of the first variant:
4864*e4b17023SJohn Marino     for (object in array)    { do something with object }
4865*e4b17023SJohn Marino    we call the first expression ("object") the "object_expression" and
4866*e4b17023SJohn Marino    the second expression ("array") the "collection_expression".
4867*e4b17023SJohn Marino    object_expression must be an lvalue of type "id" (a generic Objective-C
4868*e4b17023SJohn Marino    object) because the loop works by assigning to object_expression the
4869*e4b17023SJohn Marino    various objects from the collection_expression.  collection_expression
4870*e4b17023SJohn Marino    must evaluate to something of type "id" which responds to the method
4871*e4b17023SJohn Marino    countByEnumeratingWithState:objects:count:.
4872*e4b17023SJohn Marino 
4873*e4b17023SJohn Marino    The canonical example of the second variant is:
4874*e4b17023SJohn Marino     for (id object in array)    { do something with object }
4875*e4b17023SJohn Marino    which is completely equivalent to
4876*e4b17023SJohn Marino     {
4877*e4b17023SJohn Marino       id object;
4878*e4b17023SJohn Marino       for (object in array) { do something with object }
4879*e4b17023SJohn Marino     }
4880*e4b17023SJohn Marino    Note that initizializing 'object' in some way (eg, "for ((object =
4881*e4b17023SJohn Marino    xxx) in array) { do something with object }") is possibly
4882*e4b17023SJohn Marino    technically valid, but completely pointless as 'object' will be
4883*e4b17023SJohn Marino    assigned to something else as soon as the loop starts.  We should
4884*e4b17023SJohn Marino    most likely reject it (TODO).
4885*e4b17023SJohn Marino 
4886*e4b17023SJohn Marino    The beginning of the Objective-C foreach-statement looks exactly
4887*e4b17023SJohn Marino    like the beginning of the for-statement, and we can tell it is a
4888*e4b17023SJohn Marino    foreach-statement only because the initial declaration or
4889*e4b17023SJohn Marino    expression is terminated by 'in' instead of ';'.
4890*e4b17023SJohn Marino */
4891*e4b17023SJohn Marino 
4892*e4b17023SJohn Marino static void
c_parser_for_statement(c_parser * parser)4893*e4b17023SJohn Marino c_parser_for_statement (c_parser *parser)
4894*e4b17023SJohn Marino {
4895*e4b17023SJohn Marino   tree block, cond, incr, save_break, save_cont, body;
4896*e4b17023SJohn Marino   /* The following are only used when parsing an ObjC foreach statement.  */
4897*e4b17023SJohn Marino   tree object_expression;
4898*e4b17023SJohn Marino   /* Silence the bogus uninitialized warning.  */
4899*e4b17023SJohn Marino   tree collection_expression = NULL;
4900*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
4901*e4b17023SJohn Marino   location_t for_loc = c_parser_peek_token (parser)->location;
4902*e4b17023SJohn Marino   bool is_foreach_statement = false;
4903*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
4904*e4b17023SJohn Marino   c_parser_consume_token (parser);
4905*e4b17023SJohn Marino   /* Open a compound statement in Objective-C as well, just in case this is
4906*e4b17023SJohn Marino      as foreach expression.  */
4907*e4b17023SJohn Marino   block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
4908*e4b17023SJohn Marino   cond = error_mark_node;
4909*e4b17023SJohn Marino   incr = error_mark_node;
4910*e4b17023SJohn Marino   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4911*e4b17023SJohn Marino     {
4912*e4b17023SJohn Marino       /* Parse the initialization declaration or expression.  */
4913*e4b17023SJohn Marino       object_expression = error_mark_node;
4914*e4b17023SJohn Marino       parser->objc_could_be_foreach_context = c_dialect_objc ();
4915*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4916*e4b17023SJohn Marino 	{
4917*e4b17023SJohn Marino 	  parser->objc_could_be_foreach_context = false;
4918*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
4919*e4b17023SJohn Marino 	  c_finish_expr_stmt (loc, NULL_TREE);
4920*e4b17023SJohn Marino 	}
4921*e4b17023SJohn Marino       else if (c_parser_next_tokens_start_declaration (parser))
4922*e4b17023SJohn Marino 	{
4923*e4b17023SJohn Marino 	  c_parser_declaration_or_fndef (parser, true, true, true, true, true,
4924*e4b17023SJohn Marino 					 &object_expression);
4925*e4b17023SJohn Marino 	  parser->objc_could_be_foreach_context = false;
4926*e4b17023SJohn Marino 
4927*e4b17023SJohn Marino 	  if (c_parser_next_token_is_keyword (parser, RID_IN))
4928*e4b17023SJohn Marino 	    {
4929*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
4930*e4b17023SJohn Marino 	      is_foreach_statement = true;
4931*e4b17023SJohn Marino 	      if (check_for_loop_decls (for_loc, true) == NULL_TREE)
4932*e4b17023SJohn Marino 		c_parser_error (parser, "multiple iterating variables in fast enumeration");
4933*e4b17023SJohn Marino 	    }
4934*e4b17023SJohn Marino 	  else
4935*e4b17023SJohn Marino 	    check_for_loop_decls (for_loc, flag_isoc99);
4936*e4b17023SJohn Marino 	}
4937*e4b17023SJohn Marino       else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
4938*e4b17023SJohn Marino 	{
4939*e4b17023SJohn Marino 	  /* __extension__ can start a declaration, but is also an
4940*e4b17023SJohn Marino 	     unary operator that can start an expression.  Consume all
4941*e4b17023SJohn Marino 	     but the last of a possible series of __extension__ to
4942*e4b17023SJohn Marino 	     determine which.  */
4943*e4b17023SJohn Marino 	  while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
4944*e4b17023SJohn Marino 		 && (c_parser_peek_2nd_token (parser)->keyword
4945*e4b17023SJohn Marino 		     == RID_EXTENSION))
4946*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
4947*e4b17023SJohn Marino 	  if (c_token_starts_declaration (c_parser_peek_2nd_token (parser)))
4948*e4b17023SJohn Marino 	    {
4949*e4b17023SJohn Marino 	      int ext;
4950*e4b17023SJohn Marino 	      ext = disable_extension_diagnostics ();
4951*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
4952*e4b17023SJohn Marino 	      c_parser_declaration_or_fndef (parser, true, true, true, true,
4953*e4b17023SJohn Marino 					     true, &object_expression);
4954*e4b17023SJohn Marino 	      parser->objc_could_be_foreach_context = false;
4955*e4b17023SJohn Marino 
4956*e4b17023SJohn Marino 	      restore_extension_diagnostics (ext);
4957*e4b17023SJohn Marino 	      if (c_parser_next_token_is_keyword (parser, RID_IN))
4958*e4b17023SJohn Marino 		{
4959*e4b17023SJohn Marino 		  c_parser_consume_token (parser);
4960*e4b17023SJohn Marino 		  is_foreach_statement = true;
4961*e4b17023SJohn Marino 		  if (check_for_loop_decls (for_loc, true) == NULL_TREE)
4962*e4b17023SJohn Marino 		    c_parser_error (parser, "multiple iterating variables in fast enumeration");
4963*e4b17023SJohn Marino 		}
4964*e4b17023SJohn Marino 	      else
4965*e4b17023SJohn Marino 		check_for_loop_decls (for_loc, flag_isoc99);
4966*e4b17023SJohn Marino 	    }
4967*e4b17023SJohn Marino 	  else
4968*e4b17023SJohn Marino 	    goto init_expr;
4969*e4b17023SJohn Marino 	}
4970*e4b17023SJohn Marino       else
4971*e4b17023SJohn Marino 	{
4972*e4b17023SJohn Marino 	init_expr:
4973*e4b17023SJohn Marino 	  {
4974*e4b17023SJohn Marino 	    tree init_expression;
4975*e4b17023SJohn Marino 	    init_expression = c_parser_expression (parser).value;
4976*e4b17023SJohn Marino 	    parser->objc_could_be_foreach_context = false;
4977*e4b17023SJohn Marino 	    if (c_parser_next_token_is_keyword (parser, RID_IN))
4978*e4b17023SJohn Marino 	      {
4979*e4b17023SJohn Marino 		c_parser_consume_token (parser);
4980*e4b17023SJohn Marino 		is_foreach_statement = true;
4981*e4b17023SJohn Marino 		if (! lvalue_p (init_expression))
4982*e4b17023SJohn Marino 		  c_parser_error (parser, "invalid iterating variable in fast enumeration");
4983*e4b17023SJohn Marino 		object_expression = c_fully_fold (init_expression, false, NULL);
4984*e4b17023SJohn Marino 	      }
4985*e4b17023SJohn Marino 	    else
4986*e4b17023SJohn Marino 	      {
4987*e4b17023SJohn Marino 		c_finish_expr_stmt (loc, init_expression);
4988*e4b17023SJohn Marino 		c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
4989*e4b17023SJohn Marino 	      }
4990*e4b17023SJohn Marino 	  }
4991*e4b17023SJohn Marino 	}
4992*e4b17023SJohn Marino       /* Parse the loop condition.  In the case of a foreach
4993*e4b17023SJohn Marino 	 statement, there is no loop condition.  */
4994*e4b17023SJohn Marino       gcc_assert (!parser->objc_could_be_foreach_context);
4995*e4b17023SJohn Marino       if (!is_foreach_statement)
4996*e4b17023SJohn Marino 	{
4997*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4998*e4b17023SJohn Marino 	    {
4999*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
5000*e4b17023SJohn Marino 	      cond = NULL_TREE;
5001*e4b17023SJohn Marino 	    }
5002*e4b17023SJohn Marino 	  else
5003*e4b17023SJohn Marino 	    {
5004*e4b17023SJohn Marino 	      cond = c_parser_condition (parser);
5005*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5006*e4b17023SJohn Marino 	    }
5007*e4b17023SJohn Marino 	}
5008*e4b17023SJohn Marino       /* Parse the increment expression (the third expression in a
5009*e4b17023SJohn Marino 	 for-statement).  In the case of a foreach-statement, this is
5010*e4b17023SJohn Marino 	 the expression that follows the 'in'.  */
5011*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5012*e4b17023SJohn Marino 	{
5013*e4b17023SJohn Marino 	  if (is_foreach_statement)
5014*e4b17023SJohn Marino 	    {
5015*e4b17023SJohn Marino 	      c_parser_error (parser, "missing collection in fast enumeration");
5016*e4b17023SJohn Marino 	      collection_expression = error_mark_node;
5017*e4b17023SJohn Marino 	    }
5018*e4b17023SJohn Marino 	  else
5019*e4b17023SJohn Marino 	    incr = c_process_expr_stmt (loc, NULL_TREE);
5020*e4b17023SJohn Marino 	}
5021*e4b17023SJohn Marino       else
5022*e4b17023SJohn Marino 	{
5023*e4b17023SJohn Marino 	  if (is_foreach_statement)
5024*e4b17023SJohn Marino 	    collection_expression = c_fully_fold (c_parser_expression (parser).value,
5025*e4b17023SJohn Marino 						  false, NULL);
5026*e4b17023SJohn Marino 	  else
5027*e4b17023SJohn Marino 	    incr = c_process_expr_stmt (loc, c_parser_expression (parser).value);
5028*e4b17023SJohn Marino 	}
5029*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
5030*e4b17023SJohn Marino     }
5031*e4b17023SJohn Marino   save_break = c_break_label;
5032*e4b17023SJohn Marino   c_break_label = NULL_TREE;
5033*e4b17023SJohn Marino   save_cont = c_cont_label;
5034*e4b17023SJohn Marino   c_cont_label = NULL_TREE;
5035*e4b17023SJohn Marino   body = c_parser_c99_block_statement (parser);
5036*e4b17023SJohn Marino   if (is_foreach_statement)
5037*e4b17023SJohn Marino     objc_finish_foreach_loop (loc, object_expression, collection_expression, body, c_break_label, c_cont_label);
5038*e4b17023SJohn Marino   else
5039*e4b17023SJohn Marino     c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label, true);
5040*e4b17023SJohn Marino   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99 || c_dialect_objc ()));
5041*e4b17023SJohn Marino   c_break_label = save_break;
5042*e4b17023SJohn Marino   c_cont_label = save_cont;
5043*e4b17023SJohn Marino }
5044*e4b17023SJohn Marino 
5045*e4b17023SJohn Marino /* Parse an asm statement, a GNU extension.  This is a full-blown asm
5046*e4b17023SJohn Marino    statement with inputs, outputs, clobbers, and volatile tag
5047*e4b17023SJohn Marino    allowed.
5048*e4b17023SJohn Marino 
5049*e4b17023SJohn Marino    asm-statement:
5050*e4b17023SJohn Marino      asm type-qualifier[opt] ( asm-argument ) ;
5051*e4b17023SJohn Marino      asm type-qualifier[opt] goto ( asm-goto-argument ) ;
5052*e4b17023SJohn Marino 
5053*e4b17023SJohn Marino    asm-argument:
5054*e4b17023SJohn Marino      asm-string-literal
5055*e4b17023SJohn Marino      asm-string-literal : asm-operands[opt]
5056*e4b17023SJohn Marino      asm-string-literal : asm-operands[opt] : asm-operands[opt]
5057*e4b17023SJohn Marino      asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers[opt]
5058*e4b17023SJohn Marino 
5059*e4b17023SJohn Marino    asm-goto-argument:
5060*e4b17023SJohn Marino      asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
5061*e4b17023SJohn Marino        : asm-goto-operands
5062*e4b17023SJohn Marino 
5063*e4b17023SJohn Marino    Qualifiers other than volatile are accepted in the syntax but
5064*e4b17023SJohn Marino    warned for.  */
5065*e4b17023SJohn Marino 
5066*e4b17023SJohn Marino static tree
c_parser_asm_statement(c_parser * parser)5067*e4b17023SJohn Marino c_parser_asm_statement (c_parser *parser)
5068*e4b17023SJohn Marino {
5069*e4b17023SJohn Marino   tree quals, str, outputs, inputs, clobbers, labels, ret;
5070*e4b17023SJohn Marino   bool simple, is_goto;
5071*e4b17023SJohn Marino   location_t asm_loc = c_parser_peek_token (parser)->location;
5072*e4b17023SJohn Marino   int section, nsections;
5073*e4b17023SJohn Marino 
5074*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
5075*e4b17023SJohn Marino   c_parser_consume_token (parser);
5076*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_VOLATILE))
5077*e4b17023SJohn Marino     {
5078*e4b17023SJohn Marino       quals = c_parser_peek_token (parser)->value;
5079*e4b17023SJohn Marino       c_parser_consume_token (parser);
5080*e4b17023SJohn Marino     }
5081*e4b17023SJohn Marino   else if (c_parser_next_token_is_keyword (parser, RID_CONST)
5082*e4b17023SJohn Marino 	   || c_parser_next_token_is_keyword (parser, RID_RESTRICT))
5083*e4b17023SJohn Marino     {
5084*e4b17023SJohn Marino       warning_at (c_parser_peek_token (parser)->location,
5085*e4b17023SJohn Marino 		  0,
5086*e4b17023SJohn Marino 		  "%E qualifier ignored on asm",
5087*e4b17023SJohn Marino 		  c_parser_peek_token (parser)->value);
5088*e4b17023SJohn Marino       quals = NULL_TREE;
5089*e4b17023SJohn Marino       c_parser_consume_token (parser);
5090*e4b17023SJohn Marino     }
5091*e4b17023SJohn Marino   else
5092*e4b17023SJohn Marino     quals = NULL_TREE;
5093*e4b17023SJohn Marino 
5094*e4b17023SJohn Marino   is_goto = false;
5095*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_GOTO))
5096*e4b17023SJohn Marino     {
5097*e4b17023SJohn Marino       c_parser_consume_token (parser);
5098*e4b17023SJohn Marino       is_goto = true;
5099*e4b17023SJohn Marino     }
5100*e4b17023SJohn Marino 
5101*e4b17023SJohn Marino   /* ??? Follow the C++ parser rather than using the
5102*e4b17023SJohn Marino      lex_untranslated_string kludge.  */
5103*e4b17023SJohn Marino   parser->lex_untranslated_string = true;
5104*e4b17023SJohn Marino   ret = NULL;
5105*e4b17023SJohn Marino 
5106*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5107*e4b17023SJohn Marino     goto error;
5108*e4b17023SJohn Marino 
5109*e4b17023SJohn Marino   str = c_parser_asm_string_literal (parser);
5110*e4b17023SJohn Marino   if (str == NULL_TREE)
5111*e4b17023SJohn Marino     goto error_close_paren;
5112*e4b17023SJohn Marino 
5113*e4b17023SJohn Marino   simple = true;
5114*e4b17023SJohn Marino   outputs = NULL_TREE;
5115*e4b17023SJohn Marino   inputs = NULL_TREE;
5116*e4b17023SJohn Marino   clobbers = NULL_TREE;
5117*e4b17023SJohn Marino   labels = NULL_TREE;
5118*e4b17023SJohn Marino 
5119*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
5120*e4b17023SJohn Marino     goto done_asm;
5121*e4b17023SJohn Marino 
5122*e4b17023SJohn Marino   /* Parse each colon-delimited section of operands.  */
5123*e4b17023SJohn Marino   nsections = 3 + is_goto;
5124*e4b17023SJohn Marino   for (section = 0; section < nsections; ++section)
5125*e4b17023SJohn Marino     {
5126*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_COLON,
5127*e4b17023SJohn Marino 			     is_goto
5128*e4b17023SJohn Marino 			     ? "expected %<:%>"
5129*e4b17023SJohn Marino 			     : "expected %<:%> or %<)%>"))
5130*e4b17023SJohn Marino 	goto error_close_paren;
5131*e4b17023SJohn Marino 
5132*e4b17023SJohn Marino       /* Once past any colon, we're no longer a simple asm.  */
5133*e4b17023SJohn Marino       simple = false;
5134*e4b17023SJohn Marino 
5135*e4b17023SJohn Marino       if ((!c_parser_next_token_is (parser, CPP_COLON)
5136*e4b17023SJohn Marino 	   && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5137*e4b17023SJohn Marino 	  || section == 3)
5138*e4b17023SJohn Marino 	switch (section)
5139*e4b17023SJohn Marino 	  {
5140*e4b17023SJohn Marino 	  case 0:
5141*e4b17023SJohn Marino 	    /* For asm goto, we don't allow output operands, but reserve
5142*e4b17023SJohn Marino 	       the slot for a future extension that does allow them.  */
5143*e4b17023SJohn Marino 	    if (!is_goto)
5144*e4b17023SJohn Marino 	      outputs = c_parser_asm_operands (parser, false);
5145*e4b17023SJohn Marino 	    break;
5146*e4b17023SJohn Marino 	  case 1:
5147*e4b17023SJohn Marino 	    inputs = c_parser_asm_operands (parser, true);
5148*e4b17023SJohn Marino 	    break;
5149*e4b17023SJohn Marino 	  case 2:
5150*e4b17023SJohn Marino 	    clobbers = c_parser_asm_clobbers (parser);
5151*e4b17023SJohn Marino 	    break;
5152*e4b17023SJohn Marino 	  case 3:
5153*e4b17023SJohn Marino 	    labels = c_parser_asm_goto_operands (parser);
5154*e4b17023SJohn Marino 	    break;
5155*e4b17023SJohn Marino 	  default:
5156*e4b17023SJohn Marino 	    gcc_unreachable ();
5157*e4b17023SJohn Marino 	  }
5158*e4b17023SJohn Marino 
5159*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
5160*e4b17023SJohn Marino 	goto done_asm;
5161*e4b17023SJohn Marino     }
5162*e4b17023SJohn Marino 
5163*e4b17023SJohn Marino  done_asm:
5164*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
5165*e4b17023SJohn Marino     {
5166*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5167*e4b17023SJohn Marino       goto error;
5168*e4b17023SJohn Marino     }
5169*e4b17023SJohn Marino 
5170*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
5171*e4b17023SJohn Marino     c_parser_skip_to_end_of_block_or_statement (parser);
5172*e4b17023SJohn Marino 
5173*e4b17023SJohn Marino   ret = build_asm_stmt (quals, build_asm_expr (asm_loc, str, outputs, inputs,
5174*e4b17023SJohn Marino 					       clobbers, labels, simple));
5175*e4b17023SJohn Marino 
5176*e4b17023SJohn Marino  error:
5177*e4b17023SJohn Marino   parser->lex_untranslated_string = false;
5178*e4b17023SJohn Marino   return ret;
5179*e4b17023SJohn Marino 
5180*e4b17023SJohn Marino  error_close_paren:
5181*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5182*e4b17023SJohn Marino   goto error;
5183*e4b17023SJohn Marino }
5184*e4b17023SJohn Marino 
5185*e4b17023SJohn Marino /* Parse asm operands, a GNU extension.  If CONVERT_P (for inputs but
5186*e4b17023SJohn Marino    not outputs), apply the default conversion of functions and arrays
5187*e4b17023SJohn Marino    to pointers.
5188*e4b17023SJohn Marino 
5189*e4b17023SJohn Marino    asm-operands:
5190*e4b17023SJohn Marino      asm-operand
5191*e4b17023SJohn Marino      asm-operands , asm-operand
5192*e4b17023SJohn Marino 
5193*e4b17023SJohn Marino    asm-operand:
5194*e4b17023SJohn Marino      asm-string-literal ( expression )
5195*e4b17023SJohn Marino      [ identifier ] asm-string-literal ( expression )
5196*e4b17023SJohn Marino */
5197*e4b17023SJohn Marino 
5198*e4b17023SJohn Marino static tree
c_parser_asm_operands(c_parser * parser,bool convert_p)5199*e4b17023SJohn Marino c_parser_asm_operands (c_parser *parser, bool convert_p)
5200*e4b17023SJohn Marino {
5201*e4b17023SJohn Marino   tree list = NULL_TREE;
5202*e4b17023SJohn Marino   location_t loc;
5203*e4b17023SJohn Marino   while (true)
5204*e4b17023SJohn Marino     {
5205*e4b17023SJohn Marino       tree name, str;
5206*e4b17023SJohn Marino       struct c_expr expr;
5207*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
5208*e4b17023SJohn Marino 	{
5209*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
5210*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_NAME))
5211*e4b17023SJohn Marino 	    {
5212*e4b17023SJohn Marino 	      tree id = c_parser_peek_token (parser)->value;
5213*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
5214*e4b17023SJohn Marino 	      name = build_string (IDENTIFIER_LENGTH (id),
5215*e4b17023SJohn Marino 				   IDENTIFIER_POINTER (id));
5216*e4b17023SJohn Marino 	    }
5217*e4b17023SJohn Marino 	  else
5218*e4b17023SJohn Marino 	    {
5219*e4b17023SJohn Marino 	      c_parser_error (parser, "expected identifier");
5220*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
5221*e4b17023SJohn Marino 	      return NULL_TREE;
5222*e4b17023SJohn Marino 	    }
5223*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5224*e4b17023SJohn Marino 				     "expected %<]%>");
5225*e4b17023SJohn Marino 	}
5226*e4b17023SJohn Marino       else
5227*e4b17023SJohn Marino 	name = NULL_TREE;
5228*e4b17023SJohn Marino       str = c_parser_asm_string_literal (parser);
5229*e4b17023SJohn Marino       if (str == NULL_TREE)
5230*e4b17023SJohn Marino 	return NULL_TREE;
5231*e4b17023SJohn Marino       parser->lex_untranslated_string = false;
5232*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5233*e4b17023SJohn Marino 	{
5234*e4b17023SJohn Marino 	  parser->lex_untranslated_string = true;
5235*e4b17023SJohn Marino 	  return NULL_TREE;
5236*e4b17023SJohn Marino 	}
5237*e4b17023SJohn Marino       loc = c_parser_peek_token (parser)->location;
5238*e4b17023SJohn Marino       expr = c_parser_expression (parser);
5239*e4b17023SJohn Marino       mark_exp_read (expr.value);
5240*e4b17023SJohn Marino       if (convert_p)
5241*e4b17023SJohn Marino 	expr = default_function_array_conversion (loc, expr);
5242*e4b17023SJohn Marino       expr.value = c_fully_fold (expr.value, false, NULL);
5243*e4b17023SJohn Marino       parser->lex_untranslated_string = true;
5244*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
5245*e4b17023SJohn Marino 	{
5246*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5247*e4b17023SJohn Marino 	  return NULL_TREE;
5248*e4b17023SJohn Marino 	}
5249*e4b17023SJohn Marino       list = chainon (list, build_tree_list (build_tree_list (name, str),
5250*e4b17023SJohn Marino 					     expr.value));
5251*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_COMMA))
5252*e4b17023SJohn Marino 	c_parser_consume_token (parser);
5253*e4b17023SJohn Marino       else
5254*e4b17023SJohn Marino 	break;
5255*e4b17023SJohn Marino     }
5256*e4b17023SJohn Marino   return list;
5257*e4b17023SJohn Marino }
5258*e4b17023SJohn Marino 
5259*e4b17023SJohn Marino /* Parse asm clobbers, a GNU extension.
5260*e4b17023SJohn Marino 
5261*e4b17023SJohn Marino    asm-clobbers:
5262*e4b17023SJohn Marino      asm-string-literal
5263*e4b17023SJohn Marino      asm-clobbers , asm-string-literal
5264*e4b17023SJohn Marino */
5265*e4b17023SJohn Marino 
5266*e4b17023SJohn Marino static tree
c_parser_asm_clobbers(c_parser * parser)5267*e4b17023SJohn Marino c_parser_asm_clobbers (c_parser *parser)
5268*e4b17023SJohn Marino {
5269*e4b17023SJohn Marino   tree list = NULL_TREE;
5270*e4b17023SJohn Marino   while (true)
5271*e4b17023SJohn Marino     {
5272*e4b17023SJohn Marino       tree str = c_parser_asm_string_literal (parser);
5273*e4b17023SJohn Marino       if (str)
5274*e4b17023SJohn Marino 	list = tree_cons (NULL_TREE, str, list);
5275*e4b17023SJohn Marino       else
5276*e4b17023SJohn Marino 	return NULL_TREE;
5277*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_COMMA))
5278*e4b17023SJohn Marino 	c_parser_consume_token (parser);
5279*e4b17023SJohn Marino       else
5280*e4b17023SJohn Marino 	break;
5281*e4b17023SJohn Marino     }
5282*e4b17023SJohn Marino   return list;
5283*e4b17023SJohn Marino }
5284*e4b17023SJohn Marino 
5285*e4b17023SJohn Marino /* Parse asm goto labels, a GNU extension.
5286*e4b17023SJohn Marino 
5287*e4b17023SJohn Marino    asm-goto-operands:
5288*e4b17023SJohn Marino      identifier
5289*e4b17023SJohn Marino      asm-goto-operands , identifier
5290*e4b17023SJohn Marino */
5291*e4b17023SJohn Marino 
5292*e4b17023SJohn Marino static tree
c_parser_asm_goto_operands(c_parser * parser)5293*e4b17023SJohn Marino c_parser_asm_goto_operands (c_parser *parser)
5294*e4b17023SJohn Marino {
5295*e4b17023SJohn Marino   tree list = NULL_TREE;
5296*e4b17023SJohn Marino   while (true)
5297*e4b17023SJohn Marino     {
5298*e4b17023SJohn Marino       tree name, label;
5299*e4b17023SJohn Marino 
5300*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_NAME))
5301*e4b17023SJohn Marino 	{
5302*e4b17023SJohn Marino 	  c_token *tok = c_parser_peek_token (parser);
5303*e4b17023SJohn Marino 	  name = tok->value;
5304*e4b17023SJohn Marino 	  label = lookup_label_for_goto (tok->location, name);
5305*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
5306*e4b17023SJohn Marino 	  TREE_USED (label) = 1;
5307*e4b17023SJohn Marino 	}
5308*e4b17023SJohn Marino       else
5309*e4b17023SJohn Marino 	{
5310*e4b17023SJohn Marino 	  c_parser_error (parser, "expected identifier");
5311*e4b17023SJohn Marino 	  return NULL_TREE;
5312*e4b17023SJohn Marino 	}
5313*e4b17023SJohn Marino 
5314*e4b17023SJohn Marino       name = build_string (IDENTIFIER_LENGTH (name),
5315*e4b17023SJohn Marino 			   IDENTIFIER_POINTER (name));
5316*e4b17023SJohn Marino       list = tree_cons (name, label, list);
5317*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_COMMA))
5318*e4b17023SJohn Marino 	c_parser_consume_token (parser);
5319*e4b17023SJohn Marino       else
5320*e4b17023SJohn Marino 	return nreverse (list);
5321*e4b17023SJohn Marino     }
5322*e4b17023SJohn Marino }
5323*e4b17023SJohn Marino 
5324*e4b17023SJohn Marino /* Parse an expression other than a compound expression; that is, an
5325*e4b17023SJohn Marino    assignment expression (C90 6.3.16, C99 6.5.16).  If AFTER is not
5326*e4b17023SJohn Marino    NULL then it is an Objective-C message expression which is the
5327*e4b17023SJohn Marino    primary-expression starting the expression as an initializer.
5328*e4b17023SJohn Marino 
5329*e4b17023SJohn Marino    assignment-expression:
5330*e4b17023SJohn Marino      conditional-expression
5331*e4b17023SJohn Marino      unary-expression assignment-operator assignment-expression
5332*e4b17023SJohn Marino 
5333*e4b17023SJohn Marino    assignment-operator: one of
5334*e4b17023SJohn Marino      = *= /= %= += -= <<= >>= &= ^= |=
5335*e4b17023SJohn Marino 
5336*e4b17023SJohn Marino    In GNU C we accept any conditional expression on the LHS and
5337*e4b17023SJohn Marino    diagnose the invalid lvalue rather than producing a syntax
5338*e4b17023SJohn Marino    error.  */
5339*e4b17023SJohn Marino 
5340*e4b17023SJohn Marino static struct c_expr
c_parser_expr_no_commas(c_parser * parser,struct c_expr * after)5341*e4b17023SJohn Marino c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
5342*e4b17023SJohn Marino {
5343*e4b17023SJohn Marino   struct c_expr lhs, rhs, ret;
5344*e4b17023SJohn Marino   enum tree_code code;
5345*e4b17023SJohn Marino   location_t op_location, exp_location;
5346*e4b17023SJohn Marino   gcc_assert (!after || c_dialect_objc ());
5347*e4b17023SJohn Marino   lhs = c_parser_conditional_expression (parser, after);
5348*e4b17023SJohn Marino   op_location = c_parser_peek_token (parser)->location;
5349*e4b17023SJohn Marino   switch (c_parser_peek_token (parser)->type)
5350*e4b17023SJohn Marino     {
5351*e4b17023SJohn Marino     case CPP_EQ:
5352*e4b17023SJohn Marino       code = NOP_EXPR;
5353*e4b17023SJohn Marino       break;
5354*e4b17023SJohn Marino     case CPP_MULT_EQ:
5355*e4b17023SJohn Marino       code = MULT_EXPR;
5356*e4b17023SJohn Marino       break;
5357*e4b17023SJohn Marino     case CPP_DIV_EQ:
5358*e4b17023SJohn Marino       code = TRUNC_DIV_EXPR;
5359*e4b17023SJohn Marino       break;
5360*e4b17023SJohn Marino     case CPP_MOD_EQ:
5361*e4b17023SJohn Marino       code = TRUNC_MOD_EXPR;
5362*e4b17023SJohn Marino       break;
5363*e4b17023SJohn Marino     case CPP_PLUS_EQ:
5364*e4b17023SJohn Marino       code = PLUS_EXPR;
5365*e4b17023SJohn Marino       break;
5366*e4b17023SJohn Marino     case CPP_MINUS_EQ:
5367*e4b17023SJohn Marino       code = MINUS_EXPR;
5368*e4b17023SJohn Marino       break;
5369*e4b17023SJohn Marino     case CPP_LSHIFT_EQ:
5370*e4b17023SJohn Marino       code = LSHIFT_EXPR;
5371*e4b17023SJohn Marino       break;
5372*e4b17023SJohn Marino     case CPP_RSHIFT_EQ:
5373*e4b17023SJohn Marino       code = RSHIFT_EXPR;
5374*e4b17023SJohn Marino       break;
5375*e4b17023SJohn Marino     case CPP_AND_EQ:
5376*e4b17023SJohn Marino       code = BIT_AND_EXPR;
5377*e4b17023SJohn Marino       break;
5378*e4b17023SJohn Marino     case CPP_XOR_EQ:
5379*e4b17023SJohn Marino       code = BIT_XOR_EXPR;
5380*e4b17023SJohn Marino       break;
5381*e4b17023SJohn Marino     case CPP_OR_EQ:
5382*e4b17023SJohn Marino       code = BIT_IOR_EXPR;
5383*e4b17023SJohn Marino       break;
5384*e4b17023SJohn Marino     default:
5385*e4b17023SJohn Marino       return lhs;
5386*e4b17023SJohn Marino     }
5387*e4b17023SJohn Marino   c_parser_consume_token (parser);
5388*e4b17023SJohn Marino   exp_location = c_parser_peek_token (parser)->location;
5389*e4b17023SJohn Marino   rhs = c_parser_expr_no_commas (parser, NULL);
5390*e4b17023SJohn Marino   rhs = default_function_array_read_conversion (exp_location, rhs);
5391*e4b17023SJohn Marino   ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
5392*e4b17023SJohn Marino 				 code, exp_location, rhs.value,
5393*e4b17023SJohn Marino 				 rhs.original_type);
5394*e4b17023SJohn Marino   if (code == NOP_EXPR)
5395*e4b17023SJohn Marino     ret.original_code = MODIFY_EXPR;
5396*e4b17023SJohn Marino   else
5397*e4b17023SJohn Marino     {
5398*e4b17023SJohn Marino       TREE_NO_WARNING (ret.value) = 1;
5399*e4b17023SJohn Marino       ret.original_code = ERROR_MARK;
5400*e4b17023SJohn Marino     }
5401*e4b17023SJohn Marino   ret.original_type = NULL;
5402*e4b17023SJohn Marino   return ret;
5403*e4b17023SJohn Marino }
5404*e4b17023SJohn Marino 
5405*e4b17023SJohn Marino /* Parse a conditional expression (C90 6.3.15, C99 6.5.15).  If AFTER
5406*e4b17023SJohn Marino    is not NULL then it is an Objective-C message expression which is
5407*e4b17023SJohn Marino    the primary-expression starting the expression as an initializer.
5408*e4b17023SJohn Marino 
5409*e4b17023SJohn Marino    conditional-expression:
5410*e4b17023SJohn Marino      logical-OR-expression
5411*e4b17023SJohn Marino      logical-OR-expression ? expression : conditional-expression
5412*e4b17023SJohn Marino 
5413*e4b17023SJohn Marino    GNU extensions:
5414*e4b17023SJohn Marino 
5415*e4b17023SJohn Marino    conditional-expression:
5416*e4b17023SJohn Marino      logical-OR-expression ? : conditional-expression
5417*e4b17023SJohn Marino */
5418*e4b17023SJohn Marino 
5419*e4b17023SJohn Marino static struct c_expr
c_parser_conditional_expression(c_parser * parser,struct c_expr * after)5420*e4b17023SJohn Marino c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
5421*e4b17023SJohn Marino {
5422*e4b17023SJohn Marino   struct c_expr cond, exp1, exp2, ret;
5423*e4b17023SJohn Marino   location_t cond_loc, colon_loc, middle_loc;
5424*e4b17023SJohn Marino 
5425*e4b17023SJohn Marino   gcc_assert (!after || c_dialect_objc ());
5426*e4b17023SJohn Marino 
5427*e4b17023SJohn Marino   cond = c_parser_binary_expression (parser, after, PREC_NONE);
5428*e4b17023SJohn Marino 
5429*e4b17023SJohn Marino   if (c_parser_next_token_is_not (parser, CPP_QUERY))
5430*e4b17023SJohn Marino     return cond;
5431*e4b17023SJohn Marino   cond_loc = c_parser_peek_token (parser)->location;
5432*e4b17023SJohn Marino   cond = default_function_array_read_conversion (cond_loc, cond);
5433*e4b17023SJohn Marino   c_parser_consume_token (parser);
5434*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_COLON))
5435*e4b17023SJohn Marino     {
5436*e4b17023SJohn Marino       tree eptype = NULL_TREE;
5437*e4b17023SJohn Marino 
5438*e4b17023SJohn Marino       middle_loc = c_parser_peek_token (parser)->location;
5439*e4b17023SJohn Marino       pedwarn (middle_loc, OPT_pedantic,
5440*e4b17023SJohn Marino 	       "ISO C forbids omitting the middle term of a ?: expression");
5441*e4b17023SJohn Marino       warn_for_omitted_condop (middle_loc, cond.value);
5442*e4b17023SJohn Marino       if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
5443*e4b17023SJohn Marino 	{
5444*e4b17023SJohn Marino 	  eptype = TREE_TYPE (cond.value);
5445*e4b17023SJohn Marino 	  cond.value = TREE_OPERAND (cond.value, 0);
5446*e4b17023SJohn Marino 	}
5447*e4b17023SJohn Marino       /* Make sure first operand is calculated only once.  */
5448*e4b17023SJohn Marino       exp1.value = c_save_expr (default_conversion (cond.value));
5449*e4b17023SJohn Marino       if (eptype)
5450*e4b17023SJohn Marino 	exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
5451*e4b17023SJohn Marino       exp1.original_type = NULL;
5452*e4b17023SJohn Marino       cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
5453*e4b17023SJohn Marino       c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
5454*e4b17023SJohn Marino     }
5455*e4b17023SJohn Marino   else
5456*e4b17023SJohn Marino     {
5457*e4b17023SJohn Marino       cond.value
5458*e4b17023SJohn Marino 	= c_objc_common_truthvalue_conversion
5459*e4b17023SJohn Marino 	(cond_loc, default_conversion (cond.value));
5460*e4b17023SJohn Marino       c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
5461*e4b17023SJohn Marino       exp1 = c_parser_expression_conv (parser);
5462*e4b17023SJohn Marino       mark_exp_read (exp1.value);
5463*e4b17023SJohn Marino       c_inhibit_evaluation_warnings +=
5464*e4b17023SJohn Marino 	((cond.value == truthvalue_true_node)
5465*e4b17023SJohn Marino 	 - (cond.value == truthvalue_false_node));
5466*e4b17023SJohn Marino     }
5467*e4b17023SJohn Marino 
5468*e4b17023SJohn Marino   colon_loc = c_parser_peek_token (parser)->location;
5469*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5470*e4b17023SJohn Marino     {
5471*e4b17023SJohn Marino       c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
5472*e4b17023SJohn Marino       ret.value = error_mark_node;
5473*e4b17023SJohn Marino       ret.original_code = ERROR_MARK;
5474*e4b17023SJohn Marino       ret.original_type = NULL;
5475*e4b17023SJohn Marino       return ret;
5476*e4b17023SJohn Marino     }
5477*e4b17023SJohn Marino   {
5478*e4b17023SJohn Marino     location_t exp2_loc = c_parser_peek_token (parser)->location;
5479*e4b17023SJohn Marino     exp2 = c_parser_conditional_expression (parser, NULL);
5480*e4b17023SJohn Marino     exp2 = default_function_array_read_conversion (exp2_loc, exp2);
5481*e4b17023SJohn Marino   }
5482*e4b17023SJohn Marino   c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
5483*e4b17023SJohn Marino   ret.value = build_conditional_expr (colon_loc, cond.value,
5484*e4b17023SJohn Marino 				      cond.original_code == C_MAYBE_CONST_EXPR,
5485*e4b17023SJohn Marino 				      exp1.value, exp1.original_type,
5486*e4b17023SJohn Marino 				      exp2.value, exp2.original_type);
5487*e4b17023SJohn Marino   ret.original_code = ERROR_MARK;
5488*e4b17023SJohn Marino   if (exp1.value == error_mark_node || exp2.value == error_mark_node)
5489*e4b17023SJohn Marino     ret.original_type = NULL;
5490*e4b17023SJohn Marino   else
5491*e4b17023SJohn Marino     {
5492*e4b17023SJohn Marino       tree t1, t2;
5493*e4b17023SJohn Marino 
5494*e4b17023SJohn Marino       /* If both sides are enum type, the default conversion will have
5495*e4b17023SJohn Marino 	 made the type of the result be an integer type.  We want to
5496*e4b17023SJohn Marino 	 remember the enum types we started with.  */
5497*e4b17023SJohn Marino       t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
5498*e4b17023SJohn Marino       t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
5499*e4b17023SJohn Marino       ret.original_type = ((t1 != error_mark_node
5500*e4b17023SJohn Marino 			    && t2 != error_mark_node
5501*e4b17023SJohn Marino 			    && (TYPE_MAIN_VARIANT (t1)
5502*e4b17023SJohn Marino 				== TYPE_MAIN_VARIANT (t2)))
5503*e4b17023SJohn Marino 			   ? t1
5504*e4b17023SJohn Marino 			   : NULL);
5505*e4b17023SJohn Marino     }
5506*e4b17023SJohn Marino   return ret;
5507*e4b17023SJohn Marino }
5508*e4b17023SJohn Marino 
5509*e4b17023SJohn Marino /* Parse a binary expression; that is, a logical-OR-expression (C90
5510*e4b17023SJohn Marino    6.3.5-6.3.14, C99 6.5.5-6.5.14).  If AFTER is not NULL then it is
5511*e4b17023SJohn Marino    an Objective-C message expression which is the primary-expression
5512*e4b17023SJohn Marino    starting the expression as an initializer.  PREC is the starting
5513*e4b17023SJohn Marino    precedence, usually PREC_NONE.
5514*e4b17023SJohn Marino 
5515*e4b17023SJohn Marino    multiplicative-expression:
5516*e4b17023SJohn Marino      cast-expression
5517*e4b17023SJohn Marino      multiplicative-expression * cast-expression
5518*e4b17023SJohn Marino      multiplicative-expression / cast-expression
5519*e4b17023SJohn Marino      multiplicative-expression % cast-expression
5520*e4b17023SJohn Marino 
5521*e4b17023SJohn Marino    additive-expression:
5522*e4b17023SJohn Marino      multiplicative-expression
5523*e4b17023SJohn Marino      additive-expression + multiplicative-expression
5524*e4b17023SJohn Marino      additive-expression - multiplicative-expression
5525*e4b17023SJohn Marino 
5526*e4b17023SJohn Marino    shift-expression:
5527*e4b17023SJohn Marino      additive-expression
5528*e4b17023SJohn Marino      shift-expression << additive-expression
5529*e4b17023SJohn Marino      shift-expression >> additive-expression
5530*e4b17023SJohn Marino 
5531*e4b17023SJohn Marino    relational-expression:
5532*e4b17023SJohn Marino      shift-expression
5533*e4b17023SJohn Marino      relational-expression < shift-expression
5534*e4b17023SJohn Marino      relational-expression > shift-expression
5535*e4b17023SJohn Marino      relational-expression <= shift-expression
5536*e4b17023SJohn Marino      relational-expression >= shift-expression
5537*e4b17023SJohn Marino 
5538*e4b17023SJohn Marino    equality-expression:
5539*e4b17023SJohn Marino      relational-expression
5540*e4b17023SJohn Marino      equality-expression == relational-expression
5541*e4b17023SJohn Marino      equality-expression != relational-expression
5542*e4b17023SJohn Marino 
5543*e4b17023SJohn Marino    AND-expression:
5544*e4b17023SJohn Marino      equality-expression
5545*e4b17023SJohn Marino      AND-expression & equality-expression
5546*e4b17023SJohn Marino 
5547*e4b17023SJohn Marino    exclusive-OR-expression:
5548*e4b17023SJohn Marino      AND-expression
5549*e4b17023SJohn Marino      exclusive-OR-expression ^ AND-expression
5550*e4b17023SJohn Marino 
5551*e4b17023SJohn Marino    inclusive-OR-expression:
5552*e4b17023SJohn Marino      exclusive-OR-expression
5553*e4b17023SJohn Marino      inclusive-OR-expression | exclusive-OR-expression
5554*e4b17023SJohn Marino 
5555*e4b17023SJohn Marino    logical-AND-expression:
5556*e4b17023SJohn Marino      inclusive-OR-expression
5557*e4b17023SJohn Marino      logical-AND-expression && inclusive-OR-expression
5558*e4b17023SJohn Marino 
5559*e4b17023SJohn Marino    logical-OR-expression:
5560*e4b17023SJohn Marino      logical-AND-expression
5561*e4b17023SJohn Marino      logical-OR-expression || logical-AND-expression
5562*e4b17023SJohn Marino */
5563*e4b17023SJohn Marino 
5564*e4b17023SJohn Marino static struct c_expr
c_parser_binary_expression(c_parser * parser,struct c_expr * after,enum c_parser_prec prec)5565*e4b17023SJohn Marino c_parser_binary_expression (c_parser *parser, struct c_expr *after,
5566*e4b17023SJohn Marino 			    enum c_parser_prec prec)
5567*e4b17023SJohn Marino {
5568*e4b17023SJohn Marino   /* A binary expression is parsed using operator-precedence parsing,
5569*e4b17023SJohn Marino      with the operands being cast expressions.  All the binary
5570*e4b17023SJohn Marino      operators are left-associative.  Thus a binary expression is of
5571*e4b17023SJohn Marino      form:
5572*e4b17023SJohn Marino 
5573*e4b17023SJohn Marino      E0 op1 E1 op2 E2 ...
5574*e4b17023SJohn Marino 
5575*e4b17023SJohn Marino      which we represent on a stack.  On the stack, the precedence
5576*e4b17023SJohn Marino      levels are strictly increasing.  When a new operator is
5577*e4b17023SJohn Marino      encountered of higher precedence than that at the top of the
5578*e4b17023SJohn Marino      stack, it is pushed; its LHS is the top expression, and its RHS
5579*e4b17023SJohn Marino      is everything parsed until it is popped.  When a new operator is
5580*e4b17023SJohn Marino      encountered with precedence less than or equal to that at the top
5581*e4b17023SJohn Marino      of the stack, triples E[i-1] op[i] E[i] are popped and replaced
5582*e4b17023SJohn Marino      by the result of the operation until the operator at the top of
5583*e4b17023SJohn Marino      the stack has lower precedence than the new operator or there is
5584*e4b17023SJohn Marino      only one element on the stack; then the top expression is the LHS
5585*e4b17023SJohn Marino      of the new operator.  In the case of logical AND and OR
5586*e4b17023SJohn Marino      expressions, we also need to adjust c_inhibit_evaluation_warnings
5587*e4b17023SJohn Marino      as appropriate when the operators are pushed and popped.  */
5588*e4b17023SJohn Marino 
5589*e4b17023SJohn Marino   struct {
5590*e4b17023SJohn Marino     /* The expression at this stack level.  */
5591*e4b17023SJohn Marino     struct c_expr expr;
5592*e4b17023SJohn Marino     /* The precedence of the operator on its left, PREC_NONE at the
5593*e4b17023SJohn Marino        bottom of the stack.  */
5594*e4b17023SJohn Marino     enum c_parser_prec prec;
5595*e4b17023SJohn Marino     /* The operation on its left.  */
5596*e4b17023SJohn Marino     enum tree_code op;
5597*e4b17023SJohn Marino     /* The source location of this operation.  */
5598*e4b17023SJohn Marino     location_t loc;
5599*e4b17023SJohn Marino   } stack[NUM_PRECS];
5600*e4b17023SJohn Marino   int sp;
5601*e4b17023SJohn Marino   /* Location of the binary operator.  */
5602*e4b17023SJohn Marino   location_t binary_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
5603*e4b17023SJohn Marino #define POP								      \
5604*e4b17023SJohn Marino   do {									      \
5605*e4b17023SJohn Marino     switch (stack[sp].op)						      \
5606*e4b17023SJohn Marino       {									      \
5607*e4b17023SJohn Marino       case TRUTH_ANDIF_EXPR:						      \
5608*e4b17023SJohn Marino 	c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value	      \
5609*e4b17023SJohn Marino 					  == truthvalue_false_node);	      \
5610*e4b17023SJohn Marino 	break;								      \
5611*e4b17023SJohn Marino       case TRUTH_ORIF_EXPR:						      \
5612*e4b17023SJohn Marino 	c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value	      \
5613*e4b17023SJohn Marino 					  == truthvalue_true_node);	      \
5614*e4b17023SJohn Marino 	break;								      \
5615*e4b17023SJohn Marino       default:								      \
5616*e4b17023SJohn Marino 	break;								      \
5617*e4b17023SJohn Marino       }									      \
5618*e4b17023SJohn Marino     stack[sp - 1].expr							      \
5619*e4b17023SJohn Marino       = default_function_array_read_conversion (stack[sp - 1].loc,	      \
5620*e4b17023SJohn Marino 						stack[sp - 1].expr);	      \
5621*e4b17023SJohn Marino     stack[sp].expr							      \
5622*e4b17023SJohn Marino       = default_function_array_read_conversion (stack[sp].loc,		      \
5623*e4b17023SJohn Marino 						stack[sp].expr);	      \
5624*e4b17023SJohn Marino     stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc,		      \
5625*e4b17023SJohn Marino 						 stack[sp].op,		      \
5626*e4b17023SJohn Marino 						 stack[sp - 1].expr,	      \
5627*e4b17023SJohn Marino 						 stack[sp].expr);	      \
5628*e4b17023SJohn Marino     sp--;								      \
5629*e4b17023SJohn Marino   } while (0)
5630*e4b17023SJohn Marino   gcc_assert (!after || c_dialect_objc ());
5631*e4b17023SJohn Marino   stack[0].loc = c_parser_peek_token (parser)->location;
5632*e4b17023SJohn Marino   stack[0].expr = c_parser_cast_expression (parser, after);
5633*e4b17023SJohn Marino   stack[0].prec = prec;
5634*e4b17023SJohn Marino   sp = 0;
5635*e4b17023SJohn Marino   while (true)
5636*e4b17023SJohn Marino     {
5637*e4b17023SJohn Marino       enum c_parser_prec oprec;
5638*e4b17023SJohn Marino       enum tree_code ocode;
5639*e4b17023SJohn Marino       if (parser->error)
5640*e4b17023SJohn Marino 	goto out;
5641*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->type)
5642*e4b17023SJohn Marino 	{
5643*e4b17023SJohn Marino 	case CPP_MULT:
5644*e4b17023SJohn Marino 	  oprec = PREC_MULT;
5645*e4b17023SJohn Marino 	  ocode = MULT_EXPR;
5646*e4b17023SJohn Marino 	  break;
5647*e4b17023SJohn Marino 	case CPP_DIV:
5648*e4b17023SJohn Marino 	  oprec = PREC_MULT;
5649*e4b17023SJohn Marino 	  ocode = TRUNC_DIV_EXPR;
5650*e4b17023SJohn Marino 	  break;
5651*e4b17023SJohn Marino 	case CPP_MOD:
5652*e4b17023SJohn Marino 	  oprec = PREC_MULT;
5653*e4b17023SJohn Marino 	  ocode = TRUNC_MOD_EXPR;
5654*e4b17023SJohn Marino 	  break;
5655*e4b17023SJohn Marino 	case CPP_PLUS:
5656*e4b17023SJohn Marino 	  oprec = PREC_ADD;
5657*e4b17023SJohn Marino 	  ocode = PLUS_EXPR;
5658*e4b17023SJohn Marino 	  break;
5659*e4b17023SJohn Marino 	case CPP_MINUS:
5660*e4b17023SJohn Marino 	  oprec = PREC_ADD;
5661*e4b17023SJohn Marino 	  ocode = MINUS_EXPR;
5662*e4b17023SJohn Marino 	  break;
5663*e4b17023SJohn Marino 	case CPP_LSHIFT:
5664*e4b17023SJohn Marino 	  oprec = PREC_SHIFT;
5665*e4b17023SJohn Marino 	  ocode = LSHIFT_EXPR;
5666*e4b17023SJohn Marino 	  break;
5667*e4b17023SJohn Marino 	case CPP_RSHIFT:
5668*e4b17023SJohn Marino 	  oprec = PREC_SHIFT;
5669*e4b17023SJohn Marino 	  ocode = RSHIFT_EXPR;
5670*e4b17023SJohn Marino 	  break;
5671*e4b17023SJohn Marino 	case CPP_LESS:
5672*e4b17023SJohn Marino 	  oprec = PREC_REL;
5673*e4b17023SJohn Marino 	  ocode = LT_EXPR;
5674*e4b17023SJohn Marino 	  break;
5675*e4b17023SJohn Marino 	case CPP_GREATER:
5676*e4b17023SJohn Marino 	  oprec = PREC_REL;
5677*e4b17023SJohn Marino 	  ocode = GT_EXPR;
5678*e4b17023SJohn Marino 	  break;
5679*e4b17023SJohn Marino 	case CPP_LESS_EQ:
5680*e4b17023SJohn Marino 	  oprec = PREC_REL;
5681*e4b17023SJohn Marino 	  ocode = LE_EXPR;
5682*e4b17023SJohn Marino 	  break;
5683*e4b17023SJohn Marino 	case CPP_GREATER_EQ:
5684*e4b17023SJohn Marino 	  oprec = PREC_REL;
5685*e4b17023SJohn Marino 	  ocode = GE_EXPR;
5686*e4b17023SJohn Marino 	  break;
5687*e4b17023SJohn Marino 	case CPP_EQ_EQ:
5688*e4b17023SJohn Marino 	  oprec = PREC_EQ;
5689*e4b17023SJohn Marino 	  ocode = EQ_EXPR;
5690*e4b17023SJohn Marino 	  break;
5691*e4b17023SJohn Marino 	case CPP_NOT_EQ:
5692*e4b17023SJohn Marino 	  oprec = PREC_EQ;
5693*e4b17023SJohn Marino 	  ocode = NE_EXPR;
5694*e4b17023SJohn Marino 	  break;
5695*e4b17023SJohn Marino 	case CPP_AND:
5696*e4b17023SJohn Marino 	  oprec = PREC_BITAND;
5697*e4b17023SJohn Marino 	  ocode = BIT_AND_EXPR;
5698*e4b17023SJohn Marino 	  break;
5699*e4b17023SJohn Marino 	case CPP_XOR:
5700*e4b17023SJohn Marino 	  oprec = PREC_BITXOR;
5701*e4b17023SJohn Marino 	  ocode = BIT_XOR_EXPR;
5702*e4b17023SJohn Marino 	  break;
5703*e4b17023SJohn Marino 	case CPP_OR:
5704*e4b17023SJohn Marino 	  oprec = PREC_BITOR;
5705*e4b17023SJohn Marino 	  ocode = BIT_IOR_EXPR;
5706*e4b17023SJohn Marino 	  break;
5707*e4b17023SJohn Marino 	case CPP_AND_AND:
5708*e4b17023SJohn Marino 	  oprec = PREC_LOGAND;
5709*e4b17023SJohn Marino 	  ocode = TRUTH_ANDIF_EXPR;
5710*e4b17023SJohn Marino 	  break;
5711*e4b17023SJohn Marino 	case CPP_OR_OR:
5712*e4b17023SJohn Marino 	  oprec = PREC_LOGOR;
5713*e4b17023SJohn Marino 	  ocode = TRUTH_ORIF_EXPR;
5714*e4b17023SJohn Marino 	  break;
5715*e4b17023SJohn Marino 	default:
5716*e4b17023SJohn Marino 	  /* Not a binary operator, so end of the binary
5717*e4b17023SJohn Marino 	     expression.  */
5718*e4b17023SJohn Marino 	  goto out;
5719*e4b17023SJohn Marino 	}
5720*e4b17023SJohn Marino       binary_loc = c_parser_peek_token (parser)->location;
5721*e4b17023SJohn Marino       while (oprec <= stack[sp].prec)
5722*e4b17023SJohn Marino 	{
5723*e4b17023SJohn Marino 	  if (sp == 0)
5724*e4b17023SJohn Marino 	    goto out;
5725*e4b17023SJohn Marino 	  POP;
5726*e4b17023SJohn Marino 	}
5727*e4b17023SJohn Marino       c_parser_consume_token (parser);
5728*e4b17023SJohn Marino       switch (ocode)
5729*e4b17023SJohn Marino 	{
5730*e4b17023SJohn Marino 	case TRUTH_ANDIF_EXPR:
5731*e4b17023SJohn Marino 	  stack[sp].expr
5732*e4b17023SJohn Marino 	    = default_function_array_read_conversion (stack[sp].loc,
5733*e4b17023SJohn Marino 						      stack[sp].expr);
5734*e4b17023SJohn Marino 	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
5735*e4b17023SJohn Marino 	    (stack[sp].loc, default_conversion (stack[sp].expr.value));
5736*e4b17023SJohn Marino 	  c_inhibit_evaluation_warnings += (stack[sp].expr.value
5737*e4b17023SJohn Marino 					    == truthvalue_false_node);
5738*e4b17023SJohn Marino 	  break;
5739*e4b17023SJohn Marino 	case TRUTH_ORIF_EXPR:
5740*e4b17023SJohn Marino 	  stack[sp].expr
5741*e4b17023SJohn Marino 	    = default_function_array_read_conversion (stack[sp].loc,
5742*e4b17023SJohn Marino 						      stack[sp].expr);
5743*e4b17023SJohn Marino 	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
5744*e4b17023SJohn Marino 	    (stack[sp].loc, default_conversion (stack[sp].expr.value));
5745*e4b17023SJohn Marino 	  c_inhibit_evaluation_warnings += (stack[sp].expr.value
5746*e4b17023SJohn Marino 					    == truthvalue_true_node);
5747*e4b17023SJohn Marino 	  break;
5748*e4b17023SJohn Marino 	default:
5749*e4b17023SJohn Marino 	  break;
5750*e4b17023SJohn Marino 	}
5751*e4b17023SJohn Marino       sp++;
5752*e4b17023SJohn Marino       stack[sp].loc = binary_loc;
5753*e4b17023SJohn Marino       stack[sp].expr = c_parser_cast_expression (parser, NULL);
5754*e4b17023SJohn Marino       stack[sp].prec = oprec;
5755*e4b17023SJohn Marino       stack[sp].op = ocode;
5756*e4b17023SJohn Marino       stack[sp].loc = binary_loc;
5757*e4b17023SJohn Marino     }
5758*e4b17023SJohn Marino  out:
5759*e4b17023SJohn Marino   while (sp > 0)
5760*e4b17023SJohn Marino     POP;
5761*e4b17023SJohn Marino   return stack[0].expr;
5762*e4b17023SJohn Marino #undef POP
5763*e4b17023SJohn Marino }
5764*e4b17023SJohn Marino 
5765*e4b17023SJohn Marino /* Parse a cast expression (C90 6.3.4, C99 6.5.4).  If AFTER is not
5766*e4b17023SJohn Marino    NULL then it is an Objective-C message expression which is the
5767*e4b17023SJohn Marino    primary-expression starting the expression as an initializer.
5768*e4b17023SJohn Marino 
5769*e4b17023SJohn Marino    cast-expression:
5770*e4b17023SJohn Marino      unary-expression
5771*e4b17023SJohn Marino      ( type-name ) unary-expression
5772*e4b17023SJohn Marino */
5773*e4b17023SJohn Marino 
5774*e4b17023SJohn Marino static struct c_expr
c_parser_cast_expression(c_parser * parser,struct c_expr * after)5775*e4b17023SJohn Marino c_parser_cast_expression (c_parser *parser, struct c_expr *after)
5776*e4b17023SJohn Marino {
5777*e4b17023SJohn Marino   location_t cast_loc = c_parser_peek_token (parser)->location;
5778*e4b17023SJohn Marino   gcc_assert (!after || c_dialect_objc ());
5779*e4b17023SJohn Marino   if (after)
5780*e4b17023SJohn Marino     return c_parser_postfix_expression_after_primary (parser,
5781*e4b17023SJohn Marino 						      cast_loc, *after);
5782*e4b17023SJohn Marino   /* If the expression begins with a parenthesized type name, it may
5783*e4b17023SJohn Marino      be either a cast or a compound literal; we need to see whether
5784*e4b17023SJohn Marino      the next character is '{' to tell the difference.  If not, it is
5785*e4b17023SJohn Marino      an unary expression.  Full detection of unknown typenames here
5786*e4b17023SJohn Marino      would require a 3-token lookahead.  */
5787*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
5788*e4b17023SJohn Marino       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
5789*e4b17023SJohn Marino     {
5790*e4b17023SJohn Marino       struct c_type_name *type_name;
5791*e4b17023SJohn Marino       struct c_expr ret;
5792*e4b17023SJohn Marino       struct c_expr expr;
5793*e4b17023SJohn Marino       c_parser_consume_token (parser);
5794*e4b17023SJohn Marino       type_name = c_parser_type_name (parser);
5795*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
5796*e4b17023SJohn Marino       if (type_name == NULL)
5797*e4b17023SJohn Marino 	{
5798*e4b17023SJohn Marino 	  ret.value = error_mark_node;
5799*e4b17023SJohn Marino 	  ret.original_code = ERROR_MARK;
5800*e4b17023SJohn Marino 	  ret.original_type = NULL;
5801*e4b17023SJohn Marino 	  return ret;
5802*e4b17023SJohn Marino 	}
5803*e4b17023SJohn Marino 
5804*e4b17023SJohn Marino       /* Save casted types in the function's used types hash table.  */
5805*e4b17023SJohn Marino       used_types_insert (type_name->specs->type);
5806*e4b17023SJohn Marino 
5807*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5808*e4b17023SJohn Marino 	return c_parser_postfix_expression_after_paren_type (parser, type_name,
5809*e4b17023SJohn Marino 							     cast_loc);
5810*e4b17023SJohn Marino       {
5811*e4b17023SJohn Marino 	location_t expr_loc = c_parser_peek_token (parser)->location;
5812*e4b17023SJohn Marino 	expr = c_parser_cast_expression (parser, NULL);
5813*e4b17023SJohn Marino 	expr = default_function_array_read_conversion (expr_loc, expr);
5814*e4b17023SJohn Marino       }
5815*e4b17023SJohn Marino       ret.value = c_cast_expr (cast_loc, type_name, expr.value);
5816*e4b17023SJohn Marino       ret.original_code = ERROR_MARK;
5817*e4b17023SJohn Marino       ret.original_type = NULL;
5818*e4b17023SJohn Marino       return ret;
5819*e4b17023SJohn Marino     }
5820*e4b17023SJohn Marino   else
5821*e4b17023SJohn Marino     return c_parser_unary_expression (parser);
5822*e4b17023SJohn Marino }
5823*e4b17023SJohn Marino 
5824*e4b17023SJohn Marino /* Parse an unary expression (C90 6.3.3, C99 6.5.3).
5825*e4b17023SJohn Marino 
5826*e4b17023SJohn Marino    unary-expression:
5827*e4b17023SJohn Marino      postfix-expression
5828*e4b17023SJohn Marino      ++ unary-expression
5829*e4b17023SJohn Marino      -- unary-expression
5830*e4b17023SJohn Marino      unary-operator cast-expression
5831*e4b17023SJohn Marino      sizeof unary-expression
5832*e4b17023SJohn Marino      sizeof ( type-name )
5833*e4b17023SJohn Marino 
5834*e4b17023SJohn Marino    unary-operator: one of
5835*e4b17023SJohn Marino      & * + - ~ !
5836*e4b17023SJohn Marino 
5837*e4b17023SJohn Marino    GNU extensions:
5838*e4b17023SJohn Marino 
5839*e4b17023SJohn Marino    unary-expression:
5840*e4b17023SJohn Marino      __alignof__ unary-expression
5841*e4b17023SJohn Marino      __alignof__ ( type-name )
5842*e4b17023SJohn Marino      && identifier
5843*e4b17023SJohn Marino 
5844*e4b17023SJohn Marino    (C11 permits _Alignof with type names only.)
5845*e4b17023SJohn Marino 
5846*e4b17023SJohn Marino    unary-operator: one of
5847*e4b17023SJohn Marino      __extension__ __real__ __imag__
5848*e4b17023SJohn Marino 
5849*e4b17023SJohn Marino    Transactional Memory:
5850*e4b17023SJohn Marino 
5851*e4b17023SJohn Marino    unary-expression:
5852*e4b17023SJohn Marino      transaction-expression
5853*e4b17023SJohn Marino 
5854*e4b17023SJohn Marino    In addition, the GNU syntax treats ++ and -- as unary operators, so
5855*e4b17023SJohn Marino    they may be applied to cast expressions with errors for non-lvalues
5856*e4b17023SJohn Marino    given later.  */
5857*e4b17023SJohn Marino 
5858*e4b17023SJohn Marino static struct c_expr
c_parser_unary_expression(c_parser * parser)5859*e4b17023SJohn Marino c_parser_unary_expression (c_parser *parser)
5860*e4b17023SJohn Marino {
5861*e4b17023SJohn Marino   int ext;
5862*e4b17023SJohn Marino   struct c_expr ret, op;
5863*e4b17023SJohn Marino   location_t op_loc = c_parser_peek_token (parser)->location;
5864*e4b17023SJohn Marino   location_t exp_loc;
5865*e4b17023SJohn Marino   ret.original_code = ERROR_MARK;
5866*e4b17023SJohn Marino   ret.original_type = NULL;
5867*e4b17023SJohn Marino   switch (c_parser_peek_token (parser)->type)
5868*e4b17023SJohn Marino     {
5869*e4b17023SJohn Marino     case CPP_PLUS_PLUS:
5870*e4b17023SJohn Marino       c_parser_consume_token (parser);
5871*e4b17023SJohn Marino       exp_loc = c_parser_peek_token (parser)->location;
5872*e4b17023SJohn Marino       op = c_parser_cast_expression (parser, NULL);
5873*e4b17023SJohn Marino       op = default_function_array_read_conversion (exp_loc, op);
5874*e4b17023SJohn Marino       return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
5875*e4b17023SJohn Marino     case CPP_MINUS_MINUS:
5876*e4b17023SJohn Marino       c_parser_consume_token (parser);
5877*e4b17023SJohn Marino       exp_loc = c_parser_peek_token (parser)->location;
5878*e4b17023SJohn Marino       op = c_parser_cast_expression (parser, NULL);
5879*e4b17023SJohn Marino       op = default_function_array_read_conversion (exp_loc, op);
5880*e4b17023SJohn Marino       return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
5881*e4b17023SJohn Marino     case CPP_AND:
5882*e4b17023SJohn Marino       c_parser_consume_token (parser);
5883*e4b17023SJohn Marino       op = c_parser_cast_expression (parser, NULL);
5884*e4b17023SJohn Marino       mark_exp_read (op.value);
5885*e4b17023SJohn Marino       return parser_build_unary_op (op_loc, ADDR_EXPR, op);
5886*e4b17023SJohn Marino     case CPP_MULT:
5887*e4b17023SJohn Marino       c_parser_consume_token (parser);
5888*e4b17023SJohn Marino       exp_loc = c_parser_peek_token (parser)->location;
5889*e4b17023SJohn Marino       op = c_parser_cast_expression (parser, NULL);
5890*e4b17023SJohn Marino       op = default_function_array_read_conversion (exp_loc, op);
5891*e4b17023SJohn Marino       ret.value = build_indirect_ref (op_loc, op.value, RO_UNARY_STAR);
5892*e4b17023SJohn Marino       return ret;
5893*e4b17023SJohn Marino     case CPP_PLUS:
5894*e4b17023SJohn Marino       if (!c_dialect_objc () && !in_system_header)
5895*e4b17023SJohn Marino 	warning_at (op_loc,
5896*e4b17023SJohn Marino 		    OPT_Wtraditional,
5897*e4b17023SJohn Marino 		    "traditional C rejects the unary plus operator");
5898*e4b17023SJohn Marino       c_parser_consume_token (parser);
5899*e4b17023SJohn Marino       exp_loc = c_parser_peek_token (parser)->location;
5900*e4b17023SJohn Marino       op = c_parser_cast_expression (parser, NULL);
5901*e4b17023SJohn Marino       op = default_function_array_read_conversion (exp_loc, op);
5902*e4b17023SJohn Marino       return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
5903*e4b17023SJohn Marino     case CPP_MINUS:
5904*e4b17023SJohn Marino       c_parser_consume_token (parser);
5905*e4b17023SJohn Marino       exp_loc = c_parser_peek_token (parser)->location;
5906*e4b17023SJohn Marino       op = c_parser_cast_expression (parser, NULL);
5907*e4b17023SJohn Marino       op = default_function_array_read_conversion (exp_loc, op);
5908*e4b17023SJohn Marino       return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
5909*e4b17023SJohn Marino     case CPP_COMPL:
5910*e4b17023SJohn Marino       c_parser_consume_token (parser);
5911*e4b17023SJohn Marino       exp_loc = c_parser_peek_token (parser)->location;
5912*e4b17023SJohn Marino       op = c_parser_cast_expression (parser, NULL);
5913*e4b17023SJohn Marino       op = default_function_array_read_conversion (exp_loc, op);
5914*e4b17023SJohn Marino       return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
5915*e4b17023SJohn Marino     case CPP_NOT:
5916*e4b17023SJohn Marino       c_parser_consume_token (parser);
5917*e4b17023SJohn Marino       exp_loc = c_parser_peek_token (parser)->location;
5918*e4b17023SJohn Marino       op = c_parser_cast_expression (parser, NULL);
5919*e4b17023SJohn Marino       op = default_function_array_read_conversion (exp_loc, op);
5920*e4b17023SJohn Marino       return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
5921*e4b17023SJohn Marino     case CPP_AND_AND:
5922*e4b17023SJohn Marino       /* Refer to the address of a label as a pointer.  */
5923*e4b17023SJohn Marino       c_parser_consume_token (parser);
5924*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_NAME))
5925*e4b17023SJohn Marino 	{
5926*e4b17023SJohn Marino 	  ret.value = finish_label_address_expr
5927*e4b17023SJohn Marino 	    (c_parser_peek_token (parser)->value, op_loc);
5928*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
5929*e4b17023SJohn Marino 	}
5930*e4b17023SJohn Marino       else
5931*e4b17023SJohn Marino 	{
5932*e4b17023SJohn Marino 	  c_parser_error (parser, "expected identifier");
5933*e4b17023SJohn Marino 	  ret.value = error_mark_node;
5934*e4b17023SJohn Marino 	}
5935*e4b17023SJohn Marino 	return ret;
5936*e4b17023SJohn Marino     case CPP_KEYWORD:
5937*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->keyword)
5938*e4b17023SJohn Marino 	{
5939*e4b17023SJohn Marino 	case RID_SIZEOF:
5940*e4b17023SJohn Marino 	  return c_parser_sizeof_expression (parser);
5941*e4b17023SJohn Marino 	case RID_ALIGNOF:
5942*e4b17023SJohn Marino 	  return c_parser_alignof_expression (parser);
5943*e4b17023SJohn Marino 	case RID_EXTENSION:
5944*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
5945*e4b17023SJohn Marino 	  ext = disable_extension_diagnostics ();
5946*e4b17023SJohn Marino 	  ret = c_parser_cast_expression (parser, NULL);
5947*e4b17023SJohn Marino 	  restore_extension_diagnostics (ext);
5948*e4b17023SJohn Marino 	  return ret;
5949*e4b17023SJohn Marino 	case RID_REALPART:
5950*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
5951*e4b17023SJohn Marino 	  exp_loc = c_parser_peek_token (parser)->location;
5952*e4b17023SJohn Marino 	  op = c_parser_cast_expression (parser, NULL);
5953*e4b17023SJohn Marino 	  op = default_function_array_conversion (exp_loc, op);
5954*e4b17023SJohn Marino 	  return parser_build_unary_op (op_loc, REALPART_EXPR, op);
5955*e4b17023SJohn Marino 	case RID_IMAGPART:
5956*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
5957*e4b17023SJohn Marino 	  exp_loc = c_parser_peek_token (parser)->location;
5958*e4b17023SJohn Marino 	  op = c_parser_cast_expression (parser, NULL);
5959*e4b17023SJohn Marino 	  op = default_function_array_conversion (exp_loc, op);
5960*e4b17023SJohn Marino 	  return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
5961*e4b17023SJohn Marino 	case RID_TRANSACTION_ATOMIC:
5962*e4b17023SJohn Marino 	case RID_TRANSACTION_RELAXED:
5963*e4b17023SJohn Marino 	  return c_parser_transaction_expression (parser,
5964*e4b17023SJohn Marino 	      c_parser_peek_token (parser)->keyword);
5965*e4b17023SJohn Marino 	default:
5966*e4b17023SJohn Marino 	  return c_parser_postfix_expression (parser);
5967*e4b17023SJohn Marino 	}
5968*e4b17023SJohn Marino     default:
5969*e4b17023SJohn Marino       return c_parser_postfix_expression (parser);
5970*e4b17023SJohn Marino     }
5971*e4b17023SJohn Marino }
5972*e4b17023SJohn Marino 
5973*e4b17023SJohn Marino /* Parse a sizeof expression.  */
5974*e4b17023SJohn Marino 
5975*e4b17023SJohn Marino static struct c_expr
c_parser_sizeof_expression(c_parser * parser)5976*e4b17023SJohn Marino c_parser_sizeof_expression (c_parser *parser)
5977*e4b17023SJohn Marino {
5978*e4b17023SJohn Marino   struct c_expr expr;
5979*e4b17023SJohn Marino   location_t expr_loc;
5980*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
5981*e4b17023SJohn Marino   c_parser_consume_token (parser);
5982*e4b17023SJohn Marino   c_inhibit_evaluation_warnings++;
5983*e4b17023SJohn Marino   in_sizeof++;
5984*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
5985*e4b17023SJohn Marino       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
5986*e4b17023SJohn Marino     {
5987*e4b17023SJohn Marino       /* Either sizeof ( type-name ) or sizeof unary-expression
5988*e4b17023SJohn Marino 	 starting with a compound literal.  */
5989*e4b17023SJohn Marino       struct c_type_name *type_name;
5990*e4b17023SJohn Marino       c_parser_consume_token (parser);
5991*e4b17023SJohn Marino       expr_loc = c_parser_peek_token (parser)->location;
5992*e4b17023SJohn Marino       type_name = c_parser_type_name (parser);
5993*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
5994*e4b17023SJohn Marino       if (type_name == NULL)
5995*e4b17023SJohn Marino 	{
5996*e4b17023SJohn Marino 	  struct c_expr ret;
5997*e4b17023SJohn Marino 	  c_inhibit_evaluation_warnings--;
5998*e4b17023SJohn Marino 	  in_sizeof--;
5999*e4b17023SJohn Marino 	  ret.value = error_mark_node;
6000*e4b17023SJohn Marino 	  ret.original_code = ERROR_MARK;
6001*e4b17023SJohn Marino 	  ret.original_type = NULL;
6002*e4b17023SJohn Marino 	  return ret;
6003*e4b17023SJohn Marino 	}
6004*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6005*e4b17023SJohn Marino 	{
6006*e4b17023SJohn Marino 	  expr = c_parser_postfix_expression_after_paren_type (parser,
6007*e4b17023SJohn Marino 							       type_name,
6008*e4b17023SJohn Marino 							       expr_loc);
6009*e4b17023SJohn Marino 	  goto sizeof_expr;
6010*e4b17023SJohn Marino 	}
6011*e4b17023SJohn Marino       /* sizeof ( type-name ).  */
6012*e4b17023SJohn Marino       c_inhibit_evaluation_warnings--;
6013*e4b17023SJohn Marino       in_sizeof--;
6014*e4b17023SJohn Marino       return c_expr_sizeof_type (expr_loc, type_name);
6015*e4b17023SJohn Marino     }
6016*e4b17023SJohn Marino   else
6017*e4b17023SJohn Marino     {
6018*e4b17023SJohn Marino       expr_loc = c_parser_peek_token (parser)->location;
6019*e4b17023SJohn Marino       expr = c_parser_unary_expression (parser);
6020*e4b17023SJohn Marino     sizeof_expr:
6021*e4b17023SJohn Marino       c_inhibit_evaluation_warnings--;
6022*e4b17023SJohn Marino       in_sizeof--;
6023*e4b17023SJohn Marino       mark_exp_read (expr.value);
6024*e4b17023SJohn Marino       if (TREE_CODE (expr.value) == COMPONENT_REF
6025*e4b17023SJohn Marino 	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
6026*e4b17023SJohn Marino 	error_at (expr_loc, "%<sizeof%> applied to a bit-field");
6027*e4b17023SJohn Marino       return c_expr_sizeof_expr (expr_loc, expr);
6028*e4b17023SJohn Marino     }
6029*e4b17023SJohn Marino }
6030*e4b17023SJohn Marino 
6031*e4b17023SJohn Marino /* Parse an alignof expression.  */
6032*e4b17023SJohn Marino 
6033*e4b17023SJohn Marino static struct c_expr
c_parser_alignof_expression(c_parser * parser)6034*e4b17023SJohn Marino c_parser_alignof_expression (c_parser *parser)
6035*e4b17023SJohn Marino {
6036*e4b17023SJohn Marino   struct c_expr expr;
6037*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
6038*e4b17023SJohn Marino   tree alignof_spelling = c_parser_peek_token (parser)->value;
6039*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
6040*e4b17023SJohn Marino   /* A diagnostic is not required for the use of this identifier in
6041*e4b17023SJohn Marino      the implementation namespace; only diagnose it for the C11
6042*e4b17023SJohn Marino      spelling because of existing code using the other spellings.  */
6043*e4b17023SJohn Marino   if (!flag_isoc11
6044*e4b17023SJohn Marino       && strcmp (IDENTIFIER_POINTER (alignof_spelling), "_Alignof") == 0)
6045*e4b17023SJohn Marino     {
6046*e4b17023SJohn Marino       if (flag_isoc99)
6047*e4b17023SJohn Marino 	pedwarn (loc, OPT_pedantic, "ISO C99 does not support %qE",
6048*e4b17023SJohn Marino 		 alignof_spelling);
6049*e4b17023SJohn Marino       else
6050*e4b17023SJohn Marino 	pedwarn (loc, OPT_pedantic, "ISO C90 does not support %qE",
6051*e4b17023SJohn Marino 		 alignof_spelling);
6052*e4b17023SJohn Marino     }
6053*e4b17023SJohn Marino   c_parser_consume_token (parser);
6054*e4b17023SJohn Marino   c_inhibit_evaluation_warnings++;
6055*e4b17023SJohn Marino   in_alignof++;
6056*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6057*e4b17023SJohn Marino       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6058*e4b17023SJohn Marino     {
6059*e4b17023SJohn Marino       /* Either __alignof__ ( type-name ) or __alignof__
6060*e4b17023SJohn Marino 	 unary-expression starting with a compound literal.  */
6061*e4b17023SJohn Marino       location_t loc;
6062*e4b17023SJohn Marino       struct c_type_name *type_name;
6063*e4b17023SJohn Marino       struct c_expr ret;
6064*e4b17023SJohn Marino       c_parser_consume_token (parser);
6065*e4b17023SJohn Marino       loc = c_parser_peek_token (parser)->location;
6066*e4b17023SJohn Marino       type_name = c_parser_type_name (parser);
6067*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
6068*e4b17023SJohn Marino       if (type_name == NULL)
6069*e4b17023SJohn Marino 	{
6070*e4b17023SJohn Marino 	  struct c_expr ret;
6071*e4b17023SJohn Marino 	  c_inhibit_evaluation_warnings--;
6072*e4b17023SJohn Marino 	  in_alignof--;
6073*e4b17023SJohn Marino 	  ret.value = error_mark_node;
6074*e4b17023SJohn Marino 	  ret.original_code = ERROR_MARK;
6075*e4b17023SJohn Marino 	  ret.original_type = NULL;
6076*e4b17023SJohn Marino 	  return ret;
6077*e4b17023SJohn Marino 	}
6078*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6079*e4b17023SJohn Marino 	{
6080*e4b17023SJohn Marino 	  expr = c_parser_postfix_expression_after_paren_type (parser,
6081*e4b17023SJohn Marino 							       type_name,
6082*e4b17023SJohn Marino 							       loc);
6083*e4b17023SJohn Marino 	  goto alignof_expr;
6084*e4b17023SJohn Marino 	}
6085*e4b17023SJohn Marino       /* alignof ( type-name ).  */
6086*e4b17023SJohn Marino       c_inhibit_evaluation_warnings--;
6087*e4b17023SJohn Marino       in_alignof--;
6088*e4b17023SJohn Marino       ret.value = c_alignof (loc, groktypename (type_name, NULL, NULL));
6089*e4b17023SJohn Marino       ret.original_code = ERROR_MARK;
6090*e4b17023SJohn Marino       ret.original_type = NULL;
6091*e4b17023SJohn Marino       return ret;
6092*e4b17023SJohn Marino     }
6093*e4b17023SJohn Marino   else
6094*e4b17023SJohn Marino     {
6095*e4b17023SJohn Marino       struct c_expr ret;
6096*e4b17023SJohn Marino       expr = c_parser_unary_expression (parser);
6097*e4b17023SJohn Marino     alignof_expr:
6098*e4b17023SJohn Marino       mark_exp_read (expr.value);
6099*e4b17023SJohn Marino       c_inhibit_evaluation_warnings--;
6100*e4b17023SJohn Marino       in_alignof--;
6101*e4b17023SJohn Marino       pedwarn (loc, OPT_pedantic, "ISO C does not allow %<%E (expression)%>",
6102*e4b17023SJohn Marino 	       alignof_spelling);
6103*e4b17023SJohn Marino       ret.value = c_alignof_expr (loc, expr.value);
6104*e4b17023SJohn Marino       ret.original_code = ERROR_MARK;
6105*e4b17023SJohn Marino       ret.original_type = NULL;
6106*e4b17023SJohn Marino       return ret;
6107*e4b17023SJohn Marino     }
6108*e4b17023SJohn Marino }
6109*e4b17023SJohn Marino 
6110*e4b17023SJohn Marino /* Helper function to read arguments of builtins which are interfaces
6111*e4b17023SJohn Marino    for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
6112*e4b17023SJohn Marino    others.  The name of the builtin is passed using BNAME parameter.
6113*e4b17023SJohn Marino    Function returns true if there were no errors while parsing and
6114*e4b17023SJohn Marino    stores the arguments in CEXPR_LIST.  */
6115*e4b17023SJohn Marino static bool
c_parser_get_builtin_args(c_parser * parser,const char * bname,VEC (c_expr_t,gc)** ret_cexpr_list)6116*e4b17023SJohn Marino c_parser_get_builtin_args (c_parser *parser, const char *bname,
6117*e4b17023SJohn Marino 			   VEC(c_expr_t,gc) **ret_cexpr_list)
6118*e4b17023SJohn Marino {
6119*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
6120*e4b17023SJohn Marino   VEC (c_expr_t,gc) *cexpr_list;
6121*e4b17023SJohn Marino   c_expr_t expr;
6122*e4b17023SJohn Marino 
6123*e4b17023SJohn Marino   *ret_cexpr_list = NULL;
6124*e4b17023SJohn Marino   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
6125*e4b17023SJohn Marino     {
6126*e4b17023SJohn Marino       error_at (loc, "cannot take address of %qs", bname);
6127*e4b17023SJohn Marino       return false;
6128*e4b17023SJohn Marino     }
6129*e4b17023SJohn Marino 
6130*e4b17023SJohn Marino   c_parser_consume_token (parser);
6131*e4b17023SJohn Marino 
6132*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6133*e4b17023SJohn Marino     {
6134*e4b17023SJohn Marino       c_parser_consume_token (parser);
6135*e4b17023SJohn Marino       return true;
6136*e4b17023SJohn Marino     }
6137*e4b17023SJohn Marino 
6138*e4b17023SJohn Marino   expr = c_parser_expr_no_commas (parser, NULL);
6139*e4b17023SJohn Marino   cexpr_list = VEC_alloc (c_expr_t, gc, 1);
6140*e4b17023SJohn Marino   C_EXPR_APPEND (cexpr_list, expr);
6141*e4b17023SJohn Marino   while (c_parser_next_token_is (parser, CPP_COMMA))
6142*e4b17023SJohn Marino     {
6143*e4b17023SJohn Marino       c_parser_consume_token (parser);
6144*e4b17023SJohn Marino       expr = c_parser_expr_no_commas (parser, NULL);
6145*e4b17023SJohn Marino       C_EXPR_APPEND (cexpr_list, expr);
6146*e4b17023SJohn Marino     }
6147*e4b17023SJohn Marino 
6148*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
6149*e4b17023SJohn Marino     return false;
6150*e4b17023SJohn Marino 
6151*e4b17023SJohn Marino   *ret_cexpr_list = cexpr_list;
6152*e4b17023SJohn Marino   return true;
6153*e4b17023SJohn Marino }
6154*e4b17023SJohn Marino 
6155*e4b17023SJohn Marino 
6156*e4b17023SJohn Marino /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2).
6157*e4b17023SJohn Marino 
6158*e4b17023SJohn Marino    postfix-expression:
6159*e4b17023SJohn Marino      primary-expression
6160*e4b17023SJohn Marino      postfix-expression [ expression ]
6161*e4b17023SJohn Marino      postfix-expression ( argument-expression-list[opt] )
6162*e4b17023SJohn Marino      postfix-expression . identifier
6163*e4b17023SJohn Marino      postfix-expression -> identifier
6164*e4b17023SJohn Marino      postfix-expression ++
6165*e4b17023SJohn Marino      postfix-expression --
6166*e4b17023SJohn Marino      ( type-name ) { initializer-list }
6167*e4b17023SJohn Marino      ( type-name ) { initializer-list , }
6168*e4b17023SJohn Marino 
6169*e4b17023SJohn Marino    argument-expression-list:
6170*e4b17023SJohn Marino      argument-expression
6171*e4b17023SJohn Marino      argument-expression-list , argument-expression
6172*e4b17023SJohn Marino 
6173*e4b17023SJohn Marino    primary-expression:
6174*e4b17023SJohn Marino      identifier
6175*e4b17023SJohn Marino      constant
6176*e4b17023SJohn Marino      string-literal
6177*e4b17023SJohn Marino      ( expression )
6178*e4b17023SJohn Marino 
6179*e4b17023SJohn Marino    GNU extensions:
6180*e4b17023SJohn Marino 
6181*e4b17023SJohn Marino    primary-expression:
6182*e4b17023SJohn Marino      __func__
6183*e4b17023SJohn Marino        (treated as a keyword in GNU C)
6184*e4b17023SJohn Marino      __FUNCTION__
6185*e4b17023SJohn Marino      __PRETTY_FUNCTION__
6186*e4b17023SJohn Marino      ( compound-statement )
6187*e4b17023SJohn Marino      __builtin_va_arg ( assignment-expression , type-name )
6188*e4b17023SJohn Marino      __builtin_offsetof ( type-name , offsetof-member-designator )
6189*e4b17023SJohn Marino      __builtin_choose_expr ( assignment-expression ,
6190*e4b17023SJohn Marino 			     assignment-expression ,
6191*e4b17023SJohn Marino 			     assignment-expression )
6192*e4b17023SJohn Marino      __builtin_types_compatible_p ( type-name , type-name )
6193*e4b17023SJohn Marino      __builtin_complex ( assignment-expression , assignment-expression )
6194*e4b17023SJohn Marino      __builtin_shuffle ( assignment-expression , assignment-expression )
6195*e4b17023SJohn Marino      __builtin_shuffle ( assignment-expression ,
6196*e4b17023SJohn Marino 			 assignment-expression ,
6197*e4b17023SJohn Marino 			 assignment-expression, )
6198*e4b17023SJohn Marino 
6199*e4b17023SJohn Marino    offsetof-member-designator:
6200*e4b17023SJohn Marino      identifier
6201*e4b17023SJohn Marino      offsetof-member-designator . identifier
6202*e4b17023SJohn Marino      offsetof-member-designator [ expression ]
6203*e4b17023SJohn Marino 
6204*e4b17023SJohn Marino    Objective-C:
6205*e4b17023SJohn Marino 
6206*e4b17023SJohn Marino    primary-expression:
6207*e4b17023SJohn Marino      [ objc-receiver objc-message-args ]
6208*e4b17023SJohn Marino      @selector ( objc-selector-arg )
6209*e4b17023SJohn Marino      @protocol ( identifier )
6210*e4b17023SJohn Marino      @encode ( type-name )
6211*e4b17023SJohn Marino      objc-string-literal
6212*e4b17023SJohn Marino      Classname . identifier
6213*e4b17023SJohn Marino */
6214*e4b17023SJohn Marino 
6215*e4b17023SJohn Marino static struct c_expr
c_parser_postfix_expression(c_parser * parser)6216*e4b17023SJohn Marino c_parser_postfix_expression (c_parser *parser)
6217*e4b17023SJohn Marino {
6218*e4b17023SJohn Marino   struct c_expr expr, e1;
6219*e4b17023SJohn Marino   struct c_type_name *t1, *t2;
6220*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;;
6221*e4b17023SJohn Marino   expr.original_code = ERROR_MARK;
6222*e4b17023SJohn Marino   expr.original_type = NULL;
6223*e4b17023SJohn Marino   switch (c_parser_peek_token (parser)->type)
6224*e4b17023SJohn Marino     {
6225*e4b17023SJohn Marino     case CPP_NUMBER:
6226*e4b17023SJohn Marino       expr.value = c_parser_peek_token (parser)->value;
6227*e4b17023SJohn Marino       loc = c_parser_peek_token (parser)->location;
6228*e4b17023SJohn Marino       c_parser_consume_token (parser);
6229*e4b17023SJohn Marino       if (TREE_CODE (expr.value) == FIXED_CST
6230*e4b17023SJohn Marino 	  && !targetm.fixed_point_supported_p ())
6231*e4b17023SJohn Marino 	{
6232*e4b17023SJohn Marino 	  error_at (loc, "fixed-point types not supported for this target");
6233*e4b17023SJohn Marino 	  expr.value = error_mark_node;
6234*e4b17023SJohn Marino 	}
6235*e4b17023SJohn Marino       break;
6236*e4b17023SJohn Marino     case CPP_CHAR:
6237*e4b17023SJohn Marino     case CPP_CHAR16:
6238*e4b17023SJohn Marino     case CPP_CHAR32:
6239*e4b17023SJohn Marino     case CPP_WCHAR:
6240*e4b17023SJohn Marino       expr.value = c_parser_peek_token (parser)->value;
6241*e4b17023SJohn Marino       c_parser_consume_token (parser);
6242*e4b17023SJohn Marino       break;
6243*e4b17023SJohn Marino     case CPP_STRING:
6244*e4b17023SJohn Marino     case CPP_STRING16:
6245*e4b17023SJohn Marino     case CPP_STRING32:
6246*e4b17023SJohn Marino     case CPP_WSTRING:
6247*e4b17023SJohn Marino     case CPP_UTF8STRING:
6248*e4b17023SJohn Marino       expr.value = c_parser_peek_token (parser)->value;
6249*e4b17023SJohn Marino       expr.original_code = STRING_CST;
6250*e4b17023SJohn Marino       c_parser_consume_token (parser);
6251*e4b17023SJohn Marino       break;
6252*e4b17023SJohn Marino     case CPP_OBJC_STRING:
6253*e4b17023SJohn Marino       gcc_assert (c_dialect_objc ());
6254*e4b17023SJohn Marino       expr.value
6255*e4b17023SJohn Marino 	= objc_build_string_object (c_parser_peek_token (parser)->value);
6256*e4b17023SJohn Marino       c_parser_consume_token (parser);
6257*e4b17023SJohn Marino       break;
6258*e4b17023SJohn Marino     case CPP_NAME:
6259*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->id_kind)
6260*e4b17023SJohn Marino 	{
6261*e4b17023SJohn Marino 	case C_ID_ID:
6262*e4b17023SJohn Marino 	  {
6263*e4b17023SJohn Marino 	    tree id = c_parser_peek_token (parser)->value;
6264*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
6265*e4b17023SJohn Marino 	    expr.value = build_external_ref (loc, id,
6266*e4b17023SJohn Marino 					     (c_parser_peek_token (parser)->type
6267*e4b17023SJohn Marino 					      == CPP_OPEN_PAREN),
6268*e4b17023SJohn Marino 					     &expr.original_type);
6269*e4b17023SJohn Marino 	    break;
6270*e4b17023SJohn Marino 	  }
6271*e4b17023SJohn Marino 	case C_ID_CLASSNAME:
6272*e4b17023SJohn Marino 	  {
6273*e4b17023SJohn Marino 	    /* Here we parse the Objective-C 2.0 Class.name dot
6274*e4b17023SJohn Marino 	       syntax.  */
6275*e4b17023SJohn Marino 	    tree class_name = c_parser_peek_token (parser)->value;
6276*e4b17023SJohn Marino 	    tree component;
6277*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
6278*e4b17023SJohn Marino 	    gcc_assert (c_dialect_objc ());
6279*e4b17023SJohn Marino 	    if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
6280*e4b17023SJohn Marino 	      {
6281*e4b17023SJohn Marino 		expr.value = error_mark_node;
6282*e4b17023SJohn Marino 		break;
6283*e4b17023SJohn Marino 	      }
6284*e4b17023SJohn Marino 	    if (c_parser_next_token_is_not (parser, CPP_NAME))
6285*e4b17023SJohn Marino 	      {
6286*e4b17023SJohn Marino 		c_parser_error (parser, "expected identifier");
6287*e4b17023SJohn Marino 		expr.value = error_mark_node;
6288*e4b17023SJohn Marino 		break;
6289*e4b17023SJohn Marino 	      }
6290*e4b17023SJohn Marino 	    component = c_parser_peek_token (parser)->value;
6291*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
6292*e4b17023SJohn Marino 	    expr.value = objc_build_class_component_ref (class_name,
6293*e4b17023SJohn Marino 							 component);
6294*e4b17023SJohn Marino 	    break;
6295*e4b17023SJohn Marino 	  }
6296*e4b17023SJohn Marino 	default:
6297*e4b17023SJohn Marino 	  c_parser_error (parser, "expected expression");
6298*e4b17023SJohn Marino 	  expr.value = error_mark_node;
6299*e4b17023SJohn Marino 	  break;
6300*e4b17023SJohn Marino 	}
6301*e4b17023SJohn Marino       break;
6302*e4b17023SJohn Marino     case CPP_OPEN_PAREN:
6303*e4b17023SJohn Marino       /* A parenthesized expression, statement expression or compound
6304*e4b17023SJohn Marino 	 literal.  */
6305*e4b17023SJohn Marino       if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
6306*e4b17023SJohn Marino 	{
6307*e4b17023SJohn Marino 	  /* A statement expression.  */
6308*e4b17023SJohn Marino 	  tree stmt;
6309*e4b17023SJohn Marino 	  location_t brace_loc;
6310*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6311*e4b17023SJohn Marino 	  brace_loc = c_parser_peek_token (parser)->location;
6312*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6313*e4b17023SJohn Marino 	  if (!building_stmt_list_p ())
6314*e4b17023SJohn Marino 	    {
6315*e4b17023SJohn Marino 	      error_at (loc, "braced-group within expression allowed "
6316*e4b17023SJohn Marino 			"only inside a function");
6317*e4b17023SJohn Marino 	      parser->error = true;
6318*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
6319*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6320*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6321*e4b17023SJohn Marino 	      break;
6322*e4b17023SJohn Marino 	    }
6323*e4b17023SJohn Marino 	  stmt = c_begin_stmt_expr ();
6324*e4b17023SJohn Marino 	  c_parser_compound_statement_nostart (parser);
6325*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6326*e4b17023SJohn Marino 				     "expected %<)%>");
6327*e4b17023SJohn Marino 	  pedwarn (loc, OPT_pedantic,
6328*e4b17023SJohn Marino 		   "ISO C forbids braced-groups within expressions");
6329*e4b17023SJohn Marino 	  expr.value = c_finish_stmt_expr (brace_loc, stmt);
6330*e4b17023SJohn Marino 	  mark_exp_read (expr.value);
6331*e4b17023SJohn Marino 	}
6332*e4b17023SJohn Marino       else if (c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6333*e4b17023SJohn Marino 	{
6334*e4b17023SJohn Marino 	  /* A compound literal.  ??? Can we actually get here rather
6335*e4b17023SJohn Marino 	     than going directly to
6336*e4b17023SJohn Marino 	     c_parser_postfix_expression_after_paren_type from
6337*e4b17023SJohn Marino 	     elsewhere?  */
6338*e4b17023SJohn Marino 	  location_t loc;
6339*e4b17023SJohn Marino 	  struct c_type_name *type_name;
6340*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6341*e4b17023SJohn Marino 	  loc = c_parser_peek_token (parser)->location;
6342*e4b17023SJohn Marino 	  type_name = c_parser_type_name (parser);
6343*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6344*e4b17023SJohn Marino 				     "expected %<)%>");
6345*e4b17023SJohn Marino 	  if (type_name == NULL)
6346*e4b17023SJohn Marino 	    {
6347*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6348*e4b17023SJohn Marino 	    }
6349*e4b17023SJohn Marino 	  else
6350*e4b17023SJohn Marino 	    expr = c_parser_postfix_expression_after_paren_type (parser,
6351*e4b17023SJohn Marino 								 type_name,
6352*e4b17023SJohn Marino 								 loc);
6353*e4b17023SJohn Marino 	}
6354*e4b17023SJohn Marino       else
6355*e4b17023SJohn Marino 	{
6356*e4b17023SJohn Marino 	  /* A parenthesized expression.  */
6357*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6358*e4b17023SJohn Marino 	  expr = c_parser_expression (parser);
6359*e4b17023SJohn Marino 	  if (TREE_CODE (expr.value) == MODIFY_EXPR)
6360*e4b17023SJohn Marino 	    TREE_NO_WARNING (expr.value) = 1;
6361*e4b17023SJohn Marino 	  if (expr.original_code != C_MAYBE_CONST_EXPR)
6362*e4b17023SJohn Marino 	    expr.original_code = ERROR_MARK;
6363*e4b17023SJohn Marino 	  /* Don't change EXPR.ORIGINAL_TYPE.  */
6364*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6365*e4b17023SJohn Marino 				     "expected %<)%>");
6366*e4b17023SJohn Marino 	}
6367*e4b17023SJohn Marino       break;
6368*e4b17023SJohn Marino     case CPP_KEYWORD:
6369*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->keyword)
6370*e4b17023SJohn Marino 	{
6371*e4b17023SJohn Marino 	case RID_FUNCTION_NAME:
6372*e4b17023SJohn Marino 	case RID_PRETTY_FUNCTION_NAME:
6373*e4b17023SJohn Marino 	case RID_C99_FUNCTION_NAME:
6374*e4b17023SJohn Marino 	  expr.value = fname_decl (loc,
6375*e4b17023SJohn Marino 				   c_parser_peek_token (parser)->keyword,
6376*e4b17023SJohn Marino 				   c_parser_peek_token (parser)->value);
6377*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6378*e4b17023SJohn Marino 	  break;
6379*e4b17023SJohn Marino 	case RID_VA_ARG:
6380*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6381*e4b17023SJohn Marino 	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6382*e4b17023SJohn Marino 	    {
6383*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6384*e4b17023SJohn Marino 	      break;
6385*e4b17023SJohn Marino 	    }
6386*e4b17023SJohn Marino 	  e1 = c_parser_expr_no_commas (parser, NULL);
6387*e4b17023SJohn Marino 	  mark_exp_read (e1.value);
6388*e4b17023SJohn Marino 	  e1.value = c_fully_fold (e1.value, false, NULL);
6389*e4b17023SJohn Marino 	  if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
6390*e4b17023SJohn Marino 	    {
6391*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6392*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6393*e4b17023SJohn Marino 	      break;
6394*e4b17023SJohn Marino 	    }
6395*e4b17023SJohn Marino 	  loc = c_parser_peek_token (parser)->location;
6396*e4b17023SJohn Marino 	  t1 = c_parser_type_name (parser);
6397*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6398*e4b17023SJohn Marino 				     "expected %<)%>");
6399*e4b17023SJohn Marino 	  if (t1 == NULL)
6400*e4b17023SJohn Marino 	    {
6401*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6402*e4b17023SJohn Marino 	    }
6403*e4b17023SJohn Marino 	  else
6404*e4b17023SJohn Marino 	    {
6405*e4b17023SJohn Marino 	      tree type_expr = NULL_TREE;
6406*e4b17023SJohn Marino 	      expr.value = c_build_va_arg (loc, e1.value,
6407*e4b17023SJohn Marino 					   groktypename (t1, &type_expr, NULL));
6408*e4b17023SJohn Marino 	      if (type_expr)
6409*e4b17023SJohn Marino 		{
6410*e4b17023SJohn Marino 		  expr.value = build2 (C_MAYBE_CONST_EXPR,
6411*e4b17023SJohn Marino 				       TREE_TYPE (expr.value), type_expr,
6412*e4b17023SJohn Marino 				       expr.value);
6413*e4b17023SJohn Marino 		  C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
6414*e4b17023SJohn Marino 		}
6415*e4b17023SJohn Marino 	    }
6416*e4b17023SJohn Marino 	  break;
6417*e4b17023SJohn Marino 	case RID_OFFSETOF:
6418*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6419*e4b17023SJohn Marino 	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6420*e4b17023SJohn Marino 	    {
6421*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6422*e4b17023SJohn Marino 	      break;
6423*e4b17023SJohn Marino 	    }
6424*e4b17023SJohn Marino 	  t1 = c_parser_type_name (parser);
6425*e4b17023SJohn Marino 	  if (t1 == NULL)
6426*e4b17023SJohn Marino 	    parser->error = true;
6427*e4b17023SJohn Marino 	  if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
6428*e4b17023SJohn Marino             gcc_assert (parser->error);
6429*e4b17023SJohn Marino 	  if (parser->error)
6430*e4b17023SJohn Marino 	    {
6431*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6432*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6433*e4b17023SJohn Marino 	      break;
6434*e4b17023SJohn Marino 	    }
6435*e4b17023SJohn Marino 
6436*e4b17023SJohn Marino 	  {
6437*e4b17023SJohn Marino 	    tree type = groktypename (t1, NULL, NULL);
6438*e4b17023SJohn Marino 	    tree offsetof_ref;
6439*e4b17023SJohn Marino 	    if (type == error_mark_node)
6440*e4b17023SJohn Marino 	      offsetof_ref = error_mark_node;
6441*e4b17023SJohn Marino 	    else
6442*e4b17023SJohn Marino 	      {
6443*e4b17023SJohn Marino 		offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
6444*e4b17023SJohn Marino 		SET_EXPR_LOCATION (offsetof_ref, loc);
6445*e4b17023SJohn Marino 	      }
6446*e4b17023SJohn Marino 	    /* Parse the second argument to __builtin_offsetof.  We
6447*e4b17023SJohn Marino 	       must have one identifier, and beyond that we want to
6448*e4b17023SJohn Marino 	       accept sub structure and sub array references.  */
6449*e4b17023SJohn Marino 	    if (c_parser_next_token_is (parser, CPP_NAME))
6450*e4b17023SJohn Marino 	      {
6451*e4b17023SJohn Marino 		offsetof_ref = build_component_ref
6452*e4b17023SJohn Marino 		  (loc, offsetof_ref, c_parser_peek_token (parser)->value);
6453*e4b17023SJohn Marino 		c_parser_consume_token (parser);
6454*e4b17023SJohn Marino 		while (c_parser_next_token_is (parser, CPP_DOT)
6455*e4b17023SJohn Marino 		       || c_parser_next_token_is (parser,
6456*e4b17023SJohn Marino 						  CPP_OPEN_SQUARE)
6457*e4b17023SJohn Marino 		       || c_parser_next_token_is (parser,
6458*e4b17023SJohn Marino 						  CPP_DEREF))
6459*e4b17023SJohn Marino 		  {
6460*e4b17023SJohn Marino 		    if (c_parser_next_token_is (parser, CPP_DEREF))
6461*e4b17023SJohn Marino 		      {
6462*e4b17023SJohn Marino 			loc = c_parser_peek_token (parser)->location;
6463*e4b17023SJohn Marino 			offsetof_ref = build_array_ref (loc,
6464*e4b17023SJohn Marino 							offsetof_ref,
6465*e4b17023SJohn Marino 							integer_zero_node);
6466*e4b17023SJohn Marino 			goto do_dot;
6467*e4b17023SJohn Marino 		      }
6468*e4b17023SJohn Marino 		    else if (c_parser_next_token_is (parser, CPP_DOT))
6469*e4b17023SJohn Marino 		      {
6470*e4b17023SJohn Marino 		      do_dot:
6471*e4b17023SJohn Marino 			c_parser_consume_token (parser);
6472*e4b17023SJohn Marino 			if (c_parser_next_token_is_not (parser,
6473*e4b17023SJohn Marino 							CPP_NAME))
6474*e4b17023SJohn Marino 			  {
6475*e4b17023SJohn Marino 			    c_parser_error (parser, "expected identifier");
6476*e4b17023SJohn Marino 			    break;
6477*e4b17023SJohn Marino 			  }
6478*e4b17023SJohn Marino 			offsetof_ref = build_component_ref
6479*e4b17023SJohn Marino 			  (loc, offsetof_ref,
6480*e4b17023SJohn Marino 			   c_parser_peek_token (parser)->value);
6481*e4b17023SJohn Marino 			c_parser_consume_token (parser);
6482*e4b17023SJohn Marino 		      }
6483*e4b17023SJohn Marino 		    else
6484*e4b17023SJohn Marino 		      {
6485*e4b17023SJohn Marino 			tree idx;
6486*e4b17023SJohn Marino 			loc = c_parser_peek_token (parser)->location;
6487*e4b17023SJohn Marino 			c_parser_consume_token (parser);
6488*e4b17023SJohn Marino 			idx = c_parser_expression (parser).value;
6489*e4b17023SJohn Marino 			idx = c_fully_fold (idx, false, NULL);
6490*e4b17023SJohn Marino 			c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6491*e4b17023SJohn Marino 						   "expected %<]%>");
6492*e4b17023SJohn Marino 			offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
6493*e4b17023SJohn Marino 		      }
6494*e4b17023SJohn Marino 		  }
6495*e4b17023SJohn Marino 	      }
6496*e4b17023SJohn Marino 	    else
6497*e4b17023SJohn Marino 	      c_parser_error (parser, "expected identifier");
6498*e4b17023SJohn Marino 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6499*e4b17023SJohn Marino 				       "expected %<)%>");
6500*e4b17023SJohn Marino 	    expr.value = fold_offsetof (offsetof_ref);
6501*e4b17023SJohn Marino 	  }
6502*e4b17023SJohn Marino 	  break;
6503*e4b17023SJohn Marino 	case RID_CHOOSE_EXPR:
6504*e4b17023SJohn Marino 	  {
6505*e4b17023SJohn Marino 	    VEC (c_expr_t, gc) *cexpr_list;
6506*e4b17023SJohn Marino 	    c_expr_t *e1_p, *e2_p, *e3_p;
6507*e4b17023SJohn Marino 	    tree c;
6508*e4b17023SJohn Marino 
6509*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
6510*e4b17023SJohn Marino 	    if (!c_parser_get_builtin_args (parser,
6511*e4b17023SJohn Marino 					    "__builtin_choose_expr",
6512*e4b17023SJohn Marino 					    &cexpr_list))
6513*e4b17023SJohn Marino 	      {
6514*e4b17023SJohn Marino 		expr.value = error_mark_node;
6515*e4b17023SJohn Marino 		break;
6516*e4b17023SJohn Marino 	      }
6517*e4b17023SJohn Marino 
6518*e4b17023SJohn Marino 	    if (VEC_length (c_expr_t, cexpr_list) != 3)
6519*e4b17023SJohn Marino 	      {
6520*e4b17023SJohn Marino 		error_at (loc, "wrong number of arguments to "
6521*e4b17023SJohn Marino 			       "%<__builtin_choose_expr%>");
6522*e4b17023SJohn Marino 		expr.value = error_mark_node;
6523*e4b17023SJohn Marino 		break;
6524*e4b17023SJohn Marino 	      }
6525*e4b17023SJohn Marino 
6526*e4b17023SJohn Marino 	    e1_p = VEC_index (c_expr_t, cexpr_list, 0);
6527*e4b17023SJohn Marino 	    e2_p = VEC_index (c_expr_t, cexpr_list, 1);
6528*e4b17023SJohn Marino 	    e3_p = VEC_index (c_expr_t, cexpr_list, 2);
6529*e4b17023SJohn Marino 
6530*e4b17023SJohn Marino 	    c = e1_p->value;
6531*e4b17023SJohn Marino 	    mark_exp_read (e2_p->value);
6532*e4b17023SJohn Marino 	    mark_exp_read (e3_p->value);
6533*e4b17023SJohn Marino 	    if (TREE_CODE (c) != INTEGER_CST
6534*e4b17023SJohn Marino 		|| !INTEGRAL_TYPE_P (TREE_TYPE (c)))
6535*e4b17023SJohn Marino 	      error_at (loc,
6536*e4b17023SJohn Marino 			"first argument to %<__builtin_choose_expr%> not"
6537*e4b17023SJohn Marino 			" a constant");
6538*e4b17023SJohn Marino 	    constant_expression_warning (c);
6539*e4b17023SJohn Marino 	    expr = integer_zerop (c) ? *e3_p : *e2_p;
6540*e4b17023SJohn Marino 	    break;
6541*e4b17023SJohn Marino 	  }
6542*e4b17023SJohn Marino 	case RID_TYPES_COMPATIBLE_P:
6543*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6544*e4b17023SJohn Marino 	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6545*e4b17023SJohn Marino 	    {
6546*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6547*e4b17023SJohn Marino 	      break;
6548*e4b17023SJohn Marino 	    }
6549*e4b17023SJohn Marino 	  t1 = c_parser_type_name (parser);
6550*e4b17023SJohn Marino 	  if (t1 == NULL)
6551*e4b17023SJohn Marino 	    {
6552*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6553*e4b17023SJohn Marino 	      break;
6554*e4b17023SJohn Marino 	    }
6555*e4b17023SJohn Marino 	  if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
6556*e4b17023SJohn Marino 	    {
6557*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6558*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6559*e4b17023SJohn Marino 	      break;
6560*e4b17023SJohn Marino 	    }
6561*e4b17023SJohn Marino 	  t2 = c_parser_type_name (parser);
6562*e4b17023SJohn Marino 	  if (t2 == NULL)
6563*e4b17023SJohn Marino 	    {
6564*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6565*e4b17023SJohn Marino 	      break;
6566*e4b17023SJohn Marino 	    }
6567*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6568*e4b17023SJohn Marino 				     "expected %<)%>");
6569*e4b17023SJohn Marino 	  {
6570*e4b17023SJohn Marino 	    tree e1, e2;
6571*e4b17023SJohn Marino 	    e1 = groktypename (t1, NULL, NULL);
6572*e4b17023SJohn Marino 	    e2 = groktypename (t2, NULL, NULL);
6573*e4b17023SJohn Marino 	    if (e1 == error_mark_node || e2 == error_mark_node)
6574*e4b17023SJohn Marino 	      {
6575*e4b17023SJohn Marino 		expr.value = error_mark_node;
6576*e4b17023SJohn Marino 		break;
6577*e4b17023SJohn Marino 	      }
6578*e4b17023SJohn Marino 
6579*e4b17023SJohn Marino 	    e1 = TYPE_MAIN_VARIANT (e1);
6580*e4b17023SJohn Marino 	    e2 = TYPE_MAIN_VARIANT (e2);
6581*e4b17023SJohn Marino 
6582*e4b17023SJohn Marino 	    expr.value
6583*e4b17023SJohn Marino 	      = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
6584*e4b17023SJohn Marino 	  }
6585*e4b17023SJohn Marino 	  break;
6586*e4b17023SJohn Marino 	case RID_BUILTIN_COMPLEX:
6587*e4b17023SJohn Marino 	  {
6588*e4b17023SJohn Marino 	    VEC(c_expr_t, gc) *cexpr_list;
6589*e4b17023SJohn Marino 	    c_expr_t *e1_p, *e2_p;
6590*e4b17023SJohn Marino 
6591*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
6592*e4b17023SJohn Marino 	    if (!c_parser_get_builtin_args (parser,
6593*e4b17023SJohn Marino 					    "__builtin_complex",
6594*e4b17023SJohn Marino 					    &cexpr_list))
6595*e4b17023SJohn Marino 	      {
6596*e4b17023SJohn Marino 		expr.value = error_mark_node;
6597*e4b17023SJohn Marino 		break;
6598*e4b17023SJohn Marino 	      }
6599*e4b17023SJohn Marino 
6600*e4b17023SJohn Marino 	    if (VEC_length (c_expr_t, cexpr_list) != 2)
6601*e4b17023SJohn Marino 	      {
6602*e4b17023SJohn Marino 		error_at (loc, "wrong number of arguments to "
6603*e4b17023SJohn Marino 			       "%<__builtin_complex%>");
6604*e4b17023SJohn Marino 		expr.value = error_mark_node;
6605*e4b17023SJohn Marino 		break;
6606*e4b17023SJohn Marino 	      }
6607*e4b17023SJohn Marino 
6608*e4b17023SJohn Marino 	    e1_p = VEC_index (c_expr_t, cexpr_list, 0);
6609*e4b17023SJohn Marino 	    e2_p = VEC_index (c_expr_t, cexpr_list, 1);
6610*e4b17023SJohn Marino 
6611*e4b17023SJohn Marino 	    mark_exp_read (e1_p->value);
6612*e4b17023SJohn Marino 	    if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
6613*e4b17023SJohn Marino 	      e1_p->value = convert (TREE_TYPE (e1_p->value),
6614*e4b17023SJohn Marino 				     TREE_OPERAND (e1_p->value, 0));
6615*e4b17023SJohn Marino 	    mark_exp_read (e2_p->value);
6616*e4b17023SJohn Marino 	    if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
6617*e4b17023SJohn Marino 	      e2_p->value = convert (TREE_TYPE (e2_p->value),
6618*e4b17023SJohn Marino 				     TREE_OPERAND (e2_p->value, 0));
6619*e4b17023SJohn Marino 	    if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
6620*e4b17023SJohn Marino 		|| DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
6621*e4b17023SJohn Marino 		|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
6622*e4b17023SJohn Marino 		|| DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
6623*e4b17023SJohn Marino 	      {
6624*e4b17023SJohn Marino 		error_at (loc, "%<__builtin_complex%> operand "
6625*e4b17023SJohn Marino 			  "not of real binary floating-point type");
6626*e4b17023SJohn Marino 		expr.value = error_mark_node;
6627*e4b17023SJohn Marino 		break;
6628*e4b17023SJohn Marino 	      }
6629*e4b17023SJohn Marino 	    if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
6630*e4b17023SJohn Marino 		!= TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
6631*e4b17023SJohn Marino 	      {
6632*e4b17023SJohn Marino 		error_at (loc,
6633*e4b17023SJohn Marino 			  "%<__builtin_complex%> operands of different types");
6634*e4b17023SJohn Marino 		expr.value = error_mark_node;
6635*e4b17023SJohn Marino 		break;
6636*e4b17023SJohn Marino 	      }
6637*e4b17023SJohn Marino 	    if (!flag_isoc99)
6638*e4b17023SJohn Marino 	      pedwarn (loc, OPT_pedantic,
6639*e4b17023SJohn Marino 		       "ISO C90 does not support complex types");
6640*e4b17023SJohn Marino 	    expr.value = build2 (COMPLEX_EXPR,
6641*e4b17023SJohn Marino 				 build_complex_type
6642*e4b17023SJohn Marino 				   (TYPE_MAIN_VARIANT
6643*e4b17023SJohn Marino 				     (TREE_TYPE (e1_p->value))),
6644*e4b17023SJohn Marino 				 e1_p->value, e2_p->value);
6645*e4b17023SJohn Marino 	    break;
6646*e4b17023SJohn Marino 	  }
6647*e4b17023SJohn Marino 	case RID_BUILTIN_SHUFFLE:
6648*e4b17023SJohn Marino 	  {
6649*e4b17023SJohn Marino 	    VEC(c_expr_t,gc) *cexpr_list;
6650*e4b17023SJohn Marino 	    unsigned int i;
6651*e4b17023SJohn Marino 	    c_expr_t *p;
6652*e4b17023SJohn Marino 
6653*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
6654*e4b17023SJohn Marino 	    if (!c_parser_get_builtin_args (parser,
6655*e4b17023SJohn Marino 					    "__builtin_shuffle",
6656*e4b17023SJohn Marino 					    &cexpr_list))
6657*e4b17023SJohn Marino 	      {
6658*e4b17023SJohn Marino 		expr.value = error_mark_node;
6659*e4b17023SJohn Marino 		break;
6660*e4b17023SJohn Marino 	      }
6661*e4b17023SJohn Marino 
6662*e4b17023SJohn Marino 	    FOR_EACH_VEC_ELT (c_expr_t, cexpr_list, i, p)
6663*e4b17023SJohn Marino 	      mark_exp_read (p->value);
6664*e4b17023SJohn Marino 
6665*e4b17023SJohn Marino 	    if (VEC_length (c_expr_t, cexpr_list) == 2)
6666*e4b17023SJohn Marino 	      expr.value =
6667*e4b17023SJohn Marino 		c_build_vec_perm_expr
6668*e4b17023SJohn Marino 		  (loc, VEC_index (c_expr_t, cexpr_list, 0)->value,
6669*e4b17023SJohn Marino 		   NULL_TREE, VEC_index (c_expr_t, cexpr_list, 1)->value);
6670*e4b17023SJohn Marino 
6671*e4b17023SJohn Marino 	    else if (VEC_length (c_expr_t, cexpr_list) == 3)
6672*e4b17023SJohn Marino 	      expr.value =
6673*e4b17023SJohn Marino 		c_build_vec_perm_expr
6674*e4b17023SJohn Marino 		  (loc, VEC_index (c_expr_t, cexpr_list, 0)->value,
6675*e4b17023SJohn Marino 		   VEC_index (c_expr_t, cexpr_list, 1)->value,
6676*e4b17023SJohn Marino 		   VEC_index (c_expr_t, cexpr_list, 2)->value);
6677*e4b17023SJohn Marino 	    else
6678*e4b17023SJohn Marino 	      {
6679*e4b17023SJohn Marino 		error_at (loc, "wrong number of arguments to "
6680*e4b17023SJohn Marino 			       "%<__builtin_shuffle%>");
6681*e4b17023SJohn Marino 		expr.value = error_mark_node;
6682*e4b17023SJohn Marino 	      }
6683*e4b17023SJohn Marino 	    break;
6684*e4b17023SJohn Marino 	  }
6685*e4b17023SJohn Marino 	case RID_AT_SELECTOR:
6686*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
6687*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6688*e4b17023SJohn Marino 	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6689*e4b17023SJohn Marino 	    {
6690*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6691*e4b17023SJohn Marino 	      break;
6692*e4b17023SJohn Marino 	    }
6693*e4b17023SJohn Marino 	  {
6694*e4b17023SJohn Marino 	    tree sel = c_parser_objc_selector_arg (parser);
6695*e4b17023SJohn Marino 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6696*e4b17023SJohn Marino 				       "expected %<)%>");
6697*e4b17023SJohn Marino 	    expr.value = objc_build_selector_expr (loc, sel);
6698*e4b17023SJohn Marino 	  }
6699*e4b17023SJohn Marino 	  break;
6700*e4b17023SJohn Marino 	case RID_AT_PROTOCOL:
6701*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
6702*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6703*e4b17023SJohn Marino 	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6704*e4b17023SJohn Marino 	    {
6705*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6706*e4b17023SJohn Marino 	      break;
6707*e4b17023SJohn Marino 	    }
6708*e4b17023SJohn Marino 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
6709*e4b17023SJohn Marino 	    {
6710*e4b17023SJohn Marino 	      c_parser_error (parser, "expected identifier");
6711*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6712*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6713*e4b17023SJohn Marino 	      break;
6714*e4b17023SJohn Marino 	    }
6715*e4b17023SJohn Marino 	  {
6716*e4b17023SJohn Marino 	    tree id = c_parser_peek_token (parser)->value;
6717*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
6718*e4b17023SJohn Marino 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6719*e4b17023SJohn Marino 				       "expected %<)%>");
6720*e4b17023SJohn Marino 	    expr.value = objc_build_protocol_expr (id);
6721*e4b17023SJohn Marino 	  }
6722*e4b17023SJohn Marino 	  break;
6723*e4b17023SJohn Marino 	case RID_AT_ENCODE:
6724*e4b17023SJohn Marino 	  /* Extension to support C-structures in the archiver.  */
6725*e4b17023SJohn Marino 	  gcc_assert (c_dialect_objc ());
6726*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6727*e4b17023SJohn Marino 	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6728*e4b17023SJohn Marino 	    {
6729*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6730*e4b17023SJohn Marino 	      break;
6731*e4b17023SJohn Marino 	    }
6732*e4b17023SJohn Marino 	  t1 = c_parser_type_name (parser);
6733*e4b17023SJohn Marino 	  if (t1 == NULL)
6734*e4b17023SJohn Marino 	    {
6735*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6736*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6737*e4b17023SJohn Marino 	      break;
6738*e4b17023SJohn Marino 	    }
6739*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6740*e4b17023SJohn Marino 				     "expected %<)%>");
6741*e4b17023SJohn Marino 	  {
6742*e4b17023SJohn Marino 	    tree type = groktypename (t1, NULL, NULL);
6743*e4b17023SJohn Marino 	    expr.value = objc_build_encode_expr (type);
6744*e4b17023SJohn Marino 	  }
6745*e4b17023SJohn Marino 	  break;
6746*e4b17023SJohn Marino 	default:
6747*e4b17023SJohn Marino 	  c_parser_error (parser, "expected expression");
6748*e4b17023SJohn Marino 	  expr.value = error_mark_node;
6749*e4b17023SJohn Marino 	  break;
6750*e4b17023SJohn Marino 	}
6751*e4b17023SJohn Marino       break;
6752*e4b17023SJohn Marino     case CPP_OPEN_SQUARE:
6753*e4b17023SJohn Marino       if (c_dialect_objc ())
6754*e4b17023SJohn Marino 	{
6755*e4b17023SJohn Marino 	  tree receiver, args;
6756*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6757*e4b17023SJohn Marino 	  receiver = c_parser_objc_receiver (parser);
6758*e4b17023SJohn Marino 	  args = c_parser_objc_message_args (parser);
6759*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6760*e4b17023SJohn Marino 				     "expected %<]%>");
6761*e4b17023SJohn Marino 	  expr.value = objc_build_message_expr (receiver, args);
6762*e4b17023SJohn Marino 	  break;
6763*e4b17023SJohn Marino 	}
6764*e4b17023SJohn Marino       /* Else fall through to report error.  */
6765*e4b17023SJohn Marino     default:
6766*e4b17023SJohn Marino       c_parser_error (parser, "expected expression");
6767*e4b17023SJohn Marino       expr.value = error_mark_node;
6768*e4b17023SJohn Marino       break;
6769*e4b17023SJohn Marino     }
6770*e4b17023SJohn Marino   return c_parser_postfix_expression_after_primary (parser, loc, expr);
6771*e4b17023SJohn Marino }
6772*e4b17023SJohn Marino 
6773*e4b17023SJohn Marino /* Parse a postfix expression after a parenthesized type name: the
6774*e4b17023SJohn Marino    brace-enclosed initializer of a compound literal, possibly followed
6775*e4b17023SJohn Marino    by some postfix operators.  This is separate because it is not
6776*e4b17023SJohn Marino    possible to tell until after the type name whether a cast
6777*e4b17023SJohn Marino    expression has a cast or a compound literal, or whether the operand
6778*e4b17023SJohn Marino    of sizeof is a parenthesized type name or starts with a compound
6779*e4b17023SJohn Marino    literal.  TYPE_LOC is the location where TYPE_NAME starts--the
6780*e4b17023SJohn Marino    location of the first token after the parentheses around the type
6781*e4b17023SJohn Marino    name.  */
6782*e4b17023SJohn Marino 
6783*e4b17023SJohn Marino static struct c_expr
c_parser_postfix_expression_after_paren_type(c_parser * parser,struct c_type_name * type_name,location_t type_loc)6784*e4b17023SJohn Marino c_parser_postfix_expression_after_paren_type (c_parser *parser,
6785*e4b17023SJohn Marino 					      struct c_type_name *type_name,
6786*e4b17023SJohn Marino 					      location_t type_loc)
6787*e4b17023SJohn Marino {
6788*e4b17023SJohn Marino   tree type;
6789*e4b17023SJohn Marino   struct c_expr init;
6790*e4b17023SJohn Marino   bool non_const;
6791*e4b17023SJohn Marino   struct c_expr expr;
6792*e4b17023SJohn Marino   location_t start_loc;
6793*e4b17023SJohn Marino   tree type_expr = NULL_TREE;
6794*e4b17023SJohn Marino   bool type_expr_const = true;
6795*e4b17023SJohn Marino   check_compound_literal_type (type_loc, type_name);
6796*e4b17023SJohn Marino   start_init (NULL_TREE, NULL, 0);
6797*e4b17023SJohn Marino   type = groktypename (type_name, &type_expr, &type_expr_const);
6798*e4b17023SJohn Marino   start_loc = c_parser_peek_token (parser)->location;
6799*e4b17023SJohn Marino   if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
6800*e4b17023SJohn Marino     {
6801*e4b17023SJohn Marino       error_at (type_loc, "compound literal has variable size");
6802*e4b17023SJohn Marino       type = error_mark_node;
6803*e4b17023SJohn Marino     }
6804*e4b17023SJohn Marino   init = c_parser_braced_init (parser, type, false);
6805*e4b17023SJohn Marino   finish_init ();
6806*e4b17023SJohn Marino   maybe_warn_string_init (type, init);
6807*e4b17023SJohn Marino 
6808*e4b17023SJohn Marino   if (type != error_mark_node
6809*e4b17023SJohn Marino       && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
6810*e4b17023SJohn Marino       && current_function_decl)
6811*e4b17023SJohn Marino     {
6812*e4b17023SJohn Marino       error ("compound literal qualified by address-space qualifier");
6813*e4b17023SJohn Marino       type = error_mark_node;
6814*e4b17023SJohn Marino     }
6815*e4b17023SJohn Marino 
6816*e4b17023SJohn Marino   if (!flag_isoc99)
6817*e4b17023SJohn Marino     pedwarn (start_loc, OPT_pedantic, "ISO C90 forbids compound literals");
6818*e4b17023SJohn Marino   non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
6819*e4b17023SJohn Marino 	       ? CONSTRUCTOR_NON_CONST (init.value)
6820*e4b17023SJohn Marino 	       : init.original_code == C_MAYBE_CONST_EXPR);
6821*e4b17023SJohn Marino   non_const |= !type_expr_const;
6822*e4b17023SJohn Marino   expr.value = build_compound_literal (start_loc, type, init.value, non_const);
6823*e4b17023SJohn Marino   expr.original_code = ERROR_MARK;
6824*e4b17023SJohn Marino   expr.original_type = NULL;
6825*e4b17023SJohn Marino   if (type_expr)
6826*e4b17023SJohn Marino     {
6827*e4b17023SJohn Marino       if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
6828*e4b17023SJohn Marino 	{
6829*e4b17023SJohn Marino 	  gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
6830*e4b17023SJohn Marino 	  C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
6831*e4b17023SJohn Marino 	}
6832*e4b17023SJohn Marino       else
6833*e4b17023SJohn Marino 	{
6834*e4b17023SJohn Marino 	  gcc_assert (!non_const);
6835*e4b17023SJohn Marino 	  expr.value = build2 (C_MAYBE_CONST_EXPR, type,
6836*e4b17023SJohn Marino 			       type_expr, expr.value);
6837*e4b17023SJohn Marino 	}
6838*e4b17023SJohn Marino     }
6839*e4b17023SJohn Marino   return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
6840*e4b17023SJohn Marino }
6841*e4b17023SJohn Marino 
6842*e4b17023SJohn Marino /* Parse a postfix expression after the initial primary or compound
6843*e4b17023SJohn Marino    literal; that is, parse a series of postfix operators.
6844*e4b17023SJohn Marino 
6845*e4b17023SJohn Marino    EXPR_LOC is the location of the primary expression.  */
6846*e4b17023SJohn Marino 
6847*e4b17023SJohn Marino static struct c_expr
c_parser_postfix_expression_after_primary(c_parser * parser,location_t expr_loc,struct c_expr expr)6848*e4b17023SJohn Marino c_parser_postfix_expression_after_primary (c_parser *parser,
6849*e4b17023SJohn Marino 					   location_t expr_loc,
6850*e4b17023SJohn Marino 					   struct c_expr expr)
6851*e4b17023SJohn Marino {
6852*e4b17023SJohn Marino   struct c_expr orig_expr;
6853*e4b17023SJohn Marino   tree ident, idx;
6854*e4b17023SJohn Marino   VEC(tree,gc) *exprlist;
6855*e4b17023SJohn Marino   VEC(tree,gc) *origtypes;
6856*e4b17023SJohn Marino   while (true)
6857*e4b17023SJohn Marino     {
6858*e4b17023SJohn Marino       location_t op_loc = c_parser_peek_token (parser)->location;
6859*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->type)
6860*e4b17023SJohn Marino 	{
6861*e4b17023SJohn Marino 	case CPP_OPEN_SQUARE:
6862*e4b17023SJohn Marino 	  /* Array reference.  */
6863*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6864*e4b17023SJohn Marino 	  idx = c_parser_expression (parser).value;
6865*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6866*e4b17023SJohn Marino 				     "expected %<]%>");
6867*e4b17023SJohn Marino 	  expr.value = build_array_ref (op_loc, expr.value, idx);
6868*e4b17023SJohn Marino 	  expr.original_code = ERROR_MARK;
6869*e4b17023SJohn Marino 	  expr.original_type = NULL;
6870*e4b17023SJohn Marino 	  break;
6871*e4b17023SJohn Marino 	case CPP_OPEN_PAREN:
6872*e4b17023SJohn Marino 	  /* Function call.  */
6873*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6874*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6875*e4b17023SJohn Marino 	    exprlist = NULL;
6876*e4b17023SJohn Marino 	  else
6877*e4b17023SJohn Marino 	    exprlist = c_parser_expr_list (parser, true, false, &origtypes);
6878*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6879*e4b17023SJohn Marino 				     "expected %<)%>");
6880*e4b17023SJohn Marino 	  orig_expr = expr;
6881*e4b17023SJohn Marino 	  mark_exp_read (expr.value);
6882*e4b17023SJohn Marino 	  /* FIXME diagnostics: Ideally we want the FUNCNAME, not the
6883*e4b17023SJohn Marino 	     "(" after the FUNCNAME, which is what we have now.    */
6884*e4b17023SJohn Marino 	  expr.value = build_function_call_vec (op_loc, expr.value, exprlist,
6885*e4b17023SJohn Marino 						origtypes);
6886*e4b17023SJohn Marino 	  expr.original_code = ERROR_MARK;
6887*e4b17023SJohn Marino 	  if (TREE_CODE (expr.value) == INTEGER_CST
6888*e4b17023SJohn Marino 	      && TREE_CODE (orig_expr.value) == FUNCTION_DECL
6889*e4b17023SJohn Marino 	      && DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL
6890*e4b17023SJohn Marino 	      && DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
6891*e4b17023SJohn Marino 	    expr.original_code = C_MAYBE_CONST_EXPR;
6892*e4b17023SJohn Marino 	  expr.original_type = NULL;
6893*e4b17023SJohn Marino 	  if (exprlist != NULL)
6894*e4b17023SJohn Marino 	    {
6895*e4b17023SJohn Marino 	      release_tree_vector (exprlist);
6896*e4b17023SJohn Marino 	      release_tree_vector (origtypes);
6897*e4b17023SJohn Marino 	    }
6898*e4b17023SJohn Marino 	  break;
6899*e4b17023SJohn Marino 	case CPP_DOT:
6900*e4b17023SJohn Marino 	  /* Structure element reference.  */
6901*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6902*e4b17023SJohn Marino 	  expr = default_function_array_conversion (expr_loc, expr);
6903*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_NAME))
6904*e4b17023SJohn Marino 	    ident = c_parser_peek_token (parser)->value;
6905*e4b17023SJohn Marino 	  else
6906*e4b17023SJohn Marino 	    {
6907*e4b17023SJohn Marino 	      c_parser_error (parser, "expected identifier");
6908*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6909*e4b17023SJohn Marino 	      expr.original_code = ERROR_MARK;
6910*e4b17023SJohn Marino               expr.original_type = NULL;
6911*e4b17023SJohn Marino 	      return expr;
6912*e4b17023SJohn Marino 	    }
6913*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6914*e4b17023SJohn Marino 	  expr.value = build_component_ref (op_loc, expr.value, ident);
6915*e4b17023SJohn Marino 	  expr.original_code = ERROR_MARK;
6916*e4b17023SJohn Marino 	  if (TREE_CODE (expr.value) != COMPONENT_REF)
6917*e4b17023SJohn Marino 	    expr.original_type = NULL;
6918*e4b17023SJohn Marino 	  else
6919*e4b17023SJohn Marino 	    {
6920*e4b17023SJohn Marino 	      /* Remember the original type of a bitfield.  */
6921*e4b17023SJohn Marino 	      tree field = TREE_OPERAND (expr.value, 1);
6922*e4b17023SJohn Marino 	      if (TREE_CODE (field) != FIELD_DECL)
6923*e4b17023SJohn Marino 		expr.original_type = NULL;
6924*e4b17023SJohn Marino 	      else
6925*e4b17023SJohn Marino 		expr.original_type = DECL_BIT_FIELD_TYPE (field);
6926*e4b17023SJohn Marino 	    }
6927*e4b17023SJohn Marino 	  break;
6928*e4b17023SJohn Marino 	case CPP_DEREF:
6929*e4b17023SJohn Marino 	  /* Structure element reference.  */
6930*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6931*e4b17023SJohn Marino 	  expr = default_function_array_conversion (expr_loc, expr);
6932*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_NAME))
6933*e4b17023SJohn Marino 	    ident = c_parser_peek_token (parser)->value;
6934*e4b17023SJohn Marino 	  else
6935*e4b17023SJohn Marino 	    {
6936*e4b17023SJohn Marino 	      c_parser_error (parser, "expected identifier");
6937*e4b17023SJohn Marino 	      expr.value = error_mark_node;
6938*e4b17023SJohn Marino 	      expr.original_code = ERROR_MARK;
6939*e4b17023SJohn Marino 	      expr.original_type = NULL;
6940*e4b17023SJohn Marino 	      return expr;
6941*e4b17023SJohn Marino 	    }
6942*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6943*e4b17023SJohn Marino 	  expr.value = build_component_ref (op_loc,
6944*e4b17023SJohn Marino 					    build_indirect_ref (op_loc,
6945*e4b17023SJohn Marino 								expr.value,
6946*e4b17023SJohn Marino 								RO_ARROW),
6947*e4b17023SJohn Marino 					    ident);
6948*e4b17023SJohn Marino 	  expr.original_code = ERROR_MARK;
6949*e4b17023SJohn Marino 	  if (TREE_CODE (expr.value) != COMPONENT_REF)
6950*e4b17023SJohn Marino 	    expr.original_type = NULL;
6951*e4b17023SJohn Marino 	  else
6952*e4b17023SJohn Marino 	    {
6953*e4b17023SJohn Marino 	      /* Remember the original type of a bitfield.  */
6954*e4b17023SJohn Marino 	      tree field = TREE_OPERAND (expr.value, 1);
6955*e4b17023SJohn Marino 	      if (TREE_CODE (field) != FIELD_DECL)
6956*e4b17023SJohn Marino 		expr.original_type = NULL;
6957*e4b17023SJohn Marino 	      else
6958*e4b17023SJohn Marino 		expr.original_type = DECL_BIT_FIELD_TYPE (field);
6959*e4b17023SJohn Marino 	    }
6960*e4b17023SJohn Marino 	  break;
6961*e4b17023SJohn Marino 	case CPP_PLUS_PLUS:
6962*e4b17023SJohn Marino 	  /* Postincrement.  */
6963*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6964*e4b17023SJohn Marino 	  expr = default_function_array_read_conversion (expr_loc, expr);
6965*e4b17023SJohn Marino 	  expr.value = build_unary_op (op_loc,
6966*e4b17023SJohn Marino 				       POSTINCREMENT_EXPR, expr.value, 0);
6967*e4b17023SJohn Marino 	  expr.original_code = ERROR_MARK;
6968*e4b17023SJohn Marino 	  expr.original_type = NULL;
6969*e4b17023SJohn Marino 	  break;
6970*e4b17023SJohn Marino 	case CPP_MINUS_MINUS:
6971*e4b17023SJohn Marino 	  /* Postdecrement.  */
6972*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
6973*e4b17023SJohn Marino 	  expr = default_function_array_read_conversion (expr_loc, expr);
6974*e4b17023SJohn Marino 	  expr.value = build_unary_op (op_loc,
6975*e4b17023SJohn Marino 				       POSTDECREMENT_EXPR, expr.value, 0);
6976*e4b17023SJohn Marino 	  expr.original_code = ERROR_MARK;
6977*e4b17023SJohn Marino 	  expr.original_type = NULL;
6978*e4b17023SJohn Marino 	  break;
6979*e4b17023SJohn Marino 	default:
6980*e4b17023SJohn Marino 	  return expr;
6981*e4b17023SJohn Marino 	}
6982*e4b17023SJohn Marino     }
6983*e4b17023SJohn Marino }
6984*e4b17023SJohn Marino 
6985*e4b17023SJohn Marino /* Parse an expression (C90 6.3.17, C99 6.5.17).
6986*e4b17023SJohn Marino 
6987*e4b17023SJohn Marino    expression:
6988*e4b17023SJohn Marino      assignment-expression
6989*e4b17023SJohn Marino      expression , assignment-expression
6990*e4b17023SJohn Marino */
6991*e4b17023SJohn Marino 
6992*e4b17023SJohn Marino static struct c_expr
c_parser_expression(c_parser * parser)6993*e4b17023SJohn Marino c_parser_expression (c_parser *parser)
6994*e4b17023SJohn Marino {
6995*e4b17023SJohn Marino   struct c_expr expr;
6996*e4b17023SJohn Marino   expr = c_parser_expr_no_commas (parser, NULL);
6997*e4b17023SJohn Marino   while (c_parser_next_token_is (parser, CPP_COMMA))
6998*e4b17023SJohn Marino     {
6999*e4b17023SJohn Marino       struct c_expr next;
7000*e4b17023SJohn Marino       tree lhsval;
7001*e4b17023SJohn Marino       location_t loc = c_parser_peek_token (parser)->location;
7002*e4b17023SJohn Marino       location_t expr_loc;
7003*e4b17023SJohn Marino       c_parser_consume_token (parser);
7004*e4b17023SJohn Marino       expr_loc = c_parser_peek_token (parser)->location;
7005*e4b17023SJohn Marino       lhsval = expr.value;
7006*e4b17023SJohn Marino       while (TREE_CODE (lhsval) == COMPOUND_EXPR)
7007*e4b17023SJohn Marino 	lhsval = TREE_OPERAND (lhsval, 1);
7008*e4b17023SJohn Marino       if (DECL_P (lhsval) || handled_component_p (lhsval))
7009*e4b17023SJohn Marino 	mark_exp_read (lhsval);
7010*e4b17023SJohn Marino       next = c_parser_expr_no_commas (parser, NULL);
7011*e4b17023SJohn Marino       next = default_function_array_conversion (expr_loc, next);
7012*e4b17023SJohn Marino       expr.value = build_compound_expr (loc, expr.value, next.value);
7013*e4b17023SJohn Marino       expr.original_code = COMPOUND_EXPR;
7014*e4b17023SJohn Marino       expr.original_type = next.original_type;
7015*e4b17023SJohn Marino     }
7016*e4b17023SJohn Marino   return expr;
7017*e4b17023SJohn Marino }
7018*e4b17023SJohn Marino 
7019*e4b17023SJohn Marino /* Parse an expression and convert functions or arrays to
7020*e4b17023SJohn Marino    pointers.  */
7021*e4b17023SJohn Marino 
7022*e4b17023SJohn Marino static struct c_expr
c_parser_expression_conv(c_parser * parser)7023*e4b17023SJohn Marino c_parser_expression_conv (c_parser *parser)
7024*e4b17023SJohn Marino {
7025*e4b17023SJohn Marino   struct c_expr expr;
7026*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
7027*e4b17023SJohn Marino   expr = c_parser_expression (parser);
7028*e4b17023SJohn Marino   expr = default_function_array_conversion (loc, expr);
7029*e4b17023SJohn Marino   return expr;
7030*e4b17023SJohn Marino }
7031*e4b17023SJohn Marino 
7032*e4b17023SJohn Marino /* Parse a non-empty list of expressions.  If CONVERT_P, convert
7033*e4b17023SJohn Marino    functions and arrays to pointers.  If FOLD_P, fold the expressions.
7034*e4b17023SJohn Marino 
7035*e4b17023SJohn Marino    nonempty-expr-list:
7036*e4b17023SJohn Marino      assignment-expression
7037*e4b17023SJohn Marino      nonempty-expr-list , assignment-expression
7038*e4b17023SJohn Marino */
7039*e4b17023SJohn Marino 
VEC(tree,gc)7040*e4b17023SJohn Marino static VEC(tree,gc) *
7041*e4b17023SJohn Marino c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
7042*e4b17023SJohn Marino 		    VEC(tree,gc) **p_orig_types)
7043*e4b17023SJohn Marino {
7044*e4b17023SJohn Marino   VEC(tree,gc) *ret;
7045*e4b17023SJohn Marino   VEC(tree,gc) *orig_types;
7046*e4b17023SJohn Marino   struct c_expr expr;
7047*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
7048*e4b17023SJohn Marino 
7049*e4b17023SJohn Marino   ret = make_tree_vector ();
7050*e4b17023SJohn Marino   if (p_orig_types == NULL)
7051*e4b17023SJohn Marino     orig_types = NULL;
7052*e4b17023SJohn Marino   else
7053*e4b17023SJohn Marino     orig_types = make_tree_vector ();
7054*e4b17023SJohn Marino 
7055*e4b17023SJohn Marino   expr = c_parser_expr_no_commas (parser, NULL);
7056*e4b17023SJohn Marino   if (convert_p)
7057*e4b17023SJohn Marino     expr = default_function_array_read_conversion (loc, expr);
7058*e4b17023SJohn Marino   if (fold_p)
7059*e4b17023SJohn Marino     expr.value = c_fully_fold (expr.value, false, NULL);
7060*e4b17023SJohn Marino   VEC_quick_push (tree, ret, expr.value);
7061*e4b17023SJohn Marino   if (orig_types != NULL)
7062*e4b17023SJohn Marino     VEC_quick_push (tree, orig_types, expr.original_type);
7063*e4b17023SJohn Marino   while (c_parser_next_token_is (parser, CPP_COMMA))
7064*e4b17023SJohn Marino     {
7065*e4b17023SJohn Marino       c_parser_consume_token (parser);
7066*e4b17023SJohn Marino       loc = c_parser_peek_token (parser)->location;
7067*e4b17023SJohn Marino       expr = c_parser_expr_no_commas (parser, NULL);
7068*e4b17023SJohn Marino       if (convert_p)
7069*e4b17023SJohn Marino 	expr = default_function_array_read_conversion (loc, expr);
7070*e4b17023SJohn Marino       if (fold_p)
7071*e4b17023SJohn Marino 	expr.value = c_fully_fold (expr.value, false, NULL);
7072*e4b17023SJohn Marino       VEC_safe_push (tree, gc, ret, expr.value);
7073*e4b17023SJohn Marino       if (orig_types != NULL)
7074*e4b17023SJohn Marino 	VEC_safe_push (tree, gc, orig_types, expr.original_type);
7075*e4b17023SJohn Marino     }
7076*e4b17023SJohn Marino   if (orig_types != NULL)
7077*e4b17023SJohn Marino     *p_orig_types = orig_types;
7078*e4b17023SJohn Marino   return ret;
7079*e4b17023SJohn Marino }
7080*e4b17023SJohn Marino 
7081*e4b17023SJohn Marino /* Parse Objective-C-specific constructs.  */
7082*e4b17023SJohn Marino 
7083*e4b17023SJohn Marino /* Parse an objc-class-definition.
7084*e4b17023SJohn Marino 
7085*e4b17023SJohn Marino    objc-class-definition:
7086*e4b17023SJohn Marino      @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
7087*e4b17023SJohn Marino        objc-class-instance-variables[opt] objc-methodprotolist @end
7088*e4b17023SJohn Marino      @implementation identifier objc-superclass[opt]
7089*e4b17023SJohn Marino        objc-class-instance-variables[opt]
7090*e4b17023SJohn Marino      @interface identifier ( identifier ) objc-protocol-refs[opt]
7091*e4b17023SJohn Marino        objc-methodprotolist @end
7092*e4b17023SJohn Marino      @interface identifier ( ) objc-protocol-refs[opt]
7093*e4b17023SJohn Marino        objc-methodprotolist @end
7094*e4b17023SJohn Marino      @implementation identifier ( identifier )
7095*e4b17023SJohn Marino 
7096*e4b17023SJohn Marino    objc-superclass:
7097*e4b17023SJohn Marino      : identifier
7098*e4b17023SJohn Marino 
7099*e4b17023SJohn Marino    "@interface identifier (" must start "@interface identifier (
7100*e4b17023SJohn Marino    identifier ) ...": objc-methodprotolist in the first production may
7101*e4b17023SJohn Marino    not start with a parenthesized identifier as a declarator of a data
7102*e4b17023SJohn Marino    definition with no declaration specifiers if the objc-superclass,
7103*e4b17023SJohn Marino    objc-protocol-refs and objc-class-instance-variables are omitted.  */
7104*e4b17023SJohn Marino 
7105*e4b17023SJohn Marino static void
c_parser_objc_class_definition(c_parser * parser,tree attributes)7106*e4b17023SJohn Marino c_parser_objc_class_definition (c_parser *parser, tree attributes)
7107*e4b17023SJohn Marino {
7108*e4b17023SJohn Marino   bool iface_p;
7109*e4b17023SJohn Marino   tree id1;
7110*e4b17023SJohn Marino   tree superclass;
7111*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
7112*e4b17023SJohn Marino     iface_p = true;
7113*e4b17023SJohn Marino   else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
7114*e4b17023SJohn Marino     iface_p = false;
7115*e4b17023SJohn Marino   else
7116*e4b17023SJohn Marino     gcc_unreachable ();
7117*e4b17023SJohn Marino 
7118*e4b17023SJohn Marino   c_parser_consume_token (parser);
7119*e4b17023SJohn Marino   if (c_parser_next_token_is_not (parser, CPP_NAME))
7120*e4b17023SJohn Marino     {
7121*e4b17023SJohn Marino       c_parser_error (parser, "expected identifier");
7122*e4b17023SJohn Marino       return;
7123*e4b17023SJohn Marino     }
7124*e4b17023SJohn Marino   id1 = c_parser_peek_token (parser)->value;
7125*e4b17023SJohn Marino   c_parser_consume_token (parser);
7126*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
7127*e4b17023SJohn Marino     {
7128*e4b17023SJohn Marino       /* We have a category or class extension.  */
7129*e4b17023SJohn Marino       tree id2;
7130*e4b17023SJohn Marino       tree proto = NULL_TREE;
7131*e4b17023SJohn Marino       c_parser_consume_token (parser);
7132*e4b17023SJohn Marino       if (c_parser_next_token_is_not (parser, CPP_NAME))
7133*e4b17023SJohn Marino 	{
7134*e4b17023SJohn Marino 	  if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7135*e4b17023SJohn Marino 	    {
7136*e4b17023SJohn Marino 	      /* We have a class extension.  */
7137*e4b17023SJohn Marino 	      id2 = NULL_TREE;
7138*e4b17023SJohn Marino 	    }
7139*e4b17023SJohn Marino 	  else
7140*e4b17023SJohn Marino 	    {
7141*e4b17023SJohn Marino 	      c_parser_error (parser, "expected identifier or %<)%>");
7142*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7143*e4b17023SJohn Marino 	      return;
7144*e4b17023SJohn Marino 	    }
7145*e4b17023SJohn Marino 	}
7146*e4b17023SJohn Marino       else
7147*e4b17023SJohn Marino 	{
7148*e4b17023SJohn Marino 	  id2 = c_parser_peek_token (parser)->value;
7149*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7150*e4b17023SJohn Marino 	}
7151*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7152*e4b17023SJohn Marino       if (!iface_p)
7153*e4b17023SJohn Marino 	{
7154*e4b17023SJohn Marino 	  objc_start_category_implementation (id1, id2);
7155*e4b17023SJohn Marino 	  return;
7156*e4b17023SJohn Marino 	}
7157*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_LESS))
7158*e4b17023SJohn Marino 	proto = c_parser_objc_protocol_refs (parser);
7159*e4b17023SJohn Marino       objc_start_category_interface (id1, id2, proto, attributes);
7160*e4b17023SJohn Marino       c_parser_objc_methodprotolist (parser);
7161*e4b17023SJohn Marino       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
7162*e4b17023SJohn Marino       objc_finish_interface ();
7163*e4b17023SJohn Marino       return;
7164*e4b17023SJohn Marino     }
7165*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_COLON))
7166*e4b17023SJohn Marino     {
7167*e4b17023SJohn Marino       c_parser_consume_token (parser);
7168*e4b17023SJohn Marino       if (c_parser_next_token_is_not (parser, CPP_NAME))
7169*e4b17023SJohn Marino 	{
7170*e4b17023SJohn Marino 	  c_parser_error (parser, "expected identifier");
7171*e4b17023SJohn Marino 	  return;
7172*e4b17023SJohn Marino 	}
7173*e4b17023SJohn Marino       superclass = c_parser_peek_token (parser)->value;
7174*e4b17023SJohn Marino       c_parser_consume_token (parser);
7175*e4b17023SJohn Marino     }
7176*e4b17023SJohn Marino   else
7177*e4b17023SJohn Marino     superclass = NULL_TREE;
7178*e4b17023SJohn Marino   if (iface_p)
7179*e4b17023SJohn Marino     {
7180*e4b17023SJohn Marino       tree proto = NULL_TREE;
7181*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_LESS))
7182*e4b17023SJohn Marino 	proto = c_parser_objc_protocol_refs (parser);
7183*e4b17023SJohn Marino       objc_start_class_interface (id1, superclass, proto, attributes);
7184*e4b17023SJohn Marino     }
7185*e4b17023SJohn Marino   else
7186*e4b17023SJohn Marino     objc_start_class_implementation (id1, superclass);
7187*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7188*e4b17023SJohn Marino     c_parser_objc_class_instance_variables (parser);
7189*e4b17023SJohn Marino   if (iface_p)
7190*e4b17023SJohn Marino     {
7191*e4b17023SJohn Marino       objc_continue_interface ();
7192*e4b17023SJohn Marino       c_parser_objc_methodprotolist (parser);
7193*e4b17023SJohn Marino       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
7194*e4b17023SJohn Marino       objc_finish_interface ();
7195*e4b17023SJohn Marino     }
7196*e4b17023SJohn Marino   else
7197*e4b17023SJohn Marino     {
7198*e4b17023SJohn Marino       objc_continue_implementation ();
7199*e4b17023SJohn Marino       return;
7200*e4b17023SJohn Marino     }
7201*e4b17023SJohn Marino }
7202*e4b17023SJohn Marino 
7203*e4b17023SJohn Marino /* Parse objc-class-instance-variables.
7204*e4b17023SJohn Marino 
7205*e4b17023SJohn Marino    objc-class-instance-variables:
7206*e4b17023SJohn Marino      { objc-instance-variable-decl-list[opt] }
7207*e4b17023SJohn Marino 
7208*e4b17023SJohn Marino    objc-instance-variable-decl-list:
7209*e4b17023SJohn Marino      objc-visibility-spec
7210*e4b17023SJohn Marino      objc-instance-variable-decl ;
7211*e4b17023SJohn Marino      ;
7212*e4b17023SJohn Marino      objc-instance-variable-decl-list objc-visibility-spec
7213*e4b17023SJohn Marino      objc-instance-variable-decl-list objc-instance-variable-decl ;
7214*e4b17023SJohn Marino      objc-instance-variable-decl-list ;
7215*e4b17023SJohn Marino 
7216*e4b17023SJohn Marino    objc-visibility-spec:
7217*e4b17023SJohn Marino      @private
7218*e4b17023SJohn Marino      @protected
7219*e4b17023SJohn Marino      @public
7220*e4b17023SJohn Marino 
7221*e4b17023SJohn Marino    objc-instance-variable-decl:
7222*e4b17023SJohn Marino      struct-declaration
7223*e4b17023SJohn Marino */
7224*e4b17023SJohn Marino 
7225*e4b17023SJohn Marino static void
c_parser_objc_class_instance_variables(c_parser * parser)7226*e4b17023SJohn Marino c_parser_objc_class_instance_variables (c_parser *parser)
7227*e4b17023SJohn Marino {
7228*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
7229*e4b17023SJohn Marino   c_parser_consume_token (parser);
7230*e4b17023SJohn Marino   while (c_parser_next_token_is_not (parser, CPP_EOF))
7231*e4b17023SJohn Marino     {
7232*e4b17023SJohn Marino       tree decls;
7233*e4b17023SJohn Marino       /* Parse any stray semicolon.  */
7234*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7235*e4b17023SJohn Marino 	{
7236*e4b17023SJohn Marino 	  pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
7237*e4b17023SJohn Marino 		   "extra semicolon");
7238*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7239*e4b17023SJohn Marino 	  continue;
7240*e4b17023SJohn Marino 	}
7241*e4b17023SJohn Marino       /* Stop if at the end of the instance variables.  */
7242*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
7243*e4b17023SJohn Marino 	{
7244*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7245*e4b17023SJohn Marino 	  break;
7246*e4b17023SJohn Marino 	}
7247*e4b17023SJohn Marino       /* Parse any objc-visibility-spec.  */
7248*e4b17023SJohn Marino       if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
7249*e4b17023SJohn Marino 	{
7250*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7251*e4b17023SJohn Marino 	  objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
7252*e4b17023SJohn Marino 	  continue;
7253*e4b17023SJohn Marino 	}
7254*e4b17023SJohn Marino       else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
7255*e4b17023SJohn Marino 	{
7256*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7257*e4b17023SJohn Marino 	  objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
7258*e4b17023SJohn Marino 	  continue;
7259*e4b17023SJohn Marino 	}
7260*e4b17023SJohn Marino       else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
7261*e4b17023SJohn Marino 	{
7262*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7263*e4b17023SJohn Marino 	  objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
7264*e4b17023SJohn Marino 	  continue;
7265*e4b17023SJohn Marino 	}
7266*e4b17023SJohn Marino       else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
7267*e4b17023SJohn Marino 	{
7268*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7269*e4b17023SJohn Marino 	  objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
7270*e4b17023SJohn Marino 	  continue;
7271*e4b17023SJohn Marino 	}
7272*e4b17023SJohn Marino       else if (c_parser_next_token_is (parser, CPP_PRAGMA))
7273*e4b17023SJohn Marino 	{
7274*e4b17023SJohn Marino 	  c_parser_pragma (parser, pragma_external);
7275*e4b17023SJohn Marino 	  continue;
7276*e4b17023SJohn Marino 	}
7277*e4b17023SJohn Marino 
7278*e4b17023SJohn Marino       /* Parse some comma-separated declarations.  */
7279*e4b17023SJohn Marino       decls = c_parser_struct_declaration (parser);
7280*e4b17023SJohn Marino       if (decls == NULL)
7281*e4b17023SJohn Marino 	{
7282*e4b17023SJohn Marino 	  /* There is a syntax error.  We want to skip the offending
7283*e4b17023SJohn Marino 	     tokens up to the next ';' (included) or '}'
7284*e4b17023SJohn Marino 	     (excluded).  */
7285*e4b17023SJohn Marino 
7286*e4b17023SJohn Marino 	  /* First, skip manually a ')' or ']'.  This is because they
7287*e4b17023SJohn Marino 	     reduce the nesting level, so c_parser_skip_until_found()
7288*e4b17023SJohn Marino 	     wouldn't be able to skip past them.  */
7289*e4b17023SJohn Marino 	  c_token *token = c_parser_peek_token (parser);
7290*e4b17023SJohn Marino 	  if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
7291*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
7292*e4b17023SJohn Marino 
7293*e4b17023SJohn Marino 	  /* Then, do the standard skipping.  */
7294*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
7295*e4b17023SJohn Marino 
7296*e4b17023SJohn Marino 	  /* We hopefully recovered.  Start normal parsing again.  */
7297*e4b17023SJohn Marino 	  parser->error = false;
7298*e4b17023SJohn Marino 	  continue;
7299*e4b17023SJohn Marino 	}
7300*e4b17023SJohn Marino       else
7301*e4b17023SJohn Marino 	{
7302*e4b17023SJohn Marino 	  /* Comma-separated instance variables are chained together
7303*e4b17023SJohn Marino 	     in reverse order; add them one by one.  */
7304*e4b17023SJohn Marino 	  tree ivar = nreverse (decls);
7305*e4b17023SJohn Marino 	  for (; ivar; ivar = DECL_CHAIN (ivar))
7306*e4b17023SJohn Marino 	    objc_add_instance_variable (copy_node (ivar));
7307*e4b17023SJohn Marino 	}
7308*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7309*e4b17023SJohn Marino     }
7310*e4b17023SJohn Marino }
7311*e4b17023SJohn Marino 
7312*e4b17023SJohn Marino /* Parse an objc-class-declaration.
7313*e4b17023SJohn Marino 
7314*e4b17023SJohn Marino    objc-class-declaration:
7315*e4b17023SJohn Marino      @class identifier-list ;
7316*e4b17023SJohn Marino */
7317*e4b17023SJohn Marino 
7318*e4b17023SJohn Marino static void
c_parser_objc_class_declaration(c_parser * parser)7319*e4b17023SJohn Marino c_parser_objc_class_declaration (c_parser *parser)
7320*e4b17023SJohn Marino {
7321*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
7322*e4b17023SJohn Marino   c_parser_consume_token (parser);
7323*e4b17023SJohn Marino   /* Any identifiers, including those declared as type names, are OK
7324*e4b17023SJohn Marino      here.  */
7325*e4b17023SJohn Marino   while (true)
7326*e4b17023SJohn Marino     {
7327*e4b17023SJohn Marino       tree id;
7328*e4b17023SJohn Marino       if (c_parser_next_token_is_not (parser, CPP_NAME))
7329*e4b17023SJohn Marino 	{
7330*e4b17023SJohn Marino 	  c_parser_error (parser, "expected identifier");
7331*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
7332*e4b17023SJohn Marino 	  parser->error = false;
7333*e4b17023SJohn Marino 	  return;
7334*e4b17023SJohn Marino 	}
7335*e4b17023SJohn Marino       id = c_parser_peek_token (parser)->value;
7336*e4b17023SJohn Marino       objc_declare_class (id);
7337*e4b17023SJohn Marino       c_parser_consume_token (parser);
7338*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_COMMA))
7339*e4b17023SJohn Marino 	c_parser_consume_token (parser);
7340*e4b17023SJohn Marino       else
7341*e4b17023SJohn Marino 	break;
7342*e4b17023SJohn Marino     }
7343*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7344*e4b17023SJohn Marino }
7345*e4b17023SJohn Marino 
7346*e4b17023SJohn Marino /* Parse an objc-alias-declaration.
7347*e4b17023SJohn Marino 
7348*e4b17023SJohn Marino    objc-alias-declaration:
7349*e4b17023SJohn Marino      @compatibility_alias identifier identifier ;
7350*e4b17023SJohn Marino */
7351*e4b17023SJohn Marino 
7352*e4b17023SJohn Marino static void
c_parser_objc_alias_declaration(c_parser * parser)7353*e4b17023SJohn Marino c_parser_objc_alias_declaration (c_parser *parser)
7354*e4b17023SJohn Marino {
7355*e4b17023SJohn Marino   tree id1, id2;
7356*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
7357*e4b17023SJohn Marino   c_parser_consume_token (parser);
7358*e4b17023SJohn Marino   if (c_parser_next_token_is_not (parser, CPP_NAME))
7359*e4b17023SJohn Marino     {
7360*e4b17023SJohn Marino       c_parser_error (parser, "expected identifier");
7361*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
7362*e4b17023SJohn Marino       return;
7363*e4b17023SJohn Marino     }
7364*e4b17023SJohn Marino   id1 = c_parser_peek_token (parser)->value;
7365*e4b17023SJohn Marino   c_parser_consume_token (parser);
7366*e4b17023SJohn Marino   if (c_parser_next_token_is_not (parser, CPP_NAME))
7367*e4b17023SJohn Marino     {
7368*e4b17023SJohn Marino       c_parser_error (parser, "expected identifier");
7369*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
7370*e4b17023SJohn Marino       return;
7371*e4b17023SJohn Marino     }
7372*e4b17023SJohn Marino   id2 = c_parser_peek_token (parser)->value;
7373*e4b17023SJohn Marino   c_parser_consume_token (parser);
7374*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7375*e4b17023SJohn Marino   objc_declare_alias (id1, id2);
7376*e4b17023SJohn Marino }
7377*e4b17023SJohn Marino 
7378*e4b17023SJohn Marino /* Parse an objc-protocol-definition.
7379*e4b17023SJohn Marino 
7380*e4b17023SJohn Marino    objc-protocol-definition:
7381*e4b17023SJohn Marino      @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
7382*e4b17023SJohn Marino      @protocol identifier-list ;
7383*e4b17023SJohn Marino 
7384*e4b17023SJohn Marino    "@protocol identifier ;" should be resolved as "@protocol
7385*e4b17023SJohn Marino    identifier-list ;": objc-methodprotolist may not start with a
7386*e4b17023SJohn Marino    semicolon in the first alternative if objc-protocol-refs are
7387*e4b17023SJohn Marino    omitted.  */
7388*e4b17023SJohn Marino 
7389*e4b17023SJohn Marino static void
c_parser_objc_protocol_definition(c_parser * parser,tree attributes)7390*e4b17023SJohn Marino c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
7391*e4b17023SJohn Marino {
7392*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
7393*e4b17023SJohn Marino 
7394*e4b17023SJohn Marino   c_parser_consume_token (parser);
7395*e4b17023SJohn Marino   if (c_parser_next_token_is_not (parser, CPP_NAME))
7396*e4b17023SJohn Marino     {
7397*e4b17023SJohn Marino       c_parser_error (parser, "expected identifier");
7398*e4b17023SJohn Marino       return;
7399*e4b17023SJohn Marino     }
7400*e4b17023SJohn Marino   if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
7401*e4b17023SJohn Marino       || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
7402*e4b17023SJohn Marino     {
7403*e4b17023SJohn Marino       /* Any identifiers, including those declared as type names, are
7404*e4b17023SJohn Marino 	 OK here.  */
7405*e4b17023SJohn Marino       while (true)
7406*e4b17023SJohn Marino 	{
7407*e4b17023SJohn Marino 	  tree id;
7408*e4b17023SJohn Marino 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
7409*e4b17023SJohn Marino 	    {
7410*e4b17023SJohn Marino 	      c_parser_error (parser, "expected identifier");
7411*e4b17023SJohn Marino 	      break;
7412*e4b17023SJohn Marino 	    }
7413*e4b17023SJohn Marino 	  id = c_parser_peek_token (parser)->value;
7414*e4b17023SJohn Marino 	  objc_declare_protocol (id, attributes);
7415*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7416*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_COMMA))
7417*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
7418*e4b17023SJohn Marino 	  else
7419*e4b17023SJohn Marino 	    break;
7420*e4b17023SJohn Marino 	}
7421*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7422*e4b17023SJohn Marino     }
7423*e4b17023SJohn Marino   else
7424*e4b17023SJohn Marino     {
7425*e4b17023SJohn Marino       tree id = c_parser_peek_token (parser)->value;
7426*e4b17023SJohn Marino       tree proto = NULL_TREE;
7427*e4b17023SJohn Marino       c_parser_consume_token (parser);
7428*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_LESS))
7429*e4b17023SJohn Marino 	proto = c_parser_objc_protocol_refs (parser);
7430*e4b17023SJohn Marino       parser->objc_pq_context = true;
7431*e4b17023SJohn Marino       objc_start_protocol (id, proto, attributes);
7432*e4b17023SJohn Marino       c_parser_objc_methodprotolist (parser);
7433*e4b17023SJohn Marino       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
7434*e4b17023SJohn Marino       parser->objc_pq_context = false;
7435*e4b17023SJohn Marino       objc_finish_interface ();
7436*e4b17023SJohn Marino     }
7437*e4b17023SJohn Marino }
7438*e4b17023SJohn Marino 
7439*e4b17023SJohn Marino /* Parse an objc-method-type.
7440*e4b17023SJohn Marino 
7441*e4b17023SJohn Marino    objc-method-type:
7442*e4b17023SJohn Marino      +
7443*e4b17023SJohn Marino      -
7444*e4b17023SJohn Marino 
7445*e4b17023SJohn Marino    Return true if it is a class method (+) and false if it is
7446*e4b17023SJohn Marino    an instance method (-).
7447*e4b17023SJohn Marino */
7448*e4b17023SJohn Marino static inline bool
c_parser_objc_method_type(c_parser * parser)7449*e4b17023SJohn Marino c_parser_objc_method_type (c_parser *parser)
7450*e4b17023SJohn Marino {
7451*e4b17023SJohn Marino   switch (c_parser_peek_token (parser)->type)
7452*e4b17023SJohn Marino     {
7453*e4b17023SJohn Marino     case CPP_PLUS:
7454*e4b17023SJohn Marino       c_parser_consume_token (parser);
7455*e4b17023SJohn Marino       return true;
7456*e4b17023SJohn Marino     case CPP_MINUS:
7457*e4b17023SJohn Marino       c_parser_consume_token (parser);
7458*e4b17023SJohn Marino       return false;
7459*e4b17023SJohn Marino     default:
7460*e4b17023SJohn Marino       gcc_unreachable ();
7461*e4b17023SJohn Marino     }
7462*e4b17023SJohn Marino }
7463*e4b17023SJohn Marino 
7464*e4b17023SJohn Marino /* Parse an objc-method-definition.
7465*e4b17023SJohn Marino 
7466*e4b17023SJohn Marino    objc-method-definition:
7467*e4b17023SJohn Marino      objc-method-type objc-method-decl ;[opt] compound-statement
7468*e4b17023SJohn Marino */
7469*e4b17023SJohn Marino 
7470*e4b17023SJohn Marino static void
c_parser_objc_method_definition(c_parser * parser)7471*e4b17023SJohn Marino c_parser_objc_method_definition (c_parser *parser)
7472*e4b17023SJohn Marino {
7473*e4b17023SJohn Marino   bool is_class_method = c_parser_objc_method_type (parser);
7474*e4b17023SJohn Marino   tree decl, attributes = NULL_TREE, expr = NULL_TREE;
7475*e4b17023SJohn Marino   parser->objc_pq_context = true;
7476*e4b17023SJohn Marino   decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
7477*e4b17023SJohn Marino 				    &expr);
7478*e4b17023SJohn Marino   if (decl == error_mark_node)
7479*e4b17023SJohn Marino     return;  /* Bail here. */
7480*e4b17023SJohn Marino 
7481*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7482*e4b17023SJohn Marino     {
7483*e4b17023SJohn Marino       c_parser_consume_token (parser);
7484*e4b17023SJohn Marino       pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
7485*e4b17023SJohn Marino 	       "extra semicolon in method definition specified");
7486*e4b17023SJohn Marino     }
7487*e4b17023SJohn Marino 
7488*e4b17023SJohn Marino   if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7489*e4b17023SJohn Marino     {
7490*e4b17023SJohn Marino       c_parser_error (parser, "expected %<{%>");
7491*e4b17023SJohn Marino       return;
7492*e4b17023SJohn Marino     }
7493*e4b17023SJohn Marino 
7494*e4b17023SJohn Marino   parser->objc_pq_context = false;
7495*e4b17023SJohn Marino   if (objc_start_method_definition (is_class_method, decl, attributes, expr))
7496*e4b17023SJohn Marino     {
7497*e4b17023SJohn Marino       add_stmt (c_parser_compound_statement (parser));
7498*e4b17023SJohn Marino       objc_finish_method_definition (current_function_decl);
7499*e4b17023SJohn Marino     }
7500*e4b17023SJohn Marino   else
7501*e4b17023SJohn Marino     {
7502*e4b17023SJohn Marino       /* This code is executed when we find a method definition
7503*e4b17023SJohn Marino 	 outside of an @implementation context (or invalid for other
7504*e4b17023SJohn Marino 	 reasons).  Parse the method (to keep going) but do not emit
7505*e4b17023SJohn Marino 	 any code.
7506*e4b17023SJohn Marino       */
7507*e4b17023SJohn Marino       c_parser_compound_statement (parser);
7508*e4b17023SJohn Marino     }
7509*e4b17023SJohn Marino }
7510*e4b17023SJohn Marino 
7511*e4b17023SJohn Marino /* Parse an objc-methodprotolist.
7512*e4b17023SJohn Marino 
7513*e4b17023SJohn Marino    objc-methodprotolist:
7514*e4b17023SJohn Marino      empty
7515*e4b17023SJohn Marino      objc-methodprotolist objc-methodproto
7516*e4b17023SJohn Marino      objc-methodprotolist declaration
7517*e4b17023SJohn Marino      objc-methodprotolist ;
7518*e4b17023SJohn Marino      @optional
7519*e4b17023SJohn Marino      @required
7520*e4b17023SJohn Marino 
7521*e4b17023SJohn Marino    The declaration is a data definition, which may be missing
7522*e4b17023SJohn Marino    declaration specifiers under the same rules and diagnostics as
7523*e4b17023SJohn Marino    other data definitions outside functions, and the stray semicolon
7524*e4b17023SJohn Marino    is diagnosed the same way as a stray semicolon outside a
7525*e4b17023SJohn Marino    function.  */
7526*e4b17023SJohn Marino 
7527*e4b17023SJohn Marino static void
c_parser_objc_methodprotolist(c_parser * parser)7528*e4b17023SJohn Marino c_parser_objc_methodprotolist (c_parser *parser)
7529*e4b17023SJohn Marino {
7530*e4b17023SJohn Marino   while (true)
7531*e4b17023SJohn Marino     {
7532*e4b17023SJohn Marino       /* The list is terminated by @end.  */
7533*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->type)
7534*e4b17023SJohn Marino 	{
7535*e4b17023SJohn Marino 	case CPP_SEMICOLON:
7536*e4b17023SJohn Marino 	  pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
7537*e4b17023SJohn Marino 		   "ISO C does not allow extra %<;%> outside of a function");
7538*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7539*e4b17023SJohn Marino 	  break;
7540*e4b17023SJohn Marino 	case CPP_PLUS:
7541*e4b17023SJohn Marino 	case CPP_MINUS:
7542*e4b17023SJohn Marino 	  c_parser_objc_methodproto (parser);
7543*e4b17023SJohn Marino 	  break;
7544*e4b17023SJohn Marino 	case CPP_PRAGMA:
7545*e4b17023SJohn Marino 	  c_parser_pragma (parser, pragma_external);
7546*e4b17023SJohn Marino 	  break;
7547*e4b17023SJohn Marino 	case CPP_EOF:
7548*e4b17023SJohn Marino 	  return;
7549*e4b17023SJohn Marino 	default:
7550*e4b17023SJohn Marino 	  if (c_parser_next_token_is_keyword (parser, RID_AT_END))
7551*e4b17023SJohn Marino 	    return;
7552*e4b17023SJohn Marino 	  else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
7553*e4b17023SJohn Marino 	    c_parser_objc_at_property_declaration (parser);
7554*e4b17023SJohn Marino 	  else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
7555*e4b17023SJohn Marino 	    {
7556*e4b17023SJohn Marino 	      objc_set_method_opt (true);
7557*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
7558*e4b17023SJohn Marino 	    }
7559*e4b17023SJohn Marino 	  else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
7560*e4b17023SJohn Marino 	    {
7561*e4b17023SJohn Marino 	      objc_set_method_opt (false);
7562*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
7563*e4b17023SJohn Marino 	    }
7564*e4b17023SJohn Marino 	  else
7565*e4b17023SJohn Marino 	    c_parser_declaration_or_fndef (parser, false, false, true,
7566*e4b17023SJohn Marino 					   false, true, NULL);
7567*e4b17023SJohn Marino 	  break;
7568*e4b17023SJohn Marino 	}
7569*e4b17023SJohn Marino     }
7570*e4b17023SJohn Marino }
7571*e4b17023SJohn Marino 
7572*e4b17023SJohn Marino /* Parse an objc-methodproto.
7573*e4b17023SJohn Marino 
7574*e4b17023SJohn Marino    objc-methodproto:
7575*e4b17023SJohn Marino      objc-method-type objc-method-decl ;
7576*e4b17023SJohn Marino */
7577*e4b17023SJohn Marino 
7578*e4b17023SJohn Marino static void
c_parser_objc_methodproto(c_parser * parser)7579*e4b17023SJohn Marino c_parser_objc_methodproto (c_parser *parser)
7580*e4b17023SJohn Marino {
7581*e4b17023SJohn Marino   bool is_class_method = c_parser_objc_method_type (parser);
7582*e4b17023SJohn Marino   tree decl, attributes = NULL_TREE;
7583*e4b17023SJohn Marino 
7584*e4b17023SJohn Marino   /* Remember protocol qualifiers in prototypes.  */
7585*e4b17023SJohn Marino   parser->objc_pq_context = true;
7586*e4b17023SJohn Marino   decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
7587*e4b17023SJohn Marino 				    NULL);
7588*e4b17023SJohn Marino   /* Forget protocol qualifiers now.  */
7589*e4b17023SJohn Marino   parser->objc_pq_context = false;
7590*e4b17023SJohn Marino 
7591*e4b17023SJohn Marino   /* Do not allow the presence of attributes to hide an erroneous
7592*e4b17023SJohn Marino      method implementation in the interface section.  */
7593*e4b17023SJohn Marino   if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
7594*e4b17023SJohn Marino     {
7595*e4b17023SJohn Marino       c_parser_error (parser, "expected %<;%>");
7596*e4b17023SJohn Marino       return;
7597*e4b17023SJohn Marino     }
7598*e4b17023SJohn Marino 
7599*e4b17023SJohn Marino   if (decl != error_mark_node)
7600*e4b17023SJohn Marino     objc_add_method_declaration (is_class_method, decl, attributes);
7601*e4b17023SJohn Marino 
7602*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7603*e4b17023SJohn Marino }
7604*e4b17023SJohn Marino 
7605*e4b17023SJohn Marino /* If we are at a position that method attributes may be present, check that
7606*e4b17023SJohn Marino    there are not any parsed already (a syntax error) and then collect any
7607*e4b17023SJohn Marino    specified at the current location.  Finally, if new attributes were present,
7608*e4b17023SJohn Marino    check that the next token is legal ( ';' for decls and '{' for defs).  */
7609*e4b17023SJohn Marino 
7610*e4b17023SJohn Marino static bool
c_parser_objc_maybe_method_attributes(c_parser * parser,tree * attributes)7611*e4b17023SJohn Marino c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
7612*e4b17023SJohn Marino {
7613*e4b17023SJohn Marino   bool bad = false;
7614*e4b17023SJohn Marino   if (*attributes)
7615*e4b17023SJohn Marino     {
7616*e4b17023SJohn Marino       c_parser_error (parser,
7617*e4b17023SJohn Marino 		    "method attributes must be specified at the end only");
7618*e4b17023SJohn Marino       *attributes = NULL_TREE;
7619*e4b17023SJohn Marino       bad = true;
7620*e4b17023SJohn Marino     }
7621*e4b17023SJohn Marino 
7622*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
7623*e4b17023SJohn Marino     *attributes = c_parser_attributes (parser);
7624*e4b17023SJohn Marino 
7625*e4b17023SJohn Marino   /* If there were no attributes here, just report any earlier error.  */
7626*e4b17023SJohn Marino   if (*attributes == NULL_TREE || bad)
7627*e4b17023SJohn Marino     return bad;
7628*e4b17023SJohn Marino 
7629*e4b17023SJohn Marino   /* If the attributes are followed by a ; or {, then just report any earlier
7630*e4b17023SJohn Marino      error.  */
7631*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_SEMICOLON)
7632*e4b17023SJohn Marino       || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7633*e4b17023SJohn Marino     return bad;
7634*e4b17023SJohn Marino 
7635*e4b17023SJohn Marino   /* We've got attributes, but not at the end.  */
7636*e4b17023SJohn Marino   c_parser_error (parser,
7637*e4b17023SJohn Marino 		  "expected %<;%> or %<{%> after method attribute definition");
7638*e4b17023SJohn Marino   return true;
7639*e4b17023SJohn Marino }
7640*e4b17023SJohn Marino 
7641*e4b17023SJohn Marino /* Parse an objc-method-decl.
7642*e4b17023SJohn Marino 
7643*e4b17023SJohn Marino    objc-method-decl:
7644*e4b17023SJohn Marino      ( objc-type-name ) objc-selector
7645*e4b17023SJohn Marino      objc-selector
7646*e4b17023SJohn Marino      ( objc-type-name ) objc-keyword-selector objc-optparmlist
7647*e4b17023SJohn Marino      objc-keyword-selector objc-optparmlist
7648*e4b17023SJohn Marino      attributes
7649*e4b17023SJohn Marino 
7650*e4b17023SJohn Marino    objc-keyword-selector:
7651*e4b17023SJohn Marino      objc-keyword-decl
7652*e4b17023SJohn Marino      objc-keyword-selector objc-keyword-decl
7653*e4b17023SJohn Marino 
7654*e4b17023SJohn Marino    objc-keyword-decl:
7655*e4b17023SJohn Marino      objc-selector : ( objc-type-name ) identifier
7656*e4b17023SJohn Marino      objc-selector : identifier
7657*e4b17023SJohn Marino      : ( objc-type-name ) identifier
7658*e4b17023SJohn Marino      : identifier
7659*e4b17023SJohn Marino 
7660*e4b17023SJohn Marino    objc-optparmlist:
7661*e4b17023SJohn Marino      objc-optparms objc-optellipsis
7662*e4b17023SJohn Marino 
7663*e4b17023SJohn Marino    objc-optparms:
7664*e4b17023SJohn Marino      empty
7665*e4b17023SJohn Marino      objc-opt-parms , parameter-declaration
7666*e4b17023SJohn Marino 
7667*e4b17023SJohn Marino    objc-optellipsis:
7668*e4b17023SJohn Marino      empty
7669*e4b17023SJohn Marino      , ...
7670*e4b17023SJohn Marino */
7671*e4b17023SJohn Marino 
7672*e4b17023SJohn Marino static tree
c_parser_objc_method_decl(c_parser * parser,bool is_class_method,tree * attributes,tree * expr)7673*e4b17023SJohn Marino c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
7674*e4b17023SJohn Marino 			   tree *attributes, tree *expr)
7675*e4b17023SJohn Marino {
7676*e4b17023SJohn Marino   tree type = NULL_TREE;
7677*e4b17023SJohn Marino   tree sel;
7678*e4b17023SJohn Marino   tree parms = NULL_TREE;
7679*e4b17023SJohn Marino   bool ellipsis = false;
7680*e4b17023SJohn Marino   bool attr_err = false;
7681*e4b17023SJohn Marino 
7682*e4b17023SJohn Marino   *attributes = NULL_TREE;
7683*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
7684*e4b17023SJohn Marino     {
7685*e4b17023SJohn Marino       c_parser_consume_token (parser);
7686*e4b17023SJohn Marino       type = c_parser_objc_type_name (parser);
7687*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7688*e4b17023SJohn Marino     }
7689*e4b17023SJohn Marino   sel = c_parser_objc_selector (parser);
7690*e4b17023SJohn Marino   /* If there is no selector, or a colon follows, we have an
7691*e4b17023SJohn Marino      objc-keyword-selector.  If there is a selector, and a colon does
7692*e4b17023SJohn Marino      not follow, that selector ends the objc-method-decl.  */
7693*e4b17023SJohn Marino   if (!sel || c_parser_next_token_is (parser, CPP_COLON))
7694*e4b17023SJohn Marino     {
7695*e4b17023SJohn Marino       tree tsel = sel;
7696*e4b17023SJohn Marino       tree list = NULL_TREE;
7697*e4b17023SJohn Marino       while (true)
7698*e4b17023SJohn Marino 	{
7699*e4b17023SJohn Marino 	  tree atype = NULL_TREE, id, keyworddecl;
7700*e4b17023SJohn Marino 	  tree param_attr = NULL_TREE;
7701*e4b17023SJohn Marino 	  if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7702*e4b17023SJohn Marino 	    break;
7703*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
7704*e4b17023SJohn Marino 	    {
7705*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
7706*e4b17023SJohn Marino 	      atype = c_parser_objc_type_name (parser);
7707*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
7708*e4b17023SJohn Marino 					 "expected %<)%>");
7709*e4b17023SJohn Marino 	    }
7710*e4b17023SJohn Marino 	  /* New ObjC allows attributes on method parameters.  */
7711*e4b17023SJohn Marino 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
7712*e4b17023SJohn Marino 	    param_attr = c_parser_attributes (parser);
7713*e4b17023SJohn Marino 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
7714*e4b17023SJohn Marino 	    {
7715*e4b17023SJohn Marino 	      c_parser_error (parser, "expected identifier");
7716*e4b17023SJohn Marino 	      return error_mark_node;
7717*e4b17023SJohn Marino 	    }
7718*e4b17023SJohn Marino 	  id = c_parser_peek_token (parser)->value;
7719*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7720*e4b17023SJohn Marino 	  keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
7721*e4b17023SJohn Marino 	  list = chainon (list, keyworddecl);
7722*e4b17023SJohn Marino 	  tsel = c_parser_objc_selector (parser);
7723*e4b17023SJohn Marino 	  if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
7724*e4b17023SJohn Marino 	    break;
7725*e4b17023SJohn Marino 	}
7726*e4b17023SJohn Marino 
7727*e4b17023SJohn Marino       attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
7728*e4b17023SJohn Marino 
7729*e4b17023SJohn Marino       /* Parse the optional parameter list.  Optional Objective-C
7730*e4b17023SJohn Marino 	 method parameters follow the C syntax, and may include '...'
7731*e4b17023SJohn Marino 	 to denote a variable number of arguments.  */
7732*e4b17023SJohn Marino       parms = make_node (TREE_LIST);
7733*e4b17023SJohn Marino       while (c_parser_next_token_is (parser, CPP_COMMA))
7734*e4b17023SJohn Marino 	{
7735*e4b17023SJohn Marino 	  struct c_parm *parm;
7736*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7737*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
7738*e4b17023SJohn Marino 	    {
7739*e4b17023SJohn Marino 	      ellipsis = true;
7740*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
7741*e4b17023SJohn Marino 	      attr_err |= c_parser_objc_maybe_method_attributes
7742*e4b17023SJohn Marino 						(parser, attributes) ;
7743*e4b17023SJohn Marino 	      break;
7744*e4b17023SJohn Marino 	    }
7745*e4b17023SJohn Marino 	  parm = c_parser_parameter_declaration (parser, NULL_TREE);
7746*e4b17023SJohn Marino 	  if (parm == NULL)
7747*e4b17023SJohn Marino 	    break;
7748*e4b17023SJohn Marino 	  parms = chainon (parms,
7749*e4b17023SJohn Marino 			   build_tree_list (NULL_TREE, grokparm (parm, expr)));
7750*e4b17023SJohn Marino 	}
7751*e4b17023SJohn Marino       sel = list;
7752*e4b17023SJohn Marino     }
7753*e4b17023SJohn Marino   else
7754*e4b17023SJohn Marino     attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
7755*e4b17023SJohn Marino 
7756*e4b17023SJohn Marino   if (sel == NULL)
7757*e4b17023SJohn Marino     {
7758*e4b17023SJohn Marino       c_parser_error (parser, "objective-c method declaration is expected");
7759*e4b17023SJohn Marino       return error_mark_node;
7760*e4b17023SJohn Marino     }
7761*e4b17023SJohn Marino 
7762*e4b17023SJohn Marino   if (attr_err)
7763*e4b17023SJohn Marino     return error_mark_node;
7764*e4b17023SJohn Marino 
7765*e4b17023SJohn Marino   return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
7766*e4b17023SJohn Marino }
7767*e4b17023SJohn Marino 
7768*e4b17023SJohn Marino /* Parse an objc-type-name.
7769*e4b17023SJohn Marino 
7770*e4b17023SJohn Marino    objc-type-name:
7771*e4b17023SJohn Marino      objc-type-qualifiers[opt] type-name
7772*e4b17023SJohn Marino      objc-type-qualifiers[opt]
7773*e4b17023SJohn Marino 
7774*e4b17023SJohn Marino    objc-type-qualifiers:
7775*e4b17023SJohn Marino      objc-type-qualifier
7776*e4b17023SJohn Marino      objc-type-qualifiers objc-type-qualifier
7777*e4b17023SJohn Marino 
7778*e4b17023SJohn Marino    objc-type-qualifier: one of
7779*e4b17023SJohn Marino      in out inout bycopy byref oneway
7780*e4b17023SJohn Marino */
7781*e4b17023SJohn Marino 
7782*e4b17023SJohn Marino static tree
c_parser_objc_type_name(c_parser * parser)7783*e4b17023SJohn Marino c_parser_objc_type_name (c_parser *parser)
7784*e4b17023SJohn Marino {
7785*e4b17023SJohn Marino   tree quals = NULL_TREE;
7786*e4b17023SJohn Marino   struct c_type_name *type_name = NULL;
7787*e4b17023SJohn Marino   tree type = NULL_TREE;
7788*e4b17023SJohn Marino   while (true)
7789*e4b17023SJohn Marino     {
7790*e4b17023SJohn Marino       c_token *token = c_parser_peek_token (parser);
7791*e4b17023SJohn Marino       if (token->type == CPP_KEYWORD
7792*e4b17023SJohn Marino 	  && (token->keyword == RID_IN
7793*e4b17023SJohn Marino 	      || token->keyword == RID_OUT
7794*e4b17023SJohn Marino 	      || token->keyword == RID_INOUT
7795*e4b17023SJohn Marino 	      || token->keyword == RID_BYCOPY
7796*e4b17023SJohn Marino 	      || token->keyword == RID_BYREF
7797*e4b17023SJohn Marino 	      || token->keyword == RID_ONEWAY))
7798*e4b17023SJohn Marino 	{
7799*e4b17023SJohn Marino 	  quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
7800*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7801*e4b17023SJohn Marino 	}
7802*e4b17023SJohn Marino       else
7803*e4b17023SJohn Marino 	break;
7804*e4b17023SJohn Marino     }
7805*e4b17023SJohn Marino   if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
7806*e4b17023SJohn Marino     type_name = c_parser_type_name (parser);
7807*e4b17023SJohn Marino   if (type_name)
7808*e4b17023SJohn Marino     type = groktypename (type_name, NULL, NULL);
7809*e4b17023SJohn Marino 
7810*e4b17023SJohn Marino   /* If the type is unknown, and error has already been produced and
7811*e4b17023SJohn Marino      we need to recover from the error.  In that case, use NULL_TREE
7812*e4b17023SJohn Marino      for the type, as if no type had been specified; this will use the
7813*e4b17023SJohn Marino      default type ('id') which is good for error recovery.  */
7814*e4b17023SJohn Marino   if (type == error_mark_node)
7815*e4b17023SJohn Marino     type = NULL_TREE;
7816*e4b17023SJohn Marino 
7817*e4b17023SJohn Marino   return build_tree_list (quals, type);
7818*e4b17023SJohn Marino }
7819*e4b17023SJohn Marino 
7820*e4b17023SJohn Marino /* Parse objc-protocol-refs.
7821*e4b17023SJohn Marino 
7822*e4b17023SJohn Marino    objc-protocol-refs:
7823*e4b17023SJohn Marino      < identifier-list >
7824*e4b17023SJohn Marino */
7825*e4b17023SJohn Marino 
7826*e4b17023SJohn Marino static tree
c_parser_objc_protocol_refs(c_parser * parser)7827*e4b17023SJohn Marino c_parser_objc_protocol_refs (c_parser *parser)
7828*e4b17023SJohn Marino {
7829*e4b17023SJohn Marino   tree list = NULL_TREE;
7830*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
7831*e4b17023SJohn Marino   c_parser_consume_token (parser);
7832*e4b17023SJohn Marino   /* Any identifiers, including those declared as type names, are OK
7833*e4b17023SJohn Marino      here.  */
7834*e4b17023SJohn Marino   while (true)
7835*e4b17023SJohn Marino     {
7836*e4b17023SJohn Marino       tree id;
7837*e4b17023SJohn Marino       if (c_parser_next_token_is_not (parser, CPP_NAME))
7838*e4b17023SJohn Marino 	{
7839*e4b17023SJohn Marino 	  c_parser_error (parser, "expected identifier");
7840*e4b17023SJohn Marino 	  break;
7841*e4b17023SJohn Marino 	}
7842*e4b17023SJohn Marino       id = c_parser_peek_token (parser)->value;
7843*e4b17023SJohn Marino       list = chainon (list, build_tree_list (NULL_TREE, id));
7844*e4b17023SJohn Marino       c_parser_consume_token (parser);
7845*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_COMMA))
7846*e4b17023SJohn Marino 	c_parser_consume_token (parser);
7847*e4b17023SJohn Marino       else
7848*e4b17023SJohn Marino 	break;
7849*e4b17023SJohn Marino     }
7850*e4b17023SJohn Marino   c_parser_require (parser, CPP_GREATER, "expected %<>%>");
7851*e4b17023SJohn Marino   return list;
7852*e4b17023SJohn Marino }
7853*e4b17023SJohn Marino 
7854*e4b17023SJohn Marino /* Parse an objc-try-catch-finally-statement.
7855*e4b17023SJohn Marino 
7856*e4b17023SJohn Marino    objc-try-catch-finally-statement:
7857*e4b17023SJohn Marino      @try compound-statement objc-catch-list[opt]
7858*e4b17023SJohn Marino      @try compound-statement objc-catch-list[opt] @finally compound-statement
7859*e4b17023SJohn Marino 
7860*e4b17023SJohn Marino    objc-catch-list:
7861*e4b17023SJohn Marino      @catch ( objc-catch-parameter-declaration ) compound-statement
7862*e4b17023SJohn Marino      objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
7863*e4b17023SJohn Marino 
7864*e4b17023SJohn Marino    objc-catch-parameter-declaration:
7865*e4b17023SJohn Marino      parameter-declaration
7866*e4b17023SJohn Marino      '...'
7867*e4b17023SJohn Marino 
7868*e4b17023SJohn Marino    where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
7869*e4b17023SJohn Marino 
7870*e4b17023SJohn Marino    PS: This function is identical to cp_parser_objc_try_catch_finally_statement
7871*e4b17023SJohn Marino    for C++.  Keep them in sync.  */
7872*e4b17023SJohn Marino 
7873*e4b17023SJohn Marino static void
c_parser_objc_try_catch_finally_statement(c_parser * parser)7874*e4b17023SJohn Marino c_parser_objc_try_catch_finally_statement (c_parser *parser)
7875*e4b17023SJohn Marino {
7876*e4b17023SJohn Marino   location_t location;
7877*e4b17023SJohn Marino   tree stmt;
7878*e4b17023SJohn Marino 
7879*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
7880*e4b17023SJohn Marino   c_parser_consume_token (parser);
7881*e4b17023SJohn Marino   location = c_parser_peek_token (parser)->location;
7882*e4b17023SJohn Marino   objc_maybe_warn_exceptions (location);
7883*e4b17023SJohn Marino   stmt = c_parser_compound_statement (parser);
7884*e4b17023SJohn Marino   objc_begin_try_stmt (location, stmt);
7885*e4b17023SJohn Marino 
7886*e4b17023SJohn Marino   while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
7887*e4b17023SJohn Marino     {
7888*e4b17023SJohn Marino       struct c_parm *parm;
7889*e4b17023SJohn Marino       tree parameter_declaration = error_mark_node;
7890*e4b17023SJohn Marino       bool seen_open_paren = false;
7891*e4b17023SJohn Marino 
7892*e4b17023SJohn Marino       c_parser_consume_token (parser);
7893*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
7894*e4b17023SJohn Marino 	seen_open_paren = true;
7895*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
7896*e4b17023SJohn Marino 	{
7897*e4b17023SJohn Marino 	  /* We have "@catch (...)" (where the '...' are literally
7898*e4b17023SJohn Marino 	     what is in the code).  Skip the '...'.
7899*e4b17023SJohn Marino 	     parameter_declaration is set to NULL_TREE, and
7900*e4b17023SJohn Marino 	     objc_being_catch_clauses() knows that that means
7901*e4b17023SJohn Marino 	     '...'.  */
7902*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
7903*e4b17023SJohn Marino 	  parameter_declaration = NULL_TREE;
7904*e4b17023SJohn Marino 	}
7905*e4b17023SJohn Marino       else
7906*e4b17023SJohn Marino 	{
7907*e4b17023SJohn Marino 	  /* We have "@catch (NSException *exception)" or something
7908*e4b17023SJohn Marino 	     like that.  Parse the parameter declaration.  */
7909*e4b17023SJohn Marino 	  parm = c_parser_parameter_declaration (parser, NULL_TREE);
7910*e4b17023SJohn Marino 	  if (parm == NULL)
7911*e4b17023SJohn Marino 	    parameter_declaration = error_mark_node;
7912*e4b17023SJohn Marino 	  else
7913*e4b17023SJohn Marino 	    parameter_declaration = grokparm (parm, NULL);
7914*e4b17023SJohn Marino 	}
7915*e4b17023SJohn Marino       if (seen_open_paren)
7916*e4b17023SJohn Marino 	c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7917*e4b17023SJohn Marino       else
7918*e4b17023SJohn Marino 	{
7919*e4b17023SJohn Marino 	  /* If there was no open parenthesis, we are recovering from
7920*e4b17023SJohn Marino 	     an error, and we are trying to figure out what mistake
7921*e4b17023SJohn Marino 	     the user has made.  */
7922*e4b17023SJohn Marino 
7923*e4b17023SJohn Marino 	  /* If there is an immediate closing parenthesis, the user
7924*e4b17023SJohn Marino 	     probably forgot the opening one (ie, they typed "@catch
7925*e4b17023SJohn Marino 	     NSException *e)".  Parse the closing parenthesis and keep
7926*e4b17023SJohn Marino 	     going.  */
7927*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7928*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
7929*e4b17023SJohn Marino 
7930*e4b17023SJohn Marino 	  /* If these is no immediate closing parenthesis, the user
7931*e4b17023SJohn Marino 	     probably doesn't know that parenthesis are required at
7932*e4b17023SJohn Marino 	     all (ie, they typed "@catch NSException *e").  So, just
7933*e4b17023SJohn Marino 	     forget about the closing parenthesis and keep going.  */
7934*e4b17023SJohn Marino 	}
7935*e4b17023SJohn Marino       objc_begin_catch_clause (parameter_declaration);
7936*e4b17023SJohn Marino       if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
7937*e4b17023SJohn Marino 	c_parser_compound_statement_nostart (parser);
7938*e4b17023SJohn Marino       objc_finish_catch_clause ();
7939*e4b17023SJohn Marino     }
7940*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
7941*e4b17023SJohn Marino     {
7942*e4b17023SJohn Marino       c_parser_consume_token (parser);
7943*e4b17023SJohn Marino       location = c_parser_peek_token (parser)->location;
7944*e4b17023SJohn Marino       stmt = c_parser_compound_statement (parser);
7945*e4b17023SJohn Marino       objc_build_finally_clause (location, stmt);
7946*e4b17023SJohn Marino     }
7947*e4b17023SJohn Marino   objc_finish_try_stmt ();
7948*e4b17023SJohn Marino }
7949*e4b17023SJohn Marino 
7950*e4b17023SJohn Marino /* Parse an objc-synchronized-statement.
7951*e4b17023SJohn Marino 
7952*e4b17023SJohn Marino    objc-synchronized-statement:
7953*e4b17023SJohn Marino      @synchronized ( expression ) compound-statement
7954*e4b17023SJohn Marino */
7955*e4b17023SJohn Marino 
7956*e4b17023SJohn Marino static void
c_parser_objc_synchronized_statement(c_parser * parser)7957*e4b17023SJohn Marino c_parser_objc_synchronized_statement (c_parser *parser)
7958*e4b17023SJohn Marino {
7959*e4b17023SJohn Marino   location_t loc;
7960*e4b17023SJohn Marino   tree expr, stmt;
7961*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
7962*e4b17023SJohn Marino   c_parser_consume_token (parser);
7963*e4b17023SJohn Marino   loc = c_parser_peek_token (parser)->location;
7964*e4b17023SJohn Marino   objc_maybe_warn_exceptions (loc);
7965*e4b17023SJohn Marino   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
7966*e4b17023SJohn Marino     {
7967*e4b17023SJohn Marino       expr = c_parser_expression (parser).value;
7968*e4b17023SJohn Marino       expr = c_fully_fold (expr, false, NULL);
7969*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7970*e4b17023SJohn Marino     }
7971*e4b17023SJohn Marino   else
7972*e4b17023SJohn Marino     expr = error_mark_node;
7973*e4b17023SJohn Marino   stmt = c_parser_compound_statement (parser);
7974*e4b17023SJohn Marino   objc_build_synchronized (loc, expr, stmt);
7975*e4b17023SJohn Marino }
7976*e4b17023SJohn Marino 
7977*e4b17023SJohn Marino /* Parse an objc-selector; return NULL_TREE without an error if the
7978*e4b17023SJohn Marino    next token is not an objc-selector.
7979*e4b17023SJohn Marino 
7980*e4b17023SJohn Marino    objc-selector:
7981*e4b17023SJohn Marino      identifier
7982*e4b17023SJohn Marino      one of
7983*e4b17023SJohn Marino        enum struct union if else while do for switch case default
7984*e4b17023SJohn Marino        break continue return goto asm sizeof typeof __alignof
7985*e4b17023SJohn Marino        unsigned long const short volatile signed restrict _Complex
7986*e4b17023SJohn Marino        in out inout bycopy byref oneway int char float double void _Bool
7987*e4b17023SJohn Marino 
7988*e4b17023SJohn Marino    ??? Why this selection of keywords but not, for example, storage
7989*e4b17023SJohn Marino    class specifiers?  */
7990*e4b17023SJohn Marino 
7991*e4b17023SJohn Marino static tree
c_parser_objc_selector(c_parser * parser)7992*e4b17023SJohn Marino c_parser_objc_selector (c_parser *parser)
7993*e4b17023SJohn Marino {
7994*e4b17023SJohn Marino   c_token *token = c_parser_peek_token (parser);
7995*e4b17023SJohn Marino   tree value = token->value;
7996*e4b17023SJohn Marino   if (token->type == CPP_NAME)
7997*e4b17023SJohn Marino     {
7998*e4b17023SJohn Marino       c_parser_consume_token (parser);
7999*e4b17023SJohn Marino       return value;
8000*e4b17023SJohn Marino     }
8001*e4b17023SJohn Marino   if (token->type != CPP_KEYWORD)
8002*e4b17023SJohn Marino     return NULL_TREE;
8003*e4b17023SJohn Marino   switch (token->keyword)
8004*e4b17023SJohn Marino     {
8005*e4b17023SJohn Marino     case RID_ENUM:
8006*e4b17023SJohn Marino     case RID_STRUCT:
8007*e4b17023SJohn Marino     case RID_UNION:
8008*e4b17023SJohn Marino     case RID_IF:
8009*e4b17023SJohn Marino     case RID_ELSE:
8010*e4b17023SJohn Marino     case RID_WHILE:
8011*e4b17023SJohn Marino     case RID_DO:
8012*e4b17023SJohn Marino     case RID_FOR:
8013*e4b17023SJohn Marino     case RID_SWITCH:
8014*e4b17023SJohn Marino     case RID_CASE:
8015*e4b17023SJohn Marino     case RID_DEFAULT:
8016*e4b17023SJohn Marino     case RID_BREAK:
8017*e4b17023SJohn Marino     case RID_CONTINUE:
8018*e4b17023SJohn Marino     case RID_RETURN:
8019*e4b17023SJohn Marino     case RID_GOTO:
8020*e4b17023SJohn Marino     case RID_ASM:
8021*e4b17023SJohn Marino     case RID_SIZEOF:
8022*e4b17023SJohn Marino     case RID_TYPEOF:
8023*e4b17023SJohn Marino     case RID_ALIGNOF:
8024*e4b17023SJohn Marino     case RID_UNSIGNED:
8025*e4b17023SJohn Marino     case RID_LONG:
8026*e4b17023SJohn Marino     case RID_INT128:
8027*e4b17023SJohn Marino     case RID_CONST:
8028*e4b17023SJohn Marino     case RID_SHORT:
8029*e4b17023SJohn Marino     case RID_VOLATILE:
8030*e4b17023SJohn Marino     case RID_SIGNED:
8031*e4b17023SJohn Marino     case RID_RESTRICT:
8032*e4b17023SJohn Marino     case RID_COMPLEX:
8033*e4b17023SJohn Marino     case RID_IN:
8034*e4b17023SJohn Marino     case RID_OUT:
8035*e4b17023SJohn Marino     case RID_INOUT:
8036*e4b17023SJohn Marino     case RID_BYCOPY:
8037*e4b17023SJohn Marino     case RID_BYREF:
8038*e4b17023SJohn Marino     case RID_ONEWAY:
8039*e4b17023SJohn Marino     case RID_INT:
8040*e4b17023SJohn Marino     case RID_CHAR:
8041*e4b17023SJohn Marino     case RID_FLOAT:
8042*e4b17023SJohn Marino     case RID_DOUBLE:
8043*e4b17023SJohn Marino     case RID_VOID:
8044*e4b17023SJohn Marino     case RID_BOOL:
8045*e4b17023SJohn Marino       c_parser_consume_token (parser);
8046*e4b17023SJohn Marino       return value;
8047*e4b17023SJohn Marino     default:
8048*e4b17023SJohn Marino       return NULL_TREE;
8049*e4b17023SJohn Marino     }
8050*e4b17023SJohn Marino }
8051*e4b17023SJohn Marino 
8052*e4b17023SJohn Marino /* Parse an objc-selector-arg.
8053*e4b17023SJohn Marino 
8054*e4b17023SJohn Marino    objc-selector-arg:
8055*e4b17023SJohn Marino      objc-selector
8056*e4b17023SJohn Marino      objc-keywordname-list
8057*e4b17023SJohn Marino 
8058*e4b17023SJohn Marino    objc-keywordname-list:
8059*e4b17023SJohn Marino      objc-keywordname
8060*e4b17023SJohn Marino      objc-keywordname-list objc-keywordname
8061*e4b17023SJohn Marino 
8062*e4b17023SJohn Marino    objc-keywordname:
8063*e4b17023SJohn Marino      objc-selector :
8064*e4b17023SJohn Marino      :
8065*e4b17023SJohn Marino */
8066*e4b17023SJohn Marino 
8067*e4b17023SJohn Marino static tree
c_parser_objc_selector_arg(c_parser * parser)8068*e4b17023SJohn Marino c_parser_objc_selector_arg (c_parser *parser)
8069*e4b17023SJohn Marino {
8070*e4b17023SJohn Marino   tree sel = c_parser_objc_selector (parser);
8071*e4b17023SJohn Marino   tree list = NULL_TREE;
8072*e4b17023SJohn Marino   if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
8073*e4b17023SJohn Marino     return sel;
8074*e4b17023SJohn Marino   while (true)
8075*e4b17023SJohn Marino     {
8076*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8077*e4b17023SJohn Marino 	return list;
8078*e4b17023SJohn Marino       list = chainon (list, build_tree_list (sel, NULL_TREE));
8079*e4b17023SJohn Marino       sel = c_parser_objc_selector (parser);
8080*e4b17023SJohn Marino       if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
8081*e4b17023SJohn Marino 	break;
8082*e4b17023SJohn Marino     }
8083*e4b17023SJohn Marino   return list;
8084*e4b17023SJohn Marino }
8085*e4b17023SJohn Marino 
8086*e4b17023SJohn Marino /* Parse an objc-receiver.
8087*e4b17023SJohn Marino 
8088*e4b17023SJohn Marino    objc-receiver:
8089*e4b17023SJohn Marino      expression
8090*e4b17023SJohn Marino      class-name
8091*e4b17023SJohn Marino      type-name
8092*e4b17023SJohn Marino */
8093*e4b17023SJohn Marino 
8094*e4b17023SJohn Marino static tree
c_parser_objc_receiver(c_parser * parser)8095*e4b17023SJohn Marino c_parser_objc_receiver (c_parser *parser)
8096*e4b17023SJohn Marino {
8097*e4b17023SJohn Marino   if (c_parser_peek_token (parser)->type == CPP_NAME
8098*e4b17023SJohn Marino       && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
8099*e4b17023SJohn Marino 	  || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
8100*e4b17023SJohn Marino     {
8101*e4b17023SJohn Marino       tree id = c_parser_peek_token (parser)->value;
8102*e4b17023SJohn Marino       c_parser_consume_token (parser);
8103*e4b17023SJohn Marino       return objc_get_class_reference (id);
8104*e4b17023SJohn Marino     }
8105*e4b17023SJohn Marino   return c_fully_fold (c_parser_expression (parser).value, false, NULL);
8106*e4b17023SJohn Marino }
8107*e4b17023SJohn Marino 
8108*e4b17023SJohn Marino /* Parse objc-message-args.
8109*e4b17023SJohn Marino 
8110*e4b17023SJohn Marino    objc-message-args:
8111*e4b17023SJohn Marino      objc-selector
8112*e4b17023SJohn Marino      objc-keywordarg-list
8113*e4b17023SJohn Marino 
8114*e4b17023SJohn Marino    objc-keywordarg-list:
8115*e4b17023SJohn Marino      objc-keywordarg
8116*e4b17023SJohn Marino      objc-keywordarg-list objc-keywordarg
8117*e4b17023SJohn Marino 
8118*e4b17023SJohn Marino    objc-keywordarg:
8119*e4b17023SJohn Marino      objc-selector : objc-keywordexpr
8120*e4b17023SJohn Marino      : objc-keywordexpr
8121*e4b17023SJohn Marino */
8122*e4b17023SJohn Marino 
8123*e4b17023SJohn Marino static tree
c_parser_objc_message_args(c_parser * parser)8124*e4b17023SJohn Marino c_parser_objc_message_args (c_parser *parser)
8125*e4b17023SJohn Marino {
8126*e4b17023SJohn Marino   tree sel = c_parser_objc_selector (parser);
8127*e4b17023SJohn Marino   tree list = NULL_TREE;
8128*e4b17023SJohn Marino   if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
8129*e4b17023SJohn Marino     return sel;
8130*e4b17023SJohn Marino   while (true)
8131*e4b17023SJohn Marino     {
8132*e4b17023SJohn Marino       tree keywordexpr;
8133*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8134*e4b17023SJohn Marino 	return error_mark_node;
8135*e4b17023SJohn Marino       keywordexpr = c_parser_objc_keywordexpr (parser);
8136*e4b17023SJohn Marino       list = chainon (list, build_tree_list (sel, keywordexpr));
8137*e4b17023SJohn Marino       sel = c_parser_objc_selector (parser);
8138*e4b17023SJohn Marino       if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
8139*e4b17023SJohn Marino 	break;
8140*e4b17023SJohn Marino     }
8141*e4b17023SJohn Marino   return list;
8142*e4b17023SJohn Marino }
8143*e4b17023SJohn Marino 
8144*e4b17023SJohn Marino /* Parse an objc-keywordexpr.
8145*e4b17023SJohn Marino 
8146*e4b17023SJohn Marino    objc-keywordexpr:
8147*e4b17023SJohn Marino      nonempty-expr-list
8148*e4b17023SJohn Marino */
8149*e4b17023SJohn Marino 
8150*e4b17023SJohn Marino static tree
c_parser_objc_keywordexpr(c_parser * parser)8151*e4b17023SJohn Marino c_parser_objc_keywordexpr (c_parser *parser)
8152*e4b17023SJohn Marino {
8153*e4b17023SJohn Marino   tree ret;
8154*e4b17023SJohn Marino   VEC(tree,gc) *expr_list = c_parser_expr_list (parser, true, true, NULL);
8155*e4b17023SJohn Marino   if (VEC_length (tree, expr_list) == 1)
8156*e4b17023SJohn Marino     {
8157*e4b17023SJohn Marino       /* Just return the expression, remove a level of
8158*e4b17023SJohn Marino 	 indirection.  */
8159*e4b17023SJohn Marino       ret = VEC_index (tree, expr_list, 0);
8160*e4b17023SJohn Marino     }
8161*e4b17023SJohn Marino   else
8162*e4b17023SJohn Marino     {
8163*e4b17023SJohn Marino       /* We have a comma expression, we will collapse later.  */
8164*e4b17023SJohn Marino       ret = build_tree_list_vec (expr_list);
8165*e4b17023SJohn Marino     }
8166*e4b17023SJohn Marino   release_tree_vector (expr_list);
8167*e4b17023SJohn Marino   return ret;
8168*e4b17023SJohn Marino }
8169*e4b17023SJohn Marino 
8170*e4b17023SJohn Marino /* A check, needed in several places, that ObjC interface, implementation or
8171*e4b17023SJohn Marino    method definitions are not prefixed by incorrect items.  */
8172*e4b17023SJohn Marino static bool
c_parser_objc_diagnose_bad_element_prefix(c_parser * parser,struct c_declspecs * specs)8173*e4b17023SJohn Marino c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
8174*e4b17023SJohn Marino 					   struct c_declspecs *specs)
8175*e4b17023SJohn Marino {
8176*e4b17023SJohn Marino   if (!specs->declspecs_seen_p || specs->non_sc_seen_p
8177*e4b17023SJohn Marino       || specs->typespec_kind != ctsk_none)
8178*e4b17023SJohn Marino     {
8179*e4b17023SJohn Marino       c_parser_error (parser,
8180*e4b17023SJohn Marino       		      "no type or storage class may be specified here,");
8181*e4b17023SJohn Marino       c_parser_skip_to_end_of_block_or_statement (parser);
8182*e4b17023SJohn Marino       return true;
8183*e4b17023SJohn Marino     }
8184*e4b17023SJohn Marino   return false;
8185*e4b17023SJohn Marino }
8186*e4b17023SJohn Marino 
8187*e4b17023SJohn Marino /* Parse an Objective-C @property declaration.  The syntax is:
8188*e4b17023SJohn Marino 
8189*e4b17023SJohn Marino    objc-property-declaration:
8190*e4b17023SJohn Marino      '@property' objc-property-attributes[opt] struct-declaration ;
8191*e4b17023SJohn Marino 
8192*e4b17023SJohn Marino    objc-property-attributes:
8193*e4b17023SJohn Marino     '(' objc-property-attribute-list ')'
8194*e4b17023SJohn Marino 
8195*e4b17023SJohn Marino    objc-property-attribute-list:
8196*e4b17023SJohn Marino      objc-property-attribute
8197*e4b17023SJohn Marino      objc-property-attribute-list, objc-property-attribute
8198*e4b17023SJohn Marino 
8199*e4b17023SJohn Marino    objc-property-attribute
8200*e4b17023SJohn Marino      'getter' = identifier
8201*e4b17023SJohn Marino      'setter' = identifier
8202*e4b17023SJohn Marino      'readonly'
8203*e4b17023SJohn Marino      'readwrite'
8204*e4b17023SJohn Marino      'assign'
8205*e4b17023SJohn Marino      'retain'
8206*e4b17023SJohn Marino      'copy'
8207*e4b17023SJohn Marino      'nonatomic'
8208*e4b17023SJohn Marino 
8209*e4b17023SJohn Marino   For example:
8210*e4b17023SJohn Marino     @property NSString *name;
8211*e4b17023SJohn Marino     @property (readonly) id object;
8212*e4b17023SJohn Marino     @property (retain, nonatomic, getter=getTheName) id name;
8213*e4b17023SJohn Marino     @property int a, b, c;
8214*e4b17023SJohn Marino 
8215*e4b17023SJohn Marino   PS: This function is identical to cp_parser_objc_at_propery_declaration
8216*e4b17023SJohn Marino   for C++.  Keep them in sync.  */
8217*e4b17023SJohn Marino static void
c_parser_objc_at_property_declaration(c_parser * parser)8218*e4b17023SJohn Marino c_parser_objc_at_property_declaration (c_parser *parser)
8219*e4b17023SJohn Marino {
8220*e4b17023SJohn Marino   /* The following variables hold the attributes of the properties as
8221*e4b17023SJohn Marino      parsed.  They are 'false' or 'NULL_TREE' if the attribute was not
8222*e4b17023SJohn Marino      seen.  When we see an attribute, we set them to 'true' (if they
8223*e4b17023SJohn Marino      are boolean properties) or to the identifier (if they have an
8224*e4b17023SJohn Marino      argument, ie, for getter and setter).  Note that here we only
8225*e4b17023SJohn Marino      parse the list of attributes, check the syntax and accumulate the
8226*e4b17023SJohn Marino      attributes that we find.  objc_add_property_declaration() will
8227*e4b17023SJohn Marino      then process the information.  */
8228*e4b17023SJohn Marino   bool property_assign = false;
8229*e4b17023SJohn Marino   bool property_copy = false;
8230*e4b17023SJohn Marino   tree property_getter_ident = NULL_TREE;
8231*e4b17023SJohn Marino   bool property_nonatomic = false;
8232*e4b17023SJohn Marino   bool property_readonly = false;
8233*e4b17023SJohn Marino   bool property_readwrite = false;
8234*e4b17023SJohn Marino   bool property_retain = false;
8235*e4b17023SJohn Marino   tree property_setter_ident = NULL_TREE;
8236*e4b17023SJohn Marino 
8237*e4b17023SJohn Marino   /* 'properties' is the list of properties that we read.  Usually a
8238*e4b17023SJohn Marino      single one, but maybe more (eg, in "@property int a, b, c;" there
8239*e4b17023SJohn Marino      are three).  */
8240*e4b17023SJohn Marino   tree properties;
8241*e4b17023SJohn Marino   location_t loc;
8242*e4b17023SJohn Marino 
8243*e4b17023SJohn Marino   loc = c_parser_peek_token (parser)->location;
8244*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
8245*e4b17023SJohn Marino 
8246*e4b17023SJohn Marino   c_parser_consume_token (parser);  /* Eat '@property'.  */
8247*e4b17023SJohn Marino 
8248*e4b17023SJohn Marino   /* Parse the optional attribute list...  */
8249*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
8250*e4b17023SJohn Marino     {
8251*e4b17023SJohn Marino       /* Eat the '(' */
8252*e4b17023SJohn Marino       c_parser_consume_token (parser);
8253*e4b17023SJohn Marino 
8254*e4b17023SJohn Marino       /* Property attribute keywords are valid now.  */
8255*e4b17023SJohn Marino       parser->objc_property_attr_context = true;
8256*e4b17023SJohn Marino 
8257*e4b17023SJohn Marino       while (true)
8258*e4b17023SJohn Marino 	{
8259*e4b17023SJohn Marino 	  bool syntax_error = false;
8260*e4b17023SJohn Marino 	  c_token *token = c_parser_peek_token (parser);
8261*e4b17023SJohn Marino 	  enum rid keyword;
8262*e4b17023SJohn Marino 
8263*e4b17023SJohn Marino 	  if (token->type != CPP_KEYWORD)
8264*e4b17023SJohn Marino 	    {
8265*e4b17023SJohn Marino 	      if (token->type == CPP_CLOSE_PAREN)
8266*e4b17023SJohn Marino 		c_parser_error (parser, "expected identifier");
8267*e4b17023SJohn Marino 	      else
8268*e4b17023SJohn Marino 		{
8269*e4b17023SJohn Marino 		  c_parser_consume_token (parser);
8270*e4b17023SJohn Marino 		  c_parser_error (parser, "unknown property attribute");
8271*e4b17023SJohn Marino 		}
8272*e4b17023SJohn Marino 	      break;
8273*e4b17023SJohn Marino 	    }
8274*e4b17023SJohn Marino 	  keyword = token->keyword;
8275*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
8276*e4b17023SJohn Marino 	  switch (keyword)
8277*e4b17023SJohn Marino 	    {
8278*e4b17023SJohn Marino 	    case RID_ASSIGN:    property_assign = true;    break;
8279*e4b17023SJohn Marino 	    case RID_COPY:      property_copy = true;      break;
8280*e4b17023SJohn Marino 	    case RID_NONATOMIC: property_nonatomic = true; break;
8281*e4b17023SJohn Marino 	    case RID_READONLY:  property_readonly = true;  break;
8282*e4b17023SJohn Marino 	    case RID_READWRITE: property_readwrite = true; break;
8283*e4b17023SJohn Marino 	    case RID_RETAIN:    property_retain = true;    break;
8284*e4b17023SJohn Marino 
8285*e4b17023SJohn Marino 	    case RID_GETTER:
8286*e4b17023SJohn Marino 	    case RID_SETTER:
8287*e4b17023SJohn Marino 	      if (c_parser_next_token_is_not (parser, CPP_EQ))
8288*e4b17023SJohn Marino 		{
8289*e4b17023SJohn Marino 		  if (keyword == RID_GETTER)
8290*e4b17023SJohn Marino 		    c_parser_error (parser,
8291*e4b17023SJohn Marino 				    "missing %<=%> (after %<getter%> attribute)");
8292*e4b17023SJohn Marino 		  else
8293*e4b17023SJohn Marino 		    c_parser_error (parser,
8294*e4b17023SJohn Marino 				    "missing %<=%> (after %<setter%> attribute)");
8295*e4b17023SJohn Marino 		  syntax_error = true;
8296*e4b17023SJohn Marino 		  break;
8297*e4b17023SJohn Marino 		}
8298*e4b17023SJohn Marino 	      c_parser_consume_token (parser); /* eat the = */
8299*e4b17023SJohn Marino 	      if (c_parser_next_token_is_not (parser, CPP_NAME))
8300*e4b17023SJohn Marino 		{
8301*e4b17023SJohn Marino 		  c_parser_error (parser, "expected identifier");
8302*e4b17023SJohn Marino 		  syntax_error = true;
8303*e4b17023SJohn Marino 		  break;
8304*e4b17023SJohn Marino 		}
8305*e4b17023SJohn Marino 	      if (keyword == RID_SETTER)
8306*e4b17023SJohn Marino 		{
8307*e4b17023SJohn Marino 		  if (property_setter_ident != NULL_TREE)
8308*e4b17023SJohn Marino 		    c_parser_error (parser, "the %<setter%> attribute may only be specified once");
8309*e4b17023SJohn Marino 		  else
8310*e4b17023SJohn Marino 		    property_setter_ident = c_parser_peek_token (parser)->value;
8311*e4b17023SJohn Marino 		  c_parser_consume_token (parser);
8312*e4b17023SJohn Marino 		  if (c_parser_next_token_is_not (parser, CPP_COLON))
8313*e4b17023SJohn Marino 		    c_parser_error (parser, "setter name must terminate with %<:%>");
8314*e4b17023SJohn Marino 		  else
8315*e4b17023SJohn Marino 		    c_parser_consume_token (parser);
8316*e4b17023SJohn Marino 		}
8317*e4b17023SJohn Marino 	      else
8318*e4b17023SJohn Marino 		{
8319*e4b17023SJohn Marino 		  if (property_getter_ident != NULL_TREE)
8320*e4b17023SJohn Marino 		    c_parser_error (parser, "the %<getter%> attribute may only be specified once");
8321*e4b17023SJohn Marino 		  else
8322*e4b17023SJohn Marino 		    property_getter_ident = c_parser_peek_token (parser)->value;
8323*e4b17023SJohn Marino 		  c_parser_consume_token (parser);
8324*e4b17023SJohn Marino 		}
8325*e4b17023SJohn Marino 	      break;
8326*e4b17023SJohn Marino 	    default:
8327*e4b17023SJohn Marino 	      c_parser_error (parser, "unknown property attribute");
8328*e4b17023SJohn Marino 	      syntax_error = true;
8329*e4b17023SJohn Marino 	      break;
8330*e4b17023SJohn Marino 	    }
8331*e4b17023SJohn Marino 
8332*e4b17023SJohn Marino 	  if (syntax_error)
8333*e4b17023SJohn Marino 	    break;
8334*e4b17023SJohn Marino 
8335*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_COMMA))
8336*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
8337*e4b17023SJohn Marino 	  else
8338*e4b17023SJohn Marino 	    break;
8339*e4b17023SJohn Marino 	}
8340*e4b17023SJohn Marino       parser->objc_property_attr_context = false;
8341*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
8342*e4b17023SJohn Marino     }
8343*e4b17023SJohn Marino   /* ... and the property declaration(s).  */
8344*e4b17023SJohn Marino   properties = c_parser_struct_declaration (parser);
8345*e4b17023SJohn Marino 
8346*e4b17023SJohn Marino   if (properties == error_mark_node)
8347*e4b17023SJohn Marino     {
8348*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
8349*e4b17023SJohn Marino       parser->error = false;
8350*e4b17023SJohn Marino       return;
8351*e4b17023SJohn Marino     }
8352*e4b17023SJohn Marino 
8353*e4b17023SJohn Marino   if (properties == NULL_TREE)
8354*e4b17023SJohn Marino     c_parser_error (parser, "expected identifier");
8355*e4b17023SJohn Marino   else
8356*e4b17023SJohn Marino     {
8357*e4b17023SJohn Marino       /* Comma-separated properties are chained together in
8358*e4b17023SJohn Marino 	 reverse order; add them one by one.  */
8359*e4b17023SJohn Marino       properties = nreverse (properties);
8360*e4b17023SJohn Marino 
8361*e4b17023SJohn Marino       for (; properties; properties = TREE_CHAIN (properties))
8362*e4b17023SJohn Marino 	objc_add_property_declaration (loc, copy_node (properties),
8363*e4b17023SJohn Marino 				       property_readonly, property_readwrite,
8364*e4b17023SJohn Marino 				       property_assign, property_retain,
8365*e4b17023SJohn Marino 				       property_copy, property_nonatomic,
8366*e4b17023SJohn Marino 				       property_getter_ident, property_setter_ident);
8367*e4b17023SJohn Marino     }
8368*e4b17023SJohn Marino 
8369*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
8370*e4b17023SJohn Marino   parser->error = false;
8371*e4b17023SJohn Marino }
8372*e4b17023SJohn Marino 
8373*e4b17023SJohn Marino /* Parse an Objective-C @synthesize declaration.  The syntax is:
8374*e4b17023SJohn Marino 
8375*e4b17023SJohn Marino    objc-synthesize-declaration:
8376*e4b17023SJohn Marino      @synthesize objc-synthesize-identifier-list ;
8377*e4b17023SJohn Marino 
8378*e4b17023SJohn Marino    objc-synthesize-identifier-list:
8379*e4b17023SJohn Marino      objc-synthesize-identifier
8380*e4b17023SJohn Marino      objc-synthesize-identifier-list, objc-synthesize-identifier
8381*e4b17023SJohn Marino 
8382*e4b17023SJohn Marino    objc-synthesize-identifier
8383*e4b17023SJohn Marino      identifier
8384*e4b17023SJohn Marino      identifier = identifier
8385*e4b17023SJohn Marino 
8386*e4b17023SJohn Marino   For example:
8387*e4b17023SJohn Marino     @synthesize MyProperty;
8388*e4b17023SJohn Marino     @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
8389*e4b17023SJohn Marino 
8390*e4b17023SJohn Marino   PS: This function is identical to cp_parser_objc_at_synthesize_declaration
8391*e4b17023SJohn Marino   for C++.  Keep them in sync.
8392*e4b17023SJohn Marino */
8393*e4b17023SJohn Marino static void
c_parser_objc_at_synthesize_declaration(c_parser * parser)8394*e4b17023SJohn Marino c_parser_objc_at_synthesize_declaration (c_parser *parser)
8395*e4b17023SJohn Marino {
8396*e4b17023SJohn Marino   tree list = NULL_TREE;
8397*e4b17023SJohn Marino   location_t loc;
8398*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
8399*e4b17023SJohn Marino   loc = c_parser_peek_token (parser)->location;
8400*e4b17023SJohn Marino 
8401*e4b17023SJohn Marino   c_parser_consume_token (parser);
8402*e4b17023SJohn Marino   while (true)
8403*e4b17023SJohn Marino     {
8404*e4b17023SJohn Marino       tree property, ivar;
8405*e4b17023SJohn Marino       if (c_parser_next_token_is_not (parser, CPP_NAME))
8406*e4b17023SJohn Marino 	{
8407*e4b17023SJohn Marino 	  c_parser_error (parser, "expected identifier");
8408*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
8409*e4b17023SJohn Marino 	  /* Once we find the semicolon, we can resume normal parsing.
8410*e4b17023SJohn Marino 	     We have to reset parser->error manually because
8411*e4b17023SJohn Marino 	     c_parser_skip_until_found() won't reset it for us if the
8412*e4b17023SJohn Marino 	     next token is precisely a semicolon.  */
8413*e4b17023SJohn Marino 	  parser->error = false;
8414*e4b17023SJohn Marino 	  return;
8415*e4b17023SJohn Marino 	}
8416*e4b17023SJohn Marino       property = c_parser_peek_token (parser)->value;
8417*e4b17023SJohn Marino       c_parser_consume_token (parser);
8418*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_EQ))
8419*e4b17023SJohn Marino 	{
8420*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
8421*e4b17023SJohn Marino 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
8422*e4b17023SJohn Marino 	    {
8423*e4b17023SJohn Marino 	      c_parser_error (parser, "expected identifier");
8424*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
8425*e4b17023SJohn Marino 	      parser->error = false;
8426*e4b17023SJohn Marino 	      return;
8427*e4b17023SJohn Marino 	    }
8428*e4b17023SJohn Marino 	  ivar = c_parser_peek_token (parser)->value;
8429*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
8430*e4b17023SJohn Marino 	}
8431*e4b17023SJohn Marino       else
8432*e4b17023SJohn Marino 	ivar = NULL_TREE;
8433*e4b17023SJohn Marino       list = chainon (list, build_tree_list (ivar, property));
8434*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_COMMA))
8435*e4b17023SJohn Marino 	c_parser_consume_token (parser);
8436*e4b17023SJohn Marino       else
8437*e4b17023SJohn Marino 	break;
8438*e4b17023SJohn Marino     }
8439*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
8440*e4b17023SJohn Marino   objc_add_synthesize_declaration (loc, list);
8441*e4b17023SJohn Marino }
8442*e4b17023SJohn Marino 
8443*e4b17023SJohn Marino /* Parse an Objective-C @dynamic declaration.  The syntax is:
8444*e4b17023SJohn Marino 
8445*e4b17023SJohn Marino    objc-dynamic-declaration:
8446*e4b17023SJohn Marino      @dynamic identifier-list ;
8447*e4b17023SJohn Marino 
8448*e4b17023SJohn Marino    For example:
8449*e4b17023SJohn Marino      @dynamic MyProperty;
8450*e4b17023SJohn Marino      @dynamic MyProperty, AnotherProperty;
8451*e4b17023SJohn Marino 
8452*e4b17023SJohn Marino   PS: This function is identical to cp_parser_objc_at_dynamic_declaration
8453*e4b17023SJohn Marino   for C++.  Keep them in sync.
8454*e4b17023SJohn Marino */
8455*e4b17023SJohn Marino static void
c_parser_objc_at_dynamic_declaration(c_parser * parser)8456*e4b17023SJohn Marino c_parser_objc_at_dynamic_declaration (c_parser *parser)
8457*e4b17023SJohn Marino {
8458*e4b17023SJohn Marino   tree list = NULL_TREE;
8459*e4b17023SJohn Marino   location_t loc;
8460*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
8461*e4b17023SJohn Marino   loc = c_parser_peek_token (parser)->location;
8462*e4b17023SJohn Marino 
8463*e4b17023SJohn Marino   c_parser_consume_token (parser);
8464*e4b17023SJohn Marino   while (true)
8465*e4b17023SJohn Marino     {
8466*e4b17023SJohn Marino       tree property;
8467*e4b17023SJohn Marino       if (c_parser_next_token_is_not (parser, CPP_NAME))
8468*e4b17023SJohn Marino 	{
8469*e4b17023SJohn Marino 	  c_parser_error (parser, "expected identifier");
8470*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
8471*e4b17023SJohn Marino 	  parser->error = false;
8472*e4b17023SJohn Marino 	  return;
8473*e4b17023SJohn Marino 	}
8474*e4b17023SJohn Marino       property = c_parser_peek_token (parser)->value;
8475*e4b17023SJohn Marino       list = chainon (list, build_tree_list (NULL_TREE, property));
8476*e4b17023SJohn Marino       c_parser_consume_token (parser);
8477*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_COMMA))
8478*e4b17023SJohn Marino 	c_parser_consume_token (parser);
8479*e4b17023SJohn Marino       else
8480*e4b17023SJohn Marino 	break;
8481*e4b17023SJohn Marino     }
8482*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
8483*e4b17023SJohn Marino   objc_add_dynamic_declaration (loc, list);
8484*e4b17023SJohn Marino }
8485*e4b17023SJohn Marino 
8486*e4b17023SJohn Marino 
8487*e4b17023SJohn Marino /* Handle pragmas.  Some OpenMP pragmas are associated with, and therefore
8488*e4b17023SJohn Marino    should be considered, statements.  ALLOW_STMT is true if we're within
8489*e4b17023SJohn Marino    the context of a function and such pragmas are to be allowed.  Returns
8490*e4b17023SJohn Marino    true if we actually parsed such a pragma.  */
8491*e4b17023SJohn Marino 
8492*e4b17023SJohn Marino static bool
c_parser_pragma(c_parser * parser,enum pragma_context context)8493*e4b17023SJohn Marino c_parser_pragma (c_parser *parser, enum pragma_context context)
8494*e4b17023SJohn Marino {
8495*e4b17023SJohn Marino   unsigned int id;
8496*e4b17023SJohn Marino 
8497*e4b17023SJohn Marino   id = c_parser_peek_token (parser)->pragma_kind;
8498*e4b17023SJohn Marino   gcc_assert (id != PRAGMA_NONE);
8499*e4b17023SJohn Marino 
8500*e4b17023SJohn Marino   switch (id)
8501*e4b17023SJohn Marino     {
8502*e4b17023SJohn Marino     case PRAGMA_OMP_BARRIER:
8503*e4b17023SJohn Marino       if (context != pragma_compound)
8504*e4b17023SJohn Marino 	{
8505*e4b17023SJohn Marino 	  if (context == pragma_stmt)
8506*e4b17023SJohn Marino 	    c_parser_error (parser, "%<#pragma omp barrier%> may only be "
8507*e4b17023SJohn Marino 			    "used in compound statements");
8508*e4b17023SJohn Marino 	  goto bad_stmt;
8509*e4b17023SJohn Marino 	}
8510*e4b17023SJohn Marino       c_parser_omp_barrier (parser);
8511*e4b17023SJohn Marino       return false;
8512*e4b17023SJohn Marino 
8513*e4b17023SJohn Marino     case PRAGMA_OMP_FLUSH:
8514*e4b17023SJohn Marino       if (context != pragma_compound)
8515*e4b17023SJohn Marino 	{
8516*e4b17023SJohn Marino 	  if (context == pragma_stmt)
8517*e4b17023SJohn Marino 	    c_parser_error (parser, "%<#pragma omp flush%> may only be "
8518*e4b17023SJohn Marino 			    "used in compound statements");
8519*e4b17023SJohn Marino 	  goto bad_stmt;
8520*e4b17023SJohn Marino 	}
8521*e4b17023SJohn Marino       c_parser_omp_flush (parser);
8522*e4b17023SJohn Marino       return false;
8523*e4b17023SJohn Marino 
8524*e4b17023SJohn Marino     case PRAGMA_OMP_TASKWAIT:
8525*e4b17023SJohn Marino       if (context != pragma_compound)
8526*e4b17023SJohn Marino 	{
8527*e4b17023SJohn Marino 	  if (context == pragma_stmt)
8528*e4b17023SJohn Marino 	    c_parser_error (parser, "%<#pragma omp taskwait%> may only be "
8529*e4b17023SJohn Marino 			    "used in compound statements");
8530*e4b17023SJohn Marino 	  goto bad_stmt;
8531*e4b17023SJohn Marino 	}
8532*e4b17023SJohn Marino       c_parser_omp_taskwait (parser);
8533*e4b17023SJohn Marino       return false;
8534*e4b17023SJohn Marino 
8535*e4b17023SJohn Marino     case PRAGMA_OMP_TASKYIELD:
8536*e4b17023SJohn Marino       if (context != pragma_compound)
8537*e4b17023SJohn Marino 	{
8538*e4b17023SJohn Marino 	  if (context == pragma_stmt)
8539*e4b17023SJohn Marino 	    c_parser_error (parser, "%<#pragma omp taskyield%> may only be "
8540*e4b17023SJohn Marino 			    "used in compound statements");
8541*e4b17023SJohn Marino 	  goto bad_stmt;
8542*e4b17023SJohn Marino 	}
8543*e4b17023SJohn Marino       c_parser_omp_taskyield (parser);
8544*e4b17023SJohn Marino       return false;
8545*e4b17023SJohn Marino 
8546*e4b17023SJohn Marino     case PRAGMA_OMP_THREADPRIVATE:
8547*e4b17023SJohn Marino       c_parser_omp_threadprivate (parser);
8548*e4b17023SJohn Marino       return false;
8549*e4b17023SJohn Marino 
8550*e4b17023SJohn Marino     case PRAGMA_OMP_SECTION:
8551*e4b17023SJohn Marino       error_at (c_parser_peek_token (parser)->location,
8552*e4b17023SJohn Marino 		"%<#pragma omp section%> may only be used in "
8553*e4b17023SJohn Marino 		"%<#pragma omp sections%> construct");
8554*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
8555*e4b17023SJohn Marino       return false;
8556*e4b17023SJohn Marino 
8557*e4b17023SJohn Marino     case PRAGMA_GCC_PCH_PREPROCESS:
8558*e4b17023SJohn Marino       c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
8559*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
8560*e4b17023SJohn Marino       return false;
8561*e4b17023SJohn Marino 
8562*e4b17023SJohn Marino     default:
8563*e4b17023SJohn Marino       if (id < PRAGMA_FIRST_EXTERNAL)
8564*e4b17023SJohn Marino 	{
8565*e4b17023SJohn Marino 	  if (context == pragma_external)
8566*e4b17023SJohn Marino 	    {
8567*e4b17023SJohn Marino 	    bad_stmt:
8568*e4b17023SJohn Marino 	      c_parser_error (parser, "expected declaration specifiers");
8569*e4b17023SJohn Marino 	      c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
8570*e4b17023SJohn Marino 	      return false;
8571*e4b17023SJohn Marino 	    }
8572*e4b17023SJohn Marino 	  c_parser_omp_construct (parser);
8573*e4b17023SJohn Marino 	  return true;
8574*e4b17023SJohn Marino 	}
8575*e4b17023SJohn Marino       break;
8576*e4b17023SJohn Marino     }
8577*e4b17023SJohn Marino 
8578*e4b17023SJohn Marino   c_parser_consume_pragma (parser);
8579*e4b17023SJohn Marino   c_invoke_pragma_handler (id);
8580*e4b17023SJohn Marino 
8581*e4b17023SJohn Marino   /* Skip to EOL, but suppress any error message.  Those will have been
8582*e4b17023SJohn Marino      generated by the handler routine through calling error, as opposed
8583*e4b17023SJohn Marino      to calling c_parser_error.  */
8584*e4b17023SJohn Marino   parser->error = true;
8585*e4b17023SJohn Marino   c_parser_skip_to_pragma_eol (parser);
8586*e4b17023SJohn Marino 
8587*e4b17023SJohn Marino   return false;
8588*e4b17023SJohn Marino }
8589*e4b17023SJohn Marino 
8590*e4b17023SJohn Marino /* The interface the pragma parsers have to the lexer.  */
8591*e4b17023SJohn Marino 
8592*e4b17023SJohn Marino enum cpp_ttype
pragma_lex(tree * value)8593*e4b17023SJohn Marino pragma_lex (tree *value)
8594*e4b17023SJohn Marino {
8595*e4b17023SJohn Marino   c_token *tok = c_parser_peek_token (the_parser);
8596*e4b17023SJohn Marino   enum cpp_ttype ret = tok->type;
8597*e4b17023SJohn Marino 
8598*e4b17023SJohn Marino   *value = tok->value;
8599*e4b17023SJohn Marino   if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
8600*e4b17023SJohn Marino     ret = CPP_EOF;
8601*e4b17023SJohn Marino   else
8602*e4b17023SJohn Marino     {
8603*e4b17023SJohn Marino       if (ret == CPP_KEYWORD)
8604*e4b17023SJohn Marino 	ret = CPP_NAME;
8605*e4b17023SJohn Marino       c_parser_consume_token (the_parser);
8606*e4b17023SJohn Marino     }
8607*e4b17023SJohn Marino 
8608*e4b17023SJohn Marino   return ret;
8609*e4b17023SJohn Marino }
8610*e4b17023SJohn Marino 
8611*e4b17023SJohn Marino static void
c_parser_pragma_pch_preprocess(c_parser * parser)8612*e4b17023SJohn Marino c_parser_pragma_pch_preprocess (c_parser *parser)
8613*e4b17023SJohn Marino {
8614*e4b17023SJohn Marino   tree name = NULL;
8615*e4b17023SJohn Marino 
8616*e4b17023SJohn Marino   c_parser_consume_pragma (parser);
8617*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_STRING))
8618*e4b17023SJohn Marino     {
8619*e4b17023SJohn Marino       name = c_parser_peek_token (parser)->value;
8620*e4b17023SJohn Marino       c_parser_consume_token (parser);
8621*e4b17023SJohn Marino     }
8622*e4b17023SJohn Marino   else
8623*e4b17023SJohn Marino     c_parser_error (parser, "expected string literal");
8624*e4b17023SJohn Marino   c_parser_skip_to_pragma_eol (parser);
8625*e4b17023SJohn Marino 
8626*e4b17023SJohn Marino   if (name)
8627*e4b17023SJohn Marino     c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
8628*e4b17023SJohn Marino }
8629*e4b17023SJohn Marino 
8630*e4b17023SJohn Marino /* OpenMP 2.5 parsing routines.  */
8631*e4b17023SJohn Marino 
8632*e4b17023SJohn Marino /* Returns name of the next clause.
8633*e4b17023SJohn Marino    If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
8634*e4b17023SJohn Marino    the token is not consumed.  Otherwise appropriate pragma_omp_clause is
8635*e4b17023SJohn Marino    returned and the token is consumed.  */
8636*e4b17023SJohn Marino 
8637*e4b17023SJohn Marino static pragma_omp_clause
c_parser_omp_clause_name(c_parser * parser)8638*e4b17023SJohn Marino c_parser_omp_clause_name (c_parser *parser)
8639*e4b17023SJohn Marino {
8640*e4b17023SJohn Marino   pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
8641*e4b17023SJohn Marino 
8642*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_IF))
8643*e4b17023SJohn Marino     result = PRAGMA_OMP_CLAUSE_IF;
8644*e4b17023SJohn Marino   else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
8645*e4b17023SJohn Marino     result = PRAGMA_OMP_CLAUSE_DEFAULT;
8646*e4b17023SJohn Marino   else if (c_parser_next_token_is (parser, CPP_NAME))
8647*e4b17023SJohn Marino     {
8648*e4b17023SJohn Marino       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
8649*e4b17023SJohn Marino 
8650*e4b17023SJohn Marino       switch (p[0])
8651*e4b17023SJohn Marino 	{
8652*e4b17023SJohn Marino 	case 'c':
8653*e4b17023SJohn Marino 	  if (!strcmp ("collapse", p))
8654*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_COLLAPSE;
8655*e4b17023SJohn Marino 	  else if (!strcmp ("copyin", p))
8656*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_COPYIN;
8657*e4b17023SJohn Marino           else if (!strcmp ("copyprivate", p))
8658*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
8659*e4b17023SJohn Marino 	  break;
8660*e4b17023SJohn Marino 	case 'f':
8661*e4b17023SJohn Marino 	  if (!strcmp ("final", p))
8662*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_FINAL;
8663*e4b17023SJohn Marino 	  else if (!strcmp ("firstprivate", p))
8664*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
8665*e4b17023SJohn Marino 	  break;
8666*e4b17023SJohn Marino 	case 'l':
8667*e4b17023SJohn Marino 	  if (!strcmp ("lastprivate", p))
8668*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
8669*e4b17023SJohn Marino 	  break;
8670*e4b17023SJohn Marino 	case 'm':
8671*e4b17023SJohn Marino 	  if (!strcmp ("mergeable", p))
8672*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_MERGEABLE;
8673*e4b17023SJohn Marino 	  break;
8674*e4b17023SJohn Marino 	case 'n':
8675*e4b17023SJohn Marino 	  if (!strcmp ("nowait", p))
8676*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_NOWAIT;
8677*e4b17023SJohn Marino 	  else if (!strcmp ("num_threads", p))
8678*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
8679*e4b17023SJohn Marino 	  break;
8680*e4b17023SJohn Marino 	case 'o':
8681*e4b17023SJohn Marino 	  if (!strcmp ("ordered", p))
8682*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_ORDERED;
8683*e4b17023SJohn Marino 	  break;
8684*e4b17023SJohn Marino 	case 'p':
8685*e4b17023SJohn Marino 	  if (!strcmp ("private", p))
8686*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_PRIVATE;
8687*e4b17023SJohn Marino 	  break;
8688*e4b17023SJohn Marino 	case 'r':
8689*e4b17023SJohn Marino 	  if (!strcmp ("reduction", p))
8690*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_REDUCTION;
8691*e4b17023SJohn Marino 	  break;
8692*e4b17023SJohn Marino 	case 's':
8693*e4b17023SJohn Marino 	  if (!strcmp ("schedule", p))
8694*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_SCHEDULE;
8695*e4b17023SJohn Marino 	  else if (!strcmp ("shared", p))
8696*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_SHARED;
8697*e4b17023SJohn Marino 	  break;
8698*e4b17023SJohn Marino 	case 'u':
8699*e4b17023SJohn Marino 	  if (!strcmp ("untied", p))
8700*e4b17023SJohn Marino 	    result = PRAGMA_OMP_CLAUSE_UNTIED;
8701*e4b17023SJohn Marino 	  break;
8702*e4b17023SJohn Marino 	}
8703*e4b17023SJohn Marino     }
8704*e4b17023SJohn Marino 
8705*e4b17023SJohn Marino   if (result != PRAGMA_OMP_CLAUSE_NONE)
8706*e4b17023SJohn Marino     c_parser_consume_token (parser);
8707*e4b17023SJohn Marino 
8708*e4b17023SJohn Marino   return result;
8709*e4b17023SJohn Marino }
8710*e4b17023SJohn Marino 
8711*e4b17023SJohn Marino /* Validate that a clause of the given type does not already exist.  */
8712*e4b17023SJohn Marino 
8713*e4b17023SJohn Marino static void
check_no_duplicate_clause(tree clauses,enum omp_clause_code code,const char * name)8714*e4b17023SJohn Marino check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
8715*e4b17023SJohn Marino 			   const char *name)
8716*e4b17023SJohn Marino {
8717*e4b17023SJohn Marino   tree c;
8718*e4b17023SJohn Marino 
8719*e4b17023SJohn Marino   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
8720*e4b17023SJohn Marino     if (OMP_CLAUSE_CODE (c) == code)
8721*e4b17023SJohn Marino       {
8722*e4b17023SJohn Marino 	location_t loc = OMP_CLAUSE_LOCATION (c);
8723*e4b17023SJohn Marino 	error_at (loc, "too many %qs clauses", name);
8724*e4b17023SJohn Marino 	break;
8725*e4b17023SJohn Marino       }
8726*e4b17023SJohn Marino }
8727*e4b17023SJohn Marino 
8728*e4b17023SJohn Marino /* OpenMP 2.5:
8729*e4b17023SJohn Marino    variable-list:
8730*e4b17023SJohn Marino      identifier
8731*e4b17023SJohn Marino      variable-list , identifier
8732*e4b17023SJohn Marino 
8733*e4b17023SJohn Marino    If KIND is nonzero, create the appropriate node and install the
8734*e4b17023SJohn Marino    decl in OMP_CLAUSE_DECL and add the node to the head of the list.
8735*e4b17023SJohn Marino    If KIND is nonzero, CLAUSE_LOC is the location of the clause.
8736*e4b17023SJohn Marino 
8737*e4b17023SJohn Marino    If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
8738*e4b17023SJohn Marino    return the list created.  */
8739*e4b17023SJohn Marino 
8740*e4b17023SJohn Marino static tree
c_parser_omp_variable_list(c_parser * parser,location_t clause_loc,enum omp_clause_code kind,tree list)8741*e4b17023SJohn Marino c_parser_omp_variable_list (c_parser *parser,
8742*e4b17023SJohn Marino 			    location_t clause_loc,
8743*e4b17023SJohn Marino 			    enum omp_clause_code kind,
8744*e4b17023SJohn Marino                             tree list)
8745*e4b17023SJohn Marino {
8746*e4b17023SJohn Marino   if (c_parser_next_token_is_not (parser, CPP_NAME)
8747*e4b17023SJohn Marino       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
8748*e4b17023SJohn Marino     c_parser_error (parser, "expected identifier");
8749*e4b17023SJohn Marino 
8750*e4b17023SJohn Marino   while (c_parser_next_token_is (parser, CPP_NAME)
8751*e4b17023SJohn Marino 	 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
8752*e4b17023SJohn Marino     {
8753*e4b17023SJohn Marino       tree t = lookup_name (c_parser_peek_token (parser)->value);
8754*e4b17023SJohn Marino 
8755*e4b17023SJohn Marino       if (t == NULL_TREE)
8756*e4b17023SJohn Marino 	undeclared_variable (c_parser_peek_token (parser)->location,
8757*e4b17023SJohn Marino 			     c_parser_peek_token (parser)->value);
8758*e4b17023SJohn Marino       else if (t == error_mark_node)
8759*e4b17023SJohn Marino 	;
8760*e4b17023SJohn Marino       else if (kind != 0)
8761*e4b17023SJohn Marino 	{
8762*e4b17023SJohn Marino 	  tree u = build_omp_clause (clause_loc, kind);
8763*e4b17023SJohn Marino 	  OMP_CLAUSE_DECL (u) = t;
8764*e4b17023SJohn Marino 	  OMP_CLAUSE_CHAIN (u) = list;
8765*e4b17023SJohn Marino 	  list = u;
8766*e4b17023SJohn Marino 	}
8767*e4b17023SJohn Marino       else
8768*e4b17023SJohn Marino 	list = tree_cons (t, NULL_TREE, list);
8769*e4b17023SJohn Marino 
8770*e4b17023SJohn Marino       c_parser_consume_token (parser);
8771*e4b17023SJohn Marino 
8772*e4b17023SJohn Marino       if (c_parser_next_token_is_not (parser, CPP_COMMA))
8773*e4b17023SJohn Marino 	break;
8774*e4b17023SJohn Marino 
8775*e4b17023SJohn Marino       c_parser_consume_token (parser);
8776*e4b17023SJohn Marino     }
8777*e4b17023SJohn Marino 
8778*e4b17023SJohn Marino   return list;
8779*e4b17023SJohn Marino }
8780*e4b17023SJohn Marino 
8781*e4b17023SJohn Marino /* Similarly, but expect leading and trailing parenthesis.  This is a very
8782*e4b17023SJohn Marino    common case for omp clauses.  */
8783*e4b17023SJohn Marino 
8784*e4b17023SJohn Marino static tree
c_parser_omp_var_list_parens(c_parser * parser,enum omp_clause_code kind,tree list)8785*e4b17023SJohn Marino c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
8786*e4b17023SJohn Marino 			      tree list)
8787*e4b17023SJohn Marino {
8788*e4b17023SJohn Marino   /* The clauses location.  */
8789*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
8790*e4b17023SJohn Marino 
8791*e4b17023SJohn Marino   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
8792*e4b17023SJohn Marino     {
8793*e4b17023SJohn Marino       list = c_parser_omp_variable_list (parser, loc, kind, list);
8794*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
8795*e4b17023SJohn Marino     }
8796*e4b17023SJohn Marino   return list;
8797*e4b17023SJohn Marino }
8798*e4b17023SJohn Marino 
8799*e4b17023SJohn Marino /* OpenMP 3.0:
8800*e4b17023SJohn Marino    collapse ( constant-expression ) */
8801*e4b17023SJohn Marino 
8802*e4b17023SJohn Marino static tree
c_parser_omp_clause_collapse(c_parser * parser,tree list)8803*e4b17023SJohn Marino c_parser_omp_clause_collapse (c_parser *parser, tree list)
8804*e4b17023SJohn Marino {
8805*e4b17023SJohn Marino   tree c, num = error_mark_node;
8806*e4b17023SJohn Marino   HOST_WIDE_INT n;
8807*e4b17023SJohn Marino   location_t loc;
8808*e4b17023SJohn Marino 
8809*e4b17023SJohn Marino   check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
8810*e4b17023SJohn Marino 
8811*e4b17023SJohn Marino   loc = c_parser_peek_token (parser)->location;
8812*e4b17023SJohn Marino   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
8813*e4b17023SJohn Marino     {
8814*e4b17023SJohn Marino       num = c_parser_expr_no_commas (parser, NULL).value;
8815*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
8816*e4b17023SJohn Marino     }
8817*e4b17023SJohn Marino   if (num == error_mark_node)
8818*e4b17023SJohn Marino     return list;
8819*e4b17023SJohn Marino   if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
8820*e4b17023SJohn Marino       || !host_integerp (num, 0)
8821*e4b17023SJohn Marino       || (n = tree_low_cst (num, 0)) <= 0
8822*e4b17023SJohn Marino       || (int) n != n)
8823*e4b17023SJohn Marino     {
8824*e4b17023SJohn Marino       error_at (loc,
8825*e4b17023SJohn Marino 		"collapse argument needs positive constant integer expression");
8826*e4b17023SJohn Marino       return list;
8827*e4b17023SJohn Marino     }
8828*e4b17023SJohn Marino   c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
8829*e4b17023SJohn Marino   OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
8830*e4b17023SJohn Marino   OMP_CLAUSE_CHAIN (c) = list;
8831*e4b17023SJohn Marino   return c;
8832*e4b17023SJohn Marino }
8833*e4b17023SJohn Marino 
8834*e4b17023SJohn Marino /* OpenMP 2.5:
8835*e4b17023SJohn Marino    copyin ( variable-list ) */
8836*e4b17023SJohn Marino 
8837*e4b17023SJohn Marino static tree
c_parser_omp_clause_copyin(c_parser * parser,tree list)8838*e4b17023SJohn Marino c_parser_omp_clause_copyin (c_parser *parser, tree list)
8839*e4b17023SJohn Marino {
8840*e4b17023SJohn Marino   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
8841*e4b17023SJohn Marino }
8842*e4b17023SJohn Marino 
8843*e4b17023SJohn Marino /* OpenMP 2.5:
8844*e4b17023SJohn Marino    copyprivate ( variable-list ) */
8845*e4b17023SJohn Marino 
8846*e4b17023SJohn Marino static tree
c_parser_omp_clause_copyprivate(c_parser * parser,tree list)8847*e4b17023SJohn Marino c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
8848*e4b17023SJohn Marino {
8849*e4b17023SJohn Marino   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
8850*e4b17023SJohn Marino }
8851*e4b17023SJohn Marino 
8852*e4b17023SJohn Marino /* OpenMP 2.5:
8853*e4b17023SJohn Marino    default ( shared | none ) */
8854*e4b17023SJohn Marino 
8855*e4b17023SJohn Marino static tree
c_parser_omp_clause_default(c_parser * parser,tree list)8856*e4b17023SJohn Marino c_parser_omp_clause_default (c_parser *parser, tree list)
8857*e4b17023SJohn Marino {
8858*e4b17023SJohn Marino   enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
8859*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
8860*e4b17023SJohn Marino   tree c;
8861*e4b17023SJohn Marino 
8862*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
8863*e4b17023SJohn Marino     return list;
8864*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_NAME))
8865*e4b17023SJohn Marino     {
8866*e4b17023SJohn Marino       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
8867*e4b17023SJohn Marino 
8868*e4b17023SJohn Marino       switch (p[0])
8869*e4b17023SJohn Marino 	{
8870*e4b17023SJohn Marino 	case 'n':
8871*e4b17023SJohn Marino 	  if (strcmp ("none", p) != 0)
8872*e4b17023SJohn Marino 	    goto invalid_kind;
8873*e4b17023SJohn Marino 	  kind = OMP_CLAUSE_DEFAULT_NONE;
8874*e4b17023SJohn Marino 	  break;
8875*e4b17023SJohn Marino 
8876*e4b17023SJohn Marino 	case 's':
8877*e4b17023SJohn Marino 	  if (strcmp ("shared", p) != 0)
8878*e4b17023SJohn Marino 	    goto invalid_kind;
8879*e4b17023SJohn Marino 	  kind = OMP_CLAUSE_DEFAULT_SHARED;
8880*e4b17023SJohn Marino 	  break;
8881*e4b17023SJohn Marino 
8882*e4b17023SJohn Marino 	default:
8883*e4b17023SJohn Marino 	  goto invalid_kind;
8884*e4b17023SJohn Marino 	}
8885*e4b17023SJohn Marino 
8886*e4b17023SJohn Marino       c_parser_consume_token (parser);
8887*e4b17023SJohn Marino     }
8888*e4b17023SJohn Marino   else
8889*e4b17023SJohn Marino     {
8890*e4b17023SJohn Marino     invalid_kind:
8891*e4b17023SJohn Marino       c_parser_error (parser, "expected %<none%> or %<shared%>");
8892*e4b17023SJohn Marino     }
8893*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
8894*e4b17023SJohn Marino 
8895*e4b17023SJohn Marino   if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
8896*e4b17023SJohn Marino     return list;
8897*e4b17023SJohn Marino 
8898*e4b17023SJohn Marino   check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
8899*e4b17023SJohn Marino   c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
8900*e4b17023SJohn Marino   OMP_CLAUSE_CHAIN (c) = list;
8901*e4b17023SJohn Marino   OMP_CLAUSE_DEFAULT_KIND (c) = kind;
8902*e4b17023SJohn Marino 
8903*e4b17023SJohn Marino   return c;
8904*e4b17023SJohn Marino }
8905*e4b17023SJohn Marino 
8906*e4b17023SJohn Marino /* OpenMP 2.5:
8907*e4b17023SJohn Marino    firstprivate ( variable-list ) */
8908*e4b17023SJohn Marino 
8909*e4b17023SJohn Marino static tree
c_parser_omp_clause_firstprivate(c_parser * parser,tree list)8910*e4b17023SJohn Marino c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
8911*e4b17023SJohn Marino {
8912*e4b17023SJohn Marino   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
8913*e4b17023SJohn Marino }
8914*e4b17023SJohn Marino 
8915*e4b17023SJohn Marino /* OpenMP 3.1:
8916*e4b17023SJohn Marino    final ( expression ) */
8917*e4b17023SJohn Marino 
8918*e4b17023SJohn Marino static tree
c_parser_omp_clause_final(c_parser * parser,tree list)8919*e4b17023SJohn Marino c_parser_omp_clause_final (c_parser *parser, tree list)
8920*e4b17023SJohn Marino {
8921*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
8922*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
8923*e4b17023SJohn Marino     {
8924*e4b17023SJohn Marino       tree t = c_parser_paren_condition (parser);
8925*e4b17023SJohn Marino       tree c;
8926*e4b17023SJohn Marino 
8927*e4b17023SJohn Marino       check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
8928*e4b17023SJohn Marino 
8929*e4b17023SJohn Marino       c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
8930*e4b17023SJohn Marino       OMP_CLAUSE_FINAL_EXPR (c) = t;
8931*e4b17023SJohn Marino       OMP_CLAUSE_CHAIN (c) = list;
8932*e4b17023SJohn Marino       list = c;
8933*e4b17023SJohn Marino     }
8934*e4b17023SJohn Marino   else
8935*e4b17023SJohn Marino     c_parser_error (parser, "expected %<(%>");
8936*e4b17023SJohn Marino 
8937*e4b17023SJohn Marino   return list;
8938*e4b17023SJohn Marino }
8939*e4b17023SJohn Marino 
8940*e4b17023SJohn Marino /* OpenMP 2.5:
8941*e4b17023SJohn Marino    if ( expression ) */
8942*e4b17023SJohn Marino 
8943*e4b17023SJohn Marino static tree
c_parser_omp_clause_if(c_parser * parser,tree list)8944*e4b17023SJohn Marino c_parser_omp_clause_if (c_parser *parser, tree list)
8945*e4b17023SJohn Marino {
8946*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
8947*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
8948*e4b17023SJohn Marino     {
8949*e4b17023SJohn Marino       tree t = c_parser_paren_condition (parser);
8950*e4b17023SJohn Marino       tree c;
8951*e4b17023SJohn Marino 
8952*e4b17023SJohn Marino       check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if");
8953*e4b17023SJohn Marino 
8954*e4b17023SJohn Marino       c = build_omp_clause (loc, OMP_CLAUSE_IF);
8955*e4b17023SJohn Marino       OMP_CLAUSE_IF_EXPR (c) = t;
8956*e4b17023SJohn Marino       OMP_CLAUSE_CHAIN (c) = list;
8957*e4b17023SJohn Marino       list = c;
8958*e4b17023SJohn Marino     }
8959*e4b17023SJohn Marino   else
8960*e4b17023SJohn Marino     c_parser_error (parser, "expected %<(%>");
8961*e4b17023SJohn Marino 
8962*e4b17023SJohn Marino   return list;
8963*e4b17023SJohn Marino }
8964*e4b17023SJohn Marino 
8965*e4b17023SJohn Marino /* OpenMP 2.5:
8966*e4b17023SJohn Marino    lastprivate ( variable-list ) */
8967*e4b17023SJohn Marino 
8968*e4b17023SJohn Marino static tree
c_parser_omp_clause_lastprivate(c_parser * parser,tree list)8969*e4b17023SJohn Marino c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
8970*e4b17023SJohn Marino {
8971*e4b17023SJohn Marino   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LASTPRIVATE, list);
8972*e4b17023SJohn Marino }
8973*e4b17023SJohn Marino 
8974*e4b17023SJohn Marino /* OpenMP 3.1:
8975*e4b17023SJohn Marino    mergeable */
8976*e4b17023SJohn Marino 
8977*e4b17023SJohn Marino static tree
c_parser_omp_clause_mergeable(c_parser * parser ATTRIBUTE_UNUSED,tree list)8978*e4b17023SJohn Marino c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
8979*e4b17023SJohn Marino {
8980*e4b17023SJohn Marino   tree c;
8981*e4b17023SJohn Marino 
8982*e4b17023SJohn Marino   /* FIXME: Should we allow duplicates?  */
8983*e4b17023SJohn Marino   check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
8984*e4b17023SJohn Marino 
8985*e4b17023SJohn Marino   c = build_omp_clause (c_parser_peek_token (parser)->location,
8986*e4b17023SJohn Marino 			OMP_CLAUSE_MERGEABLE);
8987*e4b17023SJohn Marino   OMP_CLAUSE_CHAIN (c) = list;
8988*e4b17023SJohn Marino 
8989*e4b17023SJohn Marino   return c;
8990*e4b17023SJohn Marino }
8991*e4b17023SJohn Marino 
8992*e4b17023SJohn Marino /* OpenMP 2.5:
8993*e4b17023SJohn Marino    nowait */
8994*e4b17023SJohn Marino 
8995*e4b17023SJohn Marino static tree
c_parser_omp_clause_nowait(c_parser * parser ATTRIBUTE_UNUSED,tree list)8996*e4b17023SJohn Marino c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
8997*e4b17023SJohn Marino {
8998*e4b17023SJohn Marino   tree c;
8999*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
9000*e4b17023SJohn Marino 
9001*e4b17023SJohn Marino   check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
9002*e4b17023SJohn Marino 
9003*e4b17023SJohn Marino   c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
9004*e4b17023SJohn Marino   OMP_CLAUSE_CHAIN (c) = list;
9005*e4b17023SJohn Marino   return c;
9006*e4b17023SJohn Marino }
9007*e4b17023SJohn Marino 
9008*e4b17023SJohn Marino /* OpenMP 2.5:
9009*e4b17023SJohn Marino    num_threads ( expression ) */
9010*e4b17023SJohn Marino 
9011*e4b17023SJohn Marino static tree
c_parser_omp_clause_num_threads(c_parser * parser,tree list)9012*e4b17023SJohn Marino c_parser_omp_clause_num_threads (c_parser *parser, tree list)
9013*e4b17023SJohn Marino {
9014*e4b17023SJohn Marino   location_t num_threads_loc = c_parser_peek_token (parser)->location;
9015*e4b17023SJohn Marino   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
9016*e4b17023SJohn Marino     {
9017*e4b17023SJohn Marino       location_t expr_loc = c_parser_peek_token (parser)->location;
9018*e4b17023SJohn Marino       tree c, t = c_parser_expression (parser).value;
9019*e4b17023SJohn Marino       mark_exp_read (t);
9020*e4b17023SJohn Marino       t = c_fully_fold (t, false, NULL);
9021*e4b17023SJohn Marino 
9022*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
9023*e4b17023SJohn Marino 
9024*e4b17023SJohn Marino       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
9025*e4b17023SJohn Marino 	{
9026*e4b17023SJohn Marino 	  c_parser_error (parser, "expected integer expression");
9027*e4b17023SJohn Marino 	  return list;
9028*e4b17023SJohn Marino 	}
9029*e4b17023SJohn Marino 
9030*e4b17023SJohn Marino       /* Attempt to statically determine when the number isn't positive.  */
9031*e4b17023SJohn Marino       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
9032*e4b17023SJohn Marino 		       build_int_cst (TREE_TYPE (t), 0));
9033*e4b17023SJohn Marino       if (CAN_HAVE_LOCATION_P (c))
9034*e4b17023SJohn Marino 	SET_EXPR_LOCATION (c, expr_loc);
9035*e4b17023SJohn Marino       if (c == boolean_true_node)
9036*e4b17023SJohn Marino 	{
9037*e4b17023SJohn Marino 	  warning_at (expr_loc, 0,
9038*e4b17023SJohn Marino 		      "%<num_threads%> value must be positive");
9039*e4b17023SJohn Marino 	  t = integer_one_node;
9040*e4b17023SJohn Marino 	}
9041*e4b17023SJohn Marino 
9042*e4b17023SJohn Marino       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
9043*e4b17023SJohn Marino 
9044*e4b17023SJohn Marino       c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
9045*e4b17023SJohn Marino       OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
9046*e4b17023SJohn Marino       OMP_CLAUSE_CHAIN (c) = list;
9047*e4b17023SJohn Marino       list = c;
9048*e4b17023SJohn Marino     }
9049*e4b17023SJohn Marino 
9050*e4b17023SJohn Marino   return list;
9051*e4b17023SJohn Marino }
9052*e4b17023SJohn Marino 
9053*e4b17023SJohn Marino /* OpenMP 2.5:
9054*e4b17023SJohn Marino    ordered */
9055*e4b17023SJohn Marino 
9056*e4b17023SJohn Marino static tree
c_parser_omp_clause_ordered(c_parser * parser,tree list)9057*e4b17023SJohn Marino c_parser_omp_clause_ordered (c_parser *parser, tree list)
9058*e4b17023SJohn Marino {
9059*e4b17023SJohn Marino   tree c;
9060*e4b17023SJohn Marino 
9061*e4b17023SJohn Marino   check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
9062*e4b17023SJohn Marino 
9063*e4b17023SJohn Marino   c = build_omp_clause (c_parser_peek_token (parser)->location,
9064*e4b17023SJohn Marino 			OMP_CLAUSE_ORDERED);
9065*e4b17023SJohn Marino   OMP_CLAUSE_CHAIN (c) = list;
9066*e4b17023SJohn Marino 
9067*e4b17023SJohn Marino   return c;
9068*e4b17023SJohn Marino }
9069*e4b17023SJohn Marino 
9070*e4b17023SJohn Marino /* OpenMP 2.5:
9071*e4b17023SJohn Marino    private ( variable-list ) */
9072*e4b17023SJohn Marino 
9073*e4b17023SJohn Marino static tree
c_parser_omp_clause_private(c_parser * parser,tree list)9074*e4b17023SJohn Marino c_parser_omp_clause_private (c_parser *parser, tree list)
9075*e4b17023SJohn Marino {
9076*e4b17023SJohn Marino   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
9077*e4b17023SJohn Marino }
9078*e4b17023SJohn Marino 
9079*e4b17023SJohn Marino /* OpenMP 2.5:
9080*e4b17023SJohn Marino    reduction ( reduction-operator : variable-list )
9081*e4b17023SJohn Marino 
9082*e4b17023SJohn Marino    reduction-operator:
9083*e4b17023SJohn Marino      One of: + * - & ^ | && ||
9084*e4b17023SJohn Marino 
9085*e4b17023SJohn Marino    OpenMP 3.1:
9086*e4b17023SJohn Marino 
9087*e4b17023SJohn Marino    reduction-operator:
9088*e4b17023SJohn Marino      One of: + * - & ^ | && || max min  */
9089*e4b17023SJohn Marino 
9090*e4b17023SJohn Marino static tree
c_parser_omp_clause_reduction(c_parser * parser,tree list)9091*e4b17023SJohn Marino c_parser_omp_clause_reduction (c_parser *parser, tree list)
9092*e4b17023SJohn Marino {
9093*e4b17023SJohn Marino   location_t clause_loc = c_parser_peek_token (parser)->location;
9094*e4b17023SJohn Marino   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
9095*e4b17023SJohn Marino     {
9096*e4b17023SJohn Marino       enum tree_code code;
9097*e4b17023SJohn Marino 
9098*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->type)
9099*e4b17023SJohn Marino 	{
9100*e4b17023SJohn Marino 	case CPP_PLUS:
9101*e4b17023SJohn Marino 	  code = PLUS_EXPR;
9102*e4b17023SJohn Marino 	  break;
9103*e4b17023SJohn Marino 	case CPP_MULT:
9104*e4b17023SJohn Marino 	  code = MULT_EXPR;
9105*e4b17023SJohn Marino 	  break;
9106*e4b17023SJohn Marino 	case CPP_MINUS:
9107*e4b17023SJohn Marino 	  code = MINUS_EXPR;
9108*e4b17023SJohn Marino 	  break;
9109*e4b17023SJohn Marino 	case CPP_AND:
9110*e4b17023SJohn Marino 	  code = BIT_AND_EXPR;
9111*e4b17023SJohn Marino 	  break;
9112*e4b17023SJohn Marino 	case CPP_XOR:
9113*e4b17023SJohn Marino 	  code = BIT_XOR_EXPR;
9114*e4b17023SJohn Marino 	  break;
9115*e4b17023SJohn Marino 	case CPP_OR:
9116*e4b17023SJohn Marino 	  code = BIT_IOR_EXPR;
9117*e4b17023SJohn Marino 	  break;
9118*e4b17023SJohn Marino 	case CPP_AND_AND:
9119*e4b17023SJohn Marino 	  code = TRUTH_ANDIF_EXPR;
9120*e4b17023SJohn Marino 	  break;
9121*e4b17023SJohn Marino 	case CPP_OR_OR:
9122*e4b17023SJohn Marino 	  code = TRUTH_ORIF_EXPR;
9123*e4b17023SJohn Marino 	  break;
9124*e4b17023SJohn Marino         case CPP_NAME:
9125*e4b17023SJohn Marino 	  {
9126*e4b17023SJohn Marino 	    const char *p
9127*e4b17023SJohn Marino 	      = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
9128*e4b17023SJohn Marino 	    if (strcmp (p, "min") == 0)
9129*e4b17023SJohn Marino 	      {
9130*e4b17023SJohn Marino 		code = MIN_EXPR;
9131*e4b17023SJohn Marino 		break;
9132*e4b17023SJohn Marino 	      }
9133*e4b17023SJohn Marino 	    if (strcmp (p, "max") == 0)
9134*e4b17023SJohn Marino 	      {
9135*e4b17023SJohn Marino 		code = MAX_EXPR;
9136*e4b17023SJohn Marino 		break;
9137*e4b17023SJohn Marino 	      }
9138*e4b17023SJohn Marino 	  }
9139*e4b17023SJohn Marino 	  /* FALLTHRU */
9140*e4b17023SJohn Marino 	default:
9141*e4b17023SJohn Marino 	  c_parser_error (parser,
9142*e4b17023SJohn Marino 			  "expected %<+%>, %<*%>, %<-%>, %<&%>, "
9143*e4b17023SJohn Marino 			  "%<^%>, %<|%>, %<&&%>, %<||%>, %<min%> or %<max%>");
9144*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
9145*e4b17023SJohn Marino 	  return list;
9146*e4b17023SJohn Marino 	}
9147*e4b17023SJohn Marino       c_parser_consume_token (parser);
9148*e4b17023SJohn Marino       if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
9149*e4b17023SJohn Marino 	{
9150*e4b17023SJohn Marino 	  tree nl, c;
9151*e4b17023SJohn Marino 
9152*e4b17023SJohn Marino 	  nl = c_parser_omp_variable_list (parser, clause_loc,
9153*e4b17023SJohn Marino 					   OMP_CLAUSE_REDUCTION, list);
9154*e4b17023SJohn Marino 	  for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
9155*e4b17023SJohn Marino 	    OMP_CLAUSE_REDUCTION_CODE (c) = code;
9156*e4b17023SJohn Marino 
9157*e4b17023SJohn Marino 	  list = nl;
9158*e4b17023SJohn Marino 	}
9159*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
9160*e4b17023SJohn Marino     }
9161*e4b17023SJohn Marino   return list;
9162*e4b17023SJohn Marino }
9163*e4b17023SJohn Marino 
9164*e4b17023SJohn Marino /* OpenMP 2.5:
9165*e4b17023SJohn Marino    schedule ( schedule-kind )
9166*e4b17023SJohn Marino    schedule ( schedule-kind , expression )
9167*e4b17023SJohn Marino 
9168*e4b17023SJohn Marino    schedule-kind:
9169*e4b17023SJohn Marino      static | dynamic | guided | runtime | auto
9170*e4b17023SJohn Marino */
9171*e4b17023SJohn Marino 
9172*e4b17023SJohn Marino static tree
c_parser_omp_clause_schedule(c_parser * parser,tree list)9173*e4b17023SJohn Marino c_parser_omp_clause_schedule (c_parser *parser, tree list)
9174*e4b17023SJohn Marino {
9175*e4b17023SJohn Marino   tree c, t;
9176*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
9177*e4b17023SJohn Marino 
9178*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
9179*e4b17023SJohn Marino     return list;
9180*e4b17023SJohn Marino 
9181*e4b17023SJohn Marino   c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
9182*e4b17023SJohn Marino 
9183*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_NAME))
9184*e4b17023SJohn Marino     {
9185*e4b17023SJohn Marino       tree kind = c_parser_peek_token (parser)->value;
9186*e4b17023SJohn Marino       const char *p = IDENTIFIER_POINTER (kind);
9187*e4b17023SJohn Marino 
9188*e4b17023SJohn Marino       switch (p[0])
9189*e4b17023SJohn Marino 	{
9190*e4b17023SJohn Marino 	case 'd':
9191*e4b17023SJohn Marino 	  if (strcmp ("dynamic", p) != 0)
9192*e4b17023SJohn Marino 	    goto invalid_kind;
9193*e4b17023SJohn Marino 	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
9194*e4b17023SJohn Marino 	  break;
9195*e4b17023SJohn Marino 
9196*e4b17023SJohn Marino         case 'g':
9197*e4b17023SJohn Marino 	  if (strcmp ("guided", p) != 0)
9198*e4b17023SJohn Marino 	    goto invalid_kind;
9199*e4b17023SJohn Marino 	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
9200*e4b17023SJohn Marino 	  break;
9201*e4b17023SJohn Marino 
9202*e4b17023SJohn Marino 	case 'r':
9203*e4b17023SJohn Marino 	  if (strcmp ("runtime", p) != 0)
9204*e4b17023SJohn Marino 	    goto invalid_kind;
9205*e4b17023SJohn Marino 	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
9206*e4b17023SJohn Marino 	  break;
9207*e4b17023SJohn Marino 
9208*e4b17023SJohn Marino 	default:
9209*e4b17023SJohn Marino 	  goto invalid_kind;
9210*e4b17023SJohn Marino 	}
9211*e4b17023SJohn Marino     }
9212*e4b17023SJohn Marino   else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
9213*e4b17023SJohn Marino     OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
9214*e4b17023SJohn Marino   else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
9215*e4b17023SJohn Marino     OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
9216*e4b17023SJohn Marino   else
9217*e4b17023SJohn Marino     goto invalid_kind;
9218*e4b17023SJohn Marino 
9219*e4b17023SJohn Marino   c_parser_consume_token (parser);
9220*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_COMMA))
9221*e4b17023SJohn Marino     {
9222*e4b17023SJohn Marino       location_t here;
9223*e4b17023SJohn Marino       c_parser_consume_token (parser);
9224*e4b17023SJohn Marino 
9225*e4b17023SJohn Marino       here = c_parser_peek_token (parser)->location;
9226*e4b17023SJohn Marino       t = c_parser_expr_no_commas (parser, NULL).value;
9227*e4b17023SJohn Marino       mark_exp_read (t);
9228*e4b17023SJohn Marino       t = c_fully_fold (t, false, NULL);
9229*e4b17023SJohn Marino 
9230*e4b17023SJohn Marino       if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
9231*e4b17023SJohn Marino 	error_at (here, "schedule %<runtime%> does not take "
9232*e4b17023SJohn Marino 		  "a %<chunk_size%> parameter");
9233*e4b17023SJohn Marino       else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
9234*e4b17023SJohn Marino 	error_at (here,
9235*e4b17023SJohn Marino 		  "schedule %<auto%> does not take "
9236*e4b17023SJohn Marino 		  "a %<chunk_size%> parameter");
9237*e4b17023SJohn Marino       else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
9238*e4b17023SJohn Marino 	OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
9239*e4b17023SJohn Marino       else
9240*e4b17023SJohn Marino 	c_parser_error (parser, "expected integer expression");
9241*e4b17023SJohn Marino 
9242*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
9243*e4b17023SJohn Marino     }
9244*e4b17023SJohn Marino   else
9245*e4b17023SJohn Marino     c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9246*e4b17023SJohn Marino 			       "expected %<,%> or %<)%>");
9247*e4b17023SJohn Marino 
9248*e4b17023SJohn Marino   check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
9249*e4b17023SJohn Marino   OMP_CLAUSE_CHAIN (c) = list;
9250*e4b17023SJohn Marino   return c;
9251*e4b17023SJohn Marino 
9252*e4b17023SJohn Marino  invalid_kind:
9253*e4b17023SJohn Marino   c_parser_error (parser, "invalid schedule kind");
9254*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
9255*e4b17023SJohn Marino   return list;
9256*e4b17023SJohn Marino }
9257*e4b17023SJohn Marino 
9258*e4b17023SJohn Marino /* OpenMP 2.5:
9259*e4b17023SJohn Marino    shared ( variable-list ) */
9260*e4b17023SJohn Marino 
9261*e4b17023SJohn Marino static tree
c_parser_omp_clause_shared(c_parser * parser,tree list)9262*e4b17023SJohn Marino c_parser_omp_clause_shared (c_parser *parser, tree list)
9263*e4b17023SJohn Marino {
9264*e4b17023SJohn Marino   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
9265*e4b17023SJohn Marino }
9266*e4b17023SJohn Marino 
9267*e4b17023SJohn Marino /* OpenMP 3.0:
9268*e4b17023SJohn Marino    untied */
9269*e4b17023SJohn Marino 
9270*e4b17023SJohn Marino static tree
c_parser_omp_clause_untied(c_parser * parser ATTRIBUTE_UNUSED,tree list)9271*e4b17023SJohn Marino c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
9272*e4b17023SJohn Marino {
9273*e4b17023SJohn Marino   tree c;
9274*e4b17023SJohn Marino 
9275*e4b17023SJohn Marino   /* FIXME: Should we allow duplicates?  */
9276*e4b17023SJohn Marino   check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
9277*e4b17023SJohn Marino 
9278*e4b17023SJohn Marino   c = build_omp_clause (c_parser_peek_token (parser)->location,
9279*e4b17023SJohn Marino 			OMP_CLAUSE_UNTIED);
9280*e4b17023SJohn Marino   OMP_CLAUSE_CHAIN (c) = list;
9281*e4b17023SJohn Marino 
9282*e4b17023SJohn Marino   return c;
9283*e4b17023SJohn Marino }
9284*e4b17023SJohn Marino 
9285*e4b17023SJohn Marino /* Parse all OpenMP clauses.  The set clauses allowed by the directive
9286*e4b17023SJohn Marino    is a bitmask in MASK.  Return the list of clauses found; the result
9287*e4b17023SJohn Marino    of clause default goes in *pdefault.  */
9288*e4b17023SJohn Marino 
9289*e4b17023SJohn Marino static tree
c_parser_omp_all_clauses(c_parser * parser,unsigned int mask,const char * where)9290*e4b17023SJohn Marino c_parser_omp_all_clauses (c_parser *parser, unsigned int mask,
9291*e4b17023SJohn Marino 			  const char *where)
9292*e4b17023SJohn Marino {
9293*e4b17023SJohn Marino   tree clauses = NULL;
9294*e4b17023SJohn Marino   bool first = true;
9295*e4b17023SJohn Marino 
9296*e4b17023SJohn Marino   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
9297*e4b17023SJohn Marino     {
9298*e4b17023SJohn Marino       location_t here;
9299*e4b17023SJohn Marino       pragma_omp_clause c_kind;
9300*e4b17023SJohn Marino       const char *c_name;
9301*e4b17023SJohn Marino       tree prev = clauses;
9302*e4b17023SJohn Marino 
9303*e4b17023SJohn Marino       if (!first && c_parser_next_token_is (parser, CPP_COMMA))
9304*e4b17023SJohn Marino 	c_parser_consume_token (parser);
9305*e4b17023SJohn Marino 
9306*e4b17023SJohn Marino       first = false;
9307*e4b17023SJohn Marino       here = c_parser_peek_token (parser)->location;
9308*e4b17023SJohn Marino       c_kind = c_parser_omp_clause_name (parser);
9309*e4b17023SJohn Marino 
9310*e4b17023SJohn Marino       switch (c_kind)
9311*e4b17023SJohn Marino 	{
9312*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_COLLAPSE:
9313*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_collapse (parser, clauses);
9314*e4b17023SJohn Marino 	  c_name = "collapse";
9315*e4b17023SJohn Marino 	  break;
9316*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_COPYIN:
9317*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_copyin (parser, clauses);
9318*e4b17023SJohn Marino 	  c_name = "copyin";
9319*e4b17023SJohn Marino 	  break;
9320*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
9321*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_copyprivate (parser, clauses);
9322*e4b17023SJohn Marino 	  c_name = "copyprivate";
9323*e4b17023SJohn Marino 	  break;
9324*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_DEFAULT:
9325*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_default (parser, clauses);
9326*e4b17023SJohn Marino 	  c_name = "default";
9327*e4b17023SJohn Marino 	  break;
9328*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
9329*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_firstprivate (parser, clauses);
9330*e4b17023SJohn Marino 	  c_name = "firstprivate";
9331*e4b17023SJohn Marino 	  break;
9332*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_FINAL:
9333*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_final (parser, clauses);
9334*e4b17023SJohn Marino 	  c_name = "final";
9335*e4b17023SJohn Marino 	  break;
9336*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_IF:
9337*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_if (parser, clauses);
9338*e4b17023SJohn Marino 	  c_name = "if";
9339*e4b17023SJohn Marino 	  break;
9340*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
9341*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_lastprivate (parser, clauses);
9342*e4b17023SJohn Marino 	  c_name = "lastprivate";
9343*e4b17023SJohn Marino 	  break;
9344*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_MERGEABLE:
9345*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_mergeable (parser, clauses);
9346*e4b17023SJohn Marino 	  c_name = "mergeable";
9347*e4b17023SJohn Marino 	  break;
9348*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_NOWAIT:
9349*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_nowait (parser, clauses);
9350*e4b17023SJohn Marino 	  c_name = "nowait";
9351*e4b17023SJohn Marino 	  break;
9352*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_NUM_THREADS:
9353*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_num_threads (parser, clauses);
9354*e4b17023SJohn Marino 	  c_name = "num_threads";
9355*e4b17023SJohn Marino 	  break;
9356*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_ORDERED:
9357*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_ordered (parser, clauses);
9358*e4b17023SJohn Marino 	  c_name = "ordered";
9359*e4b17023SJohn Marino 	  break;
9360*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_PRIVATE:
9361*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_private (parser, clauses);
9362*e4b17023SJohn Marino 	  c_name = "private";
9363*e4b17023SJohn Marino 	  break;
9364*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_REDUCTION:
9365*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_reduction (parser, clauses);
9366*e4b17023SJohn Marino 	  c_name = "reduction";
9367*e4b17023SJohn Marino 	  break;
9368*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_SCHEDULE:
9369*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_schedule (parser, clauses);
9370*e4b17023SJohn Marino 	  c_name = "schedule";
9371*e4b17023SJohn Marino 	  break;
9372*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_SHARED:
9373*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_shared (parser, clauses);
9374*e4b17023SJohn Marino 	  c_name = "shared";
9375*e4b17023SJohn Marino 	  break;
9376*e4b17023SJohn Marino 	case PRAGMA_OMP_CLAUSE_UNTIED:
9377*e4b17023SJohn Marino 	  clauses = c_parser_omp_clause_untied (parser, clauses);
9378*e4b17023SJohn Marino 	  c_name = "untied";
9379*e4b17023SJohn Marino 	  break;
9380*e4b17023SJohn Marino 	default:
9381*e4b17023SJohn Marino 	  c_parser_error (parser, "expected %<#pragma omp%> clause");
9382*e4b17023SJohn Marino 	  goto saw_error;
9383*e4b17023SJohn Marino 	}
9384*e4b17023SJohn Marino 
9385*e4b17023SJohn Marino       if (((mask >> c_kind) & 1) == 0 && !parser->error)
9386*e4b17023SJohn Marino 	{
9387*e4b17023SJohn Marino 	  /* Remove the invalid clause(s) from the list to avoid
9388*e4b17023SJohn Marino 	     confusing the rest of the compiler.  */
9389*e4b17023SJohn Marino 	  clauses = prev;
9390*e4b17023SJohn Marino 	  error_at (here, "%qs is not valid for %qs", c_name, where);
9391*e4b17023SJohn Marino 	}
9392*e4b17023SJohn Marino     }
9393*e4b17023SJohn Marino 
9394*e4b17023SJohn Marino  saw_error:
9395*e4b17023SJohn Marino   c_parser_skip_to_pragma_eol (parser);
9396*e4b17023SJohn Marino 
9397*e4b17023SJohn Marino   return c_finish_omp_clauses (clauses);
9398*e4b17023SJohn Marino }
9399*e4b17023SJohn Marino 
9400*e4b17023SJohn Marino /* OpenMP 2.5:
9401*e4b17023SJohn Marino    structured-block:
9402*e4b17023SJohn Marino      statement
9403*e4b17023SJohn Marino 
9404*e4b17023SJohn Marino    In practice, we're also interested in adding the statement to an
9405*e4b17023SJohn Marino    outer node.  So it is convenient if we work around the fact that
9406*e4b17023SJohn Marino    c_parser_statement calls add_stmt.  */
9407*e4b17023SJohn Marino 
9408*e4b17023SJohn Marino static tree
c_parser_omp_structured_block(c_parser * parser)9409*e4b17023SJohn Marino c_parser_omp_structured_block (c_parser *parser)
9410*e4b17023SJohn Marino {
9411*e4b17023SJohn Marino   tree stmt = push_stmt_list ();
9412*e4b17023SJohn Marino   c_parser_statement (parser);
9413*e4b17023SJohn Marino   return pop_stmt_list (stmt);
9414*e4b17023SJohn Marino }
9415*e4b17023SJohn Marino 
9416*e4b17023SJohn Marino /* OpenMP 2.5:
9417*e4b17023SJohn Marino    # pragma omp atomic new-line
9418*e4b17023SJohn Marino      expression-stmt
9419*e4b17023SJohn Marino 
9420*e4b17023SJohn Marino    expression-stmt:
9421*e4b17023SJohn Marino      x binop= expr | x++ | ++x | x-- | --x
9422*e4b17023SJohn Marino    binop:
9423*e4b17023SJohn Marino      +, *, -, /, &, ^, |, <<, >>
9424*e4b17023SJohn Marino 
9425*e4b17023SJohn Marino   where x is an lvalue expression with scalar type.
9426*e4b17023SJohn Marino 
9427*e4b17023SJohn Marino    OpenMP 3.1:
9428*e4b17023SJohn Marino    # pragma omp atomic new-line
9429*e4b17023SJohn Marino      update-stmt
9430*e4b17023SJohn Marino 
9431*e4b17023SJohn Marino    # pragma omp atomic read new-line
9432*e4b17023SJohn Marino      read-stmt
9433*e4b17023SJohn Marino 
9434*e4b17023SJohn Marino    # pragma omp atomic write new-line
9435*e4b17023SJohn Marino      write-stmt
9436*e4b17023SJohn Marino 
9437*e4b17023SJohn Marino    # pragma omp atomic update new-line
9438*e4b17023SJohn Marino      update-stmt
9439*e4b17023SJohn Marino 
9440*e4b17023SJohn Marino    # pragma omp atomic capture new-line
9441*e4b17023SJohn Marino      capture-stmt
9442*e4b17023SJohn Marino 
9443*e4b17023SJohn Marino    # pragma omp atomic capture new-line
9444*e4b17023SJohn Marino      capture-block
9445*e4b17023SJohn Marino 
9446*e4b17023SJohn Marino    read-stmt:
9447*e4b17023SJohn Marino      v = x
9448*e4b17023SJohn Marino    write-stmt:
9449*e4b17023SJohn Marino      x = expr
9450*e4b17023SJohn Marino    update-stmt:
9451*e4b17023SJohn Marino      expression-stmt | x = x binop expr
9452*e4b17023SJohn Marino    capture-stmt:
9453*e4b17023SJohn Marino      v = x binop= expr | v = x++ | v = ++x | v = x-- | v = --x
9454*e4b17023SJohn Marino    capture-block:
9455*e4b17023SJohn Marino      { v = x; update-stmt; } | { update-stmt; v = x; }
9456*e4b17023SJohn Marino 
9457*e4b17023SJohn Marino   where x and v are lvalue expressions with scalar type.
9458*e4b17023SJohn Marino 
9459*e4b17023SJohn Marino   LOC is the location of the #pragma token.  */
9460*e4b17023SJohn Marino 
9461*e4b17023SJohn Marino static void
c_parser_omp_atomic(location_t loc,c_parser * parser)9462*e4b17023SJohn Marino c_parser_omp_atomic (location_t loc, c_parser *parser)
9463*e4b17023SJohn Marino {
9464*e4b17023SJohn Marino   tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE;
9465*e4b17023SJohn Marino   tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
9466*e4b17023SJohn Marino   tree stmt, orig_lhs;
9467*e4b17023SJohn Marino   enum tree_code code = OMP_ATOMIC, opcode = NOP_EXPR;
9468*e4b17023SJohn Marino   struct c_expr rhs_expr;
9469*e4b17023SJohn Marino   bool structured_block = false;
9470*e4b17023SJohn Marino 
9471*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_NAME))
9472*e4b17023SJohn Marino     {
9473*e4b17023SJohn Marino       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
9474*e4b17023SJohn Marino 
9475*e4b17023SJohn Marino       if (!strcmp (p, "read"))
9476*e4b17023SJohn Marino 	code = OMP_ATOMIC_READ;
9477*e4b17023SJohn Marino       else if (!strcmp (p, "write"))
9478*e4b17023SJohn Marino 	code = NOP_EXPR;
9479*e4b17023SJohn Marino       else if (!strcmp (p, "update"))
9480*e4b17023SJohn Marino 	code = OMP_ATOMIC;
9481*e4b17023SJohn Marino       else if (!strcmp (p, "capture"))
9482*e4b17023SJohn Marino 	code = OMP_ATOMIC_CAPTURE_NEW;
9483*e4b17023SJohn Marino       else
9484*e4b17023SJohn Marino 	p = NULL;
9485*e4b17023SJohn Marino       if (p)
9486*e4b17023SJohn Marino 	c_parser_consume_token (parser);
9487*e4b17023SJohn Marino     }
9488*e4b17023SJohn Marino   c_parser_skip_to_pragma_eol (parser);
9489*e4b17023SJohn Marino 
9490*e4b17023SJohn Marino   switch (code)
9491*e4b17023SJohn Marino     {
9492*e4b17023SJohn Marino     case OMP_ATOMIC_READ:
9493*e4b17023SJohn Marino     case NOP_EXPR: /* atomic write */
9494*e4b17023SJohn Marino       v = c_parser_unary_expression (parser).value;
9495*e4b17023SJohn Marino       v = c_fully_fold (v, false, NULL);
9496*e4b17023SJohn Marino       if (v == error_mark_node)
9497*e4b17023SJohn Marino 	goto saw_error;
9498*e4b17023SJohn Marino       loc = c_parser_peek_token (parser)->location;
9499*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
9500*e4b17023SJohn Marino 	goto saw_error;
9501*e4b17023SJohn Marino       if (code == NOP_EXPR)
9502*e4b17023SJohn Marino 	lhs = c_parser_expression (parser).value;
9503*e4b17023SJohn Marino       else
9504*e4b17023SJohn Marino 	lhs = c_parser_unary_expression (parser).value;
9505*e4b17023SJohn Marino       lhs = c_fully_fold (lhs, false, NULL);
9506*e4b17023SJohn Marino       if (lhs == error_mark_node)
9507*e4b17023SJohn Marino 	goto saw_error;
9508*e4b17023SJohn Marino       if (code == NOP_EXPR)
9509*e4b17023SJohn Marino 	{
9510*e4b17023SJohn Marino 	  /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
9511*e4b17023SJohn Marino 	     opcode.  */
9512*e4b17023SJohn Marino 	  code = OMP_ATOMIC;
9513*e4b17023SJohn Marino 	  rhs = lhs;
9514*e4b17023SJohn Marino 	  lhs = v;
9515*e4b17023SJohn Marino 	  v = NULL_TREE;
9516*e4b17023SJohn Marino 	}
9517*e4b17023SJohn Marino       goto done;
9518*e4b17023SJohn Marino     case OMP_ATOMIC_CAPTURE_NEW:
9519*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9520*e4b17023SJohn Marino 	{
9521*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
9522*e4b17023SJohn Marino 	  structured_block = true;
9523*e4b17023SJohn Marino 	}
9524*e4b17023SJohn Marino       else
9525*e4b17023SJohn Marino 	{
9526*e4b17023SJohn Marino 	  v = c_parser_unary_expression (parser).value;
9527*e4b17023SJohn Marino 	  v = c_fully_fold (v, false, NULL);
9528*e4b17023SJohn Marino 	  if (v == error_mark_node)
9529*e4b17023SJohn Marino 	    goto saw_error;
9530*e4b17023SJohn Marino 	  if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
9531*e4b17023SJohn Marino 	    goto saw_error;
9532*e4b17023SJohn Marino 	}
9533*e4b17023SJohn Marino       break;
9534*e4b17023SJohn Marino     default:
9535*e4b17023SJohn Marino       break;
9536*e4b17023SJohn Marino     }
9537*e4b17023SJohn Marino 
9538*e4b17023SJohn Marino   /* For structured_block case we don't know yet whether
9539*e4b17023SJohn Marino      old or new x should be captured.  */
9540*e4b17023SJohn Marino restart:
9541*e4b17023SJohn Marino   lhs = c_parser_unary_expression (parser).value;
9542*e4b17023SJohn Marino   lhs = c_fully_fold (lhs, false, NULL);
9543*e4b17023SJohn Marino   orig_lhs = lhs;
9544*e4b17023SJohn Marino   switch (TREE_CODE (lhs))
9545*e4b17023SJohn Marino     {
9546*e4b17023SJohn Marino     case ERROR_MARK:
9547*e4b17023SJohn Marino     saw_error:
9548*e4b17023SJohn Marino       c_parser_skip_to_end_of_block_or_statement (parser);
9549*e4b17023SJohn Marino       if (structured_block)
9550*e4b17023SJohn Marino 	{
9551*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
9552*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
9553*e4b17023SJohn Marino 	  else if (code == OMP_ATOMIC_CAPTURE_NEW)
9554*e4b17023SJohn Marino 	    {
9555*e4b17023SJohn Marino 	      c_parser_skip_to_end_of_block_or_statement (parser);
9556*e4b17023SJohn Marino 	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
9557*e4b17023SJohn Marino 		c_parser_consume_token (parser);
9558*e4b17023SJohn Marino 	    }
9559*e4b17023SJohn Marino 	}
9560*e4b17023SJohn Marino       return;
9561*e4b17023SJohn Marino 
9562*e4b17023SJohn Marino     case POSTINCREMENT_EXPR:
9563*e4b17023SJohn Marino       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
9564*e4b17023SJohn Marino 	code = OMP_ATOMIC_CAPTURE_OLD;
9565*e4b17023SJohn Marino       /* FALLTHROUGH */
9566*e4b17023SJohn Marino     case PREINCREMENT_EXPR:
9567*e4b17023SJohn Marino       lhs = TREE_OPERAND (lhs, 0);
9568*e4b17023SJohn Marino       opcode = PLUS_EXPR;
9569*e4b17023SJohn Marino       rhs = integer_one_node;
9570*e4b17023SJohn Marino       break;
9571*e4b17023SJohn Marino 
9572*e4b17023SJohn Marino     case POSTDECREMENT_EXPR:
9573*e4b17023SJohn Marino       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
9574*e4b17023SJohn Marino 	code = OMP_ATOMIC_CAPTURE_OLD;
9575*e4b17023SJohn Marino       /* FALLTHROUGH */
9576*e4b17023SJohn Marino     case PREDECREMENT_EXPR:
9577*e4b17023SJohn Marino       lhs = TREE_OPERAND (lhs, 0);
9578*e4b17023SJohn Marino       opcode = MINUS_EXPR;
9579*e4b17023SJohn Marino       rhs = integer_one_node;
9580*e4b17023SJohn Marino       break;
9581*e4b17023SJohn Marino 
9582*e4b17023SJohn Marino     case COMPOUND_EXPR:
9583*e4b17023SJohn Marino       if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
9584*e4b17023SJohn Marino 	  && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
9585*e4b17023SJohn Marino 	  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
9586*e4b17023SJohn Marino 	  && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
9587*e4b17023SJohn Marino 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
9588*e4b17023SJohn Marino 					      (TREE_OPERAND (lhs, 1), 0), 0)))
9589*e4b17023SJohn Marino 	     == BOOLEAN_TYPE)
9590*e4b17023SJohn Marino 	/* Undo effects of boolean_increment for post {in,de}crement.  */
9591*e4b17023SJohn Marino 	lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
9592*e4b17023SJohn Marino       /* FALLTHRU */
9593*e4b17023SJohn Marino     case MODIFY_EXPR:
9594*e4b17023SJohn Marino       if (TREE_CODE (lhs) == MODIFY_EXPR
9595*e4b17023SJohn Marino 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
9596*e4b17023SJohn Marino 	{
9597*e4b17023SJohn Marino 	  /* Undo effects of boolean_increment.  */
9598*e4b17023SJohn Marino 	  if (integer_onep (TREE_OPERAND (lhs, 1)))
9599*e4b17023SJohn Marino 	    {
9600*e4b17023SJohn Marino 	      /* This is pre or post increment.  */
9601*e4b17023SJohn Marino 	      rhs = TREE_OPERAND (lhs, 1);
9602*e4b17023SJohn Marino 	      lhs = TREE_OPERAND (lhs, 0);
9603*e4b17023SJohn Marino 	      opcode = NOP_EXPR;
9604*e4b17023SJohn Marino 	      if (code == OMP_ATOMIC_CAPTURE_NEW
9605*e4b17023SJohn Marino 		  && !structured_block
9606*e4b17023SJohn Marino 		  && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
9607*e4b17023SJohn Marino 		code = OMP_ATOMIC_CAPTURE_OLD;
9608*e4b17023SJohn Marino 	      break;
9609*e4b17023SJohn Marino 	    }
9610*e4b17023SJohn Marino 	  if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
9611*e4b17023SJohn Marino 	      && TREE_OPERAND (lhs, 0)
9612*e4b17023SJohn Marino 		 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
9613*e4b17023SJohn Marino 	    {
9614*e4b17023SJohn Marino 	      /* This is pre or post decrement.  */
9615*e4b17023SJohn Marino 	      rhs = TREE_OPERAND (lhs, 1);
9616*e4b17023SJohn Marino 	      lhs = TREE_OPERAND (lhs, 0);
9617*e4b17023SJohn Marino 	      opcode = NOP_EXPR;
9618*e4b17023SJohn Marino 	      if (code == OMP_ATOMIC_CAPTURE_NEW
9619*e4b17023SJohn Marino 		  && !structured_block
9620*e4b17023SJohn Marino 		  && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
9621*e4b17023SJohn Marino 		code = OMP_ATOMIC_CAPTURE_OLD;
9622*e4b17023SJohn Marino 	      break;
9623*e4b17023SJohn Marino 	    }
9624*e4b17023SJohn Marino 	}
9625*e4b17023SJohn Marino       /* FALLTHRU */
9626*e4b17023SJohn Marino     default:
9627*e4b17023SJohn Marino       switch (c_parser_peek_token (parser)->type)
9628*e4b17023SJohn Marino 	{
9629*e4b17023SJohn Marino 	case CPP_MULT_EQ:
9630*e4b17023SJohn Marino 	  opcode = MULT_EXPR;
9631*e4b17023SJohn Marino 	  break;
9632*e4b17023SJohn Marino 	case CPP_DIV_EQ:
9633*e4b17023SJohn Marino 	  opcode = TRUNC_DIV_EXPR;
9634*e4b17023SJohn Marino 	  break;
9635*e4b17023SJohn Marino 	case CPP_PLUS_EQ:
9636*e4b17023SJohn Marino 	  opcode = PLUS_EXPR;
9637*e4b17023SJohn Marino 	  break;
9638*e4b17023SJohn Marino 	case CPP_MINUS_EQ:
9639*e4b17023SJohn Marino 	  opcode = MINUS_EXPR;
9640*e4b17023SJohn Marino 	  break;
9641*e4b17023SJohn Marino 	case CPP_LSHIFT_EQ:
9642*e4b17023SJohn Marino 	  opcode = LSHIFT_EXPR;
9643*e4b17023SJohn Marino 	  break;
9644*e4b17023SJohn Marino 	case CPP_RSHIFT_EQ:
9645*e4b17023SJohn Marino 	  opcode = RSHIFT_EXPR;
9646*e4b17023SJohn Marino 	  break;
9647*e4b17023SJohn Marino 	case CPP_AND_EQ:
9648*e4b17023SJohn Marino 	  opcode = BIT_AND_EXPR;
9649*e4b17023SJohn Marino 	  break;
9650*e4b17023SJohn Marino 	case CPP_OR_EQ:
9651*e4b17023SJohn Marino 	  opcode = BIT_IOR_EXPR;
9652*e4b17023SJohn Marino 	  break;
9653*e4b17023SJohn Marino 	case CPP_XOR_EQ:
9654*e4b17023SJohn Marino 	  opcode = BIT_XOR_EXPR;
9655*e4b17023SJohn Marino 	  break;
9656*e4b17023SJohn Marino 	case CPP_EQ:
9657*e4b17023SJohn Marino 	  if (structured_block || code == OMP_ATOMIC)
9658*e4b17023SJohn Marino 	    {
9659*e4b17023SJohn Marino 	      location_t aloc = c_parser_peek_token (parser)->location;
9660*e4b17023SJohn Marino 	      location_t rhs_loc;
9661*e4b17023SJohn Marino 	      enum c_parser_prec oprec = PREC_NONE;
9662*e4b17023SJohn Marino 
9663*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
9664*e4b17023SJohn Marino 	      rhs1 = c_parser_unary_expression (parser).value;
9665*e4b17023SJohn Marino 	      rhs1 = c_fully_fold (rhs1, false, NULL);
9666*e4b17023SJohn Marino 	      if (rhs1 == error_mark_node)
9667*e4b17023SJohn Marino 		goto saw_error;
9668*e4b17023SJohn Marino 	      switch (c_parser_peek_token (parser)->type)
9669*e4b17023SJohn Marino 		{
9670*e4b17023SJohn Marino 		case CPP_SEMICOLON:
9671*e4b17023SJohn Marino 		  if (code == OMP_ATOMIC_CAPTURE_NEW)
9672*e4b17023SJohn Marino 		    {
9673*e4b17023SJohn Marino 		      code = OMP_ATOMIC_CAPTURE_OLD;
9674*e4b17023SJohn Marino 		      v = lhs;
9675*e4b17023SJohn Marino 		      lhs = NULL_TREE;
9676*e4b17023SJohn Marino 		      lhs1 = rhs1;
9677*e4b17023SJohn Marino 		      rhs1 = NULL_TREE;
9678*e4b17023SJohn Marino 		      c_parser_consume_token (parser);
9679*e4b17023SJohn Marino 		      goto restart;
9680*e4b17023SJohn Marino 		    }
9681*e4b17023SJohn Marino 		  c_parser_error (parser,
9682*e4b17023SJohn Marino 				  "invalid form of %<#pragma omp atomic%>");
9683*e4b17023SJohn Marino 		  goto saw_error;
9684*e4b17023SJohn Marino 		case CPP_MULT:
9685*e4b17023SJohn Marino 		  opcode = MULT_EXPR;
9686*e4b17023SJohn Marino 		  oprec = PREC_MULT;
9687*e4b17023SJohn Marino 		  break;
9688*e4b17023SJohn Marino 		case CPP_DIV:
9689*e4b17023SJohn Marino 		  opcode = TRUNC_DIV_EXPR;
9690*e4b17023SJohn Marino 		  oprec = PREC_MULT;
9691*e4b17023SJohn Marino 		  break;
9692*e4b17023SJohn Marino 		case CPP_PLUS:
9693*e4b17023SJohn Marino 		  opcode = PLUS_EXPR;
9694*e4b17023SJohn Marino 		  oprec = PREC_ADD;
9695*e4b17023SJohn Marino 		  break;
9696*e4b17023SJohn Marino 		case CPP_MINUS:
9697*e4b17023SJohn Marino 		  opcode = MINUS_EXPR;
9698*e4b17023SJohn Marino 		  oprec = PREC_ADD;
9699*e4b17023SJohn Marino 		  break;
9700*e4b17023SJohn Marino 		case CPP_LSHIFT:
9701*e4b17023SJohn Marino 		  opcode = LSHIFT_EXPR;
9702*e4b17023SJohn Marino 		  oprec = PREC_SHIFT;
9703*e4b17023SJohn Marino 		  break;
9704*e4b17023SJohn Marino 		case CPP_RSHIFT:
9705*e4b17023SJohn Marino 		  opcode = RSHIFT_EXPR;
9706*e4b17023SJohn Marino 		  oprec = PREC_SHIFT;
9707*e4b17023SJohn Marino 		  break;
9708*e4b17023SJohn Marino 		case CPP_AND:
9709*e4b17023SJohn Marino 		  opcode = BIT_AND_EXPR;
9710*e4b17023SJohn Marino 		  oprec = PREC_BITAND;
9711*e4b17023SJohn Marino 		  break;
9712*e4b17023SJohn Marino 		case CPP_OR:
9713*e4b17023SJohn Marino 		  opcode = BIT_IOR_EXPR;
9714*e4b17023SJohn Marino 		  oprec = PREC_BITOR;
9715*e4b17023SJohn Marino 		  break;
9716*e4b17023SJohn Marino 		case CPP_XOR:
9717*e4b17023SJohn Marino 		  opcode = BIT_XOR_EXPR;
9718*e4b17023SJohn Marino 		  oprec = PREC_BITXOR;
9719*e4b17023SJohn Marino 		  break;
9720*e4b17023SJohn Marino 		default:
9721*e4b17023SJohn Marino 		  c_parser_error (parser,
9722*e4b17023SJohn Marino 				  "invalid operator for %<#pragma omp atomic%>");
9723*e4b17023SJohn Marino 		  goto saw_error;
9724*e4b17023SJohn Marino 		}
9725*e4b17023SJohn Marino 	      loc = aloc;
9726*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
9727*e4b17023SJohn Marino 	      rhs_loc = c_parser_peek_token (parser)->location;
9728*e4b17023SJohn Marino 	      if (commutative_tree_code (opcode))
9729*e4b17023SJohn Marino 		oprec = (enum c_parser_prec) (oprec - 1);
9730*e4b17023SJohn Marino 	      rhs_expr = c_parser_binary_expression (parser, NULL, oprec);
9731*e4b17023SJohn Marino 	      rhs_expr = default_function_array_read_conversion (rhs_loc,
9732*e4b17023SJohn Marino 								 rhs_expr);
9733*e4b17023SJohn Marino 	      rhs = rhs_expr.value;
9734*e4b17023SJohn Marino 	      rhs = c_fully_fold (rhs, false, NULL);
9735*e4b17023SJohn Marino 	      goto stmt_done;
9736*e4b17023SJohn Marino 	    }
9737*e4b17023SJohn Marino 	  /* FALLTHROUGH */
9738*e4b17023SJohn Marino 	default:
9739*e4b17023SJohn Marino 	  c_parser_error (parser,
9740*e4b17023SJohn Marino 			  "invalid operator for %<#pragma omp atomic%>");
9741*e4b17023SJohn Marino 	  goto saw_error;
9742*e4b17023SJohn Marino 	}
9743*e4b17023SJohn Marino 
9744*e4b17023SJohn Marino       /* Arrange to pass the location of the assignment operator to
9745*e4b17023SJohn Marino 	 c_finish_omp_atomic.  */
9746*e4b17023SJohn Marino       loc = c_parser_peek_token (parser)->location;
9747*e4b17023SJohn Marino       c_parser_consume_token (parser);
9748*e4b17023SJohn Marino       {
9749*e4b17023SJohn Marino 	location_t rhs_loc = c_parser_peek_token (parser)->location;
9750*e4b17023SJohn Marino 	rhs_expr = c_parser_expression (parser);
9751*e4b17023SJohn Marino 	rhs_expr = default_function_array_read_conversion (rhs_loc, rhs_expr);
9752*e4b17023SJohn Marino       }
9753*e4b17023SJohn Marino       rhs = rhs_expr.value;
9754*e4b17023SJohn Marino       rhs = c_fully_fold (rhs, false, NULL);
9755*e4b17023SJohn Marino       break;
9756*e4b17023SJohn Marino     }
9757*e4b17023SJohn Marino stmt_done:
9758*e4b17023SJohn Marino   if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
9759*e4b17023SJohn Marino     {
9760*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
9761*e4b17023SJohn Marino 	goto saw_error;
9762*e4b17023SJohn Marino       v = c_parser_unary_expression (parser).value;
9763*e4b17023SJohn Marino       v = c_fully_fold (v, false, NULL);
9764*e4b17023SJohn Marino       if (v == error_mark_node)
9765*e4b17023SJohn Marino 	goto saw_error;
9766*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
9767*e4b17023SJohn Marino 	goto saw_error;
9768*e4b17023SJohn Marino       lhs1 = c_parser_unary_expression (parser).value;
9769*e4b17023SJohn Marino       lhs1 = c_fully_fold (lhs1, false, NULL);
9770*e4b17023SJohn Marino       if (lhs1 == error_mark_node)
9771*e4b17023SJohn Marino 	goto saw_error;
9772*e4b17023SJohn Marino     }
9773*e4b17023SJohn Marino   if (structured_block)
9774*e4b17023SJohn Marino     {
9775*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
9776*e4b17023SJohn Marino       c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
9777*e4b17023SJohn Marino     }
9778*e4b17023SJohn Marino done:
9779*e4b17023SJohn Marino   stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1);
9780*e4b17023SJohn Marino   if (stmt != error_mark_node)
9781*e4b17023SJohn Marino     add_stmt (stmt);
9782*e4b17023SJohn Marino 
9783*e4b17023SJohn Marino   if (!structured_block)
9784*e4b17023SJohn Marino     c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
9785*e4b17023SJohn Marino }
9786*e4b17023SJohn Marino 
9787*e4b17023SJohn Marino 
9788*e4b17023SJohn Marino /* OpenMP 2.5:
9789*e4b17023SJohn Marino    # pragma omp barrier new-line
9790*e4b17023SJohn Marino */
9791*e4b17023SJohn Marino 
9792*e4b17023SJohn Marino static void
c_parser_omp_barrier(c_parser * parser)9793*e4b17023SJohn Marino c_parser_omp_barrier (c_parser *parser)
9794*e4b17023SJohn Marino {
9795*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
9796*e4b17023SJohn Marino   c_parser_consume_pragma (parser);
9797*e4b17023SJohn Marino   c_parser_skip_to_pragma_eol (parser);
9798*e4b17023SJohn Marino 
9799*e4b17023SJohn Marino   c_finish_omp_barrier (loc);
9800*e4b17023SJohn Marino }
9801*e4b17023SJohn Marino 
9802*e4b17023SJohn Marino /* OpenMP 2.5:
9803*e4b17023SJohn Marino    # pragma omp critical [(name)] new-line
9804*e4b17023SJohn Marino      structured-block
9805*e4b17023SJohn Marino 
9806*e4b17023SJohn Marino   LOC is the location of the #pragma itself.  */
9807*e4b17023SJohn Marino 
9808*e4b17023SJohn Marino static tree
c_parser_omp_critical(location_t loc,c_parser * parser)9809*e4b17023SJohn Marino c_parser_omp_critical (location_t loc, c_parser *parser)
9810*e4b17023SJohn Marino {
9811*e4b17023SJohn Marino   tree stmt, name = NULL;
9812*e4b17023SJohn Marino 
9813*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
9814*e4b17023SJohn Marino     {
9815*e4b17023SJohn Marino       c_parser_consume_token (parser);
9816*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_NAME))
9817*e4b17023SJohn Marino 	{
9818*e4b17023SJohn Marino 	  name = c_parser_peek_token (parser)->value;
9819*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
9820*e4b17023SJohn Marino 	  c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
9821*e4b17023SJohn Marino 	}
9822*e4b17023SJohn Marino       else
9823*e4b17023SJohn Marino 	c_parser_error (parser, "expected identifier");
9824*e4b17023SJohn Marino     }
9825*e4b17023SJohn Marino   else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
9826*e4b17023SJohn Marino     c_parser_error (parser, "expected %<(%> or end of line");
9827*e4b17023SJohn Marino   c_parser_skip_to_pragma_eol (parser);
9828*e4b17023SJohn Marino 
9829*e4b17023SJohn Marino   stmt = c_parser_omp_structured_block (parser);
9830*e4b17023SJohn Marino   return c_finish_omp_critical (loc, stmt, name);
9831*e4b17023SJohn Marino }
9832*e4b17023SJohn Marino 
9833*e4b17023SJohn Marino /* OpenMP 2.5:
9834*e4b17023SJohn Marino    # pragma omp flush flush-vars[opt] new-line
9835*e4b17023SJohn Marino 
9836*e4b17023SJohn Marino    flush-vars:
9837*e4b17023SJohn Marino      ( variable-list ) */
9838*e4b17023SJohn Marino 
9839*e4b17023SJohn Marino static void
c_parser_omp_flush(c_parser * parser)9840*e4b17023SJohn Marino c_parser_omp_flush (c_parser *parser)
9841*e4b17023SJohn Marino {
9842*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
9843*e4b17023SJohn Marino   c_parser_consume_pragma (parser);
9844*e4b17023SJohn Marino   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
9845*e4b17023SJohn Marino     c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
9846*e4b17023SJohn Marino   else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
9847*e4b17023SJohn Marino     c_parser_error (parser, "expected %<(%> or end of line");
9848*e4b17023SJohn Marino   c_parser_skip_to_pragma_eol (parser);
9849*e4b17023SJohn Marino 
9850*e4b17023SJohn Marino   c_finish_omp_flush (loc);
9851*e4b17023SJohn Marino }
9852*e4b17023SJohn Marino 
9853*e4b17023SJohn Marino /* Parse the restricted form of the for statement allowed by OpenMP.
9854*e4b17023SJohn Marino    The real trick here is to determine the loop control variable early
9855*e4b17023SJohn Marino    so that we can push a new decl if necessary to make it private.
9856*e4b17023SJohn Marino    LOC is the location of the OMP in "#pragma omp".  */
9857*e4b17023SJohn Marino 
9858*e4b17023SJohn Marino static tree
c_parser_omp_for_loop(location_t loc,c_parser * parser,tree clauses,tree * par_clauses)9859*e4b17023SJohn Marino c_parser_omp_for_loop (location_t loc,
9860*e4b17023SJohn Marino 		       c_parser *parser, tree clauses, tree *par_clauses)
9861*e4b17023SJohn Marino {
9862*e4b17023SJohn Marino   tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
9863*e4b17023SJohn Marino   tree declv, condv, incrv, initv, ret = NULL;
9864*e4b17023SJohn Marino   bool fail = false, open_brace_parsed = false;
9865*e4b17023SJohn Marino   int i, collapse = 1, nbraces = 0;
9866*e4b17023SJohn Marino   location_t for_loc;
9867*e4b17023SJohn Marino   VEC(tree,gc) *for_block = make_tree_vector ();
9868*e4b17023SJohn Marino 
9869*e4b17023SJohn Marino   for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
9870*e4b17023SJohn Marino     if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
9871*e4b17023SJohn Marino       collapse = tree_low_cst (OMP_CLAUSE_COLLAPSE_EXPR (cl), 0);
9872*e4b17023SJohn Marino 
9873*e4b17023SJohn Marino   gcc_assert (collapse >= 1);
9874*e4b17023SJohn Marino 
9875*e4b17023SJohn Marino   declv = make_tree_vec (collapse);
9876*e4b17023SJohn Marino   initv = make_tree_vec (collapse);
9877*e4b17023SJohn Marino   condv = make_tree_vec (collapse);
9878*e4b17023SJohn Marino   incrv = make_tree_vec (collapse);
9879*e4b17023SJohn Marino 
9880*e4b17023SJohn Marino   if (!c_parser_next_token_is_keyword (parser, RID_FOR))
9881*e4b17023SJohn Marino     {
9882*e4b17023SJohn Marino       c_parser_error (parser, "for statement expected");
9883*e4b17023SJohn Marino       return NULL;
9884*e4b17023SJohn Marino     }
9885*e4b17023SJohn Marino   for_loc = c_parser_peek_token (parser)->location;
9886*e4b17023SJohn Marino   c_parser_consume_token (parser);
9887*e4b17023SJohn Marino 
9888*e4b17023SJohn Marino   for (i = 0; i < collapse; i++)
9889*e4b17023SJohn Marino     {
9890*e4b17023SJohn Marino       int bracecount = 0;
9891*e4b17023SJohn Marino 
9892*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
9893*e4b17023SJohn Marino 	goto pop_scopes;
9894*e4b17023SJohn Marino 
9895*e4b17023SJohn Marino       /* Parse the initialization declaration or expression.  */
9896*e4b17023SJohn Marino       if (c_parser_next_tokens_start_declaration (parser))
9897*e4b17023SJohn Marino 	{
9898*e4b17023SJohn Marino 	  if (i > 0)
9899*e4b17023SJohn Marino 	    VEC_safe_push (tree, gc, for_block, c_begin_compound_stmt (true));
9900*e4b17023SJohn Marino 	  c_parser_declaration_or_fndef (parser, true, true, true, true, true, NULL);
9901*e4b17023SJohn Marino 	  decl = check_for_loop_decls (for_loc, flag_isoc99);
9902*e4b17023SJohn Marino 	  if (decl == NULL)
9903*e4b17023SJohn Marino 	    goto error_init;
9904*e4b17023SJohn Marino 	  if (DECL_INITIAL (decl) == error_mark_node)
9905*e4b17023SJohn Marino 	    decl = error_mark_node;
9906*e4b17023SJohn Marino 	  init = decl;
9907*e4b17023SJohn Marino 	}
9908*e4b17023SJohn Marino       else if (c_parser_next_token_is (parser, CPP_NAME)
9909*e4b17023SJohn Marino 	       && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
9910*e4b17023SJohn Marino 	{
9911*e4b17023SJohn Marino 	  struct c_expr decl_exp;
9912*e4b17023SJohn Marino 	  struct c_expr init_exp;
9913*e4b17023SJohn Marino 	  location_t init_loc;
9914*e4b17023SJohn Marino 
9915*e4b17023SJohn Marino 	  decl_exp = c_parser_postfix_expression (parser);
9916*e4b17023SJohn Marino 	  decl = decl_exp.value;
9917*e4b17023SJohn Marino 
9918*e4b17023SJohn Marino 	  c_parser_require (parser, CPP_EQ, "expected %<=%>");
9919*e4b17023SJohn Marino 
9920*e4b17023SJohn Marino 	  init_loc = c_parser_peek_token (parser)->location;
9921*e4b17023SJohn Marino 	  init_exp = c_parser_expr_no_commas (parser, NULL);
9922*e4b17023SJohn Marino 	  init_exp = default_function_array_read_conversion (init_loc,
9923*e4b17023SJohn Marino 							     init_exp);
9924*e4b17023SJohn Marino 	  init = build_modify_expr (init_loc, decl, decl_exp.original_type,
9925*e4b17023SJohn Marino 				    NOP_EXPR, init_loc, init_exp.value,
9926*e4b17023SJohn Marino 				    init_exp.original_type);
9927*e4b17023SJohn Marino 	  init = c_process_expr_stmt (init_loc, init);
9928*e4b17023SJohn Marino 
9929*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
9930*e4b17023SJohn Marino 	}
9931*e4b17023SJohn Marino       else
9932*e4b17023SJohn Marino 	{
9933*e4b17023SJohn Marino 	error_init:
9934*e4b17023SJohn Marino 	  c_parser_error (parser,
9935*e4b17023SJohn Marino 			  "expected iteration declaration or initialization");
9936*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9937*e4b17023SJohn Marino 				     "expected %<)%>");
9938*e4b17023SJohn Marino 	  fail = true;
9939*e4b17023SJohn Marino 	  goto parse_next;
9940*e4b17023SJohn Marino 	}
9941*e4b17023SJohn Marino 
9942*e4b17023SJohn Marino       /* Parse the loop condition.  */
9943*e4b17023SJohn Marino       cond = NULL_TREE;
9944*e4b17023SJohn Marino       if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
9945*e4b17023SJohn Marino 	{
9946*e4b17023SJohn Marino 	  location_t cond_loc = c_parser_peek_token (parser)->location;
9947*e4b17023SJohn Marino 	  struct c_expr cond_expr = c_parser_binary_expression (parser, NULL,
9948*e4b17023SJohn Marino 								PREC_NONE);
9949*e4b17023SJohn Marino 
9950*e4b17023SJohn Marino 	  cond = cond_expr.value;
9951*e4b17023SJohn Marino 	  cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
9952*e4b17023SJohn Marino 	  cond = c_fully_fold (cond, false, NULL);
9953*e4b17023SJohn Marino 	  switch (cond_expr.original_code)
9954*e4b17023SJohn Marino 	    {
9955*e4b17023SJohn Marino 	    case GT_EXPR:
9956*e4b17023SJohn Marino 	    case GE_EXPR:
9957*e4b17023SJohn Marino 	    case LT_EXPR:
9958*e4b17023SJohn Marino 	    case LE_EXPR:
9959*e4b17023SJohn Marino 	      break;
9960*e4b17023SJohn Marino 	    default:
9961*e4b17023SJohn Marino 	      /* Can't be cond = error_mark_node, because we want to preserve
9962*e4b17023SJohn Marino 		 the location until c_finish_omp_for.  */
9963*e4b17023SJohn Marino 	      cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
9964*e4b17023SJohn Marino 	      break;
9965*e4b17023SJohn Marino 	    }
9966*e4b17023SJohn Marino 	  protected_set_expr_location (cond, cond_loc);
9967*e4b17023SJohn Marino 	}
9968*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
9969*e4b17023SJohn Marino 
9970*e4b17023SJohn Marino       /* Parse the increment expression.  */
9971*e4b17023SJohn Marino       incr = NULL_TREE;
9972*e4b17023SJohn Marino       if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
9973*e4b17023SJohn Marino 	{
9974*e4b17023SJohn Marino 	  location_t incr_loc = c_parser_peek_token (parser)->location;
9975*e4b17023SJohn Marino 
9976*e4b17023SJohn Marino 	  incr = c_process_expr_stmt (incr_loc,
9977*e4b17023SJohn Marino 				      c_parser_expression (parser).value);
9978*e4b17023SJohn Marino 	}
9979*e4b17023SJohn Marino       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
9980*e4b17023SJohn Marino 
9981*e4b17023SJohn Marino       if (decl == NULL || decl == error_mark_node || init == error_mark_node)
9982*e4b17023SJohn Marino 	fail = true;
9983*e4b17023SJohn Marino       else
9984*e4b17023SJohn Marino 	{
9985*e4b17023SJohn Marino 	  TREE_VEC_ELT (declv, i) = decl;
9986*e4b17023SJohn Marino 	  TREE_VEC_ELT (initv, i) = init;
9987*e4b17023SJohn Marino 	  TREE_VEC_ELT (condv, i) = cond;
9988*e4b17023SJohn Marino 	  TREE_VEC_ELT (incrv, i) = incr;
9989*e4b17023SJohn Marino 	}
9990*e4b17023SJohn Marino 
9991*e4b17023SJohn Marino     parse_next:
9992*e4b17023SJohn Marino       if (i == collapse - 1)
9993*e4b17023SJohn Marino 	break;
9994*e4b17023SJohn Marino 
9995*e4b17023SJohn Marino       /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
9996*e4b17023SJohn Marino 	 in between the collapsed for loops to be still considered perfectly
9997*e4b17023SJohn Marino 	 nested.  Hopefully the final version clarifies this.
9998*e4b17023SJohn Marino 	 For now handle (multiple) {'s and empty statements.  */
9999*e4b17023SJohn Marino       do
10000*e4b17023SJohn Marino 	{
10001*e4b17023SJohn Marino 	  if (c_parser_next_token_is_keyword (parser, RID_FOR))
10002*e4b17023SJohn Marino 	    {
10003*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
10004*e4b17023SJohn Marino 	      break;
10005*e4b17023SJohn Marino 	    }
10006*e4b17023SJohn Marino 	  else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10007*e4b17023SJohn Marino 	    {
10008*e4b17023SJohn Marino 	      c_parser_consume_token (parser);
10009*e4b17023SJohn Marino 	      bracecount++;
10010*e4b17023SJohn Marino 	    }
10011*e4b17023SJohn Marino 	  else if (bracecount
10012*e4b17023SJohn Marino 		   && c_parser_next_token_is (parser, CPP_SEMICOLON))
10013*e4b17023SJohn Marino 	    c_parser_consume_token (parser);
10014*e4b17023SJohn Marino 	  else
10015*e4b17023SJohn Marino 	    {
10016*e4b17023SJohn Marino 	      c_parser_error (parser, "not enough perfectly nested loops");
10017*e4b17023SJohn Marino 	      if (bracecount)
10018*e4b17023SJohn Marino 		{
10019*e4b17023SJohn Marino 		  open_brace_parsed = true;
10020*e4b17023SJohn Marino 		  bracecount--;
10021*e4b17023SJohn Marino 		}
10022*e4b17023SJohn Marino 	      fail = true;
10023*e4b17023SJohn Marino 	      collapse = 0;
10024*e4b17023SJohn Marino 	      break;
10025*e4b17023SJohn Marino 	    }
10026*e4b17023SJohn Marino 	}
10027*e4b17023SJohn Marino       while (1);
10028*e4b17023SJohn Marino 
10029*e4b17023SJohn Marino       nbraces += bracecount;
10030*e4b17023SJohn Marino     }
10031*e4b17023SJohn Marino 
10032*e4b17023SJohn Marino   save_break = c_break_label;
10033*e4b17023SJohn Marino   c_break_label = size_one_node;
10034*e4b17023SJohn Marino   save_cont = c_cont_label;
10035*e4b17023SJohn Marino   c_cont_label = NULL_TREE;
10036*e4b17023SJohn Marino   body = push_stmt_list ();
10037*e4b17023SJohn Marino 
10038*e4b17023SJohn Marino   if (open_brace_parsed)
10039*e4b17023SJohn Marino     {
10040*e4b17023SJohn Marino       location_t here = c_parser_peek_token (parser)->location;
10041*e4b17023SJohn Marino       stmt = c_begin_compound_stmt (true);
10042*e4b17023SJohn Marino       c_parser_compound_statement_nostart (parser);
10043*e4b17023SJohn Marino       add_stmt (c_end_compound_stmt (here, stmt, true));
10044*e4b17023SJohn Marino     }
10045*e4b17023SJohn Marino   else
10046*e4b17023SJohn Marino     add_stmt (c_parser_c99_block_statement (parser));
10047*e4b17023SJohn Marino   if (c_cont_label)
10048*e4b17023SJohn Marino     {
10049*e4b17023SJohn Marino       tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label);
10050*e4b17023SJohn Marino       SET_EXPR_LOCATION (t, loc);
10051*e4b17023SJohn Marino       add_stmt (t);
10052*e4b17023SJohn Marino     }
10053*e4b17023SJohn Marino 
10054*e4b17023SJohn Marino   body = pop_stmt_list (body);
10055*e4b17023SJohn Marino   c_break_label = save_break;
10056*e4b17023SJohn Marino   c_cont_label = save_cont;
10057*e4b17023SJohn Marino 
10058*e4b17023SJohn Marino   while (nbraces)
10059*e4b17023SJohn Marino     {
10060*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10061*e4b17023SJohn Marino 	{
10062*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
10063*e4b17023SJohn Marino 	  nbraces--;
10064*e4b17023SJohn Marino 	}
10065*e4b17023SJohn Marino       else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
10066*e4b17023SJohn Marino 	c_parser_consume_token (parser);
10067*e4b17023SJohn Marino       else
10068*e4b17023SJohn Marino 	{
10069*e4b17023SJohn Marino 	  c_parser_error (parser, "collapsed loops not perfectly nested");
10070*e4b17023SJohn Marino 	  while (nbraces)
10071*e4b17023SJohn Marino 	    {
10072*e4b17023SJohn Marino 	      location_t here = c_parser_peek_token (parser)->location;
10073*e4b17023SJohn Marino 	      stmt = c_begin_compound_stmt (true);
10074*e4b17023SJohn Marino 	      add_stmt (body);
10075*e4b17023SJohn Marino 	      c_parser_compound_statement_nostart (parser);
10076*e4b17023SJohn Marino 	      body = c_end_compound_stmt (here, stmt, true);
10077*e4b17023SJohn Marino 	      nbraces--;
10078*e4b17023SJohn Marino 	    }
10079*e4b17023SJohn Marino 	  goto pop_scopes;
10080*e4b17023SJohn Marino 	}
10081*e4b17023SJohn Marino     }
10082*e4b17023SJohn Marino 
10083*e4b17023SJohn Marino   /* Only bother calling c_finish_omp_for if we haven't already generated
10084*e4b17023SJohn Marino      an error from the initialization parsing.  */
10085*e4b17023SJohn Marino   if (!fail)
10086*e4b17023SJohn Marino     {
10087*e4b17023SJohn Marino       stmt = c_finish_omp_for (loc, declv, initv, condv, incrv, body, NULL);
10088*e4b17023SJohn Marino       if (stmt)
10089*e4b17023SJohn Marino 	{
10090*e4b17023SJohn Marino 	  if (par_clauses != NULL)
10091*e4b17023SJohn Marino 	    {
10092*e4b17023SJohn Marino 	      tree *c;
10093*e4b17023SJohn Marino 	      for (c = par_clauses; *c ; )
10094*e4b17023SJohn Marino 		if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
10095*e4b17023SJohn Marino 		    && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
10096*e4b17023SJohn Marino 		  c = &OMP_CLAUSE_CHAIN (*c);
10097*e4b17023SJohn Marino 		else
10098*e4b17023SJohn Marino 		  {
10099*e4b17023SJohn Marino 		    for (i = 0; i < collapse; i++)
10100*e4b17023SJohn Marino 		      if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
10101*e4b17023SJohn Marino 			break;
10102*e4b17023SJohn Marino 		    if (i == collapse)
10103*e4b17023SJohn Marino 		      c = &OMP_CLAUSE_CHAIN (*c);
10104*e4b17023SJohn Marino 		    else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
10105*e4b17023SJohn Marino 		      {
10106*e4b17023SJohn Marino 			error_at (loc,
10107*e4b17023SJohn Marino 				  "iteration variable %qD should not be firstprivate",
10108*e4b17023SJohn Marino 				  OMP_CLAUSE_DECL (*c));
10109*e4b17023SJohn Marino 			*c = OMP_CLAUSE_CHAIN (*c);
10110*e4b17023SJohn Marino 		      }
10111*e4b17023SJohn Marino 		    else
10112*e4b17023SJohn Marino 		      {
10113*e4b17023SJohn Marino 			/* Copy lastprivate (decl) clause to OMP_FOR_CLAUSES,
10114*e4b17023SJohn Marino 			   change it to shared (decl) in
10115*e4b17023SJohn Marino 			   OMP_PARALLEL_CLAUSES.  */
10116*e4b17023SJohn Marino 			tree l = build_omp_clause (OMP_CLAUSE_LOCATION (*c),
10117*e4b17023SJohn Marino 						   OMP_CLAUSE_LASTPRIVATE);
10118*e4b17023SJohn Marino 			OMP_CLAUSE_DECL (l) = OMP_CLAUSE_DECL (*c);
10119*e4b17023SJohn Marino 			OMP_CLAUSE_CHAIN (l) = clauses;
10120*e4b17023SJohn Marino 			clauses = l;
10121*e4b17023SJohn Marino 			OMP_CLAUSE_SET_CODE (*c, OMP_CLAUSE_SHARED);
10122*e4b17023SJohn Marino 		      }
10123*e4b17023SJohn Marino 		  }
10124*e4b17023SJohn Marino 	    }
10125*e4b17023SJohn Marino 	  OMP_FOR_CLAUSES (stmt) = clauses;
10126*e4b17023SJohn Marino 	}
10127*e4b17023SJohn Marino       ret = stmt;
10128*e4b17023SJohn Marino     }
10129*e4b17023SJohn Marino pop_scopes:
10130*e4b17023SJohn Marino   while (!VEC_empty (tree, for_block))
10131*e4b17023SJohn Marino     {
10132*e4b17023SJohn Marino       /* FIXME diagnostics: LOC below should be the actual location of
10133*e4b17023SJohn Marino 	 this particular for block.  We need to build a list of
10134*e4b17023SJohn Marino 	 locations to go along with FOR_BLOCK.  */
10135*e4b17023SJohn Marino       stmt = c_end_compound_stmt (loc, VEC_pop (tree, for_block), true);
10136*e4b17023SJohn Marino       add_stmt (stmt);
10137*e4b17023SJohn Marino     }
10138*e4b17023SJohn Marino   release_tree_vector (for_block);
10139*e4b17023SJohn Marino   return ret;
10140*e4b17023SJohn Marino }
10141*e4b17023SJohn Marino 
10142*e4b17023SJohn Marino /* OpenMP 2.5:
10143*e4b17023SJohn Marino    #pragma omp for for-clause[optseq] new-line
10144*e4b17023SJohn Marino      for-loop
10145*e4b17023SJohn Marino 
10146*e4b17023SJohn Marino    LOC is the location of the #pragma token.
10147*e4b17023SJohn Marino */
10148*e4b17023SJohn Marino 
10149*e4b17023SJohn Marino #define OMP_FOR_CLAUSE_MASK				\
10150*e4b17023SJohn Marino 	( (1u << PRAGMA_OMP_CLAUSE_PRIVATE)		\
10151*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
10152*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE)		\
10153*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_REDUCTION)		\
10154*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_ORDERED)		\
10155*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_SCHEDULE)		\
10156*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_COLLAPSE)		\
10157*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
10158*e4b17023SJohn Marino 
10159*e4b17023SJohn Marino static tree
c_parser_omp_for(location_t loc,c_parser * parser)10160*e4b17023SJohn Marino c_parser_omp_for (location_t loc, c_parser *parser)
10161*e4b17023SJohn Marino {
10162*e4b17023SJohn Marino   tree block, clauses, ret;
10163*e4b17023SJohn Marino 
10164*e4b17023SJohn Marino   clauses = c_parser_omp_all_clauses (parser, OMP_FOR_CLAUSE_MASK,
10165*e4b17023SJohn Marino 				      "#pragma omp for");
10166*e4b17023SJohn Marino 
10167*e4b17023SJohn Marino   block = c_begin_compound_stmt (true);
10168*e4b17023SJohn Marino   ret = c_parser_omp_for_loop (loc, parser, clauses, NULL);
10169*e4b17023SJohn Marino   block = c_end_compound_stmt (loc, block, true);
10170*e4b17023SJohn Marino   add_stmt (block);
10171*e4b17023SJohn Marino 
10172*e4b17023SJohn Marino   return ret;
10173*e4b17023SJohn Marino }
10174*e4b17023SJohn Marino 
10175*e4b17023SJohn Marino /* OpenMP 2.5:
10176*e4b17023SJohn Marino    # pragma omp master new-line
10177*e4b17023SJohn Marino      structured-block
10178*e4b17023SJohn Marino 
10179*e4b17023SJohn Marino    LOC is the location of the #pragma token.
10180*e4b17023SJohn Marino */
10181*e4b17023SJohn Marino 
10182*e4b17023SJohn Marino static tree
c_parser_omp_master(location_t loc,c_parser * parser)10183*e4b17023SJohn Marino c_parser_omp_master (location_t loc, c_parser *parser)
10184*e4b17023SJohn Marino {
10185*e4b17023SJohn Marino   c_parser_skip_to_pragma_eol (parser);
10186*e4b17023SJohn Marino   return c_finish_omp_master (loc, c_parser_omp_structured_block (parser));
10187*e4b17023SJohn Marino }
10188*e4b17023SJohn Marino 
10189*e4b17023SJohn Marino /* OpenMP 2.5:
10190*e4b17023SJohn Marino    # pragma omp ordered new-line
10191*e4b17023SJohn Marino      structured-block
10192*e4b17023SJohn Marino 
10193*e4b17023SJohn Marino    LOC is the location of the #pragma itself.
10194*e4b17023SJohn Marino */
10195*e4b17023SJohn Marino 
10196*e4b17023SJohn Marino static tree
c_parser_omp_ordered(location_t loc,c_parser * parser)10197*e4b17023SJohn Marino c_parser_omp_ordered (location_t loc, c_parser *parser)
10198*e4b17023SJohn Marino {
10199*e4b17023SJohn Marino   c_parser_skip_to_pragma_eol (parser);
10200*e4b17023SJohn Marino   return c_finish_omp_ordered (loc, c_parser_omp_structured_block (parser));
10201*e4b17023SJohn Marino }
10202*e4b17023SJohn Marino 
10203*e4b17023SJohn Marino /* OpenMP 2.5:
10204*e4b17023SJohn Marino 
10205*e4b17023SJohn Marino    section-scope:
10206*e4b17023SJohn Marino      { section-sequence }
10207*e4b17023SJohn Marino 
10208*e4b17023SJohn Marino    section-sequence:
10209*e4b17023SJohn Marino      section-directive[opt] structured-block
10210*e4b17023SJohn Marino      section-sequence section-directive structured-block
10211*e4b17023SJohn Marino 
10212*e4b17023SJohn Marino     SECTIONS_LOC is the location of the #pragma omp sections.  */
10213*e4b17023SJohn Marino 
10214*e4b17023SJohn Marino static tree
c_parser_omp_sections_scope(location_t sections_loc,c_parser * parser)10215*e4b17023SJohn Marino c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
10216*e4b17023SJohn Marino {
10217*e4b17023SJohn Marino   tree stmt, substmt;
10218*e4b17023SJohn Marino   bool error_suppress = false;
10219*e4b17023SJohn Marino   location_t loc;
10220*e4b17023SJohn Marino 
10221*e4b17023SJohn Marino   loc = c_parser_peek_token (parser)->location;
10222*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
10223*e4b17023SJohn Marino     {
10224*e4b17023SJohn Marino       /* Avoid skipping until the end of the block.  */
10225*e4b17023SJohn Marino       parser->error = false;
10226*e4b17023SJohn Marino       return NULL_TREE;
10227*e4b17023SJohn Marino     }
10228*e4b17023SJohn Marino 
10229*e4b17023SJohn Marino   stmt = push_stmt_list ();
10230*e4b17023SJohn Marino 
10231*e4b17023SJohn Marino   if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
10232*e4b17023SJohn Marino     {
10233*e4b17023SJohn Marino       substmt = push_stmt_list ();
10234*e4b17023SJohn Marino 
10235*e4b17023SJohn Marino       while (1)
10236*e4b17023SJohn Marino 	{
10237*e4b17023SJohn Marino           c_parser_statement (parser);
10238*e4b17023SJohn Marino 
10239*e4b17023SJohn Marino 	  if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
10240*e4b17023SJohn Marino 	    break;
10241*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10242*e4b17023SJohn Marino 	    break;
10243*e4b17023SJohn Marino 	  if (c_parser_next_token_is (parser, CPP_EOF))
10244*e4b17023SJohn Marino 	    break;
10245*e4b17023SJohn Marino 	}
10246*e4b17023SJohn Marino 
10247*e4b17023SJohn Marino       substmt = pop_stmt_list (substmt);
10248*e4b17023SJohn Marino       substmt = build1 (OMP_SECTION, void_type_node, substmt);
10249*e4b17023SJohn Marino       SET_EXPR_LOCATION (substmt, loc);
10250*e4b17023SJohn Marino       add_stmt (substmt);
10251*e4b17023SJohn Marino     }
10252*e4b17023SJohn Marino 
10253*e4b17023SJohn Marino   while (1)
10254*e4b17023SJohn Marino     {
10255*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10256*e4b17023SJohn Marino 	break;
10257*e4b17023SJohn Marino       if (c_parser_next_token_is (parser, CPP_EOF))
10258*e4b17023SJohn Marino 	break;
10259*e4b17023SJohn Marino 
10260*e4b17023SJohn Marino       loc = c_parser_peek_token (parser)->location;
10261*e4b17023SJohn Marino       if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
10262*e4b17023SJohn Marino 	{
10263*e4b17023SJohn Marino 	  c_parser_consume_pragma (parser);
10264*e4b17023SJohn Marino 	  c_parser_skip_to_pragma_eol (parser);
10265*e4b17023SJohn Marino 	  error_suppress = false;
10266*e4b17023SJohn Marino 	}
10267*e4b17023SJohn Marino       else if (!error_suppress)
10268*e4b17023SJohn Marino 	{
10269*e4b17023SJohn Marino 	  error_at (loc, "expected %<#pragma omp section%> or %<}%>");
10270*e4b17023SJohn Marino 	  error_suppress = true;
10271*e4b17023SJohn Marino 	}
10272*e4b17023SJohn Marino 
10273*e4b17023SJohn Marino       substmt = c_parser_omp_structured_block (parser);
10274*e4b17023SJohn Marino       substmt = build1 (OMP_SECTION, void_type_node, substmt);
10275*e4b17023SJohn Marino       SET_EXPR_LOCATION (substmt, loc);
10276*e4b17023SJohn Marino       add_stmt (substmt);
10277*e4b17023SJohn Marino     }
10278*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
10279*e4b17023SJohn Marino 			     "expected %<#pragma omp section%> or %<}%>");
10280*e4b17023SJohn Marino 
10281*e4b17023SJohn Marino   substmt = pop_stmt_list (stmt);
10282*e4b17023SJohn Marino 
10283*e4b17023SJohn Marino   stmt = make_node (OMP_SECTIONS);
10284*e4b17023SJohn Marino   SET_EXPR_LOCATION (stmt, sections_loc);
10285*e4b17023SJohn Marino   TREE_TYPE (stmt) = void_type_node;
10286*e4b17023SJohn Marino   OMP_SECTIONS_BODY (stmt) = substmt;
10287*e4b17023SJohn Marino 
10288*e4b17023SJohn Marino   return add_stmt (stmt);
10289*e4b17023SJohn Marino }
10290*e4b17023SJohn Marino 
10291*e4b17023SJohn Marino /* OpenMP 2.5:
10292*e4b17023SJohn Marino    # pragma omp sections sections-clause[optseq] newline
10293*e4b17023SJohn Marino      sections-scope
10294*e4b17023SJohn Marino 
10295*e4b17023SJohn Marino    LOC is the location of the #pragma token.
10296*e4b17023SJohn Marino */
10297*e4b17023SJohn Marino 
10298*e4b17023SJohn Marino #define OMP_SECTIONS_CLAUSE_MASK			\
10299*e4b17023SJohn Marino 	( (1u << PRAGMA_OMP_CLAUSE_PRIVATE)		\
10300*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
10301*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE)		\
10302*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_REDUCTION)		\
10303*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
10304*e4b17023SJohn Marino 
10305*e4b17023SJohn Marino static tree
c_parser_omp_sections(location_t loc,c_parser * parser)10306*e4b17023SJohn Marino c_parser_omp_sections (location_t loc, c_parser *parser)
10307*e4b17023SJohn Marino {
10308*e4b17023SJohn Marino   tree block, clauses, ret;
10309*e4b17023SJohn Marino 
10310*e4b17023SJohn Marino   clauses = c_parser_omp_all_clauses (parser, OMP_SECTIONS_CLAUSE_MASK,
10311*e4b17023SJohn Marino 				      "#pragma omp sections");
10312*e4b17023SJohn Marino 
10313*e4b17023SJohn Marino   block = c_begin_compound_stmt (true);
10314*e4b17023SJohn Marino   ret = c_parser_omp_sections_scope (loc, parser);
10315*e4b17023SJohn Marino   if (ret)
10316*e4b17023SJohn Marino     OMP_SECTIONS_CLAUSES (ret) = clauses;
10317*e4b17023SJohn Marino   block = c_end_compound_stmt (loc, block, true);
10318*e4b17023SJohn Marino   add_stmt (block);
10319*e4b17023SJohn Marino 
10320*e4b17023SJohn Marino   return ret;
10321*e4b17023SJohn Marino }
10322*e4b17023SJohn Marino 
10323*e4b17023SJohn Marino /* OpenMP 2.5:
10324*e4b17023SJohn Marino    # pragma parallel parallel-clause new-line
10325*e4b17023SJohn Marino    # pragma parallel for parallel-for-clause new-line
10326*e4b17023SJohn Marino    # pragma parallel sections parallel-sections-clause new-line
10327*e4b17023SJohn Marino 
10328*e4b17023SJohn Marino    LOC is the location of the #pragma token.
10329*e4b17023SJohn Marino */
10330*e4b17023SJohn Marino 
10331*e4b17023SJohn Marino #define OMP_PARALLEL_CLAUSE_MASK			\
10332*e4b17023SJohn Marino 	( (1u << PRAGMA_OMP_CLAUSE_IF)			\
10333*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_PRIVATE)		\
10334*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
10335*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_DEFAULT)		\
10336*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_SHARED)		\
10337*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_COPYIN)		\
10338*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_REDUCTION)		\
10339*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_NUM_THREADS))
10340*e4b17023SJohn Marino 
10341*e4b17023SJohn Marino static tree
c_parser_omp_parallel(location_t loc,c_parser * parser)10342*e4b17023SJohn Marino c_parser_omp_parallel (location_t loc, c_parser *parser)
10343*e4b17023SJohn Marino {
10344*e4b17023SJohn Marino   enum pragma_kind p_kind = PRAGMA_OMP_PARALLEL;
10345*e4b17023SJohn Marino   const char *p_name = "#pragma omp parallel";
10346*e4b17023SJohn Marino   tree stmt, clauses, par_clause, ws_clause, block;
10347*e4b17023SJohn Marino   unsigned int mask = OMP_PARALLEL_CLAUSE_MASK;
10348*e4b17023SJohn Marino 
10349*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_FOR))
10350*e4b17023SJohn Marino     {
10351*e4b17023SJohn Marino       c_parser_consume_token (parser);
10352*e4b17023SJohn Marino       p_kind = PRAGMA_OMP_PARALLEL_FOR;
10353*e4b17023SJohn Marino       p_name = "#pragma omp parallel for";
10354*e4b17023SJohn Marino       mask |= OMP_FOR_CLAUSE_MASK;
10355*e4b17023SJohn Marino       mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT);
10356*e4b17023SJohn Marino     }
10357*e4b17023SJohn Marino   else if (c_parser_next_token_is (parser, CPP_NAME))
10358*e4b17023SJohn Marino     {
10359*e4b17023SJohn Marino       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
10360*e4b17023SJohn Marino       if (strcmp (p, "sections") == 0)
10361*e4b17023SJohn Marino 	{
10362*e4b17023SJohn Marino 	  c_parser_consume_token (parser);
10363*e4b17023SJohn Marino 	  p_kind = PRAGMA_OMP_PARALLEL_SECTIONS;
10364*e4b17023SJohn Marino 	  p_name = "#pragma omp parallel sections";
10365*e4b17023SJohn Marino 	  mask |= OMP_SECTIONS_CLAUSE_MASK;
10366*e4b17023SJohn Marino 	  mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT);
10367*e4b17023SJohn Marino 	}
10368*e4b17023SJohn Marino     }
10369*e4b17023SJohn Marino 
10370*e4b17023SJohn Marino   clauses = c_parser_omp_all_clauses (parser, mask, p_name);
10371*e4b17023SJohn Marino 
10372*e4b17023SJohn Marino   switch (p_kind)
10373*e4b17023SJohn Marino     {
10374*e4b17023SJohn Marino     case PRAGMA_OMP_PARALLEL:
10375*e4b17023SJohn Marino       block = c_begin_omp_parallel ();
10376*e4b17023SJohn Marino       c_parser_statement (parser);
10377*e4b17023SJohn Marino       stmt = c_finish_omp_parallel (loc, clauses, block);
10378*e4b17023SJohn Marino       break;
10379*e4b17023SJohn Marino 
10380*e4b17023SJohn Marino     case PRAGMA_OMP_PARALLEL_FOR:
10381*e4b17023SJohn Marino       block = c_begin_omp_parallel ();
10382*e4b17023SJohn Marino       c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause);
10383*e4b17023SJohn Marino       c_parser_omp_for_loop (loc, parser, ws_clause, &par_clause);
10384*e4b17023SJohn Marino       stmt = c_finish_omp_parallel (loc, par_clause, block);
10385*e4b17023SJohn Marino       OMP_PARALLEL_COMBINED (stmt) = 1;
10386*e4b17023SJohn Marino       break;
10387*e4b17023SJohn Marino 
10388*e4b17023SJohn Marino     case PRAGMA_OMP_PARALLEL_SECTIONS:
10389*e4b17023SJohn Marino       block = c_begin_omp_parallel ();
10390*e4b17023SJohn Marino       c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause);
10391*e4b17023SJohn Marino       stmt = c_parser_omp_sections_scope (loc, parser);
10392*e4b17023SJohn Marino       if (stmt)
10393*e4b17023SJohn Marino 	OMP_SECTIONS_CLAUSES (stmt) = ws_clause;
10394*e4b17023SJohn Marino       stmt = c_finish_omp_parallel (loc, par_clause, block);
10395*e4b17023SJohn Marino       OMP_PARALLEL_COMBINED (stmt) = 1;
10396*e4b17023SJohn Marino       break;
10397*e4b17023SJohn Marino 
10398*e4b17023SJohn Marino     default:
10399*e4b17023SJohn Marino       gcc_unreachable ();
10400*e4b17023SJohn Marino     }
10401*e4b17023SJohn Marino 
10402*e4b17023SJohn Marino   return stmt;
10403*e4b17023SJohn Marino }
10404*e4b17023SJohn Marino 
10405*e4b17023SJohn Marino /* OpenMP 2.5:
10406*e4b17023SJohn Marino    # pragma omp single single-clause[optseq] new-line
10407*e4b17023SJohn Marino      structured-block
10408*e4b17023SJohn Marino 
10409*e4b17023SJohn Marino    LOC is the location of the #pragma.
10410*e4b17023SJohn Marino */
10411*e4b17023SJohn Marino 
10412*e4b17023SJohn Marino #define OMP_SINGLE_CLAUSE_MASK				\
10413*e4b17023SJohn Marino 	( (1u << PRAGMA_OMP_CLAUSE_PRIVATE)		\
10414*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
10415*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_COPYPRIVATE)		\
10416*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
10417*e4b17023SJohn Marino 
10418*e4b17023SJohn Marino static tree
c_parser_omp_single(location_t loc,c_parser * parser)10419*e4b17023SJohn Marino c_parser_omp_single (location_t loc, c_parser *parser)
10420*e4b17023SJohn Marino {
10421*e4b17023SJohn Marino   tree stmt = make_node (OMP_SINGLE);
10422*e4b17023SJohn Marino   SET_EXPR_LOCATION (stmt, loc);
10423*e4b17023SJohn Marino   TREE_TYPE (stmt) = void_type_node;
10424*e4b17023SJohn Marino 
10425*e4b17023SJohn Marino   OMP_SINGLE_CLAUSES (stmt)
10426*e4b17023SJohn Marino     = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
10427*e4b17023SJohn Marino 				"#pragma omp single");
10428*e4b17023SJohn Marino   OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser);
10429*e4b17023SJohn Marino 
10430*e4b17023SJohn Marino   return add_stmt (stmt);
10431*e4b17023SJohn Marino }
10432*e4b17023SJohn Marino 
10433*e4b17023SJohn Marino /* OpenMP 3.0:
10434*e4b17023SJohn Marino    # pragma omp task task-clause[optseq] new-line
10435*e4b17023SJohn Marino 
10436*e4b17023SJohn Marino    LOC is the location of the #pragma.
10437*e4b17023SJohn Marino */
10438*e4b17023SJohn Marino 
10439*e4b17023SJohn Marino #define OMP_TASK_CLAUSE_MASK				\
10440*e4b17023SJohn Marino 	( (1u << PRAGMA_OMP_CLAUSE_IF)			\
10441*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_UNTIED)		\
10442*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_DEFAULT)		\
10443*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_PRIVATE)		\
10444*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
10445*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_SHARED)		\
10446*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_FINAL)		\
10447*e4b17023SJohn Marino 	| (1u << PRAGMA_OMP_CLAUSE_MERGEABLE))
10448*e4b17023SJohn Marino 
10449*e4b17023SJohn Marino static tree
c_parser_omp_task(location_t loc,c_parser * parser)10450*e4b17023SJohn Marino c_parser_omp_task (location_t loc, c_parser *parser)
10451*e4b17023SJohn Marino {
10452*e4b17023SJohn Marino   tree clauses, block;
10453*e4b17023SJohn Marino 
10454*e4b17023SJohn Marino   clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
10455*e4b17023SJohn Marino 				      "#pragma omp task");
10456*e4b17023SJohn Marino 
10457*e4b17023SJohn Marino   block = c_begin_omp_task ();
10458*e4b17023SJohn Marino   c_parser_statement (parser);
10459*e4b17023SJohn Marino   return c_finish_omp_task (loc, clauses, block);
10460*e4b17023SJohn Marino }
10461*e4b17023SJohn Marino 
10462*e4b17023SJohn Marino /* OpenMP 3.0:
10463*e4b17023SJohn Marino    # pragma omp taskwait new-line
10464*e4b17023SJohn Marino */
10465*e4b17023SJohn Marino 
10466*e4b17023SJohn Marino static void
c_parser_omp_taskwait(c_parser * parser)10467*e4b17023SJohn Marino c_parser_omp_taskwait (c_parser *parser)
10468*e4b17023SJohn Marino {
10469*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
10470*e4b17023SJohn Marino   c_parser_consume_pragma (parser);
10471*e4b17023SJohn Marino   c_parser_skip_to_pragma_eol (parser);
10472*e4b17023SJohn Marino 
10473*e4b17023SJohn Marino   c_finish_omp_taskwait (loc);
10474*e4b17023SJohn Marino }
10475*e4b17023SJohn Marino 
10476*e4b17023SJohn Marino /* OpenMP 3.1:
10477*e4b17023SJohn Marino    # pragma omp taskyield new-line
10478*e4b17023SJohn Marino */
10479*e4b17023SJohn Marino 
10480*e4b17023SJohn Marino static void
c_parser_omp_taskyield(c_parser * parser)10481*e4b17023SJohn Marino c_parser_omp_taskyield (c_parser *parser)
10482*e4b17023SJohn Marino {
10483*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
10484*e4b17023SJohn Marino   c_parser_consume_pragma (parser);
10485*e4b17023SJohn Marino   c_parser_skip_to_pragma_eol (parser);
10486*e4b17023SJohn Marino 
10487*e4b17023SJohn Marino   c_finish_omp_taskyield (loc);
10488*e4b17023SJohn Marino }
10489*e4b17023SJohn Marino 
10490*e4b17023SJohn Marino /* Main entry point to parsing most OpenMP pragmas.  */
10491*e4b17023SJohn Marino 
10492*e4b17023SJohn Marino static void
c_parser_omp_construct(c_parser * parser)10493*e4b17023SJohn Marino c_parser_omp_construct (c_parser *parser)
10494*e4b17023SJohn Marino {
10495*e4b17023SJohn Marino   enum pragma_kind p_kind;
10496*e4b17023SJohn Marino   location_t loc;
10497*e4b17023SJohn Marino   tree stmt;
10498*e4b17023SJohn Marino 
10499*e4b17023SJohn Marino   loc = c_parser_peek_token (parser)->location;
10500*e4b17023SJohn Marino   p_kind = c_parser_peek_token (parser)->pragma_kind;
10501*e4b17023SJohn Marino   c_parser_consume_pragma (parser);
10502*e4b17023SJohn Marino 
10503*e4b17023SJohn Marino   switch (p_kind)
10504*e4b17023SJohn Marino     {
10505*e4b17023SJohn Marino     case PRAGMA_OMP_ATOMIC:
10506*e4b17023SJohn Marino       c_parser_omp_atomic (loc, parser);
10507*e4b17023SJohn Marino       return;
10508*e4b17023SJohn Marino     case PRAGMA_OMP_CRITICAL:
10509*e4b17023SJohn Marino       stmt = c_parser_omp_critical (loc, parser);
10510*e4b17023SJohn Marino       break;
10511*e4b17023SJohn Marino     case PRAGMA_OMP_FOR:
10512*e4b17023SJohn Marino       stmt = c_parser_omp_for (loc, parser);
10513*e4b17023SJohn Marino       break;
10514*e4b17023SJohn Marino     case PRAGMA_OMP_MASTER:
10515*e4b17023SJohn Marino       stmt = c_parser_omp_master (loc, parser);
10516*e4b17023SJohn Marino       break;
10517*e4b17023SJohn Marino     case PRAGMA_OMP_ORDERED:
10518*e4b17023SJohn Marino       stmt = c_parser_omp_ordered (loc, parser);
10519*e4b17023SJohn Marino       break;
10520*e4b17023SJohn Marino     case PRAGMA_OMP_PARALLEL:
10521*e4b17023SJohn Marino       stmt = c_parser_omp_parallel (loc, parser);
10522*e4b17023SJohn Marino       break;
10523*e4b17023SJohn Marino     case PRAGMA_OMP_SECTIONS:
10524*e4b17023SJohn Marino       stmt = c_parser_omp_sections (loc, parser);
10525*e4b17023SJohn Marino       break;
10526*e4b17023SJohn Marino     case PRAGMA_OMP_SINGLE:
10527*e4b17023SJohn Marino       stmt = c_parser_omp_single (loc, parser);
10528*e4b17023SJohn Marino       break;
10529*e4b17023SJohn Marino     case PRAGMA_OMP_TASK:
10530*e4b17023SJohn Marino       stmt = c_parser_omp_task (loc, parser);
10531*e4b17023SJohn Marino       break;
10532*e4b17023SJohn Marino     default:
10533*e4b17023SJohn Marino       gcc_unreachable ();
10534*e4b17023SJohn Marino     }
10535*e4b17023SJohn Marino 
10536*e4b17023SJohn Marino   if (stmt)
10537*e4b17023SJohn Marino     gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
10538*e4b17023SJohn Marino }
10539*e4b17023SJohn Marino 
10540*e4b17023SJohn Marino 
10541*e4b17023SJohn Marino /* OpenMP 2.5:
10542*e4b17023SJohn Marino    # pragma omp threadprivate (variable-list) */
10543*e4b17023SJohn Marino 
10544*e4b17023SJohn Marino static void
c_parser_omp_threadprivate(c_parser * parser)10545*e4b17023SJohn Marino c_parser_omp_threadprivate (c_parser *parser)
10546*e4b17023SJohn Marino {
10547*e4b17023SJohn Marino   tree vars, t;
10548*e4b17023SJohn Marino   location_t loc;
10549*e4b17023SJohn Marino 
10550*e4b17023SJohn Marino   c_parser_consume_pragma (parser);
10551*e4b17023SJohn Marino   loc = c_parser_peek_token (parser)->location;
10552*e4b17023SJohn Marino   vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
10553*e4b17023SJohn Marino 
10554*e4b17023SJohn Marino   /* Mark every variable in VARS to be assigned thread local storage.  */
10555*e4b17023SJohn Marino   for (t = vars; t; t = TREE_CHAIN (t))
10556*e4b17023SJohn Marino     {
10557*e4b17023SJohn Marino       tree v = TREE_PURPOSE (t);
10558*e4b17023SJohn Marino 
10559*e4b17023SJohn Marino       /* FIXME diagnostics: Ideally we should keep individual
10560*e4b17023SJohn Marino 	 locations for all the variables in the var list to make the
10561*e4b17023SJohn Marino 	 following errors more precise.  Perhaps
10562*e4b17023SJohn Marino 	 c_parser_omp_var_list_parens() should construct a list of
10563*e4b17023SJohn Marino 	 locations to go along with the var list.  */
10564*e4b17023SJohn Marino 
10565*e4b17023SJohn Marino       /* If V had already been marked threadprivate, it doesn't matter
10566*e4b17023SJohn Marino 	 whether it had been used prior to this point.  */
10567*e4b17023SJohn Marino       if (TREE_CODE (v) != VAR_DECL)
10568*e4b17023SJohn Marino 	error_at (loc, "%qD is not a variable", v);
10569*e4b17023SJohn Marino       else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
10570*e4b17023SJohn Marino 	error_at (loc, "%qE declared %<threadprivate%> after first use", v);
10571*e4b17023SJohn Marino       else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
10572*e4b17023SJohn Marino 	error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
10573*e4b17023SJohn Marino       else if (TREE_TYPE (v) == error_mark_node)
10574*e4b17023SJohn Marino 	;
10575*e4b17023SJohn Marino       else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
10576*e4b17023SJohn Marino 	error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
10577*e4b17023SJohn Marino       else
10578*e4b17023SJohn Marino 	{
10579*e4b17023SJohn Marino 	  if (! DECL_THREAD_LOCAL_P (v))
10580*e4b17023SJohn Marino 	    {
10581*e4b17023SJohn Marino 	      DECL_TLS_MODEL (v) = decl_default_tls_model (v);
10582*e4b17023SJohn Marino 	      /* If rtl has been already set for this var, call
10583*e4b17023SJohn Marino 		 make_decl_rtl once again, so that encode_section_info
10584*e4b17023SJohn Marino 		 has a chance to look at the new decl flags.  */
10585*e4b17023SJohn Marino 	      if (DECL_RTL_SET_P (v))
10586*e4b17023SJohn Marino 		make_decl_rtl (v);
10587*e4b17023SJohn Marino 	    }
10588*e4b17023SJohn Marino 	  C_DECL_THREADPRIVATE_P (v) = 1;
10589*e4b17023SJohn Marino 	}
10590*e4b17023SJohn Marino     }
10591*e4b17023SJohn Marino 
10592*e4b17023SJohn Marino   c_parser_skip_to_pragma_eol (parser);
10593*e4b17023SJohn Marino }
10594*e4b17023SJohn Marino 
10595*e4b17023SJohn Marino /* Parse a transaction attribute (GCC Extension).
10596*e4b17023SJohn Marino 
10597*e4b17023SJohn Marino    transaction-attribute:
10598*e4b17023SJohn Marino      attributes
10599*e4b17023SJohn Marino      [ [ any-word ] ]
10600*e4b17023SJohn Marino 
10601*e4b17023SJohn Marino    The transactional memory language description is written for C++,
10602*e4b17023SJohn Marino    and uses the C++0x attribute syntax.  For compatibility, allow the
10603*e4b17023SJohn Marino    bracket style for transactions in C as well.  */
10604*e4b17023SJohn Marino 
10605*e4b17023SJohn Marino static tree
c_parser_transaction_attributes(c_parser * parser)10606*e4b17023SJohn Marino c_parser_transaction_attributes (c_parser *parser)
10607*e4b17023SJohn Marino {
10608*e4b17023SJohn Marino   tree attr_name, attr = NULL;
10609*e4b17023SJohn Marino 
10610*e4b17023SJohn Marino   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
10611*e4b17023SJohn Marino     return c_parser_attributes (parser);
10612*e4b17023SJohn Marino 
10613*e4b17023SJohn Marino   if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
10614*e4b17023SJohn Marino     return NULL_TREE;
10615*e4b17023SJohn Marino   c_parser_consume_token (parser);
10616*e4b17023SJohn Marino   if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
10617*e4b17023SJohn Marino     goto error1;
10618*e4b17023SJohn Marino 
10619*e4b17023SJohn Marino   attr_name = c_parser_attribute_any_word (parser);
10620*e4b17023SJohn Marino   if (attr_name)
10621*e4b17023SJohn Marino     {
10622*e4b17023SJohn Marino       c_parser_consume_token (parser);
10623*e4b17023SJohn Marino       attr = build_tree_list (attr_name, NULL_TREE);
10624*e4b17023SJohn Marino     }
10625*e4b17023SJohn Marino   else
10626*e4b17023SJohn Marino     c_parser_error (parser, "expected identifier");
10627*e4b17023SJohn Marino 
10628*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
10629*e4b17023SJohn Marino  error1:
10630*e4b17023SJohn Marino   c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
10631*e4b17023SJohn Marino   return attr;
10632*e4b17023SJohn Marino }
10633*e4b17023SJohn Marino 
10634*e4b17023SJohn Marino /* Parse a __transaction_atomic or __transaction_relaxed statement
10635*e4b17023SJohn Marino    (GCC Extension).
10636*e4b17023SJohn Marino 
10637*e4b17023SJohn Marino    transaction-statement:
10638*e4b17023SJohn Marino      __transaction_atomic transaction-attribute[opt] compound-statement
10639*e4b17023SJohn Marino      __transaction_relaxed compound-statement
10640*e4b17023SJohn Marino 
10641*e4b17023SJohn Marino    Note that the only valid attribute is: "outer".
10642*e4b17023SJohn Marino */
10643*e4b17023SJohn Marino 
10644*e4b17023SJohn Marino static tree
c_parser_transaction(c_parser * parser,enum rid keyword)10645*e4b17023SJohn Marino c_parser_transaction (c_parser *parser, enum rid keyword)
10646*e4b17023SJohn Marino {
10647*e4b17023SJohn Marino   unsigned int old_in = parser->in_transaction;
10648*e4b17023SJohn Marino   unsigned int this_in = 1, new_in;
10649*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
10650*e4b17023SJohn Marino   tree stmt, attrs;
10651*e4b17023SJohn Marino 
10652*e4b17023SJohn Marino   gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
10653*e4b17023SJohn Marino       || keyword == RID_TRANSACTION_RELAXED)
10654*e4b17023SJohn Marino       && c_parser_next_token_is_keyword (parser, keyword));
10655*e4b17023SJohn Marino   c_parser_consume_token (parser);
10656*e4b17023SJohn Marino 
10657*e4b17023SJohn Marino   if (keyword == RID_TRANSACTION_RELAXED)
10658*e4b17023SJohn Marino     this_in |= TM_STMT_ATTR_RELAXED;
10659*e4b17023SJohn Marino   else
10660*e4b17023SJohn Marino     {
10661*e4b17023SJohn Marino       attrs = c_parser_transaction_attributes (parser);
10662*e4b17023SJohn Marino       if (attrs)
10663*e4b17023SJohn Marino 	this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
10664*e4b17023SJohn Marino     }
10665*e4b17023SJohn Marino 
10666*e4b17023SJohn Marino   /* Keep track if we're in the lexical scope of an outer transaction.  */
10667*e4b17023SJohn Marino   new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
10668*e4b17023SJohn Marino 
10669*e4b17023SJohn Marino   parser->in_transaction = new_in;
10670*e4b17023SJohn Marino   stmt = c_parser_compound_statement (parser);
10671*e4b17023SJohn Marino   parser->in_transaction = old_in;
10672*e4b17023SJohn Marino 
10673*e4b17023SJohn Marino   if (flag_tm)
10674*e4b17023SJohn Marino     stmt = c_finish_transaction (loc, stmt, this_in);
10675*e4b17023SJohn Marino   else
10676*e4b17023SJohn Marino     error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
10677*e4b17023SJohn Marino 	"%<__transaction_atomic%> without transactional memory support enabled"
10678*e4b17023SJohn Marino 	: "%<__transaction_relaxed %> "
10679*e4b17023SJohn Marino 	"without transactional memory support enabled"));
10680*e4b17023SJohn Marino 
10681*e4b17023SJohn Marino   return stmt;
10682*e4b17023SJohn Marino }
10683*e4b17023SJohn Marino 
10684*e4b17023SJohn Marino /* Parse a __transaction_atomic or __transaction_relaxed expression
10685*e4b17023SJohn Marino    (GCC Extension).
10686*e4b17023SJohn Marino 
10687*e4b17023SJohn Marino    transaction-expression:
10688*e4b17023SJohn Marino      __transaction_atomic ( expression )
10689*e4b17023SJohn Marino      __transaction_relaxed ( expression )
10690*e4b17023SJohn Marino */
10691*e4b17023SJohn Marino 
10692*e4b17023SJohn Marino static struct c_expr
c_parser_transaction_expression(c_parser * parser,enum rid keyword)10693*e4b17023SJohn Marino c_parser_transaction_expression (c_parser *parser, enum rid keyword)
10694*e4b17023SJohn Marino {
10695*e4b17023SJohn Marino   struct c_expr ret;
10696*e4b17023SJohn Marino   unsigned int old_in = parser->in_transaction;
10697*e4b17023SJohn Marino   unsigned int this_in = 1;
10698*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
10699*e4b17023SJohn Marino   tree attrs;
10700*e4b17023SJohn Marino 
10701*e4b17023SJohn Marino   gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
10702*e4b17023SJohn Marino       || keyword == RID_TRANSACTION_RELAXED)
10703*e4b17023SJohn Marino       && c_parser_next_token_is_keyword (parser, keyword));
10704*e4b17023SJohn Marino   c_parser_consume_token (parser);
10705*e4b17023SJohn Marino 
10706*e4b17023SJohn Marino   if (keyword == RID_TRANSACTION_RELAXED)
10707*e4b17023SJohn Marino     this_in |= TM_STMT_ATTR_RELAXED;
10708*e4b17023SJohn Marino   else
10709*e4b17023SJohn Marino     {
10710*e4b17023SJohn Marino       attrs = c_parser_transaction_attributes (parser);
10711*e4b17023SJohn Marino       if (attrs)
10712*e4b17023SJohn Marino 	this_in |= parse_tm_stmt_attr (attrs, 0);
10713*e4b17023SJohn Marino     }
10714*e4b17023SJohn Marino 
10715*e4b17023SJohn Marino   parser->in_transaction = this_in;
10716*e4b17023SJohn Marino   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
10717*e4b17023SJohn Marino     {
10718*e4b17023SJohn Marino       tree expr = c_parser_expression (parser).value;
10719*e4b17023SJohn Marino       ret.original_type = TREE_TYPE (expr);
10720*e4b17023SJohn Marino       ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
10721*e4b17023SJohn Marino       if (this_in & TM_STMT_ATTR_RELAXED)
10722*e4b17023SJohn Marino 	TRANSACTION_EXPR_RELAXED (ret.value) = 1;
10723*e4b17023SJohn Marino       SET_EXPR_LOCATION (ret.value, loc);
10724*e4b17023SJohn Marino       ret.original_code = TRANSACTION_EXPR;
10725*e4b17023SJohn Marino       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
10726*e4b17023SJohn Marino 	{
10727*e4b17023SJohn Marino 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10728*e4b17023SJohn Marino 	  goto error;
10729*e4b17023SJohn Marino 	}
10730*e4b17023SJohn Marino     }
10731*e4b17023SJohn Marino   else
10732*e4b17023SJohn Marino     {
10733*e4b17023SJohn Marino      error:
10734*e4b17023SJohn Marino       ret.value = error_mark_node;
10735*e4b17023SJohn Marino       ret.original_code = ERROR_MARK;
10736*e4b17023SJohn Marino       ret.original_type = NULL;
10737*e4b17023SJohn Marino     }
10738*e4b17023SJohn Marino   parser->in_transaction = old_in;
10739*e4b17023SJohn Marino 
10740*e4b17023SJohn Marino   if (!flag_tm)
10741*e4b17023SJohn Marino     error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
10742*e4b17023SJohn Marino 	"%<__transaction_atomic%> without transactional memory support enabled"
10743*e4b17023SJohn Marino 	: "%<__transaction_relaxed %> "
10744*e4b17023SJohn Marino 	"without transactional memory support enabled"));
10745*e4b17023SJohn Marino 
10746*e4b17023SJohn Marino   return ret;
10747*e4b17023SJohn Marino }
10748*e4b17023SJohn Marino 
10749*e4b17023SJohn Marino /* Parse a __transaction_cancel statement (GCC Extension).
10750*e4b17023SJohn Marino 
10751*e4b17023SJohn Marino    transaction-cancel-statement:
10752*e4b17023SJohn Marino      __transaction_cancel transaction-attribute[opt] ;
10753*e4b17023SJohn Marino 
10754*e4b17023SJohn Marino    Note that the only valid attribute is "outer".
10755*e4b17023SJohn Marino */
10756*e4b17023SJohn Marino 
10757*e4b17023SJohn Marino static tree
c_parser_transaction_cancel(c_parser * parser)10758*e4b17023SJohn Marino c_parser_transaction_cancel(c_parser *parser)
10759*e4b17023SJohn Marino {
10760*e4b17023SJohn Marino   location_t loc = c_parser_peek_token (parser)->location;
10761*e4b17023SJohn Marino   tree attrs;
10762*e4b17023SJohn Marino   bool is_outer = false;
10763*e4b17023SJohn Marino 
10764*e4b17023SJohn Marino   gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
10765*e4b17023SJohn Marino   c_parser_consume_token (parser);
10766*e4b17023SJohn Marino 
10767*e4b17023SJohn Marino   attrs = c_parser_transaction_attributes (parser);
10768*e4b17023SJohn Marino   if (attrs)
10769*e4b17023SJohn Marino     is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
10770*e4b17023SJohn Marino 
10771*e4b17023SJohn Marino   if (!flag_tm)
10772*e4b17023SJohn Marino     {
10773*e4b17023SJohn Marino       error_at (loc, "%<__transaction_cancel%> without "
10774*e4b17023SJohn Marino 		"transactional memory support enabled");
10775*e4b17023SJohn Marino       goto ret_error;
10776*e4b17023SJohn Marino     }
10777*e4b17023SJohn Marino   else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
10778*e4b17023SJohn Marino     {
10779*e4b17023SJohn Marino       error_at (loc, "%<__transaction_cancel%> within a "
10780*e4b17023SJohn Marino 		"%<__transaction_relaxed%>");
10781*e4b17023SJohn Marino       goto ret_error;
10782*e4b17023SJohn Marino     }
10783*e4b17023SJohn Marino   else if (is_outer)
10784*e4b17023SJohn Marino     {
10785*e4b17023SJohn Marino       if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
10786*e4b17023SJohn Marino 	  && !is_tm_may_cancel_outer (current_function_decl))
10787*e4b17023SJohn Marino 	{
10788*e4b17023SJohn Marino 	  error_at (loc, "outer %<__transaction_cancel%> not "
10789*e4b17023SJohn Marino 		    "within outer %<__transaction_atomic%>");
10790*e4b17023SJohn Marino 	  error_at (loc, "  or a %<transaction_may_cancel_outer%> function");
10791*e4b17023SJohn Marino 	  goto ret_error;
10792*e4b17023SJohn Marino 	}
10793*e4b17023SJohn Marino     }
10794*e4b17023SJohn Marino   else if (parser->in_transaction == 0)
10795*e4b17023SJohn Marino     {
10796*e4b17023SJohn Marino       error_at (loc, "%<__transaction_cancel%> not within "
10797*e4b17023SJohn Marino 		"%<__transaction_atomic%>");
10798*e4b17023SJohn Marino       goto ret_error;
10799*e4b17023SJohn Marino     }
10800*e4b17023SJohn Marino 
10801*e4b17023SJohn Marino   return add_stmt (build_tm_abort_call (loc, is_outer));
10802*e4b17023SJohn Marino 
10803*e4b17023SJohn Marino  ret_error:
10804*e4b17023SJohn Marino   return build1 (NOP_EXPR, void_type_node, error_mark_node);
10805*e4b17023SJohn Marino }
10806*e4b17023SJohn Marino 
10807*e4b17023SJohn Marino /* Parse a single source file.  */
10808*e4b17023SJohn Marino 
10809*e4b17023SJohn Marino void
c_parse_file(void)10810*e4b17023SJohn Marino c_parse_file (void)
10811*e4b17023SJohn Marino {
10812*e4b17023SJohn Marino   /* Use local storage to begin.  If the first token is a pragma, parse it.
10813*e4b17023SJohn Marino      If it is #pragma GCC pch_preprocess, then this will load a PCH file
10814*e4b17023SJohn Marino      which will cause garbage collection.  */
10815*e4b17023SJohn Marino   c_parser tparser;
10816*e4b17023SJohn Marino 
10817*e4b17023SJohn Marino   memset (&tparser, 0, sizeof tparser);
10818*e4b17023SJohn Marino   the_parser = &tparser;
10819*e4b17023SJohn Marino 
10820*e4b17023SJohn Marino   if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
10821*e4b17023SJohn Marino     c_parser_pragma_pch_preprocess (&tparser);
10822*e4b17023SJohn Marino 
10823*e4b17023SJohn Marino   the_parser = ggc_alloc_c_parser ();
10824*e4b17023SJohn Marino   *the_parser = tparser;
10825*e4b17023SJohn Marino 
10826*e4b17023SJohn Marino   /* Initialize EH, if we've been told to do so.  */
10827*e4b17023SJohn Marino   if (flag_exceptions)
10828*e4b17023SJohn Marino     using_eh_for_cleanups ();
10829*e4b17023SJohn Marino 
10830*e4b17023SJohn Marino   c_parser_translation_unit (the_parser);
10831*e4b17023SJohn Marino   the_parser = NULL;
10832*e4b17023SJohn Marino }
10833*e4b17023SJohn Marino 
10834*e4b17023SJohn Marino #include "gt-c-parser.h"
10835